summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt28
-rw-r--r--RELEASE.txt8
-rw-r--r--changes.old6027
-rw-r--r--lib/edit/a_info.txt186
-rw-r--r--lib/edit/ab_info.txt6
-rw-r--r--lib/edit/ba_info.txt46
-rw-r--r--lib/edit/d_info.txt2
-rw-r--r--lib/edit/e_info.txt18
-rw-r--r--lib/edit/k_info.txt42
-rw-r--r--lib/edit/ow_info.txt2
-rw-r--r--lib/edit/p_info.txt19
-rw-r--r--lib/edit/st_info.txt17
-rw-r--r--lib/edit/t_basic.txt80
-rw-r--r--lib/edit/t_bree.txt5
-rw-r--r--lib/edit/t_gondol.txt5
-rw-r--r--lib/edit/t_minas.txt5
-rw-r--r--lib/file/elvish.txt218
-rw-r--r--lib/help/advanced.hlp5
-rw-r--r--lib/help/c_merch.txt29
-rw-r--r--lib/help/command.txt27
-rw-r--r--lib/help/defines.txt1
-rw-r--r--lib/help/lua.hlp34
-rw-r--r--lib/help/lua_gf.txt45
-rw-r--r--lib/help/lua_intr.txt133
-rw-r--r--lib/help/lua_mon.txt535
-rw-r--r--lib/help/lua_play.txt1225
-rw-r--r--lib/help/lua_pow.txt266
-rw-r--r--lib/help/lua_ques.txt299
-rw-r--r--lib/help/lua_skil.txt342
-rw-r--r--lib/help/lua_spel.txt2150
-rw-r--r--lib/help/lua_util.txt898
-rw-r--r--lib/help/macrofaq.txt16
-rw-r--r--lib/help/option.txt69
-rw-r--r--lib/mods/theme/edit/a_info.txt228
-rw-r--r--lib/mods/theme/edit/ab_info.txt6
-rw-r--r--lib/mods/theme/edit/ba_info.txt46
-rw-r--r--lib/mods/theme/edit/d_info.txt5
-rw-r--r--lib/mods/theme/edit/e_info.txt22
-rw-r--r--lib/mods/theme/edit/k_info.txt52
-rw-r--r--lib/mods/theme/edit/ow_info.txt5
-rw-r--r--lib/mods/theme/edit/p_info.txt19
-rw-r--r--lib/mods/theme/edit/r_info.txt4
-rw-r--r--lib/mods/theme/edit/st_info.txt14
-rw-r--r--lib/mods/theme/edit/t_basic.txt66
-rw-r--r--lib/mods/theme/edit/t_gondol.txt5
-rw-r--r--lib/mods/theme/file/elvish.txt218
-rw-r--r--lib/mods/theme/help/advanced.hlp5
-rw-r--r--lib/mods/theme/help/c_merch.txt29
-rw-r--r--lib/mods/theme/help/command.txt27
-rw-r--r--lib/mods/theme/help/defines.txt1
-rw-r--r--lib/mods/theme/help/lua.hlp34
-rw-r--r--lib/mods/theme/help/lua_gf.txt45
-rw-r--r--lib/mods/theme/help/lua_intr.txt133
-rw-r--r--lib/mods/theme/help/lua_mon.txt535
-rw-r--r--lib/mods/theme/help/lua_play.txt1225
-rw-r--r--lib/mods/theme/help/lua_pow.txt266
-rw-r--r--lib/mods/theme/help/lua_ques.txt299
-rw-r--r--lib/mods/theme/help/lua_skil.txt342
-rw-r--r--lib/mods/theme/help/lua_spel.txt2150
-rw-r--r--lib/mods/theme/help/lua_util.txt898
-rw-r--r--lib/mods/theme/help/macrofaq.txt16
-rw-r--r--lib/mods/theme/help/option.txt69
-rw-r--r--lib/mods/theme/pref/graf-ami.prf64
-rw-r--r--lib/mods/theme/pref/graf-dos.prf15
-rw-r--r--lib/mods/theme/pref/graf-ibm.prf6237
-rw-r--r--lib/mods/theme/pref/graf-iso.prf5963
-rw-r--r--lib/mods/theme/pref/graf-mac.prf15
-rw-r--r--lib/mods/theme/pref/graf-new.prf6934
-rw-r--r--lib/mods/theme/pref/graf-sdl.prf37
-rw-r--r--lib/mods/theme/pref/graf-win.prf16
-rw-r--r--lib/mods/theme/pref/graf-x11.prf37
-rw-r--r--lib/mods/theme/pref/graf-xxx.prf3267
-rw-r--r--lib/mods/theme/pref/graf.prf51
-rw-r--r--lib/mods/theme/user/all.prf48
-rw-r--r--lib/pref/graf-ami.prf64
-rw-r--r--lib/pref/graf-dos.prf15
-rw-r--r--lib/pref/graf-iso.prf6878
-rw-r--r--lib/pref/graf-mac.prf15
-rw-r--r--lib/pref/graf-new.prf6847
-rw-r--r--lib/pref/graf-sdl.prf37
-rw-r--r--lib/pref/graf-win.prf16
-rw-r--r--lib/pref/graf-x11.prf37
-rw-r--r--lib/pref/graf-xxx.prf6348
-rw-r--r--lib/pref/graf.prf51
-rw-r--r--lib/xtra/graf/16x16.bmpbin1164238 -> 0 bytes
-rw-r--r--lib/xtra/graf/16x16.pngbin210021 -> 0 bytes
-rw-r--r--lib/xtra/graf/8x8.bmpbin203830 -> 0 bytes
-rw-r--r--lib/xtra/graf/8x8.pngbin44451 -> 0 bytes
-rw-r--r--lib/xtra/graf/mask.bmpbin1164342 -> 0 bytes
-rw-r--r--lib/xtra/graf/tome-128.pngbin45589 -> 0 bytes
-rw-r--r--lib/xtra/sound/Sound.cfg79
-rw-r--r--lib/xtra/sound/readme.txt33
-rw-r--r--src/.gitignore2
-rw-r--r--src/CMakeLists.txt162
-rw-r--r--src/ability_type.hpp27
-rw-r--r--src/ability_type_fwd.hpp3
-rw-r--r--src/activation.hpp13
-rw-r--r--src/alchemist_recipe.hpp11
-rw-r--r--src/alchemist_recipe_fwd.hpp3
-rw-r--r--src/alloc_entry.hpp20
-rw-r--r--src/alloc_entry_fwd.hpp3
-rw-r--r--src/angband.h26
-rw-r--r--src/angband.rc15
-rw-r--r--src/artifact_select_flag.hpp18
-rw-r--r--src/artifact_select_flag_fwd.hpp3
-rw-r--r--src/artifact_type.hpp60
-rw-r--r--src/artifact_type_fwd.hpp3
-rw-r--r--src/between_exit.hpp18
-rw-r--r--src/birth.cc (renamed from src/birth.c)463
-rw-r--r--src/birth.h14
-rw-r--r--src/birth.hpp9
-rw-r--r--src/birther.hpp35
-rw-r--r--src/bldg.cc (renamed from src/bldg.c)878
-rw-r--r--src/bldg.hpp9
-rw-r--r--src/body.hpp12
-rw-r--r--src/cave.cc (renamed from src/cave.c)1067
-rw-r--r--src/cave.hpp55
-rw-r--r--src/cave_type.hpp65
-rw-r--r--src/cave_type_fwd.hpp3
-rw-r--r--src/cli_comm.hpp13
-rw-r--r--src/cli_comm_fwd.hpp3
-rw-r--r--src/cmd1.cc (renamed from src/cmd1.c)531
-rw-r--r--src/cmd1.hpp25
-rw-r--r--src/cmd2.cc (renamed from src/cmd2.c)962
-rw-r--r--src/cmd2.hpp34
-rw-r--r--src/cmd3.cc (renamed from src/cmd3.c)731
-rw-r--r--src/cmd3.hpp24
-rw-r--r--src/cmd4.cc (renamed from src/cmd4.c)834
-rw-r--r--src/cmd4.hpp28
-rw-r--r--src/cmd5.cc (renamed from src/cmd5.c)760
-rw-r--r--src/cmd5.hpp16
-rw-r--r--src/cmd6.cc (renamed from src/cmd6.c)4978
-rw-r--r--src/cmd6.hpp18
-rw-r--r--src/cmd7.cc (renamed from src/cmd7.c)1036
-rw-r--r--src/cmd7.hpp30
-rw-r--r--src/cmovie.c496
-rw-r--r--src/config.h66
-rw-r--r--src/corrupt.cc (renamed from src/corrupt.c)51
-rw-r--r--src/corrupt.hpp47
-rw-r--r--src/defines.h869
-rw-r--r--src/deity_type.hpp11
-rw-r--r--src/deity_type_fwd.hpp3
-rw-r--r--src/device_allocation.cc20
-rw-r--r--src/device_allocation.hpp17
-rw-r--r--src/device_allocation_fwd.hpp8
-rw-r--r--src/dice.cc98
-rw-r--r--src/dice.hpp13
-rw-r--r--src/dice_fwd.hpp12
-rw-r--r--src/dungeon.cc (renamed from src/dungeon.c)754
-rw-r--r--src/dungeon.h14
-rw-r--r--src/dungeon.hpp6
-rw-r--r--src/dungeon_info_type.hpp72
-rw-r--r--src/dungeon_info_type_fwd.hpp3
-rw-r--r--src/effect_type.hpp17
-rw-r--r--src/ego_item_type.hpp68
-rw-r--r--src/ego_item_type_fwd.hpp3
-rw-r--r--src/externs.h2377
-rw-r--r--src/fate.hpp22
-rw-r--r--src/feature_type.hpp37
-rw-r--r--src/feature_type_fwd.hpp3
-rw-r--r--src/files.cc (renamed from src/files.c)416
-rw-r--r--src/files.h17
-rw-r--r--src/files.hpp27
-rw-r--r--src/flags_group.hpp20
-rw-r--r--src/gen_evol.cc (renamed from src/gen_evol.c)17
-rw-r--r--src/gen_evol.hpp6
-rw-r--r--src/gen_maze.cc (renamed from src/gen_maze.c)23
-rw-r--r--src/gen_maze.hpp5
-rw-r--r--src/generate.cc (renamed from src/generate.c)563
-rw-r--r--src/generate.hpp12
-rw-r--r--src/gf_name_type.hpp10
-rw-r--r--src/gods.cc (renamed from src/gods.c)26
-rw-r--r--src/gods.hpp13
-rw-r--r--src/h-basic.h10
-rw-r--r--src/h-config.h185
-rw-r--r--src/h-define.h19
-rw-r--r--src/h-system.h44
-rw-r--r--src/h-type.h8
-rw-r--r--src/help.cc (renamed from src/help.c)21
-rw-r--r--src/help.hpp11
-rw-r--r--src/help_info.hpp17
-rw-r--r--src/hiscore.cc (renamed from src/hiscore.c)6
-rw-r--r--src/hiscore.hpp (renamed from src/hiscore.h)24
-rw-r--r--src/hist_type.hpp16
-rw-r--r--src/hist_type_fwd.hpp3
-rw-r--r--src/hook_build_room1_in.hpp8
-rw-r--r--src/hook_calculate_hp_in.hpp7
-rw-r--r--src/hook_calculate_hp_out.hpp7
-rw-r--r--src/hook_chardump_in.hpp7
-rw-r--r--src/hook_chat_in.hpp7
-rw-r--r--src/hook_drop_in.hpp5
-rw-r--r--src/hook_eat_in.hpp7
-rw-r--r--src/hook_eat_out.hpp7
-rw-r--r--src/hook_enter_dungeon_in.hpp7
-rw-r--r--src/hook_get_in.hpp8
-rw-r--r--src/hook_give_in.hpp6
-rw-r--r--src/hook_identify_in.hpp9
-rw-r--r--src/hook_init_quest_in.hpp5
-rw-r--r--src/hook_mon_speak_in.hpp8
-rw-r--r--src/hook_monster_ai_in.hpp9
-rw-r--r--src/hook_monster_ai_out.hpp8
-rw-r--r--src/hook_monster_death_in.hpp7
-rw-r--r--src/hook_move_in.hpp6
-rw-r--r--src/hook_new_monster_end_in.hpp7
-rw-r--r--src/hook_new_monster_in.hpp7
-rw-r--r--src/hook_player_level_in.hpp5
-rw-r--r--src/hook_quest_fail_in.hpp7
-rw-r--r--src/hook_quest_finish_in.hpp7
-rw-r--r--src/hook_stair_in.hpp7
-rw-r--r--src/hook_stair_out.hpp7
-rw-r--r--src/hook_wield_in.hpp7
-rw-r--r--src/hook_wild_gen_in.hpp7
-rw-r--r--src/hooks.cc113
-rw-r--r--src/hooks.hpp10
-rw-r--r--src/identify_mode.hpp3
-rw-r--r--src/include/sglib.h1952
-rw-r--r--src/include/tome/enum_string_map.hpp55
-rw-r--r--src/include/tome/make_array.hpp13
-rw-r--r--src/include/tome/squelch/automatizer.hpp156
-rw-r--r--src/include/tome/squelch/automatizer_fwd.hpp10
-rw-r--r--src/include/tome/squelch/condition.hpp632
-rw-r--r--src/include/tome/squelch/condition_fwd.hpp15
-rw-r--r--src/include/tome/squelch/condition_metadata.hpp12
-rw-r--r--src/include/tome/squelch/condition_metadata_fwd.hpp14
-rw-r--r--src/include/tome/squelch/cursor.hpp50
-rw-r--r--src/include/tome/squelch/cursor_fwd.hpp10
-rw-r--r--src/include/tome/squelch/object_status.hpp28
-rw-r--r--src/include/tome/squelch/object_status_fwd.hpp12
-rw-r--r--src/include/tome/squelch/rule.hpp162
-rw-r--r--src/include/tome/squelch/rule_fwd.hpp16
-rw-r--r--src/include/tome/squelch/tree_printer.hpp49
-rw-r--r--src/include/tome/squelch/tree_printer_fwd.hpp10
-rw-r--r--src/init1.cc (renamed from src/init1.c)1426
-rw-r--r--src/init1.hpp27
-rw-r--r--src/init2.c2738
-rw-r--r--src/init2.cc1525
-rw-r--r--src/init2.h14
-rw-r--r--src/init2.hpp9
-rw-r--r--src/inscription_info_type.hpp14
-rw-r--r--src/inventory.hpp35
-rw-r--r--src/joke.cc (renamed from src/joke.c)17
-rw-r--r--src/joke.hpp5
-rw-r--r--src/levels.cc (renamed from src/levels.c)15
-rw-r--r--src/levels.hpp13
-rw-r--r--src/loadsave.cc (renamed from src/loadsave.c)2499
-rw-r--r--src/loadsave.h16
-rw-r--r--src/loadsave.hpp7
-rw-r--r--src/lua_bind.c342
-rw-r--r--src/lua_bind.cc277
-rw-r--r--src/lua_bind.hpp34
-rw-r--r--src/magic_power.hpp15
-rw-r--r--src/maid-x11.c855
-rw-r--r--src/main-crb.c5963
-rw-r--r--src/main-gcu.c178
-rw-r--r--src/main-gtk2.c2575
-rw-r--r--src/main-sdl.c134
-rw-r--r--src/main-win.c816
-rw-r--r--src/main-x11.c485
-rw-r--r--src/main-xaw.c1880
-rw-r--r--src/main-xxx.c785
-rw-r--r--src/main.c303
-rw-r--r--src/martial_arts.hpp18
-rw-r--r--src/melee1.cc (renamed from src/melee1.c)93
-rw-r--r--src/melee1.hpp7
-rw-r--r--src/melee2.cc (renamed from src/melee2.c)636
-rw-r--r--src/melee2.hpp12
-rw-r--r--src/messages.cc (renamed from src/messages.c)16
-rw-r--r--src/messages.h13
-rw-r--r--src/messages.hpp9
-rw-r--r--src/meta_class_type.hpp10
-rw-r--r--src/meta_class_type_fwd.hpp3
-rw-r--r--src/mimic.cc (renamed from src/mimic.c)39
-rw-r--r--src/mimic.hpp10
-rw-r--r--src/module_type.hpp64
-rw-r--r--src/modules.cc (renamed from src/modules.c)151
-rw-r--r--src/modules.h15
-rw-r--r--src/modules.hpp11
-rw-r--r--src/monster1.cc (renamed from src/monster1.c)101
-rw-r--r--src/monster1.hpp5
-rw-r--r--src/monster2.cc (renamed from src/monster2.c)410
-rw-r--r--src/monster2.hpp52
-rw-r--r--src/monster3.cc (renamed from src/monster3.c)71
-rw-r--r--src/monster3.hpp20
-rw-r--r--src/monster_blow.hpp19
-rw-r--r--src/monster_ego.hpp81
-rw-r--r--src/monster_ego_fwd.hpp3
-rw-r--r--src/monster_power.hpp14
-rw-r--r--src/monster_race.hpp116
-rw-r--r--src/monster_race_fwd.hpp3
-rw-r--r--src/monster_type.hpp90
-rw-r--r--src/monster_type_fwd.hpp3
-rw-r--r--src/move_info_type.hpp15
-rw-r--r--src/music.hpp17
-rw-r--r--src/notes.cc (renamed from src/notes.c)22
-rw-r--r--src/notes.hpp6
-rw-r--r--src/obj_theme.hpp15
-rw-r--r--src/obj_theme_fwd.hpp3
-rw-r--r--src/object1.cc (renamed from src/object1.c)1051
-rw-r--r--src/object1.hpp46
-rw-r--r--src/object2.cc (renamed from src/object2.c)535
-rw-r--r--src/object2.hpp69
-rw-r--r--src/object_filter.cc98
-rw-r--r--src/object_filter.hpp99
-rw-r--r--src/object_kind.hpp86
-rw-r--r--src/object_kind_fwd.hpp3
-rw-r--r--src/object_type.hpp104
-rw-r--r--src/object_type_fwd.hpp3
-rw-r--r--src/option_type.hpp40
-rw-r--r--src/options.cc89
-rw-r--r--src/options.hpp89
-rw-r--r--src/owner_type.hpp39
-rw-r--r--src/owner_type_fwd.hpp3
-rw-r--r--src/player_class.hpp105
-rw-r--r--src/player_class_fwd.hpp3
-rw-r--r--src/player_defs.hpp6
-rw-r--r--src/player_race.hpp83
-rw-r--r--src/player_race_fwd.hpp3
-rw-r--r--src/player_race_mod.hpp87
-rw-r--r--src/player_race_mod_fwd.hpp3
-rw-r--r--src/player_sex.hpp17
-rw-r--r--src/player_sex_fwd.hpp3
-rw-r--r--src/player_spec.hpp38
-rw-r--r--src/player_spec_fwd.hpp3
-rw-r--r--src/player_type.hpp423
-rw-r--r--src/player_type_fwd.hpp3
-rw-r--r--src/plots.c403
-rw-r--r--src/plots.h68
-rw-r--r--src/power_type.hpp19
-rw-r--r--src/powers.cc (renamed from src/powers.c)253
-rw-r--r--src/powers.hpp74
-rw-r--r--src/q_betwen.cc (renamed from src/q_betwen.c)74
-rw-r--r--src/q_betwen.hpp5
-rw-r--r--src/q_bounty.cc (renamed from src/q_bounty.c)85
-rw-r--r--src/q_bounty.hpp8
-rw-r--r--src/q_dragons.cc (renamed from src/q_dragons.c)37
-rw-r--r--src/q_dragons.hpp5
-rw-r--r--src/q_eol.cc (renamed from src/q_eol.c)98
-rw-r--r--src/q_eol.hpp5
-rw-r--r--src/q_evil.cc (renamed from src/q_evil.c)38
-rw-r--r--src/q_evil.hpp5
-rw-r--r--src/q_fireprof.cc (renamed from src/q_fireprof.c)111
-rw-r--r--src/q_fireprof.hpp7
-rw-r--r--src/q_god.cc (renamed from src/q_god.c)85
-rw-r--r--src/q_god.hpp6
-rw-r--r--src/q_haunted.cc (renamed from src/q_haunted.c)39
-rw-r--r--src/q_haunted.hpp5
-rw-r--r--src/q_hobbit.cc (renamed from src/q_hobbit.c)119
-rw-r--r--src/q_hobbit.hpp5
-rw-r--r--src/q_invas.cc (renamed from src/q_invas.c)92
-rw-r--r--src/q_invas.hpp5
-rw-r--r--src/q_library.cc (renamed from src/q_library.c)36
-rw-r--r--src/q_library.hpp8
-rw-r--r--src/q_main.cc (renamed from src/q_main.c)106
-rw-r--r--src/q_main.hpp7
-rw-r--r--src/q_narsil.cc (renamed from src/q_narsil.c)68
-rw-r--r--src/q_narsil.hpp5
-rw-r--r--src/q_nazgul.c116
-rw-r--r--src/q_nazgul.cc144
-rw-r--r--src/q_nazgul.hpp5
-rw-r--r--src/q_nirna.cc (renamed from src/q_nirna.c)46
-rw-r--r--src/q_nirna.hpp5
-rw-r--r--src/q_one.cc (renamed from src/q_one.c)141
-rw-r--r--src/q_one.hpp5
-rw-r--r--src/q_poison.cc (renamed from src/q_poison.c)78
-rw-r--r--src/q_poison.hpp5
-rw-r--r--src/q_rand.cc (renamed from src/q_rand.c)302
-rw-r--r--src/q_rand.hpp8
-rw-r--r--src/q_shroom.cc (renamed from src/q_shroom.c)206
-rw-r--r--src/q_shroom.hpp5
-rw-r--r--src/q_spider.cc (renamed from src/q_spider.c)45
-rw-r--r--src/q_spider.hpp5
-rw-r--r--src/q_thief.cc (renamed from src/q_thief.c)52
-rw-r--r--src/q_thief.hpp5
-rw-r--r--src/q_thrain.cc (renamed from src/q_thrain.c)93
-rw-r--r--src/q_thrain.hpp5
-rw-r--r--src/q_troll.cc (renamed from src/q_troll.c)79
-rw-r--r--src/q_troll.hpp5
-rw-r--r--src/q_ultrae.cc (renamed from src/q_ultrae.c)5
-rw-r--r--src/q_ultrae.hpp5
-rw-r--r--src/q_ultrag.cc (renamed from src/q_ultrag.c)82
-rw-r--r--src/q_ultrag.hpp5
-rw-r--r--src/q_wight.cc (renamed from src/q_wight.c)66
-rw-r--r--src/q_wight.hpp5
-rw-r--r--src/q_wolves.cc (renamed from src/q_wolves.c)39
-rw-r--r--src/q_wolves.hpp5
-rw-r--r--src/quark.cc (renamed from src/quark.c)16
-rw-r--r--src/quark.h18
-rw-r--r--src/quark.hpp12
-rw-r--r--src/quest.cc17
-rw-r--r--src/quest.hpp3
-rw-r--r--src/quest_type.hpp27
-rw-r--r--src/randart.cc (renamed from src/randart.c)77
-rw-r--r--src/randart.hpp9
-rw-r--r--src/randart_gen_type.hpp9
-rw-r--r--src/randart_gen_type_fwd.hpp3
-rw-r--r--src/randart_part_type.hpp43
-rw-r--r--src/randart_part_type_fwd.hpp3
-rw-r--r--src/random_artifact.hpp18
-rw-r--r--src/random_quest.hpp10
-rw-r--r--src/random_spell.hpp21
-rw-r--r--src/range.cc (renamed from src/range.c)4
-rw-r--r--src/range.hpp15
-rw-r--r--src/range_fwd.hpp4
-rw-r--r--src/readdib.c342
-rw-r--r--src/readdib.h21
-rw-r--r--src/rule_type.hpp22
-rw-r--r--src/rune_spell.hpp15
-rw-r--r--src/rune_spell_fwd.hpp3
-rw-r--r--src/school_book.hpp15
-rw-r--r--src/school_book_fwd.hpp3
-rw-r--r--src/school_type.hpp21
-rw-r--r--src/school_type_fwd.hpp3
-rw-r--r--src/script.cc (renamed from src/script.c)12
-rw-r--r--src/script.h12
-rw-r--r--src/set_type.hpp28
-rw-r--r--src/set_type_fwd.hpp3
-rw-r--r--src/skill_type.hpp37
-rw-r--r--src/skill_type_fwd.hpp3
-rw-r--r--src/skills.cc (renamed from src/skills.c)559
-rw-r--r--src/skills.hpp27
-rw-r--r--src/skills_defs.hpp64
-rw-r--r--src/spell_type.cc (renamed from src/spell_type.c)184
-rw-r--r--src/spell_type.hpp (renamed from src/spell_type.h)73
-rw-r--r--src/spell_type_fwd.hpp (renamed from src/spell_type_fwd.h)13
-rw-r--r--src/spells1.cc (renamed from src/spells1.c)381
-rw-r--r--src/spells1.hpp32
-rw-r--r--src/spells2.cc (renamed from src/spells2.c)2409
-rw-r--r--src/spells2.hpp115
-rw-r--r--src/spells3.cc (renamed from src/spells3.c)1126
-rw-r--r--src/spells3.hpp445
-rw-r--r--src/spells4.cc (renamed from src/spells4.c)343
-rw-r--r--src/spells4.hpp43
-rw-r--r--src/spells5.cc (renamed from src/spells5.c)436
-rw-r--r--src/spells5.hpp9
-rw-r--r--src/spells6.cc (renamed from src/spells6.c)106
-rw-r--r--src/spells6.hpp7
-rw-r--r--src/squelch/CMakeLists.txt9
-rw-r--r--src/squelch/automatizer.cc278
-rw-r--r--src/squelch/condition.cc1078
-rw-r--r--src/squelch/condition_metadata.cc496
-rw-r--r--src/squelch/cursor.cc96
-rw-r--r--src/squelch/object_status.cc153
-rw-r--r--src/squelch/rule.cc332
-rw-r--r--src/squelch/tree_printer.cc89
-rw-r--r--src/squeltch.c3582
-rw-r--r--src/squeltch.cc596
-rw-r--r--src/squeltch.hpp13
-rw-r--r--src/stairs_direction.hpp3
-rw-r--r--src/stats.hpp11
-rw-r--r--src/status.cc (renamed from src/status.c)70
-rw-r--r--src/status.hpp3
-rw-r--r--src/store.cc (renamed from src/store.c)262
-rw-r--r--src/store.hpp12
-rw-r--r--src/store_action_type.hpp17
-rw-r--r--src/store_action_type_fwd.hpp3
-rw-r--r--src/store_info_type.hpp32
-rw-r--r--src/store_info_type_fwd.hpp3
-rw-r--r--src/store_type.hpp43
-rw-r--r--src/store_type_fwd.hpp3
-rw-r--r--src/string_list.c52
-rw-r--r--src/tables.cc (renamed from src/tables.c)278
-rw-r--r--src/tables.h12
-rw-r--r--src/tables.hpp82
-rw-r--r--src/tactic_info_type.hpp17
-rw-r--r--src/terrain.hpp19
-rw-r--r--src/timer_type.hpp18
-rw-r--r--src/timer_type_fwd.hpp3
-rw-r--r--src/town_type.hpp21
-rw-r--r--src/town_type_fwd.hpp3
-rw-r--r--src/trap_type.hpp24
-rw-r--r--src/trap_type_fwd.hpp3
-rw-r--r--src/traps.cc (renamed from src/traps.c)183
-rw-r--r--src/traps.hpp13
-rw-r--r--src/tval_desc.hpp17
-rw-r--r--src/types.h2771
-rw-r--r--src/util.cc (renamed from src/util.c)524
-rw-r--r--src/util.h22
-rw-r--r--src/util.hpp76
-rw-r--r--src/variable.cc (renamed from src/variable.c)532
-rw-r--r--src/variable.h40
-rw-r--r--src/variable.hpp317
-rw-r--r--src/vault_type.hpp24
-rw-r--r--src/vault_type_fwd.hpp3
-rw-r--r--src/wild.cc (renamed from src/wild.c)123
-rw-r--r--src/wild.hpp6
-rw-r--r--src/wilderness_map.hpp15
-rw-r--r--src/wilderness_map_fwd.hpp3
-rw-r--r--src/wilderness_type_info.hpp25
-rw-r--r--src/wilderness_type_info_fwd.hpp3
-rw-r--r--src/wizard1.cc (renamed from src/wizard1.c)80
-rw-r--r--src/wizard1.hpp3
-rw-r--r--src/wizard2.cc (renamed from src/wizard2.c)199
-rw-r--r--src/wizard2.hpp8
-rw-r--r--src/xtra1.cc (renamed from src/xtra1.c)859
-rw-r--r--src/xtra1.hpp24
-rw-r--r--src/xtra2.cc (renamed from src/xtra2.c)656
-rw-r--r--src/xtra2.hpp94
-rw-r--r--src/z-form.c167
-rw-r--r--src/z-form.h18
-rw-r--r--src/z-rand.h8
-rw-r--r--src/z-term.c986
-rw-r--r--src/z-term.h101
-rw-r--r--src/z-util.c172
-rw-r--r--src/z-util.h60
-rw-r--r--src/z-virt.c145
-rw-r--r--src/z-virt.h164
-rw-r--r--tests/get_level_device.cc184
-rw-r--r--tests/harness.cc7
-rw-r--r--tests/lua_get_level.cc135
-rw-r--r--vendor/bandit/.travis.yml17
-rw-r--r--vendor/bandit/.vimrc0
-rw-r--r--vendor/bandit/CMakeLists.txt60
-rw-r--r--vendor/bandit/LICENSE.md21
-rw-r--r--vendor/bandit/README.md63
-rw-r--r--vendor/bandit/bandit/adapters/adapter.h12
-rw-r--r--vendor/bandit/bandit/adapters/adapters.h16
-rw-r--r--vendor/bandit/bandit/adapters/snowhouse.h22
-rw-r--r--vendor/bandit/bandit/assertion_exception.h41
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeCloseTo.h55
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeEmpty.h32
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeFalsy.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeGTE.h45
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeGreaterThan.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeLTE.h45
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeLessThan.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeNull.h29
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/BeTruthy.h35
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/Contain.h58
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/Equal.h90
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/MatchProxy.h43
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/Matcher.h74
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/MatcherException.h16
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/ThrowException.h60
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/ValueProxy.h26
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/matchers.h19
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/matchers/must.h36
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/CMakeLists.txt49
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/LICENSE_1_0.txt23
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/README.md419
-rwxr-xr-xvendor/bandit/bandit/assertion_frameworks/snowhouse/cross_compile.sh50
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/basic_assertions.cpp228
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/boolean_operators.cpp48
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/container_spec.cpp85
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/custom_matchers_test.cpp69
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/exceptions_tests.cpp97
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/expression_error_handling.cpp28
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/main.cpp43
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/map_tests.cpp38
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/operator_tests.cpp137
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/sequence_container_tests.cpp192
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_line_tests.cpp179
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_tests.cpp65
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/stringize_tests.cpp111
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/example/tests.h16
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assert.h126
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertionexception.h58
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertmacro.h22
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/constraints.h23
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/containsconstraint.h80
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/endswithconstraint.h53
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalsconstraint.h83
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalscontainerconstraint.h80
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalswithdeltaconstraint.h51
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/andexpression.h46
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression.h38
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression_fwd.h15
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/notexpression.h44
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/orexpression.h46
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/fulfillsconstraint.h51
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/haslengthconstraint.h60
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanconstraint.h55
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanorequaltoconstraint.h55
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanconstraint.h54
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanorequaltoconstraint.h55
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/startswithconstraint.h52
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/exceptions.h120
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintadapter.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintlist.h91
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/expressionbuilder.h357
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/fluent.h38
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/andoperator.h54
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/alloperator.h35
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atleastoperator.h41
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atmostoperator.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h113
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionoperator.h24
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/exactlyoperator.h39
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/noneoperator.h33
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/constraintoperator.h70
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/invalidexpressionexception.h28
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/notoperator.h53
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/oroperator.h55
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h33
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringize.h104
-rw-r--r--vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringizers.h60
-rw-r--r--vendor/bandit/bandit/bandit.h42
-rw-r--r--vendor/bandit/bandit/context.h97
-rw-r--r--vendor/bandit/bandit/external/optionparser.h2825
-rw-r--r--vendor/bandit/bandit/failure_formatters/default_failure_formatter.h30
-rw-r--r--vendor/bandit/bandit/failure_formatters/failure_formatter.h13
-rw-r--r--vendor/bandit/bandit/failure_formatters/failure_formatters.h16
-rw-r--r--vendor/bandit/bandit/failure_formatters/visual_studio_failure_formatter.h36
-rw-r--r--vendor/bandit/bandit/grammar.h185
-rw-r--r--vendor/bandit/bandit/listener.h27
-rw-r--r--vendor/bandit/bandit/options.h111
-rw-r--r--vendor/bandit/bandit/registration/registrar.h25
-rw-r--r--vendor/bandit/bandit/registration/registration.h7
-rw-r--r--vendor/bandit/bandit/registration/spec_registry.h17
-rw-r--r--vendor/bandit/bandit/reporters/colorizer.h141
-rw-r--r--vendor/bandit/bandit/reporters/dots_reporter.h69
-rw-r--r--vendor/bandit/bandit/reporters/info_reporter.h194
-rw-r--r--vendor/bandit/bandit/reporters/progress_reporter.h116
-rw-r--r--vendor/bandit/bandit/reporters/reporters.h29
-rw-r--r--vendor/bandit/bandit/reporters/single_line_reporter.h86
-rw-r--r--vendor/bandit/bandit/reporters/spec_reporter.h126
-rw-r--r--vendor/bandit/bandit/reporters/test_run_summary.h90
-rw-r--r--vendor/bandit/bandit/reporters/xunit_reporter.h109
-rw-r--r--vendor/bandit/bandit/run_policies/always_run_policy.h16
-rw-r--r--vendor/bandit/bandit/run_policies/bandit_run_policy.h161
-rw-r--r--vendor/bandit/bandit/run_policies/never_run_policy.h14
-rw-r--r--vendor/bandit/bandit/run_policies/run_policies.h9
-rw-r--r--vendor/bandit/bandit/run_policies/run_policy.h44
-rw-r--r--vendor/bandit/bandit/runner.h103
-rw-r--r--vendor/bandit/bandit/skip_policies/always_include_policy.h16
-rw-r--r--vendor/bandit/bandit/skip_policies/always_skip_policy.h15
-rw-r--r--vendor/bandit/bandit/skip_policies/name_contains_skip_policy.h28
-rw-r--r--vendor/bandit/bandit/skip_policies/skip_policies.h9
-rw-r--r--vendor/bandit/bandit/skip_policies/skip_policy.h29
-rw-r--r--vendor/bandit/bandit/test_run_error.h12
-rw-r--r--vendor/bandit/cmake/cotire.cmake3185
-rwxr-xr-xvendor/bandit/cross_compile.sh43
-rw-r--r--vendor/bandit/specs/before_each_after_each.spec.cpp78
-rw-r--r--vendor/bandit/specs/context.spec.cpp44
-rw-r--r--vendor/bandit/specs/describe.spec.cpp117
-rw-r--r--vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp21
-rw-r--r--vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp22
-rw-r--r--vendor/bandit/specs/fakes/fake_context.h69
-rw-r--r--vendor/bandit/specs/fakes/fake_reporter.h78
-rw-r--r--vendor/bandit/specs/fakes/fakes.h8
-rw-r--r--vendor/bandit/specs/fakes/logging_fake.h32
-rw-r--r--vendor/bandit/specs/fuzzbox.spec.cpp77
-rw-r--r--vendor/bandit/specs/it.spec.cpp355
-rw-r--r--vendor/bandit/specs/main.cpp6
-rw-r--r--vendor/bandit/specs/matchers/be_close_to.cpp112
-rw-r--r--vendor/bandit/specs/matchers/be_empty.cpp89
-rw-r--r--vendor/bandit/specs/matchers/be_falsy.cpp85
-rw-r--r--vendor/bandit/specs/matchers/be_greater_than.cpp105
-rw-r--r--vendor/bandit/specs/matchers/be_gte.cpp120
-rw-r--r--vendor/bandit/specs/matchers/be_less_than.cpp105
-rw-r--r--vendor/bandit/specs/matchers/be_lte.cpp119
-rw-r--r--vendor/bandit/specs/matchers/be_null.cpp43
-rw-r--r--vendor/bandit/specs/matchers/be_truthy.cpp85
-rw-r--r--vendor/bandit/specs/matchers/contain.cpp156
-rw-r--r--vendor/bandit/specs/matchers/equal.cpp214
-rw-r--r--vendor/bandit/specs/matchers/throw_exception.cpp104
-rw-r--r--vendor/bandit/specs/options.spec.cpp121
-rw-r--r--vendor/bandit/specs/reporters/colorizer.spec.cpp45
-rw-r--r--vendor/bandit/specs/reporters/dots_reporter.spec.cpp202
-rw-r--r--vendor/bandit/specs/reporters/single_line_reporter.spec.cpp201
-rw-r--r--vendor/bandit/specs/reporters/xunit_reporter.spec.cpp161
-rw-r--r--vendor/bandit/specs/run.spec.cpp77
-rw-r--r--vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp250
-rw-r--r--vendor/bandit/specs/specs.h10
-rw-r--r--vendor/bandit/specs/synopsis.spec.cpp54
-rw-r--r--vendor/bandit/specs/util/argv_helper.h62
-rw-r--r--vendor/bandit/specs/util/util.h6
667 files changed, 44186 insertions, 114058 deletions
diff --git a/.gitignore b/.gitignore
index d7793155..463afd14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
*.o
+lib*.a
*.~*
*.#*
CMakeFiles
@@ -6,3 +7,5 @@ CMakeCache.txt
cmake_install.cmake
install_manifest.txt
Makefile
+compile_commands.json
+/nbproject
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53923c57..9519785a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,14 +9,19 @@ INCLUDE(FeatureSummary)
INCLUDE(FindPkgConfig)
#
+# Basic common compiler flags.
+#
+SET(COMMON_COMPILER_FLAGS "-pipe -Wall -Wno-unused-value -fsanitize=undefined -fsanitize=address")
+
+#
# GCC/G++ flags
#
IF(CMAKE_COMPILER_IS_GNUCC)
# Let's set sensible options.
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -Wall -Wno-unused-value")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_COMPILER_FLAGS}")
SET(CMAKE_C_FLAGS_RELEASE "-O2")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -Wall -Wno-unused-value --std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_COMPILER_FLAGS} --std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
ENDIF()
@@ -25,19 +30,16 @@ ENDIF()
# Clang flags
#
IF("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -Wall -Wno-unused-value")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_COMPILER_FLAGS}")
SET(CMAKE_C_FLAGS_RELEASE "-O2")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
ENDIF()
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -Wall -Wno-unused-value --std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_COMPILER_FLAGS} --std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
ENDIF()
-# Add definitions.
-ADD_DEFINITIONS(-DUSE_PRECISE_CMOVIE)
-
# Add standard math library
SET(LIBS ${LIBS} m)
@@ -48,10 +50,22 @@ PKG_CHECK_MODULES(JANSSON REQUIRED jansson)
IF(JANSSON_FOUND)
ADD_DEFINITIONS(${JANSSON_CFLAGS})
INCLUDE_DIRECTORIES(${JANSSON_INCLUDE_DIRS})
+ LINK_DIRECTORIES(${JANSSON_LIBRARY_DIRS})
SET(LIBS ${LIBS} ${JANSSON_LIBRARIES})
ENDIF()
#
+# BOOST
+#
+FIND_PACKAGE(Boost 1.54.0 REQUIRED COMPONENTS system filesystem)
+
+IF(Boost_FOUND)
+ ADD_DEFINITIONS(-DBOOST_FILESYSTEM_NO_DEPRECATED)
+ INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
+ SET(LIBS ${LIBS} ${Boost_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY})
+ENDIF()
+
+#
# X11 support (OPTIONAL)
#
FIND_PACKAGE(X11)
diff --git a/RELEASE.txt b/RELEASE.txt
new file mode 100644
index 00000000..ab082315
--- /dev/null
+++ b/RELEASE.txt
@@ -0,0 +1,8 @@
+Release Checklist:
+==================
+
+* Bump version number.
+* Update changes.txt
+* Update IS_CVS in defines.h before tagging; undo post-tagging.
+* Check that system-wide installation succeeds.
+* Disable C/C++ compiler sanitization options
diff --git a/changes.old b/changes.old
deleted file mode 100644
index dabf85a0..00000000
--- a/changes.old
+++ /dev/null
@@ -1,6027 +0,0 @@
-24/10/1998 - PernAngband 2.9.9a
-- Added the DragonRider from the Anne McCaffrey's Books, masters of
- teleportation.
-- The CTRL+l key leaves the game without saving
-- Added the Tanker point, like the mana point, but can only be refilled
- by eating the Firestone (for DragonRiders)
-- Added the RohanKnight race, fast and wise
-- Added the Ent race, can grow trees, but slow
-- Removed some races from Zangband which were not enough tolkienian...
-- Added the BeastMaster class which can summon pets
-- Added the Blood of Life
-- DragonRider now can choose to breathe a bolt, a beam or a ball
-- Added the Unique level patch from Glenn Vanzanden
-- Added the Mage Staves , with new ego items:
- -of Mana : multiply your max mana
- -of Spell : Increase your spell power
- -of Mana & Spell : try to find !:)
- -of Power : Activate for some spell, they carry 2 spells
- All the ego mage staves have a penalty to damage and to hit
-- Added The Mage Staff of Gandalf, extremely powerful but even rarer than
- the One Ring !
-- Added the boots of jumping activatable for phase door every 10+d10 turns
-- Added Helm of the Dwarves and of the Noldor
-- Beastmasters' pets now give kill experience to the player
-- Added the Alchemist class which use power batteries to convert magic item
-- New unique level : Treasure room at level 11
-- Replaced the Trump Hound from the Trump realm by the Trump Home spell, which
- allows the player to access to her/his home from everywhere in the dungeon
-- Added the new artifact The Ring of F'lar, which belonged to F'lar the
- powerful DragonRider
-
-26/10/1998
-- Added potions of Mutation
-- Warrior-Mage now can choose Sorcery instead of Arcane
-- Invisibility, Potion of Invisibility, Ring of Invisibility and
- The One Ring now has invisibility like in the Lord Of The Rings !!!
-- Added the parchments from Kamband
-
-30/10/1998
-- Ported PernAngband to the new Zangband 2.2.0
-- Added the mimic class
-- Some Zangband bugs are fixed
-- The DragonRider can now only teleport on known terrain, because they must
- mentally show the destination to their dragons but to do this they MUST
- have seen the destination before (like in the Anne McCaffrey books) !
-- The Ringwraiths are back!
-- Some uniques like Bert, Tom, Bill are back, while others (Gandalf, Fangorn)
- are gone!
-- Morgoth and Sauron are back as the final quests
-
-01/11/1998 - PernAngband 3.0.0
-- All reference to Zangband have been removed
-- Added monster corpses
-- Added the Beastmaster Shanty for the beastmaster, the Mimic Tower for the
- Mimic, and the Weaver Tower, where you can ask for corpse quests
-- The corpse quests require you to bring back to the weaver some corpse,
- head,... of a kind of monster, and you'll get a reward, like maybe
- the full knowledge about this monster, or some armor made with the corpse
- (maybe dragon scale mail for dragon, ...)
-- Added susceptibility to fire, for the Ents! They take twice more damage from
- fire, but it's hopefully cancelled by resist fire.
-- Changed some artifacts / unique monsters to be more pernish
-- Added a new armor type : the DragonRider flying suit[9,+0] resist fire/cold
-- New monster flag : PET , the monster is your pet when it's created
-- Added the army man which use the PET flag will be used to give you an army
- in some future quest.
-
-03/11/1998
-- The exe file is now pernang.exe(in the dos version)
-- Replaced the AMBERITE monster flag by the DRAGONRIDER flag
-- Some Unique will have the PET flag so they will help you !
-- All the Amberite are now gone and replaced by DragonRiders or uniques
- (with some of them friendly)
-- Can sell the Mage staves in the Weapon smith and Magic shop.
-- Now when an alchemist tries to extract a power from an item, if he can't
- it won't show up again in the extractable list the next time
-- The DragonRider must eat more because of their dragon
-- The Troll Fortress quest
-- Added The Battle of the five armies quest !!!
-
-05/11/1998
-- Nature spell : Stop breeders
-- New ego item sword of life, it multiplies your max hitpoints
-- Now some Mimic forms give you bonuses to blows per round like the Vala:
- +5 blows !!!
-- Added a new Unique : The Philosophy Teacher !
-- Pink horrors are replaced with 2 Blue horrors when they die
-- Bloodletters of Khorne drop a blade of chaos when they die
-- Absorb light mutation bug fixed (I think)
-- Vampires and vampire mimics no longer can get food in the inns.
-- Renamed the artifacts with their real names
-- Replaced the pattern by the Straight Road (idea from GSN-Band)
-- Replaced the pattern weapons with weapons of Valinor (idea from GSN-Band)
-- Player and monsters can't pass through the trees (unless they can fly:)
-- When a Dragonrider dies he drops some firestones
-- Added the Whip of Gothmog, which can be dropped by Gothmog when killed
-- Begin to add a new feature : the between
-- Add a great description of the Ents and the Rohan's Knights from Akhronath
-
-07/11/1998
-- The between is fully implemented now.
-- The dimension door spell is replaced by the between gate.
- It put a between gate at the player position and at the destination
- location. And when you walk on the between you are transported on the other
- between gate. But the between is SO cold that when you are in you lose some
- hp even if resistant or immune to cold! Only the dragonrider can go between
- without taking damage.
-- Stole the Stone of Lore from Oangband ! :)
-- Monsters can't use the between now because of a bug
-- Now you can eat corpses and temporarily gain some of the powers of monsters!
-- Raise Death replaces Terror in the death realm, cast it on a monster corpse
- on the floor and the monster is brought back to life!
-
-09/11/1998
-- Added the boomerang, the player wears them instead of the bow and with the 'f'
- command (like for the bow) can throw them but them come back ... if they don't
- break !
-- Add 2 boomerang artifacts
-- Add another dragonrider artifact belonging to Mardra
-- Add The Anchor of Space-Time, it prevents disruption of the space-time
- continuum
-
-11/11/1998
-- Add the carry slot in the equipment, to wield monsters that can't move :)
-- Fixed a bug that prevented dragonriders from being summoned
-- Add a Neuter sex (for the neuter players) :-)
-- Add the Death Mold race (stolen from Kamband) :-)
-
-13/11/1998
-- Add in spell description the bonus of mage staves
-- Add the scroll of summon never-moving pet for wielding them !:)
-- When a monster is wielded it can attack monsters when you attack
- It can sometimes attack the wielder too, because he/she is not in perfect
- symbiosis
-- Muar the balrog is back and will drop Calris when killed
-- Add the Symbiotic realm, like a life realm for your monster
-- Add the Symbiant class which can be in perfect symbiosis with their monster
-
-15/11/1998
-- The number of artifacts is now 132
-- Add some spells to the symbiotic realm
-- Add a spell to use the spells of the monster you wear
-- Add a light-speed (nearly stop time) spell
-- Finished the Symbiotic realm, only two books because they can use their
- monster's powers.
-
-18/11/1998
-- Warriors can now spread their attacks after level 34
-- The experience factor of the races can now be > than 255
-- The DragonRider need more experience to advance (+220%) because it's a REALLY
- powerful race.
-- Monsters can now use the between but if they are not immune to cold they
- will lose some hp
-- Added a health bar for the monster you are carrying ( MH xxxxx/xxxxx )
-- Added sanity (from Kamband) ( the line SN xxxxx/xxxxx in the window)
-- Stolen the aquatic monsters from Kamband
-- Add the Gods from Kamband and GSNBand
-- The Philosophy Teacher now causes insanity !:)
-- Now only the Symbiants can carry monsters in their inventory, in fact they
- act like "living-books" !:)
-- Add the Tactics from ADOM. You can change the tactic in the Character window
-- Add a new town unique : Mathilde, the science student, she is in my class
- and giggles all the time, don't kill her ! :)
-- Fixed bug : The carried monster cannot absorb damage done by itself !
-- The Battle of the five armies now has a reward (The Arkenstone)
-
-20/11/1998 - PernAngband 3.0.2
-- Now there will be some between gates randomly placed in the levels
-- If you are in great favor with your god they can resurrect you
-
-22/11/1998
-- Add Random artifacts from Kamband - They are junk items which can be
- activated every few turns and their activation is chosen randomly
-- Fixed (I think) a bug in the unique levels
-- Add a flooded level type (enable those levels in the PernAngband options)
- to make the aquatic monsters more useful
-- Gandalf and Fangorn are back as Friendly uniques
-- Changed the Necklace of the Dwarves into The Nauglamir to be more
- Tolkien-like
-- Changed The Serpent of the Chaos into Dark God, Mighty Coder from Hell :)
-- Reworked the corpse system (stolen from Rangband), now they all have
- different weights based on the monster weight. You can hack up the corpse
- with 'h' and cure it with 'K'.
-
-24/11/1998
-- Add a new Unique : The Physics Teacher !
-- Changed the Town layout of Gondolin with the one made by Akhronath
- with 2 quests : Hunt for Eol and Maeglin's Mine
-- Add a new Unique : Eol the Dark Elf
-- Stole the silly messages when you hit a monster from Kamband
-
-26/11/1998
-- Add a scroll of Craftmanship to enchant weapon's pval.
-- The first 300 monsters have received a weight
-- Add a new spell type : Identify, now you can have a Ball of identification !
-- Add a new set of object flags (mainly unused now) :-)
-- Add a NEVER_BLOW flag for object
-- Add the NEVER_BLOW flag to The Mage Staff of Gandalf to rebalance it.
-- Add a new ego item weapon : of Nothing (with the NEVER_BLOW flag) !! :)
-
-29/11/1998
-- Add a Harper (bard) class !!! they use music books and most
- of their spells are prolonged in time, ex: you cast a hiding song,
- and for each turn you lose some mana (breath) while the effect (invisibility)
- continues. If you start singing another song the old one is stopped.
- There is also a spell which costs no mana which is used to stop singing.
-- Stolen the *Defender* ego-item from Pziband
-- Stolen the Spectral ego-item from Pziband
-
-01/12/1998
-- Added musical instruments : you wear them in the bow slot and you can
- activate them for a song. The longer the song lasts the longer it'll be
- charging, you can stop the song by activating it when it sing.
-- Finished the Harpers
-- Now the Harper mana stat is Charisma !
-- New Artifact : The Palantir of Minas Tirith, which can be activated for
- the list of the uniques of the level !
-- Added 3 new artifacts : The Harp of Master Robinton, The Drum of Piemur,
- The Flute of Menolly
-- Added the Micro$oft quest at Minas Anor
-- Changed the niceness description of the gods
-- The Harper and ONLY the harper can use a musical instrument without any
- chance of failure.
-- The wilderness size is now taken from misc.txt
-- All the monsters have a weight now ... pfff, it was a lot of work !:)
-- The Alchemists are easier to play
-- Add the Vapor quest at Minas Anor
-- Add the Rebellion in Gondolin(from Akhronath) quest at Gondolin
-
-02/12/1998 - PernAngband 3.0.4
-- Changed certain god realm name on the suggestion of Akhronath
-- Add the bounties list like in Kamband (OK, ok, stolen from Kamband) :)
-- Add the Fire-lizards, they are friendly
-- New roguelike command : 'i' for hack up corpse, 'I' for curing meat, 'C'
- for Sacrificing at altars
-
-05/12/1998
-- Add the Power Mage class, like the Corrupted in Kamband, with 100 randomly
- generated attack spells
-- Corrected the character generation bug !!!! Thanks to Tim Baker for the fix
-- Corrected the segmentation fault bug for the object 653. Thanks to Tim baker
-- Corrected the files.c bug in get_line(). Thanks to Tim baker
-- Add the GF_DESTRUCTION type of attack to allow Power Mage to have destruction
-- Changed the names of the songs, Thanks to Akhronath
-
-07/12/1998
-- Add the Eggs, some monsters (only Firelizards for the moment) can be found
- as eggs and will hatch after a certain amount of time based on the monster
- weight, you can also stop the development by "activating" them ('A' key),
- or resume the development by activating them an other time.
-- Add the last of the Gondolin's quest from Akhronath :
- Invasion of Gondolin (Danger level 90, with some funny stuff like Gothmog,
- Muar,..., some Great hell wyrms) !!!
-- Fixed a bug which made it so when you drop your wielded monster you also
- drop Nothing if you are not a Symbiant
-- You can imprint some monsters (Firelizards for now), when it has
- been given an imprint it will follow you on each levels. They may not
- appear on a certain level but they will be back for the next. To
- imprint a monster you must find an egg, carry it on you and when it'll
- hatch you'll give it the imprint
-- The Harper will begin the game with a Blue Firelizard egg
-
-09/12/1998
-- The Black market now generate items based on your level
-- Add a new shop : The Pet Shop where you can find some eggs
-
-12/12/1998
-- Your godly favor will go down when they resurrect you
-- Repaired a stupid bug : I haven't coded the Satisfy Hunger effect of the
- Symbiant class !:)
-- Add the easy floor feature !!!
-- Add an always small dungeon option
-- The scrolls of Artifact Creation can now be used on rings and amulets
-
-15/12/1998
-- The One Ring is now "just" heavy cursed !:)
-- Add 3 new vaults
-
-18/12/1998
-- Add the fate : you can be fated to meet some monsters or to find an object
- on a certain level or ..... to DIE (very rare). You don't know your
- fate until a soothsayer or a scroll of divination shows it to you. You
-also get a feeling when entering a level where you will meet your fate.
- In the future there will be more fates, like finding a great vault, an
- artifact or even, as Murazor the Witch-King of Angmar, to never die by the
- hands of a mortal !:)
-- Changed Trump Weapon to Dragon Weapon
-- Smeagol will now drop ......... A ring of invisibility (because the One Ring
- would be a little too powerful :)
-
-23/12/1998
-- Replaced the Amber notation in the player characteristics by the old one
- from Vanilla Angband
-- When the player is on a tree he can be hit by a monster for half
- normal damage
-- Paladin and Priests are given a religion at the beginning
-- In the wizard spoiler creation (A + ") you can chose to make a spoiler for
- batteries
-- The random artifacts now have a charging time (no more mass genocide every
- turn)
-- Add a Soothsayer at Bree
-- Add the batteries of extra life, you can now make a sword of Life !
-
-25/12/1998
-- The Alchemists are now better fighters, equal to the rangers
-- New extremely powerful power for the Alchemist (level 30 and higher) :
- Artifact creation !
- They just have to chose the flags, the name and to suffer the bad side effect
- like curse equipment, permanent stat loss, high failure rate and ..... they
- have their artifact ! But they can't give it an activation !
- They can also add some bad flags (like cursed, drain exp, ...) to reduce the
- chance of failure. Merry Christmas ! :)
-- Add the Runecrafter class, they use runes instead of books (see birth.txt)
-- Cleaned the Alchemist's code
-
-27/12/1998 - PernAngband 3.0.7
-- Added (.... stolen from Sangband) the Pick of Erebor. It can be activated for
- passing through secret passages in the walls.
-- The Potion of *Enlightenment* now show every grid of the dungeon, like the
- debug command 'u', I just think it's more beautiful :)
-- WOOOOOOOH I'm sorry there was a BIG bug in the PernAngband 3.0.7 release.
- The game was sometimes hanging without any solution to stop it !
- After some hours of debugging I've found it, it resulted from the correction
- of the bug of the glyph of warding! Now everything works (I hope)
-- Change the titles of the Runecrafter with the proposition of Jonathan R Lewis
-- Add TANG, The Angband Newbie Guide made by Chris Weisiger
- (jmartin@inreach.com) It's in the help directory
-
-29/12/1998
-- Fixed a bug which allowed beastmasters to sing when they summon pets!
-- Fixed the bug in the Fate screen
-- Some cosmetic changes in the r_info.txt and birth.txt with the help of
- Chris Weisiger (jmartin@inreach.com)
-- Add new ego-items for the musical instrument and the horn, there were
- suggested by Akhronath
-- New sentence to say for the speaking unique pets
-- 4 new musical instrument artifacts from Akhronath and I'm happy to declare
- there is 143 artifacts in PernAngband!
-- Added, .... stolen, 5 new artifact from Angband/64
-
-31/12/1998
-- Add the quiver slot to wield your ammo
-- A scroll of remove curse have 1 chance into (55-level) to reverse the curse
- effect ie: a ring of speed (-2) can become a ring of speed (+2)
-
-01/01/1999
-- Add a new monster flag : MORTAL, which means that the monster is a mortal
- being. It's used for the new fate : Never to die by the hand of a mortal
- being. The orcs are considered mortal, but I'm not sure, it's not mentioned
- in the silmarillion or the Lord of The Rings, the trolls are immortals along
- with the dragons, BUT the Dragonriders are mortal and Dark God (Yes, let your
- joy explode!) :-). But well, don't be afraid your preferred monsters
- (Morgoth and Sauron) are immortals :-)
- PS: If someone thinks that a monster should or not be mortal just email me
- because I'm not certain for some (ok, ok a lot of) monsters
-
-03/01/1999
-- Add the ring of precognition which work as if the player had activated the
- cheat mode (peek into object, monster, vault creation). There is no need
- to say it's very rare :-)
-- Add the black breath concept from Tolkien. Beware now the weapons of morgul
- they confer the black breath! The undead can also give it.
-
-05/01/1999
-- Changed the harpers ranking names, some racial histories with the ones from
- Akhronath
-- The One Ring is now A LOT more powerful, because at the time you find it
- you already have one or two immunities, your stats are near the max, plus
- some other things that made it less useful. Now it confers 5 blows, mana x5
- spell power x5, after all Sauron has put the most part of his power in it.
- I also plan to change the activation.
-- Add 2 wand artifacts, The Wand of Stone to Mud of Thrain and the Wand of
- Fire Balls of Mithrandir, they can be recharged at will and will never be
- destroyed, for this purpose the new RECHARGE flags has been used (note :
- it works only for the artifacts)
-
-07/01/1999
-- The runecaster is a little more playable at low levels and starts with a
- Rune [Arrow] and a Rune [Fire]
-
-10/01/1999
-- The Chaos Warriors now get chaos resistance at level 25
-- The Maia mimics get +7 speed, the Vala mimics get +15 speed
-- Updated the Rebellion in Gondolin and Hunt for Eol quests with the help of
- Akhronath (zzhou22876@aol.com)
-
-13/01/1999
-- Reimplemented the old magic system from vanilla to complement the new one
- The old mage and priest are come back as the Wizard and the Prior
-
-17/01/1999
-- Add susceptibilities to fire, cold, acid, lightning, poison for the monsters.
- ie: Now a white dragon will take a x3 damage from a fire attack.
- Thanks to Jerome Wojcik <Jerome.Wojcik@lmcp.jussieu.fr> for his help.
-- Add the pets command (press P) from Zangband 2.2.3
-- Changed the Trump realm into the Dragon Realm (mainly just name changes)
-
-19/01/1999
-- Changed the activation of the One Ring
-- The One Ring is now Permanently cursed
-- The One Ring is no longer aggravating because of it's new summoning ability
-- It's now possible to run through the grass
-
-21/01/1999
-- Add the persistent dungeon option at birth
-- When a breeder multiplies it have a 7/100 chance of mutating into an other
- monster. (in general a worse one) This would prevent monster farming abuse :)
-
-24/01/1999
-- NEW : the body changing feature! with a new class to use it. Your spirit
- can leave your body to go into another one but while your spirit is alone
- your max hp is of 1. When in the corpse of a monster your first blows are
- the monster's one and you can use it's magical power. Your life is also
- changed by the monster's one and you gain all it's abilities and resistances
- while losing those of your real race because you have left your body.
-- Add a lot of new vaults mainly from Weisiger <jmartin@inreach.com>
-
-28/01/1999
-- Death Molds now can teleport onto store entrances
-- A new randart activation that fires light after absorbing the ambient one
-
-05/02/1999
-- Changed the Roguelike commands. Now ^G to sacrifice, $ to hack up a corpse
- ^O to Cure meat
-- Updated the command.txt file
-- Add the AB's gfx for the weapon/armor
-- Multiple dungeons : The old levels 1-33 are now in the Mirkwood forest with
- trees and grass, 34-66 are the Land of Mordor with mountain, wall and dirt
- 67-127 are the Dungeon of Angband with wall and normal floor and occasionally
- flooded levels (if chosen in the options).
- The ability to levitate is now a GREAT advantage in the Mirkwood forest !
- You can reach Mirkwood from Menegroth, Mordor from Minas Anor and Angband
- from Gondolin. In the vanilla town there are three stairs.
- When you take a staircase down in the last level of a dungeon you arrive back
- in town.
-
-07/02/1999 - PernAngband 3.0.9
-- X in the roguelike mode for the pet commands
-- Updated the magic.txt file with the new classes
-
-09/02/1999
-- Updated version.txt, modified dungeon.txt
-- Shelob is now a little bit more powerful in order to make her the quest
- monster of the last Mirkwood level.
-- The Vanilla books are now sellable in the magic shop/temple and the bookstore
-
-13/02/1999
-- New class : the Sorcerer, they can't wield any weapon useless it's a Mage
- Staff and without it they are the WORST fighters of the game even bare-handed.
- But to compensate this they are the BEST magical class : the can use any
- book of any realm without having to learn the spell, but they also don't
- gain any experience from casting a spell.
-- Added the susceptibilities flags to the monsters.
-
-15/02/1999
-- Stolen the exploring system (like the tactic one) from Angband/64
-- Fix the bug of vanilla town, now the vanilla town flag is saved
-- Ents are rebalanced, they have a -9 speed penalty
-- Tweaked the Troll Fortress quest to make it less easy
-
-21/02/1999
-- Corrected some bugs in the town files. The crashing wilderness bug
- seem to be gone.
-
-23/02/1999
-- Fixed the bug of the traps. No more grey "invisible traps" on a level
- covered with grass, same for the dirt
-- Updated the Gondolin town and quest with the Akhronath's ones
-- Enabled the S-lang support
-- A new script directory is in lib, it contain a file script.sl which indicate
- every S-lang script files that must be loaded
-- Add the event's gestion to the slang script. An event is produced in certain
- conditions (like a keypress,...) and a script can put an handle on it to have
- a function called each time the event happens. I've made a stupid example
- that use the key 'y' to shout at the monsters.
- PS: Take a look at slang.txt in the help directory
-- Add the load/save function to the script
-
-24/02/1999 - PernAngband 3.1.0
-
-26/02/1999
-- I've finally successfully compiled Python. So the S-Lang support is replaced
- with the python one. The 'y' key and the thieves quest are there too.
-- Stolen and modified intro.py from Pangband
-- The random quest bug is fixed (maybe :) ). I say maybe because as for the
- wilderness one it doesn't happens by me so I can't test it :(
-- Today one of my dream have become true! With the help of a python script
- I've made a new quest for the DragonRiders that can be given at the Weyr
- of Arda in Menegroth. You enter forest area and the only thing you can use
- is the flame of your dragon(no magic, no wands, ...). And you need to
- destroy every thread while saving at least 50% of the trees, and your own
- flame can consume them!
-
-28/02/1999
-- Yeah, the wilderness bug is now gone. And a minor bug which looks like the
- the wilderness one is gone too. It happened when you try under certain
- conditions to go in the wilderness with an imprinted pet.
-- Fixed the random quest bug
-- Fixed the inventory bug that when picking up an object said you have foo
- in slot r and reorder it after that o the letter is no more r. I know it was
- really annoying but well it's now gone :)
-- The undead races now start at night
-
-02/03/1999
-- The spectres can now pass through trees and mountains
-- A new dungeon type at Bree: The Upper reaches of Galgals(level 1-10) !
-- Changed the code for the different dungeon types. Now it's a lot easier to
- add a new dungeon type. I'll maybe make a d_info.txt to define the dungeon
- types
-- Add a new dungeon: The Volcano, you reach it by going to the north east of
- Minas Anor. Level 30-45
-
-05/03/1999
-- Spectres can't pass through trees because trees are pure and natural
- things :)
-- New dungeon type: The Hell !!! Level 500 to 530, Yes 530 ! With a little
- present for you at the bottom... if you manage to survive :) I can just
- said one more thing: don't go there with your level 1 character :)
- You can reach it near the volcano hole.
-- Now fire balls can burn the trees
-- Invisibility now consume a lot of food
-- Fixed a strange bug with the pool of deep water... It was possible to
- sacrifice at and to worship (before the crash:) one :). Thanks to Steve Dice
-- Add a very nasty surprise at level 1.... Moldoux, the defenceless mold with
- 1 hp no powers, can't move, can't attack... Oh and if it's killed there just
- one Great Wyrm of Power which can be summoned to avenge it !
-
-07/03/1999
-- The look command doesn't stop anymore on the trees, grass, ...
-
-07/03/1999 - PernAngband 3.1.2
-
-13/03/1999
-- Sorcerors have now a bad pseudo-id
-- Sorcerors have now a -25% penalty of hp
-- Add a scroll of deincarnation
-- Add the possibility to engrave the floor with some magic words found in some
- parchments. The words are in Adunaic(Numeronean), Quenya, Sindarin or any
- other tongues of Middle Earth. But the parchment also give useless words
- with the useful ones, so you have to try different combinations.
-- No more "human" sex when randomly chosen
-
-16/03/1999
-- Mathilde will say the right sentences now
-- Fixed a bug in melee2.c which could produce an x and an y out of the limits
-- Disabled the engraving command for now because it's too unbalancing...
-- If you pray while low on hitpoints (< 20%) your god will do something to help
- you, like summoning pets, curing wounds, killing enemies...
-
-19/03/1999
-- There is now a minimum level needed to enter some dungeons, to prevent
- gaining great objects easily
-- Fixed the OLD bug of the pink horrors, now only 2 blue horrors
- will be summoned
-- Fixed a bug with the tiles for the non unique DragonRiders
-
-21/03/1999
-- The Dragon realm users receive some experience for the kills of their pets
-- The Palantir of Minas Tirith now can teleport you next to the quest monster
- but it'll take more time to recharge
-- Fixed the possessor's number of blows bug. Also the town uniques corpses (
- Maggot, Martti, Mathilde) can't be used to attack because their attack is
- moan with no damage
-- Added a faq (see pern_faq.txt)
-- Added a new monster ally, the Dolphiner. They came from the planet Pern
- and can summon dragonriders, their friends. They are men riding dolphins
-
-******************** Attempts to rebalance the game **************************
-- Changed the xp modifiers of the new races in an attempt to make them more
- balanced. Thanks to Shawn Cheng <mfighter@hotmail.com>
-- Invulnerability, Wraith Form and Life Multiplier now consume a *lot* of food
-- RohanKnight's gain less speed at each levels
-- Sound attacks of the harpers are less likely to stun...
-- IMPORTANT NOTE: At the character birth if you choose a forbidden class for
- your race, you'll be considered as a cheater and the game won't be scored.
- It's mainly to prevent the too powerful combination of Deathmold Mimic or
- Deathmold Possessor. The characters made before the next release won't be
- affected by that
-- Some more attempts that I don't remember :)
-- Changed the Mana and life multipliers, now mage staff of mana(100%) will
- ADD 100% of mana to your max mana and not multiply it by 100 :)
-******************************************************************************
-
-23/03/1999
-- Replaced Menegroth by the new Lothlorien skilfully made by Akhronath
- (zzhou22876@aol.com), with 2 new quests + The Battle of the Five Armies +
- (only for DragonRiders) The Fight against a Threadfall
- Thanks again Akhronath !
-- Deathmolds can now enter wilderness
-- Radically changed the score calculation, in the future it'll serve to choose
- which characters must be turned into monsters. Note that the old score files
- are compatible but the old scores mean nothing with the new system
-
-26/03/1999
-- Changed some aspect of the python implementation to make it more portable
-- The usleep python function may react strangely
-- When you pick up the same type of ammo that you wield in your quiver it
- automatically combine with it
-- The specials levels are now restricted to a certain depth AND a certain
- dungeon type
-- The number of collected bounties now count for the final score
-- Add a new option to not pick up monster's corpses. It's yes by default.
- I've made it to avoid losing good characters by auto picking up a great
- wyrm of power corpse and getting -500 speed !
-
-28/03/1999
-- Reimplemented the player ghosts, but in a different way. First the bone files
- are a lot more complex to include more aspects of the dead character. Second,
- only the best characters are allowed to become ghosts when they die, or commit
- suicide, it's based on their final score. In the bone directory there is a new
- file which held the name of the bone files that the player want to be used.
- To add a bone file, put it in the bone directory, add it to the bones.txt file
- and increment the number of bone file in the same file.
- When a game is loaded it looks for this file, try to find some unallocated
- ghosts and modify r_info with the new info from the ghost. When this is done
-the bone file is not used anymore because all the info is saved in the
- player savefile. The race/class characteristics are not fully handled now.
-- Now even with a Mage Staff the Sorcerors have a penalty of -10 to hit/dam
-- A Vampire can now wield the Phial of Undeath without being scorched, while
- all the other light artifacts scorch them
-
-30/03/1999
-- The Arcane Zap spell now works correctly
-- Updated the FAQ with the help of Leon Marrick
-- Updated magic.txt with the help of Leon Marrick
-- WOH ! Impressive ! Great work indeed ! Well, Andreas Koch has made a
- powerful graphic editor for PernAngband !!!! And it has also drew some new
- tiles! The editor is really impressive, you load the graphic file, the prf
- file and you can assign a tile to every monsters/objects/... you want, just
- with a click ! It can even scan the *_info.txt to search for new things that
- are not in the current prf file and to add them !
- You just need a big screen resolution(1152x864x16bits works for me)
- Thanks for the great work Andreas(akoch@rbg.informatik.tu-darmstadt.de) !
-- The Archer class as suggested by Mike Hommel <jamul@hamumu.com>. They gain
- some extra shot and might with levels and can also create ammo with rubble
- and junks.
-
-05/04/1999
-- Fixed a bug in the Weyr of Arda at Lothlorien
-- Add the artifact's descriptions made by ... well I don't have his/her name.
- Anyway, great work.
-- The rings of teleportation can now be activated but they'll be destroyed in
- the process. It's like a last chance option :)
-
-08/04/1999
-- The uniques used in the special levels are no longer shown as killed in the
- list and can only be created in the special level.
- Note : This will only affect the new characters.
-- Fixed : When a Power Mage spell fails it is not cast anyway.
-- Wall creation works for Power Mage
-- Divia wrote some missing artifact descriptions
-
-12/04/1999
-- Reimplemented the engraving feature. There are some parchments in the
- dungeon which contain Adunaic/Quenya/Sindarin/... words you can use to
- engrave the floor with 'x'(']' in the roguelike keyset). You must read them
- before engraving even if you know the words from your last game. Also the
- inscription is magical and so needs some mana to work. So there is a new
- and unique feature : each grid in the dungeon have some mana on it's own.
- You can sense the mana of one grid by pressing 'X'('[' in the roguelike
- keyset), but this is not very precise nor easy, it's based on the magical
- ability. When an inscription is used it decrease the grid's mana and when
- there is not enough mana the inscription don't work anymore. The maximum
- mana of each grid is 255. i.e.: when you engrave the protection inscription
- which use 8 mana on a grid with 80 mana, a monster won't be able to walk on
- it for 80/8=10 turns, but well, this can save your life !
- Note : There are not a lot of inscriptions, if you have some ideas, don't
- hesitate, email me !
-
-14/04/1999
-- Changes in the r_info for the HAS_EGG flag as suggested by Akhronath
-- Bloodletters of Khorne only have a 20% chance of dropping Blade of Chaos
-
-17/04/1999
-- Raal's Tomes of Destruction have a 20% chance of dropping a Raal's Tome of
- Destruction
-- Symbiants are more likely to receive the grow molds mutation
-
-20/04/1999
-- Quest monsters can not be pets or breeders
-- Can now place Trees(T), Mountain(M), Shallow & Deep lava(l, L) and
- Shallow & Deep water(w, W) in the special levels
-- Add a new dungeon type: The lost city of Numenor which is mainly composed
- of water and which can be found to the west of Bree
-********************* IMPORTANT *************************
-- The savefile from the old versions of PernAngband are no longer compatible
- with the new one. It's mainly due to the new magic system but also some other
- changes. I'm sorry but this would be hard to write a converter since all
- the realm change (they have more spells) and so the books too and also the
- way to remember which spells are known, forgotten, tried...
-*********************************************************
-
-22/04/1999
-- Some new graphics from Andreas Koch
-- Fixed the wilderness generation bug which sometimes hung the computer when
- trying to go on a wilderness border
-- The features(in f_info.txt) have some flags now. This allows me to create 2
- new types of wall: The Glass walls which you can see through but that you
- can't pass and the Illusion walls that you can pass but not see through
-- The screen is now correctly redrawn when leaving/entering a body
-- Add the Wands of Wall Creation
-- Death Mold powers have moved to the activation command('U')
-
-24/04/1999
-- Your are no longer crushed when flying over trees/mountain without being a
- DragonRider
-- The Vanilla feelings are back
-
-26/04/1999
-- All the spellbooks are now placed on the top of the inventory.
-- The Sorcerors can now use the Wizard and Prior books
-- The new magic system is ready. I'm just waiting for Akhronath and Shawn
- Cheng. And now adding a new realm or an old fashioned magic system is
- performed the same way and easily
-- Add the Illusionists from Kangband. Someone has asked for them so... :)
-
-28/04/1999
-- Finished the Valarin Realm
-- Between gates are now allowed in the vaults. To place them place 2 times a
- number from 0 to 7. I.e.(from weisiger <jmartin@inreach.com>):
- D:XXXXXXXXXXXXXXXXXXXXXXXXX
- D:#,,,,,X&...@X..**&X....9X
- D:#...&1X.,,,2X..**&X3...9X
- D:#...&.X1,,,.X2.**3X....9X
- D:#,,,,,X&...@X..**&X....9X
- D:XXXXXXXXXXXXXXXXXXXXXXXXX
- But BEWARE ! You MUST put the 2 occurrences of the number, no check are done
- so it'll surely crash or bug if not ! You've been warmed.
-- You can now walk over the water with a Valarin spell
-
-30/04/1999
-- A monster on a between gate when the player is using the other is teleported
- to the player location
-- Add some Between vaults from weisiger
-- Added the Sigaldry realm
-- The Rings and Amulets are now allowed to be random artifacts
-- You can use the between gates in the special levels via the numbers 4,5,6,7,
- 8,9,0
-- Alchemists MUST wear gloves (no cesti nor gauntlets) in order to do alchemy.
- They also begin the game with some gloves
-- Add a Potion of Learning which allow you to learn one more spell than you
- normally can. No need to say that they are very rare
-- The more you learn spells in a realm the more efficient with that realm
- you are
-
-02/05/1999
-- Implemented the Nether Realm
-
-09/05/1999
-- Magical stair at the bottom of each dungeon
-- Reworked the imprinted pet system, now it will work lot better
-- Add the scrolls of spell which can cast a spell like a book. They must be
- created by the Sigaldry magic, they can't be randomly generated
-- Updated the Sigaldry realm
-- Added Staves of Wishing! You can wish for objects, monsters, spells but
- NOT FOR ARTIFACTS nor for staves of wishing
-- Flying monsters can now pass over trees and mountains
-
-11/05/1999
-- The game will ask you to choose ammo from your inventory if your quiver is
- empty
-
-26/05/1999
-- Add the Crusade Realm
-- Add some new inscriptions
-- It's now possible to add up to 32 realms
-
-03/06/1999
-- Wraith form is less powerful since it's not so rare. Now damage is only
- divided by 5 and armor raised by 50
-
-05/06/1999
-- Add the speaking patch from Matt Graham. Just edit the monspeak.txt file
- to add new entries. And don't hesitate to send me what you've added !
-
-11/06/1999
-- There are fewer gods and each god has one or two preferred races and if one of
- this race pray to him they gain better benefits. Also the praying effects
- are more differentiated (based on the different gods)
-- Add the 'only once' quest type
-- It's harder to please your deity
-- The Nazguls are MUCH more powerful (ideas from Akhronath):
- ******** Quote from Akhronath mail ********
- All weapons which are not ego-items cannot harm them, and will be destroyed if
- the character hits a Nazgul with it. Ego-items which have slay evil or slay
- undead can harm them, but each hit has a 25% chance of destroying the weapon.
- Other ego-items can't damage them, and have the same 25% chance of
- destruction. An artifact weapon will be able to hit them only if the weapon
- has slay evil or undead, but the weapon will be hit with disenchantment every
- time it connects (but this is negated with disenchantment resistance on the
- character). And even these artifacts can be destroyed, although there's only a
- 5% chance. Other artifacts, of course, can't damage the Nazgul, and still have
- the 5% destruction chance.
-
- When a character does any damage to a Nazgul or is damaged by a Nazgul, he has
- a 25% chance of being afflicted by the Black Breath. Thenceforth the character
- will slowly be drained of experience and sanity. The character can stay alive
- by using restoring and curing potions, but to cure the Black Breath he must
- either drink a Potion of Life or eat (a new item) Athelas Leaf. (Athelas isn't
- really eaten, of course, but I can't think of another simple way to implement
- it.)
-
- This will really make the player think twice before going up to a Nazgul, and
- makes it very useful to carry spare weapons.
- *******************************************
- So if you encounter a Nazgul .... RUN AWAY !
-- Sensing the grid's mana is now done by pressing 'x' key to engrave the floor
- The X key is free for some new function (maybe for the new riding system)
-
-17/06/1999
-- When browsing the spells while being a Power Mage there are no more bugs
- when pressing escape
-- Removed the forbidden race/class combination feature. But it's always
- possible to recompile PernAngband with it with the FORBID_BAD_COMBINAISON
- define(in config.h)
-- New god : The RNG
-
-19/06/1999
-- The priest/prior/paladin's god is now chosen dependent on their race
-- I have enough of hunting those damn ghost bug which makes them unable to
- move. So it's now a feature ! They don't move because they are GREAT
- adventurers who now just want to stand there to find peace :)
- Hey, fixing bugs is easy this way :))
-
-22/06/1999
-- When 'A'ctivating the first screen showed is the equipment and no more the
- inventory
-- Some new gfx drew by Andreas Koch
-
-06/07/1999
-- You can place object kind in the special levels instead of artifacts by
- using 1000+k_idx as the number instead of just the artifact index
-
-17/07/1999
-- Add the Yeek race, but not as in Zangband. It's the one from Drangband.
- I was thinking of a race who advance even quicker than the humans in levels
- since a long time and I've found it !
- So they suffer lots of disadvantages but need less exp than the other
-races, i.e.: When a DragonRider comes to level 2 a Yeek can already be at
- level 7 !!
-- Added the FLY attribute, it allows you to fly over trees and mountains
- because it's no longer possible with the levitation one. It's also a lot
- rarer since it's POWERFUL in Galgals and Mirkwood. DragonRiders have it
- by default. There is also a change in the features flags, CAN_LEVITATE
- means that you can just avoid them by floating over it (like a pit,
- water, ...) and CAN_FLY means that you must have the FLY flag to cross it.
-
-19/07/1999
-- The monster's drop are now created at the same time as the monster is
- created. First it disallows scumming of monster drops. And the most
- important thing is that it will allow me to add the new ability of stealing
- objects from monsters (everyone will be able to do it, but only Rogue will
- be excellent at it). For the point of view of the player there is no change.
- It may produce some strange object disappearance in the late game since
- all the objects are generated with the dungeon. And thus it may need to
- increment the maximum size of o_list in misc.txt. If such problems shows
- up, email me.
-- Press 'Z'('[' in roguelike mode) to STEAL an item from a monster. The
- success rate is based on your dexterity, the fact that you are or aren't
- a Rogue (being one makes it easier), the weight of the object to steal and
- the base level of the monster. A Rogue will also gain some experience
- if he/she succeeds. This made them more Rogue and less Warriors.
-
-22/07/199
-- Add more graphics from Andreas Koch along with a new version of the editor
-
-26/07/1999
-- The resurrection effect of the gods is now harder to get and decreases a lot
- more your grace. It was ... well ... too powerful for the cost of some
- crappy artifacts
-- Finished the Magery realm created by Chris Weisiger (jmartin@inreach.com)
-
-03/08/1999
-- I've finally fixed it ! You know, this ugly bug that disallows the darkening
- of the grass & mud tiles when they have been lit.
-
-18/08/1999
-- Yeah ! It's done! The new magic system is finished (I will add Spirit Realm
- later). The final form is 4 Major Realms : Valarin, Nether, Magery, Shadow
- and 4 Minor Realms : Crusade, Tribal, Sigaldry, Illusion.
- The only problem is be that it could be unbalanced, especially the
- Shadow realm since I've created it :)
- Anyway it should be great. There are still a lot of old spells but some new
- coloured funny spells for you to discover, as Control the Ring, Infuse Amulet,
- Scribe Scroll, Doppleganger, Volcano Flow, Tidal Wave, and a lot of others!
- The max number of spells a character can learn depends on his class. But
- generally the player can learn fewer spells than the total number of spells he
- has in all the books he can read.
- I want to thank Akhronath (who has the first idea and who write some realms),
- Shawn Cheng, Chris Weisiger and DSCreamer<DSCreamer@aol.com> for their great
- help.
-- Moldoux can not appear at any other level than level 1
-
-21/08/1999
-- A new version of the Tile Editor plus a full set of graphs (expect the books)!
-- Moved the dungeon types definitions from tables.c to a new info file in the
- lib directory: d_info.txt
- It allows you to add new dungeon types easily.
- There is also a brand new feature: You can specify which monster flags that
- are NEEDED for a monster to be generated in the dungeon.
- There is also an addition of dungeon flags. Here is the structure:
- N:<index>:<name>
- D:<long name>
- W:<min depth>:<min depth>:<min player level>:<next dungeon>:<flags mode>:<min alloc>:<max alloc chance>
- L:<floor1>:<%1>:<floor2>:<%2>:<floor3>:<%3>
- A:<wall1>:<%1>:<wall2>:<%2>:<wall3>:<%3>:<outer wall>:<inner wall>
- F:<flags>
- M:<monster flags>
- S:<monster spells>
-- The quest rewards are always good
-- I've finally found and fixed the Mirkwood Spiders Quest
-
-24/08/1999
-- Add the MAZE flag to the dungeon type flag list, which instead of a normal
- dungeon generate a full big maze ! And it's EVIL ! Note that there will be
- no rooms and no vaults generated, just a plain evil maze
- The algorithm is from <Pierre.Bru@spotimage.fr> on rec.games.roguelike.development
-- Note about the dungeons : A dungeon can't have more than 40 levels
-- You can use SMALLEST, SMALL and BIG as dungeon flags to specify the level's
- size
-- 6 new dungeon types: a Graveyard, an Illusory Castle, an Orc cave, a Maze
- a Dragon's Lair and A Forest with specific gfxs and monsters restrictions
-- Some new gfx form Andreas Koch mostly to add more flavor to the towns
-
-29/08/1999
-- You can add a guardian and a guardian artifact to each dungeons types with
- the following flags: FINAL_ARTIFACT_artifact_number and
- FINAL_GUARDIAN_guardian_number
-
-29/08/1999 - PernAngband 4.0.0
-
-01/09/1999
-- Fixed the max_dlv non allocation error
-- Fixed the Tribal realm spell descriptions
-
-01/09/1999 - PernAngband 4.0.0b
-- New dungeon type, the Netherworld with Muar and the Wand of Fireball of
- Mithrandir at the bottom
-- You can't gain a fate before being level 10
-- Some cosmetic changes suggested by Akhronath
-- A new Artifact by Akhronath, The Long Sword of Murazor 4d5, so ... the next
- time you see a long sword 4d5, beware ...
-
-05/09/1999
-- Add a feature flag to allow running
-- Fixed the Chaos Warriors bug (they were unable to use magic !)
-- Fixed the Chaos Realm descriptions
-- You can't rest on a between gate
-- You can now steal from stores. But beware of the consequences if you fail...
-- Fixed a bug in that when recalling to the town the player was sometimes
- placed in the upper left corner
-
-08/09/1999
-- Fixed a bug that disallowed the creation of entrances to some vaults
-
-14/09/1999
-- Fixed the Dragon Tower bug
-- Add minimum player level to the random dungeons
-- Add shafts, you can use them do go up/down for up to 4 levels(but you can't
- ignore quest levels). Original patch from Static Chaos. Idea from GSN
-- Add a dungeon flags to forbid generation of doors
-
-27/09/1999
-- Some tweaks to the possessor code as written by Static Chaos i.e:
- You must possess a monster that is able to open to door to do so. The
- same applies to bashing. Your sex is modified by your body. Lots of tweaks
- to the spells that can be used...
-- The racial power of the Dwarves is now the same as The Pick of Erebor
- activation: they can find hidden passage in the walls
-- There is 1 chance in 10 that the level is an magical level, which means that
- each grid will contain more mana than a normal level.
-- Add some new sentences to the monsters sentence lists
-
-04/10/1999
-- Began to add the Druid class. But it's TOTALLY different from the other
- variant's Druids. They make intense use of the mana flow from within the
- earth and the elements, thus their spells can regenerate the mana they have
- used by pumping it from the floor, like the Tunnel spell which will blink
- the player and will try to absorb enough mana form the grid he/she lands on.
- They can also (and they are the only to be able to do that) regenerate the
- mana flow of the earth. They also can use enhanced attack types called
- Druidic Bolt/Beam/Ball that can follow a mana flow laid by the player.
-- The Druids can sense precisely the amount of mana of a grid
-
-08/10/1999
-- Added some revised graphics by Andreas Koch
-- Added the code provided by Alexey Guzeev(aga@russia.crosswinds.net) to
- compile PernAngband under OS/2 with EMX
-- It's finally fixed ! the damn bug that was crashing the game when leaving
- a town on certain system (Mac and Windows) ! this will never happen again !
-
-27/10/1999
-- Finished the Druid class. They have 40 spells (8 * 5 books). The spells that
- activate Mana Runes is not active for now, but it will in a near future.
-- Add a slightly modified Tom Morton fake artifact patch (it won't print {} at
- the end)
-
-30/10/1999
-- You can inscribe an object with !! to notify the player when it's recharged
-- Lots of bug fixes thanks to Lothar Lange <100644.2004@compuserve.com>
-- Lots of new ideas thanks to Lothar Lange <100644.2004@compuserve.com>
-
-30/10/1999 - PernAngband 4.0.1
-- "Foolish mortal! Thou hast not pleased me! I'll doom your game with the new
- horrible DG curse !"
- Yes I've done it, the DG curse is even worse than the TY one. One of it's
- most perverse feature is that it can replicate itself to contaminate sane
- objects that can't be cured. Also if you remove the curse of a DG cursed
- object, it will recurse itself automatically !
- Beware of the horrible Long Sword of Murazor because it carries the ancient
- morgothian curse !
- Oh, there are also some monsters that give the DG Curse when dying ... but
- I'll let you find whose they are by yourself :-<|> (Dark God makes an evil
- smile). I can just say one thing : you should *REALLY* *NOT* kill Mathilde...
- But do not worry she's got much more HP, so you can't kill her anymore :)
-
-01/11/1999
-- Add the Rod of Home Summoning, which acts like the old dragon spells
- "Call Home"
-
-08/11/1999
-- Drastically reduced the recharging time of the Dragon Scale mails in order
- to render them useful.
-- Added a new weapon ego-item: of Spinning, which will make you spin around
- in order to hit every monster around you. Note that you'll only get one
- blow for each monsters whatever your normal number of blow is.
-- Added (ok stolen) the question in the GSNband FAQ about wrists hurting (it can
- be useful, so everyone should know)
-- Rogues and monks gain more and more stealth as they gain levels (SBF)
-- Added some sentences for the Dwarves (in monspeak.txt)
-- Added the support of two-handed weapons (from GSN). Thus there are weapons
- that can be handled with two or one hand (but with one hand it halves the
- damage). A 2 handed weapon can't be wielded with a shield.
-- Added the random character name generation from Cthangband
-- Added rivers (water & lava) from the Steven Fuerst fractal patch. Note that
- you have to add WATER_RIVER, LAVA_RIVER, WATER_RIVERS or LVA_RIVERS to a
- dungeon to have some rivers generated (actually in Mordor(lava), Dragon lair
- (Lava) and Forest(Multiple Water))
-- Updated generate.c to the Steven Fuerst fractal patch room generator (using
- room_alloc), in order to implement the remaining part of the patch easier.
- But I'm still having problems adapting it to my extended dungeon generator.
-- Ahah ! I've resolved the problem !! there are now fractal rooms (15%, can be
- always enabled by specifying the CAVE flag), now the orc caves looks great
-
-10/11/1999
-- Added the Caverns(enabled via the CAVERN flag)
-- Hell has been moved down, it now begins at level 666! :)
-
-12/11/1999
-- Add the Static Chaos persistent dungeon patch that save every level of a
- dungeon (which has the PERSISTENT flag) on disk and reload it instead of
- regenerating a new level.
-- Add the Outer World dungeon type (this is an entrance to a place of an
- incredible stability). It use the PERSISTENT flag and thus will be saved.
- Only level 50 characters can go there to prevent abuse(like have an old
- ultra powerful character and a new one and going into the Outer World to
- exchange some stuff). And yes the saved dungeons are the same for EVERY
- characters. But to add ... err ... variety, I've put it from level 300 to
- 305, I've put it to have at least 30 monsters from the beginning AND to have
- an higher monster generation rate(1/60 instead of 1/160 !), thus you'll
- NEVER get bored there :)
-- Implemented the much more complex trap system from Angband/64 thanks to the
- patch made by Static Chaos. There is 169 traps (see tr_info.txt).
- Beware that on average the traps are deadlier...
-- It comes along with a new feature for stat system: temporary stat drain,
- it's cool
-
-14/11/1999
-- Renamed Power Batteries to Essences
-- The DG_CURSE can put the NEVER_BLOW flag on a weapon ... sadistic !!!
-
-16/11/1999
-- DSMs now have been granted the FLY flag
-
-19/11/1999
-- The monster memory now colors some important things about the monster (like
- resists, speed, ...)
-- Fixed a wand of wishing bug, that made them sometimes NOT use a charge
-- Moved the special level DeathWatch to the Orc Cave
-- Moved the special level Treasure Room to the Maze so people are forced
- to play those dungeons if they want the artifacts
-- Random quests will only occurs on PRINCIPAL dungeons (the one created by
- splitting the vanilla dungeon into 4 smaller ones, Galgals, Mirkwood,
- Mordor and Angband itself)
-- To prevent too many YASD from the DG curse of Mathilde she has now been
- granted 22500 hp, but as usual she can't attack :))
-- Fixed a bug that disabled the guardian at the bottom of some dungeons
-
-25/11/1999
-- Added main-gcu from Angband/64 to allow larger screens
-- Added the new note command that dumps to a file from "Tom Morton"
- <tmorton@yikesstation.freeserve.co.uk>
-
-27/11/1999
-- Added funny time message from Z
-- Added object experience as suggested by Ceilti <Ceilti@aol.com>
-- Fixed a bug when the magestaves were cursed
-
-29/11/1999
-- Added the small trees (along with a new feature flag: SUPPORT_LIGHT) to
- replace the walls in the Forest and Mirkwood
-- Some new gfx from Andreas, and the town of Bree with the new tiles
-
-02/12/1999
-- Add 4 dungeons by variaz@hotmail.com: Vanilla Dungeon(only from Vanilla Town,
- The Small Water Cave, The Sacred Land Of Mountains(if you don't fly ...
- do not even plan on going there),
- The Wild Land Of Kurukar(It sure looks great)
-
-04/12/1999
-- New dungeon flags: HOT and COLD that affect object decay
-- Add YA*IF (Yet Another *_info File): wt_info.txt
- It defines wilderness features *, allowing a better wilderness map. Since
- it now defines nearly everything a wilderness need to have, the map itself
- only have to be an array of feature and seed, thus allowing a much bigger
- wilderness. I also plan to have a Omega wilderness mode where you can have
- an overview of the wilderness to travel quicker (but time will pass much
- quicker too:)
- The structure of w_info is also changed, it's uglier but well .... :)
- The wilderness size must be EXACTLY the same as the size defined in misc.txt.
-
-06/12/1999
-- Scrolls of Reset Recall are now WORKING !!!!!
-- The new wilderness mode is done ! When you reach the border of a wilderness
- screen you go to the small scale wilderness map, where you can see all
- the wilderness map with the towns/dungeons/... A lot of commands are
- disabled there and moving takes MUCH more time, so beware of the food !
- You can enter the big scale mode by pressing > (this allow you to enter towns)
- NOTE: The Death Molds CAN'T reach the small scale mode because their
- erratic movements are impossible to handle in such a scale.
- BEWARE: Your imprinted pets WON'T follow you in the wilderness !!!
-
-11/12/1999
-- Add wilderness encounters
-- Add Oangband rod/wand stacking
-- Amulets of the Serpent from Sadi Khan <sadik@christa.unh.edu>:
- Resist Poison, Dexterity, some AC and Poison breathing
-
-12/12/1999 - PernAngband 4.0.5
-
-18/12/1999
-- Updated the makefiles and renamed object3.c to traps.c
-- Add 5 new essences from Sadi Khan: Force, Darkness, Lightning, Mana and
- Knowledge
-- Fixed the bug that was placing the player at the town entrance when
- leaving a building
-
-20/12/1999
-- Add the tool slot. It's actually only used to wield a shovel/pick but I've
- some plans for it
-- You can only dig walls if you use a shovel/pick in your tool slot
-
-24/12/1999
-- Removed the player ghosts, well in fact made them a compile-time option(see
- config.h)
-
-26/12/1999
-- Added the Necromancer class. But again not quite the same as you've seen
- before. They can't be killed as easily as the other class. In fact when
- their HP comes to 0 they don't die but become undead for a while. While
- being undead their HP is replaced by DP(Death Points) that have a max
- inferior to the max HP and that are slowly decreasing(1 DP less each turn).
- They can use all the healing spells/potions/... but this won't stop them
- from being reduced again. The only way for them to come back in the world
- of the living is to kill 2 * player_level monsters.
-
-01/01/2000
-- Happy New Year !
-
-02/01/2000
-- Add a new curse(as suggested by LucFrench@aol.com). When a weapon has this
- curse and that the wielder attacks a monster with it, it can clone it !
- And it's REALLY REALLY annoying, especially when fighting some kinds of
- wyrms :)
-
-10/01/2000
-- Finally fixed the flags shown on the character display.
-- The quit without save command(CTRL + L) is now a compile time option disabled
- by default
-- The Necromancer class now has 5 spells (used the same way as the mindcrafter
- powers)
-
-17/01/2000
-- Power gained by levelling artifacts has been reduced
-- New unique monster: The Greater Lag Monster... beware :)
-- AHAHHAHAH ! I got it ! the wilderness bug that made the game crash when
- entering a town is fixed ! And the wilderness system has been greatly
- improved.
- Now to switch the wilderness mode, just press < or >.
- Everything should now works properly
-
-16/02/2000
-- Each Nazgul will now drop his Ring of Power. They are randomly generated
- and thus they don't appear in a_info.txt. They always give invisibility,
- life draining and are heavy cursed.
-
-21/02/2000
-- Changed the format of w_info.txt again, it's much more readable now.
- I also added a additional parameter to the W lines of wf_info to define
- which letter will be used in w_info.txt
-- 60x20, this is the scale of the new wilderness, it tries to looks like
- the 3rd age middle earth map. Thus some dungeons leaved the towns they
- were used to be to join their "real" place on the map. Only the Upper
- Reaches of Galgals are still reachable from Bree.
-
-24/03/2000
-- Added a small hack from Static chaos to allow running faster with the
- overhead map enabled.
-
-24/03/2000 - PernAngband 4.0.6
-- Possessors now have a MUCH better pseudo id, equal to warrior's one
-
-06/04/2000
-- Changed the wilderness map with the one provided by Gwidon S. Naskrent
- (naskrent@artemida.amu.edu.pl). It's bigger, it's better :)
-- Fixed a bug with the chasm opening inscription
-
-08/04/2000
-- Fixed a bug with the staff of wishing
-- Druids can now pass through trees
-- Stairs are now noticed again (when you see one it will stay on your screen
- even when out of torch radius)
-
-10/04/2000
-- When a Necromancer turns into an undead he/she/it gets cured of everything
-
-05/05/2000
-- MAYBE fixed the damn wild bug ... again ? oh please GREAT RNG help me !
-
-08/05/2000
-- Added the Notes patch from Chris Kern. That allows you to get a .txt file
- recording great events in your life, your notes, ...
- Very useful I think
-
-11/05/2000
-- Fixed the artifact wands stacking bug
-- Removed the Netherworld dungeon
-- Added the Moria dungeon, it's not random and can be found in ... the moria
- mountain chain :) There is Muar waiting you at the bottom, guarding the
- Quarterstaff of Olorin
-- Waldern, the king of water is back, and he is the final monster of the
- small water cave, guarding a the Trident of Ulmo. But beware it is more
- powerful than in vanilla
-- Dungeon guardians and dungeon guarding's artifacts can only be generated
- in their respective dungeons
-- Removed rumors that were still Zangbandish and some others I didn't like :)
-
-14/05/2000
-- The MONSTER_PERCENT_ flag can be added to some dungeons to specify the
- amount of monsters that are affected by the dungeon specific restrictions
-- Random dungeons now appear on the overhead wilderness view
-- COULD IT BE !!!!!! yes it could !!!! thanks to Tom Demuyt that sent me a
- savefile where he wasn't able to learn spells, I may have finally fixed the
- dreaded spell bug !!!! I say may because I'm waiting for some fellow
- mac user to compile it to see if it really fixes the bug.
-- IT WASN'T ! but now it *IS* !!!!
- That was an other bug. And now Gob, the great Gob, the powerful Gob,
- found the dreaded mac spell bug !!! thanks Gob !!!!
-- Changed the price for Runes/Essences to be more accurate
-- Changed some uniques in r_info to their former vanilla glory
-- The look command can now show the trap's types
-
-18/05/2000
-- Fixed some typos(thanks whimsy)
-- Began to add the Body parts system to allow more rings, weapons,
- everything, depending on your current corpse (dragons will have more rings,
- mariliths 2 weapons, ...)
-- If your corpse allows the use of more than one weapon, you can use them :)
- let see a Sorceror using Ringil AND Gandalf ! :) well first he has to find
- the rare scroll to change body and then to find a corpse that allows 2
- weapons
-- Changed color of shafts (brown now) because they were hardly visible
-- Flying no longer allows passing over mountains, you MUST have a Climbing Set
-
-22/05/2000
-- Fast autoroller as a birth option
-- E'x'amining books in stores now browses them if your class can read them
-- Add a bookstore to Lothlorien town
-
-26/05/2000
-- When in battle rage(berserk) and using the ascii mode the screen goes all
- red (as it is white for invulnerability and black for wraithform)
-- r_info is modified to give all monsters some inventory slots. the format is
- E:weapon:torso:arms:finger:head:legs
-
-27/05/2000 - PernAngband 4.0.7
-- add a new dir to lib, DNGN which contain the definition of the LEVELS
- not the dungeons. one file for each level named dun$dungeon$.$level$
- In it you can have some declarations, like B:dungeontype which will
- create a stairway to an other dungeon, thus allowing to have "branches"
- in the dungeons.
- L:dungeontype and L:level specify which is the "father" dungeon and at which
- level the stair appear.
- S:ext means to save the level(and thus to reload it) in the player.ext file
- so allowing the use of persistent levels(the persistent dungeons option
- is gone)
-
-29/05/2000
-- Necromancers can use the Nether realm in addition to their old set of
- powers(now accessible through 'U')
-
-01/06/2000
-- Boomerangs of spinning are no longer allowed (that was silly)
-- Increased the rarity of the ULTIMATE artifacts (Magestaff of Gandalf,
- Longsword of Eru, Seeker Bolt/Xbow of the Elves)
-- Fixed the displaying of attributes under the 'C'haracter display
-
--04/06/2000
-- Players can now choose which kinds of monsters they don't want in their game
- at birth (wipe all Pern monsters, all Cth, monsters, joke monsters, ..)
- Note that monsters in fixed quests are not affected.
- Thanks Static Chaos.
-- In the Maze you can no longer remember anything, that means everything you
- see is what it's in your light radius ! MUAHAHHAH, I'm *NASTY*
-- Archers now get a better chance of not breaking their ammo as they
- advance levels
-
-08/06/2000
-- Note taking bug should be fixed
-- Fixed a bug with the incarnation code
-
-11/06/2000
-- Added the Orc Barracks special level (level 35 of Moria) from
- Chris Weisiger (jmartin@inreach.com)
-- The maze is now guarded by The Baby Minotaur who is holding The Steel
- helm of Hammerhand
-- The graveyard is guarded by Vecna holding Doomcaller
-- You can now use the 'l'ook command in the small wilderness view
-***********IMPORTANT************
-- Between gates are no longer automatic, you must press > while standing on
- one to activate it
-********************************
-
-16/06/2000
-- Revised the Adventurer's guide thanks to Chris Weisiger(jmartin@inreach.com)
-- You can no more recall from a quest
-- You can no longer target pets
-- Re-enabled the "Control the rings" spells of the Shadow realm
-- Between gates are now purple +
-
-02/07/2000
-- Only priest-like characters can use the Valarin realm
-- Removed all the references to Logrus
-- Tunnelling rubble will place the standard floor of the current dungeon and
- not the floor feature
-- Grow trees no longer crashes when used near the dungeon edge
-
-05/07/2000
-- Fixed the character dump resistances
-- When a full character dump is requested (upon death) the self-knowledge
- screen is used instead of the grid of abilities, that looks better :)
-- Fixed a bug in the placement of stairs which sometimes led to a stairway
- to another dungeon when not requested
-- Fixed the bug that generated 'unknown' grids
-- Should now compile (nearly) without any warnings
-- Fixed the mountain bug that hung the game when entering mountain chains
- in the wilderness
-
-07/07/2000
-- Some more monsters from Angband/64 and some more work on r_info from
- Static Chaos. That brings the number of monsters to ... 1023 !
-- Damage taken from going between is divided by (ac / 50) + 1
- So between 0 and 49 ac it's full damage, between 50 and 99 it's half
- damage and so on
-- Greater Hell Beasts now have .. 1 hp :)
-
-11/07/2000
-- Add the Unbeliever class, they are anti magicians. Great warriors, they
- have the worst magic device skill of all the classes, they continuously
- generate an anti-summoning field around them disabling monsters from
- summoning. The radius of the field increase with levels. After level 20
- they can also disrupt the magic continuum, thus getting the same effects
- as Anti-Magic, Anti-Tele and The Stone of Lore(nobody on the level can
- teleport)
-
-13/07/2000
-- Add an option to auto tunnel walls when bumping into them.
- NOTE that it'll ALWAYS take a turn then, so beware...
-- Really fixed the note taking bug (ok stole the fix from Zangband :) )
-- Changed the object description so now it's "Smeagol's Corpse" instead of
- "The Smeagol's Corpse"
-
-13/07/2000 - PernAngband 4.0.9
-
-29/07/2000
-- Orc Barrack's between doors are fixed
-- God favor is reinitialized upon birth
-- Added the Daemologist class along with a brand new realm and lots of new
- cool effects(try making all your pets explode ! :)
- All made by Static Chaos
-
-31/07/2000
-- Fixed lots of compilation warnings thanks to Static Chaos
-- Added the random vaults and crypt vaults from Zangband with the help of
- Static Chaos
-- Fixed some bugs pointed out by Bablos
-- The Ray Rune now relay make a beam and not a pseudo bolt
-
-03/08/2000
-- 2 handed weapons wielded with a shield now really restrict your fighting
- abilities (I forgot to add the code before) :)
-- Possessors can't leave their body while they wear cursed items
-- Word of Destruction is no longer allowed in quests
-- Add a fate spoiler created by Dustin Ragan
-- Removed the old new player ghosts implementation
-- Added the new old player ghost implementation (stolen from Drangband)
-- Rod system have been totally reworked. Now you can find "base" rods without
- power (rods of nothing) with a certain quality (wooden, iron, ...) on which
- depends the amount of mana they contain. You can also find rod tips which
- contain the real spells but cannot be activated alone. You must attach (with
- the 'z' command) a rod tip to a base rod before using it. The spells of the
- different rod tips need different amounts of mana (so illumination is less
- mana-hungry than healing) :). You can also have base rods ego-items (artifacts
- soon) that can decrease the mana cost of the spell, increase the capacity
- of the rod, decrease the time needed to zap the rod, ...
- Oh BTW, you should be eager to get an Adamantite Rod of Healing of the
- Istari :)
- Now rods will hopefully be useful.
- Note that you have to identify the base rod to get the mana indicator
-- Note files are now playername.nte instead of playername.txt
-So if you want your note file to be carried to the next version you'd better
- rename it :)
-- Fixed a bug that prevented Azog from being generated at the bottom of the Orc
- Caves
-
-07/08/2000
-****************** IMPORTANT *****************
-- Removed the Python support because it was slowing the game, adding
- weight to the executable (and thus to the archive), was mainly unused,
- and was never present in some ports
-**********************************************
-
-09/08/2000
-- Unbelievers are now much better at perception, and actually become even
- better as they go up levels
-- Fixed several bugs thanks to Iain McFall
-- Reset recall is now much nicer to use thanks to Iain (again :)
-- When a character is infected by the Black Breath it is show in the char
- screen & dump
-
-15/08/2000
-- Cursed mage staves should no longer crash the game when identified
-- A Marilith can now drop it's corpse when killed
-- Add the gods spoiler made by Dustin Ragan
-- Fixed a bug that could eventually crash the game when looking at the quests
- screen
-- Fixed a bug in the random junk artifacts that made them cure fear when said to
- cure confusion
-- Add the squelch patch from Iain McFall
-- Boomerangs are now pseudo-id'd
-
-19/08/2000
-- The *thanc artifact daggers are less common because they are so powerful
-
-24/08/2000
-- The Midas Touch 30k gold limit has been removed (suggestion from Chris)
-- Fixed (ok ok Iain fixed :) ) several trap related bugs
-- Squelch now use the pseudo-id thanks to Iain
-- Pseudo-id inscriptions are no longer part of the real inscription of an object
- and thus ... it's better :)
-- Tribal spell "Life Drain" now reduces your stat permanently 30% of the time
- and the other 70% it can be cured via restore stats pots. The damage is now
- always 50d50 and is no longer affected by mage staves of spell
-- Tribal spell "Meditate" no longer hastes/heals you
- (it still heals your sanity) and the glyphs' radius have been decreased
-- Add the Trap of Acquirement that will give a great object and then mutate
- into an other trap. It can never be identified and the color varies.
- Idea from Iain
-- When casting charm upon monsters only the non-pet ones will be affected
-- Elder Aranea HP reduced
-- Small trees are burned by fire
-- Randomly activated mutations are no longer activated in the overview
- wilderness
-- Ghoulkings are now z instead of p
-- Thrown potions now give xp when killing by a ball effect
-- Scrolls of reincarnation have been removed now you can only find scrolls of
- deincarnation. To reincarnate into a new body 'U'se the appropriate power
-- Recharging is now useful again
-- Breeders should be a BIT slower
-- Reduced mutation chance of breeders from 7% to 3%
-
-03/09/2000
-- New, unified store/building code
-
-08/09/2000
-- Add quest plots. Feature 75, 76, 77, 78 are now permanent walls but used
- as quest plot info holders. Before the new building code quest info was
- stored in the building feature but now all stores/buildings use the same
- feature(74) and the "special" value defines them.
-- Add semi-random towns. Now if the ' ' (space) character is used in the town
- definition this grid will be replaced by the feature calculated by the
- plasma generator as if it was a normal wilderness screen. So the forest of
- Lothlorien is plasma generated and not fixed. It add variety and consistency
- with the rest of the wilderness
-- All towns are now updated to the new store/building code
-- Removed the "you are being crushed" bug when going in the overview map thanks
- to Iain McFall (as usual :) )
-
-10/09/2000
-- When you use a 2 handed weapon and press 'e' the equipment list will show
- the weapon(and some info) in the shield slot too
-- Monsters can't have fewer arms than weapons
-- Mimics have been upgraded. They now have 5 powers. First is to use books of
- lore as before. Second is invisibility. The other ones are Mimicries.
- There are 3 mimicries, legs mimicry, wall mimicry and arms mimicry.
- Legs and arms mimicry will "create" a new body part (or some) for a certain
- duration. Wall mimicry will make the caster able to walk in walls (he becomes
- a wall) but ONLY in walls .. not on floor .. so beware with this one
-
-27/09/2000
-- For your god to resurrect you need 3 times more grace and your grace
- will drop to -100000
-
-30/09/2000
-- Add exploding ammos (bolt, arrows, shots) thanks to a patch by Static Chaos
-
-13/10/2000
-- Add some patches from Kusunose Toru <kusunose@hcn.zaq.ne.jp>
-- Neuters get a weight & height
-
-13/10/2000 - PernAngband 4.1.2
-
-14/10/2000
-- Building doors can't be erased
-
-28/10/2000
-- Fixed a bug in the rod system when attaching form the floor
-- Added fountains that you can quaff from ('H' in normal mode, 'V' in roguelike
- mode, yeah I know it was for version number .. but .. mhh who is using it ?:)
- Thanks to Static Chaos for the patch
-- You can fill empty options with fountains(thanks static chaos)
-- Added the Iain McFall Show Monster patch to show all viewable monsters
-
-08/11/2000
-- Fixed numerous bugs
-- Fixed the st_info & ba_info files thanks to Kusunose Toru
-
-16/11/2000
-- Godly blasts can't be reflected anymore, so beware, puny mortal !!! :)
-- Added a whole bunch of new floor features (ice, mud, sand, sandwalls, ...)
- thanks to Static Chaos.
-- More spell effect will affect the dungeon, for example, fire will melt ice,
- nether will kill trees, fire will create ash, cold will freeze water, ...
- thanks to Static Chaos again :)
-- Cleaned up the feature code again (that was a REALLY messy part of angband...
- and especially of Zangband)
-- Note: Sandwalls can be dug WITHOUT any digging tools
-- Teleport scrolls/staves are back in the shops
-- Mages, Wizards and Sorcerors now only get a wand of fire bolt at birth
-- Finally fixed the Alchemists extracting powers
-- Fixed numerous bugs thanks to KUSUNOSE Toru
-- Desert and Glacier wilderness features now really look like desert &
- glacier :)
-
-18/11/2000
-- Debug commands are allowed in the overview map, but beware, do not create
- objects & monsters there ...
-- The wilderness map is no longer fully known, you have to explore it
-- New wild.c file to support all wilderness functions
-- Maps can be found to reveal some places of the wilderness
-
-27/11/2000
-- Exp gaining weapons will gain levels way slower
-- Ring & Amulet random artifacts will only be "Ring of foo" and not
- "Ring of Slow digestion of foo"
-
-30/11/2000
-- Level gaining Artifacts have been significantly toned down
-- Sauron lost his chances to drop The One Ring
-- Blood of Life potions & Staves of Wishing are more rare
-- Your god wont always resurrect you even if you have enough piety
-- When leaving corpses, Possessor equipment will be dropped to floor
- to prevent their form being "lost"
-- Sandworm lair, a new dungeon
-- Staves of wishing now only have 1 charge
-
-12/12/2000
-- A patch to the alchemist patch from KUSUNOSE Toru, they should now work
- perfectly
-- h-system.h fixed so it should compile fine on Linux
-
-29/12/2000
-- New r_info.txt with the HAS_LITE flag, thanks to Static Chaos :)
-- Now some monsters can have a light around them
-
-03/01/2001
-- Phial of Galadriel and Phial of Undeath now use the same symbol(yellow ~)
-
-06/01/2001
-- Fates now show up in the character dump (thanks Kusunose)
-- Scrolls of Divination are more friendly now (thanks Kusunose)
-- Artifacts in monster inventories not yet seen are not shown in the
- artifact list (thanks Kusunose)
-
-08/01/2001
-- Zweihanders are now 2-handed weapons(as they always should have been :) )
-
-11/01/2001
-- Ego Rods are now "xxx rod of egoname of power" and not
- "xxx rod of power of egoname"
-- Fixed some typos(parchEment, NumeRoNean, ...)
-- Fixed a bug with junk randarts
-
-18/01/2001
-- Gods now need more sacrifices
-- Disabled the monster lite feature right now because it's HORRIBLY buggy
-- The Sandworm Queen will now drop the Sandworm armour when killed
-
-03/02/2001
-- Now you can separate a dungeon entrance from a dungeon exit on the
- wilderness map using the WILD_ix_iy__ox_oy flag in d_info.txt.
- ix, iy are the coordinates on the wilderness map of the entrance.
- ox, oy are the coordinates of the exit.
- Note that each of them(entrance and exit) must have a physical entrance
- on the wilderness map(that is a line in w_info.txt).
- When you use the entrance to enter you get to the first level but when you
- use the exit to enter you get to the last level.
- So now you can have dungeons that create shortcuts in the map.
- Or even allow to go in previously unreachable places(like now the dungeon
- of Moria allows you to reach a secret valley in the Mountains of the Moria
- which allow getting to some other dungeons)
-- Fixed a bug with fountains (yeah, fountains of the Blood of Life were quite
- unbalancing :)
-- Priests can't use Tribal magic anymore
-- Mages can't use Crusade & Illusion Magic anymore
-- Rogues can't use Crusade anymore
-
-05/02/2001
-- Found why under certain circumstances forbidden objects could still be
- generated (and that's also fixed now :) )
-- Dungeons & Monsters can now have object themes (yeah I know, I stole that
- from Zangband, though the dungeon theme was in my head for long, but
- when I steal I do admit it ...)
- For example The Sandworm lair is really full of magical items, while the
- Orc Caves are more on the side of the weapons & armors. And the Dragon Lair
- is filled with ... oh well everything :) and so on.
- So it's now really worth to get out of the 4 basic dungeons and see the
- wild world!
- All dungeons are done with the themes, it could take a bit longer for
- the (1031) monsters... :)
- NOTE: Dragon Scale Mails are considered TREASURES
-
-07/02/2001
-- Ego Monsters, yes like Ego items but for monsters. New file re_info.txt
- defines all possible ego monsters types (skeletons, zombie, ...). It can
- modify, the flags, spells, level, speed, ac, ... of the monster that is
- turned into an ego monster.
- This will increase the randomness of the game, increase the number of
- monsters from 1031 to .. a lot... :)
- There are not much ego monsters right now, so feel free to submit them
-
-09/02/2001
-- Sorcerors can't use much armor
-- Beastmasters have been give access to the Tribal realm, the Beastmaster's
- powers are now available through the 'U' key
-- Player Raise death spells will now really create an undead. For example
- you cast raise death upon a kobold corpse and you can get a Skeleton Kobold,
- or a Zombie or a Spectre one. New Undead types will be added later. And I'm
- open to ideas naturally
-- Narya activation is now Healing (500)
-- Nenya activation is now Healing (800)
-- Vilya activation is now Healing (900) and cures Black Breath
-- Daemonologists can now wield their books (in the weapon slot). When used this
- way, spells are cast in 1/3 of a turn otherwise it takes 5 turns
-
-11/02/2001
-- Specialized ESP, like Orc ESP, Troll ESP, Dragon ESP, ...
- They are less rare than full esp, but full esp is more rare
-- Fixed a Runecrafter bug which could crash the game if no second rune was
- selected
-
-11/02/2001 - PernAngband 4.1.5
-
-11/02/2001
-- Ents get nearly no sustenance from eating
-
-15/02/2001
-- Center player option
-- Alchemist artifact creation now requires player level magic essences to
- work. The stats are permanently reduced upon failure (as it always meant to
- be). You PERMANENTLY lose 100 max hp when trying to create an artifact.
- This should reduce the number of mad alchemists :)
-- Dark Swords as a new item type. They generate an antimagic field of 50%
- minus the sum of the enchantment (a +5+5 one will only do 40%) on a
- 5 tile radius (also minus the enchantment)
-- Unbelievers now generate a (player level)% antimagic field on a distance of
- (player level / 10)
-- An antimagic field disables any form of magic on the user, and can prevent
- monsters from casting spells (not breathing). A 50% antimagic field will have
- a 50% chance of stopping a spell
-
-18/02/2001
-- Normal Artifacts. Normal Artifacts are artifacts found directly in k_info
- that doesn't require a place in a_info. That allow strange artifacts, like
- wands, rods, staff (those were possible already but ugly), ... and even
- food
-- The Rod Tip of Home Summoning is now a Normal Artifact
-- The Greater Ration of Health is the first (very rare) food artifact !
- When eaten it provide +70 hp permanently
-- The Potion of the Blood of Life is now a Normal Artifact
-- Invulnerability can no longer appear in fountains
-- The Ring of Precognition is now a Normal Artifact
-- The Ring of Wraithform is now a Normal Artifact
-- The Scroll of Deincarnation is now a Normal Artifact
-- Hell is now the Nether Realm
-- Fixed a bug that created stairs at bottoms of dungeons
-- Extra blows can only be provided by things in the weapon slots
-- The Scroll of Mass Resurrection
-- Renamed Warrior-Mage to Warlock
-
-20/02/2001
-- The Wand of Stone to Mud of Thrain and The Wand of Fireball of Gandalf
- got the EASY_USE flag, allowing them to be used even by unskilled
- characters
-- As does the Stone of lore
-
-23/02/2001
-- Fixed a bug that allowed people in quests to use the '<' key to get to the
- wilderness timescale
-- Fixed a quest bug that allowed players to regenerate the quest many times
-- The Control the Three shadow spell is now much much more effective, since
- it removes black breath and DG_CURSE. The only little annoying thing is that
- it requires that player to wear the *THREE* rings. And that can only be
- accomplished with either the Possessor class (though they CAN'T cast the
- spell -- no hope for them) or The Scroll of Deincarnation
-
-10/03/2001
-- Monks can choose which spell to learn
-- Fixed a bug with limited ESP description
-- Fixed a bug in Possessor titles
-
-09/04/2001
-- DeathMolds can now teleport onto stores & such (all features that are
- considered floor by the game)
-- Objects cannot be dropped on traps anymore
-- The Sandworm Queen no longer appears multiple times
-- Harpers wont crash at the start anymore
-- Panic saves will use the playername.pnc filename (thanks Improv)
-- Symbiants can't hypnotize monsters that aren't pets anymore
-
-15/04/2001
-- Add an old patch from SC which allows dungeons to project an attack every
- few turns. For example a player in the Nether Realm will be hurt by nether
- every 3 turns for a damage of 10d10.
- The syntax is(up to 4 lines):
- E:<dice>d<sides>:<frequency>:<attack type>
-- Volcano now does 2d10 damage each 10 turns, beware scrolls on the floor :)
-- Lost Ruins of Numenor does 1d1 acid damage each turn (water will RUST you)
-- Cirith Ungol will poison you every 20 turns for 4d4
-- Illusory Castle will confuse you every 6 turns for 6d2
-- Small Water Cave does 1d1 acid damage each 20 turns (water will RUST you)
-- Nether Realm is unlightable (as is the Maze) and always empty levels
-- Nether Realm is now guarded by Tik'srvzllat who guards the Ring of Phasing
- a powerful ring that allow wraithform and immunity to nether
-
-16/04/2001
-- New Race system, Now you select a race AND a race modifier at birth.
- For example you choose to be a human vampire, or a dwarf skeleton, ...
- Then some modifiers apply (stats, skills, extra powers, ...). Note that
- all races can't use all race modifiers
-- New race modifier, Barbarian, the old barbarian race is gone
-- New race, the Wood Elf from CathAngband, masters of the bow, with 1 extra
- might and 1 more if they use bow and are high level enough
-- Extra Might can now be > 1
-- Penalty for priests using non blessed swords/axes/polearms is now (-15,-15)
-- New weapon category: Axes
-- Add Weaponmaster class from Gumband, trained into one weapon category, being
- great with it but bad with anything else
-
-18/04/2001
-- Aranruth is a broad sword, 15lb, 3d5
-- Fixed lots of spelling errors/typos thanks to Improv
-- Add a new birth option: Astral (ghosts from Kamband, name from Gumband)
- It enforces vanilla town and makes you start at level 98, you can't recall
- and need to reach town
-- Trap doors can't appear at the last level of dungeons or in non dungeons
-- The concept of non-dungeon places: some "dungeons" got the FLAT flag
- meaning they are ... flat, like a forest
-- The concept of Towers, going up instead of down
-- Updated birth.txt to take in account the race modifiers
-- Wood Elves can go through trees
-- Ammo similar to the one in your quiver will always be picked up
-
-20/04/2001
-- The death fate is way different now. When the player enters level he is
- fated to die on he gets teleported to a special level in a special dungeon.
- the level is empty, small and full of really out of depth monsters. Recall,
- genocide, ... are forbidden. There are no stairs, the only way to leave it is
- to kill every single monster of the level. Then the player is teleported
- back to town. Chance of surviving are *LOW* but not nonexistent :)
-- The knowledge rune will now probe monsters
-- Runecrafters are now playable (new damage formula) even at low levels !
- Now lets hope they are not TOO powerful :)
-- Runecrafters upgraded. They can now:
- 1) Cast a spell on the fly (as before)
-2) Cast a runespell they memorized before (can memorize up to 100)
- 3) Cast it from a carved runestone (uses 75% mana and does NOT need the
- runes to be present in the inventory, but consumes the runes during
- creation and it must be carried around to be used)
-- Mormegil is now a Darksword and is quite nice
-- Lesser & Greater Krakens now drop corpses
-
-24/04/2001
-- Add random towns in the dungeons. There can be up to 4 towns per dungeons.
- Not all dungeons (well should say places) can hold towns. Random town shops
- are took from the possible shops in st_info.txt with the RANDOM flag
-- Stores in st_info.txt got flags
-- When carving a Runestone the involved runes are destroyed
-- Random towns can have different shapes, from vanilla one to hidden one
- (the stores are placed randomly on the level, without any buildings)
-- When the player is invisible and does not have see invisible the @ symbol
- disappears
-- Cannot locate undetected traps by simply 'l'ooking around
-- Mariliths cannot use boots
-
-26/04/2001
-- The player is no longer "teleported away" when leaving some buildings
-- Level gaining artifacts rarity have been increased
-- Death Ray will actually kill the player
-- Removed traps of death ray (now that death ray insta-kills)
-- Recharged wands/staves cannot be extracted anymore
-- Wraithform no longer reduces damage
-- New hp formula for Possessors
-- Some sentences for the DarkGod monster to say, based on #angband :)
-
-28/04/2001
-- *WARNING*, squelch list has to be checked upon importing an old savefile
-- Every item can provides blows since Alchemists can't create that many arts
- now
-- Wielding a mage staff (even non ego ones) will provide with a decrease of 20%
- of the casting speed (using 80 energy instead of 100)
-- Add makefile.bcc thanks to Arch
-
-29/04/2001
-- Some Spelling/Grammar fixes in lib/help/ -- Improv
-- Levelling artifacts will now use a new scheme:
- There are now groups of abilities (the Fire realm, the Cold Realm and so on)
- Whenever a weapon goes up a level, it gets to either:
- 1. become enchanted by +2/+1
- 2. gain another attribute from a group it already has.
- 3. gain +1 to hit, and a point.
- when a weapon gains a certain number of points, it might buy access to a new
- group. Note that some groups can contain good AND bad abilities
-- Pet shop now sells scrolls of summon never moving pets
-- Lots of fixes (ammo weight, god flags, ...) thanks to Kusunose Toru
-- Towers deactivated for the time begin
-- Rods considered good
-
-01/05/2001 - PernAngband 4.2.2
-- Force attacks will pull away monsters (from Dr)
-- Fist of Force is now a force attack
-- Unbelievers can now detect traps at level 25 and destroy them at level 35
- Press 'm'
-
-03/05/2001
-- GoI no longer protects from insanity
-- Colored messages
-- Artifact creation results in a 40hp loss
-
-05/05/2001
-- Hermit subrace, magic adepts weaker physically but have more mana reserves
-- Use upx for exe compression of the DOS version in makefile
-
-07/05/2001
-- Fixed makefile difficulties in makefile.org, and uncommented one of
- the safer sets of CFLAGS/LIBS in that file as a good default -- Improv
-- Fixed some other spelling problems, notably in cmd7.c -- Improv
-
-13/05/2001
-- Reworked the old (ugly) activatable mutations, race powers, ... system to a
- new unified one. Race, subrace, class powers are defined in the tables in
- tables.c. Now the new system will allow for artifacts to grant powers, it
- also allow intrinsic powers (i.e. you quaff The Potion of Blinking
- and from now on you can blink at will)
-- There is a 2% chance of gaining the grow mold mutation when eating a slime
- mold
-- Priests gets the curse detection power
-- Oops the Sandworm Queen wasn't confusion resistant :)
-- Added various granted powers to various artifacts and ego items
-- Sorceror allowed spellbooks are now in tables.c (Mrealm_choice)
-- Changed the install rule to do something sensible on Unix. Changed config.h
- to suit. Default dir for lib is now /usr/lib/games/pernband/
- Hopefully this won't make too many people angry -- Improv
-
-15/05/2001
-- New GFX by Andreas Koch
-- Fixed some entries in a_info
-- Monster memory now tells people when they're facing a Nazgul (Kevin W Thomas)
-- Fixed a bug in dungeon town generation (Kevin W Thomas)
-
-16/05/2001
-- Added makefile.WHICH, fixed up my earlier patches to add a real install
- rule - Improv
-- Pseudo id now works for potions, scrolls, wands, staves and rods. Magicians
-are better at pseudo id-ing those than warriors (SC)
-- Can only use one ultimate artifact at a time (not that it really
- matters given that no-one will ever find one :) )
-- Fixed a bug preventing The Baby Minotaur from being generated if it was
- already generated for a previous character using the same savefile
-
-17/05/2001
-- Upgraded to latest z-term code
-- Illusory castle got a guardian, The Glass Golem (a NASTY thing) hoarding
- The Helm of Knowledge, which auto ids every item you walk onto and activates
- for insanity + *id*
-- Crushed all oriental items(nearly) of the game, they just doesn't fit the
- general theme
-- Gigantic dungeons (flag DOUBLE) from SC
-- Ice lair as a Gigantic dungeon from SC
-- Dragon Lair is gigantic now
-- Between gates travelling damage is now /2
-
-18/05/2001
-- Checked in an EXTREMELY raw and broken version of my z-term changes that
- produce cmovie files. It's disabled by default, if you want to play with
- it, play with z-term.c ... Until I incorporate a cmovie player into
- Pernangband, you can use the one I wrote for MY roguelike MoLD, available
- at http://www.sourceforge.net/projects/mold/ . Little plug there. -- Improv
-
-21/05/2001
-- Moria WILL have downstairs at the bottom
-
-24/05/2001
-- New quest code ! Quests are no longer in *_info.txt files but are able to do
- many new things, and the code is less ugly than it was :)
-- Random Quests refitted to use new quest code, now each level with a random
- quest will have a vault with the monsters you need to kill inside, and a
- princess that is held prisoner (your goal being to save her)
-- Refitted Thieves quest
-- New Bree quest, The Lost Hobbit ! save Merton !!
-- New key, 'y' to give items to monsters
-- Elven vampires no longer get resist lite, that was silly AND unbalancing
-- Artifact arrows wont come in piles anymore
-
-26/05/2001
-- Removed Wizard & prior classes, Mages & Priests can now use their realms
-- Refitted Crusade realm, some new (fun) spells
-- cmovie changes to make it work better. Should have it all cleaned up and
- portable very soon. -- Improv
-- Updated pern_faq -- Improv
-- Power mages start with a 2d4 spells
-- Fixed a bug which made random artifacts destroyed by auto-squelch. --
- Kusunose
-- Changed spellbooks colors to be more .. accurate
-- Add the Spirit realm, taking the place that was designed for it a long time
- ago, the one that tribal used until now, between Valarin and Shadow.
- Tribal is not removed, but it can only be used by some nature-like classes
- (like beastmasters, rangers, ...). Some spell names & spellbooks names are
- took from psiband Psionicists
-
-28/05/2001
-- disturb_move option off by default
-- Bree town totally redesigned by Mynstral to be more accurate the LoTR
- description of it and to be more .. beautiful :)
-- New quest in Bree after the hobbit one, The Trolls Glade
-- Dark Horseman quest required level raised to 35
-- Massive updates to tables.c, fixed spelling of several spells, renamed a
- few, fixed spelling of several lvl-specific class names, renamed a few.
- Also working on maintainability for race/class restriction code in same
- file. -- Improv
-- Entirely replaced TANG.txt with new stuff I wrote -- Improv
-- Permanent wraithform no more do the "You feel opaque" every few turns
-- Recoded the passwall() function to be... less ugly and less buggy
-- Archers learn to protect their arrows from fire as they advance levels
-- The Toris Mejistos guarded by Ar-Pharazon the Golden at the bottom of
- the lost ruins of Numenor
-- Fixed random artifacts activation bug
-
-30/05/2001
-- Spell lists are now colored
-- Spell descriptions when browsing
-- Half magery spells descriptions done by Parak
-- The potion of learning is a k_info artifact now
-- Added color to seen unique list, quests list and a few others
-
-31/05/2001
-- Descriptions added to first five Shadow books (Shaun "arch" Sides)
-- Nazguls lost the DG_CURSE upon death
-- The Spiders of Mirkwood quest is the first Lothlorien quest
-- Magestaff of power now increases spell power while magestaff of spell
- holds 2 spells (switching their previous behaviors)
-- New ego item system, externalized everything, it's half based on Matthias
- Kurzke patch
-- Rewrote e_info.txt for the new ego system, the rarity should look like the
- same
-- Bows of Numenor & Lothlorien as new ego items
-- DSM can be ego
-- some new ego & tweaks to existing egos
-- 3 new light types: Everburning torches, Dwarven lanterns and Feanorian
- lamps
-- New ego lights: of Brightness, of *Brightness*, of Illumination, of Boldness,
- of the Shadows, of Infravision, of the Eternal Eye
-- The Phial of Galadriel is now level 20 rarity 10, the ego lights & other
- perm lights should be enough until then
-- Ego light: of Fading, will make non-permanent the permanent lights :)
-
-01/06/2001
-- Add auto curse
-- The One Ring will not be cursed when generated but will have the auto_curse
- flag, so it is possible to use it and take it off for VERY brief periods...
- but if it becomes cursed while you're wearing it .. you're stuck with it
-- The same applies for the Toris Mejistos (except that it's not permacursed)
-- Moved options around
-- No more books of lore, they are now Cloaks of Mimicry (and can be ego items
- or randart)
-- Monsters that can suicide cannot be random quest monsters
-- Alchemist artifact creation totally changed. It now takes player level
- essences of magic and 1 hp to "imbue" a normal non-artifact, non-ego item
- into a pseudo artifact.
- You will then wield/wear it and it'll gain some xp when you do
- (reducing the amount you gain)
- When you think you have enough xp, you finalize it (actually select the
- flags that now cost xp) with the xp it has and the pval you choose.
-- Did more spelling updates on this file -- Improv :)
-- Finished moving the class-race combos in tables.c to a cleaner
- format -- Improv
-
-02/06/2001
-- Copied Vanilla random artifacts name generator
-- Random ring & amulets are now "The Ring of foo"
-- Lights can be random artifacts
-- Described all Valarin spells
-- All non spellbook spells (Mindcrafters, necromancers, mimics) got a
- description
-- All harper songs described
-- DragonRiders will learn to fly at level 17 (but they always can levitate),
-that's an old Divia suggestion
-- Magestaves of Spell still carry 2 spells, but they are randomly generated
- using the runespell (magic of the Runecrafters) system
-- First draft of monsters gaining xp & levels
-- Magestaff of Mana & Power renamed to Magestaff of Wizardry (suggested by JLE)
-
-03/06/2001
-- Beginning work on unifying the load/save code to make
- maintenance easier -- Improv
-- load2.c and save.c are now one file, loadsave.c ... Will now be working on
- moving them to using unified functions so this code will be easier to
- maintain. -- Improv
-- Reworked monster AI. A monster can now be enemy, neutral(oriented toward
- player or monster or full neutral), friendly, pet or companion(will follow
- you on other levels)
-- Pets (and other friends) will be less stupid
-
-04/06/2001
-- You can now assign a target to a pet
-- The Phial will now have a similar effect to song of morning (tribal)
-- The number of companions killed is taken into account in the score
-- New quest at Lothlorien, the poisoned water, with an unique reward,
- a DSM of elvenkind (cannot be generated under normal circumstances)
-- Renamed Nibelungs to Petty Dwarves
-- New curse, you cannot drop the item
-
-06/06/2001
-- Multiple messages will show up as only one message with a multiplier
-- New Minas Anor layout (MUCH BIGGER) by Mynstral
-- Fixed the princess not appearing (she WAS there but got killed)
-
-08/06/2001
-- Fixed Mormegil (it was possible to use it with magic)
-- Companions stay even if you use the overview wilderness mode
-- Some monsters will tease the player but always stay out of melee range
-- A new pet command to make them forget their target
-- New ego type for heavy armors (Dwarven) with + to STR and maybe CON
-- Ammo & diggers doesn't add the tohit/todam to your total
-- Herbal healing at Gondolin will cure black breath
-- New store type: Master Archer
-- Rings can be ego objects now
-- Scrolls can be ego now (Fireproof)
-- Wands & Staffs (except of wishing) can be ego item: of Plenty
-
-10/06/2001
-- Possessor now have mana (based on INT) and use it to cast the spells of the
- monster they are using
-
-12/06/2001
-- Deathmolds can now use the overview wilderness map but the travel time is
- higher and there is a chance to not blink right and move onto an undesired
- square
-- Changed Summon Cyberdemon to Summon High Demon (with the incoming new JLE
- demons it'll be nasty)
-- Added Possessor monsters, they'll hunt corpses and incarnate into them !!
- Now you must fear even dead monsters
-- The Phial of Undeath now has a radius of 5
-- Unique monsters list is now sorted (but Morgoth is always at the bottom)
-- Add monster traps from PsiAngband. Rogues can now set them (with the powers
- menu, 'U' key)
- Direct quote from Psiband change file:
- Rogues can set traps for monsters. This requires a "trapping kit" as a trigger
- and something to "load" the trap with.
- All scrolls, potions, wands, staffs and rods can be used (with the appropriate
- trigger) as traps to confuse, poison, teleport, genocide, ... unwary monsters.
- But standing next to a trap with area effects will hurt the player, too.
- There are also traps that shoot ammo: hidden catapults, bows and xbows.
-
- Some monsters can disarm traps, and a monster that has disarmed one of your
- traps will learn how to disarm all of them...
-
- Ammo Traps can have (+hit,+dam) just like bows. They can also be enchanted.
- All traps can have a [+AC] showing how hard it is to disarm it.
- There are also ego and artifact traps.
-- Add the ego & artifacts trap kits from PsiAngband
-
-15/06/2001
-- Hallucination monster attack (JLE will use it for the review of r_info)
-- You can use up to 5 R_CHAR_x flags in the F: line or re_info.txt to specify
- races to which the ego powers are available
-- Crusade realm described
-- The Star of Elendil now has a light radius of 4
-
-17/06/2001
-- The dungeon info file (d_info) now allows more than one monster generation
- rule. The R: line specifies the percent of monsters affected by the rule
- and the mode of the rule(AND, NAND, OR, NOR). So it is now possible to
- have 60% of orcs, 30% of trolls and 10% dragons
-- New dungeon in Mirkwood, Dol Guldur !
-- Sorcerors cannot use Valarin (prayers should not be available to mages) and
- Tribal (instead they get Spirit)
-- Fixed some misspellings in lib/help/ -- Kusunose
-
-18/06/2001
-- Auto pickup option now defaults to false
-- Fixed bugs with the cursed ego items
-- Described the remaining Magery spells
-
-19/06/2001
-- Point based character generation
-
-20/06/2001
-- Finish cmovie support !
-- Added an interface to cmovie (press | key in both normal or roguelike set)
- It asks for a name (it will add the extension itself) and then if you wish
- to play or record it.
- The cmovie files (.cmv) are located in lib/cmov, note that they quickly
- become huge and so you REALLY should compress them before sending to friends
-- Fixed a bug that prevented mutations from being correctly cleaned
-
-21/06/2001
-- Special artifacts can be placed anywhere in a_info, they just need the
- INSTA_ART flag
-- Emptying lite warnings should work now
-- Added new quest, not found in a castle.. I won't say anything more :)
-
-23/06/2001
-- Added 2 new dungeon flags:
- LIFE_LEVEL will generate levels with a cellular automaton algorithm (looks
- like a game of life)
- EVOLVE will make a LIFE_LEVEL be continuously parsed by the cellular
- automaton algorithm while the player moves, resulting in a living effect
-- New dungeon: The Heart of the Earth, branching on level 25 of Mirkwood
- it uses the evolving algorithm :)
-- Added the new Minas Anor (one map screen total). Fully functional
- (except for the random terrain via the plasma generator *hint,
- hint -> DG*) --Mynstral
-- Moved the rarity of the Phial of Undeath to the one of Galadriel
-- Add Death Orb monster as suggested by Prfnoff a long time ago.
- They only move when in LOS. They multiply (quickly) and can hit to parasite
- which will make a new death orb spawns out of you later
-- Fixed a bug in cmovie that messed up the recording when the user specified
- different char than the normal ones
-- Loadsave work is now pretty much complete. Barring the addition of
- transparent compression, which might happen later, there shouldn't be any
- reason why savefile compatibility should ever break again. -- Improv
-
-24/06/2001
-- Several bugfixes -- Kusunose
- Player's symbol was never displayed if VARIABLE_PLAYER_GRAPH or
- USE_GRAPHICS was #undef'ed
- Eating a corpse sometimes crashed the game.
- Stealing from a monster sometimes crashed the game.
- Nether immunity won't work if player had nether resistance.
- and some minor bugfixes.
-- Birth classes selection is now more user friendly
-
-27/06/2001
-- D: line enabled in k_info.txt
-- Added ingame information about the different objects kind one can find
- It is accessed via the observe key ('I' in original keyset)
-
-28/06/2001
-- Add back the Eol quest at Gondolin, but it's now dynamically created
- (the level layout and trap places are random)
-
-30/06/2001
-- Reimplemented Nirnaeth Arnoediad quest at Gondolin, but with a different
- reward
-- Add a spoiler menu to the help menu, thanks to Dawnmist
-- Fixed a bug; Steal Item Trap sometimes crashed the game. -- Kusunose
-- Working on rewriting more documents in lib/help/ -- Improv
-
-03/07/2001
-- Fixed a long-lived bug with power mages. This greatly affects play-balance
- with them -- no longer will the cost of many of their high level spells
- be merely 1 mana. Also, removed some of their effects that never really
- worked anyhow. -- Improv
-
-07/07/2001
-- Some more misspellings on this file are fixed. -- Kusunose
-
-11/07/2001
-- Cannot add essences to artifacts
-- Object descriptions are added in the character dump
-- Notes are saved in lib/note
-- Priests and paladins begins with 10 times more grace with their god
-
-12/07/2001
-- Rods with rod tips attached sells for higher price
-- Down shafts cannot get you out of a dungeon
-- Cannot enter water and such in overview mode when too burdened
-- The no_pickup_corpse option changed to prompt_pickup_heavy which will ask
- a confirmation before picking up objects that might slow you
-- Add an menu to the option screen to dump/load options to a pref file
-- Fixed a bug with dungeon guardians being generated more than once
-
-13/07/2001
-- Unique list is now in 2 columns
-- Race selection screen made more user friendly with race desc
-
-14/07/2001
-- Reworked the spell system
- Now each spell got a level that you increase as you learn it more and more.
- The higher the spell level is the more damage it does, the more time it
- lasts and such.
- Also each class have a specific max on the number of levels they can achieve
- in each spells. This should help the high mage class since they get twice the
- max level of mages. Also illusionists gets more than mages.
- Also note that sometimes one more level wont change anything while 2 or 3
- more WILL change. And lastly some spells are not affected by levels at all
- One last thing, sorcerors cannot learn spells and thus cannot increase their
- spell level which will always be 1
-- Player races now have inherent body parts, so a deathmold cannot use
- headgear or boots but can wear more rings
-- New DarkGod sentences by Static Chaos
-- Fortune cookie by SC
-
-15/07/2001
-- The more you known a spell the faster it is to cast
-- Every class can now choose which spell/prayer to learn
-- Began reworking the spell bonuses(from spell levels or mage staves) to a much
-smoother distribution, so if a point if used it WILL have impact. Done the
- Valarin Realm
-- Done Magery Realm
-- Done Symbiotic Realm
-- Done Music Realm
-- Done Shadow Realm
-
-16/07/2001
-- Done Chaos Realm
-- Ingame contextual help(on by default, can be turned off in the options)
- Only few stuff got help right now, but that'll be extended
-
-17/07/2001
-- Spell list with levels included in the character dump
-- Updated docs thanks to Dawnmist
-
-18/07/2001
-- Hypertext help system, use up/down/space/- to scroll, left/right to move
- between links and enter to activate a link
-- Race mods selection screen upgraded
-- The k_info artifacts will have a name again(was a stupid bug)
-- Done Nether Realm
-- Unified savefile loading screen. Now when the game is started it presents
- a screen allowing to create new characters or to load/destroy existing ones
-
-19/07/2001
-- No more breeders in poisoned quest
-- Add an option to show exp needed for next level instead of total exp
-- Objects with the temporary flag will be destroyed when it's timeout
-becomes 0, allowing spells to summon fiery blades and such
-- Valarin Realm got a spell to create a temporary Holy Avenger
-
-20/07/2001
-- Created a cygwin makefile (makefile.cyg) for Windows -- Dawnmist
-- Split spoiler help files into true spoilers and newbie help files -- Dawnmist
-- Continued minor edits of help files. -- Dawnmist
-- Possessors reworked again
- Now they get between 1 and 20 mana based on the spell rate of the monster.
- When you cast a spell the failure rate is determined based on the player
- level, player wisdom, monster level and spell difficulty. If the spell
- fails it is still cast but you lose a few mana. If it succeeds you don't
- lose mana. If it takes you below 0 mana you are forced to leave your corpse.
-- Done Spirit Realm
-- Done Tribal Realm
-
-22/07/2001
-- fixed a bug in project_meteor() that crashed the game. -- Kusunose
-- Updated option.txt for exp_need option. -- Dawnmist.
-- Continued edits on help files. -- Dawnmist.
-- Done Crusade Realm
-- Rewrote bldg.txt for Pern 4.x.x. -- Dawnmist.
-
-23/07/2001
-- Redone help file colour scheme to allow orange/yellow hyperlinks -- Dawnmist.
-- Continued edits on help files -- Dawnmist.
-- Spell checked tables.c -- Dawnmist.
-- Spell checked this file :-) -- Dawnmist.
-- Updated features and objects in dungeon.txt help file. -- Dawnmist.
-- JLE reworked the monster list, some monsters are gone, some monsters are
- changed and some are new
-- Along with r_info JLE also modified d_info, big thanks to him
-- No more quest for shelob in mirkwood(she guards cirith ungol now)
- Instead you must hunt the necromancer that is said to lurk in dol guldur
-- As long as sauron his alive the nazguls cannot be permanently slain
-- Attacking a nazgul no longer destroy artifacts(well it can, but the chance
- is 1 in 1000)
-- Done Daemon and Sigaldry realms
-
-24/07/2001
-- SURPRISE!! I did something (but what it was is a surprise too) -- Mynstral
-- Added debug 'B' command, changes body -- Improv
-- Added colours and hyperlinks throughout command.txt -- Dawnmist
-- Updated most command descriptions in command.txt -- Dawnmist
-- Minor updates to some other help files -- Dawnmist
-
-25/07/2001
-- Massive merges from my internal cvs tree of loadsave.c
- Hooked experimental bzlib integration in an #ifdef
- Gutted the old 'encryption' code
- Hoping to gut RLE if bzlib changes work out
- Added nice sentinel function -- Improv
-- Fixed class selection screen bugs, fixed savefile manager so it will work
- with unix. -- Improv
-
-26/07/2001
-- Added a quest map for Gondolin. -- Mynstral
-- Gondolon last quest: Invasion of Gondolin !
-- Upgraded max suport to the new birth interface thanks to pelpel
-- Several fixes thanks to pelpel
-- Add an option to use either the new r_info coloring scheme(based on V one)
- or the old one(based on Z)
-
-28/07/2001
-- Fixed a lock problem with global.svg on multiuser system thanks to pelpel
-- Done Magic Realm
-- Done Druidisic Realm
-
-30/07/2001
-- One can press 4 (left arrow) in class selection to get back to meta-class
- selection
-
-02/08/2001
-- Updated several *_info files thanks to JLE, new arts, ego, objects, ego
- monsters
-- Fixed a bug in ego monsters, now they works perfectly :)
-
-03/08/2001
-- Done Illusion Realm
-- Added macrofaq.txt to help system -- Dawnmist.
-- Updated/fixed a few problems in the help files, and linked in new macro FAQ -- Dawnmist.
-- Increased chance for player ghost to appear
-- No more ego monsters in town
-- Spectre subrace can only use 1 ring
-- Made bree and gondolin finally use the plasma generator, and added two terrain
- features. -- Mynstral
-
-04/08/2001
-- Fixed a bug with ego monster generation that inversed ego rarities, thus
- explaining the incredible numbre of spectres running around
-
-05/08/2001
-- Fixed the orc level in the moria
-- Bladeturner is now an UNTIMATE artifact, but can be activated for invulnerability
-- Major rewrite of magic and class help files -- Dawnmist.
-- Fixed a bug with saving/loading while doing invasion of ogondolin quest
-
-07/08/2001
-- Fixed Tribal realm
-- Major rewrite of race modifier help files -- Dawnmist.
-- Spellchecked this file - Improv
-- Reintroduced water hounds - Improv
-- Major rewrite of race help files -- Dawnmist
-- Graphics for shop doors -- Kusunose
-- With help of Antimatter, squashed item bugs related to negative pvals and
- the signedness of some functions. -- Improv
-- Done Prayer Realm
-
-09/08/2001
-- Fixed a bug with evolving dungeon when saved/loaded
-- Only the quest monsters counts for quest, not clones, not normaly generated
- ones
-- undead ego monsters cannot be mortal
-- Monster ego name can appear before or after the monster name(:B or :A at the
- end of the W: line)
-- Object ego name can appear before or after the object name(B or A on the X:
- line)
-- Fixed a long-lived item-pickup bug -- Improv
-
-10/08/2001
-- Ego monsters will be drawn in gfx mode
-- Add a birth menu to select the god to worship, druids are forced to get
- Yavanna, priests and paladins are forced to have a god, others can choose
- to be atheist
-- No more multiple artifact arrows
-- Continued edits on the help files -- Dawnmist
-- Completed the spell descriptions for the Shadow Realm -- Dawnmist
-- Vampiric weapons can be sold again
-- Staff & Wand of nothing of plenty cannot exist
-- Staff of wishing CAN be of plenty
-
-11/08/2001
-- fixed a bug with esp and flags5 not being saved thanks to kevin w.thomas
-- fixed a bug in nirnaeth quest
-- Reduced sorceror hp penality to -10%
-- Removed the screen coloration when berserk/wraith/goi
-
-12/08/2001
-- Fixed invasion of gondolin quest
-- Fixed lightning res amu
-- Add the Merchant class(thanks static chaos), they can get loans(watch out if
- you dont pay back quickly) and request items at the merchant guild.
- they can appraise items, identify items, warp items in chests. They get
- an object based ESP(see monsters carrying objects) at higher levels, they
- constantly detect objects around them and they can use portable holes
- to get a bigger inventory(but items in it weights more)
-
-13/08/2001
-- Fixed font-ibm thanks to pelpel
-- Merchants gets the midas touch
-- Vanilla town option removed. Astral mode now make the player start in the
- Halls of Mandos(levels 1-98) which do not have any entrance from the
- wilderness(or any dungeons). When they get out they are in the wilderness
- and can start playing normaly. And uniques cannot be generated in the halls
- of mandos
-
-14/08/2001
-- Updated font-ibm and font-win thanks to pelpel
-- When selecting the number of random quests, * will get a random number
-- Score list now shows the subrace, but it breaks the compatibility with old
- ones
-- Reduced xp needed by monsters to gain levels
-- Ego items are wishable now. i.e you can ask for "fiery dagger"
-- Updated font-ibm and font-win thanks to pelpel
-
-14/08/2001
-- Added the map for a new quest. -- Mynstral
-- Finished the Last Alliance quest
-- Number of companion a player can have at max depends of the class
- necro gets 1 + (plev / 10), beastmasters 4 + (plev / 10, harpers 5
- all others 2
-
-16/08/2001
-- Fixed ambushes
-- Added merchant help
-- updated mac suport thanks to pelpel
-- Reduced by about 6mb the memory req
-- Hidden towns are generable
-- Fixed a bug with weapon specialty at birth -- Kusunose
-- New item ability, some rare rings can add %(based on pval) to the chance
- of getting a critical hit
-- Objects can now shimmer(ATTR_MULTI), but only base types (k_info) can have
- the flag
-- Features can now shimmer, note that this can be slow. Please report if it
- is unbearable on your machine(you can also disabled the avoid_other option)
-- Reduced memory footprint again
-- Reworked the 'U' power menu to be more nicer and intuitive while still
- allowing macros. Each powers gets a fixed number that can be used as a
- prefix to the command to bypass the menu. For example teleport is 5 so
- to directly get teleport one can always do 05U
-
-17/08/2001
-- Described Chaos realm
-- Described Nether realm
-- Described Sigaldry realm
-- described Spirit realm
-- Fixed a bug with random quests
-- Fixed a bug in note taking, thanks to pelpel
-- Fixed the interact with visuals menu thanks to pelpel(the fix is not even
- in vanilla yet :)
-- Fixed cmovie recording
-- Merchants can request ego items(same interface as wishes)
-- Towns in dungeons now get townpeople in it ... leveled townpeople
-- Eggs are now , instead of o
-
-17/08/2001 - PernAngband 5.0.0 aka "Mirmidonic Carbonizer"
-- Birth options now appear in the normal option screen, but as read only
-
-18/08/2001
-- Special levels reworked
-- Volcano is now Mount Doom and is found on level 65 of Mordor
-- fixed help system crash thanks to pelpel
-
-21/08/2001
-- fixed the hypnotic gaze bug
-- reduced between gates damage
-- daemon books can be enchanted
-
-19/08/2001
-- Beginning work on a new, better status screen. For now, it's assigned
- to the debugging menu as the 'A' command. -- Improv
-- fatespoil.txt changed to fatespoi.txt
-- rogues get some shots for their trapkit at birth
-- Cannot dismiss the princess anymore
-
-23/08/2001
-- Fixed the special levels, thanks to mynstral
-- Described Daemon realm
-
-23/08/2001 - PernAngband 5.0.0b aka "Mirmidonic Carbonizer II"
-- Default pref files are in lib/pref
-- Random quests are disabled when using ironman_room
-- Add auto_more option -- beware it can be very dangerous
-
-24/08/2001
-- Increased general store price limit
-- Trapkits added to squelch list
-- Fixed a bug when displaying some k_info artifacts
-- Wand of Gandalf and Thrain are now k_info artifacts
-- Fixed 2 bugs with rogue traps
-
-25/08/2001
-- Necromancers can turn pets into companions
-
-26/08/2001
-- Special levels are no more fully known
-- Fixed fountain bug; shape of XXX did not take effect -- Kusunose
-- Described Illusion and Tribal realm spells -- Dawnmist.
-
-27/08/2001
-- Fixed bug with scrollable list of powers
-- Added Magical diggers, they grant stone to mud power
-- Added the Corrupted subrace gaining corruptions as they level thanks to
- Luc French
-- Changed mutations to corruptions
-- Dragonriders are no more considered evil
-
-28/08/2001
-- Fixed some cmovie bugs
-- Fixed *godness* song on non artifacts
-- Greatly increased herbal healing price in gondolin, since it cures black
- breath
-- Fixed bug with store item creation -- Kusunose
-
-29/08/2001
-- Totaly rewrote the random artifact system. It now use an external ra_info
- file to define what power the artifact will get. The format is very similar
- to e_info(expect it doesnt include the 5 flags sets). Each entry define for
- which tval/sval it can be applied. Then when the game wants to create a
- randart it simply defines a number of powers to grab and randomly pick up
- the powers from ra_info(following the restriction, rarity and levels).
- This allow a totaly change of the randarts if needed, an easy addition of
- new powers, ...
-
-30/08/2001
-- Hidden doors are now hidden, in mirkwood they will look like trees, in
- barrow downs they will be mountains or trees, and so on
-- Beastmasters can turn a pet into a companion
-
-31/08/2001
-- Half elf lost the str penality
-- Half orcs and half Trolls or now Orcs and Trolls
-- Saved levels are deleted when a new character is created
-- Renamed Holy Advangers to weapons of Aman, thanks to Timo Pietila for the
- idea
-- Cannot reset recall to Mount Doom
-- The game time is now counted with the elven calendar (reckoning of Imladris)
- (It isnt PERFECT, every 12 years it should have years of 368 days, but I
- dont think many will get upset :)
- A year is 365 days, with 6 months (Tuile, Laire, Yavie, Quelle, Hrive and
- Coire), 3 middle days(Enderi) and one starting(Yestare) and one ending
- (Mettare) day.
- The game begins the 43rd Yavie the year 2890 of the third age, note that it
- is the birthday of Bilbo :)
-- Note files (mainly) use the elven calendar to record things
-
-02/09/2001
-- Fixed several bugs (runespell deletion, ego wand and staff stacking etc)
- thanks to oops -- Kusunose
-
-03/09/2001
-- Changed the 'Lev xxx' thing to a 3 letter name corresponding to the current
- place(dungeon, orc cave, ..)
-- Enabled f_info D: line with an index(0 is general desc, 1 is to (forbid)
- tunneling)
-- Changed the way total weight is calculed thanks to Kieron Dunbar
-- One can edit his background history at birth :)
-- Lich ego monsters can use the base monster powers
-- Raise death can bring a lich
-
-04/09/2001
-- Enabled E: line in f_info(same format as d_info)
-- F: lines enabled in lib/dngn files, they specify flags for the level
-- Fixed a bug with special level generation
-- Add bleeding and poisoning monster effects from EyAngband
-- The One Ring quest
-
-05/09/2001
-- Fixed the crashing bug after level 100 in angband
-- Gave Sauron 30% chances to drop The One if it is not already created
-- Code now allows bi-ego objects, thoght they are impossible to generate yet.
- It will allow additing weapon/armors qulities(crude, broken, ..) easily
-- Add a quick start option that let you use the same char as you previous one.
- Everything is the same execpt life rating
-
-06/09/2001
-- Abort menu in the Windows version is now compile option, disabled by
- default. -- Kusunose
-
-07/09/2001
-- When a new day comes the game tells the player(at midnight)
-- Drain hp and mana are cumulative
-- Fixed file existence function for dumb systems :)
-
-07/09/2001 - PernAngband 5.0.1 aka "Brunswik Disipator"
-
-09/09/2001
-[B]- Turns in scores are based upon the start of the game not of the year
-[M]- Mimic are REALLY mimics, they can look like any object and appears as
- objects when looked at. And they got an emperor
-[I]- Enhanced realm selection menu
-[B]- Farmer maggot shows up in the unique list
-[M]- Monster vs monster damage is now x3 to shorten fights
-
-10/09/2001
-[P]- Changed the boring Half-Giants race to the much more interresting
- Beorning race. Descandant of beorn they can all shapeshift into a powerful
- bear form at will. In bear form you cannot use weapons, gloves, shields
- and boots. But you get powerful stunning/slowing/wounding attacks
- (claw, bite, swat, hug) and innate blows. You also get bonuses and minuses
- to some stats and to to hit, to dam and speed
-
-12/09/2001
-[O]- One Ring cannot be dropped by traps
-[G]- Implemented luck, an invisible stat which can only be approximately known
- via self knowledge spell/potion. It affects quite a few dice rolls.
- Each race gets a luck modifier, for most it is 0, but some gets penalities
- or bonuses(hobbits are a lucky bunch).
- Some objects also can grant luck
-
-14/09/2001
-[D]- The graveyard will now project a raise death spell on all bodies, meaning
- you'll have to kill a monster, and destroy its body before it get raised
- back in the form of a skeleton, spectre, lich, ...
- PS: MOUHAHAHAHHAHA
-
-15/09/2001
-[B]- Bugfixes -- Kusunose
- A message "XXXX blocking your way" was displayed when you went through
- some walls or trees.
- Hidden doors remained hidden if they were detected by spells, or if they
- were opened by monsters and then closed. Thanks to kobayasi.
- and some minor fixes.
-
-16/09/2001
-[m]- Implemented lua scripting language! More on that on the to-be docs
- You need to get lua3.2 to make it work.
-[m]- Integrated lua3.2 source into the source, no more need for external
- librairie
-[M]- Fixed store lockup bug thanks to Kusunose toru
-[I]- Partial 8x8 tile update -- Dawnmist.
-[m]- Cygwin makefile update -- Dawnmist.
-[P]- Externalized player races and histories
-
-17/09/2001
-[P]- Elves cannot be vampire anymore
-[P]- Hobbits get intrinsinc xtra might with slings at lvl 25
-[P]- Extended the possibilities of the player races file, it is now possible to
- select what flags will be applied at what level and for what pval(if
- revelant)
-[B]- Fixed non connected stairs on quests, thanks to luc french
-[I]- Removed screen dump/load commands, redundant with cmovie, and frees to keys
-[I]- Y( ( in roguelike keyset) key to chat with monsters
-[G]- Changed the way to get the lost hobbit quest
-[B]- Fixed a bug with eat magic corruption
-
-18/09/2001
-[G]- System shock when thrown out of one's body while wzearing cursed items
-[G]- Set the joke/Z/cth monsters off by default
-[P]- Externalized subraces to p_info
-[M]- No more joke mosters as quests
-[m]- Integrated an automatic help file converter(creates html files), command
- line option -h
-
-28/09/2001
-[m]- makefile.org now supports Lua, uses Improv's installation rule
- in all cases, it also understands make depend as well.
- Read it, make necessary changes for your system, then make depend
- followed by make.
-[B]- validate_bg() referenced a null pointer.
-[m]- CodeWarrior project file for the Mac port supports Lua.
-[m]- main-xxx.c for the Mac is now in sync with my Vanilla port -- pelpel
-
-29/09/2001
-[B]- Fixed herbal healing price
-[I]- 16x16 bmp/mask added to the cvs
-[G]- Cth/Z/Joke monsters options appears in char dump
-[B]- Fixed Crusade spell book browsing bug (Bug list #33) -- pelpel
-[B]- Fixed a bug; the first harper book was never sold in the bookstore
- (Bug list #15) -- Kusunose
-
-30/09/2001
-[G]- Increased min player level for some dugneons
-[I]- Message can be multi colored
-[m]- Yesterday I got OS 10.1 and found that it fixed the new window
- position bug (search for (_ _#) in main-crb.c), so I conditionalised
- the workaround -- pelpel
-[B]- Fixed the combined rod pricing (Bug list #30) -- pelpel
-[B]- Typo in files.c: cht_monsters -> cth_monsters. Replaced non-ASCII
- 0xa0's in angdos.cfg with 0x20 (i.e. space) -- pelpel
-
-01/10/2001
-[B]- Monks and Bear form didn't have combat messages -- since many lines
- in the current flavoured messages mention weapons, I introduced a
- hack to temporarily disable flavored_attacks for them, then just
- process messages as usual, and restore the flag later (Bug list
- #44 and #53) -- pelpel
-
-02/10/2001
-[B]- The trap/door destruction spell didn't destroy doors (Bug list #25) --
- use of floor_type[rand_int(100)] results in a 'natural' terrain,
- but isn't compatible with digging etc. Do they need fixing too? -- pelpel
-[m]- The main window resist resizing in the Windows port, like the Mac
- ones (Arcum's problem, future Bug list #74 and #75) -- pelpel
-
-07/10/2001
-[B]- Fixed PowerMage mana consumption bug (Bug list #114) thanks to krosky
- -- pelpel
-
-08/10/2001
-[B]- Fixed light source stacking bug (Bug list #7) -- Kusunose
-
-21/10/2001
-[M]- Add NO_CUT to some monsters
-
-22/10/2001
-[I]- Colors to news.txt
-
-25/10/2001
-[M]- Added gamma correction function taken from V2.9.x in util.c, since
- new X11 file requires it, so does my main-gtk.c, ready to be submitted
- -- pelpel
-[G]- Cannot use overhead wild map if being recalled
-
-26/10/2001
-[B]- Fixed long-lived dragonrider bug (xtra1.c), Darkgod please check to see
- if the behavior is as you want it -- Improv
-
-27/10/2001
-[P]- Externalized classes to p_info.txt
-[P]- Externalized meta classes to p_info.txt
-
-28/10/2001
-[B]- Fixed display of race/subrace/class flags
-[I]- Add some color to the identify screen
-[I]- Ignore Acid, elec, fire and cold are merged in identify screen
-[I]- Inventory/equipment letter are color-coded when *identified*
-[O]- Item sets ! Some artifacts are working together. If you wear them
- at the same time you get bonus powers. You can get partial bonuses i.e:
- You have 2 artifacts of 3 artifacts set, you will get some bonuses for
- them but not all.
-[M]- Add NO_CUT flag to monsters needing it thanks to
- Runescrye
-
-01/11/2001
-[B]- Changed king to the actual winner name in the quest dump
-
-03/11/2001
-[m]- Upgraded to lua4
-[m]- It is now possible to define new magic powers(ala mindcrafter, necro, ..
- powers) with a small lua script
-[O]- New item set the Dragon Slayer
-[m]- New gtk port thanks to pelpel !
-[m]- Mac makefile equivalent is updated, now with lua4 for all targets -- pelpel
-[m]- src/lauxlib.h is synchronised with src/lua/lauxlib.h -- pelpel
-[m]- LUA_NUM_TYPE in makefile.org is removed because src/lua/llimits.h now
- has correct (read integer :-) default -- pelpel
-
-04/11/2001
-[M]- All dragons now shimmer, according to their breath types(took from LM's 4GAI)
- That is also thanks to the neat info editor of static chaos :)
-[m]- Change my email adress to darkgod@pernangband.net, adds ideas@pernangband.net
- and bugs@pernangband.net thanks to Tom Le
-[I]- Added gamma correction subcommand to "Interact with colours", and
- updated main-gtk.c and maid-x11.c to work with that (they formerly
- used an environment variable for this). Also added gamma correction
- support to main-ibm.c and main-dos.c. CAVEAT: tiles don't react to
- changes in gamma immediately, for performance reasons -- pelpel
-
-05/11/2001
-[m]- Removed notice of sf_extra value from savefile load code. We probably should
- make the spot where it loads it a ls_skip and remove that older family of
- versioning variables -- Improv
-[m]- Took a stab at code to make a dynamically allocated loadsave section. It's
- not called because it needs support code that presumably DG will write.
- With any luck it'll be sufficient to do the job -- Improv
-[I]- Updates to experimental new status screen -- Improv
-[B]- Fixed a bug that caused all monsters drop inappropriate things. Hydras now
- just drop money again. Yay. -- Improv
-
-06/11/2001
-[m]- Added an automatic nice changelog generator based on changes.txt. To all people
- with cvs access, please use the new format for changes.txt.
- It is activated with the -c flag: pernangband -c changes.txt changes.nice
-
-07/11/2001
-[P]- It is possible to define player power(under the U menu) with lua scripts
- (and thats easy :)
-
-09/11/2001
-[B]- (IBM, DOS, GTK) gamma_val is reset as well as old_gamma_val
- when invalid values are specified, ensuring correct reaction -- pelpel
-[B]- File-Save was never active in the Gtk port -- pelpel
-[m]- gamma correction for Windows port. I'm too lazy to save it in preferences,
- though. May be redundant since many drivers provide similar functions
- -- pelpel
-[G]- Flat places no more have stairs, they have ways to next/previous areas that
- are always placed on the edge of the level
-[D]- Level borders are now of the same type as the level walls, no more forest
- surrounded by granite walls
-[B]- Haste Monster cannot haste as much as before
-[I]- Pets infight wont disturb the player anymore if disturb_other is off
- (it is by default). In combinaison with auto_more it will totaly ignore
- pet messages
-[O]- New item set, The Trinity
-[m]- Lua-ified item types(can add new ones with simple lua script)
-
-10/11/2001
-[m]- Added Gtk entries in the system pref files, also enabled new graphics
- for X11/Gtk ports -- pelpel
-[I]- The target prompt will indicate if the targetted monster is a quest
- monster or not
-
-12/11/2001
-[m]- Updated main-xaw.c to that from the same version as main-x11.c
- i.e. 2.9.2. It now reacts pref colours and has graphics mode
- (doesn't work with 8bpp though). CAVEAT: main-x11.c and main-xaw.c
- should free unused colours after allocating new one. -- pelpel
-[G]- Troll galde quest only available at night
-[G]- Genocide is forbiden in the last alliance quest
-[G]- Invasion of gondolin quest will wait the end of the current quest to be
- generated
-
-13/11/2001
-[m]- Variable savefile ! Lua scripts(or C scripts(quests)) can now add stuff
- to the savefile without ever breaking the compatibility !
- See an example ofthat in test.lua
-[B]- SPECIAL_GENE objects were generated out of context -- pelpel
-[B]- Inappropriate monsters could be assigned to randquests in
- rare occasions. CAVEAT: it now uses an infinite loop to
- avoid illegal choices! -- pelpel
-
-14/11/2001
-[G]- New quest, try cahtting with maggot instead of killing him, you murderer !
-[m]- Re-implemented object allocation table caching -- pelpel
-
-15/11/2001
-[B]- Inserted /* Paranoia */ code in kind_is_theme() to prevent "(Nothing)"
- from generated due to missing drop theme in r_info. Player ghosts
- had this behaviour as far as I know -- pelpel
-[m]- Changed the rand quest reward generation to make it compatible with
- yesterday's fix -- pelpel
-[O]- Added new ego rod, of simplicity, thanks to Runescyre for the idea
-[m]- Max number of classes, races, subraces and realms is now 64
-
-16/11/2001
-[I]- Stole the death screen of KaMband, much nicer :)
-[P]- Removed the astral option. It is replaced by a subrace, Lostsoul, they
- have intrinsinc wraithform(until they get back to the surface), start
- with some identify scrolls and have all levels enlightened
-[B]- The find artefact fate was able to grant SPECIAL_GENE artefacts -- pelpel
-
-17/11/2001
-[D]- Dragon Lair renamed to Erebor, the misty mountains
-[P]- Rogues gets level/3% more changes of critical hits
-[D]- The wilderness "borders" are now Ekkaia, the Encircling Sea
-[I]- I ran out of keys, so I added an extended command mode. Press '#' (')' in
- roguelike command mode) to acess to it. You can then enter the command
- name or a shortcut if the command have one(usualy a command have a 1
- letter name and a complete name). You can also press ? or help to get
- the list of commands
-[I]- The time command is avaiable again for roguelike command set in the form
- of the t/time extended command
-[I]- D/html-dump extended command to take an html screenshot
-[I]- Quest list is now ordered by danger level
-
-18/11/2001
-[B]- Attempting to go down shaft gave the message "I see no down staircase
- here", thanks to Kevin W. Thomas -- pelpel
-
-19/11/2001
-[G]- Reduced the Spirit Realm Project Force spell radius as it increase levels
-[B]- Entering Nether Realm crashed the game, thanks to M.Itakura
- -- Kusunose
-[B]- Polymorphing monsters in the wall crashed the game, thanks to to
- M.Itakura -- Kusunose
-[B]- Sometimes random quest appeared on deep(dlv>98) Angband -- Kusunose
-[B]- Cursed EASY_KNOW items were not squelched -- Kusunose
-[B]- Replaced all checks against RF1_QUESTOR to MFLAG_QUEST -- Kusunose
-[B]- Shafts were not detected by detect stair spell -- Kusunose
-
-20/11/2001
-[G]- Traps have been tweaked down to be a bit less deadly, thanks Runescrye
-[P]- Summoner class! Thanks to Luc French for the idea and quite a bit of
- the code
-[I]- New splash screen made by Jans
-
-21/11/2001
-[B]- Mathilde was allowed to use wepaon(when possessed)
-[I]- Finished all spells description, thanks to Runescrye
-
-22/11/2001
-[m]- Quests are lua-ified
-[m]- flush() is called before *that* DragonRider question, to prevent
- catastrophic(?) accidents, taken from Kusunose's Japanese version
- -- pelpel
-
-25/11/2001
-[B]- (GTK)Widget instance names should have begun with lowercase letters
- -- pelpel
-[B]- (makefile)LUA_NUM_TYPE macro removed (see my 3/11/2001 mod
- for makefile.org) -- pelpel
-[D]- Museum(Mathon-house) added to Bree thanks to Kusunose
-
-27/11/2001
-[I]- Added an option to allow the @ to turn into a number when health
- drops. ideas from Mangband/PernMangband
-
-28/11/2001
-[m]- ANGBAND_DIR_USER is moved to ~/.pernangband on multiuser systems
- (Unix, GNU/Linux), according to DG's preference, and against the
- V/Z way... IMPORTANT NOTE FOR 422color USERS: please move
- 422color.prf to lib/pref directory -- pelpel
-
-30/11/2001
-[B]- I forgot to give Tom Demuyt credits for the Unbelievers idea.
-
-01/12/2001
-[m]- Updated makefile.bcc. It now supports lua4. -- Kusunose
-[B]- The broken sword quest generates the real reward, thanks
- Dawnmist
-[m]- Windows port now saves gamma_val in .INI file. -- Kusunose
-
-03/12/2001
-[M]- Rejoice ! no more nazguls as random quests
-
-04/12/2001
-[m]- Some patches from Kieron, thanks
-[I]- Kieron save squelch patch, modified to not save from chars to chars
- it can just be used to dump suqelch to a .prf file and load it
-
-05/12/2001
-[P]- New class from Luc French, the Blade, weaponless fighter able to dodge
- melee & some spells
-
-07/12/2001
-[B]- One could steal guardians' artefacts and reenter level to
- obtain multiple copies (buglist??) -- pelpel
-[B]- Fates could be lost during level regeneration (auto_scum and/or
- too many objects/monsters) -- pelpel
-[B]- (GTK)Fixed terribly stupid menu crash bug -- pelpel
-[B]- Climbing sets can now be pluralized thanks to John Q. Smith
-
-10/12/2001
-[I]- No more annoying infighting monster messages when turning disturb_other
- off
-
-11/12/2001
-[B]- Randquests and special levels must be immune to all types of level
- regeneration now -- pelpel
-
-12/12/2001
-[B]- Fixed alchemist art creation bug that allowed to use 4x exp
-
-13/12/2001
-[M]- Krakens lost their 6 ring slots, the tentacles are too big to put
- rings on them ;)
-[B]- Bashed down doors weren't revealed -- pelpel
-[B]- The Phial and other activatable items didn't have (charging) message
- -- pelpel
-[B]- There were extra spaces after names of unique corpses -- pelpel
-
-14/12/2001
-[B]- Detected traps should prevent running now -- pelpel
-[B]- The easy disarm code used easy_disarm and always_pickup flags in a very
- strange way, resulting in undesirable pickup behaviours -- pelpel
-[B]- "Grass with flowers" shouldn't disturb running now -- pelpel
-
-15/12/2001
-[B]- Entrances to vaults used dungeon-themed terrain features,
- sometimes making it impossible to dig them through -- pelpel
-[B]- DG's 27/11 mod is conditionalised to avoid doing so in the graphics
- modes, because it hardcoded characters and breaks the graphics support
- -- pelpel
-[B]- Mimic features are cleared when overwritten by streamers, to
- avoid, say, tree-looking deep water -- pelpel
-
-16/12/2001
-[I]- Added overlay graphics for ego monsters, player subraces and traps
- -- Kusunose
-[I]- Added 'search by name' feature to '/' command. -- Kusunose
-
-17/12/2001
-[I]- Player now drops out of the overhead wilderness view when becoming hungry/
- emptying lite
-[B]- Change in spell stat did not affect Mana/Spells if spell stat were
- not INT/WIS/CHR, thanks to kobayasi-san. -- Kusunose
-[B]- Change in WIS did not affect Sanity Points if WIS was not spell stat.
- -- Kusunose
-[B]- Costs of Symbiontic power were not displayed in first page, thanks to
- kobayasi-san. -- Kusunose
-[B]- Symbiontic power, scare and blind, was misordered, thanks to
- kobayasi-san. -- Kusunose
-
-18/12/2001
-[I]- Graphics overlay for the three X11 ports (untested). It requires
- USE_TRANSPARENCY and USE_EGO_GRAPHICS. USE_TRANSPARENCY was ugly,
- but this... -- pelpel
-[I]- Graphics overlay for the two Macintosh ports, again, untested -- pelpel
-[I]- Add ra_info.txt (randart generator info file) thanks to Runescrye
-
-19/12/2001
-[I]- Graphics overlay for the DOS port (USE_DOS). Also fixed a bug in
- the overlay support in the Mac ports. I removed always_pict
- code from the GTK+ port, because it's really slow, judging from
- the graphics performance on the Mac ports which use the mode
- to support tile width/height customisation -- pelpel
-[B]- Left good_item_flag for special levels, but adjusted rating boost
- a bit, because later fixes made +50 boost unnecessary
- Also toned down the rating boost for randquests -- pelpel
-[D]- New quest in Dol Guldur
-
-21/12/2001
-[B]- Fixed the very old artefact generation bug (present in
- Angband 2.7.8 -- 2.8.2) that forced "special artefacts" to be
- generated in the a_info.txt order. It is really problematic
- in Pern because of the depth of the Phial -- pelpel
-
-22/12/2001
-[B]- A Beorning's father was a Storm Giant sometime, and A Petty-Dwarve
- was one of several children of a Nibelung. -- Kusunose
-
-23/12/2001
-[B]- Fixed a bug that allowed to throw items with CURSE_NO_DROP.
- -- Kusunose
-[m]- Added spell spoiler creation in wizard mode. -- Kusunose
-
-24/12/2001
-[m]- (Mac)Eliminated busy waits in CheckEvents and TERM_XTRA_DELAY.
- It works well on my machine, but I left the original code using
- "#if 1/0" just in case -- pelpel
-[I]- Player now drops out of overhead wilderness view if a vampire and it's
- daylight
-
-25/12/2001
-[B]- Reintroduced OoD restriction on randquest monsters (until dlev 49)
- -- pelpel
-[B]- a fix for RNG problem with 64-bit machines, taken from V(?) -- pelpel
-
-27/12/2001
-[I]- Basic IRC facilities! 3 new extended commands: C to connect
- D to disconnect and : to chat. Highly experimental.
-[B]- Find artefact fate could cause permanent loss of artefacts. The code
- now tries to create a randart when there are no good choices instead
- of always defaults to the Phial -- pelpel
-[B]- Randquests sometimes requested players to kill slain uniques,
- making it impossible to continue the game -- pelpel
-[B]- (Carbon)Removed the dialogue indicating errors in AEProcessAppleEvent,
- because an r.g.r.a post pointed out that this can be quite annoying
- and Apple says they should generally be ignored -- pelpel
-[I]- DOS support for the irc client, needs libsocket:
- http://www.phekda.freeserve.co.uk/richdawe/lsck/lsck.htm
-[O]- Updated ra_info, thanks to Runescrye !
-[I]- X11 Support for the IRC client.
-
-29/12/2001
-[G]- a New randquest type !
-[B]- Companions cannot be hurt by the player anymore
-
-30/12/2001
-[B]- Reduced all force spells because of the side effects of force attacks
-[M]- Monster breathing/casting force attacks will bounce the player.
- Just like player's force attacks bounce monsters :)
-[M]- Fixed the IRC client some more.
-
-01/01/2001 - PernAngband 5.1.0 aka "Into the Fire"
-
-2002/02/19
-[B]- Normal (non-vampire) races didn't get mana regenerated at Inn -- pelpel
-[B]- The Mathom house acted like a normal shop when selling. -- Kusunose
-[B]- '-s' crashed the game. Thanks kobayashi for the fix -- pelpel
-[O]- Combining rod and rod tip now considers rod's cheapness flag.
- -- Kusunose
-[B]- Beastmaster Shanty overpayed a bounty if monster's corpses are stacked.
- -- Kusunose
-[B]- The random text code left files open in many error cases -- pelpel
-
-2002/02/20
-[B]- WeaponMasters were not restricted with their weapons. -- Kusunose
-[B]- Info text of 'disrupt mind' was described as 'dam'. -- Kusunose
-[B]- Fixed the "automatic ego filter" bug in the squeltch filter -- pelpel
-
-2002/02/26
-[B]- The polymorph random effect could crash the game. Thanks Kevin W.
- Thomas for the detailed analysis of the problem -- pelpel
-[B]- Stat draining effect of Black breath could crash the game. Thanks
- Kevin W. Thomas again for the patch -- pelpel
-[B]- With easy_disarm set, players were totally safe from detected traps,
- whatever messages might say -- pelpel
-[B]- Ego graphics code is now only active when and only when 16x16 tiles
- are selected -- pelpel
-[B]- Quest entrances/exits now require players to type '>'/'<' commands
- to move in/out -- pelpel
-[m]- Shimmering terrain features no longer shimmer while running/resting,
- to make them more bearable on slower machines and slow I/O systems
- like GCU -- pelpel
-[I]- Incorporated the hopefully improved running code from the CVS version.
- It uses CAN_RUN and DONT_NOTICE_RUNNING flags for non-conditional
- checks (i.e. not controlled by the disturbance flags or requiring
- immunity), so that most running problem can be fixed by editing
- f_info.txt -- pelpel
-
-2002/02/27
-[B]- Many room walls didn't have the CAVE_ROOM flag set -- pelpel
-[m]- The tunnel code (ordinary one) now performs double check for
- feat_wall_outer and CAVE_ROOM, so it is safe to use any terrain
- features for outer wall, including those identical to fill_type.
- Note: These two changes have very significant effect on the Sacred
- Land of Mountains. I'm not 100% sure if this is what DG intended,
- but I believe so reading flags given to it in d_info.txt -- pelpel
-[D]- There should be less not-at-all secret "secret" doors.
- This does *not* mean that ancient prob, but those mountains enbedded in
- plain wall in Barrow-Downs, for example -- pelpel
-[I]- Inven/equip/item choice in subwindows now clears to the bottom of screen,
- to avoid glitches and in accordance with the way it worked -- pelpel
-[I]- Identify and *Identify* don't list known/fully known items in
- object selection -- pelpel
-[m]- Depth/field name area is now 13 character long, so that names like
- "shallow water" will fit, and "Lothlorien" is not truncated in GCU.
- Also added short dungeon name prefix to the depth-in-feet mode -- pelpel
-
-2002/2/28
-[B]- Dungeon town generation could crash the game. Thanks Mogami
- for the analysis of the problem -- pelpel
-
-1/03/2002
-[B]- Supplied missing suid code in 1) savefile removal action in the startup
- screen, 2) time table lookup, 3) dungeon savefile removal, and
- 4) bone file removal. Thanks kobayasi for the patch -- pelpel
-[B]- Less platform-dependent savefile processing code for the game start
- menu, thanks again for kobayasi. It now uses files.c utility routines
- for building appropriate savefile names -- pelpel
-[B]- Magical branding of weapon/ammo, when successful, now sets enchanted
- item's discount rate to 100%, so that one can no longer make vast
- profit or easily gain his/her deity's favour. Code adopted from
- T.o.M.E. 2.0.0 CVS -- pelpel
-
-03/03/2002
-[P]- Give Ents scrolls of satisfy hunger instead of some food. -- Kusunose
-[M]- Added a command to dismiss companions in the pet menu. Code adopted
- from T.o.M.E. 2.0.0 CVS -- Kusunose
-
-04/03/2002
-[B]- '/' in item selection didn't update screen correctly -- pelpel
-[m]- Moved auto-squelch code from process_player() to process_world() -- pelpel
-
-05/03/2002
-[m]- CAVE_TRDT wasn't cleared when a trap is disarmed, which had some
- subtle effects and forced coders to double check c_ptr->info and
- c_ptr->t_idx in various places -- pelpel
-
-06/03/2002
-[B]- Level generation could cause infinite loop in the Sacred Land of
- Mountains -- pelpel
-[B]- Player ghosts were disabled in a way causing special feeling on
- every level -- pelpel
-[m]- Changed repeated message code to V-CVS one -- pelpel
-[m]- Added another graphics mode variable called graphics_mode :),
- somewhat like use_graphics in ZAngband, but it doesn't
- require any changes to main-xxx.c. It's set within reset_visuals()
- and used by map_info(), so that it doesn't have to do streq()
- each time it is called -- pelpel
-[B]- Took 64-bit safe RNG from Vanilla -- pelpel
-
-11/04/2002
-[B]- Gave SPECIAL_GENE flags to the k_info.txt entries of SPECIAL_GENE
- special artefacts -- pelpel
-
-20/04/2002
-[B]- Player is now guaranteed to have initialive after entering a level.
- Thanks Joseph William Dixon for the patch -- pelpel
-
-22/04/2002
-[m]- Renamed 422colors.prf to 422color.prf, to make it fit with the 8.3 naming
- convention -- pelpel
-
-24/04/2002
-[m]- Add support for multiline comments in lua: --[[ ... ]]
-
-28/04/2002
-[B]- Fixed a bug that caused gods start casting nasty effects when player's
- grace becomes negative. It should have been -60000. -- Kusunose
-[D]- The inn in Bree is now The Prancing Pony. -- Kusunose
-[m]- Improved lua interface for defining new 'm' keys, magic powers, quests, ...
-
-05/05/2002 - T.o.M.E. 1.0.0 aka "Between the Darkness and the Light"
-
-02/1/2002
-[m]- (Mac, Carbon)Graphics mode performance improvement. When a user
- chooses a fixed width font (as is almost always the case) and
- doesn't change tile width & height, the higher_pict method is
- used instead of *very* slow and inefficient always_pict to
- draw things -- pelpel
-
-04/1/2002
-[B]- Normal (non-vampire) races didn't get mana regenerated at Inn -- pelpel
-[B]- Fixed the monster casting at other monsters but targetting you bug
-
-11/01/2002
-[B]- Sacrificing wands now decreases charges
-
-12/1/2002
-[B]- The random text code left files open in many error cases -- pelpel
-[m]- The prf file loader always searches for the user directory first,
- then the pref directory if it can't find it there, so that user
- can override the system defaults keeping the distributed files
- intact. This also simpifies the pref loading codes in several
- places -- pelpel
-
-13/01/2002
-[B]- Fixed more running problems (FEAT_SAND and FEAT_ASH) -- pelpel
-[B]- Some routines called malloc/free instead of C_MAKE/C_FREE in
- the vault generation -- pelpel
-[B]- One wrong sign in the fractal cave code (vertical average) -- pelpel
-[B]- Fixed the store info file thanks to wrabhit23
-
-14/01/2002
-[B]- Ego items had extra spaces in their names -- pelpel
-[B]- (XAW)Terminals used wrong names. USE_EGO_GRAPHICS didn't even
- compile -- pelpel
-[I]- IRC code for the XAW port. Caveat: it causes a linker error
- if you USE_X11 and USE_XAW at the same time... -- pelpel
-[m]- the html help file converter now gets it's header and footer
- from head.aux and foot.aux in lib/help to help website
- designer adapt the generated files to whatever they want
-
-19/01/2002
-[B]- The Mathom house acted like a normal shop when selling. -- Kusunose
-[I]- Removed hard-coded direction keys in the skills menu -- pelpel
-[B]- Many room walls didn't have the CAVE_ROOM flag set -- pelpel
-[B]- More running problem (small trees in Mirkwood) -- pelpel
-
-20/01/2002
-[B]- final artifacts were not generated if they are k_info artifacts.
- -- Kusunose
-[B]- Fixed get_com interface for lua
-
-22/01/2002
-[B]- Squelch on sense now destroys {good} items if it's told
- "destroy good", but only when the "strong" pseudo-ID is in
- effect. Doing so for the "weak" method would be too dangerous -- pelpel
-[m]- The running code now uses DONT_NOTICE_RUNNING and CAN_RUN terrain
- feature flags for non-conditional checks, i.e. everything but doors,
- stairs and alike, and those requiring levitation or immunity -- pelpel
-
-23/01/2002
-[m]- Included the lua tutorials by Fearof4s
-
-24/01/2002
-[m]- Replaced the field of view code with that from Angband 2.8.3--
- -- pelpel
-[I]- view_special_lite and view_granite_lite that work with non-white
- terrains (for ASCII mode only, already done for 16x16 tiles) -- pelpel
-
-25/01/2002
-[B]- '-s' crashed the game. Thanks kobayashi for the fix -- pelpel
-[B]- Doors are remembered, so that they work better with easy_open.
- The easy_open code now performs checks for the perennially hard-to-handle
- feature mimic field -- pelpel
-
-27/01/2002
-[D]- A fair number of dungeon guardians lost their defined artifact drop
- and got a randart drop instead. The removed arts are back top normal
- behavior(can be found)
-[I]- Inven/equip/item choice in subwindows now clears to the bottom of screen,
- to avoid glitches and in accordance with the way it worked -- pelpel
-[I]- Identify and *Identify* don't list known/fully known items in
- object selection -- pelpel
-
-29/01/2002
-[B]- monster_carry() could cause permanant artefact loss. A similar code
- in quests and guardian artefact generation are also fixed -- pelpel
-[D]- There should be less not-at-all secret "secret" doors.
- This does *not* mean that ancient prob, but those mountains enbedded in
- plain wall in Barrow-Downs, for example -- pelpel
-
-20/01/2002
-[D]- Some spells can now stay in effect for a while, like a cloud of poison
- will stay in place and poison everything passing in it
-[P]- Changed the magic system, it now uses schools of magic instead of
- realms. A school contains much less spells than a realm. Each spell
- is unique and dont make others redundant. Also all spells tries to stay
- usefull for the whole game, by increasing in power and effects with levels.
- A spell can be assigned to more than more school, in which case all the
- schools need to be raised to obtain more power. All spells are implemented
- in lua, to make it easy to tweak them.
- All spells arent coded yet but my plans are for those schools:
- Mana, Fire, Water, Air, Earth, Mind, Conveyance, Meta, Temporal,
- Divination, Nature and Nether
- It may change somewhat but thats the general idea :)
- Books are not specific to a school, they can contain any spell from any
- schools, it is even imaginable to have randomly created books
-
-01/2/2002
-[D]- Streamers use small tress instead of trees, a la KAngband and
- variants that borrowed it's code. And they should look more like
- streamers in most dungeons -- pelpel
-[D]- Neither player or monsters can see through, breath, or cast spells
- over small trees, that are outer wall in Mirkwood -- arena levels
- were too nasty otherwise... -- pelpel
-
-02/2/2002
-[m]- los, player's field of view, and spell/breath projection now all use
- FF1_NO_VISION for the sake of consistency (in addition to the wall
- check in case of spell/breath projection) -- pelpel
-[M]- Added a command to dismiss companions in the pet menu
-
-03/2/2002
-[D]- Moved wiz_dark() implementing the maze level from move_player() to
- process_player(), so that a spellcaster can no longer do magic mapping--
- detect monsters--detect traps then casting teleport as often as s/he
- wishes to make things incredibly easy. Because of my laziness detected
- traps aren't displayed if they are out of sight. This would require
- tremendous hack. Anyway, don't worry, they are still remembered -- pelpel
-[I]- Auto-squelch menu now accepts ^R as an alternative to ^S, to be nice
- for those who USE_GCU. Thanks Skylar Thompson for the problem report
- -- pelpel
-[m]- CAVE_TRDT wasn't cleared when a trap is disarmed, which had some
- subtle effects and forced coders to double check c_ptr->info and
- c_ptr->t_idx in various places -- pelpel
-
-06/02/2002
-[B]- Do not drop from wild if player were not in wild mode in previous turn;
- it put player in wrong place and could crash the game. -- Kusunose
-[B]- Summoning monsters from totems could crash the game. -- Kusunose
-[B]- The Heavy Crossbow of the Elves was 'the ultimate armor' in the
- fully identified description. -- Kusunose
-
-07/02/2002
-[m]- Added FF1_DOOR flag to open doors for lightning effects in map_info()
- and have the trap creation code explicitly avoid them, because traps
- have and should never been performance bottlenecks -- pelpel
-
-08/02/2002
-[m]- Some process_world() sections (most notably monster generation and
- lingering spell effects) are conditionalised so that they don't run
- in the overhead map -- pelpel
-[D]- Added a dungeon flag that prevents generation of streamers, and
- gave it to those with water/lava rivers and places like Numenor
- and the Sacred Land of Mountains. Maze and evolving levels don't
- require this. Also made lava deeper (dlev 34 or below). Trees can
- appear on any flat levels. And eliminated undesirable calls to
- the RNG in the streamer code -- pelpel
-[m]- Changed all the signed (!) flags I was able to find to unsigned, because
- they don't make any sense. Savefile code should be modified as well
- if we ever care for savefile portability -- pelpel
-[m]- The tunnel code (ordinary one) now performs double check for
- feat_wall_outer and CAVE_ROOM (which was added a couple of weeks ago),
- so it is safe to use any terrain features for outer wall, including
- those identical to fill_type -- pelpel
-
-09/02/2002
-[D]- Rewrote place_new_way() so that it doesn't create unconnected dungeon
- sections, destroy outer walls of rooms, or dig room corners -- pelpel
-[I]- Hopefully finished special lighting effects. Now it works this way
- (with all lighting effects options on):
- Perma-lit grids and lit walls/doors within sight, and remembered important
- features = f_info colours, Perma-lit floors and walls/doors out of
- sight = darker colours, torch-lit "boring" floor = yellow, torch-lit
- grids out-of-sight = dark grey, blindness = B&W -- pelpel
-[D]- Angband dungeon now adjusts monster levels to the dungeon level.
- The monsters here will have a minimun level in the range of:
- level / 2 to level. So at level 67 the lowest monster you can encounter
- will be level 33. This means that if a white icky thing is generated
- it will be a level 33 white icky thing. If the base monster level is higher
- then nothing is adjusted.
-
-11/02/2002
-[m]- (Temporary note) Separated staying effect handling code from
- process_world() and made it a function, so that it can be called in
- any place with in dungeon() [can be activated by #define pelpel :)]
- I temporarily placed it after process_player(), but we have to spend
- some time testing this, seeking for the best turn structure -- pelpel
-[m]- Auto-squelch is performed *before* a player turn, just before the
- pack overflow code to prevent some interface problems. This means
- that squelching occurs as the very last action of a player turn,
- after monster drops or even after pseudo-ID, so that you don't have to
- press extra space to squelch items. Another possible arrangement
- would be within process_world(), right after sensing -- pelpel
-
-12/02/2002
-[B]- Fixed a bug in the hook code that may or may not be the cause of
- various quest-related bugs -- pelpel
-[D]- Altars now have CAN_RUN flag, so that you no longer see the
- message "You cannot run in that direction" when trying to run
- across them -- pelpel
-[m]- Added flush() before all the quest questions to prevent accidental
- loss/declination/acceptance of quest rewards/quests, also added
- very important flush_failure and flush() to the lua interface and
- put that in the spell failure code, so that spells can be macroed
- safely -- pelpel
-[B]- Fixed a bug in the 6 monster randquest thanks to Louis-Frederic Michaud
-
-13/02/2002
-[O]- Elvish waybread renamed to lembas, thanks to nimloth
-[I]- Because I find detection no longer works on panels, added DTrap status
- line as well as a new disturbance option disturb_detect. Also removed
- hardcoded row/column positions in the status line code, in preparation
- for big-screen support -- pelpel
-
-16/02/2002
-[I]- Added scrolling target/look code, which is bastardised :) form of
- Z and V ones -- pelpel
-[m]- Depth/field name area is now 13 character long, so that names like
- "shallow water" will fit, and "Lothlorien" is not truncated in GCU.
- Also added short dungeon name prefix to the depth-in-feet mode -- pelpel
-[m]- Because map_info() is the #1 bottleneck routine and because I felt
- hack_map_info_default is incredibly ugly :(, I removed
- hack_map_info_default and added specialised version of map_info()
- for use by cmovie and the HTML screen shot saver -- pelpel
-[B]- Fixed the "automatic ego filter" bug in the squeltch filter -- pelpel
-[I]- Big screen is sort of working now, but main-xxx.c (have
- to remove restrinction on size of the PernAngband window) and
- cmovie are still needing upgrade -- pelpel
-
-17/02/2002
-[B]- Made panel_bound() more paranoid about the current dungeon size,
- to prevent many big screen-related crashes -- pelpel
-
-18/02/2002
-[m]- Added 8x8 graphics support to trap display code -- pelpel
-[m]- Added another graphics mode variable called graphics_mode :),
- somewhat like use_graphics in ZAngband, but it doesn't
- require any changes to main-xxx.c. It's set within reset_visuals()
- and used by map_info(), so that it doesn't have to do streq()
- each time it is called -- pelpel
-
-19/02/2002
-[m]- Added term resize hooks so that one doesn't have to hit the redraw
- key and alike when s/he resizes windows. Hooked functions are placed
- in xtra2.c, because they are only related to big screen support
- and other panel related codes are there. Don't like the way stuffs
- are initialised -- assumption about max number of terms, setting terms
- package hooks from within the upper layer codes -- but the existing
- implementations do it this way, and the "right" way requires changes
- to main-xxx.c, which I'm too lazy to do... -- pelpel
-[I]- Big screen support for X11 and XAW ports (already done for Gtk, Mac
- and Windows ports). Also added an option -o to force the use of 8x8
- tiles in graphics mode. Say "-g -- -o" to activate it. And please note
- that because of the way transparency effect is implemented in
- X11/XAW/Gtk ports, it is available even with 8x8 tiles -- pelpel
-
-20/02/2002
-[B]- Beastmaster Shanty overpayed a bounty if monster's corpses are stacked.
- -- Kusunose
-[O]- Combining rod and rod tip now considers rod's cheapness flag.
- -- Kusunose
-
-22/02/2002
-[M]- Restored monster light code, modeled after Steven Fuerst's implementation
- insteand of APW one this time, but without his support for multiple radii.
- -- pelpel
-[M]- Made monster light a run-time option. CAVEAT: It'll cause display
- weirdness when you turn this option from ON to OFF while playing.
- Save/Restart or entering new level will fix the problem.
- Should call forget_mon_lite() when the game detects it... -- pelpel
-[M]- monster lite option is on by default
-
-23/02/2002
-[B]- A failure in disarming traps using easy-disarm caused another attempt
- at disarming traps (because it calls move_player_aux which calls
- do_cmd_disarm_aux which calls move_player_aux...), growing call
- stack infinitely. It's dangerous, and, in fact, players were totally
- safe from traps (messages said "You set off...", but traps were never
- activated) -- pelpel
-[B]- Black breath could crash the game (it's really evil, isn't it :)
- Thanks Kevin W. Thomas for the patch -- pelpel
-[m]- Ego graphics code now only tries to use graphics overlays for
- monsters and players if and only if 16x16 tiles are used -- pelpel
-[B]- map_info() had problem with walls mimicking floors -- pelpel
-[m]- Shimmering terrain features no longer shimmer while running or resting
- to make themselves somewhat more bearable on slower machines -- pelpel
-
-24/02/2002
-[m]- Updated lighting effect code so that it works the same as rr9's Angband
- versions. Also removed hardcoded IBM pseudo graphics code points, so that
- if anyone is ever interested in updating its font & prf files, s/he
- can do so freely without editing the source code.
- And map_info / map_info_default is now fully aware of c_ptr->mimic,
- so that map edges will not have strange lighting effects etc.,
- hopefully -- pelpel
-
-26/02/2002
-[B]- Polymorphing random effect of Chaos Warriors could crash the game.
- Special thanks for Kevin W. Thomas for the detailed analysis
- of the problem -- pelpel
-[I]- Moving onto quest entrance/exit no longer causes annoying automatic
- stair movements. You have to tell the game '>' or '<' to enter/leave
- -- pelpel
-[m]- Renamed see_wall() in cmd1.c to see_obstacle() also added a grid-based
- version of the function to be used by run_test(), so that those who have
- immunity and/or levitation can run over lava fields, deep water etc.
- -- pelpel
-[O]- There are 2 kinds of spellbooks for the magic schools, the ones that
- are named "a Spellbook of foo" where foo is a randomly choosen spell
- (selection is based on the dungeon level)
- and other names that are fixed books
-
-27/02/2002
-[O]- School spellbooks can be fireproof ego items
-[B]- Dungeon town generation could crash the game. Thanks Mogami
- for the analysis of the problem -- pelpel
-
-01/03/2002
-[B]- Supplied missing suid code in 1) savefile removal action in the startup
- screen, 2) dungeon savefile removal, and 3) bone file removal.
- Thanks kobayasi for the patch -- pelpel
-[m]- Less platform-dependent savefile processing code for the game start
- menu, thanks again for kobayasi. It now uses files.c utility routines
- for building appropriate savefile names -- pelpel
-
-03/03/2002
-[B]- Special level names wherent corrently displayed if the N: line was the
- first of the file in lib/dngn
-
-03/03/2002
-[m]- Added initialization code to add SPECIAL_GENE flag to final guardians
- and their artifacts (and DROP_RANDART if there are no final artifacts).
- -- Kusunose
-[D]- Put yet another fractal code (unlike the others it's quite simple)
- in the level filler generator, and added a F: parameter in d_info.txt
- to control its behaviour. Its syntax is FILL_METHOD_#, where # is
- 0: use the first filler w/o calling RNG (for Angband, Mirkwood etc.),
- 1: the same as the previous versions (default), 2: slightly smoothed,
- 3: more smoothed, or 4: max smoothing (initial step of 8 grids) -- pelpel
-
-04/03/2002
-[B]- '/' in item selection didn't update screen correctly -- pelpel
-[m]- Moved squelch-on-sense code from process_player() to process_world()
- -- pelpel
-
-04/03/2002
-[P]- High intelligence increase mana regeneration rate
-
-06/03/2002
-[B]- Level generation could cause infinite loop in the Sacred Land of
- Mountains -- pelpel
-[m]- Changed repeated message code to V-CVS one -- pelpel
-[B]- Player ghosts were disabled in a way causing special feeling on
- every level -- pelpel
-
-07/03/2002
-[m]- Trap display now uses x_attr/x_char of FEAT_TRAP (f_info N:17)
- 1) if a trap is set on a "boring" terrain in the ASCII mode, where
- only x_char is used and attr is taken from tr_info.txt XXX XXX XXX
- or 2) if attr/char for a trap is not defined in prf files in the
- graphics modes -- pelpel
-[m]- Removed FAKE_VER_*, because it has been quite long since we lost savefile
- compatibility with Angband 2.8.1 and info.txt files can be updated
- by sed/perl/whatever script in a snap -- pelpel
-[B]- Took 64-bit safe RNG from Vanilla -- pelpel
-
-08/03/2002
-[m]- To accommodate the practice of not upgrading version stamp of info.txt
- files at each release (never done in V-based variants, but common among
- Z-based ones for historical reasons), version stamp checks against game
- data files in lib/edit is made a compile time option
- (VERIFY_VERSION_STAMP), off by default. With this option off, version
- stamp checks for the binary files are still performed and they always
- have version signature of the game, not those specified by the V: lines
- -- pelpel
-[B]- Wide light radius worked in the small scale wilderness map,
- where it should have been WILDERNESS_SEE_RADIUS -- pelpel
-
-10/03/2002
-[m]- Upgraded the lua bitlib so it can handle stuff like bor(1, 2, 4, 8)
-
-11/03/2002
-[M]- Confusion, stunning, charming now works on uniques(those that dont have the
- corresponding resistance)
-
-24/03/2002
-[I]- Stats can now be displayed in a linear mode(from 3 to 37) instead of
- 3 to 18/***, the option is off by default
-
-25/03/2002
-[D]- No more shafts in the halls of mandos
-[m]- Block comments( --[[...]] ) in Lua enabled
-
-27/03/2002
-[D]- Tweaked the door code a bit so that some doors are much harder
- to find -- pelpel
-[I]- Added recall depth subcommand to the knowledge menu -- pelpel
-
-03/04/2002
-[I]- Removed the flavoured_attack option and made most 'silly' messages
- off by default. They are now controlled by 'insanity roll', which is
- d100 roll against (max_sanity - current_sanity) * 100 / max_sanity.
- The same roll is also used to determine if the game should use
- silly monster descriptions (in addition to the hallucination
- effects) -- pelpel
-
-04/04/2002
-[I]- The skill interface no longer asks question whenever you increase skills.
- Changes to skill values are made permanent if the player confirms them
- when s/he leave the skill menu, otherwise, they are simply ignored
- -- pelpel
-[P]- The skill system is ready ! Some small tweakings are needed, but it is
- mostly ready. Each level you gain a few skill points that you can spend
- on various skills(like combat, weaponmastery, magic, ...). Most actions
- are now tied to skills.
-[P]- Classes revamped as more or less skill templates. Classes now can have
- specializations which allow starting with somewhat different skill set.
-[B]- Since streamers can create unconnected dungeon sections, the code for
- it is moved after stair and player allocation -- pelpel
-[m]- Reorganised the linkage order of makefile.org a bit, so that similar
- files are grouped together, also frequently called files are not coupled
- together with rarely used ones. This *might* help on-demand-paging memory
- manager a bit -- pelpel
-[m]- Changed all occurances of " ?" in strings to "? ". --takkaria
-
-08/04/2002
-[B]- Some player_type fields and corresponding lua interface definitions
- were of different types. Fix thanks to rr9. -- pelpel
-
-09/04/2002
-[I]- Bigtile patch for windows, x11 and mac ports thanks to Takeshi Mogami
-
-11/04/2002
-[B]- Gave SPECIAL_GENE flags to the k_info.txt entries of SPECIAL_GENE
- special artefacts -- pelpel
-
-15/04/2002
-[M]- Revision of the conf/stun/sleep resists for uniques thanks to Runescrye
-
-18/04/2002
-[G]- The adventurer quest reward is now either the adventurer or some skills
-[I]- Asks for a last screenshot upon death
-
-20/04/2002
-[I]- You can now dump a frame of a cmovie as an html screenshot(while playing
- the movie)
-[P]- New god system, each god will be much more different from all others.
- Altars are less vital. There are less gods.
-[m]- Renamed inappropriately called global array 'town' to 'town_info', also
- moved some boolean town_type members into 'flags', in order to support
- dungeon town information subcommand of do_cmd_knowledge -- pelpel
-[m]- Commented out or moved many local variables causing 'unused' warnings,
- because of badly placed if 0's -- pelpel
-[B]- Player is now guaranteed to have initialive after entering a level.
- Thanks Joseph William Dixon for the patch -- pelpel
-[I]- The commands for skills and spells are swapped. Please use 'G' to learn/
- check skills and '$' ('\$' in roguelike) to learn spells.
-
-22/04/2002
-[m]- Renamed 422colors.prf to 422color.prf, to make it fit with the 8.3 naming
- convention -- pelpel
-
-23/04/2002
-[O]- Bound the wands & staves damage/power to the Magic skill, attack wands
- should actually be usefull now
-
-25/04/2002
-[P]- Magic skill now allows you to copy spells from books into various
- objects. Not all objects can contain spells naturally, but most object
- of the Magi can, and all mage staves
-[P]- Spectres loses HP while in walls, it was too abusable(and in fact, I never
- planned to remove it)
-
-28/04/2002
-[D]- The inn in Bree is now The Prancing Pony. -- Kusunose
-
-01/05/2002
-[D]- Small levels cannot generate full levels anymore
-[I]- The prompt to cast a spell now understand to press @, which will ask for
- a spell name, it'll look all books and cast it if you can.
- It EASES macros, a macro will now look like:
- 02m@Manathrust\r*t
-[I]- Message recall now understands bigscreen thanks to pav
-[I]- Help now understands bigscreen thanks to pav
-[I]- Skill screen now understands bigscreen thanks to pav
-[I]- No more pickup prompt with autopickup when inventory is full, thanks to pav
-
-03/05/2002
-[B]- The skill increase/decrease code was unable to detect underflow -- pelpel
-
-06/05/2002
-[P]- Made running commands exempt from do_nothing processing, because this
- can be abusable and makes no sense -- you could, for example, hold down
- movment keys when following Eru and use running when following other
- deities -- pelpel
-[I]- Took big screen code for horizontal scrolling of message recalls
- from Vanilla -- pelpel
-[I]- You can navigate through option menus with roguelike_keys -- in fact,
- I didn't know users of the original keyset can go up before I play
- the latest V and see its code... Taken from Vanilla CVS -- pelpel
-[m]- Entirely removed function definining macros from script.c, because
- it can confuse some compilers (a lcc case was reported), and some
- preprocessor reports syntax error for missing macro arguments -- pelpel
-[I]- Added big screen support for GCU -- pelpel
-
-12/05/2002
-[m]- Some, if not all, command line options are documented -- pelpel
-[B]- Full map command displayed only half of current dungeon level when
- bigtile mode is used. Thanks for Takeshi Mogami for tha patch
- -- Kusunose
-
-19/05/2002
-[m]- 1) Slightly reorganised menus in the Mac ports, because there were so
- many of them on the menu bar. 2) added a switch (-b) to the GCU port
- to select multiple terms or one big screen. 3) the GTK port issued
- huge number of fatal warnings if the graphics mode was turned on and off.
- 4) Compiled latest V CVS with main-gtk.c in T.o.M.E. and fixed some
- portability problems. -- pelpel
-[P]- Pseudo-id is now bound to the Combat skill(for weapons/armors) and the
- Magic skill(potions, ...)
-[P]- It is now possible to press @ at the 'm' key prompt to select a skill action
- by it's full name. Thus allowing unbreakable macro:
- m@Cast a spell\r@Manathrust\r*t
-[I]- The skill screen cannot be abused to get more skills anymore
-
-27/05/2002
-[P]- New god Melkor Bauglir
-[P]- Weaponmastery, Archery and Barehand skills increase Combat skill much more
-
-02/06/2002
-[B]- Various spell effects that polymorph monsters could crash the game.
- -- Kusunose
-[B]- Compare weapons command miscalculated muliplying bonus. -- Kusunose
-
-12/06/2002
-[P]- Deathmold fetch ability pickups gold and objects(if autopickup is set) thanks
- to "kenderband" <kenderband@hotmail.com>
-[m]- Exported cur_hgt and cur_wid to lua by request of Fearof4s. (takkaria)
-
-14/02/2002
-[m]- Updated the lua help files thanks to Fearof4s and Chris Hadgis
-
-17/06/2002
-[B]- Fixed junk artifacts and music instruments stacking bug in stores
- -- Kusunose
-
-03/07/2002
-[M]- Monsters drop stolen gold when killed
-
-04/07/2002
-[B]- Capped max number of extra blows at 2 when the limit_blow flag is set
- in two places -- pelpel
-
-09/07/2002
-[B]- Cancelling a scroll of reset recall didn't work. -- Kusunose
-[O]- Reset recall now lists all the dungeons a player has visited and
- additionally allow a player to select by name. -- Kusunose
-
-13/07/2002
-[O]- Enabled the generation of double ego items. An item cannot get 2 prefix
- or 2 suffix, it will always be a prefix and a suffix
-
-14/07/2002
-[P]- New bounty quest available at the beastmaster shanty! Bring back a corpse
- and get some monster-lore skill and the ability to learn corpse-preservation
- skill if you couldn't already
-
-15/07/2002
-[P]- Replaced first necromancy spell with Horrify from the old Nether realm and
- the third spell with absorb soul, provides some health upon monster death
-
-16/07/2002
-[m]- Updated lua_ques.txt to fix some misinformation. -- fearoffours
-
-17/07/2002
-[B]- One was able to have another entry in the score file for a dead/retired
- character by loading him/her with the -w option, then answering 'n' to
- the wizard mode confirmation. Bug report and fix (for Angband 3.0.1, but
- applicable for all variants) by Hallvard B. Furuseth, Takeshi Mogami and
- Robert Ruehlmann -- pelpel
-
-22/07/2002
-[m]- More lua documentation fixes, particularly adding square brackets to field
- names on lines that would allow this without mucking up colour formatting.
- -- fearoffours
-
-23/07/2002 - T.o.M.E 2.0.0 aka "Point of No Return"
-
-24/07/2002
-[m]- The splash screen now shows "Tales of Middle Earth" or "Troubles of Middle
- Earth" randomly. Thanks to Scott Holder for the idea and some code.
- (takkaria)
-[m]- makefile.org now defaultds to ./lib for the lib directory
-[m]- makefile.org is now makefile.std
-[B]- Fixed a silly bug preventing Polearm masstery from wroking
-
-26/07/2002
-[B]- In multiuser installations, notes and cmovie were written under the lib
- directory using the game's permission, making them inaccessible by
- the player. I moved them to ~/.tome. Note: This means that a coder
- shouldn't grab permission before opening files in these directories
- -- pelpel
-[B]- There are still inappropriate (and even unbalanced!!!) calls to
- safe_setuid_grab() and safe_setuid_drop() in the game. Thanks Neil
- for pointing out those in the macro save commands. There are so many
- places that I have to look at, but I'm trying... -- pelpel
-[I]- Better (hopefully) object identification screen
-
-28/07/2002
-[m]- Added safe_setuid_grab/safe_setuid_drop to all the functions that
- access files in the lib directory. I did so even for the game
- initialisation, knowing that it's very unorthodox. This is because
- I found some of them in the init[12].c. There's no other sure ways
- to keep them from messing multiuser installations. -- pelpel
-[m]- Added makefile.dos, which is a copy of makefile (now), in order to
- prevent overwriting accidents. Ideally, 'makefile' should be in the
- .cvsignore, so that every developper can feel at ease with his/her
- own preferred environment -- pelpel
-
-01/08/2002
-[P]- New corruption system, savefiles are compatibles but you will loose
- all your corruptions.
- Most corruptions now have a good and a bad effect. Some corruptions
- depends of others, it means that you can only get them when you have
- the ones they depend of(i.e: Balrog Form need Balrog Wings, Balrog
- Aura and balrog Strength to work). Some corruptions can be mutualy
- exclusive. The list of corruption is totaly rewrote. They are more
- in-theme now.
-[B]- Perma curse cannot happen on randarts anymore
-
-02/08/2002
-[B]- Player could not pick up items from home if he did not have enough
- gold. -- Kusunose
-[B]- Traps of wasting wand dont mess up wands
-[B]- Dragon helms get resistances
-
-03/08/2002
-[B]- No races were allowed to be loremasters
-[B]- Fixed a bug in Character classes allowed, tahnks to Alex Wilkins
-[m]- Added Melkor to the gods docs.
-[B]- Spells cannot be cast while blinded or confused(execpt for a few)
-[G]- Wielding the One Ring has some ... disadvantages now ...
-[B]- Poor Melkor didnt had his altar generated in dungeons, while he is the
- only god for a use of an altar
-
-05/08/2002
-[m]- Improved the adventurer guide and added a section for macros to it
-[P]- All Udun spells are no more multi-school spells
-[P]- Reorganized the skill tree to remove the Misc skill tree. Alchemy is now
- under Magic, Antimagic is in Combat and Music in Spirituality
-
-07/08/2002
-[B]- Fixed the -1 activation power of some mage staves of spell
-[G]- Troll Glade/Wight Grave selection is now (usualy) based on the
- Combat/Magic skills level
-
-08/08/2002
-[I]- The game asks confirmation before learning a skill that can exclude an
- already known one
-[I]- When 'I'nspecting(or upon *id*) a fully *id* weapon/ammo the game will
- tell you the damage it would do if you used it(idea from Ey)
-
-10/08/2002
-[I]- 'U' power menu is now usable with repeat key 'n'
-
-11/08/2002
-[G]- The chance for combat item pseudo-ID now improves exponentially,
- just like V Warriors (combat skill 0 == plev 0, maxed == plev 50),
- while that for magic items improves slowly, just like V Rangers
- and Mages but with higher success rate (more than ten times as
- frequent as V Rangers) -- pelpel
-
-12/08/2002
-[B]- Added missing spell frequency to Fire golem. -- Kusunose
-[B]- Symbiant cannot pickup a hypnotized pet from a pile. Thanks to kobayasi
- for the patch. -- Kusunose
-[P]- Give Ents scrolls of satisfy hunger instead of some food. -- Kusunose
-[B]- Stats more than 18/220 were displayed incorrectly if linear_stats was ON.
- -- Kusunose
-
-13/08/2002
-[m]- Made chg_to_txt in files.c conditional, so that it won't be included in
- Windows, Mac and RISCOS ports (they don't call the function, so it has
- been dead code) -- pelpel
-[D]- Since Tome generated small levels once in three times when requested,
- which I think is too often, and in Z and Ey the chance is 1/5 and 1/10
- respectively, I lowered the chance to 1/6 -- pelpel
-[B]- The small_level option had the same effect as always_small_levels
- -- pelpel
-[O]- Removed CURSE_NO_DROP from ego items. Players want new curses, and when
- they get them they complain...
-
-14/08/2002
-[I]- Added avoid_shimmer efficiency option to suppress shimmering of terrain
- features, because I have had problems with them on really big screens
- -- pelpel
-[P]- Increased the modifier of the masteries for warriors
-[P]- New Warrior subclass, the Demonologist, spell enhanced warriors. They
- use the new Demon school and the renewed Demonblades, Demonshields and
- Demonhorns. Their spells enhance their fighting potential. They can either
- be seen as a force of good, fighting against demons with their own powers
- or as a force of evil fighting to bring corruption to the world.
-[P]- Sorcerors begin with a robe instead of a dagger
-[I]- Easy close is now slightly more intelligent in their handling of
- broken doors -- pelpel
-
-15/08/2002
-[O]- Ring/Amulet of Spell, cheap, early objects that can contain a spell
-[B]- Exploding ammo dont stack with normal ammo
-
-16/08/2002
-[B]- Ammo creation is bound to Arechery skill instead of player level
-[B]- Fixed a bug in related skills, when one increased a skills sometimes the
- related skills didnt increased
-
-17/08/2002
-[m]- Do not grab/drop permissions twice. Thanks to kobayasi for the patch.
- -- Kusunose
-
-18/08/2002
-[B]- Temporal stat drain no longer cancels normal stat drain. -- Kusunose
-
-19/08/2002
-[O]- Temple will now stock random spells from god schools, Magic Shop will
- only stock non god spells and bookstore will contain both
-[O]- Stores buyable list is now lua defined
-[B]- The amount of mana in each grid was always magical level. -- Kusunose
-[P]- Changed the formula to calc the player HP when using possession so that
- a higher possession skill will be prefered
-
-20/08/2002
-[B]- Extracted essences overwrote a weapon slot when inventry was full.
- -- Kusunose
-
-21/08/2002
-[I]- Ingame contextual help is on by default(it was before, but it was bugged..)
- It is now proccessed by lua, file help.lua and should be much easier to
- add new sections to than before. So all feel free :)
-[G]- Added town of Khazad-Dum (where 'exit' from Moria was) with nice Mining
- supply shop. -- fearoffours
-
-23/08/2002
-[I]- Contextual help for the birth screens too. Press ? when over a race,
- class, ... and it'll bring the specific help for it
-[M]- Monster ego wont start awake
-[P]- lost Souls now have see invisible, I know I'm far too nice :)
-[I]- Contexual help to skill screen, press ?
-[I]- Easy macro recorder! Just press $ and press a normal key sequence!
-
-26/08/2002
-[m]- Removed the autosquelch to replace it with a new Automatizer that should
- be much more powerful. It lacks a gui, but that should soon change :)
-
-28/08/2002
-[I]- The new Automatizer got a GUI :) It should be quite easy to grasp, you
- define rules to match and action to take. But it does allow very complex
- rules.
-
-27/08/2002
-[m]- Added updated class help documents. Removed extraneous ones. Amended
- links in birth.txt to reflect changes. Added appropriate entries to
- help.lua for contextual class help at birth. Thanks to Mef. -- fearoffours
-[m]- More contextual help: races and god selection at birth, rod tips, rods and
- trapping kits. -- feaoffours
-
-29/08/2002
-[G]- Added new god quest. Given at random time by your god, you have to retrieve
- a piece of a relic generated at a random level of a randomly places dungeon.
- More than one of these quests may be given (currently up to 4), though only
- if you complete previous quests. The relic is only generated once in each
- dungeon, so look carefully for it. Diving won't help you. -- fearoffours
-
-31/08/2002
-[P]- New Water spell: Vapor, it create a low damage wide radius short lasting
- cloud of water. It is designed to be a cheap attack spell for annoying
- critters. Beware, random spellbooks & inscribed objects spells will "morph"
- to other ones, sorry, unavoidable
-
-03/09/2002
-[B]- Fix mushrooms stacking for the maggot quest
-[m]- Fix birth.txt crash -- fearoffours
-
-04/09/2002
-[O]- Scythes of Slicing are now vorpal, rarer and deeper
-
-05/09/2002
-[G]- Added the fireproofing quest. Visit the Mage tower in lothlorien to get the
- quest, bring back something for the mage, get books fireproofed in return.
- -- fearoffours
-
-08/09/2002
-[I]- Updated the forgotten IBM pseudographics, based on my unknown work for
- Pern 4.1.2. Also added an X11 BDF file so that it can be used on
- the three X ports -- copy graf-ibm.prf to font-x11.prf in your user
- directory (i.e. ~/.tome) and set the font of main window to the font
- made from lib/xtra/ang16.bdf. Instruction for installing new X fonts
- should be found in the bdftopcf, mkfontdir and xset man pages.
- -- pelpel
-
-10/09/2002
-[I]- Current location(town, level, ...) is show in orange when about to recall
-
-17/09/2002
-[m]- Updated skill docs, thanks to lemming
-[m]- More minor help file updates. thanks mef and Chris Hadgis
-
-21/09/2002
-[P]- Mindcrafters gets esp even after level 40
-
-22/09/2002
-[I]- You can press $ at object destruction prompt to automaticaly create a new rule
- for the Automatizer about the object being destroyed
-[B]- Casting "Disperse Magic" when spell level is 20 or more produced a lua
- error. -- Kusunose
-[m]- Reformatted the makefile.WHICH file. Do we really need this file anymore?
- other variants get by without it, I don't really think it's needed...
- (takkaria)
-[m]- Reformatted the todo list, removed some entries which have been done.
- Also added a section for stuff which I will do (one day). (takkaria)
-[m]- I've reformatted and reorganized a fair bit of notes.c; I've made stuff
- less hacky and made the function which writes notes to file use
- my_fputs()... Also replaced some hardcoded buffer sizes with sizeof().
- (takkaria)
-[m]- Removed hardcoded buffer sizes in wizard1.c. (takkaria)
-
-23/09/2002
-[M]- Farmer maggot quest provides a better reward, thanks to Revanant Morituri
- and Wil Hunt for the idea
-
-25/09/2002
-[B]- The centre player option failed to do so while running. Thanks Neil
- Stevens for the patch. -- pelpel
-[B]- Random Artifact arrows should now stack properly. -- wilh
-[B]- Mindcrafters lost their ESP at level 40. Now they have it permanently
- at that level. (p_info.txt) -- wilh
-[B]- Above bug was supposed to be skill level 40, not clvl 40. Fixed. :)
-
-28/09/2002
-[I]- Macro-patch from Mogami, now the macro prf files are portable between Windows,
- X11 and Mac. It also shows readable triggers like: \[shift-F1] and such
-
-29/09/2002
-[m]- Added .cvsignore to the src directory to prevent makefile overwriting
- accidents from happening. Currently it excludes makefile (developers
- are expected to update platform-specific makefile if s/he indents to
- make permanent changes to them), tome, tolua, TOME.EXE and TOLUA.EXE.
- -- pelpel
-
-01/10/2002
-[G]- Alchemy totaly changed! Thanks to John Gilmore for the patch! It has now entered
- cvs to begin being tested and "balanced" ;)
-
-05/10/2002
-[P]- Symbiotic power changed to be bookless
-
-06/10/2002
-[P]- Available skills to leanr via random quests are defined in s_info.txt
-[P]- Trying to mimic when already mimiced(with the skill) will turn you back to
- normal form
-[O]- All objects now have a description, thanks to Konijn
- When identifying an item you can then press 'I'nspect to check it. It si most
- usefull for scrolls & such, they tell you what exactly they will do
-[B]- Fixed a bug that made mage staves very costy
-
-07/10/2002
-[I]- Replaced font-ibm.prf, graf-ibm.prf, font-win.prf and font-mac.new (a
- font-mac.prf replacement that has IBM-like pseudographics definitions)
- with program-generated ones, hopefully up-to-date with recent changes
- in info.txt files -- pelpel
-
-11/10/2002
-[I]- Unusable skills do not show anymore on the skill screen
-
-17/10/2002
-[I]- New option to not have the equipment/inventory windows move items around
- when a prompt ask for an item. Thanks to John Gilmore
-[B]- Fix a bug of wands in store
-[B]- Fix an old spelling error: "droped" not "dropped" -- Neil
-
-18/10/2002
-[O]- Behold! The new Grand Scheme For Wands, Staves and Rods!;)
- Now all sticks in the game use the same system as the spells. The unified
- spell system could we say ;)
- What does it changes? sticks should now be usefull, jsut as spells are.
- For example a wand of manathrust is not to be laughed at.
- Hw does it work? 'I'nspect the stick you want to know about you'll see
- he details, each stick gets a spell and a base level. The base level
- means the spell will be cast at that level if you have 0 in the
- Magic Device skill. If you have Magic Device it increases the level.
- Works a bit like Spell-power for the spells.
- Also the distinction of wands/staves is tenuous now, wands are attack
- stuff and staves not but wands can sometimes NOT be targeted spells
-
-20/10/2002
-[P]- Yavanna Kementari as a new Vala, protectress of nature. Along with her
- priests, the Druids
-
-21/10/2002
-[m]- Updated symbiant helpfiles including full list of their new bookless spells
- in m_symbio.txt -- fearoffours
-
-23/10/2002
-[I]- Recording cmovies is now working on a microsecond timeframe, much better looking
- Let's just hope that silly systems know gettimeofday()
-
-26/10/2002
-[m]- Introduced a performance measure for process_world_hook, which I suspect
- is causing slow movement problems in the reduced map mode. Please read
- the comment in process_world() [in dungeon.c] for alternative solutions.
- -- pelpel
-
-27/10/2002
-[m]- Changed every instance of "essense" to the correctly-spelled "essence".
- Update your macros. -- neil
-[M]- Changed "The Balrog of Moria" to "Durin's Bane". Less of a mouthful, and more
- in-theme -- fearoffours
-[M]- added the "spirits". They are the inhabitants of the void. They're nasty.
- -- fearoffours
-
-28/10/2002
-[P]- Typo in Druid description: Kemenari -> Kementari. --fearoffours
-[B]- Fixed bug where ironman_rooms would give you the number of random quests
- you played last time, instead of zero. -- neil
-
-29/10/2002
-[D]- Added SPIRIT flag to The Void, so that Spirits are actually generated there now
- -- fearoffours
-
-02/11/2002
-[P]- Subraces can now have skill mods
-[P]- Spells bound to two or more schools now require at least one point in
- each of the schools to be used
-[m]- Trimmed down the size of chardumps(removed uselessness from object
- descriptions)
-
-05/11/2002
-[I]- Obvious object flags will show up when 'I'nspecting items when they are
- only identified(no more need for *id*). Obvious flags are like acid
- resisatnce on an armor of resist acid and such
-
-06/11/2002
-[P]- New skill, Stunning-blows, a haftedmastery subskill, just like critical
- hits is a subskill of swordmasery. It requires a hafted weapon > 5 lb
-[O]- Activations are now a_info/k_info/e_info definable with a: lines
- You can do a:HARDCORE=NAME where NAME is an activation name
- that is hardcoded in the C source.
- Or a:SPELL=Name where Name is a "spell" name as defined in the unified
- spell system(the first defined spell(index 0) cannot be used this way
-
-07/11/2002
-[B]- Allow non-artifact, non-ego items with activations be activated. -- neil
-[I]- Cause of death is now shown in chardumps
-
-08/11/2002
-[m]- Added descriptions to Totems, removed redundant need to identify them.
- -- neil
-[G]- Yavanna's followers now have a God quest. -- fearoffours
-[m]- Help docs for Yavanna and Druids, thanks Mef and Massimiliano Marangio.
- -- fearoffours
-
-09/11/2002
-[M]- Only gain exp from pet kills, not from every monsters, when using Monster
- Lore skill
-
-10/11/2002
-[m]- Yes, more help updates. In tome_faq.txt and TANG.txt I added links to
- skills.txt, magic.txt, birth.txt and gods.txt where appropriate. Removed
- two references to Pern that got missed in tome_faq.txt.Added a
- c_priest.txt file for contextual help at birth when choosing a main class.
- Corrected typo in r_info (SPirit became Spirit). -- fearoffours
-
-11/11/2002
-[I]- CTRL+] to save an html screenshot anytime(ie: to preserve the current
- message)
-[P]- Necromancers start with corpse preservation skill
-
-13/11/2002
-[B]- Don't let the Maggot sling be generated randomly. -- neil
-
-15/11/2002
-[m]- Added a new TERM_XTRA call, TERM_XTRA_GET_DELAY which should return the
- time in microseconds. What time exactly isnt meaningfull but it must be
- usable to compute the length of time an action takes.
-[I]- Thanks to the new TERM_XTRA_GET_DELAY the cmovie code is now cleaner
- and should work fine:) Windows and unix platforms should now be able
- of microsecond resolution cmovies!
-[m]- Made all the socket code into z-sock.[ch] and wrapped it into a
- virtualizing layer so that the rest of the code can use it independantly
- of the implementation. Currently unix and windows sockets are supported.
-
-16/11/2002
-[B]- Prevent the automatizer from treating "good" bows as "average" -- neil
-[B]- Prevent earthquake damage for characters with wraithform, and prevent
- some of the damage for characters with semi-wraithform -- neil
-[B]- Fix spelling of Book of Teleportation -- neil
-
-17/11/2002
-[P]- New Meta/Conveyance Spell: Tracker, it will track the last teleportation
- that happened on the level and teleport you to its destination
-
-18/11/2002
-[G]- The Old Mage in Lothlorien will now fireproof staves or scrolls as well as
- books, making it profitable for non-spellcasters. Currently he has enough
- errr 'fireproofing material' for 3 books or 4 staves or 12 scrolls, or a
- combination of these. Check fireprof.lua for the code. -- fearoffours
-[I]- Skills that have sub-skills in which you do not (and cannot) have points
- no longer display the redundant +/- sign. thanks lemming for the code.
- -- fearoffours
-[m]- Lots and lots of itsy-witsy help file updates. Stunning-blows, other
- references to Pern, more links to other files... -- fearoffours
-
-19/11/2002
-[m]- Compress the grid in the character dump, eliminating blank lines and only
- showing lines without '+'s for the resistances and sustains page -- neil
-[m]- Show the Mathom-house contents in the character dump -- neil
-
-21/11/2002
-[O]- When 'I'nspecting objects you'll know how you found them
-[B]- Magelock cannot override permanent walls(or walls for taht matter) and works
- only in LOS
-
-22/11/2002
-[O]- 3 new artifacts of Gothmog, regrouped in an item set
-[m]- Cleaned up the notes code a little. (takkaria)
-[P]- Summon skill doesnt caerte drops for partial summons
-[P]- Summon skill doesnt work in an antimagic field
-
-23/11/2002
-[B]- Automatizer should not treat enchanted ammo and tools as average, either.
- -- neil
-[B]- Fixed the bug that allowed to use unallowed gods
-[P]- Lost souls start with many satisfy hunger scrolls, I'm really too nice...
-[M]- Themed townspeople! In Lothlorien and GOndolin you find elven people and
- dwarven in Khazad-dum
-
-24/11/2002
-[m]- Display in the dump how interesting items were found -- neil
-[B]- Two-handed artifact weapons now act as such -- neil
-[O]- Darksword antimagic field now scales on the antimagic skill
- So using one with 0 in the skill is not worth much
-[m]- DESTDIR support in makefile.std -- neil
-
-25/11/2002
-[B]- Don't mark items as store bought until they are bought -- neil
-[O]- Distinguish stolen items from bought items -- neil
-[m]- main-net.c display module which redirects display over the z-sock layer
- and thus over any ip network to allow to create very lightweight terminals
- to play ToME everywhere. This is still experimental
-[B]- Don't show Gondolin twice in the dump -- neil
-[O]- Cut down the price of Spectral weapon given their .. usefullness
-[I]- Fixed the bug that told you you could buy more items than you really could.
- At least when using auto_haggle. Poor sods that dont use it shall burn
- in hell
-[I]- Damage info is displayed for items that are only identified
-
-26/11/2002
-[G]- OK the god quest is a little easier now, as you're told the dungeon is to
- the north/south and east/west of you. -- fearoffours
-[G]- Having autosquelch on will now not affect the essence in the fireproof
- quest. And the mage gives a warning about the fact it may be easy to
- destroy it too. -- fearoffours
-[B]- Fixed the incredible townspeople generation rate
-[B]- String fixes from lemming -- neil
-[B]- Don't print discomfort messages when examining and comparing weapons -- neil
-[I]- new <state> function to the automatizer to detect identified state
-[I]- Automatizer rules are automatically apply upon exit of the screen or
- autogeneration of a rule with the 'k' command
-
-28/11/2002
-[B]- Add experimental support to the automatizer for marking "bad" rings and
- amulets -- neil
-[m]- Distinguish average, disarmed, and empty chests in the automatizer -- neil
-[B]- Let summoners summon again (patch by masmarangio) -- neil
-[B]- Remove duplicate warning of an empty quiver (patch by masmarangio) -- neil
-
-29/11/2002
-[O]- Let Demonshields and Demonhorns be treated as armor -- neil
-[m]- Can include string terminators in help file tags i.e:
- *****foo.txt*7[see:\] it works;)]
-[m]- Can save screenshots to help file format, this is only usefull to
- documentation writters and thus the option only appears when wizard mode
- is activated. It uses the new verbatim mode &&&&& at the line beginning
-
-01/12/2002
-[m]- The helpfile typo corrections just keep coming! Added Udun school help,
- and demonologist school help, thanks Mef and masmarangio. -- fearoffours
-[m]- Some more spelling errors corrected. Updated warriors skills in the
- help files -- masmarangio
-
-02/12/2002
-[m]- Skill updates for more character classes in the help files. -- masmarangio
-[m]- Automatizer tutorial added. -- fearoffours
-[G]- God quest relic is now inscribed to prevent automatizer 'accidents'
- -- fearoffours
-
-02/12/2002
-[O]- Wands/staves are now described this way: a wand of foo[bonus|max]
- Bonus is the bonus spell levels you get, and max is the limit of spell
- levels for that wand. It means even if you have Magic Device at level 50
- you cannot get a level 50 spell from a wand with max 30. Naturally the
- max(and bonus) increase with the depth you find the wand/staff :)
-[P]- Players in monster form can now use barehanded combat, instead of
- reverting to monster attacks. -- neil
-[O]- Fix and reduce the wand and staff pricing -- neil
-[B]- Make the automatizer work independently of the player's body -- neil
-
-03/12/2002
-[m]- Clean out some unused variables and some other valid warnings -- neil
-[B]- Don't spoil things in the dump -- neil
-
-04/12/2002
-[m]- Updates of the character races help files -- masmarangio
-
-05/12/2002
-[B]- Maiar can't choose a god anymore -- masmarangio
-[I]- Added a message if you don't have powers but press 'U' -- masmarangio
-
-06/12/2002
-[B]- Staves are properly fireproofed now. -- fearoffours
-[m]- God quest gets more clues to the location, and they're printed in the
- 'Ctrl-Q'uest screen. I'm too nice. -- fearoffours
-
-07/12/2002
-[I]- Added the extended command #quest (or #Q for short) to get quest list
- because some prts catch the CTRL+Q combo
-[m]- Added contextual help for wands/staves, also added a section in the help
- about it. --fearoffours
-[m]- Some small help file updates (Muar becomes Durin's Bane) -- masmarangio
-[m]- Added full mindcrafting spell info in the same form as other schools of
- magic. Removed help on the Music skill, as this will not be included for
- 2.1.0. Added some other help stuff. -- fearoffours
-
-08/12/2002
-[B]- Correct Damage/Round display for bare and bear combat. -- neil
-[m]- Help now has an alphabetical index! -- fearoffours
-[B]- Melkor wants you to sacrifice corpses, not raw meat -- neil
-
-09/12/2002
-[B]- Fixed an off-by-one error in loadsave.c that caused savefile corruption
- if the number of monsters or objects saved was maximal -- masmarangio
-[m]- Removed help on the Druidistic skill since Druids are normal Priests now.
- Minor changes to the skill example to match human warriors.
- Updated Option help file, some other minor changes -- masmarangio
-[O]- Allow Wooden Rods to be sold at the Magic Shop -- neil
-
-10/12/2002
-[B]- Corrected the price of enchanted boomerangs and instruments. -- masmarangio
-[B]- Corrected the used multiplier while 'I'nspecting ammo.
- Fixed the damage of throwing items / boomerangs -- masmarangio
-
-11/12/2002
-[I]- 'Compare weapons' works only with melee weapons, item selection changed.
- Expanded the description of a god at birth. -- masmarangio
-
-12/12/2002
-[m]- Removed Tank Points and firestones. -- neil
-[m]- Removed PERNANGBAND monster flag and renamed as many Pern monsters,
- artifacts, and other references as I could find -- neil
-[M]- Firebirds (formerly firelizards) and Thunderlords are B, not d and D
- -- neil
-[B]- Fix some artifact activations -- neil
-[B]- Fixed (temporarily) item activation and description. Some items could
- activate for the unified activation, and display the other activation, so
- further changes are needed. -- masmarangio
-[I]- Removed the silly 'You are shooting with a flute' message. -- masmarangio
-
-13/12/2002
-[m]- Renamed instruments in luckspoi.txt, comment changes -- masmarangio
-[I]- Added OBJ_FOUND_SELFMADE for items that were created by the player.
- Alchemist should also use it (not changed yet). Replaced the plain
- description "in the Town" for items fond on the surface -- masmarangio
-
-14/12/2002
-[O]- Monster traps are disarmed by GF_KILL_TRAP and GF_KILL_DOOR -- masmarangio
-[m]- The description of ACT_DEST_DOOR includes traps, better description of
- deactivating music instruments. -- masmarangio
-[M]- Increase Thunderlord rarities -- neil
-
-14/12/2002 -- T.o.M.E 2.1.0 aka "No Surrender, No Retreat"
-
-14/12/2002
-[B]- Artifact spoiler was messed up
-
-15/12/2002
-[m]- some small help files updates (Melkor, GoI, races) -- masmarangio
-[B]- some Orc Cave crashes fixed -- masmarangio
-
-16/12/2002
-[B]- Fixed the Mushroom Quest: mushrooms are taken before creating the rewards,
- and these are created even with a full inventory -- masmarangio
-[B]- Grammar fix for breathing messages -- neil
-[B]- Changed order of level feelings, removed unused feelings. -- masmarangio
-[B]- A Rod of Drain Life is needed for vampiric artifacts instead of the Wand.
- Renamed one ego light of Boldness (now of Fearlessness). -- masmarangio
-[m]- Updated and reformatted the essence spoiler. -- masmarangio
-
-18/12/2002
-[O]- Removed the double pval for Mana-items (40%)(+2). The description of
- Mana and Life items is now with percents. -- masmarangio
-[m]- Small updates to m_demono.txt -- fearoffours
-[m]- Added mindcraft in magic.txt and a paragraph in m_mindcr.txt -- masmarangio
-
-19/12/2002
-[B]- Adjusted the melee damage shown in the status screen. -- masmarangio
-[B]- Spelling errors corrected. Thanks to markrax -- masmarangio
-[B]- Fixed bashing the trigger doors in the Thieves Quest -- masmarangio
-[B]- Allow Amulets of the Magi and *Defender* weapons to be sold -- neil
-[B]- Fix alchemist creation of ego staves, etc. (patch from "oops") -- neil
-[B]- Don't let gold into the inventory -- neil
-[B]- Temple doesn't want unblessed edged weapons -- neil
-[B]- Properly handle obvious flags on non-*ID*d objects (fixes things like
- resistances grid and selling Blessed weapons in the temple) -- neil
-[B]- Squelch at different times, to avoid destroying the wrong items -- neil
-
-20/12/2002
-[m]- Removed some compiler warnings. Thanks to markrax -- masmarangio
-[I]- Work / fixes in spoiler creation (items, essences, menu) -- masmarangio
-[B]- Automatizer: <symbol> works with graphic modes -- masmarangio
-[B]- Fixed pval3 for artifact staves and wands in apply_magic -- masmarangio
-[m]- Corrected some typos and some comments. Thanks to markrax -- masmarangio
-[m]- Spell description edit -- neil
-[B]- Exclusive skill fix (patch by markrax) -- neil
-[B]- Yet more copyediting by markrax -- neil
-
-21/12/2002
-[m]- Corrected most of the typos found by vrak. -- masmarangio
-[B]- Fixed a display bug when passing through walls, thanks jup
-[B]- Copyediting of lib/edit/* -- markrax
-[B]- Copyediting of monster description books (lib/file/book-1[0-9].txt)
- -- markrax
-[B]- Copyediting of misc. files in lib/file/ -- markrax
-[B]- Copyediting of most files in lib/help/ -- markrax
-[B]- Copyediting and description tweaks to tables.c -- markrax
-[B]- More minor copyediting -- markrax
-[m]- Minor externs.h code cleanup, remove dups -- markrax
-[B]- Let keypad 5 key work in X11 target -- markrax
-[I]- Add columns, tweak UI in character info sheet -- markrax
-[I]- Updated the artifact spoiler creation -- masmarangio
-[m]- Corrected some errors in a_info.txt -- masmarangio
-[B]- Display the arm slot when not wearing a two-handed weapon -- neil
-[I]- Cleaned up some code in the character info sheet -- masmarangio
-[B]- Fix drop message for junk artifacts (patch by jup) -- neil
-
-22/12/2002
-[m]- Copyediting of lib/edit/k_info.txt -- markrax
-[m]- Copyediting of lib/edit/al_info.txt -- markrax
-[m]- Added ENGLISH.txt file with ToME textual conventions -- markrax
-[m]- Standardized on "Middle-earth" spelling -- markrax
-[m]- More grammatical fixes (mostly "it's") -- markrax
-[m]- Removal of many Americanisms, grammatical fixes -- markrax
-[O]- Centered Map around Minas Anor -- masmarangio
-[I]- Allowed the user to abort when asked to engrave on a grid. Also, don't
- let the player engrave on a grid with no mana. Thanks to Pav of
- angband.~.cz for this patch. -- takkaria
-[m]- Updated and relocated style guide -- markrax
-[O]- CURSED two items with HEAVY_CURSE, thanks jup -- markrax
-[O]- CURSED Ring of Durin (had HEAVY_CURSE), thanks jup -- markrax
-[B]- Let *Identify* of your pack work the same as an individual *Identify*
- for the purposes of alchemists -- neil
-
-23/12/2002
-[I]- Updated the broken spell spoiler creation (works for the bookless powers).
- LUA schools should be added -- masmarangio
-[m]- Parchment titles capitalised. Spacing of artifacts and some americanisms
- and errors in a_info.txt, tables.c, and other files corrected.
- -- masmarangio
-
-24/12/2002
-[O]- Added description from Sangband to the Shield of Gil-Galad -- masmarangio
-[B]- tried to prevent printing of alchemy items in spell spoiler -- masmarangio
-[B]- Fixed two alchemy bugs: Same sval for Rings of Critical Hits and the Ring
- of Durin. Corrected the sval of Rings of Constitution -- masmarangio
-
-25/12/2002 - Mery xmass!
-[P]- Boulder throwing skill :) For Ents .. Don't get used to it as I don't know
- if I'll let it in
-[B]- Destruction cannot kill quest monsters
-[B]- The lost temple (god quest) dungeon really cannot be generated in
- inaccessible places now. -- fearoffours
-[I]- Unidentified objects are marked in slate(the inventory letter)
-
-26/12/2002
-[m]- Updated the skill gain in skills.txt, corrected some spelling errors.
- Added Boulder-throwing to the help files -- masmarangio
-
-27/12/2002
-[B]- Fixed note file problem under windows -- masmarangio
-[m]- Corrected some americanisms and spelling errors -- masmarangio
-[B]- Fixed an alchemy error with fireproofed staves, removed tabs from c_prt
- calls -- masmarangio
-
-28/12/2002
-[P]- Added dynamic subrace. This means that "things" in the game can somewhat
- change your subrace. This is used by the 3 new Vampire corruptions, which
- when combined will permanently turn you into a full blown Vampire.
- The Vampire subrace has been removed, it might come back as a template for
- the corruptions, or not. All others undead subrace will have the same
- fate. This means that soon you'll be able to turn into an undead rather
- than start as one. The penalties will be tweaked too so we don't end up
- with every char being an undead.
-[B]- Fixed a branding bug that allowed to modify artifacts and ego-items.
- -- Kusunose
-[m]- Updated corruption_spoiler_generation (includes index tags, don't show the
- Lose message for not removable corruptions) and corspoil.txt -- masmarangio
-
-29/12/2002
-[I]- Stores/homes inventory letters are colored just like inventory/equipment
- thanks to Pav
-[m]- Music system performance improvement -- neil
-[m]- Added help on pets to dungeon.txt and some clarification about Spell-power
- affecting only the 11 primary schools of magic. -- fearoffours
-[m]- Added to Spell-power the other affected Schools (Udun, Demonology, Gods),
- as well as naming Sorcery in the Udun School help file -- masmarangio
-
-30/12/2002
-[O]- init1.c: added two times OBJ_FOUND_SPECIAL -- masmarangio
-[m]- al_info.txt: removed double acid essences in amulet of resistance, grouped
- entries for ring of extra attacks, renamed some entries -- masmarangio
-[m]- wizard1.c: Added IS_CVS to header, create artifacts at 25, not 35, added
- index in Essence Spoiler. essences.txt: new spoiler file -- masmarangio
-[m]- cmd1.c: removed a compiler warning. caves.c: simplified a test -- masmarangio
-[m]- Info on spell-power and multi-school-spell interaction, typo fix in
- m_mindcr.txt -- fearoffours
-
-31/12/2002
-[B]- object2.c: Initialised Artifacts with LEVELS in apply_magic -- masmarangio
-[O]- generate.c: OBJ_FOUND_MONSTER for final artifacts / objects -- masmarangio
-[B]- al_info.txt: Svals of Ring of Sustain Con and Dex exchanged -- masmarangio
-
-01/01/2003 - Happy new year !!!
-[B]- store.c: Fixed bug with prices of wands, indentation -- masmarangio
-[I]- Better fountain command interface. -- Kusunose
-[B]- al_info.txt: Added Ammo of slay animal. Amulet of regeneration with new
- sval. Ego Weapons of Life added -- masmarangio
-
-02/01/2003
-[B]- find_ignore_stairs, set or unset, failed to handle some quest related
- stairs properly. -- pelpel
-[B]- cmd7.c: Fixed bug with TR4_ART_EXP not set correctly -- masmarangio
-[O]- cmd7.c: Added OBJ_FOUND_SELFMADE for created items/artifacts -- masmarangio
-[B]- Don't allow a change from weapon combat if a cursed weapon is wielded
- -- neil
-[m]- wizard1.c: Changed position of IS_CVS, added double ego items in essence
- spoiler. essences.txt: reflects this -- masmarangio
-
-03/01/2003
-[B]- wizard2.c: Some bound checks to prevent crashes -- masmarangio
-[B]- cmd7.c: Fixed reduced capacity of ego rods -- masmarangio
-[B]- object1.c: Added a "It cannot be destroyed" msg in place of "it has blah%
- chance of breaking upon hit" for artifact ammo. thanks lemming for fix
- -- fearoffours
-
-04/01/2003
-[O]- e_info.txt: Added indestructible and cursed amulets to simplify alchemy
- -- masmarangio
-[B]- cmd7.c: Allow creation of artifacts from single ego items; don't change
- artifacts and double ego items if you don't wish to create an artifact.
- Simplified amulet handling and other code fragments -- masmarangio
-[m]- QUITING-> QUITTING, COMBINAISON->COMBINATION: two cases of typos
- that I've long been aware of... -- pelpel
-[D]- Changed the marker(#172) to look like open floor(#1) -- masmarangio
-[B]- Updated Amulets and Rings in defines.h / defines.txt -- masmarangio
-[B]- al_info.txt: Amulet of Adornment without pval. cmd7.c: skill >= 25
- needed to create artifacts, not > 25 -- masmarangio
-[B]- Warning about leaving a trap detected zone don't cost energy -- masmarangio
-
-05/01/2003
-[m]- First update of commands.txt -- masmarangio
-[B]- spells2.c, self_knowledge(): f4 through esp were not initialised before
- referenced. -- pelpel
-[B]- cmd7.c, extern.h: changed the variable "tocreate" in alchemist_items_check()
- from bool to int -- masmarangio
-[B]- xtra1.c, apply_flags(): Added bounds checks for antimagic. -- pelpel
-[B]- xtra1.c, apply_flags(): changed the type of bit field variables from s32b
- to u32b, for obvious reasons. -- pelpel
-[G]- Princess now offer 3 reward and the player selects one
-
-06/01/2003
-[B]- cmd7.c: Fixing three bugs in Alchemy: Extracting from double ego items and
- from stacks of staves, as well as generating all leeched empty items.
- Problems may still arise when you leech a stack of objects from the floor
- and essences get dropped over them. Boomerangs can be enchanted now.
- -- masmarangio
-[B]- generate.c: Moved the room creating loop (fix from 15/12). Something better
- should be used than this brute force method -- masmarangio
-[B]- Minor spelling and grammar fix -- neil
-[B]- Changed the type of dungeon_flags to u32b, as in types.h -- masmarangio
-[B]- cmd7.c: Instruments can be enchanted now. -- masmarangio
-[G]- Applied the Artifact Activation patch -- masmarangio
-[B]- Fix activations -- neil
-[G]- Alchemists can no longer make artifacts granting Precognition or Immunity
- to Nether -- neil
-[B]- Avoid some bad periods in monster descriptions -- neil
-
-07/01/2003
-[P]- p_info.txt: Updated, compacted history-chart. Trolls, Orcs, Elves with new
- entries, some other small changes. Deleted the unused races -- masmarangio
-[m]- Added Activations to essence spoiler, new help file created -- masmarangio
-[B]- Reset the pval of extracted rings and amulets, prevent creation of cursed
- empty items -- masmarangio
-[B]- Make ego staves / wands of nothing extractable, disallow empowering of ego
- items / artifacts that are not wearable (e.g. staves) -- masmarangio
-
-08/01/2003
-[I]- squeltch.c: Ask for overwriting rules file and display saving message in the
- same box -- masmarangio
-
-10/01/2003
-[m]- Added a (conservative and preliminary) port to OS X + gcc + makefile.
- The four *.icns files are faithful conversions of the traditional Angband
- icons that have long been used by Mac ports, even before Ben.
- makefile.std itself is not updated. Please read comments in main-crb.c.
- -- pelpel
-[m]- Module support. It means that people can write ToME "modules" which will
- go in lib/mods and contain "variants" that use the same game engine but
- different lib/foo files. The module selection screen only appears when
- the game detects more than one module. The new -Mfoo command line option
- allows to bypass module selection
-[m]- 'Death' Message of a Nazgul: Choose pronoun 'she' or 'he' according to the
- sex -- masmarangio
-[G]- God quest wont trigger for Lost Souls until they reach the surface
-[m]- Turn off some ToME things when using a non-ToME module -- neil
-[B]- Fix the monster description messages even better -- neil
-[B]- Better honor the NO_TARGET flag -- neil
-[M]- Give Farmer Maggot the NO_TARGET flag -- neil
-[B]- Fixed (hopefully) the wrong activation bug -- masmarangio
-[m]- (Mac, Carbon) Modernised file system interface (currently only turned on
- for Mach-O Carbon port), improved Mach-O Carbon support, incorporated my
- 32x32 tiles support code for V3.0.2, and more gcc porting note -- pelpel
-[m]- Let the player see which game module he selected in the character
- selection screen -- neil
-
-11/01/2003
-[B]- Fixed one wrong sval in al_info.txt -- masmarangio
-[m]- Added makefile and some auxiliary files for developer CD gcc compilation
- of Carbon port -- pelpel
-[m]- (OS X Carbon) Changed the format of graphics tiles from PICT in the
- resource fork to plain PNG files, only for gcc compilation at the moment
- -- pelpel
-
-12/01/2003
-[B]- Alchemy: The song of music instruments, the type of explosive ammo and
- the level of sticks are not changed by enchanting / leeching the items.
- -- masmarangio
-[m]- Expanded the description of Antimagic, small index updates -- masmarangio
-[I]- wizard2.c: Initialised the lua command (^A >) with the help file index
- generation -- masmarangio
-[m]- (OS X Carbon) Cleaned up my recent updates. It's fairly stable now.
- To do: move to .nib based menu/dialogues, pulling sound out of resource
- fork, and better sound code. -- pelpel
-[B]- cmd7.c: Allow extraction of the charges of Sticks of Plenty -- masmarangio
-
-13/01/2003
-[m]- preliminary SCANDIR support for gcu, gtk, xaw borrowed from x11 -- neil
-
-14/01/2003
-[m]- Modules can control the number of levels over the player level a skill
- may have allocated now, using max_skill_overage. -- neil
-[m]- HOOK_FIRE added -- neil
-[m]- Changed the help files about vampires; classes, races etc. are listed
- in alphabetical order in birth.txt -- masmarangio
-[m]- Races & subraces get a starting object list in p_info, less hacks in birth.c
-[I]- Automatizer can now be used to auto-inscribe items, thanks to jepler
-[I]- Automatizer can now display rules in a more english like maner, xml mode
- is also available, switch by pressing 'x', thanks to jepler
-
-15/01/2003
-[G]- Summoner can extract totems from skeletons / carapaces. -- masmarangio
-[B]- Trap of Wasting Wands (affects also Staves) change the Wand/Staff to the of
- nothing type. Deleted SV_WAND(STAFF)_NASTY_WAND(STAFF), since in the new
- stick system the worthless sticks don't have the first svals -- masmarangio
-[B]- Fixed a fountain filling bug, simplified the item_tester -- masmarangio
-
-16/01/2003
-[B]- (Mac, OS X) Tilewidth/height code ceased to work because menu API started
- to return Unicode crap instead of holy ASCII -- pelpel
-
-17/01/2003
-[m]- HOOK_EAT added -- neil
-[O]- New artifact: The Sling of the Thain -- neil
-
-18/01/2003
-[B]- empty chests are generated as known (i.e. they were opened) -- masmarangio
-[B]- do_cmd_rest flushes input if the player can't do so for some reasons
- and flush_failure is set.
- Note: flush() doesn't seem to work as it used to do... Any changes have
- been made to inkey, or some code touches its various control variables?
- -- pelpel
-[m]- (Gtk) Added support for the "bigtile" mode. Please start the game with
- "tome -- -w" if you don't like to see horrible glitches... This is not
- Gtk-specific problem by the way. Scrolling the map and hitting ^R fixes
- it too, if you prefer menu command -- pelpel
-[G]- Trees are now passable by wraith beings. Monsters that fly will pass trees.
- Dead small trees will be dead small trees. Monsters tunneling will also
- destroy trees
-[P]- Extra HP bonus(from quest, melkor, ...) is applied before sorcery penality
-
-19/01/2003
-[B]- (Gtk) Fixed problems with wide tile mode when it is used with backing
- store. Seems more like the problem is in z-term (it only updates every
- two columns of the dungeon map...), but it works now -- pelpel
-[B]- (Mac) The asynchronous sound player unlocked and released sound data
- without confirming its completion. Wrote an alternative implementation
- that holds data until a channel it is played is reused, to avoid using
- interrupt-time code (which is quite complicated business in 68K).
- Because this means that a fairly large amount of data can be locked in
- memory for a long time, I reduced number of channels used to
- 4 in Classic and 8 for Carbon -- pelpel
-
-20/01/2003
-[G]- Trees/grass can only grow one some terrains(yes that DO exclude lava;)
-[I]- z) slot is hidden until needed -- thanks to Scott Bigham
-[I]- Some cosmetic changes and improvements to char dumps -- thanks to Scott Bigham
-
-21/01/2003
-[B]- Monster traps: Changed the code so that the new wands and staves are
- functional in device monster traps. This is commented out with #if 0 since
- the code must be tested. Perhaps a lua solution is better ? -- masmarangio
-
-22/01/2003
-[B]- Deathmolds could use their racial power without spending a turn!
-[B]- 'U' powers didn't remove Disruption Shield
-[m]- (Mac, Windows) Added an in-game menu command to view current scoreboard.
- Taken from the latest [V] (Win port only there), minus the use of
- display_scores_aux, which I regard first-degree Mega-Hack -- pelpel
-[G]- Wielding the One Ring now has real disadvantages, you've been warned :)
- What ? I didn't mention what disadvantages ? Oh yes, I didn't.
-[G]- Bump required level and difficulty rating of Minas Anor quest, as the
- trees changes have made it just a little harder. -- neil
-
-23/01/2003
-[I]- Hopeless attempts to dig will be noticed to the player -- thanks to jepler
-[B]- Potions of Cure Water are no more extractable by Alchemy
-
-25/01/2003
-[P]- Bard class is back(was called Harper before) with a new Music skill.
- Instruments carries the spells, and they work a bit like Psi foci in
- psiband. An instrument (+2) can only play songs that are marked (I) or
- (II) not (III) or (IV)
-[B]- Ordered the music songs according to the needed pval, then level.
- Fixed the svals of artifact instruments, changing the Flute to a Harp.
- Added a better description of Bards. Please check it ! -- masmarangio
-
-26/01/2003
-[B]- An Alchemist can now fireproof spellbooks -- masmarangio
-[m]- Bard and Music docs are done. Please check em. -- fearoffours
-[B]- A possessor (the creature, not the class) can only possess whole
- corpses and skeletons, not pieces of meat -- masmarangio
-
-27/01/2003
-[B]- Make wielding more than one demonshield (or demonsword I suppose) work
- -- neil
-
-28/01/2003
-[B]- Possession something while encumbered to the point of having 0 mana
- allowed free use of body spells without failure
-[P]- Mana is now function of the Magic skill and either INT or WIS, whichever
- is higher
-
-30/01/2003
-[B]- Possibly the relic in the god quest couldn't have been generated.
- Wasn't me honest guv. -- fearoffours
-[G]- The lost temples for god quests now have harder monsters to make the piety
- gain rather more substantial and obvious I hope. Deeper monsters appear
- as player clvl increases. -- fearoffours
-[m]- Help file corrections on Music skill. -- fearoffours
-
-01/02/2003
-[B]- Some menus exits when 'e' was hit on some comapilation.
- Note: '\e' for escape is compiler dependant extension so do not
- use it. Thanks kobayasi for fix. -- Kusunose
-[B]- All known staves and wands are displayed as 'Globe of Light' in
- the Known Object list. Thanks kobayasi for fix. -- Kusunose
-
-08/02/2003
-[m]- Make HOOK_QUAFF take an o_ptr, and let HOOK_EAT return the identify success
- -- neil
-
-12/02/2003
-[I]- Useless but fun, when a wield monster takes damage instead of you
- the monster will be named. If you named it(with the #foo inscription)
-
-16/02/2003
-[B]- Chaging the melee style did not update bonuses. Thanks to kobayasi for
- the patch. -- Kusunose
-[B]- <sval> in automatizer worked even when the player was not aware of
- the object. It was possible to use this as a free ID. Thanks to
- kobayasi for the patch. -- Kusunose
-
-24/02/2003
-[B]- Cancelling the reward skill sellection could crash the game. -- Kusunose
-
-26/02/2003
-[I]- Boomerangs now display damage with 'I'nspecting, thanks to Scott Bigham
-
-27/02/2003
-[B]- Inspecting or Identifying something shouldn't infect you with the
- Black Breath -- neil
-
-28/02/2003
-[I]- Genocide and genocide like effects that require monster race now allow
- targetting of a monster to select the race. Gfx users can now correctly
- genocide :)
-
-01/03/2003
-[I]- d/s and g/p work in both home & stores. Pfft.
-
-02/03/2003
-[m]- Fixed a typo in The Dragon Helm of Turin Turambar -- WeZ
-[G]- Fixed the teleport-level ability of Deathmolds, so they
- can teleport out of a dungeon, instead of getting a
- message saying there's only air above them. -- WeZ
-
-04/03/2003
-[P]- Probability travel level teleport ability & teleport level spells
- wont work in some dungeon
-
-05/03/2003
-[G]- A new quest! An ultra ending! "Falling Toward Apotheosis"
- After banning Morgoth spirit in the Void, you can pursue him
- there to forever end the darkness. But beware, it is more than
- likely that you will die. But for the few that succeed, the fame
- will be great!
- Note: you can only do it if you choosed the way of Good and thus
- destroyed the One Ring. An evil ultra ending is planned and will
- come a bit latter.
-
-06/03/2003
-[P]- Dwarves get a bonus to axe mastery, as they rightfully should
-[O]- Cloak of Air. Generates an air bubble around you so you can breath.
- Just in case you need it ..
-
-08/03/2003
-[G]- Another new quest! An old mage in Minas Anor needs help, too. -- neil
-
-12/03/2003
-[B]- Non-enemy monsters now won't hold up victory in the Spiders and Library
- quests. -- neil
-[B]- Various Library quest fixes -- neil
-
-13/03/2003
-[O]- Lebohaum activation is now true to the original material..
-[P]- All mages start with 0.1 less mod to Sorcery. Specialists dont have sorcery.
- Runecrafters dont iether, nor Alchemists. Thaumaturgists do.
- Specialists also get a bit better Spell-power
-
-16/03/2003
-[I]- Only show enemies in the uniques list -- neil
-
-20/03/2003
-[m]- The various ?_info.txt files can now include otehr files with the <:file.txt
- command. This allows people to split up too big files
-
-23/03/2003
-[I]- X11 port can now do text selection copy&paste with the mouse, thanks to kieron
-
-27/03/2003
-[B]- Mage staves, rod tips, and magic tomes are now "good" items. This should
- fix the problem of Saruman, Sauron, and others dropping nothing but rods.
- -- neil
-
-28/03/2003
-[I]- Show "ironman_rooms" setting in the character dump -- neil
-
-29/03/2003
-[P]- The adventurer quest skill reward will now only provide a modifier of 0.3
- if you dont have the skill, but if you have it it will improve the modifier
- by 0.1 if it is below 0.5
-[I]- Automatizer rules now have an module attribute, defaulting to "ToME". The
- module name is case sensitive, as always. <rule module="ToME" name="Die"
- type="destroy"> will only destroy items when you're playing the ToME
- module. -- neil
-
-02/04/2003
-[B]- Fix grammar error pointed out by "JanaRaissa" -- neil
-[B]- Prevent instrument-wielders from firing things, as pointed out by
- "Chudus" -- neil
-[B]- Those who can breathe water or don't need to breathe at all should not
- drown in pools of water, as pointed out by "Zonk" -- neil
-[B]- Fix Rods of Simplicity for those who need it most, as pointed out by
- "Zizzo" -- neil
-
-03/04/2003
-[O]- Dragon Scale Mail now has more options for egos and random artifacts
- -- neil
-
-04/04/2003
-[B]- Fix god quest temple placement error pointed out by "Fringe Worthy"
- -- neil
-
-05/04/2003
-[I]- Somewhat nicer char screen, thanks to lemmings(I think ;)
-[B]- No more (broken) pattern vaults -- neil
-
-08/04/2003
-[m]- Ability to add timers in lua
-[B]- Fix spelling: PARCHEMENT -> PARCHMENT. Automatizer rules and other scripts
- that use PARCHEMENT will still work, though. -- neil
-
-09/04/2003
-[M]- Companions and pet uniques can now be killed
-
-11/04/2003
-[P]- Trolls cannot get the troll blood corruption
-[P]- At Monster lore skill level 12 one can turn a pet in a loyal companion.
- Note that you are limited in companion number
-[P]- Reduced Necromancy spell failure damage
-
-12/04/2003
-[P]- Skill multipliers of Rogues and Assassins are higher now. -- neil
-[B]- Fixed alchemy making of xtra shots/might
-[P]- Some skills have more chances to be taugth than others by fumblefinger
-
-13/04/2003
-[P]- Melkor Curse spell autocast chance formula changed
-[O]- Wishing for dual ego items works
-
-14/04/2003
-[P]- Spellbinder spell will reveal more info about itself when cast while
- already active
-[P]- Increase Mage's Weaponmastery Multiplier by 0.1 -- neil
-[P]- Experimentally double Barehanded Combat martial arts damage dice
- to make Monks more attractive -- neil
-
-16/04/2003
-[O]- Goods stolen from stores now get a 100% discount. -- neil
-[P]- One can now steal from more places -- neil
-
-17/04/2003
-[B]- Everburning torches, Feanorian Lanterns, and Dwarven Lanterns of Fading
- couldn't be filled -- neil
-[B]- The Crumpled Scroll of Mass Resurrection no longer revives special
- monsters who won't ever appear again anyway. -- neil
-
-18/04/2003
-[B]- Gauntlets that contain spells no longer hinder spellcasters -- neil
-[I]- Some junk removed from the character resistances grid -- neil
-
-18/04/2003
-[G]- Bree house is not available from start anymore, you have to get it
- as a reward from the thieves quest
-
-20/04/2003
-[G]- The Lothlorien and Gondolin homes aren't free anymore, either -- neil
-
-21/04/2003
-[G]- The Minas Anor and Khazad-dum homes must be won, too -- neil
-
-24/04/2003
-[I]- Reworked 16x16 gfx by P_laloli@hotmail.com
-
-25/04/2003
-[B]- Fix the case where some birth items wouldn't stack -- neil
-[B]- Disarming a trap on a stair should not destroy the stair -- neil
-
-26/04/2003
-[B]- Player invisibility shouldn't hinder monsters attacking targets other
- than the player (patch by Jeff Epler) -- neil
-
-27/04/2003
-[B]- Mana and Life drains should not cause infinite rest loops -- neil
-
-28/04/2003
-[O]- Handmade items like arrows and totems are fully identified -- neil
-
-29/04/2003
-[m]- Max skills internaly increased to 200
-[G]- Random quest are now disabled when persistent dungeon levels are enabled.
- -- neil
-
-30/04/2003
-[O]- The artifact that had aggravation and a stealth bonus no longer has
- that useless stealth bonus -- neil
-[O]- It's now much harder for sentient weapons to get the Acid realm -- neil
-
-01/05/2003
-[I]- '+' command(alter terrain) wil ltry to open doors instead of tunneling
- them
-
-02/05/2003
-[P]- Shots now pierce when they used to ricochet in random directions -- neil
-[P]- Piercing shots are now togglable -- neil
-[G]- Singing happy drunks will freely accept alcoholic beverages from you.
- -- fearoffours
-[m]- Class helpfiles updated to reflect some changes in skill allocation.
- -- fearoffours
-[I]- Turned on by default the linear stats display
-[m]- Chris Hadgis submitetd the first documented package of the ToME API!
- More comming :)
-[I]- Maxxed stats now show a "!" in the character screen and dump, too -- neil
-[P]- If you play something experimental, it now shows up in the character
- dump. Alchemists and Death Molds are marked as such for now -- neil
-[P]- Necromantic magic got a new spell: Necromantic Teeth
-
-05/05/2003
-[B]- Stone Prison spell would create floor where it shouldn't, possibly
- trapping you in places like the Eol quest. -- neil
-
-06/05/2003
-[G]- Angband now blocks the magic of the Thunderlords' Nest -- neil
-[B]- Fix activation descriptions patch by Chris Hadgis -- neil
-
-09/05/2003
-[I]- ToME should try harder to use proper thematic flooring when appropriate
- -- neil
-[B]- Stone Prison should not be able to turn walls into floors. -- neil
-
-11/05/2003
-[B]- Sound effects shouldn't give knowledge the player wouldn't otherwise
- know (like the generation of the relic) -- neil
-
-12/05/2003
-[B]- Don't show silly chance to break for exploding ammo -- neil
-
-14/05/2003
-[m]- lib/patch directory to contains auto-loaded patches.
- Each patch must be contained in it's own subdirectory and
- must contain a patch.lua file with a patch_init() function in it
- that must return the patch name and version
-
-16/05/2003
-[P]- Abilities. Abilities are like skills, but are booleans. That is
- you either know them or not, there is no scale. One can learn
- abilities by spending skill points in the abilitie screen(press 'N').
- Abilities can have prerequisites to be meet before one can learn them.
- (Like some can need a stat level, a skill level, ...)
- Some classes get abilities for free at certain level. Like warriors
- will get Spread-blows ability at level 25 for free(even if they dont
- actually meet the prereqs).
-[P]- All classes now get 4 max blows. But there abilities that can increase
- the max. Warriors gets them for free at birth, and other classes also
- get some so they are not less powerful than before the change. This
- will however help people create warrior-mages for example.
-[m]- Internal change: Magic Realms are gone. -- neil
-[I]- No more spell list window flag. It hadn't done anything since ToME 2.0
- anyway -- neil
-[m]- Total savefile compatibility break. Hopefully we can do better from now
- on -- neil
-
-21/05/2003
-[I]- The player now gets warned during race/class/subrace selection that a
- class is experimental. -- neil
-
-23/05/2003
-[B]- Innate monster friendliness shoudln't take precedence over summoned pet
- or companion status -- neil
-[B]- The Helm of Knowledge and Automatizer pickup now get along -- neil
-
-26/05/2003
-[m]- Initial helpfiles update for Abilities. -- fearoffours
-
-27/05/2003
-[I]- Princess quest reward selection is not cancelable
-
-28/05/2003
-[P]- New skill: Geomancy, works in combinaison with the 4 elemental skills
- to produce various effects from the raw elements around teh caster
- (grass, sand, ...). Elementalists becomes Geomancers now.
- Thanks to Fubar Obfusco for the detailed idea
-[P]- Runecraft is not gainable from fumblefingers until it is reworked
-
-29/05/2003
-[m]- More help updates - Artifact Creation ability, plus addtions to FAQ and
- skills.txt and others. Thanks to Michael Beatty for some suggestions.
- -- fearoffours
-[I]- Autoroller now uses linear stats when requested
-[I]- Object window will now display the 'I'nspection of the last manipulated
- item
-
-30/05/2003
-[B]- Resting ignores HP or SP if a drain on HP or SP is induced by an object
-[O]- Beat down the power of randart rings yet more -- neil
-
-31/05/2003
-[m]- Geomancy help. -- fearoffours
-[O]- heavy Xbows of Siegecraft, thanks to Fang
-
-01/06/2003
-[B]- The automatic drop from wilderness should no longer be abusable. No longer
- can you hit < when you're hungry, cut, poisoned, or sensitive to light during
- the day -- neil
-[P]- Far reaching attack ability. When using a long polearm you can attack monsters
- 1 or even 2 grids away(at the cost of a reduced number of blows)
- Idea taken from Adamant
-[O]- Ingeborg S. Norden's artifact bolts added -- neil
-[P]- Trapping is now an ability instead of a skill. Rogues, but not Assassins,
- start with it -- neil
-[m]- Help updated to reflect new abilities. Deathmold question added to FAQ.
- -- fearoffours
-
-06/06/2003
-[P]- Undead Form is now an ability
-[m]- Documentation for Undead Form added. -- fearoffours
-
-08/06/2003
-[m]- Added skill tests abilities to .prf files thanks to Scott Bigham
-[B]- Thaumaturgy attacks will travel more than one grid when not targeted
- at a monster thanks to Scott Bigham
-[I]- Inscription and discount clauses for the automatizer thanks to Scott Bigham
-
-09/06/2003
-[O]- Boomerangs now have just a 1% chance to break, have their chance to hit
- improved by Boomerang-mastery, get sold in shops, and are a bit less
- rare -- neil
-
-10/06/2003
-[G]- The god quest is a (little) bit more forgiving about the direction the
- dungeon lies in, and you also get an approximation of it's distance.
- -- fearoffours
-
-11/06/2003
-[B]- Thaumaturgy spells could be too weak -- neil
-[B]- Demonologists couldn't use the Demon Summon spell -- fearoffours
-
-14/06/2003
-[P]- Thaumaturgy spell levels now range from 1-50 instead of 1-100, so now
- one won't get spells with impossible failure rates, as suggested by
- Jules Bean -- neil
-
-16/06/2003 -- T.o.M.E 2.2.0 aka "Born to the Purple"
-
-18/06/2003
-[B]- Fix manwe spell Avatar
-
-19/06/2003
-[B]- Silly silly bug in god quest fixed. -- fearoffours
-
-20/06/2003
-[B]- Mimics starts with a cloak
-[B]- Using the @ key in skill menu wont crash
-[B]- Cannot copy uncopiable spells
-[B]- Dripping Tread will put feats on the last grid, not the current one
-
-21/06/2003
-[m]- Clearer descriptions for spells which require more than one school
- -- fearoffours
-[P]- Geomancer tweaks: Geyser's mana progression now matches its damage
- progression. Geomancy now gives much larger bonuses to its child
- skills, so Geomancers are now intended to max out the elements. -- neil
-
-22/06/2003
-[B]- Potions of Cure Water are inscribed for you to prevent mishaps with
- the automatizer -- neil
-[B]- Don't let people travel with extra limbs, to prevent them losing
- weapons by mistake -- neil
-[B]- Allow hypnosis of companions, make hypnosis failure messages more
- useful - neil
-
-23/06/2003
-[m]- Mimicry help. Magic help now has it's own menu, other minor help
- updates. -- fearoffours
-
-29/06/2003
-[m]- "Investing in the <foo> skill? You might be interested in the <bar>
- ability." links in skills.txt --fearoffours
-[B]- God quest bug genuinely fixed now -- fearoffours
-[P]- Bear form will now starts at -5 speed but end at +5
-
-29/06/2003 -- T.o.M.E 2.2.1 aka "There All the Honor Lies"
-
-09/07/2003
-[B]- Prevent forbidden staves from being generated
-
-14/07/2003
-[B]- Really fix the God quest this time, we hope
-
-15/07/2003
-[m]- Mac OS X Module support
-[m]- Solaris compile workaround from Kevin W. Thomas
-
-16/07/2003
-[B]- Fix broken status in auto automatizer rules -- neil
-[m]- Valid XHTML in the HTML screenshots now -- neil
-
-17/07/2003
-[B]- HPUX support -- neil
-
-20/07/2003 -- T.o.M.E 2.2.2 aka 'And Now For a Word'
-
-20/07/2003
-[P]- No more involuntary corruptions
-
-02/08/2003
-[B]- Fixed crash on 'l'ook in rare conditions, thanks slappy0042
-[B]- Fixed inflation of ammo damage display, patch by 'Zizzo' -- neil
-
-05/08/2003
-[m]- Help updates - spectres lose hp when passing walls, thieves cannot shoot
- arrows (very well), non-geomancer mages have a 0.00 modifier to Geomancy.
- -- fearoffours
-[m]- Help updates - typo in rm_spec.txt and High-elves have good wisdom
- -- fearoffours.
-
-08/08/2003
-[B]- Tulkas piety gains now match the documentation -- jules
-
-10/08/2003
-[m]- helpfiles - Clearer geomancy skill values for non-Geomancer Mages, a note
- about effect of stealing from shops in skills.txt, and some FAQ additions
- about FF and random quests. -- fearoffours
-
-13/08/2003
-[B]- Manwe, Eru, Yavanna, and Tulkas will not yet you start following them if you
- are wearing the One -- neil
-
-24/08/2003
-[B]- Set number of charges correctly when a wand is stolen -- neil
-
-26/08/2003
-[m]- Scott Bigham's tome-autoabil.diff: Adds a new automatizer class
- <ability>, which is true when you have the given ability -- neil
-
-27/08/2003
-[m]- Riscos support thanks to Antony Sidwell
-
-30/08/2003
-[m]- Savefiles are now stores in ~/.tome/save[/modulename] on multiuser systems
-[m]- Apply patches based on those from FreeBSD ports -- neil
-
-06/09/2003
-[O]- Beaked Axes, Battle Axes and Lochaber Axes are recognized as polearms
- again. -- neil
-[O]- Misleading "polearm" description removed from non-polearm
- Quarterstaff -- neil
-
-14/09/2003
-[m]- Added help for 'repeat last command' to command.txt. -- fearoffours
-
-15/09/2003
-[B]- Fixed autopickup of ammo crash under some circumstances
-[B]- Fix monster list mimic bug
-[B]- Tree Roots incorrect bonuses fixed
-[B]- Fixed incorrect display of some skill bonuses
-
-15/09/2003 -- T.o.M.E 2.2.3 aka 'The Quality of Mercy'
-
-22/09/2003
-[B]- Detect doors and traps displays as costing 3, not 5 now. -- fearoffours
-[B]- Maeglin quest reward wording altered (saves confusion for sorcerors).
- -- fearoffours
-[I]- Adam Bolt's Tiles are now "New Tiles", as others have worked on them and
- stuff. -- fearoffours
-
-25/09/2003
-[B]- Typos in One Ring parchment and Necromancy help fixed. -- fearoffours
-
-27/09/2003
-[B]- Typos in ultra-good ending, lost-sword quest rewards and flag description
- fixed. -- fearoffours
-[O]- Restore spaces to artifact descriptions -- neil
-
-28/09/2003
-[B]- Axemasters now start with a Hatchet -- neil
-[B]- Fix "analyze monster" activation -- neil
-
-04/10/2003
-[B]- Fix library quest breakage of Melkor curses -- neil
-
-05/10/2003
-[B]- Fix failure rates for abilities in possessed bodies, patch by 'Slappy'
- -- neil
-
-06/10/2003
-[B]- Monsters detected ONLY by telepathy were not removed from visible monsters
- list after they had gone out of range. Thanks Slappy for fix. -- fearoffours
-[B]- Recharged junkarts would not always give a notification message. Thanks
- Slappy for fix. -- fearoffours
-[O]- Changed descriptions of some junkart activations. -- fearoffours
-[B]- Completion of Necromancer quest could be triggered incorrectly.
- -- fearoffours
-[D]- "The lava burns you", becomes "you move across the lava" to accomodate
- IM_FIRE and flying characters. -- fearoffours
-
-07/10/2003
-[m]- Applied Ken Dubuc's patches to parsers to make them line ending independant
-[m]- Savefiles on multiuser systems are now in HOME/.tome/2.2/save, to comply
- with the new 3.0.0 naming scheme that is coming.
- People upgrading from 2.2.x to 2.2.4 should move their savefiles there
-
-08/10/2003
-[B]- Monsters don't appear to disappear for a turn if you polymorph them -- neil
-[m]- Setting module to "all" for an automatizer rule makes the rule apply
- to all modules -- neil
-
-11/10/2003
-[B]- Flying semi-wraiths shouldn't be hurt by flying over trees -- neil
-
-13/10/2003
-[B]- Recalling to new lost temples could have crashed the game. -- fearoffours
-[B]- God quest directions could be grammatically incorrect. -- fearoffours
-
-23/10/2003
-[B]- Items containing spells should be browsable again -- neil
-[B]- Random artifact mimicry cloaks should now show up correctly -- neil
-[B]- Random artifacts that can contain spells will not come with
- Globe of Light anymore -- neil
-[B]- Certain non-random artifacts that can contain spells will not come with
- Globe of Light anymore, either -- neil
-[B]- Pack overflow/weapon disappearing bug fixed, with big thanks to Kevin
- W. Thomas for telling me where to look -- neil
-[m]- Wizard mode is now turned off at birth -- neil
-[B]- Trap of Divine Wrath would benefit you -- neil
-[B]- Blood of Life would revive necromancers in undead form -- neil
-[B]- Hostile monsters won't get free kills of friendly monsters anymore -- neil
-
-28/10/2003
-[B]- Eggs work again -- neil
-[B]- Wishing for ego rods works -- neil
-
-29/10/2003
-[B]- Temples now accept blessed boomerangs -- neil
-[O]- Non-functioning artifact instrument activations removed -- neil
-[B]- If you learn anti-magic, you stop following any Valar -- neil
-[P]- Wood Elves and Hobbits weren't getting the extra might bonuses
- they were entitled to -- neil
-[B]- typo in v_info.txt -- fearoffours
-[m]- Help updates: macros and macro recorder, dwarf racial ability, more on
- dodging, link to m_mimic.txt from skills.txt, object inventory letter
- colouring significance. -- fearoffours
-[B]- Old Mage's quest wouldn't always disappear from quest screen when fully
- rewarded. -- fearoffours
-
-30/10/2003
-[m]- Helpfiles updated to reflect that corruptions are permanent and there is
- no corrupted sub-race. --fearoffours
-
-03/11/2003
-[B]- No more shafts in certain places -- neil
-[B]- Percing shots will not grossly inflate in damage anymore -- neil
-[B]- No genocide in home quests -- neil
-
-11/11/2003
-[B]- Silent Switching can no longer take off permanently cursed items -- neil
-[B]- Fix memory error in command handling -- neil
-[B]- Hypnotizing and restoring levelled monsters now works correctly -- neil
-[B]- permanent_levels marked experimental because it is broken -- neil
-
-17/11/2003 -- T.o.M.E 2.2.4 aka 'A Bug's Life'
-
-19/11/2003
-[B]- Fix monster possessor crash -- neil
-[B]- Fix random quest skill requester -- neil
-
-20/11/2003
-[B]- Fix crash when picking up ammo into your quiver that can't be fired
- with the launcher you are wielding -- neil
-
-22/11/2003
-[B]- God quest fix -- neil
-
-24/11/2003
-[B]- Disintegrating walls should not bother Yavanna -- neil
-
-01/12/2003
-[B]- Yet another try at fixing levelled carried monsters. Their attacks
- are affected by their level now and their hitpoints are handled better.
- I should have said this for the last release, but un-hypnotize any pets
- before upgrading from 2.2.2. Otherwise compatibility is fine. -- neil
-
-05/12/2003
-[B]- Semi-wraiths should not be hurt by climbing over mountains -- neil
-
-08/12/2003
-[B]- Fixed Flame of Udun spell
-
-10/12/2003
-[B]- Diggers are not weapons and should not be displayed as such -- neil
-[O]- Some items that give damage bonuses will be more clear about it -- neil
-[M]- Drain attacks can't drain the one artifact wand, staff, or horn -- neil
-
-[V] T.o.M.E 2.2.5 aka "Death of a Bug"
-
-23/12/2003
-[B]- Prevent recall to Lost Temple before getting the quest -- neil
-
-01/01/2004
-[I]- Pressing Escape gets you out of the pet dismissal list -- neil
-
-03/01/2004
-[B]- Automatizer now accepts TV_TOTEM -- neil
-
-08/01/2004
-[m]- Helpfiles: bearform combat help, music typos, barbarian revisions.
- -- fearoffours
-[B]- Some vaults incorrectly named -- fearoffours
-
-15/01/2004
-[B]- Wight quest crash fix by 'amaurea' -- neil
-
-16/01/2004
-[B]- God choosen at random was broken -- masmarangio
-
-18/01/2004
-[B]- Typo in q_one.c (or -> of)
-
-20/01/2004
-[B]- Don't use a turn when cancelling a possessor action -- neil
-
-21/01/2004
-[B] - summon_true crashed the game with a summon skill < 1 -- masmarangio
-[B] - test_object_wish: aware status is saved and restored -- masmarangio
-
-27/01/2004
-[m] - Typos in the description of arrows, shots, bolts; punctuation in the
- mushroom quest -- masmarangio
-
-30/01/2004
-[m]- HOOK_CALC_BONUS_END hooks
-
-06/02/2004
-[m]- Helpfiles: corrected starting equipment of mindcrafters -- masmarangio
-
-07/02/2004
-[m] - Backport of old helpfile updates: no Geomancy for Alchemists and Rune-
- crafters, updated luck spoiler, corruption spoiler in crpt_aux.lua, a
- link in skills.txt, an example in automatizer.txt.
- monsters3.c: changed 'golem' to 'creature', since the Mind Steal Spell
- also allows to control a monster. -- masmarangio
-
-[m]- Typo (massage -> message) from the forum -- masmarangio
-[m]- Capitalisation in the names of junkarts -- masmarangio
-
-13/02/2004
-[m]- mindcraft_info: Corrected and expanded the info for mindcraft powers
- -- masmarangio
-[m]- Small corrections in luck spoiler, description of Manwe's Blessing and
- m_mimic.txt -- masmarangio
-
-19/02/2004
-[B]- God quest will no longer give inaccurate or misleading directions. It
- also will now give directions from two static features, and an
- approximate, relative distance from each of those points.
- -- fearoffours
-
-[V] T.o.M.E 2.2.6 "Won't Get Fooled Again"
-
-27/02/2004
-[m]- Missing space in the description of Vecna -- masmarangio
-
-12/03/2004
-[B]- Eating some corpses produced a division by 0 error -- masmarangio
-
-15/03/2004
-[B]- Wearing an item of life (-100%) reduced the mhp to 0, causing a
- division by 0 error in cave.c -- masmarangio
-
-16/03/2004
-[B]- Corrected the spell selection for monsters:
- defines.h: Added RF6_S_ANIMALS in RF6_SUMMON_MASK.
- melee2.c: Updated comments in monst_spell_monst and make_attack_spell.
- Removed the spells RF4_MULTIPLY, RF4_S_ANIMAL, RF5_SCARE from spell_attack.
- Corrected the spell numbers of RF6_TELE_AWAY and RF6_TELE_LEVEL in
- spell_escape (formerly RF6_DARKNESS and RF6_TRAPS were used).
- Corrected the spell numbers of RF6_TELE_TO, RF6_DARKNESS, RF6_TRAPS,
- RF6_FORGET in spell_annoy (formerly RF6_RAISE_DEAD, RF6_S_BUG, RF6_S_RNG
- were used).
- Added RF4_S_ANIMAL and RF6_S_ANIMALS and limited the spell number to
- 160 + 31 in spell_summon. -- masmarangio
-
-18/03/2004
-[O]- The activation of an items with the ACTIVATE_NO_WIELD flag is described
- without the line "if it is being worn. " -- masmarangio
-[B]- Barad-dur doesn't exist, it is still Mordor. Corrected god quest directions
- to reflect this. -- fearoffours
-
-20/03/2004
-[m]- Corrected some typos (mostly from the forum, thanks to Carg85)
- s_yavann.lua: spell 'grow grass' description: 'a grass' -> on grass
- q_haunted.c: cave -> building
- a_info.txt: some missing spaces in the description of artifact bolts
- corrupt.lua, corspoil.txt: 'teeth allows' -> 'teeth allow'
- k_info.txt: missing space (Golden Horn of the Thunderlords)
- s_stick.lua: 'a thunderlords' -> 'a thunderlord'
- d_info.txt: 'the the land of Rhun' -> 'the land of Rhun'
- -- masmarangio
-
-23/03/2004
-[B]- Fixed the speed of Bearform combat -- masmarangio
-[m]- Updated luck spoiler -- masmarangio
-
-26/03/2004
-[B]- Fix for Flame Imperishable from the forum -- masmarangio
-[B]- You should now receieve a message about failing the god quest at the
- correct moment, and not when in a random dungeon. -- fearoffours
-[m]- The Old Mage's quest will erase from your quest screen when fully rewarded.
- -- fearoffours
-
-29/03/2004
-[B]- Further measures taken to ensure god quest relic is created appropriately.
- -- fearoffours
-[B]- Scumming for god quests (by losing and regaining xp) is now prevented.
- -- fearoffours
-
-02/04/2004
-[m]- Backport of mostly old helpfile updates: wrong school in m_divin.txt,
- comments in spells.lua, deleted hint about shoes in r_hobbit.txt,
- ability.txt, ab_info.txt: updated Ammo-creation and Far-reaching attack,
- c_axemas.txt: starting weapon is a hatchet,
- magic.txt, skills.txt: Updated schools improved by Spell-power,
- corspoil.txt: Updated the info about permanent corruptions,
- birth.txt: removed corrupted subrace, vampires are a normal subrace,
- m_air.txt: Updated description of Noxious Cloud -- masmarangio
-
-03/04/2004
-[B]- Fixed device trapkits loaded with rods -- masmarangio
-
-05/04/2004
-[B]- Exploding ammo used in trapkits will explode after hitting a monster.
- -- masmarangio
-[m]- Corrected Alchemist, Assassin, Axemaster, Rogue helpfiles -- masmarangio
-
-08/04/2004
-[B]- Mage staves were without the WIELD_CAST flag -- masmarangio
-
-09/04/2004
-[G]- No more nuke traps -- neil
-
-21/04/2004
-[m]- skills.txt: Corrected information about Spell-power -- masmarangio
-
-02/05/2004
-[B]- Between quest crash fix, also for Thieves and Trolls quests -- masmarangio
-
-07/05/2004
-[m]- Capitalisation: Metal Boomerang, Lay of Protection.
- r_pettyd.txt: magic items -> magically enchanted items -- masmarangio
-
-08/05/2004
-[B]- god.lua: The relic could be created in a wrong position -- masmarangio
-
-09/05/2004
-[O]- object1.c: Added descriptions for SENS_FIRE (thanks to Scott Bigham)
- and IMMOVABLE, removed IM_NETHER from the resistances -- masmarangio
-
-10/05/2004
-[m]- bounty.lua: Added a period -- masmarangio
-[B]- cmd7.c: Preserve the spell stored in random spellbooks --masmarangio
-[O]- Show "to damage" and "to accuracy" messages for yet more confusing items
- -- neil
-
-11/05/2004
-[B]- xtra1.c: Lucky characters (current luck > 0) don't get death fates;
- fixed a typo in luckspoi.txt (from the forum) -- masmarangio
-[m]- spells2.c: Typo (vulerable -> vulnerable) -- masmarangio
-
-13/05/2004
-[m]- skills.txt: Fixed broken link -- masmarangio
-[B]- generate.c: Fixed arena levels by refilling the level -- masmarangio
-
-14/05/2004
-[m]- Added new help file for the debug commands -- iain_mac
-
-26/05/2004
-[B]- Correctly cap the spell levels of wands (patch by 'Sumendar') -- neil
-
-[V] T.o.M.E 2.2.7 aka "Stoke Me A Clipper"
-
-04/06/2004
-[P]- Class no longer influences the internal Angband 'skills' of Disarming,
- Magic Devices, Saving Throw, Stealth, Searching, Perception, Hand-to-Hand
- combat, Missile Combat, and Throwing. ToME skills instead have the same
- effect for all classes. -- neil
-
-05/06/2004
-[G]- Added the new Mimic shapes and updated the old ones -- masmarangio
-
-07/06/2004
-[G]- Destroying items manually now takes no time -- neil
-
-10/06/2004
-[B]- dungeon.c: Light should consume fuel at a rate of 1 / turn -- masmarangio
-
-11/06/2004
-[P]- Water Bite no longer has a damage cap -- neil
-
-12/06/2004
-[B]- A store (e.g. the mathom house) can contain up to 255 items (in defines.h
- STORE_INVEN_MAX limited the number of items to 24) (Note: the limit is
- stored in a byte in loadsaves.c) -- masmarangio
-
-21/06/2004
-[m]- a_info.txt: Updated names of artifacts in the comments -- masmarangio
-
-23/06/2004
-[m]- object.pkg: Added psychometry() for easier mindcraft testing.
-
-24/06/2004
-[m]- birth.txt, index.txt : Corrected and added abbreviations
- gen_idx.lua: removed non-existent file and sorted file list
-[G]- Added the spell Sterilize and Staves of Sterilization from ToME 3.0.0.
-[D]- Added the first new special level from ToME 3.0.0, Galleon in Helcaraxe
- -- masmarangio
-
-02/07/2004
-[D]- Added the special level Factory in the Illusory Castle -- masmarangio
-
-04/07/2004
-[G]- Added the spell Inertia Control from ToME 3.0.0 -- masmarangio
-
-05/072004
-[m]- Updated luckspoiler -- masmarangio
-
-09/07/2004
-[m]- Typo in s_fire.lua, from the wiki -- masmarangio
-[m]- rm_skeleton.txt, rm_zombie.txt: They cannot restore life force, and zombies
- are not resistant to nether -- masmarangio
-
-19/07/2004
-[P]- Except for infravision, all innate class or racial effects on skills are
- gone. All skills have equal effect for all classes, and races now give
- starting skill bonuses. -- Neil
-
-22/07/2004
-[B]- s_meta.lua: Inertia controlled spells are not casted in wilderness mode.
- s_mana.lua: Inertia level of Disruption Shield is 9 (needed spell level 45)
- m_meta.txt: Added a list of controllable spells -- masmarangio
-
-24/07/2004
-[P]- Mages are more geared toward a mix of Magic and Combat, while Sorcerors
- have more options than pure Sorcery -- Neil
-
-26/07/2004
-[B]- p_info.txt: Archers and Rangers gain the missing Spirituality skill
- p_info.txt: Removed the old Mimic Cloak (new cloak in player.lua)
-[m]- Helpfile updates for all character classes. -- masmarangio
-
-30/07/2004
-[B]- p_info.txt: Thunderlords start with Stealth -16.000 (from the wiki)
-[B]- cmd7.c: Fixed Alchemy recharging bug (thanks to Scott)
-[B]- al_info.txt: Removed the old Mimic Potions -- masmarangio
-[m]- util.pkg: Added lite_spot() and note_spot() for modules -- masmarangio
-
-31/07/2004
-[B]- monspeak.txt: Added some lines for Groo to fix a bug -- masmarangio
-[B]- files.c: Corrected display of Climb flag, immunity to Nether, negative
- pvals < -9. Added Sentient, Clone, Spider ESP flags. -- masmarangio
-
-02/08/2004
-[m]- g_melkor.txt: Added fire resistance for worshippers of Melkor
-[B]- files.c: Added flags from the gods and spell schools to the character
- screen. Added also flags from wielded symbiotes. -- masmarangio
-
-04/08/2004
-[m]- p_info.txt: Removed the useless skill Prayer for Maiar -- masmarangio
-[B]- cmd4.c: Quest list without random quests in DL > 98 -- masmarangio
-
-19/08/2004
-[m]- help file documentation restructuring, copying appropriate rewrites from
- wiki. -- fearoffours
-
-20/08/2004
-[B]- randart.c: An item with pval > 0 (e.g. an Elven Cloak) can gain parts
- with a max_pval = 0 (e.g. resistances and immunities) -- masmarangio
-
-24/08/2004
-[m]- Various minor changes to helpfiles, reflecting current changes to
- documentaiton on the wiki. --fearoffours
-
-28/08/2004
-[O]- Removed portable holes as have been useless for as long as merchants have
- been removed from game. --fearoffours
-
-30/08/2004
-[m]- k_info.txt: Fixed name of the commented out portable holes -- masmarangio
-
-14/09/2004
-[m]- Fixed some typographical errors, mostly from the wiki:
- cmd1.c: [The monster] fall -> falls, deleted space (Bug # 80 from the wiki)
- k_info.txt: Added & for Climbing sets (Bug # 81 from the wiki)
- q_one.c: You felt -> You fell (Bug # 94 from the wiki)
- monster2.c: It tries to breed but he fails: he -> it (Bug # 98 from the wiki)
- bldg.c: Changed wording of the soothsayer (Bug # 106 from the wiki)
- tables.c: Minor changes in the One Ring quest (Bug # 117 from the wiki)
- q_invas.c: jumps out of the between -> appears, deleted spaces,
- added single quotes in direct speech (Bug # 119 from the wiki)
- q_between.c: Deleted space, changed comments -- masmarangio
-
-20/09/2004
-[m]- book-4.txt: Capitalised 'Ring' (Bug # 135 from the wiki) -- masmarangio
-[B]- ow_info.txt: missing C: lines reduced the purse to 0 -- masmarangio
-[B]- object1.c: don't wield bolts with instruments and pebbles with boomerangs
- (Bug # 127 from the wiki) -- masmarangio
-
-21/09/2004
-[B]- object1.c: mention_use and describe_use list all available slots, check all
- weapon weights and distinguish between instruments and bows (Bug # 87)
- object1.c: Res Chaos implies Res Confusion (for the character screen)
- xtra1.c: Magical breath implies Water breath (from the wiki) -- masmarangio
-
-23/09/2004
-[B]- Z and Cth monster options removed, as in ToME 3. This fixes, among other
- things, the Death Orb issues. -- neil
-
-24/09/2004
-[m]- options.txt: Also removed the options from the help file -- masmarangio
-[B]- a_info.txt: Corrected two typos (Bugs # 140, 146 from the wiki)
- k_info.txt: Changed description of Bastard Sword, added RES_CHAOS to the
- known flags of a Blade of Chaos (it's mentioned in the description)
- files.c: Terminated highscore strings with \0, changed total_points
- slightly to prevent an overflow error (Bug # 139 from the wiki)
- v_info.txt: Corrected the x size of vault 99 and 104 -- masmarangio
-
-28/09/2004
-[D]- dungeon.c: Level of the Death dungeon is the minimum level from d_info.txt
-[B]- dungeon.c: Set dungeon_type to wilderness when recalling out. This should
- fix the various Moria recalling bugs (Bug # 95)
-[m]- cmd6.c: replaced the recall activation code by recall_player -- masmarangio
-[m]- monster1.c: missing spaces in description (Bug # 169) -- masmarangio
-
-
-29/09/2004
-[m]- Modules need to define three new variables to control the chance or
- random artifact generation. random_artifact_weapon_chance,
- random_artifact_armor_chance, random_artifact_jewelry_chance control
- the chance for different types of items. -- neil
-
-30/09/2004
-[B]- spells2.c: Redraw trap status after passwall (Bug # 51)
- store.c: Removed '))' when displaying a large store -- masmarangio
-
-01/10/2004
-[m]- mods_aux.lua: Added default values for random artifact generation;
- updated the skill values -- masmarangio
-
-02/10/2004
-[B]- al_info.txt: removed recipe for Scroll of Spell (Bug # 179), added recipe
- for Staff of Sterilisation (Bug # 77) -- masmarangio
-[m]- cmd6.c: protect evil -> protection from evil, s_stick.lua: town -> surface
- q_betwen.c, q_invas.c: speak -> speaks (from the forum) -- masmarangio
-
-03/10/2004
-[m]- tr_info.txt: Spelling of Lite (Bug # 182), Armor, Paralyzing -- masmarangio
-[B]- cmd6.c: Added timeout for junkarts in the activation description (ugly fix)
- tables.c: Replaced ACT_CURE_POISON by not used ACT_CURE_POIS -- masmarangio
-[B]- Once a god quest is failed, you will not receive any more god quests.
- -- fearoffours
-[m]- The (Ctrl-Q) Quest screen now shows which number god quest you have been given
- and an additional line in your character dump shows how many have been
- successfully completed. -- fearoffours
-[m]- Help updates from the wiki - lots of it Maylith's work, esp FAQ updates.
- -- fearoffours
-
-04/10/2004
-[m]- Corrected the description of the Disarm, Call the Elements and Channel
- Elements spells (without changing the code) (Bug # 175) -- masmarangio
-
-08/10/2004
-[B]- bldg.c: Research item (Bug # 191) and research monster are now paid
- correctly -- masmarangio
-[B]- spells2.c: Diggers cannot be enchanted with scrolls -- masmarangio
-[m]- tome-faq.txt, index.txt: Typo (Bug # 196) -- masmarangio
-
-10/10/2004
-[m]- s_info.txt: Antimagic: generates -> generate (Bug # 198) -- masmarangio
-[B]- files.c: Fixed displayed barehanded damage (Patch from Scott, Bug # 195)
- -- masmarangio
-
-11/10/2004
-[m]- powers.c: replaced the recall power code by recall_player
- q_troll.c: Fixed typos from the wiki (Bug # 208) -- masmarangio
-
-12/10/2004
-[m]- tables.c: Removed harpers and some other small changes (Bug # 212)
- cmd6.c: Added "and" in the description of ACT_ROHAN (Bug # 213)
- -- masmarangio
-
-13/10/2004
-[m]- m_demono.txt, s_demon.lua: armor -> armour class (Bug # 217)
-[O]- k_info.txt: Changed comments and descriptions of the items, mostly from
- the wiki (Bug # 176) and added missing descriptions (IdeaArchive)
- Added article (&) in the name of armours (Bug # 81),
- The spelling of some item names was changed: Scroll of Enchant Armour,
- *Enchant Armour*, Curse Armour, Summon Monsters, Basilard
- Added COULD2H to the Claymore and MUST2H to the Espadon.
-[m]- dun3.18: description of DimGates: fills -> fill (Bug # 223)
- -- masmarangio
-
-15/10/2004
-[B]- files.c: Remove / restore CAVE_VIEW before / after saving the game.
- This solves a long standing bug with the lighting of the dungeon
- since the temporary arrays that hold the position of the viewed
- grids are not stored in the save file (Bug # 19). -- masmarangio
-
-16/10/2004
-[m]- init1.c: The parser adds missing spaces at the end of the
- description of artifacts, like it did for objects. -- masmarangio
-[m]- Race, class and race modifier help files updates to reflect changes
- in skill bonuses. -- fearoffours
-
-18/10/2004
- Some changes to random artifact and scrolls of artifact creation
- (See Bugs # 206, 222, 226 on the wiki):
-[m]- externs.h: Moved some functions listed under spells2.c to proper sections
-[m]- k_info.txt: Added "mundane" to the description of the scroll
-[B]- cmd6.c: the selection of artifactable items can be escaped now
- randart.c: *ID* the object before listing the powers, some re-ordering
-[B]- spells2.c: Re-add diggers to item_tester_artifactable, and limit the
- selection to normal items due to complains (no ego items or artifacts)
-[O]- ra_info.txt: Added a STR-increasing part without combat bonuses for diggers
-[B]- ra_info.txt: Fixed two W-lines with 4 entries and added a missing C-line
-[O]- e_info.txt: Diggers cannot be of Earthquakes anymore (there are combat boni
- involved) - perhaps an own ego type should be added... -- masmarangio
-[m]- q_ultrag.c: Quest texts changed as reported in Bug # 210 -- masmarangio
-
-23/10/2004
-[B]- k_info.txt: Reduced throwing damage of totems to 1 -- masmarangio
-
-25/10/2004
-[P]- Priests disarm as well as Warriors do now -- neil
-[B]- st_info.txt: Fixed the changed item names in the stores (StatusReport3)
-[m]- spells.lua: Sorted the Conveyance spells by level (Bug # 233)
- -- masmarangio
-[m]- Helpfiles reflect changes to skills (priest disarming and racial
- spirituality update). -- fearoffours
-
-01/11/2004
-[m]- library.lua: Added OBJ_FOUND_REWARD to the tome (Bug # 237) -- masmarangio
-
-13/11/2004
-[B]- Fix for disappearing artifacts (especially guardian artifacts) during load / save
- thanks to SimonSorc
-
-17/11/2004
-[O]- No more blessed boomerangs -- neil
-
-[V] T.o.M.E 2.3.0 aka "One more try to get Mages working"
-
-10/12/2004
-[B]- Fix loading and saving of skills, I hope. Unfortunately this breaks save
- compatiability, though. The saves must be deleted again. -- Neil
-
-29/12/2004
-[B]- Fix negative skills -- Neil
-[B]- Don't use weaponmastery combat when weaponmastery skill is negative -- Neil
-
-[V] T.o.M.E 2.3.1 aka "2.3.0.1"
-
-2005/05/19
-[I]- If easy_disarm is off, don't trigger known traps while walking normally.
- Added a new extended command "blunder" to let players trigger traps on
- purpose. -- gwooledge
-[I]- Lots of documentation, spelling and grammar fixes, including:
- * the now-outdated race/class ability tables, replaced with skill tables
- * the missing documentation for the set of extended commands
- * far too many others to mention here
- -- gwooledge
-
-2005/05/20
-[I]- Added sanity and speed to the character screen (and hence the text dump).
- Consolidated HP and SP into one line to make room. -- gwooledge
-
-2005/05/21
-[B]- Don't allow trap doors on quest levels or on chests. -- gwooledge
-[I]- Allow shopping to use the correct keys in roguelike mode. -- gwooledge
-
-2005/05/22
-[B]- Update view after high-powered globe of light. -- gwooledge
-
-2005/05/26
-[I]- Push a certain potion type a little deeper into the dungeon -- Neil
-[I]- Make piety display light blue when praying, to make it easier to tell
- when you're praying. -- gwooledge
-
-2005/06/02
-[I]- Don't display ordinary resists when there's also an immunity to the same
- element, in an object description. -- gwooledge
-[B]- Don't allow use of stairs (any < or > movement command) while rooted
- to the floor (by the Yavanna spell). -- gwooledge
-
-2005/06/04
-[I]- Display the (colored) character for uniques in the Known Uniques list (~2).
- -- gwooledge
-
-2005/06/05
-[I]- Add "Check abilities" extended command/macro. This gives roguelike keyset
- players a way to access the ability screen other than "\N", although it's
- still one more keystroke than "\N" is.... -- gwooledge
-
-2005/06/11
-[B]- Try again to keep traps from wrecking a certain plot element -- Neil
-
-2005/06/18
-[B]- Fix module file handling for multi-user installs. Now character sheets,
- automatizer file, and the rest will be read and written in
- ~/.tome/2.3/modulename as they should. -- Neil
-
-2005/06/19
-[B]- Try harder to save persistent levels when recalling out -- Neil
-[B]- Fix all sub-racial skill bonuses, along with Maia racial skill bonuses
- -- Neil
-[O]- Prevent random artifact bolts from giving extra blows -- Neil
-
-2005/06/21
-[O]- Correct the types of certain artifact trap sets to match their weights
- and descriptions. -- gwooledge
-
-2005/07/13
-[I]- Clean up some offensive messages, patch courtesy of 'The Fury' -- Neil
-
-2005/07/14
-[I]- Include the resistances grid on character sheets dumped on death.
- This makes them consistent with the ones generated before death, and
- is more informative and useful for post mortem analyses. -- gwooledge
-
-2005/07/15
-[P]- Warriors no longer get a secret special three bonus blows spread over the
- 50 character levels. The three blows are now tied to Weaponmastery.
-
- Module authors should adjust accordingly, or their warriors may get three
- blows they didn't have before. -- Neil
-
-2005/07/16
-[O]- Potions of Cure Insanity were too cheap. -- gwooledge
-
-2005/07/24
-[I]- Examining a totem will recall the monster it summons -- Neil
-[I]- Examining a corpse will recall the monster it was -- Neil
-
-2005/07/27
-[V] T.o.M.E 2.3.2 aka "Unrealized Reality"
-
-28/07/2005
-[G]- Lost sword quest rewards always give a minimum skill modifier of 0.3.
- -- gwooledge
-
-29/07/2005
-[D]- Edit one vault to open up some inaccessible rooms -- Neil
-
-11/08/2005
-[B]- Alchemy: disallow repowering double-ego items, unless the character has
- the artifact creation ability. Based on patch by Andrey Egoshin.
- -- gwooledge
-[B]- Lost sword quest skill reward probabilities were computed incorrectly.
- Fix suggested by Dan Rosenberry. -- gwooledge
-[I]- Miscellaneous documentation, spelling and grammar fixes. -- gwooledge
-
-12/08/2005
-[B]- Don't let a player trick the Valar by getting drained and re-gaining
- levels -- Neil
-[I]- Update AC display after fixing armor in the buildings. -- gwooledge
-
-16/08/2005
-[B]- Don't allow Runecraft and Thaumaturgy spells to go explode inside walls
- and seep through -- Neil
-
-17/08/2005
-[I]- Fix damage display for Thaumaturgy ball spells. -- gwooledge
-[O]- Removed pointless slays, brands, and bonuses on Pick of Erebor -- Neil
-
-19/08/2005
-[B]- When consuming magic essences, don't stop prematurely. Based on patch
- by Andrey Egoshin. -- gwooledge
-
-30/08/2005
-[B]- Upkeep cost for partial summons was not always charged. -- gwooledge
-
-05/09/2005
-[B]- Some staves were being generated with the wrong tval, causing several bugs
- including (but not limited to) staves being unrechargeable. -- gwooledge
-
-11/09/2005
-[B]- Saving throw was not calculated correctly. -- gwooledge
-
-14/09/2005
-[P]- All new partial summon upkeep formula -- neil
-
-26/09/2005
-[B]- Disallow negative experience alchemy abuses. Based on patch by Andrey
- Egoshin. -- gwooledge
-[O]- When examining books, demonology equipment and instruments in stores, show
- both the object's powers and its spells. -- gwooledge
-[B]- Nonliving and undead pets won't be angered by lack of breathable air.
- -- gwooledge
-[D]- A certain early trap should be less deadly (and appear a bit later).
- -- gwooledge
-[I]- Honor exp_need option when displaying object experience. -- gwooledge
-
-27/09/2005
-[I]- Restored and updated some missing help files. -- gwooledge
-[G]- (Mass) Genocide damage is applied all at once to avoid bug #228.
- -- gwooledge
-
-28/09/2005
-[B]- Don't use the "POSIX" setuid calls on Mac OS X, as they apparently break
- compilation -- neil
-
-29/09/2005
-[O]- Junk should stack just like skeletons. Patch by StarweaverBlue.
- -- gwooledge
-[M]- Kavlax should be many-headed. -- gwooledge
-
-14/10/2005
-[B]- Certain monster spells were hard-coded for the wrong number of equipment
- slots. -- gwooledge
-
-18/10/2005
-[B]- Incorrect operator used in cave generation code. Effect unknown, but it
- *might* possibly fix some of the Orc cave crashes.-- gwooledge
-
-26/10/2005
-[M]- Regular (non-Joke, non-Cth, non-Z) monsters should not breathe nuke,
- because it has a side effect we don't want in ToME -- Neil
-
-29/10/2005
-[O]- Mac OS X builds now put all the game data into the bundle, storing all
- user data in the user's Library (some preferences in
- Library/Preferences/net.t-o-m-e.tome.plist, the rest in
- Library/Application Support/ToME. -- Neil
-
-16/11/2005
-[I]- Handling of Command key modified in Mac OS X UI. It should be accessible
- in macros now if it wasn't before -- Neil
-
-26/11/2005
-[B]- Don't allow uniques or quest monsters to just disappear to the move of
- another monster -- Neil
-
-14/12/2005 - ToME 2.3.3 "Realized Unreality"
-
-15/10/2006
-[B]- Remove buggy trap of Stair Movement -- Neil
-
-12/12/2005
-[B]- Fix typo in one monster's flags - Iain
-
-31/1/2005
-[I]- Fix window position saving on Mac OS, patch by John Love-Jensen
- -- Neil
-
-19/2/2005
-[B]- Fix word wrapping in character sheet, patch from "ZizzoTheInfinite"
- -- Neil
-
-[V] T.o.M.E 2.3.4 aka "An Unexpected Party"
diff --git a/lib/edit/a_info.txt b/lib/edit/a_info.txt
index 427d5060..60ce6008 100644
--- a/lib/edit/a_info.txt
+++ b/lib/edit/a_info.txt
@@ -38,7 +38,7 @@ W:20:10:10:10000
P:0:1d1:0:0:0
F:ACTIVATE | SEARCH | LITE3 | LUCK
F:INSTA_ART | HIDE_TYPE
-a:HARDCORE=LIGHT
+a:LIGHT
D:A small crystal phial, with the light of Earendil's Star contained inside.
D:Its light is imperishable, and near it darkness cannot endure.
@@ -51,7 +51,7 @@ W:30:25:5:32500
P:0:1d1:0:0:0
F:ACTIVATE | SEE_INVIS | HOLD_LIFE |
F:INSTA_ART | SPEED | LITE3 | LITE1 | HIDE_TYPE
-a:HARDCORE=MAP_LIGHT
+a:MAP_LIGHT
Z:detect curses
D:The shining Star of the West, a famed heirloom of Elendil's house.
@@ -65,7 +65,7 @@ W:50:50:5:50000
P:0:1d1:0:0:0
F:ACTIVATE | SEE_INVIS | HOLD_LIFE | RES_CHAOS | HIDE_TYPE | LUCK
F:INSTA_ART | SPEED | RES_LITE | RES_DARK | ESP_ORC | LITE3
-a:HARDCORE=THRAIN
+a:THRAIN
D:A great globe seemingly filled with moonlight, the famed Heart of the
D:Mountain, which splinters the light that falls upon it into a thousand
D:glowing shards.
@@ -79,7 +79,7 @@ W:50:10:3:60000
F:CON | HIDE_TYPE |
F:ACTIVATE | RES_FIRE |
F:INSTA_ART
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
D:A fiery circle of bronze, with mighty spells to ward off evil.
@@ -92,7 +92,7 @@ F:INT | WIS | CHR | SEARCH | INFRA | HIDE_TYPE |
F:SEE_INVIS | FREE_ACT | ACTIVATE |
F:RES_ACID | RES_COLD | RES_ELEC |
F:INSTA_ART
-a:HARDCORE=DISP_EVIL
+a:DISP_EVIL
D:The ancient heirloom of Ingwe, high lord of the Vanyar, against whom nothing
D:of evil could stand.
@@ -120,7 +120,7 @@ F:STR | CON | CHR | HIDE_TYPE |
F:IM_FIRE | ACTIVATE | SEARCH |
F:ESP_THUNDERLORD | SEE_INVIS | FLY |
F:INSTA_ART
-a:HARDCORE=DIM_DOOR
+a:DIM_DOOR
Z:swap position
D:The mighty ring of the Thunderlord Flare that makes the wearer
D:strong and healthy. Once a ring of power, it was
@@ -136,7 +136,7 @@ W:50:25:2:75000
F:STR | INT | WIS | DEX | CON | CHR | STEALTH | HIDE_TYPE |
F:RES_POIS | RES_DARK | ACTIVATE | SEE_INVIS | SEARCH |
F:INSTA_ART
-a:HARDCORE=BARAHIR
+a:BARAHIR
D:A ring shaped into twinned serpents with eyes of emerald meeting beneath
D:a crown of flowers, an ancient treasure of Isildur's house.
@@ -149,7 +149,7 @@ W:70:50:2:175000
F:STR | DEX | CON | HIDE_TYPE |
F:ACTIVATE | SPEED | ESP_EVIL |
F:INSTA_ART
-a:HARDCORE=TULKAS
+a:TULKAS
D:The treasure of Tulkas, most fleet and wrathful of the Valar.
@@ -164,7 +164,7 @@ F:ACTIVATE | FREE_ACT | SEE_INVIS |
F:SUST_STR | SUST_CON | SUST_WIS | SUST_CHR | SPECIAL_GENE |
F:IM_FIRE | RES_NETHER | RES_FEAR | REGEN |
F:INSTA_ART
-a:HARDCORE=NARYA
+a:NARYA
D:The Ring of Fire, set with a ruby that glows like flame. Narya is one
D:of the three Rings of Power created by the Elves and hidden by them from
D:Sauron.
@@ -181,7 +181,7 @@ F:ACTIVATE | HOLD_LIFE | FREE_ACT | SEE_INVIS |
F:SUST_INT | SUST_WIS | SUST_CHR |
F:IM_COLD | RES_BLIND | STEALTH | ESP_ALL |
F:INSTA_ART
-a:HARDCORE=NENYA
+a:NENYA
D:The Ring of Adamant, with a pure white stone as centrepiece. Nenya is one
D:of the three Rings of Power created by the Elves and hidden by them from
D:Sauron.
@@ -199,7 +199,7 @@ F:FEATHER | SLOW_DIGEST | REGEN |
F:SUST_STR | SUST_DEX | SUST_CON |
F:IM_ELEC | RES_POIS | RES_DISEN |
F:INSTA_ART
-a:HARDCORE=VILYA
+a:VILYA
D:The Ring of Sapphire, with clear blue gems that shine like stars,
D:glittering untouchable despite all that Sauron ever wrought. Vilya is
D:one of the three Rings of Power created by the Elves and hidden by them
@@ -221,7 +221,7 @@ F:SUST_INT | SUST_WIS | SUST_CHR |
F:RES_BLIND | RES_POIS | RES_DISEN | RES_NETHER | ESP_ALL |
F:DRAIN_MANA | DRAIN_HP | DRAIN_EXP |
F:INSTA_ART
-a:HARDCORE=POWER
+a:POWER
Z:change the world
D:"Ash nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh
D:burzum-ishi krimpatul". Unadorned, made of massive gold,
@@ -252,7 +252,7 @@ W:15:12:15:20000
P:0:1d1:0:0:0
F:ACTIVATE | SPECIAL_GENE | EASY_USE | LITE1 |
F:INSTA_ART
-a:HARDCORE=STONE_LORE
+a:STONE_LORE
D:A great emerald that fills your mind with images of knowledge and dreadful
D:understanding as you stare into its depths.
@@ -267,7 +267,7 @@ F:FREE_ACT | IM_ELEC | SPECIAL_GENE |
F:RES_FIRE | RES_COLD | RES_POIS | RES_LITE | RES_DARK |
F:LITE1 | SEE_INVIS | AGGRAVATE | ESP_DRAGON
F:ACTIVATE
-a:HARDCORE=RAZORBACK
+a:RAZORBACK
D:A massive suit of heavy dragon scales deeply saturated with many colours.
D:It throbs with angry energies, and you feel the raw elemental might of
D:untamed Lightning as you put it on.
@@ -286,7 +286,7 @@ F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK | ULTIMATE |
F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_BLIND | RES_CONF |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | SPECIAL_GENE
F:ACTIVATE
-a:HARDCORE=BLADETURNER
+a:BLADETURNER
D:A suit of adamant, set with scales of every colour, surrounded in a nimbus
D:of perfectly untramelled yet inextricably intermingled and utterly mastered
D:powers elemental and ethereal.
@@ -314,7 +314,7 @@ F:CON |
F:HOLD_LIFE | SUST_CON | ESP_UNDEAD | RES_CONF | RES_FEAR |
F:RES_ACID | RES_COLD | RES_DARK | RES_NETHER | RES_NEXUS | RES_CHAOS |
F:ACTIVATE
-a:HARDCORE=CURE_1000
+a:CURE_1000
D:A suit of imperishable adamant, with unconquerable strength to endure evil
D:and disruptive magics, that protects the life force of its wearer as
D:nothing else can.
@@ -357,7 +357,7 @@ F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS |
F:HOLD_LIFE | RES_DARK | RES_FEAR |
F:SEE_INVIS |
F:ACTIVATE
-a:HARDCORE=BELEGENNON
+a:BELEGENNON
D:This wondrous suit of fine-linked chain shimmers as though of pure silver.
D:It stands untouched amidst the fury of the elements, and a power of
D:concealment rests within.
@@ -372,7 +372,7 @@ P:35:2d4:-3:0:25
F:STR | CHR | HIDE_TYPE | ESP_ORC
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_DARK |
F:RES_DISEN | ACTIVATE
-a:HARDCORE=GENOCIDE
+a:GENOCIDE
D:A shimmering suit of true-silver, forged long ago by dwarven smiths of
D:legend. It gleams with purest white as you gaze upon it, and mighty are
D:its powers to protect and banish.
@@ -399,7 +399,7 @@ W:25:9:270:40000
P:16:1d4:-2:0:20
F:INT | WIS | CON | HIDE_TYPE |
F:RES_ACID | RES_POIS | RES_CONF | ACTIVATE
-a:HARDCORE=DEST_DOOR
+a:DEST_DOOR
D:A hauberk, leggings, and sleeves of interlocking steel rings, strategically
D:reinforced at vital locations with a second layer of chain. Magics to
D:enhance body and mind lie within, and no door can hope to resist the wearer.
@@ -509,7 +509,7 @@ F:STR | CON | HIDE_TYPE | BRAND_ACID | RES_ACID | LITE1 | DRAIN_MANA |
F:SLAY_ORC | KILL_DEMON | SLAY_TROLL | ACTIVATE | SHOW_MODS
F:MUST2H
f:MUST2H
-a:HARDCORE=HURIN
+a:HURIN
D:Wielded by Hurin Thalion in the Fifth Battle of Beleriand, this
D:troll-bane smoked in the black blood of Gothmog's guards.
@@ -593,7 +593,7 @@ P:8:1d3:0:0:20
F:STR | DEX | CON | HIDE_TYPE |
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_LITE | RES_BLIND |
F:LITE1 | SEE_INVIS | ESP_DRAGON | ESP_THUNDERLORD | ACTIVATE
-a:HARDCORE=GORLIM
+a:GORLIM
D:The legendary dragon helm of Turin Turambar, an object of dread to the
D:servants of Morgoth.
@@ -605,7 +605,7 @@ W:20:5:75:100000
P:5:1d3:0:0:10
F:INT | WIS | SEARCH | HIDE_TYPE |
F:RES_BLIND | SEE_INVIS | ACTIVATE
-a:HARDCORE=DETECT_ALL
+a:DETECT_ALL
D:A famous helm of forged iron granting extraordinary powers of mind and
D:awareness.
@@ -621,7 +621,7 @@ F:SEE_INVIS | NO_MAGIC | HEAVY_CURSE | TY_CURSE
F:RES_DISEN | RES_FEAR | FREE_ACT | RES_ACID | RES_FIRE | RES_POIS |
F:IM_COLD | ACTIVATE | DRAIN_HP |
F:TELEPORT | CURSED
-a:HARDCORE=GORLIM
+a:GORLIM
D:A headpiece, gaudy and barbaric, that betrayed a warrior when he most
D:needed succor.
@@ -635,7 +635,7 @@ P:0:1d1:0:0:15
F:STR | WIS | CON | HIDE_TYPE | SPEED | RES_CONF | RES_SOUND |
F:RES_COLD | RES_FIRE | RES_LITE | RES_BLIND | RES_ELEC | RES_CHAOS |
F:LITE1 | SEE_INVIS | REGEN | ACTIVATE
-a:HARDCORE=CURE_700
+a:CURE_700
D:The shining winged circlet brought by Elendil from dying Numenor, emblem of
D:Gondor through an age of the world.
@@ -651,7 +651,7 @@ F:INT | DEX | CHR | SEARCH | SPEED | HIDE_TYPE |
F:SEE_INVIS | FREE_ACT | RES_DARK | RES_BLIND |
F:RES_SHARDS | RES_SOUND | RES_LITE | RES_COLD |
F:LITE1 | ACTIVATE | DRAIN_MANA
-a:HARDCORE=NUMENOR
+a:NUMENOR
D:A crown of massive gold, set with wondrous jewels of thought and warding,
D:worn by the kings of ancient Numenor. Its wearer may go into battle
D:always knowing what he faces - unless his own folly blinds him to the
@@ -665,7 +665,7 @@ I:35:1:0
W:5:45:10:40000
P:1:0d0:0:0:20
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | ACTIVATE | ESP_GOOD
-a:HARDCORE=COLLUIN
+a:COLLUIN
D:A cape worn by a hero from Valinor, a land utterly beyond the strife
D:of Elements.
@@ -678,7 +678,7 @@ W:5:25:10:13000
P:1:0d0:0:0:4
F:INT | WIS | SPEED | STEALTH | HIDE_TYPE |
F:RES_ACID | ACTIVATE
-a:HARDCORE=SLEEP
+a:SLEEP
D:This elven-grey mantle possesses great powers of tranquility and of
D:concealment, and grants the wearer the knowledge and understanding of
D:the Sindar.
@@ -692,7 +692,7 @@ W:10:50:10:35000
P:1:0d0:0:0:18
F:DEX | CHR | HIDE_TYPE |
F:FREE_ACT | RES_ACID | RES_FIRE | RES_COLD | ACTIVATE
-a:HARDCORE=RECHARGE
+a:RECHARGE
D:A sable-hued cloak, with glowing elven-runes to restore magic showing calm
D:and clear as moonlight on still water.
@@ -717,7 +717,7 @@ W:5:20:10:11000
P:1:0d0:0:0:15
F:STEALTH | SPEED | RES_NEXUS |
F:RES_ACID | ACTIVATE
-a:HARDCORE=TELEPORT
+a:TELEPORT
D:A crystal-blue cape of fine silk worn by a silent messenger of
D:the forces of Law. Somehow, its wearer is always able to escape
D:trouble.
@@ -731,7 +731,7 @@ W:40:40:5:55000
P:6:0d0:0:0:20
F:INT | WIS | CHR | HIDE_TYPE | SPEED | STEALTH | INVIS | LUCK
F:RES_ACID | RES_FIRE | RES_COLD | SPECIAL_GENE | ACTIVATE | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=REST_LIFE
+a:REST_LIFE
D:The opaque midnight folds, inset with a multitude of tiny diamonds, of
D:this cloak swirl around you and you feel a hint, a fragment of the
D:knowledge and power to restore that lay in Luthien, the most beautiful
@@ -780,7 +780,7 @@ W:10:3:5:30000
P:1:0d0:0:0:10
F:FREE_ACT | RES_LITE | SUST_CON | LITE1 | ACTIVATE
F:SPECIAL_GENE
-a:HARDCORE=BO_MISS_1
+a:BO_MISS_1
D:These gloves glow so brightly as to light the way for their owner and cast
D:magical bolts with great frequency.
@@ -792,7 +792,7 @@ I:31:2:0
W:10:5:25:15000
P:2:1d1:0:0:15
F:RES_FIRE | ACTIVATE | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_FIRE_1
+a:BO_FIRE_1
D:A fiery set of gauntlets that can even shoot fire from the user's
D:hands.
@@ -805,7 +805,7 @@ W:10:5:25:33000
P:2:1d1:0:0:15
F:RES_COLD | ACTIVATE
F:SUST_CON | CON | REGEN | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_COLD_1
+a:BO_COLD_1
D:A set of handgear so icy as to be able to fire frost bolts.
@@ -816,7 +816,7 @@ I:31:2:0
W:10:5:25:11000
P:2:1d1:0:0:15
F:RES_ELEC | ACTIVATE | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_ELEC_1
+a:BO_ELEC_1
D:A set of handgear with sparks surrounding it, able to fire
D:bolts of electricity.
@@ -828,7 +828,7 @@ I:31:2:0
W:10:5:25:12000
P:2:1d1:0:0:15
F:RES_ACID | ACTIVATE | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_ACID_1
+a:BO_ACID_1
D:A set of handgear so corrosive that it may fire bolts of acid.
@@ -853,7 +853,7 @@ W:40:15:40:110000
P:5:1d1:10:10:20
F:DEX | HIDE_TYPE | LUCK
F:FREE_ACT | RES_ACID | ACTIVATE | SHOW_MODS
-a:HARDCORE=BO_MISS_2
+a:BO_MISS_2
Z:magic missile
D:The hand-sheathing of Fingolfin, warrior-king of Elves and Men, who gave
D:Morgoth seven mighty wounds and pain that will last forever.
@@ -867,7 +867,7 @@ W:40:120:40:300000
P:3:1d1:0:0:20
F:SPEED | HIDE_TYPE |
F:RES_NEXUS | ACTIVATE
-a:HARDCORE=SPEED
+a:SPEED
D:This wondrous pair of leather boots once sped Feanor, creator of the
D:Silmarils and the mightiest of the Eldar, along the Grinding Ice and to
D:Middle-earth at last.
@@ -882,7 +882,7 @@ P:2:1d1:0:0:15
F:DEX | HIDE_TYPE | CHR | SUST_CHR |
F:ACTIVATE | FREE_ACT |
F:RES_NETHER | RES_CHAOS | RES_CONF | SUST_CON
-a:HARDCORE=CURE_POISON
+a:CURE_POISON
D:A pair of high-laced shoes, strong against the powers of corruption and
D:withering, that grant the wearer extraordinary agility.
@@ -952,7 +952,7 @@ I:23:4:0
W:4:100:12:12000
P:0:1d4:4:6:0
F:BRAND_FIRE | RES_FIRE | ACTIVATE | SHOW_MODS | LITE1 | LEVELS
-a:HARDCORE=BO_FIRE_1
+a:BO_FIRE_1
D:A fiery dagger finely balanced for deadly throws.
@@ -963,7 +963,7 @@ I:23:4:0
W:3:100:12:11000
P:0:1d4:4:6:0
F:BRAND_COLD | RES_COLD | ACTIVATE | SHOW_MODS | LEVELS
-a:HARDCORE=BO_COLD_1
+a:BO_COLD_1
D:A frosty dagger finely balanced for deadly throws.
@@ -974,7 +974,7 @@ I:23:4:0
W:5:100:12:13000
P:0:1d4:4:6:0
F:BRAND_ELEC | RES_ELEC | ACTIVATE | SHOW_MODS | LEVELS
-a:HARDCORE=BO_ELEC_1
+a:BO_ELEC_1
D:A dagger covered in sparks and finely balanced for deadly throws.
@@ -985,7 +985,7 @@ I:23:4:0
W:5:40:12:35000
P:0:2d4:4:3:0
F:SLAY_ORC | RES_POIS | RES_DISEN | ACTIVATE | SHOW_MODS | BRAND_POIS
-a:HARDCORE=BA_POIS_1
+a:BA_POIS_1
D:A large stiletto dagger that glistens with odourless poison, to which the
D:wearer seems oddly immune.
@@ -1000,7 +1000,7 @@ F:DEX | HIDE_TYPE | SPEED | BLOWS |
F:BRAND_COLD | RES_COLD |
F:SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS | BRAND_POIS
-a:HARDCORE=BELANGIL
+a:BELANGIL
D:A frosty dagger surrounded in a nimbus of ice with a hilt of elk horn and
D:an edge to wound the wind.
@@ -1182,7 +1182,7 @@ F:SPEED | HIDE_TYPE | RES_FEAR | BLESSED |
F:SLAY_EVIL | BRAND_COLD | SLAY_UNDEAD | KILL_DEMON | SLAY_TROLL |
F:FREE_ACT | RES_COLD | RES_LITE | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS
-a:HARDCORE=BA_COLD_2
+a:BA_COLD_2
D:The weapon of Fingolfin, High King of the Noldor; it shines like a column
D:of ice lit by light unquenchable. Morgoth came but unwillingly to meet it
D:of old; his lame foot will remind him of its might should he meet it again.
@@ -1198,7 +1198,7 @@ F:STR | DEX | HIDE_TYPE | RES_FEAR | FREE_ACT | BLESSED | LUCK
F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | FREE_ACT |
F:RES_FIRE | SUST_DEX | SEE_INVIS | ACTIVATE | SHOW_MODS | LITE1
F:RES_DISEN | SPECIAL_GENE
-a:HARDCORE=BA_FIRE_1
+a:BA_FIRE_1
D:The famed "Flame of the West", the sword that was broken and is forged
D:again. It glows with the essence of fire, its wearer is mighty in combat,
D:and no creature of Sauron can withstand it. It will never be stained or
@@ -1333,7 +1333,7 @@ W:20:15:180:40000
P:0:2d6:8:10:0
F:WIS | CON | HIDE_TYPE |
F:SLAY_DRAGON | ESP_EVIL | ESP_UNDEAD | SLOW_DIGEST | ACTIVATE | SHOW_MODS
-a:HARDCORE=DRAIN_2
+a:DRAIN_2
D:The narrow axe head of this weapon, finely balanced by a crow's beak,
D:would pierce even the armour of Smaug, and its wielder becomes aware of
D:the minds of their enemies.
@@ -1394,7 +1394,7 @@ F:BRAND_COLD | BRAND_ELEC | LITE1 |
F:SLAY_TROLL | SLAY_ORC | SLAY_GIANT | KILL_UNDEAD |
F:FREE_ACT | RES_COLD | RES_ELEC | RES_LITE |
F:SLOW_DIGEST | ACTIVATE | BLESSED | SHOW_MODS |
-a:HARDCORE=BA_ELEC_2
+a:BA_ELEC_2
D:The mighty spear of Gil-galad, famed as "Snow-point" in the songs of
D:Elves, against which all the foul corruptions of Sauron dashed in vain.
@@ -1412,7 +1412,7 @@ F:RES_FIRE | RES_LITE | HOLD_LIFE | RES_FEAR |
F:FEATHER | ESP_GIANT
F:SEE_INVIS |
F:ACTIVATE | BLESSED | SHOW_MODS
-a:HARDCORE=STONE_MUD
+a:STONE_MUD
D:The thrusting spear of wise Orome the Vala, strong against giants of frost,
D:which can melt rock or flesh with ease.
@@ -1472,7 +1472,7 @@ F:STR | INT | WIS | DEX | CON | CHR | HIDE_TYPE |
F:SLAY_EVIL | BRAND_COLD | KILL_DEMON | SLAY_UNDEAD | ESP_NONLIVING
F:SLAY_ORC | FREE_ACT | IM_COLD | SEE_INVIS | ACTIVATE |
F:BLESSED | SHOW_MODS
-a:HARDCORE=MASS_GENO
+a:MASS_GENO
D:The axe of Eonwe, leader of the Hosts of the West before the gates of
D:Thangorodrim, strikes with icy wrath at the undead, disperses hosts of
D:evil at a word, and grants Maia-like powers of body and mind.
@@ -1502,7 +1502,7 @@ W:30:15:170:21000
P:0:2d8:4:3:0
F:STR | DEX | HIDE_TYPE |
F:SLAY_TROLL | SLAY_ORC | ACTIVATE | SHOW_MODS
-a:HARDCORE=CURE_MW
+a:CURE_MW
D:A superbly crafted double-bladed axe that slays the creatures of earth and
D:allows rapid recovery from their blows.
@@ -1564,7 +1564,7 @@ F:DEX | HIDE_TYPE |
F:SLAY_DRAGON | SLAY_ANIMAL | FREE_ACT | HOLD_LIFE | IM_ACID |
F:RES_NETHER | SEE_INVIS | SLOW_DIGEST | REGEN | ACTIVATE |
F:BLESSED | SHOW_MODS | WATER_BREATH
-a:HARDCORE=TELE_AWAY
+a:TELE_AWAY
D:The awesome weapon of the Vala Ulmo, Lord of Waters. Mightiest of all the
D:powers of good save Manwe himself, Ulmo laughs in scorn at the dread powers
D:of the undead, and is utterly in command of the element of water.
@@ -1581,7 +1581,7 @@ F:BRAND_COLD | BRAND_FIRE | FREE_ACT | RES_FIRE | RES_COLD |
F:RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS
F:COULD2H
f:COULD2H
-a:HARDCORE=RECALL
+a:RECALL
D:With elemental powers whose struggles turn this weapon red and purest
D:white, this shining reaper bears within it a power of going forth and
D:returning.
@@ -1596,7 +1596,7 @@ P:0:3d5:20:20:0
F:ACTIVATE | BRAND_FIRE | FREE_ACT | RES_FIRE | INFRA | LEVELS |
F:SLAY_EVIL | SLAY_DRAGON | SLAY_UNDEAD | SLAY_DEMON | VORPAL | CLONE |
F:CHR | SUST_CHR | RES_FEAR | RES_LITE | RES_BLIND | REGEN | SHOW_MODS
-a:HARDCORE=DAWN
+a:DAWN
D:Forged in the farthest East by a race of mighty spellcasters, this
D:shiny pale sword gleams with the rays of rising sun as you invoke
D:its power of commanding legions of powerful immortal warriors...
@@ -1614,7 +1614,7 @@ F:RES_COLD | SEE_INVIS | ESP_ALL | AGGRAVATE | SHOW_MODS | INSTA_ART |
F:LEVELS | ACTIVATE | SPECIAL_GENE
F:MUST2H
f:MUST2H
-a:HARDCORE=GROND
+a:GROND
D:The mighty Hammer of the Underworld, blackened by doomspells of shattering,
D:whose wielder holds the lives of all Morgoth's servants in his hand.
@@ -1630,7 +1630,7 @@ F:SLAY_EVIL | BRAND_FIRE | RES_FIRE | RES_CONF | ACTIVATE |
F:SHOW_MODS | LITE1
F:COULD2H
f:COULD2H
-a:HARDCORE=CONFUSE
+a:CONFUSE
D:A flail whose head befuddles those who stare as you whirl it around, and
D:becomes a fiery comet as you bring it down.
@@ -1671,7 +1671,7 @@ I:21:12:0
W:20:100:150:35000
P:0:2d6:5:7:2
F:BRAND_FIRE | IM_FIRE | ACTIVATE | SHOW_MODS | LITE1
-a:HARDCORE=FIRESTAR
+a:FIRESTAR
D:A famed battle-lord of old, with a ruddy head, coloured as embers are that
D:can yet rise up in wrath.
@@ -1685,7 +1685,7 @@ P:0:3d4:12:12:0
F:KILL_DRAGON | BRAND_ELEC | IM_ELEC | ACTIVATE | SHOW_MODS
F:COULD2H
f:COULD2H
-a:HARDCORE=SPEED
+a:SPEED
D:A great ridged mace that calls around you a nimbus of living lightning;
D:you remain utterly untouched even as fat sparks arc around your
D:fingers and eyebrows.
@@ -1730,7 +1730,7 @@ W:20:18:150:20000
P:0:1d9:3:5:0
F:INT | WIS | HIDE_TYPE | ESP_EVIL | SPELL_CONTAIN | WIELD_CAST
F:SLAY_EVIL | RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS
-a:HARDCORE=ID_PLAIN
+a:ID_PLAIN
D:The radiant golden staff of an Istari of legend, this wizard's companion
D:grants keen sight and the knowledge of many hidden things.
@@ -1744,7 +1744,7 @@ P:0:2d9:10:13:0
F:INT | WIS | CHR | HIDE_TYPE | SEARCH | BRAND_FIRE |
F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | SPELL_CONTAIN | WIELD_CAST
F:HOLD_LIFE | RES_FIRE | RES_NETHER | SEE_INVIS | ACTIVATE | SHOW_MODS
-a:HARDCORE=DETECT_XTRA
+a:DETECT_XTRA
D:A staff tall and sturdy, with rough-hewn runes that invoke the element of
D:Earth, and which strikes down all creatures who live in the shadow of
D:mountains.
@@ -1780,7 +1780,7 @@ F:BRAND_COLD | SLAY_ORC | RES_COLD | RES_LITE | REGEN |
F:ACTIVATE | SHOW_MODS | ESP_ORC | ESP_TROLL | ESP_GIANT
F:COULD2H
f:COULD2H
-a:HARDCORE=TURMIL
+a:TURMIL
D:Wielded by the High Priest of Meneltarma, this great mace gleams coldly as
D:though moonlit, and it can strike as mighty a blow spiritually as
D:physically.
@@ -1833,7 +1833,7 @@ W:50:25:110:50000
P:0:0d0:10:14:0
F:SPEED | HIDE_TYPE |
F:RES_FIRE | ACTIVATE | SHOW_MODS
-a:HARDCORE=CUBRAGOL
+a:CUBRAGOL
D:A crossbow that grants fiery speed to he who finds it, and from which
D:shoot bolts that blaze with flame unquenchable.
@@ -1852,7 +1852,7 @@ F:SEE_INVIS | ESP_EVIL | ESP_DEMON | NEVER_BLOW | INFRA
F:PRECOGNITION | IM_FIRE | ULTIMATE | SPELL_CONTAIN | WIELD_CAST
F:COULD2H
f:COULD2H
-a:HARDCORE=GANDALF
+a:GANDALF
D:A simple, wooden wizard's staff. Unremarkable in all aspects...
D:except that it pulses with overwhelming power.
@@ -1992,7 +1992,7 @@ W:50:15:200:55000
P:0:3d4:0:0:0
F:STR | TUNNEL | SUST_STR | HIDE_TYPE | LITE1 | ACTIVATE | CLIMB
F:RES_CHAOS | RES_LITE | RES_DARK
-a:HARDCORE=EREBOR
+a:EREBOR
D:A pick that provides a magical light by which to see while tunnelling.
@@ -2003,7 +2003,7 @@ I:14:58:4
W:19:10:15:10000
P:0:3d4:0:0:0
F:ACTIVATE | STEALTH | SEARCH | INFRA | RES_POIS | RES_DARK | WIELD_CAST
-a:HARDCORE=DRUEDAIN
+a:DRUEDAIN
D:The fabled Drum of the Druedain that will protect those who play it
D:from darkness and poison attacks. It also aids in the seeing of
D:warm-blooded creatures.
@@ -2016,7 +2016,7 @@ I:14:60:2
W:14:10:15:80000
P:0:3d4:0:0:0
F:ACTIVATE | CHR | WIS | ESP_DRAGON | WIELD_CAST
-a:HARDCORE=ROHAN
+a:ROHAN
D:A horn carved from the bones of the Dragon of Ered-Mithrin, this
D:heirloom of the House of Eorl bestows to its user the gifts of
D:courage and command.
@@ -2029,7 +2029,7 @@ I:14:60:2
W:16:10:15:15000
P:0:3d4:0:0:0
F:ACTIVATE | STR | CON | IM_COLD | RES_NETHER | RES_FEAR | WIELD_CAST
-a:HARDCORE=HELM
+a:HELM
D:Heedless of cold, fearless of darkness -- besiegers fled at the wind
D:of the solitary coming of King Helm Hammerhand, proclaimed by a single
D:horn-blast in the dead of winter.
@@ -2042,7 +2042,7 @@ I:14:60:3
W:18:10:15:18000
P:0:3d4:0:0:0
F:ACTIVATE | STR | CON | RES_FEAR | RES_FIRE | AGGRAVATE | WIELD_CAST
-a:HARDCORE=BOROMIR
+a:BOROMIR
D:Boromir's horn gives courage and endurance to the wearer, provided he does
D:not wish to travel in secrecy: for it must always sound when its wielder
D:sets forth on a journey. "Loud and clear it sounds in the valleys of the
@@ -2056,7 +2056,7 @@ I:22:28:-4
W:30:8:250:30000
P:0:3d8:14:19:0
F:BRAND_FIRE | IM_FIRE | CHR | ACTIVATE | SHOW_MODS | CURSED | TY_CURSE
-a:HARDCORE=AXE_GOTHMOG
+a:AXE_GOTHMOG
D:The black axe of Gothmog, which struck Fingon at Nirnaeth. Mighty
D:spells of evil make it unsafe in any hands but those of its original wielder.
@@ -2085,7 +2085,7 @@ F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | SLAY_TROLL | SLAY_DEMON |
F:FREE_ACT | RES_FIRE | RES_DARK | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS | BLESSED |
F:PRECOGNITION | NO_MAGIC | ULTIMATE | SPECIAL_GENE
-a:HARDCORE=ERU
+a:ERU
D:A warm light bathes this translucent blade. The power of the fates are
D:at the command of its wielder as the weapon passes Supreme Judgment on
D:the inhabitants of Angband.
@@ -2111,7 +2111,7 @@ W:10:10:5:20000
P:0:0d0:20:0:0
F:INFRA | SEARCH | HIDE_TYPE |
F:XTRA_SHOTS | SHOW_MODS | ACTIVATE | SPECIAL_GENE
-a:SPELL=Artifact Maggot
+a:MAGGOT
D:This ordinary seeming leather sling has been raised to legendary
D:status amongst generations of hobbit children. Farmer Maggot's
D:ability to notice and strike any mushroom thief anywhere within
@@ -2210,7 +2210,7 @@ P:0:2d7:20:14:0
F:DEX | SEARCH | SLAY_ORC | ACTIVATE | HIDE_TYPE | SHOW_MODS
F:COULD2H
f:COULD2H
-a:HARDCORE=ORCHAST
+a:ORCHAST
D:Forged by the dwarves of Khazad-dum in a time of desperation,
D:this axe turned many a battle against the invading orcs.
@@ -2223,7 +2223,7 @@ W:45:20:45:34000
P:0:2d6:34:22:0
F:DEX | STEALTH | VAMPIRIC | KILL_UNDEAD | RES_DARK | HIDE_TYPE |
F:SHOW_MODS | SEE_INVIS | ACTIVATE | DRAIN_EXP
-a:HARDCORE=NIGHT
+a:NIGHT
D:Found on an unmarked grave after a violent storm, this hatchet
D:has a sinister aura of darkness and decay.
@@ -2236,7 +2236,7 @@ W:70:20:300:28400
P:0:5d7:31:27:0
F:STR | SLAY_ANIMAL | SUST_STR | RES_SHARDS | RES_NEXUS | FEATHER |
F:HIDE_TYPE | SHOW_MODS | ACTIVATE | DRAIN_HP
-a:HARDCORE=NATUREBANE
+a:NATUREBANE
D:Used by the orcs in their battle at Dagor Bragollach against the elves, this
D:axe has a bloodthirst for nature.
@@ -2261,7 +2261,7 @@ W:20:5:75:100000
P:6:1d3:0:0:20
F:LITE1 | HIDE_TYPE | SPECIAL_GENE | LUCK
F:AUTO_ID | ACTIVATE
-a:HARDCORE=KNOWLEDGE
+a:KNOWLEDGE
D:This helm, designed by Petty-Dwarves ages ago to act as the brain of a
D:long lost project, is made of finest glass. Its light banishes all secrets,
D:and makes audible whispers from the deceased.
@@ -2326,8 +2326,8 @@ N:165:'Lebohaum'
I:32:6:0
W:20:15:15:25000
P:20:0d0:0:0:80
-F:ACTIVATE
-a:SPELL=Artifact Lebauhaum
+F:ACTIVATE | EASY_USE
+a:LEBOHAUM
D:With the Helm 'Lebohaum' your head is safe!
@@ -2342,7 +2342,7 @@ F:RES_NEXUS | RES_CHAOS | AGGRAVATE | REGEN |
F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_CONF |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
F:ACTIVATE
-a:HARDCORE=MEDIATOR
+a:MEDIATOR
D:A mighty suit of dragon armour, set with the scales of dragons of both
D:Law and Chaos, and with power over both.
@@ -2354,7 +2354,7 @@ I:36:6:0
W:50:20:100:35000
P:6:0d0:0:0:15
F:RES_CHAOS | RES_NETHER | RES_POIS | ACTIVATE
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
D:Contained within this studded cuirass of pliable leather is the memory of
D:unvanquished Himring, defiant fortress surrounded by the legions of Morgoth.
@@ -2382,7 +2382,7 @@ F:ACTIVATE |
F:LITE1 | WIS | CHR | SEARCH | LUCK
F:RES_ELEC | RES_ACID | RES_DISEN | RES_DARK | HIDE_TYPE |
F:SUST_WIS | SUST_DEX | SUST_CHR
-a:HARDCORE=GILGALAD
+a:GILGALAD
D:The legendary shield of Gil-Galad, who fought his way to the gates of
D:the Dark Tower, and with whom came light even to Gorgoroth.
@@ -2396,7 +2396,7 @@ P:3:1d1:0:0:18
F:INT | DEX | CHR | SPELL | SEARCH |
F:RES_FIRE | RES_ACID | RES_DISEN | RES_SHARDS |
F:ACTIVATE
-a:HARDCORE=CELEBRIMBOR
+a:CELEBRIMBOR
D:This once belonged to Celebrimbor, maker of the Rings of Power. One who
D:knows both fire and acid, from the business of forging and engraving, will
D:fear neither: nor have his enchantments ever faded. Celebrimbor was even
@@ -2413,7 +2413,7 @@ P:0:4d1:18:18:0
F:STR | CON | XTRA_MIGHT | AGGRAVATE |
F:RES_LITE | RES_DARK | RES_BLIND | RES_ELEC |
F:HIDE_TYPE | ACTIVATE | SHOW_MODS
-a:HARDCORE=UMBAR
+a:UMBAR
D:A great brazen arbalest with arms of gleaming steel, shooting quarrels with
D:speed and power for those brave enough to risk betrayal.
@@ -2459,7 +2459,7 @@ F:TUNNEL | INFRA | SEARCH | STR | ESP_ORC | CLIMB |
F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | SLAY_DRAGON |
F:BRAND_ACID | RES_ACID | RES_DARK | RES_DISEN |
F:ACTIVATE
-a:HARDCORE=STONE_MUD
+a:STONE_MUD
D:Wielded by Nain of the Iron Hills at the Battle of Azanulbizar, this great
D:mattock brought victory to the Dwarves over Azog's Orcs - though Nain
D:himself fell at the last, even with victory already assured.
@@ -2477,7 +2477,7 @@ F:RES_FIRE | RES_ELEC | RES_NETHER | RES_DISEN | HOLD_LIFE |
F:ACTIVATE
F:COULD2H
f:COULD2H
-a:HARDCORE=FUNDIN
+a:FUNDIN
D:The weapon of one of the great dwarven priests, with powers
D:to preserve body, soul and enchantments, and the bane of those
D:who seek life beyond death.
@@ -2492,7 +2492,7 @@ P:4:1d2:0:0:15
F:ACTIVATE |
F:STR | CON | SUST_STR | SUST_CON | HIDE_TYPE |
F:RES_FEAR | RES_BLIND | RES_POIS | AGGRAVATE
-a:HARDCORE=HARADRIM
+a:HARADRIM
D:A great shield from the far lands of the South, whose wielder
D:will go charging into battle heedless of danger, with the
D:strength and endurance of a madman. Nor will he fear poison, for
@@ -2512,7 +2512,7 @@ F:KILL_DRAGON | SLAY_ANIMAL | BRAND_POIS | BRAND_ELEC |
F:ACTIVATE
F:COULD2H
f:COULD2H
-a:HARDCORE=SKULLCLEAVER
+a:SKULLCLEAVER
D:This mighty bludgeon brings destruction to all around it, and is the
D:bane of dragons and magic.
@@ -2525,7 +2525,7 @@ W:55:35:25:40000
P:3:1d1:0:0:15
F:INT | MANA | FREE_ACT | FEATHER | RES_ELEC | RES_DARK | RES_POIS | ACTIVATE
F:LUCK | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=EOL
+a:EOL
D:The iron-shod gauntlets of the Dark Elven smith Eol, tingling with magics
D:that he could channel in battle.
@@ -2595,8 +2595,8 @@ I:23:17:3
W:5:10:130:500
P:0:2d5:5:6:0
F:RES_FEAR | LUCK
-F:ACTIVATE | SHOW_MODS
-a:SPELL=Artifact Durandil
+F:ACTIVATE | EASY_USE | SHOW_MODS
+a:DURANDIL
D:Don't go adventuring without your Durandil sword!
@@ -2609,7 +2609,7 @@ P:0:1d1:0:0:0
F:CURSED | INT | WIS | CON | DEX | CHR | STR | ACTIVATE |
F:LITE3 | LITE2 | LUCK | MAGIC_BREATH
F:INSTA_ART | DG_CURSE | ESP_UNDEAD |
-a:HARDCORE=UNDEATH
+a:UNDEATH
D:It appears like the Phial of Galadriel at first - but wait! It
D:is a cursed phial created by an evil wizard to lure adventurers
D:into wielding it unknowingly.
@@ -2633,7 +2633,7 @@ P:0:10d10:0:0:0
F:WIS | INT | SEARCH | INFRA | HIDE_TYPE | ACTIVATE | ESP_ALL |
F:SEE_INVIS | RES_BLIND | AGGRAVATE | DRAIN_MANA | LITE2
F:INSTA_ART
-a:HARDCORE=PALANTIR
+a:PALANTIR
D:A shining white ball of unbreakable crystal, the ancient Palantiri
D:were used by kings of Numenor and later by the Exiles for rapid
D:communication between distant lands. Nothing is hidden from one who
@@ -2702,7 +2702,7 @@ P:0:0d0:7:7:10
F:STR | WIS | CHR | SPEED | LITE3 | INSTA_ART |
F:RES_FEAR | RES_FIRE | RES_POIS | RES_DISEN | HIDE_TYPE |
F:ACTIVATE
-a:HARDCORE=ELESSAR
+a:ELESSAR
D:This green gem glows with inner light. Aragorn son of Arathorn wore
D:it at the Battle of the Pelennor Fields, and he was himself given the
D:name of 'Elessar' by the people of Gondor because of this.
@@ -2716,7 +2716,7 @@ W:50:50:3:35000
F:HOLD_LIFE | SUST_CON | SUST_WIS | SUST_INT | LITE1 | CON |
F:RES_DARK | RES_COLD | RES_NETHER | REGEN | INSTA_ART |
F:ACTIVATE
-a:HARDCORE=REST_ALL
+a:REST_ALL
D:A pure white jewel, the last gift of Queen Arwen Undomiel to Frodo
D:Baggins, intended to be worn around his neck on the chain that had
D:once borne the One Ring.
@@ -2731,7 +2731,7 @@ P:0:10d10:0:0:-30
F:LIFE | CON | INT | WIS | ESP_ALL | LITE3 | LITE1
F:CURSED | HEAVY_CURSE | TY_CURSE | DRAIN_EXP |
F:RES_BLIND | SEE_INVIS | ACTIVATE
-a:HARDCORE=PALANTIR
+a:PALANTIR
D:A shining white ball of unbreakable crystal, the ancient Palantiri
D:were used by kings of Numenor and later by the Exiles for rapid
D:communication between distant lands. This Palantir, however, was
diff --git a/lib/edit/ab_info.txt b/lib/edit/ab_info.txt
index 7b9aa152..9e0bd81d 100644
--- a/lib/edit/ab_info.txt
+++ b/lib/edit/ab_info.txt
@@ -22,8 +22,6 @@
# E:excluding ability:excluding ability
-# If you need more sophisticated prereqs use the HOOK_LEARN_ABILITY
-
# Version stamp (required)
# Do not forget to update misc.txt with an entry like the following :
@@ -36,9 +34,9 @@ N:0:Spread blows
D:If a monster dies to your attack but you still have blows left
D:you won't lose the full turn, allowing you to attack some other
D:monster in the same turn
-D:Prereq: Weaponmastery skill@30, Dex@17
+D:Prereq: Combat@30, Dex@17
I:5
-k:30:Weaponmastery
+k:30:Combat
S:17:DEX
N:1:Tree walking
diff --git a/lib/edit/ba_info.txt b/lib/edit/ba_info.txt
index 8156fd2f..38444c13 100644
--- a/lib/edit/ba_info.txt
+++ b/lib/edit/ba_info.txt
@@ -65,10 +65,6 @@ N:10:Play craps
C:0:0:0
I:14:0:c
-N:11:Spin the wheel
-C:0:0:0
-I:15:0:s
-
N:12:Play dice slots
C:0:0:0
I:16:0:d
@@ -97,14 +93,6 @@ N:18:Research monster
C:1600:1500:1400
I:20:0:r
-N:19:View bounties
-C:0:0:0
-I:38:0:v
-
-N:20:Receive bounty money
-C:0:0:0
-I:39:0:b
-
N:21:Get quest monster
C:0:0:0
I:54:0:q
@@ -165,19 +153,6 @@ N:35:Get a quest
C:0:0:0
I:6:0:q
-# Restrict to liked/normal
-N:36:Get a quest
-C:0:0:0
-I:46:1:q
-
-N:37:Get a quest
-C:0:0:0
-I:47:0:q
-
-N:38:Get a quest
-C:0:0:0
-I:49:0:q
-
N:39:Herbal Healing
C:32000:10000:0
I:50:0:h
@@ -190,10 +165,6 @@ N:41:Distribute earnings
C:0:0:0
I:7:2:d
-N:42:Morph restoration
-C:3000:1500:750
-I:37:0:r
-
#for The Mirror
N:43:View fate
C:500:500:500
@@ -204,11 +175,6 @@ N:44:Research item
C:1500:1500:1500
I:1:0:a
-#for library in gondol
-N:45:Research item
-C:2000:2000:2000
-I:1:0:a
-
#for Star-Dome
N:46:Identify possessions
C:1200:1000:250
@@ -257,18 +223,6 @@ N:55:Get an item
C:0:0:0
I:44:0:g:p
-N:56:Request an item
-C:0:0:0
-I:51:2:r
-
-N:57:Ask for loan
-C:0:0:0
-I:52:2:a
-
-N:58:Pay back loan
-C:0:0:0
-I:53:2:p
-
N:59:Donate an item
C:0:0:0
I:43:0:d
diff --git a/lib/edit/d_info.txt b/lib/edit/d_info.txt
index 59a1e6f2..757d396e 100644
--- a/lib/edit/d_info.txt
+++ b/lib/edit/d_info.txt
@@ -303,7 +303,7 @@ M:ORC | R_CHAR_k | R_CHAR_o | R_CHAR_O
# There is Glaurung
N:20:Erebor
D:Ere:a tunnel leading into depths of the Lonely Mountain.
-W:60:72:35:0:20:140
+W:60:72:30:0:20:140
L:88:100:1:0:1:0
A:97:90:87:10:56:0:57:97
O:40:40:40:40
diff --git a/lib/edit/e_info.txt b/lib/edit/e_info.txt
index f01d8cf7..6c2e585f 100644
--- a/lib/edit/e_info.txt
+++ b/lib/edit/e_info.txt
@@ -231,7 +231,7 @@ C:0:0:0:3
Z:blink
R:100
F:ACTIVATE
-a:HARDCORE=JUMP
+a:JUMP
### Shields ###
@@ -321,7 +321,7 @@ C:0:0:0:2
W:0:1:8:500
R:100
F:DEX | SUST_DEX | ACTIVATE | ESP_ORC
-a:HARDCORE=NOLDOR
+a:NOLDOR
N:24:of Intelligence
X:A:33:13
@@ -859,7 +859,7 @@ W:0:1:44:9000
C:8:8:0:2
R:100
F:DEX | STR | VORPAL | ACTIVATE
-a:HARDCORE=SPIN
+a:SPIN
# The "Elemental" brands (4) (6)
@@ -1239,7 +1239,7 @@ T:24:0:255
X:A:24:22
W:0:1:100:7000
C:4:4:0:2
-a:HARDCORE=TELEPORT
+a:TELEPORT
R:100
F:SLAY_EVIL | KILL_DRAGON | TELEPORT | FREE_ACT | SEARCH | BRAND_ELEC
F:REGEN | SLOW_DIGEST | RES_NEXUS | ACTIVATE | FLY | ESP_DRAGON
@@ -1295,7 +1295,7 @@ W:0:1:5:5000
R:100
F:SLAY_UNDEAD | SEE_INVIS | HOLD_LIFE | DRAIN_HP
F:ACTIVATE
-a:HARDCORE=SPECTRAL
+a:SPECTRAL
N:103:of Morgul
T:125:0:255
@@ -1602,7 +1602,7 @@ R:50
F:PVAL_M1
R:25
F:PVAL_M1
-a:HARDCORE=BA_ACID_H
+a:BA_ACID_H
# Rods ego
N:131:Capacity of
@@ -2123,7 +2123,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_COLD_3
+a:BA_COLD_3
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
@@ -2132,7 +2132,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_ELEC_3
+a:BA_ELEC_3
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
@@ -2141,7 +2141,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_FIRE_H
+a:BA_FIRE_H
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
diff --git a/lib/edit/k_info.txt b/lib/edit/k_info.txt
index aba86074..289e00f5 100644
--- a/lib/edit/k_info.txt
+++ b/lib/edit/k_info.txt
@@ -1404,7 +1404,7 @@ G:=:d
I:45:4:0
W:5:0:2:250
A:5/1
-a:HARDCORE=DEST_TELE
+a:DEST_TELE
F:CURSED | TELEPORT | EASY_KNOW | ACTIVATE
f:TELEPORT
D:This ring will uncontrollably send you to different places at its whim.
@@ -1483,7 +1483,7 @@ I:45:18:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_FIRE_4
+a:BA_FIRE_4
F:RES_FIRE | IGNORE_FIRE | ACTIVATE
f:RES_FIRE
D:This fiery circlet grants you protection, makes fire less dangerous and even
@@ -1495,7 +1495,7 @@ I:45:17:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_ACID_4
+a:BA_ACID_4
F:RES_ACID | IGNORE_ACID | ACTIVATE
f:RES_ACID
D:This magical ring is imbued with spells of devouring acid, granting protection against such
@@ -1506,7 +1506,7 @@ G:=:d
I:45:19:0
W:50:0:2:3000
A:50/1
-a:HARDCORE=BA_COLD_4
+a:BA_COLD_4
P:0:0d0:0:0:15
F:RES_COLD | IGNORE_COLD | ACTIVATE
f:RES_COLD
@@ -2775,9 +2775,9 @@ W:127:0:4:0
A:127/255
P:0:1d1:0:0:0
T:39:2
-F:NORM_ART | FULL_NAME | SPECIAL_GENE
+F:NORM_ART | FULL_NAME | SPECIAL_GENE | EASY_USE
F:ACTIVATE | ACTIVATE_NO_WIELD
-a:SPELL=Artifact Eternal Flame
+a:ETERNAL_FLAME
D:An impossibly bright, flickering living flame. It can be used
D:once to imbue an object with the power of Eru Iluvatar himself.
@@ -3518,7 +3518,7 @@ I:38:1:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_ACID
+a:BR_ACID
F:RES_ACID | FLY |
f:RES_ACID |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3530,7 +3530,7 @@ I:38:2:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_ELEC
+a:BR_ELEC
F:RES_ELEC | FLY |
f:RES_ELEC |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3541,7 +3541,7 @@ G:[:w
I:38:3:0
W:50:0:200:40000
A:50/8
-a:HARDCORE=BR_COLD
+a:BR_COLD
P:30:2d4:-2:0:10
F:RES_COLD | FLY |
f:RES_COLD |
@@ -3554,7 +3554,7 @@ I:38:4:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_FIRE
+a:BR_FIRE
F:RES_FIRE | FLY |
f:RES_FIRE |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3566,7 +3566,7 @@ I:38:5:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_POIS
+a:BR_POIS
F:RES_POIS | FLY |
f:RES_POIS |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3578,7 +3578,7 @@ I:38:6:0
W:90:0:200:150000
A:90/32
P:30:2d4:-2:0:10
-a:HARDCORE=BR_MANY
+a:BR_MANY
F:ATTR_MULTI
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | FLY |
f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS |
@@ -3591,7 +3591,7 @@ I:38:10:0
W:70:0:200:70000
A:70/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_LIGHT
+a:BR_LIGHT
F:RES_LITE | RES_DARK | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of armour made of dragon hide, glowing with a strange light, or is it darkness?
@@ -3602,7 +3602,7 @@ I:38:12:0
W:80:0:200:80000
A:80/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_SHARD
+a:BR_SHARD
F:RES_SOUND | RES_SHARDS | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A piece of dragonhide cut and shaped so it can be worn as armour. The scales are very sharp,
@@ -3614,7 +3614,7 @@ I:38:14:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_CONF
+a:BR_CONF
F:RES_CONF | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of armour made from dragon skin. Its brownish scales glitter in a dazzling light.
@@ -3625,7 +3625,7 @@ I:38:16:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_SOUND
+a:BR_SOUND
F:RES_SOUND | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of golden-hued armour made of dragonhide. The rustle of its scales occasionally
@@ -3637,7 +3637,7 @@ I:38:18:0
W:80:0:200:80000
A:80/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_CHAOS
+a:BR_CHAOS
F:ATTR_MULTI
F:RES_CHAOS | RES_DISEN | FLY |
f:RES_CHAOS |
@@ -3652,7 +3652,7 @@ I:38:20:0
W:95:0:200:100000
A:95/32
P:30:2d4:-2:0:10
-a:HARDCORE=BR_BALANCE
+a:BR_BALANCE
F:RES_CHAOS | RES_DISEN | RES_SOUND | RES_SHARDS | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of armour made of the hide of a dead dragon. When wearing it, you feel like you
@@ -3664,7 +3664,7 @@ I:38:30:0
W:100:0:250:350000
A:100/64
P:40:2d4:-3:0:15
-a:HARDCORE=BR_POWER
+a:BR_POWER
F:ATTR_MULTI
F:RES_ACID | RES_FIRE | RES_COLD | RES_ELEC | RES_POIS | FLY |
F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK |
@@ -4901,7 +4901,7 @@ I:45:56:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_ELEC_4
+a:BA_ELEC_4
F:RES_ELEC | IGNORE_ELEC | ACTIVATE
f:RES_ELEC |
D:This sparkling circlet grants you protection, makes electricity less
@@ -6047,7 +6047,7 @@ G:":G
I:40:17:0
W:25:0:3:10000
A:25/1
-a:HARDCORE=BA_POIS_4
+a:BA_POIS_4
F:RES_POIS | DEX | ACTIVATE
D:A petrified serpent's tongue, hung on a thin chain to be clasped around your neck. It makes you
D:like unto snakes, able to wriggle out of tight corners, impervious to poisons and poisonous
diff --git a/lib/edit/ow_info.txt b/lib/edit/ow_info.txt
index 4bd7c41a..333113ce 100644
--- a/lib/edit/ow_info.txt
+++ b/lib/edit/ow_info.txt
@@ -437,8 +437,6 @@ H:Orc | Troll | Half-Ogre | Beorning | Kobold |
N:68:Kanris(Human)
I:5000:140
C:120:100:80
-#L:Merchant
-#H:Rogue
N:69:Barliman Butterbur(Human)
I:100:120
diff --git a/lib/edit/p_info.txt b/lib/edit/p_info.txt
index 1531f4fd..69e87acb 100644
--- a/lib/edit/p_info.txt
+++ b/lib/edit/p_info.txt
@@ -1953,22 +1953,3 @@ M:C:Rogue
M:C:Mage
M:C:Priest
M:C:Loremaster
-#M:C:Test
-#M:C:Chaos-Warrior
-
-#M:N:1:B:Spellcasters -- Magic is The One True Way
-
-#M:N:2:y:Priests -- Hail the powers of the Ainur
-#M:C:Mindcrafter
-
-#M:N:3:G:Beastfriends -- Monsters are fun
-#M:C:BeastMaster
-
-#M:N:4:v:Others -- The way to your independence
-#M:C:Harper
-#M:C:Merchant
-
-#M:N:5:o:Tests -- Test is you dare !
-#M:C:Test
-#M:C:Blade
-#M:C:Black-Knight
diff --git a/lib/edit/st_info.txt b/lib/edit/st_info.txt
index 3762d0c5..4cda4421 100644
--- a/lib/edit/st_info.txt
+++ b/lib/edit/st_info.txt
@@ -1,13 +1,5 @@
# File: st_info.txt
-# Fixed Potions of Cure Light/Serious Wounds in the Temple, Potions of
-# Restore Str/Con in the Alchemist
-# Magic Shop - Amulet of Slow Digestion, Wand of Light, Staffs of Enlightenment,
-# Door/Stair Location, Detect Invis/Evil, and Remove Curse
-
-# This file is used to initialize the "lib/raw/st_info.raw" file, which is
-# used to initialize the "store info type" information for the Angband game.
-
# Do not modify this file unless you know exactly what you are doing,
# unless you wish to risk possible system crashes and broken savefiles.
@@ -348,9 +340,6 @@ G:+:s
W:0
N:16:Beastmaster Shanty
-# Disabled the bounty list for the time being to not confuse people
-# with the bounty quest
-# A:18:0:19:20:21:22
A:18:0:21:22:0:0
O:19:19:19:19
G:+:g
@@ -692,12 +681,6 @@ F:RANDOM | MEDIUM_LEVEL | DEPEND_LEVEL
F:RARE
W:24
-N:56:Merchants Guild
-A:0:0:56:57:58:0
-O:68:68:68:68
-G:+:g
-W:0
-
N:57:The Mathom-house
A:0:0:59:0:3:0
O:0:0:0:0
diff --git a/lib/edit/t_basic.txt b/lib/edit/t_basic.txt
deleted file mode 100644
index 78103425..00000000
--- a/lib/edit/t_basic.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-# File: t_lite.txt
-
-# *Basic* town (vanilla style)
-
-
-############### Town Layout ###############
-
-F:*:7:3:0:0:0:0:0:8
-
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:###################################################################................................................................###################################################################
-D:###################################################################................................................................###################################################################
-D:###################################################################................................................................###################################################################
-D:###################################################################.....................#########...................#########......###################################################################
-D:###################################################################.......#########.....#########......#######......#########......###################################################################
-D:###################################################################.......#########.....####3####......#######......####1####......###################################################################
-D:###################################################################.......####4####....................#######.....................###################################################################
-D:###################################################################....................................###2###.....................###################################################################
-D:###################################################################................................................................###################################################################
-D:###################################################################.................................*..............................###################################################################
-D:###################################################################...##8##........................................................###################################################################
-D:###################################################################...#####..............####5####...................###7###.......###################################################################
-D:###################################################################...#####..............#########.....####6####.....#######.......###################################################################
-D:###################################################################...#####..............#########.....#########.....#######.......###################################################################
-D:###################################################################...........###9###....#########.....#########.....#######.......###################################################################
-D:###################################################################...........#######..................#########.....#######.......###################################################################
-D:###################################################################...........#######................................#######.......###################################################################
-D:###################################################################..................................................#######.......###################################################################
-D:###################################################################................................................................###################################################################
-D:###################################################################................................................................###################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-D:######################################################################################################################################################################################################
-
-############### Starting positions ###############
-
-# Standard starting position for normal races
-P:32:100
diff --git a/lib/edit/t_bree.txt b/lib/edit/t_bree.txt
index c74fd58a..3ea29922 100644
--- a/lib/edit/t_bree.txt
+++ b/lib/edit/t_bree.txt
@@ -44,9 +44,6 @@ F:a:74:3:0:0:0:0:0:58
# Soothsayer
F:c:74:3:0:0:0:0:0:12
-# Merchant Guild
-F:d:74:3:0:0:0:0:0:56
-
# The Mathom-house
F:e:74:3:0:0:0:0:0:57
@@ -93,7 +90,7 @@ D:# ---- ---- ,,CT--.B#.-SStSS-
D:# ------- ---- ,,CTT-....-sssss--,,,,,,-------------OO-,--SSSSSt-ss-,-,---...-T^^ ^ ^ -, OOOO #
D:# ------- ------ ,,CCTT---..#2###-,sssss,-SSSSSSSS-----OO,--ssssss-tS--,.....---^^ ^^ ^^^ -, OOOOOOOO #
D:# ----- ----- ,,CCT----..,,,,,-StSSS,-ssssssss------OOO-#1##a#-ss....-----T^^ ^^ -,- OOOOO #
-D:# ---- -------- ,,CCTT----..----,sssss,-##7###d#--------OO,.,,.,-##.----TTTT^^ ^ ^^ -, OOOOO #
+D:# ---- -------- ,,CCTT----..----,sssss,-##7#####--------OO,.,,.,-##.----TTTT^^ ^ ^^ -, OOOOO #
D:# --------------- ,,,CCTTTT--..---,##3##-,--,,,---------...OOOOOOOOOOOTTTTTCC^^^ ^^ ^^ ,- OOO #
D:# -------- ,,,CCCC --..........,-,,---,--.......-------TTTTTOCCCCC,,^^^^^^^^^^^ -.- OOOOO #
D:# ---------- ,, ,,CCCTT----------.....-......-------TTTTTTTCCCCO,,,,, ^^^^^^^ -.- O #
diff --git a/lib/edit/t_gondol.txt b/lib/edit/t_gondol.txt
index 779c4fbb..51cf4b39 100644
--- a/lib/edit/t_gondol.txt
+++ b/lib/edit/t_gondol.txt
@@ -123,9 +123,6 @@ F:m:74:3:0:0:0:0:0:37
# Thunderlord's Hide
F:n:74:3:0:0:0:0:0:22
-# Merchant guild
-F:o:74:3:0:0:0:0:0:56
-
# Force elven monsters
f:ELVEN
@@ -178,7 +175,7 @@ D:######$$$$$$$$$$$$$$$$$### ...
D:######$$$$$$$$$$$$$$$$$$## ... C##T.V#######V...........TTTT#######TTTT..................TT####C----,--TTT##TTT----TTT##TTTTTT------,,,,,^^^^###
D:#####$$$$$$$$$$$$$$$$$$$## ######### ... ############# CC#T.VV#####VV.............................................TTT#CC----,---TT#TT--------TT##T-T-TT------,,,,^^^^###
D:#####$$$$$$$#####$$$$$$$## ######### ... ############# C#T..VV###VV.....TTTTTTTTTTT.......TTTTTTTTTTT..............T#C-----,,,,,,,,,,,,,,,,,,,e#TT-TTT------,,,,^^^^###
-D:####$$$$#############$$$$# ########o.........7############ C#T...VVVVV....TTT#########TTT...TTT#########TTT............T#C----------T#TT--------TT##TTT-------,,,,^^^^^^###
+D:####$$$$#############$$$$# #########.........7############ C#T...VVVVV....TTT#########TTT...TTT#########TTT............T#C----------T#TT--------TT##TTT-------,,,,^^^^^^###
D:####$###################$# ######### ... ############# C#TT..........TT###VVVVVV####TT.TT####WWWWWW###TT..........TT#C--------TTT##TTT----TTT##TTTTT-----,,,,^^^^^^^###
D:########################## ######### ... ############# C##T..........T##VVV....VVV###TTT###WWW....WWW##T..........T##C-------TTTTT###TTTTTT###TTTTT-----,,,,,^^^^^^^###
D:########################### ... CC#T..........T#VV........VV#######WW........WW#T..........T#CC -----TTTT-TTT########TTTTTT------,,,,,,,^^^^^###
diff --git a/lib/edit/t_minas.txt b/lib/edit/t_minas.txt
index 51c74da3..9f6ae669 100644
--- a/lib/edit/t_minas.txt
+++ b/lib/edit/t_minas.txt
@@ -64,9 +64,6 @@ F:l:74:3:0:0:0:0:0:22
# Castle: Plot Minas Anor
F:B:75:3:0:0:0:0:0:5
-# Merchant guild
-F:m:74:3:0:0:0:0:0:56
-
# Library Quest
F:x:63:3
@@ -84,7 +81,7 @@ D:#^^----ssss-----###--------####------ ^^^^^^
D:#^^^---StSS-------###--#ssss--###------- ^^^^^^^^ @@VVVVVVVV@VVV@@@@@@@@ @@@V@@ @@@@VV@@@@ , #
D:#^^----ssss----OO---##--#StSS---####------ ^^^^^^^^ @@V@V,@@@@@@VVVVVVVV@@@VVV@ @@VVVV@@ ,, #
D:#^^----x#a#-----OOO--##--#sssss----###------ ^^^^^^^^ @@@@@ @@@@@@@@VVVVV@@@ @@@@VV@@@ ,,, #
-D:#^ ---------------OO--###-#m#7#------###----- ^^^^^^^^^^ @VVV@@ @@VVV@@ ,O, #
+D:#^ ---------------OO--###-###7#------###----- ^^^^^^^^^^ @VVV@@ @@VVV@@ ,O, #
D:#^ StSSSS-----ss---OO---##-----OOOOO---###---- ^^^^^^^^^^^ @@@ @@VVV@@ OO #
D:#^^ssssss----Ssss---OOO--##---OOOOOOOO---##---- ^l^^^^^^^ @@VVV@ OO #
D:#^ ####9#---sstSss---OOO--##-OOOOOOOOOOO--##---- ^^^^^ @@VVV@@ OO #
diff --git a/lib/file/elvish.txt b/lib/file/elvish.txt
deleted file mode 100644
index a00b5a22..00000000
--- a/lib/file/elvish.txt
+++ /dev/null
@@ -1,218 +0,0 @@
-216
-******** BUFFER LINE *********************************** DO NOT REMOVE *******
-adan
-ael
-in
-agl
-ar
-aina
-alda
-al
-qua
-am
-arth
-amon
-anca
-an
-dune
-anga
-anna
-ann
-on
-ar
-ien
-atar
-band
-bar
-ad
-bel
-eg
-brag
-ol
-breth
-il
-brith
-cal
-en
-gal
-en
-cam
-car
-ak
-cel
-eb
-cor
-on
-cu
-cui
-vie
-cul
-curu
-dae
-dag
-or
-del
-din
-dol
-dor
-draug
-du
-duin
-dur
-ear
-ech
-or
-edh
-el
-eith
-elen
-er
-ereg
-es
-gal
-fal
-as
-far
-oth
-faug
-fea
-fin
-for
-men
-fuin
-gaer
-gaur
-gil
-gir
-ith
-glin
-gol
-odh
-gond
-gor
-groth
-grod
-gul
-gurth
-gwaith
-gwath
-wath
-had
-hod
-haudh
-heru
-him
-hini
-hith
-hoth
-hyar
-men
-ia
-iant
-iath
-iaur
-ilm
-iluve
-kal
-gal
-kano
-kel
-kemen
-khel
-ek
-khil
-kir
-lad
-laure
-lhach
-lin
-lith
-lok
-lom
-lome
-londe
-los
-loth
-luin
-maeg
-mal
-man
-mel
-men
-menel
-mer
-eth
-min
-as
-mir
-mith
-mor
-moth
-nan
-nar
-naug
-dil
-dur
-nel
-dor
-nen
-nim
-orn
-orod
-os
-pal
-an
-pel
-quen
-quet
-ram
-ran
-rant
-ras
-rauko
-ril
-rim
-ring
-ris
-roch
-rom
-rond
-ros
-ruin
-ruth
-sarn
-ser
-eg
-sil
-sir
-sul
-tal
-dal
-tal
-ath
-tar
-tath
-ar
-taur
-tel
-thal
-thang
-thar
-thaur
-thin
-thol
-thon
-thor
-on
-til
-tin
-tir
-tol
-tum
-tur
-uial
-ur
-val
-wen
-wing
-yave
diff --git a/lib/help/advanced.hlp b/lib/help/advanced.hlp
index 3f6fe4bd..8595712b 100644
--- a/lib/help/advanced.hlp
+++ b/lib/help/advanced.hlp
@@ -7,9 +7,8 @@ Please choose one of the following help files:
*****/aoption.txt*0[(a) Options]
*****/bmacrofaq.txt*0[(b) Macros]
*****/cautomat.txt*0[(c) Automatizer help]
- (d) Lua scripting help - coming soon
- *****/edebug.txt*0[(e) Debug commands]
- *****/fversion.txt*0[(f) Version information] A history of ToME's roots
+ *****/ddebug.txt*0[(d) Debug commands]
+ *****/eversion.txt*0[(e) Version information] A history of ToME's roots
*****/zhelp.hlp*0[(z) Main Help menu]
diff --git a/lib/help/c_merch.txt b/lib/help/c_merch.txt
deleted file mode 100644
index 31fb60dd..00000000
--- a/lib/help/c_merch.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-#####R=== Merchants ===
-
-#####GDescription
-A Merchant is neither a warrior nor a spellcaster. They still have some great
-advantages, they can use chests to warp items into other items, they can
-indentify items, they soon learn to detect all objects in the area, and
-at higher level they can see all monsters carrying objects. They will also
-get the power to appraise items and to turn them into gold. A merchant will
-naturraly get better prices in shops and get access to the merchant guild
-services, loan and item request.
-
-#####GPrimary Stats
-Charisma
-Intelligence (Ability stat)
-
-#####GMagic Usage
-Merchants can use portable holes to carry more stuff than other classes but
-at the cost of an increased weight. To do that they must wear a portable hole
-and use it with 'm'.
-They also can use their merchants abilities and midas touch in the 'U' menu.
-
-#####GStarting Equipment
-A merchant begins the game with:
- A portable hole
- A small steel chest containing gold and items
- A long sword
- A wand of tame monsters
-
-
diff --git a/lib/help/command.txt b/lib/help/command.txt
index 2c2f1646..ee58a77e 100644
--- a/lib/help/command.txt
+++ b/lib/help/command.txt
@@ -137,7 +137,7 @@ that you can always, for example, use "\" + "." + "6", to specify "run east".
*****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit]
*****command.txt*76[. Run] ^Y (unused)
*****command.txt*77[> Go down staircase] ^Z (special - borg command)
- *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies]
+ *****command.txt*79[\ (special - bypass keymap)]
*****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge]
*****command.txt*83[/ Identify symbol] *****command.txt*84[? Help]
*****command.txt*98[^\] Take an html screenshot]
@@ -198,13 +198,13 @@ that you can always, for example, use "\" + "." + "6", to specify "run east".
*****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit]
*****command.txt*72[. Stay still (with pickup)] *****command.txt*95[^Y (tunnel - north west)]
*****command.txt*77[> Go down staircase] ^Z (special - borg command)
- *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies]
+ *****command.txt*79[\ (special - bypass keymap)]
*****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge]
*****command.txt*83[/ Identify symbol] *****command.txt*84[? Help]
~~~~~102|Commands|Special keys
#####R=== Special Keys ===
-
+
Certain special keys may be intercepted by the operating system or
the host machine, causing unexpected results. In general, these special keys
are control keys, and often, you can disable their special effects.
@@ -498,12 +498,7 @@ for a quantity will convert any "letters" into the maximal legal value.
each corresponding to a different location on the body, and each of
which may contain only a single object at a time, and each of which
may only contain objects of the proper "type".
- If the option "show_labels" is set, the slots are labelled as follows:
- Wielding (weapon), Shooting (missile launcher or instruments),
- On finger (ring), Around neck (amulet), Light source (light source),
- On body (armor), About body (cloak), On arm (shield), On head (helmet),
- On hands (gloves), On feet (boots), Carrying (symbiote), Quiver (ammo),
- Using (tool). You must be using an object to receive any of its special
+ You must be using an object to receive any of its special
powers.
~~~~~7
[[[[[GDrop an item (d)]
@@ -518,8 +513,7 @@ for a quantity will convert any "letters" into the maximal legal value.
[[[[[GDestroy an item (k) or Destroy an item (^D)]
This destroys an item in your inventory or on the dungeon floor.
If the selected pile contains multiple objects, you may specify
- a quantity. You must always verify this command, unless the item
- is cursed or worthless and the option "auto_destroy" is set.
+ a quantity. You must always verify this command.
~~~~~42
[[[[[GWear/Wield equipment (w)]
To wear or wield an object in your inventory, use this command.
@@ -1215,17 +1209,6 @@ for a quantity will convert any "letters" into the maximal legal value.
command allows the player to force the game to finish the current song
and move on to another one (i.e. if you are tired of hearing the current
song, you can change it).
-~~~~~80
-[[[[[GDo cmovies (|)]
- The cmovie command (press | key in both normal or roguelike set) allows
- you to make a "movie" that you can send to people showing your movement
- through a part of the dungeon (like clearing that GCV . . .)
-
- It asks for a name (it will add the extension itself) and then if you wish
- to play or record it.
-
- The cmovie files (.cmv) are located in lib/cmov, note that they quickly
- become huge and so you REALLY should compress them before sending to friends.
~~~~~97
[[[[[GRecord macros ($)]
This is an easier way to create macros. Activate it, press the key
diff --git a/lib/help/defines.txt b/lib/help/defines.txt
index ac997501..13609658 100644
--- a/lib/help/defines.txt
+++ b/lib/help/defines.txt
@@ -66,7 +66,6 @@ TV_BOOK 111 /* spell books */
~~~~~12|Svals
/* The "sval" codes for TV_TOOL */
SV_TOOL_CLIMB 0
- SV_PORTABLE_HOLE 1
~~~~~16
/* The "sval" codes for TV_SHOT/TV_ARROW/TV_BOLT */
SV_AMMO_LIGHT 0 /* pebbles */
diff --git a/lib/help/lua.hlp b/lib/help/lua.hlp
deleted file mode 100644
index ba61676a..00000000
--- a/lib/help/lua.hlp
+++ /dev/null
@@ -1,34 +0,0 @@
-|||||oy
-~~~~~01|Help|Lua scripting for ToME
-#####R Welcome to the ToME Lua Help System.
-#####R=============================================
-
-Please choose one of the following help files:
-
- *****/alua_intr.txt*0[(a) An Introduction to scripting]
- *****/blua_pow.txt*0[(b) Adding a racial power (the 'U' menu)]
- *****/clua_skil.txt*0[(c) Adding new skills (the 'm' menu)]
- *****/dlua_ques.txt*0[(d) Adding a quest]
-
-
- *****/elua_mon.txt*0[(e) Useful functions in monster.pkg]
- *****/flua_play.txt*0[(f) Useful functions in player.pkg]
- *****/glua_spel.txt*0[(g) Useful functions in spell.pkg]
- *****/hlua_util.txt*0[(h) Useful functions in util.pkg]
-
- *****/ilua_gf.txt*0[(g) A list of GF_FOO flags]
-
-
- *****/zhelp.hlp*0[(z) Main Help menu]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/help/lua_gf.txt b/lib/help/lua_gf.txt
deleted file mode 100644
index 000f4af5..00000000
--- a/lib/help/lua_gf.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-|||||oy
-#####R /--------------------------\
-#####R< A partial list of GF_FLAGS >
-#####R \--------------------------/
-
-GF_ARROW: arrows
-GF_MISSILE: magic missiles
-GF_MANA: mana
-GF_LITE_WEAK: light
-GF_DARK_WEAK: dark
-GF_WATER: water
-GF_PLASMA: plasma
-GF_METEOR: meteors
-GF_ICE: ice
-GF_GRAVITY: gravity
-GF_INERTIA: inertia
-GF_FORCE: force
-GF_TIME: pure time
-GF_ACID: acid
-GF_ELEC: lightning
-GF_FIRE: flames
-GF_COLD: cold
-GF_POIS: poison
-GF_LITE: pure light
-GF_DARK: pure dark
-GF_CONFUSION: confusion
-GF_SOUND: sound
-GF_SHARDS: shards
-GF_NEXUS: nexus
-GF_NETHER: nether
-GF_CHAOS: chaos
-GF_DISENCHANT: disenchantment
-GF_KILL_WALL: wall destruction
-GF_KILL_DOOR: door destruction
-GF_KILL_TRAP: trap destruction
-GF_STONE_WALL: wall creation
-GF_MAKE_DOOR: door creation
-GF_MAKE_TRAP: trap creation
-GF_DESTRUCTION: destruction
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
-
-
diff --git a/lib/help/lua_intr.txt b/lib/help/lua_intr.txt
deleted file mode 100644
index ccb87067..00000000
--- a/lib/help/lua_intr.txt
+++ /dev/null
@@ -1,133 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Scripting for ToME with lua >
-#####R \----------------------------------------/
-
-So, you want to patch ToME eh? Maybe you've had a look at how the edit files
-work, maybe even added your own race/class, but want to go further and add
-new racial (U) or magic (m) powers. Well these help files will show a little
-bit of how to do that.
-
-I am not a master at this kind of thing. I wrote a small script, with much
-help from DarkGod, and he subsequently asked me to write these help files. I
-was looking forward to when the lua help files came out so that I could look
-at them myself. Little did I know I'd be asked to write them. Therefore I
-apologise for any inaccuracies or errors that you find, and if you care to let
-me know of any improvements which could be made (especially if you're an
-experienced programmer/scripter), I'd love to know. Email me at
-[[[[[gfearoffours@moppy.co.uk].
-
-#####R=== The example scripts ===
-
-These help files take the form of a tutorial, adding a line at a time to a
-script, and explaining important concepts along the way. To see it all in
-action, I strongly suggest that you download my example script pack from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm]. As well as including all the
-scripts covered in these help files, they also include the addition of my
-"hina" race which has a Lua scripted racial power which you might like to look
-at. There's also a quest which I will be including documentation for as a
-tutorial soon. Plus there's all the other lua scripts in the lib\scpt
-directory to look at. Most of what you see in these files has been learned from
-those files anyway!
-
-The source code is invaluable as well. There's a searchable and browsable
-version of the latest ToME source code available online at
-[[[[[Ghttp://www.t-o-m-e.net/cvs.php]. Use it!
-
-If you don't want to download and install the example scripts, then just
-follow the tutorials with a text editor open! But I'll say it again, it's a lot
-easier if you download and install the example scripts.
-
-This file goes on to explain the concepts of scripting, programming,
-variables and functions. If you're familiar with these concepts, you might
-as well take a look at how to add a power to the U menu in the
-*****lua_pow.txt*0[Scripting a racial power] file.
-
-
-#####R=== Defining some basic stuff ===
-
-Computers don't do anything that they're not told to do. When we script, or
-program, we must assume they know nothing. We have to tell them each little
-bit of information from the ground up.
-
-A program, or a script (we'll talk about exact differences later) is like a
-set of instructions. Let's imagine that people responded to programs, and
-that we had a program called "Housework". Its series of instructions might
-look something like this:
-
-#####BDo the Washing up.
-#####BClean the kitchen.
-#####BDust the shelves.
-#####BHoover the lounge.
-
-Each step above could be called a function, as they are all actions that
-need to be carried out. Now to you and me, we'd understand that program just
-fine, but if someone didn't know HOW to wash, or what hoovering was, they'd
-soon run into problems. For those people we'd need to define each function
-clearly. Thus "do the washing up" might be -
-
-#####BRun hot water into bowl.
-#####BAdd washing up liquid.
-#####BPut dirty plates into bowl
-#####BScrub plates till clean
-#####BPlace clean plates on rack to dry,
-
-There's still plenty of problems here though. We've not said to turn the tap
-off, or what the bowl is, or to wash any dirty cutlery, mugs, saucepans, etc.,
-etc. Whilst this might seem fairly obvious to a person, this is how we need
-to think when writing programs for computers.
-
-Lets look now at some of the terms we're going to be using, in the rest of
-these help files, and what they mean...
-
-#####R=== Variables and Constants ===
-A variable is a way to store information in a computer. Just as you store
-things in your own memory, you can store things in the computer's memory. And
-just as things change in your memory, so things can change in the computer's
-memory. This factor of change is why they're called "variables" and not
-"statics".
-
-For instance, you may have a friend's email address committed to memory, but
-things change over time, they get a new ISP or domain, and so their email
-address changes. You commit this new address to memory, and eventually
-forget the old one. The thing you have stored in your memory is the same
-(your friend's address) but the value (property) of what you have stored has
-changed (from friend@old-address.com to friend@new-address.com).
-
-Variables are the building blocks out of which you will create your patch.
-
-A variable which will *never* change its value is called a constant.
-
-#####R===Functions===
-
-A function is a series of steps or statements, grouped together and given
-one name. When you want to carry out those steps, you simply ask the
-computer to carry out that function. To go back to our original example,
-rather than saying, "I'd like you to run some hot water into a bowl, add the
-washing up liquid, put the dirty plates into it, and then scrub them till
-they're clean", we just say "do the washing up".
-
-This is where we come to the difference between scripting and programming.
-With scripting we can use the functions and variables that exist in the
-ToME code. Maintainers like DarkGod have already made sure that the
-computer knows how to "do the washing up", including turning the tap off and
-what the bowl is. All we need to do in our script is say "do the washing
-up". Or to look at it in a more relevant way, the game has been coded so
-that when a magic missile is fired, a bolt or beam spell with a black line
-of asterisks will be drawn in the direction indicated by the player, the
-mana of that spell will be used up, the monster will take the appropriate
-amount of damage, and so on. All we need to do in our script is say "fire a
-magic missile".
-
-As you script, you will still be designing your own functions, and
-variables, but the hardest parts have been done for you!
-
-Not every function and global variable in the source-code has been exported to
-use in your scripting. But the ones that have are easily identifiable by
-looking in any source files with the extension .pkg . Chris Hadgis has written
-some excellent documentation which outline the use of the most important
-functions in some of these files. They outline the functions from the
-
-OK, the first tutorial proper is on *****lua_pow.txt*0[adding a racial power] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/help/lua_mon.txt b/lib/help/lua_mon.txt
deleted file mode 100644
index 9bb363c0..00000000
--- a/lib/help/lua_mon.txt
+++ /dev/null
@@ -1,535 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < monster.pkg functions helper file >
-#####R \----------------------------------------/
-
-
-----------------------------------------------------------------------
-
-#####R=== race_info_idx ===
-
-#####GDeclaration
- extern monster_race* race_info_idx(int r_idx, int ego);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Return a (monster_race*) with the combinations of the monster
- * properties and the ego type
- */
-
-#####GDescription
-Get monster info and ego info for monster with monster index "r_idx"
-and monster ego "ego". The ego information is applied to the monster
-information and the new monster information is returned.
-
-For example, race_info_idx(141,7) will create a brown yeek (monster)
-shaman (ego).
-
-#####GParameters
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-
-----------------------------------------------------------------------
-
-#####R=== delete_monster_idx ===
-
-#####GDeclaration
- extern void delete_monster_idx(int i);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Delete a monster by index.
- *
- * When a monster is deleted, all of its objects are deleted.
- */
-
-#####GDescription
-Delete monster "i" from the monster array.
-
-#####GParameters
-> "i" is the index for the monster list (m_list[]). Beware: there is
- no range checking.
-
-----------------------------------------------------------------------
-
-#####R=== m_pop ===
-
-#####GDeclaration
- extern s16b m_pop(void);
-
-#####GFile
- monsters2.c
-
-#####GComment
-/*
- * Acquires and returns the index of a "free" monster.
- *
- * This routine should almost never fail, but it *can* happen.
- */
-
-#####GDescription
-Get an empty slot in the monster list (m_list[]). If there are no
-empty slots, a slot will be reclaimed from a "dead" monster. If all
-slots are full, 0 is returned, which means the function has failed
-("Too many monsters!").
-
-----------------------------------------------------------------------
-
-#####R=== get_mon_num_prep ===
-
-#####GDeclaration
- extern errr get_mon_num_prep(void);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Apply a "monster restriction function" to the "monster allocation table"
- */
-
-#####GDescription
-There are no parameters, but there are some other variables which will
-need to be set. They are get_mon_num_hook and get_mon_num2_hook. They
-are pointers to functions.
-
-For example, get_mon_num_hook = monster_volcano means when
-get_mon_num_hook is called (*get_mon_num_hook)(index), the actual
-function called is monster_volcano(index). This particular function
-returns TRUE if the monster indicated by "index" has the
-RF8_WILD_VOLCANO flag set.
-
-It is a good idea to store the old value of get_mon_num_hook before
-setting a new one, and restoring it when your function is finished.
-
-Following is a list of functions which can be assigned to
-get_mon_num_hook:
-
-create_molds_hook
-create_townpeople_hook
-mon_hook_bounty
-monster_dungeon
-monster_grass
-monster_mountain
-monster_ocean
-monster_quest
-monster_shore
-monster_town
-monster_volcano
-monster_waste
-monster_wood
-mutate_monster_okay
-place_monster_okay
-summon_specific_okay
-vault_aux_animal
-vault_aux_chapel
-vault_aux_clone
-vault_aux_demon
-vault_aux_dragon
-vault_aux_giant
-vault_aux_jelly
-vault_aux_kennel
-vault_aux_orc
-vault_aux_symbol
-vault_aux_treasure
-vault_aux_troll
-vault_aux_undead
-
-Or you can write your own. The function must take an integer (index)
-as a parameter and return boolean (TRUE if the monster is selected,
-or FALSE if it is not).
-
-----------------------------------------------------------------------
-
-#####R=== get_mon_num ===
-
-#####GDeclaration
- extern s16b get_mon_num(int level);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Choose a monster race that seems "appropriate" to the given level
- *
- * This function uses the "prob2" field of the "monster allocation table",
- * and various local information, to calculate the "prob3" field of the
- * same table, which is then used to choose an "appropriate" monster, in
- * a relatively efficient manner.
- *
- * Note that "town" monsters will *only* be created in the town, and
- * "normal" monsters will *never* be created in the town, unless the
- * "level" is "modified", for example, by polymorph or summoning.
- *
- * There is a small chance (1/50) of "boosting" the given depth by
- * a small amount (up to four levels), except in the town.
- *
- * It is (slightly) more likely to acquire a monster of the given level
- * than one of a lower level. This is done by choosing several monsters
- * appropriate to the given level and keeping the "hardest" one.
- *
- * Note that if no monsters are "appropriate", then this function will
- * fail, and return zero, but this should *almost* never happen.
- */
-
-Description:
-For the given level "level", return the index of an appropriate
-monster race.
-
-#####GParameters
-> "level" is a dungeon level
-
-----------------------------------------------------------------------
-
-#####R=== monster_desc ===
-
-#####GDeclaration
- extern void monster_desc(char *desc, monster_type *m_ptr,
- int mode);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Build a string describing a monster in some way.
- *
- * We can correctly describe monsters based on their visibility.
- * We can force all monsters to be treated as visible or invisible.
- * We can build nominatives, objectives, possessives, or reflexives.
- * We can selectively pronominalize hidden, visible, or all monsters.
- * We can use definite or indefinite descriptions for hidden monsters.
- * We can use definite or indefinite descriptions for visible monsters.
- *
- * Pronominalization involves the gender whenever possible and allowed,
- * so that by cleverly requesting pronominalization / visibility, you
- * can get messages like "You hit someone. She screams in agony!".
- *
- * Reflexives are acquired by requesting Objective plus Possessive.
- *
- * If no m_ptr arg is given (?), the monster is assumed to be hidden,
- * unless the "Assume Visible" mode is requested.
- *
- * If no r_ptr arg is given, it is extracted from m_ptr and r_info
- * If neither m_ptr nor r_ptr is given, the monster is assumed to
- * be neuter, singular, and hidden (unless "Assume Visible" is set),
- * in which case you may be in trouble... :-)
- *
- * I am assuming that no monster name is more than 70 characters long,
- * so that "char desc[80];" is sufficiently large for any result.
- *
- * Mode Flags:
- * 0x01 --> Objective (or Reflexive)
- * 0x02 --> Possessive (or Reflexive)
- * 0x04 --> Use indefinites for hidden monsters ("something")
- * 0x08 --> Use indefinites for visible monsters ("a kobold")
- * 0x10 --> Pronominalize hidden monsters
- * 0x20 --> Pronominalize visible monsters
- * 0x40 --> Assume the monster is hidden
- * 0x80 --> Assume the monster is visible
- *
- * Useful Modes:
- * 0x00 --> Full nominative name ("the kobold") or "it"
- * 0x04 --> Full nominative name ("the kobold") or "something"
- * 0x80 --> Genocide resistance name ("the kobold")
- * 0x88 --> Killing name ("a kobold")
- * 0x22 --> Possessive, genderized if visible ("his") or "its"
- * 0x23 --> Reflexive, genderized if visible ("himself") or "itself"
- */
-
-#####GDescription
-Return a monster description "desc" for monster "monster_type" using
-flag "mode". The modes are described above.
-
-#####GParameters
-> "desc" is the returned description.
-> "monster type" is the monster (monster pointer).
-> "mode" is one of the modes described in the comments.
-
-----------------------------------------------------------------------
-
-#####R=== monster_race_desc ===
-
-#####GDeclaration
- extern void monster_race_desc(char *desc, int r_idx,
- int ego);
-
-#####GFile
- monster2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the monster description "desc" for monster with monster index
-"r_idx" and monster ego "ego". The monster description is made up of
-the ego name (if any) and monster name, or the unique name.
-
-#####GParameters
-> "desc" is the returned description.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-
-----------------------------------------------------------------------
-
-#####R=== place_monster_aux ===
-
-#####GDeclaration
- extern bool place_monster_aux(int y, int x, int r_idx,
- bool slp, bool grp, int status);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Attempt to place a monster of the given race at the given location
- *
- * Note that certain monsters are now marked as requiring "friends".
- * These monsters, if successfully placed, and if the "grp" parameter
- * is TRUE, will be surrounded by a "group" of identical monsters.
- *
- * Note that certain monsters are now marked as requiring an "escort",
- * which is a collection of monsters with similar "race" but lower
- * level.
- *
- * Some monsters induce a fake "group" flag on their escorts.
- *
- * Note the "bizarre" use of non-recursion to prevent annoying output
- * when running a code profiler.
- *
- * Note the use of the new "monster allocation table" code to restrict
- * the "get_mon_num()" function to "legal" escort types.
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster has monster
-index "m_idx". The monster may be asleep ("slp"). The monster may be
-surrounded by a group of identical monsters ("grp"). The monster has
-a status of "status" (see below). The function returns TRUE if the
-monster is placed successfully, otherwise FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "grp" is TRUE if the monster is surrounded by a group, otherwise
- FALSE.
-> "status" is the status of the monster
- *****fields.txt*0[status]
-
-----------------------------------------------------------------------
-
-#####R=== place_monster ===
-
-#####GDeclaration
- extern bool place_monster(int y, int x, bool slp,
- bool grp);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Hack -- attempt to place a monster at the given location
- *
- * Attempt to find a monster appropriate to the "monster_level"
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster may be asleep
-("slp"). The monster may be surrounded by a group of identical
-monsters ("grp"). The monster is of the appropriate monster level. The
-function returns TRUE if the monster is placed successfully, otherwise
-FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "grp" is TRUE if the monster is surrounded by a group, otherwise
- FALSE.
-
-----------------------------------------------------------------------
-
-#####R=== place_monster_one ===
-
-#####GDeclaration
- extern s16b place_monster_one(int y, int x, int r_idx,
- int ego, bool slp, int status);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Attempt to place a monster of the given race at the given location.
- *
- * To give the player a sporting chance, any monster that appears in
- * line-of-sight and is extremely dangerous can be marked as
- * "FORCE_SLEEP", which will cause them to be placed with low energy,
- * which often (but not always) lets the player move before they do.
- *
- * This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.
- *
- * XXX XXX XXX Use special "here" and "dead" flags for unique monsters,
- * remove old "cur_num" and "max_num" fields.
- *
- * XXX XXX XXX Actually, do something similar for artifacts, to simplify
- * the "preserve" mode, and to make the "what artifacts" flag more useful.
- *
- * This is the only function which may place a monster in the dungeon,
- * except for the savefile loading code.
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster has monster
-index "m_idx". The monster may be asleep ("slp"). The monster may have
-an ego type ("ego"). The monster has a status of "status" (see below).
-The function returns TRUE if the monster is placed successfully,
-otherwise FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-> "status" is the status of the monster
- *****fields.txt*0[status]
-
-----------------------------------------------------------------------
-
-#####R=== is_friend ===
-
-#####GDeclaration
- extern int is_friend(monster_type *m_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-/*
- * Is the monster in friendly state(pet, friend, ..)
- * -1 = enemy, 0 = neutral, 1 = friend
- */
-
-#####GDescription
-Return a value to indicate the status of monster "m_ptr".
- *****fields.txt*0[status]
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-
-----------------------------------------------------------------------
-
-#####R=== is_enemy ===
-
-#####GDeclaration
- extern bool is_enemy(monster_type *m_ptr,
- monster_type *t_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-/* Should they attack each others */
-
-#####GDescription
-Return TRUE if monster "m_ptr" should attack monster "t_ptr". If
-"m_ptr" is stupid and "r_ptr" is a different type of monster then the
-function will return TRUE. If "m_ptr" is not neutral and "r_ptr" is a
-breeder, and "r_ptr" is a different type of monster then the function
-will return TRUE (and vice versa). If both monsters are not neutral
-and one is friendly and the other isn't then the function will return
-TRUE. Otherwise the function returns FALSE.
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-> "t_ptr" is a pointer to a monster (target).
-
-----------------------------------------------------------------------
-
-#####R=== change_side ===
-
-#####GDeclaration
- extern bool change_side(monster_type *m_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-(none)
-
-#####GDescription
-Change the status of monster "m_ptr" from friendly to unfriendly and
-vice versa. Friends and pets become enemies. Neutral Ms become
-neutral Ps and vice versa. Companions are unaffected. The
-function returns TRUE if the status changed, otherwise FALSE.
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-
-----------------------------------------------------------------------
-
-#####R=== find_position ===
-
-#####GDeclaration
- extern void find_position(int y, int x, int *yy = 0,
- int *xx = 0);
-
-#####GFile
- lua_bind.c
-
-#####GComment
-(none)
-
-#####GDescription
-Find a new grid "yy", "xx" within 6 grids of target grid "y", "x".
-The new grid must be within line-of-sight of the target grid. A
-maximum of 5000 attempts is made.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "yy" is the y co-ordinate of the new grid.
-> "xx" is the x co-ordinate of the new grid.
-
-----------------------------------------------------------------------
-
-#####R=== can_create_companion ===
-
-#####GDeclaration
- extern bool can_create_companion();
-
-#####GFile
- monster3.c
-
-#####GComment
-/* Returns if a new companion is allowed */
-
-#####GDescription
-Return TRUE if a companion can be created, otherwise FALSE.
-
-----------------------------------------------------------------------
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
diff --git a/lib/help/lua_play.txt b/lib/help/lua_play.txt
deleted file mode 100644
index 6ab64ddb..00000000
--- a/lib/help/lua_play.txt
+++ /dev/null
@@ -1,1225 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < player.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####RFunction: set_parasite
-
-#####GDeclaration: bool set_parasite(int v, int r);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until parasite with monster index "r" is created. The
-player gets the message "You feel something growing in you" if "v"
-is > 0. Otherwise the player gets the message "Your body convulse
-and spawn <monster name>" if the monster is created (80% chance) or
-"The hideous thing growing in you seems to die" if the monster dies.
-
-#####GParameters:
->v is the time until the parasite gestates (must be between 0 and
- 10000).
->r is the monster index of parasite to be created.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_disrupt_shield
-
-#####GDeclaration: bool set_disrupt_shield(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->disrupt_shield"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until shield of invulnerability expires. The player gets
-the message "You feel invulnerable" if "v" is > 0. Otherwise the
-player gets the message "You are more vulnerable".
-
-#####GParameters:
->v is the time until the shield expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_prob_travel
-
-#####GDeclaration: bool set_prob_travel(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->prob_travel"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until random teleportation expires. The player gets
-the message "You feel instable" if "v" is > 0. Otherwise the
-player gets the message "You are more stable".
-
-#####GParameters:
->v is the time until random teleportation expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_deadly
-
-#####GDeclaration: bool set_tim_deadly(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_deadly"
-*/
-
-#####GDescription:
-Set time "v" until deadly accuracy expires. The player gets the
-message "You feel extremely accurate" if "v" is > 0. Otherwise the
-player gets the message "You are suddenly much less accurate".
-
-#####GParameters:
->v is the time until deadly accuracy expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_res_time
-
-#####GDeclaration: bool set_tim_res_time(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_res_time"
-*/
-
-#####GDescription:
-Set time "v" until space-time distortions expire. The player gets the
-message "You are now protected against the space-time distortions" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the space-time distortions".
-
-#####GParameters:
->v is the time until space-time distortions expire (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_reflect
-
-#####GDeclaration: bool set_tim_reflect(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_reflect"
-*/
-
-#####GDescription:
-Set time "v" until reflection expire. The player gets the message
-"You start reflecting the world around you" if "v" is > 0. Otherwise
-the player gets the message "You stop reflecting".
-
-#####GParameters:
->v is the time until reflection expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_meditation
-
-#####GDeclaration: bool set_meditation(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->meditation"
-*/
-
-#####GDescription:
-Set time "v" until meditation expire. The player gets the message
-"You start meditating on yourself" if "v" is > 0. Otherwise the
-player gets the message "You stop your self meditation".
-
-#####GParameters:
->v is the time until meditation expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_strike
-
-#####GDeclaration: bool set_strike(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->strike"
-*/
-
-#####GDescription:
-Set time "v" until accurate strikes expire. The player gets the
-message "You feel very accurate" if "v" is > 0. Otherwise the player
-gets the message "You are no longer very accurate".
-
-#####GParameters:
->v is the time until accurate strikes expire (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_walk_water
-
-#####GDeclaration: bool set_walk_water(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->walk_water", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until walking on water expires. The player gets the
-message "You feel strangely insubmersible" if "v" is > 0. Otherwise
-the player gets the message "You are no longer insubmersible".
-
-#####GParameters:
->v is the time until walking on water expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_ffall
-
-#####GDeclaration: bool set_tim_ffall(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_ffall"
-*/
-
-#####GDescription:
-Set time "v" until feather-fall expires. The player gets the message
-"You feel very light" if "v" is > 0. Otherwise the player gets the
-message "You are suddenly heavier".
-
-#####GParameters:
->v is the time until feather-fall expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_fire_aura
-
-#####GDeclaration: bool set_tim_fire_aura(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_fire_aura"
-*/
-
-#####GDescription:
-Set time "v" until fiery aura expires. The player gets the message
-"You are enveloped in flames" if "v" is > 0. Otherwise the player
-gets the message "You are no longer enveloped in flames".
-
-#####GParameters:
->v is the time until fiery aura expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_holy
-
-#####GDeclaration: bool set_holy(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->holy", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until holiness expires. The player gets the message
-"You feel a holy aura around you" if "v" is > 0. Otherwise the
-player gets the message "The holy aura vanishes".
-
-#####GParameters:
->v is the time until holiness expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_grace
-
-#####GDeclaration: void set_grace(s32b v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->grace", notice observable changes
-*/
-
-#####GDescription:
-Set grace to value "v". Don't allow grace to fall below -30000 or
-rise above 30000.
-
-#####GParameters:
->v is the value of grace.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_mimic
-
-#####GDeclaration: bool set_mimic(int v, int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_mimic", and "p_ptr->mimic_form",
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until morph into monster with monster index "p" expires.
-The player gets the message "You feel your body change" if "v" is > 0.
-Otherwise the player gets the message "You are no longer transformed".
-
-#####GParameters:
->v is the time until transformation expires (must be between 0 and
- 10000).
->p is the monster index of the monster the player wants to mimic.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_no_breeders
-
-#####GDeclaration: bool set_no_breeders(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "no_breeds"
-*/
-
-#####GDescription:
-Set time "v" until breeders can breed again. The player gets the
-message "You feel an anti-sexual aura" if "v" is > 0. Otherwise the
-player gets the message "You no longer feel an anti-sexual aura".
-Okay...
-
-#####GParameters:
->v is the time until breeders can breed again (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_invis
-
-#####GDeclaration: bool set_invis(int v,int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow",
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until invisibility expires. The player gets the message
-"You feel your body fade away" if "v" is > 0. Otherwise the player
-gets the message "You are no longer invisible".
-
-#####GParameters:
->v is the time until invisibility expires (must be between 0 and
- 10000).
->p is the power of timed invisibility.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_lite
-
-#####GDeclaration: bool set_lite(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_lite", notice observable changes
-*
-* Note the use of "PU_VIEW", which is needed to
-* memorise any terrain features which suddenly become "visible".
-* Note that blindness is currently the only thing which can affect
-* "player_can_see_bold()".
-*/
-
-#####GDescription:
-Set time "v" until brightness expires. The player gets the message
-"You suddenly seem brighter" if "v" is > 0. Otherwise the player
-gets the message "You are no longer bright".
-
-#####GParameters:
->v is the time until brightness expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_blind
-
-#####GDeclaration: bool set_blind(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->blind", notice observable changes
-*
-* Note the use of "PU_UN_VIEW", which is needed to memorise any terrain
-* features which suddenly become "visible".
-* Note that blindness is currently the only thing which can affect
-* "player_can_see_bold()".
-*/
-
-#####GDescription:
-Set time "v" until blindness expires. The player gets the message "You
-are blind" if "v" is > 0. Otherwise the player gets the message "You
-can see again".
-
-#####GParameters:
->v is the time until blindness expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_confused
-
-#####GDeclaration: bool set_confused(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->confused", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until confusion expires. The player gets the message "You
-are confused" if "v" is > 0. Otherwise the player gets the message
-"You feel less confused now".
-
-#####GParameters:
->v is the time until confusion expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_poisoned
-
-#####GDeclaration: bool set_poisoned(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->poisoned", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until poison expires. The player gets the message "You
-are poisoned" if "v" is > 0. Otherwise the player gets the message
-"You are no longer poisoned".
-
-#####GParameters:
->v is the time until poison expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_afraid
-
-#####GDeclaration: bool set_afraid(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->afraid", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until fear expires. The player gets the message "You are
-terrified" if "v" is > 0. Otherwise the player gets the message "You
-feel bolder now".
-
-#####GParameters:
->v is the time until fear expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_paralyzed
-
-#####GDeclaration: bool set_paralyzed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->paralyzed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until paralysis expires. The player gets the message "You
-are paralyzed" if "v" is > 0. Otherwise the player gets the message
-"You can move again".
-
-#####GParameters:
->v is the time until paralysis expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_image
-
-#####GDeclaration: bool set_image(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->image", notice observable changes
-*
-* Note that we must redraw the map when hallucination changes.
-*/
-
-#####GDescription:
-Set time "v" until hallucination expires. The player gets the message
-"Oh, wow! Everything looks so cosmic now" if "v" is > 0. Otherwise
-the player gets the message "You can see clearly again".
-
-#####GParameters:
->v is the time until hallucination expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_fast
-
-#####GDeclaration: bool set_fast(int v, int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-(none)
-
-#####GDescription:
-Set time "v" until speed of speed factor "p" expires. The player gets
-the message "You feel yourself moving faster" if "v" is > 0. Otherwise
-the player gets the message "You feel yourself slow down".
-
-#####GParameters:
->v is the time until speed expires (must be between 0 and 10000).
->p is the speed factor.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_light_speed
-
-#####GDeclaration: bool set_light_speed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->lightspeed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until light-speed expires. The player gets the message
-"You feel as if time has stopped" if "v" is > 0. Otherwise the player
-gets the message "You feel time returning to its normal rate".
-
-#####GParameters:
->v is the time until light-speed expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_slow
-
-#####GDeclaration: bool set_slow(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->slow", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until slowness expires. The player gets the message "You
-feel yourself moving slower" if "v" is > 0. Otherwise the player gets
-the message "You feel yourself speed up".
-
-#####GParameters:
->v is the time until slowness expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_shield
-
-#####GDeclaration: bool set_shield(int v, int p, s16b o, s16b d1, s16b d2);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->shield", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until stone-shield expires. The player gets the message
-"Your skin turns to stone" if "v" is > 0. Otherwise the player gets
-the message "Your skin returns to normal". Stone-shield has spell
-power "p", spell option "o", and power options "d1" and "d2".
-
-#####GParameters:
->v is the time until stone-shield expires (must be between 0 and
- 10000).
->p is the power of the stone-shield spell.
->o is the option of the stone-shield spell.
->d1 is the power for option 1 of the stone-shield spell.
->d2 is the power for option 2 of the stone-shield spell.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_blessed
-
-#####GDeclaration: bool set_blessed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->blessed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until blessing expires. The player gets the message "You
-feel righteous" if "v" is > 0. Otherwise the player gets the message
-"The prayer has expired".
-
-#####GParameters:
->v is the time until blessing expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_hero
-
-#####GDeclaration: bool set_hero(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->hero", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until heroism expires. The player gets the message "You
-feel like a hero" if "v" is > 0. Otherwise the player gets the
-message "The heroism wears off".
-
-#####GParameters:
->v is the time until heroism expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_shero
-
-#####GDeclaration: bool set_shero(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->shero", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until berserk expires. The player gets the message "You
-feel like a killing machine" if "v" is > 0. Otherwise the player gets
-the message "You feel less Berserk".
-
-#####GParameters:
->v is the time until berserk expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protevil
-
-#####GDeclaration: bool set_protevil(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protevil", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from evil expires. The player gets the
-message "You feel safe from evil" if "v" is > 0. Otherwise the player
-gets the message "You no longer feel safe from evil".
-
-#####GParameters:
->v is the time until protection from evil expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protgood
-
-#####GDeclaration: bool set_protgood(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protgood", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from good expires. The player gets the
-message "You feel safe from good" if "v" is > 0. Otherwise the player
-gets the message "You no longer feel safe from good".
-
-#####GParameters:
->v is the time until protection from evil expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protundead
-
-#####GDeclaration: bool set_protundead(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protundead", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from undead expires. The player gets the
-message "You feel safe from undead" if "v" is > 0. Otherwise the
-player gets the message "You no longer feel safe from undead".
-
-#####GParameters:
->v is the time until protection from undead expires (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_invuln
-
-#####GDeclaration: bool set_invuln(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->invuln", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until invulnerability expires. The player gets the
-message "Invulnerability" if "v" is > 0. Otherwise the player gets
-the message "The invulnerability wears off".
-
-#####GParameters:
->v is the time until invulnerability expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_invis
-
-#####GDeclaration: bool set_tim_invis(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_invis", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until see invisible expires. The player gets the message
-"Your eyes feel very sensitive" if "v" is > 0. Otherwise the player
-gets the message "Your eyes feel less sensitive".
-
-#####GParameters:
->v is the time until see invisible expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_infra
-
-#####GDeclaration: bool set_tim_infra(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_infra", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until infravision expires. The player gets the message
-"Your eyes begin to tingle" if "v" is > 0. Otherwise the player gets
-the message "Your eyes stop tingling".
-
-#####GParameters:
->v is the time until infravision expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_mental_barrier
-
-#####GDeclaration: bool set_mental_barrier(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_mental_barrier", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until mental barrier expires. The player gets the message
-"Your mind grows stronger" if "v" is > 0. Otherwise the player gets
-the message "Your mind is no longer especially strong".
-
-#####GParameters:
->v is the time until mental barrier expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_acid
-
-#####GDeclaration: bool set_oppose_acid(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-
-#####GDescription:
-Set time "v" until feather-fall expires. The player gets the message
-"You feel very light" if "v" is > 0. Otherwise the player gets the
-message "You are suddenly heavier".
-
-#####GParameters:
->v is the time until feather-fall expires (must be between 0 and
- 10000).
->v is the time until feather-fall expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_elec
-
-#####GDeclaration: bool set_oppose_elec(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_elec", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until electricity resistance expires. The player gets
-the message "You feel resistant to electricity" if "v" is > 0.
-Otherwise the player gets the message "You feel less resistant to
-electricity".
-
-#####GParameters:
->v is the time until electricity resistance expires (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_fire
-
-#####GDeclaration: bool set_oppose_fire(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_fire", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until fire resistance expires. The player gets the
-message "You feel resistant to fire" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to fire".
-
-#####GParameters:
->v is the time until fire resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_cold
-
-#####GDeclaration: bool set_oppose_cold(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_cold", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until cold resistance expires. The player gets the
-message "You feel resistant to cold" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to cold".
-
-#####GParameters:
->v is the time until cold resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_pois
-
-#####GDeclaration: bool set_oppose_pois(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_pois", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until poison resistance expires. The player gets the
-message "You feel resistant to poison" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to poison".
-
-#####GParameters:
->v is the time until poison resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_ld
-
-#####GDeclaration: bool set_oppose_ld(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_ld"
-*/
-
-#####GDescription:
-Set time "v" until light and dark resistance expires. The player gets
-the message "You feel protected against the light's fluctuation" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the light's fluctuation".
-
-#####GParameters:
->v is the time until light and dark resistance expires (must be
- between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_cc
-
-#####GDeclaration: bool set_oppose_cc(int v);
-
-#####GFile: xtra2.c
-/*
-* Set "p_ptr->oppose_cc"
-*/
-
-#####GComment:
-
-#####GDescription:
-Set time "v" until chaos resistance expires. The player gets the
-message "You feel protected against raw chaos" if "v" is > 0.
-Otherwise the player gets the message "You are no longer protected
-against chaos".
-
-#####GParameters:
->v is the time until chaos resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_ss
-
-#####GDeclaration: bool set_oppose_ss(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_ss"
-*/
-
-#####GDescription:
-Set time "v" until sound and shard resistance expires. The player gets
-the message "You feel protected against the ravages of sound and
-shards" if "v" is > 0. Otherwise the player gets the message "You are
-no longer protected against the ravages of sound and shards".
-
-#####GParameters:
->v is the time until sound and shard resistance expires (must be
- between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_nex
-
-#####GDeclaration: bool set_oppose_nex(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_nex"
-*/
-
-#####GDescription:
-Set time "v" until nexus resistance expires. The player gets the
-message "You feel protected against the strange forces of nexus" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the strange forces of nexus".
-
-#####GParameters:
->v is the time until nexus resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_stun
-
-#####GDeclaration: bool set_stun(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->stun", notice observable changes
-*
-* Note the special code to only notice "range" changes.
-*/
-
-#####GDescription:
-Set stun level "v". If the player race can't be stunned then the level
-is forced to 0. A value > 100 means the player is knocked out. A value
->50 is a heavy stun. A value > 0 is a stun. If the stun level has
-increased, a message is printed. There is a small chance of stun level
-in 1000, or a 1 in 16 chance of a vicious blow which decreases
-intelligence and/or wisdom for a while.
-
-#####GParameters:
->v is the stun level.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_cut
-
-#####GDeclaration: bool set_cut(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->cut", notice observable changes
-*
-* Note the special code to only notice "range" changes.
-*/
-
-#####GDescription:
-Set cut level "v". If the player race can't be cut then the time is
-forced to 0. A value > 1000 is a mortal wound. A value > 200 is a deep
-gash. A value > 100 is a severe cut. A value > 50 is a nasty cut. A
-value > 25 is a bad cut. A value > 10 is a light cut. A value > 0 is a
-graze. If the cut level has increased, a message is printed. There is
-a small chance of stun level in 1000, or a 1 in 16 chance of scarring
-which decreases charisma for a while.
-
-#####GParameters:
->v is the cut level.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_food
-
-#####GDeclaration: bool set_food(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->food", notice observable changes
-*
-* The "p_ptr->food" variable can get as large as 20000, allowing the
-* addition of the most "filling" item, Elvish Waybread, which adds
-* 7500 food units, without overflowing the 32767 maximum limit.
-*
-* Perhaps we should disturb the player with various messages,
-* especially messages about hunger status changes. XXX XXX XXX
-*
-* Digestion of food is handled in "dungeon.c", in which, normally,
-* the player digests about 20 food units per 100 game turns, more
-* when "fast", more when "regenerating", less with "slow digestion",
-* but when the player is "gorged", he digests 100 food units per 10
-* game turns, or a full 1000 food units per 100 game turns.
-*
-* Note that the player's speed is reduced by 10 units while gorged,
-* so if the player eats a single food ration (5000 food units) when
-* full (15000 food units), he will be gorged for (5000/100)*10 = 500
-* game turns, or 500/(100/5) = 25 player turns (if nothing else is
-* affecting the player speed).
-*/
-
-#####GDescription:
-Set hunger level "v". A value < 500 is fainting. A value < 1000 is
-weak. A value < 2000 is weak. A value < 10000 is full. A value
-< 15000 is bloated. A value < 20000 is gorged. If one of these
-levels is crossed a message is printed.
-
-#####GParameters:
->v is the hunger level (must be between 0 and 20000).
-
-----------------------------------------------------------------------
-
-#####RFunction: check_experience
-
-#####GDeclaration: void check_experience(void);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Advance experience levels and print experience
-*/
-
-#####GDescription:
-Check if player experience level has changed. If a player has achieved
-a level for the first time, give reward or corruption (1 chance in 3)
-if they apply, and increase skill points.
-
-----------------------------------------------------------------------
-
-#####RFunction: check_experience_obj
-
-#####GDeclaration: void check_experience_obj(object_type *o_ptr);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Advance experience levels and print experience
-*/
-
-#####GDescription:
-Check if object "o_ptr" experience level has changed. If an object has
-achieved a level for the first time, apply gains.
-
-#####GParameters:
->o_ptr is the pointer to the object gaining experience.
-
-----------------------------------------------------------------------
-
-#####RFunction: gain_exp
-
-#####GDeclaration: void gain_exp(s32b amount);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Gain experience (share it to objects if needed)
-*/
-
-#####GDescription:
-Gain "amount" of experience. Count the number of objects which will
-gain experience. The objects share equally 2/3 of "amount". Give
-corruption if it applies. Gain experience. If experience is less
-than maximum, then increase maximum experience by 20% of "amount".
-Check for level change and print experience (check_experience).
-
-#####GParameters:
->amount is the amount of experience to share.
-
-----------------------------------------------------------------------
-
-#####RFunction: lose_exp
-
-#####GDeclaration: void lose_exp(s32b amount);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Lose experience
-*/
-
-#####GDescription:
-Decrease experience by "amount". Experience can not fall below zero.
-Check for level change and print experience (check_experience).
-
-#####GParameters:
->amount is the amount of experience to lose.
-
-----------------------------------------------------------------------
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
-
-
diff --git a/lib/help/lua_pow.txt b/lib/help/lua_pow.txt
deleted file mode 100644
index c221a664..00000000
--- a/lib/help/lua_pow.txt
+++ /dev/null
@@ -1,266 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding new racial powers >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-You *must* download and install my lua example files from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm]. And also you should read the
-*****lua_intr.txt*0[scripting introduction] file if you haven't already done
-so.
-
-The (commented) accompanying script file for this tutorial is
-lib\scpt\pheonix.lua. Open it in your text editor!
-
-#####R=== The Racial Power ===
-
-Let's start with something simple. Let's say you wanted your new race (let's
-call it "Pheonix") to be able to cast fire balls as their racial power.
-
-#####R=== Starting off ===
-
-If you have a look at pheonix.lua you'll note the first lines are comments.
-I'll talk a bit more about comments later, but it's worth pointing out that any
-lines of text preceded by a double hyphen ([[[[[B--]) will be ignored by the
-scripting engine, and are therefore comments.
-After the comments, the first 10 lines of code are as follows:
-
-#####BPHEONIX_POWER = add_power
-#####B{
-#####B ["name"] = "Fire Breath",
-#####B ["desc"] = "You are able to cast fireballs",
-#####B ["desc_get"] = "Your beak glows red",
-#####B ["desc_lose"] = "Your beak goes cold again",
-#####B ["level"] = 10,
-#####B ["cost"] = 11,
-#####B ["stat"] = A_INT,
-#####B ["fail"] = 14,
-
-So, [[[[[BPHEONIX_POWER = add_power] is registering our power. We're giving it
-a name (PHEONIX_POWER) and saying that it is defined by calling the special
-function [[[[[Badd_power]. This special function is only used to define lua-
-scripted
-powers, and has attributes which are identified by their inclusion in square
-brackets.
-Note the following:
-- Lua is case sensitive. The name of our power is a constant, will never change
-so that's been named with capitals. variables and functions are named all in
-lower case. Technically speaking, Lua does not support constants, but we can
-emulate them by variables in this way. They don't have to be capitalised, but
-if you capitalise all your constants, it makes things easier to read, and
-you'll be following normal programming protocol.
-- There are no spaces in the name of the power. Use an underscore for spaces
-if you need to improve legibility.
-
-[[[[[B"name" = "Fire Breath",] This is the name of the power as it is
-displayed in the
-U menu, and as you will define it in p_info.txt (more about that later).
-
-[[[[[B"desc" = "You are able to cast fireballs",] This is what would
-appear in the
-information display list if you drank a potion of self knowledge or
-similar.
-
-[[[[[B"desc_get" = "Your beak glows red",] This is the information displayed
-when you
-gain this power.
-
-[[[[[B"desc_lose" = "Your beak goes cold again",] This is the information
-displayed when
-you lose this power. Eg After a mutation/corruption.
-
-[[[[[B"level" = 10,] Character level which must be gained in order to use
-power,
-
-[[[[[B"cost" = 11,] Amount of mana to cast this power.
-
-[[[[[B"stat" = A_INT,] stat which will define whether it works or not,
-
-[[[[[B"fail" = 14,] how high that stat must be.
-
-So our Pheonix will be able to cast PHEONIX_POWER from clvl 10, at a cost of
-11 mana, providing that the player's intelligence is 14 and upwards.
-
-#####R=== The function ===
-
-The next section is a lot longer, so we'll look at it line by line. I'll
-strip the comments for the purpose of this helpfile.
-
-#####B["power"] = function()
-#####B local ret, dir, damage
-#####B ret, dir = get_aim_dir();
-#####B if (ret == FALSE) then
-#####B return
-#####B end
-#####B damage = player.lev*3
-#####B msg_print("You breathe fire.")
-#####B fire_ball(GF_FIRE, dir, damage, 3)
-#####Bend,
-
-The [[[[[B"power"] bit is what actually happens when the player accesses this
-power
-from their 'U' menu. Every function must start with the word [[[[[Bfunction].
-Normally, we'd also declare its name at this point, but as this is contained
-within the [[[[[Badd_power] function, we just use the word [[[[[Bfunction] The
-empty
-brackets after this denote that no arguments are passed to the function.
-Lets look at the next line.
-
-#####B local ret, dir, damage
-
-The [[[[[Blocal] bit is saying that we're going to declare some local
-variables. That
-is, that there will be three variables used in this function , that apply
-exclusively to this function, and to no others. Global variables are
-variables that apply to the whole script, in multiple functions. The three
-variables will be called [[[[[Bret] (return), [[[[[Bdir] (direction), and
-[[[[[Bdamage]. They will be used to determine the direction the ball
-will fire in, and how much damage it will do. We'll see them in use when we add
-the third line:
-
-#####B ret, dir = get_aim_dir();
-
-here we're saying that the variables will take their value from the result
-of a function. The program performs the function [[[[[Bget_aim_dir] which
-essentially asks the player to choose a direction or pick a target.
-[[[[[Bget_aim_dir]
-assigns the value [[[[[Bret] to either TRUE (if the player correctly selected a
-direction) or FALSE (if the player failed to do so (maybe they changed their
-mind, or hit the wrong key!)). The value [[[[[Bdir] is the direction which was
-selected (or the path to the target if a target was selected). OK so let's add
-the next line:
-
-#####B if (ret == FALSE) then return end
-
-This introduces another fundamental scripting concept - [[[[[Bif] statements.
-They work just as you would expect them too. You say "if a certain condition is
-met, then do the following things."
-So in this function we're saying, "if the value of [[[[[Bret] is FALSE then
-[[[[[Breturn]."
-As I mentioned above, [[[[[Bret] is false if the player aborted (either
-deliberately or accidentally) the spell casting whilst choosing a direction
-for the spell. The double equals sign are used to mean "is equal to" as a
-single equals sign is used for defining variables remember? A single equals
-sign is more of a "let x be equal to y" thing.
-[[[[[Breturn] means stop the current function. And [[[[[Bend] signifies the
-close of the [[[[[Bif]
-statement. Every [[[[[Bif] statement must begin with an [[[[[Bif] and finish
-with an [[[[[Bend].
-So, what our [[[[[Bif] statement is saying is; "if the player failed to specify
-a direction or target for the spell, stop the function here."
-If the player has correctly specified a direction/target, the function
-continues to the next line:
-
-#####B damage = player.lev*3
-
-Here we're saying that the variable [[[[[Bdamage] has a value equal to the
-players current character level, multiplied by 3.
-
-#####B msg_print("You breathe fire.")
-
-Fairly easy to see what this does - displays the message "You breathe fire."
-I could have put anything there obviously, like [[[[[Bmsg_print("You open]
-[[[[[Byour mouth and everyone falls over with the smell of hot curry")] or
-some other such rubbish. But note that the message is enclosed within double
-quotes. The quotes aren't displayed in the message on screen, but signify the
-start and end of the message.
-
-#####B fire_ball(GF_FIRE, dir, damage, 3)
-
-This is the line that casts the spell. it says execute the function
-[[[[[Bfire_ball]. Now, this doesn't mean a fireball, it means fire a ball.
-There's an important distinction there! All it knows it is doing is firing a
-ball, it doesn't know what kind of ball, or where, or how big, or how much
-damage.
-The [[[[[BGF_FIRE,] bit is what tell us it is a fire ball. If it was
-[[[[[BGF_COLD,]
- we'd have a cold ball, or [[[[[BGF_CHAOS,] it would be a chaos ball and
-so on and so on. A full list of those types can be found in *****lua_gf.txt*0[lua_gf.txt].
-[[[[[B dir,] is the direction, from the [[[[[Bget_aim_dir()] bit.
-[[[[[B damage,] is the damage. As we've already said, this will be clvl*3.
-[[[[[B 3)] is the radius.
-and finally...
-
-#####B end,
-#####B}
-
-[[[[[Bend,] tells it the function has ended. Every function must finish with
-[[[[[Bend].
-You should have spotted that after the end of each attribute is a comma. Make
-sure you include this, and don't forget the braces at the very very end to
-close the [[[[[Badd_power] function.
-
-#####R=== Finishing the LUA file ===
-
-Save this as a text file 'pheonix.lua' Put it into the lib\scrpt directory
-of ToME, and open the init.lua file which you'll find in the same
-directory.
-
-Add the following line and resave the init.lua file.
-
-#####Btome_dofile("pheonix.lua")
-
-This ensures that ToME loads your file on start-up. Because you've installed
-the example scripts, this has all been done for you.
-
-#####R=== A quick word about comments ===
-
-One of the reasons Angband has so many variants is because the source code is
-clearly commented. Almost every line of code has an accompanying comment,
-explaining what that line does. It's good practice to add comments to any code
-or script you write. It's helpful to others who are learning, anyone who takes
-over your project, and also to yourself when you come back in a month's time
-and can't remember what you did! So comment your code clearly, and well!
-
-You can also add multi line comments which should be enclosed by [[[[[B--[[]
-and
-#####B]]
-
-#####R=== Tying it all together ===
-
-You'll now need to link this 'U' power to the pheonix race via the
-p_info.txt file. Simply add a line within the class definition file that has
-the format [[[[[BR:Z:<name>]the name of the power as it appears in the
-[[[[[B"name"]
-section we did right at the beginning, remember? Seeing as there is no pheonix
-race, I've gone ahead and made one up as a demonstration. If you've downloaded
-and installed the example files from [[[[[Ghttp://www.moppy.co.uk/angband.htm/]
-then
-you'll notice you already have the pheonix race available. Printed below is
-the p_info.txt entry for it.
-
-
-#####BR:N:23:Pheonix
-#####BR:D:Born from flame, these powerful bird like creatures gain fire related
-#####BR:D:abilities as they grow.
-#####BR:S:1:0:2:1:-3:2:-5
-#####BR:K:-8:15:20:-10:5:-1:-5:-5
-#####BR:P:8:130:5:210
-#####BR:M:255:70:2:1:20:5:2:1:18:3
-#####BR:E:1:1:1:2:1:1
-#####BR:C:Warrior | Mage | Priest | Rogue | Ranger | Paladin | Blade |
-#####BR:C:Warlock | Chaos-Warrior | Monk | Mindcrafter | High-Mage |
-#####BR:C:BeastMaster | Alchemist | Power-Mage | Runecrafter |
-#####BR:C:Sorceror | Archer | Illusionist | Druid | Necromancer | Black-Knight
-|
-#####BR:C:Daemonologist | Weaponmaster | Summoner |
-#####BR:Z:Fire Ball
-#####BR:R:1:0
-#####BR:F:RES_FIRE | FEATHER |
-
-Note the [[[[[BR:Z:] line.
-
-If all is well, you should be able to start ToME now and breathe fire! Once
-you get to lvl 10 anyhow. Don't forget, this is the kind of thing wizard mode
-was invented for! Ctrl-A and confirm at the prompt, and then 'e' will allow
-you to alter stats, including experience. Approx 1000 exp should do to get you
-to clvl 10.
-
-Ready for more? How about adding a new *****lua_skil.txt*0[skill] ?
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
-
-
-
-
diff --git a/lib/help/lua_ques.txt b/lib/help/lua_ques.txt
deleted file mode 100644
index 1d4b9c65..00000000
--- a/lib/help/lua_ques.txt
+++ /dev/null
@@ -1,299 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding a new quest >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-Adding a quest involves a bit more work, and there is, in some ways, rather
-more potential for things to go wrong! But it's a great way of showing just
-WHAT can be done with lua scripting. It proves just how much a lua patch can
-change the overall feel of the game. And it will give you a much better idea of
-how lua interfaces with the game source. You should have read the
-*****lua_intr.txt*0[scripting introduction], *****lua_pow.txt*0[racial power tutorial]
-and *****lua_skil.txt*0[adding new skills tutorial] before going much
-further. All of the above files contain some fairly fundamental information
-which you will find necessary for full understanding of this file.
-
-The script we're looking at is going to create a quest entrance in the middle
-of Bree. Entering the quest you see a little girl who has had her necklace
-stolen. Your job is to travel down a corridor, killing some monsters on the
-way, pick up the amulet and return it to the girl. Once done, she'll reveal the
-stairs back to Bree, and give you a (randomly generated) ring. If you feel the
-monsters are too hard, the only thing to do is talk to the little girl who will
-reveal the stairs again, failing the quest for you, and also block off the
-entrance to the amulet so that you can't cheat and make off with the amulet!
-
-#####R=== Getting started ===
-
-Open amulet.lua (you have downloaded the example scripts from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The first thing you
-should see is that yet again we're calling a function that takes its arguments
-from a table, making it easy to read what's going on in the script.
-
-This time our function is add_quest and we have the following keys and values:
-
-#####B["global"] = "AMULET_QUEST",
-#####B["name"] = "Hannahs lost amulet",
-#####B["desc"] = {
-#####B "Retrieve an amulet for Hannah Cooke. It's guarded!"
-#####B },
-#####B["level"] = 5,
-#####B["hooks"] = {
-
-[[[[[B"global" = ] is a constant that we set when we refer to this quest in
-various places...
-[[[[[B"name" = ] Obviously a long name for the quest. This will appear in the
-quest screen (Ctrl-Q) and we may use in some map files too.
-[[[[[B"desc" = ] This is a long description for the quest. Again this is what
-will appear in the quest screen, and each line should be not more than 80
-characters.
-[[[[[B"level" = ] This is a rough indicator of how hard the quest is, and again,
-appears in the quest screen
-[[[[[B"hooks" = ] This is the real 'meat' of the quest. Like the [[[[[B"spell_list"] key
-in the [[[[[Badd_magic] function, this is another sub-table.
-
-To understand fully the structure of the "hooks" key it's worth taking a bit of
-a detour at this point and discussing how the scripting interface works in
-general.
-
-#####R=== How the scripts work (ish) ===
-
-Essentially there's a list of events that happen in the game. As each of these
-events happen they run a check to see if there's any functions that they need
-to run at that event. When we ran the add_mkey part of adding a new skill
-power, we essentially said "when the 'm' key is pressed in the game, perform
-the [[[[[Bexecute_magic(constructor_powers)] function". Likewise we did a similar
-thing with adding the racial power, only we hooked onto the pressing of the
-'U' key.
-
-All of this was partly hidden because of the way that the [[[[[Badd_magic] and
-[[[[[Badd_power] functions work. But here in the [[[[[Badd_quest] function it's a bit more
-specific. We are going to specify what events we're going to hook onto, and
-what functions we want to trigger at that event.
-
-A full list of hooks can be found in the source-file util.pkg.
-
-#####R=== The hooks ===
-
-#####B[HOOK_BIRTH_OBJECTS] = function()
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_TAKEN
-#####Bend,
-
-So here we are with our first hook. We've declared that we're adding it to the
-birth of your character. That is, the function will be called when you create
-your character. And what we're doing here is automatically declaring the quest
-as being taken, like the Dol Guldur quest is. Each quest has 7 different
-statuses:
-
-[[[[[BQUEST_STATUS_IGNORED -1 ] This is unused, but the quest is
-ignored (will not be taken and has not been taken).
-[[[[[BQUEST_STATUS_UNTAKEN 0 ] The quest has not been accepted yet
-[[[[[BQUEST_STATUS_TAKEN 1 ] You have accepted the quest
-[[[[[BQUEST_STATUS_COMPLETED 2 ] You have completed the quest
-successfully but not been rewarded for it
-[[[[[BQUEST_STATUS_REWARDED 3 ] You've completed and rewarded the quest
-[[[[[BQUEST_STATUS_FAILED 4 ] You've failed the quest
-[[[[[BQUEST_STATUS_FINISHED 5 ] The quest is completely finished
-successfully.
-[[[[[BQUEST_STATUS_FAILED_DONE 6 ] The quest is completely finished
-unsuccessfully.
-
-You see that we've used the constant we defined in the "global" section is
-passed as an argument to [[[[[Bquest.status].
-
-Next hook then:
-
-#####B[HOOK_GEN_QUEST] = function()
-#####B if (player.inside_quest ~= AMULET_QUEST) then
-#####B return FALSE
-#####B else
-#####B load_map("amulet.map", 2, 2)
-#####B return TRUE
-#####B end
-#####Bend,
-
-Ok, we're hooking onto the generation of the quest here. This is specifically
-triggered in this instance by going down the quest entrance stairs in Bree.
-Once you've gone down the stairs, you are technically inside the quest, which
-means we can say if the person is not inside the amulet quest, then ignore this
-function, otherwise load the file 'amulet.map' at co-ordinates x=2 y=2. You'll
-find the amulet.map file in the edit directory, make sure you check it out. The
-syntax for map files is fairly simple, though I might get round to writing a
-tutorial on them some day! In the mean time holler for me at the usual email
-address if you're unsure.
-
-#####B[HOOK_FEELING] = function()
-#####B if (player.inside_quest ~= AMULET_QUEST) then
-#####B return FALSE
-#####B else
-#####B cmsg_print(TERM_L_BLUE, "Hannah speaks to you:")
-#####B cmsg_print(TERM_YELLOW, "'Some nasty monsters stole my
-#####B favourite necklace.'")
-#####B cmsg_print(TERM_YELLOW, "'It's hidden at the back of that
-#####B corridor! Please fetch it for me'")
-#####B return TRUE
-#####B end
-#####Bend,
-
-We're moving into some rather more obvious territory here, and getting into the
-meat of the quest. The [[[[[BHOOK_FEELING] is triggered at the point when the level
-feeling appears. It's important that this is run only if the player is inside
-the amulet quest, as otherwise it will trigger EVERY time a level feeling
-occurs, when you go down a level in the barrow-downs, whenever! Returning TRUE
-will replace the level feeling with what's above, returning FALSE will still
-perform the function but will amend the normal level feeling - so here if we'd
-returned false we'd still get our custom messages, but they'd follow with
-'looks like a typical quest level'. Of course returning false may cause you
-other problems (see end of this file!) depending on what else you have in your
-function.
-
-#####B[HOOK_GIVE] = function(m_idx, item)
-
-#####B m_ptr = monster(m_idx)
-#####B o_ptr = get_object(item)
-
-#####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl"))
-#####B and (o_ptr.tval == TV_AMULET) and (o_ptr.sval == 2) then
-
-#####B cmsg_print(TERM_YELLOW, "'Thank-you!'")
-
-#####B inven_item_increase(item, -1)
-#####B inven_item_optimize(item)
-
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_COMPLETED
-
-#####B cave_set_feat(7, 6, 6)
-
-#####B cmsg_print(TERM_YELLOW, "'Here, take this pretty ring I found
-#####B as a token of gratitude!'")
-#####B random_type = randint(57)
-#####B reward = create_object(TV_RING, random_type)
-#####B drop_near(reward, -1, py, px)
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_REWARDED
-#####B return TRUE
-#####B else
-#####B return FALSE
-#####B end
-#####Bend,
-
-This is a fairly long function, but don't be intimidated. It's not really
-difficult to understand. As you can see we're hooking into the giving of an
-object to a monster (the 'y' key). Because of this, the function takes two
-arguments - [[[[[Bm_idx] (the monster that you're giving to) and [[[[[Bitem] (the item that
-you're giving).
-
-We then make it possible to work with the monster and item variables by
-referencing them to two functions which identify them from the edit files:
-[[[[[Bmonster()] and [[[[[Bget_object()]. This enables us to now say, 'if the name of the
-monster is "Hannah Cooke, a little girl" and the type of item is an amulet and
-that amulet is an amulet of adornment, then carry out the following commands'.
-
-We then say call the function [[[[[Binven_item_increase()] which places an object in
-the inventory. It takes two arguments, the first being what object to put in
-the inventory and the second being how many of that type of objects to put in
-the inventory. You can see that by placing -1 as the second argument it fairly
-obviously subtracts that item from the inventory. The [[[[[Binven_item_optimize()]
-function checks that there are no empty inventory slots, and if there are,
-erases them.
-
-The quest is then completed, and the stairs are revealed using the
-[[[[[Bcave_set_feat()] function. This function takes three arguments, the first is the
-x co-ordinate of the cave square you wish to change (counted from top left) the
-second is the y co-ordinate, and the third is the index number of the feature
-you wish the square to become as defined in f_info.txt.
-
-We then set about rewarding the player. As you can see we call [[[[[Bcreate_object()]
-which takes two variables: the first is the type of object (these are all
-listed in object.pkg) and the second is the sub-type of that object. I searched
-k_info.txt to see how many different types of ring there were (57) and used a
-randomly selected number with a maximum value of 57 as that specific sub-type.
-
-We then drop the object (although it's been created, it has only been created
-in the game's memory, it's nowhere that the player can interact with it until
-we drop it). The [[[[[Bdrop_near()] function takes 3 variables, the first being the
-object that you wish to drop, the second being the chance that it disappears
-(like an arrow, or mimicked creature) on drop. If you set it to -1, it won't
-ever disappear. The last two are the co-ordinates at which the object will be
-dropped. py and px are the global variables defined by where the player is
-standing, so in this case it will drop under the player. You could do
-[[[[[Binven_item_increase(reward, 1)] if you wanted, but I wanted to show a variety of
-ways of handling objects.
-
-OK, let's take a look at the next hook:
-
-#####B[HOOK_CHAT] = function(m_idx)
-#####B m_ptr = monster(m_idx)
-#####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl")) then
-#####B if (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) then
-#####B cmsg_print(TERM_YELLOW, "'Bye!'")
-#####B else
-#####B cmsg_print(TERM_YELLOW, "'Are the monsters too tough?
-#####B Do you want to leave?'")
-#####B if (get_check("Really leave and fail the quest?") ==
-#####B FALSE)
-#####B then
-#####B cmsg_print(TERM_YELLOW, "'Go and get my
-#####B amulet then!'")
-#####B else
-#####B cmsg_print(TERM_YELLOW, "'Awww. Never
-#####B mind. It was only a bit of rabbits foot'")
-#####B quest(AMULET_QUEST).status =
-#####B QUEST_STATUS_FAILED
-#####B cave_set_feat(7, 6, 6)
-#####B cave_set_feat(12, 5, 60)
-#####B end
-#####B end
-#####B return TRUE
-#####B end
-#####B return FALSE
-#####Bend,
-
-This only looks complicated because of the nested 'if' statements. It's easy to
-lose your way when doing this kind of thing, always make sure you close all the
-statements and put the returns in the right place. [[[[[BHOOK_CHAT] functions have one
-argument - the monster you are chatting to. As you can see, we perform a check
-to make sure it's the right monster and then away we go.... If the player wants
-to leave the quest without completion they talk to Hannah, who gives them a
-chance to change their mind! If the player asks to leave the entrance to the
-corridor is blocked off (the second cave_set_feat()) so that the user can't
-then go and get the amulet. Gumband or Zangband players may at this point think
-they've lost out on the rabbits foot of burglary! (they haven't though as it
-doesn't exist in ToME).
-
-#####B[HOOK_CHAR_DUMP] = function()
-#####B if (quest(AMULET_QUEST).status == QUEST_STATUS_FAILED) then
-#####B print_hook("\n You chickened out of rescuing a necklace and
-#####B made a little girl sad. ")
-#####B elseif (quest(AMULET_QUEST).status == QUEST_STATUS_COMPLETED) or
-#####B (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) or
-#####B (quest(AMULET_QUEST).status == QUEST_STATUS_FINISHED) then
-#####B print_hook("\n You rescued little Hannah Cooke's necklace from
-#####B the nasty monsters ")
-#####B end
-#####B return FALSE
-#####Bend,
-
-This quite simply and obviously prints an appropriate line in the character
-dump based on the status of the quest. The [[[[[B\n] bit ensures the text goes on a
-new line, so make sure you include it! Also you should return FALSE as
-returning TRUE will stop executing all the other character dump lines (and you
-may get other quests not having their lines printed).
-
-=== A word about returning TRUE and FALSE ===
-
-As I mentioned above, you need to be careful what you return when dealing with
-HOOKS as you can mess up the game a bit. Bear in mind that if you add a
-function to [[[[[BHOOK_GEN_QUEST], every time a quest is generated, that function will
-run. If you return TRUE, then no further functions attached to that hook will
-run. If you return FALSE, it continues processing functions on that hook.
-
-That is pretty much it. Do take a look at the other included scripts that I
-haven't gone into any detail about in the files, as you'll pick up some useful
-techniques there too. Especially worthy of note is the hina.lua file which uses
-hooks outside of the quest structure and also global variables and variables in
-a table. If you have any questions, let me know at the email addy below.
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/help/lua_skil.txt b/lib/help/lua_skil.txt
deleted file mode 100644
index 87385e5d..00000000
--- a/lib/help/lua_skil.txt
+++ /dev/null
@@ -1,342 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding new skill-based powers >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-This is very much in the same vein as adding a racial/extra power, but has to
-be tied into skills, and we're defining more than one spell at once. You should
-have read the *****lua_intr.txt*0[scripting introduction] and
-*****lua_pow.txt*0[racial power tutorial] before going much further. Both of the above files
-contain some fairly fundamental information which you will find necessary for
-full understanding of this file.
-
-#####R=== Getting started ===
-
-Open construc.lua (you have downloaded the example scripts from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The idea behind this
-script is that it adds a skill which affects you ability to build/knock down
-stuff. It treats the equivalent of stone-to-mud and trap-door destruction
-spells as if they were "building skills". It also adds quite a few high-level
-'spells' which do funky things like carving out corridors and chambers in a
-single turn, and building doors and stuff. Just think of it as if the person
-who has plenty of skills in this area would be a builder-type with lots of
-strength and constitution...
-
-In order to add these powers we're going to edit the s_info.txt file which
-lives in the edit folder, and add a new skill, underneath the 'misc' tree,
-called construction. The powers will then be accessed through the 'm' menu, in
-a similar way to mindcraft or alchemy skills or such. (That is, no books are
-needed to cast them, as we're treating them as a craft that has been learnt,
-rather than spells.) Our fist line of the script file reads:
-
-#####BSKILL_CONSTRUCT = 57
-
-This merely links the skill index that we'll be defining in s_info.txt to this
-file. We'll come back to this at the end of the tutorial.
-
-#####Bconstructor_powers = add_magic
-
-In a similar way to the [[[[[Badd_power] function we called when we added the
-Phoenix racial ability, this line calls a special function which we use to
-define new skills. It follows a very specific, but easy to understand form. It
-starts with a brace, which indicates the add_magic function will be storing
-these values in a table. Don't worry about this too much, but understand that a
-table starts and ends with braces [[[[[B{] and [[[[[B}] respectively. Each key
-(or field name) takes the format [[[[[B"key" = value,] (the comma is
-important!).
-
-#####B ["fail"] = function()
-#####B msg_print("You decide now is a good time for a cuppa")
-#####B end,
-#####B ["stat"] = A_STR,
-#####B ["get_level"] = function()
-#####B return get_skill_scale(SKILL_CONSTRUCT, 50)
-#####B end,
-#####B ["spell_list"] =
-
-[[[[[B"fail"] is a function that is called whenever you ##fail to cast the
-spells##. Here it does nothing spectacular.
-[[[[[B"stat"] defines the stat used to cast the spells. Here it is strength.
-Any other stat can be used, prefix it with [[[[[BA_].
-[[[[[B"get_level"] is used to determine the level of the spell. It's associated
-with spells that increase in power the more points that are invested in the
-associated skill. I know that's not terribly clear, I'll come back to it in a
-moment.
-[[[[[B"spell_list"] is just that, a list of all the spells.
-Each of these four properties within the table must end with a comma. If a
-function is defined in the property itself then we add the comma after the
-closing [[[[[Bend]. Again compare with construct.lua to see it. Any line NOT
-ending with a comma will cause a lua error on startup, probably of the type
-[[[[[V'}' expected to close '{' at line <whatever>.]
-
-#####R=== The spell list ===
-
-Each spell, within the [[[[[B"spell_list"] key has its own set of properties
-that we need to define from a sub-table so we open another set of braces to
-start the spell list, and then a third set of braces to start the first spell.
-So with all this, our first spell looks like:
-
-#####B ["spell_list"] =
-#####B {
-#####B {
-#####B ["name"] =
-#####B ["desc"] =
-#####B ["mana"] =
-#####B ["level"] =
-#####B ["fail"] =
-#####B ["spell"] =
-#####B ["info"] =
-#####B },
-
-[[[[[B"name"] is, as you would expect, the name of the spell, as you want it to
-appear in the spell list when choosing a spell. The maximum number of
-characters for this is 29.
-[[[[[B"desc"] is the description received when you hit the capital letter of
-that spell in the menu. (i.e., press 'a' to cast the first spell, but press 'A'
-to receive info about the first spell.
-[[[[[B"mana"] is the amount of mana required to cast the spell.
-[[[[[B"level"] is the level required to use that spell (that's level of the (in
-this case construction) skill, not character level!).
-[[[[[B"fail"] is base fail rate.
-[[[[[B"spell"] is the function that is executed when the spell is cast. Note
-that it MUST take the form [[[[[Bfunction() blah end] even if you're calling
-a C function directly. If you have a look at the end of the file, you'll see
-the "rebuild dungeon" spell which is identical to the "alter_reality" spell.
-However, rather than reading [[[[[B"spell" = alter_reality()], it reads:
-
-#####B["spell"] = function()
-#####B alter_reality()
-#####Bend,
-
-which appears to be a long way round to do the same thing, but this is how it
-must be done.
-
-In a similar way, the [[[[[B"info"] key must begin with a [[[[[Bfunction()]
-and return the value of what is to be displayed alongside the spell name,
-level and mana in the spell list. The maximum number of characters that can be
-displayed here is dependent on the width of the user's screen, but try to keep
-it under 12 if you can, as this will fit in a standard 80x24 terminal screen.
-The first character will need to be a space otherwise you'll have the info line
-squashed right up against the fail rate and it will look odd. If you wish to
-have this part blank in the spell list, you still need to return a value, so
-just a single space will do : [[[[[Breturn " "]
-
-All of these keys are repeated for each spell, with each spell in its own
-table (therefore, it's own set of braces). Again, check the lua file for
-clarification.
-
-When entering the spells in the "spell_list", you must take care to specify
-them in the order which they are gained, otherwise they display incorrectly in
-the spell list.
-
-You should by now be experienced enough to understand most of what's going on
-in the actual spell functions (especially if you dig around in the source a
-bit, and check out Chris Hadgis' excellent *****lua_spel.txt*0[spell.pkg] helper
-files. I'm not going to go through the whole file line by line, as this is
-something you should do yourself, figuring out what's going on. I'm going to
-examine a few of the things we haven't covered before though, so pay attention.
-
-#####R=== The get_level() function ===
-
-Probably one of the most important functions that you see reappearing in the
-file is the [[[[[Bget_level()] function. All this does is return the numerical
-value of the power that is given as the first argument. So [[[[[Bget_level]
-[[[[[B(constructor_power)] will return the current level of the constructor power.
-Given that the level of this is taken directly from the construction skill, (we
-defined that in the [[[[[B"get_level"] key, by saying [[[[[Bget_skill_scale]
-[[[[[B(SKILL_CONSTRUCT, 50)] ) it will return the value of your construction skill.
-[[[[[Bconstructor_power] is the name of the whole power, we named it thus on
-the second line of the script!
-
-[[[[[Bget_level] takes the following arguments: [[[[[Bget_level(power, max, ]
-[[[[[Bmin)]. The power is obviously which power we're taking the value from, and the
-max and min allow you to define boundaries for the spell. For instance the
-current maximum value that [[[[[Bget_level(constructor_power)] can return is
-50, as that is the maximum number of skill points you can have in that skill.
-If you were using this as the basis for the damage of a low-level bolt spell,
-you might decide that having a damage of 50 would be too much (unlikely, but
-still possible). You could therefore define a maximum value of 20 so that when
-the value of the construction skill was over 50, the maximum value for
-damage of that spell would be 20. To achieve this you'd have:
-[[[[[Bget_level(constructor_power, 20)]. In a similar way, you can force the
-minimum value of the spell to be higher than the actual construction skill
-level, with a [[[[[Bget_level(constructor_power, 50, 15)]. This would be useful
-say for spells that you wanted to be available when the construction skill
-level reaches 10, but for whom you wanted a (for example) base damage of 15
-right from the word go. These re-scale values rather than capping them!
-
-You can leave out the minimum value as I have done above. You can also leave
-the maximum value out (it will default to 50). If you want to specify a minimum
-value though, you MUST specify a maximum value as well.
-
-As you have hopefully been able to tell, the [[[[[Bget_level()] function
-enables us to have spells that increase in usefulness as you gain levels. Let's
-take the "Dismantle" spell. The function in the [[[[[B"spell"] key is as
-follows:
-
-#####Bfunction()
-#####B local ret, dir, dam
-
-#####B if (get_level(constructor_powers, 50) >= 11) then
-#####B ret, dir = get_aim_dir();
-#####B if (ret == FALSE) then return end
-#####B fire_beam(GF_KILL_TRAP, dir, 1)
-#####B else
-#####B fire_ball(GF_KILL_TRAP, 0, 1, 1)
-#####B end
-#####Bend,
-
-The [[[[[Bif] statement is obviously what really interests us here. You'll
-notice that this has the amendment of an [[[[[Belse] clause, which the [[[[[Bif]
-statement we used in the previous tutorial did not. As you would expect, if the
-condition on the first line of this statement is met, then the instructions
-immediately below it are carried out. If the condition is not met, then the
-statements that follow the [[[[[Belse] are executed.
-
-Coming back to the [[[[[Bget_level] function, we learnt from above, that the
-[[[[[Bget_level] part of this function translates as, "if the value of the
-construction_power level (which happens to be identical to the construction
-skill level) is greater than or equal to 11, cast a beam of trap disarming in
-the specified direction. (The first part of this is all straightforward,
-getting a direction, and cancelling correctly if the player presses 'ESC'.)
-Otherwise, cast a ball of trap disarming with a radius of one, centred on the
-player."
-
-In the same way, as you look at the construc.lua file, you will see that
-[[[[[Bget_level()] is used many times in this way, to increase the power of
-detection spells, to change bolt spells to ball spells, to keep a constantly
-increasing damage going, and so on.
-
-#####R=== Elseif's and things ===
-
-If you want to provide more than one alternative condition, in an
-[[[[[Bif-then-else] statement, you can use [[[[[Belseif]s which do what you
-might expect. Take a look at the first spell, "Survey area", for an example of
-this:
-
-#####Bif (get_level(constructor_powers, 50) >= 28) then
-#####B wiz_lite()
-#####Belseif (get_level(constructor_powers, 50) >= 15) then
-#####B map_area()
-#####B detect_traps(DEFAULT_RADIUS)
-#####Belseif (get_level(constructor_powers, 50) >= 5) then
-#####B detect_traps(DEFAULT_RADIUS)
-#####B detect_stairs(DEFAULT_RADIUS)
-#####B detect_doors(DEFAULT_RADIUS)
-#####Belse
-#####B detect_stairs(DEFAULT_RADIUS)
-#####B detect_doors(DEFAULT_RADIUS)
-#####Bend
-
-If the level of constructor powers is greater or equal to 28, then the function
-[[[[[Bwiz_lite()] is performed, and no other part of the if statement is
-executed. [[[[[Bwiz_lite()] is just the enlightenment spell. If it is less than
-28, the next condition is examined: that if the level of constructor powers is
-greater than or equal to 15, then [[[[[Bmap_area()](Magic mapping) and detect
-traps are called. If the level of constructor power is less than 15, it moves
-onto the next condition, which says that if the level of constructor power is
-greater than 5, then detect stairs, traps and doors. If none of these
-conditions are met,(that is, if the level of construction skill is less than 5)
-then we just detect doors and stairs.
-
-You'll note that each of the detection spells includes a DEFAULT_RADIUS
-constant. You could change this to a numerical value, or a variable defined
-somewhere else in your script. eg [[[[[Bdetect_traps(2)] would detect traps
-with a radius of 2 centred on the player.
-
-#####R=== Registering the skill type ===
-
-This is what we do at the end of the file, and is what ties the powers we've
-defined to the action of pressing the 'm' key in game. Once more we're calling
-a special function [[[[[Badd_mkey()] which takes its arguments for a table.
-There are only two keys in this table though which keeps things simple.
-
-#####Badd_mkey
-#####B{
-#####B ["mkey"] = MKEY_CONSTRUCT_POWERS,
-#####B ["fct"] = function()
-#####B execute_magic(constructor_powers)
-#####B energy_use = energy_use + 100;
-#####B end
-#####B}
-
-[[[[[B"mkey"] must be a UNIQUE value > 1000 . Here I've defined it as a
-constant, [[[[[BMKEY_CONSTRUCT_POWERS], which has the value 1004. This value
-we'll call again in the s_info.txt file.
-[[[[[B"fct"] is the function that's called when the user presses the key in the
-'m' menu. So here, it calls the [[[[[Bexecute_magic] function which actually
-displays a list of powers for the user to choose from. The argument it takes is
-the powers it will use (alchemy, mindcraft, etc., or in this case constructor),
-and then the [[[[[Benergy_use] line tells the game to take one game turn to do
-the action.
-
-#####R=== Adding the skill in s_info.txt ===
-
-Take a look in the s_info.txt file, under the Misc section. You'll see,
-
-#####BN:57:Construction
-#####BD:Ability to use constructor powers
-#####BD:Construction powers use strength
-#####BA:1004:Build or knock down stuff
-#####BI:1000
-
-The first line is the index of the skill; again this must be unique. The second
-property is the name of the skill. The [[[[[BD] lines are the lines displayed
-when the skill is highlighted in the skill screen.
-The first entry on the [[[[[BA] line is the value of the [[[[[B"mkey"] we
-defined in the [[[[[Badd_mkey] function in our script. The second entry is the
-display for selecting the construction power in the 'm' menu.
-The [[[[[BI] line is currently unused, but add a 1000 there anyway. That's what
-all the others have so when it's introduced, at least it will affect your
-powers identically to how it affects all the other powers.
-
-If you scroll to the very bottom of the file now, you'll see I've placed the
-skill at the bottom of the Misc branch of the skills tree. I then made a new
-class, constructor, which you can see in p_info.txt.
-
-That is all that is NEEDED when writing a script to add a skill - defining an
-mkey using add_mkey, and defining any powers that are called in the
-[[[[[B"fct"] (generally using [[[[[Badd_magic] ).
-
-And I've added the line
-
-#####Btome_dofile("construc.lua")
-
-in init.lua so the script is loaded on start-up!
-
-Below I'm going to talk in depth about a few other functions that you may find
-useful in your scripting.
-
-#####R=== fire_bolt() and fire_beam() ===
-
-In the last help file we looked at the routine for firing a ball -
-[[[[[Bfire_ball()]. Here's a quick note about beams and bolts...
-[[[[[Bfire_beam()] and [[[[[Bfire_bolt()] take 2 arguments:
-[[[[[B(type, direction, damage)]. So in the dismantle spell we have the
-direction passed from [[[[[Bget_aim_dir()] (the function that asks the player
-for a direction), the type of damage is [[[[[BGF_KILL_TRAP], which as you might
-expect disarms traps. And the damage is only 1 because it's not going to hurt
-monsters, just dismantle traps.
-
-#####R=== set_oppose_elec() ===
-
-OK here's another thing. Wander on down to the sparky_skills spell. After the
-appropriate bolt/ball is fired, we have the line:
-
-#####Bif player.oppose_elec == 0 then
-#####B set_oppose_elec(randint(10) + 20 + get_level(constructor_powers, 20)*3)
-#####Bend
-
-This is the bit that grants temporary resist electricity. We've called the
-function [[[[[Bset_oppose_elec(turns)], which sets the player's resist
-electricity to "on" for the time specified in the argument "turns". We're only
-calling this if the player is not already granted temporary resist electricity,
-and we've linked the number of turns it is active to the level of the
-construction skill. I've limited the maximum value of get_level to 20 in this
-instance. A similar idea can be used for temporarily granting levitation,
-extended infravision, protection against evil, resist fire, stuns, cuts and so
-on and so on. Have a look in player.pkg in the source for a full list....
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/help/lua_spel.txt b/lib/help/lua_spel.txt
deleted file mode 100644
index aa4a532b..00000000
--- a/lib/help/lua_spel.txt
+++ /dev/null
@@ -1,2150 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < spell.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_directed ===
-
-#####GDeclaration
- extern void teleport_player_directed(int rad, int dir);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport player, using a distance and a direction as a rough guide.
- *
- * This function is not at all obsessive about correctness.
- * This function allows teleporting into vaults (!)
- */
-
-#####GDescription
-Teleport a player up to "rad" grids away roughly in "dir" direction.
-
-#####GParameters
-> "rad" must not exceed 200. The distance teleported is a minimum of a
- quarter of "rad".
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-
-----------------------------------------------------------------------
-
-#####R=== teleport_away ===
-
-#####GDeclaration
- extern void teleport_away(int m_idx, int dis);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport a monster, normally up to "dis" grids away.
- *
- * Attempt to move the monster at least "dis/2" grids away.
- *
- * But allow variation to prevent infinite loops.
- */
-
-#####GDescription
-Teleport monster indicated by "m_idx" up to "dis" grids away.
-
-#####GParameters
-> "m_idx" is the index of the monster in m_list[].
-> "dis" must not exceed 200. The distance teleported is a minimum of a
- quarter of "dis".
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player ===
-
-#####GDeclaration
- extern void teleport_player(int dis);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport the player to a location up to "dis" grids away.
- *
- * If no such spaces are readily available, the distance may increase.
- * Try very hard to move the player at least a quarter that distance.
- */
-
-#####GDescription
-Teleport player up to "dis" grids away.
-
-#####GParameters
-> "dis" must not exceed 200. The distance teleported is a minimum of a
- quarter of "dis".
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_to ===
-
-#####GDeclaration
- extern void teleport_player_to(int ny, int nx);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport player to a grid near the given location
- *
- * This function is slightly obsessive about correctness.
- * This function allows teleporting into vaults (!)
- */
-
-#####GDescription
-Teleport player to a grid near the given location ("ny", "nx"). If
-the location is empty, the player goes there, otherwise they go to
-a grid as close as possible to the location.
-
-#####GParameters
-> "ny" is the y co-ordinate of the location.
-> "nx" is the x co-ordinate of the location.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_monster_to ===
-
-#####GDeclaration
- extern void teleport_monster_to(int m_idx, int ny,
- int nx);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport a monster to a grid near the given location
- *
- * This function is slightly obsessive about correctness.
- */
-
-#####GDescription
-Teleport monster indicated by "m_idx" to a grid near the given
-location ("ny", "nx"). If the location is empty, the monster goes
-there, otherwise they go to a grid as close as possible to the
-location.
-
-#####GParameters
-> "m_idx" is the index of the monster in m_list[].
-> "ny" is the y co-ordinate of the location.
-> "nx" is the x co-ordinate of the location.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_level ===
-
-#####GDeclaration
- extern void teleport_player_level(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport the player one level up or down (random when legal)
- */
-
-#####GDescription
-Teleport the player one level up or down at random.
-
-----------------------------------------------------------------------
-
-#####R=== recall_player ===
-
-#####GDeclaration
- extern void recall_player(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Recall the player to town or dungeon
- */
-
-#####GDescription
-Recall the player to town (if in dungeon) or dungeon (if in town).
-
-----------------------------------------------------------------------
-
-#####R=== take_hit ===
-
-#####GDeclaration
- extern void take_hit(int damage, cptr kb_str);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Decreases players hit points and sets death flag if necessary
- *
- * XXX XXX XXX Invulnerability needs to be changed into a "shield"
- *
- * XXX XXX XXX 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".
- */
-
-#####GDescription
-Reduce the player's current hit points by "damage" points. If the
-player dies, "kb_str" is used to record what the player was killed by
-(see high-score table).
-
-#####GParameters
-> "damage" is the amount of damage.
-> "kb_str" is a string describing what killed the player.
-
-----------------------------------------------------------------------
-
-#####R=== take_sanity_hit ===
-
-#####GDeclaration
- extern void take_sanity_hit(int damage, cptr hit_from);
-
-#####GFile
- spells1.c
-
-#####GComment
-/* Decrease player's sanity. This is a copy of the function above. */
-
-#####GDescription
-Reduce the player's current sanity points by "damage" points. If the
-player dies, "hit_from" is used to record what the player was killed
-by (see high-score table).
-
-#####GParameters
-> "damage" is the amount of damage.
-> "hit_from" is a string describing what killed the player.
-
-----------------------------------------------------------------------
-
-#####R=== project ===
-
-#####GDeclaration
- extern bool project(int who, int rad, int y, int x,
- int dam, int typ, int flg);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Generic "beam"/"bolt"/"ball" projection routine.
- *
- * Input:
- * who: Index of "source" monster (negative for "player")
- * jk -- -2 for traps, only used with project_jump
- * rad: Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
- * y,x: Target location (or location to travel "towards")
- * dam: Base damage roll to apply to affected monsters (or player)
- * typ: Type of damage to apply to monsters (and objects)
- * flg: Extra bit flags (see PROJECT_xxxx in "defines.h")
- *
- * Return:
- * TRUE if any "effects" of the projection were observed, else FALSE
- *
- * Allows a monster (or player) to project a beam/bolt/ball of a given kind
- * towards a given location (optionally passing over the heads of interposing
- * monsters), and have it do a given amount of damage to the monsters (and
- * optionally objects) within the given radius of the final location.
- *
- * A "bolt" travels from source to target and affects only the target grid.
- * A "beam" travels from source to target, affecting all grids passed through.
- * A "ball" travels from source to the target, exploding at the target, and
- * affecting everything within the given radius of the target location.
- *
- * Traditionally, a "bolt" does not affect anything on the ground, and does
- * not pass over the heads of interposing monsters, much like a traditional
- * missile, and will "stop" abruptly at the "target" even if no monster is
- * positioned there, while a "ball", on the other hand, passes over the heads
- * of monsters between the source and target, and affects everything except
- * the source monster which lies within the final radius, while a "beam"
- * affects every monster between the source and target, except for the casting
- * monster (or player), and rarely affects things on the ground.
- *
- * Two special flags allow us to use this function in special ways, the
- * "PROJECT_HIDE" flag allows us to perform "invisible" projections, while
- * the "PROJECT_JUMP" flag allows us to affect a specific grid, without
- * actually projecting from the source monster (or player).
- *
- * The player will only get "experience" for monsters killed by himself
- * Unique monsters can only be destroyed by attacks from the player
- *
- * Only 256 grids can be affected per projection, limiting the effective
- * "radius" of standard ball attacks to nine units (diameter nineteen).
- *
- * One can project in a given "direction" by combining PROJECT_THRU with small
- * offsets to the initial location (see "line_spell()"), or by calculating
- * "virtual targets" far away from the player.
- *
- * One can also use PROJECT_THRU to send a beam/bolt along an angled path,
- * continuing until it actually hits something (useful for "stone to mud").
- *
- * Bolts and Beams explode INSIDE walls, so that they can destroy doors.
- *
- * Balls must explode BEFORE hitting walls, or they would affect monsters
- * on both sides of a wall. Some bug reports indicate that this is still
- * happening in 2.7.8 for Windows, though it appears to be impossible.
- *
- * We "pre-calculate" the blast area only in part for efficiency.
- * More importantly, this lets us do "explosions" from the "inside" out.
- * This results in a more logical distribution of "blast" treasure.
- * It also produces a better (in my opinion) animation of the explosion.
- * It could be (but is not) used to have the treasure dropped by monsters
- * in the middle of the explosion fall "outwards", and then be damaged by
- * the blast as it spreads outwards towards the treasure drop location.
- *
- * Walls and doors are included in the blast area, so that they can be
- * "burned" or "melted" in later versions.
- *
- * This algorithm is intended to maximise simplicity, not necessarily
- * efficiency, since this function is not a bottleneck in the code.
- *
- * We apply the blast effect from ground zero outwards, in several passes,
- * first affecting features, then objects, then monsters, then the player.
- * This allows walls to be removed before checking the object or monster
- * in the wall, and protects objects which are dropped by monsters killed
- * in the blast, and allows the player to see all affects before he is
- * killed or teleported away. The semantics of this method are open to
- * various interpretations, but they seem to work well in practice.
- *
- * We process the blast area from ground-zero outwards to allow for better
- * distribution of treasure dropped by monsters, and because it provides a
- * pleasing visual effect at low cost.
- *
- * Note that the damage done by "ball" explosions decreases with distance.
- * This decrease is rapid, grids at radius "dist" take "1/dist" damage.
- *
- * Notice the "napalm" effect of "beam" weapons. First they "project" to
- * the target, and then the damage "flows" along this beam of destruction.
- * The damage at every grid is the same as at the "centre" of a "ball"
- * explosion, since the "beam" grids are treated as if they ARE at the
- * centre of a "ball" explosion.
- *
- * Currently, specifying "beam" plus "ball" means that locations which are
- * covered by the initial "beam", and also covered by the final "ball", except
- * for the final grid (the epicentre of the ball), will be "hit twice", once
- * by the initial beam, and once by the exploding ball. For the grid right
- * next to the epicentre, this results in 150% damage being done. The centre
- * does not have this problem, for the same reason the final grid in a "beam"
- * plus "bolt" does not -- it is explicitly removed. Simply removing "beam"
- * grids which are covered by the "ball" will NOT work, as then they will
- * receive LESS damage than they should. Do not combine "beam" with "ball".
- *
- * The array "gy[],gx[]" with current size "grids" is used to hold the
- * collected locations of all grids in the "blast area" plus "beam path".
- *
- * Note the rather complex usage of the "gm[]" array. First, gm[0] is always
- * zero. Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the
- * first blast grid (see above) with radius "N" from the blast centre. Note
- * that only the first gm[1] grids in the blast area thus take full damage.
- * Also, note that gm[rad+1] is always equal to "grids", which is the total
- * number of blast grids.
- *
- * Note that once the projection is complete, (y2,x2) holds the final location
- * of bolts/beams, and the "epicentre" of balls.
- *
- * Note also that "rad" specifies the "inclusive" radius of projection blast,
- * so that a "rad" of "one" actually covers 5 or 9 grids, depending on the
- * implementation of the "distance" function. Also, a bolt can be properly
- * viewed as a "ball" with a "rad" of "zero".
- *
- * Note that if no "target" is reached before the beam/bolt/ball travels the
- * maximum distance allowed (MAX_RANGE), no "blast" will be induced. This
- * may be relevant even for bolts, since they have a "1x1" mini-blast.
- *
- * 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
- * of the path, since it either starts at the player or ends on the player.
- *
- * 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.
- */
-
-#####GDescription
-Generate a beam/bolt/ball starting from "who" with a radius of "rad"
-at target grid "y,x" for "damage" points of "typ" damage. The beam/
-bolt/ball can have various properties as denoted by "flg".
-
-#####GParameters
-> "who" is > 0 (index of monster in m_list[]), < 0 and
- not -100 or -101 (player), -100 or -101 (trap).
-> "rad" is 0 for a beam/bolt and 1-9 for a ball.
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "dam" is the number of points of damage.
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== corrupt_player ===
-
-#####GDeclaration
- extern void corrupt_player(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-(none)
-
-#####GDescription
-Swap two of the players stats at random.
-
-----------------------------------------------------------------------
-
-#####R=== grow_trees ===
-
-#####GDeclaration
- extern void grow_trees(int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Grow trees
- */
-
-#####GDescription
-Grow up to (("rad" x "rad") + 11) trees around the player.
-
-#####GParameters
-> "rad" is the radius of the area where trees may grow.
-
-----------------------------------------------------------------------
-
-#####R=== hp_player ===
-
-#####GDeclaration
- extern bool hp_player(int num);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Increase players hit points, notice effects
- */
-
-#####GDescription
-Add "num" points to the player's current hit points. The total can
-not exceed the maximum.
-
-#####GParameters
-> "num" is the number of points to add.
-
-----------------------------------------------------------------------
-
-#####R=== heal_insanity ===
-
-#####GDeclaration
- extern bool heal_insanity(int val);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Heal insanity. */
-
-#####GDescription
-Add "val" points to the player's current sanity points. The total can
-not exceed the maximum.
-
-#####GParameters
-> "val" is the number of points to add.
-
-----------------------------------------------------------------------
-
-#####R=== warding_glyph ===
-
-#####GDeclaration
- extern void warding_glyph(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Leave a "glyph of warding" which prevents monster movement
- */
-
-#####GDescription
-Place a glyph at the player's location. The location must be bare.
-
-----------------------------------------------------------------------
-
-#####R=== explosive_rune ===
-
-#####GDeclaration
- extern void explosive_rune(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Place a minor glyph (explosive rune) at the player's location. The
-location must be bare.
-
-----------------------------------------------------------------------
-
-#####R=== do_dec_stat ===
-
-#####GDeclaration
- extern bool do_dec_stat(int stat, int mode);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Lose a "point"
- */
-
-#####GDescription
-Attempt to reduce the player's "stat" statistic by a point.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-> "mode" is the type of decrease: temporary, normal, or permanent
- *****fields.txt*0[STAT_DEC_fields]
-
-----------------------------------------------------------------------
-
-#####R=== do_res_stat ===
-
-#####GDeclaration
- extern bool do_res_stat(int stat);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Restore lost "points" in a stat
- */
-
-#####GDescription
-Restore the player's "stat" statistic.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-
-----------------------------------------------------------------------
-
-#####R=== do_inc_stat ===
-
-#####GDeclaration
- extern bool do_inc_stat(int stat);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Gain a "point" in a stat
- */
-
-#####GDescription
-Increase the player's "stat" statistic by a point.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-
-----------------------------------------------------------------------
-
-#####R=== identify_pack ===
-
-#####GDeclaration
- extern void identify_pack(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Identify everything being carried.
- * Done by a potion of "self knowledge".
- */
-
-#####GDescription
-Identify all items in the inventory.
-
-----------------------------------------------------------------------
-
-#####R=== remove_curse ===
-
-#####GDeclaration
- extern bool remove_curse(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Remove most curses
- */
-
-#####GDescription
-Remove all curses except for heavy curses.
-
-----------------------------------------------------------------------
-
-#####R=== remove_all_curse ===
-
-#####GDeclaration
- extern bool remove_all_curse(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Remove all curses
- */
-
-#####GDescription
-Remove all curses including heavy curses.
-
-----------------------------------------------------------------------
-
-#####R=== restore_level ===
-
-#####GDeclaration
- extern bool restore_level(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Restores any drained experience
- */
-
-#####GDescription
-Restore all drained experience points (if any).
-
-----------------------------------------------------------------------
-
-#####R=== self_knowledge ===
-
-#####GDeclaration
- extern void self_knowledge(FILE *fff);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * self-knowledge... idea from nethack. Useful for determining powers and
- * resistances of items. It saves the screen, clears it, then starts listing
- * attributes, a screenful at a time. (There are a LOT of attributes to
- * list. It will probably take 2 or 3 screens for a powerful character whose
- * using several artifacts...) -CFT
- *
- * It is now a lot more efficient. -BEN-
- *
- * See also "identify_fully()".
- *
- * XXX XXX XXX Use the "show_file()" method, perhaps.
- */
-
-#####GDescription
-Show all attributes including racial powers, mutations, and equipment
-effects.
-
-#####GParameters
-> "*ffff" points to a file (write info to file) or is NULL (write info
- to screen).
-
-----------------------------------------------------------------------
-
-#####R=== lose_all_info ===
-
-#####GDeclaration
- extern bool lose_all_info(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Forget everything
- */
-
-#####GDescription
-Forget about objects and the map.
-
-----------------------------------------------------------------------
-
-#####R=== detect_traps ===
-
-#####GDeclaration
- extern bool detect_traps(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all traps on current panel
- */
-
-#####GDescription
-Detect all traps on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_doors ===
-
-#####GDeclaration
- extern bool detect_doors(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all doors on current panel
- */
-
-#####GDescription
-Detect all doors on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_stairs ===
-
-#####GDeclaration
- extern bool detect_stairs(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all stairs on current panel
- */
-
-#####GDescription
-Detect all stairs on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_treasure ===
-
-#####GDeclaration
- extern bool detect_treasure(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect any treasure on the current panel
- */
-
-#####GDescription
-Detect any treasure on the current panel.
-
-----------------------------------------------------------------------
-
-Field: hack_no_detect_message
-Value: FALSE
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_gold ===
-
-#####GDeclaration
- extern bool detect_objects_gold(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "gold" objects on the current panel
- */
-
-#####GDescription
-Detect all objects with the TV_GOLD flag.
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_normal ===
-
-#####GDeclaration
- extern bool detect_objects_normal(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "normal" objects on the current panel
- */
-
-#####GDescription
-Detect all objects without the TV_GOLD flag.
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_magic ===
-
-#####GDeclaration
- extern bool detect_objects_magic(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "magic" objects on the current panel.
- *
- * This will light up all spaces with "magic" items, including artifacts,
- * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
- * and "enchanted" items of the "good" variety.
- *
- * It can probably be argued that this function is now too powerful.
- */
-
-#####GDescription
-Detect all "magic" objects which are artefacts, ego items, or have one
-of the following flags - TV_AMULET, TV_RING, TV_BATERIE, TV_STAFF,
-TV_WAND, TV_ROD, TV_ROD_MAIN, TV_SCROLL, TV_POTION, TV_POTION2,
-TV_VALARIN_BOOK, TV_MAGERY_BOOK, TV_SHADOW_BOOK, TV_CHAOS_BOOK,
-TV_SPIRIT_BOOK, TV_NETHER_BOOK, TV_DAEMON_BOOK, TV_CRUSADE_BOOK,
-TV_SIGALDRY_BOOK, TV_SYMBIOTIC_BOOK, TV_MUSIC_BOOK.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_normal ===
-
-#####GDeclaration
- extern bool detect_monsters_normal(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "normal" monsters on the current panel
- */
-
-#####GDescription
-Detect all non-invisible monsters (without RF2_INVISIBLE).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_invis ===
-
-#####GDeclaration
- extern bool detect_monsters_invis(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "invisible" monsters on current panel
- */
-
-#####GDescription
-Detect all invisible monsters (with RF2_INVISIBLE).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_evil ===
-
-#####GDeclaration
- extern bool detect_monsters_evil(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "evil" monsters on current panel
- */
-
-#####GDescription
-Detect all evil monsters (with RF3_EVIL).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_good ===
-
-#####GDeclaration
- extern bool detect_monsters_good(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Detect good monsters */
-
-#####GDescription
-Detect all good monsters (with RF3_GOOD).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_xxx ===
-
-#####GDeclaration
- extern bool detect_monsters_xxx(u32b match_flag);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * A "generic" detect monsters routine, tagged to flags3
- */
-
-#####GDescription
-Detect all monsters with "match_flag" flag.
-
-#####GParameters
-> "match_flag" can be any RF3_ flag (see defines.h) but only
- RF3_DEMON, RF3_UNDEAD, RF3_GOOD work.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_string ===
-
-#####GDeclaration
- extern bool detect_monsters_string(cptr);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all (string) monsters on current panel
- */
-
-#####GDescription
-Detect all monsters whose default monster character matches a
-character pointed to by "cptr".
-
-#####GParameters
-> "cptr" is a pointer to a single character, eg 'Z' for hounds. For
- available characters, see the "symbol" field of the graphics (G)
- line of r_info.txt.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_nonliving ===
-
-#####GDeclaration
- extern bool detect_monsters_nonliving(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "nonliving", "undead" or "demonic" monsters on current panel
- */
-
-#####GDescription
-Detect all non-living monsters (with RF3_NONLIVING, RF3_UNDEAD, or
-RF3_DEMON).
-
-----------------------------------------------------------------------
-
-#####R=== detect_all ===
-
-#####GDeclaration
- extern bool detect_all(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect everything
- */
-
-#####GDescription
-Detects traps, doors, stairs, treasure, gold objects, normal objects,
-invisible monsters, normal (visible) monsters.
-
-----------------------------------------------------------------------
-
-#####R=== stair_creation ===
-
-#####GDeclaration
- extern void stair_creation(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Create stairs at the player location
- */
-
-#####GDescription
-Create stairs at the player location. This is not allowed if the grid
-is not empty, the player is not in a dungeon, the player is on a
-special level, the player is in an arena or quest. If the player is
-in the town or wilderness the stairs will go down. If the player is
-on a quest level or at the bottom of a dungeon, the stairs will go up.
-Otherwise there is an even chance the stairs will go up or down.
-
-----------------------------------------------------------------------
-
-#####R=== wall_stone ===
-
-#####GDeclaration
- extern bool wall_stone(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Create a stone wall on the player's grid. This function uses the
-project() function to create the stone wall. Apparently zero can be
-used as the "who" parameter for the player. See details for the
-project() function elsewhere in this document.
-
-----------------------------------------------------------------------
-
-#####R=== create_artifact ===
-
-#####GDeclaration
- extern bool create_artifact(object_type *o_ptr,
- bool a_scroll, bool get_name);
-
-#####GFile
- randart.c
-
-#####GComment
-(none)
-
-#####GDescription
-Create an artifact from object "*optr".
-
-#####GParameters
-> "*optr* is a pointer to an object
-> "a_scroll" is true if the artifact is created by reading a scroll
-> "get_name" is true if the artifact is to be named by the player (if
- a_scroll is true) or created randomly (a_scroll is false), or false
- if an inscription is used.
-
-----------------------------------------------------------------------
-
-#####R=== ident_spell ===
-
-#####GDeclaration
- extern bool ident_spell(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Identify an object in the inventory (or on the floor)
- * This routine does *not* automatically combine objects.
- * Returns TRUE if something was identified, else FALSE.
- */
-
-#####GDescription
-Identify an object in the inventory (or on the floor).
-
-----------------------------------------------------------------------
-
-#####R=== identify_fully ===
-
-#####GDeclaration
- extern bool identify_fully(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Fully "identify" an object in the inventory -BEN-
- * This routine returns TRUE if an item was identified.
- */
-
-#####GDescription
-Fully "identify" an object in the inventory (or on the floor).
-
-----------------------------------------------------------------------
-
-#####R=== recharge ===
-
-#####GDeclaration
- extern bool recharge(int num);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Recharge a wand/staff/rod from the pack or on the floor.
- * This function has been rewritten in Oangband. -LM-
- *
- * Mage -- Recharge I --> recharge(90)
- * Mage -- Recharge II --> recharge(150)
- * Mage -- Recharge III --> recharge(220)
- *
- * Priest or Necromancer -- Recharge --> recharge(140)
- *
- * Scroll of recharging --> recharge(130)
- * Scroll of *recharging* --> recharge(200)
- *
- * It is harder to recharge high level, and highly charged wands,
- * staffs, and rods. The more wands in a stack, the more easily and
- * strongly they recharge. Staffs, however, each get fewer charges if
- * stacked.
- *
- * XXX XXX XXX Beware of "sliding index errors".
- */
-
-#####GDescription
-Recharge an object in the inventory (or on the floor) with "num"
-power.
-
-#####GParameters
-> "num" is the power used in recharging. It is compared to the
- object's level to determine whether the item is recharged
- successfully or destroyed. If it is recharged, it also determines
- how many charges are added, or how much recharge time is reduced.
-
-----------------------------------------------------------------------
-
-#####R=== aggravate_monsters ===
-
-#####GDeclaration
- extern void aggravate_monsters(int who);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Wake up all monsters, and speed up "los" monsters.
- */
-
-#####GDescription
-Aggravate monsters, originating from "who".
-
-#####GParameters
-> "who" is the index of monster in m_list[] (1 if it is the player)
- which triggers the aggravation;
-
-----------------------------------------------------------------------
-
-#####R=== genocide ===
-
-#####GDeclaration
- extern bool genocide(bool player_cast);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Genocide a monster race.
-
-#####GParameters
-> "player_cast" is true if the player cast the spell so the player can
- take damage.
-
-----------------------------------------------------------------------
-
-#####R=== mass_genocide ===
-
-#####GDeclaration
- extern bool mass_genocide(bool player_cast);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Delete all nearby (non-unique) monsters
- */
-
-#####GDescription
-Delete all nearby (non-unique) monsters.
-
-#####GParameters
-> "player_cast" is true if the player cast the spell so the player can
- take damage.
-
-----------------------------------------------------------------------
-
-#####R=== probing ===
-
-#####GDeclaration
- extern bool probing(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Probe nearby monsters
- */
-
-#####GDescription
-Probe all nearby monsters.
-
-----------------------------------------------------------------------
-
-#####R=== banish_evil ===
-
-#####GDeclaration
- extern bool banish_evil(int dist);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Banish evil monsters
- */
-
-#####GDescription
-Banish nearby evil monsters doing "dist" points of GF_AWAY_EVIL
-damage.
-
-#####GParameters
-> "dist" is the amount of damage done to each monster.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_evil ===
-
-#####GDeclaration
- extern bool dispel_evil(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel evil monsters
- */
-
-#####GDescription
-Dispel nearby evil monsters doing "dam" points of GF_DISP_EVIL
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_good ===
-
-#####GDeclaration
- extern bool dispel_good(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel good monsters
- */
-
-#####GDescription
-Dispel nearby good monsters doing "dam" points of GF_DISP_GOOD
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_undead ===
-
-#####GDeclaration
- extern bool dispel_undead(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel undead monsters
- */
-
-#####GDescription
-Dispel nearby undead monsters doing "dam" points of GF_DISP_UNDEAD
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_monsters ===
-
-#####GDeclaration
- extern bool dispel_monsters(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel all monsters
- */
-
-#####GDescription
-Dispel all nearby monsters doing "dam" points of GF_DISP_ALL
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_living ===
-
-#####GDeclaration
- extern bool dispel_living(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel 'living' monsters
- */
-
-#####GDescription
-Dispel nearby living monsters doing "dam" points of GF_DISP_LIVING
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_demons ===
-
-#####GDeclaration
- extern bool dispel_demons(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel demons
- */
-
-#####GDescription
-Dispel nearby demon monsters doing "dam" points of GF_DISP_DEMON
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== turn_undead ===
-
-#####GDeclaration
- extern bool turn_undead(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Turn undead
- */
-
-#####GDescription
-Turn nearby undead monsters doing a point of GF_TURN_UNDEAD damage for
-each player level.
-
-----------------------------------------------------------------------
-
-#####R=== wipe ===
-
-#####GDeclaration
- extern void wipe(int y1, int x1, int r);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Wipe -- Empties a part of the dungeon
- */
-
-#####GDescription
-Delete monsters and objects from an area of the dungeon centred at
-grid "y1,x1" for a radius "r". This does not work on special levels or
-quests. The player may be blinded. The player forgets the affected
-area and it becomes dark. All grids become floor.
-
-#####GParameters
-> "y1" is the y-coordinate of the wipe's origin.
-> "x1" is the x-coordinate of the wipe's origin.
-> "r" is the radius of the wipe.
-
-----------------------------------------------------------------------
-
-#####R=== destroy_area ===
-
-#####GDeclaration
- extern void destroy_area(int y1, int x1, int r,
- bool full);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * The spell of destruction
- *
- * This spell "deletes" monsters (instead of "killing" them).
- *
- * Later we may use one function for both "destruction" and
- * "earthquake" by using the "full" to select "destruction".
- */
-
-#####GDescription
-Delete monsters and objects from an area of the dungeon centred at
-grid "y1,x1" for a radius "r". This does not work on special levels or
-quests. The epicentre is NOT affected. The player may be blinded. The
-player forgets the affected area and it becomes dark. The grids can
-become granite, quartz, magma, or floor.
-
-#####GParameters
-> "y1" is the y-coordinate of the destruction's origin.
-> "x1" is the x-coordinate of the destruction's origin.
-> "r" is the radius of the destruction.
-> "full" is currently unused.
-
-----------------------------------------------------------------------
-
-#####R=== earthquake ===
-
-#####GDeclaration
- extern void earthquake(int cy, int cx, int r);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Induce an "earthquake" of the given radius at the given location.
- *
- * This will turn some walls into floors and some floors into walls.
- *
- * The player will take damage and "jump" into a safe grid if possible,
- * otherwise, he will "tunnel" through the rubble instantaneously.
- *
- * Monsters will take damage, and "jump" into a safe grid if possible,
- * otherwise they will be "buried" in the rubble, disappearing from
- * the level in the same way that they do when genocided.
- *
- * Note that thus the player and monsters (except eaters of walls and
- * passers through walls) will never occupy the same grid as a wall.
- * Note that as of now (2.7.8) no monster may occupy a "wall" grid, even
- * for a single turn, unless that monster can pass_walls or kill_walls.
- * This has allowed massive simplification of the "monster" code.
- */
-
-#####GDescription
-Create an earthquake centred on grid "cy,cx" with a radius of "r".
-This does not work on quest levels. The epicentre is NOT affected.
-Only about 15% of the grids are affected. The player takes 300 points
-of damage if they can't be moved to a safe grid, otherwise damage is
-from 10 to 40 points. The player forgets the affected area and it
-becomes dark. The grids can become granite, quartz, magma, or floor.
-
-#####GParameters
-Parameters:
-> "cy" is the y-coordinate of the earthquake origin.
-> "cx" is the x-coordinate of the earthquake origin.
-> "r" is the radius of the earthquake.
-
-----------------------------------------------------------------------
-
-#####R=== map_area ===
-
-#####GDeclaration
- extern void map_area(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Hack -- map the current panel (plus some) ala "magic mapping"
- */
-
-#####GDescription
-Map the current panel plus up to 10 grids up and down, and up to 20
-grids left and right.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_lite ===
-
-#####GDeclaration
- extern void wiz_lite(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Light up the dungeon using "clairvoyance"
- *
- * This function "illuminates" every grid in the dungeon, memorises all
- * "objects", memorises all grids as with magic mapping, and, under the
- * standard option settings (view_perma_grids but not view_torch_grids)
- * memorises all floor grids too.
- *
- * Note that if "view_perma_grids" is not set, we do not memorise floor
- * grids, since this would defeat the purpose of "view_perma_grids", not
- * that anyone seems to play without this option.
- *
- * Note that if "view_torch_grids" is set, we do not memorise floor grids,
- * since this would prevent the use of "view_torch_grids" as a method to
- * keep track of what grids have been observed directly.
- */
-
-#####GDescription
-Light up the entire dungeon and show all monsters and objects.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_lite_extra ===
-
-#####GDeclaration
- extern void wiz_lite_extra(void);
-
-#####GFile
- cave.c
-
-#####GComment
-(none)
-
-#####GDescription
-Light up the entire dungeon and show all monsters and objects. All
-squares are lit and remembered.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_dark ===
-
-#####GDeclaration
- extern void wiz_dark(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Forget the dungeon map (ala "Thinking of Maud...").
- */
-
-#####GDescription
-Forget all grids and objects. All grids become dark.
-
-----------------------------------------------------------------------
-
-#####R=== lite_room ===
-
-#####GDeclaration
- extern void lite_room(int y1, int x1);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Illuminate any room containing the given location.
- */
-
-#####GDescription
-Light up the room (if any) of grid "y1,x1".
-
-#####GParameters
-> "y1" is the y-coordinate of the grid.
-> "x1" is the x-coordinate of the grid.
-
-----------------------------------------------------------------------
-
-#####R=== unlite_room ===
-
-#####GDeclaration
- extern void unlite_room(int y1, int x1);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Darken all rooms containing the given location
- */
-
-#####GDescription
-Darken all rooms (if any) of grid "y1,x1".
-
-#####GParameters
-> "y1" is the y-coordinate of the grid.
-> "x1" is the x-coordinate of the grid.
-
-----------------------------------------------------------------------
-
-#####R=== lite_area ===
-
-#####GDeclaration
- extern bool lite_area(int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- call light around the player
- * Affect all monsters in the projection radius
- */
-
-#####GDescription
-Light up the room (if any) of the player's grid. Monsters take "dam"
-points of GF_LITE_WEAK damage if they are within "r" grids of the
-player.
-
-#####GParameters
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage.
-
-----------------------------------------------------------------------
-
-#####R=== unlite_area ===
-
-#####GDeclaration
- extern bool unlite_area(int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- call darkness around the player
- * Affect all monsters in the projection radius
- */
-
-#####GDescription
-Darken the room (if any) of the player's grid. Monsters take "dam"
-points of GF_DARK_WEAK damage if they are within "r" grids of the
-player.
-
-#####GParameters
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_ball_beam ===
-
-#####GDeclaration
- extern bool fire_ball_beam(int typ, int dir, int dam,
- int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a ball-beamed spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball-beamed spell of type "typ" in direction "dir" for damage
-"dam" points with a radius of "rad" grids.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_ball ===
-
-#####GDeclaration
- extern bool fire_ball(int typ, int dir, int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a ball spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball spell of type "typ" in direction "dir" for "dam" points of
-damage. The ball has a radius of "rad" grids.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_bolt ===
-
-#####GDeclaration
- extern bool fire_bolt(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a bolt spell
- * Stop if we hit a monster, as a "bolt"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a bolt spell of type "typ" in direction "dir" for "dam" points of
-damage.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_beam ===
-
-#####GDeclaration
- extern bool fire_beam(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a beam spell
- * Pass through monsters, as a "beam"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a beam spell of type "typ" in direction "dir" for "dam" points of
-damage.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_ball ===
-
-#####GDeclaration
- extern bool fire_druid_ball(int typ, int dir, int dam,
- int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidic ball spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball spell of type "typ" in direction "dir" for "dam" points of
-damage. The ball has a radius of "rad" grids. The spell follows a mana
-path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_bolt ===
-
-#####GDeclaration
- extern bool fire_druid_bolt(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidic bolt spell
- * Stop if we hit a monster, as a "bolt"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a bolt spell of type "typ" in direction "dir" for "dam" points of
-damage. The spell follows a mana path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_beam ===
-
-#####GDeclaration
- extern bool fire_druid_beam(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidistic beam spell
- * Pass through monsters, as a "beam"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a beam spell of type "typ" in direction "dir" for "dam" points of
-damage. The spell follows a mana path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_bolt_or_beam ===
-
-#####GDeclaration
- extern bool fire_bolt_or_beam(int prob, int typ, int dir,
- int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a bolt spell, or rarely, a beam spell
- */
-
-#####GDescription
-Cast a beam (chance of "prob" in 100) or bolt spell of type "typ" in
-direction "dir" for "dam" points of damage.
-
-#####GParameters
-> "prob" is the number of times out of 100 that the bolt will actually
- be a beam. Obviously this value should range from 1 to 99 (0 will
- always give a beam, 100 or higher will always give a beam. There are
- separate functions for these cases).
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== alchemy ===
-
-#####GDeclaration
- extern bool alchemy(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Turns an object into gold, gain some of its value in a shop */
-
-#####GDescription
-The player selects an object (and quantity if it applies) from the
-inventory or the floor and attempts to turn it into gold. If the
-price of the item is < 0 then the player gains nothing (fool's gold),
-otherwise the player gets a third of the price in gold. Artifacts are
-not affected.
-
-----------------------------------------------------------------------
-
-#####R=== alter_reality ===
-
-#####GDeclaration
- extern void alter_reality(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-The player leaves the level immediately.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_swap ===
-
-#####GDeclaration
- extern void teleport_swap(int dir);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Player swaps places with target in direction "dir". The target must be
-a monster. It will not work if the space-time continuum can not be
-disrupted or if the monster resists teleportation.
-
-----------------------------------------------------------------------
-
-#####R=== project_meteor ===
-
-#####GDeclaration
- extern void project_meteor(int radius, int typ, int dam,
- u32b flg);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Apply a "project()" a la meteor shower
- */
-
-#####GDescription
-Generate between "rad" and "rad" x 2 ball spells of type "typ" for
-"dam" points of damage. The ball can have various properties as
-denoted by "flg".
-
-#####GParameters
-> "rad" is the minimum number of balls created. "rad" + randint("rad")
- balls are created. Each ball has a radius of 2 grids. Each target
- grid is within 5 grids of the player.
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dam" is the number of points of damage.
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== passwall ===
-
-#####GDeclaration
- extern bool passwall(int dir, bool safe);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Send the player shooting through walls in the given direction until
- * they reach a non-wall space, or a monster, or a permanent wall.
- */
-
-#####GDescription
-Move the player through walls in direction "dir". if "safe" then the
-player can not end up in a wall - if they do, the wall is replaced by
-a floor. This does not work in the wilderness, on quest levels, or if
-teleport is not allowed. Stopping on monsters or inside vaults is not
-allowed.
-
-#####GParameters
-> "dir" must be from 0 to 9. It can not be 5.
- *****fields.txt*0[direction]
-> "safe" must be true if the player is not to be trapped in a wall
- when the movement is finished.
-
-----------------------------------------------------------------------
-
-#####R=== project_hook ===
-
-#####GDeclaration
- extern bool project_hook(int typ, int dir, int dam,
- int flg);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- apply a "projection()" in a direction (or at the target)
- */
-
-#####GDescription
-Generate a beam/bolt of type "typ" in direction "dir" (or at a target)
-for "dam" points of damage. The beam/bolt can have various properties
-as denoted by "flg".
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9. 5 means use the current target.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== reset_recall ===
-
-#####GDeclaration
- extern bool reset_recall(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Ask the player for a dungeon and appropriate level within the dungeon.
-The player can not specify a dungeon they have not gone to yet. If the
-player chooses levels 99 or 100, the level is set to 98.
-
-----------------------------------------------------------------------
-
-#####R=== get_aim_dir ===
-
-#####GDeclaration
- extern bool get_aim_dir(int *dp = 0);
-
-#####GFile
- xtra2.c
-
-#####GComment
-/*
- * Get an "aiming direction" from the user.
- *
- * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
- * "0" for "current target", and "-1" for "entry aborted".
- *
- * Note that "Force Target", if set, will pre-empt user interaction,
- * if there is a usable target already set.
- *
- * Note that confusion over-rides any (explicit?) user choice.
- */
-
-#####GDescription
-Get an aiming direction from the user and store it in "dp". A target
-can be selected. If the player is confused, the direction will be
-random.
-
-#####GParameters
-> "dp" = player direction.
-
-----------------------------------------------------------------------
-
-#####R=== project_hack ===
-
-#####GDeclaration
- extern bool project_hack(int typ, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Apply a "project()" directly to all viewable monsters
- *
- * Note that affected monsters are NOT auto-tracked by this usage.
- */
-
-#####GDescription
-Generate beam/bolt spells of type "typ" for "dam" points of damage to
-all viewable monsters in line of site.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by Chris Hadgis]
diff --git a/lib/help/lua_util.txt b/lib/help/lua_util.txt
deleted file mode 100644
index 8886a2b4..00000000
--- a/lib/help/lua_util.txt
+++ /dev/null
@@ -1,898 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < util.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####R=== bst ===
-
-#####GDeclaration
- s32b bst(s32b what, s32b t);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Break scalar time
- */
-
-#####GDescription
-Return the minute, hour, day, or year for turn "t". One turn takes 7.5
-seconds.
-
-#####GParameters
-> "what" is the unit to be returned and must be one of
- MINUTE (number of turns per minute, which is 8)
- HOUR (number of turns per hour, which is 480)
- DAY (number of turns per day, which is 11,520)
- YEAR (number of turns per year, which is 4,204,800)
-> "t" is the number of turns.
-
-----------------------------------------------------------------------
-
-#####R=== path_build ===
-
-#####GDeclaration
- errr path_build(char *buf, int max, cptr path, cptr file);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Create a new path by appending a file (or directory) to a path
-*
-* This requires no special processing on simple machines, except
-* for verifying the size of the filename, but note the ability to
-* bypass the given "path" with certain special file-names.
-*
-* Note that the "file" may actually be a "sub-path", including
-* a path and a file.
-*
-* Note that this function yields a path which must be "parsed"
-* using the "parse" function above.
-*/
-
-#####GDescription
-Append file "file" to path "path" and return the result in "buf". The
-length of "buf" is a maximum of "max" characters. If "file" starts
-with '~' then return "file". If "file" starts with the path separator
-and the path separator is not blank then return "file". If there is no
-path then return "file". Otherwise return "path" + path separator +
-"file". The path separator is defined in "H-config.h".
-
-#####GParameters
-> "buf" contains the new path.
-> "max" is the maximum number of characters allowed in "buf".
-> "path" is the original path.
-> "file" is the original file.
-
-----------------------------------------------------------------------
-
-#####R=== move_cursor ===
-
-#####GDeclaration
- void move_cursor(int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Move the cursor
-*/
-
-#####GDescription
-Move the cursor to row "row" and column "col".
-
-#####GParameters
-> "row" is the row the cursor is to be moved to.
-> "col" is the column the cursor is to be moved to.
-
-----------------------------------------------------------------------
-
-#####R=== inkey ===
-
-#####GDeclaration
- char inkey(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get a keypress from the user.
-*
-* This function recognises a few "global parameters". These are variables
-* which, if set to TRUE before calling this function, will have an effect
-* on this function, and which are always reset to FALSE by this function
-* 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.
-*/
-
-#####GDescription
-Get a keypress from the user.
-
-----------------------------------------------------------------------
-
-#####R=== cmsg_print ===
-
-#####GDeclaration
- void cmsg_print(byte color, cptr msg);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Output a message to the top line of the screen.
-*
-* Break long messages into multiple pieces (40-72 chars).
-*
-* Allow multiple short messages to "share" the top line.
-*
-* Prompt the user to make sure he has a chance to read them.
-*
-* These messages are memorised 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.
-*/
-
-#####GDescription
-In color "color", output message "msg" to the top line of the screen.
-If the message is blank or has more than 1000 characters, nothing is
-printed. Long messages are split after the 40th character and before
-the 72nd character.
-
-#####GParameters
-> "color" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-
-----------------------------------------------------------------------
-
-#####R=== msg_print ===
-
-#####GDeclaration
- void msg_print(cptr msg);
-
-#####GFile
- util.c
-
-#####GComment
-/* Hack -- for compatibility and easy sake */
-
-#####GDescription
-Print message "msg" in white (see cmsg_print() above).
-
-#####GParameters
-> "msg" is the message.
-
-----------------------------------------------------------------------
-
-#####R=== screen_save ===
-
-#####GDeclaration
- void screen_save(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Save the screen, and increase the "icky" depth.
- *
- * This function must match exactly one call to "screen_load()".
- */
-
-#####GDescription
-Save a screen shot.
-
-----------------------------------------------------------------------
-
-#####R=== screen_load ===
-
-#####GDeclaration
- void screen_load(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Load the screen, and decrease the "icky" depth.
- *
- * This function must match exactly one call to "screen_save()".
- */
-
-#####GDescription
-Load a previously saved screen shot.
-
-----------------------------------------------------------------------
-
-#####R=== c_put_str ===
-
-#####GDeclaration
- void c_put_str(byte attr, cptr str, int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Display a string on the screen using an attribute.
-*
-* At the given location, using the given attribute, if allowed,
-* add the given string. Do not clear the line.
-*/
-
-#####GDescription
-Put string "str" at row "row" and column "col" with attribute "attr".
-
-#####GParameters
-> "attr" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-> "row" is the row the message is to be printed at.
-> "col" is the column the message is to be printed at.
-
-----------------------------------------------------------------------
-
-#####R=== c_prt ===
-
-#####GDeclaration
- void c_prt(byte attr, cptr str, int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Display a string on the screen using an attribute, and clear
-* to the end of the line.
-*/
-
-#####GDescription
-Clear row "row" from column "col". Put string "str" at "row", "col"
-with attribute "attr".
-
-#####GParameters
-> "attr" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-> "row" is the row the message is to be printed at.
-> "col" is the column the message is to be printed at.
-
-----------------------------------------------------------------------
-
-#####R=== clear_from ===
-
-#####GDeclaration
- void clear_from(int row);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Clear part of the screen
-*/
-
-#####GDescription
-Clear the screen from row "row" onwards.
-
-#####GParameters
-> "row" is the first row of the screen to be cleared.
-
-----------------------------------------------------------------------
-
-#####R=== askfor_aux ===
-
-#####GDeclaration
- bool askfor_aux(char *buf, int len);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get some input at the cursor location.
-* Assume the buffer is initialized to a default string.
-* Note that this string is often "empty" (see below).
-* The default buffer is displayed in yellow until cleared.
-* Pressing RETURN right away accepts the default entry.
-* Normal chars clear the default and append the char.
-* 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.
-*/
-
-#####GDescription
-Get string "buf" from the screen. "buf" is to be no more than "len"
-bytes. The string starts at the current cursor position. The length
-can not exceed the number of bytes from the cursor to the end of the
-line. Accept user input until the escape or return key is pressed.
-
-#####GParameters
-> "buf" is the string returned from the screen.
-> "len" is the length of the string. If it is <1 it is forced to 1.
-
-----------------------------------------------------------------------
-
-#####R=== get_string ===
-
-#####GDeclaration
- bool get_string(cptr prompt, char *buf, int len);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get a string from the user
-*
-* The "prompt" should take the form "Prompt: "
-*
-* Note that the initial contents of the string is used as
-* the default response, so be sure to "clear" it if needed.
-*
-* We clear the input, and return FALSE, on "ESCAPE".
-*/
-
-#####GDescription
-Print prompt "prompt" at the top-left corner of the screen and return
-response "buf" which will have a maximum length "length". If ESCAPE
-is entered, the function returns FALSE, otherwise it returns TRUE.
-
-#####GParameters
-> "prompt" is the prompt for input.
-> "buf" is the returned response.
-> "len" is the maximum length of the string.
-
-----------------------------------------------------------------------
-
-#####R=== get_check ===
-
-#####GDeclaration
- bool get_check(cptr prompt);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Verify something with the user
-*
-* The "prompt" should take the form "Query? "
-*
-* Note that "[y/n]" is appended to the prompt.
-*/
-
-#####GDescription
-Ask the user question "prompt" which requires a yes/no answer. The
-prompt appears in the top-left corner of the screen. A response of
-'Y' (either case) returns TRUE. A response of 'N' (either case) or
-ESCAPE returns FALSE.
-
-#####GParameters
-> "prompt" is the question asked. It has a maximum length of 70
- characters.
-
-----------------------------------------------------------------------
-
-#####R=== get_com_lua ===
-
-#####GDeclaration
- bool get_com_lua @ get_com(cptr promtp, int *com);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Prompts for a keypress
-*
-* The "prompt" should take the form "Command: "
-*
-* Returns TRUE unless the character is "Escape"
-*/
-
-#####GDescription
-Ask the user for command "prompt" and return the key press "com". A
-response of ESCAPE returns FALSE. All other responses return TRUE.
-
-#####GParameters
-> "prompt" is the prompt for the key press.
-> "com" is the returned key press.
-
-----------------------------------------------------------------------
-
-#####R=== get_quantity ===
-
-#####GDeclaration
- s32b get_quantity(cptr prompt, s32b max);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Request a "quantity" from the user
-*
-* Hack -- allow "command_arg" to specify a quantity
-*/
-
-#####GDescription
-Ask the user for quantity "prompt" of maximum value "max" and return
-a quantity. If the user quantity is higher than the maximum then the
-maximum is returned. If the response is a letter then the maximum is
-returned. If the user quantity is negative then zero is returned.
-
-#####GParameters
-> "prompt" is the prompt for a quantity.
-> "max" is the maximum value allowed.
-
-----------------------------------------------------------------------
-
-#####R=== test_monster_name ===
-
-#####GDeclaration
- int test_monster_name(cptr name);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Given monster name as string, return the index in r_info array. Name
- * must exactly match (look out for commas and the like!), or else 0 is
- * returned. Case doesn't matter. -GSN-
- */
-
-#####GDescription
-Return the monster index for monster with name "name". If no match is
-found then zero is returned.
-
-#####GParameters
-> "name" is the monster name.
-
-----------------------------------------------------------------------
-
-#####R=== test_item_name ===
-
-#####GDeclaration
- int test_item_name(cptr name);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Given item name as string, return the index in k_info array. Name
- * must exactly match (look out for commas and the like!), or else 0 is
- * returned. Case doesn't matter. -DG-
- */
-
-#####GDescription
-Return the item index for item with name "name". If no match is found
-then zero is returned.
-
-#####GParameters
-> "name" is the item name.
-
-----------------------------------------------------------------------
-
-#####R=== luck ===
-
-#####GDeclaration
- int luck(int min, int max);
-
-#####GFile
- xtra1.c
-
-#####GComment
-/*
- * Return a luck number between a certain range
- */
-
-#####GDescription
-Return a number for luck between minimum "min" and maximum "max". The
-value begins with the player's current luck. The value is forced to
-be between -30 and +30. 30 is added to give a value between 0 and 60.
-The value is multiplied by the range (maximum - minimum) and divided
-by 60. The value is increased by the minimum. The value is returned.
-
-For example, if the player's current luck is 15, the minimum is -10,
-and the maximum is 10 (range 20), then the value returned is
-(45 * 20) / 60 which is 900 / 60 which is 15 + the minimum -10 gives
-a returned value of 5.
-
-#####GParameters
-> "min" is the minimum luck.
-> "max" is the maximum luck. Beware: this should be greater than the
- minimum but it is not checked!
-
-----------------------------------------------------------------------
-
-#####R=== get_player_race_name ===
-
-#####GDeclaration
- cptr get_player_race_name(int pr, int ps);
-
-#####GFile
- util.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the name for player race "pr" and player sub-race "ps".
-
-#####GParameters
-> "pr" is the index for player race.
-> "ps" is the index for player sub-race.
-
-----------------------------------------------------------------------
-
-#####R=== quit ===
-
-#####GDeclaration
- void quit(cptr str);
-
-#####GFile
- z-util.c
-
-#####GComment
-/*
- * Exit (ala "exit()"). If 'str' is NULL, do "exit(0)".
- * If 'str' begins with "+" or "-", do "exit(atoi(str))".
- * Otherwise, plog() 'str' and exit with an error code of -1.
- * But always use 'quit_aux', if set, before anything else.
- */
-
-#####GDescription
-Quit the game. If "str" is a string then write the string to the
-error file or screen. If "str" is a number then exit with the
-number as the exit code.
-
-#####GParameters
-> "str" is an error message or exit code.
-
-----------------------------------------------------------------------
-
-#####R=== dump_hooks ===
-
-#####GDeclaration
- void dump_hooks();
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-Print the name and type (C or Lua) of hooks in the hook list.
-
-----------------------------------------------------------------------
-
-#####R=== add_hook_script ===
-
-#####GDeclaration
- void add_hook_script(int h_idx, char *script, cptr name);
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-To hook list with index "h_idx", add a script with script file
-"script" and name "name" as a Lua hook if a hook with that name
-does not already exist.
-
-#####GParameters
-> "h_idx" is the index of the hook list in the array of hook lists.
-> "script" is the name of the script file.
-> "name" is the name of the hook to be added.
-
-----------------------------------------------------------------------
-
-#####R=== del_hook_name ===
-
-#####GDeclaration
- void del_hook_name(int h_idx, cptr name);
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-Search hook list with index "h_idx" and remove the hook with name
-"name".
-
-#####GParameters
-> "h_idx" is the index of the hook list in the array of hook lists.
-> "name" is the name of the hook to be removed.
-
-----------------------------------------------------------------------
-
-#####R=== pern_dofile ===
-
-#####GDeclaration
- bool pern_dofile(char *file);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Parse the Lua script file "file".
-
-#####GParameters
-> "file" is the Lua script file to be parsed.
-
-----------------------------------------------------------------------
-
-#####R=== intMod ===
-
-#####GDeclaration
- s32b intMod(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of operation "a" mod "b" (a % b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intAnd ===
-
-#####GDeclaration
- s32b intAnd(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" AND "b" (a & b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intOr ===
-
-#####GDeclaration
- s32b intOr(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" OR "b" (a | b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intXor ===
-
-#####GDeclaration
- s32b intXor(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" XOR "b" (a ^ b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intShiftl ===
-
-#####GDeclaration
- s32b intShiftl(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" << "b".
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intShiftr ===
-
-#####GDeclaration
- s32b intShiftr(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" >> "b".
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intBitNot ===
-
-#####GDeclaration
- s32b intBitNot(s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation NOT "b" (~ b).
-
-#####GParameters
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== register_savefile ===
-
-#####GDeclaration
- void register_savefile(int num);
-
-#####GFile
- loadsave.c
-
-#####GComment
-/*
- * Add num slots to the savefile
- */
-
-#####GDescription
-Add "num" slots to the save file.
-
-#####GParameters
-> "num" is the number of slots to add to the savefile. If num is <0
- then "num" is forced to zero.
-
-----------------------------------------------------------------------
-
-#####R=== save_number_key ===
-
-#####GDeclaration
- void save_number_key(char *key, s32b val);
-
-#####GFile
- util.c
-
-#####GComment
-(none)
-
-#####GDescription
-Save the length of key "key", the key itself, and the value "val" as
-bytes in the savefile.
-
-#####GParameters
-> "key" is the key string for the value.
-> "val" is the value to be saved.
-
-----------------------------------------------------------------------
-
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
-
diff --git a/lib/help/macrofaq.txt b/lib/help/macrofaq.txt
index 03a00eaa..8194d7fe 100644
--- a/lib/help/macrofaq.txt
+++ b/lib/help/macrofaq.txt
@@ -975,10 +975,6 @@ These are accessible through the (=) Set options command.
*****option.txt*2[(hilite_player)] -- causes the player's symbol to be drawn with the
"cursor" on it. It will be drawn with the same color as the character.
-*****option.txt*3[(player_symbols)] -- for graphics mode only, and only works when option
-(use_graphics) is also on. This apparently varies the player graphic
-and its color based on class, race, and sex.
-
#####G----------------------------------------------------------------------
#####G4.18 Recharging a rod using a Recharge Item spell
#####G----------------------------------------------------------------------
@@ -1070,15 +1066,7 @@ create a macro for a function key.
#####G5.2 How can I automatically inscribe items when I pick them up?
#####G----------------------------------------------------------------------
-You need to turn on the "Merge inscriptions when stacking" option.
-If you are already carrying the same item with an inscription, a new
-one will be added to the stack. Note that this WON'T merge discounts.
-Although discounts display like inscriptions, they are different.
-
-1) = Options
-2) 1 User interface options
-3) "Merge inscriptions when stacking" (stack_force_notes)
- move down to this line and change to "yes".
+(Content removed because it was obsolete. Inscribe-on-pickup is now the default.)
#####G----------------------------------------------------------------------
#####G5.3 Can I use macros inside other macros?
@@ -1784,9 +1772,7 @@ options screen.
rogue_like_commands
use_old_target
always_pickup
-depth_in_feet
alert_hitpoint
-auto_haggle
auto_scum
#####G----------------------------------------------------------------------
diff --git a/lib/help/option.txt b/lib/help/option.txt
index c48d76a8..7563f83b 100644
--- a/lib/help/option.txt
+++ b/lib/help/option.txt
@@ -66,6 +66,10 @@ can also be viewed from the option menu while playing, but not changed then.
#####GYou can receive fates, good or bad [fate_option]
Allows the player to turn off ToME's *****fatespoi.txt*0[fates] for that character.
+#####GItems always sell for 0 gold [no_selling]
+ Disables selling items back to shops for money. The value of gold found in the
+ dungeon is increased to compensate.
+
~~~~~07|Options|Ingame
#####RIN GAME OPTIONS
#####R===============
@@ -109,20 +113,6 @@ off at will during the course of the game.
a door, tunnel through walls, or disarm traps or chests, that you
wish to repeat the command 99 times (see *****command.txt*0["command.txt"]).
-#####GShow dungeon level in feet [depth_in_feet]
- Display the dungeon depth in "feet" instead of as a level number (one
- level is equivalent to 50'). This also affects the monster memory display.
-
-#####GMerge inscriptions when stacking [stack_force_notes]
- Force otherwise identical objects to merge, even if one has an empty
- inscription and the other does not. The resulting stack keeps the
- non-empty inscription.
-
-#####GMerge discounts when stacking [stack_force_costs]
- Force otherwise identical objects to merge, even if they have different
- discounts. The resulting stack keeps the largest discount. This option
- may cause you to lose "value", but will give you optimal pack usage.
-
#####GAudible bell (on errors, etc) [ring_bell]
Attempt to make a "bell" noise when various errors occur.
@@ -154,7 +144,7 @@ off at will during the course of the game.
monster becomes viewable for the first time, and also whenever any
viewable monster becomes no longer viewable. This option ignores
the existence of telepathy for the purpose of determining whether
- a monster is viewable. See also the "view_reduce_view" option.
+ a monster is viewable.
#####GDisturb whenever map panel changes [disturb_panel]
This option causes you to be disturbed (stop running) when the screen
@@ -194,18 +184,6 @@ off at will during the course of the game.
dies. If this option is not selected, the "You die." message is displayed
instead.
-#####GAllow shopkeepers and uniques to speak [speak_unique]
- If this option is in use, shopkeepers may sometimes whisper rumours to
- you. Also certain monsters start boasting as they attack you, and when
- they die, they say their "last words".
-
-#####GNo query to destroy known worthless items [auto_destroy]
- It can sometimes be annoying that the Destroy command asks for confirmation
- when you are attempting to destroy a Broken sword {cursed}. If this option
- is set, no confirmation will be asked if you attempt to destroy an object
- which you know to be worthless. Of course, cursed artifacts cannot be
- destroyed even if this option is set.
-
#####GConfirm to wear/wield known cursed items [confirm_wear]
Some players may occasionally, due to a typing mistake, find themselves
wearing an item which they knew was cursed. If this option is set, you
@@ -257,18 +235,6 @@ off at will during the course of the game.
is based on the dungeon level, so the deeper you go, the better the
level will be.
-#####GAllow weapons and armor to stack [stack_allow_items]
- Allow identical weapons and armor to be combined into a stack. This
- also allows unidentified, but identical, ammo to be combined, which
- may result in the auto-identification of some of the ammo, but which
- makes it a lot easier to actually use unidentified ammo.
-
-#####GAllow wands/staffs/rods to stack [stack_allow_wands]
- Allow identical wands/staffs/rods to be combined into a stack. This
- may force the items to be unstacked to use them, which may result
- in overflow of the pack. Also, the entire stack can be recharged
- (and possibly destroyed) at the same time.
-
#####GExpand the power of the look command [expand_look]
Expand the "l"ook command to allow the user to look at grids which
are not actually in view of the player, allowing the examination of
@@ -323,27 +289,10 @@ off at will during the course of the game.
Allow monsters to make paths to the player when they are nearby. This
option is extremely slow, but can produce viciously smart monsters.
~~~~~3
-#####GUse special symbols for the player char [player_symbols]
- If this option has been compiled in, it allows you to display your
- character using race / class / sex dependent colours and graphical
- symbols. Note that the support for this option may not have been
- compiled in on all platforms.
-
-#####GPlain object descriptions [plain_descriptions]
- In ToME, this option disables "full" names for identified flavoured
- objects; in other words, if this option is not in use, an identified
- Potion of Speed could be listed (for example) as a Blue Potion of Speed.
- If you prefer simpler, less verbose descriptions, set this option.
-
#####GMonsters learn from their mistakes [smart_learn]
Allow monsters to learn what spell attacks you are resistant to,
and to use this information to choose the best attacks.
-#####GMonsters exploit players weaknesses [smart_cheat]
- Allow monsters to know what spell attacks you are resistant to, without
- first having to observe such an attack upon you, and to use this
- information to choose the best attacks.
-
#####GAllow unusually small dungeon levels [small_levels]
This option enables the creation of levels of varying sizes. Levels
that are as small as one "screen" (80x24) are possible, and they can be
@@ -370,9 +319,6 @@ off at will during the course of the game.
but is extremely annoying. Certain older versions of Angband used
this behavior always, so "purists" should turn it on.
-#####GReduce view-radius in town [view_reduce_view]
- No longer in use.
-
#####GAvoid checking for user abort [avoid_abort]
Avoid checking to see if the user has pressed a key during resting
or running or repeated commands. This not only makes the game much
@@ -490,11 +436,6 @@ Features which are unique to ToME are collected in this menu.
for new players. More experienced players may wish to switch this option
off.
-#####GShow the experience needed for the next level [exp_need]
- Setting this option alters the display of experience on the left of
- the main screen to the experience needed to reach the next character level,
- instead of the character's current total experience.
-
#####GUse the old(Z) coloring scheme(reload the game) [old_colors]
Setting this option toggles the ASCII game colour display from the
standard Angband monster colours to the Zangband-based monster colours.
diff --git a/lib/mods/theme/edit/a_info.txt b/lib/mods/theme/edit/a_info.txt
index e2a312c5..fa1cb4bb 100644
--- a/lib/mods/theme/edit/a_info.txt
+++ b/lib/mods/theme/edit/a_info.txt
@@ -40,7 +40,7 @@ W:20:10:10:10000
P:0:1d1:0:0:0
F:ACTIVATE | SEARCH | LITE3 | LUCK
F:INSTA_ART | HIDE_TYPE
-a:HARDCORE=LIGHT
+a:LIGHT
D:A small crystal phial, with the light of Earendil's Star contained inside.
D:Its light is imperishable, and near it darkness cannot endure.
@@ -53,7 +53,7 @@ W:30:25:5:32500
P:0:1d1:0:0:0
F:ACTIVATE | SEE_INVIS | HOLD_LIFE |
F:INSTA_ART | SPEED | LITE3 | LITE1 | HIDE_TYPE
-a:HARDCORE=MAP_LIGHT
+a:MAP_LIGHT
Z:detect curses
D:The shining Star of the West, a famed heirloom of Elendil's house.
D:A white diamond set as a star in a silver fillet to be bound at the
@@ -68,7 +68,7 @@ W:50:50:5:50000
P:0:1d1:0:0:0
F:ACTIVATE | SEE_INVIS | HOLD_LIFE | RES_CHAOS | HIDE_TYPE | LUCK
F:INSTA_ART | SPEED | RES_LITE | RES_DARK | ESP_ORC | LITE3 | SPECIAL_GENE
-a:HARDCORE=THRAIN
+a:THRAIN
D:A great globe seemingly filled with moonlight, the famed Heart of the
D:Mountain, which splinters the light that falls upon it into a thousand
D:glowing shards.
@@ -94,7 +94,7 @@ F:INT | WIS | CHR | SEARCH | INFRA | HIDE_TYPE |
F:SEE_INVIS | FREE_ACT | ACTIVATE |
F:RES_ACID | RES_COLD | RES_ELEC |
F:INSTA_ART
-a:HARDCORE=DISP_EVIL
+a:DISP_EVIL
D:The ancient heirloom of Ingwe, high lord of the Vanyar, against whom nothing
D:of evil could stand.
@@ -108,7 +108,7 @@ W:70:50:3:75000
F:STR | CON | DEX | INFRA | HIDE_TYPE | RES_FEAR |
F:SEE_INVIS | FREE_ACT | REGEN | LITE3 | SPEED |
F:INSTA_ART | SPECIAL_GENE
-a:HARDCORE=DIM_DOOR
+a:DIM_DOOR
D:A carencet of gold, set with a multitude of shining gems of
D:Valinor. Despite its size, its weight seems as that of gossamer.
@@ -133,7 +133,7 @@ W:50:25:2:75000
F:STR | INT | WIS | DEX | CON | CHR | STEALTH | HIDE_TYPE |
F:RES_POIS | RES_DARK | ACTIVATE | SEE_INVIS | SEARCH |
F:INSTA_ART
-a:HARDCORE=BARAHIR
+a:BARAHIR
D:A ring shaped into twinned serpents with eyes of emerald meeting beneath
D:a crown of flowers, an ancient treasure of Isildur's house.
@@ -146,7 +146,7 @@ I:24:30:5
W:90:60:300:500000
P:0:5d7:18:25:0
F:CRIT | HIDE_TYPE | KILL_DEMON | SHOW_MODS | VORPAL | WOUNDING | ACTIVATE
-a:HARDCORE=TULKAS
+a:TULKAS
D:The great axe of Tuor, Thudder-Sharp is its name. The axe that smote
D:both a heavy dint as of a club and cleft as a sword. When it was swung
D:by the hands of Tuor, it sang like the rush of eagle's wings in the
@@ -164,7 +164,7 @@ F:ACTIVATE | FREE_ACT | SEE_INVIS |
F:SUST_STR | SUST_CON | SUST_WIS | SUST_CHR | SPECIAL_GENE |
F:IM_FIRE | RES_NETHER | RES_FEAR | REGEN |
F:INSTA_ART
-a:HARDCORE=NARYA
+a:NARYA
D:The Ring of Fire, set with a ruby that glows like flame. Narya is one
D:of the three Rings of Power created by the Elves and hidden by them from
D:Sauron.
@@ -181,7 +181,7 @@ F:ACTIVATE | HOLD_LIFE | FREE_ACT | SEE_INVIS |
F:SUST_INT | SUST_WIS | SUST_CHR |
F:IM_COLD | RES_BLIND | STEALTH | ESP_ALL |
F:INSTA_ART
-a:HARDCORE=NENYA
+a:NENYA
D:The Ring of Adamant, with a pure white stone as centrepiece. Nenya is one
D:of the three Rings of Power created by the Elves and hidden by them from
D:Sauron.
@@ -199,7 +199,7 @@ F:FEATHER | SLOW_DIGEST | REGEN |
F:SUST_STR | SUST_DEX | SUST_CON |
F:IM_ELEC | RES_POIS | RES_DISEN |
F:INSTA_ART
-a:HARDCORE=VILYA
+a:VILYA
D:The Ring of Sapphire, with clear blue gems that shine like stars,
D:glittering untouchable despite all that Sauron ever wrought. Vilya is
D:one of the three Rings of Power created by the Elves and hidden by them
@@ -221,7 +221,7 @@ F:SUST_INT | SUST_WIS | SUST_CHR |
F:RES_BLIND | RES_POIS | RES_DISEN | RES_NETHER | ESP_ALL |
F:DRAIN_MANA | DRAIN_HP | DRAIN_EXP |
F:INSTA_ART
-a:HARDCORE=POWER
+a:POWER
Z:change the world
D:"Ash nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh
D:burzum-ishi krimpatul". Unadorned, made of massive gold,
@@ -251,7 +251,7 @@ W:15:12:15:20000
P:0:1d1:0:0:0
F:ACTIVATE | SPECIAL_GENE | EASY_USE | LITE1 |
F:INSTA_ART
-a:HARDCORE=STONE_LORE
+a:STONE_LORE
D:The key to the tower of Saruman, which fills your mind
D:with images of knowledge and dreadful understanding. It
D:is not a regular key - it is a perfectly round stone
@@ -268,7 +268,7 @@ F:FREE_ACT | IM_ELEC | SPECIAL_GENE |
F:RES_FIRE | RES_COLD | RES_POIS | RES_LITE | RES_DARK |
F:LITE1 | SEE_INVIS | AGGRAVATE | ESP_DRAGON
F:ACTIVATE
-a:HARDCORE=RAZORBACK
+a:RAZORBACK
D:A massive suit of heavy dragon scales deeply saturated with many colours.
D:It throbs with angry energies. May-cloud it is called, after the
D:element lightning which courses through it with unusual vigour.
@@ -285,7 +285,7 @@ F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK | ULTIMATE |
F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_BLIND | RES_CONF |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | SPECIAL_GENE
F:ACTIVATE
-a:HARDCORE=BLADETURNER
+a:BLADETURNER
D:A suit of tilkal, set with scales of every colour, surrounded in a nimbus
D:of perfectly untramelled yet inextricably intermingled and utterly mastered
D:powers elemental and ethereal.
@@ -312,7 +312,7 @@ F:CON |
F:HOLD_LIFE | SUST_CON | ESP_UNDEAD | RES_CONF | RES_FEAR |
F:RES_ACID | RES_COLD | RES_DARK | RES_NETHER | RES_NEXUS | RES_CHAOS |
F:ACTIVATE
-a:HARDCORE=CURE_1000
+a:CURE_1000
D:A suit of imperishable galvorn, with unconquerable strength to endure evil
D:and disruptive magics. It protects the life force of its wearer like
D:nothing else can. Eol the Dark Elf made it in secret for his son, but
@@ -355,7 +355,7 @@ F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS |
F:HOLD_LIFE | RES_DARK | RES_FEAR |
F:SEE_INVIS |
F:ACTIVATE
-a:HARDCORE=BELEGENNON
+a:BELEGENNON
D:This wondrous suit of fine-linked chain shimmers as though of pure silver.
D:It stands untouched amidst the fury of the elements, and a power of
D:concealment rests within.
@@ -370,7 +370,7 @@ P:35:2d4:-3:0:25
F:STR | CHR | HIDE_TYPE | ESP_ORC
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_DARK |
F:RES_DISEN | ACTIVATE
-a:HARDCORE=GENOCIDE
+a:GENOCIDE
D:A shimmering suit of true-silver, forged long ago by dwarven smiths of
D:legend. It gleams with purest white as you gaze upon it, and mighty are
D:its powers to protect and banish.
@@ -397,7 +397,7 @@ W:25:9:270:40000
P:16:1d4:-2:0:20
F:INT | WIS | CON | HIDE_TYPE |
F:RES_ACID | RES_POIS | RES_CONF | ACTIVATE
-a:HARDCORE=DEST_DOOR
+a:DEST_DOOR
D:A hauberk, leggings, and sleeves of interlocking steel rings, strategically
D:reinforced at vital locations with a second layer of chain. Magics to
D:enhance body and mind lie within, and no door can hope to resist the wearer.
@@ -412,7 +412,7 @@ I:32:8:10
W:50:80:50:20000
P:6:1d3:0:0:10
F:ACTIVATE | HIDE_TYPE | INFRA | LITE2 | LITE3 | SEARCH
-a:HARDCORE=SUNLIGHT
+a:SUNLIGHT
D:The shining helm that Gil-galad, legendary Elven-king, wore in battle.
# The Leather Jerkin of Tom Bombadil
@@ -504,7 +504,7 @@ F:STR | CON | HIDE_TYPE | BRAND_ACID | RES_ACID | LITE1 | DRAIN_MANA |
F:SLAY_ORC | KILL_DEMON | SLAY_TROLL | ACTIVATE | SHOW_MODS
F:MUST2H
f:MUST2H
-a:HARDCORE=HURIN
+a:HURIN
D:Wielded by Hurin Thalion in the Fifth Battle of Beleriand, this
D:troll-bane smoked in the black blood of Gothmog's guards.
@@ -588,7 +588,7 @@ P:8:1d3:0:0:20
F:STR | DEX | CON | HIDE_TYPE |
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_LITE | RES_BLIND |
F:LITE1 | SEE_INVIS | ESP_DRAGON | ESP_THUNDERLORD | ACTIVATE
-a:HARDCORE=GORLIM
+a:GORLIM
D:The legendary dragon helm of Turin Turambar, an object of dread to the
D:servants of Morgoth.
@@ -600,7 +600,7 @@ W:20:5:75:100000
P:5:1d3:0:0:10
F:INT | WIS | SEARCH | HIDE_TYPE |
F:RES_BLIND | SEE_INVIS | ACTIVATE
-a:HARDCORE=DETECT_ALL
+a:DETECT_ALL
D:A famous helm of forged iron granting extraordinary powers of mind and
D:awareness.
@@ -616,7 +616,7 @@ F:SEE_INVIS | NO_MAGIC | HEAVY_CURSE | TY_CURSE
F:RES_DISEN | RES_FEAR | FREE_ACT | RES_ACID | RES_FIRE | RES_POIS |
F:IM_COLD | ACTIVATE | DRAIN_HP |
F:TELEPORT | CURSED
-a:HARDCORE=GORLIM
+a:GORLIM
D:A headpiece, gaudy and barbaric, that betrayed a warrior when he most
D:needed succor.
@@ -630,7 +630,7 @@ P:0:1d1:0:0:15
F:STR | WIS | CON | HIDE_TYPE | SPEED | RES_CONF | RES_SOUND |
F:RES_COLD | RES_FIRE | RES_LITE | RES_BLIND | RES_ELEC | RES_CHAOS |
F:LITE1 | SEE_INVIS | REGEN | ACTIVATE
-a:HARDCORE=CURE_700
+a:CURE_700
D:The shining winged circlet brought by Elendil from dying Numenor, emblem of
D:Gondor through an age of the world.
@@ -646,7 +646,7 @@ F:INT | DEX | CHR | SEARCH | SPEED | HIDE_TYPE |
F:SEE_INVIS | FREE_ACT | RES_DARK | RES_BLIND |
F:RES_SHARDS | RES_SOUND | RES_LITE | RES_COLD |
F:LITE1 | ACTIVATE | DRAIN_MANA
-a:HARDCORE=NUMENOR
+a:NUMENOR
D:A crown of massive gold, set with wondrous jewels of thought and warding,
D:worn by the kings of ancient Numenor. Its wearer may go into battle
D:always knowing what he faces - unless his own folly blinds him to the
@@ -661,7 +661,7 @@ I:35:1:0
W:60:90:10:40000
P:1:0d0:0:0:20
F:ACTIVATE | IM_ACID | IM_COLD | IM_ELEC | IM_FIRE | RES_POIS
-a:HARDCORE=COLLUIN
+a:COLLUIN
D:A cape worn by a hero from Valinor, a land utterly beyond the strife
D:of the elements.
@@ -673,7 +673,7 @@ W:5:25:10:13000
P:1:0d0:0:0:4
F:INT | WIS | SPEED | STEALTH | HIDE_TYPE |
F:RES_ACID | ACTIVATE
-a:HARDCORE=SLEEP
+a:SLEEP
D:This elven-grey mantle possesses great powers of tranquility and of
D:concealment, and grants the wearer the knowledge and understanding of
D:the Sindar.
@@ -687,7 +687,7 @@ W:10:50:10:35000
P:1:0d0:0:0:18
F:DEX | CHR | HIDE_TYPE |
F:FREE_ACT | RES_ACID | RES_FIRE | RES_COLD | ACTIVATE
-a:HARDCORE=RECHARGE
+a:RECHARGE
D:A sable-hued cloak, with glowing elven-runes to restore magic showing calm
D:and clear as moonlight on still water.
@@ -712,7 +712,7 @@ W:5:20:10:11000
P:1:0d0:0:0:15
F:STEALTH | SPEED | RES_NEXUS |
F:RES_ACID | ACTIVATE
-a:HARDCORE=TELEPORT
+a:TELEPORT
D:A crystal-blue cape of fine silk worn by a silent messenger of
D:the forces of Law. Somehow, its wearer is always able to escape
D:trouble.
@@ -726,7 +726,7 @@ W:40:40:5:55000
P:6:0d0:0:0:20
F:INT | WIS | CHR | HIDE_TYPE | SPEED | STEALTH | INVIS | LUCK
F:RES_ACID | RES_FIRE | RES_COLD | SPECIAL_GENE | ACTIVATE | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=REST_LIFE
+a:REST_LIFE
D:The opaque midnight folds, inset with a multitude of tiny diamonds, of
D:this cloak swirl around you and you feel a hint, a fragment of the
D:knowledge and power to restore that lay in Luthien, the most beautiful
@@ -775,7 +775,7 @@ W:10:3:5:30000
P:1:0d0:0:0:10
F:FREE_ACT | RES_LITE | SUST_CON | LITE1 | ACTIVATE
F:SPECIAL_GENE
-a:HARDCORE=BO_MISS_1
+a:BO_MISS_1
D:These gloves glow so brightly as to light the way for their owner and cast
D:magical bolts with great frequency.
@@ -787,7 +787,7 @@ W:10:5:25:33000
P:2:1d1:0:0:15
F:RES_FIRE | ACTIVATE |
F:SUST_STR | STR | REGEN | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_FIRE_1
+a:BO_FIRE_1
D:A fiery set of gauntlets that can even shoot fire from the user's
D:hands. Wrought by Curufin's people, they guard the wearer's
D:strength and enhance it.
@@ -800,7 +800,7 @@ W:10:5:25:33000
P:2:1d1:0:0:15
F:RES_COLD | ACTIVATE |
F:SUST_CON | CON | REGEN | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_COLD_1
+a:BO_COLD_1
D:A set of handgear so icy as to be able to fire frost bolts. Wrought by
D:Finrod Felagund himself, it is inscribed with runes that guard and
D:boost health.
@@ -813,7 +813,7 @@ W:10:5:25:33000
P:2:1d1:0:0:15
F:RES_ELEC | ACTIVATE | FREE_ACT |
F:SUST_DEX | DEX | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_ELEC_1
+a:BO_ELEC_1
D:A set of handgear wrought by the Galadhrim. Sparks surround it, enabling
D:the wearer to fire bolts of electricity. Ever has lightning improved and
D:protected agility, and these gauntlets are no exception.
@@ -826,7 +826,7 @@ W:10:5:25:33000
P:2:1d1:0:0:15
F:RES_ACID | ACTIVATE |
F:SUST_CHR | CHR | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BO_ACID_1
+a:BO_ACID_1
D:Mighty was the woodcraft of the Laiquendi, for they learned to control the
D:element of acid to a level theretofore unknown. This set of handgear is so
D:corrosive that it may fire bolts of acid.
@@ -852,7 +852,7 @@ W:40:15:40:110000
P:5:1d1:10:10:20
F:DEX | HIDE_TYPE | LUCK
F:FREE_ACT | RES_ACID | ACTIVATE | SHOW_MODS
-a:HARDCORE=BO_MISS_2
+a:BO_MISS_2
Z:magic missile
D:The hand-sheathing of Fingolfin, warrior-king of Elves and Men, who gave
D:Morgoth seven mighty wounds and pain that will last forever.
@@ -866,7 +866,7 @@ W:40:120:40:300000
P:3:1d1:0:0:20
F:SPEED | HIDE_TYPE |
F:RES_NEXUS | ACTIVATE
-a:HARDCORE=SPEED
+a:SPEED
D:This wondrous pair of leather boots once sped Feanor, creator of the
D:Silmarils and the mightiest of the Eldar, along the Grinding Ice and to
D:Middle-earth at last.
@@ -881,7 +881,7 @@ P:2:1d1:0:0:15
F:DEX | HIDE_TYPE | CHR | SUST_CHR |
F:ACTIVATE | FREE_ACT |
F:RES_NETHER | RES_CHAOS | RES_CONF | SUST_CON
-a:HARDCORE=CURE_POISON
+a:CURE_POISON
D:A pair of high-laced shoes, strong against the powers of corruption and
D:withering, that grant the wearer extraordinary agility.
@@ -949,7 +949,7 @@ I:23:4:0
W:4:100:12:12000
P:0:1d4:4:6:0
F:ACTIVATE | BRAND_FIRE | LEVELS | LITE1 | RES_FIRE | SHOW_MODS
-a:HARDCORE=BO_FIRE_1
+a:BO_FIRE_1
D:The blade of Samwise Gamgee, chosen by him from the hoard of the
D:Barrow-wights. A fiery dagger finely balanced for deadly throws.
@@ -960,7 +960,7 @@ I:23:4:0
W:3:100:12:11000
P:0:1d4:4:6:0
F:ACTIVATE | BRAND_COLD | LEVELS | RES_COLD | SHOW_MODS
-a:HARDCORE=BO_COLD_1
+a:BO_COLD_1
D:The blade of Peregrin Took, chosen by him from the hoard of the
D:Barrow-wights. A frosty dagger finely balanced for deadly throws.
@@ -971,7 +971,7 @@ I:23:4:0
W:5:100:12:13000
P:0:1d4:4:6:0
F:BRAND_ELEC | RES_ELEC | ACTIVATE | SHOW_MODS | LEVELS
-a:HARDCORE=BO_ELEC_1
+a:BO_ELEC_1
D:The blade of Meriadoc Brandybuck, chosen by him from the hoard of
D:the Barrow-wights. A dagger covered in sparks and finely balanced
D:for deadly throws.
@@ -983,7 +983,7 @@ I:23:4:0
W:5:40:12:35000
P:0:2d4:4:3:0
F:SLAY_ORC | RES_POIS | RES_DISEN | ACTIVATE | SHOW_MODS | BRAND_POIS
-a:HARDCORE=BA_POIS_1
+a:BA_POIS_1
D:A large stiletto dagger that glistens with odourless poison, to which the
D:wearer seems oddly immune.
@@ -998,7 +998,7 @@ F:DEX | HIDE_TYPE | SPEED | BLOWS |
F:BRAND_COLD | RES_COLD |
F:SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS | BRAND_POIS
-a:HARDCORE=BELANGIL
+a:BELANGIL
D:A frosty dagger surrounded in a nimbus of ice with a hilt of elk horn and
D:an edge to wound the wind.
@@ -1160,7 +1160,7 @@ I:23:17:2
W:60:40:130:300000
P:0:3d5:8:9:0
F:ACTIVATE | ESP_EVIL | FREE_ACT | HIDE_TYPE | INT | RES_CONF | RES_DARK | SHOW_MODS | VORPAL
-a:HARDCORE=CURE_INSANITY
+a:CURE_INSANITY
D:The ancient blade of Theoden, King of the Mark. It was taken from
D:the king by Grima the Wormtongue, and hidden from him in a dusty
D:chest. It was once instrumental in restoring the King's wits from
@@ -1176,7 +1176,7 @@ F:SPEED | HIDE_TYPE | RES_FEAR | BLESSED |
F:SLAY_EVIL | BRAND_COLD | SLAY_UNDEAD | KILL_DEMON | SLAY_TROLL |
F:FREE_ACT | RES_COLD | RES_LITE | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS
-a:HARDCORE=BA_COLD_2
+a:BA_COLD_2
D:The weapon of Fingolfin, High King of the Noldor; it shines like a column
D:of ice lit by light unquenchable. Morgoth came but unwillingly to meet it
D:of old; his lame foot will remind him of its might should he meet it again.
@@ -1192,7 +1192,7 @@ F:STR | DEX | HIDE_TYPE | RES_FEAR | FREE_ACT | BLESSED | LUCK
F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | FREE_ACT |
F:RES_FIRE | SUST_DEX | SEE_INVIS | ACTIVATE | SHOW_MODS | LITE1 |
F:RES_DISEN | SPECIAL_GENE
-a:HARDCORE=BA_FIRE_1
+a:BA_FIRE_1
D:The famed "Flame of the West", the sword that was broken and is forged
D:again. It glows with the essence of fire, its wearer is mighty in combat,
D:and no creature of Sauron can withstand it. It will never be stained or
@@ -1321,7 +1321,7 @@ W:20:15:180:40000
P:0:2d6:8:10:0
F:WIS | CON | HIDE_TYPE |
F:SLAY_DRAGON | ESP_EVIL | ESP_UNDEAD | SLOW_DIGEST | ACTIVATE | SHOW_MODS
-a:HARDCORE=DRAIN_2
+a:DRAIN_2
D:The narrow axe head of this weapon, finely balanced by a crow's beak,
D:would pierce even the armour of Smaug, and its wielder becomes aware of
D:the minds of their enemies.
@@ -1381,7 +1381,7 @@ F:BRAND_COLD | BRAND_ELEC | LITE1 |
F:SLAY_TROLL | SLAY_ORC | SLAY_GIANT | KILL_UNDEAD |
F:FREE_ACT | RES_COLD | RES_ELEC | RES_LITE |
F:SLOW_DIGEST | ACTIVATE | BLESSED | SHOW_MODS
-a:HARDCORE=BA_ELEC_2
+a:BA_ELEC_2
D:The mighty spear of Gil-galad, famed as "Snow-point" in the songs of
D:Elves, against which all the foul corruptions of Sauron dashed in vain.
D:The spear is inscribed with Tengwar runes, reading "Gil-galad ech vae
@@ -1401,7 +1401,7 @@ F:BRAND_FIRE |
F:SLAY_GIANT | SLAY_EVIL | SLAY_DEMON | SLAY_UNDEAD | SLAY_DRAGON |
F:RES_FIRE | RES_LITE | HOLD_LIFE | RES_FEAR | FEATHER | ESP_GIANT |
F:SEE_INVIS | ACTIVATE | BLESSED | SHOW_MODS
-a:HARDCORE=STONE_MUD
+a:STONE_MUD
D:A magical spear, rumoured to have been forged by Orome himself
D:in the coldest reach of the cruel Redhorn.
@@ -1460,7 +1460,7 @@ F:STR | INT | WIS | DEX | CON | CHR | HIDE_TYPE |
F:SLAY_EVIL | BRAND_COLD | KILL_DEMON | SLAY_UNDEAD | ESP_NONLIVING
F:SLAY_ORC | FREE_ACT | IM_COLD | SEE_INVIS | ACTIVATE |
F:BLESSED | SHOW_MODS
-a:HARDCORE=MASS_GENO
+a:MASS_GENO
D:The axe of Eonwe, leader of the Hosts of the West before the gates of
D:Thangorodrim, strikes with icy wrath at the undead, disperses hosts of
D:evil at a word, and grants Maia-like powers of body and mind.
@@ -1490,7 +1490,7 @@ W:30:15:170:21000
P:0:2d8:4:3:0
F:STR | DEX | HIDE_TYPE |
F:SLAY_TROLL | SLAY_ORC | ACTIVATE | SHOW_MODS
-a:HARDCORE=CURE_MW
+a:CURE_MW
D:A superbly crafted double-bladed axe that slays the creatures of earth and
D:allows rapid recovery from their blows.
@@ -1547,7 +1547,7 @@ F:DEX | HIDE_TYPE |
F:SLAY_DRAGON | SLAY_ANIMAL | FREE_ACT | HOLD_LIFE | IM_ACID |
F:RES_NETHER | SEE_INVIS | SLOW_DIGEST | REGEN | ACTIVATE |
F:BLESSED | SHOW_MODS | WATER_BREATH
-a:HARDCORE=TELE_AWAY
+a:TELE_AWAY
D:The awesome weapon imbued with some of the power of the Vala Ulmo,
D:Lord of Waters. It allows the wearer to laugh in scorn at the dread
D:powers of the undead, and be utterly in command of the element of water.
@@ -1563,7 +1563,7 @@ F:BRAND_COLD | BRAND_FIRE | FREE_ACT | RES_FIRE | RES_COLD |
F:RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS |
F:COULD2H
f:COULD2H
-a:HARDCORE=RECALL
+a:RECALL
D:With elemental powers whose struggles turn this weapon red and purest
D:white, this shining reaper bears within it a power of going forth and
D:returning.
@@ -1597,7 +1597,7 @@ F:RES_COLD | SEE_INVIS | ESP_ALL | AGGRAVATE | SHOW_MODS | INSTA_ART |
F:LEVELS | ACTIVATE | SPECIAL_GENE |
F:MUST2H
f:MUST2H
-a:HARDCORE=GROND
+a:GROND
D:The mighty Hammer of the Underworld, blackened by doomspells of shattering,
D:whose wielder holds the lives of all Morgoth's servants in his hand.
@@ -1612,7 +1612,7 @@ F:SLAY_EVIL | BRAND_FIRE | RES_FIRE | RES_CONF | ACTIVATE |
F:SHOW_MODS | LITE1 |
F:COULD2H
f:COULD2H
-a:HARDCORE=CONFUSE
+a:CONFUSE
D:A flail whose head befuddles those who stare as you whirl it around, and
D:becomes a fiery comet as you bring it down.
@@ -1651,7 +1651,7 @@ I:21:12:0
W:20:100:150:35000
P:0:2d6:5:7:2
F:BRAND_FIRE | IM_FIRE | ACTIVATE | SHOW_MODS | LITE1
-a:HARDCORE=FIRESTAR
+a:FIRESTAR
D:A famed battle-lord of old, with a ruddy head, coloured as embers are that
D:can yet rise up in wrath.
@@ -1665,7 +1665,7 @@ P:0:3d4:12:12:0
F:KILL_DRAGON | BRAND_ELEC | IM_ELEC | ACTIVATE | SHOW_MODS |
F:COULD2H
f:COULD2H
-a:HARDCORE=SPEED
+a:SPEED
D:A great ridged mace that calls around you a nimbus of living lightning;
D:you remain utterly untouched even as fat sparks arc around your
D:fingers and eyebrows.
@@ -1709,7 +1709,7 @@ W:20:18:150:20000
P:0:1d9:3:5:0
F:INT | WIS | HIDE_TYPE | ESP_EVIL | SPELL_CONTAIN | WIELD_CAST
F:SLAY_EVIL | RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS
-a:HARDCORE=ID_PLAIN
+a:ID_PLAIN
D:The radiant golden staff of an Istari of legend, this wizard's companion
D:grants keen sight and the knowledge of many hidden things.
@@ -1723,7 +1723,7 @@ P:0:2d9:10:13:0
F:INT | WIS | CHR | HIDE_TYPE | SEARCH | BRAND_FIRE |
F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | SPELL_CONTAIN | WIELD_CAST
F:HOLD_LIFE | RES_FIRE | RES_NETHER | SEE_INVIS | ACTIVATE | SHOW_MODS
-a:HARDCORE=DETECT_XTRA
+a:DETECT_XTRA
D:A staff tall and sturdy, with rough-hewn runes that invoke the element of
D:Earth, and which strikes down all creatures who live in the shadow of
D:mountains.
@@ -1757,7 +1757,7 @@ F:BRAND_COLD | SLAY_ORC | RES_COLD | RES_LITE | REGEN |
F:ACTIVATE | SHOW_MODS | ESP_ORC | ESP_TROLL | ESP_GIANT |
F:COULD2H
f:COULD2H
-a:HARDCORE=TURMIL
+a:TURMIL
D:Wielded by the High Priest of Meneltarma, this great mace gleams coldly as
D:though moonlit, and it can strike as mighty a blow spiritually as
D:physically.
@@ -1809,7 +1809,7 @@ W:50:25:110:50000
P:0:0d0:10:14:0
F:SPEED | HIDE_TYPE |
F:RES_FIRE | ACTIVATE | SHOW_MODS
-a:HARDCORE=CUBRAGOL
+a:CUBRAGOL
D:A crossbow that grants fiery speed to he who finds it, and from which
D:shoot bolts that blaze with flame unquenchable.
@@ -1826,7 +1826,7 @@ F:SEE_INVIS | ESP_EVIL | ESP_DEMON | NEVER_BLOW | INFRA |
F:PRECOGNITION | IM_FIRE | ULTIMATE | SPELL_CONTAIN | WIELD_CAST |
F:COULD2H
f:COULD2H
-a:HARDCORE=GANDALF
+a:GANDALF
D:A simple, wooden wizard's staff. Unremarkable in all aspects...
D:except that it pulses with overwhelming power.
@@ -1926,7 +1926,7 @@ I:14:59:2
W:50:10:30:40000
P:0:1d1:0:0:0
F:ACTIVATE | CHR | INFRA | INSTA_ART | LUCK | STEALTH | SUST_CHR | TUNNEL
-a:HARDCORE=CHARM_OTHERS
+a:CHARM_OTHERS
Z:remove fear
D:This magical instrument once belonged to Thorin Oakenshield,
D:a mighty dwarf warrior of old. The sounds emanating from it
@@ -1941,7 +1941,7 @@ I:32:8:3
W:40:5:20:55000
P:10:2d4:0:0:0
F:ACTIVATE | DEX | HIDE_TYPE | HOLD_LIFE | REGEN | RES_FEAR | SUST_CON | SUST_DEX | SUST_STR
-a:HARDCORE=TERROR
+a:TERROR
D:Mighty was Thorin Oakenshield as he emerged from the Gate of the
D:Lonely Mountain on the day of the Battle of the Five Armies, clad
D:in shining armour, part of which was this helm. He gleamed like
@@ -1996,7 +1996,7 @@ W:50:15:200:55000
P:0:3d4:5:0:0
F:STR | TUNNEL | SUST_STR | HIDE_TYPE | LITE1 | ACTIVATE | CLIMB
F:RES_CHAOS | RES_LITE | RES_DARK
-a:HARDCORE=EREBOR
+a:EREBOR
D:A pick that provides a magical light by which to see while tunnelling.
@@ -2007,7 +2007,7 @@ I:14:58:4
W:19:10:15:10000
P:0:3d4:0:0:0
F:ACTIVATE | STEALTH | SEARCH | INFRA | RES_POIS | RES_DARK
-a:HARDCORE=DRUEDAIN
+a:DRUEDAIN
D:The fabled Drum of the Druedain that will protect those who play it
D:from darkness and poison attacks. It also aids in the seeing of
D:warm-blooded creatures.
@@ -2020,7 +2020,7 @@ I:14:60:2
W:14:10:15:80000
P:0:3d4:0:0:0
F:ACTIVATE | CHR | WIS | ESP_DRAGON
-a:HARDCORE=ROHAN
+a:ROHAN
D:A horn carved from the bones of the Dragon of Ered-Mithrin, this
D:heirloom of the House of Eorl bestows to its user the gifts of
D:courage and command.
@@ -2033,7 +2033,7 @@ I:14:60:2
W:16:10:15:15000
P:0:3d4:0:0:0
F:ACTIVATE | STR | CON | IM_COLD | RES_NETHER | RES_FEAR
-a:HARDCORE=HELM
+a:HELM
D:Heedless of cold, fearless of darkness -- besiegers fled at the wind
D:of the solitary coming of King Helm Hammerhand, proclaimed by a single
D:horn-blast in the dead of winter.
@@ -2046,7 +2046,7 @@ I:14:60:3
W:18:10:15:18000
P:0:3d4:0:0:0
F:ACTIVATE | STR | CON | RES_FEAR | RES_FIRE | AGGRAVATE
-a:HARDCORE=BOROMIR
+a:BOROMIR
D:The great horn made of the horns of kine of Araw. It is inlaid with silver
D:and gold signs; when blown, it can be heard for miles over. The horn gives
D:courage and endurance to its wearer, provided that secrecy is not desired.
@@ -2060,7 +2060,7 @@ I:22:28:-4
W:30:8:250:30000
P:0:3d8:14:19:0
F:BRAND_FIRE | IM_FIRE | CHR | ACTIVATE | SHOW_MODS | CURSED | TY_CURSE
-a:HARDCORE=AXE_GOTHMOG
+a:AXE_GOTHMOG
D:The black axe of Gothmog, which struck Fingon at Nirnaeth. Mighty
D:spells of evil make it unsafe in any hands but those of its original wielder.
@@ -2088,7 +2088,7 @@ F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | SLAY_TROLL | SLAY_DEMON |
F:FREE_ACT | RES_FIRE | RES_DARK | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN |
F:ACTIVATE | SHOW_MODS | BLESSED |
F:PRECOGNITION | NO_MAGIC | ULTIMATE | SPECIAL_GENE
-a:HARDCORE=ERU
+a:ERU
D:A warm light bathes this translucent blade. The power of the fates are
D:at the command of its wielder as the weapon passes Supreme Judgment on
D:the inhabitants of Angband.
@@ -2114,7 +2114,7 @@ W:10:10:5:20000
P:0:0d0:20:0:0
F:INFRA | SEARCH | HIDE_TYPE |
F:XTRA_SHOTS | SHOW_MODS | ACTIVATE | SPECIAL_GENE
-a:SPELL=Artifact Maggot
+a:MAGGOT
D:This ordinary seeming leather sling has been raised to legendary
D:status amongst generations of hobbit children. Farmer Maggot's
D:ability to notice and strike any mushroom thief anywhere within
@@ -2205,7 +2205,7 @@ P:0:2d7:20:14:0
F:DEX | SEARCH | SLAY_ORC | ACTIVATE | HIDE_TYPE | SHOW_MODS |
F:COULD2H
f:COULD2H
-a:HARDCORE=ORCHAST
+a:ORCHAST
D:Forged by the dwarves of Khazad-dum in a time of desperation,
D:this axe turned many a battle against the invading orcs.
@@ -2218,7 +2218,7 @@ W:45:20:45:34000
P:0:2d6:34:22:0
F:DEX | STEALTH | VAMPIRIC | KILL_UNDEAD | RES_DARK | HIDE_TYPE |
F:SHOW_MODS | SEE_INVIS | ACTIVATE | DRAIN_EXP
-a:HARDCORE=NIGHT
+a:NIGHT
D:Found on an unmarked grave after a violent storm, this hatchet
D:has a sinister aura of darkness and decay.
@@ -2230,7 +2230,7 @@ W:70:20:300:28400
P:0:5d7:31:27:0
F:STR | SLAY_ANIMAL | SUST_STR | RES_SHARDS | RES_NEXUS | FEATHER |
F:HIDE_TYPE | SHOW_MODS | ACTIVATE | DRAIN_HP
-a:HARDCORE=NATUREBANE
+a:NATUREBANE
D:Used by the orcs in their battle at Dagor Bragollach against the elves, this
D:axe has a bloodthirst for nature.
@@ -2254,7 +2254,7 @@ W:20:5:75:100000
P:6:1d3:0:0:20
F:LITE1 | HIDE_TYPE | SPECIAL_GENE | LUCK |
F:AUTO_ID | ACTIVATE
-a:HARDCORE=KNOWLEDGE
+a:KNOWLEDGE
D:This helm, designed by Petty-Dwarves ages ago to act as the brain of a
D:long lost project, is made of finest glass. Its light banishes all secrets,
D:and makes audible whispers from the deceased.
@@ -2317,7 +2317,7 @@ I:37:4:2
W:20:3:220:32000
P:14:1d4:3:5:11
F:ACTIVATE | ESP_TROLL | HIDE_TYPE | LITE1 | REGEN | RES_FEAR | SHOW_MODS | STR | SUST_STR
-a:HARDCORE=GORLIM
+a:GORLIM
D:This sturdy mail shirt was a gift from the nobility of Gondor to the halfling
D:Peregrin Took. It enables a warrior to fight more capably and cling to life when
D:others would be killed. It also reveals enemies (especially trolls) hiding in the
@@ -2334,7 +2334,7 @@ F:RES_NEXUS | RES_CHAOS | AGGRAVATE | REGEN |
F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_CONF |
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
F:ACTIVATE
-a:HARDCORE=MEDIATOR
+a:MEDIATOR
D:A mighty suit of dragon armour, set with the scales of dragons of both
D:Law and Chaos, and with power over both. Loknare means Dragonblaze.
@@ -2345,7 +2345,7 @@ I:36:6:0
W:50:20:100:35000
P:6:0d0:0:0:15
F:RES_CHAOS | RES_NETHER | RES_POIS | ACTIVATE
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
D:Contained within this studded cuirass of pliable leather is the memory of
D:unvanquished Himring, defiant fortress surrounded by the legions of Morgoth.
@@ -2373,7 +2373,7 @@ F:ACTIVATE |
F:LITE1 | WIS | CHR | SEARCH | LUCK
F:RES_ELEC | RES_ACID | RES_DISEN | RES_DARK | HIDE_TYPE |
F:SUST_WIS | SUST_DEX | SUST_CHR
-a:HARDCORE=GILGALAD
+a:GILGALAD
D:The legendary shield of Gil-Galad, who fought his way to the gates of
D:the Dark Tower, and with whom came light even to Gorgoroth.
@@ -2387,7 +2387,7 @@ P:3:1d1:0:0:18
F:INT | DEX | CHR | SPELL | SEARCH |
F:RES_FIRE | RES_ACID | RES_DISEN | RES_SHARDS |
F:ACTIVATE
-a:HARDCORE=CELEBRIMBOR
+a:CELEBRIMBOR
D:This once belonged to Celebrimbor, maker of the Rings of Power. One who
D:knows both fire and acid, from the business of forging and engraving, will
D:fear neither: nor have his enchantments ever faded. Celebrimbor was even
@@ -2404,7 +2404,7 @@ P:0:4d1:18:18:0
F:STR | CON | XTRA_MIGHT | AGGRAVATE |
F:RES_LITE | RES_DARK | RES_BLIND | RES_ELEC |
F:HIDE_TYPE | ACTIVATE | SHOW_MODS
-a:HARDCORE=UMBAR
+a:UMBAR
D:A great brazen arbalest with arms of gleaming steel, shooting quarrels with
D:speed and power for those brave enough to risk betrayal.
@@ -2450,7 +2450,7 @@ F:TUNNEL | INFRA | SEARCH | STR | ESP_ORC | CLIMB |
F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | SLAY_DRAGON |
F:BRAND_ACID | RES_ACID | RES_DARK | RES_DISEN |
F:ACTIVATE
-a:HARDCORE=STONE_MUD
+a:STONE_MUD
D:Wielded by Nain of the Iron Hills at the Battle of Azanulbizar, this great
D:mattock brought victory to the Dwarves over Azog's Orcs - though Nain
D:himself fell at the last, even with victory already assured.
@@ -2467,7 +2467,7 @@ F:SLAY_EVIL | SLAY_UNDEAD | ACTIVATE |
F:RES_FIRE | RES_ELEC | RES_NETHER | RES_DISEN | HOLD_LIFE |
F:COULD2H
f:COULD2H
-a:HARDCORE=FUNDIN
+a:FUNDIN
D:The weapon of one of the great dwarven priests, with powers
D:to preserve body, soul and enchantments, and the bane of those
D:who seek life beyond death.
@@ -2482,7 +2482,7 @@ P:4:1d2:0:0:15
F:ACTIVATE |
F:STR | CON | SUST_STR | SUST_CON | HIDE_TYPE |
F:RES_FEAR | RES_BLIND | RES_POIS | AGGRAVATE
-a:HARDCORE=HARADRIM
+a:HARADRIM
D:A great shield from the far lands of the South, whose wielder
D:will go charging into battle heedless of danger, with the
D:strength and endurance of a madman. Nor will he fear poison, for
@@ -2500,7 +2500,7 @@ F:RES_NEXUS | RES_BLIND | RES_SOUND |
F:KILL_DRAGON | SLAY_ANIMAL | BRAND_POIS | BRAND_ELEC |
F:COULD2H
f:COULD2H
-a:HARDCORE=SKULLCLEAVER
+a:SKULLCLEAVER
D:This mighty bludgeon brings destruction to all around it, and is the
D:bane of dragons and magic. Skull-cleaver (or head-cleaver) it is called.
@@ -2512,7 +2512,7 @@ W:55:35:25:40000
P:3:1d1:0:0:15
F:INT | MANA | FREE_ACT | FEATHER | RES_ELEC | RES_DARK | RES_POIS |
F:ACTIVATE | LUCK | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=EOL
+a:EOL
D:The iron-shod gauntlets of the Dark Elven smith Eol, tingling with magics
D:that he could channel in battle.
@@ -2581,7 +2581,7 @@ I:35:2:3
W:10:10:10:12500
P:4:0d0:0:0:16
F:ACTIVATE | CHR | DEX | HIDE_TYPE | INVIS | LUCK | SEARCH | STEALTH
-a:HARDCORE=CURE_HUNGER
+a:CURE_HUNGER
D:This simple-looking cloak, dyed in hues that blend into the woodlands, was a gift
D:from the elves of Lothlorien to the halfling Peregrin Took. Its wearer has an
D:uncanny knack for making friends, escaping bonds, moving among enemies completely
@@ -2597,7 +2597,7 @@ P:0:3d4:0:0:0
F:ACTIVATE | BLESSED | CHR | ESP_UNDEAD | FREE_ACT |
F:HIDE_TYPE | HOLD_LIFE | LIFE | LUCK | RES_FEAR |
F:RES_SOUND | SEARCH | SEE_INVIS | STEALTH | SUST_CHR
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
D:This small, serviceable wooden harp once belonged to Tom Bombadil--
D:a mysterious figure whose song prevented the Wight-King from
D:attacking Frodo and his companions. Its music still inspires
@@ -2615,7 +2615,7 @@ F:HIDE_TYPE | INFRA | INT | MANA | RES_COLD | RES_ELEC |
F:RES_FIRE | RES_MORGUL | SEARCH | SEE_INVIS | SHOW_MODS |
F:SLAY_ANIMAL | SLAY_EVIL | SPELL | SPELL_CONTAIN |
F:STEALTH | WATER_BREATH | WIELD_CAST | WIS
-a:SPELL=Artifact Radagast
+a:RADAGAST
Z:grow trees
D:Rumoured to be a gift from Yavanna to Radagast the Brown, this
D:plain-seeming oak staff shields its bearer against the elements
@@ -2634,7 +2634,7 @@ P:0:3d4:0:0:0
F:ACTIVATE | BLESSED | CON | ESP_ANIMAL | ESP_EVIL |
F:FREE_ACT | HIDE_TYPE | LUCK | RES_CONF | RES_FEAR |
F:RES_SOUND | SEARCH | SEE_INVIS | STEALTH
-a:SPELL=Artifact Valaroma
+a:VALAROMA
D:This heavenly instrument, wrought from gleaming silver, most
D:often appears in the hands of the Valarin huntsman Orome; yet
D:he may lend mortal champions the horn from time to time. Its
@@ -2651,7 +2651,7 @@ P:1:0d0:0:0:25
F:ACTIVATE | CHR | FLY | HIDE_TYPE | IM_ELEC | INFRA |
F:LITE1 | MAGIC_BREATH | RES_COLD | RES_DARK | RES_LITE |
F:SEARCH | SEE_INVIS | SUST_CHR
-a:HARDCORE=GILGALAD
+a:GILGALAD
D:This deep-blue velvet cloak, embroidered with silvery stars, sheds a
D:celestial light that reveals hidden things and bestows unearthly
D:beauty. It also wards off damage from elements of the skies, and
@@ -2694,7 +2694,7 @@ W:60:30:50:50000
P:0:0d0:0:0:0
F:ACTIVATE | ESP_UNDEAD | HIDE_TYPE | INSTA_ART | INVIS |
F:LITE1 | RES_CHAOS | RES_DARK | RES_NETHER | STEALTH
-a:HARDCORE=SUMMON_UNDEAD
+a:SUMMON_UNDEAD
D:A large banner of pure black, strangely gleaming with a dark light
D:that is faint and at the same time so bright it attracts attention.
@@ -2707,7 +2707,7 @@ W:60:80:12:60000
P:0:1d4:5:5:0
F:ACTIVATE | HIDE_TYPE | INT | MANA | SHOW_MODS | SPEED |
F:SPELL | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=BA_COLD_1
+a:BA_COLD_1
Z:weigh magic
D:A white quarterstaff that faintly gleams a pale white, it once belonged
D:to one of the most powerful beings on Middle-Earth, Saruman the White.
@@ -2723,7 +2723,7 @@ W:60:80:20:2000000
P:2:0d0:-40:-40:36
F:ACTIVATE | HIDE_TYPE | IM_COLD | IM_ELEC | SPEED | SPELL_CONTAIN |
F:SUST_CHR | SUST_CON | SUST_DEX | SUST_INT | SUST_STR | WIELD_CAST
-a:HARDCORE=BA_ELEC_2
+a:BA_ELEC_2
D:The white robe of the Istari wizard Curunir, known on Middle-earth as
D:Saruman the White and Saruman of Many Colours. Imbued with cold and
D:lightning used in the creation of the Fire of Orthanc, it grants the
@@ -2737,7 +2737,7 @@ I:19:23:10
W:30:10:110:40000
P:0:0d0:5:7:0
F:ACTIVATE | HIDE_TYPE | RES_COLD | SHOW_MODS | STEALTH
-a:HARDCORE=RUNE_EXPLO
+a:RUNE_EXPLO
D:The bow of Brand, last King of Dale. It was given to him
D:as a gift by the King under the Mountain of Erebor, and
D:has access to an especially secret realm of Dwarven lore.
@@ -2766,7 +2766,7 @@ F:ACTIVATE | AUTO_CURSE | CURSED | DRAIN_EXP | DRAIN_MANA |
F:ESP_EVIL | HEAVY_CURSE | HIDE_TYPE | INSTA_ART | LITE2 |
F:LITE3 | RES_CHAOS | RES_DARK | RES_FIRE | RES_LITE |
F:RES_NETHER | RES_NEXUS | RES_SHARDS | SEE_INVIS | STR
-a:HARDCORE=INVULN
+a:INVULN
Z:banish evil
D:A Silmaril of Feanor. It shines with the unquenchable light of the
D:White Trees of Valinor. It was stolen from the camp of Eonwe by
@@ -2786,7 +2786,7 @@ P:0:10d10:0:0:0
F:ACTIVATE | AUTO_CURSE | CURSED | DRAIN_EXP | DRAIN_HP | ESP_EVIL |
F:HEAVY_CURSE | HIDE_TYPE | INSTA_ART | INT | LITE2 | LITE3 |
F:RES_CHAOS | RES_DARK | RES_LITE | RES_NETHER | RES_NEXUS | SEE_INVIS
-a:HARDCORE=RECALL
+a:RECALL
Z:banish evil
D:A Silmaril of Feanor. It shines with the unquenchable light of the
D:White Trees of Valinor. It was stolen from the camp of Eonwe by
@@ -2804,7 +2804,7 @@ W:50:40:24:80000
P:0:0d0:0:0:0
F:ACTIVATE | AUTO_CURSE | CHR | CON | CURSED | HEAVY_CURSE |
F:INSTA_ART | LUCK | SPEED | SPELL_CONTAIN | STR | WIELD_CAST | WRAITH
-a:HARDCORE=DISP_GOOD
+a:DISP_GOOD
D:The chief mark of royalty in Westernesse, it is said to have perished
D:in the fall of Numenor. It once belonged to Ar-Pharazon the Golden and
D:the evilness of that fallen King still courses through it.
@@ -2817,7 +2817,7 @@ W:60:50:24:80000
P:0:0d0:0:0:0
F:ACTIVATE | BLESSED | CHR | FREE_ACT | INSTA_ART | LUCK |
F:RES_CONF | SPELL_CONTAIN | WIELD_CAST
-a:HARDCORE=RUNE_PROT
+a:RUNE_PROT
D:The chief mark of royalty in Arnor, possibly the oldest remaining work
D:of Men. It came from Numenor, but it belonged to the Lords of Andunie
D:of whom the first was Valandil son of Silmarien. It was passed down to
@@ -2832,7 +2832,7 @@ P:0:1d1:0:0:0
F:ACTIVATE | BLESSED | ESP_ALL | HIDE_TYPE | INFRA | INT |
F:LITE1 | LITE2 | LITE3 | RES_BLIND | RES_LITE | SEARCH |
F:SEE_INVIS | WATER_BREATH | WIS
-a:HARDCORE=PALANTIR
+a:PALANTIR
Z:detect curses
D:This holy lamp once belonged to a seeress who warned Ar-Pharazon of
D:the dire fate Numenor would suffer for daring to break the ban against
@@ -2859,7 +2859,7 @@ P:0:10d10:0:0:0
F:WIS | INT | SEARCH | INFRA | HIDE_TYPE | ACTIVATE | ESP_ALL |
F:SEE_INVIS | RES_BLIND | AGGRAVATE | DRAIN_MANA | LITE2
F:INSTA_ART
-a:HARDCORE=PALANTIR
+a:PALANTIR
D:A shining white ball of unbreakable crystal, the ancient Palantiri
D:were used by kings of Numenor and later by the Exiles for rapid
D:communication between distant lands. Nothing is hidden from one who
@@ -2922,7 +2922,7 @@ P:0:0d0:7:7:10
F:STR | WIS | CHR | SPEED | LITE3 | INSTA_ART |
F:RES_FEAR | RES_FIRE | RES_POIS | RES_DISEN | HIDE_TYPE |
F:ACTIVATE
-a:HARDCORE=ELESSAR
+a:ELESSAR
D:This green gem glows with inner light. Aragorn son of Arathorn wore
D:it at the Battle of the Pelennor Fields, and he was himself given the
D:name of 'Elessar' by the people of Gondor because of this.
@@ -2936,7 +2936,7 @@ W:50:50:3:35000
F:HOLD_LIFE | SUST_CON | SUST_WIS | SUST_INT | LITE1 | CON |
F:RES_DARK | RES_COLD | RES_NETHER | REGEN | INSTA_ART |
F:ACTIVATE
-a:HARDCORE=REST_ALL
+a:REST_ALL
D:A pure white jewel, the last gift of Queen Arwen Undomiel to Frodo
D:Baggins, intended to be worn around his neck on the chain that had
D:once borne the One Ring.
@@ -2950,7 +2950,7 @@ P:0:10d10:0:0:-30
F:LIFE | CON | INT | WIS | ESP_ALL | LITE3 | LITE1
F:CURSED | HEAVY_CURSE | TY_CURSE | DRAIN_EXP |
F:RES_BLIND | SEE_INVIS | ACTIVATE
-a:HARDCORE=PALANTIR
+a:PALANTIR
D:A shining white ball of unbreakable crystal, the ancient Palantiri
D:were used by kings of Numenor and later by the Exiles for rapid
D:communication between distant lands. This Palantir, however, was
@@ -2990,7 +2990,7 @@ I:11:14:0
W:70:100:50:100000
P:0:0d0:0:0:0
F:ACTIVATE | ACTIVATE_NO_WIELD | HIDE_TYPE | INSTA_ART | SPECIAL_GENE
-a:HARDCORE=ALCHEMY
+a:ALCHEMY
D:It was made for Thror, King under the Mountain. It is a huge golden bowl
D:with two handles, hammered and carved, with birds and flowers whose eyes
D:and leaves are made in jewels.
@@ -3002,7 +3002,7 @@ I:11:15:0
W:40:70:2:70000
P:0:0d0:0:0:0
F:ACTIVATE | ACTIVATE_NO_WIELD | HIDE_TYPE | INSTA_ART
-a:HARDCORE=BOROMIR
+a:BOROMIR
D:The summons of Gondor, an arrow sent as a symbol of desperate need from
D:Gondor to its northern allies, the Rohirrim. The tradition dates back to
D:the time of Borondir, who rode north from Gondor to summon aid from the
@@ -3120,7 +3120,7 @@ I:40:4:5
W:20:5:2:15000
P:0:1d1:0:0:10
F:ACTIVATE | CHR | INSTA_ART | RES_NEXUS | RES_POIS | SEE_INVIS | SUST_CHR
-a:HARDCORE=GROW_MOLD
+a:GROW_MOLD
D:A necklace of emeralds, green as the grass. It once belonged to Girion,
D:King of Dale, and was given to the Dwarves of the Lonely Mountain as
D:payment for a mithril mail shirt for Girion's son. It seems to have
@@ -3158,7 +3158,7 @@ I:34:8:0
W:95:80:100:90000
P:20:1d1:0:0:80
F:ACTIVATE | RES_BLIND | RES_DARK | RES_ELEC | RES_FIRE | RES_NETHER
-a:HARDCORE=BLADETURNER
+a:BLADETURNER
D:A shining shield, once borne by the great mariner Earendil, "scored with
D:runes to keep all wounds and harm from him".
@@ -3218,7 +3218,7 @@ F:NO_MAGIC | PRECOGNITION | REGEN | RES_DARK | RES_FIRE |
F:SEE_INVIS | SHOW_MODS | SLAY_DEMON | SLAY_EVIL | SLAY_TROLL |
F:SLAY_UNDEAD | SLOW_DIGEST | SPECIAL_GENE | SUST_CHR | SUST_CON |
F:SUST_DEX | SUST_INT | SUST_STR | SUST_WIS | ULTIMATE | VORPAL
-a:HARDCORE=ERU
+a:ERU
D:A weapon forged by Aule himself and blessed by Eru Iluvatar,
D:calling upon the strength of all his children (hence the name,
D:which means Children of Eru). It is Eru Iluvatar's gift to you,
@@ -3236,7 +3236,7 @@ F:NO_MAGIC | PRECOGNITION | REGEN | RES_DARK | RES_FIRE |
F:SEE_INVIS | SHOW_MODS | SLAY_DEMON | SLAY_EVIL | SLAY_TROLL |
F:SLAY_UNDEAD | SLOW_DIGEST | SPECIAL_GENE | SUST_CHR | SUST_CON |
F:SUST_DEX | SUST_INT | SUST_STR | SUST_WIS | ULTIMATE | VORPAL
-a:HARDCORE=ERU
+a:ERU
D:The awesome weapon of the Vala Ulmo, Lord of Waters. Mightiest of all the
D:powers of good save Manwe himself, Ulmo laughs in scorn at the dread powers
D:of the undead, and is utterly in command of the element of water.
@@ -3253,7 +3253,7 @@ F:NO_MAGIC | PRECOGNITION | REGEN | RES_DARK | RES_FIRE |
F:SEE_INVIS | SHOW_MODS | SLAY_DEMON | SLAY_EVIL | SLAY_TROLL |
F:SLAY_UNDEAD | SLOW_DIGEST | SPECIAL_GENE | SUST_CHR | SUST_CON |
F:SUST_DEX | SUST_INT | SUST_STR | SUST_WIS | ULTIMATE | VORPAL
-a:HARDCORE=ERU
+a:ERU
D:Aule's mighty weapon, granted to you to aid the defeat of Melkor.
# The Rapier of Vaire (Rogues, whose Critical-hits skill is only useful with lighter swords)
@@ -3268,7 +3268,7 @@ F:PRECOGNITION | REGEN | RES_DARK | RES_FIRE | SEE_INVIS | SHOW_MODS |
F:SLAY_DEMON | SLAY_EVIL | SLAY_TROLL | SLAY_UNDEAD | SLOW_DIGEST |
F:SPECIAL_GENE | SUST_CHR | SUST_CON | SUST_DEX | SUST_INT | SUST_STR |
F:SUST_WIS | ULTIMATE | VORPAL
-a:HARDCORE=ERU
+a:ERU
D:A shining rapier used by Vaire to cut the strings of time when
D:dire need arises. Its power with that of the Flame Imperishable
D:will let you destroy Melkor forever.
@@ -3333,7 +3333,7 @@ F:IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | REGEN | RES_ACID |
F:RES_BLIND | RES_CHAOS | RES_COLD | RES_CONF | RES_DARK | RES_DISEN |
F:RES_ELEC | RES_FIRE | RES_LITE | RES_NETHER | RES_NEXUS | RES_POIS |
F:RES_SHARDS | RES_SOUND | SPECIAL_GENE | ULTIMATE
-a:HARDCORE=BLADETURNER
+a:BLADETURNER
D:This amulet contains the power of Mandos, the Doomsman of the
D:Valar. It will grant you protection against the foul dark magic
D:of Melkor, though you will still need your wits and strength
diff --git a/lib/mods/theme/edit/ab_info.txt b/lib/mods/theme/edit/ab_info.txt
index 4272776a..b78346ec 100644
--- a/lib/mods/theme/edit/ab_info.txt
+++ b/lib/mods/theme/edit/ab_info.txt
@@ -22,8 +22,6 @@
# E:excluding ability:excluding ability
-# If you need more sophisticated prereqs use the HOOK_LEARN_ABILITY
-
# Version stamp (required)
# Do not forget to update misc.txt with an entry like the following :
@@ -36,9 +34,9 @@ N:0:Spread blows
D:If a monster dies to your attack but you still have blows left
D:you won't lose the full turn, allowing you to attack some other
D:monster in the same turn
-D:Prereq: Weaponmastery skill@30, Dex@17
+D:Prereq: Combat@30, Dex@17
I:5
-k:30:Weaponmastery
+k:30:Combat
S:17:DEX
N:1:Tree walking
diff --git a/lib/mods/theme/edit/ba_info.txt b/lib/mods/theme/edit/ba_info.txt
index b76f79dd..96d372bf 100644
--- a/lib/mods/theme/edit/ba_info.txt
+++ b/lib/mods/theme/edit/ba_info.txt
@@ -65,10 +65,6 @@ N:10:Play craps
C:0:0:0
I:14:0:c
-N:11:Spin the wheel
-C:0:0:0
-I:15:0:s
-
N:12:Play dice slots
C:0:0:0
I:16:0:d
@@ -97,14 +93,6 @@ N:18:Research monster
C:1600:1500:1400
I:20:0:r
-N:19:View bounties
-C:0:0:0
-I:38:0:v
-
-N:20:Receive bounty money
-C:0:0:0
-I:39:0:b
-
N:21:Get quest monster
C:0:0:0
I:54:0:q
@@ -165,19 +153,6 @@ N:35:Get a quest
C:0:0:0
I:6:0:q
-# Restrict to liked/normal
-N:36:Get a quest
-C:0:0:0
-I:46:1:q
-
-N:37:Get a quest
-C:0:0:0
-I:47:0:q
-
-N:38:Get a quest
-C:0:0:0
-I:49:0:q
-
N:39:Herbal Healing
C:32000:10000:0
I:50:0:h
@@ -190,10 +165,6 @@ N:41:Distribute earnings
C:0:0:0
I:7:2:d
-N:42:Morph restoration
-C:3000:1500:750
-I:37:0:r
-
#for The Mirror
N:43:View fate
C:500:500:500
@@ -204,11 +175,6 @@ N:44:Research item
C:1500:1500:1500
I:1:0:a
-#for library in gondol
-N:45:Research item
-C:2000:2000:2000
-I:1:0:a
-
#for Star-Dome
N:46:Identify possessions
C:1200:1000:250
@@ -257,18 +223,6 @@ N:55:Get an item
C:0:0:0
I:44:0:g:p
-N:56:Request an item
-C:0:0:0
-I:51:2:r
-
-N:57:Ask for loan
-C:0:0:0
-I:52:2:a
-
-N:58:Pay back loan
-C:0:0:0
-I:53:2:p
-
N:59:Donate an item
C:0:0:0
I:43:0:d
diff --git a/lib/mods/theme/edit/d_info.txt b/lib/mods/theme/edit/d_info.txt
index 91cf3d20..ee0833b8 100644
--- a/lib/mods/theme/edit/d_info.txt
+++ b/lib/mods/theme/edit/d_info.txt
@@ -83,7 +83,8 @@ N:4:Barrow-Downs
D:BDw:a way to the Barrow-Downs.
W:1:10:1:0:14:160
# Theme adds *fog* (dense mist) on the Barrow-Downs :)
-L:88:94:210:2:199:4
+#L:88:94:210:2:199:4
+L:88:78:89:18:199:4
A:96:80:97:19:57:1:57:97
A:100:0:0
O:20:20:20:20
@@ -308,7 +309,7 @@ M:ORC | R_CHAR_o | R_CHAR_O
# There is Glaurung
N:20:Erebor
D:Ere:a tunnel leading into depths of the Lonely Mountain.
-W:60:72:35:0:20:140
+W:60:72:30:0:20:140
L:88:100:1:0:1:0
A:97:90:87:10:56:0:57:97
O:40:40:40:40
diff --git a/lib/mods/theme/edit/e_info.txt b/lib/mods/theme/edit/e_info.txt
index 72b8348e..4d2ec5ff 100644
--- a/lib/mods/theme/edit/e_info.txt
+++ b/lib/mods/theme/edit/e_info.txt
@@ -233,7 +233,7 @@ C:0:0:0:3
Z:blink
R:100
F:ACTIVATE
-a:HARDCORE=JUMP
+a:JUMP
### Shields ###
@@ -323,7 +323,7 @@ C:0:0:0:2
W:0:1:8:500
R:100
F:DEX | SUST_DEX | ACTIVATE | ESP_ORC
-a:HARDCORE=NOLDOR
+a:NOLDOR
N:24:of Intelligence
X:A:33:13
@@ -869,7 +869,7 @@ W:0:1:44:9000
C:8:8:0:2
R:100
F:DEX | STR | VORPAL | ACTIVATE
-a:HARDCORE=SPIN
+a:SPIN
# The "Elemental" brands (4) (6)
@@ -1251,7 +1251,7 @@ T:24:0:99
X:A:24:22
W:10:6:90:45000
C:4:4:0:2
-a:HARDCORE=TELEPORT
+a:TELEPORT
R:100
F:SLAY_EVIL | KILL_DRAGON | TELEPORT | FREE_ACT | SEARCH | BRAND_ELEC
F:REGEN | SLOW_DIGEST | RES_MORGUL | ACTIVATE | ESP_DRAGON
@@ -1310,7 +1310,7 @@ W:0:1:5:5000
R:100
F:SLAY_UNDEAD | SEE_INVIS | HOLD_LIFE | DRAIN_HP
F:ACTIVATE
-a:HARDCORE=SPECTRAL
+a:SPECTRAL
N:103:of Morgul
T:125:0:99
@@ -1617,7 +1617,7 @@ R:50
F:PVAL_M1
R:25
F:PVAL_M1
-a:HARDCORE=BA_ACID_H
+a:BA_ACID_H
# Rods ego
N:131:Capacity of
@@ -2148,7 +2148,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_COLD_3
+a:BA_COLD_3
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
@@ -2157,7 +2157,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_ELEC_3
+a:BA_ELEC_3
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
@@ -2166,7 +2166,7 @@ T:14:7:7
X:B:25:20
W:0:1:2:2000
C:0:0:0:0
-a:HARDCORE=BA_FIRE_H
+a:BA_FIRE_H
R:100
F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD |
@@ -2434,7 +2434,7 @@ F:FREE_ACT | RES_BLIND | RES_CONF | R_HIGH | SUST_WIS |
F:BLESSED | ACTIVATE |
F:IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE |
f:IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | SUST_WIS |
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
r:F:CURSED | HEAVY_CURSE | AUTO_CURSE |
R:33
F:ESP_EVIL |
@@ -2453,7 +2453,7 @@ F:ACTIVATE |
F:IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE |
f:FREE_ACT | IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE |
r:F:CURSED | HEAVY_CURSE | AUTO_CURSE |
-a:HARDCORE=SPECTRAL
+a:SPECTRAL
R:33
F:RES_NETHER |
R:5
diff --git a/lib/mods/theme/edit/k_info.txt b/lib/mods/theme/edit/k_info.txt
index 07e4bbe2..4739a932 100644
--- a/lib/mods/theme/edit/k_info.txt
+++ b/lib/mods/theme/edit/k_info.txt
@@ -1413,7 +1413,7 @@ G:=:d
I:45:4:0
W:5:0:2:250
A:5/1
-a:HARDCORE=DEST_TELE
+a:DEST_TELE
F:CURSED | TELEPORT | EASY_KNOW | ACTIVATE
f:TELEPORT
D:This ring will uncontrollably send you to different places at its whim.
@@ -1474,7 +1474,7 @@ I:45:18:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_FIRE_4
+a:BA_FIRE_4
F:RES_FIRE | ACTIVATE
f:RES_FIRE | IGNORE_FIRE
D:This fiery circlet grants you protection, makes fire less dangerous and even
@@ -1486,7 +1486,7 @@ I:45:17:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_ACID_4
+a:BA_ACID_4
F:RES_ACID | ACTIVATE
f:RES_ACID | IGNORE_ACID
D:This magical ring is imbued with spells of devouring acid, granting protection against such
@@ -1497,7 +1497,7 @@ G:=:d
I:45:19:0
W:50:0:2:3000
A:50/1
-a:HARDCORE=BA_COLD_4
+a:BA_COLD_4
P:0:0d0:0:0:15
F:RES_COLD | ACTIVATE
f:RES_COLD | IGNORE_COLD
@@ -1538,7 +1538,7 @@ I:45:28:0
W:20:0:2:500
A:20/1
F:HIDE_TYPE | EASY_USE | ACTIVATE |
-a:HARDCORE=WHIRLWIND
+a:WHIRLWIND
D:This ring magically improves your control in combat, allowing you to hit more often.
D:It can also sometimes be used to hit several nearby opponents with deadly accuracy.
@@ -1621,7 +1621,7 @@ I:40:2:0
W:25:0:3:10000
A:25/1
F:EASY_KNOW | ACTIVATE | BLESSED | ESP_EVIL
-a:HARDCORE=PROT_EVIL
+a:PROT_EVIL
D:This blessed amulet fends off evil beings and warns the wearer
D:of their presence.
@@ -2698,9 +2698,9 @@ W:127:0:4:0
A:127/255
P:0:1d1:0:0:0
T:39:2
-F:NORM_ART | FULL_NAME | SPECIAL_GENE
+F:NORM_ART | FULL_NAME | SPECIAL_GENE | EASY_USE
F:ACTIVATE | ACTIVATE_NO_WIELD
-a:SPELL=Artifact Eternal Flame
+a:ETERNAL_FLAME
D:An impossibly bright, flickering living flame. It can be used
D:once to imbue an object with the power of Eru Iluvatar himself.
@@ -3472,7 +3472,7 @@ I:38:1:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_ACID
+a:BR_ACID
F:RES_ACID | FLY |
f:RES_ACID |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3485,7 +3485,7 @@ I:38:2:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_ELEC
+a:BR_ELEC
F:RES_ELEC | FLY |
f:RES_ELEC |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3497,7 +3497,7 @@ G:[:w
I:38:3:0
W:50:0:200:40000
A:50/8
-a:HARDCORE=BR_COLD
+a:BR_COLD
P:30:2d4:-2:0:10
F:RES_COLD | FLY |
f:RES_COLD |
@@ -3511,7 +3511,7 @@ I:38:4:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_FIRE
+a:BR_FIRE
F:RES_FIRE | FLY |
f:RES_FIRE |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3524,7 +3524,7 @@ I:38:5:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_POIS
+a:BR_POIS
F:RES_POIS | FLY |
f:RES_POIS |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
@@ -3537,7 +3537,7 @@ I:38:6:0
W:90:0:200:150000
A:90/32
P:30:2d4:-2:0:10
-a:HARDCORE=BR_MANY
+a:BR_MANY
F:ATTR_MULTI
F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | FLY |
f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS |
@@ -3551,7 +3551,7 @@ I:38:10:0
W:70:0:200:70000
A:70/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_LIGHT
+a:BR_LIGHT
F:RES_LITE | RES_DARK | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A strangely glowing armour made from a pseudo-dragon's hide.
@@ -3563,7 +3563,7 @@ I:38:12:0
W:80:0:200:80000
A:80/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_SHARD
+a:BR_SHARD
F:RES_SOUND | RES_SHARDS | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A sharp-scaled armour that seems to roar, made from a law dragon's hide.
@@ -3575,7 +3575,7 @@ I:38:14:0
W:50:0:200:40000
A:50/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_CONF
+a:BR_CONF
F:RES_CONF | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A brownish armour glittering in a dazzling light, made from a bronze dragon's hide.
@@ -3587,7 +3587,7 @@ I:38:16:0
W:60:0:200:50000
A:60/8
P:30:2d4:-2:0:10
-a:HARDCORE=BR_SOUND
+a:BR_SOUND
F:RES_SOUND | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of armour with rustling scales, made from a gold dragon's hide.
@@ -3599,7 +3599,7 @@ I:38:18:0
W:80:0:200:80000
A:80/16
P:30:2d4:-2:0:10
-a:HARDCORE=BR_CHAOS
+a:BR_CHAOS
F:ATTR_MULTI
F:RES_CHAOS | RES_DISEN | FLY |
f:RES_CHAOS |
@@ -3614,7 +3614,7 @@ I:38:20:0
W:95:0:200:100000
A:95/32
P:30:2d4:-2:0:10
-a:HARDCORE=BR_BALANCE
+a:BR_BALANCE
F:RES_CHAOS | RES_DISEN | RES_SOUND | RES_SHARDS | FLY |
F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD
D:A suit of armour made of the hide of a dead dragon. When wearing it, you feel like you
@@ -3626,7 +3626,7 @@ I:38:30:0
W:100:0:250:350000
A:100/64
P:40:2d4:-3:0:15
-a:HARDCORE=BR_POWER
+a:BR_POWER
F:ATTR_MULTI
F:RES_ACID | RES_FIRE | RES_COLD | RES_ELEC | RES_POIS | FLY |
F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK |
@@ -3850,7 +3850,7 @@ W:50:0:2:100000
A:50/2
F:BLOWS | ACTIVATE | EASY_USE |
f:BLOWS | ACTIVATE
-a:HARDCORE=SPIN
+a:SPIN
D:This powerful ring of fighters greatly enhances your fighting speed, allowing you to attack
D:more often in a round of combat.
@@ -4785,7 +4785,7 @@ I:45:56:0
W:50:0:2:3000
A:50/1
P:0:0d0:0:0:15
-a:HARDCORE=BA_ELEC_4
+a:BA_ELEC_4
F:RES_ELEC | ACTIVATE
f:RES_ELEC | IGNORE_ELEC
D:This sparkling circlet grants you protection, makes electricity less
@@ -5992,7 +5992,7 @@ G:":G
I:40:17:0
W:25:0:3:10000
A:25/1
-a:HARDCORE=BA_POIS_4
+a:BA_POIS_4
F:RES_POIS | DEX | ACTIVATE
D:A petrified serpent's tongue, hung on a thin chain to be clasped around your neck. It makes you
D:like a snake, able to wriggle out of tight corners, impervious to poisons and poisonous
@@ -6465,7 +6465,7 @@ A:100/10
F:SUST_STR | SUST_DEX | SUST_CON | REGEN |
F:HOLD_LIFE | LIFE |
F:HIDE_TYPE | ACTIVATE |
-a:HARDCORE=CURE_HUNGER
+a:CURE_HUNGER
f:SUST_STR | SUST_DEX | SUST_CON | REGEN |
D:This valuable ring enhances and protects the wearer's life force in every way.
@@ -6476,7 +6476,7 @@ W:100:0:2:125000
A:100/10
F:SUST_INT | SUST_WIS | RES_FEAR | RES_CONF |
F:ACTIVATE | EASY_KNOW |
-a:HARDCORE=CURE_INSANITY
+a:CURE_INSANITY
f:SUST_INT | SUST_WIS |
D:This valuable ring protects the wearer's intellect and intuition, as well as
D:guarding him from most mental attacks. From time to time, the wearer can
diff --git a/lib/mods/theme/edit/ow_info.txt b/lib/mods/theme/edit/ow_info.txt
index 92f0076a..ce9e526e 100644
--- a/lib/mods/theme/edit/ow_info.txt
+++ b/lib/mods/theme/edit/ow_info.txt
@@ -1412,8 +1412,3 @@ I:20000:130
C:110:100:80
L:Human | RohanKnight | Dunadan | High-Elf
H:Dragon | Demon | Beorning | Orc | Half-Ogre | Troll | Easterling
-
-### For the Merchants' Guild ###
-N:211:Worm(Human)
-I:30000:130
-C:110:100:90 \ No newline at end of file
diff --git a/lib/mods/theme/edit/p_info.txt b/lib/mods/theme/edit/p_info.txt
index 49832c32..965c639a 100644
--- a/lib/mods/theme/edit/p_info.txt
+++ b/lib/mods/theme/edit/p_info.txt
@@ -2834,22 +2834,3 @@ M:C:Mage
M:C:Priest
M:C:Loremaster
M:C:Pacifist
-#M:C:Test
-#M:C:Chaos-Warrior
-
-#M:N:1:B:Spellcasters -- Magic is The One True Way
-
-#M:N:2:y:Priests -- Hail the powers of the Ainur
-#M:C:Mindcrafter
-
-#M:N:3:G:Beastfriends -- Monsters are fun
-#M:C:BeastMaster
-
-#M:N:4:v:Others -- The way to your independence
-#M:C:Harper
-#M:C:Merchant
-
-#M:N:5:o:Tests -- Test is you dare !
-#M:C:Test
-#M:C:Blade
-#M:C:Black-Knight
diff --git a/lib/mods/theme/edit/r_info.txt b/lib/mods/theme/edit/r_info.txt
index bcc46bd5..ae8d118d 100644
--- a/lib/mods/theme/edit/r_info.txt
+++ b/lib/mods/theme/edit/r_info.txt
@@ -13696,7 +13696,7 @@ G:B:D
I:130:80d100:20:120:80
W:72:2:400000:45000
E:1:1:1:2:1:1
-O:50:50:0:0
+O:0:0:0:0
B:HIT:HURT:12d10
B:HIT:HURT:12d10
B:CHARGE:HURT:10d10
@@ -13704,7 +13704,7 @@ B:CHARGE:HURT:10d10
F:UNIQUE | MALE | CAN_SPEAK | RES_TELE | SPECIAL_GENE |
F:FORCE_MAXHP | REGENERATE | THUNDERLORD | CAN_FLY |
F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT |
-F:SMART | OPEN_DOOR | BASH_DOOR | DROP_CHOSEN |
+F:SMART | OPEN_DOOR | BASH_DOOR |
F:EVIL | IM_FIRE | IM_COLD | IM_POIS |
F:MORTAL | HAS_LITE
S:1_IN_4 |
diff --git a/lib/mods/theme/edit/st_info.txt b/lib/mods/theme/edit/st_info.txt
index 29ca49fc..41975bc6 100644
--- a/lib/mods/theme/edit/st_info.txt
+++ b/lib/mods/theme/edit/st_info.txt
@@ -1,13 +1,5 @@
# File: st_info.txt
-# Fixed Potions of Cure Light/Serious Wounds in the Temple, Potions of
-# Restore Str/Con in the Alchemist
-# Magic Shop - Amulet of Slow Digestion, Wand of Light, Staffs of Enlightenment,
-# Door/Stair Location, Detect Invis/Evil, and Remove Curse
-
-# This file is used to initialize the "lib/raw/st_info.raw" file, which is
-# used to initialize the "store info type" information for the Angband game.
-
# Do not modify this file unless you know exactly what you are doing,
# unless you wish to risk possible system crashes and broken savefiles.
@@ -793,12 +785,6 @@ F:RANDOM | MEDIUM_LEVEL | DEPEND_LEVEL
F:RARE
W:24
-N:56:Merchants Guild
-A:0:0:56:57:58:0
-O:211:211:211:211
-G:+:g
-W:0
-
N:57:The Museum
A:0:0:59:0:3:0
O:0:0:0:0
diff --git a/lib/mods/theme/edit/t_basic.txt b/lib/mods/theme/edit/t_basic.txt
deleted file mode 100644
index 8153f6fe..00000000
--- a/lib/mods/theme/edit/t_basic.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-D:######################################################################################################################################################################################################
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:# #
-D:###################################################################################################################################################################################################### \ No newline at end of file
diff --git a/lib/mods/theme/edit/t_gondol.txt b/lib/mods/theme/edit/t_gondol.txt
index 6b0a32cd..66807868 100644
--- a/lib/mods/theme/edit/t_gondol.txt
+++ b/lib/mods/theme/edit/t_gondol.txt
@@ -123,9 +123,6 @@ F:m:74:3:0:0:0:0:0:37
# Thunderlord's Hide
F:n:74:3:0:0:0:0:0:22
-# Merchant guild
-F:o:74:3:0:0:0:0:0:56
-
# Force elven monsters
f:ELVEN
@@ -178,7 +175,7 @@ D:######$$$$$$$$$$$$$$$$$### ...
D:######$$$$$$$$$$$$$$$$$$## ... OC##T.V#######V...........TTTT#######TTTT..................TT####CO---,--TTT##TTT----TTT##TTTTTT------,,,,,^^^^###
D:#####$$$$$$$$$$$$$$$$$$$## ######### ... ############# OCC#T.VV#####VV.............................................TTT#CCO---,---TT#TT--------TT##T-T-TT------,,,,^^^^###
D:#####$$$$$$$#####$$$$$$$## ######### ... ############# OOC#T..VV###VV.....TTTTTTTTTTT.......TTTTTTTTTTT..............T#COO---,,,,,,,,,,,,,,,,,,,e#TT-TTT------,,,,^^^^###
-D:####$$$$#############$$$$# ########o.........7############ OC#T...VVVVV....TTT#########TTT...TTT#########TTT............T#CO---------T#TT--------TT##TTT-------,,,,^^^^^^###
+D:####$$$$#############$$$$# #########.........7############ OC#T...VVVVV....TTT#########TTT...TTT#########TTT............T#CO---------T#TT--------TT##TTT-------,,,,^^^^^^###
D:####$###################$# ######### ... ############# OC#TT..........TT###VVVVVV####TT.TT####WWWWWW###TT..........TT#CO-------TTT##TTT----TTT##TTTTT-----,,,,^^^^^^^###
D:########################## ######### ... ############# OC##T..........T##VVV....VVV###TTT###WWW....WWW##T..........T##CO------TTTTT###TTTTTT###TTTTT-----,,,,,^^^^^^^###
D:########################### ... OCC#T..........T#VV........VV#######WW........WW#T..........T#CCO-----TTTT-TTT########TTTTTT------,,,,,,,^^^^^###
diff --git a/lib/mods/theme/file/elvish.txt b/lib/mods/theme/file/elvish.txt
deleted file mode 100644
index a00b5a22..00000000
--- a/lib/mods/theme/file/elvish.txt
+++ /dev/null
@@ -1,218 +0,0 @@
-216
-******** BUFFER LINE *********************************** DO NOT REMOVE *******
-adan
-ael
-in
-agl
-ar
-aina
-alda
-al
-qua
-am
-arth
-amon
-anca
-an
-dune
-anga
-anna
-ann
-on
-ar
-ien
-atar
-band
-bar
-ad
-bel
-eg
-brag
-ol
-breth
-il
-brith
-cal
-en
-gal
-en
-cam
-car
-ak
-cel
-eb
-cor
-on
-cu
-cui
-vie
-cul
-curu
-dae
-dag
-or
-del
-din
-dol
-dor
-draug
-du
-duin
-dur
-ear
-ech
-or
-edh
-el
-eith
-elen
-er
-ereg
-es
-gal
-fal
-as
-far
-oth
-faug
-fea
-fin
-for
-men
-fuin
-gaer
-gaur
-gil
-gir
-ith
-glin
-gol
-odh
-gond
-gor
-groth
-grod
-gul
-gurth
-gwaith
-gwath
-wath
-had
-hod
-haudh
-heru
-him
-hini
-hith
-hoth
-hyar
-men
-ia
-iant
-iath
-iaur
-ilm
-iluve
-kal
-gal
-kano
-kel
-kemen
-khel
-ek
-khil
-kir
-lad
-laure
-lhach
-lin
-lith
-lok
-lom
-lome
-londe
-los
-loth
-luin
-maeg
-mal
-man
-mel
-men
-menel
-mer
-eth
-min
-as
-mir
-mith
-mor
-moth
-nan
-nar
-naug
-dil
-dur
-nel
-dor
-nen
-nim
-orn
-orod
-os
-pal
-an
-pel
-quen
-quet
-ram
-ran
-rant
-ras
-rauko
-ril
-rim
-ring
-ris
-roch
-rom
-rond
-ros
-ruin
-ruth
-sarn
-ser
-eg
-sil
-sir
-sul
-tal
-dal
-tal
-ath
-tar
-tath
-ar
-taur
-tel
-thal
-thang
-thar
-thaur
-thin
-thol
-thon
-thor
-on
-til
-tin
-tir
-tol
-tum
-tur
-uial
-ur
-val
-wen
-wing
-yave
diff --git a/lib/mods/theme/help/advanced.hlp b/lib/mods/theme/help/advanced.hlp
index 3f6fe4bd..8595712b 100644
--- a/lib/mods/theme/help/advanced.hlp
+++ b/lib/mods/theme/help/advanced.hlp
@@ -7,9 +7,8 @@ Please choose one of the following help files:
*****/aoption.txt*0[(a) Options]
*****/bmacrofaq.txt*0[(b) Macros]
*****/cautomat.txt*0[(c) Automatizer help]
- (d) Lua scripting help - coming soon
- *****/edebug.txt*0[(e) Debug commands]
- *****/fversion.txt*0[(f) Version information] A history of ToME's roots
+ *****/ddebug.txt*0[(d) Debug commands]
+ *****/eversion.txt*0[(e) Version information] A history of ToME's roots
*****/zhelp.hlp*0[(z) Main Help menu]
diff --git a/lib/mods/theme/help/c_merch.txt b/lib/mods/theme/help/c_merch.txt
deleted file mode 100644
index 31fb60dd..00000000
--- a/lib/mods/theme/help/c_merch.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-#####R=== Merchants ===
-
-#####GDescription
-A Merchant is neither a warrior nor a spellcaster. They still have some great
-advantages, they can use chests to warp items into other items, they can
-indentify items, they soon learn to detect all objects in the area, and
-at higher level they can see all monsters carrying objects. They will also
-get the power to appraise items and to turn them into gold. A merchant will
-naturraly get better prices in shops and get access to the merchant guild
-services, loan and item request.
-
-#####GPrimary Stats
-Charisma
-Intelligence (Ability stat)
-
-#####GMagic Usage
-Merchants can use portable holes to carry more stuff than other classes but
-at the cost of an increased weight. To do that they must wear a portable hole
-and use it with 'm'.
-They also can use their merchants abilities and midas touch in the 'U' menu.
-
-#####GStarting Equipment
-A merchant begins the game with:
- A portable hole
- A small steel chest containing gold and items
- A long sword
- A wand of tame monsters
-
-
diff --git a/lib/mods/theme/help/command.txt b/lib/mods/theme/help/command.txt
index 2c2f1646..ee58a77e 100644
--- a/lib/mods/theme/help/command.txt
+++ b/lib/mods/theme/help/command.txt
@@ -137,7 +137,7 @@ that you can always, for example, use "\" + "." + "6", to specify "run east".
*****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit]
*****command.txt*76[. Run] ^Y (unused)
*****command.txt*77[> Go down staircase] ^Z (special - borg command)
- *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies]
+ *****command.txt*79[\ (special - bypass keymap)]
*****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge]
*****command.txt*83[/ Identify symbol] *****command.txt*84[? Help]
*****command.txt*98[^\] Take an html screenshot]
@@ -198,13 +198,13 @@ that you can always, for example, use "\" + "." + "6", to specify "run east".
*****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit]
*****command.txt*72[. Stay still (with pickup)] *****command.txt*95[^Y (tunnel - north west)]
*****command.txt*77[> Go down staircase] ^Z (special - borg command)
- *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies]
+ *****command.txt*79[\ (special - bypass keymap)]
*****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge]
*****command.txt*83[/ Identify symbol] *****command.txt*84[? Help]
~~~~~102|Commands|Special keys
#####R=== Special Keys ===
-
+
Certain special keys may be intercepted by the operating system or
the host machine, causing unexpected results. In general, these special keys
are control keys, and often, you can disable their special effects.
@@ -498,12 +498,7 @@ for a quantity will convert any "letters" into the maximal legal value.
each corresponding to a different location on the body, and each of
which may contain only a single object at a time, and each of which
may only contain objects of the proper "type".
- If the option "show_labels" is set, the slots are labelled as follows:
- Wielding (weapon), Shooting (missile launcher or instruments),
- On finger (ring), Around neck (amulet), Light source (light source),
- On body (armor), About body (cloak), On arm (shield), On head (helmet),
- On hands (gloves), On feet (boots), Carrying (symbiote), Quiver (ammo),
- Using (tool). You must be using an object to receive any of its special
+ You must be using an object to receive any of its special
powers.
~~~~~7
[[[[[GDrop an item (d)]
@@ -518,8 +513,7 @@ for a quantity will convert any "letters" into the maximal legal value.
[[[[[GDestroy an item (k) or Destroy an item (^D)]
This destroys an item in your inventory or on the dungeon floor.
If the selected pile contains multiple objects, you may specify
- a quantity. You must always verify this command, unless the item
- is cursed or worthless and the option "auto_destroy" is set.
+ a quantity. You must always verify this command.
~~~~~42
[[[[[GWear/Wield equipment (w)]
To wear or wield an object in your inventory, use this command.
@@ -1215,17 +1209,6 @@ for a quantity will convert any "letters" into the maximal legal value.
command allows the player to force the game to finish the current song
and move on to another one (i.e. if you are tired of hearing the current
song, you can change it).
-~~~~~80
-[[[[[GDo cmovies (|)]
- The cmovie command (press | key in both normal or roguelike set) allows
- you to make a "movie" that you can send to people showing your movement
- through a part of the dungeon (like clearing that GCV . . .)
-
- It asks for a name (it will add the extension itself) and then if you wish
- to play or record it.
-
- The cmovie files (.cmv) are located in lib/cmov, note that they quickly
- become huge and so you REALLY should compress them before sending to friends.
~~~~~97
[[[[[GRecord macros ($)]
This is an easier way to create macros. Activate it, press the key
diff --git a/lib/mods/theme/help/defines.txt b/lib/mods/theme/help/defines.txt
index ac997501..13609658 100644
--- a/lib/mods/theme/help/defines.txt
+++ b/lib/mods/theme/help/defines.txt
@@ -66,7 +66,6 @@ TV_BOOK 111 /* spell books */
~~~~~12|Svals
/* The "sval" codes for TV_TOOL */
SV_TOOL_CLIMB 0
- SV_PORTABLE_HOLE 1
~~~~~16
/* The "sval" codes for TV_SHOT/TV_ARROW/TV_BOLT */
SV_AMMO_LIGHT 0 /* pebbles */
diff --git a/lib/mods/theme/help/lua.hlp b/lib/mods/theme/help/lua.hlp
deleted file mode 100644
index ba61676a..00000000
--- a/lib/mods/theme/help/lua.hlp
+++ /dev/null
@@ -1,34 +0,0 @@
-|||||oy
-~~~~~01|Help|Lua scripting for ToME
-#####R Welcome to the ToME Lua Help System.
-#####R=============================================
-
-Please choose one of the following help files:
-
- *****/alua_intr.txt*0[(a) An Introduction to scripting]
- *****/blua_pow.txt*0[(b) Adding a racial power (the 'U' menu)]
- *****/clua_skil.txt*0[(c) Adding new skills (the 'm' menu)]
- *****/dlua_ques.txt*0[(d) Adding a quest]
-
-
- *****/elua_mon.txt*0[(e) Useful functions in monster.pkg]
- *****/flua_play.txt*0[(f) Useful functions in player.pkg]
- *****/glua_spel.txt*0[(g) Useful functions in spell.pkg]
- *****/hlua_util.txt*0[(h) Useful functions in util.pkg]
-
- *****/ilua_gf.txt*0[(g) A list of GF_FOO flags]
-
-
- *****/zhelp.hlp*0[(z) Main Help menu]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/mods/theme/help/lua_gf.txt b/lib/mods/theme/help/lua_gf.txt
deleted file mode 100644
index 000f4af5..00000000
--- a/lib/mods/theme/help/lua_gf.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-|||||oy
-#####R /--------------------------\
-#####R< A partial list of GF_FLAGS >
-#####R \--------------------------/
-
-GF_ARROW: arrows
-GF_MISSILE: magic missiles
-GF_MANA: mana
-GF_LITE_WEAK: light
-GF_DARK_WEAK: dark
-GF_WATER: water
-GF_PLASMA: plasma
-GF_METEOR: meteors
-GF_ICE: ice
-GF_GRAVITY: gravity
-GF_INERTIA: inertia
-GF_FORCE: force
-GF_TIME: pure time
-GF_ACID: acid
-GF_ELEC: lightning
-GF_FIRE: flames
-GF_COLD: cold
-GF_POIS: poison
-GF_LITE: pure light
-GF_DARK: pure dark
-GF_CONFUSION: confusion
-GF_SOUND: sound
-GF_SHARDS: shards
-GF_NEXUS: nexus
-GF_NETHER: nether
-GF_CHAOS: chaos
-GF_DISENCHANT: disenchantment
-GF_KILL_WALL: wall destruction
-GF_KILL_DOOR: door destruction
-GF_KILL_TRAP: trap destruction
-GF_STONE_WALL: wall creation
-GF_MAKE_DOOR: door creation
-GF_MAKE_TRAP: trap creation
-GF_DESTRUCTION: destruction
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
-
-
diff --git a/lib/mods/theme/help/lua_intr.txt b/lib/mods/theme/help/lua_intr.txt
deleted file mode 100644
index ccb87067..00000000
--- a/lib/mods/theme/help/lua_intr.txt
+++ /dev/null
@@ -1,133 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Scripting for ToME with lua >
-#####R \----------------------------------------/
-
-So, you want to patch ToME eh? Maybe you've had a look at how the edit files
-work, maybe even added your own race/class, but want to go further and add
-new racial (U) or magic (m) powers. Well these help files will show a little
-bit of how to do that.
-
-I am not a master at this kind of thing. I wrote a small script, with much
-help from DarkGod, and he subsequently asked me to write these help files. I
-was looking forward to when the lua help files came out so that I could look
-at them myself. Little did I know I'd be asked to write them. Therefore I
-apologise for any inaccuracies or errors that you find, and if you care to let
-me know of any improvements which could be made (especially if you're an
-experienced programmer/scripter), I'd love to know. Email me at
-[[[[[gfearoffours@moppy.co.uk].
-
-#####R=== The example scripts ===
-
-These help files take the form of a tutorial, adding a line at a time to a
-script, and explaining important concepts along the way. To see it all in
-action, I strongly suggest that you download my example script pack from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm]. As well as including all the
-scripts covered in these help files, they also include the addition of my
-"hina" race which has a Lua scripted racial power which you might like to look
-at. There's also a quest which I will be including documentation for as a
-tutorial soon. Plus there's all the other lua scripts in the lib\scpt
-directory to look at. Most of what you see in these files has been learned from
-those files anyway!
-
-The source code is invaluable as well. There's a searchable and browsable
-version of the latest ToME source code available online at
-[[[[[Ghttp://www.t-o-m-e.net/cvs.php]. Use it!
-
-If you don't want to download and install the example scripts, then just
-follow the tutorials with a text editor open! But I'll say it again, it's a lot
-easier if you download and install the example scripts.
-
-This file goes on to explain the concepts of scripting, programming,
-variables and functions. If you're familiar with these concepts, you might
-as well take a look at how to add a power to the U menu in the
-*****lua_pow.txt*0[Scripting a racial power] file.
-
-
-#####R=== Defining some basic stuff ===
-
-Computers don't do anything that they're not told to do. When we script, or
-program, we must assume they know nothing. We have to tell them each little
-bit of information from the ground up.
-
-A program, or a script (we'll talk about exact differences later) is like a
-set of instructions. Let's imagine that people responded to programs, and
-that we had a program called "Housework". Its series of instructions might
-look something like this:
-
-#####BDo the Washing up.
-#####BClean the kitchen.
-#####BDust the shelves.
-#####BHoover the lounge.
-
-Each step above could be called a function, as they are all actions that
-need to be carried out. Now to you and me, we'd understand that program just
-fine, but if someone didn't know HOW to wash, or what hoovering was, they'd
-soon run into problems. For those people we'd need to define each function
-clearly. Thus "do the washing up" might be -
-
-#####BRun hot water into bowl.
-#####BAdd washing up liquid.
-#####BPut dirty plates into bowl
-#####BScrub plates till clean
-#####BPlace clean plates on rack to dry,
-
-There's still plenty of problems here though. We've not said to turn the tap
-off, or what the bowl is, or to wash any dirty cutlery, mugs, saucepans, etc.,
-etc. Whilst this might seem fairly obvious to a person, this is how we need
-to think when writing programs for computers.
-
-Lets look now at some of the terms we're going to be using, in the rest of
-these help files, and what they mean...
-
-#####R=== Variables and Constants ===
-A variable is a way to store information in a computer. Just as you store
-things in your own memory, you can store things in the computer's memory. And
-just as things change in your memory, so things can change in the computer's
-memory. This factor of change is why they're called "variables" and not
-"statics".
-
-For instance, you may have a friend's email address committed to memory, but
-things change over time, they get a new ISP or domain, and so their email
-address changes. You commit this new address to memory, and eventually
-forget the old one. The thing you have stored in your memory is the same
-(your friend's address) but the value (property) of what you have stored has
-changed (from friend@old-address.com to friend@new-address.com).
-
-Variables are the building blocks out of which you will create your patch.
-
-A variable which will *never* change its value is called a constant.
-
-#####R===Functions===
-
-A function is a series of steps or statements, grouped together and given
-one name. When you want to carry out those steps, you simply ask the
-computer to carry out that function. To go back to our original example,
-rather than saying, "I'd like you to run some hot water into a bowl, add the
-washing up liquid, put the dirty plates into it, and then scrub them till
-they're clean", we just say "do the washing up".
-
-This is where we come to the difference between scripting and programming.
-With scripting we can use the functions and variables that exist in the
-ToME code. Maintainers like DarkGod have already made sure that the
-computer knows how to "do the washing up", including turning the tap off and
-what the bowl is. All we need to do in our script is say "do the washing
-up". Or to look at it in a more relevant way, the game has been coded so
-that when a magic missile is fired, a bolt or beam spell with a black line
-of asterisks will be drawn in the direction indicated by the player, the
-mana of that spell will be used up, the monster will take the appropriate
-amount of damage, and so on. All we need to do in our script is say "fire a
-magic missile".
-
-As you script, you will still be designing your own functions, and
-variables, but the hardest parts have been done for you!
-
-Not every function and global variable in the source-code has been exported to
-use in your scripting. But the ones that have are easily identifiable by
-looking in any source files with the extension .pkg . Chris Hadgis has written
-some excellent documentation which outline the use of the most important
-functions in some of these files. They outline the functions from the
-
-OK, the first tutorial proper is on *****lua_pow.txt*0[adding a racial power] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/mods/theme/help/lua_mon.txt b/lib/mods/theme/help/lua_mon.txt
deleted file mode 100644
index 9bb363c0..00000000
--- a/lib/mods/theme/help/lua_mon.txt
+++ /dev/null
@@ -1,535 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < monster.pkg functions helper file >
-#####R \----------------------------------------/
-
-
-----------------------------------------------------------------------
-
-#####R=== race_info_idx ===
-
-#####GDeclaration
- extern monster_race* race_info_idx(int r_idx, int ego);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Return a (monster_race*) with the combinations of the monster
- * properties and the ego type
- */
-
-#####GDescription
-Get monster info and ego info for monster with monster index "r_idx"
-and monster ego "ego". The ego information is applied to the monster
-information and the new monster information is returned.
-
-For example, race_info_idx(141,7) will create a brown yeek (monster)
-shaman (ego).
-
-#####GParameters
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-
-----------------------------------------------------------------------
-
-#####R=== delete_monster_idx ===
-
-#####GDeclaration
- extern void delete_monster_idx(int i);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Delete a monster by index.
- *
- * When a monster is deleted, all of its objects are deleted.
- */
-
-#####GDescription
-Delete monster "i" from the monster array.
-
-#####GParameters
-> "i" is the index for the monster list (m_list[]). Beware: there is
- no range checking.
-
-----------------------------------------------------------------------
-
-#####R=== m_pop ===
-
-#####GDeclaration
- extern s16b m_pop(void);
-
-#####GFile
- monsters2.c
-
-#####GComment
-/*
- * Acquires and returns the index of a "free" monster.
- *
- * This routine should almost never fail, but it *can* happen.
- */
-
-#####GDescription
-Get an empty slot in the monster list (m_list[]). If there are no
-empty slots, a slot will be reclaimed from a "dead" monster. If all
-slots are full, 0 is returned, which means the function has failed
-("Too many monsters!").
-
-----------------------------------------------------------------------
-
-#####R=== get_mon_num_prep ===
-
-#####GDeclaration
- extern errr get_mon_num_prep(void);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Apply a "monster restriction function" to the "monster allocation table"
- */
-
-#####GDescription
-There are no parameters, but there are some other variables which will
-need to be set. They are get_mon_num_hook and get_mon_num2_hook. They
-are pointers to functions.
-
-For example, get_mon_num_hook = monster_volcano means when
-get_mon_num_hook is called (*get_mon_num_hook)(index), the actual
-function called is monster_volcano(index). This particular function
-returns TRUE if the monster indicated by "index" has the
-RF8_WILD_VOLCANO flag set.
-
-It is a good idea to store the old value of get_mon_num_hook before
-setting a new one, and restoring it when your function is finished.
-
-Following is a list of functions which can be assigned to
-get_mon_num_hook:
-
-create_molds_hook
-create_townpeople_hook
-mon_hook_bounty
-monster_dungeon
-monster_grass
-monster_mountain
-monster_ocean
-monster_quest
-monster_shore
-monster_town
-monster_volcano
-monster_waste
-monster_wood
-mutate_monster_okay
-place_monster_okay
-summon_specific_okay
-vault_aux_animal
-vault_aux_chapel
-vault_aux_clone
-vault_aux_demon
-vault_aux_dragon
-vault_aux_giant
-vault_aux_jelly
-vault_aux_kennel
-vault_aux_orc
-vault_aux_symbol
-vault_aux_treasure
-vault_aux_troll
-vault_aux_undead
-
-Or you can write your own. The function must take an integer (index)
-as a parameter and return boolean (TRUE if the monster is selected,
-or FALSE if it is not).
-
-----------------------------------------------------------------------
-
-#####R=== get_mon_num ===
-
-#####GDeclaration
- extern s16b get_mon_num(int level);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Choose a monster race that seems "appropriate" to the given level
- *
- * This function uses the "prob2" field of the "monster allocation table",
- * and various local information, to calculate the "prob3" field of the
- * same table, which is then used to choose an "appropriate" monster, in
- * a relatively efficient manner.
- *
- * Note that "town" monsters will *only* be created in the town, and
- * "normal" monsters will *never* be created in the town, unless the
- * "level" is "modified", for example, by polymorph or summoning.
- *
- * There is a small chance (1/50) of "boosting" the given depth by
- * a small amount (up to four levels), except in the town.
- *
- * It is (slightly) more likely to acquire a monster of the given level
- * than one of a lower level. This is done by choosing several monsters
- * appropriate to the given level and keeping the "hardest" one.
- *
- * Note that if no monsters are "appropriate", then this function will
- * fail, and return zero, but this should *almost* never happen.
- */
-
-Description:
-For the given level "level", return the index of an appropriate
-monster race.
-
-#####GParameters
-> "level" is a dungeon level
-
-----------------------------------------------------------------------
-
-#####R=== monster_desc ===
-
-#####GDeclaration
- extern void monster_desc(char *desc, monster_type *m_ptr,
- int mode);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Build a string describing a monster in some way.
- *
- * We can correctly describe monsters based on their visibility.
- * We can force all monsters to be treated as visible or invisible.
- * We can build nominatives, objectives, possessives, or reflexives.
- * We can selectively pronominalize hidden, visible, or all monsters.
- * We can use definite or indefinite descriptions for hidden monsters.
- * We can use definite or indefinite descriptions for visible monsters.
- *
- * Pronominalization involves the gender whenever possible and allowed,
- * so that by cleverly requesting pronominalization / visibility, you
- * can get messages like "You hit someone. She screams in agony!".
- *
- * Reflexives are acquired by requesting Objective plus Possessive.
- *
- * If no m_ptr arg is given (?), the monster is assumed to be hidden,
- * unless the "Assume Visible" mode is requested.
- *
- * If no r_ptr arg is given, it is extracted from m_ptr and r_info
- * If neither m_ptr nor r_ptr is given, the monster is assumed to
- * be neuter, singular, and hidden (unless "Assume Visible" is set),
- * in which case you may be in trouble... :-)
- *
- * I am assuming that no monster name is more than 70 characters long,
- * so that "char desc[80];" is sufficiently large for any result.
- *
- * Mode Flags:
- * 0x01 --> Objective (or Reflexive)
- * 0x02 --> Possessive (or Reflexive)
- * 0x04 --> Use indefinites for hidden monsters ("something")
- * 0x08 --> Use indefinites for visible monsters ("a kobold")
- * 0x10 --> Pronominalize hidden monsters
- * 0x20 --> Pronominalize visible monsters
- * 0x40 --> Assume the monster is hidden
- * 0x80 --> Assume the monster is visible
- *
- * Useful Modes:
- * 0x00 --> Full nominative name ("the kobold") or "it"
- * 0x04 --> Full nominative name ("the kobold") or "something"
- * 0x80 --> Genocide resistance name ("the kobold")
- * 0x88 --> Killing name ("a kobold")
- * 0x22 --> Possessive, genderized if visible ("his") or "its"
- * 0x23 --> Reflexive, genderized if visible ("himself") or "itself"
- */
-
-#####GDescription
-Return a monster description "desc" for monster "monster_type" using
-flag "mode". The modes are described above.
-
-#####GParameters
-> "desc" is the returned description.
-> "monster type" is the monster (monster pointer).
-> "mode" is one of the modes described in the comments.
-
-----------------------------------------------------------------------
-
-#####R=== monster_race_desc ===
-
-#####GDeclaration
- extern void monster_race_desc(char *desc, int r_idx,
- int ego);
-
-#####GFile
- monster2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the monster description "desc" for monster with monster index
-"r_idx" and monster ego "ego". The monster description is made up of
-the ego name (if any) and monster name, or the unique name.
-
-#####GParameters
-> "desc" is the returned description.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-
-----------------------------------------------------------------------
-
-#####R=== place_monster_aux ===
-
-#####GDeclaration
- extern bool place_monster_aux(int y, int x, int r_idx,
- bool slp, bool grp, int status);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Attempt to place a monster of the given race at the given location
- *
- * Note that certain monsters are now marked as requiring "friends".
- * These monsters, if successfully placed, and if the "grp" parameter
- * is TRUE, will be surrounded by a "group" of identical monsters.
- *
- * Note that certain monsters are now marked as requiring an "escort",
- * which is a collection of monsters with similar "race" but lower
- * level.
- *
- * Some monsters induce a fake "group" flag on their escorts.
- *
- * Note the "bizarre" use of non-recursion to prevent annoying output
- * when running a code profiler.
- *
- * Note the use of the new "monster allocation table" code to restrict
- * the "get_mon_num()" function to "legal" escort types.
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster has monster
-index "m_idx". The monster may be asleep ("slp"). The monster may be
-surrounded by a group of identical monsters ("grp"). The monster has
-a status of "status" (see below). The function returns TRUE if the
-monster is placed successfully, otherwise FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "grp" is TRUE if the monster is surrounded by a group, otherwise
- FALSE.
-> "status" is the status of the monster
- *****fields.txt*0[status]
-
-----------------------------------------------------------------------
-
-#####R=== place_monster ===
-
-#####GDeclaration
- extern bool place_monster(int y, int x, bool slp,
- bool grp);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Hack -- attempt to place a monster at the given location
- *
- * Attempt to find a monster appropriate to the "monster_level"
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster may be asleep
-("slp"). The monster may be surrounded by a group of identical
-monsters ("grp"). The monster is of the appropriate monster level. The
-function returns TRUE if the monster is placed successfully, otherwise
-FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "grp" is TRUE if the monster is surrounded by a group, otherwise
- FALSE.
-
-----------------------------------------------------------------------
-
-#####R=== place_monster_one ===
-
-#####GDeclaration
- extern s16b place_monster_one(int y, int x, int r_idx,
- int ego, bool slp, int status);
-
-#####GFile
- monster2.c
-
-#####GComment
-/*
- * Attempt to place a monster of the given race at the given location.
- *
- * To give the player a sporting chance, any monster that appears in
- * line-of-sight and is extremely dangerous can be marked as
- * "FORCE_SLEEP", which will cause them to be placed with low energy,
- * which often (but not always) lets the player move before they do.
- *
- * This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.
- *
- * XXX XXX XXX Use special "here" and "dead" flags for unique monsters,
- * remove old "cur_num" and "max_num" fields.
- *
- * XXX XXX XXX Actually, do something similar for artifacts, to simplify
- * the "preserve" mode, and to make the "what artifacts" flag more useful.
- *
- * This is the only function which may place a monster in the dungeon,
- * except for the savefile loading code.
- */
-
-#####GDescription
-Attempt to place a monster at grid "y", "x". The monster has monster
-index "m_idx". The monster may be asleep ("slp"). The monster may have
-an ego type ("ego"). The monster has a status of "status" (see below).
-The function returns TRUE if the monster is placed successfully,
-otherwise FALSE.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
- range checking.
-> "slp" is TRUE if the monster is asleep, otherwise FALSE.
-> "ego" is an entry from the "re_info.txt". Beware: there is no range
- checking.
-> "status" is the status of the monster
- *****fields.txt*0[status]
-
-----------------------------------------------------------------------
-
-#####R=== is_friend ===
-
-#####GDeclaration
- extern int is_friend(monster_type *m_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-/*
- * Is the monster in friendly state(pet, friend, ..)
- * -1 = enemy, 0 = neutral, 1 = friend
- */
-
-#####GDescription
-Return a value to indicate the status of monster "m_ptr".
- *****fields.txt*0[status]
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-
-----------------------------------------------------------------------
-
-#####R=== is_enemy ===
-
-#####GDeclaration
- extern bool is_enemy(monster_type *m_ptr,
- monster_type *t_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-/* Should they attack each others */
-
-#####GDescription
-Return TRUE if monster "m_ptr" should attack monster "t_ptr". If
-"m_ptr" is stupid and "r_ptr" is a different type of monster then the
-function will return TRUE. If "m_ptr" is not neutral and "r_ptr" is a
-breeder, and "r_ptr" is a different type of monster then the function
-will return TRUE (and vice versa). If both monsters are not neutral
-and one is friendly and the other isn't then the function will return
-TRUE. Otherwise the function returns FALSE.
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-> "t_ptr" is a pointer to a monster (target).
-
-----------------------------------------------------------------------
-
-#####R=== change_side ===
-
-#####GDeclaration
- extern bool change_side(monster_type *m_ptr);
-
-#####GFile
- monster3.c
-
-#####GComment
-(none)
-
-#####GDescription
-Change the status of monster "m_ptr" from friendly to unfriendly and
-vice versa. Friends and pets become enemies. Neutral Ms become
-neutral Ps and vice versa. Companions are unaffected. The
-function returns TRUE if the status changed, otherwise FALSE.
-
-#####GParameters
-> "m_ptr" is a pointer to a monster.
-
-----------------------------------------------------------------------
-
-#####R=== find_position ===
-
-#####GDeclaration
- extern void find_position(int y, int x, int *yy = 0,
- int *xx = 0);
-
-#####GFile
- lua_bind.c
-
-#####GComment
-(none)
-
-#####GDescription
-Find a new grid "yy", "xx" within 6 grids of target grid "y", "x".
-The new grid must be within line-of-sight of the target grid. A
-maximum of 5000 attempts is made.
-
-#####GParameters
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "yy" is the y co-ordinate of the new grid.
-> "xx" is the x co-ordinate of the new grid.
-
-----------------------------------------------------------------------
-
-#####R=== can_create_companion ===
-
-#####GDeclaration
- extern bool can_create_companion();
-
-#####GFile
- monster3.c
-
-#####GComment
-/* Returns if a new companion is allowed */
-
-#####GDescription
-Return TRUE if a companion can be created, otherwise FALSE.
-
-----------------------------------------------------------------------
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
diff --git a/lib/mods/theme/help/lua_play.txt b/lib/mods/theme/help/lua_play.txt
deleted file mode 100644
index 6ab64ddb..00000000
--- a/lib/mods/theme/help/lua_play.txt
+++ /dev/null
@@ -1,1225 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < player.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####RFunction: set_parasite
-
-#####GDeclaration: bool set_parasite(int v, int r);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until parasite with monster index "r" is created. The
-player gets the message "You feel something growing in you" if "v"
-is > 0. Otherwise the player gets the message "Your body convulse
-and spawn <monster name>" if the monster is created (80% chance) or
-"The hideous thing growing in you seems to die" if the monster dies.
-
-#####GParameters:
->v is the time until the parasite gestates (must be between 0 and
- 10000).
->r is the monster index of parasite to be created.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_disrupt_shield
-
-#####GDeclaration: bool set_disrupt_shield(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->disrupt_shield"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until shield of invulnerability expires. The player gets
-the message "You feel invulnerable" if "v" is > 0. Otherwise the
-player gets the message "You are more vulnerable".
-
-#####GParameters:
->v is the time until the shield expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_prob_travel
-
-#####GDeclaration: bool set_prob_travel(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->prob_travel"
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until random teleportation expires. The player gets
-the message "You feel instable" if "v" is > 0. Otherwise the
-player gets the message "You are more stable".
-
-#####GParameters:
->v is the time until random teleportation expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_deadly
-
-#####GDeclaration: bool set_tim_deadly(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_deadly"
-*/
-
-#####GDescription:
-Set time "v" until deadly accuracy expires. The player gets the
-message "You feel extremely accurate" if "v" is > 0. Otherwise the
-player gets the message "You are suddenly much less accurate".
-
-#####GParameters:
->v is the time until deadly accuracy expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_res_time
-
-#####GDeclaration: bool set_tim_res_time(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_res_time"
-*/
-
-#####GDescription:
-Set time "v" until space-time distortions expire. The player gets the
-message "You are now protected against the space-time distortions" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the space-time distortions".
-
-#####GParameters:
->v is the time until space-time distortions expire (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_reflect
-
-#####GDeclaration: bool set_tim_reflect(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_reflect"
-*/
-
-#####GDescription:
-Set time "v" until reflection expire. The player gets the message
-"You start reflecting the world around you" if "v" is > 0. Otherwise
-the player gets the message "You stop reflecting".
-
-#####GParameters:
->v is the time until reflection expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_meditation
-
-#####GDeclaration: bool set_meditation(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->meditation"
-*/
-
-#####GDescription:
-Set time "v" until meditation expire. The player gets the message
-"You start meditating on yourself" if "v" is > 0. Otherwise the
-player gets the message "You stop your self meditation".
-
-#####GParameters:
->v is the time until meditation expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_strike
-
-#####GDeclaration: bool set_strike(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->strike"
-*/
-
-#####GDescription:
-Set time "v" until accurate strikes expire. The player gets the
-message "You feel very accurate" if "v" is > 0. Otherwise the player
-gets the message "You are no longer very accurate".
-
-#####GParameters:
->v is the time until accurate strikes expire (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_walk_water
-
-#####GDeclaration: bool set_walk_water(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->walk_water", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until walking on water expires. The player gets the
-message "You feel strangely insubmersible" if "v" is > 0. Otherwise
-the player gets the message "You are no longer insubmersible".
-
-#####GParameters:
->v is the time until walking on water expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_ffall
-
-#####GDeclaration: bool set_tim_ffall(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_ffall"
-*/
-
-#####GDescription:
-Set time "v" until feather-fall expires. The player gets the message
-"You feel very light" if "v" is > 0. Otherwise the player gets the
-message "You are suddenly heavier".
-
-#####GParameters:
->v is the time until feather-fall expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_fire_aura
-
-#####GDeclaration: bool set_tim_fire_aura(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_fire_aura"
-*/
-
-#####GDescription:
-Set time "v" until fiery aura expires. The player gets the message
-"You are enveloped in flames" if "v" is > 0. Otherwise the player
-gets the message "You are no longer enveloped in flames".
-
-#####GParameters:
->v is the time until fiery aura expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_holy
-
-#####GDeclaration: bool set_holy(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->holy", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until holiness expires. The player gets the message
-"You feel a holy aura around you" if "v" is > 0. Otherwise the
-player gets the message "The holy aura vanishes".
-
-#####GParameters:
->v is the time until holiness expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_grace
-
-#####GDeclaration: void set_grace(s32b v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->grace", notice observable changes
-*/
-
-#####GDescription:
-Set grace to value "v". Don't allow grace to fall below -30000 or
-rise above 30000.
-
-#####GParameters:
->v is the value of grace.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_mimic
-
-#####GDeclaration: bool set_mimic(int v, int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_mimic", and "p_ptr->mimic_form",
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until morph into monster with monster index "p" expires.
-The player gets the message "You feel your body change" if "v" is > 0.
-Otherwise the player gets the message "You are no longer transformed".
-
-#####GParameters:
->v is the time until transformation expires (must be between 0 and
- 10000).
->p is the monster index of the monster the player wants to mimic.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_no_breeders
-
-#####GDeclaration: bool set_no_breeders(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "no_breeds"
-*/
-
-#####GDescription:
-Set time "v" until breeders can breed again. The player gets the
-message "You feel an anti-sexual aura" if "v" is > 0. Otherwise the
-player gets the message "You no longer feel an anti-sexual aura".
-Okay...
-
-#####GParameters:
->v is the time until breeders can breed again (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_invis
-
-#####GDeclaration: bool set_invis(int v,int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow",
-* notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until invisibility expires. The player gets the message
-"You feel your body fade away" if "v" is > 0. Otherwise the player
-gets the message "You are no longer invisible".
-
-#####GParameters:
->v is the time until invisibility expires (must be between 0 and
- 10000).
->p is the power of timed invisibility.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_lite
-
-#####GDeclaration: bool set_lite(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_lite", notice observable changes
-*
-* Note the use of "PU_VIEW", which is needed to
-* memorise any terrain features which suddenly become "visible".
-* Note that blindness is currently the only thing which can affect
-* "player_can_see_bold()".
-*/
-
-#####GDescription:
-Set time "v" until brightness expires. The player gets the message
-"You suddenly seem brighter" if "v" is > 0. Otherwise the player
-gets the message "You are no longer bright".
-
-#####GParameters:
->v is the time until brightness expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_blind
-
-#####GDeclaration: bool set_blind(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->blind", notice observable changes
-*
-* Note the use of "PU_UN_VIEW", which is needed to memorise any terrain
-* features which suddenly become "visible".
-* Note that blindness is currently the only thing which can affect
-* "player_can_see_bold()".
-*/
-
-#####GDescription:
-Set time "v" until blindness expires. The player gets the message "You
-are blind" if "v" is > 0. Otherwise the player gets the message "You
-can see again".
-
-#####GParameters:
->v is the time until blindness expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_confused
-
-#####GDeclaration: bool set_confused(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->confused", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until confusion expires. The player gets the message "You
-are confused" if "v" is > 0. Otherwise the player gets the message
-"You feel less confused now".
-
-#####GParameters:
->v is the time until confusion expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_poisoned
-
-#####GDeclaration: bool set_poisoned(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->poisoned", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until poison expires. The player gets the message "You
-are poisoned" if "v" is > 0. Otherwise the player gets the message
-"You are no longer poisoned".
-
-#####GParameters:
->v is the time until poison expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_afraid
-
-#####GDeclaration: bool set_afraid(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->afraid", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until fear expires. The player gets the message "You are
-terrified" if "v" is > 0. Otherwise the player gets the message "You
-feel bolder now".
-
-#####GParameters:
->v is the time until fear expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_paralyzed
-
-#####GDeclaration: bool set_paralyzed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->paralyzed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until paralysis expires. The player gets the message "You
-are paralyzed" if "v" is > 0. Otherwise the player gets the message
-"You can move again".
-
-#####GParameters:
->v is the time until paralysis expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_image
-
-#####GDeclaration: bool set_image(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->image", notice observable changes
-*
-* Note that we must redraw the map when hallucination changes.
-*/
-
-#####GDescription:
-Set time "v" until hallucination expires. The player gets the message
-"Oh, wow! Everything looks so cosmic now" if "v" is > 0. Otherwise
-the player gets the message "You can see clearly again".
-
-#####GParameters:
->v is the time until hallucination expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_fast
-
-#####GDeclaration: bool set_fast(int v, int p);
-
-#####GFile: xtra2.c
-
-#####GComment:
-(none)
-
-#####GDescription:
-Set time "v" until speed of speed factor "p" expires. The player gets
-the message "You feel yourself moving faster" if "v" is > 0. Otherwise
-the player gets the message "You feel yourself slow down".
-
-#####GParameters:
->v is the time until speed expires (must be between 0 and 10000).
->p is the speed factor.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_light_speed
-
-#####GDeclaration: bool set_light_speed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->lightspeed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until light-speed expires. The player gets the message
-"You feel as if time has stopped" if "v" is > 0. Otherwise the player
-gets the message "You feel time returning to its normal rate".
-
-#####GParameters:
->v is the time until light-speed expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_slow
-
-#####GDeclaration: bool set_slow(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->slow", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until slowness expires. The player gets the message "You
-feel yourself moving slower" if "v" is > 0. Otherwise the player gets
-the message "You feel yourself speed up".
-
-#####GParameters:
->v is the time until slowness expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_shield
-
-#####GDeclaration: bool set_shield(int v, int p, s16b o, s16b d1, s16b d2);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->shield", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until stone-shield expires. The player gets the message
-"Your skin turns to stone" if "v" is > 0. Otherwise the player gets
-the message "Your skin returns to normal". Stone-shield has spell
-power "p", spell option "o", and power options "d1" and "d2".
-
-#####GParameters:
->v is the time until stone-shield expires (must be between 0 and
- 10000).
->p is the power of the stone-shield spell.
->o is the option of the stone-shield spell.
->d1 is the power for option 1 of the stone-shield spell.
->d2 is the power for option 2 of the stone-shield spell.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_blessed
-
-#####GDeclaration: bool set_blessed(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->blessed", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until blessing expires. The player gets the message "You
-feel righteous" if "v" is > 0. Otherwise the player gets the message
-"The prayer has expired".
-
-#####GParameters:
->v is the time until blessing expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_hero
-
-#####GDeclaration: bool set_hero(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->hero", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until heroism expires. The player gets the message "You
-feel like a hero" if "v" is > 0. Otherwise the player gets the
-message "The heroism wears off".
-
-#####GParameters:
->v is the time until heroism expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_shero
-
-#####GDeclaration: bool set_shero(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->shero", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until berserk expires. The player gets the message "You
-feel like a killing machine" if "v" is > 0. Otherwise the player gets
-the message "You feel less Berserk".
-
-#####GParameters:
->v is the time until berserk expires (must be between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protevil
-
-#####GDeclaration: bool set_protevil(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protevil", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from evil expires. The player gets the
-message "You feel safe from evil" if "v" is > 0. Otherwise the player
-gets the message "You no longer feel safe from evil".
-
-#####GParameters:
->v is the time until protection from evil expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protgood
-
-#####GDeclaration: bool set_protgood(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protgood", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from good expires. The player gets the
-message "You feel safe from good" if "v" is > 0. Otherwise the player
-gets the message "You no longer feel safe from good".
-
-#####GParameters:
->v is the time until protection from evil expires (must be between 0
- and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_protundead
-
-#####GDeclaration: bool set_protundead(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->protundead", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until protection from undead expires. The player gets the
-message "You feel safe from undead" if "v" is > 0. Otherwise the
-player gets the message "You no longer feel safe from undead".
-
-#####GParameters:
->v is the time until protection from undead expires (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_invuln
-
-#####GDeclaration: bool set_invuln(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->invuln", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until invulnerability expires. The player gets the
-message "Invulnerability" if "v" is > 0. Otherwise the player gets
-the message "The invulnerability wears off".
-
-#####GParameters:
->v is the time until invulnerability expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_invis
-
-#####GDeclaration: bool set_tim_invis(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_invis", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until see invisible expires. The player gets the message
-"Your eyes feel very sensitive" if "v" is > 0. Otherwise the player
-gets the message "Your eyes feel less sensitive".
-
-#####GParameters:
->v is the time until see invisible expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_tim_infra
-
-#####GDeclaration: bool set_tim_infra(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_infra", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until infravision expires. The player gets the message
-"Your eyes begin to tingle" if "v" is > 0. Otherwise the player gets
-the message "Your eyes stop tingling".
-
-#####GParameters:
->v is the time until infravision expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_mental_barrier
-
-#####GDeclaration: bool set_mental_barrier(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->tim_mental_barrier", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until mental barrier expires. The player gets the message
-"Your mind grows stronger" if "v" is > 0. Otherwise the player gets
-the message "Your mind is no longer especially strong".
-
-#####GParameters:
->v is the time until mental barrier expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_acid
-
-#####GDeclaration: bool set_oppose_acid(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-
-#####GDescription:
-Set time "v" until feather-fall expires. The player gets the message
-"You feel very light" if "v" is > 0. Otherwise the player gets the
-message "You are suddenly heavier".
-
-#####GParameters:
->v is the time until feather-fall expires (must be between 0 and
- 10000).
->v is the time until feather-fall expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_elec
-
-#####GDeclaration: bool set_oppose_elec(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_elec", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until electricity resistance expires. The player gets
-the message "You feel resistant to electricity" if "v" is > 0.
-Otherwise the player gets the message "You feel less resistant to
-electricity".
-
-#####GParameters:
->v is the time until electricity resistance expires (must be between
- 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_fire
-
-#####GDeclaration: bool set_oppose_fire(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_fire", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until fire resistance expires. The player gets the
-message "You feel resistant to fire" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to fire".
-
-#####GParameters:
->v is the time until fire resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_cold
-
-#####GDeclaration: bool set_oppose_cold(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_cold", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until cold resistance expires. The player gets the
-message "You feel resistant to cold" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to cold".
-
-#####GParameters:
->v is the time until cold resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_pois
-
-#####GDeclaration: bool set_oppose_pois(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_pois", notice observable changes
-*/
-
-#####GDescription:
-Set time "v" until poison resistance expires. The player gets the
-message "You feel resistant to poison" if "v" is > 0. Otherwise the
-player gets the message "You feel less resistant to poison".
-
-#####GParameters:
->v is the time until poison resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_ld
-
-#####GDeclaration: bool set_oppose_ld(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_ld"
-*/
-
-#####GDescription:
-Set time "v" until light and dark resistance expires. The player gets
-the message "You feel protected against the light's fluctuation" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the light's fluctuation".
-
-#####GParameters:
->v is the time until light and dark resistance expires (must be
- between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_cc
-
-#####GDeclaration: bool set_oppose_cc(int v);
-
-#####GFile: xtra2.c
-/*
-* Set "p_ptr->oppose_cc"
-*/
-
-#####GComment:
-
-#####GDescription:
-Set time "v" until chaos resistance expires. The player gets the
-message "You feel protected against raw chaos" if "v" is > 0.
-Otherwise the player gets the message "You are no longer protected
-against chaos".
-
-#####GParameters:
->v is the time until chaos resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_ss
-
-#####GDeclaration: bool set_oppose_ss(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_ss"
-*/
-
-#####GDescription:
-Set time "v" until sound and shard resistance expires. The player gets
-the message "You feel protected against the ravages of sound and
-shards" if "v" is > 0. Otherwise the player gets the message "You are
-no longer protected against the ravages of sound and shards".
-
-#####GParameters:
->v is the time until sound and shard resistance expires (must be
- between 0 and 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_oppose_nex
-
-#####GDeclaration: bool set_oppose_nex(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->oppose_nex"
-*/
-
-#####GDescription:
-Set time "v" until nexus resistance expires. The player gets the
-message "You feel protected against the strange forces of nexus" if
-"v" is > 0. Otherwise the player gets the message "You are no longer
-protected against the strange forces of nexus".
-
-#####GParameters:
->v is the time until nexus resistance expires (must be between 0 and
- 10000).
-
-----------------------------------------------------------------------
-
-#####RFunction: set_stun
-
-#####GDeclaration: bool set_stun(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->stun", notice observable changes
-*
-* Note the special code to only notice "range" changes.
-*/
-
-#####GDescription:
-Set stun level "v". If the player race can't be stunned then the level
-is forced to 0. A value > 100 means the player is knocked out. A value
->50 is a heavy stun. A value > 0 is a stun. If the stun level has
-increased, a message is printed. There is a small chance of stun level
-in 1000, or a 1 in 16 chance of a vicious blow which decreases
-intelligence and/or wisdom for a while.
-
-#####GParameters:
->v is the stun level.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_cut
-
-#####GDeclaration: bool set_cut(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->cut", notice observable changes
-*
-* Note the special code to only notice "range" changes.
-*/
-
-#####GDescription:
-Set cut level "v". If the player race can't be cut then the time is
-forced to 0. A value > 1000 is a mortal wound. A value > 200 is a deep
-gash. A value > 100 is a severe cut. A value > 50 is a nasty cut. A
-value > 25 is a bad cut. A value > 10 is a light cut. A value > 0 is a
-graze. If the cut level has increased, a message is printed. There is
-a small chance of stun level in 1000, or a 1 in 16 chance of scarring
-which decreases charisma for a while.
-
-#####GParameters:
->v is the cut level.
-
-----------------------------------------------------------------------
-
-#####RFunction: set_food
-
-#####GDeclaration: bool set_food(int v);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Set "p_ptr->food", notice observable changes
-*
-* The "p_ptr->food" variable can get as large as 20000, allowing the
-* addition of the most "filling" item, Elvish Waybread, which adds
-* 7500 food units, without overflowing the 32767 maximum limit.
-*
-* Perhaps we should disturb the player with various messages,
-* especially messages about hunger status changes. XXX XXX XXX
-*
-* Digestion of food is handled in "dungeon.c", in which, normally,
-* the player digests about 20 food units per 100 game turns, more
-* when "fast", more when "regenerating", less with "slow digestion",
-* but when the player is "gorged", he digests 100 food units per 10
-* game turns, or a full 1000 food units per 100 game turns.
-*
-* Note that the player's speed is reduced by 10 units while gorged,
-* so if the player eats a single food ration (5000 food units) when
-* full (15000 food units), he will be gorged for (5000/100)*10 = 500
-* game turns, or 500/(100/5) = 25 player turns (if nothing else is
-* affecting the player speed).
-*/
-
-#####GDescription:
-Set hunger level "v". A value < 500 is fainting. A value < 1000 is
-weak. A value < 2000 is weak. A value < 10000 is full. A value
-< 15000 is bloated. A value < 20000 is gorged. If one of these
-levels is crossed a message is printed.
-
-#####GParameters:
->v is the hunger level (must be between 0 and 20000).
-
-----------------------------------------------------------------------
-
-#####RFunction: check_experience
-
-#####GDeclaration: void check_experience(void);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Advance experience levels and print experience
-*/
-
-#####GDescription:
-Check if player experience level has changed. If a player has achieved
-a level for the first time, give reward or corruption (1 chance in 3)
-if they apply, and increase skill points.
-
-----------------------------------------------------------------------
-
-#####RFunction: check_experience_obj
-
-#####GDeclaration: void check_experience_obj(object_type *o_ptr);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Advance experience levels and print experience
-*/
-
-#####GDescription:
-Check if object "o_ptr" experience level has changed. If an object has
-achieved a level for the first time, apply gains.
-
-#####GParameters:
->o_ptr is the pointer to the object gaining experience.
-
-----------------------------------------------------------------------
-
-#####RFunction: gain_exp
-
-#####GDeclaration: void gain_exp(s32b amount);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Gain experience (share it to objects if needed)
-*/
-
-#####GDescription:
-Gain "amount" of experience. Count the number of objects which will
-gain experience. The objects share equally 2/3 of "amount". Give
-corruption if it applies. Gain experience. If experience is less
-than maximum, then increase maximum experience by 20% of "amount".
-Check for level change and print experience (check_experience).
-
-#####GParameters:
->amount is the amount of experience to share.
-
-----------------------------------------------------------------------
-
-#####RFunction: lose_exp
-
-#####GDeclaration: void lose_exp(s32b amount);
-
-#####GFile: xtra2.c
-
-#####GComment:
-/*
-* Lose experience
-*/
-
-#####GDescription:
-Decrease experience by "amount". Experience can not fall below zero.
-Check for level change and print experience (check_experience).
-
-#####GParameters:
->amount is the amount of experience to lose.
-
-----------------------------------------------------------------------
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
-
-
diff --git a/lib/mods/theme/help/lua_pow.txt b/lib/mods/theme/help/lua_pow.txt
deleted file mode 100644
index c221a664..00000000
--- a/lib/mods/theme/help/lua_pow.txt
+++ /dev/null
@@ -1,266 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding new racial powers >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-You *must* download and install my lua example files from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm]. And also you should read the
-*****lua_intr.txt*0[scripting introduction] file if you haven't already done
-so.
-
-The (commented) accompanying script file for this tutorial is
-lib\scpt\pheonix.lua. Open it in your text editor!
-
-#####R=== The Racial Power ===
-
-Let's start with something simple. Let's say you wanted your new race (let's
-call it "Pheonix") to be able to cast fire balls as their racial power.
-
-#####R=== Starting off ===
-
-If you have a look at pheonix.lua you'll note the first lines are comments.
-I'll talk a bit more about comments later, but it's worth pointing out that any
-lines of text preceded by a double hyphen ([[[[[B--]) will be ignored by the
-scripting engine, and are therefore comments.
-After the comments, the first 10 lines of code are as follows:
-
-#####BPHEONIX_POWER = add_power
-#####B{
-#####B ["name"] = "Fire Breath",
-#####B ["desc"] = "You are able to cast fireballs",
-#####B ["desc_get"] = "Your beak glows red",
-#####B ["desc_lose"] = "Your beak goes cold again",
-#####B ["level"] = 10,
-#####B ["cost"] = 11,
-#####B ["stat"] = A_INT,
-#####B ["fail"] = 14,
-
-So, [[[[[BPHEONIX_POWER = add_power] is registering our power. We're giving it
-a name (PHEONIX_POWER) and saying that it is defined by calling the special
-function [[[[[Badd_power]. This special function is only used to define lua-
-scripted
-powers, and has attributes which are identified by their inclusion in square
-brackets.
-Note the following:
-- Lua is case sensitive. The name of our power is a constant, will never change
-so that's been named with capitals. variables and functions are named all in
-lower case. Technically speaking, Lua does not support constants, but we can
-emulate them by variables in this way. They don't have to be capitalised, but
-if you capitalise all your constants, it makes things easier to read, and
-you'll be following normal programming protocol.
-- There are no spaces in the name of the power. Use an underscore for spaces
-if you need to improve legibility.
-
-[[[[[B"name" = "Fire Breath",] This is the name of the power as it is
-displayed in the
-U menu, and as you will define it in p_info.txt (more about that later).
-
-[[[[[B"desc" = "You are able to cast fireballs",] This is what would
-appear in the
-information display list if you drank a potion of self knowledge or
-similar.
-
-[[[[[B"desc_get" = "Your beak glows red",] This is the information displayed
-when you
-gain this power.
-
-[[[[[B"desc_lose" = "Your beak goes cold again",] This is the information
-displayed when
-you lose this power. Eg After a mutation/corruption.
-
-[[[[[B"level" = 10,] Character level which must be gained in order to use
-power,
-
-[[[[[B"cost" = 11,] Amount of mana to cast this power.
-
-[[[[[B"stat" = A_INT,] stat which will define whether it works or not,
-
-[[[[[B"fail" = 14,] how high that stat must be.
-
-So our Pheonix will be able to cast PHEONIX_POWER from clvl 10, at a cost of
-11 mana, providing that the player's intelligence is 14 and upwards.
-
-#####R=== The function ===
-
-The next section is a lot longer, so we'll look at it line by line. I'll
-strip the comments for the purpose of this helpfile.
-
-#####B["power"] = function()
-#####B local ret, dir, damage
-#####B ret, dir = get_aim_dir();
-#####B if (ret == FALSE) then
-#####B return
-#####B end
-#####B damage = player.lev*3
-#####B msg_print("You breathe fire.")
-#####B fire_ball(GF_FIRE, dir, damage, 3)
-#####Bend,
-
-The [[[[[B"power"] bit is what actually happens when the player accesses this
-power
-from their 'U' menu. Every function must start with the word [[[[[Bfunction].
-Normally, we'd also declare its name at this point, but as this is contained
-within the [[[[[Badd_power] function, we just use the word [[[[[Bfunction] The
-empty
-brackets after this denote that no arguments are passed to the function.
-Lets look at the next line.
-
-#####B local ret, dir, damage
-
-The [[[[[Blocal] bit is saying that we're going to declare some local
-variables. That
-is, that there will be three variables used in this function , that apply
-exclusively to this function, and to no others. Global variables are
-variables that apply to the whole script, in multiple functions. The three
-variables will be called [[[[[Bret] (return), [[[[[Bdir] (direction), and
-[[[[[Bdamage]. They will be used to determine the direction the ball
-will fire in, and how much damage it will do. We'll see them in use when we add
-the third line:
-
-#####B ret, dir = get_aim_dir();
-
-here we're saying that the variables will take their value from the result
-of a function. The program performs the function [[[[[Bget_aim_dir] which
-essentially asks the player to choose a direction or pick a target.
-[[[[[Bget_aim_dir]
-assigns the value [[[[[Bret] to either TRUE (if the player correctly selected a
-direction) or FALSE (if the player failed to do so (maybe they changed their
-mind, or hit the wrong key!)). The value [[[[[Bdir] is the direction which was
-selected (or the path to the target if a target was selected). OK so let's add
-the next line:
-
-#####B if (ret == FALSE) then return end
-
-This introduces another fundamental scripting concept - [[[[[Bif] statements.
-They work just as you would expect them too. You say "if a certain condition is
-met, then do the following things."
-So in this function we're saying, "if the value of [[[[[Bret] is FALSE then
-[[[[[Breturn]."
-As I mentioned above, [[[[[Bret] is false if the player aborted (either
-deliberately or accidentally) the spell casting whilst choosing a direction
-for the spell. The double equals sign are used to mean "is equal to" as a
-single equals sign is used for defining variables remember? A single equals
-sign is more of a "let x be equal to y" thing.
-[[[[[Breturn] means stop the current function. And [[[[[Bend] signifies the
-close of the [[[[[Bif]
-statement. Every [[[[[Bif] statement must begin with an [[[[[Bif] and finish
-with an [[[[[Bend].
-So, what our [[[[[Bif] statement is saying is; "if the player failed to specify
-a direction or target for the spell, stop the function here."
-If the player has correctly specified a direction/target, the function
-continues to the next line:
-
-#####B damage = player.lev*3
-
-Here we're saying that the variable [[[[[Bdamage] has a value equal to the
-players current character level, multiplied by 3.
-
-#####B msg_print("You breathe fire.")
-
-Fairly easy to see what this does - displays the message "You breathe fire."
-I could have put anything there obviously, like [[[[[Bmsg_print("You open]
-[[[[[Byour mouth and everyone falls over with the smell of hot curry")] or
-some other such rubbish. But note that the message is enclosed within double
-quotes. The quotes aren't displayed in the message on screen, but signify the
-start and end of the message.
-
-#####B fire_ball(GF_FIRE, dir, damage, 3)
-
-This is the line that casts the spell. it says execute the function
-[[[[[Bfire_ball]. Now, this doesn't mean a fireball, it means fire a ball.
-There's an important distinction there! All it knows it is doing is firing a
-ball, it doesn't know what kind of ball, or where, or how big, or how much
-damage.
-The [[[[[BGF_FIRE,] bit is what tell us it is a fire ball. If it was
-[[[[[BGF_COLD,]
- we'd have a cold ball, or [[[[[BGF_CHAOS,] it would be a chaos ball and
-so on and so on. A full list of those types can be found in *****lua_gf.txt*0[lua_gf.txt].
-[[[[[B dir,] is the direction, from the [[[[[Bget_aim_dir()] bit.
-[[[[[B damage,] is the damage. As we've already said, this will be clvl*3.
-[[[[[B 3)] is the radius.
-and finally...
-
-#####B end,
-#####B}
-
-[[[[[Bend,] tells it the function has ended. Every function must finish with
-[[[[[Bend].
-You should have spotted that after the end of each attribute is a comma. Make
-sure you include this, and don't forget the braces at the very very end to
-close the [[[[[Badd_power] function.
-
-#####R=== Finishing the LUA file ===
-
-Save this as a text file 'pheonix.lua' Put it into the lib\scrpt directory
-of ToME, and open the init.lua file which you'll find in the same
-directory.
-
-Add the following line and resave the init.lua file.
-
-#####Btome_dofile("pheonix.lua")
-
-This ensures that ToME loads your file on start-up. Because you've installed
-the example scripts, this has all been done for you.
-
-#####R=== A quick word about comments ===
-
-One of the reasons Angband has so many variants is because the source code is
-clearly commented. Almost every line of code has an accompanying comment,
-explaining what that line does. It's good practice to add comments to any code
-or script you write. It's helpful to others who are learning, anyone who takes
-over your project, and also to yourself when you come back in a month's time
-and can't remember what you did! So comment your code clearly, and well!
-
-You can also add multi line comments which should be enclosed by [[[[[B--[[]
-and
-#####B]]
-
-#####R=== Tying it all together ===
-
-You'll now need to link this 'U' power to the pheonix race via the
-p_info.txt file. Simply add a line within the class definition file that has
-the format [[[[[BR:Z:<name>]the name of the power as it appears in the
-[[[[[B"name"]
-section we did right at the beginning, remember? Seeing as there is no pheonix
-race, I've gone ahead and made one up as a demonstration. If you've downloaded
-and installed the example files from [[[[[Ghttp://www.moppy.co.uk/angband.htm/]
-then
-you'll notice you already have the pheonix race available. Printed below is
-the p_info.txt entry for it.
-
-
-#####BR:N:23:Pheonix
-#####BR:D:Born from flame, these powerful bird like creatures gain fire related
-#####BR:D:abilities as they grow.
-#####BR:S:1:0:2:1:-3:2:-5
-#####BR:K:-8:15:20:-10:5:-1:-5:-5
-#####BR:P:8:130:5:210
-#####BR:M:255:70:2:1:20:5:2:1:18:3
-#####BR:E:1:1:1:2:1:1
-#####BR:C:Warrior | Mage | Priest | Rogue | Ranger | Paladin | Blade |
-#####BR:C:Warlock | Chaos-Warrior | Monk | Mindcrafter | High-Mage |
-#####BR:C:BeastMaster | Alchemist | Power-Mage | Runecrafter |
-#####BR:C:Sorceror | Archer | Illusionist | Druid | Necromancer | Black-Knight
-|
-#####BR:C:Daemonologist | Weaponmaster | Summoner |
-#####BR:Z:Fire Ball
-#####BR:R:1:0
-#####BR:F:RES_FIRE | FEATHER |
-
-Note the [[[[[BR:Z:] line.
-
-If all is well, you should be able to start ToME now and breathe fire! Once
-you get to lvl 10 anyhow. Don't forget, this is the kind of thing wizard mode
-was invented for! Ctrl-A and confirm at the prompt, and then 'e' will allow
-you to alter stats, including experience. Approx 1000 exp should do to get you
-to clvl 10.
-
-Ready for more? How about adding a new *****lua_skil.txt*0[skill] ?
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
-
-
-
-
diff --git a/lib/mods/theme/help/lua_ques.txt b/lib/mods/theme/help/lua_ques.txt
deleted file mode 100644
index 1d4b9c65..00000000
--- a/lib/mods/theme/help/lua_ques.txt
+++ /dev/null
@@ -1,299 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding a new quest >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-Adding a quest involves a bit more work, and there is, in some ways, rather
-more potential for things to go wrong! But it's a great way of showing just
-WHAT can be done with lua scripting. It proves just how much a lua patch can
-change the overall feel of the game. And it will give you a much better idea of
-how lua interfaces with the game source. You should have read the
-*****lua_intr.txt*0[scripting introduction], *****lua_pow.txt*0[racial power tutorial]
-and *****lua_skil.txt*0[adding new skills tutorial] before going much
-further. All of the above files contain some fairly fundamental information
-which you will find necessary for full understanding of this file.
-
-The script we're looking at is going to create a quest entrance in the middle
-of Bree. Entering the quest you see a little girl who has had her necklace
-stolen. Your job is to travel down a corridor, killing some monsters on the
-way, pick up the amulet and return it to the girl. Once done, she'll reveal the
-stairs back to Bree, and give you a (randomly generated) ring. If you feel the
-monsters are too hard, the only thing to do is talk to the little girl who will
-reveal the stairs again, failing the quest for you, and also block off the
-entrance to the amulet so that you can't cheat and make off with the amulet!
-
-#####R=== Getting started ===
-
-Open amulet.lua (you have downloaded the example scripts from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The first thing you
-should see is that yet again we're calling a function that takes its arguments
-from a table, making it easy to read what's going on in the script.
-
-This time our function is add_quest and we have the following keys and values:
-
-#####B["global"] = "AMULET_QUEST",
-#####B["name"] = "Hannahs lost amulet",
-#####B["desc"] = {
-#####B "Retrieve an amulet for Hannah Cooke. It's guarded!"
-#####B },
-#####B["level"] = 5,
-#####B["hooks"] = {
-
-[[[[[B"global" = ] is a constant that we set when we refer to this quest in
-various places...
-[[[[[B"name" = ] Obviously a long name for the quest. This will appear in the
-quest screen (Ctrl-Q) and we may use in some map files too.
-[[[[[B"desc" = ] This is a long description for the quest. Again this is what
-will appear in the quest screen, and each line should be not more than 80
-characters.
-[[[[[B"level" = ] This is a rough indicator of how hard the quest is, and again,
-appears in the quest screen
-[[[[[B"hooks" = ] This is the real 'meat' of the quest. Like the [[[[[B"spell_list"] key
-in the [[[[[Badd_magic] function, this is another sub-table.
-
-To understand fully the structure of the "hooks" key it's worth taking a bit of
-a detour at this point and discussing how the scripting interface works in
-general.
-
-#####R=== How the scripts work (ish) ===
-
-Essentially there's a list of events that happen in the game. As each of these
-events happen they run a check to see if there's any functions that they need
-to run at that event. When we ran the add_mkey part of adding a new skill
-power, we essentially said "when the 'm' key is pressed in the game, perform
-the [[[[[Bexecute_magic(constructor_powers)] function". Likewise we did a similar
-thing with adding the racial power, only we hooked onto the pressing of the
-'U' key.
-
-All of this was partly hidden because of the way that the [[[[[Badd_magic] and
-[[[[[Badd_power] functions work. But here in the [[[[[Badd_quest] function it's a bit more
-specific. We are going to specify what events we're going to hook onto, and
-what functions we want to trigger at that event.
-
-A full list of hooks can be found in the source-file util.pkg.
-
-#####R=== The hooks ===
-
-#####B[HOOK_BIRTH_OBJECTS] = function()
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_TAKEN
-#####Bend,
-
-So here we are with our first hook. We've declared that we're adding it to the
-birth of your character. That is, the function will be called when you create
-your character. And what we're doing here is automatically declaring the quest
-as being taken, like the Dol Guldur quest is. Each quest has 7 different
-statuses:
-
-[[[[[BQUEST_STATUS_IGNORED -1 ] This is unused, but the quest is
-ignored (will not be taken and has not been taken).
-[[[[[BQUEST_STATUS_UNTAKEN 0 ] The quest has not been accepted yet
-[[[[[BQUEST_STATUS_TAKEN 1 ] You have accepted the quest
-[[[[[BQUEST_STATUS_COMPLETED 2 ] You have completed the quest
-successfully but not been rewarded for it
-[[[[[BQUEST_STATUS_REWARDED 3 ] You've completed and rewarded the quest
-[[[[[BQUEST_STATUS_FAILED 4 ] You've failed the quest
-[[[[[BQUEST_STATUS_FINISHED 5 ] The quest is completely finished
-successfully.
-[[[[[BQUEST_STATUS_FAILED_DONE 6 ] The quest is completely finished
-unsuccessfully.
-
-You see that we've used the constant we defined in the "global" section is
-passed as an argument to [[[[[Bquest.status].
-
-Next hook then:
-
-#####B[HOOK_GEN_QUEST] = function()
-#####B if (player.inside_quest ~= AMULET_QUEST) then
-#####B return FALSE
-#####B else
-#####B load_map("amulet.map", 2, 2)
-#####B return TRUE
-#####B end
-#####Bend,
-
-Ok, we're hooking onto the generation of the quest here. This is specifically
-triggered in this instance by going down the quest entrance stairs in Bree.
-Once you've gone down the stairs, you are technically inside the quest, which
-means we can say if the person is not inside the amulet quest, then ignore this
-function, otherwise load the file 'amulet.map' at co-ordinates x=2 y=2. You'll
-find the amulet.map file in the edit directory, make sure you check it out. The
-syntax for map files is fairly simple, though I might get round to writing a
-tutorial on them some day! In the mean time holler for me at the usual email
-address if you're unsure.
-
-#####B[HOOK_FEELING] = function()
-#####B if (player.inside_quest ~= AMULET_QUEST) then
-#####B return FALSE
-#####B else
-#####B cmsg_print(TERM_L_BLUE, "Hannah speaks to you:")
-#####B cmsg_print(TERM_YELLOW, "'Some nasty monsters stole my
-#####B favourite necklace.'")
-#####B cmsg_print(TERM_YELLOW, "'It's hidden at the back of that
-#####B corridor! Please fetch it for me'")
-#####B return TRUE
-#####B end
-#####Bend,
-
-We're moving into some rather more obvious territory here, and getting into the
-meat of the quest. The [[[[[BHOOK_FEELING] is triggered at the point when the level
-feeling appears. It's important that this is run only if the player is inside
-the amulet quest, as otherwise it will trigger EVERY time a level feeling
-occurs, when you go down a level in the barrow-downs, whenever! Returning TRUE
-will replace the level feeling with what's above, returning FALSE will still
-perform the function but will amend the normal level feeling - so here if we'd
-returned false we'd still get our custom messages, but they'd follow with
-'looks like a typical quest level'. Of course returning false may cause you
-other problems (see end of this file!) depending on what else you have in your
-function.
-
-#####B[HOOK_GIVE] = function(m_idx, item)
-
-#####B m_ptr = monster(m_idx)
-#####B o_ptr = get_object(item)
-
-#####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl"))
-#####B and (o_ptr.tval == TV_AMULET) and (o_ptr.sval == 2) then
-
-#####B cmsg_print(TERM_YELLOW, "'Thank-you!'")
-
-#####B inven_item_increase(item, -1)
-#####B inven_item_optimize(item)
-
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_COMPLETED
-
-#####B cave_set_feat(7, 6, 6)
-
-#####B cmsg_print(TERM_YELLOW, "'Here, take this pretty ring I found
-#####B as a token of gratitude!'")
-#####B random_type = randint(57)
-#####B reward = create_object(TV_RING, random_type)
-#####B drop_near(reward, -1, py, px)
-#####B quest(AMULET_QUEST).status = QUEST_STATUS_REWARDED
-#####B return TRUE
-#####B else
-#####B return FALSE
-#####B end
-#####Bend,
-
-This is a fairly long function, but don't be intimidated. It's not really
-difficult to understand. As you can see we're hooking into the giving of an
-object to a monster (the 'y' key). Because of this, the function takes two
-arguments - [[[[[Bm_idx] (the monster that you're giving to) and [[[[[Bitem] (the item that
-you're giving).
-
-We then make it possible to work with the monster and item variables by
-referencing them to two functions which identify them from the edit files:
-[[[[[Bmonster()] and [[[[[Bget_object()]. This enables us to now say, 'if the name of the
-monster is "Hannah Cooke, a little girl" and the type of item is an amulet and
-that amulet is an amulet of adornment, then carry out the following commands'.
-
-We then say call the function [[[[[Binven_item_increase()] which places an object in
-the inventory. It takes two arguments, the first being what object to put in
-the inventory and the second being how many of that type of objects to put in
-the inventory. You can see that by placing -1 as the second argument it fairly
-obviously subtracts that item from the inventory. The [[[[[Binven_item_optimize()]
-function checks that there are no empty inventory slots, and if there are,
-erases them.
-
-The quest is then completed, and the stairs are revealed using the
-[[[[[Bcave_set_feat()] function. This function takes three arguments, the first is the
-x co-ordinate of the cave square you wish to change (counted from top left) the
-second is the y co-ordinate, and the third is the index number of the feature
-you wish the square to become as defined in f_info.txt.
-
-We then set about rewarding the player. As you can see we call [[[[[Bcreate_object()]
-which takes two variables: the first is the type of object (these are all
-listed in object.pkg) and the second is the sub-type of that object. I searched
-k_info.txt to see how many different types of ring there were (57) and used a
-randomly selected number with a maximum value of 57 as that specific sub-type.
-
-We then drop the object (although it's been created, it has only been created
-in the game's memory, it's nowhere that the player can interact with it until
-we drop it). The [[[[[Bdrop_near()] function takes 3 variables, the first being the
-object that you wish to drop, the second being the chance that it disappears
-(like an arrow, or mimicked creature) on drop. If you set it to -1, it won't
-ever disappear. The last two are the co-ordinates at which the object will be
-dropped. py and px are the global variables defined by where the player is
-standing, so in this case it will drop under the player. You could do
-[[[[[Binven_item_increase(reward, 1)] if you wanted, but I wanted to show a variety of
-ways of handling objects.
-
-OK, let's take a look at the next hook:
-
-#####B[HOOK_CHAT] = function(m_idx)
-#####B m_ptr = monster(m_idx)
-#####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl")) then
-#####B if (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) then
-#####B cmsg_print(TERM_YELLOW, "'Bye!'")
-#####B else
-#####B cmsg_print(TERM_YELLOW, "'Are the monsters too tough?
-#####B Do you want to leave?'")
-#####B if (get_check("Really leave and fail the quest?") ==
-#####B FALSE)
-#####B then
-#####B cmsg_print(TERM_YELLOW, "'Go and get my
-#####B amulet then!'")
-#####B else
-#####B cmsg_print(TERM_YELLOW, "'Awww. Never
-#####B mind. It was only a bit of rabbits foot'")
-#####B quest(AMULET_QUEST).status =
-#####B QUEST_STATUS_FAILED
-#####B cave_set_feat(7, 6, 6)
-#####B cave_set_feat(12, 5, 60)
-#####B end
-#####B end
-#####B return TRUE
-#####B end
-#####B return FALSE
-#####Bend,
-
-This only looks complicated because of the nested 'if' statements. It's easy to
-lose your way when doing this kind of thing, always make sure you close all the
-statements and put the returns in the right place. [[[[[BHOOK_CHAT] functions have one
-argument - the monster you are chatting to. As you can see, we perform a check
-to make sure it's the right monster and then away we go.... If the player wants
-to leave the quest without completion they talk to Hannah, who gives them a
-chance to change their mind! If the player asks to leave the entrance to the
-corridor is blocked off (the second cave_set_feat()) so that the user can't
-then go and get the amulet. Gumband or Zangband players may at this point think
-they've lost out on the rabbits foot of burglary! (they haven't though as it
-doesn't exist in ToME).
-
-#####B[HOOK_CHAR_DUMP] = function()
-#####B if (quest(AMULET_QUEST).status == QUEST_STATUS_FAILED) then
-#####B print_hook("\n You chickened out of rescuing a necklace and
-#####B made a little girl sad. ")
-#####B elseif (quest(AMULET_QUEST).status == QUEST_STATUS_COMPLETED) or
-#####B (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) or
-#####B (quest(AMULET_QUEST).status == QUEST_STATUS_FINISHED) then
-#####B print_hook("\n You rescued little Hannah Cooke's necklace from
-#####B the nasty monsters ")
-#####B end
-#####B return FALSE
-#####Bend,
-
-This quite simply and obviously prints an appropriate line in the character
-dump based on the status of the quest. The [[[[[B\n] bit ensures the text goes on a
-new line, so make sure you include it! Also you should return FALSE as
-returning TRUE will stop executing all the other character dump lines (and you
-may get other quests not having their lines printed).
-
-=== A word about returning TRUE and FALSE ===
-
-As I mentioned above, you need to be careful what you return when dealing with
-HOOKS as you can mess up the game a bit. Bear in mind that if you add a
-function to [[[[[BHOOK_GEN_QUEST], every time a quest is generated, that function will
-run. If you return TRUE, then no further functions attached to that hook will
-run. If you return FALSE, it continues processing functions on that hook.
-
-That is pretty much it. Do take a look at the other included scripts that I
-haven't gone into any detail about in the files, as you'll pick up some useful
-techniques there too. Especially worthy of note is the hina.lua file which uses
-hooks outside of the quest structure and also global variables and variables in
-a table. If you have any questions, let me know at the email addy below.
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/mods/theme/help/lua_skil.txt b/lib/mods/theme/help/lua_skil.txt
deleted file mode 100644
index 87385e5d..00000000
--- a/lib/mods/theme/help/lua_skil.txt
+++ /dev/null
@@ -1,342 +0,0 @@
-|||||oy
-#####R /----------------------------------------\
-#####R < Adding new skill-based powers >
-#####R \----------------------------------------/
-
-#####R=== Introduction ===
-
-This is very much in the same vein as adding a racial/extra power, but has to
-be tied into skills, and we're defining more than one spell at once. You should
-have read the *****lua_intr.txt*0[scripting introduction] and
-*****lua_pow.txt*0[racial power tutorial] before going much further. Both of the above files
-contain some fairly fundamental information which you will find necessary for
-full understanding of this file.
-
-#####R=== Getting started ===
-
-Open construc.lua (you have downloaded the example scripts from
-[[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The idea behind this
-script is that it adds a skill which affects you ability to build/knock down
-stuff. It treats the equivalent of stone-to-mud and trap-door destruction
-spells as if they were "building skills". It also adds quite a few high-level
-'spells' which do funky things like carving out corridors and chambers in a
-single turn, and building doors and stuff. Just think of it as if the person
-who has plenty of skills in this area would be a builder-type with lots of
-strength and constitution...
-
-In order to add these powers we're going to edit the s_info.txt file which
-lives in the edit folder, and add a new skill, underneath the 'misc' tree,
-called construction. The powers will then be accessed through the 'm' menu, in
-a similar way to mindcraft or alchemy skills or such. (That is, no books are
-needed to cast them, as we're treating them as a craft that has been learnt,
-rather than spells.) Our fist line of the script file reads:
-
-#####BSKILL_CONSTRUCT = 57
-
-This merely links the skill index that we'll be defining in s_info.txt to this
-file. We'll come back to this at the end of the tutorial.
-
-#####Bconstructor_powers = add_magic
-
-In a similar way to the [[[[[Badd_power] function we called when we added the
-Phoenix racial ability, this line calls a special function which we use to
-define new skills. It follows a very specific, but easy to understand form. It
-starts with a brace, which indicates the add_magic function will be storing
-these values in a table. Don't worry about this too much, but understand that a
-table starts and ends with braces [[[[[B{] and [[[[[B}] respectively. Each key
-(or field name) takes the format [[[[[B"key" = value,] (the comma is
-important!).
-
-#####B ["fail"] = function()
-#####B msg_print("You decide now is a good time for a cuppa")
-#####B end,
-#####B ["stat"] = A_STR,
-#####B ["get_level"] = function()
-#####B return get_skill_scale(SKILL_CONSTRUCT, 50)
-#####B end,
-#####B ["spell_list"] =
-
-[[[[[B"fail"] is a function that is called whenever you ##fail to cast the
-spells##. Here it does nothing spectacular.
-[[[[[B"stat"] defines the stat used to cast the spells. Here it is strength.
-Any other stat can be used, prefix it with [[[[[BA_].
-[[[[[B"get_level"] is used to determine the level of the spell. It's associated
-with spells that increase in power the more points that are invested in the
-associated skill. I know that's not terribly clear, I'll come back to it in a
-moment.
-[[[[[B"spell_list"] is just that, a list of all the spells.
-Each of these four properties within the table must end with a comma. If a
-function is defined in the property itself then we add the comma after the
-closing [[[[[Bend]. Again compare with construct.lua to see it. Any line NOT
-ending with a comma will cause a lua error on startup, probably of the type
-[[[[[V'}' expected to close '{' at line <whatever>.]
-
-#####R=== The spell list ===
-
-Each spell, within the [[[[[B"spell_list"] key has its own set of properties
-that we need to define from a sub-table so we open another set of braces to
-start the spell list, and then a third set of braces to start the first spell.
-So with all this, our first spell looks like:
-
-#####B ["spell_list"] =
-#####B {
-#####B {
-#####B ["name"] =
-#####B ["desc"] =
-#####B ["mana"] =
-#####B ["level"] =
-#####B ["fail"] =
-#####B ["spell"] =
-#####B ["info"] =
-#####B },
-
-[[[[[B"name"] is, as you would expect, the name of the spell, as you want it to
-appear in the spell list when choosing a spell. The maximum number of
-characters for this is 29.
-[[[[[B"desc"] is the description received when you hit the capital letter of
-that spell in the menu. (i.e., press 'a' to cast the first spell, but press 'A'
-to receive info about the first spell.
-[[[[[B"mana"] is the amount of mana required to cast the spell.
-[[[[[B"level"] is the level required to use that spell (that's level of the (in
-this case construction) skill, not character level!).
-[[[[[B"fail"] is base fail rate.
-[[[[[B"spell"] is the function that is executed when the spell is cast. Note
-that it MUST take the form [[[[[Bfunction() blah end] even if you're calling
-a C function directly. If you have a look at the end of the file, you'll see
-the "rebuild dungeon" spell which is identical to the "alter_reality" spell.
-However, rather than reading [[[[[B"spell" = alter_reality()], it reads:
-
-#####B["spell"] = function()
-#####B alter_reality()
-#####Bend,
-
-which appears to be a long way round to do the same thing, but this is how it
-must be done.
-
-In a similar way, the [[[[[B"info"] key must begin with a [[[[[Bfunction()]
-and return the value of what is to be displayed alongside the spell name,
-level and mana in the spell list. The maximum number of characters that can be
-displayed here is dependent on the width of the user's screen, but try to keep
-it under 12 if you can, as this will fit in a standard 80x24 terminal screen.
-The first character will need to be a space otherwise you'll have the info line
-squashed right up against the fail rate and it will look odd. If you wish to
-have this part blank in the spell list, you still need to return a value, so
-just a single space will do : [[[[[Breturn " "]
-
-All of these keys are repeated for each spell, with each spell in its own
-table (therefore, it's own set of braces). Again, check the lua file for
-clarification.
-
-When entering the spells in the "spell_list", you must take care to specify
-them in the order which they are gained, otherwise they display incorrectly in
-the spell list.
-
-You should by now be experienced enough to understand most of what's going on
-in the actual spell functions (especially if you dig around in the source a
-bit, and check out Chris Hadgis' excellent *****lua_spel.txt*0[spell.pkg] helper
-files. I'm not going to go through the whole file line by line, as this is
-something you should do yourself, figuring out what's going on. I'm going to
-examine a few of the things we haven't covered before though, so pay attention.
-
-#####R=== The get_level() function ===
-
-Probably one of the most important functions that you see reappearing in the
-file is the [[[[[Bget_level()] function. All this does is return the numerical
-value of the power that is given as the first argument. So [[[[[Bget_level]
-[[[[[B(constructor_power)] will return the current level of the constructor power.
-Given that the level of this is taken directly from the construction skill, (we
-defined that in the [[[[[B"get_level"] key, by saying [[[[[Bget_skill_scale]
-[[[[[B(SKILL_CONSTRUCT, 50)] ) it will return the value of your construction skill.
-[[[[[Bconstructor_power] is the name of the whole power, we named it thus on
-the second line of the script!
-
-[[[[[Bget_level] takes the following arguments: [[[[[Bget_level(power, max, ]
-[[[[[Bmin)]. The power is obviously which power we're taking the value from, and the
-max and min allow you to define boundaries for the spell. For instance the
-current maximum value that [[[[[Bget_level(constructor_power)] can return is
-50, as that is the maximum number of skill points you can have in that skill.
-If you were using this as the basis for the damage of a low-level bolt spell,
-you might decide that having a damage of 50 would be too much (unlikely, but
-still possible). You could therefore define a maximum value of 20 so that when
-the value of the construction skill was over 50, the maximum value for
-damage of that spell would be 20. To achieve this you'd have:
-[[[[[Bget_level(constructor_power, 20)]. In a similar way, you can force the
-minimum value of the spell to be higher than the actual construction skill
-level, with a [[[[[Bget_level(constructor_power, 50, 15)]. This would be useful
-say for spells that you wanted to be available when the construction skill
-level reaches 10, but for whom you wanted a (for example) base damage of 15
-right from the word go. These re-scale values rather than capping them!
-
-You can leave out the minimum value as I have done above. You can also leave
-the maximum value out (it will default to 50). If you want to specify a minimum
-value though, you MUST specify a maximum value as well.
-
-As you have hopefully been able to tell, the [[[[[Bget_level()] function
-enables us to have spells that increase in usefulness as you gain levels. Let's
-take the "Dismantle" spell. The function in the [[[[[B"spell"] key is as
-follows:
-
-#####Bfunction()
-#####B local ret, dir, dam
-
-#####B if (get_level(constructor_powers, 50) >= 11) then
-#####B ret, dir = get_aim_dir();
-#####B if (ret == FALSE) then return end
-#####B fire_beam(GF_KILL_TRAP, dir, 1)
-#####B else
-#####B fire_ball(GF_KILL_TRAP, 0, 1, 1)
-#####B end
-#####Bend,
-
-The [[[[[Bif] statement is obviously what really interests us here. You'll
-notice that this has the amendment of an [[[[[Belse] clause, which the [[[[[Bif]
-statement we used in the previous tutorial did not. As you would expect, if the
-condition on the first line of this statement is met, then the instructions
-immediately below it are carried out. If the condition is not met, then the
-statements that follow the [[[[[Belse] are executed.
-
-Coming back to the [[[[[Bget_level] function, we learnt from above, that the
-[[[[[Bget_level] part of this function translates as, "if the value of the
-construction_power level (which happens to be identical to the construction
-skill level) is greater than or equal to 11, cast a beam of trap disarming in
-the specified direction. (The first part of this is all straightforward,
-getting a direction, and cancelling correctly if the player presses 'ESC'.)
-Otherwise, cast a ball of trap disarming with a radius of one, centred on the
-player."
-
-In the same way, as you look at the construc.lua file, you will see that
-[[[[[Bget_level()] is used many times in this way, to increase the power of
-detection spells, to change bolt spells to ball spells, to keep a constantly
-increasing damage going, and so on.
-
-#####R=== Elseif's and things ===
-
-If you want to provide more than one alternative condition, in an
-[[[[[Bif-then-else] statement, you can use [[[[[Belseif]s which do what you
-might expect. Take a look at the first spell, "Survey area", for an example of
-this:
-
-#####Bif (get_level(constructor_powers, 50) >= 28) then
-#####B wiz_lite()
-#####Belseif (get_level(constructor_powers, 50) >= 15) then
-#####B map_area()
-#####B detect_traps(DEFAULT_RADIUS)
-#####Belseif (get_level(constructor_powers, 50) >= 5) then
-#####B detect_traps(DEFAULT_RADIUS)
-#####B detect_stairs(DEFAULT_RADIUS)
-#####B detect_doors(DEFAULT_RADIUS)
-#####Belse
-#####B detect_stairs(DEFAULT_RADIUS)
-#####B detect_doors(DEFAULT_RADIUS)
-#####Bend
-
-If the level of constructor powers is greater or equal to 28, then the function
-[[[[[Bwiz_lite()] is performed, and no other part of the if statement is
-executed. [[[[[Bwiz_lite()] is just the enlightenment spell. If it is less than
-28, the next condition is examined: that if the level of constructor powers is
-greater than or equal to 15, then [[[[[Bmap_area()](Magic mapping) and detect
-traps are called. If the level of constructor power is less than 15, it moves
-onto the next condition, which says that if the level of constructor power is
-greater than 5, then detect stairs, traps and doors. If none of these
-conditions are met,(that is, if the level of construction skill is less than 5)
-then we just detect doors and stairs.
-
-You'll note that each of the detection spells includes a DEFAULT_RADIUS
-constant. You could change this to a numerical value, or a variable defined
-somewhere else in your script. eg [[[[[Bdetect_traps(2)] would detect traps
-with a radius of 2 centred on the player.
-
-#####R=== Registering the skill type ===
-
-This is what we do at the end of the file, and is what ties the powers we've
-defined to the action of pressing the 'm' key in game. Once more we're calling
-a special function [[[[[Badd_mkey()] which takes its arguments for a table.
-There are only two keys in this table though which keeps things simple.
-
-#####Badd_mkey
-#####B{
-#####B ["mkey"] = MKEY_CONSTRUCT_POWERS,
-#####B ["fct"] = function()
-#####B execute_magic(constructor_powers)
-#####B energy_use = energy_use + 100;
-#####B end
-#####B}
-
-[[[[[B"mkey"] must be a UNIQUE value > 1000 . Here I've defined it as a
-constant, [[[[[BMKEY_CONSTRUCT_POWERS], which has the value 1004. This value
-we'll call again in the s_info.txt file.
-[[[[[B"fct"] is the function that's called when the user presses the key in the
-'m' menu. So here, it calls the [[[[[Bexecute_magic] function which actually
-displays a list of powers for the user to choose from. The argument it takes is
-the powers it will use (alchemy, mindcraft, etc., or in this case constructor),
-and then the [[[[[Benergy_use] line tells the game to take one game turn to do
-the action.
-
-#####R=== Adding the skill in s_info.txt ===
-
-Take a look in the s_info.txt file, under the Misc section. You'll see,
-
-#####BN:57:Construction
-#####BD:Ability to use constructor powers
-#####BD:Construction powers use strength
-#####BA:1004:Build or knock down stuff
-#####BI:1000
-
-The first line is the index of the skill; again this must be unique. The second
-property is the name of the skill. The [[[[[BD] lines are the lines displayed
-when the skill is highlighted in the skill screen.
-The first entry on the [[[[[BA] line is the value of the [[[[[B"mkey"] we
-defined in the [[[[[Badd_mkey] function in our script. The second entry is the
-display for selecting the construction power in the 'm' menu.
-The [[[[[BI] line is currently unused, but add a 1000 there anyway. That's what
-all the others have so when it's introduced, at least it will affect your
-powers identically to how it affects all the other powers.
-
-If you scroll to the very bottom of the file now, you'll see I've placed the
-skill at the bottom of the Misc branch of the skills tree. I then made a new
-class, constructor, which you can see in p_info.txt.
-
-That is all that is NEEDED when writing a script to add a skill - defining an
-mkey using add_mkey, and defining any powers that are called in the
-[[[[[B"fct"] (generally using [[[[[Badd_magic] ).
-
-And I've added the line
-
-#####Btome_dofile("construc.lua")
-
-in init.lua so the script is loaded on start-up!
-
-Below I'm going to talk in depth about a few other functions that you may find
-useful in your scripting.
-
-#####R=== fire_bolt() and fire_beam() ===
-
-In the last help file we looked at the routine for firing a ball -
-[[[[[Bfire_ball()]. Here's a quick note about beams and bolts...
-[[[[[Bfire_beam()] and [[[[[Bfire_bolt()] take 2 arguments:
-[[[[[B(type, direction, damage)]. So in the dismantle spell we have the
-direction passed from [[[[[Bget_aim_dir()] (the function that asks the player
-for a direction), the type of damage is [[[[[BGF_KILL_TRAP], which as you might
-expect disarms traps. And the damage is only 1 because it's not going to hurt
-monsters, just dismantle traps.
-
-#####R=== set_oppose_elec() ===
-
-OK here's another thing. Wander on down to the sparky_skills spell. After the
-appropriate bolt/ball is fired, we have the line:
-
-#####Bif player.oppose_elec == 0 then
-#####B set_oppose_elec(randint(10) + 20 + get_level(constructor_powers, 20)*3)
-#####Bend
-
-This is the bit that grants temporary resist electricity. We've called the
-function [[[[[Bset_oppose_elec(turns)], which sets the player's resist
-electricity to "on" for the time specified in the argument "turns". We're only
-calling this if the player is not already granted temporary resist electricity,
-and we've linked the number of turns it is active to the level of the
-construction skill. I've limited the maximum value of get_level to 20 in this
-instance. A similar idea can be used for temporarily granting levitation,
-extended infravision, protection against evil, resist fire, stuns, cuts and so
-on and so on. Have a look in player.pkg in the source for a full list....
-
- [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)]
diff --git a/lib/mods/theme/help/lua_spel.txt b/lib/mods/theme/help/lua_spel.txt
deleted file mode 100644
index aa4a532b..00000000
--- a/lib/mods/theme/help/lua_spel.txt
+++ /dev/null
@@ -1,2150 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < spell.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_directed ===
-
-#####GDeclaration
- extern void teleport_player_directed(int rad, int dir);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport player, using a distance and a direction as a rough guide.
- *
- * This function is not at all obsessive about correctness.
- * This function allows teleporting into vaults (!)
- */
-
-#####GDescription
-Teleport a player up to "rad" grids away roughly in "dir" direction.
-
-#####GParameters
-> "rad" must not exceed 200. The distance teleported is a minimum of a
- quarter of "rad".
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-
-----------------------------------------------------------------------
-
-#####R=== teleport_away ===
-
-#####GDeclaration
- extern void teleport_away(int m_idx, int dis);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport a monster, normally up to "dis" grids away.
- *
- * Attempt to move the monster at least "dis/2" grids away.
- *
- * But allow variation to prevent infinite loops.
- */
-
-#####GDescription
-Teleport monster indicated by "m_idx" up to "dis" grids away.
-
-#####GParameters
-> "m_idx" is the index of the monster in m_list[].
-> "dis" must not exceed 200. The distance teleported is a minimum of a
- quarter of "dis".
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player ===
-
-#####GDeclaration
- extern void teleport_player(int dis);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport the player to a location up to "dis" grids away.
- *
- * If no such spaces are readily available, the distance may increase.
- * Try very hard to move the player at least a quarter that distance.
- */
-
-#####GDescription
-Teleport player up to "dis" grids away.
-
-#####GParameters
-> "dis" must not exceed 200. The distance teleported is a minimum of a
- quarter of "dis".
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_to ===
-
-#####GDeclaration
- extern void teleport_player_to(int ny, int nx);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport player to a grid near the given location
- *
- * This function is slightly obsessive about correctness.
- * This function allows teleporting into vaults (!)
- */
-
-#####GDescription
-Teleport player to a grid near the given location ("ny", "nx"). If
-the location is empty, the player goes there, otherwise they go to
-a grid as close as possible to the location.
-
-#####GParameters
-> "ny" is the y co-ordinate of the location.
-> "nx" is the x co-ordinate of the location.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_monster_to ===
-
-#####GDeclaration
- extern void teleport_monster_to(int m_idx, int ny,
- int nx);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport a monster to a grid near the given location
- *
- * This function is slightly obsessive about correctness.
- */
-
-#####GDescription
-Teleport monster indicated by "m_idx" to a grid near the given
-location ("ny", "nx"). If the location is empty, the monster goes
-there, otherwise they go to a grid as close as possible to the
-location.
-
-#####GParameters
-> "m_idx" is the index of the monster in m_list[].
-> "ny" is the y co-ordinate of the location.
-> "nx" is the x co-ordinate of the location.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_player_level ===
-
-#####GDeclaration
- extern void teleport_player_level(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Teleport the player one level up or down (random when legal)
- */
-
-#####GDescription
-Teleport the player one level up or down at random.
-
-----------------------------------------------------------------------
-
-#####R=== recall_player ===
-
-#####GDeclaration
- extern void recall_player(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Recall the player to town or dungeon
- */
-
-#####GDescription
-Recall the player to town (if in dungeon) or dungeon (if in town).
-
-----------------------------------------------------------------------
-
-#####R=== take_hit ===
-
-#####GDeclaration
- extern void take_hit(int damage, cptr kb_str);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Decreases players hit points and sets death flag if necessary
- *
- * XXX XXX XXX Invulnerability needs to be changed into a "shield"
- *
- * XXX XXX XXX 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".
- */
-
-#####GDescription
-Reduce the player's current hit points by "damage" points. If the
-player dies, "kb_str" is used to record what the player was killed by
-(see high-score table).
-
-#####GParameters
-> "damage" is the amount of damage.
-> "kb_str" is a string describing what killed the player.
-
-----------------------------------------------------------------------
-
-#####R=== take_sanity_hit ===
-
-#####GDeclaration
- extern void take_sanity_hit(int damage, cptr hit_from);
-
-#####GFile
- spells1.c
-
-#####GComment
-/* Decrease player's sanity. This is a copy of the function above. */
-
-#####GDescription
-Reduce the player's current sanity points by "damage" points. If the
-player dies, "hit_from" is used to record what the player was killed
-by (see high-score table).
-
-#####GParameters
-> "damage" is the amount of damage.
-> "hit_from" is a string describing what killed the player.
-
-----------------------------------------------------------------------
-
-#####R=== project ===
-
-#####GDeclaration
- extern bool project(int who, int rad, int y, int x,
- int dam, int typ, int flg);
-
-#####GFile
- spells1.c
-
-#####GComment
-/*
- * Generic "beam"/"bolt"/"ball" projection routine.
- *
- * Input:
- * who: Index of "source" monster (negative for "player")
- * jk -- -2 for traps, only used with project_jump
- * rad: Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
- * y,x: Target location (or location to travel "towards")
- * dam: Base damage roll to apply to affected monsters (or player)
- * typ: Type of damage to apply to monsters (and objects)
- * flg: Extra bit flags (see PROJECT_xxxx in "defines.h")
- *
- * Return:
- * TRUE if any "effects" of the projection were observed, else FALSE
- *
- * Allows a monster (or player) to project a beam/bolt/ball of a given kind
- * towards a given location (optionally passing over the heads of interposing
- * monsters), and have it do a given amount of damage to the monsters (and
- * optionally objects) within the given radius of the final location.
- *
- * A "bolt" travels from source to target and affects only the target grid.
- * A "beam" travels from source to target, affecting all grids passed through.
- * A "ball" travels from source to the target, exploding at the target, and
- * affecting everything within the given radius of the target location.
- *
- * Traditionally, a "bolt" does not affect anything on the ground, and does
- * not pass over the heads of interposing monsters, much like a traditional
- * missile, and will "stop" abruptly at the "target" even if no monster is
- * positioned there, while a "ball", on the other hand, passes over the heads
- * of monsters between the source and target, and affects everything except
- * the source monster which lies within the final radius, while a "beam"
- * affects every monster between the source and target, except for the casting
- * monster (or player), and rarely affects things on the ground.
- *
- * Two special flags allow us to use this function in special ways, the
- * "PROJECT_HIDE" flag allows us to perform "invisible" projections, while
- * the "PROJECT_JUMP" flag allows us to affect a specific grid, without
- * actually projecting from the source monster (or player).
- *
- * The player will only get "experience" for monsters killed by himself
- * Unique monsters can only be destroyed by attacks from the player
- *
- * Only 256 grids can be affected per projection, limiting the effective
- * "radius" of standard ball attacks to nine units (diameter nineteen).
- *
- * One can project in a given "direction" by combining PROJECT_THRU with small
- * offsets to the initial location (see "line_spell()"), or by calculating
- * "virtual targets" far away from the player.
- *
- * One can also use PROJECT_THRU to send a beam/bolt along an angled path,
- * continuing until it actually hits something (useful for "stone to mud").
- *
- * Bolts and Beams explode INSIDE walls, so that they can destroy doors.
- *
- * Balls must explode BEFORE hitting walls, or they would affect monsters
- * on both sides of a wall. Some bug reports indicate that this is still
- * happening in 2.7.8 for Windows, though it appears to be impossible.
- *
- * We "pre-calculate" the blast area only in part for efficiency.
- * More importantly, this lets us do "explosions" from the "inside" out.
- * This results in a more logical distribution of "blast" treasure.
- * It also produces a better (in my opinion) animation of the explosion.
- * It could be (but is not) used to have the treasure dropped by monsters
- * in the middle of the explosion fall "outwards", and then be damaged by
- * the blast as it spreads outwards towards the treasure drop location.
- *
- * Walls and doors are included in the blast area, so that they can be
- * "burned" or "melted" in later versions.
- *
- * This algorithm is intended to maximise simplicity, not necessarily
- * efficiency, since this function is not a bottleneck in the code.
- *
- * We apply the blast effect from ground zero outwards, in several passes,
- * first affecting features, then objects, then monsters, then the player.
- * This allows walls to be removed before checking the object or monster
- * in the wall, and protects objects which are dropped by monsters killed
- * in the blast, and allows the player to see all affects before he is
- * killed or teleported away. The semantics of this method are open to
- * various interpretations, but they seem to work well in practice.
- *
- * We process the blast area from ground-zero outwards to allow for better
- * distribution of treasure dropped by monsters, and because it provides a
- * pleasing visual effect at low cost.
- *
- * Note that the damage done by "ball" explosions decreases with distance.
- * This decrease is rapid, grids at radius "dist" take "1/dist" damage.
- *
- * Notice the "napalm" effect of "beam" weapons. First they "project" to
- * the target, and then the damage "flows" along this beam of destruction.
- * The damage at every grid is the same as at the "centre" of a "ball"
- * explosion, since the "beam" grids are treated as if they ARE at the
- * centre of a "ball" explosion.
- *
- * Currently, specifying "beam" plus "ball" means that locations which are
- * covered by the initial "beam", and also covered by the final "ball", except
- * for the final grid (the epicentre of the ball), will be "hit twice", once
- * by the initial beam, and once by the exploding ball. For the grid right
- * next to the epicentre, this results in 150% damage being done. The centre
- * does not have this problem, for the same reason the final grid in a "beam"
- * plus "bolt" does not -- it is explicitly removed. Simply removing "beam"
- * grids which are covered by the "ball" will NOT work, as then they will
- * receive LESS damage than they should. Do not combine "beam" with "ball".
- *
- * The array "gy[],gx[]" with current size "grids" is used to hold the
- * collected locations of all grids in the "blast area" plus "beam path".
- *
- * Note the rather complex usage of the "gm[]" array. First, gm[0] is always
- * zero. Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the
- * first blast grid (see above) with radius "N" from the blast centre. Note
- * that only the first gm[1] grids in the blast area thus take full damage.
- * Also, note that gm[rad+1] is always equal to "grids", which is the total
- * number of blast grids.
- *
- * Note that once the projection is complete, (y2,x2) holds the final location
- * of bolts/beams, and the "epicentre" of balls.
- *
- * Note also that "rad" specifies the "inclusive" radius of projection blast,
- * so that a "rad" of "one" actually covers 5 or 9 grids, depending on the
- * implementation of the "distance" function. Also, a bolt can be properly
- * viewed as a "ball" with a "rad" of "zero".
- *
- * Note that if no "target" is reached before the beam/bolt/ball travels the
- * maximum distance allowed (MAX_RANGE), no "blast" will be induced. This
- * may be relevant even for bolts, since they have a "1x1" mini-blast.
- *
- * 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
- * of the path, since it either starts at the player or ends on the player.
- *
- * 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.
- */
-
-#####GDescription
-Generate a beam/bolt/ball starting from "who" with a radius of "rad"
-at target grid "y,x" for "damage" points of "typ" damage. The beam/
-bolt/ball can have various properties as denoted by "flg".
-
-#####GParameters
-> "who" is > 0 (index of monster in m_list[]), < 0 and
- not -100 or -101 (player), -100 or -101 (trap).
-> "rad" is 0 for a beam/bolt and 1-9 for a ball.
-> "y" is the y co-ordinate of the target grid.
-> "x" is the x co-ordinate of the target grid.
-> "dam" is the number of points of damage.
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== corrupt_player ===
-
-#####GDeclaration
- extern void corrupt_player(void);
-
-#####GFile
- spells1.c
-
-#####GComment
-(none)
-
-#####GDescription
-Swap two of the players stats at random.
-
-----------------------------------------------------------------------
-
-#####R=== grow_trees ===
-
-#####GDeclaration
- extern void grow_trees(int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Grow trees
- */
-
-#####GDescription
-Grow up to (("rad" x "rad") + 11) trees around the player.
-
-#####GParameters
-> "rad" is the radius of the area where trees may grow.
-
-----------------------------------------------------------------------
-
-#####R=== hp_player ===
-
-#####GDeclaration
- extern bool hp_player(int num);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Increase players hit points, notice effects
- */
-
-#####GDescription
-Add "num" points to the player's current hit points. The total can
-not exceed the maximum.
-
-#####GParameters
-> "num" is the number of points to add.
-
-----------------------------------------------------------------------
-
-#####R=== heal_insanity ===
-
-#####GDeclaration
- extern bool heal_insanity(int val);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Heal insanity. */
-
-#####GDescription
-Add "val" points to the player's current sanity points. The total can
-not exceed the maximum.
-
-#####GParameters
-> "val" is the number of points to add.
-
-----------------------------------------------------------------------
-
-#####R=== warding_glyph ===
-
-#####GDeclaration
- extern void warding_glyph(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Leave a "glyph of warding" which prevents monster movement
- */
-
-#####GDescription
-Place a glyph at the player's location. The location must be bare.
-
-----------------------------------------------------------------------
-
-#####R=== explosive_rune ===
-
-#####GDeclaration
- extern void explosive_rune(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Place a minor glyph (explosive rune) at the player's location. The
-location must be bare.
-
-----------------------------------------------------------------------
-
-#####R=== do_dec_stat ===
-
-#####GDeclaration
- extern bool do_dec_stat(int stat, int mode);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Lose a "point"
- */
-
-#####GDescription
-Attempt to reduce the player's "stat" statistic by a point.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-> "mode" is the type of decrease: temporary, normal, or permanent
- *****fields.txt*0[STAT_DEC_fields]
-
-----------------------------------------------------------------------
-
-#####R=== do_res_stat ===
-
-#####GDeclaration
- extern bool do_res_stat(int stat);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Restore lost "points" in a stat
- */
-
-#####GDescription
-Restore the player's "stat" statistic.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-
-----------------------------------------------------------------------
-
-#####R=== do_inc_stat ===
-
-#####GDeclaration
- extern bool do_inc_stat(int stat);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Gain a "point" in a stat
- */
-
-#####GDescription
-Increase the player's "stat" statistic by a point.
-
-#####GParameters
-> "stat" is the statistic
- *****fields.txt*0[A_fields]
-
-----------------------------------------------------------------------
-
-#####R=== identify_pack ===
-
-#####GDeclaration
- extern void identify_pack(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Identify everything being carried.
- * Done by a potion of "self knowledge".
- */
-
-#####GDescription
-Identify all items in the inventory.
-
-----------------------------------------------------------------------
-
-#####R=== remove_curse ===
-
-#####GDeclaration
- extern bool remove_curse(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Remove most curses
- */
-
-#####GDescription
-Remove all curses except for heavy curses.
-
-----------------------------------------------------------------------
-
-#####R=== remove_all_curse ===
-
-#####GDeclaration
- extern bool remove_all_curse(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Remove all curses
- */
-
-#####GDescription
-Remove all curses including heavy curses.
-
-----------------------------------------------------------------------
-
-#####R=== restore_level ===
-
-#####GDeclaration
- extern bool restore_level(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Restores any drained experience
- */
-
-#####GDescription
-Restore all drained experience points (if any).
-
-----------------------------------------------------------------------
-
-#####R=== self_knowledge ===
-
-#####GDeclaration
- extern void self_knowledge(FILE *fff);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * self-knowledge... idea from nethack. Useful for determining powers and
- * resistances of items. It saves the screen, clears it, then starts listing
- * attributes, a screenful at a time. (There are a LOT of attributes to
- * list. It will probably take 2 or 3 screens for a powerful character whose
- * using several artifacts...) -CFT
- *
- * It is now a lot more efficient. -BEN-
- *
- * See also "identify_fully()".
- *
- * XXX XXX XXX Use the "show_file()" method, perhaps.
- */
-
-#####GDescription
-Show all attributes including racial powers, mutations, and equipment
-effects.
-
-#####GParameters
-> "*ffff" points to a file (write info to file) or is NULL (write info
- to screen).
-
-----------------------------------------------------------------------
-
-#####R=== lose_all_info ===
-
-#####GDeclaration
- extern bool lose_all_info(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Forget everything
- */
-
-#####GDescription
-Forget about objects and the map.
-
-----------------------------------------------------------------------
-
-#####R=== detect_traps ===
-
-#####GDeclaration
- extern bool detect_traps(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all traps on current panel
- */
-
-#####GDescription
-Detect all traps on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_doors ===
-
-#####GDeclaration
- extern bool detect_doors(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all doors on current panel
- */
-
-#####GDescription
-Detect all doors on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_stairs ===
-
-#####GDeclaration
- extern bool detect_stairs(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all stairs on current panel
- */
-
-#####GDescription
-Detect all stairs on current panel.
-
-----------------------------------------------------------------------
-
-#####R=== detect_treasure ===
-
-#####GDeclaration
- extern bool detect_treasure(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect any treasure on the current panel
- */
-
-#####GDescription
-Detect any treasure on the current panel.
-
-----------------------------------------------------------------------
-
-Field: hack_no_detect_message
-Value: FALSE
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_gold ===
-
-#####GDeclaration
- extern bool detect_objects_gold(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "gold" objects on the current panel
- */
-
-#####GDescription
-Detect all objects with the TV_GOLD flag.
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_normal ===
-
-#####GDeclaration
- extern bool detect_objects_normal(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "normal" objects on the current panel
- */
-
-#####GDescription
-Detect all objects without the TV_GOLD flag.
-
-----------------------------------------------------------------------
-
-#####R=== detect_objects_magic ===
-
-#####GDeclaration
- extern bool detect_objects_magic(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "magic" objects on the current panel.
- *
- * This will light up all spaces with "magic" items, including artifacts,
- * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
- * and "enchanted" items of the "good" variety.
- *
- * It can probably be argued that this function is now too powerful.
- */
-
-#####GDescription
-Detect all "magic" objects which are artefacts, ego items, or have one
-of the following flags - TV_AMULET, TV_RING, TV_BATERIE, TV_STAFF,
-TV_WAND, TV_ROD, TV_ROD_MAIN, TV_SCROLL, TV_POTION, TV_POTION2,
-TV_VALARIN_BOOK, TV_MAGERY_BOOK, TV_SHADOW_BOOK, TV_CHAOS_BOOK,
-TV_SPIRIT_BOOK, TV_NETHER_BOOK, TV_DAEMON_BOOK, TV_CRUSADE_BOOK,
-TV_SIGALDRY_BOOK, TV_SYMBIOTIC_BOOK, TV_MUSIC_BOOK.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_normal ===
-
-#####GDeclaration
- extern bool detect_monsters_normal(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "normal" monsters on the current panel
- */
-
-#####GDescription
-Detect all non-invisible monsters (without RF2_INVISIBLE).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_invis ===
-
-#####GDeclaration
- extern bool detect_monsters_invis(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "invisible" monsters on current panel
- */
-
-#####GDescription
-Detect all invisible monsters (with RF2_INVISIBLE).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_evil ===
-
-#####GDeclaration
- extern bool detect_monsters_evil(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "evil" monsters on current panel
- */
-
-#####GDescription
-Detect all evil monsters (with RF3_EVIL).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_good ===
-
-#####GDeclaration
- extern bool detect_monsters_good(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Detect good monsters */
-
-#####GDescription
-Detect all good monsters (with RF3_GOOD).
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_xxx ===
-
-#####GDeclaration
- extern bool detect_monsters_xxx(u32b match_flag);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * A "generic" detect monsters routine, tagged to flags3
- */
-
-#####GDescription
-Detect all monsters with "match_flag" flag.
-
-#####GParameters
-> "match_flag" can be any RF3_ flag (see defines.h) but only
- RF3_DEMON, RF3_UNDEAD, RF3_GOOD work.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_string ===
-
-#####GDeclaration
- extern bool detect_monsters_string(cptr);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all (string) monsters on current panel
- */
-
-#####GDescription
-Detect all monsters whose default monster character matches a
-character pointed to by "cptr".
-
-#####GParameters
-> "cptr" is a pointer to a single character, eg 'Z' for hounds. For
- available characters, see the "symbol" field of the graphics (G)
- line of r_info.txt.
-
-----------------------------------------------------------------------
-
-#####R=== detect_monsters_nonliving ===
-
-#####GDeclaration
- extern bool detect_monsters_nonliving(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect all "nonliving", "undead" or "demonic" monsters on current panel
- */
-
-#####GDescription
-Detect all non-living monsters (with RF3_NONLIVING, RF3_UNDEAD, or
-RF3_DEMON).
-
-----------------------------------------------------------------------
-
-#####R=== detect_all ===
-
-#####GDeclaration
- extern bool detect_all(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Detect everything
- */
-
-#####GDescription
-Detects traps, doors, stairs, treasure, gold objects, normal objects,
-invisible monsters, normal (visible) monsters.
-
-----------------------------------------------------------------------
-
-#####R=== stair_creation ===
-
-#####GDeclaration
- extern void stair_creation(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Create stairs at the player location
- */
-
-#####GDescription
-Create stairs at the player location. This is not allowed if the grid
-is not empty, the player is not in a dungeon, the player is on a
-special level, the player is in an arena or quest. If the player is
-in the town or wilderness the stairs will go down. If the player is
-on a quest level or at the bottom of a dungeon, the stairs will go up.
-Otherwise there is an even chance the stairs will go up or down.
-
-----------------------------------------------------------------------
-
-#####R=== wall_stone ===
-
-#####GDeclaration
- extern bool wall_stone(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Create a stone wall on the player's grid. This function uses the
-project() function to create the stone wall. Apparently zero can be
-used as the "who" parameter for the player. See details for the
-project() function elsewhere in this document.
-
-----------------------------------------------------------------------
-
-#####R=== create_artifact ===
-
-#####GDeclaration
- extern bool create_artifact(object_type *o_ptr,
- bool a_scroll, bool get_name);
-
-#####GFile
- randart.c
-
-#####GComment
-(none)
-
-#####GDescription
-Create an artifact from object "*optr".
-
-#####GParameters
-> "*optr* is a pointer to an object
-> "a_scroll" is true if the artifact is created by reading a scroll
-> "get_name" is true if the artifact is to be named by the player (if
- a_scroll is true) or created randomly (a_scroll is false), or false
- if an inscription is used.
-
-----------------------------------------------------------------------
-
-#####R=== ident_spell ===
-
-#####GDeclaration
- extern bool ident_spell(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Identify an object in the inventory (or on the floor)
- * This routine does *not* automatically combine objects.
- * Returns TRUE if something was identified, else FALSE.
- */
-
-#####GDescription
-Identify an object in the inventory (or on the floor).
-
-----------------------------------------------------------------------
-
-#####R=== identify_fully ===
-
-#####GDeclaration
- extern bool identify_fully(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Fully "identify" an object in the inventory -BEN-
- * This routine returns TRUE if an item was identified.
- */
-
-#####GDescription
-Fully "identify" an object in the inventory (or on the floor).
-
-----------------------------------------------------------------------
-
-#####R=== recharge ===
-
-#####GDeclaration
- extern bool recharge(int num);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Recharge a wand/staff/rod from the pack or on the floor.
- * This function has been rewritten in Oangband. -LM-
- *
- * Mage -- Recharge I --> recharge(90)
- * Mage -- Recharge II --> recharge(150)
- * Mage -- Recharge III --> recharge(220)
- *
- * Priest or Necromancer -- Recharge --> recharge(140)
- *
- * Scroll of recharging --> recharge(130)
- * Scroll of *recharging* --> recharge(200)
- *
- * It is harder to recharge high level, and highly charged wands,
- * staffs, and rods. The more wands in a stack, the more easily and
- * strongly they recharge. Staffs, however, each get fewer charges if
- * stacked.
- *
- * XXX XXX XXX Beware of "sliding index errors".
- */
-
-#####GDescription
-Recharge an object in the inventory (or on the floor) with "num"
-power.
-
-#####GParameters
-> "num" is the power used in recharging. It is compared to the
- object's level to determine whether the item is recharged
- successfully or destroyed. If it is recharged, it also determines
- how many charges are added, or how much recharge time is reduced.
-
-----------------------------------------------------------------------
-
-#####R=== aggravate_monsters ===
-
-#####GDeclaration
- extern void aggravate_monsters(int who);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Wake up all monsters, and speed up "los" monsters.
- */
-
-#####GDescription
-Aggravate monsters, originating from "who".
-
-#####GParameters
-> "who" is the index of monster in m_list[] (1 if it is the player)
- which triggers the aggravation;
-
-----------------------------------------------------------------------
-
-#####R=== genocide ===
-
-#####GDeclaration
- extern bool genocide(bool player_cast);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Genocide a monster race.
-
-#####GParameters
-> "player_cast" is true if the player cast the spell so the player can
- take damage.
-
-----------------------------------------------------------------------
-
-#####R=== mass_genocide ===
-
-#####GDeclaration
- extern bool mass_genocide(bool player_cast);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Delete all nearby (non-unique) monsters
- */
-
-#####GDescription
-Delete all nearby (non-unique) monsters.
-
-#####GParameters
-> "player_cast" is true if the player cast the spell so the player can
- take damage.
-
-----------------------------------------------------------------------
-
-#####R=== probing ===
-
-#####GDeclaration
- extern bool probing(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Probe nearby monsters
- */
-
-#####GDescription
-Probe all nearby monsters.
-
-----------------------------------------------------------------------
-
-#####R=== banish_evil ===
-
-#####GDeclaration
- extern bool banish_evil(int dist);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Banish evil monsters
- */
-
-#####GDescription
-Banish nearby evil monsters doing "dist" points of GF_AWAY_EVIL
-damage.
-
-#####GParameters
-> "dist" is the amount of damage done to each monster.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_evil ===
-
-#####GDeclaration
- extern bool dispel_evil(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel evil monsters
- */
-
-#####GDescription
-Dispel nearby evil monsters doing "dam" points of GF_DISP_EVIL
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_good ===
-
-#####GDeclaration
- extern bool dispel_good(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel good monsters
- */
-
-#####GDescription
-Dispel nearby good monsters doing "dam" points of GF_DISP_GOOD
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_undead ===
-
-#####GDeclaration
- extern bool dispel_undead(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel undead monsters
- */
-
-#####GDescription
-Dispel nearby undead monsters doing "dam" points of GF_DISP_UNDEAD
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_monsters ===
-
-#####GDeclaration
- extern bool dispel_monsters(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel all monsters
- */
-
-#####GDescription
-Dispel all nearby monsters doing "dam" points of GF_DISP_ALL
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_living ===
-
-#####GDeclaration
- extern bool dispel_living(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel 'living' monsters
- */
-
-#####GDescription
-Dispel nearby living monsters doing "dam" points of GF_DISP_LIVING
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== dispel_demons ===
-
-#####GDeclaration
- extern bool dispel_demons(int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Dispel demons
- */
-
-#####GDescription
-Dispel nearby demon monsters doing "dam" points of GF_DISP_DEMON
-damage.
-
-#####GParameters
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== turn_undead ===
-
-#####GDeclaration
- extern bool turn_undead(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Turn undead
- */
-
-#####GDescription
-Turn nearby undead monsters doing a point of GF_TURN_UNDEAD damage for
-each player level.
-
-----------------------------------------------------------------------
-
-#####R=== wipe ===
-
-#####GDeclaration
- extern void wipe(int y1, int x1, int r);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Wipe -- Empties a part of the dungeon
- */
-
-#####GDescription
-Delete monsters and objects from an area of the dungeon centred at
-grid "y1,x1" for a radius "r". This does not work on special levels or
-quests. The player may be blinded. The player forgets the affected
-area and it becomes dark. All grids become floor.
-
-#####GParameters
-> "y1" is the y-coordinate of the wipe's origin.
-> "x1" is the x-coordinate of the wipe's origin.
-> "r" is the radius of the wipe.
-
-----------------------------------------------------------------------
-
-#####R=== destroy_area ===
-
-#####GDeclaration
- extern void destroy_area(int y1, int x1, int r,
- bool full);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * The spell of destruction
- *
- * This spell "deletes" monsters (instead of "killing" them).
- *
- * Later we may use one function for both "destruction" and
- * "earthquake" by using the "full" to select "destruction".
- */
-
-#####GDescription
-Delete monsters and objects from an area of the dungeon centred at
-grid "y1,x1" for a radius "r". This does not work on special levels or
-quests. The epicentre is NOT affected. The player may be blinded. The
-player forgets the affected area and it becomes dark. The grids can
-become granite, quartz, magma, or floor.
-
-#####GParameters
-> "y1" is the y-coordinate of the destruction's origin.
-> "x1" is the x-coordinate of the destruction's origin.
-> "r" is the radius of the destruction.
-> "full" is currently unused.
-
-----------------------------------------------------------------------
-
-#####R=== earthquake ===
-
-#####GDeclaration
- extern void earthquake(int cy, int cx, int r);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Induce an "earthquake" of the given radius at the given location.
- *
- * This will turn some walls into floors and some floors into walls.
- *
- * The player will take damage and "jump" into a safe grid if possible,
- * otherwise, he will "tunnel" through the rubble instantaneously.
- *
- * Monsters will take damage, and "jump" into a safe grid if possible,
- * otherwise they will be "buried" in the rubble, disappearing from
- * the level in the same way that they do when genocided.
- *
- * Note that thus the player and monsters (except eaters of walls and
- * passers through walls) will never occupy the same grid as a wall.
- * Note that as of now (2.7.8) no monster may occupy a "wall" grid, even
- * for a single turn, unless that monster can pass_walls or kill_walls.
- * This has allowed massive simplification of the "monster" code.
- */
-
-#####GDescription
-Create an earthquake centred on grid "cy,cx" with a radius of "r".
-This does not work on quest levels. The epicentre is NOT affected.
-Only about 15% of the grids are affected. The player takes 300 points
-of damage if they can't be moved to a safe grid, otherwise damage is
-from 10 to 40 points. The player forgets the affected area and it
-becomes dark. The grids can become granite, quartz, magma, or floor.
-
-#####GParameters
-Parameters:
-> "cy" is the y-coordinate of the earthquake origin.
-> "cx" is the x-coordinate of the earthquake origin.
-> "r" is the radius of the earthquake.
-
-----------------------------------------------------------------------
-
-#####R=== map_area ===
-
-#####GDeclaration
- extern void map_area(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Hack -- map the current panel (plus some) ala "magic mapping"
- */
-
-#####GDescription
-Map the current panel plus up to 10 grids up and down, and up to 20
-grids left and right.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_lite ===
-
-#####GDeclaration
- extern void wiz_lite(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Light up the dungeon using "clairvoyance"
- *
- * This function "illuminates" every grid in the dungeon, memorises all
- * "objects", memorises all grids as with magic mapping, and, under the
- * standard option settings (view_perma_grids but not view_torch_grids)
- * memorises all floor grids too.
- *
- * Note that if "view_perma_grids" is not set, we do not memorise floor
- * grids, since this would defeat the purpose of "view_perma_grids", not
- * that anyone seems to play without this option.
- *
- * Note that if "view_torch_grids" is set, we do not memorise floor grids,
- * since this would prevent the use of "view_torch_grids" as a method to
- * keep track of what grids have been observed directly.
- */
-
-#####GDescription
-Light up the entire dungeon and show all monsters and objects.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_lite_extra ===
-
-#####GDeclaration
- extern void wiz_lite_extra(void);
-
-#####GFile
- cave.c
-
-#####GComment
-(none)
-
-#####GDescription
-Light up the entire dungeon and show all monsters and objects. All
-squares are lit and remembered.
-
-----------------------------------------------------------------------
-
-#####R=== wiz_dark ===
-
-#####GDeclaration
- extern void wiz_dark(void);
-
-#####GFile
- cave.c
-
-#####GComment
-/*
- * Forget the dungeon map (ala "Thinking of Maud...").
- */
-
-#####GDescription
-Forget all grids and objects. All grids become dark.
-
-----------------------------------------------------------------------
-
-#####R=== lite_room ===
-
-#####GDeclaration
- extern void lite_room(int y1, int x1);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Illuminate any room containing the given location.
- */
-
-#####GDescription
-Light up the room (if any) of grid "y1,x1".
-
-#####GParameters
-> "y1" is the y-coordinate of the grid.
-> "x1" is the x-coordinate of the grid.
-
-----------------------------------------------------------------------
-
-#####R=== unlite_room ===
-
-#####GDeclaration
- extern void unlite_room(int y1, int x1);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Darken all rooms containing the given location
- */
-
-#####GDescription
-Darken all rooms (if any) of grid "y1,x1".
-
-#####GParameters
-> "y1" is the y-coordinate of the grid.
-> "x1" is the x-coordinate of the grid.
-
-----------------------------------------------------------------------
-
-#####R=== lite_area ===
-
-#####GDeclaration
- extern bool lite_area(int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- call light around the player
- * Affect all monsters in the projection radius
- */
-
-#####GDescription
-Light up the room (if any) of the player's grid. Monsters take "dam"
-points of GF_LITE_WEAK damage if they are within "r" grids of the
-player.
-
-#####GParameters
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage.
-
-----------------------------------------------------------------------
-
-#####R=== unlite_area ===
-
-#####GDeclaration
- extern bool unlite_area(int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- call darkness around the player
- * Affect all monsters in the projection radius
- */
-
-#####GDescription
-Darken the room (if any) of the player's grid. Monsters take "dam"
-points of GF_DARK_WEAK damage if they are within "r" grids of the
-player.
-
-#####GParameters
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_ball_beam ===
-
-#####GDeclaration
- extern bool fire_ball_beam(int typ, int dir, int dam,
- int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a ball-beamed spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball-beamed spell of type "typ" in direction "dir" for damage
-"dam" points with a radius of "rad" grids.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_ball ===
-
-#####GDeclaration
- extern bool fire_ball(int typ, int dir, int dam, int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a ball spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball spell of type "typ" in direction "dir" for "dam" points of
-damage. The ball has a radius of "rad" grids.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_bolt ===
-
-#####GDeclaration
- extern bool fire_bolt(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a bolt spell
- * Stop if we hit a monster, as a "bolt"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a bolt spell of type "typ" in direction "dir" for "dam" points of
-damage.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_beam ===
-
-#####GDeclaration
- extern bool fire_beam(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a beam spell
- * Pass through monsters, as a "beam"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a beam spell of type "typ" in direction "dir" for "dam" points of
-damage.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_ball ===
-
-#####GDeclaration
- extern bool fire_druid_ball(int typ, int dir, int dam,
- int rad);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidic ball spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-
-#####GDescription
-Cast a ball spell of type "typ" in direction "dir" for "dam" points of
-damage. The ball has a radius of "rad" grids. The spell follows a mana
-path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "rad" is the radius of the effect of the damage (must be <= 16).
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_bolt ===
-
-#####GDeclaration
- extern bool fire_druid_bolt(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidic bolt spell
- * Stop if we hit a monster, as a "bolt"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a bolt spell of type "typ" in direction "dir" for "dam" points of
-damage. The spell follows a mana path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_druid_beam ===
-
-#####GDeclaration
- extern bool fire_druid_beam(int typ, int dir, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a druidistic beam spell
- * Pass through monsters, as a "beam"
- * Affect monsters (not grids or objects)
- */
-
-#####GDescription
-Cast a beam spell of type "typ" in direction "dir" for "dam" points of
-damage. The spell follows a mana path.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== fire_bolt_or_beam ===
-
-#####GDeclaration
- extern bool fire_bolt_or_beam(int prob, int typ, int dir,
- int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Cast a bolt spell, or rarely, a beam spell
- */
-
-#####GDescription
-Cast a beam (chance of "prob" in 100) or bolt spell of type "typ" in
-direction "dir" for "dam" points of damage.
-
-#####GParameters
-> "prob" is the number of times out of 100 that the bolt will actually
- be a beam. Obviously this value should range from 1 to 99 (0 will
- always give a beam, 100 or higher will always give a beam. There are
- separate functions for these cases).
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-#####R=== alchemy ===
-
-#####GDeclaration
- extern bool alchemy(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-/* Turns an object into gold, gain some of its value in a shop */
-
-#####GDescription
-The player selects an object (and quantity if it applies) from the
-inventory or the floor and attempts to turn it into gold. If the
-price of the item is < 0 then the player gains nothing (fool's gold),
-otherwise the player gets a third of the price in gold. Artifacts are
-not affected.
-
-----------------------------------------------------------------------
-
-#####R=== alter_reality ===
-
-#####GDeclaration
- extern void alter_reality(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-The player leaves the level immediately.
-
-----------------------------------------------------------------------
-
-#####R=== teleport_swap ===
-
-#####GDeclaration
- extern void teleport_swap(int dir);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Player swaps places with target in direction "dir". The target must be
-a monster. It will not work if the space-time continuum can not be
-disrupted or if the monster resists teleportation.
-
-----------------------------------------------------------------------
-
-#####R=== project_meteor ===
-
-#####GDeclaration
- extern void project_meteor(int radius, int typ, int dam,
- u32b flg);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Apply a "project()" a la meteor shower
- */
-
-#####GDescription
-Generate between "rad" and "rad" x 2 ball spells of type "typ" for
-"dam" points of damage. The ball can have various properties as
-denoted by "flg".
-
-#####GParameters
-> "rad" is the minimum number of balls created. "rad" + randint("rad")
- balls are created. Each ball has a radius of 2 grids. Each target
- grid is within 5 grids of the player.
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dam" is the number of points of damage.
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== passwall ===
-
-#####GDeclaration
- extern bool passwall(int dir, bool safe);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Send the player shooting through walls in the given direction until
- * they reach a non-wall space, or a monster, or a permanent wall.
- */
-
-#####GDescription
-Move the player through walls in direction "dir". if "safe" then the
-player can not end up in a wall - if they do, the wall is replaced by
-a floor. This does not work in the wilderness, on quest levels, or if
-teleport is not allowed. Stopping on monsters or inside vaults is not
-allowed.
-
-#####GParameters
-> "dir" must be from 0 to 9. It can not be 5.
- *****fields.txt*0[direction]
-> "safe" must be true if the player is not to be trapped in a wall
- when the movement is finished.
-
-----------------------------------------------------------------------
-
-#####R=== project_hook ===
-
-#####GDeclaration
- extern bool project_hook(int typ, int dir, int dam,
- int flg);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Hack -- apply a "projection()" in a direction (or at the target)
- */
-
-#####GDescription
-Generate a beam/bolt of type "typ" in direction "dir" (or at a target)
-for "dam" points of damage. The beam/bolt can have various properties
-as denoted by "flg".
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dir" must be from 0 to 9. 5 means use the current target.
- *****fields.txt*0[direction]
-> "dam" is the number of points of damage.
-> "flg" is the projection effect
- *****fields.txt*0[PROJECT_fields]
-
-----------------------------------------------------------------------
-
-#####R=== reset_recall ===
-
-#####GDeclaration
- extern bool reset_recall(void);
-
-#####GFile
- spells2.c
-
-#####GComment
-(none)
-
-#####GDescription
-Ask the player for a dungeon and appropriate level within the dungeon.
-The player can not specify a dungeon they have not gone to yet. If the
-player chooses levels 99 or 100, the level is set to 98.
-
-----------------------------------------------------------------------
-
-#####R=== get_aim_dir ===
-
-#####GDeclaration
- extern bool get_aim_dir(int *dp = 0);
-
-#####GFile
- xtra2.c
-
-#####GComment
-/*
- * Get an "aiming direction" from the user.
- *
- * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
- * "0" for "current target", and "-1" for "entry aborted".
- *
- * Note that "Force Target", if set, will pre-empt user interaction,
- * if there is a usable target already set.
- *
- * Note that confusion over-rides any (explicit?) user choice.
- */
-
-#####GDescription
-Get an aiming direction from the user and store it in "dp". A target
-can be selected. If the player is confused, the direction will be
-random.
-
-#####GParameters
-> "dp" = player direction.
-
-----------------------------------------------------------------------
-
-#####R=== project_hack ===
-
-#####GDeclaration
- extern bool project_hack(int typ, int dam);
-
-#####GFile
- spells2.c
-
-#####GComment
-/*
- * Apply a "project()" directly to all viewable monsters
- *
- * Note that affected monsters are NOT auto-tracked by this usage.
- */
-
-#####GDescription
-Generate beam/bolt spells of type "typ" for "dam" points of damage to
-all viewable monsters in line of site.
-
-#####GParameters
-> "typ" is the type of damage
- *****fields.txt*0[GF_fields]
-> "dam" is the number of points of damage.
-
-----------------------------------------------------------------------
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
- [[[[[gThis file by Chris Hadgis]
diff --git a/lib/mods/theme/help/lua_util.txt b/lib/mods/theme/help/lua_util.txt
deleted file mode 100644
index 8886a2b4..00000000
--- a/lib/mods/theme/help/lua_util.txt
+++ /dev/null
@@ -1,898 +0,0 @@
-|||||oy
-
-#####R /----------------------------------------\
-#####R < util.pkg functions helper file >
-#####R \----------------------------------------/
-
-----------------------------------------------------------------------
-
-#####R=== bst ===
-
-#####GDeclaration
- s32b bst(s32b what, s32b t);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Break scalar time
- */
-
-#####GDescription
-Return the minute, hour, day, or year for turn "t". One turn takes 7.5
-seconds.
-
-#####GParameters
-> "what" is the unit to be returned and must be one of
- MINUTE (number of turns per minute, which is 8)
- HOUR (number of turns per hour, which is 480)
- DAY (number of turns per day, which is 11,520)
- YEAR (number of turns per year, which is 4,204,800)
-> "t" is the number of turns.
-
-----------------------------------------------------------------------
-
-#####R=== path_build ===
-
-#####GDeclaration
- errr path_build(char *buf, int max, cptr path, cptr file);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Create a new path by appending a file (or directory) to a path
-*
-* This requires no special processing on simple machines, except
-* for verifying the size of the filename, but note the ability to
-* bypass the given "path" with certain special file-names.
-*
-* Note that the "file" may actually be a "sub-path", including
-* a path and a file.
-*
-* Note that this function yields a path which must be "parsed"
-* using the "parse" function above.
-*/
-
-#####GDescription
-Append file "file" to path "path" and return the result in "buf". The
-length of "buf" is a maximum of "max" characters. If "file" starts
-with '~' then return "file". If "file" starts with the path separator
-and the path separator is not blank then return "file". If there is no
-path then return "file". Otherwise return "path" + path separator +
-"file". The path separator is defined in "H-config.h".
-
-#####GParameters
-> "buf" contains the new path.
-> "max" is the maximum number of characters allowed in "buf".
-> "path" is the original path.
-> "file" is the original file.
-
-----------------------------------------------------------------------
-
-#####R=== move_cursor ===
-
-#####GDeclaration
- void move_cursor(int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Move the cursor
-*/
-
-#####GDescription
-Move the cursor to row "row" and column "col".
-
-#####GParameters
-> "row" is the row the cursor is to be moved to.
-> "col" is the column the cursor is to be moved to.
-
-----------------------------------------------------------------------
-
-#####R=== inkey ===
-
-#####GDeclaration
- char inkey(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get a keypress from the user.
-*
-* This function recognises a few "global parameters". These are variables
-* which, if set to TRUE before calling this function, will have an effect
-* on this function, and which are always reset to FALSE by this function
-* 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.
-*/
-
-#####GDescription
-Get a keypress from the user.
-
-----------------------------------------------------------------------
-
-#####R=== cmsg_print ===
-
-#####GDeclaration
- void cmsg_print(byte color, cptr msg);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Output a message to the top line of the screen.
-*
-* Break long messages into multiple pieces (40-72 chars).
-*
-* Allow multiple short messages to "share" the top line.
-*
-* Prompt the user to make sure he has a chance to read them.
-*
-* These messages are memorised 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.
-*/
-
-#####GDescription
-In color "color", output message "msg" to the top line of the screen.
-If the message is blank or has more than 1000 characters, nothing is
-printed. Long messages are split after the 40th character and before
-the 72nd character.
-
-#####GParameters
-> "color" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-
-----------------------------------------------------------------------
-
-#####R=== msg_print ===
-
-#####GDeclaration
- void msg_print(cptr msg);
-
-#####GFile
- util.c
-
-#####GComment
-/* Hack -- for compatibility and easy sake */
-
-#####GDescription
-Print message "msg" in white (see cmsg_print() above).
-
-#####GParameters
-> "msg" is the message.
-
-----------------------------------------------------------------------
-
-#####R=== screen_save ===
-
-#####GDeclaration
- void screen_save(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Save the screen, and increase the "icky" depth.
- *
- * This function must match exactly one call to "screen_load()".
- */
-
-#####GDescription
-Save a screen shot.
-
-----------------------------------------------------------------------
-
-#####R=== screen_load ===
-
-#####GDeclaration
- void screen_load(void);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Load the screen, and decrease the "icky" depth.
- *
- * This function must match exactly one call to "screen_save()".
- */
-
-#####GDescription
-Load a previously saved screen shot.
-
-----------------------------------------------------------------------
-
-#####R=== c_put_str ===
-
-#####GDeclaration
- void c_put_str(byte attr, cptr str, int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Display a string on the screen using an attribute.
-*
-* At the given location, using the given attribute, if allowed,
-* add the given string. Do not clear the line.
-*/
-
-#####GDescription
-Put string "str" at row "row" and column "col" with attribute "attr".
-
-#####GParameters
-> "attr" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-> "row" is the row the message is to be printed at.
-> "col" is the column the message is to be printed at.
-
-----------------------------------------------------------------------
-
-#####R=== c_prt ===
-
-#####GDeclaration
- void c_prt(byte attr, cptr str, int row, int col);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Display a string on the screen using an attribute, and clear
-* to the end of the line.
-*/
-
-#####GDescription
-Clear row "row" from column "col". Put string "str" at "row", "col"
-with attribute "attr".
-
-#####GParameters
-> "attr" is the color of the message.
- *****fields.txt*0[colors]
-> "msg" is the message.
-> "row" is the row the message is to be printed at.
-> "col" is the column the message is to be printed at.
-
-----------------------------------------------------------------------
-
-#####R=== clear_from ===
-
-#####GDeclaration
- void clear_from(int row);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Clear part of the screen
-*/
-
-#####GDescription
-Clear the screen from row "row" onwards.
-
-#####GParameters
-> "row" is the first row of the screen to be cleared.
-
-----------------------------------------------------------------------
-
-#####R=== askfor_aux ===
-
-#####GDeclaration
- bool askfor_aux(char *buf, int len);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get some input at the cursor location.
-* Assume the buffer is initialized to a default string.
-* Note that this string is often "empty" (see below).
-* The default buffer is displayed in yellow until cleared.
-* Pressing RETURN right away accepts the default entry.
-* Normal chars clear the default and append the char.
-* 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.
-*/
-
-#####GDescription
-Get string "buf" from the screen. "buf" is to be no more than "len"
-bytes. The string starts at the current cursor position. The length
-can not exceed the number of bytes from the cursor to the end of the
-line. Accept user input until the escape or return key is pressed.
-
-#####GParameters
-> "buf" is the string returned from the screen.
-> "len" is the length of the string. If it is <1 it is forced to 1.
-
-----------------------------------------------------------------------
-
-#####R=== get_string ===
-
-#####GDeclaration
- bool get_string(cptr prompt, char *buf, int len);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Get a string from the user
-*
-* The "prompt" should take the form "Prompt: "
-*
-* Note that the initial contents of the string is used as
-* the default response, so be sure to "clear" it if needed.
-*
-* We clear the input, and return FALSE, on "ESCAPE".
-*/
-
-#####GDescription
-Print prompt "prompt" at the top-left corner of the screen and return
-response "buf" which will have a maximum length "length". If ESCAPE
-is entered, the function returns FALSE, otherwise it returns TRUE.
-
-#####GParameters
-> "prompt" is the prompt for input.
-> "buf" is the returned response.
-> "len" is the maximum length of the string.
-
-----------------------------------------------------------------------
-
-#####R=== get_check ===
-
-#####GDeclaration
- bool get_check(cptr prompt);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Verify something with the user
-*
-* The "prompt" should take the form "Query? "
-*
-* Note that "[y/n]" is appended to the prompt.
-*/
-
-#####GDescription
-Ask the user question "prompt" which requires a yes/no answer. The
-prompt appears in the top-left corner of the screen. A response of
-'Y' (either case) returns TRUE. A response of 'N' (either case) or
-ESCAPE returns FALSE.
-
-#####GParameters
-> "prompt" is the question asked. It has a maximum length of 70
- characters.
-
-----------------------------------------------------------------------
-
-#####R=== get_com_lua ===
-
-#####GDeclaration
- bool get_com_lua @ get_com(cptr promtp, int *com);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Prompts for a keypress
-*
-* The "prompt" should take the form "Command: "
-*
-* Returns TRUE unless the character is "Escape"
-*/
-
-#####GDescription
-Ask the user for command "prompt" and return the key press "com". A
-response of ESCAPE returns FALSE. All other responses return TRUE.
-
-#####GParameters
-> "prompt" is the prompt for the key press.
-> "com" is the returned key press.
-
-----------------------------------------------------------------------
-
-#####R=== get_quantity ===
-
-#####GDeclaration
- s32b get_quantity(cptr prompt, s32b max);
-
-#####GFile
- util.c
-
-#####GComment
-/*
-* Request a "quantity" from the user
-*
-* Hack -- allow "command_arg" to specify a quantity
-*/
-
-#####GDescription
-Ask the user for quantity "prompt" of maximum value "max" and return
-a quantity. If the user quantity is higher than the maximum then the
-maximum is returned. If the response is a letter then the maximum is
-returned. If the user quantity is negative then zero is returned.
-
-#####GParameters
-> "prompt" is the prompt for a quantity.
-> "max" is the maximum value allowed.
-
-----------------------------------------------------------------------
-
-#####R=== test_monster_name ===
-
-#####GDeclaration
- int test_monster_name(cptr name);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Given monster name as string, return the index in r_info array. Name
- * must exactly match (look out for commas and the like!), or else 0 is
- * returned. Case doesn't matter. -GSN-
- */
-
-#####GDescription
-Return the monster index for monster with name "name". If no match is
-found then zero is returned.
-
-#####GParameters
-> "name" is the monster name.
-
-----------------------------------------------------------------------
-
-#####R=== test_item_name ===
-
-#####GDeclaration
- int test_item_name(cptr name);
-
-#####GFile
- util.c
-
-#####GComment
-/*
- * Given item name as string, return the index in k_info array. Name
- * must exactly match (look out for commas and the like!), or else 0 is
- * returned. Case doesn't matter. -DG-
- */
-
-#####GDescription
-Return the item index for item with name "name". If no match is found
-then zero is returned.
-
-#####GParameters
-> "name" is the item name.
-
-----------------------------------------------------------------------
-
-#####R=== luck ===
-
-#####GDeclaration
- int luck(int min, int max);
-
-#####GFile
- xtra1.c
-
-#####GComment
-/*
- * Return a luck number between a certain range
- */
-
-#####GDescription
-Return a number for luck between minimum "min" and maximum "max". The
-value begins with the player's current luck. The value is forced to
-be between -30 and +30. 30 is added to give a value between 0 and 60.
-The value is multiplied by the range (maximum - minimum) and divided
-by 60. The value is increased by the minimum. The value is returned.
-
-For example, if the player's current luck is 15, the minimum is -10,
-and the maximum is 10 (range 20), then the value returned is
-(45 * 20) / 60 which is 900 / 60 which is 15 + the minimum -10 gives
-a returned value of 5.
-
-#####GParameters
-> "min" is the minimum luck.
-> "max" is the maximum luck. Beware: this should be greater than the
- minimum but it is not checked!
-
-----------------------------------------------------------------------
-
-#####R=== get_player_race_name ===
-
-#####GDeclaration
- cptr get_player_race_name(int pr, int ps);
-
-#####GFile
- util.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the name for player race "pr" and player sub-race "ps".
-
-#####GParameters
-> "pr" is the index for player race.
-> "ps" is the index for player sub-race.
-
-----------------------------------------------------------------------
-
-#####R=== quit ===
-
-#####GDeclaration
- void quit(cptr str);
-
-#####GFile
- z-util.c
-
-#####GComment
-/*
- * Exit (ala "exit()"). If 'str' is NULL, do "exit(0)".
- * If 'str' begins with "+" or "-", do "exit(atoi(str))".
- * Otherwise, plog() 'str' and exit with an error code of -1.
- * But always use 'quit_aux', if set, before anything else.
- */
-
-#####GDescription
-Quit the game. If "str" is a string then write the string to the
-error file or screen. If "str" is a number then exit with the
-number as the exit code.
-
-#####GParameters
-> "str" is an error message or exit code.
-
-----------------------------------------------------------------------
-
-#####R=== dump_hooks ===
-
-#####GDeclaration
- void dump_hooks();
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-Print the name and type (C or Lua) of hooks in the hook list.
-
-----------------------------------------------------------------------
-
-#####R=== add_hook_script ===
-
-#####GDeclaration
- void add_hook_script(int h_idx, char *script, cptr name);
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-To hook list with index "h_idx", add a script with script file
-"script" and name "name" as a Lua hook if a hook with that name
-does not already exist.
-
-#####GParameters
-> "h_idx" is the index of the hook list in the array of hook lists.
-> "script" is the name of the script file.
-> "name" is the name of the hook to be added.
-
-----------------------------------------------------------------------
-
-#####R=== del_hook_name ===
-
-#####GDeclaration
- void del_hook_name(int h_idx, cptr name);
-
-#####GFile
- plots.c
-
-#####GComment
-(none)
-
-#####GDescription
-Search hook list with index "h_idx" and remove the hook with name
-"name".
-
-#####GParameters
-> "h_idx" is the index of the hook list in the array of hook lists.
-> "name" is the name of the hook to be removed.
-
-----------------------------------------------------------------------
-
-#####R=== pern_dofile ===
-
-#####GDeclaration
- bool pern_dofile(char *file);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Parse the Lua script file "file".
-
-#####GParameters
-> "file" is the Lua script file to be parsed.
-
-----------------------------------------------------------------------
-
-#####R=== intMod ===
-
-#####GDeclaration
- s32b intMod(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of operation "a" mod "b" (a % b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intAnd ===
-
-#####GDeclaration
- s32b intAnd(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" AND "b" (a & b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intOr ===
-
-#####GDeclaration
- s32b intOr(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" OR "b" (a | b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intXor ===
-
-#####GDeclaration
- s32b intXor(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" XOR "b" (a ^ b).
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intShiftl ===
-
-#####GDeclaration
- s32b intShiftl(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" << "b".
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intShiftr ===
-
-#####GDeclaration
- s32b intShiftr(s32b a, s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation "a" >> "b".
-
-#####GParameters
-> "a" is a number.
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== intBitNot ===
-
-#####GDeclaration
- s32b intBitNot(s32b b);
-
-#####GFile
- script.c
-
-#####GComment
-(none)
-
-#####GDescription
-Return the result of bitwise operation NOT "b" (~ b).
-
-#####GParameters
-> "b" is a number.
-
-----------------------------------------------------------------------
-
-#####R=== register_savefile ===
-
-#####GDeclaration
- void register_savefile(int num);
-
-#####GFile
- loadsave.c
-
-#####GComment
-/*
- * Add num slots to the savefile
- */
-
-#####GDescription
-Add "num" slots to the save file.
-
-#####GParameters
-> "num" is the number of slots to add to the savefile. If num is <0
- then "num" is forced to zero.
-
-----------------------------------------------------------------------
-
-#####R=== save_number_key ===
-
-#####GDeclaration
- void save_number_key(char *key, s32b val);
-
-#####GFile
- util.c
-
-#####GComment
-(none)
-
-#####GDescription
-Save the length of key "key", the key itself, and the value "val" as
-bytes in the savefile.
-
-#####GParameters
-> "key" is the key string for the value.
-> "val" is the value to be saved.
-
-----------------------------------------------------------------------
-
-
-
-Back to the *****lua.hlp*0[lua help index] .
-
-
- [[[[[gThis file by Chris Hadgis]
-
diff --git a/lib/mods/theme/help/macrofaq.txt b/lib/mods/theme/help/macrofaq.txt
index 97fad944..035f674b 100644
--- a/lib/mods/theme/help/macrofaq.txt
+++ b/lib/mods/theme/help/macrofaq.txt
@@ -975,10 +975,6 @@ These are accessible through the (=) Set options command.
*****option.txt*2[(hilite_player)] -- causes the player's symbol to be drawn with the
"cursor" on it. It will be drawn with the same color as the character.
-*****option.txt*3[(player_symbols)] -- for graphics mode only, and only works when option
-(use_graphics) is also on. This apparently varies the player graphic
-and its color based on class, race, and sex.
-
#####G----------------------------------------------------------------------
#####G4.18 Recharging a rod using a Recharge Item spell
#####G----------------------------------------------------------------------
@@ -1070,15 +1066,7 @@ create a macro for a function key.
#####G5.2 How can I automatically inscribe items when I pick them up?
#####G----------------------------------------------------------------------
-You need to turn on the "Merge inscriptions when stacking" option.
-If you are already carrying the same item with an inscription, a new
-one will be added to the stack. Note that this WON'T merge discounts.
-Although discounts display like inscriptions, they are different.
-
-1) = Options
-2) 1 User interface options
-3) "Merge inscriptions when stacking" (stack_force_notes)
- move down to this line and change to "yes".
+(Content removed because it was obsolete. Inscribe-on-pickup is now the default.)
#####G----------------------------------------------------------------------
#####G5.3 Can I use macros inside other macros?
@@ -1788,9 +1776,7 @@ options screen.
rogue_like_commands
use_old_target
always_pickup
-depth_in_feet
alert_hitpoint
-auto_haggle
auto_scum
#####G----------------------------------------------------------------------
diff --git a/lib/mods/theme/help/option.txt b/lib/mods/theme/help/option.txt
index 6f538d91..00ee15a4 100644
--- a/lib/mods/theme/help/option.txt
+++ b/lib/mods/theme/help/option.txt
@@ -66,6 +66,10 @@ can also be viewed from the option menu while playing, but not changed then.
#####GYou can receive fates, good or bad [fate_option]
Allows the player to turn off ToME's *****fatespoi.txt*0[fates] for that character.
+#####GItems always sell for 0 gold [no_selling]
+ Disables selling items back to shops for money. The value of gold found in the
+ dungeon is increased to compensate.
+
~~~~~07|Options|Ingame
#####RIN GAME OPTIONS
#####R===============
@@ -109,20 +113,6 @@ off at will during the course of the game.
a door, tunnel through walls, or disarm traps or chests, that you
wish to repeat the command 99 times (see *****command.txt*0["command.txt"]).
-#####GShow dungeon level in feet [depth_in_feet]
- Display the dungeon depth in "feet" instead of as a level number (one
- level is equivalent to 50'). This also affects the monster memory display.
-
-#####GMerge inscriptions when stacking [stack_force_notes]
- Force otherwise identical objects to merge, even if one has an empty
- inscription and the other does not. The resulting stack keeps the
- non-empty inscription.
-
-#####GMerge discounts when stacking [stack_force_costs]
- Force otherwise identical objects to merge, even if they have different
- discounts. The resulting stack keeps the largest discount. This option
- may cause you to lose "value", but will give you optimal pack usage.
-
#####GAudible bell (on errors, etc) [ring_bell]
Attempt to make a "bell" noise when various errors occur.
@@ -154,7 +144,7 @@ off at will during the course of the game.
monster becomes viewable for the first time, and also whenever any
viewable monster becomes no longer viewable. This option ignores
the existence of telepathy for the purpose of determining whether
- a monster is viewable. See also the "view_reduce_view" option.
+ a monster is viewable.
#####GDisturb whenever map panel changes [disturb_panel]
This option causes you to be disturbed (stop running) when the screen
@@ -194,18 +184,6 @@ off at will during the course of the game.
dies. If this option is not selected, the "You die." message is displayed
instead.
-#####GAllow shopkeepers and uniques to speak [speak_unique]
- If this option is in use, shopkeepers may sometimes whisper rumours to
- you. Also certain monsters start boasting as they attack you, and when
- they die, they say their "last words".
-
-#####GNo query to destroy known worthless items [auto_destroy]
- It can sometimes be annoying that the Destroy command asks for confirmation
- when you are attempting to destroy a Broken sword {cursed}. If this option
- is set, no confirmation will be asked if you attempt to destroy an object
- which you know to be worthless. Of course, cursed artifacts cannot be
- destroyed even if this option is set.
-
#####GConfirm to wear/wield known cursed items [confirm_wear]
Some players may occasionally, due to a typing mistake, find themselves
wearing an item which they knew was cursed. If this option is set, you
@@ -257,18 +235,6 @@ off at will during the course of the game.
is based on the dungeon level, so the deeper you go, the better the
level will be.
-#####GAllow weapons and armor to stack [stack_allow_items]
- Allow identical weapons and armor to be combined into a stack. This
- also allows unidentified, but identical, ammo to be combined, which
- may result in the auto-identification of some of the ammo, but which
- makes it a lot easier to actually use unidentified ammo.
-
-#####GAllow wands/staffs/rods to stack [stack_allow_wands]
- Allow identical wands/staffs/rods to be combined into a stack. This
- may force the items to be unstacked to use them, which may result
- in overflow of the pack. Also, the entire stack can be recharged
- (and possibly destroyed) at the same time.
-
#####GExpand the power of the look command [expand_look]
Expand the "l"ook command to allow the user to look at grids which
are not actually in view of the player, allowing the examination of
@@ -323,27 +289,10 @@ off at will during the course of the game.
Allow monsters to make paths to the player when they are nearby. This
option is extremely slow, but can produce viciously smart monsters.
~~~~~3
-#####GUse special symbols for the player char [player_symbols]
- If this option has been compiled in, it allows you to display your
- character using race / class / sex dependent colours and graphical
- symbols. Note that the support for this option may not have been
- compiled in on all platforms.
-
-#####GPlain object descriptions [plain_descriptions]
- In ToME, this option disables "full" names for identified flavoured
- objects; in other words, if this option is not in use, an identified
- Potion of Speed could be listed (for example) as a Blue Potion of Speed.
- If you prefer simpler, less verbose descriptions, set this option.
-
#####GMonsters learn from their mistakes [smart_learn]
Allow monsters to learn what spell attacks you are resistant to,
and to use this information to choose the best attacks.
-#####GMonsters exploit players weaknesses [smart_cheat]
- Allow monsters to know what spell attacks you are resistant to, without
- first having to observe such an attack upon you, and to use this
- information to choose the best attacks.
-
#####GAllow unusually small dungeon levels [small_levels]
This option enables the creation of levels of varying sizes. Levels
that are as small as one "screen" (80x24) are possible, and they can be
@@ -370,9 +319,6 @@ off at will during the course of the game.
but is extremely annoying. Certain older versions of Angband used
this behavior always, so "purists" should turn it on.
-#####GReduce view-radius in town [view_reduce_view]
- No longer in use.
-
#####GAvoid checking for user abort [avoid_abort]
Avoid checking to see if the user has pressed a key during resting
or running or repeated commands. This not only makes the game much
@@ -489,11 +435,6 @@ Features which are unique to ToME are collected in this menu.
for new players. More experienced players may wish to switch this option
off.
-#####GShow the experience needed for the next level [exp_need]
- Setting this option alters the display of experience on the left of
- the main screen to the experience needed to reach the next character level,
- instead of the character's current total experience.
-
#####GUse the old(Z) coloring scheme(reload the game) [old_colors]
Setting this option toggles the ASCII game colour display from the
standard Angband monster colours to the Zangband-based monster colours.
diff --git a/lib/mods/theme/pref/graf-ami.prf b/lib/mods/theme/pref/graf-ami.prf
deleted file mode 100644
index d9b1b356..00000000
--- a/lib/mods/theme/pref/graf-ami.prf
+++ /dev/null
@@ -1,64 +0,0 @@
-# File: graf-ami.prf
-
-#
-# This file contains color definitions and
-# graphics remapping for the Amiga version.
-#
-# Lars Haugseth <larshau@ifi.uio.no>
-#
-
-
-# Color palette - Graphics
-V:0:0x01:0x00:0x00:0x00
-V:1:0x01:0xF0:0xE0:0xD0
-V:2:0x01:0x80:0x80:0x80
-V:3:0x01:0x50:0x50:0x50
-V:4:0x01:0xE0:0xB0:0x00
-V:5:0x01:0xC0:0xA0:0x70
-V:6:0x01:0x80:0x60:0x40
-V:7:0x01:0x40:0x30:0x20
-V:8:0x01:0x00:0xA0:0xF0
-V:9:0x01:0x00:0x00:0xF0
-V:10:0x01:0x00:0x00:0x70
-V:11:0x01:0xF0:0x00:0x00
-V:12:0x01:0x80:0x00:0x00
-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
-V:17:0x01:0xFF:0xFF:0xFF
-V:18:0x01:0xC7:0xC7:0xC7
-V:19:0x01:0xFF:0x92:0x00
-V:20:0x01:0xFF:0x00:0x00
-V:21:0x01:0x00:0xCD:0x00
-V:22:0x01:0x00:0x00:0xFE
-V:23:0x01:0xC8:0x64:0x00
-V:24:0x01:0x8A:0x8A:0x8A
-V:25:0x01:0xE0:0xE0:0xE0
-V:26:0x01:0xA5:0x00:0xFF
-V:27:0x01:0xFF:0xFD:0x00
-V:28:0x01:0xFF:0x00:0xBC
-V:29:0x01:0x00:0xFF:0x00
-V:30:0x01:0x00:0xC8:0xFF
-V:31:0x01:0xFF:0xCC:0x80
-
-
-# Standard file
-%:graf-xxx.prf
-
-
-### Feature attr/char definitions
-
-# nothing
-F:0:0x01/0x20
-
-# open floor
-F:1:0x81/0x8E
-
-# invis trap
-F:2:0x81/0x8E
-
-
diff --git a/lib/mods/theme/pref/graf-dos.prf b/lib/mods/theme/pref/graf-dos.prf
deleted file mode 100644
index 41f38c76..00000000
--- a/lib/mods/theme/pref/graf-dos.prf
+++ /dev/null
@@ -1,15 +0,0 @@
-# File: graf-win.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/mods/theme/pref/graf-ibm.prf b/lib/mods/theme/pref/graf-ibm.prf
deleted file mode 100644
index eee54a13..00000000
--- a/lib/mods/theme/pref/graf-ibm.prf
+++ /dev/null
@@ -1,6237 +0,0 @@
-# File: graf-ibm.prf
-
-# This file defines special attr/char mappings for use in the pseudo
-# graphics mode using character generator font redefinitions. It can
-# also be used with X11/XAW/GTK ports by generating a bdf (then pcf)
-# file from lib/xtra/angband.fnt. How to do so is beyond the scope of
-# this file.
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-##### 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:0x00/0x2A
-S:0x31:0x01/0x2A
-S:0x32:0x02/0x2A
-S:0x33:0x03/0x2A
-S:0x34:0x04/0x2A
-S:0x35:0x05/0x2A
-S:0x36:0x06/0x2A
-S:0x37:0x07/0x2A
-S:0x38:0x08/0x2A
-S:0x39:0x09/0x2A
-S:0x3A:0x0A/0x2A
-S:0x3B:0x0B/0x2A
-S:0x3C:0x0C/0x2A
-S:0x3D:0x0D/0x2A
-S:0x3E:0x0E/0x2A
-S:0x3F:0x0F/0x2A
-
-# Spells (|)
-S:0x40:0x00/0x7C
-S:0x41:0x01/0x7C
-S:0x42:0x02/0x7C
-S:0x43:0x03/0x7C
-S:0x44:0x04/0x7C
-S:0x45:0x05/0x7C
-S:0x46:0x06/0x7C
-S:0x47:0x07/0x7C
-S:0x48:0x08/0x7C
-S:0x49:0x09/0x7C
-S:0x4A:0x0A/0x7C
-S:0x4B:0x0B/0x7C
-S:0x4C:0x0C/0x7C
-S:0x4D:0x0D/0x7C
-S:0x4E:0x0E/0x7C
-S:0x4F:0x0F/0x7C
-
-# Spells (-)
-S:0x50:0x00/0x2D
-S:0x51:0x01/0x2D
-S:0x52:0x02/0x2D
-S:0x53:0x03/0x2D
-S:0x54:0x04/0x2D
-S:0x55:0x05/0x2D
-S:0x56:0x06/0x2D
-S:0x57:0x07/0x2D
-S:0x58:0x08/0x2D
-S:0x59:0x09/0x2D
-S:0x5A:0x0A/0x2D
-S:0x5B:0x0B/0x2D
-S:0x5C:0x0C/0x2D
-S:0x5D:0x0D/0x2D
-S:0x5E:0x0E/0x2D
-S:0x5F:0x0F/0x2D
-
-# Spells (/)
-S:0x60:0x00/0x2F
-S:0x61:0x01/0x2F
-S:0x62:0x02/0x2F
-S:0x63:0x03/0x2F
-S:0x64:0x04/0x2F
-S:0x65:0x05/0x2F
-S:0x66:0x06/0x2F
-S:0x67:0x07/0x2F
-S:0x68:0x08/0x2F
-S:0x69:0x09/0x2F
-S:0x6A:0x0A/0x2F
-S:0x6B:0x0B/0x2F
-S:0x6C:0x0C/0x2F
-S:0x6D:0x0D/0x2F
-S:0x6E:0x0E/0x2F
-S:0x6F:0x0F/0x2F
-
-# Spells (\)
-S:0x70:0x00/0x5C
-S:0x71:0x01/0x5C
-S:0x72:0x02/0x5C
-S:0x73:0x03/0x5C
-S:0x74:0x04/0x5C
-S:0x75:0x05/0x5C
-S:0x76:0x06/0x5C
-S:0x77:0x07/0x5C
-S:0x78:0x08/0x5C
-S:0x79:0x09/0x5C
-S:0x7A:0x0A/0x5C
-S:0x7B:0x0B/0x5C
-S:0x7C:0x0C/0x5C
-S:0x7D:0x0D/0x5C
-S:0x7E:0x0E/0x5C
-S:0x7F:0x0F/0x5C
-
-# Amulets
-S:0x80:0x00/0xE7
-S:0x81:0x01/0xE7
-S:0x82:0x02/0xE7
-S:0x83:0x03/0xE7
-S:0x84:0x04/0xE7
-S:0x85:0x05/0xE7
-S:0x86:0x06/0xE7
-S:0x87:0x07/0xE7
-S:0x88:0x08/0xE7
-S:0x89:0x09/0xE7
-S:0x8A:0x0A/0xE7
-S:0x8B:0x0B/0xE7
-S:0x8C:0x0C/0xE7
-S:0x8D:0x0D/0xE7
-S:0x8E:0x0E/0xE7
-S:0x8F:0x0F/0xE7
-
-# Rings
-S:0x90:0x00/0xE8
-S:0x91:0x01/0xE8
-S:0x92:0x02/0xE8
-S:0x93:0x03/0xE8
-S:0x94:0x04/0xE8
-S:0x95:0x05/0xE8
-S:0x96:0x06/0xE8
-S:0x97:0x07/0xE8
-S:0x98:0x08/0xE8
-S:0x99:0x09/0xE8
-S:0x9A:0x0A/0xE8
-S:0x9B:0x0B/0xE8
-S:0x9C:0x0C/0xE8
-S:0x9D:0x0D/0xE8
-S:0x9E:0x0E/0xE8
-S:0x9F:0x0F/0xE8
-
-# Staffs
-S:0xA0:0x00/0xE9
-S:0xA1:0x01/0xE9
-S:0xA2:0x02/0xE9
-S:0xA3:0x03/0xE9
-S:0xA4:0x04/0xE9
-S:0xA5:0x05/0xE9
-S:0xA6:0x06/0xE9
-S:0xA7:0x07/0xE9
-S:0xA8:0x08/0xE9
-S:0xA9:0x09/0xE9
-S:0xAA:0x0A/0xE9
-S:0xAB:0x0B/0xE9
-S:0xAC:0x0C/0xE9
-S:0xAD:0x0D/0xE9
-S:0xAE:0x0E/0xE9
-S:0xAF:0x0F/0xE9
-
-# Wands
-S:0xB0:0x00/0xEA
-S:0xB1:0x01/0xEA
-S:0xB2:0x02/0xEA
-S:0xB3:0x03/0xEA
-S:0xB4:0x04/0xEA
-S:0xB5:0x05/0xEA
-S:0xB6:0x06/0xEA
-S:0xB7:0x07/0xEA
-S:0xB8:0x08/0xEA
-S:0xB9:0x09/0xEA
-S:0xBA:0x0A/0xEA
-S:0xBB:0x0B/0xEA
-S:0xBC:0x0C/0xEA
-S:0xBD:0x0D/0xEA
-S:0xBE:0x0E/0xEA
-S:0xBF:0x0F/0xEA
-
-# Rods
-S:0xC0:0x00/0xEB
-S:0xC1:0x01/0xEB
-S:0xC2:0x02/0xEB
-S:0xC3:0x03/0xEB
-S:0xC4:0x04/0xEB
-S:0xC5:0x05/0xEB
-S:0xC6:0x06/0xEB
-S:0xC7:0x07/0xEB
-S:0xC8:0x08/0xEB
-S:0xC9:0x09/0xEB
-S:0xCA:0x0A/0xEB
-S:0xCB:0x0B/0xEB
-S:0xCC:0x0C/0xEB
-S:0xCD:0x0D/0xEB
-S:0xCE:0x0E/0xEB
-S:0xCF:0x0F/0xEB
-
-# Scrolls
-S:0xD0:0x00/0xEC
-S:0xD1:0x01/0xEC
-S:0xD2:0x02/0xEC
-S:0xD3:0x03/0xEC
-S:0xD4:0x04/0xEC
-S:0xD5:0x05/0xEC
-S:0xD6:0x06/0xEC
-S:0xD7:0x07/0xEC
-S:0xD8:0x08/0xEC
-S:0xD9:0x09/0xEC
-S:0xDA:0x0A/0xEC
-S:0xDB:0x0B/0xEC
-S:0xDC:0x0C/0xEC
-S:0xDD:0x0D/0xEC
-S:0xDE:0x0E/0xEC
-S:0xDF:0x0F/0xEC
-
-# Potions
-S:0xE0:0x00/0xED
-S:0xE1:0x01/0xED
-S:0xE2:0x02/0xED
-S:0xE3:0x03/0xED
-S:0xE4:0x04/0xED
-S:0xE5:0x05/0xED
-S:0xE6:0x06/0xED
-S:0xE7:0x07/0xED
-S:0xE8:0x08/0xED
-S:0xE9:0x09/0xED
-S:0xEA:0x0A/0xED
-S:0xEB:0x0B/0xED
-S:0xEC:0x0C/0xED
-S:0xED:0x0D/0xED
-S:0xEE:0x0E/0xED
-S:0xEF:0x0F/0xED
-
-# Food
-S:0xF0:0x00/0xEE
-S:0xF1:0x01/0xEE
-S:0xF2:0x02/0xEE
-S:0xF3:0x03/0xEE
-S:0xF4:0x04/0xEE
-S:0xF5:0x05/0xEE
-S:0xF6:0x06/0xEE
-S:0xF7:0x07/0xEE
-S:0xF8:0x08/0xEE
-S:0xF9:0x09/0xEE
-S:0xFA:0x0A/0xEE
-S:0xFB:0x0B/0xEE
-S:0xFC:0x0C/0xEE
-S:0xFD:0x0D/0xEE
-S:0xFE:0x0E/0xEE
-S:0xFF:0x0F/0xEE
-
-
-##### Feature attr/char definitions #####
-
-# nothing
-# F:0:0x01/0x20
-
-# open floor
-F:1:0x01/0xB5
-
-# fountain
-F:2:0x0E/0xC8
-
-# glyph of warding
-F:3:0x0B/0xC6
-
-# open door
-F:4:0x0F/0xB9
-
-# broken door
-F:5:0x0F/0xBA
-
-# up staircase
-F:6:0x01/0xB6
-
-# down staircase
-F:7:0x01/0xB7
-
-# quest entrance
-F:8:0x0B/0xB7
-
-# quest exit
-F:9:0x0B/0xB6
-
-# quest down level
-F:10:0x04/0xB7
-
-# quest up level
-F:11:0x04/0xB6
-
-# town exit
-F:12:0x05/0xB7
-
-# shaft down
-F:13:0x0F/0xB7
-
-# shaft up
-F:14:0x0F/0xB6
-
-# fountain
-F:15:0x08/0xC8
-
-# web
-F:16:0x0B/0xCA
-
-# trap
-F:17:0x01/0xC7
-
-# door
-F:32:0x0F/0xB8
-
-# locked door
-F:33:0x0F/0xB8
-
-# locked door
-F:34:0x0F/0xB8
-
-# locked door
-F:35:0x0F/0xB8
-
-# locked door
-F:36:0x0F/0xB8
-
-# locked door
-F:37:0x0F/0xB8
-
-# locked door
-F:38:0x0F/0xB8
-
-# locked door
-F:39:0x0F/0xB8
-
-# jammed door
-F:40:0x0F/0xB8
-
-# jammed door
-F:41:0x0F/0xB8
-
-# jammed door
-F:42:0x0F/0xB8
-
-# jammed door
-F:43:0x0F/0xB8
-
-# jammed door
-F:44:0x0F/0xB8
-
-# jammed door
-F:45:0x0F/0xB8
-
-# jammed door
-F:46:0x0F/0xB8
-
-# jammed door
-F:47:0x0F/0xB8
-
-# secret door
-F:48:0x02/0xBC
-
-# pile of rubble
-F:49:0x02/0xBB
-
-# magma vein
-F:50:0x01/0xBC
-
-# quartz vein
-F:51:0x09/0xBC
-
-# magma vein
-F:52:0x01/0xBC
-
-# quartz vein
-F:53:0x09/0xBC
-
-# magma vein with treasure
-F:54:0x03/0xBC
-
-# quartz vein with treasure
-F:55:0x03/0xBC
-
-# granite wall
-F:56:0x02/0xBC
-
-# granite wall
-F:57:0x02/0xBC
-
-# granite wall
-F:58:0x02/0xBC
-
-# granite wall
-F:59:0x02/0xBC
-
-# permanent wall
-F:60:0x02/0xBC
-
-# permanent wall
-F:61:0x02/0xBC
-
-# permanent wall
-F:62:0x02/0xBC
-
-# permanent wall
-F:63:0x02/0xBC
-
-# explosive rune
-F:64:0x0C/0xC6
-
-# Straight Road startpoint
-F:65:0x01/0xCA
-
-# section of the Straight Road
-F:66:0x0E/0xCA
-
-# section of the Straight Road
-F:67:0x06/0xCA
-
-# section of the Straight Road
-F:68:0x0E/0xCA
-
-# section of the Straight Road
-F:69:0x06/0xCA
-
-# section of the Straight Road
-F:70:0x09/0xCA
-
-# section of the Straight Road (discharged)
-F:71:0x09/0xCA
-
-# Straight Road exit
-F:72:0x01/0xCA
-
-# corrupted section of the Straight Road
-F:73:0x08/0xCA
-
-# Building
-F:74:0x0F/0xC5
-
-# permanent wall
-F:75:0x02/0xBC
-
-# permanent wall
-F:76:0x02/0xBC
-
-# permanent wall
-F:77:0x02/0xBC
-
-# permanent wall
-F:78:0x02/0xBC
-
-# stream of shallow water
-F:84:0x0E/0xCB
-
-# pool of deep lava
-F:85:0x04/0xCB
-
-# stream of shallow lava
-F:86:0x0C/0xCB
-
-# dark pit
-F:87:0x08/0xD0
-
-# dirt
-F:88:0x07/0xB5
-
-# patch of grass
-F:89:0x0D/0xC9
-
-# ice
-F:90:0x01/0xD0
-
-# sand
-F:91:0x0F/0xB5
-
-# dead tree
-F:92:0x08/0xCC
-
-# ash
-F:93:0x02/0xB5
-
-# mud
-F:94:0x07/0xB5
-
-# ice wall
-F:95:0x01/0xCF
-
-# tree
-F:96:0x05/0xCC
-
-# mountain chain
-F:97:0x02/0xCE
-
-# sandwall
-F:98:0x0F/0xCF
-
-# sandwall
-F:99:0x0F/0xCF
-
-# sandwall with treasure
-F:100:0x03/0xCF
-
-# high mountain chain
-F:101:0x01/0xCE
-
-# nether mist
-F:102:0x0A/0xCA
-
-# Void Jumpgate
-F:160:0x0A/0xB9
-
-# Altar of Being
-F:161:0x09/0xD1
-
-# Altar of Winds
-F:162:0x0E/0xD1
-
-# Altar of Force
-F:163:0x0C/0xD1
-
-# Altar of Darkness
-F:164:0x08/0xD1
-
-# Altar of Nature
-# F:165:0x05/0x30
-
-# floor
-F:172:0x01/0xB5
-
-# Underground Tunnel
-F:173:0x02/0xB9
-
-# stream of tainted water
-F:174:0x0A/0xCB
-
-# monster trap
-F:175:0x0A/0xC6
-
-# Void Jumpgate
-F:176:0x0A/0xB9
-
-# lava wall
-F:177:0x0C/0xBC
-
-# Great Fire
-F:178:0x0C/0xCB
-
-# path to the next area
-F:179:0x01/0xB7
-
-# path to the previous area
-F:180:0x01/0xB6
-
-# field
-F:181:0x05/0xB5
-
-# Ekkaia, the Encircling Sea
-F:182:0x06/0xCB
-
-# pool of deep water
-F:187:0x06/0xCB
-
-# glass wall
-F:188:0x0E/0xD0
-
-# illusion wall
-F:189:0x02/0xBC
-
-# Grass roof
-F:190:0x0F/0xCA
-
-# grass roof top
-F:191:0x0F/0xCA
-
-# grass roof chimney
-F:192:0x0F/0xCA
-
-# brick roof
-F:193:0x04/0xCF
-
-# brick roof top
-F:194:0x04/0xCF
-
-# brick roof chimney
-F:195:0x04/0xCF
-
-# window
-F:196:0x01/0x4F
-
-# small window
-F:197:0x01/0x6F
-
-# rain barrel
-F:198:0x02/0xBC
-
-# grass with flowers
-F:199:0x04/0xC9
-
-# cobblestone road
-F:200:0x02/0xB5
-
-# cobblestone with outlet
-F:201:0x02/0xB5
-
-# small tree
-F:202:0x0D/0xCD
-
-# town
-F:203:0x01/0xC5
-
-# Underground Tunnel
-F:204:0x02/0xB9
-
-# a blazing fire
-F:205:0x0C/0xCB
-
-# pile of rubble
-F:206:0x02/0xBB
-
-# rocky ground
-F:207:0x02/0xB5
-
-# cloud-like vapour
-F:208:0x09/0xCA
-
-# condensing water
-F:209:0x0E/0xCB
-
-# dense mist
-F:210:0x01/0xCA
-
-# hail-stone wall
-F:211:0x09/0xBC
-
-
-##### Building attr/char definitions #####
-
-# General Store
-B:0:0x0F/0xBD
-
-# Armoury
-B:1:0x02/0xBE
-
-# Weaponsmith
-B:2:0x01/0xBF
-
-# Temple
-B:3:0x05/0xC0
-
-# Alchemy shop
-B:4:0x06/0xC1
-
-# Magic shop
-B:5:0x04/0xC4
-
-# Black Market
-B:6:0x08/0xC3
-
-# Home
-B:7:0x0B/0xB8
-
-# Book Store
-B:8:0x03/0xC2
-
-# Pet Shop
-B:9:0x06/0xB8
-
-# Mayor's Office
-B:10:0x03/0xB8
-
-# Inn
-B:11:0x01/0xB8
-
-# The Soothsayer
-B:12:0x0E/0xB8
-
-# Library
-B:13:0x0F/0xC2
-
-# Castle
-B:14:0x03/0xB8
-
-# Casino
-B:15:0x02/0xB8
-
-# Beastmaster Shanty
-B:16:0x05/0xB8
-
-# Fighters Hall
-B:17:0x02/0xB8
-
-# Tower of Magery
-B:18:0x06/0xB8
-
-# Inner Temple
-B:19:0x0D/0xC0
-
-# Paladins Guild
-B:20:0x05/0xB8
-
-# Rangers Guild
-B:21:0x07/0xB8
-
-# Thunderlords' Nest
-B:22:0x0F/0xB8
-
-# The Mirror
-B:23:0x0F/0xB8
-
-# Seat of Ruling
-B:24:0x0F/0xCC
-
-# Wizards Spire
-B:25:0x0F/0xB8
-
-# Priests Circle
-B:26:0x03/0xB8
-
-# Tower of the King
-B:27:0x0F/0xB8
-
-# Library
-B:28:0x0F/0xC2
-
-# The White Tree
-B:29:0x01/0xCC
-
-# Craftsmaster
-B:30:0x02/0xB8
-
-# Earth-Dome (Nature)
-B:31:0x0F/0xB8
-
-# Minstrels Haven
-B:32:0x0F/0xB8
-
-# Star-Dome
-B:33:0x0F/0xB8
-
-# Valarin Temple
-B:34:0x0F/0xC0
-
-# Sea-Dome
-B:35:0x0F/0xB8
-
-# The Golden Flower
-B:36:0x0F/0xB8
-
-# The Fountain
-B:37:0x0F/0xC8
-
-# Axe Smith
-B:38:0x01/0xBF
-
-# Hafted Smith
-B:39:0x01/0xBF
-
-# Polearm Smith
-B:40:0x01/0xBF
-
-# Sword Smith
-B:41:0x01/0xBF
-
-# Rare Jewelry Shop
-B:42:0x0A/0xC4
-
-# Jewelry Shop
-B:43:0x0B/0xC4
-
-# Footwear Shop
-B:44:0x04/0xBE
-
-# Rare Footwear Shop
-B:45:0x04/0xBE
-
-# Library
-B:46:0x0B/0xC2
-
-# Forbidden Library
-B:47:0x0A/0xC2
-
-# Expensive Black Market
-B:48:0x0A/0xC3
-
-# Common Shop
-B:49:0x0F/0xBD
-
-# Dragon Hunter
-B:50:0x0A/0xBE
-
-# Speed Ring Market
-B:51:0x0D/0xC4
-
-# Scribe
-B:52:0x0E/0xC1
-
-# Potion Store
-B:53:0x0E/0xC1
-
-# Recaller
-B:54:0x06/0xB8
-
-# Master Archer
-B:55:0x05/0xBF
-
-# Merchants Guild
-B:56:0x05/0xB8
-
-# The Mathom-house
-B:57:0x05/0xB8
-
-# The Prancing Pony
-B:58:0x01/0xB8
-
-# Mining Supply store
-B:59:0x02/0xB8
-
-
-##### Object attr/char definitions #####
-
-# something
-# K:0:0x01/0x26
-
-# Blindness
-K:1:0x00/0xEE
-
-# Paranoia
-K:2:0x00/0xEE
-
-# Confusion
-K:3:0x00/0xEE
-
-# Hallucination
-K:4:0x00/0xEE
-
-# Cure Poison
-K:5:0x00/0xEE
-
-# Cure Blindness
-K:6:0x00/0xEE
-
-# Cure Paranoia
-K:7:0x00/0xEE
-
-# Cure Confusion
-K:8:0x00/0xEE
-
-# Weakness
-K:9:0x00/0xEE
-
-# Unhealth
-K:10:0x00/0xEE
-
-# Restore Constitution
-K:11:0x00/0xEE
-
-# Restoring
-K:12:0x00/0xEE
-
-# Stupidity
-K:13:0x00/0xEE
-
-# Naivety
-K:14:0x00/0xEE
-
-# Poison
-K:15:0x00/0xEE
-
-# Sickness
-K:16:0x00/0xEE
-
-# Paralysis
-K:17:0x00/0xEE
-
-# Restore Strength
-K:18:0x00/0xEE
-
-# Disease
-K:19:0x00/0xEE
-
-# Cure Serious Wounds
-K:20:0x00/0xEE
-
-# & Ration~ of Food
-K:21:0x0F/0xF2
-
-# & Hard Biscuit~
-K:22:0x0F/0xF2
-
-# & Strip~ of Venison
-K:23:0x07/0xF2
-
-# & Slime Mold~
-K:24:0x05/0xF2
-
-# & Lembas~
-K:25:0x0E/0xF2
-
-# & Pint~ of Fine Ale
-K:26:0x0B/0xED
-
-# & Pint~ of Fine Wine
-K:27:0x04/0xED
-
-# & Mattock~
-K:28:0x08/0xD9
-
-# & Blue Stone~
-K:29:0x0E/0xE7
-
-# & Broken Dagger~
-K:30:0x08/0xDC
-
-# & Bastard Sword~
-K:31:0x09/0xDC
-
-# & Scimitar~
-K:32:0x09/0xDC
-
-# & Tulwar~
-K:33:0x09/0xDC
-
-# & Broad Sword~
-K:34:0x09/0xDC
-
-# & Short Sword~
-K:35:0x09/0xDC
-
-# & Blade~ of Chaos
-K:36:0x0A/0xDC
-
-# & Two-Handed Sword~
-K:37:0x09/0xDC
-
-# & Main Gauche~
-K:38:0x09/0xDC
-
-# & Cutlass~
-K:39:0x09/0xDC
-
-# & Executioner's Sword~
-K:40:0x04/0xDC
-
-# & Katana~
-K:41:0x09/0xDC
-
-# & Long Sword~
-K:42:0x09/0xDC
-
-# & Dagger~
-K:43:0x09/0xDC
-
-# & Rapier~
-K:44:0x09/0xDC
-
-# & Sabre~
-K:45:0x09/0xDC
-
-# & Small Sword~
-K:46:0x09/0xDC
-
-# & Broken Sword~
-K:47:0x08/0xDC
-
-# & Ball-and-Chain~
-K:48:0x08/0xDA
-
-# & Whip~
-K:49:0x08/0xDA
-
-# & Flail~
-K:50:0x08/0xDA
-
-# & Two-Handed Flail~
-K:51:0x0B/0xDA
-
-# & Morning Star~
-K:52:0x08/0xDA
-
-# & Mace~
-K:53:0x08/0xDA
-
-# & Quarterstaff~
-K:54:0x0F/0xDA
-
-# & War Hammer~
-K:55:0x08/0xDA
-
-# & Lead-Filled Mace~
-K:56:0x08/0xDA
-
-# & Mace~ of Disruption
-K:57:0x0A/0xDA
-
-# & Lucerne Hammer~
-K:58:0x0E/0xDA
-
-# & Beaked Axe~
-K:59:0x02/0xDB
-
-# & Glaive~
-K:60:0x02/0xDB
-
-# & Halberd~
-K:61:0x02/0xDB
-
-# & Awl-Pike~
-K:62:0x02/0xDB
-
-# & Pike~
-K:63:0x02/0xDB
-
-# & Spear~
-K:64:0x02/0xDB
-
-# & Trident~
-K:65:0x0B/0xDB
-
-# & Lance~
-K:66:0x02/0xDB
-
-# & Great Axe~
-K:67:0x02/0xDB
-
-# & Battle Axe~
-K:68:0x02/0xDB
-
-# & Lochaber Axe~
-K:69:0x08/0xDB
-
-# & Broad Axe~
-K:70:0x02/0xDB
-
-# & Scythe~
-K:71:0x02/0xDB
-
-# & Scythe~ of Slicing
-K:72:0x04/0xDB
-
-# & Short Bow~
-K:73:0x0F/0xD8
-
-# & Long Bow~
-K:74:0x0F/0xD8
-
-# & Light Crossbow~
-K:75:0x02/0xD8
-
-# & Heavy Crossbow~
-K:76:0x02/0xD8
-
-# & Sling~
-K:77:0x07/0xD8
-
-# & Arrow~
-K:78:0x0F/0xD7
-
-# & Seeker Arrow~
-K:79:0x0D/0xD7
-
-# & Bolt~
-K:80:0x02/0xD7
-
-# & Seeker Bolt~
-K:81:0x0E/0xD7
-
-# & Rounded Pebble~
-K:82:0x02/0xD6
-
-# & Iron Shot~
-K:83:0x02/0xD6
-
-# & Shovel~
-K:84:0x02/0xD9
-
-# & Gnomish Shovel~
-K:85:0x0D/0xD9
-
-# & Dwarven Shovel~
-K:86:0x0E/0xD9
-
-# & Pick~
-K:87:0x02/0xD9
-
-# & Orcish Pick~
-K:88:0x05/0xD9
-
-# & Dwarven Pick~
-K:89:0x06/0xD9
-
-# & Elven Cloak~
-K:90:0x0D/0xE2
-
-# & Pair~ of Soft Leather Boots
-K:91:0x0F/0xDD
-
-# & Pair~ of Hard Leather Boots
-K:92:0x0F/0xDD
-
-# & Pair~ of Metal Shod Boots
-K:93:0x02/0xDD
-
-# & Hard Leather Cap~
-K:94:0x07/0xDF
-
-# & Metal Cap~
-K:95:0x02/0xDF
-
-# & Iron Helm~
-K:96:0x02/0xDF
-
-# & Steel Helm~
-K:97:0x09/0xDF
-
-# & Iron Crown~
-K:98:0x02/0xE0
-
-# & Golden Crown~
-K:99:0x0B/0xE0
-
-# & Jewel Encrusted Crown~
-K:100:0x0A/0xE0
-
-# & Robe~
-K:101:0x06/0xE3
-
-# & Filthy Rag~
-K:102:0x08/0xE3
-
-# Soft Leather Armour~
-K:103:0x0F/0xE3
-
-# Soft Studded Leather~
-K:104:0x0F/0xE3
-
-# Hard Leather Armour~
-K:105:0x0F/0xE3
-
-# Hard Studded Leather~
-K:106:0x0F/0xE3
-
-# Leather Scale Mail~
-K:107:0x0F/0xE3
-
-# Metal Scale Mail~
-K:108:0x02/0xE4
-
-# Chain Mail~
-K:109:0x02/0xE4
-
-# Rusty Chain Mail~
-K:110:0x04/0xE4
-
-# Augmented Chain Mail~
-K:111:0x02/0xE4
-
-# Bar Chain Mail~
-K:112:0x02/0xE4
-
-# Metal Brigandine Armour~
-K:113:0x02/0xE4
-
-# Partial Plate Armour~
-K:114:0x09/0xE4
-
-# Metal Lamellar Armour~
-K:115:0x09/0xE4
-
-# Full Plate Armour~
-K:116:0x09/0xE4
-
-# Ribbed Plate Armour~
-K:117:0x09/0xE4
-
-# Adamantite Plate Mail~
-K:118:0x0D/0xE4
-
-# Mithril Plate Mail~
-K:119:0x0E/0xE4
-
-# Mithril Chain Mail~
-K:120:0x0E/0xE4
-
-# Double Chain Mail~
-K:121:0x02/0xE4
-
-# & Shield~ of Deflection
-K:122:0x0E/0xE1
-
-# & Cloak~
-K:123:0x05/0xE2
-
-# & Shadow Cloak~
-K:124:0x08/0xE2
-
-# & Set~ of Leather Gloves
-K:125:0x0F/0xDE
-
-# & Set~ of Gauntlets
-K:126:0x0F/0xDE
-
-# & Set~ of Cesti
-K:127:0x09/0xDE
-
-# & Small Leather Shield~
-K:128:0x0F/0xE1
-
-# & Large Leather Shield~
-K:129:0x0F/0xE1
-
-# & Small Metal Shield~
-K:130:0x02/0xE1
-
-# & Large Metal Shield~
-K:131:0x02/0xE1
-
-# Strength
-K:132:0x00/0xE8
-
-# Dexterity
-K:133:0x00/0xE8
-
-# Constitution
-K:134:0x00/0xE8
-
-# Intelligence
-K:135:0x00/0xE8
-
-# Speed
-K:136:0x00/0xE8
-
-# Searching
-K:137:0x00/0xE8
-
-# Teleportation
-K:138:0x00/0xE8
-
-# Slow Digestion
-K:139:0x00/0xE8
-
-# Fire Resistance
-K:140:0x00/0xE8
-
-# Cold Resistance
-K:141:0x00/0xE8
-
-# Levitation
-K:142:0x00/0xE8
-
-# Poison Resistance
-K:143:0x00/0xE8
-
-# Free Action
-K:144:0x00/0xE8
-
-# Weakness
-K:145:0x00/0xE8
-
-# Flames
-K:146:0x00/0xE8
-
-# Acid
-K:147:0x00/0xE8
-
-# Ice
-K:148:0x00/0xE8
-
-# Woe
-K:149:0x00/0xE8
-
-# Stupidity
-K:150:0x00/0xE8
-
-# Damage
-K:151:0x00/0xE8
-
-# Accuracy
-K:152:0x00/0xE8
-
-# Protection
-K:153:0x00/0xE8
-
-# Aggravate Monster
-K:154:0x00/0xE8
-
-# See Invisible
-K:155:0x00/0xE8
-
-# Sustain Strength
-K:156:0x00/0xE8
-
-# Sustain Intelligence
-K:157:0x00/0xE8
-
-# Sustain Wisdom
-K:158:0x00/0xE8
-
-# Sustain Constitution
-K:159:0x00/0xE8
-
-# Sustain Dexterity
-K:160:0x00/0xE8
-
-# Sustain Charisma
-K:161:0x00/0xE8
-
-# Slaying
-K:162:0x00/0xE8
-
-# Brilliance
-K:163:0x00/0xE7
-
-# Charisma
-K:164:0x00/0xE7
-
-# Searching
-K:165:0x00/0xE7
-
-# Teleportation
-K:166:0x00/0xE7
-
-# Slow Digestion
-K:167:0x00/0xE7
-
-# Acid Resistance
-K:168:0x00/0xE7
-
-# Adornment
-K:169:0x00/0xE7
-
-# Double Ring Mail~
-K:170:0x02/0xE4
-
-# the Magi
-K:171:0x00/0xE7
-
-# Doom
-K:172:0x00/0xE7
-
-# Enchant Weapon To-Hit
-K:173:0x00/0xEC
-
-# Enchant Weapon To-Dam
-K:174:0x00/0xEC
-
-# Enchant Armor
-K:175:0x00/0xEC
-
-# Identify
-K:176:0x00/0xEC
-
-# *Identify*
-K:177:0x00/0xEC
-
-# Rumour
-K:178:0x00/0xEC
-
-# Chaos
-K:179:0x00/0xEC
-
-# Remove Curse
-K:180:0x00/0xEC
-
-# Light
-K:181:0x00/0xEC
-
-# Fire
-K:182:0x00/0xEC
-
-# Ice
-K:183:0x00/0xEC
-
-# Summon Monster
-K:184:0x00/0xEC
-
-# Phase Door
-K:185:0x00/0xEC
-
-# Teleportation
-K:186:0x00/0xEC
-
-# Teleport Level
-K:187:0x00/0xEC
-
-# Monster Confusion
-K:188:0x00/0xEC
-
-# Magic Mapping
-K:189:0x00/0xEC
-
-# Rune of Protection
-K:190:0x00/0xEC
-
-# *Remove Curse*
-K:191:0x00/0xEC
-
-# Treasure Detection
-K:192:0x00/0xEC
-
-# Object Detection
-K:193:0x00/0xEC
-
-# Trap Detection
-K:194:0x00/0xEC
-
-# & Sheaf Arrow~
-K:195:0x03/0xD7
-
-# & Mithril Shot~
-K:196:0x0E/0xD6
-
-# Door/Stair Location
-K:197:0x00/0xEC
-
-# Acquirement
-K:198:0x00/0xEC
-
-# *Acquirement*
-K:199:0x00/0xEC
-
-# Mass Genocide
-K:200:0x00/0xEC
-
-# Detect Invisible
-K:201:0x00/0xEC
-
-# Aggravate Monster
-K:202:0x00/0xEC
-
-# Trap Creation
-K:203:0x00/0xEC
-
-# Trap/Door Destruction
-K:204:0x00/0xEC
-
-# Artifact Creation
-K:205:0x00/0xEC
-
-# Recharging
-K:206:0x00/0xEC
-
-# Genocide
-K:207:0x00/0xEC
-
-# Darkness
-K:208:0x00/0xEC
-
-# Protection from Evil
-K:209:0x00/0xEC
-
-# Satisfy Hunger
-K:210:0x00/0xEC
-
-# Dispel Undead
-K:211:0x00/0xEC
-
-# *Enchant Weapon*
-K:212:0x00/0xEC
-
-# Curse Weapon
-K:213:0x00/0xEC
-
-# *Enchant Armor*
-K:214:0x00/0xEC
-
-# Curse Armor
-K:215:0x00/0xEC
-
-# Summon Undead
-K:216:0x00/0xEC
-
-# Blessing
-K:217:0x00/0xEC
-
-# Holy Chant
-K:218:0x00/0xEC
-
-# Holy Prayer
-K:219:0x00/0xEC
-
-# Word of Recall
-K:220:0x00/0xEC
-
-# *Destruction*
-K:221:0x00/0xEC
-
-# Slime Mold Juice
-K:222:0x00/0xED
-
-# Apple Juice
-K:223:0x00/0xED
-
-# Water
-K:224:0x00/0xED
-
-# Strength
-K:225:0x00/0xED
-
-# Weakness
-K:226:0x00/0xED
-
-# Restore Strength
-K:227:0x00/0xED
-
-# Intelligence
-K:228:0x00/0xED
-
-# Stupidity
-K:229:0x00/0xED
-
-# Restore Intelligence
-K:230:0x00/0xED
-
-# Wisdom
-K:231:0x00/0xED
-
-# Naivety
-K:232:0x00/0xED
-
-# Restore Wisdom
-K:233:0x00/0xED
-
-# Charisma
-K:234:0x00/0xED
-
-# Ugliness
-K:235:0x00/0xED
-
-# Restore Charisma
-K:236:0x00/0xED
-
-# Curing
-K:237:0x00/0xED
-
-# Invulnerability
-K:238:0x00/0xED
-
-# New Life
-K:239:0x00/0xED
-
-# Cure Serious Wounds
-K:240:0x00/0xED
-
-# Cure Critical Wounds
-K:241:0x00/0xED
-
-# Healing
-K:242:0x00/0xED
-
-# Constitution
-K:243:0x00/0xED
-
-# Experience
-K:244:0x00/0xED
-
-# Sleep
-K:245:0x00/0xED
-
-# Blindness
-K:246:0x00/0xED
-
-# Booze
-K:247:0x00/0xED
-
-# Poison
-K:248:0x00/0xED
-
-# Speed
-K:249:0x00/0xED
-
-# Slowness
-K:250:0x00/0xED
-
-# Dexterity
-K:251:0x00/0xED
-
-# Restore Dexterity
-K:252:0x00/0xED
-
-# Restore Constitution
-K:253:0x00/0xED
-
-# Lose Memories
-K:254:0x00/0xED
-
-# Salt Water
-K:255:0x00/0xED
-
-# Enlightenment
-K:256:0x00/0xED
-
-# Heroism
-K:257:0x00/0xED
-
-# Berserk Strength
-K:258:0x00/0xED
-
-# Boldness
-K:259:0x00/0xED
-
-# Restore Life Levels
-K:260:0x00/0xED
-
-# Resist Heat
-K:261:0x00/0xED
-
-# Resist Cold
-K:262:0x00/0xED
-
-# Detect Invisible
-K:263:0x00/0xED
-
-# Slow Poison
-K:264:0x00/0xED
-
-# Neutralise Poison
-K:265:0x00/0xED
-
-# Restore Mana
-K:266:0x00/0xED
-
-# Infra-vision
-K:267:0x00/0xED
-
-# Resistance
-K:268:0x00/0xED
-
-# Spell
-K:269:0x00/0xEA
-
-# Manathrust
-K:270:0x00/0xEA
-
-# Fireflash
-K:271:0x00/0xEA
-
-# Firewall
-K:272:0x00/0xEA
-
-# Tidal Wave
-K:273:0x00/0xEA
-
-# Ice Storm
-K:274:0x00/0xEA
-
-# Noxious Cloud
-K:275:0x00/0xEA
-
-# Poison Blood
-K:276:0x00/0xEA
-
-# Thunderstorm
-K:277:0x00/0xEA
-
-# Dig
-K:278:0x00/0xEA
-
-# Stone Prison
-K:279:0x00/0xEA
-
-# Strike
-K:280:0x00/0xEA
-
-# Teleport Away
-K:281:0x00/0xEA
-
-# Summon Animal
-K:282:0x00/0xEA
-
-# Magelock
-K:283:0x00/0xEA
-
-# Slow Monster
-K:284:0x00/0xEA
-
-# Essence of Speed
-K:285:0x00/0xEA
-
-# Banishment
-K:286:0x00/0xEA
-
-# Disperse Magic
-K:287:0x00/0xEA
-
-# Charm
-K:288:0x00/0xEA
-
-# Confuse
-K:289:0x00/0xEA
-
-# Demon Blade
-K:290:0x00/0xEA
-
-# Heal Monster
-K:291:0x00/0xEA
-
-# Haste Monster
-K:292:0x00/0xEA
-
-# & Flight Arrow~
-K:293:0x0B/0xD7
-
-# Spell
-K:300:0x00/0xE9
-
-# Nothing
-K:301:0x00/0xE9
-
-# Globe of Light
-K:302:0x00/0xE9
-
-# Fiery Shield
-K:303:0x00/0xE9
-
-# Remove Curses
-K:304:0x00/0xE9
-
-# Wings of Winds
-K:305:0x00/0xE9
-
-# Shake
-K:306:0x00/0xE9
-
-# Disarm
-K:307:0x00/0xE9
-
-# Teleportation
-K:308:0x00/0xE9
-
-# Probability Travel
-K:309:0x00/0xE9
-
-# Recovery
-K:310:0x00/0xE9
-
-# Healing
-K:311:0x00/0xE9
-
-# Vision
-K:312:0x00/0xE9
-
-# Identify
-K:313:0x00/0xE9
-
-# Sense Hidden
-K:314:0x00/0xE9
-
-# Reveal Ways
-K:315:0x00/0xE9
-
-# Sense Monsters
-K:316:0x00/0xE9
-
-# Genocide
-K:317:0x00/0xE9
-
-# Summon
-K:318:0x00/0xE9
-
-# Wish
-K:320:0x00/0xE9
-
-# Mana
-K:321:0x00/0xE9
-
-# & Tome~ of Magical Energy
-K:330:0x0E/0xEF
-
-# & Tome~ of the Eternal Flame
-K:331:0x0C/0xEF
-
-# & Tome~ of the Blowing Wind
-K:332:0x06/0xEF
-
-# & Tome~ of the Impenetrable Earth
-K:333:0x0F/0xEF
-
-# & Tome~ of the Everrunning Wave
-K:334:0x0E/0xEF
-
-# & Tome~ of Translocation
-K:335:0x0E/0xEF
-
-# & Tome~ of the Tree
-K:336:0x0D/0xEF
-
-# & Tome~ of Knowledge
-K:337:0x08/0xEF
-
-# & Small wooden chest~
-K:338:0x02/0xD5
-
-# & Large wooden chest~
-K:339:0x02/0xD5
-
-# & Small iron chest~
-K:340:0x02/0xD5
-
-# & Large iron chest~
-K:341:0x02/0xD5
-
-# & Small steel chest~
-K:342:0x02/0xD5
-
-# & Large steel chest~
-K:343:0x02/0xD5
-
-# & Ruined chest~
-K:344:0x02/0xD5
-
-# & Iron Spike~
-K:345:0x09/0xD4
-
-# & Wooden Torch~
-K:346:0x07/0xF1
-
-# & Brass Lantern~
-K:347:0x0F/0xE6
-
-# & Flask~ of oil
-K:348:0x0B/0xED
-
-# & Empty Bottle~
-K:349:0x01/0xED
-
-# Havoc
-K:350:0x00/0xEB
-
-# Door/Stair Location
-K:351:0x00/0xEB
-
-# Trap Location
-K:352:0x00/0xEB
-
-# Probing
-K:353:0x00/0xEB
-
-# Recall
-K:354:0x00/0xEB
-
-# Illumination
-K:355:0x00/0xEB
-
-# Light
-K:356:0x00/0xEB
-
-# Lightning Bolts
-K:357:0x00/0xEB
-
-# Frost Bolts
-K:358:0x00/0xEB
-
-# Fire Bolts
-K:359:0x00/0xEB
-
-# Polymorph
-K:360:0x00/0xEB
-
-# Slow Monster
-K:361:0x00/0xEB
-
-# Sleep Monster
-K:362:0x00/0xEB
-
-# Drain Life
-K:363:0x00/0xEB
-
-# Teleport Other
-K:364:0x00/0xEB
-
-# Disarming
-K:365:0x00/0xEB
-
-# Lightning Balls
-K:366:0x00/0xEB
-
-# Cold Balls
-K:367:0x00/0xEB
-
-# Fire Balls
-K:368:0x00/0xEB
-
-# Acid Balls
-K:369:0x00/0xEB
-
-# Acid Bolts
-K:370:0x00/0xEB
-
-# Enlightenment
-K:371:0x00/0xEB
-
-# Perception
-K:372:0x00/0xEB
-
-# Curing
-K:373:0x00/0xEB
-
-# Healing
-K:374:0x00/0xEB
-
-# Detection
-K:375:0x00/0xEB
-
-# Restoration
-K:376:0x00/0xEB
-
-# Speed
-K:377:0x00/0xEB
-
-# Spell
-K:378:0x00/0xE8
-
-# Spell
-K:379:0x00/0xE7
-
-# & Broken Skull~
-K:391:0x01/0xD3
-
-# & Broken Bone~
-K:392:0x01/0xD3
-
-# & Canine Skeleton~
-K:393:0x01/0xD3
-
-# & Rodent Skeleton~
-K:394:0x01/0xD3
-
-# & Human Skeleton~
-K:395:0x01/0xD3
-
-# & Dwarf Skeleton~
-K:396:0x01/0xD3
-
-# & Elf Skeleton~
-K:397:0x01/0xD3
-
-# & Gnome Skeleton~
-K:398:0x01/0xD3
-
-# & Great Hammer~
-K:399:0x08/0xDA
-
-# Black Dragon Scale Mail~
-K:400:0x02/0xE5
-
-# Blue Dragon Scale Mail~
-K:401:0x06/0xE5
-
-# White Dragon Scale Mail~
-K:402:0x01/0xE5
-
-# Red Dragon Scale Mail~
-K:403:0x04/0xE5
-
-# Green Dragon Scale Mail~
-K:404:0x05/0xE5
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x0A/0xE5
-
-# Pseudo Dragon Scale Mail~
-K:406:0x0A/0xE5
-
-# Law Dragon Scale Mail~
-K:407:0x0E/0xE5
-
-# Bronze Dragon Scale Mail~
-K:408:0x0F/0xE5
-
-# Gold Dragon Scale Mail~
-K:409:0x0B/0xE5
-
-# Chaos Dragon Scale Mail~
-K:410:0x0A/0xE5
-
-# Balance Dragon Scale Mail~
-K:411:0x0A/0xE5
-
-# Power Dragon Scale Mail~
-K:412:0x0A/0xE5
-
-# & Dragon Helm~
-K:413:0x0D/0xDF
-
-# & Dragon Shield~
-K:414:0x0D/0xE1
-
-# Death
-K:415:0x00/0xED
-
-# Ruination
-K:416:0x00/0xED
-
-# Detonations
-K:417:0x00/0xED
-
-# Augmentation
-K:418:0x00/0xED
-
-# *Healing*
-K:419:0x00/0xED
-
-# Life
-K:420:0x00/0xED
-
-# Self Knowledge
-K:421:0x00/0xED
-
-# *Enlightenment*
-K:422:0x00/0xED
-
-# Fear Resistance
-K:425:0x00/0xE8
-
-# Light and Darkness Resistance
-K:426:0x00/0xE8
-
-# Nether Resistance
-K:427:0x00/0xE8
-
-# Nexus Resistance
-K:428:0x00/0xE8
-
-# Sound Resistance
-K:429:0x00/0xE8
-
-# Confusion Resistance
-K:430:0x00/0xE8
-
-# Shard Resistance
-K:431:0x00/0xE8
-
-# Disenchantment Resistance
-K:432:0x00/0xE8
-
-# Chaos Resistance
-K:433:0x00/0xE8
-
-# Blindness Resistance
-K:434:0x00/0xE8
-
-# Lordly Protection
-K:435:0x00/0xE8
-
-# Extra Attacks
-K:436:0x00/0xE8
-
-# Cure Light Wounds
-K:437:0x00/0xED
-
-# Clumsiness
-K:438:0x00/0xED
-
-# Sickliness
-K:439:0x00/0xED
-
-# Map of Bree
-K:440:0x02/0xEC
-
-# Map of Gondolin
-K:441:0x02/0xEC
-
-# Map of Lothlorien
-K:442:0x02/0xEC
-
-# Map of Minas Anor
-K:443:0x02/0xEC
-
-# & Silver Arrow~
-K:465:0x09/0xD7
-
-# & Silver Bolt~
-K:466:0x01/0xD7
-
-# Lightning Resistance
-K:467:0x00/0xE7
-
-# Wisdom
-K:468:0x00/0xE7
-
-# Regeneration
-K:469:0x00/0xE7
-
-# Infravision
-K:470:0x00/0xE7
-
-# Devotion
-K:471:0x00/0xE7
-
-# Weaponmastery
-K:472:0x00/0xE7
-
-# Trickery
-K:473:0x00/0xE7
-
-# Telepathy
-K:474:0x00/0xE7
-
-# Sustenance
-K:475:0x00/0xE7
-
-# & Palantir~
-K:476:0x0B/0xF0
-
-# & Elfstone~
-K:477:0x05/0xE7
-
-# & Jewel~
-K:478:0x01/0xE7
-
-# & Ring~
-K:479:0x00/0xE8
-
-# copper
-K:480:0x07/0xF3
-
-# copper
-K:481:0x07/0xF3
-
-# copper
-K:482:0x07/0xF3
-
-# silver
-K:483:0x02/0xF3
-
-# silver
-K:484:0x02/0xF3
-
-# silver
-K:485:0x02/0xF3
-
-# garnets
-K:486:0x04/0xF4
-
-# garnets
-K:487:0x04/0xF4
-
-# gold
-K:488:0x0B/0xF3
-
-# gold
-K:489:0x0B/0xF3
-
-# gold
-K:490:0x0B/0xF3
-
-# opals
-K:491:0x09/0xF4
-
-# sapphires
-K:492:0x06/0xF4
-
-# rubies
-K:493:0x04/0xF4
-
-# diamonds
-K:494:0x01/0xF4
-
-# emeralds
-K:495:0x05/0xF4
-
-# mithril
-K:496:0x0E/0xF3
-
-# adamantite
-K:497:0x0D/0xF3
-
-# & Mighty Hammer~
-K:498:0x08/0xDA
-
-# & Massive Iron Crown~
-K:499:0x08/0xE0
-
-# & Phial~
-K:500:0x0B/0xF0
-
-# & Star~
-K:501:0x0E/0xF0
-
-# & Arkenstone~
-K:502:0x0C/0xF0
-
-# & Amulet~
-K:503:0x00/0xE7
-
-# & Amulet~
-K:504:0x00/0xE7
-
-# & Necklace~
-K:505:0x00/0xE7
-
-# & Ring~
-K:506:0x00/0xE8
-
-# & Ring~
-K:507:0x00/0xE8
-
-# & Ring~
-K:508:0x00/0xE8
-
-# & Ring~
-K:509:0x00/0xE8
-
-# & Ring~
-K:510:0x00/0xE8
-
-# & Ring~
-K:511:0x0B/0xE8
-
-# Reflection
-K:520:0x00/0xE7
-
-# Anti-Magic
-K:521:0x00/0xE7
-
-# Anti-Teleportation
-K:522:0x00/0xE7
-
-# Resistance
-K:523:0x00/0xE7
-
-# & Zweihander~
-K:524:0x01/0xDC
-
-# & Dwarven Lantern~
-K:525:0x06/0xE6
-
-# Splint Mail~
-K:526:0x08/0xE4
-
-# & Everburning Torch~
-K:527:0x0C/0xF1
-
-# & Trifurcate Spear~
-K:528:0x03/0xDB
-
-# & Three Piece Rod~
-K:529:0x07/0xDA
-
-# & Feanorian Lamp~
-K:530:0x0E/0xE6
-
-# & Fur Cloak~
-K:531:0x09/0xE2
-
-# Water Curing
-K:532:0x00/0xED
-
-# & Hatchet~
-K:533:0x02/0xDB
-
-# Rhino Hide Armour~
-K:535:0x02/0xE3
-
-# Leather Jacket~
-K:536:0x0F/0xE3
-
-# & Sickle~
-K:537:0x02/0xDB
-
-# & Club~
-K:542:0x07/0xDA
-
-# & Broad Spear~
-K:543:0x01/0xDB
-
-# & Khopesh~
-K:544:0x09/0xDC
-
-# & Flamberge~
-K:545:0x09/0xDC
-
-# & Claymore~
-K:546:0x09/0xDC
-
-# & Espadon~
-K:547:0x09/0xDC
-
-# & Great Scimitar~
-K:548:0x09/0xDC
-
-# Arrow
-K:549:0x04/0xF8
-
-# Bolt
-K:550:0x03/0xF8
-
-# & Fauchard~
-K:551:0x02/0xDB
-
-# & Guisarme~
-K:552:0x02/0xDB
-
-# & Heavy Lance~
-K:553:0x02/0xDB
-
-# & Basillard~
-K:554:0x01/0xDC
-
-# Catapult
-K:555:0x0C/0xF8
-
-# Ring Mail~
-K:556:0x02/0xE4
-
-# Cord Armour~
-K:557:0x0B/0xE3
-
-# Paper Armour~
-K:558:0x01/0xE3
-
-# Padded Armour~
-K:559:0x0B/0xE3
-
-# Fumes
-K:560:0x0D/0xF8
-
-# Stone and Hide Armour~
-K:561:0x0F/0xE3
-
-# Magic
-K:562:0x05/0xF8
-
-# Device
-K:563:0x0A/0xF8
-
-# Nothing
-K:564:0x00/0xEC
-
-# Poison
-K:565:0x0D/0xF6
-
-# Nothing
-K:566:0x00/0xEA
-
-# Nothing
-K:567:0x00/0xE8
-
-# Nothing
-K:568:0x00/0xE9
-
-# Nothing
-K:569:0x00/0xEB
-
-# Explosion
-K:570:0x0D/0xF6
-
-# Teleport
-K:571:0x0D/0xF6
-
-# Nothing
-K:572:0x00/0xE7
-
-# & Blood~ of Life
-K:573:0x00/0xED
-
-# Cold
-K:574:0x0D/0xF6
-
-# Fire
-K:575:0x0D/0xF6
-
-# Acid
-K:576:0x0D/0xF6
-
-# & Mage Staff~
-K:577:0x0E/0xE9
-
-# Lightning
-K:578:0x00/0xE8
-
-# Life
-K:579:0x0D/0xF6
-
-# Confusion
-K:580:0x0D/0xF6
-
-# Light
-K:581:0x0D/0xF6
-
-# & Ring~
-K:582:0x0B/0xE8
-
-# Invisibility
-K:583:0x00/0xED
-
-# Chaos
-K:584:0x0D/0xF6
-
-# Corruption
-K:585:0x00/0xED
-
-# Invisibility
-K:586:0x00/0xE8
-
-# Time
-K:587:0x0D/0xF6
-
-# Deep Thoughts
-K:588:0x03/0xEC
-
-# More Deep Thoughts
-K:589:0x03/0xEC
-
-# Compendium of Deep Thoughts
-K:590:0x03/0xEC
-
-# Artifact Lore Vol. I
-K:591:0x03/0xEC
-
-# Artifact Lore Vol. II
-K:592:0x03/0xEC
-
-# Artifact Lore Vol. III
-K:593:0x03/0xEC
-
-# Monstrous Compendium 1
-K:594:0x03/0xEC
-
-# Monstrous Compendium 2
-K:595:0x03/0xEC
-
-# Monstrous Compendium 3
-K:596:0x03/0xEC
-
-# Monstrous Compendium 4
-K:597:0x03/0xEC
-
-# Monstrous Compendium 5
-K:598:0x03/0xEC
-
-# Monstrous Compendium 6
-K:599:0x03/0xEC
-
-# Monstrous Compendium 7
-K:600:0x03/0xEC
-
-# Monstrous Compendium 8
-K:601:0x03/0xEC
-
-# Monstrous Compendium 9
-K:602:0x03/0xEC
-
-# Monstrous Compendium 10
-K:603:0x03/0xEC
-
-# Monstrous Compendium 11
-K:604:0x03/0xEC
-
-# Abomination
-K:605:0x00/0xED
-
-# Shape of Wolf
-K:606:0x00/0xED
-
-# Shape of Ape
-K:607:0x00/0xED
-
-# Shape of Goat
-K:608:0x00/0xED
-
-# Shape of Insect
-K:609:0x00/0xED
-
-# Shape of Sparrow
-K:610:0x00/0xED
-
-# Shape of Ent
-K:611:0x00/0xED
-
-# Shape of Vampire
-K:612:0x00/0xED
-
-# Shape of Spider
-K:613:0x00/0xED
-
-# Shape of Mana ball
-K:614:0x00/0xED
-
-# Shape of Fire cloud
-K:615:0x00/0xED
-
-# Shape of Cold cloud
-K:616:0x00/0xED
-
-# Shape of Chaos cloud
-K:617:0x00/0xED
-
-# [Wolf]
-K:618:0x0B/0xE2
-
-# [Ape]
-K:619:0x0B/0xE2
-
-# [Goat]
-K:620:0x0B/0xE2
-
-# [Insect]
-K:621:0x0B/0xE2
-
-# [Sparrow]
-K:622:0x0B/0xE2
-
-# [Ent]
-K:623:0x0B/0xE2
-
-# [Vampire]
-K:624:0x0B/0xE2
-
-# [Spider]
-K:625:0x0B/0xE2
-
-# [Mana ball]
-K:626:0x0B/0xE2
-
-# [Fire cloud]
-K:627:0x0B/0xE2
-
-# [Cold cloud]
-K:628:0x0B/0xE2
-
-# [Chaos Cloud]
-K:629:0x0B/0xE2
-
-# [Ghost]
-K:630:0x0B/0xE2
-
-# [Kobold]
-K:631:0x0B/0xE2
-
-# [Dragon]
-K:632:0x0B/0xE2
-
-# [Demon]
-K:633:0x0B/0xE2
-
-# [Hound]
-K:634:0x0B/0xE2
-
-# [Quylthulg]
-K:635:0x0B/0xE2
-
-# [Maia]
-K:636:0x0B/0xE2
-
-# [Serpent]
-K:637:0x0B/0xE2
-
-# [Giant]
-K:638:0x0B/0xE2
-
-# [Vala]
-K:639:0x0B/0xE2
-
-# Magic
-K:640:0x0D/0xF6
-
-# corpse
-K:641:0x0F/0xD2
-
-# skeleton
-K:642:0x0F/0xD2
-
-# head
-K:643:0x0F/0xD2
-
-# skull
-K:644:0x0F/0xD2
-
-# raw meat
-K:645:0x0F/0xD2
-
-# & Thunderlord Coat~
-K:646:0x0B/0xE3
-
-# & Stone~
-K:647:0x05/0xF0
-
-# & Small Wooden Boomerang~
-K:648:0x0B/0xD8
-
-# & Wooden Boomerang~
-K:649:0x0B/0xD8
-
-# & Small Metal Boomerang~
-K:650:0x0B/0xD8
-
-# & metal Boomerang~
-K:651:0x0B/0xD8
-
-# & Anchor~
-K:652:0x0A/0xF0
-
-# & ~
-K:653:0x0B/0xD2
-
-# Summon Never-Moving Pet
-K:654:0x00/0xEC
-
-# Cure Light Insanity
-K:657:0x00/0xED
-
-# Cure Serious Insanity
-K:658:0x00/0xED
-
-# Cure Critical Insanity
-K:659:0x00/0xED
-
-# Cure Insanity
-K:660:0x00/0xED
-
-# & Phial~
-K:661:0x0B/0xF0
-
-# Random Artifact
-K:662:0x03/0xD3
-
-# Craftmanship
-K:663:0x00/0xEC
-
-# The One Ring
-K:664:0x02/0xEC
-
-# & Book~ of the Lays of the Heroes
-K:665:0x0B/0xEF
-
-# & Book~ of Sound Patterns
-K:666:0x0B/0xEF
-
-# & Flute~
-K:669:0x09/0xF7
-
-# & Drum~
-K:670:0x09/0xF7
-
-# & Harp~
-K:671:0x09/0xF7
-
-# & Banjo~
-K:672:0x09/0xF7
-
-# & Lute~
-K:673:0x09/0xF7
-
-# & Mandolin~
-K:674:0x09/0xF7
-
-# & Palantir~
-K:675:0x0B/0xF0
-
-# Egg
-K:676:0x09/0xD6
-
-# Reset Recall
-K:677:0x00/0xEC
-
-# Divination
-K:678:0x00/0xEC
-
-# Self
-K:679:0x06/0xF5
-
-# Ray
-K:680:0x06/0xF5
-
-# Sphere
-K:681:0x06/0xF5
-
-# Knowledge
-K:682:0x06/0xF5
-
-# Life
-K:683:0x08/0xF5
-
-# Fire
-K:684:0x04/0xF5
-
-# Cold
-K:685:0x06/0xF5
-
-# Lightning
-K:686:0x09/0xF5
-
-# Acid
-K:687:0x0E/0xF5
-
-# Element
-K:688:0x05/0xF5
-
-# Chaos
-K:689:0x0A/0xF5
-
-# Mind
-K:690:0x08/0xF5
-
-# Holding
-K:691:0x0E/0xF5
-
-# Arrow
-K:692:0x06/0xF5
-
-# Power Surge
-K:693:0x06/0xF5
-
-# Armageddon
-K:694:0x06/0xF5
-
-# Gravity
-K:695:0x0D/0xF5
-
-# Extra Life
-K:696:0x0D/0xF6
-
-# Undeath
-K:697:0x0D/0xF5
-
-# Protection
-K:698:0x0D/0xF5
-
-# & Horn~
-K:699:0x09/0xF7
-
-# & Ring~ of Precognition
-K:700:0x00/0xE8
-
-# & Sprig~ of Athelas
-K:701:0x05/0xF2
-
-# & Old Scroll~ of Deincarnation
-K:720:0x00/0xEC
-
-# & Dark Sword~
-K:721:0x08/0xDC
-
-# Numenorean for Beginners (I)
-K:722:0x02/0xEC
-
-# Numenorean for Beginners (II)
-K:723:0x02/0xEC
-
-# Advanced lessons of Numenorean
-K:724:0x02/0xEC
-
-# Advanced lessons of Sindarin
-K:725:0x02/0xEC
-
-# & Shard~ of Pottery
-K:726:0x04/0xD3
-
-# & Broken Stick~
-K:727:0x04/0xD3
-
-# & Book~ of Beginner Cantrips
-K:738:0x01/0xEF
-
-# & Book~ of Teleportation
-K:739:0x01/0xEF
-
-# & Book~ of Recall
-K:740:0x01/0xEF
-
-# & Book~ of Summoning
-K:741:0x01/0xEF
-
-# & Book~ of Fireflash
-K:742:0x01/0xEF
-
-# & Potion~ of Learning
-K:743:0x00/0xED
-
-# Spell
-K:749:0x00/0xEC
-
-# Khuzdul - The Hidden Tongue of the Dwarves
-K:751:0x02/0xEC
-
-# Nandorin for Dummies
-K:752:0x02/0xEC
-
-# Advanced Lessons of Orcish
-K:753:0x02/0xEC
-
-# Flying
-K:755:0x00/0xE8
-
-# & Tome~ of the Time
-K:756:0x06/0xEF
-
-# & Spellbook~ of #
-K:757:0x01/0xEF
-
-# & Tome~ of Meta Spells
-K:758:0x0A/0xEF
-
-# & Tome~ of the Mind
-K:759:0x0E/0xEF
-
-# & Holy Tome~ of Eru Iluvatar
-K:760:0x0D/0xEF
-
-# & Holy Tome~ of Manwe Sulimo
-K:761:0x0E/0xEF
-
-# & War Tome~ of Tulkas
-K:762:0x0C/0xEF
-
-# & Unholy Tome~ of the Hellflame
-K:763:0x0A/0xEF
-
-# & Corrupted Tome~ of Melkor
-K:764:0x08/0xEF
-
-# & Forest Tome~ of Yavanna
-K:768:0x0D/0xEF
-
-# & Ring~
-K:770:0x00/0xE8
-
-# [Earth]
-K:771:0x0C/0xEF
-
-# [Fire]
-K:772:0x0C/0xEF
-
-# [Air]
-K:773:0x04/0xEF
-
-# [Water]
-K:774:0x04/0xEF
-
-# [Mana]
-K:775:0x04/0xEF
-
-# Home Summoning
-K:776:0x00/0xEB
-
-# & Shadow Blade~
-K:777:0x08/0xDC
-
-# & Bluesteel Blade~
-K:778:0x06/0xDC
-
-# the Serpents
-K:779:0x0D/0xE7
-
-# Darkness
-K:780:0x0D/0xF6
-
-# Knowledge
-K:781:0x0D/0xF6
-
-# Force
-K:782:0x0D/0xF6
-
-# Lightning
-K:783:0x0D/0xF6
-
-# Mana
-K:784:0x0D/0xF6
-
-# Ring~ of Power
-K:785:0x00/0xE8
-
-# Climbing Set~
-K:786:0x0E/0xF8
-
-# Adventurer's Guide to Middle-earth
-K:787:0x03/0xEC
-
-# & Demonblade~
-K:788:0x0C/0xEF
-
-# & Demonshield~
-K:789:0x0C/0xEF
-
-# & Demonhorn~
-K:790:0x0C/0xEF
-
-# & Wooden Rod~ of#
-K:793:0x07/0xEB
-
-# & Copper Rod~ of#
-K:794:0x02/0xEB
-
-# & Iron Rod~ of#
-K:795:0x08/0xEB
-
-# & Moonstone Rod~ of#
-K:796:0x0F/0xEB
-
-# & Silver Rod~ of#
-K:797:0x02/0xEB
-
-# & Golden Rod~ of#
-K:798:0x0B/0xEB
-
-# & Mithril Rod~ of#
-K:799:0x0E/0xEB
-
-# & Adamantite Rod~ of#
-K:800:0x0A/0xEB
-
-# & Greater Ration~ of Health
-K:801:0x05/0xF2
-
-# & Crumpled Scroll~ of Mass Resurrection
-K:802:0x00/0xEC
-
-# & Cleaver~
-K:803:0x02/0xDB
-
-# & Light War Axe~
-K:804:0x02/0xDB
-
-# & Slaughter Axe~
-K:805:0x0D/0xDB
-
-# & Runestone~
-K:806:0x0A/0xF5
-
-# & Fortune cookie~
-K:807:0x0F/0xF2
-
-# Portable hole
-K:808:0x0E/0xF8
-
-# Critical Hits
-K:809:0x00/0xE8
-
-# & Wand~ of Digging of Thrain
-K:810:0x00/0xEA
-
-# & Gnarled Staff~ of Holy Fire of Mithrandir
-K:811:0x00/0xE9
-
-# Partial Totem
-K:812:0x0A/0xF8
-
-# True Totem
-K:813:0x0A/0xF8
-
-# & Piece~ of the Relic of Eru
-K:814:0x0A/0xD3
-
-# & Piece~ of the Relic of Manwe
-K:815:0x0A/0xD3
-
-# & Piece~ of the Relic of Tulkas
-K:816:0x0A/0xD3
-
-# & Piece~ of the Relic of Melkor
-K:817:0x0A/0xD3
-
-# & Piece~ of the Relic of Yavanna
-K:818:0x0A/0xD3
-
-
-##### Monster attr/char definitions #####
-
-# Player
-R:0:0x01/0x80
-
-# Filthy street urchin
-R:1:0x08/0xAE
-
-# Scrawny cat
-R:2:0x0F/0xA0
-
-# Sparrow
-R:3:0x0F/0x82
-
-# Chaffinch
-R:4:0x04/0x82
-
-# Wild rabbit
-R:5:0x0F/0xAC
-
-# Woodsman
-R:6:0x05/0xAE
-
-# Scruffy little dog
-R:7:0x0F/0x83
-
-# Farmer Maggot
-R:8:0x01/0xA2
-
-# Blubbering idiot
-R:9:0x09/0xAE
-
-# Boil-covered wretch
-R:10:0x05/0xAE
-
-# Village idiot
-R:11:0x0D/0xAE
-
-# Pitiful-looking beggar
-R:12:0x0F/0xAE
-
-# Mangy-looking leper
-R:13:0x07/0xAE
-
-# Agent of the black market
-R:14:0x06/0xAE
-
-# Singing, happy drunk
-R:15:0x0B/0xAE
-
-# Aimless-looking merchant
-R:16:0x03/0xAE
-
-# Mean-looking mercenary
-R:17:0x04/0xAE
-
-# Battle-scarred veteran
-R:18:0x0E/0xAE
-
-# Martti Ihrasaari
-R:19:0x01/0x90
-
-# Grey mold
-R:20:0x02/0xA7
-
-# Large white snake
-R:21:0x01/0x8A
-
-# Grey mushroom patch
-R:22:0x02/0xEE
-
-# Newt
-R:23:0x0B/0x92
-
-# Giant white centipede
-R:24:0x01/0x9D
-
-# White icky thing
-R:25:0x01/0xA3
-
-# Clear icky thing
-R:26:0x0E/0xA3
-
-# Giant white mouse
-R:27:0x01/0xAC
-
-# Large brown snake
-R:28:0x07/0x8A
-
-# Small kobold
-R:29:0x0B/0xA5
-
-# Kobold
-R:30:0x0D/0xA5
-
-# White worm mass
-R:31:0x01/0xB1
-
-# Floating eye
-R:32:0x03/0x9F
-
-# Rock lizard
-R:33:0x0F/0x92
-
-# Grid bug
-R:34:0x0A/0x89
-
-# Jackal
-R:35:0x0F/0x83
-
-# Soldier ant
-R:36:0x07/0x9B
-
-# Fruit bat
-R:37:0x03/0x9C
-
-# Insect swarm
-R:38:0x07/0x89
-
-# The Greater hell-beast
-R:39:0x02/0x95
-
-# Shrieker mushroom patch
-R:40:0x0C/0xEE
-
-# Blubbering icky thing
-R:41:0x09/0xA3
-
-# Metallic green centipede
-R:42:0x05/0x9D
-
-# Novice warrior
-R:43:0x07/0xAA
-
-# Novice rogue
-R:44:0x06/0xAA
-
-# Novice priest
-R:45:0x05/0xAA
-
-# Novice mage
-R:46:0x04/0xAA
-
-# Yellow mushroom patch
-R:47:0x0B/0xEE
-
-# White jelly
-R:48:0x01/0xA4
-
-# Giant black ant
-R:49:0x08/0x9B
-
-# Salamander
-R:50:0x03/0x92
-
-# White harpy
-R:51:0x01/0x88
-
-# Blue yeek
-R:52:0x06/0xB3
-
-# Grip, Farmer Maggot's dog
-R:53:0x01/0x83
-
-# Wolf, Farmer Maggot's dog
-R:54:0x01/0x83
-
-# Fang, Farmer Maggot's dog
-R:55:0x01/0x83
-
-# Giant green frog
-R:56:0x05/0x92
-
-# Freesia
-R:57:0x07/0xA0
-
-# Green worm mass
-R:58:0x05/0xB1
-
-# Large yellow snake
-R:59:0x0B/0x8A
-
-# Cave spider
-R:60:0x08/0x93
-
-# Crow
-R:61:0x02/0x82
-
-# Wild cat
-R:62:0x0F/0xA0
-
-# Smeagol
-R:63:0x0E/0xA2
-
-# Green ooze
-R:64:0x05/0xA4
-
-# Poltergeist
-R:65:0x02/0x87
-
-# Yellow jelly
-R:66:0x0B/0xA4
-
-# Metallic blue centipede
-R:67:0x06/0x9D
-
-# Raven
-R:68:0x08/0x82
-
-# Giant white louse
-R:69:0x01/0x89
-
-# Giant yellow centipede
-R:70:0x0B/0x9D
-
-# Black naga
-R:71:0x08/0xA8
-
-# Spotted mushroom patch
-R:72:0x03/0xEE
-
-# Silver jelly
-R:73:0x09/0xA4
-
-# Scruffy-looking hobbit
-R:74:0x02/0xA2
-
-# Giant white ant
-R:75:0x01/0x9B
-
-# Yellow mold
-R:76:0x0B/0xA7
-
-# Metallic red centipede
-R:77:0x04/0x9D
-
-# Yellow worm mass
-R:78:0x0B/0xB1
-
-# Clear worm mass
-R:79:0x0E/0xB1
-
-# Radiation eye
-R:80:0x0C/0x9F
-
-# Yellow light
-R:81:0x0B/0xF0
-
-# Cave lizard
-R:82:0x07/0x92
-
-# Novice ranger
-R:83:0x09/0xAA
-
-# Blue jelly
-R:84:0x06/0xA4
-
-# Creeping copper coins
-R:85:0x07/0xF3
-
-# Giant white rat
-R:86:0x09/0xAC
-
-# Snotling
-R:87:0x0F/0xA9
-
-# Swordfish
-R:88:0x09/0x7E
-
-# Blue worm mass
-R:89:0x06/0xB1
-
-# Large grey snake
-R:90:0x02/0x8A
-
-# Skeleton kobold
-R:91:0x09/0xAD
-
-# Ewok
-R:92:0x0D/0xA2
-
-# Novice mage
-R:93:0x04/0xAA
-
-# Green naga
-R:94:0x05/0xA8
-
-# Giant leech
-R:95:0x07/0xB1
-
-# Barracuda
-R:96:0x0D/0x7E
-
-# Novice paladin
-R:97:0x01/0xAA
-
-# Zog
-R:98:0x06/0xA2
-
-# Blue ooze
-R:99:0x06/0xA4
-
-# Green glutton ghost
-R:100:0x05/0x87
-
-# Green jelly
-R:101:0x05/0xA4
-
-# Large kobold
-R:102:0x06/0xA5
-
-# Grey icky thing
-R:103:0x02/0xA3
-
-# Disenchanter eye
-R:104:0x0A/0x9F
-
-# Red worm mass
-R:105:0x04/0xB1
-
-# Copperhead snake
-R:106:0x03/0x8A
-
-# Death sword
-R:107:0x09/0xDC
-
-# Purple mushroom patch
-R:108:0x0A/0xEE
-
-# Novice priest
-R:109:0x05/0xAA
-
-# Novice warrior
-R:110:0x07/0xAA
-
-# Nibelung
-R:111:0x08/0xA2
-
-# The disembodied hand that strangled people
-R:112:0x05/0xB4
-
-# Brown mold
-R:113:0x07/0xA7
-
-# Giant brown bat
-R:114:0x07/0x9C
-
-# Rat-thing
-R:115:0x0C/0xAC
-
-# Novice rogue
-R:116:0x06/0xAA
-
-# Creeping silver coins
-R:117:0x02/0xF3
-
-# Snaga
-R:118:0x0F/0xA9
-
-# Rattlesnake
-R:119:0x04/0x8A
-
-# Giant slug
-R:120:0x0F/0xB1
-
-# Giant pink frog
-R:121:0x04/0x92
-
-# Dark elf
-R:122:0x08/0xA2
-
-# Zombified kobold
-R:123:0x02/0xB4
-
-# Crypt creep
-R:124:0x08/0xAD
-
-# Rotting corpse
-R:125:0x0C/0xB4
-
-# Cave orc
-R:126:0x0D/0xA9
-
-# Wood spider
-R:127:0x0F/0x93
-
-# Manes
-R:128:0x04/0xAF
-
-# Bloodshot eye
-R:129:0x04/0x9F
-
-# Red naga
-R:130:0x04/0xA8
-
-# Red jelly
-R:131:0x04/0xA4
-
-# Green icky thing
-R:132:0x05/0xA3
-
-# Lost soul
-R:133:0x09/0x87
-
-# Night lizard
-R:134:0x06/0x92
-
-# Mughash, the Kobold Lord
-R:135:0x0A/0xA5
-
-# Skeleton orc
-R:136:0x09/0xAD
-
-# Wormtongue, Agent of Saruman
-R:137:0x0E/0xAA
-
-# Robin Hood, the Outlaw
-R:138:0x0D/0xAA
-
-# Nurgling
-R:139:0x03/0xAF
-
-# Lagduf, the Snaga
-R:140:0x0B/0xA9
-
-# Brown yeek
-R:141:0x07/0xB3
-
-# Novice ranger
-R:142:0x09/0xAA
-
-# Giant salamander
-R:143:0x0C/0x92
-
-# Space monster
-R:144:0x00/0xB5
-
-# Carnivorous flying monkey
-R:145:0x0C/0x88
-
-# Green mold
-R:146:0x05/0xA7
-
-# Novice paladin
-R:147:0x01/0xAA
-
-# Lemure
-R:148:0x0F/0xAF
-
-# Hill orc
-R:149:0x07/0xA9
-
-# Bandit
-R:150:0x06/0xAA
-
-# Hunting hawk
-R:151:0x07/0x82
-
-# Phantom warrior
-R:152:0x0E/0x87
-
-# Gremlin
-R:153:0x07/0xAF
-
-# Yeti
-R:154:0x01/0x99
-
-# Bloodshot icky thing
-R:155:0x04/0xA3
-
-# Giant grey rat
-R:156:0x02/0xAC
-
-# Black harpy
-R:157:0x08/0x88
-
-# Skaven
-R:158:0x0D/0xAC
-
-# The wounded bear
-R:159:0x04/0xAB
-
-# Cave bear
-R:160:0x07/0xAB
-
-# Rock mole
-R:161:0x02/0xAC
-
-# Mindcrafter
-R:162:0x0B/0xAA
-
-# Baby blue dragon
-R:163:0x06/0x9E
-
-# Baby white dragon
-R:164:0x01/0x9E
-
-# Baby green dragon
-R:165:0x05/0x9E
-
-# Baby black dragon
-R:166:0x02/0x9E
-
-# Baby red dragon
-R:167:0x04/0x9E
-
-# Giant red ant
-R:168:0x04/0x9B
-
-# Brodda, the Easterling
-R:169:0x0F/0xAA
-
-# Bloodfang, the Wolf
-R:170:0x0C/0x83
-
-# King cobra
-R:171:0x05/0x8A
-
-# Eagle
-R:172:0x07/0x82
-
-# War bear
-R:173:0x07/0xAB
-
-# Killer bee
-R:174:0x0B/0x89
-
-# Giant spider
-R:175:0x0A/0x93
-
-# Giant white tick
-R:176:0x01/0x93
-
-# The Borshin
-R:177:0x01/0xA1
-
-# Dark elven mage
-R:178:0x04/0xA2
-
-# Kamikaze yeek
-R:179:0x04/0xB3
-
-# Orfax, Son of Boldor
-R:180:0x0E/0xB3
-
-# Servant of Glaaki
-R:181:0x0D/0xB4
-
-# Dark elven warrior
-R:182:0x07/0xA2
-
-# Sand-dweller
-R:183:0x0B/0xAF
-
-# Clear mushroom patch
-R:184:0x0E/0xEE
-
-# Quiver slot
-R:185:0x0F/0xEE
-
-# Grishnakh, the Hill Orc
-R:186:0x0B/0xA9
-
-# Giant tan bat
-R:187:0x0F/0x9C
-
-# Owlbear
-R:188:0x03/0x88
-
-# Blue horror
-R:189:0x0E/0xAF
-
-# Hairy mold
-R:190:0x03/0xA7
-
-# Grizzly bear
-R:191:0x0F/0xAB
-
-# Disenchanter mold
-R:192:0x0A/0xA7
-
-# Pseudo dragon
-R:193:0x03/0x9E
-
-# Tengu
-R:194:0x06/0xAF
-
-# Creeping gold coins
-R:195:0x0B/0xF3
-
-# Wolf
-R:196:0x07/0x83
-
-# Giant fruit fly
-R:197:0x0D/0x89
-
-# Panther
-R:198:0x08/0xA0
-
-# Brigand
-R:199:0x06/0xAA
-
-# Hobbes the Tiger
-R:200:0x0B/0xA0
-
-# Shadow Creature of Fiona
-R:201:0x02/0xA2
-
-# Undead mass
-R:202:0x07/0xA4
-
-# Chaos shapechanger
-R:203:0x0A/0x88
-
-# Baby multi-hued dragon
-R:204:0x0A/0x9E
-
-# Vorpal bunny
-R:205:0x01/0xAC
-
-# Old Man Willow
-R:206:0x02/0xCC
-
-# Hippocampus
-R:207:0x0E/0x88
-
-# Zombified orc
-R:208:0x02/0xB4
-
-# Hippogriff
-R:209:0x0F/0x88
-
-# Black mamba
-R:210:0x08/0x8A
-
-# White wolf
-R:211:0x01/0x83
-
-# Grape jelly
-R:212:0x0A/0xA4
-
-# Nether worm mass
-R:213:0x08/0xB1
-
-# Abyss worm mass
-R:214:0x08/0xB1
-
-# Golfimbul, the Hill Orc Chief
-R:215:0x0B/0xA9
-
-# Swordsman
-R:216:0x07/0xAA
-
-# Skaven shaman
-R:217:0x05/0xAC
-
-# Baby bronze dragon
-R:218:0x0F/0x9E
-
-# Baby gold dragon
-R:219:0x0B/0x9E
-
-# Evil eye
-R:220:0x08/0x9F
-
-# Mine-dog
-R:221:0x07/0x83
-
-# Hellcat
-R:222:0x0C/0xA0
-
-# Moon beast
-R:223:0x09/0xAB
-
-# Master yeek
-R:224:0x05/0xB3
-
-# Priest
-R:225:0x05/0xAA
-
-# Dark elven priest
-R:226:0x05/0xA2
-
-# Air spirit
-R:227:0x0E/0x85
-
-# Skeleton human
-R:228:0x09/0xAD
-
-# Zombified human
-R:229:0x02/0xB4
-
-# Tiger
-R:230:0x03/0xA0
-
-# Moaning spirit
-R:231:0x07/0x87
-
-# Stegocentipede
-R:232:0x07/0x9D
-
-# Spotted jelly
-R:233:0x03/0xA4
-
-# Drider
-R:234:0x06/0x93
-
-# Mongbat
-R:235:0x0F/0x9C
-
-# Killer brown beetle
-R:236:0x07/0x8B
-
-# Boldor, King of the Yeeks
-R:237:0x0A/0xB3
-
-# Ogre
-R:238:0x0F/0x8F
-
-# Creeping mithril coins
-R:239:0x0E/0xF3
-
-# Illusionist
-R:240:0x0C/0xAA
-
-# Druid
-R:241:0x0D/0xAA
-
-# Pink horror
-R:242:0x0C/0xAF
-
-# Cloaker
-R:243:0x05/0xE2
-
-# Black orc
-R:244:0x08/0xA9
-
-# Ochre jelly
-R:245:0x0F/0xA4
-
-# Software bug
-R:246:0x04/0x89
-
-# Lurker
-R:247:0x01/0xB5
-
-# Tangleweed
-R:248:0x05/0xCC
-
-# Vlasta
-R:249:0x0E/0x92
-
-# Giant white dragon fly
-R:250:0x01/0x86
-
-# Snaga sapper
-R:251:0x0F/0xA9
-
-# Blue icky thing
-R:252:0x06/0xA3
-
-# Gibbering mouther
-R:253:0x03/0xA4
-
-# Wolfhound of Flora
-R:254:0x02/0x83
-
-# Hill giant
-R:255:0x0F/0x90
-
-# Flesh golem
-R:256:0x0C/0xA1
-
-# Warg
-R:257:0x08/0x83
-
-# Cheerful leprechaun
-R:258:0x0D/0xA2
-
-# Giant flea
-R:259:0x02/0x89
-
-# Ufthak of Cirith Ungol
-R:260:0x05/0xA9
-
-# Clay golem
-R:261:0x0F/0xA1
-
-# Black ogre
-R:262:0x08/0x8F
-
-# Dweller on the threshold
-R:263:0x02/0x99
-
-# Half-orc
-R:264:0x02/0xA9
-
-# Dark naga
-R:265:0x02/0xA8
-
-# Poison ivy
-R:266:0x05/0xCC
-
-# Magic mushroom patch
-R:267:0x0E/0xEE
-
-# Plaguebearer of Nurgle
-R:268:0x03/0xB4
-
-# Guardian naga
-R:269:0x0B/0xA8
-
-# Wererat
-R:270:0x08/0xAC
-
-# Light hound
-R:271:0x03/0x9A
-
-# Dark hound
-R:272:0x08/0x9A
-
-# Flying skull
-R:273:0x02/0xAD
-
-# Mi-Go
-R:274:0x0C/0x89
-
-# Giant tarantula
-R:275:0x03/0x93
-
-# Giant clear centipede
-R:276:0x0E/0x9D
-
-# Mirkwood spider
-R:277:0x0D/0x93
-
-# Frost giant
-R:278:0x01/0x90
-
-# Griffon
-R:279:0x07/0x88
-
-# Homunculus
-R:280:0x0B/0xAF
-
-# Gnome mage
-R:281:0x0C/0xA2
-
-# Clear hound
-R:282:0x0E/0x9A
-
-# Umber hulk
-R:283:0x0F/0x98
-
-# Rust monster
-R:284:0x03/0xAB
-
-# Ogrillon
-R:285:0x09/0x8F
-
-# Gelatinous cube
-R:286:0x0D/0xA4
-
-# Giant green dragon fly
-R:287:0x0D/0x86
-
-# Fire giant
-R:288:0x04/0x90
-
-# Hummerhorn
-R:289:0x0B/0x89
-
-# Lizard man
-R:290:0x0D/0xA2
-
-# Ulfast, Son of Ulfang
-R:291:0x0F/0xAA
-
-# Crebain
-R:292:0x08/0x82
-
-# Berserker
-R:293:0x07/0xAA
-
-# Quasit
-R:294:0x03/0xAF
-
-# Sphinx
-R:295:0x03/0x88
-
-# Imp
-R:296:0x05/0xAF
-
-# Forest troll
-R:297:0x05/0x94
-
-# Freezing sphere
-R:298:0x01/0xF0
-
-# Jumping fireball
-R:299:0x04/0xF0
-
-# Ball lightning
-R:300:0x0E/0xF0
-
-# 2-headed hydra
-R:301:0x07/0x8D
-
-# Swamp thing
-R:302:0x05/0x88
-
-# Water spirit
-R:303:0x06/0x85
-
-# Giant red scorpion
-R:304:0x04/0x93
-
-# Earth spirit
-R:305:0x07/0x85
-
-# Fire spirit
-R:306:0x04/0x85
-
-# Fire hound
-R:307:0x04/0x9A
-
-# Cold hound
-R:308:0x01/0x9A
-
-# Energy hound
-R:309:0x06/0x9A
-
-# Lesser Mimic
-R:310:0x0B/0xA7
-
-# Door mimic
-R:311:0x0F/0xB8
-
-# Blink dog
-R:312:0x0E/0x83
-
-# Uruk
-R:313:0x0E/0xA9
-
-# Shagrat, the Orc Captain
-R:314:0x05/0xA9
-
-# Gorbag, the Orc Captain
-R:315:0x05/0xA9
-
-# Shambling mound
-R:316:0x05/0xEE
-
-# Giant Venus Flytrap
-R:317:0x05/0xCC
-
-# Chaos beastman
-R:318:0x07/0x88
-
-# Daemonette of Slaanesh
-R:319:0x0C/0xAF
-
-# Giant bronze dragon fly
-R:320:0x0F/0x86
-
-# Stone giant
-R:321:0x09/0x90
-
-# Giant black dragon fly
-R:322:0x02/0x86
-
-# Stone golem
-R:323:0x09/0xA1
-
-# Red mold
-R:324:0x04/0xA7
-
-# Giant gold dragon fly
-R:325:0x0B/0x86
-
-# Stunwall
-R:326:0x09/0xBC
-
-# Ghast
-R:327:0x07/0xB4
-
-# Neekerbreeker
-R:328:0x08/0x89
-
-# Huorn
-R:329:0x05/0xCC
-
-# Bolg, Son of Azog
-R:330:0x0A/0xA9
-
-# Phase spider
-R:331:0x0E/0x93
-
-# Lizard king
-R:332:0x05/0xA2
-
-# Landmine
-R:333:0x01/0xB5
-
-# Wyvern
-R:334:0x05/0x9E
-
-# Great eagle
-R:335:0x07/0x82
-
-# Livingstone
-R:336:0x09/0xBC
-
-# Earth hound
-R:337:0x07/0x9A
-
-# Air hound
-R:338:0x05/0x9A
-
-# Sabre-tooth tiger
-R:339:0x0B/0xA0
-
-# Acid hound
-R:340:0x02/0x9A
-
-# Chimaera
-R:341:0x04/0x88
-
-# Quylthulg
-R:342:0x0B/0x91
-
-# Sasquatch
-R:343:0x09/0x99
-
-# Weir
-R:344:0x09/0x83
-
-# Ranger
-R:345:0x09/0xAA
-
-# Paladin
-R:346:0x01/0xAA
-
-# Werewolf
-R:347:0x08/0x83
-
-# Dark elven lord
-R:348:0x02/0xA2
-
-# Cloud giant
-R:349:0x06/0x90
-
-# Ugluk, the Uruk
-R:350:0x0A/0xA9
-
-# Blue dragon bat
-R:351:0x06/0x9C
-
-# Mimic
-R:352:0x0B/0xA7
-
-# Ultimate Mimic
-R:353:0x0B/0xA7
-
-# Fire vortex
-R:354:0x04/0xB0
-
-# Acid vortex
-R:355:0x02/0xB0
-
-# Lugdush, the Uruk
-R:356:0x0A/0xA9
-
-# Arch-vile
-R:357:0x09/0xAF
-
-# Cold vortex
-R:358:0x01/0xB0
-
-# Energy vortex
-R:359:0x06/0xB0
-
-# Globefish
-R:360:0x01/0x7E
-
-# Giant firefly
-R:361:0x04/0x89
-
-# Mummified orc
-R:362:0x01/0xB4
-
-# Wolf chieftain
-R:363:0x08/0x83
-
-# Serpent man
-R:364:0x0D/0x8A
-
-# Vampiric mist
-R:365:0x08/0xCA
-
-# Killer stag beetle
-R:366:0x05/0x8B
-
-# Iron golem
-R:367:0x02/0xA1
-
-# Auto-roller
-R:368:0x02/0xA1
-
-# Giant yellow scorpion
-R:369:0x0B/0x93
-
-# Jade monk
-R:370:0x0D/0xAA
-
-# Black ooze
-R:371:0x08/0xA4
-
-# Hardened warrior
-R:372:0x07/0xAA
-
-# Azog, King of the Uruk-Hai
-R:373:0x0A/0xA9
-
-# Fleshhound of Khorne
-R:374:0x0C/0x83
-
-# Dark elven warlock
-R:375:0x0A/0xA2
-
-# Master rogue
-R:376:0x06/0xAA
-
-# Red dragon bat
-R:377:0x04/0x9C
-
-# Killer white beetle
-R:378:0x01/0x8B
-
-# Ice skeleton
-R:379:0x01/0xAD
-
-# Angamaite of Umbar
-R:380:0x0F/0xAA
-
-# Forest wight
-R:381:0x05/0x97
-
-# Khim, Son of Mim
-R:382:0x03/0xA2
-
-# Ibun, Son of Mim
-R:383:0x03/0xA2
-
-# Meneldor the Swift
-R:384:0x07/0x82
-
-# Phantom beast
-R:385:0x0E/0x87
-
-# Giant silver ant
-R:386:0x09/0x9B
-
-# 4-headed hydra
-R:387:0x0B/0x8D
-
-# Lesser hell-beast
-R:388:0x02/0x95
-
-# Tyrannosaur
-R:389:0x05/0x92
-
-# Mummified human
-R:390:0x01/0xB4
-
-# Vampire bat
-R:391:0x08/0x9C
-
-# Sangahyando of Umbar
-R:392:0x0F/0xAA
-
-# It
-R:393:0x09/0xB5
-
-# Banshee
-R:394:0x06/0x87
-
-# Carrion crawler
-R:395:0x03/0x9D
-
-# Xiclotlan
-R:396:0x08/0xCC
-
-# Silent watcher
-R:397:0x02/0xA1
-
-# Pukelman
-R:398:0x08/0xA1
-
-# Disenchanter beast
-R:399:0x0A/0xAB
-
-# Dark elven druid
-R:400:0x0D/0xA2
-
-# Stone troll
-R:401:0x09/0x94
-
-# Black
-R:402:0x00/0xA4
-
-# Hill troll
-R:403:0x02/0x94
-
-# Wereworm
-R:404:0x07/0xB1
-
-# Killer red beetle
-R:405:0x04/0x8B
-
-# Disenchanter bat
-R:406:0x0A/0x9C
-
-# Gnoph-Keh
-R:407:0x02/0xAB
-
-# Giant grey ant
-R:408:0x02/0x9B
-
-# Khufu, the Mummified King
-R:409:0x0A/0xB4
-
-# Gwaihir the Windlord
-R:410:0x07/0x82
-
-# Giant fire tick
-R:411:0x0C/0x93
-
-# Displacer beast
-R:412:0x06/0xA0
-
-# Ulwarth, Son of Ulfang
-R:413:0x0F/0xAA
-
-# Werebear
-R:414:0x08/0xAB
-
-# Cave ogre
-R:415:0x07/0x8F
-
-# White wraith
-R:416:0x01/0x97
-
-# Angel
-R:417:0x03/0x81
-
-# Ghoul
-R:418:0x0F/0xB4
-
-# Mim, Betrayer of Turin
-R:419:0x03/0xA2
-
-# Hellblade
-R:420:0x0A/0xDC
-
-# Killer fire beetle
-R:421:0x0C/0x8B
-
-# Beast of Nurgle
-R:422:0x0B/0xAB
-
-# Creeping adamantite coins
-R:423:0x0D/0xF3
-
-# Algroth
-R:424:0x03/0x94
-
-# Flamer of Tzeentch
-R:425:0x04/0xEE
-
-# Roper
-R:426:0x08/0xBC
-
-# Headless
-R:427:0x07/0x88
-
-# Vibration hound
-R:428:0x0B/0x9A
-
-# Nexus hound
-R:429:0x0A/0x9A
-
-# Half-ogre
-R:430:0x03/0x8F
-
-# Lokkak, the Ogre Chieftain
-R:431:0x0A/0x8F
-
-# Vampire
-R:432:0x09/0x96
-
-# Gorgimaera
-R:433:0x03/0x88
-
-# Shantak
-R:434:0x08/0x88
-
-# Colbran
-R:435:0x0B/0xA1
-
-# Spirit naga
-R:436:0x01/0xA8
-
-# Corpser
-R:437:0x08/0xEE
-
-# Fiend of Slaanesh
-R:438:0x0C/0x93
-
-# Stairway to Hell
-R:439:0x09/0xB7
-
-# 5-headed hydra
-R:440:0x05/0x8D
-
-# Barney the Dinosaur
-R:441:0x0A/0x92
-
-# Black knight
-R:442:0x02/0xAA
-
-# Seahorse
-R:443:0x03/0x7E
-
-# Cyclops
-R:444:0x07/0x90
-
-# Clairvoyant
-R:445:0x0B/0xAA
-
-# Purple worm
-R:446:0x0A/0xB1
-
-# Catoblepas
-R:447:0x05/0xAB
-
-# Lesser wall monster
-R:448:0x09/0xBC
-
-# Mage
-R:449:0x04/0xAA
-
-# Mind flayer
-R:450:0x0A/0xA2
-
-# The Ultimate Dungeon Cleaner
-R:451:0x08/0xA1
-
-# Deep one
-R:452:0x05/0xAF
-
-# Basilisk
-R:453:0x02/0x92
-
-# Ice troll
-R:454:0x01/0x94
-
-# Dhole
-R:455:0x02/0xB1
-
-# Archangel
-R:456:0x0E/0x81
-
-# Greater Mimic
-R:457:0x0B/0xA7
-
-# Chaos tile
-R:458:0x0A/0xB5
-
-# Young blue dragon
-R:459:0x06/0x9E
-
-# Young white dragon
-R:460:0x01/0x9E
-
-# Young green dragon
-R:461:0x05/0x9E
-
-# Young bronze dragon
-R:462:0x0F/0x9E
-
-# Aklash
-R:463:0x0C/0x94
-
-# Mithril golem
-R:464:0x0E/0xA1
-
-# Skeleton troll
-R:465:0x09/0xAD
-
-# Skeletal tyrannosaur
-R:466:0x01/0x92
-
-# Beorn, the Shape-Changer
-R:467:0x08/0xAB
-
-# Thorondor, Lord of Eagles
-R:468:0x07/0x82
-
-# Giant blue ant
-R:469:0x06/0x9B
-
-# Grave wight
-R:470:0x06/0x97
-
-# Shadow drake
-R:471:0x0D/0x9E
-
-# Manticore
-R:472:0x0B/0x88
-
-# Giant army ant
-R:473:0x03/0x9B
-
-# Killer slicer beetle
-R:474:0x0B/0x8B
-
-# Gorgon
-R:475:0x06/0x88
-
-# Gug
-R:476:0x0D/0x90
-
-# Ghost
-R:477:0x01/0x87
-
-# Death watch beetle
-R:478:0x08/0x8B
-
-# Mountain ogre
-R:479:0x02/0x8F
-
-# Nexus quylthulg
-R:480:0x0A/0x91
-
-# Shelob, Spider of Darkness
-R:481:0x08/0x93
-
-# Giant squid
-R:482:0x05/0x7E
-
-# Ghoulking
-R:483:0x08/0xB4
-
-# Doombat
-R:484:0x0C/0x9C
-
-# Ninja
-R:485:0x07/0xAA
-
-# Memory moss
-R:486:0x06/0xEE
-
-# Storm giant
-R:487:0x0E/0x90
-
-# Spectator
-R:488:0x0E/0x9F
-
-# Bokrug
-R:489:0x0A/0x92
-
-# Biclops
-R:490:0x07/0x90
-
-# Half-troll
-R:491:0x0F/0x94
-
-# Ivory monk
-R:492:0x01/0xAA
-
-# Bert the Stone Troll
-R:493:0x09/0x94
-
-# Bill the Stone Troll
-R:494:0x09/0x94
-
-# Tom the Stone Troll
-R:495:0x09/0x94
-
-# Cave troll
-R:496:0x07/0x94
-
-# Anti-paladin
-R:497:0x08/0xAA
-
-# Chaos master
-R:498:0x0A/0xAA
-
-# Barrow wight
-R:499:0x0A/0x97
-
-# Skeleton ettin
-R:500:0x09/0xAD
-
-# Chaos drake
-R:501:0x0A/0x9E
-
-# Law drake
-R:502:0x0E/0x9E
-
-# Balance drake
-R:503:0x0A/0x9E
-
-# Ethereal drake
-R:504:0x03/0x9E
-
-# Groo, the Wanderer
-R:505:0x0F/0xAA
-
-# Fasolt the Giant
-R:506:0x07/0x90
-
-# Shade
-R:507:0x08/0x87
-
-# Spectre
-R:508:0x0F/0x87
-
-# Water troll
-R:509:0x0E/0x94
-
-# Fire elemental
-R:510:0x04/0x85
-
-# Cherub
-R:511:0x0D/0x81
-
-# Water elemental
-R:512:0x06/0x85
-
-# Multi-hued hound
-R:513:0x0A/0x9A
-
-# Invisible stalker
-R:514:0x0B/0x85
-
-# Carrion crawler
-R:515:0x03/0x9D
-
-# Master thief
-R:516:0x06/0xAA
-
-# The Watcher in the Water
-R:517:0x0A/0x7E
-
-# Lich
-R:518:0x03/0x8C
-
-# Gas spore
-R:519:0x05/0x9F
-
-# Master vampire
-R:520:0x05/0x96
-
-# Oriental vampire
-R:521:0x02/0x96
-
-# Greater mummy
-R:522:0x0B/0xB4
-
-# Bloodletter of Khorne
-R:523:0x04/0x95
-
-# Giant grey scorpion
-R:524:0x02/0x93
-
-# Earth elemental
-R:525:0x07/0x85
-
-# Air elemental
-R:526:0x0E/0x85
-
-# Shimmering mold
-R:527:0x06/0xA7
-
-# Gargoyle
-R:528:0x02/0xAF
-
-# Malicious leprechaun
-R:529:0x0A/0xA2
-
-# Eog golem
-R:530:0x07/0xA1
-
-# Little Boy
-R:531:0x08/0xD6
-
-# Dagashi
-R:532:0x07/0xAA
-
-# Headless ghost
-R:533:0x07/0x87
-
-# Dread
-R:534:0x03/0x87
-
-# Leng spider
-R:535:0x0A/0x93
-
-# Gauth
-R:536:0x02/0x9F
-
-# Smoke elemental
-R:537:0x0C/0x85
-
-# Olog
-R:538:0x0B/0x94
-
-# Halfling slinger
-R:539:0x0F/0xA2
-
-# Gravity hound
-R:540:0x09/0x9A
-
-# Acidic cytoplasm
-R:541:0x02/0xA4
-
-# Inertia hound
-R:542:0x09/0x9A
-
-# Impact hound
-R:543:0x07/0x9A
-
-# Shardstorm
-R:544:0x07/0xB0
-
-# Ooze elemental
-R:545:0x05/0x85
-
-# Young black dragon
-R:546:0x02/0x9E
-
-# Mumak
-R:547:0x02/0xAB
-
-# Giant fire ant
-R:548:0x0C/0x9B
-
-# Mature white dragon
-R:549:0x01/0x9E
-
-# Xorn
-R:550:0x07/0x98
-
-# Rogrog the Black Troll
-R:551:0x08/0x94
-
-# Mist giant
-R:552:0x0E/0xCA
-
-# Phantom
-R:553:0x0A/0x87
-
-# Grey wraith
-R:554:0x02/0x97
-
-# Revenant
-R:555:0x07/0x97
-
-# Young multi-hued dragon
-R:556:0x0A/0x9E
-
-# Raal's Tome of Destruction
-R:557:0x04/0xEF
-
-# Colossus
-R:558:0x0D/0xA1
-
-# Young gold dragon
-R:559:0x0B/0x9E
-
-# Mature blue dragon
-R:560:0x06/0x9E
-
-# Mature green dragon
-R:561:0x05/0x9E
-
-# Mature bronze dragon
-R:562:0x0F/0x9E
-
-# Young red dragon
-R:563:0x04/0x9E
-
-# Nightblade
-R:564:0x08/0xA2
-
-# Trapper
-R:565:0x01/0xB5
-
-# Bodak
-R:566:0x04/0xAF
-
-# Time bomb
-R:567:0x01/0xB5
-
-# Mezzodaemon
-R:568:0x03/0xAF
-
-# Elder thing
-R:569:0x0D/0xAF
-
-# Ice elemental
-R:570:0x01/0x85
-
-# Necromancer
-R:571:0x0C/0xAA
-
-# The Greater hell magic mushroom were-quylthulg
-R:572:0x02/0x91
-
-# Lorgan, Chief of the Easterlings
-R:573:0x0A/0xAA
-
-# Chaos spawn
-R:574:0x02/0x9F
-
-# Mummified troll
-R:575:0x01/0xB4
-
-# Storm of Unmagic
-R:576:0x0A/0xB0
-
-# Crypt thing
-R:577:0x0D/0x8C
-
-# Chaos butterfly
-R:578:0x0D/0x89
-
-# Time elemental
-R:579:0x0D/0x85
-
-# Flying polyp
-R:580:0x0C/0x7E
-
-# The Queen Ant
-R:581:0x0A/0x9B
-
-# Will o' the wisp
-R:582:0x09/0x85
-
-# Shan
-R:583:0x0E/0x89
-
-# Magma elemental
-R:584:0x03/0x85
-
-# Black pudding
-R:585:0x08/0xA4
-
-# Killer iridescent beetle
-R:586:0x0A/0x8B
-
-# Nexus vortex
-R:587:0x0A/0xB0
-
-# Plasma vortex
-R:588:0x0C/0xB0
-
-# Mature red dragon
-R:589:0x04/0x9E
-
-# Mature gold dragon
-R:590:0x0B/0x9E
-
-# Crystal drake
-R:591:0x07/0x9E
-
-# Mature black dragon
-R:592:0x02/0x9E
-
-# Mature multi-hued dragon
-R:593:0x0A/0x9E
-
-# Sky whale
-R:594:0x0D/0x7E
-
-# Draebor, the Imp
-R:595:0x0A/0xAF
-
-# Mother Hydra
-R:596:0x0A/0xAF
-
-# Death knight
-R:597:0x08/0xAA
-
-# Castamir the Usurper
-R:598:0x0C/0xAA
-
-# Time vortex
-R:599:0x0E/0xB0
-
-# Shimmering vortex
-R:600:0x03/0xB0
-
-# Ancient blue dragon
-R:601:0x06/0x84
-
-# Ancient bronze dragon
-R:602:0x0F/0x84
-
-# Beholder
-R:603:0x0F/0x9F
-
-# Emperor wight
-R:604:0x04/0x97
-
-# Seraph
-R:605:0x04/0x81
-
-# Vargo, Tyrant of Fire
-R:606:0x04/0x85
-
-# Black wraith
-R:607:0x08/0x97
-
-# Nightgaunt
-R:608:0x08/0x95
-
-# Baron of hell
-R:609:0x0F/0x95
-
-# Scylla
-R:610:0x0E/0x8D
-
-# Monastic lich
-R:611:0x07/0x8C
-
-# Nether wraith
-R:612:0x0D/0x97
-
-# Hellhound
-R:613:0x04/0x83
-
-# 7-headed hydra
-R:614:0x0D/0x8D
-
-# Waldern, King of Water
-R:615:0x06/0x85
-
-# Kavlax the Many-Headed
-R:616:0x0A/0x9E
-
-# Ancient white dragon
-R:617:0x01/0x84
-
-# Ancient green dragon
-R:618:0x05/0x84
-
-# Chthonian
-R:619:0x08/0xB1
-
-# Eldrak
-R:620:0x04/0x94
-
-# Ettin
-R:621:0x06/0x94
-
-# Night mare
-R:622:0x0D/0xAB
-
-# Vampire lord
-R:623:0x06/0x96
-
-# Ancient black dragon
-R:624:0x02/0x84
-
-# Weird fume
-R:625:0x0A/0xCA
-
-# Spawn of Ubbo-Sathla
-R:626:0x0A/0xA4
-
-# Fat Man
-R:627:0x08/0xD6
-
-# Malekith the Accursed
-R:628:0x0A/0xA2
-
-# Shadowfax, steed of Gandalf
-R:629:0x0A/0xAB
-
-# Spirit troll
-R:630:0x0D/0x87
-
-# War troll
-R:631:0x06/0x94
-
-# Disenchanter worm mass
-R:632:0x0A/0xB1
-
-# Rotting quylthulg
-R:633:0x07/0x91
-
-# Lesser titan
-R:634:0x0B/0x90
-
-# 9-headed hydra
-R:635:0x04/0x8D
-
-# Enchantress
-R:636:0x0C/0xAA
-
-# Ranger chieftain
-R:637:0x09/0xAA
-
-# Sorcerer
-R:638:0x0C/0xAA
-
-# Xaren
-R:639:0x02/0x98
-
-# Giant roc
-R:640:0x07/0x82
-
-# Minotaur
-R:641:0x0F/0x88
-
-# Medusa, the Gorgon
-R:642:0x0A/0xA8
-
-# Death drake
-R:643:0x0D/0x84
-
-# Ancient red dragon
-R:644:0x04/0x84
-
-# Ancient gold dragon
-R:645:0x0B/0x84
-
-# Great crystal drake
-R:646:0x0F/0x84
-
-# Wyrd sister
-R:647:0x0A/0xAA
-
-# Vrock
-R:648:0x02/0x95
-
-# Death quasit
-R:649:0x08/0xAF
-
-# Giganto, the Gargantuan
-R:650:0x02/0x7E
-
-# Strygalldwir
-R:651:0x09/0x95
-
-# Fallen angel
-R:652:0x02/0x81
-
-# Giant headless
-R:653:0x07/0x88
-
-# Judge Fire
-R:654:0x0C/0xAD
-
-# Ubbo-Sathla, the Unbegotten Source
-R:655:0x09/0xA4
-
-# Judge Mortis
-R:656:0x0D/0xB4
-
-# Dark elven sorcerer
-R:657:0x0C/0xA2
-
-# Master lich
-R:658:0x04/0x8C
-
-# Byakhee
-R:659:0x08/0x95
-
-# Eol, the Dark Elf
-R:660:0x08/0xA2
-
-# Archon
-R:661:0x0B/0x81
-
-# Formless spawn of Tsathoggua
-R:662:0x08/0x95
-
-# Hunting horror
-R:663:0x08/0x95
-
-# Undead beholder
-R:664:0x07/0x9F
-
-# Shadow
-R:665:0x08/0x87
-
-# Iron lich
-R:666:0x02/0x8C
-
-# Dread
-R:667:0x03/0x87
-
-# Greater basilisk
-R:668:0x08/0x92
-
-# Charybdis
-R:669:0x04/0x7E
-
-# Jack of Shadows
-R:670:0x02/0xAA
-
-# Zephyr Lord
-R:671:0x0A/0x97
-
-# Juggernaut of Khorne
-R:672:0x08/0xA1
-
-# Mumak
-R:673:0x02/0xAB
-
-# Judge Fear
-R:674:0x08/0x97
-
-# Ancient multi-hued dragon
-R:675:0x0A/0x84
-
-# Ethereal dragon
-R:676:0x03/0x84
-
-# Dark young of Shub-Niggurath
-R:677:0x05/0x95
-
-# Colour out of space
-R:678:0x0A/0xB5
-
-# Quaker, Master of Earth
-R:679:0x07/0x85
-
-# Death leprechaun
-R:680:0x08/0xA2
-
-# Chaugnar Faugn, Horror from the Hills
-R:681:0x08/0xAB
-
-# Lloigor
-R:682:0x0E/0xB0
-
-# Utgard-Loke
-R:683:0x0A/0x90
-
-# Quachil Uttaus, Treader of the Dust
-R:684:0x08/0xB4
-
-# Shoggoth
-R:685:0x08/0xA4
-
-# Judge Death
-R:686:0x08/0x97
-
-# Ariel, Queen of Air
-R:687:0x0E/0x85
-
-# 11-headed hydra
-R:688:0x0C/0x8D
-
-# Patriarch
-R:689:0x0D/0xAA
-
-# Dreadmaster
-R:690:0x0B/0x87
-
-# Drolem
-R:691:0x05/0xA1
-
-# Scatha the Worm
-R:692:0x09/0x84
-
-# Warrior of the Dawn
-R:693:0x0C/0xAA
-
-# Lesser black reaver
-R:694:0x08/0x8C
-
-# Zoth-Ommog
-R:695:0x0A/0x92
-
-# Grand master thief
-R:696:0x06/0xAA
-
-# Smaug the Golden
-R:697:0x0C/0x84
-
-# The Stormbringer
-R:698:0x08/0xDC
-
-# Knight Templar
-R:699:0x01/0xAA
-
-# Leprechaun fanatic
-R:700:0x04/0xA2
-
-# Dracolich
-R:701:0x0D/0x84
-
-# Greater titan
-R:702:0x03/0x90
-
-# Dracolisk
-R:703:0x0C/0x84
-
-# Winged Horror
-R:704:0x08/0x82
-
-# Spectral tyrannosaur
-R:705:0x0D/0x92
-
-# Yibb-Tstll, the Patient One
-R:706:0x08/0x90
-
-# Ghatanothoa
-R:707:0x08/0xB0
-
-# Ent
-R:708:0x0D/0xCC
-
-# Hru
-R:709:0x02/0x90
-
-# Itangast the Fire Drake
-R:710:0x0C/0x84
-
-# Death mold
-R:711:0x08/0xA7
-
-# Fafner the Dragon
-R:712:0x0D/0x84
-
-# Charon, Boatman of the Styx
-R:713:0x0E/0x97
-
-# Quickbeam, the Ent
-R:714:0x0D/0xCC
-
-# Glaurung, Father of the Dragons
-R:715:0x0C/0x84
-
-# Behemoth
-R:716:0x0E/0x88
-
-# Garm, Guardian of Hel
-R:717:0x06/0x83
-
-# Greater wall monster
-R:718:0x09/0xBC
-
-# Nycadaemon
-R:719:0x03/0x95
-
-# Barbazu
-R:720:0x0D/0x95
-
-# Goat of Mendes
-R:721:0x08/0xAB
-
-# Nightwing
-R:722:0x08/0x97
-
-# Maulotaur
-R:723:0x02/0x88
-
-# Nether hound
-R:724:0x0D/0x9A
-
-# Time hound
-R:725:0x0E/0x9A
-
-# Plasma hound
-R:726:0x0C/0x9A
-
-# Demonic quylthulg
-R:727:0x04/0x91
-
-# Great Storm Wyrm
-R:728:0x06/0x84
-
-# Ulik the Troll
-R:729:0x0A/0x94
-
-# Baphomet the Minotaur Lord
-R:730:0x0A/0x88
-
-# Hell knight
-R:731:0x08/0xAA
-
-# Bull Gates
-R:732:0x08/0xAA
-
-# Santa Claus
-R:733:0x04/0xA2
-
-# Eihort, the Thing in the Labyrinth
-R:734:0x0C/0xA4
-
-# The King in Yellow
-R:735:0x0B/0x8C
-
-# Great unclean one
-R:736:0x05/0x95
-
-# Lord of Chaos
-R:737:0x0A/0xAA
-
-# Old Sorcerer
-R:738:0x0C/0xAA
-
-# Ethereal hound
-R:739:0x0D/0x9A
-
-# Lesser kraken
-R:740:0x0D/0x7E
-
-# Great Ice Wyrm
-R:741:0x01/0x84
-
-# Demilich
-R:742:0x0F/0x8C
-
-# The Phoenix
-R:743:0x04/0x82
-
-# Nightcrawler
-R:744:0x08/0x97
-
-# Lord of Change
-R:745:0x0A/0x95
-
-# Keeper of Secrets
-R:746:0x0D/0x88
-
-# Shudde M'ell
-R:747:0x02/0xB1
-
-# Hand druj
-R:748:0x0B/0xAD
-
-# Eye druj
-R:749:0x04/0xAD
-
-# Skull druj
-R:750:0x03/0xAD
-
-# Chaos vortex
-R:751:0x0A/0xB0
-
-# Aether vortex
-R:752:0x0A/0xB0
-
-# Nidhogg, the Hel-Drake
-R:753:0x08/0x84
-
-# The Lernaean Hydra
-R:754:0x0A/0x8D
-
-# Thuringwethil, the Vampire Messenger
-R:755:0x0A/0x96
-
-# Great Hell Wyrm
-R:756:0x04/0x84
-
-# Hastur the Unspeakable
-R:757:0x06/0x88
-
-# Bloodthirster
-R:758:0x04/0x95
-
-# Draconic quylthulg
-R:759:0x05/0x91
-
-# Nyogtha, the Thing that Should not Be
-R:760:0x08/0xA4
-
-# Ahtu, Avatar of Nyarlathotep
-R:761:0x08/0xBC
-
-# Fundin Bluecloak
-R:762:0x0E/0xA2
-
-# Bile Demon
-R:763:0x0C/0x95
-
-# Uriel, Angel of Fire
-R:764:0x0C/0x81
-
-# Azriel, Angel of Death
-R:765:0x08/0x81
-
-# Ancalagon the Black
-R:766:0x08/0x84
-
-# Daoloth, the Render of the Veils
-R:767:0x02/0x95
-
-# Nightwalker
-R:768:0x08/0x97
-
-# Gabriel, the Messenger
-R:769:0x01/0x81
-
-# Artsi, the Champion of Chaos
-R:770:0x0A/0xA2
-
-# Saruman of Many Colours
-R:771:0x0A/0xAA
-
-# Harowen the Black Hand
-R:772:0x0E/0xAA
-
-# Osyluth
-R:773:0x09/0x95
-
-# Dreadlord
-R:774:0x04/0x87
-
-# Greater kraken
-R:775:0x0D/0x7E
-
-# Archlich
-R:776:0x0E/0x8C
-
-# The Cat Lord
-R:777:0x0A/0xA0
-
-# Jabberwock
-R:778:0x0A/0x88
-
-# Chaos hound
-R:779:0x0A/0x9A
-
-# Vlad Dracula, Prince of Darkness
-R:780:0x08/0x96
-
-# Beholder hive-mother
-R:781:0x0B/0x9F
-
-# Leviathan
-R:782:0x0A/0x7E
-
-# Great Wyrm of Chaos
-R:783:0x0A/0x84
-
-# Great Wyrm of Law
-R:784:0x0E/0x84
-
-# Great Wyrm of Balance
-R:785:0x0A/0x84
-
-# Shambler
-R:786:0x09/0x85
-
-# Gelugon
-R:787:0x01/0x95
-
-# Glaaki
-R:788:0x0A/0x7E
-
-# Trone, the Rebel Thunderlord
-R:789:0x08/0x82
-
-# Great Wyrm of Many Colours
-R:790:0x0A/0x84
-
-# Marda, rider of gold Laronth
-R:791:0x0B/0x82
-
-# Tselakus, the Dreadlord
-R:792:0x0C/0x87
-
-# Sky Drake
-R:793:0x0E/0x84
-
-# Eilinel the Entrapped
-R:794:0x08/0xAA
-
-# Horned Reaper
-R:795:0x0E/0x95
-
-# The Norsa
-R:796:0x0E/0x88
-
-# Rhan-Tegoth
-R:797:0x06/0x93
-
-# Black reaver
-R:798:0x08/0x8C
-
-# Master mindcrafter
-R:799:0x0B/0xAA
-
-# Greater demonic quylthulg
-R:800:0x0C/0x91
-
-# Greater draconic quylthulg
-R:801:0x0D/0x91
-
-# Greater rotting quylthulg
-R:802:0x0F/0x91
-
-# Null, the Living Void
-R:803:0x00/0xB5
-
-# Feagwath, the Undead Sorcerer
-R:804:0x0B/0x8C
-
-# Omarax the Eye Tyrant
-R:805:0x0A/0x9F
-
-# Tsathoggua, the Sleeper of N'kai
-R:806:0x08/0x92
-
-# Greater Balrog
-R:807:0x0A/0x95
-
-# Ungoliant, the Unlight
-R:808:0x08/0x93
-
-# Atlach-Nacha, the Spider God
-R:809:0x08/0x93
-
-# Y'golonac
-R:810:0x0C/0x88
-
-# Aether hound
-R:811:0x0A/0x9A
-
-# Pit Fiend
-R:812:0x03/0x95
-
-# The Serpent of Chaos
-R:813:0x0A/0x8A
-
-# Yig, Father of Serpents
-R:814:0x06/0x8A
-
-# Unmaker
-R:815:0x0A/0x85
-
-# Cyberdemon
-R:816:0x07/0x95
-
-# Hela, Queen of the Dead
-R:817:0x0D/0xAA
-
-# The Mouth of Sauron
-R:818:0x0A/0xAA
-
-# The Necromancer of Dol Guldur
-R:819:0x0A/0xAA
-
-# Lisa, rider of gold Romth
-R:820:0x0B/0x82
-
-# Master quylthulg
-R:821:0x0E/0x91
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0x0A/0x91
-
-# Cthugha, the Living Flame
-R:823:0x0C/0x85
-
-# Flare, rider of bronze Moonth
-R:824:0x0F/0x82
-
-# Maeglin, the Traitor of Gondolin
-R:825:0x08/0xA2
-
-# Cyaegha
-R:826:0x0D/0x9F
-
-# Pazuzu, Lord of Air
-R:827:0x06/0x95
-
-# Ithaqua the Windwalker
-R:828:0x0E/0x99
-
-# Greater Hellhound
-R:829:0x04/0x83
-
-# Cantoras, the Skeletal Lord
-R:830:0x0A/0xAD
-
-# Mephistopheles, Lord of Hell
-R:831:0x04/0x95
-
-# Godzilla
-R:832:0x0A/0x92
-
-# Abhoth, Source of Uncleanness
-R:833:0x0D/0xA4
-
-# Ymir, the Ice Giant
-R:834:0x01/0x90
-
-# Loki, the Trickster
-R:835:0x08/0x90
-
-# Star-spawn of Cthulhu
-R:836:0x0D/0x95
-
-# Surtur, the Fire Giant
-R:837:0x04/0x90
-
-# The Tarrasque
-R:838:0x0A/0x92
-
-# Lungorthin, the Balrog of White Fire
-R:839:0x0A/0x95
-
-# Draugluin, Sire of All Werewolves
-R:840:0x0A/0x83
-
-# Shuma-Gorath
-R:841:0x0D/0x9F
-
-# Tulzscha, the Green Flame
-R:842:0x0D/0x85
-
-# Oremorj, the Cyberdemon Lord
-R:843:0x07/0x95
-
-# Vecna, the Emperor Lich
-R:844:0x0A/0x8C
-
-# Yog-Sothoth, the All-in-One
-R:845:0x0A/0xA4
-
-# Fenris Wolf
-R:846:0x08/0x83
-
-# Great Wyrm of Power
-R:847:0x0A/0x84
-
-# Shub-Niggurath, Black Goat of the Woods
-R:848:0x08/0x95
-
-# Nodens, Lord of the Great Abyss
-R:849:0x09/0x90
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x08/0x83
-
-# Nyarlathotep, the Crawling Chaos
-R:851:0x04/0x95
-
-# Azathoth, the Daemon Sultan
-R:852:0x0E/0x85
-
-# Huan, Wolfhound of the Valar
-R:853:0x09/0x83
-
-# Jormungand the Midgard Serpent
-R:854:0x0A/0x8A
-
-# The Destroyer
-R:855:0x0A/0xA1
-
-# Gothmog, the High Captain of Balrogs
-R:856:0x0A/0x95
-
-# Great Cthulhu
-R:857:0x05/0x95
-
-# Sarko, rider of gold Foronth
-R:858:0x0B/0x82
-
-# The Unicorn of Order
-R:859:0x01/0xAB
-
-# Sauron, the Sorcerer
-R:860:0x0A/0xAA
-
-# DarkGod, the Mighty Coder of Hell
-R:861:0x0E/0x90
-
-# Morgoth, Lord of Darkness
-R:862:0x08/0x90
-
-# Human Warrior
-R:863:0x07/0xAA
-
-# Elven archer
-R:864:0x09/0xA2
-
-# Dwarven warrior
-R:865:0x0F/0xA2
-
-# Elite uruk
-R:866:0x01/0xA9
-
-# The Philosophy Teacher
-R:867:0x04/0xAA
-
-# The Variant Maintainer
-R:868:0x0E/0xAA
-
-# Random Number Generator
-R:869:0x06/0x89
-
-# Rocket mine
-R:870:0x0C/0xB5
-
-# Bouncing mine
-R:871:0x0E/0xB5
-
-# Durin's Bane
-R:872:0x0A/0x95
-
-# The Icky Queen
-R:873:0x0A/0xA3
-
-# Rot jelly
-R:874:0x07/0xA4
-
-# Death
-R:875:0x08/0x87
-
-# Famine
-R:876:0x0F/0x87
-
-# Pestilence
-R:877:0x0D/0x87
-
-# War
-R:878:0x04/0x87
-
-# Pike
-R:879:0x02/0x7E
-
-# Electric eel
-R:880:0x0E/0x8A
-
-# Giant crayfish
-R:881:0x0C/0x7E
-
-# Mermaid
-R:882:0x0D/0xA2
-
-# Box jellyfish
-R:883:0x0E/0x7E
-
-# Giant piranha
-R:884:0x05/0x7E
-
-# Piranha
-R:885:0x05/0x7E
-
-# Bullywug
-R:886:0x05/0xA2
-
-# Bullywug warrior
-R:887:0x05/0xA2
-
-# Bullywug shaman
-R:888:0x05/0xA2
-
-# Whale
-R:889:0x0D/0x7E
-
-# Sand mite
-R:890:0x0E/0x7E
-
-# Octopus
-R:891:0x05/0x7E
-
-# Giant octopus
-R:892:0x05/0x7E
-
-# Eye of the deep
-R:893:0x06/0x9F
-
-# Murk dweller
-R:894:0x02/0x93
-
-# Drowned soul
-R:895:0x0E/0x87
-
-# Tiger shark
-R:896:0x05/0x7E
-
-# Hammerhead shark
-R:897:0x05/0x7E
-
-# Great white shark
-R:898:0x01/0x7E
-
-# Aquatic golem
-R:899:0x06/0xA1
-
-# Aquatic kobold
-R:900:0x0E/0xA5
-
-# White shark
-R:901:0x09/0x7E
-
-# Scrag
-R:902:0x0E/0x94
-
-# Jaws
-R:903:0x01/0x7E
-
-# Aquatic elf
-R:904:0x06/0xA2
-
-# Aquatic elven warrior
-R:905:0x06/0xA2
-
-# Aquatic elven shaman
-R:906:0x06/0xA2
-
-# Stargazer
-R:907:0x0B/0x7E
-
-# Elder stargazer
-R:908:0x0B/0x7E
-
-# Flounder
-R:909:0x02/0x7E
-
-# Giant turtle
-R:910:0x0D/0x92
-
-# Baby dragon turtle
-R:911:0x09/0x9E
-
-# Young dragon turtle
-R:912:0x09/0x9E
-
-# Mature dragon turtle
-R:913:0x09/0x9E
-
-# Ancient dragon turtle
-R:914:0x09/0x84
-
-# Fastitocalon
-R:915:0x05/0x84
-
-# Undead stargazer
-R:916:0x0B/0x7E
-
-# Killer whale
-R:917:0x01/0x7E
-
-# Merrow
-R:918:0x0E/0x8F
-
-# Water naga
-R:919:0x0E/0xA8
-
-# Devilfish
-R:920:0x02/0x7E
-
-# Undead devilfish
-R:921:0x08/0x7E
-
-# Moby Dick, the White Whale
-R:922:0x01/0x7E
-
-# Aquatic hound
-R:923:0x0E/0x9A
-
-# Water demon
-R:924:0x0E/0x95
-
-# Ixitxachitl
-R:925:0x02/0x7E
-
-# Ixitxachitl priest
-R:926:0x02/0x7E
-
-# Vampiric ixitxachitl
-R:927:0x08/0x7E
-
-# Mathilde, the Science Student
-R:928:0x0B/0xA2
-
-# Child spirit
-R:929:0x09/0x87
-
-# Young spirit
-R:930:0x09/0x87
-
-# Mature spirit
-R:931:0x09/0x87
-
-# Experienced spirit
-R:932:0x09/0x87
-
-# Wise spirit
-R:933:0x09/0x87
-
-# Fangorn the Treebeard, Lord of the Ents
-R:934:0x0D/0xCC
-
-# Gandalf the Grey
-R:935:0x02/0xAA
-
-# Nar, the Dwarf
-R:936:0x0B/0xA2
-
-# Novice mindcrafter
-R:937:0x0B/0xAA
-
-# Great Swamp Wyrm
-R:938:0x05/0x84
-
-# Great Bile Wyrm
-R:939:0x02/0x84
-
-# Blue Firebird
-R:940:0x0E/0x82
-
-# Green Firebird
-R:941:0x0D/0x82
-
-# Brown Firebird
-R:942:0x07/0x82
-
-# Bronze Firebird
-R:943:0x0F/0x82
-
-# Gold Firebird
-R:944:0x0B/0x82
-
-# High-elven ranger
-R:945:0x0D/0xA2
-
-# Uvatha the Horseman
-R:946:0x08/0x97
-
-# Adunaphel the Quiet
-R:947:0x08/0x97
-
-# Akhorahil the Blind
-R:948:0x08/0x97
-
-# Ren the Unclean
-R:949:0x08/0x97
-
-# Ji Indur Dawndeath
-R:950:0x08/0x97
-
-# Dwar, Dog Lord of Waw
-R:951:0x08/0x97
-
-# Hoarmurath of Dir
-R:952:0x08/0x97
-
-# Khamul, the Black Easterling
-R:953:0x08/0x97
-
-# The Witch-King of Angmar
-R:954:0x08/0x97
-
-# Green Thunderlord
-R:955:0x05/0x82
-
-# Blue Thunderlord
-R:956:0x06/0x82
-
-# Brown Thunderlord
-R:957:0x07/0x82
-
-# Bronze Thunderlord
-R:958:0x0F/0x82
-
-# Gold Thunderlord
-R:959:0x0B/0x82
-
-# Blood Sprout
-R:960:0x05/0xEE
-
-# Gorlim, Betrayer of Barahir
-R:961:0x02/0xAA
-
-# The Blubbering idiot, agent of black market, Simon the weak
-R:962:0x09/0xAE
-
-# Aranea
-R:963:0x04/0x93
-
-# Elder aranea
-R:964:0x0A/0x93
-
-# Giant brown tick
-R:965:0x07/0x93
-
-# Wavelord
-R:966:0x06/0xAA
-
-# Novice possessor (soul)
-R:967:0x08/0x87
-
-# Bat of Gorgoroth
-R:968:0x05/0x9C
-
-# The Princess
-R:969:0x0B/0xAA
-
-# Merton Proudfoot, the lost hobbit
-R:970:0x0A/0xA2
-
-# The Wight-King of the Barrow-downs
-R:971:0x0A/0x97
-
-# Adventurer
-R:972:0x0F/0x80
-
-# Experienced possessor (soul)
-R:973:0x08/0x87
-
-# Old possessor (soul)
-R:974:0x08/0x87
-
-# Death orb
-R:975:0x08/0x85
-
-# Bronze dragon worm
-R:976:0x0F/0xB1
-
-# Gold dragon worm
-R:977:0x0B/0xB1
-
-# Moldoux, the Defenceless Mold
-R:978:0x0A/0xA7
-
-# The Physics Teacher
-R:979:0x01/0xAA
-
-# Ar-Pharazon the Golden
-R:980:0x0B/0xAA
-
-# Doppelganger
-R:981:0x01/0x80
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0x09/0x90
-
-# The Greater Lag Monster
-R:983:0x0A/0x95
-
-# Hrungnir, the Stone Giant
-R:984:0x09/0x90
-
-# Bullroarer the Hobbit
-R:985:0x0F/0xA2
-
-# 3-headed hydra
-R:986:0x03/0x8D
-
-# Uldor the Accursed
-R:987:0x0F/0xAA
-
-# Mystic
-R:988:0x03/0xAA
-
-# Elder vampire
-R:989:0x04/0x96
-
-# Ulfang the Black
-R:990:0x0F/0xAA
-
-# Demonologist
-R:991:0x0C/0xAA
-
-# Hezrou
-R:992:0x05/0x95
-
-# Glabrezu
-R:993:0x0F/0x95
-
-# Nalfeshnee
-R:994:0x04/0x95
-
-# Marilith
-R:995:0x0B/0x95
-
-# Lesser Balrog
-R:996:0x0A/0x95
-
-# Master mystic
-R:997:0x03/0xAA
-
-# Grand master mystic
-R:998:0x03/0xAA
-
-# Erinyes
-R:999:0x07/0x95
-
-# Novice mindcrafter
-R:1000:0x0B/0xAA
-
-# Polyphemus, the Blind Cyclops
-R:1001:0x05/0x90
-
-# Great Wyrm of Perplexity
-R:1002:0x0F/0x84
-
-# Hound of Tindalos
-R:1003:0x02/0x9A
-
-# Great Wyrm of Thunder
-R:1004:0x0B/0x84
-
-# Silver mouse
-R:1005:0x09/0xAC
-
-# The Rat King
-R:1006:0x0A/0xAC
-
-# Vort the Kobold Queen
-R:1007:0x0A/0xA5
-
-# Giant black louse
-R:1008:0x08/0x89
-
-# Fire Phantom
-R:1009:0x04/0x87
-
-# The Insane Player
-R:1010:0x0A/0xAA
-
-# Glaryssa, Succubus Queen
-R:1011:0x09/0x95
-
-# Vermicious Knid
-R:1012:0x02/0xA4
-
-# Bone golem
-R:1013:0x01/0xA1
-
-# Snake of Yig
-R:1014:0x06/0x8A
-
-# Bronze golem
-R:1015:0x03/0xA1
-
-# Dimensional shambler
-R:1016:0x0E/0xA2
-
-# Cultist
-R:1017:0x0D/0xAA
-
-# Cult leader
-R:1018:0x0D/0xAA
-
-# Servitor of the outer gods
-R:1019:0x0B/0x88
-
-# Avatar of Nyarlathotep
-R:1020:0x0C/0xAA
-
-# Thiazi, the Storm Giant
-R:1021:0x0E/0x90
-
-# Hypnos, Lord of Sleep
-R:1022:0x0D/0xAA
-
-# Blue dragon worm
-R:1023:0x0E/0xB1
-
-# White dragon worm
-R:1024:0x09/0xB1
-
-# Green dragon worm
-R:1025:0x0D/0xB1
-
-# Black dragon worm
-R:1026:0x02/0xB1
-
-# Red dragon worm
-R:1027:0x0C/0xB1
-
-# Multi-hued dragon worm
-R:1028:0x0A/0xB1
-
-# The Minotaur of the Labyrinth
-R:1029:0x02/0x88
-
-# The Sandworm Queen
-R:1030:0x0A/0xB1
-
-# Sandworm
-R:1031:0x0B/0xB1
-
-# Tik'srvzllat
-R:1032:0x0A/0x87
-
-# The Glass Golem
-R:1033:0x09/0xBC
-
-# The White Balrog
-R:1034:0x09/0x95
-
-# Golgarach, the Living Rock
-R:1035:0x09/0xBC
-
-# Atlas, the Titan
-R:1036:0x02/0x90
-
-# Kronos, Lord of the Titans
-R:1037:0x0A/0x90
-
-# Water hound
-R:1038:0x04/0x9A
-
-# Improv, the mighty MoLD
-R:1039:0x0A/0xA7
-
-# Emperor Mimic
-R:1040:0x0B/0xA7
-
-# Melinda Proudfoot
-R:1041:0x0A/0xA2
-
-# Thrain, the King Under the Mountain
-R:1042:0x0E/0xA2
-
-# Fire golem
-R:1043:0x04/0xA1
-
-# Melkor, Lord of Darkness
-R:1044:0x0A/0x87
-
-# Spirit
-R:1045:0x0A/0x87
-
-# Spirit
-R:1046:0x0E/0x87
-
-# Spirit
-R:1047:0x0E/0x87
-
-# Spirit
-R:1048:0x0A/0x87
-
-# Spirit
-R:1049:0x0F/0x87
-
-# Spirit
-R:1050:0x0A/0x87
-
-# Spirit
-R:1051:0x05/0x87
-
-# Spirit
-R:1052:0x0A/0x87
-
-# Spirit
-R:1053:0x09/0xB5
-
-# Spirit
-R:1054:0x05/0x87
-
-# Spirit
-R:1055:0x09/0x87
-
-# Spirit
-R:1056:0x00/0x87
-
-# Spirit
-R:1057:0x07/0x87
-
-# Spirit
-R:1058:0x04/0x87
-
-# Spirit
-R:1059:0x0D/0x87
-
-# Spirit
-R:1060:0x09/0x87
-
-# Spirit
-R:1061:0x02/0x87
-
-# Spirit
-R:1062:0x06/0x87
-
-# Spirit
-R:1063:0x04/0x87
-
-# Spirit
-R:1064:0x01/0x87
-
-# Spirit
-R:1065:0x02/0x87
-
-# Spirit
-R:1066:0x06/0x87
-
-# Spirit
-R:1067:0x0A/0x87
-
-# Spirit
-R:1068:0x00/0x87
-
-# Spirit
-R:1069:0x09/0x87
-
-# Spirit
-R:1070:0x0A/0x87
-
-# Spirit
-R:1071:0x0D/0x87
-
-# Spirit
-R:1072:0x0B/0x87
-
-# Spirit
-R:1073:0x08/0x87
-
-# Spirit
-R:1074:0x03/0x87
-
-# Spirit
-R:1075:0x0A/0x87
-
-
diff --git a/lib/mods/theme/pref/graf-iso.prf b/lib/mods/theme/pref/graf-iso.prf
deleted file mode 100644
index eaf26901..00000000
--- a/lib/mods/theme/pref/graf-iso.prf
+++ /dev/null
@@ -1,5963 +0,0 @@
-# File: graf-iso.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-# with the isometric view.
-#
-# By Hansjoerg Malthaner < hansjoerg.malthaner@gmx.de >
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-# Scrolls (?)
-S:0xD0:0x80/0xBF
-S:0xD1:0x80/0xBF
-S:0xD2:0x80/0xBF
-S:0xD3:0x80/0xBF
-S:0xD4:0x80/0xBF
-S:0xD5:0x80/0xBF
-S:0xD6:0x80/0xBF
-S:0xD7:0x80/0xBF
-S:0xD8:0x80/0xBF
-S:0xD9:0x80/0xBF
-S:0xDA:0x80/0xBF
-S:0xDB:0x80/0xBF
-S:0xDC:0x80/0xBF
-S:0xDD:0x80/0xBF
-S:0xDE:0x80/0xBF
-S:0xDF:0x80/0xBF
-
-# Potions (!)
-S:0xE0:0x81/0x68
-S:0xE1:0x81/0x69
-S:0xE2:0x81/0x6A
-S:0xE3:0x81/0x6B
-S:0xE4:0x81/0x6C
-S:0xE5:0x81/0x6D
-S:0xE6:0x81/0x6E
-S:0xE7:0x81/0x6F
-S:0xE8:0x81/0x68
-S:0xE9:0x81/0x69
-S:0xEA:0x81/0x6A
-S:0xEB:0x81/0x6B
-S:0xEC:0x81/0x6C
-S:0xED:0x81/0x6D
-S:0xEE:0x81/0x6E
-S:0xEF:0x81/0x6F
-
-
-# Food (,)
-S:0xF0:0x90/0x92
-S:0xF1:0x90/0x92
-S:0xF2:0x90/0x92
-S:0xF3:0x90/0x92
-S:0xF4:0x90/0x92
-S:0xF5:0x90/0x92
-S:0xF6:0x90/0x92
-S:0xF7:0x90/0x92
-S:0xF8:0x90/0x92
-S:0xF9:0x90/0x92
-S:0xFA:0x90/0x92
-S:0xFB:0x90/0x92
-S:0xFC:0x90/0x92
-S:0xFD:0x90/0x92
-S:0xFE:0x90/0x92
-S:0xFF:0x90/0x92
-
-
-# Spells (*)
-S:48:0x82/0x60
-S:49:0x82/0x61
-S:50:0x82/0x62
-S:51:0x82/0x63
-S:52:0x82/0x64
-S:53:0x82/0x65
-S:54:0x82/0x66
-S:55:0x82/0x67
-S:56:0x82/0x60
-S:57:0x82/0x61
-S:58:0x82/0x62
-S:59:0x82/0x63
-S:60:0x82/0x64
-S:61:0x82/0x65
-S:62:0x82/0x66
-S:63:0x82/0x67
-
-# Spells (|)
-S:64:0x82/0x40
-S:65:0x82/0x44
-S:66:0x82/0x48
-S:67:0x82/0x4C
-S:68:0x82/0x50
-S:69:0x82/0x54
-S:70:0x82/0x58
-S:71:0x82/0x5C
-S:72:0x82/0x40
-S:73:0x82/0x44
-S:74:0x82/0x48
-S:75:0x82/0x4C
-S:76:0x82/0x50
-S:77:0x82/0x54
-S:78:0x82/0x58
-S:79:0x82/0x5C
-
-# Spells (-)
-S:80:0x82/0x41
-S:81:0x82/0x45
-S:82:0x82/0x49
-S:83:0x82/0x4D
-S:84:0x82/0x51
-S:85:0x82/0x55
-S:86:0x82/0x59
-S:87:0x82/0x5D
-S:88:0x82/0x41
-S:89:0x82/0x45
-S:90:0x82/0x49
-S:91:0x82/0x4D
-S:92:0x82/0x51
-S:93:0x82/0x55
-S:94:0x82/0x59
-S:95:0x82/0x5D
-
-# Spells (/)
-S:96:0x82/0x42
-S:97:0x82/0x46
-S:98:0x82/0x4A
-S:99:0x82/0x4E
-S:100:0x82/0x52
-S:101:0x82/0x56
-S:102:0x82/0x5A
-S:103:0x82/0x5D
-S:104:0x82/0x42
-S:105:0x82/0x46
-S:106:0x82/0x4A
-S:107:0x82/0x4D
-S:108:0x82/0x52
-S:109:0x82/0x56
-S:110:0x82/0x5A
-S:111:0x82/0x5D
-
-# Spells (\)
-S:112:0x82/0x43
-S:113:0x82/0x47
-S:114:0x82/0x4B
-S:115:0x82/0x4F
-S:116:0x82/0x53
-S:117:0x82/0x57
-S:118:0x82/0x5B
-S:119:0x82/0x5F
-S:120:0x82/0x43
-S:121:0x82/0x47
-S:122:0x82/0x4B
-S:123:0x82/0x4F
-S:124:0x82/0x53
-S:125:0x82/0x57
-S:126:0x82/0x5B
-S:127:0x82/0x5F
-
-
-# Feature attr/char definitions
-
-# nothing
-F:0:0x80:0xA0
-
-# open floor
-F:1:0x82:0xBC
-
-# fountain
-F:2:0x81:0x8D
-
-# glyph of warding
-F:3:0x80:0xBB
-
-# open door
-F:4:0x80:0xA7
-
-# broken door
-F:5:0x80:0xA7
-
-# up staircase
-F:6:0x80:0xBC
-
-# down staircase
-F:7:0x80:0xBE
-
-# quest entrance
-F:8:0x80:0xBE
-
-# quest exit
-F:9:0x80:0xBC
-
-# quest down level
-F:10:0x80:0xBE
-
-# quest up level
-F:11:0x80:0xBC
-
-# town exit
-F:12:0x80:0xBE
-
-# shaft down
-F:13:0x80:0xBE
-
-# shaft up
-F:14:0x80:0xBC
-
-# fountain
-F:15:0x81:0x8D
-
-# door
-F:32:0x80:0xAB
-
-# locked door
-F:33:0x80:0xAB
-
-# locked door
-F:34:0x80:0xAB
-
-# locked door
-F:35:0x80:0xAB
-
-# locked door
-F:36:0x80:0xAB
-
-# locked door
-F:37:0x80:0xAB
-
-# locked door
-F:38:0x80:0xAB
-
-# locked door
-F:39:0x80:0xAB
-
-# jammed door
-F:40:0x80:0xAB
-
-# jammed door
-F:41:0x80:0xAB
-
-# jammed door
-F:42:0x80:0xAB
-
-# jammed door
-F:43:0x80:0xAB
-
-# jammed door
-F:44:0x80:0xAB
-
-# jammed door
-F:45:0x80:0xAB
-
-# jammed door
-F:46:0x80:0xAB
-
-# jammed door
-F:47:0x80:0xAB
-
-# secret door
-F:48:0x80:0xA3
-
-# pile of rubble
-F:49:0x80:0xBA
-
-# magma vein
-F:50:0x80:0xA5
-
-# quartz vein
-F:51:0x81:0xF3
-
-# magma vein
-F:52:0x81:0xF3
-
-# quartz vein
-F:53:0x81:0xF3
-
-# magma vein with treasure
-F:54:0x80:0xAA
-
-# quartz vein with treasure
-F:55:0x80:0xAA
-
-# granite wall
-F:56:0x81:0xF0
-
-# granite wall
-F:57:0x81:0xF0
-
-# granite wall
-F:58:0x81:0xF0
-
-# granite wall
-F:59:0x81:0xF0
-
-# permanent wall
-F:60:0x81:0xF3
-
-# permanent wall
-F:61:0x81:0xF3
-
-# permanent wall
-F:62:0x81:0xF3
-
-# permanent wall
-F:63:0x81:0xF3
-
-# explosive rune
-F:64:0x80:0xAA
-
-# Straight Road startpoint
-F:65:0x80:0xAA
-
-# section of the Straight Road
-F:66:0x80:0xAA
-
-# section of the Straight Road
-F:67:0x80:0xAA
-
-# section of the Straight Road
-F:68:0x80:0xAA
-
-# section of the Straight Road
-F:69:0x80:0xAA
-
-# section of the Straight Road
-F:70:0x80:0xAA
-
-# section of the Straight Road (discharged)
-F:71:0x80:0xAA
-
-# Straight Road exit
-F:72:0x80:0xAA
-
-# corrupted section of the Straight Road
-F:73:0x80:0xAA
-
-# General Store
-B:0:0x80:0xB0
-
-# Armoury
-B:1:0x80:0xB1
-
-# Weapon Smiths
-B:2:0x80:0xB2
-
-# Temple
-B:3:0x80:0xB3
-
-# Alchemy Shop
-B:4:0x80:0xB4
-
-# Magic Shop
-B:5:0x80:0xB5
-
-# Black Market
-B:6:0x80:0xB6
-
-# Home
-B:7:0x80:0xB7
-
-# Bookstore
-B:8:0x80:0xB8
-
-# Pet shop
-B:9:0x80:0xAB
-
-# Mayors office
-B:10:0x80:0xAB
-
-# Inn
-B:11:0x80:0xAB
-
-# The Soothsayer
-B:12:0x80:0xAB
-
-# The library
-B:13:0x80:0xAB
-
-B:14:0x80:0xAB
-B:15:0x80:0xAB
-B:16:0x80:0xAB
-B:17:0x80:0xAB
-B:18:0x80:0xAB
-B:19:0x80:0xAB
-B:20:0x80:0xAB
-B:21:0x80:0xAB
-B:22:0x80:0xAB
-B:23:0x80:0xAB
-B:24:0x80:0xAB
-B:25:0x80:0xAB
-B:26:0x80:0xAB
-B:27:0x80:0xAB
-B:28:0x80:0xAB
-B:29:0x80:0xAB
-B:30:0x80:0xAB
-B:31:0x80:0xAB
-B:32:0x80:0xAB
-B:33:0x80:0xAB
-B:34:0x80:0xAB
-B:35:0x80:0xAB
-B:36:0x80:0xAB
-B:37:0x80:0xAB
-
-# Building
-F:74:0x80:0xB1
-
-# permanent wall
-F:75:0x80:0xA3
-
-# permanent wall
-F:76:0x80:0xA3
-
-# permanent wall
-F:77:0x80:0xA3
-
-# permanent wall
-F:78:0x80:0xA3
-
-# Deep water
-F:83:0xCB:0x81
-
-# stream of shallow water
-F:84:0x82:0xEB
-
-# pool of deep lava
-F:85:0x80:0xA3
-
-# stream of shallow lava
-F:86:0x80:0xA3
-
-# dark pit
-F:87:0x83:0x8B
-
-# dirt
-F:88:0x82:0xF3
-
-# patch of grass
-F:89:0x82:0xE8
-
-# ice
-F:90:0x80:0xAE
-
-# sand
-F:91:0x80:0xAE
-
-# dead tree
-F:92:0x80:0xA3
-
-# ash
-F:93:0x80:0xAE
-
-# mud
-F:94:0x80:0xAE
-
-# ice wall
-F:95:0x80:0x80
-
-# tree
-F:96:0x83:0x88
-
-# mountain chain
-F:97:0x81:0x9D
-
-# sandwall
-F:98:0x80:0xA3
-
-# sandwall
-F:99:0x80:0xA5
-
-# sandwall with treasure
-F:100:0x80:0xAA
-
-# high mountain chain
-F:101:0x80:0xDE
-
-# nether mist
-F:102:0x80:0x80
-
-# molten glass wall
-F:103:0x80:0xAE
-
-# Between gate
-F:160:0x81:0x8C
-
-# Altar of Forests
-F:161:0x81:0x94
-
-# Altar of Water
-F:162:0x81:0x94
-
-# Altar of Earth
-F:163:0x81:0x94
-
-# Altar of Darkness
-F:164:0x81:0x94
-
-# Altar of Moon
-F:165:0x81:0x94
-
-# Altar of Sun
-F:166:0x81:0x94
-
-# Altar of Rage
-F:167:0x81:0x94
-
-# Altar of Winds
-F:168:0x81:0x94
-
-# Altar of Stars
-F:169:0x81:0x94
-
-# Altar of Being
-F:170:0x81:0x94
-
-# Altar of Randomness
-F:171:0x81:0x94
-
-# pool of deep water
-F:187:0x82:0xF0
-
-# glass wall
-F:188:0x80:0xAE
-
-# illusion wall
-F:189:0x80:0xA3
-
-# Grass roof
-F:190:0x82:0xF6
-
-# grass roof top
-F:191:0x82:0xFE
-
-# grass roof chimney
-F:192:0x82:0xF7
-
-# brick roof
-F:193:0x82:0xEE
-
-# brick roof top
-F:194:0x82:0xEF
-
-# brick roof chimney
-F:195:0x80:0xA3
-
-# window
-F:196:0x80:0xA3
-
-# small window
-F:197:0x80:0xA3
-
-# rain barrel
-F:198:0x80:0xA3
-
-# grass with flowers
-F:199:0x82:0xF8
-
-# cobblestone road
-F:200:0x83:0x83
-
-# cobblestone with outlet
-F:201:0x80:0xAE
-
-# small tree
-F:202:0x80:0xA3
-
-# town
-F:203:0x80:0xAA
-
-
-
-
-
-
-
-# Object attr/char definitions
-
-# something
-K:0:0x80:0xA6
-
-# Blindness
-K:1:0x80:0xAC
-
-# Paranoia
-K:2:0x80:0xAC
-
-# Confusion
-K:3:0x80:0xAC
-
-# Hallucination
-K:4:0x80:0xAC
-
-# Cure Poison
-K:5:0x80:0xAC
-
-# Cure Blindness
-K:6:0x80:0xAC
-
-# Cure Paranoia
-K:7:0x80:0xAC
-
-# Cure Confusion
-K:8:0x80:0xAC
-
-# Weakness
-K:9:0x80:0xAC
-
-# Unhealth
-K:10:0x80:0xAC
-
-# Restore Constitution
-K:11:0x80:0xAC
-
-# Restoring
-K:12:0x80:0xAC
-
-# Stupidity
-K:13:0x80:0xAC
-
-# Naivety
-K:14:0x80:0xAC
-
-# Poison
-K:15:0x80:0xAC
-
-# Sickness
-K:16:0x80:0xAC
-
-# Paralysis
-K:17:0x80:0xAC
-
-# Restore Strength
-K:18:0x80:0xAC
-
-# Disease
-K:19:0x80:0xAC
-
-# Cure Serious Wounds
-K:20:0x80:0xAC
-
-# & Ration~ of Food
-K:21:0x80:0xAC
-
-# & Hard Biscuit~
-K:22:0x80:0xAC
-
-# & Strip~ of Venison
-K:23:0x80:0xAC
-
-# & Slime Mold~
-K:24:0x80:0xAC
-
-# & Piece~ of Elvish Waybread
-K:25:0x80:0xAC
-
-# & Pint~ of Fine Ale
-K:26:0x80:0xAC
-
-# & Pint~ of Fine Wine
-K:27:0x80:0xAC
-
-# & Mattock~
-K:28:0x80:0xDC
-
-# & No-dachi~
-K:29:0x80:0xFC
-
-# & Broken Dagger~
-K:30:0x80:0xFC
-
-# & Bastard Sword~
-K:31:0x80:0xFC
-
-# & Scimitar~
-K:32:0x80:0xFC
-
-# & Tulwar~
-K:33:0x80:0xFC
-
-# & Broad Sword~
-K:34:0x80:0xFC
-
-# & Short Sword~
-K:35:0x80:0xFC
-
-# & Blade~ of Chaos
-K:36:0x80:0xFC
-
-# & Two-Handed Sword~
-K:37:0x80:0xFC
-
-# & Main Gauche~
-K:38:0x80:0xFC
-
-# & Cutlass~
-K:39:0x80:0xFC
-
-# & Executioner's Sword~
-K:40:0x80:0xFC
-
-# & Katana~
-K:41:0x80:0xFC
-
-# & Long Sword~
-K:42:0x80:0xFC
-
-# & Dagger~
-K:43:0x80:0xFC
-
-# & Rapier~
-K:44:0x80:0xFC
-
-# & Sabre~
-K:45:0x80:0xFC
-
-# & Small Sword~
-K:46:0x80:0xFC
-
-# & Broken Sword~
-K:47:0x80:0xFC
-
-# & Ball-and-Chain~
-K:48:0x80:0xDC
-
-# & Whip~
-K:49:0x80:0xDC
-
-# & Flail~
-K:50:0x80:0xDC
-
-# & Two-Handed Flail~
-K:51:0x80:0xDC
-
-# & Morning Star~
-K:52:0x80:0xDC
-
-# & Mace~
-K:53:0x80:0xDC
-
-# & Quarterstaff~
-K:54:0x80:0xDC
-
-# & War Hammer~
-K:55:0x80:0xDC
-
-# & Lead-Filled Mace~
-K:56:0x80:0xDC
-
-# & Mace~ of Disruption
-K:57:0x80:0xDC
-
-# & Lucerne Hammer~
-K:58:0x80:0xDC
-
-# & Beaked Axe~
-K:59:0x80:0xAF
-
-# & Glaive~
-K:60:0x80:0xAF
-
-# & Halberd~
-K:61:0x80:0xAF
-
-# & Awl-Pike~
-K:62:0x80:0xAF
-
-# & Pike~
-K:63:0x80:0xAF
-
-# & Spear~
-K:64:0x80:0xAF
-
-# & Trident~
-K:65:0x80:0xAF
-
-# & Lance~
-K:66:0x80:0xAF
-
-# & Great Axe~
-K:67:0x80:0xAF
-
-# & Battle Axe~
-K:68:0x80:0xAF
-
-# & Lochaber Axe~
-K:69:0x80:0xAF
-
-# & Broad Axe~
-K:70:0x80:0xAF
-
-# & Scythe~
-K:71:0x80:0xAF
-
-# & Scythe~ of Slicing
-K:72:0x80:0xAF
-
-# & Short Bow~
-K:73:0x80:0xFD
-
-# & Long Bow~
-K:74:0x80:0xFD
-
-# & Light Crossbow~
-K:75:0x80:0xFD
-
-# & Heavy Crossbow~
-K:76:0x80:0xFD
-
-# & Sling~
-K:77:0x80:0xFD
-
-# & Arrow~
-K:78:0x80:0xFB
-
-# & Seeker Arrow~
-K:79:0x80:0xFB
-
-# & Bolt~
-K:80:0x80:0xFB
-
-# & Seeker Bolt~
-K:81:0x80:0xFB
-
-# & Rounded Pebble~
-K:82:0x81:0x93
-
-# & Iron Shot~
-K:83:0x80:0xFB
-
-# & Shovel~
-K:84:0x80:0xDC
-
-# & Gnomish Shovel~
-K:85:0x80:0xDC
-
-# & Dwarven Shovel~
-K:86:0x80:0xDC
-
-# & Pick~
-K:87:0x80:0xDC
-
-# & Orcish Pick~
-K:88:0x80:0xDC
-
-# & Dwarven Pick~
-K:89:0x80:0xDC
-
-# & Elven Cloak~
-K:90:0x80:0xA8
-
-# & Pair~ of Soft Leather Boots
-K:91:0x80:0xDD
-
-# & Pair~ of Hard Leather Boots
-K:92:0x80:0xDD
-
-# & Pair~ of Metal Shod Boots
-K:93:0x80:0xDD
-
-# & Hard Leather Cap~
-K:94:0x80:0xDD
-
-# & Metal Cap~
-K:95:0x80:0xDD
-
-# & Iron Helm~
-K:96:0x80:0xDD
-
-# & Steel Helm~
-K:97:0x80:0xDD
-
-# & Iron Crown~
-K:98:0x80:0xDD
-
-# & Golden Crown~
-K:99:0x80:0xDD
-
-# & Jewel Encrusted Crown~
-K:100:0x80:0xDD
-
-# & Robe~
-K:101:0x80:0xA8
-
-# & Filthy Rag~
-K:102:0x80:0xA8
-
-# Soft Leather Armour~
-K:103:0x80:0xA8
-
-# Soft Studded Leather~
-K:104:0x80:0xA8
-
-# Hard Leather Armour~
-K:105:0x80:0xA8
-
-# Hard Studded Leather~
-K:106:0x80:0xA8
-
-# Leather Scale Mail~
-K:107:0x80:0xA8
-
-# Metal Scale Mail~
-K:108:0x80:0xDB
-
-# Chain Mail~
-K:109:0x80:0xDB
-
-# Rusty Chain Mail~
-K:110:0x80:0xDB
-
-# Augmented Chain Mail~
-K:111:0x80:0xDB
-
-# Bar Chain Mail~
-K:112:0x80:0xDB
-
-# Metal Brigandine Armour~
-K:113:0x80:0xDB
-
-# Partial Plate Armour~
-K:114:0x80:0xDB
-
-# Metal Lamellar Armour~
-K:115:0x80:0xDB
-
-# Full Plate Armour~
-K:116:0x80:0xDB
-
-# Ribbed Plate Armour~
-K:117:0x80:0xDB
-
-# Adamantite Plate Mail~
-K:118:0x80:0xDB
-
-# Mithril Plate Mail~
-K:119:0x80:0xDB
-
-# Mithril Chain Mail~
-K:120:0x80:0xDB
-
-# Double Chain Mail~
-K:121:0x80:0xDB
-
-# & Shield~ of Deflection
-K:122:0x80:0xDB
-
-# & Cloak~
-K:123:0x80:0xA8
-
-# & Shadow Cloak~
-K:124:0x80:0xA8
-
-# & Set~ of Leather Gloves
-K:125:0x80:0xDD
-
-# & Set~ of Gauntlets
-K:126:0x80:0xDD
-
-# & Set~ of Cesti
-K:127:0x80:0xDD
-
-# & Small Leather Shield~
-K:128:0x80:0xA9
-
-# & Large Leather Shield~
-K:129:0x80:0xA9
-
-# & Small Metal Shield~
-K:130:0x80:0xA9
-
-# & Large Metal Shield~
-K:131:0x80:0xA9
-
-# Strength
-K:132:0x80:0xBD
-
-# Dexterity
-K:133:0x80:0xBD
-
-# Constitution
-K:134:0x80:0xBD
-
-# Intelligence
-K:135:0x80:0xBD
-
-# Speed
-K:136:0x80:0xBD
-
-# Searching
-K:137:0x80:0xBD
-
-# Teleportation
-K:138:0x80:0xBD
-
-# Slow Digestion
-K:139:0x80:0xBD
-
-# Resist Fire
-K:140:0x80:0xBD
-
-# Resist Cold
-K:141:0x80:0xBD
-
-# Levitation
-K:142:0x80:0xBD
-
-# Poison Resistance
-K:143:0x80:0xBD
-
-# Free Action
-K:144:0x80:0xBD
-
-# Weakness
-K:145:0x80:0xBD
-
-# Flames
-K:146:0x80:0xBD
-
-# Acid
-K:147:0x80:0xBD
-
-# Ice
-K:148:0x80:0xBD
-
-# Woe
-K:149:0x80:0xBD
-
-# Stupidity
-K:150:0x80:0xBD
-
-# Damage
-K:151:0x80:0xBD
-
-# Accuracy
-K:152:0x80:0xBD
-
-# Protection
-K:153:0x80:0xBD
-
-# Aggravate Monster
-K:154:0x80:0xBD
-
-# See Invisible
-K:155:0x80:0xBD
-
-# Sustain Strength
-K:156:0x80:0xBD
-
-# Sustain Intelligence
-K:157:0x80:0xBD
-
-# Sustain Wisdom
-K:158:0x80:0xBD
-
-# Sustain Constitution
-K:159:0x80:0xBD
-
-# Sustain Dexterity
-K:160:0x80:0xBD
-
-# Sustain Charisma
-K:161:0x80:0xBD
-
-# Slaying
-K:162:0x80:0xBD
-
-# Brilliance
-K:163:0x80:0xA2
-
-# Charisma
-K:164:0x80:0xA2
-
-# Searching
-K:165:0x80:0xA2
-
-# Teleportation
-K:166:0x80:0xA2
-
-# Slow Digestion
-K:167:0x80:0xA2
-
-# Resist Acid
-K:168:0x80:0xA2
-
-# Adornment
-K:169:0x80:0xA2
-
-# Double Ring Mail~
-K:170:0x80:0xDB
-
-# the Magi
-K:171:0x80:0xA2
-
-# DOOM
-K:172:0x80:0xA2
-
-# Enchant Weapon To-Hit
-K:173:0x80:0xBF
-
-# Enchant Weapon To-Dam
-K:174:0x80:0xBF
-
-# Enchant Armor
-K:175:0x80:0xBF
-
-# Identify
-K:176:0x80:0xBF
-
-# *Identify*
-K:177:0x80:0xBF
-
-# Rumour
-K:178:0x80:0xBF
-
-# Chaos
-K:179:0x80:0xBF
-
-# Remove Curse
-K:180:0x80:0xBF
-
-# Light
-K:181:0x80:0xBF
-
-# Fire
-K:182:0x80:0xBF
-
-# Ice
-K:183:0x80:0xBF
-
-# Summon Monster
-K:184:0x80:0xBF
-
-# Phase Door
-K:185:0x80:0xBF
-
-# Teleportation
-K:186:0x80:0xBF
-
-# Teleport Level
-K:187:0x80:0xBF
-
-# Monster Confusion
-K:188:0x80:0xBF
-
-# Magic Mapping
-K:189:0x80:0xBF
-
-# Rune of Protection
-K:190:0x80:0xBF
-
-# *Remove Curse*
-K:191:0x80:0xBF
-
-# Treasure Detection
-K:192:0x80:0xBF
-
-# Object Detection
-K:193:0x80:0xBF
-
-# Trap Detection
-K:194:0x80:0xBF
-
-# & Sheaf Arrow~
-K:195:0x80:0xFB
-
-# & Mithril Shot~
-K:196:0x80:0xFB
-
-# Door/Stair Location
-K:197:0x80:0xBF
-
-# Acquirement
-K:198:0x80:0xBF
-
-# *Acquirement*
-K:199:0x80:0xBF
-
-# Mass Genocide
-K:200:0x80:0xBF
-
-# Detect Invisible
-K:201:0x80:0xBF
-
-# Aggravate Monster
-K:202:0x80:0xBF
-
-# Trap Creation
-K:203:0x80:0xBF
-
-# Trap/Door Destruction
-K:204:0x80:0xBF
-
-# Artifact Creation
-K:205:0x80:0xBF
-
-# Recharging
-K:206:0x80:0xBF
-
-# Genocide
-K:207:0x80:0xBF
-
-# Darkness
-K:208:0x80:0xBF
-
-# Protection from Evil
-K:209:0x80:0xBF
-
-# Satisfy Hunger
-K:210:0x80:0xBF
-
-# Dispel Undead
-K:211:0x80:0xBF
-
-# *Enchant Weapon*
-K:212:0x80:0xBF
-
-# Curse Weapon
-K:213:0x80:0xBF
-
-# *Enchant Armor*
-K:214:0x80:0xBF
-
-# Curse Armor
-K:215:0x80:0xBF
-
-# Summon Undead
-K:216:0x80:0xBF
-
-# Blessing
-K:217:0x80:0xBF
-
-# Holy Chant
-K:218:0x80:0xBF
-
-# Holy Prayer
-K:219:0x80:0xBF
-
-# Word of Recall
-K:220:0x80:0xBF
-
-# *Destruction*
-K:221:0x80:0xBF
-
-# Slime Mold Juice
-K:222:0x80:0xA1
-
-# Apple Juice
-K:223:0x80:0xA1
-
-# Water
-K:224:0x80:0xA1
-
-# Strength
-K:225:0x80:0xA1
-
-# Weakness
-K:226:0x80:0xA1
-
-# Restore Strength
-K:227:0x80:0xA1
-
-# Intelligence
-K:228:0x80:0xA1
-
-# Stupidity
-K:229:0x80:0xA1
-
-# Restore Intelligence
-K:230:0x80:0xA1
-
-# Wisdom
-K:231:0x80:0xA1
-
-# Naivety
-K:232:0x80:0xA1
-
-# Restore Wisdom
-K:233:0x80:0xA1
-
-# Charisma
-K:234:0x80:0xA1
-
-# Ugliness
-K:235:0x80:0xA1
-
-# Restore Charisma
-K:236:0x80:0xA1
-
-# Curing
-K:237:0x80:0xA1
-
-# Invulnerability
-K:238:0x80:0xA1
-
-# New Life
-K:239:0x80:0xA1
-
-# Cure Serious Wounds
-K:240:0x80:0xA1
-
-# Cure Critical Wounds
-K:241:0x80:0xA1
-
-# Healing
-K:242:0x80:0xA1
-
-# Constitution
-K:243:0x80:0xA1
-
-# Experience
-K:244:0x80:0xA1
-
-# Sleep
-K:245:0x80:0xA1
-
-# Blindness
-K:246:0x80:0xA1
-
-# Booze
-K:247:0x80:0xA1
-
-# Poison
-K:248:0x80:0xA1
-
-# Speed
-K:249:0x80:0xA1
-
-# Slowness
-K:250:0x80:0xA1
-
-# Dexterity
-K:251:0x80:0xA1
-
-# Restore Dexterity
-K:252:0x80:0xA1
-
-# Restore Constitution
-K:253:0x80:0xA1
-
-# Lose Memories
-K:254:0x80:0xA1
-
-# Salt Water
-K:255:0x80:0xA1
-
-# Enlightenment
-K:256:0x80:0xA1
-
-# Heroism
-K:257:0x80:0xA1
-
-# Berserk Strength
-K:258:0x80:0xA1
-
-# Boldness
-K:259:0x80:0xA1
-
-# Restore Life Levels
-K:260:0x80:0xA1
-
-# Resist Heat
-K:261:0x80:0xA1
-
-# Resist Cold
-K:262:0x80:0xA1
-
-# Detect Invisible
-K:263:0x80:0xA1
-
-# Slow Poison
-K:264:0x80:0xA1
-
-# Neutralise Poison
-K:265:0x80:0xA1
-
-# Restore Mana
-K:266:0x80:0xA1
-
-# Infra-vision
-K:267:0x80:0xA1
-
-# Resistance
-K:268:0x80:0xA1
-
-# Light
-K:269:0x80:0xAD
-
-# Tame Monster
-K:270:0x80:0xAD
-
-# Frost Bolts
-K:271:0x80:0xAD
-
-# Fire Bolts
-K:272:0x80:0xAD
-
-# Stone to Mud
-K:273:0x80:0xAD
-
-# Polymorph
-K:274:0x80:0xAD
-
-# Heal Monster
-K:275:0x80:0xAD
-
-# Haste Monster
-K:276:0x80:0xAD
-
-# Slow Monster
-K:277:0x80:0xAD
-
-# Confuse Monster
-K:278:0x80:0xAD
-
-# Sleep Monster
-K:279:0x80:0xAD
-
-# Drain Life
-K:280:0x80:0xAD
-
-# Trap/Door Destruction
-K:281:0x80:0xAD
-
-# Magic Missile
-K:282:0x80:0xAD
-
-# Clone Monster
-K:283:0x80:0xAD
-
-# Scare Monster
-K:284:0x80:0xAD
-
-# Teleport Other
-K:285:0x80:0xAD
-
-# Disarming
-K:286:0x80:0xAD
-
-# Lightning Balls
-K:287:0x80:0xAD
-
-# Cold Balls
-K:288:0x80:0xAD
-
-# Fire Balls
-K:289:0x80:0xAD
-
-# Stinking Cloud
-K:290:0x80:0xAD
-
-# Acid Balls
-K:291:0x80:0xAD
-
-# Wonder
-K:292:0x80:0xAD
-
-# & Flight Arrow~
-K:293:0x80:0xFB
-
-# Acid Bolts
-K:294:0x80:0xAD
-
-# Dragon's Flame
-K:295:0x80:0xAD
-
-# Dragon's Frost
-K:296:0x80:0xAD
-
-# Dragon's Breath
-K:297:0x80:0xAD
-
-# Annihilation
-K:298:0x80:0xAD
-
-# Rockets
-K:299:0x80:0xAD
-
-# Trap Location
-K:300:0x80:0xDF
-
-# Treasure Location
-K:301:0x80:0xDF
-
-# Object Location
-K:302:0x80:0xDF
-
-# Teleportation
-K:303:0x80:0xDF
-
-# Earthquakes
-K:304:0x80:0xDF
-
-# Summoning
-K:305:0x80:0xDF
-
-# Light
-K:306:0x80:0xDF
-
-# *Destruction*
-K:307:0x80:0xDF
-
-# Starlight
-K:308:0x80:0xDF
-
-# Haste Monsters
-K:309:0x80:0xDF
-
-# Slow Monsters
-K:310:0x80:0xDF
-
-# Sleep Monsters
-K:311:0x80:0xDF
-
-# Cure Light Wounds
-K:312:0x80:0xDF
-
-# Detect Invisible
-K:313:0x80:0xDF
-
-# Speed
-K:314:0x80:0xDF
-
-# Slowness
-K:315:0x80:0xDF
-
-# Door/Stair Location
-K:316:0x80:0xDF
-
-# Remove Curse
-K:317:0x80:0xDF
-
-# Detect Evil
-K:318:0x80:0xDF
-
-# Curing
-K:319:0x80:0xDF
-
-# Dispel Evil
-K:320:0x80:0xDF
-
-# Probing
-K:321:0x80:0xDF
-
-# Darkness
-K:322:0x80:0xDF
-
-# Genocide
-K:323:0x80:0xDF
-
-# Power
-K:324:0x80:0xDF
-
-# the Magi
-K:325:0x80:0xDF
-
-# Perception
-K:326:0x80:0xDF
-
-# Holiness
-K:327:0x80:0xDF
-
-# Enlightenment
-K:328:0x80:0xDF
-
-# Healing
-K:329:0x80:0xDF
-
-# [Call of the West]
-K:330:0x80:0xBF
-
-# [Light of Valinor]
-K:331:0x80:0xBF
-
-# [Divine Mastery]
-K:332:0x80:0xBF
-
-# [Words of Power]
-K:333:0x80:0xBF
-
-# [Apprentice Handbook]
-K:334:0x80:0xBF
-
-# [Mystical Words]
-K:335:0x80:0xBF
-
-# [Arcane Chants]
-K:336:0x80:0xBF
-
-# [Locus of Force]
-K:337:0x80:0xBF
-
-# & Small wooden chest~
-K:338:0x80:0xFE
-
-# & Large wooden chest~
-K:339:0x80:0xFE
-
-# & Small iron chest~
-K:340:0x80:0xFE
-
-# & Large iron chest~
-K:341:0x80:0xFE
-
-# & Small steel chest~
-K:342:0x80:0xFE
-
-# & Large steel chest~
-K:343:0x80:0xFE
-
-# & Ruined chest~
-K:344:0x80:0xFE
-
-# & Iron Spike~
-K:345:0x81:0x91
-
-# & Wooden Torch~
-K:346:0x80:0xFE
-
-# & Brass Lantern~
-K:347:0x80:0xFE
-
-# & Flask~ of oil
-K:348:0x80:0xA1
-
-# & Empty Bottle~
-K:349:0x80:0xA1
-
-# Havoc
-K:350:0x80:0xAD
-
-# Door/Stair Location
-K:351:0x80:0xAD
-
-# Trap Location
-K:352:0x80:0xAD
-
-# Probing
-K:353:0x80:0xAD
-
-# Recall
-K:354:0x80:0xAD
-
-# Illumination
-K:355:0x80:0xAD
-
-# Light
-K:356:0x80:0xAD
-
-# Lightning Bolts
-K:357:0x80:0xAD
-
-# Frost Bolts
-K:358:0x80:0xAD
-
-# Fire Bolts
-K:359:0x80:0xAD
-
-# Polymorph
-K:360:0x80:0xAD
-
-# Slow Monster
-K:361:0x80:0xAD
-
-# Sleep Monster
-K:362:0x80:0xAD
-
-# Drain Life
-K:363:0x80:0xAD
-
-# Teleport Other
-K:364:0x80:0xAD
-
-# Disarming
-K:365:0x80:0xAD
-
-# Lightning Balls
-K:366:0x80:0xAD
-
-# Cold Balls
-K:367:0x80:0xAD
-
-# Fire Balls
-K:368:0x80:0xAD
-
-# Acid Balls
-K:369:0x80:0xAD
-
-# Acid Bolts
-K:370:0x80:0xAD
-
-# Enlightenment
-K:371:0x80:0xAD
-
-# Perception
-K:372:0x80:0xAD
-
-# Curing
-K:373:0x80:0xAD
-
-# Healing
-K:374:0x80:0xAD
-
-# Detection
-K:375:0x80:0xAD
-
-# Restoration
-K:376:0x80:0xAD
-
-# Speed
-K:377:0x80:0xAD
-
-# [Inner Void]
-K:378:0x80:0xBF
-
-# [Lurkings of the Night]
-K:379:0x80:0xBF
-
-# [Beings of Darkness]
-K:380:0x80:0xBF
-
-# [Material Shadow]
-K:381:0x80:0xBF
-
-# [Sign of Chaos]
-K:383:0x80:0xBF
-
-# [Chaos Mastery]
-K:384:0x80:0xBF
-
-# [Chaos Channels]
-K:385:0x80:0xBF
-
-# [Armageddon Tome]
-K:386:0x80:0xBF
-
-# [Nether Openings]
-K:387:0x80:0xBF
-
-# [Unholy Blessings]
-K:388:0x80:0xBF
-
-# & Firestone~
-K:389:0x80:0xFE
-
-# & Small Firestone~
-K:390:0x80:0xFE
-
-# & Broken Skull~
-K:391:0x80:0xFE
-
-# & Broken Bone~
-K:392:0x80:0xFE
-
-# & Canine Skeleton~
-K:393:0x80:0xFE
-
-# & Rodent Skeleton~
-K:394:0x80:0xFE
-
-# & Human Skeleton~
-K:395:0x80:0xFE
-
-# & Dwarf Skeleton~
-K:396:0x80:0xFE
-
-# & Elf Skeleton~
-K:397:0x80:0xFE
-
-# & Gnome Skeleton~
-K:398:0x80:0xFE
-
-# & Great Hammer~
-K:399:0x80:0xDC
-
-# Black Dragon Scale Mail~
-K:400:0x80:0xDB
-
-# Blue Dragon Scale Mail~
-K:401:0x80:0xDB
-
-# White Dragon Scale Mail~
-K:402:0x80:0xDB
-
-# Red Dragon Scale Mail~
-K:403:0x80:0xDB
-
-# Green Dragon Scale Mail~
-K:404:0x80:0xDB
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x80:0xDB
-
-# Pseudo Dragon Scale Mail~
-K:406:0x80:0xDB
-
-# Law Dragon Scale Mail~
-K:407:0x80:0xDB
-
-# Bronze Dragon Scale Mail~
-K:408:0x80:0xDB
-
-# Gold Dragon Scale Mail~
-K:409:0x80:0xDB
-
-# Chaos Dragon Scale Mail~
-K:410:0x80:0xDB
-
-# Balance Dragon Scale Mail~
-K:411:0x80:0xDB
-
-# Power Dragon Scale Mail~
-K:412:0x80:0xDB
-
-# & Dragon Helm~
-K:413:0x80:0xDD
-
-# & Dragon Shield~
-K:414:0x80:0xDB
-
-# Death
-K:415:0x80:0xA1
-
-# Ruination
-K:416:0x80:0xA1
-
-# Detonations
-K:417:0x80:0xA1
-
-# Augmentation
-K:418:0x80:0xA1
-
-# *Healing*
-K:419:0x80:0xA1
-
-# Life
-K:420:0x80:0xA1
-
-# Self Knowledge
-K:421:0x80:0xA1
-
-# *Enlightenment*
-K:422:0x80:0xA1
-
-# [Necromantic Incantations]
-K:423:0x80:0xBF
-
-# [Curses of Angmar]
-K:424:0x80:0xBF
-
-# Fear Resistance
-K:425:0x80:0xBD
-
-# Light and Darkness Resistance
-K:426:0x80:0xBD
-
-# Nether Resistance
-K:427:0x80:0xBD
-
-# Nexus Resistance
-K:428:0x80:0xBD
-
-# Sound Resistance
-K:429:0x80:0xBD
-
-# Confusion Resistance
-K:430:0x80:0xBD
-
-# Shard Resistance
-K:431:0x80:0xBD
-
-# Disenchantment Resistance
-K:432:0x80:0xBD
-
-# Chaos Resistance
-K:433:0x80:0xBD
-
-# Blindness Resistance
-K:434:0x80:0xBD
-
-# Lordly Protection
-K:435:0x80:0xBD
-
-# Extra Attacks
-K:436:0x80:0xBD
-
-# Cure Light Wounds
-K:437:0x80:0xA1
-
-# Clumsiness
-K:438:0x80:0xA1
-
-# Sickliness
-K:439:0x80:0xA1
-
-# Map of Bree
-K:440:0x80:0xBF
-
-# Map of Gondolin
-K:441:0x80:0xBF
-
-# Map of LothLorien
-K:442:0x80:0xBF
-
-# Map of Minas Anor
-K:443:0x80:0xBF
-
-# copper
-K:480:0x81:0xCA
-
-# copper
-K:481:0x81:0xC9
-
-# copper
-K:482:0x81:0xC8
-
-# silver
-K:483:0x80:0xA4
-
-# silver
-K:484:0x80:0xA4
-
-# silver
-K:485:0x80:0xA4
-
-# garnets
-K:486:0x80:0xA4
-
-# garnets
-K:487:0x80:0xA4
-
-# gold
-K:488:0x80:0xA4
-
-# gold
-K:489:0x80:0xA4
-
-# gold
-K:490:0x80:0xA4
-
-# opals
-K:491:0x80:0xA4
-
-# sapphires
-K:492:0x80:0xA4
-
-# rubies
-K:493:0x80:0xA4
-
-# diamonds
-K:494:0x80:0xA4
-
-# emeralds
-K:495:0x80:0xA4
-
-# mithril
-K:496:0x80:0xA4
-
-# adamantite
-K:497:0x80:0xA4
-
-# & Mighty Hammer~
-K:498:0x80:0xDC
-
-# & Massive Iron Crown~
-K:499:0x80:0xDD
-
-# & Phial~
-K:500:0x80:0xFE
-
-# & Star~
-K:501:0x80:0xFE
-
-# & Arkenstone~
-K:502:0x80:0xFE
-
-# & Amulet~
-K:503:0x80:0xA2
-
-# & Amulet~
-K:504:0x80:0xA2
-
-# & Necklace~
-K:505:0x80:0xA2
-
-# & Ring~
-K:506:0x80:0xBD
-
-# & Ring~
-K:507:0x80:0xBD
-
-# & Ring~
-K:508:0x80:0xBD
-
-# & Ring~
-K:509:0x80:0xBD
-
-# & Ring~
-K:510:0x80:0xBD
-
-# & Ring~
-K:511:0x80:0xBD
-
-# [Rites of Initiation]
-K:512:0x80:0xBF
-
-# [Ways of War]
-K:513:0x80:0xBF
-
-# [Divine Retribution]
-K:514:0x80:0xBF
-
-# [Essence of Fury]
-K:515:0x80:0xBF
-
-# [Novice Crafts]
-K:516:0x80:0xBF
-
-# [Arcane Channels]
-K:517:0x80:0xBF
-
-# [Sigils of Wizardry]
-K:518:0x80:0xBF
-
-# [Mana Focus]
-K:519:0x80:0xBF
-
-# Reflection
-K:520:0x80:0xA2
-
-# Anti-Magic
-K:521:0x80:0xA2
-
-# Anti-Teleportation
-K:522:0x80:0xA2
-
-# Resistance
-K:523:0x80:0xA2
-
-# & Zweihander~
-K:524:0x80:0xFC
-
-# & Tanto~
-K:525:0x80:0xFC
-
-# Splint Mail~
-K:526:0x80:0xDB
-
-# Do-maru~
-K:527:0x80:0xDB
-
-# & Trifurcate Spear~
-K:528:0x80:0xAF
-
-# & Three Piece Rod~
-K:529:0x80:0xDC
-
-# O-yoroi~
-K:530:0x80:0xDB
-
-# & Fur Cloak~
-K:531:0x80:0xA8
-
-# & Lajatang~
-K:532:0x80:0xAF
-
-# & Hatchet~
-K:533:0x80:0xAF
-
-# Rhino Hide Armour~
-K:535:0x80:0xA8
-
-# Leather Jacket~
-K:536:0x80:0xA8
-
-# & Sickle~
-K:537:0x80:0xAF
-
-# & Tetsubo~
-K:538:0x80:0xDC
-
-# & Nunchaku~
-K:539:0x80:0xDC
-
-# & Bo Staff~
-K:540:0x80:0xDC
-
-# & Jo Staff~
-K:541:0x80:0xDC
-
-# & Club~
-K:542:0x80:0xDC
-
-# & Broad Spear~
-K:543:0x80:0xAF
-
-# & Khopesh~
-K:544:0x80:0xFC
-
-# & Flamberge~
-K:545:0x80:0xFC
-
-# & Claymore~
-K:546:0x80:0xFC
-
-# & Espadon~
-K:547:0x80:0xFC
-
-# & Great Scimitar~
-K:548:0x80:0xFC
-
-# & Wakizashi~
-K:549:0x80:0xFC
-
-# & Naginata~
-K:550:0x80:0xAF
-
-# & Fauchard~
-K:551:0x80:0xAF
-
-# & Guisarme~
-K:552:0x80:0xAF
-
-# & Heavy Lance~
-K:553:0x80:0xAF
-
-# & Basillard~
-K:554:0x80:0xFC
-
-# & Ninjato~
-K:555:0x80:0xFC
-
-# Ring Mail~
-K:556:0x80:0xDB
-
-# Cord Armour~
-K:557:0x80:0xA8
-
-# Paper Armour~
-K:558:0x80:0xA8
-
-# Padded Armour~
-K:559:0x80:0xA8
-
-# & Kabuto~
-K:560:0x80:0xDD
-
-# Stone and Hide Armour~
-K:561:0x80:0xA8
-
-# & Jingasa~
-K:562:0x80:0xDD
-
-# Haramakido~
-K:563:0x80:0xDB
-
-# Nothing
-K:564:0x80:0xBF
-
-# Poison
-K:565:0x80:0xAA
-
-# Nothing
-K:566:0x80:0xAD
-
-# Nothing
-K:567:0x80:0xAD
-
-# Nothing
-K:568:0x80:0xAD
-
-# Nothing
-K:569:0x80:0xAD
-
-# Explosion
-K:570:0x80:0xAA
-
-# Teleport
-K:571:0x80:0xAA
-
-# Nothing
-K:572:0x80:0xAD
-
-# the Blood of Life
-K:573:0x80:0xA1
-
-# Cold
-K:574:0x80:0xAA
-
-# Fire
-K:575:0x80:0xAA
-
-# Acid
-K:576:0x80:0xAA
-
-# & Mage Staff~
-K:577:0x80:0xDC
-
-# Life
-K:579:0x80:0xAA
-
-# Confusion
-K:580:0x80:0xAA
-
-# Light
-K:581:0x80:0xAA
-
-# & Ring~
-K:582:0x80:0xBD
-
-# Invisibility
-K:583:0x80:0xA1
-
-# Chaos
-K:584:0x80:0xAA
-
-# Mutation
-K:585:0x80:0xA1
-
-# Invisibility
-K:586:0x80:0xBD
-
-# Time
-K:587:0x80:0xAA
-
-# Deep Thoughts
-K:588:0x80:0xBF
-
-# More Deep Thoughts
-K:589:0x80:0xBF
-
-# Compendium of Deep Thoughts
-K:590:0x80:0xBF
-
-# Artifact Lore Vol. I
-K:591:0x80:0xBF
-
-# Artifact Lore Vol. II
-K:592:0x80:0xBF
-
-# Artifact Lore Vol. III
-K:593:0x80:0xBF
-
-# Monstrous Compendium 1
-K:594:0x80:0xBF
-
-# Monstrous Compendium 2
-K:595:0x80:0xBF
-
-# Monstrous Compendium 3
-K:596:0x80:0xBF
-
-# Monstrous Compendium 4
-K:597:0x80:0xBF
-
-# Monstrous Compendium 5
-K:598:0x80:0xBF
-
-# Monstrous Compendium 6
-K:599:0x80:0xBF
-
-# Monstrous Compendium 7
-K:600:0x80:0xBF
-
-# Monstrous Compendium 8
-K:601:0x80:0xBF
-
-# Monstrous Compendium 9
-K:602:0x80:0xBF
-
-# Monstrous Compendium 10
-K:603:0x80:0xBF
-
-# Monstrous Compendium 11
-K:604:0x80:0xBF
-
-# Abomination
-K:605:0x80:0xA1
-
-# Shape of Wolf
-K:606:0x80:0xA1
-
-# Shape of Ape
-K:607:0x80:0xA1
-
-# Shape of Goat
-K:608:0x80:0xA1
-
-# Shape of Insect
-K:609:0x80:0xA1
-
-# Shape of Sparrow
-K:610:0x80:0xA1
-
-# Shape of Ent
-K:611:0x80:0xA1
-
-# Shape of Vampire
-K:612:0x80:0xA1
-
-# Shape of Spider
-K:613:0x80:0xA1
-
-# Shape of Mana ball
-K:614:0x80:0xA1
-
-# Shape of Fire cloud
-K:615:0x80:0xA1
-
-# Shape of Cold cloud
-K:616:0x80:0xA1
-
-# Shape of Chaos cloud
-K:617:0x80:0xA1
-
-# [Wolf]
-K:618:0x80:0xBF
-
-# [Ape]
-K:619:0x80:0xBF
-
-# [Goat]
-K:620:0x80:0xBF
-
-# [Insect]
-K:621:0x80:0xBF
-
-# [Sparrow]
-K:622:0x80:0xBF
-
-# [Ent]
-K:623:0x80:0xBF
-
-# [Vampire]
-K:624:0x80:0xBF
-
-# [Spider]
-K:625:0x80:0xBF
-
-# [Mana ball]
-K:626:0x80:0xBF
-
-# [Fire cloud]
-K:627:0x80:0xBF
-
-# [Cold cloud]
-K:628:0x80:0xBF
-
-# [Chaos Cloud]
-K:629:0x80:0xBF
-
-# [Ghost]
-K:630:0x80:0xBF
-
-# [Kobold]
-K:631:0x80:0xBF
-
-# [Dragon]
-K:632:0x80:0xBF
-
-# [Demon]
-K:633:0x80:0xBF
-
-# [Hound]
-K:634:0x80:0xBF
-
-# [Quylthulg]
-K:635:0x80:0xBF
-
-# [Maia]
-K:636:0x80:0xBF
-
-# [Serpent]
-K:637:0x80:0xBF
-
-# [Giant]
-K:638:0x80:0xBF
-
-# [Vala]
-K:639:0x80:0xBF
-
-# Magic
-K:640:0x80:0xAA
-
-# corpse
-K:641:0x80:0xFE
-
-# skeleton
-K:642:0x80:0xFE
-
-# head
-K:643:0x80:0xFE
-
-# skull
-K:644:0x80:0xFE
-
-# raw meat
-K:645:0x80:0xFE
-
-# & Dragonrider Coat~
-K:646:0x80:0xA8
-
-# & Stone~
-K:647:0x80:0xFE
-
-# & small wooden Boomerang~
-K:648:0x80:0xFB
-
-# & wooden Boomerang~
-K:649:0x80:0xFB
-
-# & small metal Boomerang~
-K:650:0x80:0xFB
-
-# & metal Boomerang~
-K:651:0x80:0xFB
-
-# & Anchor~
-K:652:0x80:0xFE
-
-# & ~
-K:653:0x80:0xFE
-
-# Summon never-moving pet
-K:654:0x80:0xBF
-
-# [Life in symbiosis]
-K:655:0x80:0xBF
-
-# [Perfect Symbiosis]
-K:656:0x80:0xBF
-
-# Cure Light Insanity
-K:657:0x80:0xA1
-
-# Cure Serious Insanity
-K:658:0x80:0xA1
-
-# Cure Critical Insanity
-K:659:0x80:0xA1
-
-# Cure Insanity
-K:660:0x80:0xA1
-
-# & Phial~
-K:661:0x80:0xFE
-
-# Random Artifact
-K:662:0x80:0xFE
-
-# Craftmanship
-K:663:0x80:0xBF
-
-# The One Ring
-K:664:0x80:0xBF
-
-# [Apprentice Handbook]
-K:665:0x80:0xBF
-
-# [Minstrel's Music]
-K:666:0x80:0xBF
-
-# [Harps of Rivendell]
-K:667:0x80:0xBF
-
-# [Lays of Beleriand]
-K:668:0x80:0xBF
-
-# & Flute~
-K:669:0x80:0xAF
-
-# & Drum~
-K:670:0x80:0xAF
-
-# & Harp~
-K:671:0x80:0xAF
-
-# & Banjo~
-K:672:0x80:0xAF
-
-# & Lute~
-K:673:0x80:0xAF
-
-# & Mandolin~
-K:674:0x80:0xAF
-
-# & Palantir~
-K:675:0x80:0xA1
-
-# Egg
-K:676:0x80:0xEF
-
-# Reset Recall
-K:677:0x80:0xBF
-
-# Divination
-K:678:0x80:0xBF
-
-# Self
-K:679:0x80:0xBF
-
-# Ray
-K:680:0x80:0xBF
-
-# Sphere
-K:681:0x80:0xBF
-
-# Knowledge
-K:682:0x80:0xBF
-
-# Life
-K:683:0x80:0xBF
-
-# Fire
-K:684:0x80:0xBF
-
-# Cold
-K:685:0x80:0xBF
-
-# Lightning
-K:686:0x80:0xBF
-
-# Acid
-K:687:0x80:0xBF
-
-# Element
-K:688:0x80:0xBF
-
-# Chaos
-K:689:0x80:0xBF
-
-# Mind
-K:690:0x80:0xBF
-
-# Holding
-K:691:0x80:0xBF
-
-# Arrow
-K:692:0x80:0xBF
-
-# Power Surge
-K:693:0x80:0xBF
-
-# Armageddon
-K:694:0x80:0xBF
-
-# Gravity
-K:695:0x80:0xBF
-
-# Extra Life
-K:696:0x80:0xAA
-
-# Anti-Death
-K:697:0x80:0xBF
-
-# Protection
-K:698:0x80:0xBF
-
-# & Horn~
-K:699:0x80:0xAF
-
-# Precognition
-K:700:0x80:0xBD
-
-# & Sprig~ of Athelas
-K:701:0x80:0xAC
-
-# [Magic for Beginners]
-K:702:0x80:0xBF
-
-# [Conjurings and Tricks]
-K:703:0x80:0xBF
-
-# [Incantations and Illusions]
-K:704:0x80:0xBF
-
-# [Sorcery and Evocations]
-K:705:0x80:0xBF
-
-# [Beginners Handbook]
-K:706:0x80:0xBF
-
-# [Words of Wisdom]
-K:707:0x80:0xBF
-
-# [Chants and Blessings]
-K:708:0x80:0xBF
-
-# [Exorcism and Dispelling]
-K:709:0x80:0xBF
-
-# [Resistance of Scarabtarices]
-K:710:0x80:0xBF
-
-# [Mordenkainen's Escapes]
-K:711:0x80:0xBF
-
-# [Kelek's Grimoire of Power]
-K:712:0x80:0xBF
-
-# [Tenser's Transformations]
-K:713:0x80:0xBF
-
-# [Raal's Tome of Destruction]
-K:714:0x80:0xBF
-
-# [Ethereal Openings]
-K:715:0x80:0xBF
-
-# [Godly Insights]
-K:716:0x80:0xBF
-
-# [Purifications and Healing]
-K:717:0x80:0xBF
-
-# [Holy Infusions]
-K:718:0x80:0xBF
-
-# [Wrath of God]
-K:719:0x80:0xBF
-
-# Deincarnation
-K:720:0x80:0xBF
-
-# Numenorean for beginners
-K:722:0x80:0xBF
-
-# Numenorean for beginners
-K:723:0x80:0xBF
-
-# Advanced lessons of Numenorean
-K:724:0x80:0xBF
-
-# Advanced lessons of Sindarin
-K:725:0x80:0xBF
-
-# & Shard~ of Pottery
-K:726:0x80:0xFE
-
-# & Broken Stick~
-K:727:0x80:0xFE
-
-# Wall Creation
-K:728:0x80:0xAD
-
-# [Illusions for Beginners]
-K:729:0x80:0xBF
-
-# [Tricks and Visions]
-K:730:0x80:0xBF
-
-# [Phantasms and Illusions]
-K:731:0x80:0xBF
-
-# [Shadows and Prisms]
-K:732:0x80:0xBF
-
-# [Serten's Immunities]
-K:733:0x80:0xBF
-
-# [Knowledge of Kenault]
-K:734:0x80:0xBF
-
-# [Otiluke's Spheres]
-K:735:0x80:0xBF
-
-# [Boccob's Book of Shadows]
-K:736:0x80:0xBF
-
-# [Bigby's Handbook]
-K:737:0x80:0xBF
-
-# [Hunt of Orome]
-K:738:0x80:0xBF
-
-# [Holy Sanctifications]
-K:739:0x80:0xBF
-
-# [Secrets of the Feanturi]
-K:740:0x80:0xBF
-
-# [War of Wrath]
-K:741:0x80:0xBF
-
-# [Gifts of Iluvatar]
-K:742:0x80:0xBF
-
-# Learning
-K:743:0x80:0xA1
-
-# [Eye of Sauron]
-K:744:0x80:0xBF
-
-# [Flame of Udun]
-K:745:0x80:0xBF
-
-# [Corruptions of Melkor]
-K:746:0x80:0xBF
-
-# [Crescent of Morgul]
-K:747:0x80:0xBF
-
-# [Morgoth's Ring]
-K:748:0x80:0xBF
-
-# Spell
-K:749:0x80:0xBF
-
-# Wishing
-K:750:0x80:0xDF
-
-# Khuzdul - The hidden tonge of the Dwarves
-K:751:0x80:0xBF
-
-# Nandorin for the dumbs
-K:752:0x80:0xBF
-
-# Advanced lessons of Orkish
-K:753:0x80:0xBF
-
-# Flying
-K:755:0x80:0xBD
-
-# [Powerful Sigils]
-K:756:0x80:0xBF
-
-# [Disruptive Forces]
-K:758:0x80:0xBF
-
-# [Forces of the Mind]
-K:759:0x80:0xBF
-
-# [Power of Ancient Sorcerors]
-K:760:0x80:0xBF
-
-# [Tricks of the Wild]
-K:761:0x80:0xBF
-
-# [Mastering the Rituals]
-K:762:0x80:0xBF
-
-# [Rites of Power]
-K:763:0x80:0xBF
-
-# [Tribal Power]
-K:764:0x80:0xBF
-
-# [Aiding Shades]
-K:765:0x80:0xBF
-
-# [Morgoth's Space-Time Warpings]
-K:766:0x80:0xBF
-
-# [Murazor Tome of Conjuring & Dispeling]
-K:767:0x80:0xBF
-
-# [Channeling the Void]
-K:768:0x80:0xBF
-
-# [Sauron's Forgotten Tome]
-K:769:0x80:0xBF
-
-# Wraith Form
-K:770:0x80:0xBD
-
-# [Earth]
-K:771:0x80:0xBF
-
-# [Fire]
-K:772:0x80:0xBF
-
-# [Air]
-K:773:0x80:0xBF
-
-# [Water]
-K:774:0x80:0xBF
-
-# [Mana]
-K:775:0x80:0xBF
-
-# Home Summoning
-K:776:0x80:0xAD
-
-# & Shadow Blade~
-K:777:0x80:0xFC
-
-# & Bluesteel Blade~
-K:778:0x80:0xFC
-
-# the Serpents
-K:779:0x80:0xA2
-
-# Darkness
-K:780:0x80:0xAA
-
-# Knowledge
-K:781:0x80:0xAA
-
-# Force
-K:782:0x80:0xAA
-
-# Lightning
-K:783:0x80:0xAA
-
-# Mana
-K:784:0x80:0xAA
-
-# Power
-K:785:0x80:0xBD
-
-# Climbing Set
-K:786:0x80:0xE0
-
-# Adventurer's Guide to Middle-earth
-K:787:0x80:0xBF
-
-# [Dark Incantations]
-K:788:0x80:0xBF
-
-# [Immortal Rituals]
-K:789:0x80:0xBF
-
-# [Minions of Azathoth]
-K:790:0x80:0xBF
-
-# [Demonthoughts]
-K:791:0x80:0xBF
-
-# [Hellfire Tome]
-K:792:0x80:0xBF
-
-# & Wooden Rod~ of#
-K:793:0x80:0xAD
-
-# & Copper Rod~ of#
-K:794:0x80:0xAD
-
-# & Iron Rod~ of#
-K:795:0x80:0xAD
-
-# & Aluminium Rod~ of#
-K:796:0x80:0xAD
-
-# & Silver Rod~ of#
-K:797:0x80:0xAD
-
-# & Golden Rod~ of#
-K:798:0x80:0xAD
-
-# & Mithril Rod~ of#
-K:799:0x80:0xAD
-
-# & Adamantite Rod~ of#
-K:800:0x80:0xAD
-
-
-
-
-
-
-
-# Monster attr/char definitions
-
-# Player
-R:0:0x80:0xC0
-
-# Filthy street urchin
-R:1:0x80:0xF4
-
-# Scrawny cat
-R:2:0x80:0xE6
-
-# Sparrow
-R:3:0x80:0xC2
-
-# Chaffinch
-R:4:0x80:0xC2
-
-# Wild rabbit
-R:5:0x80:0xF2
-
-# Woodsman
-R:6:0x80:0xF0
-
-# Scruffy little dog
-R:7:0x80:0xC3
-
-# Farmer Maggot
-R:8:0x81:0xBB
-
-# Blubbering idiot
-R:9:0x80:0xF4
-
-# Boil-covered wretch
-R:10:0x80:0xF4
-
-# Village idiot
-R:11:0x80:0xF4
-
-# Pitiful looking beggar
-R:12:0x80:0xF4
-
-# Mangy looking leper
-R:13:0x80:0xF4
-
-# Agent of black market
-R:14:0x81:0xB8
-
-# Singing, happy drunk
-R:15:0x81:0xB9
-
-# Aimless looking merchant
-R:16:0x81:0xBA
-
-# Mean looking mercenary
-R:17:0x80:0xF4
-
-# Battle scarred veteran
-R:18:0x81:0xC3
-
-# Martti Ihrasaari
-R:19:0x80:0xD0
-
-# Grey mold
-R:20:0x81:0x32
-
-# Large white snake
-R:21:0x81:0xA0
-
-# Grey mushroom patch
-R:22:0x80:0xAC
-
-# Newt
-R:23:0x80:0xD2
-
-# Giant white centipede
-R:24:0x80:0xE3
-
-# White icky thing
-R:25:0x80:0xE9
-
-# Clear icky thing
-R:26:0x80:0xE9
-
-# Giant white mouse
-R:27:0x80:0xF2
-
-# Large brown snake
-R:28:0x81:0xA1
-
-# Small kobold
-R:29:0x80:0xEB
-
-# Kobold
-R:30:0x80:0xEB
-
-# White worm mass
-R:31:0x80:0xF7
-
-# Floating eye
-R:32:0x80:0xE5
-
-# Rock lizard
-R:33:0x80:0xD2
-
-# Grid bug
-R:34:0x81:0xA9
-
-# Jackal
-R:35:0x81:0xB1
-
-# Soldier ant
-R:36:0x81:0xAA
-
-# Fruit bat
-R:37:0x80:0xE2
-
-# Insect swarm
-R:38:0x81:0xA8
-
-# Greater hell-beast
-R:39:0x80:0xD5
-
-# Shrieker mushroom patch
-R:40:0x80:0xAC
-
-# Blubbering icky thing
-R:41:0x80:0xE9
-
-# Metallic green centipede
-R:42:0x80:0xE3
-
-# Novice warrior
-R:43:0x81:0xC2
-
-# Novice rogue
-R:44:0x80:0xF0
-
-# Novice priest
-R:45:0x80:0xF0
-
-# Novice mage
-R:46:0x80:0xF0
-
-# Yellow mushroom patch
-R:47:0x80:0xAC
-
-# White jelly
-R:48:0x80:0xEA
-
-# Giant black ant
-R:49:0x80:0xE1
-
-# Salamander
-R:50:0x80:0xD2
-
-# White harpy
-R:51:0x80:0xC8
-
-# Blue yeek
-R:52:0x80:0xF9
-
-# Grip, Farmer Maggot's dog
-R:53:0x80:0xC3
-
-# Wolf, Farmer Maggot's dog
-R:54:0x80:0xC3
-
-# Fang, Farmer Maggot's dog
-R:55:0x80:0xC3
-
-# Giant green frog
-R:56:0x80:0xD2
-
-# Freesia
-R:57:0x80:0xE6
-
-# Green worm mass
-R:58:0x80:0xF7
-
-# Large yellow snake
-R:59:0x80:0xCA
-
-# Cave spider
-R:60:0x80:0xD3
-
-# Crow
-R:61:0x80:0xC2
-
-# Wild cat
-R:62:0x80:0xE6
-
-# Smeagol
-R:63:0x80:0xE8
-
-# Green ooze
-R:64:0x80:0xEA
-
-# Poltergeist
-R:65:0x80:0xC7
-
-# Yellow jelly
-R:66:0x80:0xEA
-
-# Metallic blue centipede
-R:67:0x80:0xE3
-
-# Raven
-R:68:0x80:0xC2
-
-# Giant white louse
-R:69:0x80:0xEC
-
-# Piranha
-R:70:0x80:0xFE
-
-# Black naga
-R:71:0x80:0xEE
-
-# Spotted mushroom patch
-R:72:0x80:0xAC
-
-# Silver jelly
-R:73:0x80:0xEA
-
-# Scruffy looking hobbit
-R:74:0x80:0xE8
-
-# Giant white ant
-R:75:0x80:0xE1
-
-# Yellow mold
-R:76:0x80:0xED
-
-# Metallic red centipede
-R:77:0x80:0xE3
-
-# Yellow worm mass
-R:78:0x80:0xF7
-
-# Clear worm mass
-R:79:0x80:0xF7
-
-# Radiation eye
-R:80:0x80:0xE5
-
-# Yellow light
-R:81:0x80:0xAA
-
-# Cave lizard
-R:82:0x80:0xD2
-
-# Novice ranger
-R:83:0x80:0xF0
-
-# Blue jelly
-R:84:0x80:0xEA
-
-# Creeping copper coins
-R:85:0x80:0xA4
-
-# Giant white rat
-R:86:0x80:0xF2
-
-# Snotling
-R:87:0x80:0xEF
-
-# Swordfish
-R:88:0x80:0xFE
-
-# Blue worm mass
-R:89:0x80:0xF7
-
-# Large grey snake
-R:90:0x80:0xCA
-
-# Skeleton kobold
-R:91:0x80:0xF3
-
-# Ewok
-R:92:0x80:0xE8
-
-# Novice mage
-R:93:0x80:0xF0
-
-# Green naga
-R:94:0x80:0xEE
-
-# Giant leech
-R:95:0x80:0xF7
-
-# Barracuda
-R:96:0x80:0xFE
-
-# Novice paladin
-R:97:0x80:0xF0
-
-# Zog
-R:98:0x80:0xE8
-
-# Blue ooze
-R:99:0x80:0xEA
-
-# Green glutton ghost
-R:100:0x80:0xC7
-
-# Green jelly
-R:101:0x80:0xEA
-
-# Large kobold
-R:102:0x80:0xEB
-
-# Grey icky thing
-R:103:0x80:0xE9
-
-# Disenchanter eye
-R:104:0x80:0xE5
-
-# Red worm mass
-R:105:0x80:0xF7
-
-# Copperhead snake
-R:106:0x80:0xCA
-
-# Death sword
-R:107:0x80:0xFC
-
-# Purple mushroom patch
-R:108:0x80:0xAC
-
-# Novice priest
-R:109:0x80:0xF0
-
-# Novice warrior
-R:110:0x80:0xF0
-
-# Nibelung
-R:111:0x80:0xE8
-
-# Disembodied hand that strangled people
-R:112:0x80:0xFA
-
-# Brown mold
-R:113:0x80:0xED
-
-# Giant brown bat
-R:114:0x80:0xE2
-
-# Rat-thing
-R:115:0x80:0xF2
-
-# Novice archer
-R:116:0x81:0xC1
-
-# Creeping silver coins
-R:117:0x80:0xA4
-
-# Snaga
-R:118:0x80:0xEF
-
-# Rattlesnake
-R:119:0x80:0xCA
-
-# Giant slug
-R:120:0x80:0xF7
-
-# Giant pink frog
-R:121:0x80:0xD2
-
-# Dark elf
-R:122:0x80:0xE8
-
-# Zombified kobold
-R:123:0x80:0xFA
-
-# Crypt Creep
-R:124:0x80:0xF3
-
-# Rotting corpse
-R:125:0x80:0xFA
-
-# Cave orc
-R:126:0x81:0xBC
-
-# Wood spider
-R:127:0x80:0xD3
-
-# Manes
-R:128:0x80:0xF5
-
-# Bloodshot eye
-R:129:0x80:0xE5
-
-# Red naga
-R:130:0x80:0xEE
-
-# Red jelly
-R:131:0x80:0xEA
-
-# Green icky thing
-R:132:0x80:0xE9
-
-# Lost soul
-R:133:0x80:0xC7
-
-# Night lizard
-R:134:0x80:0xD2
-
-# Mughash the Kobold Lord
-R:135:0x80:0xEB
-
-# Skeleton orc
-R:136:0x80:0xF3
-
-# Wormtongue, Agent of Saruman
-R:137:0x80:0xF0
-
-# Robin Hood, the Outlaw
-R:138:0x80:0xF0
-
-# Nurgling
-R:139:0x80:0xF5
-
-# Lagduf, the Snaga
-R:140:0x80:0xEF
-
-# Brown yeek
-R:141:0x80:0xF9
-
-# Novice ranger
-R:142:0x80:0xF0
-
-# Giant salamander
-R:143:0x80:0xD2
-
-# Space monster
-R:144:0x80:0xAE
-
-# Carnivorous flying monkey
-R:145:0x80:0xC8
-
-# Green mold
-R:146:0x80:0xED
-
-# Novice paladin
-R:147:0x80:0xF0
-
-# Lemure
-R:148:0x80:0xF5
-
-# Hill orc
-R:149:0x80:0xEF
-
-# Bandit
-R:150:0x80:0xF0
-
-# Hunting hawk
-R:151:0x80:0xC2
-
-# Phantom warrior
-R:152:0x80:0xC7
-
-# Gremlin
-R:153:0x80:0xF5
-
-# Yeti
-R:154:0x80:0xD9
-
-# Bloodshot icky thing
-R:155:0x80:0xE9
-
-# Giant grey rat
-R:156:0x80:0xF2
-
-# Black harpy
-R:157:0x80:0xC8
-
-# Skaven
-R:158:0x80:0xF2
-
-# The wounded bear
-R:159:0x80:0xF1
-
-# Portuguese man-o-war
-R:160:0x80:0xEA
-
-# Rock mole
-R:161:0x80:0xF2
-
-# Orc shaman
-R:162:0x80:0xEF
-
-# Baby blue dragon
-R:163:0x80:0xE4
-
-# Baby white dragon
-R:164:0x80:0xE4
-
-# Baby green dragon
-R:165:0x80:0xE4
-
-# Baby black dragon
-R:166:0x80:0xE4
-
-# Baby red dragon
-R:167:0x80:0xE4
-
-# Giant red ant
-R:168:0x80:0xE1
-
-# Brodda, the Easterling
-R:169:0x80:0xF0
-
-# Bloodfang the Wolf
-R:170:0x80:0xC3
-
-# King cobra
-R:171:0x80:0xCA
-
-# Eagle
-R:172:0x80:0xC2
-
-# War bear
-R:173:0x80:0xF1
-
-# Killer bee
-R:174:0x80:0xC9
-
-# Giant spider
-R:175:0x80:0xD3
-
-# Giant white tick
-R:176:0x80:0xD3
-
-# The Borshin
-R:177:0x80:0xE7
-
-# Dark elven mage
-R:178:0x80:0xE8
-
-# Kamikaze yeek
-R:179:0x80:0xF9
-
-# Orfax, Son of Boldor
-R:180:0x80:0xF9
-
-# Servant of Glaaki
-R:181:0x80:0xFA
-
-# Dark elven warrior
-R:182:0x81:0xBF
-
-# Sand-dweller
-R:183:0x80:0xF5
-
-# Clear mushroom patch
-R:184:0x80:0xAC
-
-# Quiver slot
-R:185:0x80:0xAC
-
-# Grishnakh, the Hill Orc
-R:186:0x80:0xEF
-
-# Giant piranha
-R:187:0x80:0xFE
-
-# Owlbear
-R:188:0x80:0xC8
-
-# Blue horror
-R:189:0x80:0xF5
-
-# Hairy mold
-R:190:0x80:0xED
-
-# Grizzly bear
-R:191:0x80:0xF1
-
-# Disenchanter mold
-R:192:0x80:0xED
-
-# Pseudo dragon
-R:193:0x80:0xE4
-
-# Tengu
-R:194:0x80:0xF5
-
-# Creeping gold coins
-R:195:0x80:0xA4
-
-# Wolf
-R:196:0x80:0xC3
-
-# Giant fruit fly
-R:197:0x80:0xC9
-
-# Panther
-R:198:0x80:0xE6
-
-# Brigand
-R:199:0x80:0xF0
-
-# Hobbes the Tiger
-R:200:0x80:0xE6
-
-# Shadow Creature of Fiona
-R:201:0x80:0xE8
-
-# Undead mass
-R:202:0x80:0xEA
-
-# Chaos shapechanger
-R:203:0x80:0xC8
-
-# Baby multi-hued dragon
-R:204:0x80:0xE4
-
-# Vorpal bunny
-R:205:0x80:0xF2
-
-# Old Man Willow
-R:206:0x80:0xA3
-
-# Hippocampus
-R:207:0x80:0xC8
-
-# Zombified orc
-R:208:0x80:0xFA
-
-# Hippogriff
-R:209:0x80:0xC8
-
-# Black mamba
-R:210:0x80:0xCA
-
-# White wolf
-R:211:0x80:0xC3
-
-# Grape jelly
-R:212:0x80:0xEA
-
-# Nether worm mass
-R:213:0x80:0xF7
-
-# Abyss worm mass
-R:214:0x80:0xF7
-
-# Golfimbul, the Hill Orc Chief
-R:215:0x80:0xEF
-
-# Swordsman
-R:216:0x80:0xF0
-
-# Skaven shaman
-R:217:0x80:0xF2
-
-# Gazer
-R:218:0x80:0xE5
-
-# Knight archer
-R:219:0x80:0xF0
-
-# Ixitxachitl
-R:220:0x80:0xFE
-
-# Mine-dog
-R:221:0x80:0xC3
-
-# Hellcat
-R:222:0x80:0xE6
-
-# Moon beast
-R:223:0x80:0xF1
-
-# Master yeek
-R:224:0x80:0xF9
-
-# Priest
-R:225:0x80:0xF0
-
-# Dark elven priest
-R:226:0x80:0xE8
-
-# Air spirit
-R:227:0x80:0xC5
-
-# Skeleton human
-R:228:0x80:0xF3
-
-# Zombified human
-R:229:0x80:0xFA
-
-# Tiger
-R:230:0x80:0xE6
-
-# Moaning spirit
-R:231:0x80:0xC7
-
-# Stegocentipede
-R:232:0x80:0xE3
-
-# Spotted jelly
-R:233:0x80:0xEA
-
-# Drider
-R:234:0x80:0xD3
-
-# Mongbat
-R:235:0x80:0xE2
-
-# Killer brown beetle
-R:236:0x80:0xCB
-
-# Boldor, King of the Yeeks
-R:237:0x80:0xF9
-
-# Ogre
-R:238:0x81:0xBD
-
-# Creeping mithril coins
-R:239:0x80:0xA4
-
-# Illusionist
-R:240:0x80:0xF0
-
-# Druid
-R:241:0x80:0xF0
-
-# Pink horror
-R:242:0x80:0xF5
-
-# Cloaker
-R:243:0x80:0xA8
-
-# Black orc
-R:244:0x80:0xEF
-
-# Ochre jelly
-R:245:0x80:0xEA
-
-# Software bug
-R:246:0x80:0xC9
-
-# Lurker
-R:247:0x80:0xAE
-
-# Nixie
-R:248:0x80:0xE8
-
-# Vlasta
-R:249:0x80:0xD2
-
-# Giant white dragon fly
-R:250:0x80:0xC6
-
-# Snaga sapper
-R:251:0x80:0xEF
-
-# Blue icky thing
-R:252:0x80:0xE9
-
-# Gibbering mouther
-R:253:0x80:0xEA
-
-# Irish wolfhound of Flora
-R:254:0x80:0xC3
-
-# Hill giant
-R:255:0x80:0xD0
-
-# Flesh golem
-R:256:0x80:0xE7
-
-# Warg
-R:257:0x80:0xC3
-
-# Cheerful leprechaun
-R:258:0x80:0xE8
-
-# Giant black flea
-R:259:0x80:0xC9
-
-# Ufthak of Cirith Ungol
-R:260:0x80:0xEF
-
-# Clay golem
-R:261:0x80:0xE7
-
-# Black ogre
-R:262:0x80:0xCF
-
-# Dweller on the threshold
-R:263:0x80:0xD9
-
-# Half-orc
-R:264:0x80:0xEF
-
-# Dark naga
-R:265:0x80:0xEE
-
-# Giant octopus
-R:266:0x80:0xFE
-
-# Magic mushroom patch
-R:267:0x80:0xAC
-
-# Plaguebearer of Nurgle
-R:268:0x80:0xFA
-
-# Guardian naga
-R:269:0x80:0xEE
-
-# Wererat
-R:270:0x80:0xF2
-
-# Light hound
-R:271:0x80:0xDA
-
-# Shadow hound
-R:272:0x80:0xDA
-
-# Flying skull
-R:273:0x80:0xF3
-
-# Mi-Go
-R:274:0x80:0xC9
-
-# Giant tarantula
-R:275:0x80:0xD3
-
-# Giant clear centipede
-R:276:0x80:0xE3
-
-# Mirkwood spider
-R:277:0x80:0xD3
-
-# Frost giant
-R:278:0x80:0xD0
-
-# Griffon
-R:279:0x80:0xC8
-
-# Homonculous
-R:280:0x80:0xF5
-
-# Gnome mage
-R:281:0x80:0xE8
-
-# Clear hound
-R:282:0x80:0xDA
-
-# Umber hulk
-R:283:0x80:0xD8
-
-# Rust monster
-R:284:0x80:0xF1
-
-# Orc captain
-R:285:0x80:0xEF
-
-# Gelatinous cube
-R:286:0x80:0xEA
-
-# Giant green dragon fly
-R:287:0x80:0xC6
-
-# Fire giant
-R:288:0x80:0xD0
-
-# Hummerhorn
-R:289:0x80:0xC9
-
-# Lizardman
-R:290:0x80:0xE8
-
-# Ulfast, Son of Ulfang
-R:291:0x80:0xF0
-
-# Hammerhead
-R:292:0x80:0xFE
-
-# Berserker
-R:293:0x80:0xF0
-
-# Quasit
-R:294:0x80:0xF5
-
-# Sphinx
-R:295:0x80:0xC8
-
-# Imp
-R:296:0x80:0xF5
-
-# Forest troll
-R:297:0x80:0xD4
-
-# Freezing sphere
-R:298:0x80:0xAA
-
-# Jumping fireball
-R:299:0x80:0xAA
-
-# Ball lightning
-R:300:0x80:0xAA
-
-# 2-headed hydra
-R:301:0x80:0xCD
-
-# Swamp thing
-R:302:0x80:0xC8
-
-# Water spirit
-R:303:0x80:0xC5
-
-# Giant red scorpion
-R:304:0x80:0xD3
-
-# Earth spirit
-R:305:0x80:0xC5
-
-# Fire spirit
-R:306:0x80:0xC5
-
-# Fire hound
-R:307:0x80:0xDA
-
-# Cold hound
-R:308:0x80:0xDA
-
-# Energy hound
-R:309:0x80:0xDA
-
-# Potion mimic
-R:310:0x80:0xA1
-
-# Door mimic
-R:311:0x80:0xAB
-
-# Blink dog
-R:312:0x80:0xC3
-
-# Uruk
-R:313:0x80:0xEF
-
-# Shagrat, the Orc Captain
-R:314:0x80:0xEF
-
-# Gorbag, the Orc Captain
-R:315:0x80:0xEF
-
-# Shambling mound
-R:316:0x80:0xAC
-
-# White shark
-R:317:0x80:0xFE
-
-# Chaos beastman
-R:318:0x80:0xC8
-
-# Daemonette of Slaanesh
-R:319:0x80:0xF5
-
-# Giant bronze dragon fly
-R:320:0x80:0xC6
-
-# Stone giant
-R:321:0x80:0xD0
-
-# Giant black dragon fly
-R:322:0x80:0xC6
-
-# Stone golem
-R:323:0x80:0xE7
-
-# Red mold
-R:324:0x80:0xED
-
-# Giant gold dragon fly
-R:325:0x80:0xC6
-
-# Stunwall
-R:326:0x80:0xA3
-
-# Ghast
-R:327:0x80:0xFA
-
-# Ixitxachitl priest
-R:328:0x80:0xFE
-
-# Huorn
-R:329:0x80:0xA3
-
-# Bolg, Son of Azog
-R:330:0x80:0xEF
-
-# Phase spider
-R:331:0x80:0xD3
-
-# Lizard king
-R:332:0x80:0xE8
-
-# Landmine
-R:333:0x80:0xAE
-
-# Wyvern
-R:334:0x80:0xE4
-
-# Great eagle
-R:335:0x80:0xC2
-
-# Livingstone
-R:336:0x80:0xA3
-
-# Earth hound
-R:337:0x80:0xDA
-
-# Air hound
-R:338:0x80:0xDA
-
-# Sabre-tooth tiger
-R:339:0x80:0xE6
-
-# Water hound
-R:340:0x80:0xDA
-
-# Chimera
-R:341:0x80:0xC8
-
-# Quylthulg
-R:342:0x80:0xD1
-
-# Sasquatch
-R:343:0x80:0xD9
-
-# Weir
-R:344:0x80:0xC3
-
-# Whale
-R:345:0x80:0xFE
-
-# Electric eel
-R:346:0x80:0xCA
-
-# Werewolf
-R:347:0x80:0xC3
-
-# Dark elven lord
-R:348:0x80:0xE8
-
-# Cloud giant
-R:349:0x80:0xD0
-
-# Ugluk, the Uruk
-R:350:0x80:0xEF
-
-# Blue dragon bat
-R:351:0x80:0xE2
-
-# Scroll mimic
-R:352:0x80:0xBF
-
-# Chest mimic
-R:353:0x80:0xFE
-
-# Fire vortex
-R:354:0x80:0xF6
-
-# Water vortex
-R:355:0x80:0xF6
-
-# Lugdush, the Uruk
-R:356:0x80:0xEF
-
-# Arch-vile
-R:357:0x80:0xF5
-
-# Cold vortex
-R:358:0x80:0xF6
-
-# Energy vortex
-R:359:0x80:0xF6
-
-# Globefish
-R:360:0x80:0xFE
-
-# Carrion
-R:361:0x80:0xC2
-
-# Mummified orc
-R:362:0x80:0xFA
-
-# Killer whale
-R:363:0x80:0xFE
-
-# Serpent man
-R:364:0x80:0xCA
-
-# Vampiric mist
-R:365:0x80:0xA3
-
-# Killer stag beetle
-R:366:0x80:0xCB
-
-# Iron golem
-R:367:0x80:0xE7
-
-# Auto-roller
-R:368:0x80:0xE7
-
-# Giant yellow scorpion
-R:369:0x80:0xD3
-
-# Jade monk
-R:370:0x80:0xF0
-
-# Black ooze
-R:371:0x80:0xEA
-
-# Hardened warrior
-R:372:0x80:0xF0
-
-# Azog, King of the Uruk-Hai
-R:373:0x80:0xEF
-
-# Fleshhound of Khorne
-R:374:0x80:0xC3
-
-# Dark elven warlock
-R:375:0x80:0xE8
-
-# Master rogue
-R:376:0x80:0xF0
-
-# Red dragon bat
-R:377:0x80:0xE2
-
-# Killer white beetle
-R:378:0x80:0xCB
-
-# Ice skeleton
-R:379:0x80:0xF3
-
-# Angamaite of Umbar
-R:380:0x80:0xF0
-
-# Forest wight
-R:381:0x80:0xD7
-
-# Mime, the Nibelung
-R:382:0x80:0xE8
-
-# Ibun, Son of Mim
-R:383:0x80:0xE8
-
-# Meneldor the Swift
-R:384:0x80:0xC2
-
-# Phantom beast
-R:385:0x80:0xC7
-
-# Great white shark
-R:386:0x80:0xFE
-
-# 4-headed hydra
-R:387:0x80:0xCD
-
-# Lesser hell-beast
-R:388:0x80:0xD5
-
-# Tyrannosaur
-R:389:0x80:0xD2
-
-# Mummified human
-R:390:0x80:0xFA
-
-# Vampire bat
-R:391:0x80:0xE2
-
-# Sangahyando of Umbar
-R:392:0x80:0xF0
-
-# It
-R:393:0x80:0xAE
-
-# Banshee
-R:394:0x80:0xC7
-
-# Carrion crawler
-R:395:0x80:0xE3
-
-# Xiclotlan
-R:396:0x80:0xA3
-
-# Silent watcher
-R:397:0x80:0xE7
-
-# Pukelman
-R:398:0x80:0xE7
-
-# Disenchanter beast
-R:399:0x80:0xF1
-
-# Dark elven druid
-R:400:0x80:0xE8
-
-# Stone troll
-R:401:0x80:0xD4
-
-# Black
-R:402:0x80:0xEA
-
-# Troll priest
-R:403:0x80:0xD4
-
-# Wereworm
-R:404:0x80:0xF7
-
-# Killer crimson beetle
-R:405:0x80:0xCB
-
-# Vampiric ixitxachitl
-R:406:0x80:0xFE
-
-# Gnoph-Keh
-R:407:0x80:0xF1
-
-# Giant grey ant
-R:408:0x80:0xE1
-
-# Khufu the Mummified King
-R:409:0x80:0xFA
-
-# Gwaihir the Windlord
-R:410:0x80:0xC2
-
-# Giant red tick
-R:411:0x80:0xD3
-
-# Displacer beast
-R:412:0x80:0xE6
-
-# Ulwarth, Son of Ulfang
-R:413:0x80:0xF0
-
-# Agent of Saruman
-R:414:0x80:0xF0
-
-# Cave ogre
-R:415:0x80:0xCF
-
-# White wraith
-R:416:0x80:0xD7
-
-# Monadic Deva
-R:417:0x80:0xC1
-
-# Ghoul
-R:418:0x80:0xFA
-
-# Mim, Betrayer of Turin
-R:419:0x80:0xE8
-
-# Hellblade
-R:420:0x80:0xFC
-
-# Killer red beetle
-R:421:0x80:0xCB
-
-# Beast of Nurgle
-R:422:0x80:0xF1
-
-# Creeping adamantite coins
-R:423:0x80:0xA4
-
-# Algroth
-R:424:0x80:0xD4
-
-# Flamer of Tzeentch
-R:425:0x80:0xAC
-
-# Roper
-R:426:0x80:0xA3
-
-# Headless
-R:427:0x80:0xC8
-
-# Vibration hound
-R:428:0x80:0xDA
-
-# Nexus hound
-R:429:0x80:0xDA
-
-# Ogre mage
-R:430:0x80:0xCF
-
-# Lokkak, the Ogre Chieftain
-R:431:0x80:0xCF
-
-# Vampire
-R:432:0x80:0xD6
-
-# Gorgimera
-R:433:0x80:0xC8
-
-# Shantak
-R:434:0x80:0xC2
-
-# Colbran
-R:435:0x80:0xE7
-
-# Spirit naga
-R:436:0x80:0xEE
-
-# Corpser
-R:437:0x80:0xAC
-
-# Fiend of Slaanesh
-R:438:0x80:0xD3
-
-# Stairway to hell
-R:439:0x80:0xBE
-
-# 5-headed hydra
-R:440:0x80:0xCD
-
-# Barney the Dinosaur
-R:441:0x80:0xD2
-
-# Black knight
-R:442:0x80:0xF0
-
-# Seahorse
-R:443:0x80:0xFE
-
-# Cyclops
-R:444:0x80:0xD0
-
-# Clairvoyant
-R:445:0x80:0xF0
-
-# Giant purple worm
-R:446:0x80:0xF7
-
-# Catoblepas
-R:447:0x80:0xF1
-
-# Lesser wall monster
-R:448:0x80:0xA3
-
-# Mage
-R:449:0x80:0xF0
-
-# Mind flayer
-R:450:0x80:0xE8
-
-# The Ultimate Dungeon Cleaner
-R:451:0x80:0xE7
-
-# Deep one
-R:452:0x80:0xF5
-
-# Basilisk
-R:453:0x80:0xD2
-
-# Ice troll
-R:454:0x80:0xD4
-
-# Dhole
-R:455:0x80:0xF7
-
-# Movanic Deva
-R:456:0x80:0xC1
-
-# Ring mimic
-R:457:0x80:0xBD
-
-# Chaos tile
-R:458:0x80:0xAE
-
-# Young blue dragon
-R:459:0x80:0xE4
-
-# Young white dragon
-R:460:0x80:0xE4
-
-# Young green dragon
-R:461:0x80:0xE4
-
-# Young bronze dragon
-R:462:0x80:0xE4
-
-# Aklash
-R:463:0x80:0xD4
-
-# Mithril golem
-R:464:0x80:0xE7
-
-# Skeleton troll
-R:465:0x80:0xF3
-
-# Skeletal tyrannosaur
-R:466:0x80:0xD2
-
-# Jaws
-R:467:0x80:0xFE
-
-# Thorondor
-R:468:0x80:0xC2
-
-# Giant blue ant
-R:469:0x80:0xE1
-
-# Grave wight
-R:470:0x80:0xD7
-
-# Shadow drake
-R:471:0x80:0xE4
-
-# Manticore
-R:472:0x80:0xC8
-
-# Giant army ant
-R:473:0x80:0xE1
-
-# Killer slicer beetle
-R:474:0x80:0xCB
-
-# Gorgon
-R:475:0x80:0xC8
-
-# Gug
-R:476:0x80:0xC7
-
-# Ghost
-R:477:0x80:0xC7
-
-# Death watch beetle
-R:478:0x80:0xCB
-
-# Ogre shaman
-R:479:0x80:0xCF
-
-# Nexus quylthulg
-R:480:0x80:0xD1
-
-# Shelob, Spider of Darkness
-R:481:0x80:0xD3
-
-# Giant squid
-R:482:0x80:0xFE
-
-# Ghoulking
-R:483:0x80:0xFA
-
-# Doombat
-R:484:0x80:0xE2
-
-# Ninja
-R:485:0x80:0xF0
-
-# Memory moss
-R:486:0x80:0xAC
-
-# Storm giant
-R:487:0x80:0xD0
-
-# Spectator
-R:488:0x80:0xE5
-
-# Bokrug
-R:489:0x80:0xD2
-
-# Biclops
-R:490:0x80:0xD0
-
-# Half-troll
-R:491:0x80:0xD4
-
-# Ivory monk
-R:492:0x80:0xF0
-
-# Bert the Stone Troll
-R:493:0x80:0xD4
-
-# Bill the Stone Troll
-R:494:0x80:0xD4
-
-# Tom the Stone Troll
-R:495:0x80:0xD4
-
-# Cave troll
-R:496:0x80:0xD4
-
-# Anti-paladin
-R:497:0x80:0xF0
-
-# Chaos master
-R:498:0x80:0xF0
-
-# Barrow wight
-R:499:0x80:0xD7
-
-# Giant skeleton troll
-R:500:0x80:0xF3
-
-# Chaos drake
-R:501:0x80:0xE4
-
-# Law drake
-R:502:0x80:0xE4
-
-# Balance drake
-R:503:0x80:0xE4
-
-# Ethereal drake
-R:504:0x80:0xE4
-
-# Groo the Wanderer
-R:505:0x80:0xD4
-
-# Fasolt the Giant
-R:506:0x80:0xD0
-
-# Shade
-R:507:0x80:0xC7
-
-# Spectre
-R:508:0x80:0xC7
-
-# Water troll
-R:509:0x80:0xD4
-
-# Fire elemental
-R:510:0x80:0xC5
-
-# Cherub
-R:511:0x80:0xC1
-
-# Water elemental
-R:512:0x80:0xC5
-
-# Multi-hued hound
-R:513:0x80:0xDA
-
-# Night stalker
-R:514:0x80:0xC5
-
-# Carrion crawler
-R:515:0x80:0xE3
-
-# Master thief
-R:516:0x80:0xF0
-
-# Waldern, King of Water
-R:517:0x80:0xC5
-
-# Lich
-R:518:0x80:0xCC
-
-# Gas spore
-R:519:0x80:0xE5
-
-# Master vampire
-R:520:0x80:0xD6
-
-# Oriental vampire
-R:521:0x80:0xD6
-
-# Greater mummy
-R:522:0x80:0xFA
-
-# Bloodletter of Khorne
-R:523:0x80:0xD5
-
-# Giant grey scorpion
-R:524:0x80:0xD3
-
-# Earth elemental
-R:525:0x80:0xC5
-
-# Air elemental
-R:526:0x80:0xC5
-
-# Doom drake
-R:527:0x80:0xE4
-
-# Gargoyle
-R:528:0x80:0xF5
-
-# Malicious leprechaun
-R:529:0x80:0xE8
-
-# Eog golem
-R:530:0x80:0xE7
-
-# Little Boy
-R:531:0x80:0xFB
-
-# Dagashi
-R:532:0x80:0xF0
-
-# Headless ghost
-R:533:0x80:0xC7
-
-# Dread
-R:534:0x80:0xC7
-
-# Leng spider
-R:535:0x80:0xD3
-
-# Star vampire
-R:536:0x80:0xD6
-
-# Smoke elemental
-R:537:0x80:0xC5
-
-# Olog
-R:538:0x80:0xD4
-
-# Halfling slinger
-R:539:0x80:0xE8
-
-# Gravity hound
-R:540:0x80:0xDA
-
-# Acidic cytoplasm
-R:541:0x80:0xEA
-
-# Inertia hound
-R:542:0x80:0xDA
-
-# Impact hound
-R:543:0x80:0xDA
-
-# Sea troll
-R:544:0x80:0xD4
-
-# Ooze elemental
-R:545:0x80:0xC5
-
-# Young black dragon
-R:546:0x80:0xE4
-
-# Mumak
-R:547:0x80:0xF1
-
-# Giant red ant
-R:548:0x80:0xE1
-
-# Mature white dragon
-R:549:0x80:0xE4
-
-# Xorn
-R:550:0x80:0xD8
-
-# Rogrog the Black Troll
-R:551:0x80:0xD4
-
-# Mist giant
-R:552:0x80:0xA3
-
-# Phantom
-R:553:0x80:0xC7
-
-# Grey wraith
-R:554:0x80:0xD7
-
-# Revenant
-R:555:0x80:0xD7
-
-# Young multi-hued dragon
-R:556:0x80:0xE4
-
-# Raal's Tome of Destruction
-R:557:0x80:0xBF
-
-# Colossus
-R:558:0x80:0xE7
-
-# Young gold dragon
-R:559:0x80:0xE4
-
-# Mature blue dragon
-R:560:0x80:0xE4
-
-# Mature green dragon
-R:561:0x80:0xE4
-
-# Mature bronze dragon
-R:562:0x80:0xE4
-
-# Young red dragon
-R:563:0x80:0xE4
-
-# Nightblade
-R:564:0x80:0xE8
-
-# Trapper
-R:565:0x80:0xAE
-
-# Bodak
-R:566:0x80:0xF5
-
-# Time bomb
-R:567:0x80:0xAE
-
-# Mezzodaemon
-R:568:0x80:0xF5
-
-# Elder thing
-R:569:0x80:0xF5
-
-# Ice elemental
-R:570:0x80:0xC5
-
-# Necromancer
-R:571:0x81:0xBE
-
-# The Greater hell magic mushroom were-quylthulg
-R:572:0x80:0xD1
-
-# Lorgan, Chief of the Easterlings
-R:573:0x80:0xF0
-
-# Chaos spawn
-R:574:0x80:0xE5
-
-# Mummified troll
-R:575:0x80:0xFA
-
-# Fire angel
-R:576:0x80:0xE4
-
-# Crypt thing
-R:577:0x80:0xCC
-
-# Chaos butterfly
-R:578:0x80:0xC9
-
-# Time elemental
-R:579:0x80:0xC5
-
-# Flying polyp
-R:580:0x80:0xFE
-
-# The Queen Ant
-R:581:0x80:0xE1
-
-# Will o' the wisp
-R:582:0x80:0xC5
-
-# Shan
-R:583:0x80:0xC9
-
-# Magma elemental
-R:584:0x80:0xC5
-
-# Black pudding
-R:585:0x80:0xEA
-
-# Killer iridescent beetle
-R:586:0x80:0xCB
-
-# Nexus vortex
-R:587:0x80:0xF6
-
-# Plasma vortex
-R:588:0x80:0xF6
-
-# Mature red dragon
-R:589:0x80:0xE4
-
-# Mature gold dragon
-R:590:0x80:0xE4
-
-# Crystal drake
-R:591:0x80:0xE4
-
-# Mature black dragon
-R:592:0x80:0xE4
-
-# Mature multi-hued dragon
-R:593:0x80:0xE4
-
-# Sky whale
-R:594:0x80:0xFE
-
-# Draebor, the Imp
-R:595:0x80:0xF5
-
-# Mother Hydra
-R:596:0x80:0xF5
-
-# Death knight
-R:597:0x80:0xF0
-
-# Castamir the Usurper
-R:598:0x80:0xF0
-
-# Time vortex
-R:599:0x80:0xF6
-
-# Shimmering vortex
-R:600:0x80:0xF6
-
-# Ancient blue dragon
-R:601:0x80:0xC4
-
-# Ancient bronze dragon
-R:602:0x80:0xC4
-
-# Beholder
-R:603:0x80:0xE5
-
-# Emperor wight
-R:604:0x80:0xD7
-
-# Planetar
-R:605:0x80:0xC1
-
-# Vargo, Tyrant of Fire
-R:606:0x80:0xC5
-
-# Black wraith
-R:607:0x80:0xD7
-
-# Nightgaunt
-R:608:0x80:0xD5
-
-# Baron of hell
-R:609:0x80:0xD5
-
-# Medusa
-R:610:0x80:0xCD
-
-# Monastic lich
-R:611:0x80:0xCC
-
-# Nether wraith
-R:612:0x80:0xD7
-
-# Fire vampire
-R:613:0x80:0xD6
-
-# 7-headed hydra
-R:614:0x80:0xCD
-
-# Moire, Queen of Rebma
-R:615:0x80:0xC5
-
-# Kavlax the Many-Headed
-R:616:0x80:0xE4
-
-# Ancient white dragon
-R:617:0x80:0xC4
-
-# Ancient green dragon
-R:618:0x80:0xC4
-
-# Chthonian
-R:619:0x80:0xF7
-
-# Eldrak
-R:620:0x80:0xD4
-
-# Ettin
-R:621:0x80:0xD4
-
-# Night mare
-R:622:0x80:0xF1
-
-# Vampire lord
-R:623:0x80:0xD6
-
-# Ancient black dragon
-R:624:0x80:0xC4
-
-# Weird fume
-R:625:0x80:0xA3
-
-# Spawn of Ubbo-Sathla
-R:626:0x80:0xEA
-
-# Fat Man
-R:627:0x80:0xFB
-
-# Malekith the Accursed
-R:628:0x80:0xE8
-
-# Shadowfax, steed of Gandalf
-R:629:0x80:0xF1
-
-# Spirit troll
-R:630:0x80:0xD4
-
-# War troll
-R:631:0x80:0xD4
-
-# Disenchanter worm mass
-R:632:0x80:0xF7
-
-# Rotting quylthulg
-R:633:0x80:0xD1
-
-# Lesser titan
-R:634:0x80:0xD0
-
-# 9-headed hydra
-R:635:0x80:0xCD
-
-# Enchantress
-R:636:0x80:0xF0
-
-# Archpriest
-R:637:0x80:0xF0
-
-# Sorcerer
-R:638:0x80:0xF0
-
-# Xaren
-R:639:0x80:0xD8
-
-# Giant roc
-R:640:0x80:0xC2
-
-# Minotaur
-R:641:0x80:0xC8
-
-# Jasra, Brand's Mistress
-R:642:0x80:0xEE
-
-# Death drake
-R:643:0x80:0xC4
-
-# Ancient red dragon
-R:644:0x80:0xC4
-
-# Ancient gold dragon
-R:645:0x80:0xC4
-
-# Great crystal drake
-R:646:0x80:0xC4
-
-# Wyrd sister
-R:647:0x80:0xF0
-
-# Clubber demon
-R:648:0x80:0xD5
-
-# Death quasit
-R:649:0x80:0xF5
-
-# Giganto the Gargantuan
-R:650:0x80:0xFE
-
-# Strygalldwir
-R:651:0x80:0xD5
-
-# Fallen angel
-R:652:0x80:0xC1
-
-# Giant headless
-R:653:0x80:0xC8
-
-# Judge Fire
-R:654:0x80:0xF3
-
-# Ubbo-Sathla, the Unbegotten Source
-R:655:0x80:0xEA
-
-# Judge Mortis
-R:656:0x80:0xFA
-
-# Dark elven sorceror
-R:657:0x80:0xE8
-
-# Master lich
-R:658:0x80:0xCC
-
-# Byakhee
-R:659:0x80:0xD5
-
-# Eol the Dark Elf
-R:660:0x80:0xE8
-
-# Archon
-R:661:0x80:0xC1
-
-# Formless spawn of Tsathoggua
-R:662:0x80:0xD5
-
-# Hunting horror
-R:663:0x80:0xD5
-
-# Undead beholder
-R:664:0x80:0xE5
-
-# Shadow demon
-R:665:0x80:0xC7
-
-# Iron lich
-R:666:0x80:0xCC
-
-# Dread
-R:667:0x80:0xC7
-
-# Greater basilisk
-R:668:0x80:0xD2
-
-# Charybdis
-R:669:0x80:0xFE
-
-# Jack of Shadows
-R:670:0x80:0xF0
-
-# Zephyr Lord
-R:671:0x80:0xD7
-
-# Juggernaut of Khorne
-R:672:0x80:0xE7
-
-# Great Mumak
-R:673:0x80:0xF1
-
-# Judge Fear
-R:674:0x80:0xD7
-
-# Ancient multi-hued dragon
-R:675:0x80:0xC4
-
-# Ethereal dragon
-R:676:0x80:0xC4
-
-# Dark young of Shub-Niggurath
-R:677:0x80:0xA3
-
-# Colour out of space
-R:678:0x80:0xAE
-
-# Quaker, Master of Earth
-R:679:0x80:0xC5
-
-# Death leprechaun
-R:680:0x80:0xE8
-
-# Chaugnar Faugn, Horror from the Hills
-R:681:0x80:0xF1
-
-# Lloigor
-R:682:0x80:0xF6
-
-# Utgard-Loke
-R:683:0x80:0xD0
-
-# Quachil Uttaus, Treader of the Dust
-R:684:0x80:0xFA
-
-# Shoggoth
-R:685:0x80:0xEA
-
-# Judge Death
-R:686:0x80:0xD7
-
-# Ariel, Queen of Air
-R:687:0x80:0xC5
-
-# 11-headed hydra
-R:688:0x80:0xCD
-
-# High priest
-R:689:0x80:0xF0
-
-# Dreadmaster
-R:690:0x80:0xC7
-
-# Drolem
-R:691:0x80:0xE7
-
-# Scatha the Worm
-R:692:0x80:0xC4
-
-# Warrior of the Dawn
-R:693:0x80:0xF0
-
-# Lesser black reaver
-R:694:0x80:0xCC
-
-# Zoth-Ommog
-R:695:0x80:0xD2
-
-# Grand master thief
-R:696:0x80:0xF0
-
-# Smaug the Golden
-R:697:0x80:0xC4
-
-# The Stormbringer
-R:698:0x80:0xFC
-
-# Ultra-elite paladin
-R:699:0x80:0xF0
-
-# Leprechaun fanatic
-R:700:0x80:0xE8
-
-# Dracolich
-R:701:0x80:0xC4
-
-# Greater titan
-R:702:0x80:0xD0
-
-# Dracolisk
-R:703:0x80:0xC4
-
-# Fastitocalon
-R:704:0x80:0xC4
-
-# Spectral tyrannosaur
-R:705:0x80:0xD2
-
-# Yibb-Tstll the Patient One
-R:706:0x80:0xD0
-
-# Ghatanothoa
-R:707:0x80:0xC8
-
-# Ent
-R:708:0x80:0xA3
-
-# Hru
-R:709:0x80:0xD0
-
-# Itangast the Fire Drake
-R:710:0x80:0xC4
-
-# Death mold
-R:711:0x80:0xED
-
-# Fafner the Dragon
-R:712:0x80:0xC4
-
-# Charon the Boatsman
-R:713:0x80:0xD7
-
-# Quickbeam
-R:714:0x80:0xA3
-
-# Glaurung, Father of the Dragons
-R:715:0x80:0xC4
-
-# Behemoth
-R:716:0x80:0xC8
-
-# Garm, Guardian of Hel
-R:717:0x80:0xC3
-
-# Greater wall monster
-R:718:0x80:0xA3
-
-# Nycadaemon
-R:719:0x80:0xD5
-
-# Balrog
-R:720:0x80:0xD5
-
-# Goat of Mendes
-R:721:0x80:0xF1
-
-# Nightwing
-R:722:0x80:0xD7
-
-# Maulotaur
-R:723:0x80:0xC8
-
-# Nether hound
-R:724:0x80:0xDA
-
-# Time hound
-R:725:0x80:0xDA
-
-# Plasma hound
-R:726:0x80:0xDA
-
-# Demonic quylthulg
-R:727:0x80:0xD1
-
-# Great storm wyrm
-R:728:0x80:0xC4
-
-# Ulik the Troll
-R:729:0x80:0xD4
-
-# Baphomet the Minotaur Lord
-R:730:0x80:0xC8
-
-# Hell knight
-R:731:0x80:0xF0
-
-# Bull Gates
-R:732:0x80:0xF0
-
-# Santa Claus
-R:733:0x80:0xE8
-
-# Eihort, the Thing in the Labyrinth
-R:734:0x80:0xEA
-
-# The King in Yellow
-R:735:0x80:0xCC
-
-# Great unclean one
-R:736:0x80:0xD5
-
-# Lord of Chaos
-R:737:0x80:0xF0
-
-# Old Sorcerer
-R:738:0x80:0xF0
-
-# Hound of Tindalos
-R:739:0x80:0xDA
-
-# Lesser kraken
-R:740:0x80:0xFE
-
-# Great ice wyrm
-R:741:0x80:0xC4
-
-# Demilich
-R:742:0x80:0xCC
-
-# The Phoenix
-R:743:0x80:0xC2
-
-# Nightcrawler
-R:744:0x80:0xD7
-
-# Lord of Change
-R:745:0x80:0xC2
-
-# Keeper of Secrets
-R:746:0x80:0xC8
-
-# Shudde M'ell
-R:747:0x80:0xF7
-
-# Hand druj
-R:748:0x80:0xF3
-
-# Eye druj
-R:749:0x80:0xF3
-
-# Skull druj
-R:750:0x80:0xF3
-
-# Chaos vortex
-R:751:0x80:0xF6
-
-# Aether vortex
-R:752:0x80:0xF6
-
-# Nidhogg the Hel-Drake
-R:753:0x80:0xC4
-
-# The Lernean Hydra
-R:754:0x80:0xCD
-
-# Thuringwethil
-R:755:0x80:0xD6
-
-# Great hell wyrm
-R:756:0x80:0xC4
-
-# Hastur the Unspeakable
-R:757:0x80:0xC8
-
-# Bloodthirster
-R:758:0x80:0xD5
-
-# Draconic quylthulg
-R:759:0x80:0xD1
-
-# Nyogtha, the Thing that Should not Be
-R:760:0x80:0xEA
-
-# Ahtu, Avatar of Nyarlathotep
-R:761:0x80:0xA3
-
-# Fundin Bluecloak
-R:762:0x80:0xE8
-
-# The Philosophy Teacher
-R:763:0x80:0xF0
-
-# Uriel, Angel of Fire
-R:764:0x80:0xC1
-
-# Azriel, Angel of Death
-R:765:0x80:0xC1
-
-# Ancalagon the Black
-R:766:0x80:0xC4
-
-# Daoloth, the Render of the Veils
-R:767:0x80:0xD5
-
-# Nightwalker
-R:768:0x80:0xD7
-
-# Gabriel, the Messenger
-R:769:0x80:0xC1
-
-# Artsi the Champion of Chaos
-R:770:0x80:0xE8
-
-# Saruman of Many Colours
-R:771:0x80:0xF0
-
-# Harowen the Black Hand
-R:772:0x80:0xF0
-
-# The Physics Teacher
-R:773:0x80:0xF0
-
-# Shadowlord
-R:774:0x80:0xC7
-
-# Greater kraken
-R:775:0x80:0xFE
-
-# Archlich
-R:776:0x80:0xCC
-
-# The Cat Lord
-R:777:0x80:0xE6
-
-# Chaos beetle
-R:778:0x80:0xCB
-
-# Chaos hound
-R:779:0x80:0xDA
-
-# Vlad Dracula, Prince of Darkness
-R:780:0x80:0xD6
-
-# Ultimate beholder
-R:781:0x80:0xE5
-
-# Leviathan
-R:782:0x80:0xC4
-
-# Great Wyrm of Chaos
-R:783:0x80:0xC4
-
-# Great Wyrm of Law
-R:784:0x80:0xC4
-
-# Great Wyrm of Balance
-R:785:0x80:0xC4
-
-# Shambler
-R:786:0x80:0xC5
-
-# Hypnos, Lord of Sleep
-R:787:0x80:0xD0
-
-# Glaaki
-R:788:0x80:0xFE
-
-# T'ron, the rebel DragonRider
-R:789:0x80:0xC4
-
-# Great Wyrm of Many Colours
-R:790:0x80:0xC4
-
-# Mardra, rider of the Gold Loranth
-R:791:0x80:0xC4
-
-# Tselakus, the Dreadlord
-R:792:0x80:0xC7
-
-# Sky Drake
-R:793:0x80:0xC4
-
-# Eilinel the Entrapped
-R:794:0x80:0xF0
-
-# Tiamat, Celestial Dragon of Evil
-R:795:0x80:0xC4
-
-# The Norsa
-R:796:0x80:0xC8
-
-# Rhan-Tegoth
-R:797:0x80:0xD3
-
-# Black reaver
-R:798:0x80:0xCC
-
-# Troll High Priest
-R:799:0x80:0xD4
-
-# Master quylthulg
-R:800:0x80:0xD1
-
-# Greater draconic quylthulg
-R:801:0x80:0xD1
-
-# Greater rotting quylthulg
-R:802:0x80:0xD1
-
-# Null the Living Void
-R:803:0x80:0xAE
-
-# Vecna, the Emperor Lich
-R:804:0x80:0xCC
-
-# Omarax the Eye Tyrant
-R:805:0x80:0xE5
-
-# Tsathoggua, the Sleeper of N'kai
-R:806:0x80:0xF2
-
-# Greater Balrog
-R:807:0x80:0xD5
-
-# Ungoliant, the Unlight
-R:808:0x80:0xD3
-
-# Atlach-Nacha, the Spider God
-R:809:0x80:0xD3
-
-# Y'golonac
-R:810:0x80:0xC8
-
-# Aether hound
-R:811:0x80:0xDA
-
-# Warp demon
-R:812:0x80:0xD5
-
-# Serpent of Chaos
-R:813:0x80:0xCA
-
-# Yig, Father of Serpents
-R:814:0x80:0xD2
-
-# Unmaker
-R:815:0x80:0xC5
-
-# Cyberdemon
-R:816:0x80:0xD5
-
-# Hela, Queen of the Dead
-R:817:0x80:0xF0
-
-# The Mouth of Sauron
-R:818:0x80:0xF0
-
-# Klingsor, Evil Master of Magic
-R:819:0x80:0xF0
-
-# Lessa, rider of the Gold Ramoth
-R:820:0x80:0xC4
-
-# The Emperor Quylthulg
-R:821:0x80:0xD1
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0x80:0xD1
-
-# Cthugha, the Living Flame
-R:823:0x80:0xC5
-
-# F'lar, rider of the Bronze Mnementh
-R:824:0x80:0xC4
-
-# Maeglin, Betrayer of Gondolin
-R:825:0x80:0xE8
-
-# Cyaegha
-R:826:0x80:0xE5
-
-# Pazuzu, Lord of Air
-R:827:0x80:0xC2
-
-# Ithaqua the Windwalker
-R:828:0x80:0xD9
-
-# Hell hound
-R:829:0x80:0xC3
-
-# Cantoras, the Skeletal Lord
-R:830:0x80:0xF3
-
-# Mephistopheles, Lord of Hell
-R:831:0x80:0xD5
-
-# Godzilla
-R:832:0x80:0xD2
-
-# Abhoth, Source of Uncleanness
-R:833:0x80:0xCA
-
-# Ymir the Ice Giant
-R:834:0x80:0xD0
-
-# Loki the Trickster
-R:835:0x80:0xD0
-
-# Star-spawn of Cthulhu
-R:836:0x80:0xD5
-
-# Surtur the Giant Fire Demon
-R:837:0x80:0xD0
-
-# The Tarrasque
-R:838:0x80:0xD2
-
-# Lungorthin, the Balrog of White Fire
-R:839:0x80:0xD5
-
-# Draugluin, Sire of All Werewolves
-R:840:0x80:0xC3
-
-# Shuma-Gorath
-R:841:0x80:0xE5
-
-# Tulzscha, the Green Flame
-R:842:0x80:0xC5
-
-# Oremorj the Cyberdemon Lord
-R:843:0x80:0xD5
-
-# Feagwath the Undead Sorceror
-R:844:0x80:0xCC
-
-# Yog-Sothoth, the All-in-One
-R:845:0x80:0xEA
-
-# Fenris Wolf
-R:846:0x80:0xC3
-
-# Great Wyrm of Power
-R:847:0x80:0xC4
-
-# Shub-Niggurath, Black Goat of the Woods
-R:848:0x80:0xD5
-
-# Nodens, Lord of the Great Abyss
-R:849:0x80:0xD0
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x80:0xC3
-
-# Nyarlathotep, the Crawling Chaos
-R:851:0x80:0xD5
-
-# Azathoth, the Daemon Sultan
-R:852:0x80:0xC5
-
-# Cerberus, Guardian of Hades
-R:853:0x80:0xC3
-
-# Jormungand the Midgard Serpent
-R:854:0x80:0xCA
-
-# The Destroyer
-R:855:0x80:0xE7
-
-# Gothmog, the High Captain of Balrogs
-R:856:0x80:0xD5
-
-# Great Cthulhu
-R:857:0x80:0xD5
-
-# Sorka, rider of the Gold Faranth
-R:858:0x80:0xC4
-
-# The Unicorn of Order
-R:859:0x80:0xF1
-
-# Sauron, the Sorcerer
-R:860:0x80:0xF0
-
-# Dark God, the Mighty Coder of Hell
-R:861:0x80:0xD0
-
-# Morgoth, Lord of Darkness
-R:862:0x80:0xD0
-
-# Human Warrior
-R:863:0x81:0xB7
-
-# Elven Archer
-R:864:0x81:0xC0
-
-# Dwarven Warrior
-R:865:0x80:0xE8
-
-# Mountain Orc
-R:866:0x80:0xEF
-
-# The Philosophy Teacher
-R:867:0x80:0xD0
-
-# The Variant Maintainer
-R:868:0x80:0xF0
-
-# Random Number Generator
-R:869:0x80:0xC9
-
-# Rocket mine
-R:870:0x80:0xAE
-
-# Bouncing mine
-R:871:0x80:0xAE
-
-# Muar, the Balrog
-R:872:0x80:0xD5
-
-# The Icky Queen
-R:873:0x80:0xE9
-
-# Ratmold
-R:874:0x80:0xED
-
-# Death
-R:875:0x80:0xC7
-
-# Famine
-R:876:0x80:0xC7
-
-# Pestilence
-R:877:0x80:0xC7
-
-# War
-R:878:0x80:0xC7
-
-# Pike
-R:879:0x80:0xFE
-
-# Electric eel
-R:880:0x80:0xFE
-
-# Giant crayfish
-R:881:0x80:0xFE
-
-# Mermaid
-R:882:0x80:0xE8
-
-# Merman
-R:883:0x80:0xE8
-
-# Big Pirahna
-R:884:0x80:0xFE
-
-# Lizard man
-R:885:0x80:0xE8
-
-# Frogman
-R:886:0x80:0xE8
-
-# Frogman warrior
-R:887:0x80:0xE8
-
-# Frogman shaman
-R:888:0x80:0xE8
-
-# Small medusa
-R:889:0x80:0xD1
-
-# Sand mite
-R:890:0x80:0xFE
-
-# Octopus
-R:891:0x80:0xD1
-
-# Kraken
-R:892:0x80:0xD1
-
-# Aquatic beholder
-R:893:0x80:0xE5
-
-# Murk dweller
-R:894:0x80:0xD3
-
-# Drowned soul
-R:895:0x80:0xC7
-
-# Tiger shark
-R:896:0x80:0xFE
-
-# Hammerhead shark
-R:897:0x80:0xFE
-
-# Great white shark
-R:898:0x80:0xFE
-
-# Aquatic golem
-R:899:0x80:0xE7
-
-# Aquatic kobold
-R:900:0x80:0xEB
-
-# Elder kraken
-R:901:0x80:0xD1
-
-# Aquatic troll
-R:902:0x80:0xD4
-
-# Elder aquatic beholder
-R:903:0x80:0xE5
-
-# Abysmal elf
-R:904:0x80:0xE8
-
-# Abysmal elven warrior
-R:905:0x80:0xE8
-
-# Abysmal elven shaman
-R:906:0x80:0xE8
-
-# Stargazer
-R:907:0x80:0xFE
-
-# Elder stargazer
-R:908:0x80:0xFE
-
-# Flounder
-R:909:0x80:0xFE
-
-# Giant turtle
-R:910:0x80:0xD2
-
-# Baby abysmal dragon
-R:911:0x80:0xE4
-
-# Young abysmal dragon
-R:912:0x80:0xE4
-
-# Mature abysmal dragon
-R:913:0x80:0xE4
-
-# Ancient abysmal dragon
-R:914:0x80:0xC4
-
-# Dragon turtle
-R:915:0x80:0xD2
-
-# Undead stargazer
-R:916:0x80:0xFE
-
-# Killer whale
-R:917:0x80:0xFE
-
-# Undead killer whale
-R:918:0x80:0xC7
-
-# Aquatic naga
-R:919:0x80:0xEE
-
-# Devilfish
-R:920:0x80:0xFE
-
-# Undead devilfish
-R:921:0x80:0xFE
-
-# Devilfish beholder
-R:922:0x80:0xE5
-
-# Aquatic hound
-R:923:0x80:0xDA
-
-# Aquatic demon
-R:924:0x80:0xD5
-
-# Aquatic demonlord
-R:925:0x80:0xD5
-
-# Manta ray
-R:926:0x80:0xFE
-
-# Undead manta ray
-R:927:0x80:0xFE
-
-# Mathilde, the Science Student
-R:928:0x80:0xE8
-
-# Child spirit
-R:929:0x80:0xC7
-
-# Young spirit
-R:930:0x80:0xC7
-
-# Mature spirit
-R:931:0x80:0xC7
-
-# Experienced spirit
-R:932:0x80:0xC7
-
-# Wise spirit
-R:933:0x80:0xC7
-
-# Fangorn the Treebeard
-R:934:0x80:0xA3
-
-# Gandalf the Grey
-R:935:0x80:0xF0
-
-# Nar, the Dwarf
-R:936:0x80:0xE8
-
-# Black troll
-R:937:0x80:0xD4
-
-# Troll Clan Chief
-R:938:0x80:0xD4
-
-# Troll King
-R:939:0x80:0xD4
-
-# Blue Firelizard
-R:940:0x80:0xE4
-
-# Green Firelizard
-R:941:0x80:0xE4
-
-# Brown Firelizard
-R:942:0x80:0xE4
-
-# Bronze Firelizard
-R:943:0x80:0xE4
-
-# Gold Firelizard
-R:944:0x80:0xE4
-
-# High-elven ranger
-R:945:0x80:0xE8
-
-# Uvatha the Horseman
-R:946:0x80:0xD7
-
-# Adunaphel the Quiet
-R:947:0x80:0xD7
-
-# Akhorahil the Blind
-R:948:0x80:0xD7
-
-# Ren the Unclean
-R:949:0x80:0xD7
-
-# Ji Indur Dawndeath
-R:950:0x80:0xD7
-
-# Dwar, Dog Lord of Waw
-R:951:0x80:0xD7
-
-# Hoarmurath of Dir
-R:952:0x80:0xD7
-
-# Khamul the Easterling
-R:953:0x80:0xD7
-
-# Murazor, the Witch-King of Angmar
-R:954:0x80:0xD7
-
-# Green DragonRider
-R:955:0x80:0xC4
-
-# Blue DragonRider
-R:956:0x80:0xC4
-
-# Brown DragonRider
-R:957:0x80:0xC4
-
-# Bronze DragonRider
-R:958:0x80:0xC4
-
-# Gold DragonRider
-R:959:0x80:0xC4
-
-# Thread
-R:960:0x80:0xED
-
-# Gorlim, Betrayer of Barahir
-R:961:0x80:0xF0
-
-# The Blubbering idiot, agent of black market, Simon the weak
-R:962:0x80:0xF4
-
-# Aranea
-R:963:0x80:0xD3
-
-# Elder aranea
-R:964:0x80:0xD3
-
-# Greater Aranea
-R:965:0x80:0xD3
-
-# Dolphiner
-R:966:0x80:0xF0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:967:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:968:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:969:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:970:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:971:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:972:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:973:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:974:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:975:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:976:0x80:0xC0
-
-# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-R:977:0x80:0xC0
-
-# Moldoux, the Defenceless Mold
-R:978:0x80:0xED
-
-# Ben Harrison
-R:979:0x80:0xF0
-
-# Ar-Pharazon the Golden
-R:980:0x80:0xF0
-
-# Doppleganger
-R:981:0x80:0xC0
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0x80:0xD0
-
-# The Greater Lag Monster
-R:983:0x80:0xD5
-
-# Khim, Son of Mim
-R:984:0x80:0xE8
-
-# Bullroarer the Hobbit
-R:985:0x80:0xE8
-
-# 3-headed hydra
-R:986:0x80:0xCD
-
-# Uldor the Accursed
-R:987:0x80:0xF0
-
-# Mystic
-R:988:0x80:0xF0
-
-# Invisible stalker
-R:989:0x80:0xC5
-
-# Ulfang the Black
-R:990:0x80:0xF0
-
-# Demonologist
-R:991:0x80:0xF0
-
-# Hezrou
-R:992:0x80:0xD5
-
-# Glabrezu
-R:993:0x80:0xD5
-
-# Nalfeshnee
-R:994:0x80:0xD5
-
-# Marilith
-R:995:0x80:0xD5
-
-# Lesser Balrog
-R:996:0x80:0xD5
-
-# Master mystic
-R:997:0x80:0xF0
-
-# Grand master mystic
-R:998:0x80:0xF0
-
-# Erinyes
-R:999:0x80:0xD5
-
-# Medusa, the Gorgon
-R:1000:0x80:0xEE
-
-# Vrock
-R:1001:0x80:0xD5
-
-# Solar
-R:1002:0x80:0xC1
-
-# Ethereal hound
-R:1003:0x80:0xDA
-
-# Dreadlord
-R:1004:0x80:0xC7
-
-# Redweed
-R:1005:0x81:0xB0
-
-# The Rat King
-R:1006:0x80:0xF2
-
-# Vort the Kobold Queen
-R:1007:0x80:0xEB
-
-# Giant cockroach
-R:1008:0x80:0xC9
-
-# Fire Phantom
-R:1009:0x80:0xC7
-
-# The Insane Player
-R:1010:0x80:0xF0
-
-# Glaryssa, Succubus Queen
-R:1011:0x80:0xD5
-
-# Vermicious Knid
-R:1012:0x80:0xCF
-
-# Bone golem
-R:1013:0x80:0xE7
-
-# Snake of Yig
-R:1014:0x80:0xCA
-
-# Wild Man
-R:1015:0x80:0xE8
-
-# Dimensional shambler
-R:1016:0x80:0xE8
-
-# Cultist
-R:1017:0x80:0xF0
-
-# Cult leader
-R:1018:0x80:0xF0
-
-# Servitor of the outer gods
-R:1019:0x80:0xD5
-
-# Avatar of Nyarlathotep
-R:1020:0x80:0xF0
-
-# Fthagghua, Lord of the fire vampires
-R:1021:0x80:0xD5
-
-# Hypnos
-R:1022:0x80:0xF0
-
-# Blue Dragon Worm
-R:1023:0x80:0xF7
-
-# White Dragon Worm
-R:1024:0x80:0xF7
-
-# Red Dragon Worm
-R:1025:0x80:0xF7
-
-# Black Dragon Worm
-R:1026:0x80:0xF7
-
-# Green Dragon Worm
-R:1027:0x80:0xF7
-
-# Multi-hued Dragon Worm
-R:1028:0x80:0xF7
-
-# The Baby Minotaur
-R:1029:0x80:0xC8
-
-# The Sandworm Queen
-R:1030:0x80:0xF7
-
-# Sandworm
-R:1031:0x80:0xF7
-
-# Nobody, the Undefined Ghost
-R:1032:0x80:0xC7
-
-
-
-
-
diff --git a/lib/mods/theme/pref/graf-mac.prf b/lib/mods/theme/pref/graf-mac.prf
deleted file mode 100644
index 7bb84141..00000000
--- a/lib/mods/theme/pref/graf-mac.prf
+++ /dev/null
@@ -1,15 +0,0 @@
-# File: graf-mac.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/mods/theme/pref/graf-new.prf b/lib/mods/theme/pref/graf-new.prf
deleted file mode 100644
index 2fb1b215..00000000
--- a/lib/mods/theme/pref/graf-new.prf
+++ /dev/null
@@ -1,6934 +0,0 @@
-# PRF file generated by Andreas Koch`s Tile Assigner
-# at 03.12.02 , 17:18:08 by Ja with version 1.7c
-
-# 2460 items
-# 2312 probably mapped correctly
-# 147 imported but not yet defined
-# 1 defined to value(s) lower than 0x80
-# Old header :
-# File: graf-new.prf
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-# with Adam Bolt's 16x16 tiles.
-#
-# By Robert Ruehlmann < rr9@angband.org >
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# General Store
-B:0:0x82/0x87
-
-# Armoury
-B:1:0x82/0x88
-
-# Weaponsmith
-B:2:0x82/0x89
-
-# Temple
-B:3:0x82/0x8A
-
-# Alchemy shop
-B:4:0x82/0x8B
-
-# Magic shop
-B:5:0x82/0x8C
-
-# Black Market
-B:6:0x82/0x8D
-
-# Home
-B:7:0x82/0x8E
-
-# Book Store
-B:8:0x82/0x8F
-
-# Pet Shop
-B:9:0x82/0x90
-
-# Mayor's Office
-B:10:0x86/0xA0
-
-# Inn
-B:11:0x86/0xA1
-
-# The Soothsayer
-B:12:0x86/0xA2
-
-# Library
-B:13:0x86/0xA3
-
-# Castle
-B:14:0x86/0xA4
-
-# Casino
-B:15:0x86/0xA5
-
-# Beastmaster Shanty
-B:16:0x86/0xA6
-
-# Fighters Hall
-B:17:0x86/0xA7
-
-# Tower of Magery
-B:18:0x86/0xA8
-
-# Inner Temple
-B:19:0x86/0xA9
-
-# Paladins Guild
-B:20:0x86/0xAA
-
-# Rangers Guild
-B:21:0x86/0xAB
-
-# Thunderlords' Hide
-B:22:0x86/0xAC
-
-# The Mirror
-B:23:0x86/0xAD
-
-# Seat of Ruling
-B:24:0x86/0xAE
-
-# Wizards Spire
-B:25:0x86/0xAF
-
-# Priests Circle
-B:26:0x86/0xB0
-
-# Tower of the King
-B:27:0x86/0xB1
-
-# Library
-B:28:0x86/0xA3
-
-# The White Tree
-B:29:0x86/0xB2
-
-# Craftsmaster
-B:30:0x86/0xB3
-
-# Earth-Dome (Nature)
-B:31:0x86/0xB4
-
-# Minstrels Haven
-B:32:0x86/0xB5
-
-# Star-Dome
-B:33:0x86/0xB6
-
-# Valarin Temple
-B:34:0x86/0xB7
-
-# Sea-Dome
-B:35:0x86/0xB8
-
-# The Golden Flower
-B:36:0x86/0xB9
-
-# The Fountain
-B:37:0x86/0xBA
-
-# Axe Smith
-B:38:0x86/0xBB
-
-# Hafted Smith
-B:39:0x86/0xBC
-
-# Polearm Smith
-B:40:0x86/0xBD
-
-# Sword Smith
-B:41:0x86/0xBE
-
-# Rare Jewelry Shop
-B:42:0x86/0xBF
-
-# Jewelry Shop
-B:43:0x87/0xA0
-
-# Footwear Shop
-B:44:0x87/0xA1
-
-# Rare Footwear Shop
-B:45:0x87/0xA2
-
-# Library
-B:46:0x86/0xA3
-
-# Forbidden Library
-B:47:0x87/0xA3
-
-# Expensive Black Market
-B:48:0x87/0xA4
-
-# Common Shop
-B:49:0x87/0xA5
-
-# Dragon Hunter
-B:50:0x87/0xA6
-
-# Speed Ring Market
-B:51:0x87/0xA7
-
-# Scribe
-B:52:0x87/0xA8
-
-# Potion Store
-B:53:0x87/0xA9
-
-# Recaller
-B:54:0x87/0xAA
-
-# Master Archer
-B:55:0x87/0xAB
-
-# Merchants Guild
-B:56:0x87/0xAC
-
-# The Mathom-house
-B:57:0x87/0xAD
-
-# The Prancing Pony
-B:58:0x86/0xA1
-
-# Mining Supply store
-B:59:0x86/0xB3
-
-# Library quest in Minas Anor
-B:60:0x86/0xA3
-
-# Hunting Supply Store
-B:61:0x87/0xAB
-
-# Runic Magic Shop
-B:62:0x82/0x8C
-
-# Construction Supply Store
-B:63:0x86/0xB3
-
-# Music Store
-B:64:0x86/0xB5
-
-# Magic Rod Market
-B:65:0x82/0x8C
-
-# Map store
-B:66:0x86/0xA3
-
-# Farm
-B:67:0x87/0xA5
-
-#Pelargir inn - The Grey Swan
-B:68:0x86/0xA1
-
-#Caras Galadhon inn - The Garden
-B:69:0x86/0xA1
-
-#Khazad Dum inn - The Mithril Lode
-B:70:0x86/0xA1
-
-#Dale inn - The Builder Barracks
-B:71:0x86/0xA1
-
-#Edoras inn - The Horse and Ox
-B:72:0x86/0xA1
-
-#Esgaroth inn - The Dancing Dragon
-B:73:0x86/0xA1
-
-#Hobbiton inn - The Green Dragon
-B:74:0x86/0xA1
-
-#Osgiliath inn - The Twinkling Star
-B:75:0x86/0xA1
-
-#The House of Beorn
-B:76:0x86/0xA0
-
-#Bard's Hut
-B:77:0x86/0xA0
-
-#The Ranger Conclave
-B:78:0x86/0xA0
-
-#Imladris
-B:79:0x86/0xA0
-
-#The Hornburg
-B:80:0x86/0xA0
-
-#Thranduil's Hall
-B:81:0x86/0xA0
-
-#Meduseld
-B:82:0x86/0xA0
-
-#The Master's House
-B:83:0x86/0xA0
-
-#Bag End
-B:84:0x86/0xA0
-
-#The Castle of Stars
-B:85:0x86/0xA0
-
-#The Prince's Tower
-B:86:0x86/0xA0
-
-#The Seat of Durin
-B:87:0x86/0xA0
-
-### The forge in Imladris
-B:88:0x86/0xB3
-
-# nothing
-F:0:0x80/0x80
-
-# open floor
-F:1:0x80/0x81
-
-# fountain
-F:2:0xC3/0x9A
-
-# glyph of warding
-F:3:0x8D/0x95
-
-# open door
-F:4:0x82/0x84
-
-# broken door
-F:5:0x82/0x85
-
-# up staircase
-F:6:0x80/0x96
-
-# down staircase
-F:7:0x80/0x99
-
-# quest entrance
-F:8:0x80/0x9A
-
-# quest exit
-F:9:0x80/0x97
-
-# quest down level
-F:10:0x80/0x9B
-
-# quest up level
-F:11:0x80/0x98
-
-# town exit
-F:12:0x82/0x84
-
-# shaft down
-F:13:0xC3/0x84
-
-# shaft up
-F:14:0xC3/0x85
-
-# fountain
-F:15:0xC3/0x99
-
-# web
-F:16:0x81/0x8C
-
-# trap
-F:17:0x81/0x89
-
-# visible trap -- spiked pit
-F:18:0x81/0x89
-
-# visible trap -- poison pit
-F:19:0x81/0x89
-
-# visible trap -- rune -- summon
-F:20:0x81/0x8F
-
-# visible trap -- rune -- teleport
-F:21:0x81/0x92
-
-# visible trap -- spot -- fire
-F:22:0x81/0x86
-
-# visible trap -- spot -- acid
-F:23:0x81/0x86
-
-# visible trap -- dart -- slow
-F:24:0x81/0x80
-
-# visible trap -- dart -- lose str
-F:25:0x81/0x80
-
-# visible trap -- dart -- lose dex
-F:26:0x81/0x80
-
-# visible trap -- dart -- lose con
-F:27:0x81/0x80
-
-# visible trap -- gas -- blind
-F:28:0x81/0x83
-
-# visible trap -- gas -- confuse
-F:29:0x81/0x83
-
-# visible trap -- gas -- poison
-F:30:0x81/0x83
-
-# visible trap -- gas -- sleep
-F:31:0x81/0x83
-
-# door
-F:32:0x82/0x83
-
-# locked door
-F:33:0x82/0x83
-F:34:0x82/0x83
-F:35:0x82/0x83
-F:36:0x82/0x83
-F:37:0x82/0x83
-F:38:0x82/0x86
-F:39:0x82/0x86
-
-# jammed door
-F:40:0x82/0x83
-F:41:0x82/0x83
-F:42:0x82/0x83
-F:43:0x82/0x83
-F:44:0x82/0x83
-F:45:0x82/0x86
-F:46:0x82/0x86
-F:47:0x82/0x86
-
-# secret door
-F:48:0x80/0x84
-
-# pile of rubble
-F:49:0x80/0x9C
-
-# magma vein
-F:50:0x80/0x8D
-
-# quartz vein
-F:51:0x80/0x87
-
-# magma vein
-F:52:0x80/0x90
-
-# quartz vein
-F:53:0x80/0x87
-
-# magma vein with treasure
-F:54:0x80/0x90
-
-# quartz vein with treasure
-F:55:0x80/0x8A
-
-# granite wall
-F:56:0x80/0x84
-F:57:0x80/0x84
-F:58:0x80/0x84
-F:59:0x80/0x84
-
-# permanent wall
-F:60:0x80/0x93
-F:61:0x80/0x93
-F:62:0x80/0x93
-F:63:0x80/0x93
-
-# explosive rune
-F:64:0x8D/0x9E
-
-# Straight Road startpoint
-F:65:0x81/0x95
-
-# section of the Straight Road
-F:66:0x81/0x95
-F:67:0x81/0x95
-F:68:0x81/0x95
-F:69:0x81/0x95
-F:70:0x81/0x95
-
-# section of the Straight Road (discharged)
-F:71:0x81/0x98
-
-# Straight Road exit
-F:72:0x81/0x9B
-
-# corrupted section of the Straight Road
-F:73:0x81/0x9E
-
-# Building
-F:74:0x82/0x93
-
-# permanent wall
-F:75:0x82/0x93
-F:76:0x82/0x94
-F:77:0x82/0x95
-F:78:0x82/0x96
-
-#Elanor
-F:79:0xC6:0xA0
-
-#Fumellar
-F:80:0xC6:0xA1
-
-#Anemones
-F:81:0xC6:0xA2
-
-#Niphredil
-F:82:0xC6:0xA3
-
-#Iris
-F:83:0xC6:0xA4
-
-# stream of shallow water
-F:84:0xB4/0x97
-
-# pool of deep lava
-F:85:0x83/0x8D
-
-# stream of shallow lava
-F:86:0xB4/0x9A
-
-# dark pit
-F:87:0x80/0x80
-
-# dirt
-F:88:0xB4/0x91
-
-# patch of grass
-F:89:0xB4/0x94
-
-# ice
-F:90:0xC3/0x83
-
-# sand
-F:91:0xC3/0x88
-
-# dead tree
-F:92:0xC3/0x98
-
-# ash
-F:93:0xC3/0x97
-
-# mud
-F:94:0xC3/0x96
-
-# ice wall
-F:95:0xC5/0x92
-
-# tree
-F:96:0x82/0x9A
-
-# mountain chain
-F:97:0x8D/0x98
-
-# sandwall
-F:98:0xC3/0x86
-F:99:0xC3/0x86
-
-# sandwall with treasure
-F:100:0xC3/0x87
-
-# high mountain chain
-F:101:0xC3/0x9E
-
-# nether mist
-F:102:0xC3/0x9F
-
-# molten glass wall
-F:103:0xC0/0x9F
-
-# Void Jumpgate
-F:160:0x91/0x84
-
-# Altar of Being
-F:161:0xC1/0x8E
-
-# Altar of Winds
-F:162:0xB5/0x8A
-
-# Altar of Force
-F:163:0xB5/0x86
-
-# Altar of Darkness
-F:164:0xB5/0x86
-
-# Altar of Nature
-F:165:0xB5/0x91
-
-# Altar of Sun
-F:166:0xB5/0x8F
-
-# Altar of Rage
-F:167:0xB5/0x8C
-
-# Altar of Winds
-F:168:0xB5/0x92
-
-# Altar of Stars
-F:169:0xC1/0x8F
-
-# Altar of Being
-F:170:0xB5/0x8D
-
-# Altar of Randomness
-F:171:0xB5/0x88
-
-# floor
-F:172:0x80/0x81
-
-# Underground Tunnel
-F:173:0x80/0x82
-
-# stream of tainted water
-F:174:0xAF/0x8E
-
-# monster trap
-F:175:0x81/0x9C
-
-# Void Jumpgate
-F:176:0xAF/0x8C
-
-# lava wall
-F:177:0xC6/0x8C
-
-# Great Fire
-F:178:0xC6/0x8A
-
-# path to the next area
-F:179:0x88/0xA1
-
-# path to the previous area
-F:180:0x88/0xA0
-
-# field
-F:181:0x88/0xA2
-
-# Ekkaia, the Encircling Sea
-F:182:0x88/0xA3
-
-# Altar of Energy
-F:183:0xB5/0x9A
-
-# Altar of Matter
-F:184:0xB5/0x9B
-
-# Altar of Being
-F:185:0xB5/0x9C
-
-# Altar of Unbeing
-F:186:0xB5/0x9D
-
-# pool of deep water
-F:187:0x83/0x80
-
-# glass wall
-F:188:0xC0/0x9F
-
-# illusion wall
-F:189:0x80/0x84
-
-# Grass roof
-F:190:0xC2/0x80
-
-# grass roof top
-F:191:0xC2/0x81
-
-# grass roof chimney
-F:192:0xC2/0x82
-
-# brick roof
-F:193:0xC3/0x80
-
-# brick roof top
-F:194:0xC3/0x81
-
-# brick roof chimney
-F:195:0xC3/0x82
-
-# window
-F:196:0xC2/0x83
-
-# small window
-F:197:0xC2/0x84
-
-# rain barrel
-F:198:0xC2/0x85
-
-# grass with flowers
-F:199:0xC2/0x86
-
-# cobblestone road
-F:200:0xC2/0x87
-
-# cobblestone with outlet
-F:201:0xC2/0x88
-
-# small tree
-F:202:0x82/0x9D
-
-# town
-F:203:0xC3/0x95
-
-# Underground Tunnel
-F:204:0x80/0x82
-
-# a blazing fire
-F:205:0xC6/0x8A
-
-# pile of rubble
-F:206:0xC6/0x8B
-
-# rocky ground
-F:207:0x8D/0xA0
-
-# cloud-like vapour
-F:208:0x8D/0xA1
-
-# condensing water
-F:209:0x8D/0xA2
-
-# dense mist
-F:210:0x8D/0xA3
-
-# hail-stone wall
-F:211:0x8D/0xA4
-
-# dead small tree
-F:212:0xC6:0xA5
-
-# low hill
-F:213:0xC6:0xA6
-
-# dark mountain chain
-F:214:0xC6:0xA7
-
-# blue mountain chain
-F:215:0xC6:0xA8
-
-# grey mountain chain
-F:216:0xC6:0xA9
-
-# part of Mount Doom
-F:217:0xC6:0xAA
-
-# snow-capped peak
-F:218:0xC3:0x9E
-
-# fir tree
-F:219:0xC6:0xAB
-
-# section of a flet
-F:220:0xC6:0xAC
-
-# light post
-F:221:0xC6:0xAD
-
-# water lily
-F:222:0xC6:0xAE
-
-# part of the Dead Marshes
-F:223:0xC6:0xAF
-
-# Black Gate
-F:224:0xC6:0xB0
-
-# river
-F:225:0xC6:0xB1
-
-# swamp pool
-F:226:0xC6:0xB2
-
-# stream of the Anduin river
-F:227:0xC6:0xB3
-
-# road sign that says 'Hurry to Gondolin!'
-F:228:0xC6:0xB4
-
-# beehive
-F:229:0xC6:0xB5
-
-# dirt road
-F:230:0xC6:0xB6
-
-# wide gate
-F:231:0xC6:0xB7
-
-# open gate
-F:232:0xC6:0xB8
-
-# wooden board
-F:233:0xC6:0xB9
-
-# wooden board
-F:234:0xC6:0xBA
-
-# wooden board
-F:235:0xC6:0xBB
-
-# wooden board
-F:236:0xC6:0xBC
-
-# white tree
-F:237:0xC6:0xBD
-
-# swift waterfall
-F:238:0xC6:0xBE
-
-# slippery rock ledge
-F:239:0xC5:0xA0
-
-# stable
-F:240:0xC5:0xA1
-
-# wooden plank
-F:241:0xC5:0xA2
-
-# fosse pit
-F:242:0xC5:0xA3
-
-# Mallorn
-F:243:0xC5:0xA4
-
-# copper pillar
-F:244:0xC5:0xBC
-
-# ethereal wall
-F:245:0x80/0x81
-
-# glacial wall
-F:246:0xC5/0x92
-
-# battlement
-F:247:0xC5:0xBD
-
-# dark pit
-F:248:0x82/0x84
-
-# Skeleton
-G:M:1:0xC6/0x91
-
-# Zombie
-G:M:2:0xC6/0x92
-
-# Lich
-G:M:3:0xC6/0x93
-
-# Spectral
-G:M:4:0xC6/0x94
-
-# Captain
-G:M:5:0xC6/0x95
-
-# Chieftain
-G:M:6:0xC6/0x96
-
-# Shaman
-G:M:7:0xC6/0x97
-
-# Priest
-G:M:8:0xC6/0x98
-
-# Mage
-G:M:9:0xC6/0x99
-
-# Archer
-G:M:10:0xC6/0x9A
-
-# Rogue
-G:M:11:0xC6/0x9B
-
-# Inertia Ball Trap
-G:T:95:0x82/0xBF
-
-# something
-K:0:0x01:0x20
-
-# Blindness
-K:1:0x85:0x94
-
-# Fear
-K:2:0x85:0x94
-
-# Confusion
-K:3:0x85:0x94
-
-# Hallucination
-K:4:0x85:0x94
-
-# Cure Poison
-K:5:0x85:0x94
-
-# Cure Blindness
-K:6:0x85:0x94
-
-# Cure Fear
-K:7:0xC6:0x83
-
-# Cure Confusion
-K:8:0x85:0x94
-
-# Weakness
-K:9:0x85:0x94
-
-# Unhealth
-K:10:0x85:0x94
-
-# Restore Constitution
-K:11:0x85:0x94
-
-# Restoring
-K:12:0x85:0x94
-
-# Stupidity
-K:13:0x85:0x94
-
-# Naivety
-K:14:0x85:0x94
-
-# Poison
-K:15:0x85:0x94
-
-# Sickness
-K:16:0x85:0x94
-
-# Paralysis
-K:17:0x85:0x94
-
-# Restore Strength
-K:18:0x85:0x94
-
-# Disease
-K:19:0x85:0x94
-
-# Cure Serious Wounds
-K:20:0x85:0x94
-
-# & Ration~ of Cram
-K:21:0x8E:0x84
-
-# & Round Seed-Cake~
-K:22:0x8E:0x82
-
-# & Strip~ of Venison
-K:23:0x8E:0x83
-
-# & Slime Mold~
-K:24:0x8E:0x85
-
-# & Lembas~
-K:25:0x8E:0x86
-
-# & Pint~ of Fine Ale
-K:26:0x8E:0x80
-
-# & Pint~ of Old Winyards
-K:27:0x8E:0x80
-
-# & Mattock~
-K:28:0xB6:0x8C
-
-# & Blue Stone~
-K:29:0xC5:0x93
-
-# & Broken Dagger~
-K:30:0x8A:0x8D
-
-# & Bastard Sword~
-K:31:0x8A:0x8E
-
-# & Scimitar~
-K:32:0x8A:0x97
-
-# & Tulwar~
-K:33:0x8A:0x95
-
-# & Broad Sword~
-K:34:0x8A:0x98
-
-# & Short Sword~
-K:35:0x8A:0x94
-
-# & Blade~ of Chaos
-K:36:0x8A:0x9E
-
-# & Two-Handed Sword~
-K:37:0x8A:0x9C
-
-# & Main Gauche~
-K:38:0x8A:0x90
-
-# & Cutlass~
-K:39:0x8A:0x96
-
-# & Executioner's Sword~
-K:40:0x8A:0x9D
-
-# & Katana~
-K:41:0x8A:0x9B
-
-# & Long Sword~
-K:42:0x8A:0x99
-
-# & Dagger~
-K:43:0x8A:0x8F
-
-# & Rapier~
-K:44:0x8A:0x91
-
-# & Sabre~
-K:45:0x8A:0x93
-
-# & Small Sword~
-K:46:0x8A:0x92
-
-# & Broken Sword~
-K:47:0x8A:0x8E
-
-# & Ball-and-Chain~
-K:48:0x8B:0x86
-
-# & Whip~
-K:49:0x8A:0x9F
-
-# & Flail~
-K:50:0x8B:0x83
-
-# & Two-Handed Flail~
-K:51:0x8B:0x87
-
-# & Morning Star~
-K:52:0x8B:0x84
-
-# & Mace~
-K:53:0x8B:0x81
-
-# & Quarterstaff~
-K:54:0x8B:0x82
-
-# & War Hammer~
-K:55:0x8B:0x80
-
-# & Lead-Filled Mace~
-K:56:0x8B:0x85
-
-# & Mace~ of Disruption
-K:57:0x8B:0x88
-
-# & Lucerne Hammer~
-K:58:0x8B:0x8D
-
-# & Beaked Axe~
-K:59:0x8B:0x90
-
-# & Glaive~
-K:60:0x8B:0x92
-
-# & Halberd~
-K:61:0x8B:0x93
-
-# & Awl-Pike~
-K:62:0x8B:0x8B
-
-# & Pike~
-K:63:0x8B:0x8F
-
-# & Spear~
-K:64:0x8B:0x89
-
-# & Trident~
-K:65:0x8B:0x8A
-
-# & Lance~
-K:66:0x8B:0x8C
-
-# & Great Axe~
-K:67:0x8B:0x95
-
-# & Battle Axe~
-K:68:0x8B:0x8E
-
-# & Lochaber Axe~
-K:69:0x8B:0x94
-
-# & Broad Axe~
-K:70:0x8B:0x91
-
-# & Scythe~
-K:71:0x8B:0x96
-
-# & Scythe~ of Slicing
-K:72:0x8B:0x97
-
-# & Short Bow~
-K:73:0x8B:0x98
-
-# & Long Bow~
-K:74:0x8B:0x99
-
-# & Light Crossbow~
-K:75:0x8B:0x9A
-
-# & Heavy Crossbow~
-K:76:0x8B:0x9B
-
-# & Sling~
-K:77:0x8B:0x9C
-
-# & Arrow~
-K:78:0x8C:0x80
-
-# & Seeker Arrow~
-K:79:0x8C:0x81
-
-# & Bolt~
-K:80:0x8C:0x82
-
-# & Seeker Bolt~
-K:81:0x8C:0x83
-
-# & Rounded Pebble~
-K:82:0x8C:0x84
-
-# & Iron Shot~
-K:83:0x8C:0x85
-
-# & Shovel~
-K:84:0x8E:0x8F
-
-# & Gnomish Shovel~
-K:85:0x8E:0x90
-
-# & Dwarven Shovel~
-K:86:0x8E:0x91
-
-# & Pick~
-K:87:0x8E:0x8C
-
-# & Orcish Pick~
-K:88:0x8E:0x8D
-
-# & Dwarven Pick~
-K:89:0x8E:0x91
-
-# & Elven Cloak~
-K:90:0x89:0x8A
-
-# & Pair~ of Soft Leather Boots
-K:91:0x88:0x8E
-
-# & Pair~ of Hard Leather Boots
-K:92:0x88:0x8F
-
-# & Pair~ of Metal Shod Boots
-K:93:0x88:0x90
-
-# & Hard Leather Cap~
-K:94:0x87:0x98
-
-# & Metal Cap~
-K:95:0x87:0x99
-
-# & Iron Helm~
-K:96:0x87:0x9A
-
-# & Steel Helm~
-K:97:0x87:0x9B
-
-# & Iron Crown~
-K:98:0x87:0x9C
-
-# & Golden Crown~
-K:99:0x87:0x9D
-
-# & Jewel-Encrusted Crown~
-K:100:0x87:0x9E
-
-# & Robe~
-K:101:0x89:0x8C
-
-# & Filthy Rag~
-K:102:0x89:0x8B
-
-# Soft Leather Armour~
-K:103:0x89:0x8D
-
-# Soft Studded Leather~
-K:104:0x89:0x8E
-
-# Hard Leather Armour~
-K:105:0x89:0x8F
-
-# Hard Studded Leather~
-K:106:0x89:0x90
-
-# Leather Scale Mail~
-K:107:0x89:0x91
-
-# Metal Scale Mail~
-K:108:0x89:0x92
-
-# Chain Mail~
-K:109:0x89:0x94
-
-# Rusty Chain Mail~
-K:110:0x89:0x93
-
-# Augmented Chain Mail~
-K:111:0x89:0x96
-
-# Bar Chain Mail~
-K:112:0x89:0x97
-
-# Metal Brigandine Armour~
-K:113:0x89:0x98
-
-# Partial Plate Armour~
-K:114:0x89:0x99
-
-# Metal Lamellar Armour~
-K:115:0x89:0x9A
-
-# Full Plate Armour~
-K:116:0x89:0x9B
-
-# Ribbed Plate Armour~
-K:117:0x89:0x9C
-
-# Galvorn Plate Mail~
-K:118:0x89:0x9F
-
-# Mithril Plate Mail~
-K:119:0x89:0x9E
-
-# Mithril Chain Mail~
-K:120:0x89:0x9D
-
-# Double Chain Mail~
-K:121:0x89:0x95
-
-# & Shield~ of Deflection
-K:122:0x88:0x98
-
-# & Cloak~
-K:123:0x89:0x88
-
-# & Shadow Cloak~
-K:124:0x89:0x89
-
-# & Set~ of Leather Gloves
-K:125:0x88:0x91
-
-# & Set~ of Gauntlets
-K:126:0x88:0x92
-
-# & Set~ of Cesti
-K:127:0x88:0x93
-
-# & Small Leather Shield~
-K:128:0x88:0x94
-
-# & Large Leather Shield~
-K:129:0x88:0x95
-
-# & Small Metal Shield~
-K:130:0x88:0x96
-
-# & Large Metal Shield~
-K:131:0x88:0x97
-
-# Strength
-K:132:0x84:0x81
-
-# Dexterity
-K:133:0x84:0x83
-
-# Constitution
-K:134:0x84:0x83
-
-# Intelligence
-K:135:0x84:0x83
-
-# Speed
-K:136:0x84:0x83
-
-# Searching
-K:137:0x84:0x83
-
-# Teleportation
-K:138:0x84:0x83
-
-# Slow Digestion
-K:139:0x84:0x83
-
-# Fire Resistance
-K:140:0x84:0x83
-
-# Cold Resistance
-K:141:0x84:0x83
-
-# Levitation
-K:142:0x84:0x83
-
-# Poison Resistance
-K:143:0x84:0x83
-
-# Free Action
-K:144:0x84:0x83
-
-# Weakness
-K:145:0x84:0x83
-
-# Flames
-K:146:0x84:0x83
-
-# Acid
-K:147:0x84:0x83
-
-# Ice
-K:148:0x84:0x83
-
-# Woe
-K:149:0x84:0x83
-
-# Stupidity
-K:150:0x84:0x83
-
-# Damage
-K:151:0x84:0x83
-
-# Accuracy
-K:152:0x84:0x83
-
-# Protection
-K:153:0x84:0x83
-
-# Aggravate Monster
-K:154:0x84:0x83
-
-# See Invisible
-K:155:0x84:0x83
-
-# Sustain Strength
-K:156:0x84:0x83
-
-# Sustain Intelligence
-K:157:0x84:0x83
-
-# Sustain Wisdom
-K:158:0x84:0x83
-
-# Sustain Constitution
-K:159:0x84:0x83
-
-# Sustain Dexterity
-K:160:0x84:0x83
-
-# Sustain Charisma
-K:161:0x84:0x83
-
-# Slaying
-K:162:0x84:0x83
-
-# Brilliance
-K:163:0x87:0x83
-
-# Charisma
-K:164:0x87:0x83
-
-# Searching
-K:165:0x87:0x83
-
-# Teleportation
-K:166:0x87:0x83
-
-# Slow Digestion
-K:167:0x87:0x83
-
-# Acid Resistance
-K:168:0x87:0x83
-
-# Protection from Evil
-K:169:0x87:0x83
-
-# Double Ring Mail~
-K:170:0x89:0x9B
-
-# the Magi
-K:171:0x87:0x83
-
-# Doom
-K:172:0x87:0x83
-
-# Enchant Weapon To-Hit
-K:173:0x83:0x9C
-
-# Enchant Weapon To-Dam
-K:174:0x83:0x9C
-
-# Enchant Armor
-K:175:0x83:0x9C
-
-# Identify
-K:176:0x83:0x9C
-
-# *Identify*
-K:177:0x83:0x9C
-
-# Rumour
-K:178:0x83:0x9C
-
-# Chaos
-K:179:0x83:0x9C
-
-# Remove Curse
-K:180:0x83:0x9C
-
-# Light
-K:181:0x83:0x9C
-
-# Fire
-K:182:0x83:0x9C
-
-# Ice
-K:183:0x83:0x9C
-
-# Summon Monsters
-K:184:0x83:0x9C
-
-# Phase Door
-K:185:0x83:0x9C
-
-# Teleportation
-K:186:0x83:0x9C
-
-# Teleport Level
-K:187:0x83:0x9C
-
-# Monster Confusion
-K:188:0x83:0x9C
-
-# Magic Mapping
-K:189:0x83:0x9C
-
-# Rune of Protection
-K:190:0x83:0x9C
-
-# *Remove Curse*
-K:191:0x83:0x9C
-
-# Treasure Detection
-K:192:0x83:0x9C
-
-# Object Detection
-K:193:0x83:0x9C
-
-# Trap Detection
-K:194:0x83:0x9C
-
-# & Sheaf Arrow~
-K:195:0x8C:0x81
-
-# & Mithril Shot~
-K:196:0x8C:0x85
-
-# Door/Stair Location
-K:197:0x83:0x9C
-
-# Acquirement
-K:198:0x83:0x9C
-
-# *Acquirement*
-K:199:0x83:0x9C
-
-# Mass Genocide
-K:200:0x83:0x9C
-
-# Detect Invisible
-K:201:0x83:0x9C
-
-# Aggravation
-K:202:0x83:0x9C
-
-# Trap Creation
-K:203:0x83:0x9C
-
-# Trap/Door Destruction
-K:204:0x83:0x9C
-
-# Artifact Creation
-K:205:0x83:0x9C
-
-# Recharging
-K:206:0x83:0x9C
-
-# Genocide
-K:207:0x83:0x9C
-
-# Darkness
-K:208:0x83:0x9C
-
-# Protection from Evil
-K:209:0x83:0x9C
-
-# Satisfy Hunger
-K:210:0x83:0x9C
-
-# Dispel Undead
-K:211:0x83:0x9C
-
-# *Enchant Weapon*
-K:212:0x83:0x9C
-
-# Curse Weapon
-K:213:0x83:0x9C
-
-# *Enchant Armour*
-K:214:0x83:0x9C
-
-# Curse Armour
-K:215:0x83:0x9C
-
-# Summon Undead
-K:216:0x83:0x9C
-
-# Blessing
-K:217:0x83:0x9C
-
-# Holy Chant
-K:218:0x83:0x9C
-
-# Holy Prayer
-K:219:0x83:0x9C
-
-# Word of Recall
-K:220:0x83:0x9C
-
-# *Destruction*
-K:221:0x83:0x9C
-
-# Slime Mold Juice
-K:222:0x85:0x85
-
-# Apple Juice
-K:223:0x85:0x85
-
-# Water
-K:224:0x85:0x85
-
-# Strength
-K:225:0x85:0x85
-
-# Weakness
-K:226:0x85:0x85
-
-# Restore Strength
-K:227:0x85:0x85
-
-# Intelligence
-K:228:0x85:0x85
-
-# Stupidity
-K:229:0x85:0x85
-
-# Restore Intelligence
-K:230:0x85:0x85
-
-# Wisdom
-K:231:0x85:0x85
-
-# Naivety
-K:232:0x85:0x85
-
-# Restore Wisdom
-K:233:0x85:0x85
-
-# Charisma
-K:234:0x85:0x85
-
-# Ugliness
-K:235:0x85:0x85
-
-# Restore Charisma
-K:236:0x85:0x85
-
-# Curing
-K:237:0x85:0x85
-
-# Invulnerability
-K:238:0x85:0x85
-
-# New Life
-K:239:0x85:0x85
-
-# Cure Serious Wounds
-K:240:0x85:0x85
-
-# Cure Critical Wounds
-K:241:0x85:0x85
-
-# Healing
-K:242:0x85:0x85
-
-# Constitution
-K:243:0x85:0x85
-
-# Experience
-K:244:0x85:0x85
-
-# Sleep
-K:245:0x85:0x85
-
-# Blindness
-K:246:0x85:0x85
-
-# Booze
-K:247:0x85:0x85
-
-# Poison
-K:248:0x85:0x85
-
-# Speed
-K:249:0x85:0x85
-
-# Slowness
-K:250:0x85:0x85
-
-# Dexterity
-K:251:0x85:0x85
-
-# Restore Dexterity
-K:252:0x85:0x85
-
-# Restore Constitution
-K:253:0x85:0x85
-
-# Lose Memories
-K:254:0x85:0x85
-
-# Salt Water
-K:255:0x85:0x85
-
-# Enlightenment
-K:256:0x85:0x85
-
-# Heroism
-K:257:0x85:0x85
-
-# Berserk Strength
-K:258:0x85:0x85
-
-# Boldness
-K:259:0x85:0x85
-
-# Restore Life Levels
-K:260:0x85:0x85
-
-# Resist Heat
-K:261:0x85:0x85
-
-# Resist Cold
-K:262:0x85:0x85
-
-# Detect Invisible
-K:263:0x85:0x85
-
-# Slow Poison
-K:264:0x85:0x85
-
-# Neutralise Poison
-K:265:0x85:0x85
-
-# Restore Mana
-K:266:0x85:0x85
-
-# Infra-vision
-K:267:0x85:0x85
-
-# Resistance
-K:268:0x85:0x85
-
-# Spell
-K:269:0x86:0x93
-
-# Manathrust
-K:270:0x86:0x93
-
-# Fireflash
-K:271:0x86:0x93
-
-# Firewall
-K:272:0x86:0x93
-
-# Tidal Wave
-K:273:0x86:0x93
-
-# Ice Storm
-K:274:0x86:0x93
-
-# Noxious Cloud
-K:275:0x86:0x93
-
-# Poison Blood
-K:276:0x86:0x93
-
-# Thunderstorm
-K:277:0x86:0x93
-
-# Dig
-K:278:0x86:0x93
-
-# Stone Prison
-K:279:0x86:0x93
-
-# Strike
-K:280:0x86:0x93
-
-# Teleport Away
-K:281:0x86:0x93
-
-# Summon Animal
-K:282:0x86:0x93
-
-# Magelock
-K:283:0x86:0x93
-
-# Slow Monster
-K:284:0x86:0x93
-
-# Essence of Speed
-K:285:0x86:0x93
-
-# Banishment
-K:286:0x86:0x93
-
-# Disperse Magic
-K:287:0x86:0x93
-
-# Charm
-K:288:0x86:0x93
-
-# Confuse
-K:289:0x86:0x93
-
-# Demon Blade
-K:290:0x86:0x93
-
-# Heal Monster
-K:291:0x86:0x93
-
-# Haste Monster
-K:292:0x86:0x93
-
-# & Flight Arrow~
-K:293:0x8C:0x81
-
-# & Boulder~
-K:295:0xC6:0x9F
-
-# & Flame~ Imperishable
-K:296:0xBE:0x9F
-
-# & Necromantic Teeth~
-K:297:0xC5:0xA5
-
-# & Golden Horn~ of the Eagles
-K:298:0x86:0x93
-
-# Spell
-K:300:0x87:0x92
-
-# Nothing
-K:301:0x87:0x92
-
-# Globe of Light
-K:302:0x87:0x92
-
-# Fiery Shield
-K:303:0x87:0x92
-
-# Remove Curses
-K:304:0x87:0x92
-
-# Wings of Winds
-K:305:0x87:0x92
-
-# Shake
-K:306:0x87:0x92
-
-# Disarm
-K:307:0x87:0x92
-
-# Teleportation
-K:308:0x87:0x92
-
-# Probability Travel
-K:309:0x87:0x92
-
-# Recovery
-K:310:0x87:0x92
-
-# Healing
-K:311:0x87:0x92
-
-# Vision
-K:312:0x87:0x92
-
-# Identify
-K:313:0x87:0x92
-
-# Sense Hidden
-K:314:0x87:0x92
-
-# Reveal Ways
-K:315:0x87:0x92
-
-# Sense Monsters
-K:316:0x87:0x92
-
-# Genocide
-K:317:0x87:0x92
-
-# Summon
-K:318:0x87:0x92
-
-# Sterilization
-K:319:0x87:0x92
-
-# Wish
-K:320:0x87:0x92
-
-# Mana
-K:321:0x87:0x92
-
-# & Tome~ of Magical Energy
-K:330:0x90:0xA0
-
-# & Tome~ of the Eternal Flame
-K:331:0x90:0xA1
-
-# & Tome~ of the Blowing Wind
-K:332:0x90:0xA2
-
-# & Tome~ of the Impenetrable Earth
-K:333:0x90:0xA3
-
-# & Tome~ of the Everrunning Wave
-K:334:0x90:0xA4
-
-# & Tome~ of Translocation
-K:335:0x90:0xA5
-
-# & Tome~ of the Tree
-K:336:0x90:0xA6
-
-# & Tome~ of Knowledge
-K:337:0x90:0xA7
-
-# & Small wooden chest~
-K:338:0x84:0x99
-
-# & Large wooden chest~
-K:339:0x84:0x9A
-
-# & Small iron chest~
-K:340:0x84:0x9B
-
-# & Large iron chest~
-K:341:0x84:0x9C
-
-# & Small steel chest~
-K:342:0x84:0x9D
-
-# & Large steel chest~
-K:343:0x84:0x9E
-
-# & Ruined chest~
-K:344:0x84:0x9F
-
-# & Iron Spike~
-K:345:0x8E:0x89
-
-# & Wooden Torch~
-K:346:0x8E:0x8B
-
-# & Brass Lantern~
-K:347:0x8E:0x8A
-
-# & Flask~ of oil
-K:348:0x8E:0x88
-
-# & Empty Bottle~
-K:349:0x8E:0x87
-
-# Havoc
-K:350:0x86:0x83
-
-# Door/Stair Location
-K:351:0x86:0x83
-
-# Trap Location
-K:352:0x86:0x83
-
-# Probing
-K:353:0x86:0x83
-
-# Recall
-K:354:0x86:0x83
-
-# Illumination
-K:355:0x86:0x83
-
-# Light
-K:356:0x86:0x83
-
-# Lightning Bolts
-K:357:0x86:0x83
-
-# Frost Bolts
-K:358:0x86:0x83
-
-# Fire Bolts
-K:359:0x86:0x83
-
-# Polymorph
-K:360:0x86:0x83
-
-# Slow Monster
-K:361:0x86:0x83
-
-# Sleep Monster
-K:362:0x86:0x83
-
-# Drain Life
-K:363:0x86:0x83
-
-# Teleport Other
-K:364:0x86:0x83
-
-# Disarming
-K:365:0x86:0x83
-
-# Lightning Balls
-K:366:0x86:0x83
-
-# Cold Balls
-K:367:0x86:0x83
-
-# Fire Balls
-K:368:0x86:0x83
-
-# Acid Balls
-K:369:0x86:0x83
-
-# Acid Bolts
-K:370:0x86:0x83
-
-# Enlightenment
-K:371:0x86:0x83
-
-# Perception
-K:372:0x86:0x83
-
-# Curing
-K:373:0x86:0x83
-
-# Healing
-K:374:0x86:0x83
-
-# Detection
-K:375:0x86:0x83
-
-# Restoration
-K:376:0x86:0x83
-
-# Speed
-K:377:0x86:0x83
-
-# Spell
-K:378:0x84:0x83
-
-# Spell
-K:379:0x87:0x80
-
-# & Broken Skull~
-K:391:0x8E:0x94
-
-# & Broken Bone~
-K:392:0x8E:0x95
-
-# & Canine Skeleton~
-K:393:0x8E:0x9A
-
-# & Rodent Skeleton~
-K:394:0x8E:0x9B
-
-# & Human Skeleton~
-K:395:0x8E:0x96
-
-# & Dwarf Skeleton~
-K:396:0x8E:0x98
-
-# & Elf Skeleton~
-K:397:0x8E:0x97
-
-# & Gnome Skeleton~
-K:398:0x8E:0x99
-
-# & Great Hammer~
-K:399:0xB6:0x8A
-
-# Black Dragon Scale Mail~
-K:400:0x8A:0x82
-
-# Blue Dragon Scale Mail~
-K:401:0x8A:0x80
-
-# White Dragon Scale Mail~
-K:402:0x8A:0x81
-
-# Red Dragon Scale Mail~
-K:403:0x8A:0x83
-
-# Green Dragon Scale Mail~
-K:404:0x8A:0x84
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x8A:0x8B
-
-# Pseudo Dragon Scale Mail~
-K:406:0x8A:0x87
-
-# Law Dragon Scale Mail~
-K:407:0x8A:0x89
-
-# Bronze Dragon Scale Mail~
-K:408:0x8A:0x85
-
-# Gold Dragon Scale Mail~
-K:409:0x8A:0x86
-
-# Chaos Dragon Scale Mail~
-K:410:0x8A:0x88
-
-# Balance Dragon Scale Mail~
-K:411:0x8A:0x8A
-
-# Power Dragon Scale Mail~
-K:412:0x8A:0x8C
-
-# & Dragon Helm~
-K:413:0x88:0x82
-
-# & Dragon Shield~
-K:414:0x88:0x9C
-
-# Death
-K:415:0x85:0x85
-
-# Ruination
-K:416:0x85:0x85
-
-# Detonations
-K:417:0x85:0x85
-
-# Augmentation
-K:418:0x85:0x85
-
-# *Healing*
-K:419:0x85:0x85
-
-# Life
-K:420:0x85:0x85
-
-# Self Knowledge
-K:421:0x85:0x85
-
-# *Enlightenment*
-K:422:0x85:0x85
-
-# Fear Resistance
-K:425:0x84:0x83
-
-# Light and Darkness Resistance
-K:426:0x84:0x83
-
-# Nether Resistance
-K:427:0x84:0x83
-
-# Nexus Resistance
-K:428:0x84:0x83
-
-# Sound Resistance
-K:429:0x84:0x83
-
-# Confusion Resistance
-K:430:0x84:0x83
-
-# Shard Resistance
-K:431:0x84:0x83
-
-# Disenchantment Resistance
-K:432:0x84:0x83
-
-# Chaos Resistance
-K:433:0x84:0x83
-
-# Blindness Resistance
-K:434:0x84:0x83
-
-# Lordly Protection
-K:435:0x84:0x83
-
-# Extra Attacks
-K:436:0x84:0x83
-
-# Cure Light Wounds
-K:437:0x85:0x85
-
-# Clumsiness
-K:438:0x85:0x85
-
-# Sickliness
-K:439:0x85:0x85
-
-# Map of Bree
-K:440:0xC4:0x80
-
-# Map of Gondolin
-K:441:0xC4:0x80
-
-# Map of Lothlorien
-K:442:0xC4:0x80
-
-# Map of Minas Anor
-K:443:0xC4:0x80
-
-# & Silver Arrow~
-K:465:0xC6:0x81
-
-# & Silver Bolt~
-K:466:0xC6:0x82
-
-# Lightning Resistance
-K:467:0x87:0x80
-
-# Wisdom
-K:468:0x87:0x80
-
-# Regeneration
-K:469:0x87:0x80
-
-# Infravision
-K:470:0x87:0x80
-
-# Devotion
-K:471:0x87:0x80
-
-# Weaponmastery
-K:472:0x87:0x80
-
-# Trickery
-K:473:0x87:0x80
-
-# Telepathy
-K:474:0x87:0x80
-
-# Sustenance
-K:475:0x87:0x80
-
-# & Palantir~
-K:476:0xC6:0x87
-
-# & Elfstone~
-K:477:0xC6:0x83
-
-# & Jewel~
-K:478:0xC6:0x84
-
-# & Ring~
-K:479:0xC6:0x85
-
-# copper
-K:480:0x83:0x91
-
-# copper
-K:481:0x83:0x91
-
-# copper
-K:482:0x83:0x91
-
-# silver
-K:483:0x83:0x92
-
-# silver
-K:484:0x83:0x92
-
-# silver
-K:485:0x83:0x92
-
-# garnets
-K:486:0x83:0x96
-
-# garnets
-K:487:0x83:0x96
-
-# gold
-K:488:0x83:0x93
-
-# gold
-K:489:0x83:0x93
-
-# gold
-K:490:0x83:0x93
-
-# opals
-K:491:0x83:0x97
-
-# sapphires
-K:492:0x83:0x98
-
-# rubies
-K:493:0x83:0x99
-
-# diamonds
-K:494:0x83:0x9A
-
-# emeralds
-K:495:0x83:0x9B
-
-# mithril
-K:496:0x83:0x94
-
-# adamantite
-K:497:0x83:0x95
-
-# & Mighty Hammer~
-K:498:0xB6:0x8A
-
-# & Massive Iron Crown~
-K:499:0x87:0x9C
-
-# & Phial~
-K:500:0x8E:0x9D
-
-# & Star~
-K:501:0x8E:0x9E
-
-# & Arkenstone~
-K:502:0x8E:0x9F
-
-# & Amulet~
-K:503:0x84:0x96
-
-# & Amulet~
-K:504:0x84:0x97
-
-# & Necklace~
-K:505:0x84:0x98
-
-# & Ring~
-K:506:0x84:0x8F
-
-# & Ring~
-K:507:0x84:0x83
-
-# & Ring~
-K:508:0x84:0x92
-
-# & Ring~
-K:509:0x84:0x93
-
-# & Ring~
-K:510:0x84:0x94
-
-# & Ring~
-K:511:0x84:0x95
-
-# Reflection
-K:520:0x87:0x83
-
-# Anti-Magic
-K:521:0x87:0x83
-
-# Anti-Teleportation
-K:522:0x87:0x83
-
-# Resistance
-K:523:0x87:0x83
-
-# & Zweihander~
-K:524:0xB6:0x8C
-
-# & Dwarven Lantern~
-K:525:0xC5:0x94
-
-# Splint Mail~
-K:526:0x89:0x9C
-
-# & Everburning Torch~
-K:527:0xC5:0x95
-
-# & Trifurcate Spear~
-K:528:0xB6:0x85
-
-# & Three-Piece Rod~
-K:529:0xB6:0x80
-
-# & Feanorian Lamp~
-K:530:0xC5:0x96
-
-# & Fur Cloak~
-K:531:0x89:0x89
-
-# Water Curing
-K:532:0x85:0x85
-
-# & Hatchet~
-K:533:0xB6:0x8F
-
-# Mumak Hide Armour~
-K:535:0x89:0x98
-
-# & Leather Jerkin~
-K:536:0x89:0x8F
-
-# & Sickle~
-K:537:0xB6:0x90
-
-# & Club~
-K:542:0xB6:0x92
-
-# & Broad Spear~
-K:543:0xB6:0x84
-
-# & Khopesh~
-K:544:0xB6:0x94
-
-# & Flamberge~
-K:545:0xB6:0x83
-
-# & Claymore~
-K:546:0xB6:0x8D
-
-# & Espadon~
-K:547:0xB6:0x8E
-
-# & Great Scimitar~
-K:548:0xB6:0x8B
-
-# Arrow
-K:549:0x8E:0xA0
-
-# Bolt
-K:550:0x8E:0xA1
-
-# & Fauchard~
-K:551:0xB6:0x95
-
-# & Guisarme~
-K:552:0xB6:0x96
-
-# & Heavy Lance~
-K:553:0xB6:0x82
-
-# & Bardiche~
-K:554:0xB6:0x99
-
-# Catapult
-K:555:0x8E:0xA2
-
-# Ring Mail~
-K:556:0x89:0x9C
-
-# Cord Armour~
-K:557:0x89:0x90
-
-# Paper Armour~
-K:558:0x8A:0x81
-
-# Padded Armour~
-K:559:0x89:0x91
-
-# Fumes
-K:560:0x8E:0xA3
-
-# Golden Ring Mail~
-K:561:0xC5:0xB4
-
-# Magic
-K:562:0x8E:0xA4
-
-# Device
-K:563:0x8E:0xA5
-
-# Nothing
-K:569:0x86:0x83
-
-# & Blood~ of Life
-K:573:0x85:0x85
-
-# & Mage Staff~
-K:577:0xB8:0x80
-
-# Lightning
-K:578:0x84:0x80
-
-# & Ring~
-K:582:0x84:0x85
-
-# Invisibility
-K:583:0x85:0x85
-
-# Corruption
-K:585:0x85:0x85
-
-# Invisibility
-K:586:0x84:0x80
-
-# Deep Thoughts
-K:588:0x83:0x9C
-
-# More Deep Thoughts
-K:589:0x83:0x9D
-
-# Compendium of Deep Thoughts
-K:590:0x83:0x9E
-
-# Artifact Lore Vol. I
-K:591:0x83:0x9C
-
-# Artifact Lore Vol. II
-K:592:0x83:0x9D
-
-# Artifact Lore Vol. III
-K:593:0x83:0x9F
-
-# Monstrous Compendium 1
-K:594:0x83:0x9F
-
-# Monstrous Compendium 2
-K:595:0x83:0x9E
-
-# Monstrous Compendium 3
-K:596:0x83:0x9D
-
-# Monstrous Compendium 4
-K:597:0x83:0x9C
-
-# Monstrous Compendium 5
-K:598:0x83:0x9F
-
-# Monstrous Compendium 6
-K:599:0x83:0x9E
-
-# Monstrous Compendium 7
-K:600:0x83:0x9D
-
-# Monstrous Compendium 8
-K:601:0x83:0x9C
-
-# Monstrous Compendium 9
-K:602:0x83:0x9D
-
-# Monstrous Compendium 10
-K:603:0x83:0x9E
-
-# Monstrous Compendium 11
-K:604:0x83:0x9F
-
-# & Morphic Oil~ of #
-K:605:0x85:0x85
-
-# Artifact Lore Vol. IV
-K:607:0x83:0x9C
-
-# Artifact Lore Vol. V
-K:608:0x83:0x9D
-
-# Artifact Lore Vol. VI
-K:609:0x83:0x9E
-
-# Artifact Lore Vol. VII
-K:610:0x83:0x9F
-
-# Artifact Lore Vol. VIII
-K:611:0x83:0x9C
-
-# Artifact Lore Vol. IX
-K:612:0x83:0x9D
-
-# Artifact Lore Vol. X
-K:613:0x83:0x9E
-
-# Artifact Lore Vol. XI
-K:614:0x83:0x9F
-
-# Artifact Lore Vol. IX
-K:615:0x83:0x9C
-
-# Artifact Lore Vol. X
-K:616:0x83:0x9D
-
-# Artifact Lore Vol. XI
-K:617:0x83:0x9E
-
-# & #~
-K:618:0x8F:0xA0
-
-# corpse
-K:641:0xB8:0x81
-
-# skeleton
-K:642:0x8E:0x96
-
-# head
-K:643:0x8E:0x94
-
-# skull
-K:644:0x8E:0x94
-
-# raw meat
-K:645:0x8E:0x83
-
-# & Great Eagle Down Coat~
-K:646:0x8A:0x86
-
-# & Key~
-K:647:0x8E:0x9C
-
-# & Small Wooden Boomerang~
-K:648:0xB8:0x82
-
-# & Wooden Boomerang~
-K:649:0xB8:0x83
-
-# & Small Metal Boomerang~
-K:650:0xB8:0x84
-
-# & Metal Boomerang~
-K:651:0xB8:0x85
-
-# & Anchor~
-K:652:0x8D:0x9E
-
-# & ~
-K:653:0xC5:0xB5
-
-# Summon Never-Moving Pet
-K:654:0x83:0x9D
-
-# Cure Light Insanity
-K:657:0x85:0x85
-
-# Cure Serious Insanity
-K:658:0x85:0x85
-
-# Cure Critical Insanity
-K:659:0x85:0x85
-
-# Cure Insanity
-K:660:0x85:0x85
-
-# & Phial~
-K:661:0x8E:0x9D
-
-# Junkart
-K:662:0xC5:0xB6
-
-# Craftsmanship
-K:663:0x83:0x9F
-
-# The One Ring
-K:664:0x83:0x9E
-
-# & Horn~
-K:669:0xB8:0x88
-
-# & Drum~
-K:670:0xB8:0x89
-
-# & Harp~
-K:671:0xB8:0x8A
-
-# & Palantir~
-K:675:0x8D:0x9F
-
-# Egg
-K:676:0xB7:0x8D
-
-# Reset Recall
-K:677:0x83:0x9D
-
-# Divination
-K:678:0x83:0x9D
-
-# Self
-K:679:0xB7:0x8E
-
-# Ray
-K:680:0xB7:0x8F
-
-# Sphere
-K:681:0xB7:0x90
-
-# Knowledge
-K:682:0xB7:0x94
-
-# Life
-K:683:0xB7:0x95
-
-# Fire
-K:684:0xB7:0x96
-
-# Cold
-K:685:0xB7:0x97
-
-# Lightning
-K:686:0xB7:0x98
-
-# Acid
-K:687:0xB7:0x99
-
-# Element
-K:688:0xB7:0x9A
-
-# Chaos
-K:689:0xB7:0x9B
-
-# Mind
-K:690:0xB7:0x9C
-
-# Holding
-K:691:0xB7:0x9D
-
-# Arrow
-K:692:0xB7:0x91
-
-# Power Surge
-K:693:0xB7:0x92
-
-# Armageddon
-K:694:0xB7:0x93
-
-# Gravity
-K:695:0xB7:0x9E
-
-# Undeath
-K:697:0xB6:0x9B
-
-# Protection
-K:698:0xB6:0x9C
-
-# & Ring~ of Precognition
-K:700:0x84:0x83
-
-# & Sprig~ of Athelas
-K:701:0xB8:0x8E
-
-# & Old Scroll~ of Deincarnation
-K:720:0x83:0x9F
-
-# & Dark Sword~
-K:721:0xC4:0x81
-
-# Numenorean for Beginners (I)
-K:722:0x83:0x9D
-
-# Numenorean for Beginners (II)
-K:723:0x83:0x9D
-
-# Advanced Lessons of Numenorean
-K:724:0x83:0x9D
-
-# Advanced Lessons of Sindarin
-K:725:0x83:0x9D
-
-# & Shard~ of Pottery
-K:726:0x8E:0x92
-
-# & Broken Stick~
-K:727:0x8E:0x93
-
-# & Book~ of Beginner Cantrips
-K:738:0x90:0xA0
-
-# & Book~ of Teleportation
-K:739:0x90:0xA5
-
-# & Book~ of Summoning
-K:741:0x90:0xA7
-
-# & Potion~ of Learning
-K:743:0xC1:0x82
-
-# Khuzdul - The Hidden Tongue of the Dwarves
-K:751:0x83:0x9D
-
-# Nandorin for Dummies
-K:752:0x83:0x9D
-
-# Advanced Lessons of Orcish
-K:753:0x83:0x9D
-
-# Flying
-K:755:0x84:0x88
-
-# & Tome~ of the Time
-K:756:0x90:0xA5
-
-# & Spellbook~ of #
-K:757:0x91:0xA4
-
-# & Tome~ of Meta Spells
-K:758:0x90:0xA0
-
-# & Tome~ of the Mind
-K:759:0x90:0xA7
-
-# & Holy Tome~ of Eru Iluvatar
-K:760:0x90:0xA7
-
-# & Holy Tome~ of Manwe Sulimo
-K:761:0x90:0xA2
-
-# & War Tome~ of Tulkas
-K:762:0x90:0xA5
-
-# & Unholy Tome~ of the Hellflame
-K:763:0x90:0xA1
-
-# & Corrupted Tome~ of Melkor
-K:764:0x90:0xA1
-
-# & Earth Tome~ of Aule
-K:765:0x90:0xA3
-
-# & Shining Tome~ of Varda
-K:766:0x90:0xA2
-
-# & Water Tome~ of Ulmo
-K:767:0x90:0xA4
-
-# & Forest Tome~ of Yavanna
-K:768:0x90:0xA6
-
-# Tome of#
-K:769:0x90:0xA3
-
-# & Ring~
-K:770:0x84:0x84
-
-# & Holy Tome~ of Mandos
-K:771:0x90:0xA0
-
-# & Great Rod Tip~ of Home Summoning
-K:776:0x86:0x83
-
-# & Shadow Blade~
-K:777:0xC1:0x91
-
-# & Bluesteel Blade~
-K:778:0xC1:0x92
-
-# the Serpents
-K:779:0xC4:0x88
-
-# Ring~ of Power
-K:785:0xC4:0x8E
-
-# Climbing Set~
-K:786:0xC1:0x93
-
-# Adventurer's Guide to Middle-earth
-K:787:0x83:0x9E
-
-# & Demonblade~
-K:788:0x90:0xA8
-
-# & Demonshield~
-K:789:0x90:0xA9
-
-# & Demonhorn~
-K:790:0x90:0xAA
-
-# & Wooden Rod~ of#
-K:793:0xC1:0x95
-
-# & Copper Rod~ of#
-K:794:0xC1:0x96
-
-# & Iron Rod~ of#
-K:795:0xC1:0x97
-
-# & Moonstone Rod~ of#
-K:796:0xC1:0x98
-
-# & Silver Rod~ of#
-K:797:0xC1:0x99
-
-# & Golden Rod~ of#
-K:798:0xC1:0x9B
-
-# & Mithril Rod~ of#
-K:799:0xC1:0x9C
-
-# & Tilkal Rod~ of#
-K:800:0xC1:0x9D
-
-# & Greater Ration~ of Health
-K:801:0xC4:0x87
-
-# & Crumpled Scroll~ of Mass Resurrection
-K:802:0x83:0x9E
-
-# & Cleaver~
-K:803:0xC4:0x82
-
-# & Light War Axe~
-K:804:0xC4:0x83
-
-# & Slaughter Axe~
-K:805:0xC4:0x84
-
-# & Runestone~
-K:806:0xC4:0x85
-
-# & Fortune cookie~
-K:807:0xC6:0x86
-
-# Critical Hits
-K:809:0x84:0x83
-
-# & Wand~ of Digging of Thrain
-K:810:0x86:0x93
-
-# & Gnarled Staff~ of Holy Fire of Mithrandir
-K:811:0x87:0x92
-
-# Partial Totem
-K:812:0xC6:0x9D
-
-# True Totem
-K:813:0xC6:0x9E
-
-# & Piece~ of the Relic of Eru
-K:814:0x8C:0xA2
-
-# & Piece~ of the Relic of Manwe
-K:815:0x8C:0xA3
-
-# & Piece~ of the Relic of Tulkas
-K:816:0x8C:0xA4
-
-# & Piece~ of the Relic of Melkor
-K:817:0x8C:0xA5
-
-# & Piece~ of the Relic of Yavanna
-K:818:0x8C:0xA6
-
-# & Ring~
-K:819:0x84:0x83
-
-# & Ring~
-K:820:0x84:0x83
-
-# & Ring~
-K:821:0x84:0x83
-
-# & Ring~
-K:822:0x84:0x83
-
-# & Ring~
-K:823:0x84:0x83
-
-# & Ring~
-K:824:0x84:0x83
-
-# & Piece~ of the Relic of Aule
-K:825:0x8C:0xA7
-
-# & Piece~ of the Relic of Varda
-K:826:0x8C:0xA8
-
-# & Piece~ of the Relic of Ulmo
-K:827:0x8C:0xA9
-
-# & Piece~ of the Relic of Mandos
-K:828:0x8C:0xAA
-
-# THEME
-
-# & Pinch~ of Longbottom Leaf
-K:831:0xC5:0xAA
-
-# & Ear~ of Corn
-K:832:0xC6:0xBF
-
-# & Tater~
-K:833:0xC5:0xA6
-
-# & Strawberry~
-K:834:0x93:0xA4
-
-# & Turnip~
-K:835:0xC5:0xA7
-
-# & Jar~ of Honey
-K:836:0xC5:0xA8
-
-# & Jug~ of Milk
-K:837:0xC5:0xA9
-
-# of War
-K:838:0x87:0x80
-
-# of Life
-K:839:0x87:0x80
-
-# Wizardry
-K:840:0x84:0x83
-
-# Vitality
-K:841:0x84:0x83
-
-# Clear Thought
-K:842:0x84:0x83
-
-# Clumsiness
-K:843:0x84:0x83
-
-# Sickliness
-K:844:0x84:0x83
-
-# Fortune
-K:845:0x84:0x83
-
-# Sterilise
-K:846:0x83:0x9C
-
-# Map of Middle-earth
-K:847:0xC4:0x80
-
-# Map of Edoras
-K:848:0xC4:0x80
-
-# Map of Esgaroth
-K:849:0xC4:0x80
-
-# Map of Hobbiton
-K:850:0xC4:0x80
-
-# Map of Osgiliath
-K:851:0xC4:0x80
-
-# Map of Pelargir
-K:852:0xC4:0x80
-
-# Map of Beorn's domain
-K:853:0xC4:0x80
-
-# Map of Dale
-K:854:0xC4:0x80
-
-# Map of Henneth Annun
-K:855:0xC4:0x80
-
-# Map of Helm's Deep
-K:856:0xC4:0x80
-
-# Map of Thranduil's realm
-K:857:0xC4:0x80
-
-# Map of Imladris
-K:858:0xC4:0x80
-
-# & Bearded Axe~
-K:859:0xC5:0xAD
-
-# & Double Axe~
-K:860:0xC5:0xAE
-
-# & Crusader Axe~
-K:861:0xC5:0xAF
-
-# & Reaper Axe~
-K:862:0xC5:0xB0
-
-# & Mithril Helm~
-K:863:0xC5:0xB8
-
-# & Set~ of Mithril Gauntlets
-K:864:0xC5:0xB9
-
-# & Small Mithril Shield~
-K:865:0xC5:0xBA
-
-# & Large Mithril Shield~
-K:866:0xC5:0xBB
-
-# & Map~
-K:867:0xC4:0x80
-
-# & Key~
-K:868:0x93:0xA7
-
-# & Cup~
-K:869:0xC5:0xAB
-
-# & Red Arrow~
-K:870:0xAE:0x87
-
-# & Sceptre~
-K:871:0x86:0x94
-
-# & Rod~
-K:872:0x86:0x93
-
-# & Necklace~
-K:873:0x87:0x8C
-
-# & Amulet~
-K:874:0x87:0x80
-
-# & Black Banner~
-K:875:0xC5:0xAC
-
-# & Pearl~
-K:876:0xC5:0xB1
-
-# & Silmaril~
-K:877:0xC5:0xB2
-
-# & Silmaril~
-K:878:0xC5:0xB3
-
-# & Golden Harp~
-K:879:0xC5:0xB7
-
-# Player
-R:0:0x8E/0x80
-
-# Filthy street urchin
-R:1:0xAA:0x80
-
-# Scrawny cat
-R:2:0xA7:0x82
-
-# Sparrow
-R:3:0xB4:0x9E
-
-# Chaffinch
-R:4:0xB4:0x9E
-
-# Wild rabbit
-R:5:0xB4:0x9F
-
-# Woodsman
-R:6:0xAA:0x91
-
-# Scruffy little dog
-R:7:0x9D:0x9A
-
-# Farmer Maggot
-R:8:0xAA:0x81
-
-# Blubbering idiot
-R:9:0xAA:0x82
-
-# Boil-covered wretch
-R:10:0xAA:0x83
-
-# Village idiot
-R:11:0xAA:0x84
-
-# Pitiful-looking beggar
-R:12:0xAA:0x85
-
-# Mangy-looking leper
-R:13:0xAA:0x86
-
-# Agent of the black market
-R:14:0xAA:0x87
-
-# Singing, happy drunk
-R:15:0xAA:0x88
-
-# Aimless-looking merchant
-R:16:0xAA:0x89
-
-# Mean-looking mercenary
-R:17:0xAA:0x8A
-
-# Battle-scarred veteran
-R:18:0xAA:0x8B
-
-# The Squint-eyed Southerner
-R:19:0xB0:0x80
-
-# Grey mold
-R:20:0xA8:0x9F
-
-# Large white snake
-R:21:0xA2:0x85
-
-# Grey mushroom patch
-R:22:0xB0:0x81
-
-# Newt
-R:23:0xB0:0x82
-
-# Ox
-R:24:0xC0:0xAE
-
-# Kine of Araw
-R:25:0xC0:0xAF
-
-# Sheep
-R:26:0xC0:0xB0
-
-# Giant white mouse
-R:27:0xAC:0x85
-
-# Large brown snake
-R:28:0xA2:0x84
-
-# Meara
-R:29:0xC0:0xB1
-
-# Horse
-R:30:0xC0:0xB2
-
-# White worm mass
-R:31:0xAC:0x9D
-
-# Floating eye
-R:32:0xA6:0x9B
-
-# Rock lizard
-R:33:0xA2:0x86
-
-# The Boar of Everholt
-R:34:0xC0:0xB3
-
-# Jackal
-R:35:0x9D:0x9B
-
-# Soldier ant
-R:36:0xA5:0x87
-
-# Fruit bat
-R:37:0xA5:0x8F
-
-# Insect swarm
-R:38:0xB5:0x9E
-
-# Boar
-R:39:0xC0:0xB4
-
-# Shrieker mushroom patch
-R:40:0x9D:0x86
-
-# Cow
-R:41:0xC0:0xB5
-
-# Novice warrior
-R:43:0xAA:0x8C
-
-# Novice rogue
-R:44:0xAA:0x8D
-
-# Novice priest
-R:45:0xAA:0x8E
-
-# Novice mage
-R:46:0xAA:0x8F
-
-# Yellow mushroom patch
-R:47:0x9D:0x87
-
-# White jelly
-R:48:0xA8:0x8A
-
-# Giant black ant
-R:49:0xA5:0x88
-
-# Salamander
-R:50:0xA2:0x88
-
-# White harpy
-R:51:0xA0:0x88
-
-# Deer
-R:52:0xC0:0xB6
-
-# Grip, Farmer Maggot's dog
-R:53:0x9D:0x9C
-
-# Wolf, Farmer Maggot's dog
-R:54:0x9D:0x9D
-
-# Fang, Farmer Maggot's dog
-R:55:0x9D:0x9D
-
-# Giant green frog
-R:56:0xA2:0x87
-
-# Lion
-R:57:0xC0:0xB7
-
-# Green worm mass
-R:58:0xAC:0x9E
-
-# Large yellow snake
-R:59:0xA2:0x89
-
-# Cave spider
-R:60:0xA2:0x9D
-
-# Crow
-R:61:0xB5:0x9F
-
-# Wild cat
-R:62:0xA7:0x83
-
-# Smeagol
-R:63:0xAA:0x90
-
-# Green ooze
-R:64:0xA8:0x8B
-
-# Poltergeist
-R:65:0x9F:0x99
-
-# Yellow jelly
-R:66:0xA8:0x8D
-
-# Squirrel
-R:67:0xC0:0xB8
-
-# Raven
-R:68:0xB5:0x9F
-
-# White midge
-R:69:0xA8:0x9D
-
-# Squirrel of Mirkwood
-R:70:0xC0:0xB9
-
-# Black naga
-R:71:0xA9:0x88
-
-# Spotted mushroom patch
-R:72:0x9D:0x88
-
-# Silver jelly
-R:73:0xA8:0x8C
-
-# Scruffy-looking hobbit
-R:74:0xA7:0x93
-
-# Giant white ant
-R:75:0xA5:0x89
-
-# Yellow mold
-R:76:0xA9:0x80
-
-# Ape
-R:77:0xC0:0xBA
-
-# Yellow worm mass
-R:78:0xAC:0x9F
-
-# Clear worm mass
-R:79:0xAD:0x80
-
-# Radiation eye
-R:80:0xA6:0x9C
-
-# Yellow light
-R:81:0xB8:0x93
-
-# Cave lizard
-R:82:0xA2:0x8A
-
-# Novice ranger
-R:83:0xAA:0x91
-
-# Blue jelly
-R:84:0xA8:0x8E
-
-# Creeping copper coins
-R:85:0x9D:0x80
-
-# Giant white rat
-R:86:0xAC:0x86
-
-# Snotling
-R:87:0xB9:0x89
-
-# Swordfish
-R:88:0xB6:0x9E
-
-# Blue worm mass
-R:89:0xAD:0x81
-
-# Large grey snake
-R:90:0xA2:0x8B
-
-# Corsair of Umbar
-R:91:0xC0:0xBB
-
-# Dunlending
-R:92:0xC0:0xBC
-
-# Apprentice mage
-R:93:0xAA:0x8F
-
-# Green naga
-R:94:0xA9:0x89
-
-# Giant leech
-R:95:0xB8:0x94
-
-# Barracuda
-R:96:0xB6:0x9F
-
-# Novice paladin
-R:97:0xAA:0x92
-
-# Man of Harad
-R:98:0xC0:0xBD
-
-# Blue ooze
-R:99:0xA8:0x8F
-
-# Green glutton ghost
-R:100:0x9F:0x9A
-
-# Green jelly
-R:101:0xA8:0x90
-
-# Lurtz, Uruk Captain of the White Hand
-R:102:0xA8:0x9B
-
-# Munchkin
-R:103:0xA8:0x86
-
-# Disenchanter eye
-R:104:0xA6:0x9D
-
-# Red worm mass
-R:105:0xAD:0x82
-
-# Copperhead snake
-R:106:0xA2:0x8C
-
-# Death sword
-R:107:0xB0:0x87
-
-# Purple mushroom patch
-R:108:0x9D:0x89
-
-# Apprentice priest
-R:109:0xAA:0x8E
-
-# Apprentice warrior
-R:110:0xAA:0x8C
-
-# Petty-dwarf
-R:111:0xB0:0x88
-
-# Petty-dwarf mage
-R:112:0xC0:0xBE
-
-# Brown mold
-R:113:0xA9:0x81
-
-# Giant brown bat
-R:114:0xA5:0x90
-
-# Butterfly
-R:115:0xC4:0xB3
-
-# Apprentice rogue
-R:116:0xAA:0x87
-
-# Creeping silver coins
-R:117:0x9D:0x81
-
-# Snaga
-R:118:0xA9:0x8E
-
-# Rattlesnake
-R:119:0xA2:0x8D
-
-# Giant slug
-R:120:0xB8:0x94
-
-# Giant pink frog
-R:121:0xB8:0x95
-
-# Dark elf
-R:122:0x92:0x94
-
-# Moth
-R:123:0xC4:0xB4
-
-# Crypt creep
-R:124:0xB0:0x8A
-
-# Rotting corpse
-R:125:0xB0:0x8B
-
-# Cave orc
-R:126:0xA9:0x8F
-
-# Wood spider
-R:127:0xA2:0x9E
-
-# Hurog
-R:128:0xA0:0x91
-
-# Bloodshot eye
-R:129:0xA6:0x9E
-
-# Red naga
-R:130:0xA9:0x8A
-
-# Red jelly
-R:131:0xA8:0x91
-
-# Nightingale
-R:132:0xC4:0xAD
-
-# Lost soul
-R:133:0x9F:0x9B
-
-# Night lizard
-R:134:0xA2:0x8F
-
-# Gorcrow
-R:135:0xC4:0xB1
-
-# Skeleton orc
-R:136:0xAC:0x8A
-
-# Grima the Wormtongue, Agent of Saruman
-R:137:0xAA:0x98
-
-# Robin Hood, the Outlaw
-R:138:0xB0:0x8C
-
-# Gull
-R:139:0xC4:0xAE
-
-# Lagduf, the Snaga
-R:140:0xA9:0x90
-
-# Kirinki
-R:141:0xC4:0xAF
-
-# Apprentice ranger
-R:142:0xAA:0x91
-
-# Giant salamander
-R:143:0xA2:0x90
-
-# Space monster
-R:144:0xB0:0x8D
-
-# Swan
-R:145:0xC0:0xBF
-
-# Green mold
-R:146:0xA9:0x82
-
-# Apprentice paladin
-R:147:0xAA:0x92
-
-# Caborrog
-R:148:0xA0:0x92
-
-# Hill orc
-R:149:0xA9:0x91
-
-# Bandit
-R:150:0xAA:0x9B
-
-# Hunting hawk
-R:151:0xB0:0x8E
-
-# Phantom warrior
-R:152:0xB0:0x8F
-
-# Thrush
-R:153:0xC4:0xB0
-
-# Yeti
-R:154:0xA4:0x91
-
-# Fox
-R:155:0xC4:0xAC
-
-# Giant grey rat
-R:156:0xAC:0x87
-
-# Black harpy
-R:157:0xA0:0x89
-
-# Fly of Mordor
-R:158:0xC4:0xB5
-
-# Limlug
-R:159:0xBF:0xA0
-
-# Cave bear
-R:160:0xC4:0x8F
-
-# Rock mole
-R:161:0xBA:0x82
-
-# Mindcrafter
-R:162:0xAA:0x93
-
-# Hatchling blue dragon
-R:163:0xA5:0x9D
-
-# Hatchling white dragon
-R:164:0xA5:0x9E
-
-# Hatchling green dragon
-R:165:0xA5:0x9F
-
-# Hatchling black dragon
-R:166:0xA6:0x80
-
-# Hatchling red dragon
-R:167:0xA6:0x81
-
-# Giant red ant
-R:168:0xA5:0x8D
-
-# Brodda, the Easterling
-R:169:0xAA:0x9C
-
-# Radbug, the Goblin
-R:170:0xBF:0xA1
-
-# King cobra
-R:171:0xA2:0x91
-
-# Eagle
-R:172:0xB4:0x9E
-
-# War bear
-R:173:0xB0:0x91
-
-# Killer bee
-R:174:0xB0:0x92
-
-# Giant spider
-R:175:0xA2:0x9F
-
-# Giant white tick
-R:176:0xA8:0x9D
-
-# The Lucky Hobbit
-R:177:0xBF:0xA2
-
-# Dark elven mage
-R:178:0xA7:0x96
-
-# Dark dwarven warrior
-R:179:0xBF:0xA3
-
-# Dark dwarven smith
-R:180:0xBF:0xA4
-
-# Dark dwarven lord
-R:181:0xBF:0xA5
-
-# Dark dwarven priest
-R:182:0xBF:0xA6
-
-# Dark elven warrior
-R:183:0xBF:0xA6
-
-# Clear mushroom patch
-R:184:0xB8:0x96
-
-# Quiver slot
-R:185:0xB0:0x93
-
-# Grishnakh, the Hill Orc
-R:186:0xA9:0x93
-
-# Giant tan bat
-R:187:0xC4:0x90
-
-# Owlbear
-R:188:0xBA:0x87
-
-# Clear mewlip
-R:189:0xBF:0xA7
-
-# Hairy mold
-R:190:0xA9:0x83
-
-# Grizzly bear
-R:191:0xBA:0x88
-
-# Disenchanter mold
-R:192:0xA9:0x84
-
-# Pseudo-dragon
-R:193:0xA6:0x82
-
-# Limrog
-R:194:0xA0:0x93
-
-# Creeping gold coins
-R:195:0x9D:0x82
-
-# Wolf
-R:196:0x9D:0x9E
-
-# Giant fruit fly
-R:197:0x9F:0x91
-
-# Panther
-R:198:0xA7:0x84
-
-# Brigand
-R:199:0xB0:0x94
-
-# Gray mewlip
-R:200:0xBF:0xA8
-
-# Orange mewlip
-R:201:0xBF:0xA9
-
-# Undead mass
-R:202:0xB0:0x97
-
-# Bloodshot mewlip
-R:203:0xBF:0xAA
-
-# Hatchling multi-hued dragon
-R:204:0xA6:0x83
-
-# Green mewlip
-R:205:0xBF:0xAB
-
-# Old Man Willow
-R:206:0xBA:0x89
-
-# Blue mewlip
-R:207:0xBF:0xAC
-
-# Zombified orc
-R:208:0xAC:0x8C
-
-# Hippogryph
-R:209:0xA0:0x8A
-
-# Black mamba
-R:210:0xA2:0x92
-
-# White wolf
-R:211:0x9D:0x9F
-
-# Grape jelly
-R:212:0xA8:0x92
-
-# Nether worm mass
-R:213:0xAD:0x83
-
-# Brown mewlip
-R:214:0xBF:0xAD
-
-# Golfimbul, the Hill Orc Chief
-R:215:0xA9:0x94
-
-# Swordsman
-R:216:0x97:0x81
-
-# Stone mewlip
-R:217:0xBF:0xAE
-
-# Hatchling bronze dragon
-R:218:0xA6:0x82
-
-# Hatchling gold dragon
-R:219:0xA6:0x82
-
-# Evil eye
-R:220:0xC4:0x91
-
-# Yellow mewlip
-R:221:0xBF:0xAF
-
-# Pink mewlip
-R:222:0xBF:0xB0
-
-# Tree mewlip
-R:223:0xBF:0xB1
-
-# Air mewlip
-R:224:0xBF:0xB2
-
-# Priest
-R:225:0xAA:0x9E
-
-# Dark elven priest
-R:226:0xA7:0x99
-
-# Air spirit
-R:227:0x9E:0x9F
-
-# Skeleton human
-R:228:0xAC:0x8B
-
-# Zombified human
-R:229:0xAD:0x8E
-
-# Tiger
-R:230:0xA7:0x85
-
-# Moaning spirit
-R:231:0x9F:0x9C
-
-# Plague mewlip
-R:232:0xBF:0xB3
-
-# Spotted jelly
-R:233:0xA8:0x93
-
-# Drider
-R:234:0xA3:0x80
-
-# Mongbat
-R:235:0xB0:0x9C
-
-# Killer brown beetle
-R:236:0xA0:0x9B
-
-# Death mewlip
-R:237:0xBF:0xB4
-
-# Ogre
-R:238:0xA1:0x8B
-
-# Creeping mithril coins
-R:239:0x9D:0x83
-
-# Illusionist
-R:240:0xAB:0x80
-
-# Druid
-R:241:0xAB:0x81
-
-# Fuinur, Lord of the Haradrim
-R:242:0xBF:0xB5
-
-# Cloaker
-R:243:0x89:0x88
-
-# Black orc
-R:244:0xA9:0x95
-
-# Ochre jelly
-R:245:0xA8:0x94
-
-# Software bug
-R:246:0xB0:0x9D
-
-# Lurker
-R:247:0x80:0x81
-
-# Tangleweed
-R:248:0xC4:0x92
-
-# Glorfindel of Rivendell
-R:249:0xBF:0xB6
-
-# Giant white dragonfly
-R:250:0x9F:0x93
-
-# Snaga sapper
-R:251:0xB9:0x8C
-
-# Finrod Felagund
-R:252:0xBF:0xB7
-
-# Gibbering mouther
-R:253:0xB0:0x9E
-
-# Maedhros the Tall
-R:254:0xBF:0xB8
-
-# Hill giant
-R:255:0xA1:0x91
-
-# Flesh golem
-R:256:0xA7:0x89
-
-# Warg
-R:257:0x9E:0x80
-
-# Cheerful leprawn
-R:258:0xB1:0x80
-
-# Giant flea
-R:259:0x9F:0x92
-
-# Ufthak of Cirith Ungol
-R:260:0xBA:0x8C
-
-# Clay golem
-R:261:0xB8:0x9D
-
-# Black ogre
-R:262:0xA1:0x8C
-
-# Maglor the Mighty Singer
-R:263:0xBF:0xB9
-
-# Half-orc
-R:264:0xBA:0x8D
-
-# Dark naga
-R:265:0xB8:0x9E
-
-# Poison ivy
-R:266:0xC4:0x93
-
-# Magic mushroom patch
-R:267:0x9D:0x8B
-
-# Celegorm the Fair
-R:268:0xBF:0xBA
-
-# Guardian naga
-R:269:0xA9:0x8B
-
-# Wererat
-R:270:0xBA:0x8E
-
-# Light hound
-R:271:0xA4:0x93
-
-# Dark hound
-R:272:0xA4:0x94
-
-# Flying skull
-R:273:0xB1:0x81
-
-# Caranthir the Dark
-R:274:0xBF:0xBB
-
-# Giant tarantula
-R:275:0xA3:0x81
-
-# Curufin the Crafty
-R:276:0xBF:0xBC
-
-# Mirkwood spider
-R:277:0xA3:0x82
-
-# Frost giant
-R:278:0xA1:0x92
-
-# Griffon
-R:279:0xA0:0x8B
-
-# Aewrog
-R:280:0xA0:0x94
-
-# Gnome mage
-R:281:0xA7:0x98
-
-# Clear hound
-R:282:0xA4:0x95
-
-# Umber hulk
-R:283:0xA3:0x99
-
-# Rust monster
-R:284:0xB9:0x8F
-
-# Ogrillon
-R:285:0xA9:0x98
-
-# Gelatinous cube
-R:286:0xA8:0x95
-
-# Giant green dragonfly
-R:287:0x9F:0x94
-
-# Fire giant
-R:288:0xA1:0x93
-
-# Hummerhorn
-R:289:0xBA:0x8F
-
-# Lizard man
-R:290:0xB9:0x90
-
-# Ulfast, Son of Ulfang
-R:291:0xAB:0x82
-
-# Crebain
-R:292:0xC4:0x94
-
-# Berserker
-R:293:0xA9:0x97
-
-# Draugrog
-R:294:0xA0:0x95
-
-# Sphinx
-R:295:0xB9:0x91
-
-# Narrog
-R:296:0xA0:0x96
-
-# Forest troll
-R:297:0xA3:0x89
-
-# Freezing sphere
-R:298:0xBA:0x91
-
-# Jumping fireball
-R:299:0xB9:0x92
-
-# Ball lightning
-R:300:0xBA:0x92
-
-# 2-headed hydra
-R:301:0xA2:0x93
-
-# Swamp thing
-R:302:0xB9:0x93
-
-# Water spirit
-R:303:0x9F:0x80
-
-# Giant red scorpion
-R:304:0xA3:0x83
-
-# Earth spirit
-R:305:0x9F:0x81
-
-# Fire spirit
-R:306:0x9F:0x82
-
-# Fire hound
-R:307:0xA4:0x96
-
-# Cold hound
-R:308:0xA4:0x97
-
-# Energy hound
-R:309:0xA4:0x98
-
-# Lesser mimic
-R:310:0x9D:0x8E
-
-# Door mimic
-R:311:0x82:0x83
-
-# Blink dog
-R:312:0x9E:0x81
-
-# Uruk
-R:313:0xA9:0x99
-
-# Shagrat, the Orc Captain
-R:314:0xA9:0x9A
-
-# Gorbag, the Orc Captain
-R:315:0xA9:0x9B
-
-# Shambling mound
-R:316:0x9D:0x8C
-
-# Venus Flytrap
-R:317:0xC4:0x95
-
-# Amrod, Son of Feanor
-R:318:0xBF:0xBD
-
-# Amras, Son of Feanor
-R:319:0xBF:0xBD
-
-# Giant bronze dragonfly
-R:320:0x9F:0x98
-
-# Stone giant
-R:321:0xA1:0x94
-
-# Giant black dragonfly
-R:322:0x9F:0x96
-
-# Stone golem
-R:323:0xA7:0x8B
-
-# Red mold
-R:324:0xA9:0x85
-
-# Giant gold dragonfly
-R:325:0x9F:0x97
-
-# Telchar the Smith
-R:326:0xBF:0xBE
-
-# Ghast
-R:327:0xBA:0x95
-
-# Neekerbreeker
-R:328:0xC4:0x96
-
-# Huorn
-R:329:0xBA:0x96
-
-# Bolg, Son of Azog
-R:330:0xA9:0x9C
-
-# Phase spider
-R:331:0xA3:0x84
-
-# Lizard king
-R:332:0xB9:0x97
-
-# Landmine
-R:333:0xBA:0x97
-
-# Roac, son of Carc
-R:334:0xC4:0xB2
-
-# Great eagle
-R:335:0xB9:0x98
-
-# Livingstone
-R:336:0xB1:0x84
-
-# Earth hound
-R:337:0xA4:0x99
-
-# Air hound
-R:338:0xA4:0x9A
-
-# Sabre-tooth tiger
-R:339:0xA7:0x86
-
-# Acid hound
-R:340:0xA4:0x9B
-
-# Chimaera
-R:341:0xA0:0x8C
-
-# Quylthulg
-R:342:0xA1:0x9A
-
-# Sasquatch
-R:343:0xA4:0x92
-
-# Carc of Ravenhill
-R:344:0xC4:0xB2
-
-# Ranger
-R:345:0xAA:0x97
-
-# Paladin
-R:346:0xAB:0x92
-
-# Werewolf
-R:347:0xBA:0x99
-
-# Dark elven lord
-R:348:0xA7:0x9C
-
-# Cloud giant
-R:349:0xA1:0x96
-
-# Ugluk, the Uruk
-R:350:0xA9:0x9D
-
-# Blue dragon bat
-R:351:0xA5:0x91
-
-# Mimic
-R:352:0x83:0x9D
-
-# Ultimate mimic
-R:353:0x84:0x9E
-
-# Fire vortex
-R:354:0xAC:0x94
-
-# Acid vortex
-R:355:0xAC:0x95
-
-# Lugdush, the Uruk
-R:356:0xB9:0x9A
-
-# Alatar, the Blue Wizard
-R:357:0xBF:0xBF
-
-# Cold vortex
-R:358:0xAC:0x96
-
-# Energy vortex
-R:359:0xAC:0x97
-
-# Globefish
-R:360:0xB9:0x9B
-
-# Giant firefly
-R:361:0x9F:0x95
-
-# Mummified orc
-R:362:0xA1:0x88
-
-# Wolf chieftain
-R:363:0xC4:0x97
-
-# Pallando, the Blue Wizard
-R:364:0xBF:0xBF
-
-# Vampiric mist
-R:365:0xB9:0x9D
-
-# Killer stag beetle
-R:366:0xA0:0x9D
-
-# Iron golem
-R:367:0xA7:0x8C
-
-# Auto-roller
-R:368:0xB1:0x86
-
-# Giant yellow scorpion
-R:369:0xA3:0x85
-
-# Muzgash, the Snaga
-R:370:0xBE:0xA0
-
-# Black ooze
-R:371:0xA8:0x96
-
-# Hardened warrior
-R:372:0xAB:0x83
-
-# Azog, King of the Uruk-Hai
-R:373:0xA9:0x9F
-
-# Bill Ferny
-R:374:0xBE:0xA1
-
-# Dark elven warlock
-R:375:0xB1:0x87
-
-# Master rogue
-R:376:0xAB:0x84
-
-# Red dragon bat
-R:377:0xA5:0x92
-
-# Killer white beetle
-R:378:0xBA:0x9E
-
-# Ice skeleton
-R:379:0xB9:0x9F
-
-# Angamaite of Umbar
-R:380:0xBB:0x80
-
-# Forest wight
-R:381:0xB1:0x88
-
-# Khim, Son of Mim
-R:382:0xB1:0x89
-
-# Ibun, Son of Mim
-R:383:0xB1:0x8A
-
-# Meneldor the Swift
-R:384:0xBB:0x81
-
-# Phantom beast
-R:385:0xB1:0x8B
-
-# Giant silver ant
-R:386:0xA0:0x9C
-
-# 4-headed hydra
-R:387:0xA2:0x95
-
-# Beruthiel, Queen of Cats
-R:388:0xBE:0xA2
-
-# The Hunter
-R:389:0xB1:0x8C
-
-# Mummified human
-R:390:0xA1:0x89
-
-# Vampire bat
-R:391:0xA5:0x93
-
-# Sangahyando of Umbar
-R:392:0xAB:0x85
-
-# It
-R:393:0xB1:0x8D
-
-# Banshee
-R:394:0x9F:0x9D
-
-# Herumor, Lord of the Haradrim
-R:395:0xBE:0xA3
-
-# Fimbrethil
-R:396:0xBB:0x84
-
-# Silent watcher
-R:397:0xB1:0x8E
-
-# Pukelman
-R:398:0xA7:0x8D
-
-# Mauhur, the Uruk
-R:399:0xBE:0xA4
-
-# Dark elven druid
-R:400:0xA7:0x9F
-
-# Stone troll
-R:401:0xA3:0x8A
-
-# Prince Imrahil the Proud
-R:402:0xBE:0xA5
-
-# Hill troll
-R:403:0xA3:0x8B
-
-# Wereworm
-R:404:0xAD:0x84
-
-# Killer red beetle
-R:405:0xA0:0x9F
-
-# Disenchanter bat
-R:406:0xC4:0x98
-
-# Umuiyan, Doorkeeper of Tevildo
-R:407:0xBE:0xA6
-
-# Giant grey ant
-R:408:0xA5:0x8C
-
-# Oikeroi, Bodyguard of Tevildo
-R:409:0xBE:0xA7
-
-# Gwaihir the Windlord
-R:410:0xBB:0x81
-
-# Giant fire tick
-R:411:0xBB:0x87
-
-# Lotho Sackville-Baggins, Betrayer of the Shire
-R:412:0xBE:0xA8
-
-# Ulwarth, Son of Ulfang
-R:413:0xAA:0x99
-
-# Werebear
-R:414:0xC4:0x8F
-
-# Cave ogre
-R:415:0xA1:0x8D
-
-# White wraith
-R:416:0xA3:0x9F
-
-# Thranduil, King of the Wood Elves
-R:417:0xBE:0xA9
-
-# Ghoul
-R:418:0xB4:0x8F
-
-# Mim, Betrayer of Turin
-R:419:0xB1:0x90
-
-# Hellblade
-R:420:0xB1:0x91
-
-# Killer fire beetle
-R:421:0xA1:0x80
-
-# Denethor, Steward of Gondor
-R:422:0xBE:0xAA
-
-# Creeping adamantite coins
-R:423:0x9D:0x84
-
-# Algroth
-R:424:0xA3:0x8C
-
-# Boromir, Son of Denethor
-R:425:0xBE:0xAB
-
-# Roper
-R:426:0xB9:0x80
-
-# Headless
-R:427:0xB1:0x92
-
-# Vibration hound
-R:428:0xA4:0x9C
-
-# Nexus hound
-R:429:0xA4:0x9D
-
-# Half-ogre
-R:430:0xA1:0x8E
-
-# Lokkak, the Ogre Chieftain
-R:431:0xA1:0x90
-
-# Vampire
-R:432:0xA3:0x9A
-
-# Gorgimaera
-R:433:0xA0:0x8D
-
-# Faramir, Son of Denethor
-R:434:0xBE:0xAC
-
-# Colbran
-R:435:0xA7:0x8E
-
-# Spirit naga
-R:436:0xA9:0x8C
-
-# Harry Goatleaf, Gatekeeper of Bree
-R:437:0xBE:0xAD
-
-# The Watcher of Cirith Ungol
-R:438:0xB1:0x8E
-
-# Stairway to Hell
-R:439:0xB1:0x94
-
-# 5-headed hydra
-R:440:0xA2:0x96
-
-# Tom Bombadil
-R:441:0xBE:0xAE
-
-# Wainrider
-R:442:0xAB:0x88
-
-# Seahorse
-R:443:0xBB:0x89
-
-# Cyclops
-R:444:0xBB:0x8A
-
-# Clairvoyant
-R:445:0xAB:0x86
-
-# Purple worm
-R:446:0xB9:0x82
-
-# Catoblepas
-R:447:0xAC:0x81
-
-# Lesser wall monster
-R:448:0xB1:0x96
-
-# Mage
-R:449:0xAB:0x8A
-
-# Mind flayer
-R:450:0xAB:0x8B
-
-# The Ultimate Dungeon Cleaner
-R:451:0xB1:0x97
-
-# The Mewlip Queen
-R:452:0xBE:0xAF
-
-# Basilisk
-R:453:0xA2:0x97
-
-# Snow-troll
-R:454:0xA3:0x8D
-
-# Fluithuin the Ogress, Consort of Morgoth
-R:455:0xBE:0xB0
-
-# Ulbandi the Ogress, Consort of Morgoth
-R:456:0xBE:0xB1
-
-# Naugladur, Lord of Nogrod
-R:457:0xBE:0xB2
-
-# Greater mimic
-R:458:0xB1:0x9A
-
-# Young blue dragon
-R:459:0xA6:0x84
-
-# Young white dragon
-R:460:0xA6:0x85
-
-# Young green dragon
-R:461:0xA6:0x86
-
-# Young bronze dragon
-R:462:0xA6:0x87
-
-# Androg the Outlaw
-R:463:0xBE:0xB3
-
-# Mithril golem
-R:464:0xA7:0x8F
-
-# Skeleton troll
-R:465:0xAC:0x8D
-
-# Amlach, son of Imlach
-R:466:0xBE:0xB4
-
-# Beorn, the Shape-Changer
-R:467:0xC4:0x99
-
-# Thorondor, Lord of Eagles
-R:468:0xBB:0x81
-
-# Giant blue ant
-R:469:0xA5:0x8B
-
-# Grave wight
-R:470:0xAD:0x9C
-
-# Shadow drake
-R:471:0xA6:0x88
-
-# Manticore
-R:472:0xA0:0x8E
-
-# Giant army ant
-R:473:0xAE:0x81
-
-# Killer slicer beetle
-R:474:0xA1:0x81
-
-# Gorgon
-R:475:0xBB:0x8D
-
-# Radagast the Brown
-R:476:0xBE:0xB5
-
-# Ghost
-R:477:0x9F:0x9E
-
-# Death watch beetle
-R:478:0xA1:0x82
-
-# Mountain ogre
-R:479:0xA1:0x8F
-
-# Nexus quylthulg
-R:480:0xA1:0x9B
-
-# Shelob, Spider of Darkness
-R:481:0xA3:0x86
-
-# Giant squid
-R:482:0xB9:0x83
-
-# Ghoulking
-R:483:0xAD:0x8C
-
-# Doombat
-R:484:0xB9:0x84
-
-# Easterling
-R:485:0xAB:0x8C
-
-# Memory moss
-R:486:0xA9:0x86
-
-# Storm giant
-R:487:0xA1:0x95
-
-# Spectator
-R:488:0xB1:0x9B
-
-# Bjorn the Warper
-R:489:0xC4:0x99
-
-# Vaire, the Weaver
-R:490:0xBE:0xB6
-
-# Half-troll
-R:491:0xA9:0x9E
-
-# Irmo of Lorien
-R:492:0xBE:0xB7
-
-# Bert the Stone Troll
-R:493:0xA3:0x90
-
-# Bill the Stone Troll
-R:494:0xA3:0x91
-
-# Tom the Stone Troll
-R:495:0xA3:0x92
-
-# Cave troll
-R:496:0xA3:0x8E
-
-# Este, the Gentle
-R:497:0xBE:0xB8
-
-# Barrow wight
-R:499:0xA4:0x81
-
-# Skeleton ettin
-R:500:0xC4:0x9A
-
-# Chaos drake
-R:501:0xA6:0x89
-
-# Law drake
-R:502:0xA6:0x8A
-
-# Balance drake
-R:503:0xA6:0x8B
-
-# Ethereal drake
-R:504:0xA6:0x8C
-
-# Groo, the Wanderer
-R:505:0xB1:0x9E
-
-# Nessa the Lithe
-R:506:0xBE:0xB9
-
-# Shade
-R:507:0xA4:0x89
-
-# Spectre
-R:508:0xA0:0x80
-
-# Water troll
-R:509:0xA3:0x93
-
-# Fire elemental
-R:510:0x9F:0x83
-
-# Water elemental
-R:512:0x9F:0x84
-
-# Multi-hued hound
-R:513:0xB2:0x81
-
-# Invisible stalker
-R:514:0x9F:0x85
-
-# Vana, the Ever-young
-R:515:0xBE:0xBA
-
-# Master thief
-R:516:0xAB:0x8E
-
-# The Watcher in the Water
-R:517:0xAF:0x95
-
-# Lich
-R:518:0xA1:0x83
-
-# Gas spore
-R:519:0xB2:0x8E
-
-# Master vampire
-R:520:0xA3:0x9B
-
-# Oriental vampire
-R:521:0xB2:0x83
-
-# Greater mummy
-R:522:0xA1:0x8A
-
-# Ingeborg, the Runemistress
-R:523:0xBE:0xBB
-
-# Giant grey scorpion
-R:524:0xA3:0x87
-
-# Earth elemental
-R:525:0x9F:0x86
-
-# Air elemental
-R:526:0x9F:0x87
-
-# Shimmering mold
-R:527:0xAF:0x81
-
-# Sarnrog
-R:528:0xBB:0x91
-
-# Malicious leprawn
-R:529:0xB2:0x85
-
-# Eog golem
-R:530:0xA7:0x90
-
-# Lindal Lossehelin
-R:531:0xBE:0xBC
-
-# Variag
-R:532:0x04:0x70
-
-# Headless ghost
-R:533:0xBB:0x92
-
-# Dread
-R:534:0xB9:0x87
-
-# Zizzo, Last of the Yeeks
-R:535:0xC3:0xAF
-
-# Gauth
-R:536:0xC4:0x9B
-
-# Smoke elemental
-R:537:0x9F:0x90
-
-# Olog
-R:538:0xA3:0x94
-
-# Halfling slinger
-R:539:0xB2:0x86
-
-# Gravity hound
-R:540:0xA4:0x9E
-
-# Acidic cytoplasm
-R:541:0xA8:0x97
-
-# Inertia hound
-R:542:0xA4:0x9F
-
-# Impact hound
-R:543:0xA5:0x80
-
-# Shardstorm
-R:544:0xC4:0x9C
-
-# Ooze elemental
-R:545:0x9F:0x88
-
-# Young black dragon
-R:546:0xA6:0x8D
-
-# Mumak
-R:547:0xAC:0x84
-
-# Giant fire ant
-R:548:0xA5:0x8A
-
-# Cold-drake
-R:549:0xA6:0x8E
-
-# Xorn
-R:550:0xA4:0x8F
-
-# Rogrog the Black Troll
-R:551:0xA3:0x8F
-
-# Erianyth, the Sorceress
-R:552:0xA7:0x91
-
-# Phantom
-R:553:0xB2:0x87
-
-# Grey wraith
-R:554:0xA4:0x82
-
-# Revenant
-R:555:0xA4:0x88
-
-# Young multi-hued dragon
-R:556:0xA6:0x8F
-
-# Karrazix the Brave
-R:557:0x9E:0x89
-
-# Colossus
-R:558:0xB2:0x89
-
-# Young gold dragon
-R:559:0xA6:0x90
-
-# Blue drake
-R:560:0xA6:0x91
-
-# Green drake
-R:561:0xA6:0x92
-
-# Bronze drake
-R:562:0xA6:0x93
-
-# Young red dragon
-R:563:0xA6:0x94
-
-# Sir Physt
-R:564:0x0B:0x56
-
-# Trapper
-R:565:0xAD:0x9F
-
-# Adanrog
-R:566:0xA0:0x98
-
-# Time bomb
-R:567:0xBB:0x96
-
-# Rawrog
-R:568:0xAD:0x90
-
-# Nick LeYeek, Second Last of the Yeeks
-R:569:0xC3:0xB0
-
-# Ice elemental
-R:570:0x9F:0x8A
-
-# Necromancer
-R:571:0xB2:0x8C
-
-# Slappy, Abbess of Pain
-R:572:0xBE:0xBD
-
-# Lorgan, Chief of the Easterlings
-R:573:0xB2:0x8D
-
-# Snow tiger
-R:574:0xC2:0xB0
-
-# Mummified troll
-R:575:0xBB:0x97
-
-# Storm of Unmagic
-R:576:0xC4:0x9D
-
-# Crypt thing
-R:577:0xA4:0x80
-
-# Chaos butterfly
-R:578:0xBB:0x98
-
-# Time elemental
-R:579:0xB2:0x8F
-
-# Blue yeek
-R:580:0xAD:0x87
-
-# The Queen Ant
-R:581:0xA5:0x8E
-
-# Will o' the wisp
-R:582:0x9F:0x8B
-
-# Brown yeek
-R:583:0xAD:0x88
-
-# Magma elemental
-R:584:0x9F:0x8C
-
-# Black pudding
-R:585:0xA8:0x98
-
-# Killer iridescent beetle
-R:586:0xB4:0x90
-
-# Nexus vortex
-R:587:0xAE:0x80
-
-# Plasma vortex
-R:588:0xAC:0x98
-
-# Fire-drake
-R:589:0xA6:0x95
-
-# Golden drake
-R:590:0xA6:0x96
-
-# Crystal drake
-R:591:0xA6:0x97
-
-# Black drake
-R:592:0xA6:0x98
-
-# Multi-hued drake
-R:593:0xA6:0x99
-
-# Master yeek
-R:594:0xAD:0x8A
-
-# Orfax, son of Boldor
-R:595:0xAD:0x89
-
-# Boldor, King of the Yeeks
-R:596:0xAD:0x8B
-
-# Black Numenorean
-R:597:0xAB:0x94
-
-# Castamir the Usurper
-R:598:0xB2:0x90
-
-# Time vortex
-R:599:0xAC:0x99
-
-# Shimmering vortex
-R:600:0xAC:0x9A
-
-# Ancient blue dragon
-R:601:0x9E:0x88
-
-# Ancient bronze dragon
-R:602:0x9E:0x89
-
-# Beholder
-R:603:0xA6:0x9F
-
-# Emperor wight
-R:604:0xA4:0x83
-
-# Giant tree ant
-R:605:0xC4:0xB7
-
-# Vargo, Tyrant of Fire
-R:606:0x9F:0x8D
-
-# Black wraith
-R:607:0xA4:0x84
-
-# Giant yellow ant
-R:608:0xC4:0xB8
-
-# Giant green ant
-R:609:0xC4:0xB9
-
-# Aquatic ant
-R:610:0xC4:0xBA
-
-# Monastic lich
-R:611:0xA1:0x87
-
-# Nether wraith
-R:612:0xA4:0x85
-
-# Hellhound
-R:613:0xAD:0x96
-
-# 7-headed hydra
-R:614:0xA2:0x99
-
-# Waldern, King of Water
-R:615:0x9F:0x8E
-
-# Termite
-R:616:0xC4:0xB6
-
-# Ancient white dragon
-R:617:0x9E:0x8A
-
-# Ancient green dragon
-R:618:0x9E:0x8B
-
-# Giant snow bat
-R:619:0xC4:0xBB
-
-# Eldrak
-R:620:0xA3:0x97
-
-# Ettin
-R:621:0xA3:0x96
-
-# Night mare
-R:622:0xAC:0x83
-
-# Vampire lord
-R:623:0xA3:0x9C
-
-# Ancient black dragon
-R:624:0x9E:0x8C
-
-# Weird fume
-R:625:0xAF:0x80
-
-# Giant grey bat
-R:626:0xC4:0xBC
-
-# Giant silver bat
-R:627:0xC4:0xBD
-
-# Giant yellow bat
-R:628:0xC4:0xBE
-
-# Shadowfax, steed of Gandalf
-R:629:0xBB:0x9E
-
-# Spirit troll
-R:630:0xA3:0x98
-
-# War troll
-R:631:0xB2:0x94
-
-# Disenchanter worm mass
-R:632:0xAD:0x86
-
-# Rotting quylthulg
-R:633:0xA1:0x9C
-
-# Lesser titan
-R:634:0xA1:0x97
-
-# 9-headed hydra
-R:635:0xA2:0x99
-
-# Enchantress
-R:636:0xAB:0x96
-
-# Ranger chieftain
-R:637:0xAB:0x97
-
-# Sorcerer
-R:638:0xAB:0x98
-
-# Xaren
-R:639:0xA4:0x90
-
-# Giant green bat
-R:640:0xC4:0xBF
-
-# Death vortex
-R:641:0xC3:0xA5
-
-# Gas vortex
-R:642:0xC3:0xA6
-
-# Death drake
-R:643:0x9E:0x8D
-
-# Ancient red dragon
-R:644:0x9E:0x8E
-
-# Ancient gold dragon
-R:645:0x9E:0x8F
-
-# Great crystal drake
-R:646:0x9E:0x90
-
-# Mana vortex
-R:647:0xC3:0xA7
-
-# Helcungol
-R:648:0xB2:0x95
-
-# Lygrog
-R:649:0xA0:0x99
-
-# Slow vortex
-R:650:0xC3:0xA8
-
-# Nether vortex
-R:651:0xC3:0xA9
-
-# Puzzling vortex
-R:652:0xC3:0xAA
-
-# Dark yeek
-R:653:0xC3:0xAB
-
-# Judge Fire
-R:654:0xAB:0x93
-
-# White yeek
-R:655:0xC3:0xAC
-
-# Judge Mortis
-R:656:0xBC:0x82
-
-# Dark elven sorcerer
-R:657:0xA8:0x81
-
-# Master lich
-R:658:0xA1:0x84
-
-# Gray yeek
-R:659:0xC3:0xAD
-
-# Eol, the Dark Elf
-R:660:0xB2:0x99
-
-# Yellow yeek
-R:661:0xC3:0xAE
-
-# Adventurer yeek
-R:662:0xAD:0x88
-
-# Dark mushroom patch
-R:663:0xC3:0xA1
-
-# Undead beholder
-R:664:0xA7:0x80
-
-# Shadow
-R:665:0xA0:0x81
-
-# Iron lich
-R:666:0xB2:0x9C
-
-# Dread
-R:667:0xB9:0x87
-
-# Greater basilisk
-R:668:0xBC:0x83
-
-# White mushroom patch
-R:669:0xC3:0xA0
-
-# Brown mushroom patch
-R:670:0xC3:0xA2
-
-# Silver mushroom patch
-R:671:0xC3:0xA3
-
-# Green mushroom patch
-R:672:0xC3:0xA4
-
-# Mumak
-R:673:0xAC:0x82
-
-# Judge Fear
-R:674:0xA7:0x88
-
-# Ancient multi-hued dragon
-R:675:0x9E:0x91
-
-# Ethereal dragon
-R:676:0x9E:0x92
-
-# Dark elemental
-R:677:0xC3:0xB1
-
-# Slow elemental
-R:678:0xC3:0xB2
-
-# Quaker, Master of Earth
-R:679:0x9F:0x8F
-
-# Death leprawn
-R:680:0xA7:0x9E
-
-# Chaos elemental
-R:681:0xC3:0xB4
-
-# Confusion elemental
-R:682:0xC3:0xB3
-
-# Large blue snake
-R:683:0xC2:0xA8
-
-# Large silver snake
-R:684:0xC2:0xA9
-
-# Large purple snake
-R:685:0xC2:0xAA
-
-# Judge Death
-R:686:0xBC:0x99
-
-# Ariel, Queen of Air
-R:687:0x9F:0x91
-
-# 11-headed hydra
-R:688:0xA2:0x9A
-
-# Patriarch
-R:689:0xAB:0x9A
-
-# Dreadmaster
-R:690:0xA0:0x85
-
-# Drolem
-R:691:0xA7:0x92
-
-# Scatha the Worm
-R:692:0xAD:0x9B
-
-# Warrior of the Dawn
-R:693:0xB2:0x9E
-
-# Lesser black reaver
-R:694:0xA4:0x87
-
-# Large red snake
-R:695:0xC2:0xAB
-
-# Grand master thief
-R:696:0xC2:0x8A
-
-# Smaug the Golden
-R:697:0x9E:0x93
-
-# The Stormbringer
-R:698:0xB3:0x80
-
-# Knight Templar
-R:699:0xB3:0x81
-
-# Large eel
-R:700:0xC2:0xAC
-
-# Dracolich
-R:701:0x9E:0x95
-
-# Greater titan
-R:702:0xA1:0x98
-
-# Dracolisk
-R:703:0x9E:0x94
-
-# Winged Horror
-R:704:0xC4:0x9E
-
-# Killer gray beetle
-R:705:0xC2:0xA1
-
-# Killer orange beetle
-R:706:0xC2:0xA2
-
-# Killer blue beetle
-R:707:0xC2:0xA3
-
-# Ent
-R:708:0xBC:0x86
-
-# Rock giant
-R:709:0xBC:0x9D
-
-# Itangast the Fire Drake
-R:710:0x9E:0x96
-
-# Death mold
-R:711:0xA9:0x87
-
-# Killer silver beetle
-R:712:0xC2:0xA4
-
-# Killer green beetle
-R:713:0xC2:0xA5
-
-# Quickbeam, the Ent
-R:714:0xBC:0x9F
-
-# Glaurung, Father of the Dragons
-R:715:0xAD:0x9A
-
-# Behemoth
-R:716:0xBD:0x80
-
-# Killer aquatic beetle
-R:717:0xC2:0xA6
-
-# Greater wall monster
-R:718:0xB3:0x84
-
-# Menelrog
-R:719:0xAD:0x91
-
-# Mornungol
-R:720:0xAD:0x95
-
-# Killer tree beetle
-R:721:0xC2:0xA7
-
-# Nightwing
-R:722:0xAD:0x9D
-
-# 6-headed hydra
-R:723:0xC3:0xB9
-
-# Nether hound
-R:724:0xA5:0x81
-
-# Time hound
-R:725:0xA5:0x82
-
-# Plasma hound
-R:726:0xA5:0x83
-
-# Demonic quylthulg
-R:727:0xA1:0x9D
-
-# Great Storm Worm
-R:728:0x9E:0x97
-
-# Ulik the Troll
-R:729:0xBD:0x81
-
-# 8-headed hydra
-R:730:0xC3:0xBA
-
-# Oathbreaker
-R:731:0xBD:0x82
-
-# 10-headed hydra
-R:732:0xC3:0xBB
-
-# 12-headed hydra
-R:733:0xC3:0xBC
-
-# 13-headed hydra
-R:734:0xC3:0xBD
-
-# 14-headed hydra
-R:735:0xC3:0xBE
-
-# 15-headed hydra
-R:736:0xC3:0xBF
-
-# Killer hydra
-R:737:0xC2:0xA0
-
-# Old Sorcerer
-R:738:0x9C:0x8A
-
-# Ethereal hound
-R:739:0xB3:0x8A
-
-# Lesser kraken
-R:740:0xBD:0x83
-
-# Great Ice Worm
-R:741:0x9E:0x98
-
-# Demilich
-R:742:0xA4:0x8A
-
-# The Phoenix
-R:743:0x9D:0x98
-
-# Nightcrawler
-R:744:0xA4:0x8C
-
-# Forest ogre
-R:745:0xC3:0xB8
-
-# Rebel ogre
-R:746:0xA1:0x8B
-
-# Rebel giant
-R:747:0xA1:0x91
-
-# Hand druj
-R:748:0xAC:0x8E
-
-# Eye druj
-R:749:0xAC:0x8F
-
-# Skull druj
-R:750:0xAC:0x90
-
-# Chaos vortex
-R:751:0xAC:0x9B
-
-# Aether vortex
-R:752:0xAC:0x9C
-
-# Spider quylthulg
-R:753:0xC3:0xB5
-
-# Canine quylthulg
-R:754:0xC3:0xB6
-
-# Thuringwethil, the Vampire Messenger
-R:755:0xA3:0x9D
-
-# Great Worm of Fire
-R:756:0x9E:0x99
-
-# Aquatic quylthulg
-R:757:0xC3:0xB7
-
-# Adventurer quylthulg
-R:758:0xA1:0x9A
-
-# Draconic quylthulg
-R:759:0xA1:0x9E
-
-# White hulk
-R:760:0xC4:0xA0
-
-# Death hulk
-R:761:0xC4:0xA1
-
-# Fundin Bluecloak
-R:762:0xBE:0x91
-
-# Black Balrog
-R:763:0xC0:0xA9
-
-# Orange hulk
-R:764:0xC4:0xA2
-
-# Fire hulk
-R:765:0xC4:0xA3
-
-# Ancalagon the Black
-R:766:0x9E:0x9A
-
-# Forest hulk
-R:767:0xC4:0xA4
-
-# Nightwalker
-R:768:0xBD:0x85
-
-# Night hulk
-R:769:0xC4:0xA5
-
-# Silver hulk
-R:770:0xC4:0xA6
-
-# Saruman of Many Colours
-R:771:0xAB:0x9E
-
-# Harowen the Black Hand
-R:772:0xBE:0x94
-
-# Blue Balrog
-R:773:0xC0:0xAB
-
-# Dreadlord
-R:774:0xA0:0x86
-
-# Greater kraken
-R:775:0xBD:0x86
-
-# Archlich
-R:776:0xA4:0x8D
-
-# Tevildo, Prince of Cats
-R:777:0xB3:0x8F
-
-# Jabberwock
-R:778:0xC5:0x82
-
-# Chaos hound
-R:779:0xA5:0x85
-
-# Chaos hulk
-R:780:0xC4:0xA7
-
-# Beholder hive-mother
-R:781:0xBE:0x96
-
-# Leviathan
-R:782:0xBD:0x87
-
-# Great Worm of Chaos
-R:783:0x9E:0x9B
-
-# Great Worm of Law
-R:784:0x9E:0x9C
-
-# Great Worm of Balance
-R:785:0x9E:0x9D
-
-# Yellow hulk
-R:786:0xC4:0xA8
-
-# White Balrog
-R:787:0xC0:0xAA
-
-# Red hulk
-R:788:0xC4:0xA9
-
-# Trone, the Rebel Thunderlord
-R:789:0x08:0x42
-
-# Great Worm of Many Colours
-R:790:0xB3:0x93
-
-# Marda, rider of gold Laronth
-R:791:0xB3:0x94
-
-# Tselakus, the Dreadlord
-R:792:0xA0:0x87
-
-# Sky Drake
-R:793:0xB3:0x95
-
-# Eilinel the Entrapped
-R:794:0xA0:0x83
-
-# Dagorrog
-R:795:0xC5:0x84
-
-# Green hulk
-R:796:0xC4:0xAA
-
-# Blue hulk
-R:797:0xC4:0xAB
-
-# Black reaver
-R:798:0xA1:0x85
-
-# Master mindcrafter
-R:799:0xAB:0x9F
-
-# Greater demonic quylthulg
-R:800:0xA1:0x9F
-
-# Greater draconic quylthulg
-R:801:0xA2:0x80
-
-# Greater rotting quylthulg
-R:802:0xA2:0x81
-
-# Invisible Horror
-R:803:0xBC:0x88
-
-# Feagwath, the Undead Sorcerer
-R:804:0xA1:0x86
-
-# Silver wraith
-R:805:0xA3:0x9F
-
-# Adventurer wraith
-R:806:0xA4:0x81
-
-# Balrog Captain
-R:807:0xC0:0xAC
-
-# Ungoliant, the Unlight
-R:808:0xA3:0x88
-
-# Vampire orc
-R:809:0xC0:0xA0
-
-# Vampire yeek
-R:810:0xC0:0xA1
-
-# Aether hound
-R:811:0xA5:0x86
-
-# Greater Balrog
-R:812:0xC0:0xAD
-
-# Vampire ogre
-R:813:0xC0:0xA2
-
-# Vampire troll
-R:814:0xC0:0xA3
-
-# Vampire dwarf
-R:815:0xC0:0xA4
-
-# Vampire elf
-R:816:0xC0:0xA5
-
-# Vampire gnome
-R:817:0xC0:0xA6
-
-# The Mouth of Sauron
-R:818:0xBE:0x9E
-
-# The Necromancer of Dol Guldur
-R:819:0xB3:0x9E
-
-# Lisa, rider of gold Romth
-R:820:0xB3:0x9F
-
-# Master quylthulg
-R:821:0xA2:0x82
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0xA2:0x83
-
-# Vampire adventurer
-R:823:0xA3:0x9A
-
-# Flare, rider of bronze Moonth
-R:824:0xB4:0x80
-
-# Maeglin, the Traitor of Gondolin
-R:825:0xA4:0x8E
-
-# Snow-frog
-R:826:0xC1:0xBE
-
-# Swamp lizard
-R:827:0xC1:0xBD
-
-# Giant silver frog
-R:828:0xC1:0xBE
-
-# Greater Hellhound
-R:829:0x9E:0x83
-
-# Cantoras, the Skeletal Lord
-R:830:0xAC:0x91
-
-# Blue lizard
-R:831:0xC1:0xBF
-
-# Death dragonfly
-R:832:0xC1:0xB3
-
-# Giant swamp dragonfly
-R:833:0xC1:0xB4
-
-# Giant red dragonfly
-R:834:0xC1:0xB5
-
-# Giant forest dragonfly
-R:835:0xC1:0xB6
-
-# Giant blue dragonfly
-R:836:0xC1:0xB7
-
-# Giant brown dragonfly
-R:837:0xC1:0xB8
-
-# The Tarrasque
-R:838:0xBC:0x93
-
-# Lungorthin, the Balrog of White Fire
-R:839:0xBF:0x86
-
-# Draugluin, Sire of All Werewolves
-R:840:0xBF:0x87
-
-# Giant silver dragonfly
-R:841:0xC1:0xB9
-
-# Giant violet dragonfly
-R:842:0xC1:0xBA
-
-# Giant pink dragonfly
-R:843:0xC1:0xBB
-
-# Vecna, the Emperor Lich
-R:844:0xB4:0x85
-
-# Aquatic dragonfly
-R:845:0xC1:0xBC
-
-# Giant red mouse
-R:846:0xC1:0xB0
-
-# Great Wyrm of Power
-R:847:0xB4:0x87
-
-# Giant blue mouse
-R:848:0xC1:0xB1
-
-# Giant yellow mouse
-R:849:0xC1:0xB2
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x9E:0x86
-
-# Giant pink rat
-R:851:0xC1:0xAE
-
-# Giant tree rat
-R:852:0xC1:0xAF
-
-# Huan, Wolfhound of the Valar
-R:853:0x9E:0x87
-
-# Polar bear
-R:854:0xC1:0xA8
-
-# Blue bear
-R:855:0xC1:0xA9
-
-# Gothmog, the High Captain of Balrogs
-R:856:0xAD:0x98
-
-# Old bear
-R:857:0xC1:0xAA
-
-# Sarko, rider of gold Foronth
-R:858:0xB4:0x8C
-
-# Teddy bear
-R:859:0xC1:0xAB
-
-# Sauron, the Sorcerer
-R:860:0xAC:0x80
-
-# DarkGod, the Mighty Coder of Hell
-R:861:0xC0:0x9D
-
-# Morgoth, Lord of Darkness
-R:862:0xB4:0x8E
-
-# Human Warrior
-R:863:0xB5:0x80
-
-# Elven archer
-R:864:0xB5:0x81
-
-# Dwarven warrior
-R:865:0xB5:0x82
-
-# Elite uruk
-R:866:0xB5:0x83
-
-# Fire bear
-R:867:0xC1:0xAC
-
-# The Variant Maintainer
-R:868:0xBC:0x8B
-
-# Random Number Generator
-R:869:0xBC:0x8A
-
-# Rocket mine
-R:870:0xBD:0x88
-
-# Bouncing mine
-R:871:0xBD:0x89
-
-# Durin's Bane
-R:872:0xBF:0x89
-
-# Aquatic bear
-R:873:0xC1:0xAD
-
-# Rot jelly
-R:874:0xBD:0x8A
-
-# Death
-R:875:0xBD:0x8B
-
-# Famine
-R:876:0xBD:0x8D
-
-# Pestilence
-R:877:0xBD:0x8C
-
-# War
-R:878:0xBD:0x8E
-
-# Pike
-R:879:0xBD:0x8F
-
-# Electric eel
-R:880:0xBD:0x90
-
-# Giant crayfish
-R:881:0xBD:0x91
-
-# Mermaid
-R:882:0xBD:0x92
-
-# Box jellyfish
-R:883:0xBA:0x81
-
-# Giant piranha
-R:884:0xB6:0x9D
-
-# Piranha
-R:885:0xB6:0x9D
-
-# Swamp naga
-R:886:0xC1:0xA2
-
-# Ocean naga
-R:887:0xC1:0xA3
-
-# Snail
-R:888:0xBE:0xBE
-
-# Whale
-R:889:0xBA:0x98
-
-# Sand mite
-R:890:0xBD:0x98
-
-# Octopus
-R:891:0xBD:0x99
-
-# Giant octopus
-R:892:0xBD:0x9A
-
-# Eye of the deep
-R:893:0xBD:0x9B
-
-# Murk dweller
-R:894:0xBF:0x8B
-
-# Drowned soul
-R:895:0xBF:0x8C
-
-# Tiger shark
-R:896:0xBF:0x8D
-
-# Hammerhead shark
-R:897:0xBA:0x90
-
-# Great white shark
-R:898:0xBB:0x82
-
-# Aquatic golem
-R:899:0xBF:0x8E
-
-# Brown naga
-R:900:0xC1:0xA4
-
-# White shark
-R:901:0xBB:0x82
-
-# Scrag
-R:902:0xBF:0x91
-
-# Jaws
-R:903:0xBB:0x8C
-
-# Silver naga
-R:904:0xC1:0xA5
-
-# Aquatic elven warrior
-R:905:0xBF:0x94
-
-# Aquatic elven mage
-R:906:0xBF:0x95
-
-# Stargazer
-R:907:0xBF:0x96
-
-# Elder stargazer
-R:908:0xBF:0x97
-
-# Flounder
-R:909:0xBF:0x98
-
-# Giant turtle
-R:910:0xBF:0x99
-
-# Hatchling dragon turtle
-R:911:0xBF:0x9A
-
-# Young dragon turtle
-R:912:0xBF:0x9B
-
-# Mature dragon turtle
-R:913:0xBF:0x9C
-
-# Ancient dragon turtle
-R:914:0xBF:0x9D
-
-# Fastitocalon
-R:915:0xBF:0x9E
-
-# Undead stargazer
-R:916:0xBF:0x9F
-
-# Killer whale
-R:917:0xB9:0x9C
-
-# Merrow
-R:918:0xC5:0x85
-
-# Water naga
-R:919:0xC0:0x81
-
-# Night naga
-R:920:0xC1:0xA6
-
-# Tree naga
-R:921:0xC1:0xA7
-
-# Moby Dick, the White Whale
-R:922:0xC0:0x80
-
-# Aquatic hound
-R:923:0xC0:0x85
-
-# Gaurrog
-R:924:0xC0:0x86
-
-# Adventurer naga
-R:925:0xA9:0x88
-
-# White mold
-R:926:0xC2:0xBD
-
-# Silver mold
-R:927:0xC2:0xBE
-
-# Mathilde
-R:928:0xBD:0x9C
-
-# Child spirit
-R:929:0xBD:0x9D
-
-# Young spirit
-R:930:0xBD:0x9E
-
-# Mature spirit
-R:931:0xBD:0x9F
-
-# Experienced spirit
-R:932:0xBE:0x80
-
-# Wise spirit
-R:933:0xBE:0x81
-
-# Fangorn the Treebeard, Lord of the Ents
-R:934:0xC0:0x8A
-
-# Gandalf the Grey
-R:935:0xC0:0x8B
-
-# Nar, the Dwarf
-R:936:0xC0:0x8C
-
-# Apprentice mindcrafter
-R:937:0xAA:0x9A
-
-# Great Swamp Worm
-R:938:0xC5:0x86
-
-# Great Bile Worm
-R:939:0xC5:0x87
-
-# Blue Firebird
-R:940:0xBE:0x82
-
-# Green Firebird
-R:941:0xBE:0x83
-
-# Brown Firebird
-R:942:0xBE:0x84
-
-# Bronze Firebird
-R:943:0xBE:0x85
-
-# Gold Firebird
-R:944:0xBE:0x86
-
-# High-elven ranger
-R:945:0xBE:0x87
-
-# Uvatha the Horseman
-R:946:0xC0:0x90
-
-# Adunaphel the Quiet
-R:947:0xC0:0x91
-
-# Akhorahil the Blind
-R:948:0xC0:0x92
-
-# Ren the Unclean
-R:949:0xC0:0x93
-
-# Ji Indur Dawndeath
-R:950:0xC0:0x94
-
-# Dwar, Dog Lord of Waw
-R:951:0xC0:0x95
-
-# Hoarmurath of Dir
-R:952:0xC0:0x96
-
-# Khamul, the Black Easterling
-R:953:0xC0:0x97
-
-# The Witch-King of Angmar
-R:954:0xC0:0x98
-
-# Green Thunderlord
-R:955:0xB3:0x96
-
-# Blue Thunderlord
-R:956:0xB3:0x8E
-
-# Brown Thunderlord
-R:957:0xB3:0x98
-
-# Bronze Thunderlord
-R:958:0xB3:0x98
-
-# Gold Thunderlord
-R:959:0xB3:0x94
-
-# Blood Sprout
-R:960:0xBE:0x88
-
-# Gorlim the Unhappy
-R:961:0xC0:0x99
-
-# Pink mold
-R:962:0xC2:0xBF
-
-# Aranea
-R:963:0xC1:0x9A
-
-# Elder aranea
-R:964:0xC0:0x9A
-
-# Giant brown tick
-R:965:0xC5:0x88
-
-# Wavelord
-R:966:0xC0:0x9C
-
-# Novice possessor (soul)
-R:967:0xC4:0x86
-
-# Bat of Gorgoroth
-R:968:0xC5:0x97
-
-# The Princess
-R:969:0xC5:0x98
-
-# Merton Proudfoot, the lost hobbit
-R:970:0xC5:0x99
-
-# The Wight-King of the Barrow-downs
-R:971:0xA4:0x81
-
-# Adventurer
-R:972:0xC5:0x9B
-
-# Experienced possessor (soul)
-R:973:0xC5:0x9C
-
-# Old possessor (soul)
-R:974:0xC5:0x9D
-
-# Tree mold
-R:975:0xC1:0xA0
-
-# Bronze dragon worm
-R:976:0xC6:0x80
-
-# Gold dragon worm
-R:977:0xC5:0x9F
-
-# Defenceless Mold
-R:978:0xBC:0x89
-
-# Blue mold
-R:979:0xC1:0xA1
-
-# Ar-Pharazon the Golden
-R:980:0xC0:0x9E
-
-# Doppleganger
-R:981:0x97:0x8C
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0xC1:0x8D
-
-# Adventurer mold
-R:983:0xA9:0x81
-
-# Gnome paladin
-R:984:0xC2:0xB7
-
-# Bandobras Took
-R:985:0xA7:0x9B
-
-# 3-headed hydra
-R:986:0xA2:0x94
-
-# Uldor the Accursed
-R:987:0xAB:0x95
-
-# Mystic
-R:988:0xAB:0x9B
-
-# Elder vampire
-R:989:0xA1:0x99
-
-# Ulfang the Black
-R:990:0xAA:0x96
-
-# Demonologist
-R:991:0xA8:0x82
-
-# Ungorrog
-R:992:0xA2:0x9C
-
-# Faunungol
-R:993:0xA2:0x8E
-
-# Naurungol
-R:994:0xC2:0x8E
-
-# Sererrog
-R:995:0xC2:0x8F
-
-# Red Balrog
-R:996:0xC0:0xA8
-
-# Master mystic
-R:997:0xAA:0x94
-
-# Grand master mystic
-R:998:0xAB:0x9D
-
-# Morgulrog
-R:999:0xA0:0x84
-
-# Novice mindcrafter
-R:1000:0xAA:0x9A
-
-# Gnome lord
-R:1001:0xC2:0xB8
-
-# Great Worm of Perplexity
-R:1002:0xC2:0x92
-
-# Gnome mystic
-R:1003:0xC2:0xBA
-
-# Great Worm of Thunder
-R:1004:0xC5:0x8A
-
-# Silver mouse
-R:1005:0xC5:0x8B
-
-# The Rat King
-R:1006:0xC2:0x96
-
-# Gnome priest
-R:1007:0xC2:0xB9
-
-# Black midge
-R:1008:0xC2:0x98
-
-# Fire Phantom
-R:1009:0xC2:0x99
-
-# The Insane Player
-R:1010:0x92:0x81
-
-# Gnome rogue
-R:1011:0xC2:0xBB
-
-# Vermicious Knid
-R:1012:0xC2:0x9B
-
-# Bone golem
-R:1013:0xC2:0x9C
-
-# Gnome warrior
-R:1014:0xC2:0xBC
-
-# Bronze golem
-R:1015:0xC5:0x8C
-
-# Wizard leprawn
-R:1016:0xC2:0xB5
-
-# Kender
-R:1017:0xC2:0xB6
-
-# Adventurer gnome
-R:1018:0xC2:0xBC
-
-# Tree cat
-R:1019:0xC2:0xB1
-
-# Night cat
-R:1020:0xC2:0xB2
-
-# Leopard
-R:1021:0xC2:0xB3
-
-# Cheshire cat
-R:1022:0xC2:0xB4
-
-# Blue dragon worm
-R:1023:0xC3:0x8E
-
-# White dragon worm
-R:1024:0xC3:0x8F
-
-# Green dragon worm
-R:1025:0xC3:0x92
-
-# Black dragon worm
-R:1026:0xC3:0x91
-
-# Red dragon worm
-R:1027:0xC3:0x90
-
-# Multi-hued dragon worm
-R:1028:0xC3:0x93
-
-# The Minotaur of the Labyrinth
-R:1029:0xC3:0x94
-
-# The Sandworm Queen
-R:1030:0xC3:0x9B
-
-# Sandworm
-R:1031:0xC3:0x9C
-
-# Tik'srvzllat
-R:1032:0xC3:0x9D
-
-# The Glass Golem
-R:1033:0xC5:0x8E
-
-# Elenwe the Lost
-R:1034:0xBE:0xBF
-
-# Golgarach, the Living Rock
-R:1035:0x80:0x84
-
-# Sanctimonious-looking preacher
-R:1036:0xC2:0xAD
-
-# Weary-looking traveller
-R:1037:0xC2:0xAE
-
-# Water hound
-R:1038:0xC6:0x88
-
-# Improv, the mighty MoLD
-R:1039:0xC6:0x8E
-
-# Emperor mimic
-R:1040:0xC6:0x9C
-
-# Melinda Proudfoot
-R:1041:0x88:0xAA
-
-# Thrain, the King Under the Mountain
-R:1042:0x88:0xAB
-
-# Fire golem
-R:1043:0x8C:0xA0
-
-# Melkor, Lord of Darkness
-R:1044:0x8C:0xA1
-
-# Spirit
-R:1045:0x92:0x9F
-
-# Spirit
-R:1046:0x92:0xA0
-
-# Spirit
-R:1047:0x92:0xA1
-
-# Spirit
-R:1048:0x92:0xA2
-
-# Spirit
-R:1049:0x92:0xA3
-
-# Spirit
-R:1050:0x92:0xA4
-
-# Spirit
-R:1051:0x92:0xA5
-
-# Spirit
-R:1052:0x92:0xA6
-
-# Spirit
-R:1053:0x92:0xA7
-
-# Spirit
-R:1054:0x92:0xA8
-
-# Spirit
-R:1055:0x92:0xA9
-
-# Spirit
-R:1056:0x92:0xAA
-
-# Spirit
-R:1057:0x92:0xA3
-
-# Spirit
-R:1058:0x92:0xAB
-
-# Spirit
-R:1059:0x92:0xAC
-
-# Spirit
-R:1060:0x92:0xAD
-
-# Spirit
-R:1061:0x92:0xAE
-
-# Spirit
-R:1062:0x92:0xAF
-
-# Spirit
-R:1063:0x92:0xB0
-
-# Spirit
-R:1064:0x92:0xB1
-
-# Spirit
-R:1065:0x92:0xB2
-
-# Spirit
-R:1066:0x92:0xB3
-
-# Spirit
-R:1067:0x92:0xB4
-
-# Spirit
-R:1068:0x92:0xB5
-
-# Spirit
-R:1069:0x92:0xB6
-
-# Spirit
-R:1070:0x92:0xB7
-
-# Spirit
-R:1071:0x92:0xB8
-
-# Spirit
-R:1072:0x92:0xB9
-
-# Spirit
-R:1073:0x92:0xBA
-
-# Spirit
-R:1074:0x92:0xBB
-
-# Spirit
-R:1075:0x92:0xBC
-
-# Neil, the Sorceror
-R:1076:0x0A:0x68
-
-# Swamp wight
-R:1077:0xC0:0xA7
-
-# Knight of the Swan
-R:1078:0xC2:0xAF
-
-# Spells (*)
-S:48:0x91/0x88
-S:49:0x91/0x89
-S:50:0x91/0x8A
-S:51:0x91/0x8B
-S:52:0x91/0x8C
-S:53:0x91/0x8D
-S:54:0x91/0x8E
-S:55:0x91/0x8F
-S:56:0x91/0x90
-S:57:0x91/0x91
-S:58:0x91/0x92
-S:59:0x91/0x93
-S:60:0x91/0x94
-S:61:0x91/0x95
-S:62:0x91/0x96
-S:63:0x91/0x97
-
-# Spells (|)
-S:64:0x8F/0x80
-S:65:0x8F/0x84
-S:66:0x8F/0x88
-S:67:0x8F/0x8C
-S:68:0x8F/0x90
-S:69:0x8F/0x94
-S:70:0x8F/0x98
-S:71:0x8F/0x9C
-S:72:0x90/0x80
-S:73:0x90/0x84
-S:74:0x90/0x88
-S:75:0x90/0x8C
-S:76:0x90/0x90
-S:77:0x90/0x94
-S:78:0x90/0x98
-S:79:0x90/0x9C
-
-# Spells (-)
-S:80:0x8F/0x81
-S:81:0x8F/0x85
-S:82:0x8F/0x89
-S:83:0x8F/0x8D
-S:84:0x8F/0x91
-S:85:0x8F/0x95
-S:86:0x8F/0x99
-S:87:0x8F/0x9D
-S:88:0x90/0x81
-S:89:0x90/0x85
-S:90:0x90/0x89
-S:91:0x90/0x8D
-S:92:0x90/0x91
-S:93:0x90/0x95
-S:94:0x90/0x99
-S:95:0x90/0x9D
-
-# Spells (/)
-S:96:0x8F/0x82
-S:97:0x8F/0x86
-S:98:0x8F/0x8A
-S:99:0x8F/0x8E
-S:100:0x8F/0x92
-S:101:0x8F/0x96
-S:102:0x8F/0x9A
-S:103:0x8F/0x9E
-S:104:0x90/0x82
-S:105:0x90/0x86
-S:106:0x90/0x8A
-S:107:0x90/0x8E
-S:108:0x90/0x92
-S:109:0x90/0x96
-S:110:0x90/0x9A
-S:111:0x90/0x9E
-
-# Spells (\)
-S:112:0x8F/0x83
-S:113:0x8F/0x87
-S:114:0x8F/0x8B
-S:115:0x8F/0x8F
-S:116:0x8F/0x93
-S:117:0x8F/0x97
-S:118:0x8F/0x9B
-S:119:0x8F/0x9F
-S:120:0x90/0x83
-S:121:0x90/0x87
-S:122:0x90/0x8B
-S:123:0x90/0x8F
-S:124:0x90/0x93
-S:125:0x90/0x97
-S:126:0x90/0x9B
-S:127:0x90/0x9F
-
-# Amulets (")
-S:128:0x87/0x87
-S:129:0x87/0x80
-S:130:0x87/0x88
-S:131:0x87/0x82
-S:132:0x87/0x83
-S:133:0x87/0x84
-S:134:0x87/0x85
-S:135:0x87/0x86
-S:136:0x87/0x81
-S:137:0x87/0x81
-S:138:0x87/0x89
-S:139:0x87/0x8A
-S:140:0x87/0x8B
-S:141:0x87/0x8C
-S:142:0x87/0x8D
-S:143:0x87/0x8E
-
-# Rings (=)
-S:144:0x84/0x87
-S:145:0x84/0x80
-S:146:0x84/0x88
-S:147:0x84/0x82
-S:148:0x84/0x83
-S:149:0x84/0x84
-S:150:0x84/0x85
-S:151:0x84/0x86
-S:152:0x84/0x81
-S:153:0x84/0x81
-S:154:0x84/0x89
-S:155:0x84/0x8A
-S:156:0x84/0x8B
-S:157:0x84/0x8C
-S:158:0x84/0x8D
-S:159:0x84/0x8E
-
-# Staffs (_)
-S:160:0x87/0x96
-S:161:0x87/0x95
-S:162:0x87/0x95
-S:163:0x87/0x92
-S:164:0x87/0x92
-S:165:0x87/0x93
-S:166:0x87/0x95
-S:167:0x87/0x90
-S:168:0x87/0x95
-S:169:0x87/0x95
-S:170:0x87/0x92
-S:171:0x87/0x94
-S:172:0x87/0x92
-S:173:0x87/0x93
-S:174:0x87/0x96
-S:175:0x87/0x90
-
-# Wands (-)
-S:176:0x86/0x97
-S:177:0x86/0x90
-S:178:0x86/0x98
-S:179:0x86/0x92
-S:180:0x86/0x93
-S:181:0x86/0x94
-S:182:0x86/0x95
-S:183:0x86/0x96
-S:184:0x86/0x91
-S:185:0x86/0x91
-S:186:0x86/0x99
-S:187:0x86/0x9A
-S:188:0x86/0x9B
-S:189:0x86/0x9C
-S:190:0x86/0x9D
-S:191:0x86/0x9E
-
-# Rods (-)
-S:192:0x86/0x87
-S:193:0x86/0x80
-S:194:0x86/0x88
-S:195:0x86/0x82
-S:196:0x86/0x83
-S:197:0x86/0x84
-S:198:0x86/0x85
-S:199:0x86/0x86
-S:200:0x86/0x81
-S:201:0x86/0x81
-S:202:0x86/0x89
-S:203:0x86/0x8A
-S:204:0x86/0x8B
-S:205:0x86/0x8C
-S:206:0x86/0x8D
-S:207:0x86/0x8E
-
-# Scrolls (?)
-S:208:0x83/0x9C
-S:209:0x83/0x9D
-S:210:0x83/0x9E
-S:211:0x83/0x9F
-S:212:0x83/0x9C
-S:213:0x83/0x9D
-S:214:0x83/0x9E
-S:215:0x83/0x9F
-S:216:0x83/0x9C
-S:217:0x83/0x9D
-S:218:0x83/0x9E
-S:219:0x83/0x9F
-S:220:0x83/0x9C
-S:221:0x83/0x9D
-S:222:0x83/0x9E
-S:223:0x83/0x9F
-
-# Potions (!)
-S:224:0x85/0x87
-S:225:0x85/0x80
-S:226:0x85/0x88
-S:227:0x85/0x82
-S:228:0x85/0x83
-S:229:0x85/0x84
-S:230:0x85/0x85
-S:231:0x85/0x86
-S:232:0x85/0x81
-S:233:0x85/0x81
-S:234:0x85/0x89
-S:235:0x85/0x8A
-S:236:0x85/0x8B
-S:237:0x85/0x8C
-S:238:0x85/0x8D
-S:239:0x85/0x8E
-
-# Food (,)
-S:240:0x85/0x97
-S:241:0x85/0x90
-S:242:0x85/0x98
-S:243:0x85/0x92
-S:244:0x85/0x93
-S:245:0x85/0x94
-S:246:0x85/0x95
-S:247:0x85/0x96
-S:248:0x85/0x91
-S:249:0x85/0x91
-S:250:0x85/0x99
-S:251:0x85/0x9A
-S:252:0x85/0x9B
-S:253:0x85/0x9C
-S:254:0x85/0x9D
-S:255:0x85/0x9E
-
-# Elven
-G:M:12:0x91/0xA1
-
-# Dwarven
-G:M:13:0x91/0xA0
-
-# Spirit
-R:1045:0x92/0x9F
-R:1046:0x92/0xA0
-R:1047:0x92/0xA1
-R:1048:0x92/0xA2
-R:1049:0x92/0xA3
-R:1050:0x92/0xA4
-R:1051:0x92/0xA5
-R:1052:0x92/0xA6
-R:1053:0x92/0xA7
-R:1054:0x92/0xA8
-R:1055:0x92/0xA9
-R:1056:0x92/0xAA
-R:1057:0x92/0xA3
-R:1058:0x92/0xAB
-R:1059:0x92/0xAC
-R:1060:0x92/0xAD
-R:1061:0x92/0xAE
-R:1062:0x92/0xAF
-R:1063:0x92/0xB0
-R:1064:0x92/0xB1
-R:1065:0x92/0xB2
-R:1066:0x92/0xB3
-R:1067:0x92/0xB4
-R:1068:0x92/0xB5
-R:1069:0x92/0xB6
-R:1070:0x92/0xB7
-R:1071:0x92/0xB8
-R:1072:0x92/0xB9
-R:1073:0x92/0xBA
-R:1074:0x92/0xBB
-R:1075:0x92/0xBC
-
-# & Spellbook~ of #
-K:757:0x91/0xA4
-
-# Weakness Trap
-#G:T:1:0xFF/0xFF
-#G:T:2:0xFF/0xFF
-#G:T:3:0xFF/0xFF
-
-# Intelligence Trap
-#G:T:4:0xFF/0xFF
-#G:T:5:0xFF/0xFF
-#G:T:6:0xFF/0xFF
-
-# Wisdom Trap
-#G:T:7:0xFF/0xFF
-#G:T:8:0xFF/0xFF
-#G:T:9:0xFF/0xFF
-
-# Fumbling Fingers Trap
-#G:T:10:0xFF/0xFF
-#G:T:11:0xFF/0xFF
-#G:T:12:0xFF/0xFF
-
-# Wasting Trap
-#G:T:13:0xFF/0xFF
-#G:T:14:0xFF/0xFF
-#G:T:15:0xFF/0xFF
-
-# Beauty Trap
-#G:T:16:0xFF/0xFF
-#G:T:17:0xFF/0xFF
-#G:T:18:0xFF/0xFF
-
-# Trap of Curse Weapon
-#G:T:20:0xFF/0xFF
-
-# Trap of Curse Armor
-#G:T:21:0xFF/0xFF
-
-# Earthquake Trap
-#G:T:22:0xFF/0xFF
-
-# Poison Needle Trap
-#G:T:23:0xFF/0xFF
-
-# Summon Monster Trap
-#G:T:24:0xFF/0xFF
-
-# Summon Undead Trap
-#G:T:25:0xFF/0xFF
-
-# Summon Greater Undead Trap
-#G:T:26:0xFF/0xFF
-
-# Teleport Trap
-#G:T:27:0xFF/0xFF
-
-# Paralyzing Trap
-#G:T:28:0xFF/0xFF
-
-# Explosive Device
-#G:T:29:0xFF/0xFF
-
-# Teleport Item Trap
-#G:T:30:0xFF/0xFF
-
-# Lose Memory Trap
-#G:T:31:0xFF/0xFF
-
-# Bitter Regret Trap
-#G:T:32:0xFF/0xFF
-
-# Bowel Cramps Trap
-#G:T:33:0xFF/0xFF
-
-# Blindness
-#G:T:34:0xFF/0xFF
-
-# Aggravation Trap
-#G:T:35:0xFF/0xFF
-
-# Multiplication Trap
-#G:T:36:0xFF/0xFF
-
-# Steal Item Trap
-#G:T:37:0xFF/0xFF
-
-# Summon Fast Quylthulgs Trap
-#G:T:38:0xFF/0xFF
-
-# Trap of Sinking
-#G:T:39:0xFF/0xFF
-
-# Trap of Mana Drain
-#G:T:40:0xFF/0xFF
-
-# Trap of Missing Money
-#G:T:41:0xFF/0xFF
-
-# Trap of No Return
-#G:T:42:0xFF/0xFF
-
-# Trap of Silent Switching
-#G:T:43:0xFF/0xFF
-
-# Trap of Walls
-#G:T:44:0xFF/0xFF
-
-# Trap of Calling Out
-#G:T:45:0xFF/0xFF
-
-# Trap of Sliding
-#G:T:46:0xFF/0xFF
-
-# Trap of Charges Drain
-#G:T:47:0xFF/0xFF
-
-# Trap of Stair Movement
-#G:T:48:0xFF/0xFF
-
-# Trap of New Trap
-#G:T:49:0xFF/0xFF
-
-# Trap of Scatter Items
-#G:T:50:0xFF/0xFF
-
-# Trap of Decay
-#G:T:51:0xFF/0xFF
-
-# Trap of Wasting Wands
-#G:T:52:0xFF/0xFF
-
-# Trap of Filling
-#G:T:53:0xFF/0xFF
-
-# Trap of Drain Speed
-#G:T:54:0xFF/0xFF
-
-# Lightning Bolt Trap
-#G:T:60:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:61:0xFF/0xFF
-
-# Acid Bolt Trap
-#G:T:62:0xFF/0xFF
-
-# Cold Bolt Trap
-#G:T:63:0xFF/0xFF
-
-# Fire Bolt Trap
-#G:T:64:0xFF/0xFF
-
-# Plasma Bolt Trap
-#G:T:65:0xFF/0xFF
-
-# Water Bolt Trap
-#G:T:66:0xFF/0xFF
-
-# Lite Bolt Trap
-#G:T:67:0xFF/0xFF
-
-# Dark Bolt Trap
-#G:T:68:0xFF/0xFF
-
-# Shards Bolt Trap
-#G:T:69:0xFF/0xFF
-
-# Sound Bolt Trap
-#G:T:70:0xFF/0xFF
-
-# Confusion Bolt Trap
-#G:T:71:0xFF/0xFF
-
-# Force Bolt Trap
-#G:T:72:0xFF/0xFF
-
-# Inertia Bolt Trap
-#G:T:73:0xFF/0xFF
-
-# Mana Bolt Trap
-#G:T:74:0xFF/0xFF
-
-# Ice Bolt Trap
-#G:T:75:0xFF/0xFF
-
-# Chaos Bolt Trap
-#G:T:76:0xFF/0xFF
-
-# Nether Bolt Trap
-#G:T:77:0xFF/0xFF
-
-# Disenchantment Bolt Trap
-#G:T:78:0xFF/0xFF
-
-# Nexus Bolt Trap
-#G:T:79:0xFF/0xFF
-
-# Time Bolt Trap
-#G:T:80:0xFF/0xFF
-
-# Gravity Bolt Trap
-#G:T:81:0xFF/0xFF
-
-# Lightning Ball Trap
-#G:T:82:0xFF/0xFF
-
-# Poison Ball Trap
-#G:T:83:0xFF/0xFF
-
-# Acid Ball Trap
-#G:T:84:0xFF/0xFF
-
-# Cold Ball Trap
-#G:T:85:0xFF/0xFF
-
-# Fire Ball Trap
-#G:T:86:0xFF/0xFF
-
-# Plasma Ball Trap
-#G:T:87:0xFF/0xFF
-
-# Water Ball Trap
-#G:T:88:0xFF/0xFF
-
-# Light Ball Trap
-#G:T:89:0xFF/0xFF
-
-# Darkness Ball Trap
-#G:T:90:0xFF/0xFF
-
-# Shards Ball Trap
-#G:T:91:0xFF/0xFF
-
-# Sound Ball Trap
-#G:T:92:0xFF/0xFF
-
-# Confusion Ball Trap
-#G:T:93:0xFF/0xFF
-
-# Force Ball Trap
-#G:T:94:0xFF/0xFF
-
-# Mana Ball Trap
-#G:T:96:0xFF/0xFF
-
-# Ice Ball Trap
-#G:T:97:0xFF/0xFF
-
-# Chaos Ball Trap
-#G:T:98:0xFF/0xFF
-
-# Nether Ball Trap
-#G:T:99:0xFF/0xFF
-
-# Disenchantment Ball Trap
-#G:T:100:0xFF/0xFF
-
-# Nexus Ball Trap
-#G:T:101:0xFF/0xFF
-
-# Time Ball Trap
-#G:T:102:0xFF/0xFF
-
-# Gravity Ball Trap
-#G:T:103:0xFF/0xFF
-
-# Arrow Trap
-#G:T:110:0xFF/0xFF
-
-# Bolt Trap
-#G:T:111:0xFF/0xFF
-
-# Seeker Arrow Trap
-#G:T:112:0xFF/0xFF
-
-# Seeker Bolt Trap
-#G:T:113:0xFF/0xFF
-
-# Poison Arrow Trap
-#G:T:114:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:115:0xFF/0xFF
-
-# Poison Seeker Arrow Trap
-#G:T:116:0xFF/0xFF
-
-# Poison Seeker Bolt Trap
-#G:T:117:0xFF/0xFF
-
-# Broken Dagger Trap
-#G:T:118:0xFF/0xFF
-
-# Dagger Trap
-#G:T:119:0xFF/0xFF
-
-# Poison Broken Dagger Trap
-#G:T:120:0xFF/0xFF
-
-# Poison Dagger Trap
-#G:T:121:0xFF/0xFF
-
-# Arrows Trap
-#G:T:122:0xFF/0xFF
-
-# Bolts Trap
-#G:T:123:0xFF/0xFF
-
-# Seeker Arrow Trap
-#G:T:124:0xFF/0xFF
-
-# Seeker Bolt Trap
-#G:T:125:0xFF/0xFF
-
-# Poison Arrows Trap
-#G:T:126:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:127:0xFF/0xFF
-
-# Poison Seeker Arrows Trap
-#G:T:128:0xFF/0xFF
-
-# Poison Seeker Bolts Trap
-#G:T:129:0xFF/0xFF
-
-# Broken Daggers Trap
-#G:T:130:0xFF/0xFF
-
-# Dagger Trap
-#G:T:131:0xFF/0xFF
-
-# Poison Broken Daggers Trap
-#G:T:132:0xFF/0xFF
-
-# Poison Daggers Trap
-#G:T:133:0xFF/0xFF
-
-# Trap of Drop Item
-#G:T:140:0xFF/0xFF
-
-# Trap of Drop Items
-#G:T:141:0xFF/0xFF
-
-# Trap of Drop Everything
-#G:T:142:0xFF/0xFF
-
-# Trap of Femininity
-#G:T:150:0xFF/0xFF
-
-# Trap of Masculinity
-#G:T:151:0xFF/0xFF
-
-# Trap of Neutrality
-#G:T:152:0xFF/0xFF
-
-# Trap of Aging
-#G:T:153:0xFF/0xFF
-
-# Trap of Growing
-#G:T:154:0xFF/0xFF
-
-# Trap of Shrinking
-#G:T:155:0xFF/0xFF
-
-# Trap of Tanker Drain
-#G:T:157:0xFF/0xFF
-
-# Trap of Divine Anger
-#G:T:158:0xFF/0xFF
-
-# Trap of Divine Wrath
-#G:T:159:0xFF/0xFF
-
-# Hallucination Trap
-#G:T:160:0xFF/0xFF
-
-# Greater Magic Missile Trap
-#G:T:161:0xFF/0xFF
-
-# Foulness Trap
-#G:T:162:0xFF/0xFF
-
-# Trap of Holy Fire
-#G:T:164:0xFF/0xFF
-
-# Trap of Hell Fire
-#G:T:165:0xFF/0xFF
-
-# Psi Bolt Trap
-#G:T:166:0xFF/0xFF
-
-# Psi Drain Trap
-#G:T:167:0xFF/0xFF
-
-# Plasma Ball Trap
-#G:T:168:0xFF/0xFF
-
-# Psi Ball Trap
-#G:T:169:0xFF/0xFF
-
-# Acquirement Trap
-#G:T:170:0xFF/0xFF
-
-# Greater Lightning Bolt Trap
-#G:T:171:0xFF/0xFF
-
-# Greater Poison Bolt Trap
-#G:T:172:0xFF/0xFF
-
-# Greater Acid Bolt Trap
-#G:T:173:0xFF/0xFF
-
-# Greater Cold Bolt Trap
-#G:T:174:0xFF/0xFF
-
-# Greater Fire Bolt Trap
-#G:T:175:0xFF/0xFF
-# non-defines encountered :
-# Load the special player pictures
-%:xtra-new.prf
diff --git a/lib/mods/theme/pref/graf-sdl.prf b/lib/mods/theme/pref/graf-sdl.prf
deleted file mode 100644
index 818f876a..00000000
--- a/lib/mods/theme/pref/graf-sdl.prf
+++ /dev/null
@@ -1,37 +0,0 @@
-# File: graf-x11.prf
-
-
-# Font stuff
-%:font-x11.prf
-
-
-# Color palette - Graphics
-
-#V:16:0x01:0x00:0x00:0x00
-#V:17:0x01:0xF0:0xE0:0xD0
-#V:18:0x01:0x80:0x80:0x80
-#V:19:0x01:0x50:0x50:0x50
-#V:20:0x01:0xE0:0xB0:0x00
-#V:21:0x01:0xC0:0xA0:0x70
-#V:22:0x01:0x80:0x60:0x40
-#V:23:0x01:0x50:0x3C:0x28
-#V:24:0x01:0x00:0xA0:0xF0
-#V:25:0x01:0x00:0x00:0xF0
-#V:26:0x01:0x00:0x00:0x70
-#V:27:0x01:0xF0:0x00:0x00
-#V:28:0x01:0x80:0x00:0x00
-#V:29:0x01:0x90:0x00:0xB0
-#V:30:0x01:0x00:0x60:0x10
-#V:31:0x01:0x60:0xF0:0x40
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
-
-?:1
-
diff --git a/lib/mods/theme/pref/graf-win.prf b/lib/mods/theme/pref/graf-win.prf
deleted file mode 100644
index f59edb35..00000000
--- a/lib/mods/theme/pref/graf-win.prf
+++ /dev/null
@@ -1,16 +0,0 @@
-# File: graf-win.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/mods/theme/pref/graf-x11.prf b/lib/mods/theme/pref/graf-x11.prf
deleted file mode 100644
index 818f876a..00000000
--- a/lib/mods/theme/pref/graf-x11.prf
+++ /dev/null
@@ -1,37 +0,0 @@
-# File: graf-x11.prf
-
-
-# Font stuff
-%:font-x11.prf
-
-
-# Color palette - Graphics
-
-#V:16:0x01:0x00:0x00:0x00
-#V:17:0x01:0xF0:0xE0:0xD0
-#V:18:0x01:0x80:0x80:0x80
-#V:19:0x01:0x50:0x50:0x50
-#V:20:0x01:0xE0:0xB0:0x00
-#V:21:0x01:0xC0:0xA0:0x70
-#V:22:0x01:0x80:0x60:0x40
-#V:23:0x01:0x50:0x3C:0x28
-#V:24:0x01:0x00:0xA0:0xF0
-#V:25:0x01:0x00:0x00:0xF0
-#V:26:0x01:0x00:0x00:0x70
-#V:27:0x01:0xF0:0x00:0x00
-#V:28:0x01:0x80:0x00:0x00
-#V:29:0x01:0x90:0x00:0xB0
-#V:30:0x01:0x00:0x60:0x10
-#V:31:0x01:0x60:0xF0:0x40
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
-
-?:1
-
diff --git a/lib/mods/theme/pref/graf-xxx.prf b/lib/mods/theme/pref/graf-xxx.prf
deleted file mode 100644
index 8be9d6da..00000000
--- a/lib/mods/theme/pref/graf-xxx.prf
+++ /dev/null
@@ -1,3267 +0,0 @@
-# PRF file generated by Andreas Koch`s Tile Assigner
-# at 12:19:29 AM
-
-# 2185 items
-# 2185 probably mapped correctly
-# 0 imported but not yet defined
-# 0 defined to value(s) lower than 0x80
-# Old header :
-### 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
-
-# General Store
-B:0:0x81/0x91
-
-# Armoury
-B:1:0x81/0x92
-
-# Weapon Smiths
-B:2:0x81/0x93
-
-# Temple
-B:3:0x81/0x94
-
-# Alchemy Shop
-B:4:0x81/0x95
-
-# Magic Shop
-B:5:0x81/0x96
-
-# Black Market
-B:6:0x81/0x97
-
-# Home
-B:7:0x81/0x98
-
-# Bookstore
-B:8:0x82/0x93
-
-# Pet Shop
-B:9:0xCB/0x96
-
-# Mayor's Office
-B:10:0xCB/0x92
-
-# Inn
-B:11:0xCB/0x95
-
-# The Soothsayer
-B:12:0xD4/0x85
-
-# Library
-B:13:0xD4/0x89
-
-# Castle
-B:14:0xCB/0x92
-
-# Casino
-B:15:0xD5/0x81
-
-# Beastmaster Shanty
-B:16:0xD3/0x8B
-
-# Fighters Hall
-B:17:0xD3/0x8C
-
-# Tower of Magery
-B:18:0xD4/0x8B
-
-# Inner Temple
-B:19:0xD4/0x9D
-
-# Paladins Guild
-B:20:0xCB/0x8F
-
-# Rangers Guild
-B:21:0xD3/0x83
-
-# Weyr
-B:22:0xCB/0x93
-
-# The Mirror
-B:23:0xD4/0x89
-
-# Seat of Ruling
-B:24:0xCB/0x92
-
-# Wizards Spire
-B:25:0xD4/0x8A
-
-# Priests Circle
-B:26:0xD4/0x92
-
-# Tower of the King
-B:27:0xCB/0x92
-
-# Library
-B:28:0xD4/0x89
-
-# The White Tree
-B:29:0xCB/0x95
-
-# Craftsmaster
-B:30:0xCB/0x97
-
-# Earth-Dome (Nature)
-B:31:0xCB/0x9A
-
-# Minstrels Haven
-B:32:0xD3/0x9F
-
-# Star-Dome
-B:33:0xD4/0x8C
-
-# Valarin Temple
-B:34:0xD4/0x90
-
-# Sea-Dome
-B:35:0xD4/0x91
-
-# The Golden Flower
-B:36:0xD3/0x83
-
-# The Fountain
-B:37:0xD4/0x9D
-
-# Axe Smith
-B:38:0xCC/0x96
-
-# Hafted Smith
-B:39:0xCC/0x97
-
-# Polearm Smith
-B:40:0xCC/0x98
-
-# Sword Smith
-B:41:0xCC/0x80
-
-# Rare Jewelry Shop
-B:42:0xD3/0x96
-
-# Jewelry Shop
-B:43:0xD3/0x93
-
-# Footwear Shop
-B:44:0xD3/0x9D
-
-# Rare Footwear Shop
-B:45:0xD3/0x9E
-
-# Library
-B:46:0xD3/0x9C
-
-# Forbidden Library
-B:47:0xD4/0x8F
-
-# Expensive Black Market
-B:48:0xD4/0x95
-
-# Common Shop
-B:49:0xD4/0x93
-
-# Dragon Hunter
-B:50:0xCC/0x89
-
-# Speed Ring Market
-B:51:0xD3/0x97
-
-# Scribe
-B:52:0xD4/0x86
-
-# Potion Store
-B:53:0xD4/0x80
-
-# Recaller
-B:54:0xD4/0x88
-
-# Master Archer
-B:55:0xD3/0x85
-
-# Merchants Guild
-B:56:0xD4/0x9B
-
-# The Mathom-house
-B:57:0xCB/0x9B
-
-# The Prancing Pony
-B:58:0xCB/0x95
-
-# Mining Supply store
-B:59:0xCB/0x97
-
-# Library quest in Minas Anor
-B:60:0xD3/0x9C
-
-# Hunting Supply Store
-B:61:0xD3/0x85
-
-# Runic Magic Shop
-B:62:0x81/0x96
-
-# Construction Supply Store
-B:63:0xCB/0x97
-
-# Music Store
-B:64:0xD3/0x9F
-
-# Magic Rod Market
-B:65:0x81/0x96
-
-# Map store
-B:66:0xD3/0x9C
-
-# Farm
-B:67:0xD4/0x93
-
-#Pelargir inn - The Grey Swan
-B:68:0xCB/0x95
-
-#Caras Galadhon inn - The Garden
-B:69:0xCB/0x95
-
-#Khazad Dum inn - The Mithril Lode
-B:70:0xCB/0x95
-
-#Dale inn - The Builder Barracks
-B:71:0xCB/0x95
-
-#Edoras inn - The Horse and Ox
-B:72:0xCB/0x95
-
-#Esgaroth inn - The Dancing Dragon
-B:73:0xCB/0x95
-
-#Hobbiton inn - The Green Dragon
-B:74:0xCB/0x95
-
-#Osgiliath inn - The Twinkling Star
-B:75:0xCB/0x95
-
-#The House of Beorn
-B:76:0xCB/0x92
-
-#Bard's Hut
-B:77:0xCB/0x92
-
-#The Ranger Conclave
-B:78:0xCB/0x92
-
-#Imladris
-B:79:0xCB/0x92
-
-#The Hornburg
-B:80:0xCB/0x92
-
-#Thranduil's Hall
-B:81:0xCB/0x92
-
-#Meduseld
-B:82:0xCB/0x92
-
-#The Master's House
-B:83:0xCB/0x92
-
-#Bag End
-B:84:0xCB/0x92
-
-#The Castle of Stars
-B:85:0xCB/0x92
-
-#The Prince's Tower
-B:86:0xCB/0x92
-
-#The Seat of Durin
-B:87:0xCB/0x92
-
-### The forge in Imladris
-B:88:0xCB/0x97
-
-# nothing
-F:0:0x81/0x80
-
-# open floor
-F:1:0x80/0x80
-
-# fountain - wet
-F:2:0xD1/0x83
-
-# glyph of warding
-F:3:0xA2/0x88
-
-# open door
-F:4:0x81/0x87
-
-# broken door
-F:5:0x81/0x87
-
-# up staircase
-F:6:0x81/0x9C
-
-# down staircase
-F:7:0x81/0x9E
-
-# quest entrance
-F:8:0x82/0x8E
-
-# quest exit
-F:9:0x82/0x8B
-
-# quest down level
-F:10:0x82/0x8F
-
-# quest up level
-F:11:0x82/0x8C
-
-# town exit
-F:12:0x82/0x91
-
-# shaft down
-F:13:0x82/0x90
-
-# shaft up
-F:14:0x82/0x8D
-
-# fountain
-F:15:0xD1/0x82
-
-# web
-F:16:0x82/0x92
-
-# Open pit
-F:17:0xA2/0x96
-
-# Spiked Pit
-F:18:0xA2/0x96
-
-# Poison Pit
-F:19:0xA2/0x96
-
-# Summon Rune
-F:20:0x8A/0x9C
-
-# Teleport Rune
-F:21:0x8A/0x9C
-
-# Fire spot
-F:22:0x8A/0x9B
-
-# Acid spot
-F:23:0x8A/0x9B
-
-# Slow dart trap
-F:24:0x82/0x9E
-
-# Lose str dart
-F:25:0xA2/0x89
-
-# Lose dex dart
-F:26:0xA2/0x8D
-
-# Lose con dart
-F:27:0xA2/0x92
-
-# gas trap - blind
-F:28:0xA2/0x8E
-
-# gas trap - confuse
-F:29:0xA2/0x8F
-
-# gas trap - poison
-F:30:0xA2/0x90
-
-# gas trap - sleep
-F:31:0xA2/0x91
-
-# door
-F:32:0x81/0x8B
-
-# locked door
-F:33:0x81/0x8B
-F:34:0x81/0x8B
-F:35:0x81/0x8B
-F:36:0x81/0x8B
-F:37:0x81/0x8B
-F:38:0x81/0x8B
-F:39:0x81/0x8B
-
-# jammed door
-F:40:0x81/0x8B
-F:41:0x81/0x8B
-F:42:0x81/0x8B
-F:43:0x81/0x8B
-F:44:0x81/0x8B
-F:45:0x81/0x8B
-F:46:0x81/0x8B
-F:47:0x81/0x8B
-
-# secret door
-F:48:0x80/0x82
-
-# pile of rubble
-F:49:0x81/0x9A
-
-# magma vein
-F:50:0x81/0x83
-
-# quartz vein
-F:51:0x80/0x83
-
-# magma vein
-F:52:0x81/0x83
-
-# quartz vein
-F:53:0x80/0x83
-
-# magma vein with treasure
-F:54:0x80/0x84
-
-# quartz vein with treasure
-F:55:0x80/0x84
-
-# granite wall
-F:56:0x80/0x82
-F:57:0x80/0x82
-F:58:0x80/0x82
-F:59:0x80/0x82
-
-# permanent wall
-F:60:0x80/0x95
-F:61:0x80/0x95
-F:62:0x80/0x95
-F:63:0x80/0x95
-
-# explosive rune
-F:64:0xA2/0x87
-
-# Straight Road startpoint
-F:65:0xA3/0x9D
-
-# section of the Straight Road
-F:66:0xA3/0x97
-F:67:0xA3/0x9C
-F:68:0xA3/0x9B
-F:69:0xA3/0x9A
-F:70:0xA3/0x98
-
-# section of the Straight Road (discharged)
-F:71:0xA3/0x98
-
-# Straight Road exit
-F:72:0xA3/0x9D
-
-# corrupted section of the Straight Road
-F:73:0xA3/0x99
-
-# Building
-F:74:0x81/0x91
-
-# permanent wall
-F:75:0x80/0x95
-F:76:0x80/0x95
-F:77:0x80/0x95
-F:78:0x80/0x95
-
-# grass with Elanor flowers
-F:79:0x82:0x95
-
-# grass with Fumella flowers
-F:80:0x82:0x96
-
-# grass with anemones
-F:81:0x82:0x97
-
-# grass with Niphredil flowers
-F:82:0x82:0x98
-
-# grass with irises
-F:83:0x82:0x99
-
-# stream of shallow water
-F:84:0xD2/0x81
-
-# pool of deep lava
-F:85:0xCB/0x89
-
-# stream of shallow lava
-F:86:0xCB/0x88
-
-# dark pit
-F:87:0x81/0x80
-
-# dirt
-F:88:0xCB/0x84
-
-# patch of grass
-F:89:0xD0/0x8E
-
-# ice
-F:90:0xCF/0x81
-
-# sand
-F:91:0xCF/0x8E
-
-# dead tree
-F:92:0xCF/0x85
-
-# ash
-F:93:0xCF/0x95
-
-# mud
-F:94:0xCF/0x8D
-
-# ice wall
-F:95:0xD0/0x88
-
-# tree
-F:96:0xCB/0x86
-
-# mountain chain
-F:97:0xCB/0x87
-
-# sandwall
-F:98:0xD0/0x87
-F:99:0xD0/0x87
-
-# sandwall with treasure
-F:100:0xD0/0x8A
-
-# high mountain chain
-F:101:0xCB/0x87
-
-# nether mist
-F:102:0xC5/0x8C
-
-# molten glass wall
-F:103:0xD0/0x89
-
-# Between gate
-F:160:0x8A/0x9D
-
-# Altar of Forests
-F:161:0xD1/0x85
-
-# Altar of Water
-F:162:0xD1/0x86
-
-# Altar of Earth
-F:163:0xD1/0x8E
-
-# Altar of Darkness
-F:164:0xD1/0x88
-
-# Altar of Moon
-F:165:0xD1/0x89
-
-# Altar of Sun
-F:166:0xD1/0x8C
-
-# Altar of Rage
-F:167:0xD1/0x8A
-
-# Altar of Winds
-F:168:0xD1/0x8B
-
-# Altar of Stars
-F:169:0xD1/0x8D
-
-# Altar of Being
-F:170:0xD1/0x87
-
-# Altar of Randomness
-F:171:0xD1/0x8F
-
-# floor
-F:172:0x80/0x80
-
-# Underground Tunnel
-F:173:0xCF/0x97
-
-# stream of tainted water
-F:174:0xD2/0x82
-
-# monster trap
-F:175:0x82/0x94
-
-# Between gate
-F:176:0x8A/0x9D
-
-# lava wall
-F:177:0xD0/0x86
-
-# Great Fire
-F:178:0xD1/0x90
-
-# Path to next area
-F:179:0xCF/0x9C
-
-# Path to previous area
-F:180:0xCF/0x9B
-
-# field
-F:181:0xCF/0x8A
-
-# Ekkaia, the Encircling Sea
-F:182:0xD2/0x84
-
-# pool of deep water
-F:187:0xD2/0x80
-
-# glass wall
-F:188:0xD0/0x89
-
-# illusion wall
-F:189:0xD0/0x8C
-
-# Grass roof
-F:190:0xD0/0x8F
-
-# grass roof top
-F:191:0xD0/0x8F
-
-# grass roof chimney
-F:192:0xD0/0x8F
-
-# brick roof
-F:193:0xD0/0x90
-
-# brick roof top
-F:194:0xD0/0x90
-
-# brick roof chimney
-F:195:0xD0/0x90
-
-# window
-F:196:0xD0/0x91
-
-# small window
-F:197:0xD0/0x92
-
-# rain barrel
-F:198:0xD0/0x93
-
-# grass with flowers
-F:199:0xD0/0x8D
-
-# cobblestone road
-F:200:0x82/0x8A
-
-# cobblestone with outlet
-F:201:0x82/0x8A
-
-# small tree
-F:202:0xD0/0x8B
-
-# town
-F:203:0xD0/0x94
-
-# Underground Tunnel
-F:204:0xD0/0x95
-
-# a blazing fire
-F:205:0xD1/0x84
-
-# pile of rubble
-F:206:0x81/0x9A
-
-# rocky ground
-F:207:0x82:0x9A
-
-# cloud-like vapour
-F:208:0x82:0x9B
-
-# condensing water
-F:209:0x82:0x9C
-
-# dense mist
-F:210:0x82:0x9D
-
-# hail-stone wall
-F:211:0x83:0x80
-
-# dead small tree
-F:212:0x83:0x83
-
-# low hill
-F:213:0x83:0x84
-
-# dark mountain chain
-F:214:0x83:0x85
-
-# blue mountain chain
-F:215:0x83:0x86
-
-# grey mountain chain
-F:216:0x83:0x87
-
-# part of Mount Doom
-F:217:0x83:0x88
-
-# snow-capped peak
-F:218:0x83:0x89
-
-# fir tree
-F:219:0x83:0x8A
-
-# section of a flet
-F:220:0x83:0x8B
-
-# light post
-F:221:0x83:0x8C
-
-# water lily
-F:222:0x83:0x8D
-
-# part of the Dead Marshes
-F:223:0x83:0x8E
-
-# Black Gate
-F:224:0x83:0x8F
-
-# river
-F:225:0x83:0x90
-
-# swamp pool
-F:226:0x83:0x91
-
-# stream of the Anduin river
-F:227:0x83:0x92
-
-# road sign that says 'Hurry to Gondolin!'
-F:228:0x83:0x93
-
-# beehive
-F:229:0x83:0x94
-
-# dirt road
-F:230:0x83:0x95
-
-# wide gate
-F:231:0x83:0x96
-
-# open gate
-F:232:0x83:0x97
-
-# wooden board
-F:233:0x83:0x98
-
-# wooden board
-F:234:0x83:0x99
-
-# wooden board
-F:235:0x83:0x9A
-
-# wooden board
-F:236:0x83:0x9B
-
-# white tree
-F:237:0x83:0x9C
-
-# swift waterfall
-F:238:0x83:0x9D
-
-# slippery rock ledge
-F:239:0x82:0x9A
-
-# stable
-F:240:0x83:0x9E
-
-# wooden plank
-F:241:0x83:0x9F
-
-# fosse pit
-F:242:0x82:0x9F
-
-# Mallorn
-F:243:0x81:0x9F
-
-# copper pillar
-F:244:0x86:0x93
-
-# ethereal wall
-F:245:0x80:0x80
-
-# glacial wall
-F:246:0xD0:0x88
-
-# battlement
-F:247:0x86:0x98
-
-# door of Orthanc
-F:248:0x04:0x27
-
-# something
-K:0:0x80:0x80
-
-# Blindness
-K:1:0xBA:0x81
-
-# Fear
-K:2:0xBA:0x81
-
-# Confusion
-K:3:0xBA:0x81
-
-# Hallucination
-K:4:0xBA:0x81
-
-# Cure Poison
-K:5:0xBA:0x81
-
-# Cure Blindness
-K:6:0xBA:0x81
-
-# Cure Fear
-K:7:0xBA:0x81
-
-# Cure Confusion
-K:8:0xBA:0x81
-
-# Weakness
-K:9:0xBA:0x81
-
-# Unhealth
-K:10:0xBA:0x81
-
-# Restore Constitution
-K:11:0xBA:0x81
-
-# Restoring
-K:12:0xBA:0x81
-
-# Stupidity
-K:13:0xBA:0x81
-
-# Naivety
-K:14:0xBA:0x81
-
-# Poison
-K:15:0xBA:0x81
-
-# Sickness
-K:16:0xBA:0x81
-
-# Paralysis
-K:17:0xBA:0x81
-
-# Restore Strength
-K:18:0xBA:0x81
-
-# Disease
-K:19:0xBA:0x81
-
-# Cure Serious Wounds
-K:20:0xBA:0x81
-
-# & Ration~ of Cram
-K:21:0x8B:0x82
-
-# & Round Seed-Cake~
-K:22:0x8B:0x82
-
-# & Strip~ of Venison
-K:23:0x8B:0x82
-
-# & Slime Mold~
-K:24:0x8A:0x9F
-
-# & Lembas~
-K:25:0x8B:0x80
-
-# & Pint~ of Fine Ale
-K:26:0x8A:0x95
-
-# & Pint~ of Old Winyards
-K:27:0x8A:0x96
-
-# & Mattock~
-K:28:0xCD:0x80
-
-# & Blue Stone~
-K:29:0xB6:0x89
-
-# & Broken Dagger~
-K:30:0x89:0x83
-
-# & Bastard Sword~
-K:31:0x89:0x85
-
-# & Scimitar~
-K:32:0x89:0x85
-
-# & Tulwar~
-K:33:0x89:0x84
-
-# & Broad Sword~
-K:34:0x89:0x85
-
-# & Short Sword~
-K:35:0x89:0x84
-
-# & Blade~ of Chaos
-K:36:0x89:0x87
-
-# & Two-Handed Sword~
-K:37:0x89:0x85
-
-# & Main Gauche~
-K:38:0x89:0x83
-
-# & Cutlass~
-K:39:0x89:0x84
-
-# & Executioner's Sword~
-K:40:0x89:0x86
-
-# & Katana~
-K:41:0x89:0x85
-
-# & Long Sword~
-K:42:0x89:0x85
-
-# & Dagger~
-K:43:0x89:0x83
-
-# & Rapier~
-K:44:0x89:0x84
-
-# & Sabre~
-K:45:0x89:0x84
-
-# & Small Sword~
-K:46:0x89:0x84
-
-# & Broken Sword~
-K:47:0x89:0x83
-
-# & Ball-and-Chain~
-K:48:0x89:0x88
-
-# & Whip~
-K:49:0x89:0x89
-
-# & Flail~
-K:50:0x89:0x8B
-
-# & Two-Handed Flail~
-K:51:0x89:0x8B
-
-# & Morning Star~
-K:52:0x89:0x8B
-
-# & Mace~
-K:53:0x89:0x8C
-
-# & Quarterstaff~
-K:54:0x89:0x8E
-
-# & War Hammer~
-K:55:0x89:0x8F
-
-# & Lead-Filled Mace~
-K:56:0x89:0x8C
-
-# & Mace~ of Disruption
-K:57:0x89:0x8D
-
-# & Lucerne Hammer~
-K:58:0x89:0x90
-
-# & Beaked Axe~
-K:59:0x89:0x90
-
-# & Glaive~
-K:60:0x89:0x90
-
-# & Halberd~
-K:61:0x89:0x90
-
-# & Awl-Pike~
-K:62:0x89:0x91
-
-# & Pike~
-K:63:0x89:0x91
-
-# & Spear~
-K:64:0x89:0x91
-
-# & Trident~
-K:65:0x89:0x92
-
-# & Lance~
-K:66:0x89:0x93
-
-# & Great Axe~
-K:67:0x89:0x90
-
-# & Battle Axe~
-K:68:0x89:0x90
-
-# & Lochaber Axe~
-K:69:0x89:0x90
-
-# & Broad Axe~
-K:70:0x89:0x90
-
-# & Scythe~
-K:71:0x89:0x94
-
-# & Scythe~ of Slicing
-K:72:0x89:0x94
-
-# & Short Bow~
-K:73:0x89:0x95
-
-# & Long Bow~
-K:74:0x89:0x96
-
-# & Light Crossbow~
-K:75:0x89:0x97
-
-# & Heavy Crossbow~
-K:76:0x89:0x98
-
-# & Sling~
-K:77:0x89:0x99
-
-# & Arrow~
-K:78:0x89:0x9A
-
-# & Seeker Arrow~
-K:79:0x89:0x9B
-
-# & Bolt~
-K:80:0x89:0x9C
-
-# & Seeker Bolt~
-K:81:0x89:0x9D
-
-# & Rounded Pebble~
-K:82:0x89:0x9E
-
-# & Iron Shot~
-K:83:0x89:0x9F
-
-# & Shovel~
-K:84:0x8A:0x98
-
-# & Gnomish Shovel~
-K:85:0x8B:0x8F
-
-# & Dwarven Shovel~
-K:86:0x8B:0x90
-
-# & Pick~
-K:87:0x8A:0x97
-
-# & Orcish Pick~
-K:88:0x8B:0x8D
-
-# & Dwarven Pick~
-K:89:0x8B:0x8E
-
-# & Elven Cloak~
-K:90:0x88:0x81
-
-# & Pair~ of Soft Leather Boots
-K:91:0x88:0x89
-
-# & Pair~ of Hard Leather Boots
-K:92:0x88:0x8A
-
-# & Pair~ of Metal Shod Boots
-K:93:0x88:0x8B
-
-# & Hard Leather Cap~
-K:94:0x88:0x82
-
-# & Metal Cap~
-K:95:0x88:0x83
-
-# & Iron Helm~
-K:96:0x88:0x84
-
-# & Steel Helm~
-K:97:0x88:0x85
-
-# & Iron Crown~
-K:98:0x88:0x86
-
-# & Golden Crown~
-K:99:0x88:0x87
-
-# & Jewel-Encrusted Crown~
-K:100:0x88:0x88
-
-# & Robe~
-K:101:0x88:0x95
-
-# & Filthy Rag~
-K:102:0x88:0x94
-
-# Soft Leather Armour~
-K:103:0x88:0x96
-
-# Soft Studded Leather~
-K:104:0x88:0x96
-
-# Hard Leather Armour~
-K:105:0x88:0x97
-
-# Hard Studded Leather~
-K:106:0x88:0x97
-
-# Leather Scale Mail~
-K:107:0x88:0x98
-
-# Metal Scale Mail~
-K:108:0x88:0x98
-
-# Chain Mail~
-K:109:0x88:0x99
-
-# Rusty Chain Mail~
-K:110:0x88:0x9A
-
-# Augmented Chain Mail~
-K:111:0x88:0x99
-
-# Bar Chain Mail~
-K:112:0x88:0x99
-
-# Metal Brigandine Armour~
-K:113:0x88:0x99
-
-# Partial Plate Armour~
-K:114:0x88:0x9B
-
-# Metal Lamellar Armour~
-K:115:0x88:0x9B
-
-# Full Plate Armour~
-K:116:0xCD:0x82
-
-# Ribbed Plate Armour~
-K:117:0x88:0x9B
-
-# Galvorn Plate Mail~
-K:118:0xA3:0x96
-
-# Mithril Plate Mail~
-K:119:0x85:0x96
-
-# Mithril Chain Mail~
-K:120:0x85:0x96
-
-# Double Chain Mail~
-K:121:0x88:0x99
-
-# & Shield~ of Deflection
-K:122:0x88:0x93
-
-# & Cloak~
-K:123:0x88:0x80
-
-# & Shadow Cloak~
-K:124:0x88:0x81
-
-# & Set~ of Leather Gloves
-K:125:0x88:0x8C
-
-# & Set~ of Gauntlets
-K:126:0x88:0x8D
-
-# & Set~ of Cesti
-K:127:0x88:0x8E
-
-# & Small Leather Shield~
-K:128:0x88:0x8F
-
-# & Large Leather Shield~
-K:129:0x88:0x90
-
-# & Small Metal Shield~
-K:130:0x88:0x91
-
-# & Large Metal Shield~
-K:131:0x88:0x92
-
-# Strength
-K:132:0xB5:0x81
-
-# Dexterity
-K:133:0xB5:0x81
-
-# Constitution
-K:134:0xB5:0x81
-
-# Intelligence
-K:135:0xB5:0x81
-
-# Speed
-K:136:0xB5:0x83
-
-# Searching
-K:137:0xB5:0x80
-
-# Teleportation
-K:138:0xB5:0x80
-
-# Slow Digestion
-K:139:0xB5:0x80
-
-# Fire Resistance
-K:140:0xB5:0x80
-
-# Cold Resistance
-K:141:0xB5:0x80
-
-# Levitation
-K:142:0xB5:0x80
-
-# Poison Resistance
-K:143:0xB5:0x82
-
-# Free Action
-K:144:0xB5:0x80
-
-# Weakness
-K:145:0xB5:0x80
-
-# Flames
-K:146:0xB5:0x82
-
-# Acid
-K:147:0xB5:0x82
-
-# Ice
-K:148:0xB5:0x82
-
-# Woe
-K:149:0xB5:0x82
-
-# Stupidity
-K:150:0xB5:0x80
-
-# Damage
-K:151:0xB5:0x81
-
-# Accuracy
-K:152:0xB5:0x81
-
-# Protection
-K:153:0xB5:0x80
-
-# Aggravate Monster
-K:154:0xB5:0x80
-
-# See Invisible
-K:155:0xB5:0x81
-
-# Sustain Strength
-K:156:0xB5:0x81
-
-# Sustain Intelligence
-K:157:0xB5:0x81
-
-# Sustain Wisdom
-K:158:0xB5:0x81
-
-# Sustain Constitution
-K:159:0xB5:0x81
-
-# Sustain Dexterity
-K:160:0xB5:0x81
-
-# Sustain Charisma
-K:161:0xB5:0x81
-
-# Slaying
-K:162:0xB5:0x81
-
-# Brilliance
-K:163:0xB6:0x9F
-
-# Charisma
-K:164:0xB6:0x9F
-
-# Searching
-K:165:0xB6:0x9E
-
-# Teleportation
-K:166:0xB6:0x9E
-
-# Slow Digestion
-K:167:0xB6:0x9E
-
-# Acid Resistance
-K:168:0xB6:0x9E
-
-# Protection from Evil
-K:169:0xB6:0x9E
-
-# Double Ring Mail~
-K:170:0xCD:0x83
-
-# the Magi
-K:171:0xB6:0x80
-
-# Doom
-K:172:0xB6:0x80
-
-# Enchant Weapon To-Hit
-K:173:0x86:0x80
-
-# Enchant Weapon To-Dam
-K:174:0x86:0x80
-
-# Enchant Armor
-K:175:0x86:0x80
-
-# Identify
-K:176:0x86:0x80
-
-# *Identify*
-K:177:0x86:0x82
-
-# Rumour
-K:178:0x86:0x80
-
-# Chaos
-K:179:0x86:0x80
-
-# Remove Curse
-K:180:0x86:0x80
-
-# Light
-K:181:0x86:0x80
-
-# Fire
-K:182:0x86:0x80
-
-# Ice
-K:183:0x86:0x80
-
-# Summon Monsters
-K:184:0x86:0x80
-
-# Phase Door
-K:185:0x86:0x80
-
-# Teleportation
-K:186:0x86:0x80
-
-# Teleport Level
-K:187:0x86:0x80
-
-# Monster Confusion
-K:188:0x86:0x80
-
-# Magic Mapping
-K:189:0x86:0x80
-
-# Rune of Protection
-K:190:0x86:0x82
-
-# *Remove Curse*
-K:191:0x86:0x82
-
-# Treasure Detection
-K:192:0x86:0x80
-
-# Object Detection
-K:193:0x86:0x80
-
-# Trap Detection
-K:194:0x86:0x80
-
-# & Sheaf Arrow~
-K:195:0xCD:0x84
-
-# & Mithril Shot~
-K:196:0xCD:0x85
-
-# Door/Stair Location
-K:197:0x86:0x80
-
-# Acquirement
-K:198:0x86:0x80
-
-# *Acquirement*
-K:199:0x86:0x82
-
-# Mass Genocide
-K:200:0x86:0x82
-
-# Detect Invisible
-K:201:0x86:0x80
-
-# Aggravation
-K:202:0x86:0x80
-
-# Trap Creation
-K:203:0x86:0x80
-
-# Trap/Door Destruction
-K:204:0x86:0x80
-
-# Artifact Creation
-K:205:0x86:0x82
-
-# Recharging
-K:206:0x86:0x81
-
-# Genocide
-K:207:0x86:0x81
-
-# Darkness
-K:208:0x86:0x80
-
-# Protection from Evil
-K:209:0x86:0x81
-
-# Satisfy Hunger
-K:210:0x86:0x80
-
-# Dispel Undead
-K:211:0x86:0x81
-
-# *Enchant Weapon*
-K:212:0x86:0x82
-
-# Curse Weapon
-K:213:0x86:0x82
-
-# *Enchant Armour*
-K:214:0x86:0x82
-
-# Curse Armour
-K:215:0x86:0x82
-
-# Summon Undead
-K:216:0x86:0x80
-
-# Blessing
-K:217:0x86:0x80
-
-# Holy Chant
-K:218:0x86:0x80
-
-# Holy Prayer
-K:219:0x86:0x81
-
-# Word of Recall
-K:220:0x86:0x80
-
-# *Destruction*
-K:221:0x86:0x82
-
-# Slime Mold Juice
-K:222:0xBC:0x85
-
-# Apple Juice
-K:223:0xBC:0x85
-
-# Water
-K:224:0xBC:0x85
-
-# Strength
-K:225:0xBC:0x86
-
-# Weakness
-K:226:0xBC:0x85
-
-# Restore Strength
-K:227:0xBC:0x86
-
-# Intelligence
-K:228:0xBC:0x86
-
-# Stupidity
-K:229:0xBC:0x85
-
-# Restore Intelligence
-K:230:0xBC:0x86
-
-# Wisdom
-K:231:0xBC:0x86
-
-# Naivety
-K:232:0xBC:0x85
-
-# Restore Wisdom
-K:233:0xBC:0x86
-
-# Charisma
-K:234:0xBC:0x86
-
-# Ugliness
-K:235:0xBC:0x86
-
-# Restore Charisma
-K:236:0xBC:0x86
-
-# Curing
-K:237:0xBC:0x86
-
-# Invulnerability
-K:238:0xBC:0x86
-
-# New Life
-K:239:0xBC:0x86
-
-# Cure Serious Wounds
-K:240:0xBC:0x85
-
-# Cure Critical Wounds
-K:241:0xBC:0x85
-
-# Healing
-K:242:0xBC:0x85
-
-# Constitution
-K:243:0xBC:0x86
-
-# Experience
-K:244:0xBC:0x87
-
-# Sleep
-K:245:0xBC:0x85
-
-# Blindness
-K:246:0xBC:0x85
-
-# Booze
-K:247:0xBC:0x85
-
-# Poison
-K:248:0xBC:0x85
-
-# Speed
-K:249:0xBC:0x85
-
-# Slowness
-K:250:0xBC:0x85
-
-# Dexterity
-K:251:0xBC:0x86
-
-# Restore Dexterity
-K:252:0xBC:0x86
-
-# Restore Constitution
-K:253:0xBC:0x86
-
-# Lose Memories
-K:254:0xBC:0x85
-
-# Salt Water
-K:255:0xBC:0x85
-
-# Enlightenment
-K:256:0xBC:0x85
-
-# Heroism
-K:257:0xBC:0x85
-
-# Berserk Strength
-K:258:0xBC:0x85
-
-# Boldness
-K:259:0xBC:0x85
-
-# Restore Life Levels
-K:260:0xBC:0x87
-
-# Resist Heat
-K:261:0xBC:0x85
-
-# Resist Cold
-K:262:0xBC:0x85
-
-# Detect Invisible
-K:263:0xBC:0x85
-
-# Slow Poison
-K:264:0xBC:0x85
-
-# Neutralise Poison
-K:265:0xBC:0x85
-
-# Restore Mana
-K:266:0xBC:0x86
-
-# Infra-vision
-K:267:0xBC:0x85
-
-# Resistance
-K:268:0xBC:0x85
-
-# Spell
-K:269:0xB7:0x8F
-
-# Manathrust
-K:270:0xB7:0x8F
-
-# Fireflash
-K:271:0xB7:0x8F
-
-# Firewall
-K:272:0xB7:0x90
-
-# Tidal Wave
-K:273:0xB7:0x8F
-
-# Ice Storm
-K:274:0xB7:0x8F
-
-# Noxious Cloud
-K:275:0xB7:0x8F
-
-# Poison Blood
-K:276:0xB7:0x8F
-
-# Thunderstorm
-K:277:0xB7:0x8F
-
-# Dig
-K:278:0xB7:0x8F
-
-# Stone Prison
-K:279:0xB7:0x8F
-
-# Strike
-K:280:0xB7:0x91
-
-# Teleport Away
-K:281:0xB7:0x8F
-
-# Summon Animal
-K:282:0xB7:0x8F
-
-# Magelock
-K:283:0xB7:0x90
-
-# Slow Monster
-K:284:0xB7:0x90
-
-# Essence of Speed
-K:285:0xB7:0x8F
-
-# Banishment
-K:286:0xB7:0x8F
-
-# Disperse Magic
-K:287:0xB7:0x90
-
-# Charm
-K:288:0xB7:0x90
-
-# Confuse
-K:289:0xB7:0x91
-
-# Demon Blade
-K:290:0xB7:0x8F
-
-# Heal Monster
-K:291:0xB7:0x91
-
-# Haste Monster
-K:292:0xB7:0x8F
-
-# & Flight Arrow~
-K:293:0xCD:0x86
-
-# & Boulder~
-K:295:0x85:0x97
-
-# & Flame~ Imperishable
-K:296:0x85:0x98
-
-# & Necromantic Teeth~
-K:297:0x85:0x99
-
-# & Golden Horn~ of the Eagles
-K:298:0xB7:0x91
-
-# Spell
-K:300:0xB9:0x99
-
-# Nothing
-K:301:0xB9:0x99
-
-# Globe of Light
-K:302:0xB9:0x99
-
-# Fiery Shield
-K:303:0xB9:0x99
-
-# Remove Curses
-K:304:0xB9:0x9A
-
-# Wings of Winds
-K:305:0xB9:0x99
-
-# Shake
-K:306:0xB9:0x99
-
-# Disarm
-K:307:0xB9:0x9B
-
-# Teleportation
-K:308:0xB9:0x99
-
-# Probability Travel
-K:309:0xB9:0x99
-
-# Recovery
-K:310:0xB9:0x99
-
-# Healing
-K:311:0xB9:0x99
-
-# Vision
-K:312:0xB9:0x99
-
-# Identify
-K:313:0xB9:0x99
-
-# Sense Hidden
-K:314:0xB9:0x9A
-
-# Reveal Ways
-K:315:0xB9:0x99
-
-# Sense Monsters
-K:316:0xB9:0x99
-
-# Genocide
-K:317:0xB9:0x9A
-
-# Summon
-K:318:0xB9:0x99
-
-# Sterilization
-K:319:0xB9:0x9A
-
-# Wish
-K:320:0xB9:0x9B
-
-# Mana
-K:321:0xB9:0x9A
-
-# & Tome~ of Magical Energy
-K:330:0xA3:0x8A
-
-# & Tome~ of the Eternal Flame
-K:331:0xA3:0x8A
-
-# & Tome~ of the Blowing Wind
-K:332:0xA3:0x8A
-
-# & Tome~ of the Impenetrable Earth
-K:333:0xA3:0x8A
-
-# & Tome~ of the Everrunning Wave
-K:334:0xA3:0x8C
-
-# & Tome~ of Translocation
-K:335:0xA3:0x8C
-
-# & Tome~ of the Tree
-K:336:0xA3:0x8C
-
-# & Tome~ of Knowledge
-K:337:0xA3:0x8C
-
-# & Small wooden chest~
-K:338:0x80:0x96
-
-# & Large wooden chest~
-K:339:0x80:0x97
-
-# & Small iron chest~
-K:340:0x80:0x98
-
-# & Large iron chest~
-K:341:0x80:0x99
-
-# & Small steel chest~
-K:342:0x80:0x9A
-
-# & Large steel chest~
-K:343:0x80:0x9B
-
-# & Ruined chest~
-K:344:0x80:0x9C
-
-# & Iron Spike~
-K:345:0x8B:0x84
-
-# & Wooden Torch~
-K:346:0x8B:0x86
-
-# & Brass Lantern~
-K:347:0x8B:0x85
-
-# & Flask~ of oil
-K:348:0xBC:0x90
-
-# & Empty Bottle~
-K:349:0x8A:0x99
-
-# Havoc
-K:350:0xB8:0x94
-
-# Door/Stair Location
-K:351:0xB8:0x94
-
-# Trap Location
-K:352:0xB8:0x94
-
-# Probing
-K:353:0xB8:0x97
-
-# Recall
-K:354:0xB8:0x96
-
-# Illumination
-K:355:0xB8:0x95
-
-# Light
-K:356:0xB8:0x94
-
-# Lightning Bolts
-K:357:0xB8:0x94
-
-# Frost Bolts
-K:358:0xB8:0x95
-
-# Fire Bolts
-K:359:0xB8:0x95
-
-# Polymorph
-K:360:0xB8:0x95
-
-# Slow Monster
-K:361:0xB8:0x95
-
-# Sleep Monster
-K:362:0xB8:0x95
-
-# Drain Life
-K:363:0xB8:0x97
-
-# Teleport Other
-K:364:0xB8:0x96
-
-# Disarming
-K:365:0xB8:0x95
-
-# Lightning Balls
-K:366:0xB8:0x96
-
-# Cold Balls
-K:367:0xB8:0x96
-
-# Fire Balls
-K:368:0xB8:0x97
-
-# Acid Balls
-K:369:0xB8:0x97
-
-# Acid Bolts
-K:370:0xB8:0x95
-
-# Enlightenment
-K:371:0xB8:0x97
-
-# Perception
-K:372:0xB8:0x96
-
-# Curing
-K:373:0xB8:0x97
-
-# Healing
-K:374:0xB8:0x97
-
-# Detection
-K:375:0xB8:0x95
-
-# Restoration
-K:376:0xB8:0x97
-
-# Speed
-K:377:0xB8:0x97
-
-# Spell
-K:378:0xA3:0x8E
-
-# Spell
-K:379:0x86:0x9E
-
-# & Broken Skull~
-K:391:0x8B:0x8A
-
-# & Broken Bone~
-K:392:0x8B:0x8B
-
-# & Canine Skeleton~
-K:393:0x8B:0x87
-
-# & Rodent Skeleton~
-K:394:0x8B:0x87
-
-# & Human Skeleton~
-K:395:0x8B:0x87
-
-# & Dwarf Skeleton~
-K:396:0x8B:0x87
-
-# & Elf Skeleton~
-K:397:0x8B:0x87
-
-# & Gnome Skeleton~
-K:398:0x8B:0x87
-
-# & Great Hammer~
-K:399:0xCD:0x87
-
-# Black Dragon Scale Mail~
-K:400:0x88:0x9F
-
-# Blue Dragon Scale Mail~
-K:401:0x88:0x9D
-
-# White Dragon Scale Mail~
-K:402:0x88:0x9E
-
-# Red Dragon Scale Mail~
-K:403:0x89:0x81
-
-# Green Dragon Scale Mail~
-K:404:0x89:0x80
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x89:0x82
-
-# Pseudo Dragon Scale Mail~
-K:406:0xBB:0x9C
-
-# Law Dragon Scale Mail~
-K:407:0x88:0x9F
-
-# Bronze Dragon Scale Mail~
-K:408:0x88:0x96
-
-# Gold Dragon Scale Mail~
-K:409:0x88:0x9C
-
-# Chaos Dragon Scale Mail~
-K:410:0x89:0x80
-
-# Balance Dragon Scale Mail~
-K:411:0x88:0x99
-
-# Power Dragon Scale Mail~
-K:412:0xA2:0x9E
-
-# & Dragon Helm~
-K:413:0xA2:0x9D
-
-# & Dragon Shield~
-K:414:0xA2:0x9C
-
-# Death
-K:415:0xBC:0x88
-
-# Ruination
-K:416:0xBC:0x87
-
-# Detonations
-K:417:0xBC:0x87
-
-# Augmentation
-K:418:0xBC:0x87
-
-# *Healing*
-K:419:0xBC:0x87
-
-# Life
-K:420:0xBC:0x88
-
-# Self Knowledge
-K:421:0xBC:0x87
-
-# *Enlightenment*
-K:422:0xBC:0x88
-
-# Fear Resistance
-K:425:0xB5:0x81
-
-# Light and Darkness Resistance
-K:426:0xB5:0x81
-
-# Nether Resistance
-K:427:0xB5:0x81
-
-# Nexus Resistance
-K:428:0xB5:0x81
-
-# Sound Resistance
-K:429:0xB5:0x81
-
-# Confusion Resistance
-K:430:0xB5:0x81
-
-# Shard Resistance
-K:431:0xB5:0x81
-
-# Disenchantment Resistance
-K:432:0xB5:0x81
-
-# Chaos Resistance
-K:433:0xB5:0x81
-
-# Blindness Resistance
-K:434:0xB5:0x81
-
-# Lordly Protection
-K:435:0xB5:0x81
-
-# Extra Attacks
-K:436:0xB5:0x81
-
-# Cure Light Wounds
-K:437:0xBC:0x85
-
-# Clumsiness
-K:438:0xBC:0x85
-
-# Sickliness
-K:439:0xBC:0x85
-
-# Map of Bree
-K:440:0xD8:0x81
-
-# Map of Gondolin
-K:441:0xD8:0x81
-
-# Map of Lothlorien
-K:442:0xD8:0x81
-
-# Map of Minas Anor
-K:443:0xD8:0x81
-
-# & Silver Arrow~
-K:465:0xCE:0x91
-
-# & Silver Bolt~
-K:466:0xCE:0x92
-
-# Lightning Resistance
-K:467:0x87:0x80
-
-# Wisdom
-K:468:0x87:0x80
-
-# Regeneration
-K:469:0x87:0x80
-
-# Infravision
-K:470:0x87:0x80
-
-# Devotion
-K:471:0x87:0x80
-
-# Weaponmastery
-K:472:0x87:0x80
-
-# Trickery
-K:473:0x87:0x80
-
-# Telepathy
-K:474:0x87:0x80
-
-# Sustenance
-K:475:0x87:0x80
-
-# & Palantir~
-K:476:0xD8:0x8F
-
-# & Elfstone~
-K:477:0xB6:0x8F
-
-# & Jewel~
-K:478:0xB6:0x90
-
-# & Ring~
-K:479:0xB5:0x8E
-
-# copper
-K:480:0x80:0x8B
-
-# copper
-K:481:0x80:0x8B
-
-# copper
-K:482:0x80:0x8B
-
-# silver
-K:483:0x80:0x8C
-
-# silver
-K:484:0x80:0x8C
-
-# silver
-K:485:0x80:0x8C
-
-# garnets
-K:486:0x80:0x8F
-
-# garnets
-K:487:0x80:0x8F
-
-# gold
-K:488:0x80:0x8D
-
-# gold
-K:489:0x80:0x8D
-
-# gold
-K:490:0x80:0x8D
-
-# opals
-K:491:0x80:0x90
-
-# sapphires
-K:492:0x80:0x91
-
-# rubies
-K:493:0x80:0x92
-
-# diamonds
-K:494:0x80:0x93
-
-# emeralds
-K:495:0x80:0x94
-
-# mithril
-K:496:0x80:0x8E
-
-# adamantite
-K:497:0xA3:0x95
-
-# & Mighty Hammer~
-K:498:0x87:0x9A
-
-# & Massive Iron Crown~
-K:499:0x87:0x9B
-
-# & Phial~
-K:500:0x87:0x9D
-
-# & Star~
-K:501:0x87:0x9E
-
-# & Arkenstone~
-K:502:0x87:0x9F
-
-# & Amulet~
-K:503:0xB6:0x82
-
-# & Amulet~
-K:504:0xB6:0x83
-
-# & Necklace~
-K:505:0xB6:0x84
-
-# & Ring~
-K:506:0xB5:0x83
-
-# & Ring~
-K:507:0xB5:0x83
-
-# & Ring~
-K:508:0xB5:0x84
-
-# & Ring~
-K:509:0xB5:0x85
-
-# & Ring~
-K:510:0xB5:0x86
-
-# & Ring~
-K:511:0xB5:0x87
-
-# Reflection
-K:520:0xB6:0x80
-
-# Anti-Magic
-K:521:0xB6:0x80
-
-# Anti-Teleportation
-K:522:0xB6:0x80
-
-# Resistance
-K:523:0xB6:0x80
-
-# & Zweihander~
-K:524:0xCD:0x88
-
-# & Dwarven Lantern~
-K:525:0xD8:0x86
-
-# Splint Mail~
-K:526:0xCD:0x8A
-
-# & Everburning Torch~
-K:527:0xD8:0x87
-
-# & Trifurcate Spear~
-K:528:0xCD:0x96
-
-# & Three-Piece Rod~
-K:529:0xCD:0x8C
-
-# & Feanorian Lamp~
-K:530:0xD8:0x85
-
-# & Fur Cloak~
-K:531:0xCD:0x8E
-
-# Water Curing
-K:532:0xBC:0x84
-
-# & Hatchet~
-K:533:0xCD:0x90
-
-# Mumak Hide Armour~
-K:535:0xCD:0x91
-
-# & Leather Jerkin~
-K:536:0xCD:0x92
-
-# & Sickle~
-K:537:0xCD:0x93
-
-# & Club~
-K:542:0xCD:0x99
-
-# & Broad Spear~
-K:543:0xCD:0x9A
-
-# & Khopesh~
-K:544:0xCD:0x9B
-
-# & Flamberge~
-K:545:0xCD:0x9C
-
-# & Claymore~
-K:546:0xCD:0x9D
-
-# & Espadon~
-K:547:0xCD:0x9E
-
-# & Great Scimitar~
-K:548:0xCD:0x9F
-
-# Arrow
-K:549:0xD7:0x84
-
-# Bolt
-K:550:0xD7:0x83
-
-# & Fauchard~
-K:551:0xCE:0x82
-
-# & Guisarme~
-K:552:0xCE:0x83
-
-# & Heavy Lance~
-K:553:0xCE:0x84
-
-# & Bardiche~
-K:554:0xCE:0x85
-
-# Catapult
-K:555:0xD7:0x82
-
-# Ring Mail~
-K:556:0xCE:0x87
-
-# Cord Armour~
-K:557:0xCE:0x88
-
-# Paper Armour~
-K:558:0xCE:0x89
-
-# Padded Armour~
-K:559:0xCE:0x8A
-
-# Fumes
-K:560:0xD7:0x80
-
-# Golden Ring Mail~
-K:561:0x87:0x98
-
-# Magic
-K:562:0xD7:0x81
-
-# Device
-K:563:0xD7:0x85
-
-# Nothing
-K:569:0xB8:0x95
-
-# & Blood~ of Life
-K:573:0x87:0x88
-
-# & Mage Staff~
-K:577:0xCE:0x97
-
-# Lightning
-K:578:0xB5:0x81
-
-# & Ring~
-K:582:0xB5:0x8F
-
-# Invisibility
-K:583:0xB8:0x85
-
-# Corruption
-K:585:0xB8:0x85
-
-# Invisibility
-K:586:0xB5:0x81
-
-# Deep Thoughts
-K:588:0xD8:0x80
-
-# More Deep Thoughts
-K:589:0xD8:0x80
-
-# Compendium of Deep Thoughts
-K:590:0xD8:0x80
-
-# Artifact Lore Vol. I
-K:591:0xD8:0x80
-
-# Artifact Lore Vol. II
-K:592:0xD8:0x80
-
-# Artifact Lore Vol. III
-K:593:0xD8:0x80
-
-# Monstrous Compendium 1
-K:594:0xD8:0x80
-
-# Monstrous Compendium 2
-K:595:0xD8:0x80
-
-# Monstrous Compendium 3
-K:596:0xD8:0x80
-
-# Monstrous Compendium 4
-K:597:0xD8:0x80
-
-# Monstrous Compendium 5
-K:598:0xD8:0x80
-
-# Monstrous Compendium 6
-K:599:0xD8:0x80
-
-# Monstrous Compendium 7
-K:600:0xD8:0x80
-
-# Monstrous Compendium 8
-K:601:0xD8:0x80
-
-# Monstrous Compendium 9
-K:602:0xD8:0x80
-
-# Monstrous Compendium 10
-K:603:0xD8:0x80
-
-# Monstrous Compendium 11
-K:604:0xD8:0x80
-
-# & Morphic Oil~ of #
-K:605:0xBC:0x85
-
-# Artifact Lore Vol. IV
-K:607:0xD8:0x80
-
-# Artifact Lore Vol. V
-K:608:0xD8:0x80
-
-# Artifact Lore Vol. VI
-K:609:0xD8:0x80
-
-# Artifact Lore Vol. VII
-K:610:0xD8:0x80
-
-# Artifact Lore Vol. VIII
-K:611:0xD8:0x80
-
-# Artifact Lore Vol. IX
-K:612:0xD8:0x80
-
-# Artifact Lore Vol. X
-K:613:0xD8:0x80
-
-# Artifact Lore Vol. XI
-K:614:0xD8:0x80
-
-# Artifact Lore Vol. IX
-K:615:0xD8:0x80
-
-# Artifact Lore Vol. X
-K:616:0xD8:0x80
-
-# Artifact Lore Vol. XI
-K:617:0xD8:0x80
-
-# & #~
-K:618:0xCE:0x93
-
-# corpse
-K:641:0xB4:0x90
-
-# skeleton
-K:642:0xB4:0x8B
-
-# head
-K:643:0xB4:0x8E
-
-# skull
-K:644:0xB4:0x8F
-
-# raw meat
-K:645:0xB4:0x8C
-
-# & Great Eagle Down Coat~
-K:646:0xCE:0x98
-
-# & Key~
-K:647:0xD8:0x90
-
-# & Small Wooden Boomerang~
-K:648:0xCE:0x99
-
-# & Wooden Boomerang~
-K:649:0xCE:0x9A
-
-# & Small Metal Boomerang~
-K:650:0xCE:0x9B
-
-# & Metal Boomerang~
-K:651:0xCE:0x9C
-
-# & Anchor~
-K:652:0xD8:0x91
-
-# & ~
-K:653:0x87:0x99
-
-# Summon Never-Moving Pet
-K:654:0x86:0x80
-
-# Cure Light Insanity
-K:657:0xBC:0x85
-
-# Cure Serious Insanity
-K:658:0xBC:0x85
-
-# Cure Critical Insanity
-K:659:0xBC:0x85
-
-# Cure Insanity
-K:660:0xBC:0x85
-
-# & Phial~
-K:661:0x87:0x9D
-
-# Junkart
-K:662:0x87:0x9C
-
-# Craftsmanship
-K:663:0x86:0x82
-
-# The One Ring
-K:664:0xD8:0x81
-
-# & Horn~
-K:669:0xD8:0x88
-
-# & Drum~
-K:670:0xD8:0x89
-
-# & Harp~
-K:671:0xD8:0x8A
-
-# & Palantir~
-K:675:0xD8:0x8F
-
-# Egg
-K:676:0xD8:0x84
-
-# Reset Recall
-K:677:0x86:0x81
-
-# Divination
-K:678:0x86:0x81
-
-# Self
-K:679:0xDA:0x80
-
-# Ray
-K:680:0xDA:0x80
-
-# Sphere
-K:681:0xDA:0x80
-
-# Knowledge
-K:682:0xDA:0x80
-
-# Life
-K:683:0xDA:0x84
-
-# Fire
-K:684:0xDA:0x81
-
-# Cold
-K:685:0xDA:0x80
-
-# Lightning
-K:686:0xDA:0x85
-
-# Acid
-K:687:0xDA:0x88
-
-# Element
-K:688:0xDA:0x89
-
-# Chaos
-K:689:0xDA:0x83
-
-# Mind
-K:690:0xDA:0x84
-
-# Holding
-K:691:0xDA:0x84
-
-# Arrow
-K:692:0xDA:0x80
-
-# Power Surge
-K:693:0xDA:0x80
-
-# Armageddon
-K:694:0xDA:0x80
-
-# Gravity
-K:695:0xDA:0x82
-
-# Undeath
-K:697:0xDA:0x82
-
-# Protection
-K:698:0xDA:0x82
-
-# & Ring~ of Precognition
-K:700:0xB5:0x8E
-
-# & Sprig~ of Athelas
-K:701:0xCE:0x96
-
-# & Old Scroll~ of Deincarnation
-K:720:0x86:0x82
-
-# & Dark Sword~
-K:721:0xCE:0x9D
-
-# Numenorean for Beginners (I)
-K:722:0xD8:0x81
-
-# Numenorean for Beginners (II)
-K:723:0xD8:0x81
-
-# Advanced Lessons of Numenorean
-K:724:0xD8:0x81
-
-# Advanced Lessons of Sindarin
-K:725:0xD8:0x81
-
-# & Shard~ of Pottery
-K:726:0x8B:0x88
-
-# & Broken Stick~
-K:727:0x8B:0x89
-
-# & Book~ of Beginner Cantrips
-K:738:0xA3:0x8B
-
-# & Book~ of Teleportation
-K:739:0xA3:0x8B
-
-# & Book~ of Summoning
-K:741:0xA3:0x8B
-
-# & Potion~ of Learning
-K:743:0x87:0x86
-
-# Khuzdul - The Hidden Tongue of the Dwarves
-K:751:0xD8:0x81
-
-# Nandorin for Dummies
-K:752:0xD8:0x81
-
-# Advanced Lessons of Orcish
-K:753:0xD8:0x81
-
-# Flying
-K:755:0xB5:0x80
-
-# & Tome~ of the Time
-K:756:0xA3:0x8D
-
-# & Spellbook~ of #
-K:757:0xA3:0x8A
-
-# & Tome~ of Meta Spells
-K:758:0xA3:0x8D
-
-# & Tome~ of the Mind
-K:759:0xA3:0x8D
-
-# & Holy Tome~ of Eru Iluvatar
-K:760:0xA3:0x8B
-
-# & Holy Tome~ of Manwe Sulimo
-K:761:0xA3:0x8C
-
-# & War Tome~ of Tulkas
-K:762:0xA3:0x90
-
-# & Unholy Tome~ of the Hellflame
-K:763:0xA3:0x91
-
-# & Corrupted Tome~ of Melkor
-K:764:0xA3:0x91
-
-# & Earth Tome~ of Aule
-K:765:0xA3:0x92
-
-# & Shining Tome~ of Varda
-K:766:0xA3:0x8B
-
-# & Water Tome~ of Ulmo
-K:767:0xA3:0x8D
-
-# & Forest Tome~ of Yavanna
-K:768:0xA3:0x8F
-
-# Tome of#
-K:769:0xA3:0x8F
-
-# & Ring~
-K:770:0xB5:0x8E
-
-# & Holy Tome~ of Mandos
-K:771:0xA3:0x8A
-
-# & Great Rod Tip~ of Home Summoning
-K:776:0xB8:0x84
-
-# & Shadow Blade~
-K:777:0xCD:0x9C
-
-# & Bluesteel Blade~
-K:778:0xCE:0x9E
-
-# the Serpents
-K:779:0xB6:0x9F
-
-# Ring~ of Power
-K:785:0xB5:0x85
-
-# Climbing Set~
-K:786:0xD8:0x92
-
-# Adventurer's Guide to Middle-earth
-K:787:0xD8:0x80
-
-# & Demonblade~
-K:788:0xCE:0x94
-
-# & Demonshield~
-K:789:0xCE:0x94
-
-# & Demonhorn~
-K:790:0xCE:0x95
-
-# & Wooden Rod~ of#
-K:793:0xDB:0x80
-
-# & Copper Rod~ of#
-K:794:0xDB:0x81
-
-# & Iron Rod~ of#
-K:795:0xDB:0x82
-
-# & Moonstone Rod~ of#
-K:796:0xDB:0x83
-
-# & Silver Rod~ of#
-K:797:0xDB:0x84
-
-# & Golden Rod~ of#
-K:798:0xDB:0x85
-
-# & Mithril Rod~ of#
-K:799:0xDB:0x86
-
-# & Tilkal Rod~ of#
-K:800:0xDB:0x87
-
-# & Greater Ration~ of Health
-K:801:0x8A:0x9E
-
-# & Crumpled Scroll~ of Mass Resurrection
-K:802:0x86:0x82
-
-# & Cleaver~
-K:803:0xD8:0x93
-
-# & Light War Axe~
-K:804:0xD8:0x94
-
-# & Slaughter Axe~
-K:805:0xD8:0x95
-
-# & Runestone~
-K:806:0xDA:0x83
-
-# & Fortune cookie~
-K:807:0x8A:0x93
-
-# Critical Hits
-K:809:0xB5:0x82
-
-# & Wand~ of Digging of Thrain
-K:810:0xB8:0x97
-
-# & Gnarled Staff~ of Holy Fire of Mithrandir
-K:811:0xCE:0x9F
-
-# Partial Totem
-K:812:0xB4:0x82
-
-# True Totem
-K:813:0xB4:0x85
-
-# & Piece~ of the Relic of Eru
-K:814:0x8B:0x91
-
-# & Piece~ of the Relic of Manwe
-K:815:0x8B:0x92
-
-# & Piece~ of the Relic of Tulkas
-K:816:0x8B:0x93
-
-# & Piece~ of the Relic of Melkor
-K:817:0x8B:0x94
-
-# & Piece~ of the Relic of Yavanna
-K:818:0x8B:0x95
-
-# & Ring~
-K:819:0xB5:0x82
-
-# & Ring~
-K:820:0xB5:0x82
-
-# & Ring~
-K:821:0xB5:0x82
-
-# & Ring~
-K:822:0xB5:0x82
-
-# & Ring~
-K:823:0xB5:0x82
-
-# & Ring~
-K:824:0xB5:0x82
-
-# & Piece~ of the Relic of Aule
-K:825:0x8B:0x96
-
-# & Piece~ of the Relic of Varda
-K:826:0x8B:0x97
-
-# & Piece~ of the Relic of Ulmo
-K:827:0x8B:0x98
-
-# & Piece~ of the Relic of Mandos
-K:828:0x8B:0x99
-
-# & Pinch~ of Longbottom Leaf
-K:831:0x87:0x8C
-
-# & Ear~ of Corn
-K:832:0x85:0x9A
-
-# & Tater~
-K:833:0x85:0x9B
-
-# & Strawberry~
-K:834:0x85:0x9C
-
-# & Turnip~
-K:835:0x85:0x9D
-
-# & Jar~ of Honey
-K:836:0x85:0x9E
-
-# & Jug~ of Milk
-K:837:0x85:0x9F
-
-# of War
-K:838:0xB9:0x9A
-
-# of Life
-K:839:0xB9:0x9C
-
-# Wizardry
-K:840:0x82:0x81
-
-# Vitality
-K:841:0x82:0x81
-
-# Clear Thought
-K:842:0x00:0x3D
-
-# Clumsiness
-K:843:0x82:0x81
-
-# Sickliness
-K:844:0x82:0x81
-
-# Fortune
-K:845:0x82:0x7F
-
-# Sterilise
-K:846:0xA3:0x92
-
-# Map of Middle-earth
-K:847:0xA3:0x92
-
-# Map of Edoras
-K:848:0xD8:0x81
-
-# Map of Esgaroth
-K:849:0xD8:0x81
-
-# Map of Hobbiton
-K:850:0xD8:0x81
-
-# Map of Osgiliath
-K:851:0xD8:0x81
-
-# Map of Pelargir
-K:852:0xD8:0x81
-
-# Map of Beorn's domain
-K:853:0xD8:0x81
-
-# Map of Dale
-K:854:0xD8:0x81
-
-# Map of Henneth Annun
-K:855:0xD8:0x81
-
-# Map of Helm's Deep
-K:856:0xD8:0x81
-
-# Map of Thranduil's realm
-K:857:0xD8:0x81
-
-# Map of Imladris
-K:858:0xD8:0x81
-
-# & Bearded Axe~
-K:859:0x87:0x90
-
-# & Double Axe~
-K:860:0x87:0x91
-
-# & Crusader Axe~
-K:861:0x87:0x92
-
-# & Reaper Axe~
-K:862:0x87:0x93
-
-# & Mithril Helm~
-K:863:0x8B:0x9A
-
-# & Set~ of Mithril Gauntlets
-K:864:0x8B:0x9B
-
-# & Small Mithril Shield~
-K:865:0x8B:0x9C
-
-# & Large Mithril Shield~
-K:866:0x8B:0x9D
-
-# & Map~
-K:867:0xA3:0x92
-
-# & Key~
-K:868:0x87:0x8D
-
-# & Cup~
-K:869:0x87:0x8E
-
-# & Red Arrow~
-K:870:0x87:0x8F
-
-# & Sceptre~
-K:871:0x86:0x91
-
-# & Rod~
-K:872:0x86:0x90
-
-# & Necklace~
-K:873:0x86:0x9F
-
-# & Amulet~
-K:874:0x86:0x9E
-
-# & Black Banner~
-K:875:0x87:0x94
-
-# & Pearl~
-K:876:0x87:0x95
-
-# & Silmaril~
-K:877:0x87:0x96
-
-# & Silmaril~
-K:878:0x87:0x97
-
-# & Golden Harp~
-K:879:0xD9:0x8A
-
-# Player
-R:0:0x8C/0x81
-
-# Spells (*)
-S:0x30:0x85/0x93
-S:0x31:0x85/0x92
-S:0x32:0x85/0x92
-S:0x33:0x85/0x8D
-S:0x34:0x85/0x8C
-S:0x35:0x85/0x8F
-S:0x36:0x85/0x90
-S:0x37:0x85/0x95
-S:0x38:0x85/0x93
-S:0x39:0x85/0x92
-S:0x3A:0x85/0x91
-S:0x3B:0x85/0x8E
-S:0x3C:0x85/0x8D
-S:0x3D:0x85/0x8F
-S:0x3E:0x85/0x90
-S:0x3F:0x85/0x95
-
-# Spells (|)
-S:0x40:0x84/0x9C
-S:0x41:0x84/0x98
-S:0x42:0x84/0x98
-S:0x43:0x85/0x88
-S:0x44:0x84/0x80
-S:0x45:0x84/0x8C
-S:0x46:0x84/0x90
-S:0x47:0x85/0x84
-S:0x48:0x84/0x9C
-S:0x49:0x84/0x98
-S:0x4A:0x84/0x94
-S:0x4B:0x84/0x88
-S:0x4C:0x85/0x88
-S:0x4D:0x84/0x8C
-S:0x4E:0x84/0x90
-S:0x4F:0x85/0x84
-
-# Spells (-)
-S:0x50:0x84/0x9D
-S:0x51:0x84/0x99
-S:0x52:0x84/0x99
-S:0x53:0x85/0x89
-S:0x54:0x84/0x81
-S:0x55:0x84/0x8D
-S:0x56:0x84/0x91
-S:0x57:0x85/0x85
-S:0x58:0x84/0x9D
-S:0x59:0x84/0x99
-S:0x5A:0x84/0x95
-S:0x5B:0x84/0x89
-S:0x5C:0x85/0x89
-S:0x5D:0x84/0x8D
-S:0x5E:0x84/0x91
-S:0x5F:0x85/0x85
-
-# Spells (:)
-S:0x60:0x84/0x9E
-S:0x61:0x84/0x9A
-S:0x62:0x84/0x9A
-S:0x63:0x85/0x8A
-S:0x64:0x84/0x82
-S:0x65:0x84/0x8E
-S:0x66:0x84/0x92
-S:0x67:0x85/0x86
-S:0x68:0x84/0x9E
-S:0x69:0x84/0x9A
-S:0x6A:0x84/0x96
-S:0x6B:0x84/0x8A
-S:0x6C:0x85/0x8A
-S:0x6D:0x84/0x8E
-S:0x6E:0x84/0x92
-S:0x6F:0x85/0x86
-
-# Spells (\)
-S:0x70:0x84/0x9F
-S:0x71:0x84/0x9B
-S:0x72:0x84/0x9B
-S:0x73:0x85/0x8B
-S:0x74:0x84/0x83
-S:0x75:0x84/0x8F
-S:0x76:0x84/0x93
-S:0x77:0x85/0x87
-S:0x78:0x84/0x9F
-S:0x79:0x84/0x9B
-S:0x7A:0x84/0x97
-S:0x7B:0x84/0x8B
-S:0x7C:0x85/0x8B
-S:0x7D:0x84/0x8F
-S:0x7E:0x84/0x93
-S:0x7F:0x85/0x87
-
-# Amulets (")
-S:0x80:0xB6/0x87
-S:0x81:0xB6/0x88
-S:0x82:0xB6/0x85
-S:0x83:0xB6/0x86
-S:0x84:0xB6/0x81
-S:0x85:0xB6/0x82
-S:0x86:0xB6/0x83
-S:0x87:0xB6/0x84
-S:0x88:0xB6/0x87
-S:0x89:0xB6/0x88
-S:0x8A:0xB6/0x8E
-S:0x8B:0xB6/0x86
-S:0x8C:0xB6/0x81
-S:0x8D:0xB6/0x82
-S:0x8E:0xB6/0x8B
-S:0x8F:0xB6/0x8C
-
-# Rings (=)
-S:0x90:0xB5/0x8B
-S:0x91:0xB5/0x8C
-S:0x92:0xB5/0x89
-S:0x93:0xB5/0x8A
-S:0x94:0xB5/0x81
-S:0x95:0xB5/0x82
-S:0x96:0xB5/0x83
-S:0x97:0xB5/0x88
-S:0x98:0xB5/0x8B
-S:0x99:0xB5/0x8C
-S:0x9A:0xB5/0x80
-S:0x9B:0xB5/0x8A
-S:0x9C:0xB5/0x81
-S:0x9D:0xB5/0x82
-S:0x9E:0xB5/0x83
-S:0x9F:0xB5/0x88
-
-# Staffs (_)
-S:0xA0:0xB9/0x84
-S:0xA1:0xB9/0x85
-S:0xA2:0xB9/0x85
-S:0xA3:0xB9/0x81
-S:0xA4:0xB9/0x81
-S:0xA5:0xB9/0x82
-S:0xA6:0xB9/0x80
-S:0xA7:0xB9/0x87
-S:0xA8:0xB9/0x84
-S:0xA9:0xB9/0x85
-S:0xAA:0xB9/0x83
-S:0xAB:0xB9/0x87
-S:0xAC:0xB9/0x81
-S:0xAD:0xB9/0x82
-S:0xAE:0xB9/0x80
-S:0xAF:0xB9/0x87
-
-# Wands (-)
-S:0xB0:0xB7/0x84
-S:0xB1:0xB7/0x85
-S:0xB2:0xB7/0x85
-S:0xB3:0xB7/0x86
-S:0xB4:0xB7/0x81
-S:0xB5:0xB7/0x82
-S:0xB6:0xB7/0x80
-S:0xB7:0xB7/0x87
-S:0xB8:0xB7/0x84
-S:0xB9:0xB7/0x85
-S:0xBA:0xB7/0x83
-S:0xBB:0xB7/0x86
-S:0xBC:0xB7/0x81
-S:0xBD:0xB7/0x82
-S:0xBE:0xB7/0x80
-S:0xBF:0xB7/0x87
-
-# Rods (-)
-S:0xC0:0xB8/0x84
-S:0xC1:0xB8/0x85
-S:0xC2:0xB8/0x85
-S:0xC3:0xB8/0x86
-S:0xC4:0xB8/0x81
-S:0xC5:0xB8/0x82
-S:0xC6:0xB8/0x80
-S:0xC7:0xB8/0x87
-S:0xC8:0xB8/0x84
-S:0xC9:0xB8/0x85
-S:0xCA:0xB8/0x83
-S:0xCB:0xB8/0x86
-S:0xCC:0xB8/0x81
-S:0xCD:0xB8/0x82
-S:0xCE:0xB8/0x80
-S:0xCF:0xB8/0x87
-
-# 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:0xBC/0x84
-S:0xE1:0xBC/0x83
-S:0xE2:0xBC/0x8A
-S:0xE3:0xBC/0x8B
-S:0xE4:0xBC/0x87
-S:0xE5:0xBC/0x86
-S:0xE6:0xBC/0x85
-S:0xE7:0xBC/0x89
-S:0xE8:0xBC/0x84
-S:0xE9:0xBC/0x83
-S:0xEA:0xBC/0x8E
-S:0xEB:0xBC/0x88
-S:0xEC:0xBC/0x8B
-S:0xED:0xBC/0x8C
-S:0xEE:0xBC/0x8D
-S:0xEF:0xBC/0x89
-
-# Food (,)
-S:0xF0:0xBA/0x84
-S:0xF1:0xBA/0x85
-S:0xF2:0xBA/0x85
-S:0xF3:0xBA/0x86
-S:0xF4:0xBA/0x81
-S:0xF5:0xBA/0x82
-S:0xF6:0xBA/0x80
-S:0xF7:0xBA/0x87
-S:0xF8:0xBA/0x84
-S:0xF9:0xBA/0x85
-S:0xFA:0xBA/0x83
-S:0xFB:0xBA/0x86
-S:0xFC:0xBA/0x81
-S:0xFD:0xBA/0x82
-S:0xFE:0xBA/0x80
-S:0xFF:0xBA/0x87
-
-# Unknown Amulet
-U:40:0xB6/0x81
-
-# Unknown Ring
-U:45:0xB5/0x81
-
-# Unknown Staff
-U:55:0xB9/0x81
-
-# Unknown Wand
-U:65:0xB7/0x81
-
-# Unknown Rod
-U:66:0xB8/0x81
-
-# Unknown Scroll
-U:70:0x86/0x82
-
-# Unknown Potion
-U:75:0xBC/0x85
-
-# Unknown Food
-U:80:0x8B/0x81
-# non-defines encountered :
-# Load the Trap image definitions
-%:trap-xxx.prf
diff --git a/lib/mods/theme/pref/graf.prf b/lib/mods/theme/pref/graf.prf
deleted file mode 100644
index a82ce364..00000000
--- a/lib/mods/theme/pref/graf.prf
+++ /dev/null
@@ -1,51 +0,0 @@
-# File: graf.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# This file includes, if appropriate, various "sub-files"
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-##### Standard font file #####
-
-%:font-xxx.prf
-
-
-##### System Specific Subfiles #####
-
-?:[IOR [EQU $SYS xaw] [EQU $SYS x11] [EQU $SYS gtk]]
-%:graf-x11.prf
-
-?:[EQU $SYS gcu]
-%:graf-gcu.prf
-
-?:[EQU $SYS ami]
-%:graf-ami.prf
-
-?:[EQU $SYS mac]
-%:graf-mac.prf
-
-?:[EQU $SYS dos]
-%:graf-dos.prf
-
-?:[EQU $SYS win]
-%:graf-win.prf
-
-?:[EQU $SYS ibm]
-%:graf-ibm.prf
-
-?:[EQU $SYS emx]
-%:graf-emx.prf
-
-?:[EQU $SYS acn]
-%:graf-acn.prf
-
-?:[EQU $SYS sdl]
-%:graf-sdl.prf
-
-?:1
-
-
diff --git a/lib/mods/theme/user/all.prf b/lib/mods/theme/user/all.prf
index fbb9de81..67671aa4 100644
--- a/lib/mods/theme/user/all.prf
+++ b/lib/mods/theme/user/all.prf
@@ -23,27 +23,6 @@ Y:prompt_pickup_heavy
# Option 'Repeat obvious commands'
Y:always_repeat
-# Option 'Show dungeon level in feet'
-X:depth_in_feet
-
-# Option 'Merge inscriptions when stacking'
-Y:stack_force_notes
-
-# Option 'Merge discounts when stacking'
-Y:stack_force_costs
-
-# Option 'Show labels in object listings'
-Y:show_labels
-
-# Option 'Show weights in object listings'
-Y:show_weights
-
-# Option 'Show choices in certain sub-windows'
-Y:show_choices
-
-# Option 'Show details in certain sub-windows'
-Y:show_details
-
# Option 'Audible bell (on errors, etc)'
X:ring_bell
@@ -92,12 +71,6 @@ Y:alert_failure
# Option 'Get last words when the character dies'
Y:last_words
-# Option 'Allow shopkeepers and uniques to speak'
-Y:speak_unique
-
-# Option 'No query to destroy known worthless items'
-Y:auto_destroy
-
# Option 'Confirm to wear/wield known cursed items'
Y:confirm_wear
@@ -122,12 +95,6 @@ Y:auto_haggle
# Option 'Auto-scum for good levels'
Y:auto_scum
-# Option 'Allow weapons and armour to stack'
-Y:stack_allow_items
-
-# Option 'Allow wands/staffs/rods to stack'
-Y:stack_allow_wands
-
# Option 'Expand the power of the look command'
Y:expand_look
@@ -152,18 +119,9 @@ Y:dungeon_stair
# Option 'Monsters chase current location (v.slow)'
X:flow_by_sound
-# Option 'Use special symbols for the player char'
-X:player_symbols
-
-# Option 'Plain object descriptions'
-Y:plain_descriptions
-
# Option 'Monsters learn from their mistakes'
X:smart_learn
-# Option 'Monsters exploit players weaknesses'
-X:smart_cheat
-
# Option 'Allow unusually small dungeon levels'
Y:small_levels
@@ -173,9 +131,6 @@ Y:empty_levels
# Option 'Reduce lite-radius when running'
X:view_reduce_lite
-# Option 'Reduce view-radius in town'
-X:view_reduce_view
-
# Option 'Avoid checking for user abort'
X:avoid_abort
@@ -227,9 +182,6 @@ X:center_player
# Option 'Ingame contextual help'
X:ingame_help
-# Option 'Show the experience needed for next level'
-X:exp_need
-
# Option 'Use the old(Z) coloring scheme(reload the game)'
X:old_colors
diff --git a/lib/pref/graf-ami.prf b/lib/pref/graf-ami.prf
deleted file mode 100644
index d9b1b356..00000000
--- a/lib/pref/graf-ami.prf
+++ /dev/null
@@ -1,64 +0,0 @@
-# File: graf-ami.prf
-
-#
-# This file contains color definitions and
-# graphics remapping for the Amiga version.
-#
-# Lars Haugseth <larshau@ifi.uio.no>
-#
-
-
-# Color palette - Graphics
-V:0:0x01:0x00:0x00:0x00
-V:1:0x01:0xF0:0xE0:0xD0
-V:2:0x01:0x80:0x80:0x80
-V:3:0x01:0x50:0x50:0x50
-V:4:0x01:0xE0:0xB0:0x00
-V:5:0x01:0xC0:0xA0:0x70
-V:6:0x01:0x80:0x60:0x40
-V:7:0x01:0x40:0x30:0x20
-V:8:0x01:0x00:0xA0:0xF0
-V:9:0x01:0x00:0x00:0xF0
-V:10:0x01:0x00:0x00:0x70
-V:11:0x01:0xF0:0x00:0x00
-V:12:0x01:0x80:0x00:0x00
-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
-V:17:0x01:0xFF:0xFF:0xFF
-V:18:0x01:0xC7:0xC7:0xC7
-V:19:0x01:0xFF:0x92:0x00
-V:20:0x01:0xFF:0x00:0x00
-V:21:0x01:0x00:0xCD:0x00
-V:22:0x01:0x00:0x00:0xFE
-V:23:0x01:0xC8:0x64:0x00
-V:24:0x01:0x8A:0x8A:0x8A
-V:25:0x01:0xE0:0xE0:0xE0
-V:26:0x01:0xA5:0x00:0xFF
-V:27:0x01:0xFF:0xFD:0x00
-V:28:0x01:0xFF:0x00:0xBC
-V:29:0x01:0x00:0xFF:0x00
-V:30:0x01:0x00:0xC8:0xFF
-V:31:0x01:0xFF:0xCC:0x80
-
-
-# Standard file
-%:graf-xxx.prf
-
-
-### Feature attr/char definitions
-
-# nothing
-F:0:0x01/0x20
-
-# open floor
-F:1:0x81/0x8E
-
-# invis trap
-F:2:0x81/0x8E
-
-
diff --git a/lib/pref/graf-dos.prf b/lib/pref/graf-dos.prf
deleted file mode 100644
index 41f38c76..00000000
--- a/lib/pref/graf-dos.prf
+++ /dev/null
@@ -1,15 +0,0 @@
-# File: graf-win.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/pref/graf-iso.prf b/lib/pref/graf-iso.prf
deleted file mode 100644
index 05bc8621..00000000
--- a/lib/pref/graf-iso.prf
+++ /dev/null
@@ -1,6878 +0,0 @@
-%:trap-iso.prf
-
-# General Store
-B:0:0x80:0xB1
-
-# Armoury
-B:1:0x80:0xB2
-
-# Weapon Smiths
-B:2:0x80:0xB3
-
-# Temple
-B:3:0x80:0xB4
-
-# Alchemy Shop
-B:4:0x80:0xB5
-
-# Magic Shop
-B:5:0x80:0xB6
-
-# Black Market
-B:6:0x80:0xB7
-
-# Home
-B:7:0x80:0xB8
-
-# Bookstore
-B:8:0x80:0xB9
-
-# Pet shop
-B:9:0x80:0xAB
-
-# Mayors office
-B:10:0x80:0xAB
-
-# Inn
-B:11:0x80:0xB0
-
-# The Soothsayer
-B:12:0x80:0xAB
-
-# Library
-B:13:0x80:0xAB
-
-# Castle
-B:14:0x80:0xAB
-
-# Casino
-B:15:0x80:0xAB
-
-# Beastmaster Shanty
-B:16:0x80:0xAB
-
-# Fighters Hall
-B:17:0x80:0xAB
-
-# Tower of Magery
-B:18:0x80:0xAB
-
-# Inner Temple
-B:19:0x80:0xAB
-
-# Paladins Guild
-B:20:0x80:0xAB
-
-# Rangers Guild
-B:21:0x80:0xAB
-
-# Thunderlords' Hide
-B:22:0x80:0xAB
-
-# The Mirror
-B:23:0x80:0xAB
-
-# Seat of Ruling
-B:24:0x80:0xAB
-
-# Wizards Spire
-B:25:0x80:0xAB
-
-# Priests Circle
-B:26:0x80:0xAB
-
-# Tower of the King
-B:27:0x80:0xAB
-
-# Library
-B:28:0x80:0xAB
-
-# The White Tree
-B:29:0x80:0xAB
-
-# Craftsmaster
-B:30:0x80:0xAB
-
-# Earth-Dome (Nature)
-B:31:0x80:0xAB
-
-# Minstrels Haven
-B:32:0x80:0xAB
-
-# Star-Dome
-B:33:0x80:0xAB
-
-# Valarin Temple
-B:34:0x80:0xAB
-
-# Sea-Dome
-B:35:0x80:0xAB
-
-# The Golden Flower
-B:36:0x80:0xAB
-
-# The Fountain
-B:37:0x80:0xAB
-
-# Axe Smith
-B:38:0x80:0xAB
-
-# Hafted Smith
-B:39:0x80:0xAB
-
-# Polearm Smith
-B:40:0x80:0xAB
-
-# Sword Smith
-B:41:0x80:0xAB
-
-# Rare Jewelry Shop
-B:42:0x80:0xAB
-
-# Jewelry Shop
-B:43:0x80:0xAB
-
-# Footwear Shop
-B:44:0x80:0xAB
-
-# Rare Footwear Shop
-B:45:0x80:0xAB
-
-# Library
-B:46:0x80:0xAB
-
-# Forbidden Library
-B:47:0x80:0xAB
-
-# Expensive Black Market
-B:48:0x80:0xAB
-
-# Common Shop
-B:49:0x80:0xAB
-
-# Dragon Hunter
-B:50:0x80:0xAB
-
-# Speed Ring Market
-B:51:0x80:0xAB
-
-# Scribe
-B:52:0x80:0xAB
-
-# Potion Store
-B:53:0x80:0xAB
-
-# Recaller
-B:54:0x80:0xAB
-
-# Master Archer
-B:55:0x80:0xAB
-
-# Merchants Guild
-B:56:0x80:0xAB
-
-# The Mathom-house
-B:57:0x80:0xAB
-
-# The Prancing Pony
-B:58:0x80:0xAB
-
-# nothing
-F:0:0x80:0xA0
-
-# open floor
-F:1:0x82:0xBC
-
-# fountain
-F:2:0x81:0x8D
-
-# glyph of warding
-F:3:0x8A:0xE1
-
-# open door
-F:4:0x80:0xA7
-
-# broken door
-F:5:0x80:0xA7
-
-# up staircase
-F:6:0x80:0xBC
-
-# down staircase
-F:7:0x80:0xBE
-
-# quest entrance
-F:8:0x80:0xBE
-
-# quest exit
-F:9:0x80:0xBC
-
-# quest down level
-F:10:0x80:0xBE
-
-# quest up level
-F:11:0x80:0xBC
-
-# town exit
-F:12:0x80:0xBE
-
-# shaft down
-F:13:0x80:0xBE
-
-# shaft up
-F:14:0x80:0xBC
-
-# fountain
-F:15:0x81:0x8D
-
-# web
-F:15:0x81:0x8D
-
-# trap
-F:17:0x8A:0xF9
-
-# visible trap -- spiked pit
-F:18:0x8A:0xF9
-
-# visible trap -- poison pit
-F:19:0x8A:0xF8
-
-# visible trap -- rune -- summon
-F:20:0x8A:0xF8
-
-# visible trap -- rune -- teleport
-F:21:0x8A:0xF8
-
-# visible trap -- spot -- fire
-F:22:0x8A:0xFD
-
-# visible trap -- spot -- acid
-F:23:0x8A:0xFA
-
-# visible trap -- dart -- slow
-F:24:0x8A:0xF3
-
-# visible trap -- dart -- lose str
-F:25:0x8A:0xF3
-
-# visible trap -- dart -- lose dex
-F:26:0x8A:0xF3
-
-# visible trap -- dart -- lose con
-F:27:0x8A:0xF3
-
-# visible trap -- gas -- blind
-F:28:0x8A:0xF6
-
-# visible trap -- gas -- confuse
-F:29:0x8A:0xF6
-
-# visible trap -- gas -- poison
-F:30:0x8A:0xF6
-
-# visible trap -- gas -- sleep
-F:31:0x8A:0xF6
-
-# door
-F:32:0x80:0xAB
-
-# locked door
-F:33:0x80:0xAB
-
-# locked door
-F:34:0x80:0xAB
-
-# locked door
-F:35:0x80:0xAB
-
-# locked door
-F:36:0x80:0xAB
-
-# locked door
-F:37:0x80:0xAB
-
-# locked door
-F:38:0x80:0xAB
-
-# locked door
-F:39:0x80:0xAB
-
-# jammed door
-F:40:0x80:0xAB
-
-# jammed door
-F:41:0x80:0xAB
-
-# jammed door
-F:42:0x80:0xAB
-
-# jammed door
-F:43:0x80:0xAB
-
-# jammed door
-F:44:0x80:0xAB
-
-# jammed door
-F:45:0x80:0xAB
-
-# jammed door
-F:46:0x80:0xAB
-
-# jammed door
-F:47:0x80:0xAB
-
-# secret door
-F:48:0x80:0xA3
-
-# pile of rubble
-F:49:0x8A:0xEF
-
-# magma vein
-F:50:0x80:0xA5
-
-# quartz vein
-F:51:0x81:0xF3
-
-# magma vein
-F:52:0x81:0xF3
-
-# quartz vein
-F:53:0x81:0xF3
-
-# magma vein with treasure
-F:54:0x80:0xAA
-
-# quartz vein with treasure
-F:55:0x80:0xAA
-
-# granite wall
-F:56:0x81:0xF0
-
-# granite wall
-F:57:0x81:0xF0
-
-# granite wall
-F:58:0x81:0xF0
-
-# granite wall
-F:59:0x81:0xF0
-
-# permanent wall
-F:60:0x81:0xF3
-
-# permanent wall
-F:61:0x81:0xF3
-
-# permanent wall
-F:62:0x81:0xF3
-
-# permanent wall
-F:63:0x81:0xF3
-
-# explosive rune
-F:64:0x80:0xAA
-
-# Straight Road startpoint
-F:65:0x80:0xAA
-
-# section of the Straight Road
-F:66:0x80:0xAA
-
-# section of the Straight Road
-F:67:0x80:0xAA
-
-# section of the Straight Road
-F:68:0x80:0xAA
-
-# section of the Straight Road
-F:69:0x80:0xAA
-
-# section of the Straight Road
-F:70:0x80:0xAA
-
-# section of the Straight Road (discharged)
-F:71:0x80:0xAA
-
-# Straight Road exit
-F:72:0x80:0xAA
-
-# corrupted section of the Straight Road
-F:73:0x80:0xAA
-
-# Building
-F:74:0x80:0xB1
-
-# permanent wall
-F:75:0x81:0xF3
-
-# permanent wall
-F:76:0x81:0xF3
-
-# permanent wall
-F:77:0x81:0xF3
-
-# permanent wall
-F:78:0x81:0xF3
-
-# stream of shallow water
-F:84:0x82:0xEB
-
-# pool of deep lava
-F:85:0x82:0xAB
-
-# stream of shallow lava
-F:86:0x82:0xAB
-
-# dark pit
-F:87:0x83:0x8B
-
-# dirt
-F:88:0x82:0xF3
-
-# patch of grass
-F:89:0x82:0xE8
-
-# ice
-F:90:0x80:0xAE
-
-# sand
-F:91:0x80:0xAE
-
-# dead tree
-F:92:0x80:0xA3
-
-# ash
-F:93:0x80:0xAE
-
-# mud
-F:94:0x80:0xAE
-
-# ice wall
-F:95:0x80:0x80
-
-# tree
-F:96:0x83:0x88
-
-# mountain chain
-F:97:0x81:0x9D
-
-# sandwall
-F:98:0x80:0xA3
-
-# sandwall
-F:99:0x80:0xA5
-
-# sandwall with treasure
-F:100:0x80:0xAA
-
-# high mountain chain
-F:101:0x80:0xDE
-
-# nether mist
-F:102:0x80:0x80
-
-# molten glass wall
-F:103:0x80:0xAE
-
-# Void Jumpgate
-F:160:0x81:0x8C
-
-# Altar of Being
-F:161:0x81:0x94
-
-# Altar of Winds
-F:162:0x81:0x94
-
-# Altar of Force
-F:163:0x81:0x94
-
-# Altar of Darkness
-F:164:0x81:0x94
-
-# Altar of Nature
-F:165:0x81:0x94
-
-# Altar of Sun
-F:166:0x81:0x94
-
-# Altar of Rage
-F:167:0x81:0x94
-
-# Altar of Winds
-F:168:0x81:0x94
-
-# Altar of Stars
-F:169:0x81:0x94
-
-# Altar of Being
-F:170:0x81:0x94
-
-# Altar of Randomness
-F:171:0x81:0x94
-
-# floor
-F:172:0x80:0x81
-
-# Underground Tunnel
-F:173:0x80:0x82
-
-# stream of tainted water
-F:174:0x80:0x80
-
-# monster trap
-F:175:0x81:0x9C
-
-# Void Jumpgate
-F:176:0x80:0x80
-
-# lava wall
-F:177:0x80:0x80
-
-# Great Fire
-F:178:0x80:0x80
-
-# Path to next area
-F:179:0x80:0xBE
-
-# Path to previous area
-F:180:0x80:0xBC
-
-# field
-F:181:0x80:0x80
-
-# Ekkaia, the Encircling Sea
-F:182:0x80:0x80
-
-# Altar of Energy
-F:183:0x80:0x80
-
-# Altar of Matter
-F:184:0x80:0x80
-
-# Altar of Being
-F:185:0x80:0x80
-
-# Altar of Unbeing
-F:186:0x80:0x80
-
-# pool of deep water
-F:187:0x82:0xF0
-
-# glass wall
-F:188:0x80:0xAE
-
-# illusion wall
-F:189:0x80:0xA3
-
-# Grass roof
-F:190:0x82:0xF6
-
-# grass roof top
-F:191:0x82:0xF6
-
-# grass roof chimney
-F:192:0x82:0xF7
-
-# brick roof
-F:193:0x82:0xEE
-
-# brick roof top
-F:194:0x82:0xEE
-
-# brick roof chimney
-F:195:0x82:0xF7
-
-# window
-F:196:0x80:0xA3
-
-# small window
-F:197:0x80:0xA3
-
-# rain barrel
-F:198:0x80:0xA3
-
-# grass with flowers
-F:199:0x82:0xF8
-
-# cobblestone road
-F:200:0x83:0x83
-
-# cobblestone with outlet
-F:201:0x80:0xAE
-
-# small tree
-F:202:0x83:0x88
-
-# town
-F:203:0x80:0xAA
-
-# Underground Tunnel
-F:204:0x80:0x82
-
-# a blazing fire
-F:205:0x80:0x80
-
-# pile of rubble
-F:206:0x8A:0xEF
-
-# rocky ground
-F:207:0x80:0x80
-
-# cloud-like vapour
-F:208:0x80:0x80
-
-# condensing water
-F:209:0x80:0x80
-
-# dense mist
-F:210:0x80:0x80
-
-# hail-stone wall
-F:211:0x80:0x80
-
-# dead small tree
-F:212:0x80:0x80
-
-# something
-K:0:0x80:0x80
-
-# Blindness
-K:1:0x86:0x8C
-
-# Paranoia
-K:2:0x86:0x8C
-
-# Confusion
-K:3:0x86:0x8C
-
-# Hallucination
-K:4:0x86:0x8C
-
-# Cure Poison
-K:5:0x86:0x8C
-
-# Cure Blindness
-K:6:0x86:0x8C
-
-# Cure Paranoia
-K:7:0xA6:0xBB
-
-# Cure Confusion
-K:8:0x86:0x8C
-
-# Weakness
-K:9:0x86:0x8C
-
-# Unhealth
-K:10:0x86:0x8C
-
-# Restore Constitution
-K:11:0x86:0x8C
-
-# Restoring
-K:12:0x86:0x8C
-
-# Stupidity
-K:13:0x86:0x8C
-
-# Naivety
-K:14:0x86:0x8C
-
-# Poison
-K:15:0x86:0x8C
-
-# Sickness
-K:16:0x86:0x8C
-
-# Paralysis
-K:17:0x86:0x8C
-
-# Restore Strength
-K:18:0x86:0x8C
-
-# Disease
-K:19:0x86:0x8C
-
-# Cure Serious Wounds
-K:20:0x86:0x8C
-
-# & Ration~ of Food
-K:21:0x8A:0xBC
-
-# & Hard Biscuit~
-K:22:0x8A:0xBA
-
-# & Strip~ of Venison
-K:23:0x8A:0xBB
-
-# & Slime Mold~
-K:24:0x8A:0xBD
-
-# & Lembas~
-K:25:0x8A:0xBE
-
-# & Pint~ of Fine Ale
-K:26:0x8A:0xB8
-
-# & Pint~ of Fine Wine
-K:27:0x8A:0xB8
-
-# & Mattock~
-K:28:0x9E:0xC4
-
-# & Blue Stone~
-K:29:0xA6:0x8B
-
-# & Broken Dagger~
-K:30:0x88:0xC5
-
-# & Bastard Sword~
-K:31:0x88:0xC6
-
-# & Scimitar~
-K:32:0x88:0xCF
-
-# & Tulwar~
-K:33:0x88:0xCD
-
-# & Broad Sword~
-K:34:0x88:0xD0
-
-# & Short Sword~
-K:35:0x88:0xCC
-
-# & Blade~ of Chaos
-K:36:0x88:0xD6
-
-# & Two-Handed Sword~
-K:37:0x88:0xD4
-
-# & Main Gauche~
-K:38:0x88:0xC8
-
-# & Cutlass~
-K:39:0x88:0xCE
-
-# & Executioner's Sword~
-K:40:0x88:0xD5
-
-# & Katana~
-K:41:0x88:0xD3
-
-# & Long Sword~
-K:42:0x88:0xD1
-
-# & Dagger~
-K:43:0x88:0xC7
-
-# & Rapier~
-K:44:0x88:0xC9
-
-# & Sabre~
-K:45:0x88:0xCB
-
-# & Small Sword~
-K:46:0x88:0xCA
-
-# & Broken Sword~
-K:47:0x88:0xC6
-
-# & Ball-and-Chain~
-K:48:0x88:0xFE
-
-# & Whip~
-K:49:0x88:0xD7
-
-# & Flail~
-K:50:0x88:0xFB
-
-# & Two-Handed Flail~
-K:51:0x88:0xFF
-
-# & Morning Star~
-K:52:0x88:0xFC
-
-# & Mace~
-K:53:0x88:0xF9
-
-# & Quarterstaff~
-K:54:0x88:0xFA
-
-# & War Hammer~
-K:55:0x88:0xF8
-
-# & Lead-Filled Mace~
-K:56:0x88:0xFD
-
-# & Mace~ of Disruption
-K:57:0x89:0x80
-
-# & Lucerne Hammer~
-K:58:0x89:0x85
-
-# & Beaked Axe~
-K:59:0x89:0x88
-
-# & Glaive~
-K:60:0x89:0x8A
-
-# & Halberd~
-K:61:0x89:0x8B
-
-# & Awl-Pike~
-K:62:0x89:0x83
-
-# & Pike~
-K:63:0x89:0x87
-
-# & Spear~
-K:64:0x89:0x81
-
-# & Trident~
-K:65:0x89:0x82
-
-# & Lance~
-K:66:0x89:0x84
-
-# & Great Axe~
-K:67:0x89:0x8D
-
-# & Battle Axe~
-K:68:0x89:0x86
-
-# & Lochaber Axe~
-K:69:0x89:0x8C
-
-# & Broad Axe~
-K:70:0x89:0x89
-
-# & Scythe~
-K:71:0x89:0x8E
-
-# & Scythe~ of Slicing
-K:72:0x89:0x8F
-
-# & Short Bow~
-K:73:0x89:0x90
-
-# & Long Bow~
-K:74:0x89:0x91
-
-# & Light Crossbow~
-K:75:0x89:0x92
-
-# & Heavy Crossbow~
-K:76:0x89:0x93
-
-# & Sling~
-K:77:0x89:0x94
-
-# & Arrow~
-K:78:0x89:0xB8
-
-# & Seeker Arrow~
-K:79:0x89:0xB9
-
-# & Bolt~
-K:80:0x89:0xBA
-
-# & Seeker Bolt~
-K:81:0x89:0xBB
-
-# & Rounded Pebble~
-K:82:0x89:0xBC
-
-# & Iron Shot~
-K:83:0x89:0xBD
-
-# & Shovel~
-K:84:0x8A:0xC7
-
-# & Gnomish Shovel~
-K:85:0x8A:0xC8
-
-# & Dwarven Shovel~
-K:86:0x8A:0xC9
-
-# & Pick~
-K:87:0x8A:0xC4
-
-# & Orcish Pick~
-K:88:0x8A:0xC5
-
-# & Dwarven Pick~
-K:89:0x8A:0xC9
-
-# & Elven Cloak~
-K:90:0x88:0x81
-
-# & Pair~ of Soft Leather Boots
-K:91:0x87:0xC6
-
-# & Pair~ of Hard Leather Boots
-K:92:0x87:0xC7
-
-# & Pair~ of Metal Shod Boots
-K:93:0x87:0xC8
-
-# & Hard Leather Cap~
-K:94:0x87:0x90
-
-# & Metal Cap~
-K:95:0x87:0x91
-
-# & Iron Helm~
-K:96:0x87:0x92
-
-# & Steel Helm~
-K:97:0x87:0x93
-
-# & Iron Crown~
-K:98:0x87:0x94
-
-# & Golden Crown~
-K:99:0x87:0x95
-
-# & Jewel Encrusted Crown~
-K:100:0x87:0x96
-
-# & Robe~
-K:101:0x88:0x84
-
-# & Filthy Rag~
-K:102:0x88:0x83
-
-# Soft Leather Armour~
-K:103:0x88:0x85
-
-# Soft Studded Leather~
-K:104:0x88:0x86
-
-# Hard Leather Armour~
-K:105:0x88:0x87
-
-# Hard Studded Leather~
-K:106:0x88:0x88
-
-# Leather Scale Mail~
-K:107:0x88:0x89
-
-# Metal Scale Mail~
-K:108:0x88:0x8A
-
-# Chain Mail~
-K:109:0x88:0x8C
-
-# Rusty Chain Mail~
-K:110:0x88:0x8B
-
-# Augmented Chain Mail~
-K:111:0x88:0x8E
-
-# Bar Chain Mail~
-K:112:0x88:0x8F
-
-# Metal Brigandine Armour~
-K:113:0x88:0x90
-
-# Partial Plate Armour~
-K:114:0x88:0x91
-
-# Metal Lamellar Armour~
-K:115:0x88:0x92
-
-# Full Plate Armour~
-K:116:0x88:0x93
-
-# Ribbed Plate Armour~
-K:117:0x88:0x94
-
-# Adamantite Plate Mail~
-K:118:0x88:0x97
-
-# Mithril Plate Mail~
-K:119:0x88:0x96
-
-# Mithril Chain Mail~
-K:120:0x88:0x95
-
-# Double Chain Mail~
-K:121:0x88:0x8D
-
-# & Shield~ of Deflection
-K:122:0x87:0xD0
-
-# & Cloak~
-K:123:0x88:0x80
-
-# & Shadow Cloak~
-K:124:0x88:0x81
-
-# & Set~ of Leather Gloves
-K:125:0x87:0xC9
-
-# & Set~ of Gauntlets
-K:126:0x87:0xCA
-
-# & Set~ of Cesti
-K:127:0x87:0xCB
-
-# & Small Leather Shield~
-K:128:0x87:0xCC
-
-# & Large Leather Shield~
-K:129:0x87:0xCD
-
-# & Small Metal Shield~
-K:130:0x87:0xCE
-
-# & Large Metal Shield~
-K:131:0x87:0xCF
-
-# Strength
-K:132:0x85:0xB9
-
-# Dexterity
-K:133:0x85:0xBB
-
-# Constitution
-K:134:0x85:0xBB
-
-# Intelligence
-K:135:0x85:0xBB
-
-# Speed
-K:136:0x85:0xBB
-
-# Searching
-K:137:0x85:0xBB
-
-# Teleportation
-K:138:0x85:0xBB
-
-# Slow Digestion
-K:139:0x85:0xBB
-
-# Fire Resistance
-K:140:0x85:0xBB
-
-# Cold Resistance
-K:141:0x85:0xBB
-
-# Levitation
-K:142:0x85:0xBB
-
-# Poison Resistance
-K:143:0x85:0xBB
-
-# Free Action
-K:144:0x85:0xBB
-
-# Weakness
-K:145:0x85:0xBB
-
-# Flames
-K:146:0x85:0xBB
-
-# Acid
-K:147:0x85:0xBB
-
-# Ice
-K:148:0x85:0xBB
-
-# Woe
-K:149:0x85:0xBB
-
-# Stupidity
-K:150:0x85:0xBB
-
-# Damage
-K:151:0x85:0xBB
-
-# Accuracy
-K:152:0x85:0xBB
-
-# Protection
-K:153:0x85:0xBB
-
-# Aggravate Monster
-K:154:0x85:0xBB
-
-# See Invisible
-K:155:0x85:0xBB
-
-# Sustain Strength
-K:156:0x85:0xBB
-
-# Sustain Intelligence
-K:157:0x85:0xBB
-
-# Sustain Wisdom
-K:158:0x85:0xBB
-
-# Sustain Constitution
-K:159:0x85:0xBB
-
-# Sustain Dexterity
-K:160:0x85:0xBB
-
-# Sustain Charisma
-K:161:0x85:0xBB
-
-# Slaying
-K:162:0x85:0xBB
-
-# Brilliance
-K:163:0x86:0xFB
-
-# Charisma
-K:164:0x86:0xFB
-
-# Searching
-K:165:0x86:0xFB
-
-# Teleportation
-K:166:0x86:0xFB
-
-# Slow Digestion
-K:167:0x86:0xFB
-
-# Acid Resistance
-K:168:0x86:0xFB
-
-# Adornment
-K:169:0x86:0xFB
-
-# Double Ring Mail~
-K:170:0x88:0x93
-
-# the Magi
-K:171:0x86:0xFB
-
-# Doom
-K:172:0x86:0xFB
-
-# Enchant Weapon To-Hit
-K:173:0x85:0x94
-
-# Enchant Weapon To-Dam
-K:174:0x85:0x94
-
-# Enchant Armor
-K:175:0x85:0x94
-
-# Identify
-K:176:0x85:0x94
-
-# *Identify*
-K:177:0x85:0x94
-
-# Rumour
-K:178:0x85:0x94
-
-# Chaos
-K:179:0x85:0x94
-
-# Remove Curse
-K:180:0x85:0x94
-
-# Light
-K:181:0x85:0x94
-
-# Fire
-K:182:0x85:0x94
-
-# Ice
-K:183:0x85:0x94
-
-# Summon Monster
-K:184:0x85:0x94
-
-# Phase Door
-K:185:0x85:0x94
-
-# Teleportation
-K:186:0x85:0x94
-
-# Teleport Level
-K:187:0x85:0x94
-
-# Monster Confusion
-K:188:0x85:0x94
-
-# Magic Mapping
-K:189:0x85:0x94
-
-# Rune of Protection
-K:190:0x85:0x94
-
-# *Remove Curse*
-K:191:0x85:0x94
-
-# Treasure Detection
-K:192:0x85:0x94
-
-# Object Detection
-K:193:0x85:0x94
-
-# Trap Detection
-K:194:0x85:0x94
-
-# & Sheaf Arrow~
-K:195:0x89:0xB9
-
-# & Mithril Shot~
-K:196:0x89:0xBD
-
-# Door
-K:197:0x85:0x94
-
-# Acquirement
-K:198:0x85:0x94
-
-# *Acquirement*
-K:199:0x85:0x94
-
-# Mass Genocide
-K:200:0x85:0x94
-
-# Detect Invisible
-K:201:0x85:0x94
-
-# Aggravate Monster
-K:202:0x85:0x94
-
-# Trap Creation
-K:203:0x85:0x94
-
-# Trap
-K:204:0x85:0x94
-
-# Artifact Creation
-K:205:0x85:0x94
-
-# Recharging
-K:206:0x85:0x94
-
-# Genocide
-K:207:0x85:0x94
-
-# Darkness
-K:208:0x85:0x94
-
-# Protection from Evil
-K:209:0x85:0x94
-
-# Satisfy Hunger
-K:210:0x85:0x94
-
-# Dispel Undead
-K:211:0x85:0x94
-
-# *Enchant Weapon*
-K:212:0x85:0x94
-
-# Curse Weapon
-K:213:0x85:0x94
-
-# *Enchant Armor*
-K:214:0x85:0x94
-
-# Curse Armor
-K:215:0x85:0x94
-
-# Summon Undead
-K:216:0x85:0x94
-
-# Blessing
-K:217:0x85:0x94
-
-# Holy Chant
-K:218:0x85:0x94
-
-# Holy Prayer
-K:219:0x85:0x94
-
-# Word of Recall
-K:220:0x85:0x94
-
-# *Destruction*
-K:221:0x85:0x94
-
-# Slime Mold Juice
-K:222:0x85:0xFD
-
-# Apple Juice
-K:223:0x85:0xFD
-
-# Water
-K:224:0x85:0xFD
-
-# Strength
-K:225:0x85:0xFD
-
-# Weakness
-K:226:0x85:0xFD
-
-# Restore Strength
-K:227:0x85:0xFD
-
-# Intelligence
-K:228:0x85:0xFD
-
-# Stupidity
-K:229:0x85:0xFD
-
-# Restore Intelligence
-K:230:0x85:0xFD
-
-# Wisdom
-K:231:0x85:0xFD
-
-# Naivety
-K:232:0x85:0xFD
-
-# Restore Wisdom
-K:233:0x85:0xFD
-
-# Charisma
-K:234:0x85:0xFD
-
-# Ugliness
-K:235:0x85:0xFD
-
-# Restore Charisma
-K:236:0x85:0xFD
-
-# Curing
-K:237:0x85:0xFD
-
-# Invulnerability
-K:238:0x85:0xFD
-
-# New Life
-K:239:0x85:0xFD
-
-# Cure Serious Wounds
-K:240:0x85:0xFD
-
-# Cure Critical Wounds
-K:241:0x85:0xFD
-
-# Healing
-K:242:0x85:0xFD
-
-# Constitution
-K:243:0x85:0xFD
-
-# Experience
-K:244:0x85:0xFD
-
-# Sleep
-K:245:0x85:0xFD
-
-# Blindness
-K:246:0x85:0xFD
-
-# Booze
-K:247:0x85:0xFD
-
-# Poison
-K:248:0x85:0xFD
-
-# Speed
-K:249:0x85:0xFD
-
-# Slowness
-K:250:0x85:0xFD
-
-# Dexterity
-K:251:0x85:0xFD
-
-# Restore Dexterity
-K:252:0x85:0xFD
-
-# Restore Constitution
-K:253:0x85:0xFD
-
-# Lose Memories
-K:254:0x85:0xFD
-
-# Salt Water
-K:255:0x85:0xFD
-
-# Enlightenment
-K:256:0x85:0xFD
-
-# Heroism
-K:257:0x85:0xFD
-
-# Berserk Strength
-K:258:0x85:0xFD
-
-# Boldness
-K:259:0x85:0xFD
-
-# Restore Life Levels
-K:260:0x85:0xFD
-
-# Resist Heat
-K:261:0x85:0xFD
-
-# Resist Cold
-K:262:0x85:0xFD
-
-# Detect Invisible
-K:263:0x85:0xFD
-
-# Slow Poison
-K:264:0x85:0xFD
-
-# Neutralise Poison
-K:265:0x85:0xFD
-
-# Restore Mana
-K:266:0x85:0xFD
-
-# Infra-vision
-K:267:0x85:0xFD
-
-# Resistance
-K:268:0x85:0xFD
-
-# Spell
-K:269:0x86:0xCB
-
-# Manathrust
-K:270:0x86:0xCB
-
-# Fireflash
-K:271:0x86:0xCB
-
-# Firewall
-K:272:0x86:0xCB
-
-# Tidal Wave
-K:273:0x86:0xCB
-
-# Ice Storm
-K:274:0x86:0xCB
-
-# Noxious Cloud
-K:275:0x86:0xCB
-
-# Poison Blood
-K:276:0x86:0xCB
-
-# Thunderstorm
-K:277:0x86:0xCB
-
-# Dig
-K:278:0x86:0xCB
-
-# Stone Prison
-K:279:0x86:0xCB
-
-# Strike
-K:280:0x86:0xCB
-
-# Teleport Away
-K:281:0x86:0xCB
-
-# Summon Animal
-K:282:0x86:0xCB
-
-# Magelock
-K:283:0x86:0xCB
-
-# Slow Monster
-K:284:0x86:0xCB
-
-# Essence of Speed
-K:285:0x9F:0x84
-
-# Banishment
-K:286:0x86:0xCB
-
-# Disperse Magic
-K:287:0x86:0xCB
-
-# Charm
-K:288:0x86:0xCB
-
-# Confuse
-K:289:0x86:0xCB
-
-# Demon Blade
-K:290:0x86:0xCB
-
-# Heal Monster
-K:291:0x86:0xCB
-
-# Haste Monster
-K:292:0x86:0xCB
-
-# & Flight Arrow~
-K:293:0x89:0xB9
-
-# Acid Bolts
-K:294:0x86:0xCB
-
-# Dragon's Flame
-K:295:0x86:0xCB
-
-# Dragon's Frost
-K:296:0x86:0xCB
-
-# Dragon's Breath
-K:297:0x86:0xCB
-
-# Annihilation
-K:298:0x86:0xCB
-
-# Rockets
-K:299:0x86:0xCB
-
-# Spell
-K:300:0x87:0x8A
-
-# Nothing
-K:301:0x87:0x8A
-
-# Globe of Light
-K:302:0x87:0x8A
-
-# Fiery Shield
-K:303:0x87:0x8A
-
-# Remove Curses
-K:304:0x87:0x8A
-
-# Wings of Winds
-K:305:0x87:0x8A
-
-# Shake
-K:306:0x87:0x8A
-
-# Disarm
-K:307:0x87:0x8A
-
-# Teleportation
-K:308:0x87:0x8A
-
-# Probability Travel
-K:309:0x87:0x8A
-
-# Recovery
-K:310:0x87:0x8A
-
-# Healing
-K:311:0x87:0x8A
-
-# Vision
-K:312:0x87:0x8A
-
-# Identify
-K:313:0x87:0x8A
-
-# Sense Hidden
-K:314:0x87:0x8A
-
-# Reveal Ways
-K:315:0x87:0x8A
-
-# Sense Monsters
-K:316:0x87:0x8A
-
-# Genocide
-K:317:0x87:0x8A
-
-# Summon
-K:318:0x87:0x8A
-
-# Curing
-K:319:0x87:0x8A
-
-# Wish
-K:320:0x87:0x8A
-
-# Mana
-K:321:0x87:0x8A
-
-# Darkness
-K:322:0x87:0x8A
-
-# Genocide
-K:323:0x87:0x8A
-
-# Power
-K:324:0x87:0x8A
-
-# the Magi
-K:325:0x87:0x8A
-
-# Perception
-K:326:0x87:0x8A
-
-# Holiness
-K:327:0x87:0x8A
-
-# Enlightenment
-K:328:0x87:0x8A
-
-# Healing
-K:329:0x87:0x8A
-
-# & Tome~ of Magical Energy
-K:330:0x8B:0xD8
-
-# & Tome~ of the Eternal Flame
-K:331:0x8B:0xD9
-
-# & Tome~ of the Blowing Wind
-K:332:0x8B:0xDA
-
-# & Tome~ of the Impenetrable Earth
-K:333:0x8B:0xDB
-
-# & Tome~ of the Everrunning Wave
-K:334:0x8B:0xDC
-
-# & Tome~ of Translocation
-K:335:0x8B:0xDD
-
-# & Tome~ of the Tree
-K:336:0x8B:0xDE
-
-# & Tome~ of Knowledge
-K:337:0x8B:0xDF
-
-# & Small wooden chest~
-K:338:0x85:0xD1
-
-# & Large wooden chest~
-K:339:0x85:0xD2
-
-# & Small iron chest~
-K:340:0x85:0xD3
-
-# & Large iron chest~
-K:341:0x85:0xD4
-
-# & Small steel chest~
-K:342:0x85:0xD5
-
-# & Large steel chest~
-K:343:0x85:0xD6
-
-# & Ruined chest~
-K:344:0x85:0xD7
-
-# & Iron Spike~
-K:345:0x8A:0xC1
-
-# & Wooden Torch~
-K:346:0x8A:0xC3
-
-# & Brass Lantern~
-K:347:0x8A:0xC2
-
-# & Flask~ of oil
-K:348:0x8A:0xC0
-
-# & Empty Bottle~
-K:349:0x8A:0xBF
-
-# Havoc
-K:350:0x86:0xBB
-
-# Door
-K:351:0x86:0xBB
-
-# Trap Location
-K:352:0x86:0xBB
-
-# Probing
-K:353:0x86:0xBB
-
-# Recall
-K:354:0x86:0xBB
-
-# Illumination
-K:355:0x86:0xBB
-
-# Light
-K:356:0x86:0xBB
-
-# Lightning Bolts
-K:357:0x86:0xBB
-
-# Frost Bolts
-K:358:0x86:0xBB
-
-# Fire Bolts
-K:359:0x86:0xBB
-
-# Polymorph
-K:360:0x86:0xBB
-
-# Slow Monster
-K:361:0x86:0xBB
-
-# Sleep Monster
-K:362:0x86:0xBB
-
-# Drain Life
-K:363:0x86:0xBB
-
-# Teleport Other
-K:364:0x86:0xBB
-
-# Disarming
-K:365:0x86:0xBB
-
-# Lightning Balls
-K:366:0x86:0xBB
-
-# Cold Balls
-K:367:0x86:0xBB
-
-# Fire Balls
-K:368:0x86:0xBB
-
-# Acid Balls
-K:369:0x86:0xBB
-
-# Acid Bolts
-K:370:0x86:0xBB
-
-# Enlightenment
-K:371:0x86:0xBB
-
-# Perception
-K:372:0x86:0xBB
-
-# Curing
-K:373:0x86:0xBB
-
-# Healing
-K:374:0x86:0xBB
-
-# Detection
-K:375:0x86:0xBB
-
-# Restoration
-K:376:0x86:0xBB
-
-# Speed
-K:377:0x86:0xBB
-
-# Spell
-K:378:0xA3:0xFC
-
-# Spell
-K:379:0x89:0xF8
-
-# [Beings of Darkness]
-K:380:0x89:0xF9
-
-# [Material Shadow]
-K:381:0x89:0xFA
-
-# [Nature's Wrath]
-K:382:0x89:0xFB
-
-# [Sign of Chaos]
-K:383:0x89:0xD0
-
-# [Chaos Mastery]
-K:384:0x89:0xD1
-
-# [Chaos Channels]
-K:385:0x89:0xD2
-
-# [Armageddon Tome]
-K:386:0x89:0xD3
-
-# [Nether Openings]
-K:387:0x8A:0x80
-
-# [Unholy Blessings]
-K:388:0x8A:0x81
-
-# & Firestone~
-K:389:0x8A:0xCA
-
-# & Small Firestone~
-K:390:0x8A:0xCB
-
-# & Broken Skull~
-K:391:0x8A:0xCC
-
-# & Broken Bone~
-K:392:0x8A:0xCD
-
-# & Canine Skeleton~
-K:393:0x8A:0xD2
-
-# & Rodent Skeleton~
-K:394:0x8A:0xD3
-
-# & Human Skeleton~
-K:395:0x8A:0xCE
-
-# & Dwarf Skeleton~
-K:396:0x8A:0xD0
-
-# & Elf Skeleton~
-K:397:0x8A:0xCF
-
-# & Gnome Skeleton~
-K:398:0x8A:0xD1
-
-# & Great Hammer~
-K:399:0x9E:0xC2
-
-# Black Dragon Scale Mail~
-K:400:0x88:0xBA
-
-# Blue Dragon Scale Mail~
-K:401:0x88:0xB8
-
-# White Dragon Scale Mail~
-K:402:0x88:0xB9
-
-# Red Dragon Scale Mail~
-K:403:0x88:0xBB
-
-# Green Dragon Scale Mail~
-K:404:0x88:0xBC
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x88:0xC3
-
-# Pseudo Dragon Scale Mail~
-K:406:0x88:0xBF
-
-# Law Dragon Scale Mail~
-K:407:0x88:0xC1
-
-# Bronze Dragon Scale Mail~
-K:408:0x88:0xBD
-
-# Gold Dragon Scale Mail~
-K:409:0x88:0xBE
-
-# Chaos Dragon Scale Mail~
-K:410:0x88:0xC0
-
-# Balance Dragon Scale Mail~
-K:411:0x88:0xC2
-
-# Power Dragon Scale Mail~
-K:412:0x88:0xC4
-
-# & Dragon Helm~
-K:413:0x87:0xBA
-
-# & Dragon Shield~
-K:414:0x87:0xD4
-
-# Death
-K:415:0x85:0xFD
-
-# Ruination
-K:416:0x85:0xFD
-
-# Detonations
-K:417:0x85:0xFD
-
-# Augmentation
-K:418:0x85:0xFD
-
-# *Healing*
-K:419:0x85:0xFD
-
-# Life
-K:420:0x85:0xFD
-
-# Self Knowledge
-K:421:0x85:0xFD
-
-# *Enlightenment*
-K:422:0x85:0xFD
-
-# [Necromantic Incantations]
-K:423:0x8A:0x82
-
-# [Curses of Angmar]
-K:424:0x8A:0x83
-
-# Fear Resistance
-K:425:0x85:0xBB
-
-# Light and Darkness Resistance
-K:426:0x85:0xBB
-
-# Nether Resistance
-K:427:0x85:0xBB
-
-# Nexus Resistance
-K:428:0x85:0xBB
-
-# Sound Resistance
-K:429:0x85:0xBB
-
-# Confusion Resistance
-K:430:0x85:0xBB
-
-# Shard Resistance
-K:431:0x85:0xBB
-
-# Disenchantment Resistance
-K:432:0x85:0xBB
-
-# Chaos Resistance
-K:433:0x85:0xBB
-
-# Blindness Resistance
-K:434:0x85:0xBB
-
-# Lordly Protection
-K:435:0x85:0xBB
-
-# Extra Attacks
-K:436:0x85:0xBB
-
-# Cure Light Wounds
-K:437:0x85:0xFD
-
-# Clumsiness
-K:438:0x85:0xFD
-
-# Sickliness
-K:439:0x85:0xFD
-
-# Map of Bree
-K:440:0xA5:0xB8
-
-# Map of Gondolin
-K:441:0xA5:0xB8
-
-# Map of Lothlorien
-K:442:0xA5:0xB8
-
-# Map of Minas Anor
-K:443:0xA5:0xB8
-
-# & Silver Arrow~
-K:465:0xA6:0xB9
-
-# & Silver Bolt~
-K:466:0xA6:0xBA
-
-# Lightning Resistance
-K:467:0x86:0xF8
-
-# Wisdom
-K:468:0x86:0xF8
-
-# Regeneration
-K:469:0x86:0xF8
-
-# Infravision
-K:470:0x86:0xF8
-
-# Devotion
-K:471:0x86:0xF8
-
-# Weaponmastery
-K:472:0x86:0xF8
-
-# Trickery
-K:473:0x86:0xF8
-
-# Telepathy
-K:474:0x86:0xF8
-
-# Sustenance
-K:475:0x86:0xF8
-
-# & Palantir~
-K:476:0xA6:0xBF
-
-# & Elfstone~
-K:477:0xA6:0xBB
-
-# & Jewel~
-K:478:0xA6:0xBC
-
-# & Ring~
-K:479:0xA6:0xBD
-
-# copper
-K:480:0x85:0x89
-
-# copper
-K:481:0x85:0x89
-
-# copper
-K:482:0x85:0x89
-
-# silver
-K:483:0x85:0x8A
-
-# silver
-K:484:0x85:0x8A
-
-# silver
-K:485:0x85:0x8A
-
-# garnets
-K:486:0x85:0x8E
-
-# garnets
-K:487:0x85:0x8E
-
-# gold
-K:488:0x85:0x8B
-
-# gold
-K:489:0x85:0x8B
-
-# gold
-K:490:0x85:0x8B
-
-# opals
-K:491:0x85:0x8F
-
-# sapphires
-K:492:0x85:0x90
-
-# rubies
-K:493:0x85:0x91
-
-# diamonds
-K:494:0x85:0x92
-
-# emeralds
-K:495:0x85:0x93
-
-# mithril
-K:496:0x85:0x8C
-
-# adamantite
-K:497:0x85:0x8D
-
-# & Mighty Hammer~
-K:498:0x9E:0xC2
-
-# & Massive Iron Crown~
-K:499:0x87:0x94
-
-# & Phial~
-K:500:0x8A:0xD5
-
-# & Star~
-K:501:0x8A:0xD6
-
-# & Arkenstone~
-K:502:0x8A:0xD7
-
-# & Amulet~
-K:503:0x85:0xCE
-
-# & Amulet~
-K:504:0x85:0xCF
-
-# & Necklace~
-K:505:0x85:0xD0
-
-# & Ring~
-K:506:0x85:0xC7
-
-# & Ring~
-K:507:0x85:0xC8
-
-# & Ring~
-K:508:0x85:0xCA
-
-# & Ring~
-K:509:0x85:0xCB
-
-# & Ring~
-K:510:0x85:0xCC
-
-# & Ring~
-K:511:0x85:0xCD
-
-# [Rites of Initiation]
-K:512:0x8A:0x88
-
-# [Ways of War]
-K:513:0x8A:0x89
-
-# [Divine Retribution]
-K:514:0x8A:0x8A
-
-# [Essence of Fury]
-K:515:0x8A:0x8B
-
-# [Novice Crafts]
-K:516:0x8A:0x84
-
-# [Arcane Channels]
-K:517:0x8A:0x85
-
-# [Sigils of Wizardry]
-K:518:0x8A:0x86
-
-# [Mana Focus]
-K:519:0x8A:0x87
-
-# Reflection
-K:520:0x86:0xFB
-
-# Anti-Magic
-K:521:0x86:0xFB
-
-# Anti-Teleportation
-K:522:0x86:0xFB
-
-# Resistance
-K:523:0x86:0xFB
-
-# & Zweihander~
-K:524:0x9E:0xC4
-
-# & Dwarven Lantern~
-K:525:0xA6:0x8C
-
-# Splint Mail~
-K:526:0x88:0x94
-
-# & Everburning Torch~
-K:527:0xA6:0x8D
-
-# & Trifurcate Spear~
-K:528:0x9E:0xBD
-
-# & Three Piece Rod~
-K:529:0x9E:0xB8
-
-# & Feanorian Lamp~
-K:530:0xA6:0x8E
-
-# & Fur Cloak~
-K:531:0x88:0x81
-
-# Water Curing
-K:532:0x9E:0xBE
-
-# & Hatchet~
-K:533:0x9E:0xC7
-
-# Rhino Hide Armour~
-K:535:0x88:0x90
-
-# Leather Jacket~
-K:536:0x88:0x87
-
-# & Sickle~
-K:537:0x9E:0xC8
-
-# [Psychoportation]
-K:538:0x9E:0xBF
-
-# [Clairsentience]
-K:539:0x9E:0xC9
-
-# [Telekinesis]
-K:540:0x9E:0xCB
-
-# [Empathy]
-K:541:0x9E:0xCA
-
-# & Club~
-K:542:0x9E:0xCA
-
-# & Broad Spear~
-K:543:0x9E:0xBC
-
-# & Khopesh~
-K:544:0x9E:0xCC
-
-# & Flamberge~
-K:545:0x9E:0xBB
-
-# & Claymore~
-K:546:0x9E:0xC5
-
-# & Espadon~
-K:547:0x9E:0xC6
-
-# & Great Scimitar~
-K:548:0x9E:0xC3
-
-# Arrow
-K:549:0x8A:0xD8
-
-# Bolt
-K:550:0x8A:0xD9
-
-# & Fauchard~
-K:551:0x9E:0xCD
-
-# & Guisarme~
-K:552:0x9E:0xCE
-
-# & Heavy Lance~
-K:553:0x9E:0xBA
-
-# & Basillard~
-K:554:0x9E:0xD1
-
-# Catapult
-K:555:0x8A:0xDA
-
-# Ring Mail~
-K:556:0x88:0x94
-
-# Cord Armour~
-K:557:0x88:0x88
-
-# Paper Armour~
-K:558:0x88:0xB9
-
-# Padded Armour~
-K:559:0x88:0x89
-
-# Fumes
-K:560:0x8A:0xDB
-
-# Stone and Hide Armour~
-K:561:0x88:0x8F
-
-# Magic
-K:562:0x8A:0xDC
-
-# Device
-K:563:0x8A:0xDD
-
-# Nothing
-K:564:0xA6:0xD4
-
-# Poison
-K:565:0x9E:0xF8
-
-# Nothing
-K:566:0xA6:0xD4
-
-# Nothing
-K:567:0xA6:0xD4
-
-# Nothing
-K:568:0xA6:0xD4
-
-# Nothing
-K:569:0xA6:0xD4
-
-# Explosion
-K:570:0x9E:0xF9
-
-# Teleport
-K:571:0x9E:0xFA
-
-# Nothing
-K:572:0xA6:0xD4
-
-# & Blood~ of Life
-K:573:0x85:0xFD
-
-# Cold
-K:574:0x9E:0xFB
-
-# Fire
-K:575:0x9E:0xFC
-
-# Acid
-K:576:0x9E:0xFD
-
-# & Mage Staff~
-K:577:0x9F:0xB8
-
-# Lightning
-K:578:0x85:0xB8
-
-# Life
-K:579:0x9E:0xFE
-
-# Confusion
-K:580:0x9E:0xFF
-
-# Light
-K:581:0x9F:0x80
-
-# & Ring~
-K:582:0x85:0xBD
-
-# Invisibility
-K:583:0x85:0xFD
-
-# Chaos
-K:584:0x9F:0x81
-
-# Corruption
-K:585:0x85:0xFD
-
-# Invisibility
-K:586:0x85:0xFD
-
-# Time
-K:587:0x9F:0x82
-
-# Deep Thoughts
-K:588:0x85:0x94
-
-# More Deep Thoughts
-K:589:0x85:0x95
-
-# Compendium of Deep Thoughts
-K:590:0x85:0x96
-
-# Artifact Lore Vol. I
-K:591:0x85:0x94
-
-# Artifact Lore Vol. II
-K:592:0x85:0x95
-
-# Artifact Lore Vol. III
-K:593:0x85:0x97
-
-# Monstrous Compendium 1
-K:594:0x85:0x97
-
-# Monstrous Compendium 2
-K:595:0x85:0x96
-
-# Monstrous Compendium 3
-K:596:0x85:0x95
-
-# Monstrous Compendium 4
-K:597:0x85:0x94
-
-# Monstrous Compendium 5
-K:598:0x85:0x97
-
-# Monstrous Compendium 6
-K:599:0x85:0x96
-
-# Monstrous Compendium 7
-K:600:0x85:0x95
-
-# Monstrous Compendium 8
-K:601:0x85:0x94
-
-# Monstrous Compendium 9
-K:602:0x85:0x95
-
-# Monstrous Compendium 10
-K:603:0x85:0x96
-
-# Monstrous Compendium 11
-K:604:0x85:0x97
-
-# Abomination
-K:605:0x85:0xFD
-
-# Shape of Wolf
-K:606:0x85:0xFD
-
-# Shape of Ape
-K:607:0x85:0xFD
-
-# Shape of Goat
-K:608:0x85:0xFD
-
-# Shape of Insect
-K:609:0x85:0xFD
-
-# Shape of Sparrow
-K:610:0x85:0xFD
-
-# Shape of Ent
-K:611:0x85:0xFD
-
-# Shape of Vampire
-K:612:0x85:0xFD
-
-# Shape of Spider
-K:613:0x85:0xFD
-
-# Shape of Mana ball
-K:614:0x85:0xFD
-
-# Shape of Fire cloud
-K:615:0x85:0xFD
-
-# Shape of Cold cloud
-K:616:0x85:0xFD
-
-# Shape of Chaos cloud
-K:617:0x85:0xFD
-
-# [Wolf]
-K:618:0x8B:0x98
-
-# [Ape]
-K:619:0x8B:0x99
-
-# [Goat]
-K:620:0x8B:0x9A
-
-# [Insect]
-K:621:0x8B:0x9B
-
-# [Sparrow]
-K:622:0x8B:0x9C
-
-# [Ent]
-K:623:0x8B:0x9D
-
-# [Vampire]
-K:624:0x8B:0x9E
-
-# [Spider]
-K:625:0x8B:0x9F
-
-# [Mana ball]
-K:626:0x8B:0xA0
-
-# [Fire cloud]
-K:627:0x8B:0xA1
-
-# [Cold cloud]
-K:628:0x8B:0xA2
-
-# [Chaos Cloud]
-K:629:0x8B:0xA3
-
-# [Ghost]
-K:630:0x8B:0xA4
-
-# [Kobold]
-K:631:0x8B:0xA5
-
-# [Dragon]
-K:632:0x8B:0xA6
-
-# [Demon]
-K:633:0x8B:0xA7
-
-# [Hound]
-K:634:0x8B:0xA8
-
-# [Quylthulg]
-K:635:0x8B:0xA9
-
-# [Maia]
-K:636:0x8B:0xAA
-
-# [Serpent]
-K:637:0x8B:0xAB
-
-# [Giant]
-K:638:0x8B:0xAC
-
-# [Vala]
-K:639:0x8B:0xAD
-
-# Magic
-K:640:0x9F:0x83
-
-# corpse
-K:641:0x9F:0xB9
-
-# skeleton
-K:642:0x8A:0xCE
-
-# head
-K:643:0x8A:0xCC
-
-# skull
-K:644:0x8A:0xCC
-
-# raw meat
-K:645:0x8A:0xBB
-
-# & Thunderlord Coat~
-K:646:0x88:0xBE
-
-# & Stone~
-K:647:0x8A:0xD4
-
-# & small wooden Boomerang~
-K:648:0x9F:0xBA
-
-# & wooden Boomerang~
-K:649:0x9F:0xBB
-
-# & small metal Boomerang~
-K:650:0x9F:0xBC
-
-# & metal Boomerang~
-K:651:0x9F:0xBD
-
-# & Anchor~
-K:652:0x8A:0x96
-
-# & ~
-K:653:0xA6:0xD4
-
-# Summon never-moving pet
-K:654:0x85:0x95
-
-# [Life in symbiosis]
-K:655:0x9F:0xBE
-
-# [Perfect Symbiosis]
-K:656:0x9F:0xBE
-
-# Cure Light Insanity
-K:657:0x85:0xFD
-
-# Cure Serious Insanity
-K:658:0x85:0xFD
-
-# Cure Critical Insanity
-K:659:0x85:0xFD
-
-# Cure Insanity
-K:660:0x85:0xFD
-
-# & Phial~
-K:661:0x8A:0xD5
-
-# Random Artifact
-K:662:0xA6:0xD4
-
-# Craftmanship
-K:663:0x85:0x97
-
-# The One Ring
-K:664:0x85:0x96
-
-# & Book~ of the Lays of the Heroes
-K:665:0x9F:0xBF
-
-# & Book~ of Sound Patterns
-K:666:0x9F:0xBF
-
-# [Harps of Rivendell]
-K:667:0x9F:0xBF
-
-# [Lays of Beleriand]
-K:668:0x9F:0xBF
-
-# & Flute~
-K:669:0x9F:0xC0
-
-# & Drum~
-K:670:0x9F:0xC1
-
-# & Harp~
-K:671:0x9F:0xC2
-
-# & Banjo~
-K:672:0x9F:0xC4
-
-# & Lute~
-K:673:0x9F:0xC3
-
-# & Mandolin~
-K:674:0x9F:0xC3
-
-# & Palantir~
-K:675:0x8A:0x97
-
-# Egg
-K:676:0x9F:0x85
-
-# Reset Recall
-K:677:0x85:0x95
-
-# Divination
-K:678:0x85:0x95
-
-# Self
-K:679:0x9F:0x86
-
-# Ray
-K:680:0x9F:0x87
-
-# Sphere
-K:681:0x9F:0x88
-
-# Knowledge
-K:682:0x9F:0x8C
-
-# Life
-K:683:0x9F:0x8D
-
-# Fire
-K:684:0x9F:0x8E
-
-# Cold
-K:685:0x9F:0x8F
-
-# Lightning
-K:686:0x9F:0x90
-
-# Acid
-K:687:0x9F:0x91
-
-# Element
-K:688:0x9F:0x92
-
-# Chaos
-K:689:0x9F:0x93
-
-# Mind
-K:690:0x9F:0x94
-
-# Holding
-K:691:0x9F:0x95
-
-# Arrow
-K:692:0x9F:0x89
-
-# Power Surge
-K:693:0x9F:0x8A
-
-# Armageddon
-K:694:0x9F:0x8B
-
-# Gravity
-K:695:0x9F:0x96
-
-# Extra Life
-K:696:0x9F:0x97
-
-# Undeath
-K:697:0x9E:0xD3
-
-# Protection
-K:698:0x9E:0xD4
-
-# & Horn~
-K:699:0x9F:0xC5
-
-# & Ring~ of Precognition
-K:700:0x85:0xBB
-
-# & Sprig~ of Athelas
-K:701:0x9F:0xC6
-
-# [Magic for Beginners]
-K:702:0x9F:0xC7
-
-# [Conjurings and Tricks]
-K:703:0x9F:0xC7
-
-# [Incantations and Illusions]
-K:704:0x9F:0xC7
-
-# [Sorcery and Evocations]
-K:705:0x9F:0xC7
-
-# [Beginners Handbook]
-K:706:0x9F:0xC8
-
-# [Words of Wisdom]
-K:707:0x9F:0xC8
-
-# [Chants and Blessings]
-K:708:0x9F:0xC8
-
-# [Exorcism and Dispelling]
-K:709:0x9F:0xC8
-
-# [Resistance of Scarabtarices]
-K:710:0x9F:0xCA
-
-# [Mordenkainen's Escapes]
-K:711:0x9F:0xCA
-
-# [Kelek's Grimoire of Power]
-K:712:0x9F:0xCA
-
-# [Tenser's Transformations]
-K:713:0x9F:0xCA
-
-# [Raal's Tome of Destruction]
-K:714:0x9F:0xCA
-
-# [Ethereal Openings]
-K:715:0x9F:0xCA
-
-# [Godly Insights]
-K:716:0x9F:0xC9
-
-# [Purifications and Healing]
-K:717:0x9F:0xC9
-
-# [Holy Infusions]
-K:718:0x9F:0xC9
-
-# [Wrath of God]
-K:719:0x9F:0xC9
-
-# & Old Scroll~ of Deincarnation
-K:720:0x85:0x97
-
-# & Dark Sword~
-K:721:0xA5:0xB9
-
-# Numenorean for beginners (I)
-K:722:0xA3:0xF8
-
-# Numenorean for beginners (II)
-K:723:0xA3:0xF9
-
-# Advanced lessons of Numenorean
-K:724:0xA3:0xF8
-
-# Advanced lessons of Sindarin
-K:725:0xA3:0xF9
-
-# & Shard~ of Pottery
-K:726:0x8A:0xCA
-
-# & Broken Stick~
-K:727:0x8A:0xCB
-
-# Wall Creation
-K:728:0x85:0x97
-
-# [Illusions for Beginners]
-K:729:0xA3:0xFA
-
-# [Tricks and Visions]
-K:730:0xA3:0xFA
-
-# [Phantasms and Illusions]
-K:731:0xA3:0xFA
-
-# [Shadows and Prisms]
-K:732:0xA3:0xFA
-
-# [Serten's Immunities]
-K:733:0xA3:0xFB
-
-# [Knowledge of Kenault]
-K:734:0xA3:0xFB
-
-# [Otiluke's Spheres]
-K:735:0xA3:0xFA
-
-# [Boccob's Book of Shadows]
-K:736:0xA3:0xFC
-
-# [Bigby's Handbook]
-K:737:0xA3:0xFC
-
-# & Book~ of Beginner Cantrips
-K:738:0xA3:0xFD
-
-# & Book~ of Teleportation
-K:739:0xA3:0xFE
-
-# & Book~ of Recall
-K:740:0xA3:0xFF
-
-# & Book~ of Summoning
-K:741:0xA3:0xF8
-
-# & Book~ of Fireflash
-K:742:0xA3:0xF9
-
-# & Potion~ of Learning
-K:743:0xA3:0xFA
-
-# [Eye of Sauron]
-K:744:0xA3:0xFB
-
-# [Flame of Udun]
-K:745:0xA3:0xFC
-
-# [Corruptions of Melkor]
-K:746:0xA3:0xFD
-
-# [Crescent of Morgul]
-K:747:0xA3:0xFE
-
-# [Morgoth's Ring]
-K:748:0xA3:0xFF
-
-# Spell
-K:749:0x86:0xC8
-
-# Wishing
-K:750:0x86:0xC8
-
-# Khuzdul - The hidden tongue of the Dwarves
-K:751:0x85:0x95
-
-# Nandorin for dummies
-K:752:0xA3:0xF9
-
-# Advanced lessons of Orcish
-K:753:0xA3:0xFA
-
-# & Ancient Tome~
-K:754:0xA3:0xFE
-
-# Flying
-K:755:0x85:0xC0
-
-# & Tome~ of the Time
-K:756:0xA3:0xF8
-
-# & Spellbook~ of #
-K:757:0x8C:0x9C
-
-# & Tome~ of Meta Spells
-K:758:0xA3:0xF9
-
-# & Tome~ of the Mind
-K:759:0xA3:0xFA
-
-# & Holy Tome~ of Eru Iluvatar
-K:760:0xA3:0xFB
-
-# & Holy Tome~ of Manwe Sulimo
-K:761:0xA3:0xFC
-
-# & War Tome~ of Tulkas
-K:762:0xA3:0xFD
-
-# & Unholy Tome~ of the Hellflame
-K:763:0xA3:0xFE
-
-# & Corrupted Tome~ of Melkor
-K:764:0xA3:0xFF
-
-# [Aiding Shades]
-K:765:0xA3:0xF8
-
-# [Morgoth's Space-Time Warpings]
-K:766:0xA3:0xF9
-
-# [Murazor's Tome of Conjuring & Dispelling]
-K:767:0xA3:0xFA
-
-# & Forest Tome~ of Yavanna
-K:768:0xA3:0xFB
-
-# [Sauron's Forgotten Tome]
-K:769:0xA3:0xFF
-
-# & Ring~
-K:770:0x85:0xBC
-
-# [Earth]
-K:771:0xA4:0x80
-
-# [Fire]
-K:772:0xA4:0x81
-
-# [Air]
-K:773:0xA4:0x82
-
-# [Water]
-K:774:0xA4:0x83
-
-# [Mana]
-K:775:0xA4:0x84
-
-# Home Summoning
-K:776:0x85:0x97
-
-# & Shadow Blade~
-K:777:0xA4:0x89
-
-# & Bluesteel Blade~
-K:778:0xA4:0x8A
-
-# the Serpents
-K:779:0xA5:0xC0
-
-# Darkness
-K:780:0xA5:0xC1
-
-# Knowledge
-K:781:0xA5:0xC2
-
-# Force
-K:782:0xA5:0xC3
-
-# Lightning
-K:783:0xA5:0xC4
-
-# Mana
-K:784:0xA5:0xC5
-
-# Ring~ of Power
-K:785:0xA5:0xC6
-
-# Climbing Set~
-K:786:0xA4:0x8B
-
-# Adventurer's guide to Middle-earth
-K:787:0x85:0x96
-
-# & Demonblade~
-K:788:0x8B:0xE0
-
-# & Demonshield~
-K:789:0x8B:0xE1
-
-# & Demonhorn~
-K:790:0x8B:0xE2
-
-# [Demonthoughts]
-K:791:0xA3:0xFB
-
-# [Hellfire Tome]
-K:792:0xA4:0x8C
-
-# & Wooden Rod~ of#
-K:793:0xA4:0x8D
-
-# & Copper Rod~ of#
-K:794:0xA4:0x8E
-
-# & Iron Rod~ of#
-K:795:0xA4:0x8F
-
-# & Moonstone Rod~ of#
-K:796:0xA4:0x90
-
-# & Silver Rod~ of#
-K:797:0xA4:0x91
-
-# & Golden Rod~ of#
-K:798:0xA4:0x93
-
-# & Mithril Rod~ of#
-K:799:0xA4:0x94
-
-# & Adamantite Rod~ of#
-K:800:0xA4:0x95
-
-# & Greater Ration~ of Health
-K:801:0xA5:0xBF
-
-# & Crumpled Scroll~ of Mass Resurrection
-K:802:0x85:0x96
-
-# & Cleaver~
-K:803:0xA5:0xBA
-
-# & Light War Axe~
-K:804:0xA5:0xBB
-
-# & Slaughter Axe~
-K:805:0xA5:0xBC
-
-# & Runestone~
-K:806:0xA5:0xBD
-
-# & Fortune cookie~
-K:807:0xA6:0xBE
-
-# Portable hole
-K:808:0xA6:0xC1
-
-# Critical Hits
-K:809:0xA6:0xD4
-
-# & Wand~ of Digging of Thrain
-K:810:0xA6:0xD4
-
-# & Gnarled Staff~ of Holy Fire of Mithrandir
-K:811:0xA6:0xD4
-
-# Partial Totem
-K:812:0xA6:0xD5
-
-# True Totem
-K:813:0xA6:0xD6
-
-# & piece~ of a Relic of Eru
-K:814:0x89:0xDA
-
-# & piece~ of a Relic of Manwe
-K:815:0x89:0xDB
-
-# & piece~ of a Relic of Tulkas
-K:816:0x89:0xDC
-
-# & piece~ of a Relic of Melkor
-K:817:0x89:0xDD
-
-# & piece~ of a Relic of Yavanna
-K:818:0x89:0xDE
-
-# Player
-R:0:0x80:0xC0
-
-# Filthy street urchin
-R:1:0x98:0xB8
-
-# Scrawny cat
-R:2:0x96:0xFA
-
-# Sparrow
-R:3:0x9D:0xD6
-
-# Chaffinch
-R:4:0x9D:0xD6
-
-# Wild rabbit
-R:5:0x9D:0xD7
-
-# Woodsman
-R:6:0x98:0xC9
-
-# Scruffy little dog
-R:7:0x92:0x92
-
-# Farmer Maggot
-R:8:0x98:0xB9
-
-# Blubbering idiot
-R:9:0x98:0xBA
-
-# Boil-covered wretch
-R:10:0x98:0xBB
-
-# Village idiot
-R:11:0x98:0xBC
-
-# Pitiful-looking beggar
-R:12:0x98:0xBD
-
-# Mangy-looking leper
-R:13:0x98:0xBE
-
-# Agent of the black market
-R:14:0x98:0xBF
-
-# Singing, happy drunk
-R:15:0x98:0xC0
-
-# Aimless-looking merchant
-R:16:0x98:0xC1
-
-# Mean-looking mercenary
-R:17:0x98:0xC2
-
-# Battle-scarred veteran
-R:18:0x98:0xC3
-
-# Martti Ihrasaari
-R:19:0x9B:0xB8
-
-# Grey mold
-R:20:0x97:0xD7
-
-# Large white snake
-R:21:0x94:0xBD
-
-# Grey mushroom patch
-R:22:0x9B:0xB9
-
-# Newt
-R:23:0x9B:0xBA
-
-# Giant white centipede
-R:24:0x96:0x8D
-
-# White icky thing
-R:25:0x97:0xBB
-
-# Clear icky thing
-R:26:0x97:0xBC
-
-# Giant white mouse
-R:27:0x99:0xBD
-
-# Large brown snake
-R:28:0x94:0xBC
-
-# Small kobold
-R:29:0x97:0xD1
-
-# Kobold
-R:30:0x97:0xD2
-
-# White worm mass
-R:31:0x99:0xD5
-
-# Floating eye
-R:32:0x96:0xD3
-
-# Rock lizard
-R:33:0x94:0xBE
-
-# Grid bug
-R:34:0x9B:0xBC
-
-# Jackal
-R:35:0x92:0x93
-
-# Soldier ant
-R:36:0x95:0xFF
-
-# Fruit bat
-R:37:0x96:0x87
-
-# Insect swarm
-R:38:0x9E:0x96
-
-# The Greater hell-beast
-R:39:0x9B:0xBB
-
-# Shrieker mushroom patch
-R:40:0x91:0xFE
-
-# Blubbering icky thing
-R:41:0x97:0xBD
-
-# Metallic green centipede
-R:42:0x96:0x8E
-
-# Novice warrior
-R:43:0x98:0xC4
-
-# Novice rogue
-R:44:0x98:0xC5
-
-# Novice priest
-R:45:0x98:0xC6
-
-# Novice mage
-R:46:0x98:0xC7
-
-# Yellow mushroom patch
-R:47:0x91:0xFF
-
-# White jelly
-R:48:0x97:0xC2
-
-# Giant black ant
-R:49:0x96:0x80
-
-# Salamander
-R:50:0x94:0xC0
-
-# White harpy
-R:51:0x93:0xC0
-
-# Blue yeek
-R:52:0x99:0xFF
-
-# Grip, Farmer Maggot's dog
-R:53:0x92:0x94
-
-# Wolf, Farmer Maggot's dog
-R:54:0x92:0x95
-
-# Fang, Farmer Maggot's dog
-R:55:0x92:0x95
-
-# Giant green frog
-R:56:0x94:0xBF
-
-# Freesia
-R:57:0x9B:0xBD
-
-# Green worm mass
-R:58:0x99:0xD6
-
-# Large yellow snake
-R:59:0x94:0xC1
-
-# Cave spider
-R:60:0x94:0xD5
-
-# Crow
-R:61:0x9E:0x97
-
-# Wild cat
-R:62:0x96:0xFB
-
-# Smeagol
-R:63:0x98:0xC8
-
-# Green ooze
-R:64:0x97:0xC3
-
-# Poltergeist
-R:65:0x93:0x91
-
-# Yellow jelly
-R:66:0x97:0xC5
-
-# Metallic blue centipede
-R:67:0x96:0x8F
-
-# Raven
-R:68:0x9E:0x97
-
-# Giant white louse
-R:69:0x97:0xD5
-
-# Giant yellow centipede
-R:70:0x96:0x8C
-
-# Black naga
-R:71:0x98:0x80
-
-# Spotted mushroom patch
-R:72:0x92:0x80
-
-# Silver jelly
-R:73:0x97:0xC4
-
-# Scruffy-looking hobbit
-R:74:0x97:0x8B
-
-# Giant white ant
-R:75:0x96:0x81
-
-# Yellow mold
-R:76:0x97:0xF8
-
-# Metallic red centipede
-R:77:0x96:0x90
-
-# Yellow worm mass
-R:78:0x99:0xD7
-
-# Clear worm mass
-R:79:0x99:0xF8
-
-# Radiation eye
-R:80:0x96:0xD4
-
-# Yellow light
-R:81:0x9F:0xCB
-
-# Cave lizard
-R:82:0x94:0xC2
-
-# Novice ranger
-R:83:0x98:0xC9
-
-# Blue jelly
-R:84:0x97:0xC6
-
-# Creeping copper coins
-R:85:0x91:0xF8
-
-# Giant white rat
-R:86:0x99:0xBE
-
-# Snotling
-R:87:0xA0:0x81
-
-# Swordfish
-R:88:0x9E:0xD6
-
-# Blue worm mass
-R:89:0x99:0xF9
-
-# Large grey snake
-R:90:0x94:0xC3
-
-# Skeleton kobold
-R:91:0x99:0xC1
-
-# Ewok
-R:92:0x9B:0xBE
-
-# Novice mage
-R:93:0x98:0xC7
-
-# Green naga
-R:94:0x98:0x81
-
-# Giant leech
-R:95:0x9F:0xCC
-
-# Barracuda
-R:96:0x9E:0xD7
-
-# Novice paladin
-R:97:0x98:0xCA
-
-# Zog
-R:98:0x93:0xF8
-
-# Blue ooze
-R:99:0x97:0xC7
-
-# Green glutton ghost
-R:100:0x93:0x92
-
-# Green jelly
-R:101:0x97:0xC8
-
-# Large kobold
-R:102:0x97:0xD3
-
-# Grey icky thing
-R:103:0x97:0xBE
-
-# Disenchanter eye
-R:104:0x96:0xD5
-
-# Red worm mass
-R:105:0x99:0xFA
-
-# Copperhead snake
-R:106:0x94:0xC4
-
-# Death sword
-R:107:0x9B:0xBF
-
-# Purple mushroom patch
-R:108:0x92:0x81
-
-# Novice priest
-R:109:0x98:0xC6
-
-# Novice warrior
-R:110:0x98:0xC4
-
-# Nibelung
-R:111:0x9B:0xC0
-
-# The disembodied hand that strangled people
-R:112:0x9B:0xC1
-
-# Brown mold
-R:113:0x97:0xF9
-
-# Giant brown bat
-R:114:0x96:0x88
-
-# Rat-thing
-R:115:0x99:0xC0
-
-# Novice rogue
-R:116:0x98:0xBF
-
-# Creeping silver coins
-R:117:0x91:0xF9
-
-# Snaga
-R:118:0x98:0x86
-
-# Rattlesnake
-R:119:0x94:0xC5
-
-# Giant slug
-R:120:0x9F:0xCC
-
-# Giant pink frog
-R:121:0x9F:0xCD
-
-# Dark elf
-R:122:0x8C:0xCC
-
-# Zombified kobold
-R:123:0x99:0xC1
-
-# Crypt creep
-R:124:0x9B:0xC2
-
-# Rotting corpse
-R:125:0x9B:0xC3
-
-# Cave orc
-R:126:0x98:0x87
-
-# Wood spider
-R:127:0x94:0xD6
-
-# Manes
-R:128:0x93:0xC9
-
-# Bloodshot eye
-R:129:0x96:0xD6
-
-# Red naga
-R:130:0x98:0x82
-
-# Red jelly
-R:131:0x97:0xC9
-
-# Green icky thing
-R:132:0x97:0xBF
-
-# Lost soul
-R:133:0x93:0x93
-
-# Night lizard
-R:134:0x94:0xC7
-
-# Mughash, the Kobold Lord
-R:135:0x97:0xD4
-
-# Skeleton orc
-R:136:0x99:0xC2
-
-# Wormtongue, Agent of Saruman
-R:137:0x98:0xD0
-
-# Robin Hood, the Outlaw
-R:138:0x9B:0xC4
-
-# Nurgling
-R:139:0x9F:0xCF
-
-# Lagduf, the Snaga
-R:140:0x98:0x88
-
-# Brown yeek
-R:141:0x9A:0x80
-
-# Novice ranger
-R:142:0x98:0xC9
-
-# Giant salamander
-R:143:0x94:0xC8
-
-# Space monster
-R:144:0x9B:0xC5
-
-# Carnivorous flying monkey
-R:145:0x9F:0xD0
-
-# Green mold
-R:146:0x97:0xFA
-
-# Novice paladin
-R:147:0x98:0xCA
-
-# Lemure
-R:148:0x93:0xCA
-
-# Hill orc
-R:149:0x98:0x89
-
-# Bandit
-R:150:0x98:0xD3
-
-# Hunting hawk
-R:151:0x9B:0xC6
-
-# Phantom warrior
-R:152:0x9B:0xC7
-
-# Gremlin
-R:153:0x9B:0xC8
-
-# Yeti
-R:154:0x95:0xC9
-
-# Bloodshot icky thing
-R:155:0x97:0xC0
-
-# Giant grey rat
-R:156:0x99:0xBF
-
-# Black harpy
-R:157:0x93:0xC1
-
-# Skaven
-R:158:0x9F:0xD1
-
-# The wounded bear
-R:159:0xA0:0xB8
-
-# Cave bear
-R:160:0xA5:0xC7
-
-# Rock mole
-R:161:0xA0:0xBA
-
-# Mindcrafter
-R:162:0x98:0xCB
-
-# Baby blue dragon
-R:163:0x96:0x95
-
-# Baby white dragon
-R:164:0x96:0x96
-
-# Baby green dragon
-R:165:0x96:0x97
-
-# Baby black dragon
-R:166:0x96:0xB8
-
-# Baby red dragon
-R:167:0x96:0xB9
-
-# Giant red ant
-R:168:0x96:0x85
-
-# Brodda, the Easterling
-R:169:0x98:0xD4
-
-# Bloodfang, the Wolf
-R:170:0xA0:0xBB
-
-# King cobra
-R:171:0x94:0xC9
-
-# Eagle
-R:172:0x9D:0xD6
-
-# War bear
-R:173:0x9B:0xC9
-
-# Killer bee
-R:174:0x9B:0xCA
-
-# Giant spider
-R:175:0x94:0xD7
-
-# Giant white tick
-R:176:0x97:0xD5
-
-# The Borshin
-R:177:0xA0:0xBC
-
-# Dark elven mage
-R:178:0x97:0x8E
-
-# Kamikaze yeek
-R:179:0xA0:0xCC
-
-# Orfax, Son of Boldor
-R:180:0x9A:0x81
-
-# Servant of Glaaki
-R:181:0xA0:0xBD
-
-# Dark elven warrior
-R:182:0x97:0x8F
-
-# Sand-dweller
-R:183:0xA0:0xBE
-
-# Clear mushroom patch
-R:184:0x9F:0xCE
-
-# Quiver slot
-R:185:0x9B:0xCB
-
-# Grishnakh, the Hill Orc
-R:186:0x98:0x8B
-
-# Giant tan bat
-R:187:0xA5:0xC8
-
-# Owlbear
-R:188:0xA0:0xBF
-
-# Blue horror
-R:189:0x9F:0xD2
-
-# Hairy mold
-R:190:0x97:0xFB
-
-# Grizzly bear
-R:191:0xA0:0xC0
-
-# Disenchanter mold
-R:192:0x97:0xFC
-
-# Pseudo dragon
-R:193:0x96:0xBA
-
-# Tengu
-R:194:0x93:0xCB
-
-# Creeping gold coins
-R:195:0x91:0xFA
-
-# Wolf
-R:196:0x92:0x96
-
-# Giant fruit fly
-R:197:0x93:0x89
-
-# Panther
-R:198:0x96:0xFC
-
-# Brigand
-R:199:0x9B:0xCC
-
-# Hobbes the Tiger
-R:200:0x9B:0xCD
-
-# Shadow Creature of Fiona
-R:201:0x9B:0xCE
-
-# Undead mass
-R:202:0x9B:0xCF
-
-# Chaos shapechanger
-R:203:0x9B:0xD0
-
-# Baby multi-hued dragon
-R:204:0x96:0xBB
-
-# Vorpal bunny
-R:205:0x9D:0xD7
-
-# Old Man Willow
-R:206:0xA0:0xC1
-
-# Hippocampus
-R:207:0xA0:0xC2
-
-# Zombified orc
-R:208:0x99:0xC4
-
-# Hippogriff
-R:209:0x93:0xC2
-
-# Black mamba
-R:210:0x94:0xCA
-
-# White wolf
-R:211:0x92:0x97
-
-# Grape jelly
-R:212:0x97:0xCA
-
-# Nether worm mass
-R:213:0x99:0xFB
-
-# Abyss worm mass
-R:214:0x9B:0xD1
-
-# Golfimbul, the Hill Orc Chief
-R:215:0x98:0x8C
-
-# Swordsman
-R:216:0x8E:0xF9
-
-# Skaven shaman
-R:217:0x90:0xBC
-
-# Baby bronze dragon
-R:218:0x96:0xBA
-
-# Baby gold dragon
-R:219:0x96:0xBA
-
-# Evil eye
-R:220:0xA5:0xC9
-
-# Mine-dog
-R:221:0xA0:0x83
-
-# Hellcat
-R:222:0x9B:0xD2
-
-# Moon beast
-R:223:0x9B:0xD3
-
-# Master yeek
-R:224:0x9A:0x82
-
-# Priest
-R:225:0x98:0xD6
-
-# Dark elven priest
-R:226:0x97:0x91
-
-# Air spirit
-R:227:0x92:0xD7
-
-# Skeleton human
-R:228:0x99:0xC3
-
-# Zombified human
-R:229:0x9A:0x86
-
-# Tiger
-R:230:0x96:0xFD
-
-# Moaning spirit
-R:231:0x93:0x94
-
-# Stegocentipede
-R:232:0x96:0x91
-
-# Spotted jelly
-R:233:0x97:0xCB
-
-# Drider
-R:234:0x94:0xF8
-
-# Mongbat
-R:235:0x9B:0xD4
-
-# Killer brown beetle
-R:236:0x93:0xD3
-
-# Boldor, King of the Yeeks
-R:237:0x9A:0x83
-
-# Ogre
-R:238:0x94:0x83
-
-# Creeping mithril coins
-R:239:0x91:0xFB
-
-# Illusionist
-R:240:0x98:0xF8
-
-# Druid
-R:241:0x98:0xF9
-
-# Pink horror
-R:242:0x9F:0xD3
-
-# Cloaker
-R:243:0x88:0x80
-
-# Black orc
-R:244:0x98:0x8D
-
-# Ochre jelly
-R:245:0x97:0xCC
-
-# Software bug
-R:246:0x9B:0xD5
-
-# Lurker
-R:247:0x83:0xB9
-
-# Tangleweed
-R:248:0xA5:0xCA
-
-# Vlasta
-R:249:0x95:0xFC
-
-# Giant white dragon fly
-R:250:0x93:0x8B
-
-# Snaga sapper
-R:251:0xA0:0x84
-
-# Blue icky thing
-R:252:0x97:0xC1
-
-# Gibbering mouther
-R:253:0x9B:0xD6
-
-# Wolfhound of Flora
-R:254:0x9B:0xD7
-
-# Hill giant
-R:255:0x94:0x89
-
-# Flesh golem
-R:256:0x97:0x81
-
-# Warg
-R:257:0x92:0xB8
-
-# Cheerful leprechaun
-R:258:0x9B:0xF8
-
-# Giant flea
-R:259:0x93:0x8A
-
-# Ufthak of Cirith Ungol
-R:260:0xA0:0xC4
-
-# Clay golem
-R:261:0x9F:0xD5
-
-# Black ogre
-R:262:0x94:0x84
-
-# Dweller on the threshold
-R:263:0xA0:0x85
-
-# Half-orc
-R:264:0xA0:0xC5
-
-# Dark naga
-R:265:0x9F:0xD6
-
-# Poison ivy
-R:266:0xA5:0xCB
-
-# Magic mushroom patch
-R:267:0x92:0x83
-
-# Plaguebearer of Nurgle
-R:268:0x9A:0x85
-
-# Guardian naga
-R:269:0x98:0x83
-
-# Wererat
-R:270:0xA0:0xC6
-
-# Light hound
-R:271:0x95:0xCB
-
-# Dark hound
-R:272:0x95:0xCC
-
-# Flying skull
-R:273:0x9B:0xF9
-
-# Mi-Go
-R:274:0x9B:0xFA
-
-# Giant tarantula
-R:275:0x94:0xF9
-
-# Giant clear centipede
-R:276:0x96:0x92
-
-# Mirkwood spider
-R:277:0x94:0xFA
-
-# Frost giant
-R:278:0x94:0x8A
-
-# Griffon
-R:279:0x93:0xC3
-
-# Homunculus
-R:280:0x93:0xCC
-
-# Gnome mage
-R:281:0x97:0x90
-
-# Clear hound
-R:282:0x95:0xCD
-
-# Umber hulk
-R:283:0x95:0x91
-
-# Rust monster
-R:284:0xA0:0x87
-
-# Ogrillon
-R:285:0x98:0x90
-
-# Gelatinous cube
-R:286:0x97:0xCD
-
-# Giant green dragon fly
-R:287:0x93:0x8C
-
-# Fire giant
-R:288:0x94:0x8B
-
-# Hummerhorn
-R:289:0xA0:0xC7
-
-# Lizard man
-R:290:0xA0:0x88
-
-# Ulfast, Son of Ulfang
-R:291:0x98:0xFA
-
-# Crebain
-R:292:0xA5:0xCC
-
-# Berserker
-R:293:0x98:0x8F
-
-# Quasit
-R:294:0x93:0xCD
-
-# Sphinx
-R:295:0xA0:0x89
-
-# Imp
-R:296:0x93:0xCE
-
-# Forest troll
-R:297:0x95:0x81
-
-# Freezing sphere
-R:298:0xA0:0xC9
-
-# Jumping fireball
-R:299:0xA0:0x8A
-
-# Ball lightning
-R:300:0xA0:0xCA
-
-# 2-headed hydra
-R:301:0x94:0xCB
-
-# Swamp thing
-R:302:0xA0:0x8B
-
-# Water spirit
-R:303:0x92:0xF8
-
-# Giant red scorpion
-R:304:0x94:0xFB
-
-# Earth spirit
-R:305:0x92:0xF9
-
-# Fire spirit
-R:306:0x92:0xFA
-
-# Fire hound
-R:307:0x95:0xCE
-
-# Cold hound
-R:308:0x95:0xCF
-
-# Energy hound
-R:309:0x95:0xD0
-
-# Lesser Mimic
-R:310:0x92:0x86
-
-# Door mimic
-R:311:0x84:0xBB
-
-# Blink dog
-R:312:0x92:0xB9
-
-# Uruk
-R:313:0x98:0x91
-
-# Shagrat, the Orc Captain
-R:314:0x98:0x92
-
-# Gorbag, the Orc Captain
-R:315:0x98:0x93
-
-# Shambling mound
-R:316:0x92:0x84
-
-# Giant Venus Flytrap
-R:317:0xA5:0xCD
-
-# Chaos beastman
-R:318:0xA0:0x8D
-
-# Daemonette of Slaanesh
-R:319:0xA0:0x8C
-
-# Giant bronze dragon fly
-R:320:0x93:0x90
-
-# Stone giant
-R:321:0x94:0x8C
-
-# Giant black dragon fly
-R:322:0x93:0x8E
-
-# Stone golem
-R:323:0x97:0x83
-
-# Red mold
-R:324:0x97:0xFD
-
-# Giant gold dragon fly
-R:325:0x93:0x8F
-
-# Stunwall
-R:326:0x83:0xCB
-
-# Ghast
-R:327:0xA0:0xCD
-
-# Neekerbreeker
-R:328:0xA5:0xCE
-
-# Huorn
-R:329:0xA0:0xCE
-
-# Bolg, Son of Azog
-R:330:0x98:0x94
-
-# Phase spider
-R:331:0x94:0xFC
-
-# Lizard king
-R:332:0xA0:0x8F
-
-# Landmine
-R:333:0xA0:0xCF
-
-# Wyvern
-R:334:0x9B:0xFB
-
-# Great eagle
-R:335:0xA0:0x90
-
-# Livingstone
-R:336:0x9B:0xFC
-
-# Earth hound
-R:337:0x95:0xD1
-
-# Air hound
-R:338:0x95:0xD2
-
-# Sabre-tooth tiger
-R:339:0x96:0xFE
-
-# Acid hound
-R:340:0x95:0xD3
-
-# Chimaera
-R:341:0x93:0xC4
-
-# Quylthulg
-R:342:0x94:0x92
-
-# Sasquatch
-R:343:0x95:0xCA
-
-# Weir
-R:344:0x9B:0xFD
-
-# Ranger
-R:345:0x98:0xCF
-
-# Paladin
-R:346:0x99:0x8A
-
-# Werewolf
-R:347:0xA0:0xD1
-
-# Dark elven lord
-R:348:0x97:0x94
-
-# Cloud giant
-R:349:0x94:0x8E
-
-# Ugluk, the Uruk
-R:350:0x98:0x95
-
-# Blue dragon bat
-R:351:0x96:0x89
-
-# Mimic
-R:352:0x85:0x95
-
-# Ultimate Mimic
-R:353:0x85:0xD6
-
-# Fire vortex
-R:354:0x99:0xCC
-
-# Acid vortex
-R:355:0x99:0xCD
-
-# Lugdush, the Uruk
-R:356:0xA0:0x92
-
-# Arch-vile
-R:357:0xA0:0xD2
-
-# Cold vortex
-R:358:0x99:0xCE
-
-# Energy vortex
-R:359:0x99:0xCF
-
-# Globefish
-R:360:0xA0:0x93
-
-# Giant firefly
-R:361:0x93:0x8D
-
-# Mummified orc
-R:362:0x94:0x80
-
-# Wolf chieftain
-R:363:0xA5:0xCF
-
-# Serpent man
-R:364:0xA0:0xD4
-
-# Vampiric mist
-R:365:0xA0:0x95
-
-# Killer stag beetle
-R:366:0x93:0xD5
-
-# Iron golem
-R:367:0x97:0x84
-
-# Auto-roller
-R:368:0x9B:0xFE
-
-# Giant yellow scorpion
-R:369:0x94:0xFD
-
-# Jade monk
-R:370:0xA0:0xD5
-
-# Black ooze
-R:371:0x97:0xCE
-
-# Hardened warrior
-R:372:0x98:0xFB
-
-# Azog, King of the Uruk-Hai
-R:373:0x98:0x97
-
-# Fleshhound of Khorne
-R:374:0xA0:0x96
-
-# Dark elven warlock
-R:375:0x9B:0xFF
-
-# Master rogue
-R:376:0x98:0xFC
-
-# Red dragon bat
-R:377:0x96:0x8A
-
-# Killer white beetle
-R:378:0xA0:0xD6
-
-# Ice skeleton
-R:379:0xA0:0x97
-
-# Angamaite of Umbar
-R:380:0xA0:0xF8
-
-# Forest wight
-R:381:0x9C:0x80
-
-# Khim, Son of Mim
-R:382:0x9C:0x81
-
-# Ibun, Son of Mim
-R:383:0x9C:0x82
-
-# Meneldor the Swift
-R:384:0xA0:0xF9
-
-# Phantom beast
-R:385:0x9C:0x83
-
-# Giant silver ant
-R:386:0x93:0xD4
-
-# 4-headed hydra
-R:387:0x94:0xCD
-
-# Lesser hell-beast
-R:388:0xA0:0xFB
-
-# Tyrannosaur
-R:389:0x9C:0x84
-
-# Mummified human
-R:390:0x94:0x81
-
-# Vampire bat
-R:391:0x96:0x8B
-
-# Sangahyando of Umbar
-R:392:0x98:0xFD
-
-# It
-R:393:0x9C:0x85
-
-# Banshee
-R:394:0x93:0x95
-
-# Carrion crawler
-R:395:0x96:0x93
-
-# Xiclotlan
-R:396:0xA0:0xFC
-
-# Silent watcher
-R:397:0x9C:0x86
-
-# Pukelman
-R:398:0x97:0x85
-
-# Disenchanter beast
-R:399:0xA0:0xD7
-
-# Dark elven druid
-R:400:0x97:0x97
-
-# Stone troll
-R:401:0x95:0x82
-
-# Black
-R:402:0x9B:0xC5
-
-# Hill troll
-R:403:0x95:0x83
-
-# Wereworm
-R:404:0x99:0xFC
-
-# Killer red beetle
-R:405:0x93:0xD7
-
-# Disenchanter bat
-R:406:0xA5:0xD0
-
-# Gnoph-Keh
-R:407:0xA0:0xFE
-
-# Giant grey ant
-R:408:0x96:0x84
-
-# Khufu, the Mummified King
-R:409:0x9C:0x87
-
-# Gwaihir the Windlord
-R:410:0xA0:0xF9
-
-# Giant fire tick
-R:411:0xA0:0xFF
-
-# Displacer beast
-R:412:0x96:0xFF
-
-# Ulwarth, Son of Ulfang
-R:413:0x98:0xD1
-
-# Werebear
-R:414:0xA5:0xC7
-
-# Cave ogre
-R:415:0x94:0x85
-
-# White wraith
-R:416:0x95:0x97
-
-# Angel
-R:417:0x92:0x87
-
-# Ghoul
-R:418:0x9D:0xC7
-
-# Mim, Betrayer of Turin
-R:419:0x9C:0x88
-
-# Hellblade
-R:420:0x9C:0x89
-
-# Killer fire beetle
-R:421:0x93:0xF8
-
-# Beast of Nurgle
-R:422:0xA1:0x80
-
-# Creeping adamantite coins
-R:423:0x91:0xFC
-
-# Algroth
-R:424:0x95:0x84
-
-# Flamer of Tzeentch
-R:425:0x9F:0xD7
-
-# Roper
-R:426:0x9F:0xF8
-
-# Headless
-R:427:0x9C:0x8A
-
-# Vibration hound
-R:428:0x95:0xD4
-
-# Nexus hound
-R:429:0x95:0xD5
-
-# Half-ogre
-R:430:0x94:0x86
-
-# Lokkak, the Ogre Chieftain
-R:431:0x94:0x88
-
-# Vampire
-R:432:0x95:0x92
-
-# Gorgimaera
-R:433:0x93:0xC5
-
-# Shantak
-R:434:0x9C:0x8B
-
-# Colbran
-R:435:0x97:0x86
-
-# Spirit naga
-R:436:0x98:0x84
-
-# Corpser
-R:437:0x9F:0xF9
-
-# Fiend of Slaanesh
-R:438:0x94:0xCF
-
-# Stairway to Hell
-R:439:0x9C:0x8C
-
-# 5-headed hydra
-R:440:0x94:0xCE
-
-# Barney the Dinosaur
-R:441:0x9C:0x8D
-
-# Black knight
-R:442:0x99:0x80
-
-# Seahorse
-R:443:0xA1:0x81
-
-# Cyclops
-R:444:0xA1:0x82
-
-# Clairvoyant
-R:445:0x98:0xFE
-
-# Purple worm
-R:446:0x9F:0xFA
-
-# Catoblepas
-R:447:0x99:0xB9
-
-# Lesser wall monster
-R:448:0x9C:0x8E
-
-# Mage
-R:449:0x99:0x82
-
-# Mind flayer
-R:450:0x99:0x83
-
-# The Ultimate Dungeon Cleaner
-R:451:0x9C:0x8F
-
-# Deep one
-R:452:0x95:0xBE
-
-# Basilisk
-R:453:0x94:0xCF
-
-# Ice troll
-R:454:0x95:0x85
-
-# Dhole
-R:455:0x9C:0x91
-
-# Archangel
-R:456:0x92:0x88
-
-# Greater Mimic
-R:457:0x9A:0x96
-
-# Chaos tile
-R:458:0x9C:0x92
-
-# Young blue dragon
-R:459:0x96:0xBC
-
-# Young white dragon
-R:460:0x96:0xBD
-
-# Young green dragon
-R:461:0x96:0xBE
-
-# Young bronze dragon
-R:462:0x96:0xBF
-
-# Aklash
-R:463:0xA4:0x96
-
-# Mithril golem
-R:464:0x97:0x87
-
-# Skeleton troll
-R:465:0x99:0xC5
-
-# Skeletal tyrannosaur
-R:466:0xA1:0x83
-
-# Beorn, the Shape-Changer
-R:467:0xA5:0xD1
-
-# Thorondor, Lord of Eagles
-R:468:0xA0:0xF9
-
-# Giant blue ant
-R:469:0x96:0x83
-
-# Grave wight
-R:470:0x9A:0x94
-
-# Shadow drake
-R:471:0x96:0xC0
-
-# Manticore
-R:472:0x93:0xC6
-
-# Giant army ant
-R:473:0x9A:0xB9
-
-# Killer slicer beetle
-R:474:0x93:0xF9
-
-# Gorgon
-R:475:0xA1:0x85
-
-# Gug
-R:476:0xA1:0x86
-
-# Ghost
-R:477:0x93:0x96
-
-# Death watch beetle
-R:478:0x93:0xFA
-
-# Mountain ogre
-R:479:0x94:0x87
-
-# Nexus quylthulg
-R:480:0x94:0x93
-
-# Shelob, Spider of Darkness
-R:481:0x94:0xFE
-
-# Giant squid
-R:482:0x9F:0xFB
-
-# Ghoulking
-R:483:0x9A:0x84
-
-# Doombat
-R:484:0x9F:0xFC
-
-# Ninja
-R:485:0x99:0x84
-
-# Memory moss
-R:486:0x97:0xFE
-
-# Storm giant
-R:487:0x94:0x8D
-
-# Spectator
-R:488:0x9C:0x93
-
-# Bokrug
-R:489:0xA1:0x87
-
-# Biclops
-R:490:0xA1:0x88
-
-# Half-troll
-R:491:0x98:0x96
-
-# Ivory monk
-R:492:0x98:0xCB
-
-# Bert the Stone Troll
-R:493:0x95:0x88
-
-# Bill the Stone Troll
-R:494:0x95:0x89
-
-# Tom the Stone Troll
-R:495:0x95:0x8A
-
-# Cave troll
-R:496:0x95:0x86
-
-# Anti-paladin
-R:497:0x9C:0x94
-
-# Chaos master
-R:498:0x9C:0x95
-
-# Barrow wight
-R:499:0x95:0xB9
-
-# Skeleton ettin
-R:500:0xA5:0xD2
-
-# Chaos drake
-R:501:0x96:0xC1
-
-# Law drake
-R:502:0x96:0xC2
-
-# Balance drake
-R:503:0x96:0xC3
-
-# Ethereal drake
-R:504:0x96:0xC4
-
-# Groo, the Wanderer
-R:505:0x9C:0x96
-
-# Fasolt the Giant
-R:506:0x9C:0x97
-
-# Shade
-R:507:0x95:0xC1
-
-# Spectre
-R:508:0x93:0xB8
-
-# Water troll
-R:509:0x95:0x8B
-
-# Fire elemental
-R:510:0x92:0xFB
-
-# Cherub
-R:511:0x92:0x89
-
-# Water elemental
-R:512:0x92:0xFC
-
-# Multi-hued hound
-R:513:0x9C:0xB9
-
-# Invisible stalker
-R:514:0x92:0xFD
-
-# Carrion crawler
-R:515:0x96:0x94
-
-# Master thief
-R:516:0x99:0x86
-
-# The Watcher in the Water
-R:517:0x9B:0x8D
-
-# Lich
-R:518:0x93:0xFB
-
-# Gas spore
-R:519:0x9C:0xC6
-
-# Master vampire
-R:520:0x95:0x93
-
-# Oriental vampire
-R:521:0x9C:0xBB
-
-# Greater mummy
-R:522:0x94:0x82
-
-# Bloodletter of Khorne
-R:523:0x93:0xD0
-
-# Giant grey scorpion
-R:524:0x94:0xFF
-
-# Earth elemental
-R:525:0x92:0xFE
-
-# Air elemental
-R:526:0x92:0xFF
-
-# Shimmering mold
-R:527:0x9A:0xF9
-
-# Gargoyle
-R:528:0xA1:0x89
-
-# Malicious leprechaun
-R:529:0x9C:0xBD
-
-# Eog golem
-R:530:0x97:0x88
-
-# Little Boy
-R:531:0x9F:0xFD
-
-# Dagashi
-R:532:0x99:0x88
-
-# Headless ghost
-R:533:0xA1:0x8A
-
-# Dread
-R:534:0x9F:0xFF
-
-# Leng spider
-R:535:0xA1:0x8B
-
-# Gauth
-R:536:0xA5:0xD3
-
-# Smoke elemental
-R:537:0x93:0x88
-
-# Olog
-R:538:0x95:0x8C
-
-# Halfling slinger
-R:539:0x9C:0xBE
-
-# Gravity hound
-R:540:0x95:0xD6
-
-# Acidic cytoplasm
-R:541:0x97:0xCF
-
-# Inertia hound
-R:542:0x95:0xD7
-
-# Impact hound
-R:543:0x95:0xF8
-
-# Shardstorm
-R:544:0xA5:0xD4
-
-# Ooze elemental
-R:545:0x93:0x80
-
-# Young black dragon
-R:546:0x96:0xC5
-
-# Mumak
-R:547:0x99:0xBC
-
-# Giant fire ant
-R:548:0x96:0x82
-
-# Mature white dragon
-R:549:0x96:0xC6
-
-# Xorn
-R:550:0x95:0xC7
-
-# Rogrog the Black Troll
-R:551:0x95:0x87
-
-# Mist giant
-R:552:0x97:0x89
-
-# Phantom
-R:553:0x9C:0xBF
-
-# Grey wraith
-R:554:0x95:0xBA
-
-# Revenant
-R:555:0x95:0xC0
-
-# Young multi-hued dragon
-R:556:0x96:0xC7
-
-# Raal's Tome of Destruction
-R:557:0x9C:0xC0
-
-# Colossus
-R:558:0x9C:0xC1
-
-# Young gold dragon
-R:559:0x96:0xC8
-
-# Mature blue dragon
-R:560:0x96:0xC9
-
-# Mature green dragon
-R:561:0x96:0xCA
-
-# Mature bronze dragon
-R:562:0x96:0xCB
-
-# Young red dragon
-R:563:0x96:0xCC
-
-# Nightblade
-R:564:0x9C:0xC2
-
-# Trapper
-R:565:0x9A:0x97
-
-# Bodak
-R:566:0x93:0xD0
-
-# Time bomb
-R:567:0xA1:0x8E
-
-# Mezzodaemon
-R:568:0x9A:0x88
-
-# Elder thing
-R:569:0x9C:0xC3
-
-# Ice elemental
-R:570:0x93:0x82
-
-# Necromancer
-R:571:0x9C:0xC4
-
-# The Greater hell magic mushroom were-quylthulg
-R:572:0x9F:0xFE
-
-# Lorgan, Chief of the Easterlings
-R:573:0x9C:0xC5
-
-# Chaos spawn
-R:574:0x9C:0xC6
-
-# Mummified troll
-R:575:0xA1:0x8F
-
-# Storm of Unmagic
-R:576:0xA5:0xD5
-
-# Crypt thing
-R:577:0x95:0xB8
-
-# Chaos butterfly
-R:578:0x80:0x80
-
-# Time elemental
-R:579:0x9C:0xC7
-
-# Flying polyp
-R:580:0xA1:0x91
-
-# The Queen Ant
-R:581:0x96:0x86
-
-# Will o' the wisp
-R:582:0x93:0x83
-
-# Shan
-R:583:0xA1:0x92
-
-# Magma elemental
-R:584:0x93:0x84
-
-# Black pudding
-R:585:0x97:0xD0
-
-# Killer iridescent beetle
-R:586:0x9D:0xC8
-
-# Nexus vortex
-R:587:0x9A:0xB8
-
-# Plasma vortex
-R:588:0x99:0xD0
-
-# Mature red dragon
-R:589:0x96:0xCD
-
-# Mature gold dragon
-R:590:0x96:0xCE
-
-# Crystal drake
-R:591:0x96:0xCF
-
-# Mature black dragon
-R:592:0x96:0xD0
-
-# Mature multi-hued dragon
-R:593:0x96:0xD1
-
-# Sky whale
-R:594:0xA1:0x93
-
-# Draebor, the Imp
-R:595:0xA4:0x97
-
-# Mother Hydra
-R:596:0x94:0xD0
-
-# Death knight
-R:597:0x99:0x8C
-
-# Castamir the Usurper
-R:598:0x9C:0xC8
-
-# Time vortex
-R:599:0x99:0xD1
-
-# Shimmering vortex
-R:600:0x99:0xD2
-
-# Ancient blue dragon
-R:601:0x92:0xC0
-
-# Ancient bronze dragon
-R:602:0x92:0xC1
-
-# Beholder
-R:603:0x96:0xD7
-
-# Emperor wight
-R:604:0x95:0xBB
-
-# Seraph
-R:605:0x92:0x8A
-
-# Vargo, Tyrant of Fire
-R:606:0x93:0x85
-
-# Black wraith
-R:607:0x95:0xBC
-
-# Nightgaunt
-R:608:0x9C:0xC9
-
-# Baron of hell
-R:609:0x9C:0xCA
-
-# Scylla
-R:610:0xA1:0x94
-
-# Monastic lich
-R:611:0x93:0xFF
-
-# Nether wraith
-R:612:0x95:0xBD
-
-# Hellhound
-R:613:0x9A:0x8E
-
-# 7-headed hydra
-R:614:0x94:0xD1
-
-# Waldern, King of Water
-R:615:0x93:0x86
-
-# Kavlax the Many-Headed
-R:616:0x96:0xD2
-
-# Ancient white dragon
-R:617:0x92:0xC2
-
-# Ancient green dragon
-R:618:0x92:0xC3
-
-# Chthonian
-R:619:0x9C:0xCB
-
-# Eldrak
-R:620:0x95:0x8F
-
-# Ettin
-R:621:0x95:0x8E
-
-# Night mare
-R:622:0x99:0xBB
-
-# Vampire lord
-R:623:0x95:0x94
-
-# Ancient black dragon
-R:624:0x92:0xC4
-
-# Weird fume
-R:625:0x9A:0xF8
-
-# Spawn of Ubbo-Sathla
-R:626:0xA1:0x95
-
-# Fat Man
-R:627:0x9F:0xFD
-
-# Malekith the Accursed
-R:628:0x97:0x8D
-
-# Shadowfax, steed of Gandalf
-R:629:0xA1:0x96
-
-# Spirit troll
-R:630:0x95:0x90
-
-# War troll
-R:631:0x9C:0xCC
-
-# Disenchanter worm mass
-R:632:0x99:0xFE
-
-# Rotting quylthulg
-R:633:0x94:0x94
-
-# Lesser titan
-R:634:0x94:0x8F
-
-# 9-headed hydra
-R:635:0x94:0xD1
-
-# Enchantress
-R:636:0x99:0x8E
-
-# Ranger chieftain
-R:637:0x99:0x8F
-
-# Sorcerer
-R:638:0x99:0x90
-
-# Xaren
-R:639:0x95:0xC8
-
-# Giant roc
-R:640:0x92:0x8F
-
-# Minotaur
-R:641:0x93:0xC7
-
-# Medusa, the Gorgon
-R:642:0x98:0x85
-
-# Death drake
-R:643:0x92:0xC5
-
-# Ancient red dragon
-R:644:0x92:0xC6
-
-# Ancient gold dragon
-R:645:0x92:0xC7
-
-# Great crystal drake
-R:646:0x92:0xC8
-
-# Wyrd sister
-R:647:0x97:0x95
-
-# Vrock
-R:648:0x9C:0xCD
-
-# Death quasit
-R:649:0x93:0xD1
-
-# Giganto, the Gargantuan
-R:650:0xA1:0x97
-
-# Strygalldwir
-R:651:0x9C:0xCE
-
-# Fallen angel
-R:652:0x98:0xC6
-
-# Giant headless
-R:653:0xA1:0xB8
-
-# Judge Fire
-R:654:0x99:0x8B
-
-# Ubbo-Sathla, the Unbegotten Source
-R:655:0xA1:0xB9
-
-# Judge Mortis
-R:656:0xA1:0xBA
-
-# Dark elven sorcerer
-R:657:0x97:0xB9
-
-# Master lich
-R:658:0x93:0xFC
-
-# Byakhee
-R:659:0x9C:0xCF
-
-# Eol, the Dark Elf
-R:660:0x9C:0xD1
-
-# Archon
-R:661:0x92:0x8B
-
-# Formless spawn of Tsathoggua
-R:662:0x9C:0xD2
-
-# Hunting horror
-R:663:0x9C:0xD3
-
-# Undead beholder
-R:664:0x96:0xF8
-
-# Shadow
-R:665:0x93:0xB9
-
-# Iron lich
-R:666:0x9C:0xD4
-
-# Dread
-R:667:0x9F:0xFF
-
-# Greater basilisk
-R:668:0xA1:0xBB
-
-# Charybdis
-R:669:0xA1:0xBC
-
-# Jack of Shadows
-R:670:0x99:0x94
-
-# Zephyr Lord
-R:671:0x99:0x89
-
-# Juggernaut of Khorne
-R:672:0xA1:0xBD
-
-# Mumak
-R:673:0x99:0xBA
-
-# Judge Fear
-R:674:0x97:0x80
-
-# Ancient multi-hued dragon
-R:675:0x92:0xC9
-
-# Ethereal dragon
-R:676:0x92:0xCA
-
-# Dark young of Shub-Niggurath
-R:677:0x9C:0xD5
-
-# Colour out of space
-R:678:0x8C:0x91
-
-# Quaker, Master of Earth
-R:679:0x93:0x87
-
-# Death leprechaun
-R:680:0x97:0x96
-
-# Chaugnar Faugn, Horror from the Hills
-R:681:0xA1:0xCC
-
-# Lloigor
-R:682:0xA1:0xCD
-
-# Utgard-Loke
-R:683:0xA1:0xCE
-
-# Quachil Uttaus, Treader of the Dust
-R:684:0xA1:0xCF
-
-# Shoggoth
-R:685:0xA1:0xD0
-
-# Judge Death
-R:686:0xA1:0xD1
-
-# Ariel, Queen of Air
-R:687:0x93:0x89
-
-# 11-headed hydra
-R:688:0x94:0xD2
-
-# Patriarch
-R:689:0x99:0x92
-
-# Dreadmaster
-R:690:0x93:0xBD
-
-# Drolem
-R:691:0x97:0x8A
-
-# Scatha the Worm
-R:692:0x9A:0x93
-
-# Warrior of the Dawn
-R:693:0x9C:0xD6
-
-# Lesser black reaver
-R:694:0x95:0xBF
-
-# Zoth-Ommog
-R:695:0xA2:0xC1
-
-# Grand master thief
-R:696:0xA4:0xC2
-
-# Smaug the Golden
-R:697:0x92:0xCB
-
-# The Stormbringer
-R:698:0x9C:0xF8
-
-# Knight Templar
-R:699:0x9C:0xF9
-
-# Leprechaun fanatic
-R:700:0x97:0xB8
-
-# Dracolich
-R:701:0x92:0xCD
-
-# Greater titan
-R:702:0x94:0x90
-
-# Dracolisk
-R:703:0x92:0xCC
-
-# Winged Horror
-R:704:0xA5:0xD6
-
-# Spectral tyrannosaur
-R:705:0x9C:0xFA
-
-# Yibb-Tstll, the Patient One
-R:706:0xA1:0xD3
-
-# Ghatanothoa
-R:707:0xA1:0xD4
-
-# Ent
-R:708:0xA1:0xBE
-
-# Hru
-R:709:0xA1:0xD5
-
-# Itangast the Fire Drake
-R:710:0x92:0xCE
-
-# Death mold
-R:711:0x97:0xFF
-
-# Fafner the Dragon
-R:712:0x9C:0xFB
-
-# Charon, Boatman of the Styx
-R:713:0xA1:0xD6
-
-# Quickbeam, the Ent
-R:714:0xA1:0xD7
-
-# Glaurung, Father of the Dragons
-R:715:0x9A:0x92
-
-# Behemoth
-R:716:0xA1:0xF8
-
-# Garm, Guardian of Hel
-R:717:0x92:0xBC
-
-# Greater wall monster
-R:718:0x9C:0xFC
-
-# Nycadaemon
-R:719:0x9A:0x89
-
-# Barbazu
-R:720:0x9A:0x8D
-
-# Goat of Mendes
-R:721:0x9C:0xFD
-
-# Nightwing
-R:722:0x9A:0x95
-
-# Maulotaur
-R:723:0x9C:0xFE
-
-# Nether hound
-R:724:0x95:0xF9
-
-# Time hound
-R:725:0x95:0xFA
-
-# Plasma hound
-R:726:0x95:0xFB
-
-# Demonic quylthulg
-R:727:0x94:0x95
-
-# Great Storm Wyrm
-R:728:0x92:0xCF
-
-# Ulik the Troll
-R:729:0xA1:0xF9
-
-# Baphomet the Minotaur Lord
-R:730:0x93:0xC8
-
-# Hell knight
-R:731:0xA1:0xFA
-
-# Bull Gates
-R:732:0x9C:0xFF
-
-# Santa Claus
-R:733:0x9D:0x80
-
-# Eihort, the Thing in the Labyrinth
-R:734:0xA2:0xC2
-
-# The King in Yellow
-R:735:0xA2:0xC3
-
-# Great unclean one
-R:736:0xA2:0xC4
-
-# Lord of Chaos
-R:737:0x9D:0x81
-
-# Old Sorcerer
-R:738:0x91:0xC2
-
-# Ethereal hound
-R:739:0x9D:0x82
-
-# Lesser kraken
-R:740:0xA1:0xFB
-
-# Great Ice Wyrm
-R:741:0x92:0xD0
-
-# Demilich
-R:742:0x95:0xC2
-
-# The Phoenix
-R:743:0x92:0x90
-
-# Nightcrawler
-R:744:0x95:0xC4
-
-# Lord of Change
-R:745:0xA1:0xBF
-
-# Keeper of Secrets
-R:746:0xA2:0xC5
-
-# Shudde M'ell
-R:747:0xA2:0xC6
-
-# Hand druj
-R:748:0x99:0xC6
-
-# Eye druj
-R:749:0x99:0xC7
-
-# Skull druj
-R:750:0x99:0xC8
-
-# Chaos vortex
-R:751:0x99:0xD3
-
-# Aether vortex
-R:752:0x99:0xD4
-
-# Nidhogg, the Hel-Drake
-R:753:0xA2:0xC7
-
-# The Lernaean Hydra
-R:754:0x94:0xD3
-
-# Thuringwethil, the Vampire Messenger
-R:755:0x95:0x95
-
-# Great Hell Wyrm
-R:756:0x92:0xD1
-
-# Hastur the Unspeakable
-R:757:0x9D:0x83
-
-# Bloodthirster
-R:758:0xA1:0xFC
-
-# Draconic quylthulg
-R:759:0x94:0x96
-
-# Nyogtha, the Thing that Should not Be
-R:760:0x9D:0x84
-
-# Ahtu, Avatar of Nyarlathotep
-R:761:0xA2:0xC8
-
-# Fundin Bluecloak
-R:762:0xA2:0xC9
-
-# Bile Demon
-R:763:0xA5:0xF8
-
-# Uriel, Angel of Fire
-R:764:0x92:0x8C
-
-# Azriel, Angel of Death
-R:765:0x92:0x8D
-
-# Ancalagon the Black
-R:766:0x92:0xD2
-
-# Daoloth, the Render of the Veils
-R:767:0xA2:0xCA
-
-# Nightwalker
-R:768:0xA1:0xFD
-
-# Gabriel, the Messenger
-R:769:0x92:0x8E
-
-# Artsi, the Champion of Chaos
-R:770:0xA2:0xCB
-
-# Saruman of Many Colours
-R:771:0x99:0x96
-
-# Harowen the Black Hand
-R:772:0xA2:0xCC
-
-# Osyluth
-R:773:0xA5:0xF9
-
-# Dreadlord
-R:774:0x93:0xBE
-
-# Greater kraken
-R:775:0xA1:0xFE
-
-# Archlich
-R:776:0x95:0xC5
-
-# The Cat Lord
-R:777:0x9D:0x87
-
-# Jabberwock
-R:778:0xA5:0xFA
-
-# Chaos hound
-R:779:0x95:0xFD
-
-# Vlad Dracula, Prince of Darkness
-R:780:0xA2:0xCD
-
-# Beholder hive-mother
-R:781:0xA2:0xCE
-
-# Leviathan
-R:782:0xA1:0xFF
-
-# Great Wyrm of Chaos
-R:783:0x92:0xD3
-
-# Great Wyrm of Law
-R:784:0x92:0xD4
-
-# Great Wyrm of Balance
-R:785:0x92:0xD5
-
-# Shambler
-R:786:0x9D:0x89
-
-# Gelugon
-R:787:0xA5:0xFB
-
-# Glaaki
-R:788:0xA0:0x80
-
-# T'ron, the Rebel Dragonrider
-R:789:0x9D:0x8A
-
-# Great Wyrm of Many Colours
-R:790:0x9D:0x8B
-
-# Mardra, rider of the Gold Loranth
-R:791:0x9D:0x8C
-
-# Tselakus, the Dreadlord
-R:792:0x93:0xBF
-
-# Sky Drake
-R:793:0x9D:0x8D
-
-# Eilinel the Entrapped
-R:794:0x93:0xBB
-
-# Horned Reaper
-R:795:0xA5:0xFC
-
-# The Norsa
-R:796:0x9D:0x8F
-
-# Rhan-Tegoth
-R:797:0xA2:0xD1
-
-# Black reaver
-R:798:0x93:0xFD
-
-# Master mindcrafter
-R:799:0x99:0x97
-
-# Greater demonic quylthulg
-R:800:0x94:0x97
-
-# Greater draconic quylthulg
-R:801:0x94:0xB8
-
-# Greater rotting quylthulg
-R:802:0x94:0xB9
-
-# Null, the Living Void
-R:803:0xA1:0xC0
-
-# Feagwath, the Undead Sorcerer
-R:804:0x93:0xFE
-
-# Omarax the Eye Tyrant
-R:805:0x96:0xF9
-
-# Tsathoggua, the Sleeper of N'kai
-R:806:0xA2:0xD2
-
-# Greater Balrog
-R:807:0x9A:0x8B
-
-# Ungoliant, the Unlight
-R:808:0x95:0x80
-
-# Atlach-Nacha, the Spider God
-R:809:0x9D:0x92
-
-# Y'golonac
-R:810:0xA2:0xD3
-
-# Aether hound
-R:811:0x95:0xFE
-
-# Pit Fiend
-R:812:0x9A:0x8A
-
-# The Serpent of Chaos
-R:813:0x9D:0xC5
-
-# Yig, Father of Serpents
-R:814:0xA2:0xD4
-
-# Unmaker
-R:815:0x9D:0x94
-
-# Cyberdemon
-R:816:0x9D:0x95
-
-# Hela, Queen of the Dead
-R:817:0xA2:0xD5
-
-# The Mouth of Sauron
-R:818:0xA2:0xD6
-
-# The Necromancer of Dol Guldur
-R:819:0x9D:0x96
-
-# Lessa, rider of the Gold Ramoth
-R:820:0x9D:0x97
-
-# Master quylthulg
-R:821:0x94:0xBA
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0x94:0xBB
-
-# Cthugha, the Living Flame
-R:823:0xA2:0xD7
-
-# F'lar, rider of the Bronze Mnementh
-R:824:0x9D:0xB8
-
-# Maeglin, the Traitor of Gondolin
-R:825:0x95:0xC6
-
-# Cyaegha
-R:826:0xA2:0xF8
-
-# Pazuzu, Lord of Air
-R:827:0xA2:0xF9
-
-# Ithaqua the Windwalker
-R:828:0x9D:0xB9
-
-# Greater Hellhound
-R:829:0x92:0xBB
-
-# Cantoras, the Skeletal Lord
-R:830:0x99:0xC9
-
-# Mephistopheles, Lord of Hell
-R:831:0x9D:0xBA
-
-# Godzilla
-R:832:0x9D:0xBB
-
-# Abhoth, Source of Uncleanness
-R:833:0xA2:0xFA
-
-# Ymir, the Ice Giant
-R:834:0xA2:0xFB
-
-# Loki, the Trickster
-R:835:0xA2:0xFC
-
-# Star-spawn of Cthulhu
-R:836:0x9D:0xBC
-
-# Surtur, the Fire Giant
-R:837:0xA2:0xFD
-
-# The Tarrasque
-R:838:0xA1:0xCB
-
-# Lungorthin, the Balrog of White Fire
-R:839:0xA2:0xFE
-
-# Draugluin, Sire of All Werewolves
-R:840:0xA2:0xFF
-
-# Shuma-Gorath
-R:841:0xA3:0x80
-
-# Tulzscha, the Green Flame
-R:842:0xA1:0xCA
-
-# Oremorj, the Cyberdemon Lord
-R:843:0xA1:0xC9
-
-# Vecna, the Emperor Lich
-R:844:0x9D:0xBD
-
-# Yog-Sothoth, the All-in-One
-R:845:0x9D:0xBE
-
-# Fenris Wolf
-R:846:0xA1:0xC8
-
-# Great Wyrm of Power
-R:847:0x9D:0xBF
-
-# Shub-Niggurath, Black Goat of the Woods
-R:848:0x9D:0xC0
-
-# Nodens, Lord of the Great Abyss
-R:849:0x99:0x85
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x92:0xBE
-
-# Nyarlathotep, the Crawling Chaos
-R:851:0x9D:0xC1
-
-# Azathoth, the Daemon Sultan
-R:852:0x9D:0xC2
-
-# Huan, Wolfhound of the Valar
-R:853:0x92:0xBF
-
-# Jormungand the Midgard Serpent
-R:854:0xA1:0xC7
-
-# The Destroyer
-R:855:0xA1:0xC6
-
-# Gothmog, the High Captain of Balrogs
-R:856:0x9A:0x90
-
-# Great Cthulhu
-R:857:0x9D:0xC3
-
-# Sorka, rider of the Gold Faranth
-R:858:0x9D:0xC4
-
-# The Unicorn of Order
-R:859:0xA1:0xC5
-
-# Sauron, the Sorcerer
-R:860:0x99:0xB8
-
-# DarkGod, the Mighty Coder of Hell
-R:861:0xA3:0xD5
-
-# Morgoth, Lord of Darkness
-R:862:0x9D:0xC6
-
-# Human Warrior
-R:863:0x9D:0xF8
-
-# Elven archer
-R:864:0x9D:0xF9
-
-# Dwarven warrior
-R:865:0x9D:0xFA
-
-# Elite uruk
-R:866:0x9D:0xFB
-
-# The Philosophy Teacher
-R:867:0xA1:0xC4
-
-# The Variant Maintainer
-R:868:0xA1:0xC3
-
-# Random Number Generator
-R:869:0xA1:0xC2
-
-# Rocket mine
-R:870:0xA2:0x80
-
-# Bouncing mine
-R:871:0xA2:0x81
-
-# Durin's Bane
-R:872:0xA3:0x81
-
-# The Icky Queen
-R:873:0xA3:0x82
-
-# Rot jelly
-R:874:0xA2:0x82
-
-# Death
-R:875:0xA2:0x83
-
-# Famine
-R:876:0xA2:0x85
-
-# Pestilence
-R:877:0xA2:0x84
-
-# War
-R:878:0xA2:0x86
-
-# Pike
-R:879:0xA2:0x87
-
-# Electric eel
-R:880:0xA2:0x88
-
-# Giant crayfish
-R:881:0xA2:0x89
-
-# Mermaid
-R:882:0xA2:0x8A
-
-# Box jellyfish
-R:883:0xA0:0xB9
-
-# Giant piranha
-R:884:0x9E:0xD5
-
-# Piranha
-R:885:0x9E:0xD5
-
-# Bullywug
-R:886:0xA2:0x8C
-
-# Bullywug warrior
-R:887:0xA2:0x8D
-
-# Bullywug shaman
-R:888:0xA2:0x8E
-
-# Whale
-R:889:0xA0:0xD0
-
-# Sand mite
-R:890:0xA2:0x90
-
-# Octopus
-R:891:0xA2:0x91
-
-# Giant octopus
-R:892:0xA2:0x92
-
-# Eye of the deep
-R:893:0xA2:0x93
-
-# Murk dweller
-R:894:0xA3:0x83
-
-# Drowned soul
-R:895:0xA3:0x84
-
-# Tiger shark
-R:896:0xA3:0x85
-
-# Hammerhead shark
-R:897:0xA0:0xC8
-
-# Great white shark
-R:898:0xA0:0xFA
-
-# Aquatic golem
-R:899:0xA3:0x86
-
-# Aquatic kobold
-R:900:0xA3:0x87
-
-# White shark
-R:901:0xA0:0xFA
-
-# Scrag
-R:902:0xA3:0x89
-
-# Jaws
-R:903:0xA1:0x84
-
-# Aquatic elf
-R:904:0xA3:0x8B
-
-# Aquatic elven warrior
-R:905:0xA3:0x8C
-
-# Aquatic elven shaman
-R:906:0xA3:0x8D
-
-# Stargazer
-R:907:0xA3:0x8E
-
-# Elder stargazer
-R:908:0xA3:0x8F
-
-# Flounder
-R:909:0xA3:0x90
-
-# Giant turtle
-R:910:0xA3:0x91
-
-# Baby dragon turtle
-R:911:0xA3:0x92
-
-# Young dragon turtle
-R:912:0xA3:0x93
-
-# Mature dragon turtle
-R:913:0xA3:0x94
-
-# Ancient dragon turtle
-R:914:0xA3:0x95
-
-# Fastitocalon
-R:915:0xA3:0x96
-
-# Undead stargazer
-R:916:0xA3:0x97
-
-# Killer whale
-R:917:0xA0:0x94
-
-# Merrow
-R:918:0xA5:0xFD
-
-# Water naga
-R:919:0xA3:0xB9
-
-# Devilfish
-R:920:0xA3:0xBA
-
-# Undead devilfish
-R:921:0xA3:0xBB
-
-# Moby Dick, the White Whale
-R:922:0xA3:0xB8
-
-# Aquatic hound
-R:923:0xA3:0xBD
-
-# Water demon
-R:924:0xA3:0xBE
-
-# Ixitxachitl
-R:925:0x9F:0xD4
-
-# Ixitxachitl priest
-R:926:0xA3:0xC0
-
-# Vampiric ixitxachitl
-R:927:0xA3:0xC1
-
-# Mathilde, the Science Student
-R:928:0xA2:0x94
-
-# Child spirit
-R:929:0xA2:0x95
-
-# Young spirit
-R:930:0xA2:0x96
-
-# Mature spirit
-R:931:0xA2:0x97
-
-# Experienced spirit
-R:932:0xA2:0xB8
-
-# Wise spirit
-R:933:0xA2:0xB9
-
-# Fangorn the Treebeard, Lord of the Ents
-R:934:0xA3:0xC2
-
-# Gandalf the Grey
-R:935:0xA3:0xC3
-
-# Nar, the Dwarf
-R:936:0xA3:0xC4
-
-# Novice mindcrafter
-R:937:0x98:0xD2
-
-# Great Swamp Wyrm
-R:938:0xA5:0xFE
-
-# Great Bile Wyrm
-R:939:0xA5:0xFF
-
-# Blue Firelizard
-R:940:0xA2:0xBA
-
-# Green Firelizard
-R:941:0xA2:0xBB
-
-# Brown Firelizard
-R:942:0xA2:0xBC
-
-# Bronze Firelizard
-R:943:0xA2:0xBD
-
-# Gold Firelizard
-R:944:0xA2:0xBE
-
-# High-elven ranger
-R:945:0xA2:0xBF
-
-# Uvatha the Horseman
-R:946:0xA3:0xC8
-
-# Adunaphel the Quiet
-R:947:0xA3:0xC9
-
-# Akhorahil the Blind
-R:948:0xA3:0xCA
-
-# Ren the Unclean
-R:949:0xA3:0xCB
-
-# Ji Indur Dawndeath
-R:950:0xA3:0xCC
-
-# Dwar, Dog Lord of Waw
-R:951:0xA3:0xCD
-
-# Hoarmurath of Dir
-R:952:0xA3:0xCE
-
-# Khamul, the Black Easterling
-R:953:0xA3:0xCF
-
-# The Witch-King of Angmar
-R:954:0xA3:0xD0
-
-# Green Dragonrider
-R:955:0x9D:0x8E
-
-# Blue Dragonrider
-R:956:0x9D:0x86
-
-# Brown Dragonrider
-R:957:0x9D:0x90
-
-# Bronze Dragonrider
-R:958:0x9D:0x90
-
-# Gold Dragonrider
-R:959:0x9D:0x8C
-
-# Thread
-R:960:0xA2:0xC0
-
-# Gorlim, Betrayer of Barahir
-R:961:0xA3:0xD1
-
-# The Blubbering idiot, agent of black market, Simon the weak
-R:962:0x98:0xBA
-
-# Aranea
-R:963:0xA4:0x92
-
-# Elder aranea
-R:964:0xA3:0xD2
-
-# Giant brown tick
-R:965:0xA6:0x80
-
-# Dolphiner
-R:966:0xA3:0xD4
-
-# Novice possessor (soul)
-R:967:0xA5:0xBE
-
-# Bat of Gorgoroth
-R:968:0xA6:0x8F
-
-# The Princess
-R:969:0xA6:0x90
-
-# Merton Proudfoot, the lost hobbit
-R:970:0xA6:0x91
-
-# The Wight-King of the Barrow-downs
-R:971:0xA6:0x92
-
-# Adventurer
-R:972:0xA6:0x93
-
-# Experienced possessor (soul)
-R:973:0xA6:0x94
-
-# Old possessor (soul)
-R:974:0xA6:0x95
-
-# Death orb
-R:975:0xA6:0x96
-
-# Bronze dragon worm
-R:976:0xA6:0xB8
-
-# Gold dragon worm
-R:977:0xA6:0x97
-
-# Moldoux, the Defenceless Mold
-R:978:0xA1:0xC1
-
-# The Physics Teacher
-R:979:0xA2:0xCF
-
-# Ar-Pharazon the Golden
-R:980:0xA3:0xD6
-
-# Doppelganger
-R:981:0x8F:0x84
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0xA4:0x85
-
-# The Greater Lag Monster
-R:983:0xA4:0xC5
-
-# Hrungnir, the Stone Giant
-R:984:0x97:0x82
-
-# Bullroarer the Hobbit
-R:985:0x97:0x93
-
-# 3-headed hydra
-R:986:0x94:0xCC
-
-# Uldor the Accursed
-R:987:0x99:0x8D
-
-# Mystic
-R:988:0x99:0x93
-
-# Elder vampire
-R:989:0x94:0x91
-
-# Ulfang the Black
-R:990:0x98:0xCE
-
-# Demonologist
-R:991:0x97:0xBA
-
-# Hezrou
-R:992:0x94:0xD4
-
-# Glabrezu
-R:993:0x94:0xC6
-
-# Nalfeshnee
-R:994:0xA4:0xC6
-
-# Marilith
-R:995:0xA4:0xC7
-
-# Lesser Balrog
-R:996:0x9A:0x8D
-
-# Master mystic
-R:997:0x98:0xCC
-
-# Grand master mystic
-R:998:0x99:0x95
-
-# Erinyes
-R:999:0x93:0xBC
-
-# Novice mindcrafter
-R:1000:0x98:0xD2
-
-# Polyphemus, the Blind Cyclops
-R:1001:0xA6:0x81
-
-# Great Wyrm of Perplexity
-R:1002:0xA4:0xCA
-
-# Hound of Tindalos
-R:1003:0xA4:0xCB
-
-# Great Wyrm of Thunder
-R:1004:0xA6:0x82
-
-# Silver mouse
-R:1005:0xA6:0x83
-
-# The Rat King
-R:1006:0xA4:0xCE
-
-# Vort the Kobold Queen
-R:1007:0xA4:0xCF
-
-# Giant black louse
-R:1008:0xA4:0xD0
-
-# Fire Phantom
-R:1009:0xA4:0xD1
-
-# The Insane Player
-R:1010:0x8C:0xB9
-
-# Glaryssa, Succubus Queen
-R:1011:0xA4:0xD2
-
-# Vermicious Knid
-R:1012:0xA4:0xD3
-
-# Bone golem
-R:1013:0xA4:0xD4
-
-# Snake of Yig
-R:1014:0xA4:0xD5
-
-# Bronze golem
-R:1015:0xA6:0x84
-
-# Dimensional shambler
-R:1016:0xA4:0xD7
-
-# Cultist
-R:1017:0x8D:0xD1
-
-# Cult leader
-R:1018:0x90:0x8F
-
-# Servitor of the outer gods
-R:1019:0xA5:0x82
-
-# Avatar of Nyarlathotep
-R:1020:0xA5:0x83
-
-# Thiazi, the Storm Giant
-R:1021:0xA6:0x85
-
-# Hypnos, Lord of Sleep
-R:1022:0xA5:0x85
-
-# Blue dragon worm
-R:1023:0xA5:0x86
-
-# White dragon worm
-R:1024:0xA5:0x87
-
-# Green dragon worm
-R:1025:0xA5:0x8A
-
-# Black dragon worm
-R:1026:0xA5:0x89
-
-# Red dragon worm
-R:1027:0xA5:0x88
-
-# Multi-hued dragon worm
-R:1028:0xA5:0x8B
-
-# The Minotaur of the Labyrinth
-R:1029:0xA5:0x8C
-
-# The Sandworm Queen
-R:1030:0xA5:0x93
-
-# Sandworm
-R:1031:0xA5:0x94
-
-# Tik'srvzllat
-R:1032:0xA5:0x95
-
-# The Glass Golem
-R:1033:0xA6:0x86
-
-# The White Balrog
-R:1034:0xA6:0x87
-
-# Golgarach, the Living Rock
-R:1035:0x83:0xBC
-
-# Atlas, the Titan
-R:1036:0xA6:0x88
-
-# Kronos, Lord of the Titans
-R:1037:0xA6:0x89
-
-# Water hound
-R:1038:0xA6:0xC0
-
-# Improv, the mighty MoLD
-R:1039:0xA6:0xC6
-
-# Emperor Mimic
-R:1040:0xA6:0xD4
-
-# Melinda Proudfoot
-R:1041:0x87:0xE2
-
-# Thrain, the King Under the Mountain
-R:1042:0x87:0xE3
-
-# Fire golem
-R:1043:0x89:0xD8
-
-# Melkor, Lord of Darkness
-R:1044:0x89:0xD9
-
-# Spirit
-R:1045:0x8C:0xD7
-
-# Spirit
-R:1046:0x8C:0xD8
-
-# Spirit
-R:1047:0x8C:0xD9
-
-# Spirit
-R:1048:0x8C:0xDA
-
-# Spirit
-R:1049:0x8C:0xDB
-
-# Spirit
-R:1050:0x8C:0xDC
-
-# Spirit
-R:1051:0x8C:0xDD
-
-# Spirit
-R:1052:0x8C:0xDE
-
-# Spirit
-R:1053:0x8C:0xDF
-
-# Spirit
-R:1054:0x8C:0xE0
-
-# Spirit
-R:1055:0x8C:0xE1
-
-# Spirit
-R:1056:0x8C:0xE2
-
-# Spirit
-R:1057:0x8C:0xDB
-
-# Spirit
-R:1058:0x8C:0xE3
-
-# Spirit
-R:1059:0x8C:0xE4
-
-# Spirit
-R:1060:0x8C:0xE5
-
-# Spirit
-R:1061:0x8C:0xE6
-
-# Spirit
-R:1062:0x8C:0xE7
-
-# Spirit
-R:1063:0x8C:0xE8
-
-# Spirit
-R:1064:0x8C:0xE9
-
-# Spirit
-R:1065:0x8C:0xEA
-
-# Spirit
-R:1066:0x8C:0xEB
-
-# Spirit
-R:1067:0x8C:0xEC
-
-# Spirit
-R:1068:0x8C:0xED
-
-# Spirit
-R:1069:0x8C:0xEE
-
-# Spirit
-R:1070:0x8C:0xEF
-
-# Spirit
-R:1071:0x8C:0xF0
-
-# Spirit
-R:1072:0x8C:0xF1
-
-# Spirit
-R:1073:0x8C:0xF2
-
-# Spirit
-R:1074:0x8C:0xF3
-
-# Spirit
-R:1075:0x8C:0xF4
-
-# Spells (*)
-S:48:0x8C:0x80
-
-# Spells (*)
-S:49:0x8C:0x81
-
-# Spells (*)
-S:50:0x8C:0x82
-
-# Spells (*)
-S:51:0x8C:0x83
-
-# Spells (*)
-S:52:0x8C:0x84
-
-# Spells (*)
-S:53:0x8C:0x85
-
-# Spells (*)
-S:54:0x8C:0x86
-
-# Spells (*)
-S:55:0x8C:0x87
-
-# Spells (*)
-S:56:0x8C:0x88
-
-# Spells (*)
-S:57:0x8C:0x89
-
-# Spells (*)
-S:58:0x8C:0x8A
-
-# Spells (*)
-S:59:0x8C:0x8B
-
-# Spells (*)
-S:60:0x8C:0x8C
-
-# Spells (*)
-S:61:0x8C:0x8D
-
-# Spells (*)
-S:62:0x8C:0x8E
-
-# Spells (*)
-S:63:0x8C:0x8F
-
-# Spells (|)
-S:64:0x8A:0xF8
-
-# Spells (|)
-S:65:0x8A:0xFC
-
-# Spells (|)
-S:66:0x8B:0x80
-
-# Spells (|)
-S:67:0x8B:0x84
-
-# Spells (|)
-S:68:0x8B:0x88
-
-# Spells (|)
-S:69:0x8B:0x8C
-
-# Spells (|)
-S:70:0x8B:0x90
-
-# Spells (|)
-S:71:0x8B:0x94
-
-# Spells (|)
-S:72:0x8B:0xB8
-
-# Spells (|)
-S:73:0x8B:0xBC
-
-# Spells (|)
-S:74:0x8B:0xC0
-
-# Spells (|)
-S:75:0x8B:0xC4
-
-# Spells (|)
-S:76:0x8B:0xC8
-
-# Spells (|)
-S:77:0x8B:0xCC
-
-# Spells (|)
-S:78:0x8B:0xD0
-
-# Spells (|)
-S:79:0x8B:0xD4
-
-# Spells (-)
-S:80:0x8A:0xF9
-
-# Spells (-)
-S:81:0x8A:0xFD
-
-# Spells (-)
-S:82:0x8B:0x81
-
-# Spells (-)
-S:83:0x8B:0x85
-
-# Spells (-)
-S:84:0x8B:0x89
-
-# Spells (-)
-S:85:0x8B:0x8D
-
-# Spells (-)
-S:86:0x8B:0x91
-
-# Spells (-)
-S:87:0x8B:0x95
-
-# Spells (-)
-S:88:0x8B:0xB9
-
-# Spells (-)
-S:89:0x8B:0xBD
-
-# Spells (-)
-S:90:0x8B:0xC1
-
-# Spells (-)
-S:91:0x8B:0xC5
-
-# Spells (-)
-S:92:0x8B:0xC9
-
-# Spells (-)
-S:93:0x8B:0xCD
-
-# Spells (-)
-S:94:0x8B:0xD1
-
-# Spells (-)
-S:95:0x8B:0xD5
-
-# Spells (:)
-S:96:0x8A:0xFA
-
-# Spells (:)
-S:97:0x8A:0xFE
-
-# Spells (:)
-S:98:0x8B:0x82
-
-# Spells (:)
-S:99:0x8B:0x86
-
-# Spells (:)
-S:100:0x8B:0x8A
-
-# Spells (:)
-S:101:0x8B:0x8E
-
-# Spells (:)
-S:102:0x8B:0x92
-
-# Spells (:)
-S:103:0x8B:0x96
-
-# Spells (:)
-S:104:0x8B:0xBA
-
-# Spells (:)
-S:105:0x8B:0xBE
-
-# Spells (:)
-S:106:0x8B:0xC2
-
-# Spells (:)
-S:107:0x8B:0xC6
-
-# Spells (:)
-S:108:0x8B:0xCA
-
-# Spells (:)
-S:109:0x8B:0xCE
-
-# Spells (:)
-S:110:0x8B:0xD2
-
-# Spells (:)
-S:111:0x8B:0xD6
-
-# Spells (\)
-S:112:0x8A:0xFB
-
-# Spells (\)
-S:113:0x8A:0xFF
-
-# Spells (\)
-S:114:0x8B:0x83
-
-# Spells (\)
-S:115:0x8B:0x87
-
-# Spells (\)
-S:116:0x8B:0x8B
-
-# Spells (\)
-S:117:0x8B:0x8F
-
-# Spells (\)
-S:118:0x8B:0x93
-
-# Spells (\)
-S:119:0x8B:0x97
-
-# Spells (\)
-S:120:0x8B:0xBB
-
-# Spells (\)
-S:121:0x8B:0xBF
-
-# Spells (\)
-S:122:0x8B:0xC3
-
-# Spells (\)
-S:123:0x8B:0xC7
-
-# Spells (\)
-S:124:0x8B:0xCB
-
-# Spells (\)
-S:125:0x8B:0xCF
-
-# Spells (\)
-S:126:0x8B:0xD3
-
-# Spells (\)
-S:127:0x8B:0xD7
-
-# Amulets (
-S:128:0x86:0xFF
-
-# Amulets (
-S:129:0x86:0xF8
-
-# Amulets (
-S:130:0x87:0x80
-
-# Amulets (
-S:131:0x86:0xFA
-
-# Amulets (
-S:132:0x86:0xFB
-
-# Amulets (
-S:133:0x86:0xFC
-
-# Amulets (
-S:134:0x86:0xFD
-
-# Amulets (
-S:135:0x86:0xFE
-
-# Amulets (
-S:136:0x86:0xF9
-
-# Amulets (
-S:137:0x86:0xF9
-
-# Amulets (
-S:138:0x87:0x81
-
-# Amulets (
-S:139:0x87:0x82
-
-# Amulets (
-S:140:0x87:0x83
-
-# Amulets (
-S:141:0x87:0x84
-
-# Amulets (
-S:142:0x87:0x85
-
-# Amulets (
-S:143:0x87:0x86
-
-# Rings (=)
-S:144:0x85:0xBF
-
-# Rings (=)
-S:145:0x85:0xB8
-
-# Rings (=)
-S:146:0x85:0xC0
-
-# Rings (=)
-S:147:0x85:0xBA
-
-# Rings (=)
-S:148:0x85:0xBB
-
-# Rings (=)
-S:149:0x85:0xBC
-
-# Rings (=)
-S:150:0x85:0xBD
-
-# Rings (=)
-S:151:0x85:0xBE
-
-# Rings (=)
-S:152:0x85:0xB9
-
-# Rings (=)
-S:153:0x85:0xB9
-
-# Rings (=)
-S:154:0x85:0xC1
-
-# Rings (=)
-S:155:0x85:0xC2
-
-# Rings (=)
-S:156:0x85:0xC3
-
-# Rings (=)
-S:157:0x85:0xC4
-
-# Rings (=)
-S:158:0x85:0xC5
-
-# Rings (=)
-S:159:0x85:0xC6
-
-# Staffs (_)
-S:160:0x87:0x8E
-
-# Staffs (_)
-S:161:0x87:0x8D
-
-# Staffs (_)
-S:162:0x87:0x8D
-
-# Staffs (_)
-S:163:0x87:0x8A
-
-# Staffs (_)
-S:164:0x87:0x8A
-
-# Staffs (_)
-S:165:0x87:0x8B
-
-# Staffs (_)
-S:166:0x87:0x8D
-
-# Staffs (_)
-S:167:0x87:0x88
-
-# Staffs (_)
-S:168:0x87:0x8D
-
-# Staffs (_)
-S:169:0x87:0x8D
-
-# Staffs (_)
-S:170:0x87:0x8A
-
-# Staffs (_)
-S:171:0x87:0x8C
-
-# Staffs (_)
-S:172:0x87:0x8A
-
-# Staffs (_)
-S:173:0x87:0x8B
-
-# Staffs (_)
-S:174:0x87:0x8E
-
-# Staffs (_)
-S:175:0x87:0x88
-
-# Wands (-)
-S:176:0x86:0xCF
-
-# Wands (-)
-S:177:0x86:0xC8
-
-# Wands (-)
-S:178:0x86:0xD0
-
-# Wands (-)
-S:179:0x86:0xCA
-
-# Wands (-)
-S:180:0x86:0xCB
-
-# Wands (-)
-S:181:0x86:0xCC
-
-# Wands (-)
-S:182:0x86:0xCD
-
-# Wands (-)
-S:183:0x86:0xCE
-
-# Wands (-)
-S:184:0x86:0xC9
-
-# Wands (-)
-S:185:0x86:0xC9
-
-# Wands (-)
-S:186:0x86:0xD1
-
-# Wands (-)
-S:187:0x86:0xD2
-
-# Wands (-)
-S:188:0x86:0xD3
-
-# Wands (-)
-S:189:0x86:0xD4
-
-# Wands (-)
-S:190:0x86:0xD5
-
-# Wands (-)
-S:191:0x86:0xD6
-
-# Rods (-)
-S:192:0x86:0xBF
-
-# Rods (-)
-S:193:0x86:0xB8
-
-# Rods (-)
-S:194:0x86:0xC0
-
-# Rods (-)
-S:195:0x86:0xBA
-
-# Rods (-)
-S:196:0x86:0xBB
-
-# Rods (-)
-S:197:0x86:0xBC
-
-# Rods (-)
-S:198:0x86:0xBD
-
-# Rods (-)
-S:199:0x86:0xBE
-
-# Rods (-)
-S:200:0x86:0xB9
-
-# Rods (-)
-S:201:0x86:0xB9
-
-# Rods (-)
-S:202:0x86:0xC1
-
-# Rods (-)
-S:203:0x86:0xC2
-
-# Rods (-)
-S:204:0x86:0xC3
-
-# Rods (-)
-S:205:0x86:0xC4
-
-# Rods (-)
-S:206:0x86:0xC5
-
-# Rods (-)
-S:207:0x86:0xC6
-
-# Scrolls (?)
-S:208:0x85:0x94
-
-# Scrolls (?)
-S:209:0x85:0x95
-
-# Scrolls (?)
-S:210:0x85:0x96
-
-# Scrolls (?)
-S:211:0x85:0x97
-
-# Scrolls (?)
-S:212:0x85:0x94
-
-# Scrolls (?)
-S:213:0x85:0x95
-
-# Scrolls (?)
-S:214:0x85:0x96
-
-# Scrolls (?)
-S:215:0x85:0x97
-
-# Scrolls (?)
-S:216:0x85:0x94
-
-# Scrolls (?)
-S:217:0x85:0x95
-
-# Scrolls (?)
-S:218:0x85:0x96
-
-# Scrolls (?)
-S:219:0x85:0x97
-
-# Scrolls (?)
-S:220:0x85:0x94
-
-# Scrolls (?)
-S:221:0x85:0x95
-
-# Scrolls (?)
-S:222:0x85:0x96
-
-# Scrolls (?)
-S:223:0x85:0x97
-
-# Potions (!)
-S:224:0x85:0xFF
-
-# Potions (!)
-S:225:0x85:0xF8
-
-# Potions (!)
-S:226:0x86:0x80
-
-# Potions (!)
-S:227:0x85:0xFA
-
-# Potions (!)
-S:228:0x85:0xFB
-
-# Potions (!)
-S:229:0x85:0xFC
-
-# Potions (!)
-S:230:0x85:0xFD
-
-# Potions (!)
-S:231:0x85:0xFE
-
-# Potions (!)
-S:232:0x85:0xF9
-
-# Potions (!)
-S:233:0x85:0xF9
-
-# Potions (!)
-S:234:0x86:0x81
-
-# Potions (!)
-S:235:0x86:0x82
-
-# Potions (!)
-S:236:0x86:0x83
-
-# Potions (!)
-S:237:0x86:0x84
-
-# Potions (!)
-S:238:0x86:0x85
-
-# Potions (!)
-S:239:0x86:0x86
-
-# Food (,)
-S:240:0x86:0x8F
-
-# Food (,)
-S:241:0x86:0x88
-
-# Food (,)
-S:242:0x86:0x90
-
-# Food (,)
-S:243:0x86:0x8A
-
-# Food (,)
-S:244:0x86:0x8B
-
-# Food (,)
-S:245:0x86:0x8C
-
-# Food (,)
-S:246:0x86:0x8D
-
-# Food (,)
-S:247:0x86:0x8E
-
-# Food (,)
-S:248:0x86:0x89
-
-# Food (,)
-S:249:0x86:0x89
-
-# Food (,)
-S:250:0x86:0x91
-
-# Food (,)
-S:251:0x86:0x92
-
-# Food (,)
-S:252:0x86:0x93
-
-# Food (,)
-S:253:0x86:0x94
-
-# Food (,)
-S:254:0x86:0x95
-
-# Food (,)
-S:255:0x86:0x96
-
diff --git a/lib/pref/graf-mac.prf b/lib/pref/graf-mac.prf
deleted file mode 100644
index 7bb84141..00000000
--- a/lib/pref/graf-mac.prf
+++ /dev/null
@@ -1,15 +0,0 @@
-# File: graf-mac.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/pref/graf-new.prf b/lib/pref/graf-new.prf
deleted file mode 100644
index ca806ca7..00000000
--- a/lib/pref/graf-new.prf
+++ /dev/null
@@ -1,6847 +0,0 @@
-# PRF file generated by Andreas Koch`s Tile Assigner
-# 23/06/2004 Edited manually
-
-# 2460 items
-# 2312 probably mapped correctly
-# 147 imported but not yet defined
-# 1 defined to value(s) lower than 0x80
-# Old header :
-# File: graf-new.prf
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-# with Adam Bolt's 16x16 tiles.
-#
-# By Robert Ruehlmann < rr9@angband.org >
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-# General Store
-B:0:0x82/0x87
-
-# Armoury
-B:1:0x82/0x88
-
-# Weaponsmith
-B:2:0x82/0x89
-
-# Temple
-B:3:0x82/0x8A
-
-# Alchemy shop
-B:4:0x82/0x8B
-
-# Magic shop
-B:5:0x82/0x8C
-
-# Black Market
-B:6:0x82/0x8D
-
-# Home
-B:7:0x82/0x8E
-
-# Book Store
-B:8:0x82/0x8F
-
-# Pet Shop
-B:9:0x82/0x90
-
-# Mayor's Office
-B:10:0x86/0xA0
-
-# Inn
-B:11:0x86/0xA1
-
-# The Soothsayer
-B:12:0x86/0xA2
-
-# Library
-B:13:0x86/0xA3
-
-# Castle
-B:14:0x86/0xA4
-
-# Casino
-B:15:0x86/0xA5
-
-# Beastmaster Shanty
-B:16:0x86/0xA6
-
-# Fighters Hall
-B:17:0x86/0xA7
-
-# Tower of Magery
-B:18:0x86/0xA8
-
-# Inner Temple
-B:19:0x86/0xA9
-
-# Paladins Guild
-B:20:0x86/0xAA
-
-# Rangers Guild
-B:21:0x86/0xAB
-
-# Thunderlords' Hide
-B:22:0x86/0xAC
-
-# The Mirror
-B:23:0x86/0xAD
-
-# Seat of Ruling
-B:24:0x86/0xAE
-
-# Wizards Spire
-B:25:0x86/0xAF
-
-# Priests Circle
-B:26:0x86/0xB0
-
-# Tower of the King
-B:27:0x86/0xB1
-
-# Library
-B:28:0x86/0xA3
-
-# The White Tree
-B:29:0x86/0xB2
-
-# Craftsmaster
-B:30:0x86/0xB3
-
-# Earth-Dome (Nature)
-B:31:0x86/0xB4
-
-# Minstrels Haven
-B:32:0x86/0xB5
-
-# Star-Dome
-B:33:0x86/0xB6
-
-# Valarin Temple
-B:34:0x86/0xB7
-
-# Sea-Dome
-B:35:0x86/0xB8
-
-# The Golden Flower
-B:36:0x86/0xB9
-
-# The Fountain
-B:37:0x86/0xBA
-
-# Axe Smith
-B:38:0x86/0xBB
-
-# Hafted Smith
-B:39:0x86/0xBC
-
-# Polearm Smith
-B:40:0x86/0xBD
-
-# Sword Smith
-B:41:0x86/0xBE
-
-# Rare Jewelry Shop
-B:42:0x86/0xBF
-
-# Jewelry Shop
-B:43:0x87/0xA0
-
-# Footwear Shop
-B:44:0x87/0xA1
-
-# Rare Footwear Shop
-B:45:0x87/0xA2
-
-# Library
-B:46:0x86/0xA3
-
-# Forbidden Library
-B:47:0x87/0xA3
-
-# Expensive Black Market
-B:48:0x87/0xA4
-
-# Common Shop
-B:49:0x87/0xA5
-
-# Dragon Hunter
-B:50:0x87/0xA6
-
-# Speed Ring Market
-B:51:0x87/0xA7
-
-# Scribe
-B:52:0x87/0xA8
-
-# Potion Store
-B:53:0x87/0xA9
-
-# Recaller
-B:54:0x87/0xAA
-
-# Master Archer
-B:55:0x87/0xAB
-
-# Merchants Guild
-B:56:0x87/0xAC
-
-# The Mathom-house
-B:57:0x87/0xAD
-
-# The Prancing Pony
-B:58:0x86/0xA1
-
-# nothing
-F:0:0x80/0x80
-
-# open floor
-F:1:0x80/0x81
-
-# fountain
-F:2:0xC3/0x9A
-
-# glyph of warding
-F:3:0x8D/0x95
-
-# open door
-F:4:0x82/0x84
-
-# broken door
-F:5:0x82/0x85
-
-# up staircase
-F:6:0x80/0x96
-
-# down staircase
-F:7:0x80/0x99
-
-# quest entrance
-F:8:0x80/0x9A
-
-# quest exit
-F:9:0x80/0x97
-
-# quest down level
-F:10:0x80/0x9B
-
-# quest up level
-F:11:0x80/0x98
-
-# town exit
-F:12:0x82/0x84
-
-# shaft down
-F:13:0xC3/0x84
-
-# shaft up
-F:14:0xC3/0x85
-
-# fountain
-F:15:0xC3/0x99
-
-# web
-F:16:0x81/0x8C
-
-# trap
-F:17:0x81/0x89
-
-# visible trap -- spiked pit
-F:18:0x81/0x89
-
-# visible trap -- poison pit
-F:19:0x81/0x89
-
-# visible trap -- rune -- summon
-F:20:0x81/0x8F
-
-# visible trap -- rune -- teleport
-F:21:0x81/0x92
-
-# visible trap -- spot -- fire
-F:22:0x81/0x86
-
-# visible trap -- spot -- acid
-F:23:0x81/0x86
-
-# visible trap -- dart -- slow
-F:24:0x81/0x80
-
-# visible trap -- dart -- lose str
-F:25:0x81/0x80
-
-# visible trap -- dart -- lose dex
-F:26:0x81/0x80
-
-# visible trap -- dart -- lose con
-F:27:0x81/0x80
-
-# visible trap -- gas -- blind
-F:28:0x81/0x83
-
-# visible trap -- gas -- confuse
-F:29:0x81/0x83
-
-# visible trap -- gas -- poison
-F:30:0x81/0x83
-
-# visible trap -- gas -- sleep
-F:31:0x81/0x83
-
-# door
-F:32:0x82/0x83
-
-# locked door
-F:33:0x82/0x83
-F:34:0x82/0x83
-F:35:0x82/0x83
-F:36:0x82/0x83
-F:37:0x82/0x83
-F:38:0x82/0x86
-F:39:0x82/0x86
-
-# jammed door
-F:40:0x82/0x83
-F:41:0x82/0x83
-F:42:0x82/0x83
-F:43:0x82/0x83
-F:44:0x82/0x83
-F:45:0x82/0x86
-F:46:0x82/0x86
-F:47:0x82/0x86
-
-# secret door
-F:48:0x80/0x84
-
-# pile of rubble
-F:49:0x80/0x9C
-
-# magma vein
-F:50:0x80/0x8D
-
-# quartz vein
-F:51:0x80/0x87
-
-# magma vein
-F:52:0x80/0x90
-
-# quartz vein
-F:53:0x80/0x87
-
-# magma vein with treasure
-F:54:0x80/0x90
-
-# quartz vein with treasure
-F:55:0x80/0x8A
-
-# granite wall
-F:56:0x80/0x84
-F:57:0x80/0x84
-F:58:0x80/0x84
-F:59:0x80/0x84
-
-# permanent wall
-F:60:0x80/0x93
-F:61:0x80/0x93
-F:62:0x80/0x93
-F:63:0x80/0x93
-
-# explosive rune
-F:64:0x8D/0x9E
-
-# Straight Road startpoint
-F:65:0x81/0x95
-
-# section of the Straight Road
-F:66:0x81/0x95
-F:67:0x81/0x95
-F:68:0x81/0x95
-F:69:0x81/0x95
-F:70:0x81/0x95
-
-# section of the Straight Road (discharged)
-F:71:0x81/0x98
-
-# Straight Road exit
-F:72:0x81/0x9B
-
-# corrupted section of the Straight Road
-F:73:0x81/0x9E
-
-# Building
-F:74:0x82/0x93
-
-# permanent wall
-F:75:0x82/0x93
-F:76:0x82/0x94
-F:77:0x82/0x95
-F:78:0x82/0x96
-
-# stream of shallow water
-F:84:0xB4/0x97
-
-# pool of deep lava
-F:85:0x83/0x8D
-
-# stream of shallow lava
-F:86:0xB4/0x9A
-
-# dark pit
-F:87:0x80/0x80
-
-# dirt
-F:88:0xB4/0x91
-
-# patch of grass
-F:89:0xB4/0x94
-
-# ice
-F:90:0xC3/0x83
-
-# sand
-F:91:0xC3/0x88
-
-# dead tree
-F:92:0xC3/0x98
-
-# ash
-F:93:0xC3/0x97
-
-# mud
-F:94:0xC3/0x96
-
-# ice wall
-F:95:0xC5/0x92
-
-# tree
-F:96:0x82/0x9A
-
-# mountain chain
-F:97:0x8D/0x98
-
-# sandwall
-F:98:0xC3/0x86
-F:99:0xC3/0x86
-
-# sandwall with treasure
-F:100:0xC3/0x87
-
-# high mountain chain
-F:101:0xC3/0x9E
-
-# nether mist
-F:102:0xC3/0x9F
-
-# molten glass wall
-F:103:0xC0/0x9F
-
-# Void Jumpgate
-F:160:0x91/0x84
-
-# Altar of Being
-F:161:0xC1/0x8E
-
-# Altar of Winds
-F:162:0xB5/0x8A
-
-# Altar of Force
-F:163:0xB5/0x86
-
-# Altar of Darkness
-F:164:0xB5/0x86
-
-# Altar of Nature
-F:165:0xB5/0x91
-
-# Altar of Sun
-F:166:0xB5/0x8F
-
-# Altar of Rage
-F:167:0xB5/0x8C
-
-# Altar of Winds
-F:168:0xB5/0x92
-
-# Altar of Stars
-F:169:0xC1/0x8F
-
-# Altar of Being
-F:170:0xB5/0x8D
-
-# Altar of Randomness
-F:171:0xB5/0x88
-
-# floor
-F:172:0x80/0x81
-
-# Underground Tunnel
-F:173:0x80/0x82
-
-# stream of tainted water
-F:174:0xAF/0x8E
-
-# monster trap
-F:175:0x81/0x9C
-
-# Void Jumpgate
-F:176:0xAF/0x8C
-
-# lava wall
-F:177:0xC6/0x8C
-
-# Great Fire
-F:178:0xC6/0x8A
-
-# path to the next area
-F:179:0x88/0xA1
-
-# path to the previous area
-F:180:0x88/0xA0
-
-# field
-F:181:0x88/0xA2
-
-# Ekkaia, the Encircling Sea
-F:182:0x88/0xA3
-
-# Altar of Energy
-F:183:0xB5/0x9A
-
-# Altar of Matter
-F:184:0xB5/0x9B
-
-# Altar of Being
-F:185:0xB5/0x9C
-
-# Altar of Unbeing
-F:186:0xB5/0x9D
-
-# pool of deep water
-F:187:0x83/0x80
-
-# glass wall
-F:188:0xC0/0x9F
-
-# illusion wall
-F:189:0x80/0x84
-
-# Grass roof
-F:190:0xC2/0x80
-
-# grass roof top
-F:191:0xC2/0x81
-
-# grass roof chimney
-F:192:0xC2/0x82
-
-# brick roof
-F:193:0xC3/0x80
-
-# brick roof top
-F:194:0xC3/0x81
-
-# brick roof chimney
-F:195:0xC3/0x82
-
-# window
-F:196:0xC2/0x83
-
-# small window
-F:197:0xC2/0x84
-
-# rain barrel
-F:198:0xC2/0x85
-
-# grass with flowers
-F:199:0xC2/0x86
-
-# cobblestone road
-F:200:0xC2/0x87
-
-# cobblestone with outlet
-F:201:0xC2/0x88
-
-# small tree
-F:202:0x82/0x9D
-
-# town
-F:203:0xC3/0x95
-
-# Underground Tunnel
-F:204:0x80/0x82
-
-# a blazing fire
-F:205:0xC6/0x8A
-
-# pile of rubble
-F:206:0xC6/0x8B
-
-# ethereal wall
-F:214:0x80/0x81
-
-# glacial wall
-F:215:0xC5/0x92
-
-# Skeleton
-G:M:1:0xC6/0x91
-
-# Zombie
-G:M:2:0xC6/0x92
-
-# Lich
-G:M:3:0xC6/0x93
-
-# Spectral
-G:M:4:0xC6/0x94
-
-# Captain
-G:M:5:0xC6/0x95
-
-# Chieftain
-G:M:6:0xC6/0x96
-
-# Shaman
-G:M:7:0xC6/0x97
-
-# Priest
-G:M:8:0xC6/0x98
-
-# Mage
-G:M:9:0xC6/0x99
-
-# Archer
-G:M:10:0xC6/0x9A
-
-# Rogue
-G:M:11:0xC6/0x9B
-
-# Vampire
-G:P:1:0x88/0xA4
-
-# Spectre
-G:P:2:0x88/0xA5
-
-# Skeleton
-G:P:3:0xC6/0x91
-
-# Zombie
-G:P:4:0xC6/0x92
-
-# Barbarian
-G:P:5:0x88/0xA6
-
-# Hermit
-G:P:6:0x88/0xA7
-
-# Corrupted
-G:P:7:0x88/0xA8
-
-# LostSoul
-G:P:8:0x88/0xA9
-
-# something
-K:0:0x01/0x20
-
-# Blindness
-K:1:0x85/0x94
-
-# Paranoia
-K:2:0x85/0x94
-
-# Confusion
-K:3:0x85/0x94
-
-# Hallucination
-K:4:0x85/0x94
-
-# Cure Poison
-K:5:0x85/0x94
-
-# Cure Blindness
-K:6:0x85/0x94
-
-# Cure Paranoia
-K:7:0xC6/0x83
-
-# Cure Confusion
-K:8:0x85/0x94
-
-# Weakness
-K:9:0x85/0x94
-
-# Unhealth
-K:10:0x85/0x94
-
-# Restore Constitution
-K:11:0x85/0x94
-
-# Restoring
-K:12:0x85/0x94
-
-# Stupidity
-K:13:0x85/0x94
-
-# Naivety
-K:14:0x85/0x94
-
-# Poison
-K:15:0x85/0x94
-
-# Sickness
-K:16:0x85/0x94
-
-# Paralysis
-K:17:0x85/0x94
-
-# Restore Strength
-K:18:0x85/0x94
-
-# Disease
-K:19:0x85/0x94
-
-# Cure Serious Wounds
-K:20:0x85/0x94
-
-# & Ration~ of Food
-K:21:0x8E/0x84
-
-# & Hard Biscuit~
-K:22:0x8E/0x82
-
-# & Strip~ of Venison
-K:23:0x8E/0x83
-
-# & Slime Mold~
-K:24:0x8E/0x85
-
-# & Lembas~
-K:25:0x8E/0x86
-
-# & Pint~ of Fine Ale
-K:26:0x8E/0x80
-
-# & Pint~ of Fine Wine
-K:27:0x8E/0x80
-
-# & Mattock~
-K:28:0xB6/0x8C
-
-# & Blue Stone~
-K:29:0xC5/0x93
-
-# & Broken Dagger~
-K:30:0x8A/0x8D
-
-# & Bastard Sword~
-K:31:0x8A/0x8E
-
-# & Scimitar~
-K:32:0x8A/0x97
-
-# & Tulwar~
-K:33:0x8A/0x95
-
-# & Broad Sword~
-K:34:0x8A/0x98
-
-# & Short Sword~
-K:35:0x8A/0x94
-
-# & Blade~ of Chaos
-K:36:0x8A/0x9E
-
-# & Two-Handed Sword~
-K:37:0x8A/0x9C
-
-# & Main Gauche~
-K:38:0x8A/0x90
-
-# & Cutlass~
-K:39:0x8A/0x96
-
-# & Executioner's Sword~
-K:40:0x8A/0x9D
-
-# & Katana~
-K:41:0x8A/0x9B
-
-# & Long Sword~
-K:42:0x8A/0x99
-
-# & Dagger~
-K:43:0x8A/0x8F
-
-# & Rapier~
-K:44:0x8A/0x91
-
-# & Sabre~
-K:45:0x8A/0x93
-
-# & Small Sword~
-K:46:0x8A/0x92
-
-# & Broken Sword~
-K:47:0x8A/0x8E
-
-# & Ball-and-Chain~
-K:48:0x8B/0x86
-
-# & Whip~
-K:49:0x8A/0x9F
-
-# & Flail~
-K:50:0x8B/0x83
-
-# & Two-Handed Flail~
-K:51:0x8B/0x87
-
-# & Morning Star~
-K:52:0x8B/0x84
-
-# & Mace~
-K:53:0x8B/0x81
-
-# & Quarterstaff~
-K:54:0x8B/0x82
-
-# & War Hammer~
-K:55:0x8B/0x80
-
-# & Lead-Filled Mace~
-K:56:0x8B/0x85
-
-# & Mace~ of Disruption
-K:57:0x8B/0x88
-
-# & Lucerne Hammer~
-K:58:0x8B/0x8D
-
-# & Beaked Axe~
-K:59:0x8B/0x90
-
-# & Glaive~
-K:60:0x8B/0x92
-
-# & Halberd~
-K:61:0x8B/0x93
-
-# & Awl-Pike~
-K:62:0x8B/0x8B
-
-# & Pike~
-K:63:0x8B/0x8F
-
-# & Spear~
-K:64:0x8B/0x89
-
-# & Trident~
-K:65:0x8B/0x8A
-
-# & Lance~
-K:66:0x8B/0x8C
-
-# & Great Axe~
-K:67:0x8B/0x95
-
-# & Battle Axe~
-K:68:0x8B/0x8E
-
-# & Lochaber Axe~
-K:69:0x8B/0x94
-
-# & Broad Axe~
-K:70:0x8B/0x91
-
-# & Scythe~
-K:71:0x8B/0x96
-
-# & Scythe~ of Slicing
-K:72:0x8B/0x97
-
-# & Short Bow~
-K:73:0x8B/0x98
-
-# & Long Bow~
-K:74:0x8B/0x99
-
-# & Light Crossbow~
-K:75:0x8B/0x9A
-
-# & Heavy Crossbow~
-K:76:0x8B/0x9B
-
-# & Sling~
-K:77:0x8B/0x9C
-
-# & Arrow~
-K:78:0x8C/0x80
-
-# & Seeker Arrow~
-K:79:0x8C/0x81
-
-# & Bolt~
-K:80:0x8C/0x82
-
-# & Seeker Bolt~
-K:81:0x8C/0x83
-
-# & Rounded Pebble~
-K:82:0x8C/0x84
-
-# & Iron Shot~
-K:83:0x8C/0x85
-
-# & Shovel~
-K:84:0x8E/0x8F
-
-# & Gnomish Shovel~
-K:85:0x8E/0x90
-
-# & Dwarven Shovel~
-K:86:0x8E/0x91
-
-# & Pick~
-K:87:0x8E/0x8C
-
-# & Orcish Pick~
-K:88:0x8E/0x8D
-
-# & Dwarven Pick~
-K:89:0x8E/0x91
-
-# & Elven Cloak~
-K:90:0x89/0x89
-
-# & Pair~ of Soft Leather Boots
-K:91:0x88/0x8E
-
-# & Pair~ of Hard Leather Boots
-K:92:0x88/0x8F
-
-# & Pair~ of Metal Shod Boots
-K:93:0x88/0x90
-
-# & Hard Leather Cap~
-K:94:0x87/0x98
-
-# & Metal Cap~
-K:95:0x87/0x99
-
-# & Iron Helm~
-K:96:0x87/0x9A
-
-# & Steel Helm~
-K:97:0x87/0x9B
-
-# & Iron Crown~
-K:98:0x87/0x9C
-
-# & Golden Crown~
-K:99:0x87/0x9D
-
-# & Jewel Encrusted Crown~
-K:100:0x87/0x9E
-
-# & Robe~
-K:101:0x89/0x8C
-
-# & Filthy Rag~
-K:102:0x89/0x8B
-
-# Soft Leather Armour~
-K:103:0x89/0x8D
-
-# Soft Studded Leather~
-K:104:0x89/0x8E
-
-# Hard Leather Armour~
-K:105:0x89/0x8F
-
-# Hard Studded Leather~
-K:106:0x89/0x90
-
-# Leather Scale Mail~
-K:107:0x89/0x91
-
-# Metal Scale Mail~
-K:108:0x89/0x92
-
-# Chain Mail~
-K:109:0x89/0x94
-
-# Rusty Chain Mail~
-K:110:0x89/0x93
-
-# Augmented Chain Mail~
-K:111:0x89/0x96
-
-# Bar Chain Mail~
-K:112:0x89/0x97
-
-# Metal Brigandine Armour~
-K:113:0x89/0x98
-
-# Partial Plate Armour~
-K:114:0x89/0x99
-
-# Metal Lamellar Armour~
-K:115:0x89/0x9A
-
-# Full Plate Armour~
-K:116:0x89/0x9B
-
-# Ribbed Plate Armour~
-K:117:0x89/0x9C
-
-# Adamantite Plate Mail~
-K:118:0x89/0x9F
-
-# Mithril Plate Mail~
-K:119:0x89/0x9E
-
-# Mithril Chain Mail~
-K:120:0x89/0x9D
-
-# Double Chain Mail~
-K:121:0x89/0x95
-
-# & Shield~ of Deflection
-K:122:0x88/0x98
-
-# & Cloak~
-K:123:0x89/0x88
-
-# & Shadow Cloak~
-K:124:0x89/0x89
-
-# & Set~ of Leather Gloves
-K:125:0x88/0x91
-
-# & Set~ of Gauntlets
-K:126:0x88/0x92
-
-# & Set~ of Cesti
-K:127:0x88/0x93
-
-# & Small Leather Shield~
-K:128:0x88/0x94
-
-# & Large Leather Shield~
-K:129:0x88/0x95
-
-# & Small Metal Shield~
-K:130:0x88/0x96
-
-# & Large Metal Shield~
-K:131:0x88/0x97
-
-# Strength
-K:132:0x84/0x81
-
-# Dexterity
-K:133:0x84/0x83
-
-# Constitution
-K:134:0x84/0x83
-
-# Intelligence
-K:135:0x84/0x83
-
-# Speed
-K:136:0x84/0x83
-
-# Searching
-K:137:0x84/0x83
-
-# Teleportation
-K:138:0x84/0x83
-
-# Slow Digestion
-K:139:0x84/0x83
-
-# Fire Resistance
-K:140:0x84/0x83
-
-# Cold Resistance
-K:141:0x84/0x83
-
-# Levitation
-K:142:0x84/0x83
-
-# Poison Resistance
-K:143:0x84/0x83
-
-# Free Action
-K:144:0x84/0x83
-
-# Weakness
-K:145:0x84/0x83
-
-# Flames
-K:146:0x84/0x83
-
-# Acid
-K:147:0x84/0x83
-
-# Ice
-K:148:0x84/0x83
-
-# Woe
-K:149:0x84/0x83
-
-# Stupidity
-K:150:0x84/0x83
-
-# Damage
-K:151:0x84/0x83
-
-# Accuracy
-K:152:0x84/0x83
-
-# Protection
-K:153:0x84/0x83
-
-# Aggravate Monster
-K:154:0x84/0x83
-
-# See Invisible
-K:155:0x84/0x83
-
-# Sustain Strength
-K:156:0x84/0x83
-
-# Sustain Intelligence
-K:157:0x84/0x83
-
-# Sustain Wisdom
-K:158:0x84/0x83
-
-# Sustain Constitution
-K:159:0x84/0x83
-
-# Sustain Dexterity
-K:160:0x84/0x83
-
-# Sustain Charisma
-K:161:0x84/0x83
-
-# Slaying
-K:162:0x84/0x83
-
-# Brilliance
-K:163:0x87/0x83
-
-# Charisma
-K:164:0x87/0x83
-
-# Searching
-K:165:0x87/0x83
-
-# Teleportation
-K:166:0x87/0x83
-
-# Slow Digestion
-K:167:0x87/0x83
-
-# Acid Resistance
-K:168:0x87/0x83
-
-# Adornment
-K:169:0x87/0x83
-
-# Double Ring Mail~
-K:170:0x89/0x9B
-
-# the Magi
-K:171:0x87/0x83
-
-# Doom
-K:172:0x87/0x83
-
-# Enchant Weapon To-Hit
-K:173:0x83/0x9C
-
-# Enchant Weapon To-Dam
-K:174:0x83/0x9C
-
-# Enchant Armor
-K:175:0x83/0x9C
-
-# Identify
-K:176:0x83/0x9C
-
-# *Identify*
-K:177:0x83/0x9C
-
-# Rumour
-K:178:0x83/0x9C
-
-# Chaos
-K:179:0x83/0x9C
-
-# Remove Curse
-K:180:0x83/0x9C
-
-# Light
-K:181:0x83/0x9C
-
-# Fire
-K:182:0x83/0x9C
-
-# Ice
-K:183:0x83/0x9C
-
-# Summon Monster
-K:184:0x83/0x9C
-
-# Phase Door
-K:185:0x83/0x9C
-
-# Teleportation
-K:186:0x83/0x9C
-
-# Teleport Level
-K:187:0x83/0x9C
-
-# Monster Confusion
-K:188:0x83/0x9C
-
-# Magic Mapping
-K:189:0x83/0x9C
-
-# Rune of Protection
-K:190:0x83/0x9C
-
-# *Remove Curse*
-K:191:0x83/0x9C
-
-# Treasure Detection
-K:192:0x83/0x9C
-
-# Object Detection
-K:193:0x83/0x9C
-
-# Trap Detection
-K:194:0x83/0x9C
-
-# & Sheaf Arrow~
-K:195:0x8C/0x81
-
-# & Mithril Shot~
-K:196:0x8C/0x85
-
-# Door
-K:197:0x83/0x9C
-
-# Acquirement
-K:198:0x83/0x9C
-
-# *Acquirement*
-K:199:0x83/0x9C
-
-# Mass Genocide
-K:200:0x83/0x9C
-
-# Detect Invisible
-K:201:0x83/0x9C
-
-# Aggravate Monster
-K:202:0x83/0x9C
-
-# Trap Creation
-K:203:0x83/0x9C
-
-# Trap
-K:204:0x83/0x9C
-
-# Artifact Creation
-K:205:0x83/0x9C
-
-# Recharging
-K:206:0x83/0x9C
-
-# Genocide
-K:207:0x83/0x9C
-
-# Darkness
-K:208:0x83/0x9C
-
-# Protection from Evil
-K:209:0x83/0x9C
-
-# Satisfy Hunger
-K:210:0x83/0x9C
-
-# Dispel Undead
-K:211:0x83/0x9C
-
-# *Enchant Weapon*
-K:212:0x83/0x9C
-
-# Curse Weapon
-K:213:0x83/0x9C
-
-# *Enchant Armor*
-K:214:0x83/0x9C
-
-# Curse Armor
-K:215:0x83/0x9C
-
-# Summon Undead
-K:216:0x83/0x9C
-
-# Blessing
-K:217:0x83/0x9C
-
-# Holy Chant
-K:218:0x83/0x9C
-
-# Holy Prayer
-K:219:0x83/0x9C
-
-# Word of Recall
-K:220:0x83/0x9C
-
-# *Destruction*
-K:221:0x83/0x9C
-
-# Slime Mold Juice
-K:222:0x85/0x85
-
-# Apple Juice
-K:223:0x85/0x85
-
-# Water
-K:224:0x85/0x85
-
-# Strength
-K:225:0x85/0x85
-
-# Weakness
-K:226:0x85/0x85
-
-# Restore Strength
-K:227:0x85/0x85
-
-# Intelligence
-K:228:0x85/0x85
-
-# Stupidity
-K:229:0x85/0x85
-
-# Restore Intelligence
-K:230:0x85/0x85
-
-# Wisdom
-K:231:0x85/0x85
-
-# Naivety
-K:232:0x85/0x85
-
-# Restore Wisdom
-K:233:0x85/0x85
-
-# Charisma
-K:234:0x85/0x85
-
-# Ugliness
-K:235:0x85/0x85
-
-# Restore Charisma
-K:236:0x85/0x85
-
-# Curing
-K:237:0x85/0x85
-
-# Invulnerability
-K:238:0x85/0x85
-
-# New Life
-K:239:0x85/0x85
-
-# Cure Serious Wounds
-K:240:0x85/0x85
-
-# Cure Critical Wounds
-K:241:0x85/0x85
-
-# Healing
-K:242:0x85/0x85
-
-# Constitution
-K:243:0x85/0x85
-
-# Experience
-K:244:0x85/0x85
-
-# Sleep
-K:245:0x85/0x85
-
-# Blindness
-K:246:0x85/0x85
-
-# Booze
-K:247:0x85/0x85
-
-# Poison
-K:248:0x85/0x85
-
-# Speed
-K:249:0x85/0x85
-
-# Slowness
-K:250:0x85/0x85
-
-# Dexterity
-K:251:0x85/0x85
-
-# Restore Dexterity
-K:252:0x85/0x85
-
-# Restore Constitution
-K:253:0x85/0x85
-
-# Lose Memories
-K:254:0x85/0x85
-
-# Salt Water
-K:255:0x85/0x85
-
-# Enlightenment
-K:256:0x85/0x85
-
-# Heroism
-K:257:0x85/0x85
-
-# Berserk Strength
-K:258:0x85/0x85
-
-# Boldness
-K:259:0x85/0x85
-
-# Restore Life Levels
-K:260:0x85/0x85
-
-# Resist Heat
-K:261:0x85/0x85
-
-# Resist Cold
-K:262:0x85/0x85
-
-# Detect Invisible
-K:263:0x85/0x85
-
-# Slow Poison
-K:264:0x85/0x85
-
-# Neutralise Poison
-K:265:0x85/0x85
-
-# Restore Mana
-K:266:0x85/0x85
-
-# Infra-vision
-K:267:0x85/0x85
-
-# Resistance
-K:268:0x85/0x85
-
-# Spell
-K:269:0x86/0x93
-
-# Manathrust
-K:270:0x86/0x93
-
-# Fireflash
-K:271:0x86/0x93
-
-# Firewall
-K:272:0x86/0x93
-
-# Tidal Wave
-K:273:0x86/0x93
-
-# Ice Storm
-K:274:0x86/0x93
-
-# Noxious Cloud
-K:275:0x86/0x93
-
-# Poison Blood
-K:276:0x86/0x93
-
-# Thunderstorm
-K:277:0x86/0x93
-
-# Dig
-K:278:0x86/0x93
-
-# Stone Prison
-K:279:0x86/0x93
-
-# Strike
-K:280:0x86/0x93
-
-# Teleport Away
-K:281:0x86/0x93
-
-# Summon Animal
-K:282:0x86/0x93
-
-# Magelock
-K:283:0x86/0x93
-
-# Slow Monster
-K:284:0x86/0x93
-
-# Essence of Speed
-K:285:0xB7/0x8C
-
-# Banishment
-K:286:0x86/0x93
-
-# Disperse Magic
-K:287:0x86/0x93
-
-# Charm
-K:288:0x86/0x93
-
-# Confuse
-K:289:0x86/0x93
-
-# Demon Blade
-K:290:0x86/0x93
-
-# Heal Monster
-K:291:0x86/0x93
-
-# Haste Monster
-K:292:0x86/0x93
-
-# & Flight Arrow~
-K:293:0x8C/0x81
-
-# Acid Bolts
-K:294:0x86/0x93
-
-# Dragon's Flame
-K:295:0x86/0x93
-
-# Dragon's Frost
-K:296:0x86/0x93
-
-# Dragon's Breath
-K:297:0x86/0x93
-
-# Annihilation
-K:298:0x86/0x93
-
-# Rockets
-K:299:0x86/0x93
-
-# Spell
-K:300:0x87/0x92
-
-# Nothing
-K:301:0x87/0x92
-
-# Globe of Light
-K:302:0x87/0x92
-
-# Fiery Shield
-K:303:0x87/0x92
-
-# Remove Curses
-K:304:0x87/0x92
-
-# Wings of Winds
-K:305:0x87/0x92
-
-# Shake
-K:306:0x87/0x92
-
-# Disarm
-K:307:0x87/0x92
-
-# Teleportation
-K:308:0x87/0x92
-
-# Probability Travel
-K:309:0x87/0x92
-
-# Recovery
-K:310:0x87/0x92
-
-# Healing
-K:311:0x87/0x92
-
-# Vision
-K:312:0x87/0x92
-
-# Identify
-K:313:0x87/0x92
-
-# Sense Hidden
-K:314:0x87/0x92
-
-# Reveal Ways
-K:315:0x87/0x92
-
-# Sense Monsters
-K:316:0x87/0x92
-
-# Genocide
-K:317:0x87/0x92
-
-# Summon
-K:318:0x87/0x92
-
-# Curing
-K:319:0x87/0x92
-
-# Wish
-K:320:0x87/0x92
-
-# Mana
-K:321:0x87/0x92
-
-# Darkness
-K:322:0x87/0x92
-
-# Genocide
-K:323:0x87/0x92
-
-# Power
-K:324:0x87/0x92
-
-# the Magi
-K:325:0x87/0x92
-
-# Perception
-K:326:0x87/0x92
-
-# Holiness
-K:327:0x87/0x92
-
-# Enlightenment
-K:328:0x87/0x92
-
-# Healing
-K:329:0x87/0x92
-
-# & Tome~ of Magical Energy
-K:330:0x90/0xA0
-
-# & Tome~ of the Eternal Flame
-K:331:0x90/0xA1
-
-# & Tome~ of the Blowing Wind
-K:332:0x90/0xA2
-
-# & Tome~ of the Impenetrable Earth
-K:333:0x90/0xA3
-
-# & Tome~ of the Everrunning Wave
-K:334:0x90/0xA4
-
-# & Tome~ of Translocation
-K:335:0x90/0xA5
-
-# & Tome~ of the Tree
-K:336:0x90/0xA6
-
-# & Tome~ of Knowledge
-K:337:0x90/0xA7
-
-# & Small wooden chest~
-K:338:0x84/0x99
-
-# & Large wooden chest~
-K:339:0x84/0x9A
-
-# & Small iron chest~
-K:340:0x84/0x9B
-
-# & Large iron chest~
-K:341:0x84/0x9C
-
-# & Small steel chest~
-K:342:0x84/0x9D
-
-# & Large steel chest~
-K:343:0x84/0x9E
-
-# & Ruined chest~
-K:344:0x84/0x9F
-
-# & Iron Spike~
-K:345:0x8E/0x89
-
-# & Wooden Torch~
-K:346:0x8E/0x8B
-
-# & Brass Lantern~
-K:347:0x8E/0x8A
-
-# & Flask~ of oil
-K:348:0x8E/0x88
-
-# & Empty Bottle~
-K:349:0x8E/0x87
-
-# Havoc
-K:350:0x86/0x83
-
-# Door
-K:351:0x86/0x83
-
-# Trap Location
-K:352:0x86/0x83
-
-# Probing
-K:353:0x86/0x83
-
-# Recall
-K:354:0x86/0x83
-
-# Illumination
-K:355:0x86/0x83
-
-# Light
-K:356:0x86/0x83
-
-# Lightning Bolts
-K:357:0x86/0x83
-
-# Frost Bolts
-K:358:0x86/0x83
-
-# Fire Bolts
-K:359:0x86/0x83
-
-# Polymorph
-K:360:0x86/0x83
-
-# Slow Monster
-K:361:0x86/0x83
-
-# Sleep Monster
-K:362:0x86/0x83
-
-# Drain Life
-K:363:0x86/0x83
-
-# Teleport Other
-K:364:0x86/0x83
-
-# Disarming
-K:365:0x86/0x83
-
-# Lightning Balls
-K:366:0x86/0x83
-
-# Cold Balls
-K:367:0x86/0x83
-
-# Fire Balls
-K:368:0x86/0x83
-
-# Acid Balls
-K:369:0x86/0x83
-
-# Acid Bolts
-K:370:0x86/0x83
-
-# Enlightenment
-K:371:0x86/0x83
-
-# Perception
-K:372:0x86/0x83
-
-# Curing
-K:373:0x86/0x83
-
-# Healing
-K:374:0x86/0x83
-
-# Detection
-K:375:0x86/0x83
-
-# Restoration
-K:376:0x86/0x83
-
-# Speed
-K:377:0x86/0x83
-
-# Spell
-K:378:0xC1/0x84
-K:379:0x8D/0x80
-
-# [Beings of Darkness]
-K:380:0x8D/0x81
-
-# [Material Shadow]
-K:381:0x8D/0x82
-
-# [Nature's Wrath]
-K:382:0x8D/0x83
-
-# [Sign of Chaos]
-K:383:0x8C/0x98
-
-# [Chaos Mastery]
-K:384:0x8C/0x99
-
-# [Chaos Channels]
-K:385:0x8C/0x9A
-
-# [Armageddon Tome]
-K:386:0x8C/0x9B
-
-# [Nether Openings]
-K:387:0x8D/0x88
-
-# [Unholy Blessings]
-K:388:0x8D/0x89
-
-# & Firestone~
-K:389:0x8E/0x92
-
-# & Small Firestone~
-K:390:0x8E/0x93
-
-# & Broken Skull~
-K:391:0x8E/0x94
-
-# & Broken Bone~
-K:392:0x8E/0x95
-
-# & Canine Skeleton~
-K:393:0x8E/0x9A
-
-# & Rodent Skeleton~
-K:394:0x8E/0x9B
-
-# & Human Skeleton~
-K:395:0x8E/0x96
-
-# & Dwarf Skeleton~
-K:396:0x8E/0x98
-
-# & Elf Skeleton~
-K:397:0x8E/0x97
-
-# & Gnome Skeleton~
-K:398:0x8E/0x99
-
-# & Great Hammer~
-K:399:0xB6/0x8A
-
-# Black Dragon Scale Mail~
-K:400:0x8A/0x82
-
-# Blue Dragon Scale Mail~
-K:401:0x8A/0x80
-
-# White Dragon Scale Mail~
-K:402:0x8A/0x81
-
-# Red Dragon Scale Mail~
-K:403:0x8A/0x83
-
-# Green Dragon Scale Mail~
-K:404:0x8A/0x84
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x8A/0x8B
-
-# Pseudo Dragon Scale Mail~
-K:406:0x8A/0x87
-
-# Law Dragon Scale Mail~
-K:407:0x8A/0x89
-
-# Bronze Dragon Scale Mail~
-K:408:0x8A/0x85
-
-# Gold Dragon Scale Mail~
-K:409:0x8A/0x86
-
-# Chaos Dragon Scale Mail~
-K:410:0x8A/0x88
-
-# Balance Dragon Scale Mail~
-K:411:0x8A/0x8A
-
-# Power Dragon Scale Mail~
-K:412:0x8A/0x8C
-
-# & Dragon Helm~
-K:413:0x88/0x82
-
-# & Dragon Shield~
-K:414:0x88/0x9C
-
-# Death
-K:415:0x85/0x85
-
-# Ruination
-K:416:0x85/0x85
-
-# Detonations
-K:417:0x85/0x85
-
-# Augmentation
-K:418:0x85/0x85
-
-# *Healing*
-K:419:0x85/0x85
-
-# Life
-K:420:0x85/0x85
-
-# Self Knowledge
-K:421:0x85/0x85
-
-# *Enlightenment*
-K:422:0x85/0x85
-
-# [Necromantic Incantations]
-K:423:0x8D/0x8A
-
-# [Curses of Angmar]
-K:424:0x8D/0x8B
-
-# Fear Resistance
-K:425:0x84/0x83
-
-# Light and Darkness Resistance
-K:426:0x84/0x83
-
-# Nether Resistance
-K:427:0x84/0x83
-
-# Nexus Resistance
-K:428:0x84/0x83
-
-# Sound Resistance
-K:429:0x84/0x83
-
-# Confusion Resistance
-K:430:0x84/0x83
-
-# Shard Resistance
-K:431:0x84/0x83
-
-# Disenchantment Resistance
-K:432:0x84/0x83
-
-# Chaos Resistance
-K:433:0x84/0x83
-
-# Blindness Resistance
-K:434:0x84/0x83
-
-# Lordly Protection
-K:435:0x84/0x83
-
-# Extra Attacks
-K:436:0x84/0x83
-
-# Cure Light Wounds
-K:437:0x85/0x85
-
-# Clumsiness
-K:438:0x85/0x85
-
-# Sickliness
-K:439:0x85/0x85
-
-# Map of Bree
-K:440:0xC4/0x80
-
-# Map of Gondolin
-K:441:0xC4/0x80
-
-# Map of Lothlorien
-K:442:0xC4/0x80
-
-# Map of Minas Anor
-K:443:0xC4/0x80
-
-# & Silver Arrow~
-K:465:0xC6/0x81
-
-# & Silver Bolt~
-K:466:0xC6/0x82
-
-# Lightning Resistance
-K:467:0x87/0x80
-
-# Wisdom
-K:468:0x87/0x80
-
-# Regeneration
-K:469:0x87/0x80
-
-# Infravision
-K:470:0x87/0x80
-
-# Devotion
-K:471:0x87/0x80
-
-# Weaponmastery
-K:472:0x87/0x80
-
-# Trickery
-K:473:0x87/0x80
-
-# Telepathy
-K:474:0x87/0x80
-
-# Sustenance
-K:475:0x87/0x80
-
-# & Palantir~
-K:476:0xC6/0x87
-
-# & Elfstone~
-K:477:0xC6/0x83
-
-# & Jewel~
-K:478:0xC6/0x84
-
-# & Ring~
-K:479:0xC6/0x85
-
-# copper
-K:480:0x83/0x91
-K:481:0x83/0x91
-K:482:0x83/0x91
-
-# silver
-K:483:0x83/0x92
-K:484:0x83/0x92
-K:485:0x83/0x92
-
-# garnets
-K:486:0x83/0x96
-K:487:0x83/0x96
-
-# gold
-K:488:0x83/0x93
-K:489:0x83/0x93
-K:490:0x83/0x93
-
-# opals
-K:491:0x83/0x97
-
-# sapphires
-K:492:0x83/0x98
-
-# rubies
-K:493:0x83/0x99
-
-# diamonds
-K:494:0x83/0x9A
-
-# emeralds
-K:495:0x83/0x9B
-
-# mithril
-K:496:0x83/0x94
-
-# adamantite
-K:497:0x83/0x95
-
-# & Mighty Hammer~
-K:498:0xB6/0x8A
-
-# & Massive Iron Crown~
-K:499:0x87/0x9C
-
-# & Phial~
-K:500:0x8E/0x9D
-
-# & Star~
-K:501:0x8E/0x9E
-
-# & Arkenstone~
-K:502:0x8E/0x9F
-
-# & Amulet~
-K:503:0x84/0x96
-K:504:0x84/0x97
-
-# & Necklace~
-K:505:0x84/0x98
-
-# & Ring~
-K:506:0x84/0x8F
-K:507:0x84/0x90
-K:508:0x84/0x92
-K:509:0x84/0x93
-K:510:0x84/0x94
-K:511:0x84/0x95
-
-# [Rites of Initiation]
-K:512:0x8D/0x90
-
-# [Ways of War]
-K:513:0x8D/0x91
-
-# [Divine Retribution]
-K:514:0x8D/0x92
-
-# [Essence of Fury]
-K:515:0x8D/0x93
-
-# [Novice Crafts]
-K:516:0x8D/0x8C
-
-# [Arcane Channels]
-K:517:0x8D/0x8D
-
-# [Sigils of Wizardry]
-K:518:0x8D/0x8E
-
-# [Mana Focus]
-K:519:0x8D/0x8F
-
-# Reflection
-K:520:0x87/0x83
-
-# Anti-Magic
-K:521:0x87/0x83
-
-# Anti-Teleportation
-K:522:0x87/0x83
-
-# Resistance
-K:523:0x87/0x83
-
-# & Zweihander~
-K:524:0xB6/0x8C
-
-# & Dwarven Lantern~
-K:525:0xC5/0x94
-
-# Splint Mail~
-K:526:0x89/0x9C
-
-# & Everburning Torch~
-K:527:0xC5/0x95
-
-# & Trifurcate Spear~
-K:528:0xB6/0x85
-
-# & Three Piece Rod~
-K:529:0xB6/0x80
-
-# & Feanorian Lamp~
-K:530:0xC5/0x96
-
-# & Fur Cloak~
-K:531:0x89/0x89
-
-# Water Curing
-K:532:0xB6/0x86
-
-# & Hatchet~
-K:533:0xB6/0x8F
-
-# Rhino Hide Armour~
-K:535:0x89/0x98
-
-# Leather Jacket~
-K:536:0x89/0x8F
-
-# & Sickle~
-K:537:0xB6/0x90
-
-# [Psychoportation]
-K:538:0xB6/0x87
-
-# [Clairsentience]
-K:539:0xB6/0x91
-
-# [Telekinesis]
-K:540:0xB6/0x93
-
-# [Empathy]
-K:541:0xB6/0x92
-
-# & Club~
-K:542:0xB6/0x92
-
-# & Broad Spear~
-K:543:0xB6/0x84
-
-# & Khopesh~
-K:544:0xB6/0x94
-
-# & Flamberge~
-K:545:0xB6/0x83
-
-# & Claymore~
-K:546:0xB6/0x8D
-
-# & Espadon~
-K:547:0xB6/0x8E
-
-# & Great Scimitar~
-K:548:0xB6/0x8B
-
-# Arrow
-K:549:0x8E/0xA0
-
-# Bolt
-K:550:0x8E/0xA1
-
-# & Fauchard~
-K:551:0xB6/0x95
-
-# & Guisarme~
-K:552:0xB6/0x96
-
-# & Heavy Lance~
-K:553:0xB6/0x82
-
-# & Basillard~
-K:554:0xB6/0x99
-
-# Catapult
-K:555:0x8E/0xA2
-
-# Ring Mail~
-K:556:0x89/0x9C
-
-# Cord Armour~
-K:557:0x89/0x90
-
-# Paper Armour~
-K:558:0x8A/0x81
-
-# Padded Armour~
-K:559:0x89/0x91
-
-# Fumes
-K:560:0x8E/0xA3
-
-# Stone and Hide Armour~
-K:561:0x89/0x97
-
-# Magic
-K:562:0x8E/0xA4
-
-# Device
-K:563:0x8E/0xA5
-
-# Nothing
-K:564:0xC6/0x9C
-
-# Poison
-K:565:0xB7/0x80
-
-# Nothing
-K:566:0xC6/0x9C
-K:567:0xC6/0x9C
-K:568:0xC6/0x9C
-K:569:0xC6/0x9C
-
-# Explosion
-K:570:0xB7/0x81
-
-# Teleport
-K:571:0xB7/0x82
-
-# Nothing
-K:572:0xC6/0x9C
-
-# & Blood~ of Life
-K:573:0x85/0x85
-
-# Cold
-K:574:0xB7/0x83
-
-# Fire
-K:575:0xB7/0x84
-
-# Acid
-K:576:0xB7/0x85
-
-# & Mage Staff~
-K:577:0xB8/0x80
-
-# Lightning
-K:578:0x84/0x80
-
-# Life
-K:579:0xB7/0x86
-
-# Confusion
-K:580:0xB7/0x87
-
-# Light
-K:581:0xB7/0x88
-
-# & Ring~
-K:582:0x84/0x85
-
-# Invisibility
-K:583:0x85/0x85
-
-# Chaos
-K:584:0xB7/0x89
-
-# Corruption
-K:585:0x85/0x85
-
-# Invisibility
-K:586:0x85/0x85
-
-# Time
-K:587:0xB7/0x8A
-
-# Deep Thoughts
-K:588:0x83/0x9C
-
-# More Deep Thoughts
-K:589:0x83/0x9D
-
-# Compendium of Deep Thoughts
-K:590:0x83/0x9E
-
-# Artifact Lore Vol. I
-K:591:0x83/0x9C
-
-# Artifact Lore Vol. II
-K:592:0x83/0x9D
-
-# Artifact Lore Vol. III
-K:593:0x83/0x9F
-
-# Monstrous Compendium 1
-K:594:0x83/0x9F
-
-# Monstrous Compendium 2
-K:595:0x83/0x9E
-
-# Monstrous Compendium 3
-K:596:0x83/0x9D
-
-# Monstrous Compendium 4
-K:597:0x83/0x9C
-
-# Monstrous Compendium 5
-K:598:0x83/0x9F
-
-# Monstrous Compendium 6
-K:599:0x83/0x9E
-
-# Monstrous Compendium 7
-K:600:0x83/0x9D
-
-# Monstrous Compendium 8
-K:601:0x83/0x9C
-
-# Monstrous Compendium 9
-K:602:0x83/0x9D
-
-# Monstrous Compendium 10
-K:603:0x83/0x9E
-
-# Monstrous Compendium 11
-K:604:0x83/0x9F
-
-# Abomination
-K:605:0x85/0x85
-
-# Shape of Wolf
-K:606:0x85/0x85
-
-# Shape of Ape
-K:607:0x85/0x85
-
-# Shape of Goat
-K:608:0x85/0x85
-
-# Shape of Insect
-K:609:0x85/0x85
-
-# Shape of Sparrow
-K:610:0x85/0x85
-
-# Shape of Ent
-K:611:0x85/0x85
-
-# Shape of Vampire
-K:612:0x85/0x85
-
-# Shape of Spider
-K:613:0x85/0x85
-
-# Shape of Mana ball
-K:614:0x85/0x85
-
-# Shape of Fire cloud
-K:615:0x85/0x85
-
-# Shape of Cold cloud
-K:616:0x85/0x85
-
-# Shape of Chaos cloud
-K:617:0x85/0x85
-
-# [Wolf]
-K:618:0x8F/0xA0
-
-# [Ape]
-K:619:0x8F/0xA1
-
-# [Goat]
-K:620:0x8F/0xA2
-
-# [Insect]
-K:621:0x8F/0xA3
-
-# [Sparrow]
-K:622:0x8F/0xA4
-
-# [Ent]
-K:623:0x8F/0xA5
-
-# [Vampire]
-K:624:0x8F/0xA6
-
-# [Spider]
-K:625:0x8F/0xA7
-
-# [Mana ball]
-K:626:0x8F/0xA8
-
-# [Fire cloud]
-K:627:0x8F/0xA9
-
-# [Cold cloud]
-K:628:0x8F/0xAA
-
-# [Chaos Cloud]
-K:629:0x8F/0xAB
-
-# [Ghost]
-K:630:0x8F/0xAC
-
-# [Kobold]
-K:631:0x8F/0xAD
-
-# [Dragon]
-K:632:0x8F/0xAE
-
-# [Demon]
-K:633:0x8F/0xAF
-
-# [Hound]
-K:634:0x8F/0xB0
-
-# [Quylthulg]
-K:635:0x8F/0xB1
-
-# [Maia]
-K:636:0x8F/0xB2
-
-# [Serpent]
-K:637:0x8F/0xB3
-
-# [Giant]
-K:638:0x8F/0xB4
-
-# [Vala]
-K:639:0x8F/0xB5
-
-# Magic
-K:640:0xB7/0x8B
-
-# corpse
-K:641:0xB8/0x81
-
-# skeleton
-K:642:0x8E/0x96
-
-# head
-K:643:0x8E/0x94
-
-# skull
-K:644:0x8E/0x94
-
-# raw meat
-K:645:0x8E/0x83
-
-# & Thunderlord Coat~
-K:646:0x8A/0x86
-
-# & Stone~
-K:647:0x8E/0x9C
-
-# & small wooden Boomerang~
-K:648:0xB8/0x82
-
-# & wooden Boomerang~
-K:649:0xB8/0x83
-
-# & small metal Boomerang~
-K:650:0xB8/0x84
-
-# & metal Boomerang~
-K:651:0xB8/0x85
-
-# & Anchor~
-K:652:0x8D/0x9E
-
-# & ~
-K:653:0xC6/0x9C
-
-# Summon never-moving pet
-K:654:0x83/0x9D
-
-# [Life in symbiosis]
-K:655:0xB8/0x86
-
-# [Perfect Symbiosis]
-K:656:0xB8/0x86
-
-# Cure Light Insanity
-K:657:0x85/0x85
-
-# Cure Serious Insanity
-K:658:0x85/0x85
-
-# Cure Critical Insanity
-K:659:0x85/0x85
-
-# Cure Insanity
-K:660:0x85/0x85
-
-# & Phial~
-K:661:0x8E/0x9D
-
-# Random Artifact
-K:662:0xC6/0x9C
-
-# Craftmanship
-K:663:0x83/0x9F
-
-# The One Ring
-K:664:0x83/0x9E
-
-# & Book~ of the Lays of the Heroes
-K:665:0xB8/0x87
-
-# & Book~ of Sound Patterns
-K:666:0xB8/0x87
-
-# [Harps of Rivendell]
-K:667:0xB8/0x87
-
-# [Lays of Beleriand]
-K:668:0xB8/0x87
-
-# & Flute~
-K:669:0xB8/0x88
-
-# & Drum~
-K:670:0xB8/0x89
-
-# & Harp~
-K:671:0xB8/0x8A
-
-# & Banjo~
-K:672:0xB8/0x8C
-
-# & Lute~
-K:673:0xB8/0x8B
-
-# & Mandolin~
-K:674:0xB8/0x8B
-
-# & Palantir~
-K:675:0x8D/0x9F
-
-# Egg
-K:676:0xB7/0x8D
-
-# Reset Recall
-K:677:0x83/0x9D
-
-# Divination
-K:678:0x83/0x9D
-
-# Self
-K:679:0xB7/0x8E
-
-# Ray
-K:680:0xB7/0x8F
-
-# Sphere
-K:681:0xB7/0x90
-
-# Knowledge
-K:682:0xB7/0x94
-
-# Life
-K:683:0xB7/0x95
-
-# Fire
-K:684:0xB7/0x96
-
-# Cold
-K:685:0xB7/0x97
-
-# Lightning
-K:686:0xB7/0x98
-
-# Acid
-K:687:0xB7/0x99
-
-# Element
-K:688:0xB7/0x9A
-
-# Chaos
-K:689:0xB7/0x9B
-
-# Mind
-K:690:0xB7/0x9C
-
-# Holding
-K:691:0xB7/0x9D
-
-# Arrow
-K:692:0xB7/0x91
-
-# Power Surge
-K:693:0xB7/0x92
-
-# Armageddon
-K:694:0xB7/0x93
-
-# Gravity
-K:695:0xB7/0x9E
-
-# Extra Life
-K:696:0xB7/0x9F
-
-# Undeath
-K:697:0xB6/0x9B
-
-# Protection
-K:698:0xB6/0x9C
-
-# & Horn~
-K:699:0xB8/0x8D
-
-# & Ring~ of Precognition
-K:700:0x84/0x83
-
-# & Sprig~ of Athelas
-K:701:0xB8/0x8E
-
-# [Magic for Beginners]
-K:702:0xB8/0x8F
-
-# [Conjurings and Tricks]
-K:703:0xB8/0x8F
-
-# [Incantations and Illusions]
-K:704:0xB8/0x8F
-
-# [Sorcery and Evocations]
-K:705:0xB8/0x8F
-
-# [Beginners Handbook]
-K:706:0xB8/0x90
-
-# [Words of Wisdom]
-K:707:0xB8/0x90
-
-# [Chants and Blessings]
-K:708:0xB8/0x90
-
-# [Exorcism and Dispelling]
-K:709:0xB8/0x90
-
-# [Resistance of Scarabtarices]
-K:710:0xB8/0x92
-
-# [Mordenkainen's Escapes]
-K:711:0xB8/0x92
-
-# [Kelek's Grimoire of Power]
-K:712:0xB8/0x92
-
-# [Tenser's Transformations]
-K:713:0xB8/0x92
-
-# [Raal's Tome of Destruction]
-K:714:0xB8/0x92
-
-# [Ethereal Openings]
-K:715:0xB8/0x92
-
-# [Godly Insights]
-K:716:0xB8/0x91
-
-# [Purifications and Healing]
-K:717:0xB8/0x91
-
-# [Holy Infusions]
-K:718:0xB8/0x91
-
-# [Wrath of God]
-K:719:0xB8/0x91
-
-# & Old Scroll~ of Deincarnation
-K:720:0x83/0x9F
-
-# & Dark Sword~
-K:721:0xC4/0x81
-
-# Numenorean for beginners (I)
-K:722:0xC1/0x80
-
-# Numenorean for beginners (II)
-K:723:0xC1/0x81
-
-# Advanced lessons of Numenorean
-K:724:0xC1/0x80
-
-# Advanced lessons of Sindarin
-K:725:0xC1/0x81
-
-# & Shard~ of Pottery
-K:726:0x8E/0x92
-
-# & Broken Stick~
-K:727:0x8E/0x93
-
-# Wall Creation
-K:728:0x83/0x9F
-
-# [Illusions for Beginners]
-K:729:0xC1/0x82
-
-# [Tricks and Visions]
-K:730:0xC1/0x82
-
-# [Phantasms and Illusions]
-K:731:0xC1/0x82
-
-# [Shadows and Prisms]
-K:732:0xC1/0x82
-
-# [Serten's Immunities]
-K:733:0xC1/0x83
-
-# [Knowledge of Kenault]
-K:734:0xC1/0x83
-
-# [Otiluke's Spheres]
-K:735:0xC1/0x82
-
-# [Boccob's Book of Shadows]
-K:736:0xC1/0x84
-
-# [Bigby's Handbook]
-K:737:0xC1/0x84
-
-# & Book~ of Beginner Cantrips
-K:738:0xC1/0x85
-
-# & Book~ of Teleportation
-K:739:0xC1/0x86
-
-# & Book~ of Recall
-K:740:0xC1/0x87
-
-# & Book~ of Summoning
-K:741:0xC1/0x80
-
-# & Book~ of Fireflash
-K:742:0xC1/0x81
-
-# & Potion~ of Learning
-K:743:0xC1/0x82
-
-# [Eye of Sauron]
-K:744:0xC1/0x83
-
-# [Flame of Udun]
-K:745:0xC1/0x84
-
-# [Corruptions of Melkor]
-K:746:0xC1/0x85
-
-# [Crescent of Morgul]
-K:747:0xC1/0x86
-
-# [Morgoth's Ring]
-K:748:0xC1/0x87
-
-# Spell
-K:749:0x86/0x90
-
-# Wishing
-K:750:0x86/0x90
-
-# Khuzdul - The hidden tongue of the Dwarves
-K:751:0x83/0x9D
-
-# Nandorin for dummies
-K:752:0xC1/0x81
-
-# Advanced lessons of Orcish
-K:753:0xC1/0x82
-
-# & Ancient Tome~
-K:754:0xC1/0x86
-
-# Flying
-K:755:0x84/0x88
-
-# & Tome~ of the Time
-K:756:0xC1/0x80
-
-# & Tome~ of Meta Spells
-K:758:0xC1/0x81
-
-# & Tome~ of the Mind
-K:759:0xC1/0x82
-
-# & Holy Tome~ of Eru Iluvatar
-K:760:0xC1/0x83
-
-# & Holy Tome~ of Manwe Sulimo
-K:761:0xC1/0x84
-
-# & War Tome~ of Tulkas
-K:762:0xC1/0x85
-
-# & Unholy Tome~ of the Hellflame
-K:763:0xC1/0x86
-
-# & Corrupted Tome~ of Melkor
-K:764:0xC1/0x87
-
-# [Aiding Shades]
-K:765:0xC1/0x80
-
-# [Morgoth's Space-Time Warpings]
-K:766:0xC1/0x81
-
-# [Murazor's Tome of Conjuring & Dispelling]
-K:767:0xC1/0x82
-
-# & Forest Tome~ of Yavanna
-K:768:0xC1/0x83
-
-# [Sauron's Forgotten Tome]
-K:769:0xC1/0x87
-
-# & Ring~
-K:770:0x84/0x84
-
-# [Earth]
-K:771:0xC1/0x88
-
-# [Fire]
-K:772:0xC1/0x89
-
-# [Air]
-K:773:0xC1/0x8A
-
-# [Water]
-K:774:0xC1/0x8B
-
-# [Mana]
-K:775:0xC1/0x8C
-
-# Home Summoning
-K:776:0x83/0x9F
-
-# & Shadow Blade~
-K:777:0xC1/0x91
-
-# & Bluesteel Blade~
-K:778:0xC1/0x92
-
-# the Serpents
-K:779:0xC4/0x88
-
-# Darkness
-K:780:0xC4/0x89
-
-# Knowledge
-K:781:0xC4/0x8A
-
-# Force
-K:782:0xC4/0x8B
-
-# Lightning
-K:783:0xC4/0x8C
-
-# Mana
-K:784:0xC4/0x8D
-
-# Ring~ of Power
-K:785:0xC4/0x8E
-
-# Climbing Set~
-K:786:0xC1/0x93
-
-# Adventurer's guide to Middle-earth
-K:787:0x83/0x9E
-
-# & Demonblade~
-K:788:0x90/0xA8
-
-# & Demonshield~
-K:789:0x90/0xA9
-
-# & Demonhorn~
-K:790:0x90/0xAA
-
-# [Demonthoughts]
-K:791:0xC1/0x83
-
-# [Hellfire Tome]
-K:792:0xC1/0x94
-
-# & Wooden Rod~ of#
-K:793:0xC1/0x95
-
-# & Copper Rod~ of#
-K:794:0xC1/0x96
-
-# & Iron Rod~ of#
-K:795:0xC1/0x97
-
-# & Moonstone Rod~ of#
-K:796:0xC1/0x98
-
-# & Silver Rod~ of#
-K:797:0xC1/0x99
-
-# & Golden Rod~ of#
-K:798:0xC1/0x9B
-
-# & Mithril Rod~ of#
-K:799:0xC1/0x9C
-
-# & Adamantite Rod~ of#
-K:800:0xC1/0x9D
-
-# & Greater Ration~ of Health
-K:801:0xC4/0x87
-
-# & Crumpled Scroll~ of Mass Resurrection
-K:802:0x83/0x9E
-
-# & Cleaver~
-K:803:0xC4/0x82
-
-# & Light War Axe~
-K:804:0xC4/0x83
-
-# & Slaughter Axe~
-K:805:0xC4/0x84
-
-# & Runestone~
-K:806:0xC4/0x85
-
-# & Fortune cookie~
-K:807:0xC6/0x86
-
-# Portable hole
-K:808:0xC6/0x89
-
-# Critical Hits
-K:809:0xC6/0x9C
-
-# & Wand~ of Digging of Thrain
-K:810:0xC6/0x9C
-
-# & Gnarled Staff~ of Holy Fire of Mithrandir
-K:811:0xC6/0x9C
-
-# Partial Totem
-K:812:0xC6/0x9D
-
-# True Totem
-K:813:0xC6/0x9E
-
-# Player
-R:0:0x8E/0x80
-
-# Filthy street urchin
-R:1:0xAA/0x80
-
-# Scrawny cat
-R:2:0xA7/0x82
-
-# Sparrow
-R:3:0xB4/0x9E
-
-# Chaffinch
-R:4:0xB4/0x9E
-
-# Wild rabbit
-R:5:0xB4/0x9F
-
-# Woodsman
-R:6:0xAA/0x91
-
-# Scruffy little dog
-R:7:0x9D/0x9A
-
-# Farmer Maggot
-R:8:0xAA/0x81
-
-# Blubbering idiot
-R:9:0xAA/0x82
-
-# Boil-covered wretch
-R:10:0xAA/0x83
-
-# Village idiot
-R:11:0xAA/0x84
-
-# Pitiful-looking beggar
-R:12:0xAA/0x85
-
-# Mangy-looking leper
-R:13:0xAA/0x86
-
-# Agent of the black market
-R:14:0xAA/0x87
-
-# Singing, happy drunk
-R:15:0xAA/0x88
-
-# Aimless-looking merchant
-R:16:0xAA/0x89
-
-# Mean-looking mercenary
-R:17:0xAA/0x8A
-
-# Battle-scarred veteran
-R:18:0xAA/0x8B
-
-# Martti Ihrasaari
-R:19:0xB0/0x80
-
-# Grey mold
-R:20:0xA8/0x9F
-
-# Large white snake
-R:21:0xA2/0x85
-
-# Grey mushroom patch
-R:22:0xB0/0x81
-
-# Newt
-R:23:0xB0/0x82
-
-# Giant white centipede
-R:24:0xA5/0x95
-
-# White icky thing
-R:25:0xA8/0x83
-
-# Clear icky thing
-R:26:0xA8/0x84
-
-# Giant white mouse
-R:27:0xAC/0x85
-
-# Large brown snake
-R:28:0xA2/0x84
-
-# Small kobold
-R:29:0xA8/0x99
-
-# Kobold
-R:30:0xA8/0x9A
-
-# White worm mass
-R:31:0xAC/0x9D
-
-# Floating eye
-R:32:0xA6/0x9B
-
-# Rock lizard
-R:33:0xA2/0x86
-
-# Grid bug
-R:34:0xB0/0x84
-
-# Jackal
-R:35:0x9D/0x9B
-
-# Soldier ant
-R:36:0xA5/0x87
-
-# Fruit bat
-R:37:0xA5/0x8F
-
-# Insect swarm
-R:38:0xB5/0x9E
-
-# The Greater hell-beast
-R:39:0xB0/0x83
-
-# Shrieker mushroom patch
-R:40:0x9D/0x86
-
-# Blubbering icky thing
-R:41:0xA8/0x85
-
-# Metallic green centipede
-R:42:0xA5/0x96
-
-# Novice warrior
-R:43:0xAA/0x8C
-
-# Novice rogue
-R:44:0xAA/0x8D
-
-# Novice priest
-R:45:0xAA/0x8E
-
-# Novice mage
-R:46:0xAA/0x8F
-
-# Yellow mushroom patch
-R:47:0x9D/0x87
-
-# White jelly
-R:48:0xA8/0x8A
-
-# Giant black ant
-R:49:0xA5/0x88
-
-# Salamander
-R:50:0xA2/0x88
-
-# White harpy
-R:51:0xA0/0x88
-
-# Blue yeek
-R:52:0xAD/0x87
-
-# Grip, Farmer Maggot's dog
-R:53:0x9D/0x9C
-
-# Wolf, Farmer Maggot's dog
-R:54:0x9D/0x9D
-
-# Fang, Farmer Maggot's dog
-R:55:0x9D/0x9D
-
-# Giant green frog
-R:56:0xA2/0x87
-
-# Freesia
-R:57:0xB0/0x85
-
-# Green worm mass
-R:58:0xAC/0x9E
-
-# Large yellow snake
-R:59:0xA2/0x89
-
-# Cave spider
-R:60:0xA2/0x9D
-
-# Crow
-R:61:0xB5/0x9F
-
-# Wild cat
-R:62:0xA7/0x83
-
-# Smeagol
-R:63:0xAA/0x90
-
-# Green ooze
-R:64:0xA8/0x8B
-
-# Poltergeist
-R:65:0x9F/0x99
-
-# Yellow jelly
-R:66:0xA8/0x8D
-
-# Metallic blue centipede
-R:67:0xA5/0x97
-
-# Raven
-R:68:0xB5/0x9F
-
-# Giant white louse
-R:69:0xA8/0x9D
-
-# Giant yellow centipede
-R:70:0xA5/0x94
-
-# Black naga
-R:71:0xA9/0x88
-
-# Spotted mushroom patch
-R:72:0x9D/0x88
-
-# Silver jelly
-R:73:0xA8/0x8C
-
-# Scruffy-looking hobbit
-R:74:0xA7/0x93
-
-# Giant white ant
-R:75:0xA5/0x89
-
-# Yellow mold
-R:76:0xA9/0x80
-
-# Metallic red centipede
-R:77:0xA5/0x98
-
-# Yellow worm mass
-R:78:0xAC/0x9F
-
-# Clear worm mass
-R:79:0xAD/0x80
-
-# Radiation eye
-R:80:0xA6/0x9C
-
-# Yellow light
-R:81:0xB8/0x93
-
-# Cave lizard
-R:82:0xA2/0x8A
-
-# Novice ranger
-R:83:0xAA/0x91
-
-# Blue jelly
-R:84:0xA8/0x8E
-
-# Creeping copper coins
-R:85:0x9D/0x80
-
-# Giant white rat
-R:86:0xAC/0x86
-
-# Snotling
-R:87:0xB9/0x89
-
-# Swordfish
-R:88:0xB6/0x9E
-
-# Blue worm mass
-R:89:0xAD/0x81
-
-# Large grey snake
-R:90:0xA2/0x8B
-
-# Skeleton kobold
-R:91:0xAC/0x89
-
-# Ewok
-R:92:0xB0/0x86
-
-# Novice mage
-R:93:0xAA/0x8F
-
-# Green naga
-R:94:0xA9/0x89
-
-# Giant leech
-R:95:0xB8/0x94
-
-# Barracuda
-R:96:0xB6/0x9F
-
-# Novice paladin
-R:97:0xAA/0x92
-
-# Zog
-R:98:0xA1/0x80
-
-# Blue ooze
-R:99:0xA8/0x8F
-
-# Green glutton ghost
-R:100:0x9F/0x9A
-
-# Green jelly
-R:101:0xA8/0x90
-
-# Large kobold
-R:102:0xA8/0x9B
-
-# Grey icky thing
-R:103:0xA8/0x86
-
-# Disenchanter eye
-R:104:0xA6/0x9D
-
-# Red worm mass
-R:105:0xAD/0x82
-
-# Copperhead snake
-R:106:0xA2/0x8C
-
-# Death sword
-R:107:0xB0/0x87
-
-# Purple mushroom patch
-R:108:0x9D/0x89
-
-# Novice priest
-R:109:0xAA/0x8E
-
-# Novice warrior
-R:110:0xAA/0x8C
-
-# Nibelung
-R:111:0xB0/0x88
-
-# The disembodied hand that strangled people
-R:112:0xB0/0x89
-
-# Brown mold
-R:113:0xA9/0x81
-
-# Giant brown bat
-R:114:0xA5/0x90
-
-# Rat-thing
-R:115:0xAC/0x88
-
-# Novice rogue
-R:116:0xAA/0x87
-
-# Creeping silver coins
-R:117:0x9D/0x81
-
-# Snaga
-R:118:0xA9/0x8E
-
-# Rattlesnake
-R:119:0xA2/0x8D
-
-# Giant slug
-R:120:0xB8/0x94
-
-# Giant pink frog
-R:121:0xB8/0x95
-
-# Dark elf
-R:122:0x92/0x94
-
-# Zombified kobold
-R:123:0xAC/0x89
-
-# Crypt creep
-R:124:0xB0/0x8A
-
-# Rotting corpse
-R:125:0xB0/0x8B
-
-# Cave orc
-R:126:0xA9/0x8F
-
-# Wood spider
-R:127:0xA2/0x9E
-
-# Manes
-R:128:0xA0/0x91
-
-# Bloodshot eye
-R:129:0xA6/0x9E
-
-# Red naga
-R:130:0xA9/0x8A
-
-# Red jelly
-R:131:0xA8/0x91
-
-# Green icky thing
-R:132:0xA8/0x87
-
-# Lost soul
-R:133:0x9F/0x9B
-
-# Night lizard
-R:134:0xA2/0x8F
-
-# Mughash, the Kobold Lord
-R:135:0xA8/0x9C
-
-# Skeleton orc
-R:136:0xAC/0x8A
-
-# Wormtongue, Agent of Saruman
-R:137:0xAA/0x98
-
-# Robin Hood, the Outlaw
-R:138:0xB0/0x8C
-
-# Nurgling
-R:139:0xB8/0x97
-
-# Lagduf, the Snaga
-R:140:0xA9/0x90
-
-# Brown yeek
-R:141:0xAD/0x88
-
-# Novice ranger
-R:142:0xAA/0x91
-
-# Giant salamander
-R:143:0xA2/0x90
-
-# Space monster
-R:144:0xB0/0x8D
-
-# Carnivorous flying monkey
-R:145:0xB8/0x98
-
-# Green mold
-R:146:0xA9/0x82
-
-# Novice paladin
-R:147:0xAA/0x92
-
-# Lemure
-R:148:0xA0/0x92
-
-# Hill orc
-R:149:0xA9/0x91
-
-# Bandit
-R:150:0xAA/0x9B
-
-# Hunting hawk
-R:151:0xB0/0x8E
-
-# Phantom warrior
-R:152:0xB0/0x8F
-
-# Gremlin
-R:153:0xB0/0x90
-
-# Yeti
-R:154:0xA4/0x91
-
-# Bloodshot icky thing
-R:155:0xA8/0x88
-
-# Giant grey rat
-R:156:0xAC/0x87
-
-# Black harpy
-R:157:0xA0/0x89
-
-# Skaven
-R:158:0xB8/0x99
-
-# The wounded bear
-R:159:0xBA/0x80
-
-# Cave bear
-R:160:0xC4/0x8F
-
-# Rock mole
-R:161:0xBA/0x82
-
-# Mindcrafter
-R:162:0xAA/0x93
-
-# Baby blue dragon
-R:163:0xA5/0x9D
-
-# Baby white dragon
-R:164:0xA5/0x9E
-
-# Baby green dragon
-R:165:0xA5/0x9F
-
-# Baby black dragon
-R:166:0xA6/0x80
-
-# Baby red dragon
-R:167:0xA6/0x81
-
-# Giant red ant
-R:168:0xA5/0x8D
-
-# Brodda, the Easterling
-R:169:0xAA/0x9C
-
-# Bloodfang, the Wolf
-R:170:0xBA/0x83
-
-# King cobra
-R:171:0xA2/0x91
-
-# Eagle
-R:172:0xB4/0x9E
-
-# War bear
-R:173:0xB0/0x91
-
-# Killer bee
-R:174:0xB0/0x92
-
-# Giant spider
-R:175:0xA2/0x9F
-
-# Giant white tick
-R:176:0xA8/0x9D
-
-# The Borshin
-R:177:0xBA/0x84
-
-# Dark elven mage
-R:178:0xA7/0x96
-
-# Kamikaze yeek
-R:179:0xBA/0x94
-
-# Orfax, Son of Boldor
-R:180:0xAD/0x89
-
-# Servant of Glaaki
-R:181:0xBA/0x85
-
-# Dark elven warrior
-R:182:0xA7/0x97
-
-# Sand-dweller
-R:183:0xBA/0x86
-
-# Clear mushroom patch
-R:184:0xB8/0x96
-
-# Quiver slot
-R:185:0xB0/0x93
-
-# Grishnakh, the Hill Orc
-R:186:0xA9/0x93
-
-# Giant tan bat
-R:187:0xC4/0x90
-
-# Owlbear
-R:188:0xBA/0x87
-
-# Blue horror
-R:189:0xB8/0x9A
-
-# Hairy mold
-R:190:0xA9/0x83
-
-# Grizzly bear
-R:191:0xBA/0x88
-
-# Disenchanter mold
-R:192:0xA9/0x84
-
-# Pseudo dragon
-R:193:0xA6/0x82
-
-# Tengu
-R:194:0xA0/0x93
-
-# Creeping gold coins
-R:195:0x9D/0x82
-
-# Wolf
-R:196:0x9D/0x9E
-
-# Giant fruit fly
-R:197:0x9F/0x91
-
-# Panther
-R:198:0xA7/0x84
-
-# Brigand
-R:199:0xB0/0x94
-
-# Hobbes the Tiger
-R:200:0xB0/0x95
-
-# Shadow Creature of Fiona
-R:201:0xB0/0x96
-
-# Undead mass
-R:202:0xB0/0x97
-
-# Chaos shapechanger
-R:203:0xB0/0x98
-
-# Baby multi-hued dragon
-R:204:0xA6/0x83
-
-# Vorpal bunny
-R:205:0xB4/0x9F
-
-# Old Man Willow
-R:206:0xBA/0x89
-
-# Hippocampus
-R:207:0xBA/0x8A
-
-# Zombified orc
-R:208:0xAC/0x8C
-
-# Hippogriff
-R:209:0xA0/0x8A
-
-# Black mamba
-R:210:0xA2/0x92
-
-# White wolf
-R:211:0x9D/0x9F
-
-# Grape jelly
-R:212:0xA8/0x92
-
-# Nether worm mass
-R:213:0xAD/0x83
-
-# Abyss worm mass
-R:214:0xB0/0x99
-
-# Golfimbul, the Hill Orc Chief
-R:215:0xA9/0x94
-
-# Swordsman
-R:216:0x97/0x81
-
-# Skaven shaman
-R:217:0x9A/0x84
-
-# Baby bronze dragon
-R:218:0xA6/0x82
-
-# Baby gold dragon
-R:219:0xA6/0x82
-
-# Evil eye
-R:220:0xC4/0x91
-
-# Mine-dog
-R:221:0xB9/0x8B
-
-# Hellcat
-R:222:0xB0/0x9A
-
-# Moon beast
-R:223:0xB0/0x9B
-
-# Master yeek
-R:224:0xAD/0x8A
-
-# Priest
-R:225:0xAA/0x9E
-
-# Dark elven priest
-R:226:0xA7/0x99
-
-# Air spirit
-R:227:0x9E/0x9F
-
-# Skeleton human
-R:228:0xAC/0x8B
-
-# Zombified human
-R:229:0xAD/0x8E
-
-# Tiger
-R:230:0xA7/0x85
-
-# Moaning spirit
-R:231:0x9F/0x9C
-
-# Stegocentipede
-R:232:0xA5/0x99
-
-# Spotted jelly
-R:233:0xA8/0x93
-
-# Drider
-R:234:0xA3/0x80
-
-# Mongbat
-R:235:0xB0/0x9C
-
-# Killer brown beetle
-R:236:0xA0/0x9B
-
-# Boldor, King of the Yeeks
-R:237:0xAD/0x8B
-
-# Ogre
-R:238:0xA1/0x8B
-
-# Creeping mithril coins
-R:239:0x9D/0x83
-
-# Illusionist
-R:240:0xAB/0x80
-
-# Druid
-R:241:0xAB/0x81
-
-# Pink horror
-R:242:0xB8/0x9B
-
-# Cloaker
-R:243:0x89/0x88
-
-# Black orc
-R:244:0xA9/0x95
-
-# Ochre jelly
-R:245:0xA8/0x94
-
-# Software bug
-R:246:0xB0/0x9D
-
-# Lurker
-R:247:0x80/0x81
-
-# Tangleweed
-R:248:0xC4/0x92
-
-# Vlasta
-R:249:0xA5/0x84
-
-# Giant white dragon fly
-R:250:0x9F/0x93
-
-# Snaga sapper
-R:251:0xB9/0x8C
-
-# Blue icky thing
-R:252:0xA8/0x89
-
-# Gibbering mouther
-R:253:0xB0/0x9E
-
-# Wolfhound of Flora
-R:254:0xB0/0x9F
-
-# Hill giant
-R:255:0xA1/0x91
-
-# Flesh golem
-R:256:0xA7/0x89
-
-# Warg
-R:257:0x9E/0x80
-
-# Cheerful leprechaun
-R:258:0xB1/0x80
-
-# Giant flea
-R:259:0x9F/0x92
-
-# Ufthak of Cirith Ungol
-R:260:0xBA/0x8C
-
-# Clay golem
-R:261:0xB8/0x9D
-
-# Black ogre
-R:262:0xA1/0x8C
-
-# Dweller on the threshold
-R:263:0xB9/0x8D
-
-# Half-orc
-R:264:0xBA/0x8D
-
-# Dark naga
-R:265:0xB8/0x9E
-
-# Poison ivy
-R:266:0xC4/0x93
-
-# Magic mushroom patch
-R:267:0x9D/0x8B
-
-# Plaguebearer of Nurgle
-R:268:0xAD/0x8D
-
-# Guardian naga
-R:269:0xA9/0x8B
-
-# Wererat
-R:270:0xBA/0x8E
-
-# Light hound
-R:271:0xA4/0x93
-
-# Dark hound
-R:272:0xA4/0x94
-
-# Flying skull
-R:273:0xB1/0x81
-
-# Mi-Go
-R:274:0xB1/0x82
-
-# Giant tarantula
-R:275:0xA3/0x81
-
-# Giant clear centipede
-R:276:0xA5/0x9A
-
-# Mirkwood spider
-R:277:0xA3/0x82
-
-# Frost giant
-R:278:0xA1/0x92
-
-# Griffon
-R:279:0xA0/0x8B
-
-# Homunculus
-R:280:0xA0/0x94
-
-# Gnome mage
-R:281:0xA7/0x98
-
-# Clear hound
-R:282:0xA4/0x95
-
-# Umber hulk
-R:283:0xA3/0x99
-
-# Rust monster
-R:284:0xB9/0x8F
-
-# Ogrillon
-R:285:0xA9/0x98
-
-# Gelatinous cube
-R:286:0xA8/0x95
-
-# Giant green dragon fly
-R:287:0x9F/0x94
-
-# Fire giant
-R:288:0xA1/0x93
-
-# Hummerhorn
-R:289:0xBA/0x8F
-
-# Lizard man
-R:290:0xB9/0x90
-
-# Ulfast, Son of Ulfang
-R:291:0xAB/0x82
-
-# Crebain
-R:292:0xC4/0x94
-
-# Berserker
-R:293:0xA9/0x97
-
-# Quasit
-R:294:0xA0/0x95
-
-# Sphinx
-R:295:0xB9/0x91
-
-# Imp
-R:296:0xA0/0x96
-
-# Forest troll
-R:297:0xA3/0x89
-
-# Freezing sphere
-R:298:0xBA/0x91
-
-# Jumping fireball
-R:299:0xB9/0x92
-
-# Ball lightning
-R:300:0xBA/0x92
-
-# 2-headed hydra
-R:301:0xA2/0x93
-
-# Swamp thing
-R:302:0xB9/0x93
-
-# Water spirit
-R:303:0x9F/0x80
-
-# Giant red scorpion
-R:304:0xA3/0x83
-
-# Earth spirit
-R:305:0x9F/0x81
-
-# Fire spirit
-R:306:0x9F/0x82
-
-# Fire hound
-R:307:0xA4/0x96
-
-# Cold hound
-R:308:0xA4/0x97
-
-# Energy hound
-R:309:0xA4/0x98
-
-# Lesser Mimic
-R:310:0x9D/0x8E
-
-# Door mimic
-R:311:0x82/0x83
-
-# Blink dog
-R:312:0x9E/0x81
-
-# Uruk
-R:313:0xA9/0x99
-
-# Shagrat, the Orc Captain
-R:314:0xA9/0x9A
-
-# Gorbag, the Orc Captain
-R:315:0xA9/0x9B
-
-# Shambling mound
-R:316:0x9D/0x8C
-
-# Giant Venus Flytrap
-R:317:0xC4/0x95
-
-# Chaos beastman
-R:318:0xB9/0x95
-
-# Daemonette of Slaanesh
-R:319:0xB9/0x94
-
-# Giant bronze dragon fly
-R:320:0x9F/0x98
-
-# Stone giant
-R:321:0xA1/0x94
-
-# Giant black dragon fly
-R:322:0x9F/0x96
-
-# Stone golem
-R:323:0xA7/0x8B
-
-# Red mold
-R:324:0xA9/0x85
-
-# Giant gold dragon fly
-R:325:0x9F/0x97
-
-# Stunwall
-R:326:0x80/0x93
-
-# Ghast
-R:327:0xBA/0x95
-
-# Neekerbreeker
-R:328:0xC4/0x96
-
-# Huorn
-R:329:0xBA/0x96
-
-# Bolg, Son of Azog
-R:330:0xA9/0x9C
-
-# Phase spider
-R:331:0xA3/0x84
-
-# Lizard king
-R:332:0xB9/0x97
-
-# Landmine
-R:333:0xBA/0x97
-
-# Wyvern
-R:334:0xB1/0x83
-
-# Great eagle
-R:335:0xB9/0x98
-
-# Livingstone
-R:336:0xB1/0x84
-
-# Earth hound
-R:337:0xA4/0x99
-
-# Air hound
-R:338:0xA4/0x9A
-
-# Sabre-tooth tiger
-R:339:0xA7/0x86
-
-# Acid hound
-R:340:0xA4/0x9B
-
-# Chimaera
-R:341:0xA0/0x8C
-
-# Quylthulg
-R:342:0xA1/0x9A
-
-# Sasquatch
-R:343:0xA4/0x92
-
-# Weir
-R:344:0xB1/0x85
-
-# Ranger
-R:345:0xAA/0x97
-
-# Paladin
-R:346:0xAB/0x92
-
-# Werewolf
-R:347:0xBA/0x99
-
-# Dark elven lord
-R:348:0xA7/0x9C
-
-# Cloud giant
-R:349:0xA1/0x96
-
-# Ugluk, the Uruk
-R:350:0xA9/0x9D
-
-# Blue dragon bat
-R:351:0xA5/0x91
-
-# Mimic
-R:352:0x83/0x9D
-
-# Ultimate Mimic
-R:353:0x84/0x9E
-
-# Fire vortex
-R:354:0xAC/0x94
-
-# Acid vortex
-R:355:0xAC/0x95
-
-# Lugdush, the Uruk
-R:356:0xB9/0x9A
-
-# Arch-vile
-R:357:0xBA/0x9A
-
-# Cold vortex
-R:358:0xAC/0x96
-
-# Energy vortex
-R:359:0xAC/0x97
-
-# Globefish
-R:360:0xB9/0x9B
-
-# Giant firefly
-R:361:0x9F/0x95
-
-# Mummified orc
-R:362:0xA1/0x88
-
-# Wolf chieftain
-R:363:0xC4/0x97
-
-# Serpent man
-R:364:0xBA/0x9C
-
-# Vampiric mist
-R:365:0xB9/0x9D
-
-# Killer stag beetle
-R:366:0xA0/0x9D
-
-# Iron golem
-R:367:0xA7/0x8C
-
-# Auto-roller
-R:368:0xB1/0x86
-
-# Giant yellow scorpion
-R:369:0xA3/0x85
-
-# Jade monk
-R:370:0xBA/0x9D
-
-# Black ooze
-R:371:0xA8/0x96
-
-# Hardened warrior
-R:372:0xAB/0x83
-
-# Azog, King of the Uruk-Hai
-R:373:0xA9/0x9F
-
-# Fleshhound of Khorne
-R:374:0xB9/0x9E
-
-# Dark elven warlock
-R:375:0xB1/0x87
-
-# Master rogue
-R:376:0xAB/0x84
-
-# Red dragon bat
-R:377:0xA5/0x92
-
-# Killer white beetle
-R:378:0xBA/0x9E
-
-# Ice skeleton
-R:379:0xB9/0x9F
-
-# Angamaite of Umbar
-R:380:0xBB/0x80
-
-# Forest wight
-R:381:0xB1/0x88
-
-# Khim, Son of Mim
-R:382:0xB1/0x89
-
-# Ibun, Son of Mim
-R:383:0xB1/0x8A
-
-# Meneldor the Swift
-R:384:0xBB/0x81
-
-# Phantom beast
-R:385:0xB1/0x8B
-
-# Giant silver ant
-R:386:0xA0/0x9C
-
-# 4-headed hydra
-R:387:0xA2/0x95
-
-# Lesser hell-beast
-R:388:0xBB/0x83
-
-# Tyrannosaur
-R:389:0xB1/0x8C
-
-# Mummified human
-R:390:0xA1/0x89
-
-# Vampire bat
-R:391:0xA5/0x93
-
-# Sangahyando of Umbar
-R:392:0xAB/0x85
-
-# It
-R:393:0xB1/0x8D
-
-# Banshee
-R:394:0x9F/0x9D
-
-# Carrion crawler
-R:395:0xA5/0x9B
-
-# Xiclotlan
-R:396:0xBB/0x84
-
-# Silent watcher
-R:397:0xB1/0x8E
-
-# Pukelman
-R:398:0xA7/0x8D
-
-# Disenchanter beast
-R:399:0xBA/0x9F
-
-# Dark elven druid
-R:400:0xA7/0x9F
-
-# Stone troll
-R:401:0xA3/0x8A
-
-# Black
-R:402:0xB0/0x8D
-
-# Hill troll
-R:403:0xA3/0x8B
-
-# Wereworm
-R:404:0xAD/0x84
-
-# Killer red beetle
-R:405:0xA0/0x9F
-
-# Disenchanter bat
-R:406:0xC4/0x98
-
-# Gnoph-Keh
-R:407:0xBB/0x86
-
-# Giant grey ant
-R:408:0xA5/0x8C
-
-# Khufu, the Mummified King
-R:409:0xB1/0x8F
-
-# Gwaihir the Windlord
-R:410:0xBB/0x81
-
-# Giant fire tick
-R:411:0xBB/0x87
-
-# Displacer beast
-R:412:0xA7/0x87
-
-# Ulwarth, Son of Ulfang
-R:413:0xAA/0x99
-
-# Werebear
-R:414:0xC4/0x8F
-
-# Cave ogre
-R:415:0xA1/0x8D
-
-# White wraith
-R:416:0xA3/0x9F
-
-# Angel
-R:417:0x9D/0x8F
-
-# Ghoul
-R:418:0xB4/0x8F
-
-# Mim, Betrayer of Turin
-R:419:0xB1/0x90
-
-# Hellblade
-R:420:0xB1/0x91
-
-# Killer fire beetle
-R:421:0xA1/0x80
-
-# Beast of Nurgle
-R:422:0xBB/0x88
-
-# Creeping adamantite coins
-R:423:0x9D/0x84
-
-# Algroth
-R:424:0xA3/0x8C
-
-# Flamer of Tzeentch
-R:425:0xB8/0x9F
-
-# Roper
-R:426:0xB9/0x80
-
-# Headless
-R:427:0xB1/0x92
-
-# Vibration hound
-R:428:0xA4/0x9C
-
-# Nexus hound
-R:429:0xA4/0x9D
-
-# Half-ogre
-R:430:0xA1/0x8E
-
-# Lokkak, the Ogre Chieftain
-R:431:0xA1/0x90
-
-# Vampire
-R:432:0xA3/0x9A
-
-# Gorgimaera
-R:433:0xA0/0x8D
-
-# Shantak
-R:434:0xB1/0x93
-
-# Colbran
-R:435:0xA7/0x8E
-
-# Spirit naga
-R:436:0xA9/0x8C
-
-# Corpser
-R:437:0xB9/0x81
-
-# Fiend of Slaanesh
-R:438:0xA2/0x97
-
-# Stairway to Hell
-R:439:0xB1/0x94
-
-# 5-headed hydra
-R:440:0xA2/0x96
-
-# Barney the Dinosaur
-R:441:0xB1/0x95
-
-# Black knight
-R:442:0xAB/0x88
-
-# Seahorse
-R:443:0xBB/0x89
-
-# Cyclops
-R:444:0xBB/0x8A
-
-# Clairvoyant
-R:445:0xAB/0x86
-
-# Purple worm
-R:446:0xB9/0x82
-
-# Catoblepas
-R:447:0xAC/0x81
-
-# Lesser wall monster
-R:448:0xB1/0x96
-
-# Mage
-R:449:0xAB/0x8A
-
-# Mind flayer
-R:450:0xAB/0x8B
-
-# The Ultimate Dungeon Cleaner
-R:451:0xB1/0x97
-
-# Deep one
-R:452:0xA4/0x86
-
-# Basilisk
-R:453:0xA2/0x97
-
-# Ice troll
-R:454:0xA3/0x8D
-
-# Dhole
-R:455:0xB1/0x99
-
-# Archangel
-R:456:0x9D/0x90
-
-# Greater Mimic
-R:457:0xAD/0x9E
-
-# Chaos tile
-R:458:0xB1/0x9A
-
-# Young blue dragon
-R:459:0xA6/0x84
-
-# Young white dragon
-R:460:0xA6/0x85
-
-# Young green dragon
-R:461:0xA6/0x86
-
-# Young bronze dragon
-R:462:0xA6/0x87
-
-# Aklash
-R:463:0xC1/0x9E
-
-# Mithril golem
-R:464:0xA7/0x8F
-
-# Skeleton troll
-R:465:0xAC/0x8D
-
-# Skeletal tyrannosaur
-R:466:0xBB/0x8B
-
-# Beorn, the Shape-Changer
-R:467:0xC4/0x99
-
-# Thorondor, Lord of Eagles
-R:468:0xBB/0x81
-
-# Giant blue ant
-R:469:0xA5/0x8B
-
-# Grave wight
-R:470:0xAD/0x9C
-
-# Shadow drake
-R:471:0xA6/0x88
-
-# Manticore
-R:472:0xA0/0x8E
-
-# Giant army ant
-R:473:0xAE/0x81
-
-# Killer slicer beetle
-R:474:0xA1/0x81
-
-# Gorgon
-R:475:0xBB/0x8D
-
-# Gug
-R:476:0xBB/0x8E
-
-# Ghost
-R:477:0x9F/0x9E
-
-# Death watch beetle
-R:478:0xA1/0x82
-
-# Mountain ogre
-R:479:0xA1/0x8F
-
-# Nexus quylthulg
-R:480:0xA1/0x9B
-
-# Shelob, Spider of Darkness
-R:481:0xA3/0x86
-
-# Giant squid
-R:482:0xB9/0x83
-
-# Ghoulking
-R:483:0xAD/0x8C
-
-# Doombat
-R:484:0xB9/0x84
-
-# Ninja
-R:485:0xAB/0x8C
-
-# Memory moss
-R:486:0xA9/0x86
-
-# Storm giant
-R:487:0xA1/0x95
-
-# Spectator
-R:488:0xB1/0x9B
-
-# Bokrug
-R:489:0xBB/0x8F
-
-# Biclops
-R:490:0xBB/0x90
-
-# Half-troll
-R:491:0xA9/0x9E
-
-# Ivory monk
-R:492:0xAA/0x93
-
-# Bert the Stone Troll
-R:493:0xA3/0x90
-
-# Bill the Stone Troll
-R:494:0xA3/0x91
-
-# Tom the Stone Troll
-R:495:0xA3/0x92
-
-# Cave troll
-R:496:0xA3/0x8E
-
-# Anti-paladin
-R:497:0xB1/0x9C
-
-# Chaos master
-R:498:0xB1/0x9D
-
-# Barrow wight
-R:499:0xA4/0x81
-
-# Skeleton ettin
-R:500:0xC4/0x9A
-
-# Chaos drake
-R:501:0xA6/0x89
-
-# Law drake
-R:502:0xA6/0x8A
-
-# Balance drake
-R:503:0xA6/0x8B
-
-# Ethereal drake
-R:504:0xA6/0x8C
-
-# Groo, the Wanderer
-R:505:0xB1/0x9E
-
-# Fasolt the Giant
-R:506:0xB1/0x9F
-
-# Shade
-R:507:0xA4/0x89
-
-# Spectre
-R:508:0xA0/0x80
-
-# Water troll
-R:509:0xA3/0x93
-
-# Fire elemental
-R:510:0x9F/0x83
-
-# Cherub
-R:511:0x9D/0x91
-
-# Water elemental
-R:512:0x9F/0x84
-
-# Multi-hued hound
-R:513:0xB2/0x81
-
-# Invisible stalker
-R:514:0x9F/0x85
-
-# Carrion crawler
-R:515:0xA5/0x9C
-
-# Master thief
-R:516:0xAB/0x8E
-
-# The Watcher in the Water
-R:517:0xAF/0x95
-
-# Lich
-R:518:0xA1/0x83
-
-# Gas spore
-R:519:0xB2/0x8E
-
-# Master vampire
-R:520:0xA3/0x9B
-
-# Oriental vampire
-R:521:0xB2/0x83
-
-# Greater mummy
-R:522:0xA1/0x8A
-
-# Bloodletter of Khorne
-R:523:0xA0/0x98
-
-# Giant grey scorpion
-R:524:0xA3/0x87
-
-# Earth elemental
-R:525:0x9F/0x86
-
-# Air elemental
-R:526:0x9F/0x87
-
-# Shimmering mold
-R:527:0xAF/0x81
-
-# Gargoyle
-R:528:0xBB/0x91
-
-# Malicious leprechaun
-R:529:0xB2/0x85
-
-# Eog golem
-R:530:0xA7/0x90
-
-# Little Boy
-R:531:0xB9/0x85
-
-# Dagashi
-R:532:0xAB/0x90
-
-# Headless ghost
-R:533:0xBB/0x92
-
-# Dread
-R:534:0xB9/0x87
-
-# Leng spider
-R:535:0xBB/0x93
-
-# Gauth
-R:536:0xC4/0x9B
-
-# Smoke elemental
-R:537:0x9F/0x90
-
-# Olog
-R:538:0xA3/0x94
-
-# Halfling slinger
-R:539:0xB2/0x86
-
-# Gravity hound
-R:540:0xA4/0x9E
-
-# Acidic cytoplasm
-R:541:0xA8/0x97
-
-# Inertia hound
-R:542:0xA4/0x9F
-
-# Impact hound
-R:543:0xA5/0x80
-
-# Shardstorm
-R:544:0xC4/0x9C
-
-# Ooze elemental
-R:545:0x9F/0x88
-
-# Young black dragon
-R:546:0xA6/0x8D
-
-# Mumak
-R:547:0xAC/0x84
-
-# Giant fire ant
-R:548:0xA5/0x8A
-
-# Mature white dragon
-R:549:0xA6/0x8E
-
-# Xorn
-R:550:0xA4/0x8F
-
-# Rogrog the Black Troll
-R:551:0xA3/0x8F
-
-# Mist giant
-R:552:0xA7/0x91
-
-# Phantom
-R:553:0xB2/0x87
-
-# Grey wraith
-R:554:0xA4/0x82
-
-# Revenant
-R:555:0xA4/0x88
-
-# Young multi-hued dragon
-R:556:0xA6/0x8F
-
-# Raal's Tome of Destruction
-R:557:0xB2/0x88
-
-# Colossus
-R:558:0xB2/0x89
-
-# Young gold dragon
-R:559:0xA6/0x90
-
-# Mature blue dragon
-R:560:0xA6/0x91
-
-# Mature green dragon
-R:561:0xA6/0x92
-
-# Mature bronze dragon
-R:562:0xA6/0x93
-
-# Young red dragon
-R:563:0xA6/0x94
-
-# Nightblade
-R:564:0xB2/0x8A
-
-# Trapper
-R:565:0xAD/0x9F
-
-# Bodak
-R:566:0xA0/0x98
-
-# Time bomb
-R:567:0xBB/0x96
-
-# Mezzodaemon
-R:568:0xAD/0x90
-
-# Elder thing
-R:569:0xB2/0x8B
-
-# Ice elemental
-R:570:0x9F/0x8A
-
-# Necromancer
-R:571:0xB2/0x8C
-
-# The Greater hell magic mushroom were-quylthulg
-R:572:0xB9/0x86
-
-# Lorgan, Chief of the Easterlings
-R:573:0xB2/0x8D
-
-# Chaos spawn
-R:574:0xB2/0x8E
-
-# Mummified troll
-R:575:0xBB/0x97
-
-# Storm of Unmagic
-R:576:0xC4/0x9D
-
-# Crypt thing
-R:577:0xA4/0x80
-
-# Chaos butterfly
-R:578:0xBB/0x98
-
-# Time elemental
-R:579:0xB2/0x8F
-
-# Flying polyp
-R:580:0xBB/0x99
-
-# The Queen Ant
-R:581:0xA5/0x8E
-
-# Will o' the wisp
-R:582:0x9F/0x8B
-
-# Shan
-R:583:0xBB/0x9A
-
-# Magma elemental
-R:584:0x9F/0x8C
-
-# Black pudding
-R:585:0xA8/0x98
-
-# Killer iridescent beetle
-R:586:0xB4/0x90
-
-# Nexus vortex
-R:587:0xAE/0x80
-
-# Plasma vortex
-R:588:0xAC/0x98
-
-# Mature red dragon
-R:589:0xA6/0x95
-
-# Mature gold dragon
-R:590:0xA6/0x96
-
-# Crystal drake
-R:591:0xA6/0x97
-
-# Mature black dragon
-R:592:0xA6/0x98
-
-# Mature multi-hued dragon
-R:593:0xA6/0x99
-
-# Sky whale
-R:594:0xBB/0x9B
-
-# Draebor, the Imp
-R:595:0xC1/0x9F
-
-# Mother Hydra
-R:596:0xA2/0x98
-
-# Death knight
-R:597:0xAB/0x94
-
-# Castamir the Usurper
-R:598:0xB2/0x90
-
-# Time vortex
-R:599:0xAC/0x99
-
-# Shimmering vortex
-R:600:0xAC/0x9A
-
-# Ancient blue dragon
-R:601:0x9E/0x88
-
-# Ancient bronze dragon
-R:602:0x9E/0x89
-
-# Beholder
-R:603:0xA6/0x9F
-
-# Emperor wight
-R:604:0xA4/0x83
-
-# Seraph
-R:605:0x9D/0x92
-
-# Vargo, Tyrant of Fire
-R:606:0x9F/0x8D
-
-# Black wraith
-R:607:0xA4/0x84
-
-# Nightgaunt
-R:608:0xB2/0x91
-
-# Baron of hell
-R:609:0xB2/0x92
-
-# Scylla
-R:610:0xBB/0x9C
-
-# Monastic lich
-R:611:0xA1/0x87
-
-# Nether wraith
-R:612:0xA4/0x85
-
-# Hellhound
-R:613:0xAD/0x96
-
-# 7-headed hydra
-R:614:0xA2/0x99
-
-# Waldern, King of Water
-R:615:0x9F/0x8E
-
-# Kavlax the Many-Headed
-R:616:0xA6/0x9A
-
-# Ancient white dragon
-R:617:0x9E/0x8A
-
-# Ancient green dragon
-R:618:0x9E/0x8B
-
-# Chthonian
-R:619:0xB2/0x93
-
-# Eldrak
-R:620:0xA3/0x97
-
-# Ettin
-R:621:0xA3/0x96
-
-# Night mare
-R:622:0xAC/0x83
-
-# Vampire lord
-R:623:0xA3/0x9C
-
-# Ancient black dragon
-R:624:0x9E/0x8C
-
-# Weird fume
-R:625:0xAF/0x80
-
-# Spawn of Ubbo-Sathla
-R:626:0xBB/0x9D
-
-# Fat Man
-R:627:0xB9/0x85
-
-# Malekith the Accursed
-R:628:0xA7/0x95
-
-# Shadowfax, steed of Gandalf
-R:629:0xBB/0x9E
-
-# Spirit troll
-R:630:0xA3/0x98
-
-# War troll
-R:631:0xB2/0x94
-
-# Disenchanter worm mass
-R:632:0xAD/0x86
-
-# Rotting quylthulg
-R:633:0xA1/0x9C
-
-# Lesser titan
-R:634:0xA1/0x97
-
-# 9-headed hydra
-R:635:0xA2/0x99
-
-# Enchantress
-R:636:0xAB/0x96
-
-# Ranger chieftain
-R:637:0xAB/0x97
-
-# Sorcerer
-R:638:0xAB/0x98
-
-# Xaren
-R:639:0xA4/0x90
-
-# Giant roc
-R:640:0x9D/0x97
-
-# Minotaur
-R:641:0xA0/0x8F
-
-# Medusa, the Gorgon
-R:642:0xA9/0x8D
-
-# Death drake
-R:643:0x9E/0x8D
-
-# Ancient red dragon
-R:644:0x9E/0x8E
-
-# Ancient gold dragon
-R:645:0x9E/0x8F
-
-# Great crystal drake
-R:646:0x9E/0x90
-
-# Wyrd sister
-R:647:0xA7/0x9D
-
-# Vrock
-R:648:0xB2/0x95
-
-# Death quasit
-R:649:0xA0/0x99
-
-# Giganto, the Gargantuan
-R:650:0xBB/0x9F
-
-# Strygalldwir
-R:651:0xB2/0x96
-
-# Fallen angel
-R:652:0xAA/0x8E
-
-# Giant headless
-R:653:0xBC/0x80
-
-# Judge Fire
-R:654:0xAB/0x93
-
-# Ubbo-Sathla, the Unbegotten Source
-R:655:0xBC/0x81
-
-# Judge Mortis
-R:656:0xBC/0x82
-
-# Dark elven sorcerer
-R:657:0xA8/0x81
-
-# Master lich
-R:658:0xA1/0x84
-
-# Byakhee
-R:659:0xB2/0x97
-
-# Eol, the Dark Elf
-R:660:0xB2/0x99
-
-# Archon
-R:661:0x9D/0x93
-
-# Formless spawn of Tsathoggua
-R:662:0xB2/0x9A
-
-# Hunting horror
-R:663:0xB2/0x9B
-
-# Undead beholder
-R:664:0xA7/0x80
-
-# Shadow
-R:665:0xA0/0x81
-
-# Iron lich
-R:666:0xB2/0x9C
-
-# Dread
-R:667:0xB9/0x87
-
-# Greater basilisk
-R:668:0xBC/0x83
-
-# Charybdis
-R:669:0xBC/0x84
-
-# Jack of Shadows
-R:670:0xAB/0x9C
-
-# Zephyr Lord
-R:671:0xAB/0x91
-
-# Juggernaut of Khorne
-R:672:0xBC/0x85
-
-# Mumak
-R:673:0xAC/0x82
-
-# Judge Fear
-R:674:0xA7/0x88
-
-# Ancient multi-hued dragon
-R:675:0x9E/0x91
-
-# Ethereal dragon
-R:676:0x9E/0x92
-
-# Dark young of Shub-Niggurath
-R:677:0xB2/0x9D
-
-# Colour out of space
-R:678:0x91/0x99
-
-# Quaker, Master of Earth
-R:679:0x9F/0x8F
-
-# Death leprechaun
-R:680:0xA7/0x9E
-
-# Chaugnar Faugn, Horror from the Hills
-R:681:0xBC/0x94
-
-# Lloigor
-R:682:0xBC/0x95
-
-# Utgard-Loke
-R:683:0xBC/0x96
-
-# Quachil Uttaus, Treader of the Dust
-R:684:0xBC/0x97
-
-# Shoggoth
-R:685:0xBC/0x98
-
-# Judge Death
-R:686:0xBC/0x99
-
-# Ariel, Queen of Air
-R:687:0x9F/0x91
-
-# 11-headed hydra
-R:688:0xA2/0x9A
-
-# Patriarch
-R:689:0xAB/0x9A
-
-# Dreadmaster
-R:690:0xA0/0x85
-
-# Drolem
-R:691:0xA7/0x92
-
-# Scatha the Worm
-R:692:0xAD/0x9B
-
-# Warrior of the Dawn
-R:693:0xB2/0x9E
-
-# Lesser black reaver
-R:694:0xA4/0x87
-
-# Zoth-Ommog
-R:695:0xBE/0x89
-
-# Grand master thief
-R:696:0xC2/0x8A
-
-# Smaug the Golden
-R:697:0x9E/0x93
-
-# The Stormbringer
-R:698:0xB3/0x80
-
-# Knight Templar
-R:699:0xB3/0x81
-
-# Leprechaun fanatic
-R:700:0xA8/0x80
-
-# Dracolich
-R:701:0x9E/0x95
-
-# Greater titan
-R:702:0xA1/0x98
-
-# Dracolisk
-R:703:0x9E/0x94
-
-# Winged Horror
-R:704:0xC4/0x9E
-
-# Spectral tyrannosaur
-R:705:0xB3/0x82
-
-# Yibb-Tstll, the Patient One
-R:706:0xBC/0x9B
-
-# Ghatanothoa
-R:707:0xBC/0x9C
-
-# Ent
-R:708:0xBC/0x86
-
-# Hru
-R:709:0xBC/0x9D
-
-# Itangast the Fire Drake
-R:710:0x9E/0x96
-
-# Death mold
-R:711:0xA9/0x87
-
-# Fafner the Dragon
-R:712:0xB3/0x83
-
-# Charon, Boatman of the Styx
-R:713:0xBC/0x9E
-
-# Quickbeam, the Ent
-R:714:0xBC/0x9F
-
-# Glaurung, Father of the Dragons
-R:715:0xAD/0x9A
-
-# Behemoth
-R:716:0xBD/0x80
-
-# Garm, Guardian of Hel
-R:717:0x9E/0x84
-
-# Greater wall monster
-R:718:0xB3/0x84
-
-# Nycadaemon
-R:719:0xAD/0x91
-
-# Barbazu
-R:720:0xAD/0x95
-
-# Goat of Mendes
-R:721:0xB3/0x85
-
-# Nightwing
-R:722:0xAD/0x9D
-
-# Maulotaur
-R:723:0xB3/0x86
-
-# Nether hound
-R:724:0xA5/0x81
-
-# Time hound
-R:725:0xA5/0x82
-
-# Plasma hound
-R:726:0xA5/0x83
-
-# Demonic quylthulg
-R:727:0xA1/0x9D
-
-# Great Storm Wyrm
-R:728:0x9E/0x97
-
-# Ulik the Troll
-R:729:0xBD/0x81
-
-# Baphomet the Minotaur Lord
-R:730:0xA0/0x90
-
-# Hell knight
-R:731:0xBD/0x82
-
-# Bull Gates
-R:732:0xB3/0x87
-
-# Santa Claus
-R:733:0xB3/0x88
-
-# Eihort, the Thing in the Labyrinth
-R:734:0xBE/0x8A
-
-# The King in Yellow
-R:735:0xBE/0x8B
-
-# Great unclean one
-R:736:0xBE/0x8C
-
-# Lord of Chaos
-R:737:0xB3/0x89
-
-# Old Sorcerer
-R:738:0x9C/0x8A
-
-# Ethereal hound
-R:739:0xB3/0x8A
-
-# Lesser kraken
-R:740:0xBD/0x83
-
-# Great Ice Wyrm
-R:741:0x9E/0x98
-
-# Demilich
-R:742:0xA4/0x8A
-
-# The Phoenix
-R:743:0x9D/0x98
-
-# Nightcrawler
-R:744:0xA4/0x8C
-
-# Lord of Change
-R:745:0xBC/0x87
-
-# Keeper of Secrets
-R:746:0xBE/0x8D
-
-# Shudde M'ell
-R:747:0xBE/0x8E
-
-# Hand druj
-R:748:0xAC/0x8E
-
-# Eye druj
-R:749:0xAC/0x8F
-
-# Skull druj
-R:750:0xAC/0x90
-
-# Chaos vortex
-R:751:0xAC/0x9B
-
-# Aether vortex
-R:752:0xAC/0x9C
-
-# Nidhogg, the Hel-Drake
-R:753:0xBE/0x8F
-
-# The Lernaean Hydra
-R:754:0xA2/0x9B
-
-# Thuringwethil, the Vampire Messenger
-R:755:0xA3/0x9D
-
-# Great Hell Wyrm
-R:756:0x9E/0x99
-
-# Hastur the Unspeakable
-R:757:0xB3/0x8B
-
-# Bloodthirster
-R:758:0xBD/0x84
-
-# Draconic quylthulg
-R:759:0xA1/0x9E
-
-# Nyogtha, the Thing that Should not Be
-R:760:0xB3/0x8C
-
-# Ahtu, Avatar of Nyarlathotep
-R:761:0xBE/0x90
-
-# Fundin Bluecloak
-R:762:0xBE/0x91
-
-# Bile Demon
-R:763:0xC5/0x80
-
-# Uriel, Angel of Fire
-R:764:0x9D/0x94
-
-# Azriel, Angel of Death
-R:765:0x9D/0x95
-
-# Ancalagon the Black
-R:766:0x9E/0x9A
-
-# Daoloth, the Render of the Veils
-R:767:0xBE/0x92
-
-# Nightwalker
-R:768:0xBD/0x85
-
-# Gabriel, the Messenger
-R:769:0x9D/0x96
-
-# Artsi, the Champion of Chaos
-R:770:0xBE/0x93
-
-# Saruman of Many Colours
-R:771:0xAB/0x9E
-
-# Harowen the Black Hand
-R:772:0xBE/0x94
-
-# Osyluth
-R:773:0xC5/0x81
-
-# Dreadlord
-R:774:0xA0/0x86
-
-# Greater kraken
-R:775:0xBD/0x86
-
-# Archlich
-R:776:0xA4/0x8D
-
-# The Cat Lord
-R:777:0xB3/0x8F
-
-# Jabberwock
-R:778:0xC5/0x82
-
-# Chaos hound
-R:779:0xA5/0x85
-
-# Vlad Dracula, Prince of Darkness
-R:780:0xBE/0x95
-
-# Beholder hive-mother
-R:781:0xBE/0x96
-
-# Leviathan
-R:782:0xBD/0x87
-
-# Great Wyrm of Chaos
-R:783:0x9E/0x9B
-
-# Great Wyrm of Law
-R:784:0x9E/0x9C
-
-# Great Wyrm of Balance
-R:785:0x9E/0x9D
-
-# Shambler
-R:786:0xB3/0x91
-
-# Gelugon
-R:787:0xC5/0x83
-
-# Glaaki
-R:788:0xB9/0x88
-
-# T'ron, the Rebel Dragonrider
-R:789:0xB3/0x92
-
-# Great Wyrm of Many Colours
-R:790:0xB3/0x93
-
-# Mardra, rider of the Gold Loranth
-R:791:0xB3/0x94
-
-# Tselakus, the Dreadlord
-R:792:0xA0/0x87
-
-# Sky Drake
-R:793:0xB3/0x95
-
-# Eilinel the Entrapped
-R:794:0xA0/0x83
-
-# Horned Reaper
-R:795:0xC5/0x84
-
-# The Norsa
-R:796:0xB3/0x97
-
-# Rhan-Tegoth
-R:797:0xBE/0x99
-
-# Black reaver
-R:798:0xA1/0x85
-
-# Master mindcrafter
-R:799:0xAB/0x9F
-
-# Greater demonic quylthulg
-R:800:0xA1/0x9F
-
-# Greater draconic quylthulg
-R:801:0xA2/0x80
-
-# Greater rotting quylthulg
-R:802:0xA2/0x81
-
-# Null, the Living Void
-R:803:0xBC/0x88
-
-# Feagwath, the Undead Sorcerer
-R:804:0xA1/0x86
-
-# Omarax the Eye Tyrant
-R:805:0xA7/0x81
-
-# Tsathoggua, the Sleeper of N'kai
-R:806:0xBE/0x9A
-
-# Greater Balrog
-R:807:0xAD/0x93
-
-# Ungoliant, the Unlight
-R:808:0xA3/0x88
-
-# Atlach-Nacha, the Spider God
-R:809:0xB3/0x9A
-
-# Y'golonac
-R:810:0xBE/0x9B
-
-# Aether hound
-R:811:0xA5/0x86
-
-# Pit Fiend
-R:812:0xAD/0x92
-
-# The Serpent of Chaos
-R:813:0xB4/0x8D
-
-# Yig, Father of Serpents
-R:814:0xBE/0x9C
-
-# Unmaker
-R:815:0xB3/0x9C
-
-# Cyberdemon
-R:816:0xB3/0x9D
-
-# Hela, Queen of the Dead
-R:817:0xBE/0x9D
-
-# The Mouth of Sauron
-R:818:0xBE/0x9E
-
-# The Necromancer of Dol Guldur
-R:819:0xB3/0x9E
-
-# Lessa, rider of the Gold Ramoth
-R:820:0xB3/0x9F
-
-# Master quylthulg
-R:821:0xA2/0x82
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0xA2/0x83
-
-# Cthugha, the Living Flame
-R:823:0xBE/0x9F
-
-# F'lar, rider of the Bronze Mnementh
-R:824:0xB4/0x80
-
-# Maeglin, the Traitor of Gondolin
-R:825:0xA4/0x8E
-
-# Cyaegha
-R:826:0xBF/0x80
-
-# Pazuzu, Lord of Air
-R:827:0xBF/0x81
-
-# Ithaqua the Windwalker
-R:828:0xB4/0x81
-
-# Greater Hellhound
-R:829:0x9E/0x83
-
-# Cantoras, the Skeletal Lord
-R:830:0xAC/0x91
-
-# Mephistopheles, Lord of Hell
-R:831:0xB4/0x82
-
-# Godzilla
-R:832:0xB4/0x83
-
-# Abhoth, Source of Uncleanness
-R:833:0xBF/0x82
-
-# Ymir, the Ice Giant
-R:834:0xBF/0x83
-
-# Loki, the Trickster
-R:835:0xBF/0x84
-
-# Star-spawn of Cthulhu
-R:836:0xB4/0x84
-
-# Surtur, the Fire Giant
-R:837:0xBF/0x85
-
-# The Tarrasque
-R:838:0xBC/0x93
-
-# Lungorthin, the Balrog of White Fire
-R:839:0xBF/0x86
-
-# Draugluin, Sire of All Werewolves
-R:840:0xBF/0x87
-
-# Shuma-Gorath
-R:841:0xBF/0x88
-
-# Tulzscha, the Green Flame
-R:842:0xBC/0x92
-
-# Oremorj, the Cyberdemon Lord
-R:843:0xBC/0x91
-
-# Vecna, the Emperor Lich
-R:844:0xB4/0x85
-
-# Yog-Sothoth, the All-in-One
-R:845:0xB4/0x86
-
-# Fenris Wolf
-R:846:0xBC/0x90
-
-# Great Wyrm of Power
-R:847:0xB4/0x87
-
-# Shub-Niggurath, Black Goat of the Woods
-R:848:0xB4/0x88
-
-# Nodens, Lord of the Great Abyss
-R:849:0xAB/0x8D
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x9E/0x86
-
-# Nyarlathotep, the Crawling Chaos
-R:851:0xB4/0x89
-
-# Azathoth, the Daemon Sultan
-R:852:0xB4/0x8A
-
-# Huan, Wolfhound of the Valar
-R:853:0x9E/0x87
-
-# Jormungand the Midgard Serpent
-R:854:0xBC/0x8F
-
-# The Destroyer
-R:855:0xBC/0x8E
-
-# Gothmog, the High Captain of Balrogs
-R:856:0xAD/0x98
-
-# Great Cthulhu
-R:857:0xB4/0x8B
-
-# Sorka, rider of the Gold Faranth
-R:858:0xB4/0x8C
-
-# The Unicorn of Order
-R:859:0xBC/0x8D
-
-# Sauron, the Sorcerer
-R:860:0xAC/0x80
-
-# DarkGod, the Mighty Coder of Hell
-R:861:0xC0/0x9D
-
-# Morgoth, Lord of Darkness
-R:862:0xB4/0x8E
-
-# Human Warrior
-R:863:0xB5/0x80
-
-# Elven archer
-R:864:0xB5/0x81
-
-# Dwarven warrior
-R:865:0xB5/0x82
-
-# Elite uruk
-R:866:0xB5/0x83
-
-# The Philosophy Teacher
-R:867:0xBC/0x8C
-
-# The Variant Maintainer
-R:868:0xBC/0x8B
-
-# Random Number Generator
-R:869:0xBC/0x8A
-
-# Rocket mine
-R:870:0xBD/0x88
-
-# Bouncing mine
-R:871:0xBD/0x89
-
-# Durin's Bane
-R:872:0xBF/0x89
-
-# The Icky Queen
-R:873:0xBF/0x8A
-
-# Rot jelly
-R:874:0xBD/0x8A
-
-# Death
-R:875:0xBD/0x8B
-
-# Famine
-R:876:0xBD/0x8D
-
-# Pestilence
-R:877:0xBD/0x8C
-
-# War
-R:878:0xBD/0x8E
-
-# Pike
-R:879:0xBD/0x8F
-
-# Electric eel
-R:880:0xBD/0x90
-
-# Giant crayfish
-R:881:0xBD/0x91
-
-# Mermaid
-R:882:0xBD/0x92
-
-# Box jellyfish
-R:883:0xBA/0x81
-
-# Giant piranha
-R:884:0xB6/0x9D
-
-# Piranha
-R:885:0xB6/0x9D
-
-# Bullywug
-R:886:0xBD/0x94
-
-# Bullywug warrior
-R:887:0xBD/0x95
-
-# Bullywug shaman
-R:888:0xBD/0x96
-
-# Whale
-R:889:0xBA/0x98
-
-# Sand mite
-R:890:0xBD/0x98
-
-# Octopus
-R:891:0xBD/0x99
-
-# Giant octopus
-R:892:0xBD/0x9A
-
-# Eye of the deep
-R:893:0xBD/0x9B
-
-# Murk dweller
-R:894:0xBF/0x8B
-
-# Drowned soul
-R:895:0xBF/0x8C
-
-# Tiger shark
-R:896:0xBF/0x8D
-
-# Hammerhead shark
-R:897:0xBA/0x90
-
-# Great white shark
-R:898:0xBB/0x82
-
-# Aquatic golem
-R:899:0xBF/0x8E
-
-# Aquatic kobold
-R:900:0xBF/0x8F
-
-# White shark
-R:901:0xBB/0x82
-
-# Scrag
-R:902:0xBF/0x91
-
-# Jaws
-R:903:0xBB/0x8C
-
-# Aquatic elf
-R:904:0xBF/0x93
-
-# Aquatic elven warrior
-R:905:0xBF/0x94
-
-# Aquatic elven shaman
-R:906:0xBF/0x95
-
-# Stargazer
-R:907:0xBF/0x96
-
-# Elder stargazer
-R:908:0xBF/0x97
-
-# Flounder
-R:909:0xBF/0x98
-
-# Giant turtle
-R:910:0xBF/0x99
-
-# Baby dragon turtle
-R:911:0xBF/0x9A
-
-# Young dragon turtle
-R:912:0xBF/0x9B
-
-# Mature dragon turtle
-R:913:0xBF/0x9C
-
-# Ancient dragon turtle
-R:914:0xBF/0x9D
-
-# Fastitocalon
-R:915:0xBF/0x9E
-
-# Undead stargazer
-R:916:0xBF/0x9F
-
-# Killer whale
-R:917:0xB9/0x9C
-
-# Merrow
-R:918:0xC5/0x85
-
-# Water naga
-R:919:0xC0/0x81
-
-# Devilfish
-R:920:0xC0/0x82
-
-# Undead devilfish
-R:921:0xC0/0x83
-
-# Moby Dick, the White Whale
-R:922:0xC0/0x80
-
-# Aquatic hound
-R:923:0xC0/0x85
-
-# Water demon
-R:924:0xC0/0x86
-
-# Ixitxachitl
-R:925:0xB8/0x9C
-
-# Ixitxachitl priest
-R:926:0xC0/0x88
-
-# Vampiric ixitxachitl
-R:927:0xC0/0x89
-
-# Mathilde, the Science Student
-R:928:0xBD/0x9C
-
-# Child spirit
-R:929:0xBD/0x9D
-
-# Young spirit
-R:930:0xBD/0x9E
-
-# Mature spirit
-R:931:0xBD/0x9F
-
-# Experienced spirit
-R:932:0xBE/0x80
-
-# Wise spirit
-R:933:0xBE/0x81
-
-# Fangorn the Treebeard, Lord of the Ents
-R:934:0xC0/0x8A
-
-# Gandalf the Grey
-R:935:0xC0/0x8B
-
-# Nar, the Dwarf
-R:936:0xC0/0x8C
-
-# Novice mindcrafter
-R:937:0xAA/0x9A
-
-# Great Swamp Wyrm
-R:938:0xC5/0x86
-
-# Great Bile Wyrm
-R:939:0xC5/0x87
-
-# Blue Firelizard
-R:940:0xBE/0x82
-
-# Green Firelizard
-R:941:0xBE/0x83
-
-# Brown Firelizard
-R:942:0xBE/0x84
-
-# Bronze Firelizard
-R:943:0xBE/0x85
-
-# Gold Firelizard
-R:944:0xBE/0x86
-
-# High-elven ranger
-R:945:0xBE/0x87
-
-# Uvatha the Horseman
-R:946:0xC0/0x90
-
-# Adunaphel the Quiet
-R:947:0xC0/0x91
-
-# Akhorahil the Blind
-R:948:0xC0/0x92
-
-# Ren the Unclean
-R:949:0xC0/0x93
-
-# Ji Indur Dawndeath
-R:950:0xC0/0x94
-
-# Dwar, Dog Lord of Waw
-R:951:0xC0/0x95
-
-# Hoarmurath of Dir
-R:952:0xC0/0x96
-
-# Khamul, the Black Easterling
-R:953:0xC0/0x97
-
-# The Witch-King of Angmar
-R:954:0xC0/0x98
-
-# Green Dragonrider
-R:955:0xB3/0x96
-
-# Blue Dragonrider
-R:956:0xB3/0x8E
-
-# Brown Dragonrider
-R:957:0xB3/0x98
-
-# Bronze Dragonrider
-R:958:0xB3/0x98
-
-# Gold Dragonrider
-R:959:0xB3/0x94
-
-# Thread
-R:960:0xBE/0x88
-
-# Gorlim, Betrayer of Barahir
-R:961:0xC0/0x99
-
-# The Blubbering idiot, agent of black market, Simon the weak
-R:962:0xAA/0x82
-
-# Aranea
-R:963:0xC1/0x9A
-
-# Elder aranea
-R:964:0xC0/0x9A
-
-# Giant brown tick
-R:965:0xC5/0x88
-
-# Dolphiner
-R:966:0xC0/0x9C
-
-# Novice possessor (soul)
-R:967:0xC4/0x86
-
-# Bat of Gorgoroth
-R:968:0xC5/0x97
-
-# The Princess
-R:969:0xC5/0x98
-
-# Merton Proudfoot, the lost hobbit
-R:970:0xC5/0x99
-
-# The Wight-King of the Barrow-downs
-R:971:0xC5/0x9A
-
-# Adventurer
-R:972:0xC5/0x9B
-
-# Experienced possessor (soul)
-R:973:0xC5/0x9C
-
-# Old possessor (soul)
-R:974:0xC5/0x9D
-
-# Death orb
-R:975:0xC5/0x9E
-
-# Bronze dragon worm
-R:976:0xC6/0x80
-
-# Gold dragon worm
-R:977:0xC5/0x9F
-
-# Moldoux, the Defenceless Mold
-R:978:0xBC/0x89
-
-# The Physics Teacher
-R:979:0xBE/0x97
-
-# Ar-Pharazon the Golden
-R:980:0xC0/0x9E
-
-# Doppelganger
-R:981:0x97/0x8C
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0xC1/0x8D
-
-# The Greater Lag Monster
-R:983:0xC2/0x8D
-
-# Hrungnir, the Stone Giant
-R:984:0xA7/0x8A
-
-# Bullroarer the Hobbit
-R:985:0xA7/0x9B
-
-# 3-headed hydra
-R:986:0xA2/0x94
-
-# Uldor the Accursed
-R:987:0xAB/0x95
-
-# Mystic
-R:988:0xAB/0x9B
-
-# Elder vampire
-R:989:0xA1/0x99
-
-# Ulfang the Black
-R:990:0xAA/0x96
-
-# Demonologist
-R:991:0xA8/0x82
-
-# Hezrou
-R:992:0xA2/0x9C
-
-# Glabrezu
-R:993:0xA2/0x8E
-
-# Nalfeshnee
-R:994:0xC2/0x8E
-
-# Marilith
-R:995:0xC2/0x8F
-
-# Lesser Balrog
-R:996:0xAD/0x95
-
-# Master mystic
-R:997:0xAA/0x94
-
-# Grand master mystic
-R:998:0xAB/0x9D
-
-# Erinyes
-R:999:0xA0/0x84
-
-# Novice mindcrafter
-R:1000:0xAA/0x9A
-
-# Polyphemus, the Blind Cyclops
-R:1001:0xC5/0x89
-
-# Great Wyrm of Perplexity
-R:1002:0xC2/0x92
-
-# Hound of Tindalos
-R:1003:0xC2/0x93
-
-# Great Wyrm of Thunder
-R:1004:0xC5/0x8A
-
-# Silver mouse
-R:1005:0xC5/0x8B
-
-# The Rat King
-R:1006:0xC2/0x96
-
-# Vort the Kobold Queen
-R:1007:0xC2/0x97
-
-# Giant black louse
-R:1008:0xC2/0x98
-
-# Fire Phantom
-R:1009:0xC2/0x99
-
-# The Insane Player
-R:1010:0x92/0x81
-
-# Glaryssa, Succubus Queen
-R:1011:0xC2/0x9A
-
-# Vermicious Knid
-R:1012:0xC2/0x9B
-
-# Bone golem
-R:1013:0xC2/0x9C
-
-# Snake of Yig
-R:1014:0xC2/0x9D
-
-# Bronze golem
-R:1015:0xC5/0x8C
-
-# Dimensional shambler
-R:1016:0xC2/0x9F
-
-# Cultist
-R:1017:0x94/0x99
-
-# Cult leader
-R:1018:0x99/0x97
-
-# Servitor of the outer gods
-R:1019:0xC3/0x8A
-
-# Avatar of Nyarlathotep
-R:1020:0xC3/0x8B
-
-# Thiazi, the Storm Giant
-R:1021:0xC5/0x8D
-
-# Hypnos, Lord of Sleep
-R:1022:0xC3/0x8D
-
-# Blue dragon worm
-R:1023:0xC3/0x8E
-
-# White dragon worm
-R:1024:0xC3/0x8F
-
-# Green dragon worm
-R:1025:0xC3/0x92
-
-# Black dragon worm
-R:1026:0xC3/0x91
-
-# Red dragon worm
-R:1027:0xC3/0x90
-
-# Multi-hued dragon worm
-R:1028:0xC3/0x93
-
-# The Minotaur of the Labyrinth
-R:1029:0xC3/0x94
-
-# The Sandworm Queen
-R:1030:0xC3/0x9B
-
-# Sandworm
-R:1031:0xC3/0x9C
-
-# Tik'srvzllat
-R:1032:0xC3/0x9D
-
-# The Glass Golem
-R:1033:0xC5/0x8E
-
-# The White Balrog
-R:1034:0xC5/0x8F
-
-# Golgarach, the Living Rock
-R:1035:0x80/0x84
-
-# Atlas, the Titan
-R:1036:0xC5/0x90
-
-# Kronos, Lord of the Titans
-R:1037:0xC5/0x91
-
-# Water hound
-R:1038:0xC6/0x88
-
-# Improv, the mighty MoLD
-R:1039:0xC6/0x8E
-
-# Emperor Mimic
-R:1040:0xC6/0x9C
-
-# Melinda Proudfoot
-R:1041:0x88/0xAA
-
-# Thrain, the King Under the Mountain
-R:1042:0x88/0xAB
-
-# Spells (*)
-S:48:0x91/0x88
-S:49:0x91/0x89
-S:50:0x91/0x8A
-S:51:0x91/0x8B
-S:52:0x91/0x8C
-S:53:0x91/0x8D
-S:54:0x91/0x8E
-S:55:0x91/0x8F
-S:56:0x91/0x90
-S:57:0x91/0x91
-S:58:0x91/0x92
-S:59:0x91/0x93
-S:60:0x91/0x94
-S:61:0x91/0x95
-S:62:0x91/0x96
-S:63:0x91/0x97
-
-# Spells (|)
-S:64:0x8F/0x80
-S:65:0x8F/0x84
-S:66:0x8F/0x88
-S:67:0x8F/0x8C
-S:68:0x8F/0x90
-S:69:0x8F/0x94
-S:70:0x8F/0x98
-S:71:0x8F/0x9C
-S:72:0x90/0x80
-S:73:0x90/0x84
-S:74:0x90/0x88
-S:75:0x90/0x8C
-S:76:0x90/0x90
-S:77:0x90/0x94
-S:78:0x90/0x98
-S:79:0x90/0x9C
-
-# Spells (-)
-S:80:0x8F/0x81
-S:81:0x8F/0x85
-S:82:0x8F/0x89
-S:83:0x8F/0x8D
-S:84:0x8F/0x91
-S:85:0x8F/0x95
-S:86:0x8F/0x99
-S:87:0x8F/0x9D
-S:88:0x90/0x81
-S:89:0x90/0x85
-S:90:0x90/0x89
-S:91:0x90/0x8D
-S:92:0x90/0x91
-S:93:0x90/0x95
-S:94:0x90/0x99
-S:95:0x90/0x9D
-
-# Spells (/)
-S:96:0x8F/0x82
-S:97:0x8F/0x86
-S:98:0x8F/0x8A
-S:99:0x8F/0x8E
-S:100:0x8F/0x92
-S:101:0x8F/0x96
-S:102:0x8F/0x9A
-S:103:0x8F/0x9E
-S:104:0x90/0x82
-S:105:0x90/0x86
-S:106:0x90/0x8A
-S:107:0x90/0x8E
-S:108:0x90/0x92
-S:109:0x90/0x96
-S:110:0x90/0x9A
-S:111:0x90/0x9E
-
-# Spells (\)
-S:112:0x8F/0x83
-S:113:0x8F/0x87
-S:114:0x8F/0x8B
-S:115:0x8F/0x8F
-S:116:0x8F/0x93
-S:117:0x8F/0x97
-S:118:0x8F/0x9B
-S:119:0x8F/0x9F
-S:120:0x90/0x83
-S:121:0x90/0x87
-S:122:0x90/0x8B
-S:123:0x90/0x8F
-S:124:0x90/0x93
-S:125:0x90/0x97
-S:126:0x90/0x9B
-S:127:0x90/0x9F
-
-# Amulets (")
-S:128:0x87/0x87
-S:129:0x87/0x80
-S:130:0x87/0x88
-S:131:0x87/0x82
-S:132:0x87/0x83
-S:133:0x87/0x84
-S:134:0x87/0x85
-S:135:0x87/0x86
-S:136:0x87/0x81
-S:137:0x87/0x81
-S:138:0x87/0x89
-S:139:0x87/0x8A
-S:140:0x87/0x8B
-S:141:0x87/0x8C
-S:142:0x87/0x8D
-S:143:0x87/0x8E
-
-# Rings (=)
-S:144:0x84/0x87
-S:145:0x84/0x80
-S:146:0x84/0x88
-S:147:0x84/0x82
-S:148:0x84/0x83
-S:149:0x84/0x84
-S:150:0x84/0x85
-S:151:0x84/0x86
-S:152:0x84/0x81
-S:153:0x84/0x81
-S:154:0x84/0x89
-S:155:0x84/0x8A
-S:156:0x84/0x8B
-S:157:0x84/0x8C
-S:158:0x84/0x8D
-S:159:0x84/0x8E
-
-# Staffs (_)
-S:160:0x87/0x96
-S:161:0x87/0x95
-S:162:0x87/0x95
-S:163:0x87/0x92
-S:164:0x87/0x92
-S:165:0x87/0x93
-S:166:0x87/0x95
-S:167:0x87/0x90
-S:168:0x87/0x95
-S:169:0x87/0x95
-S:170:0x87/0x92
-S:171:0x87/0x94
-S:172:0x87/0x92
-S:173:0x87/0x93
-S:174:0x87/0x96
-S:175:0x87/0x90
-
-# Wands (-)
-S:176:0x86/0x97
-S:177:0x86/0x90
-S:178:0x86/0x98
-S:179:0x86/0x92
-S:180:0x86/0x93
-S:181:0x86/0x94
-S:182:0x86/0x95
-S:183:0x86/0x96
-S:184:0x86/0x91
-S:185:0x86/0x91
-S:186:0x86/0x99
-S:187:0x86/0x9A
-S:188:0x86/0x9B
-S:189:0x86/0x9C
-S:190:0x86/0x9D
-S:191:0x86/0x9E
-
-# Rods (-)
-S:192:0x86/0x87
-S:193:0x86/0x80
-S:194:0x86/0x88
-S:195:0x86/0x82
-S:196:0x86/0x83
-S:197:0x86/0x84
-S:198:0x86/0x85
-S:199:0x86/0x86
-S:200:0x86/0x81
-S:201:0x86/0x81
-S:202:0x86/0x89
-S:203:0x86/0x8A
-S:204:0x86/0x8B
-S:205:0x86/0x8C
-S:206:0x86/0x8D
-S:207:0x86/0x8E
-
-# Scrolls (?)
-S:208:0x83/0x9C
-S:209:0x83/0x9D
-S:210:0x83/0x9E
-S:211:0x83/0x9F
-S:212:0x83/0x9C
-S:213:0x83/0x9D
-S:214:0x83/0x9E
-S:215:0x83/0x9F
-S:216:0x83/0x9C
-S:217:0x83/0x9D
-S:218:0x83/0x9E
-S:219:0x83/0x9F
-S:220:0x83/0x9C
-S:221:0x83/0x9D
-S:222:0x83/0x9E
-S:223:0x83/0x9F
-
-# Potions (!)
-S:224:0x85/0x87
-S:225:0x85/0x80
-S:226:0x85/0x88
-S:227:0x85/0x82
-S:228:0x85/0x83
-S:229:0x85/0x84
-S:230:0x85/0x85
-S:231:0x85/0x86
-S:232:0x85/0x81
-S:233:0x85/0x81
-S:234:0x85/0x89
-S:235:0x85/0x8A
-S:236:0x85/0x8B
-S:237:0x85/0x8C
-S:238:0x85/0x8D
-S:239:0x85/0x8E
-
-# Food (,)
-S:240:0x85/0x97
-S:241:0x85/0x90
-S:242:0x85/0x98
-S:243:0x85/0x92
-S:244:0x85/0x93
-S:245:0x85/0x94
-S:246:0x85/0x95
-S:247:0x85/0x96
-S:248:0x85/0x91
-S:249:0x85/0x91
-S:250:0x85/0x99
-S:251:0x85/0x9A
-S:252:0x85/0x9B
-S:253:0x85/0x9C
-S:254:0x85/0x9D
-S:255:0x85/0x9E
-
-# Fire golem
-R:1043:0x8C/0xA0
-
-# Melkor, Lord of Darkness
-R:1044:0x8C/0xA1
-
-# & piece~ of a Relic of Eru
-K:814:0x8C/0xA2
-
-# & piece~ of a Relic of Manwe
-K:815:0x8C/0xA3
-
-# & piece~ of a Relic of Tulkas
-K:816:0x8C/0xA4
-
-# & piece~ of a Relic of Melkor
-K:817:0x8C/0xA5
-
-# rocky ground
-F:207:0x8D/0xA0
-
-# cloud-like vapour
-F:208:0x8D/0xA1
-
-# condensing water
-F:209:0x8D/0xA2
-
-# dense mist
-F:210:0x8D/0xA3
-
-# hail-stone wall
-F:211:0x8D/0xA4
-
-# Mining Supply store
-B:59:0x87/0xAE
-
-# & piece~ of a Relic of Yavanna
-K:818:0x8C/0xA6
-
-# Elven
-G:M:12:0x91/0xA1
-
-# Dwarven
-G:M:13:0x91/0xA0
-
-# Spirit
-R:1045:0x92/0x9F
-R:1046:0x92/0xA0
-R:1047:0x92/0xA1
-R:1048:0x92/0xA2
-R:1049:0x92/0xA3
-R:1050:0x92/0xA4
-R:1051:0x92/0xA5
-R:1052:0x92/0xA6
-R:1053:0x92/0xA7
-R:1054:0x92/0xA8
-R:1055:0x92/0xA9
-R:1056:0x92/0xAA
-R:1057:0x92/0xA3
-R:1058:0x92/0xAB
-R:1059:0x92/0xAC
-R:1060:0x92/0xAD
-R:1061:0x92/0xAE
-R:1062:0x92/0xAF
-R:1063:0x92/0xB0
-R:1064:0x92/0xB1
-R:1065:0x92/0xB2
-R:1066:0x92/0xB3
-R:1067:0x92/0xB4
-R:1068:0x92/0xB5
-R:1069:0x92/0xB6
-R:1070:0x92/0xB7
-R:1071:0x92/0xB8
-R:1072:0x92/0xB9
-R:1073:0x92/0xBA
-R:1074:0x92/0xBB
-R:1075:0x92/0xBC
-
-# & Spellbook~ of #
-K:757:0x91/0xA4
-
-# Weakness Trap
-#G:T:1:0xFF/0xFF
-#G:T:2:0xFF/0xFF
-#G:T:3:0xFF/0xFF
-
-# Intelligence Trap
-#G:T:4:0xFF/0xFF
-#G:T:5:0xFF/0xFF
-#G:T:6:0xFF/0xFF
-
-# Wisdom Trap
-#G:T:7:0xFF/0xFF
-#G:T:8:0xFF/0xFF
-#G:T:9:0xFF/0xFF
-
-# Fumbling Fingers Trap
-#G:T:10:0xFF/0xFF
-#G:T:11:0xFF/0xFF
-#G:T:12:0xFF/0xFF
-
-# Wasting Trap
-#G:T:13:0xFF/0xFF
-#G:T:14:0xFF/0xFF
-#G:T:15:0xFF/0xFF
-
-# Beauty Trap
-#G:T:16:0xFF/0xFF
-#G:T:17:0xFF/0xFF
-#G:T:18:0xFF/0xFF
-
-# Trap of Curse Weapon
-#G:T:20:0xFF/0xFF
-
-# Trap of Curse Armor
-#G:T:21:0xFF/0xFF
-
-# Earthquake Trap
-#G:T:22:0xFF/0xFF
-
-# Poison Needle Trap
-#G:T:23:0xFF/0xFF
-
-# Summon Monster Trap
-#G:T:24:0xFF/0xFF
-
-# Summon Undead Trap
-#G:T:25:0xFF/0xFF
-
-# Summon Greater Undead Trap
-#G:T:26:0xFF/0xFF
-
-# Teleport Trap
-#G:T:27:0xFF/0xFF
-
-# Paralyzing Trap
-#G:T:28:0xFF/0xFF
-
-# Explosive Device
-#G:T:29:0xFF/0xFF
-
-# Teleport Item Trap
-#G:T:30:0xFF/0xFF
-
-# Lose Memory Trap
-#G:T:31:0xFF/0xFF
-
-# Bitter Regret Trap
-#G:T:32:0xFF/0xFF
-
-# Bowel Cramps Trap
-#G:T:33:0xFF/0xFF
-
-# Blindness
-#G:T:34:0xFF/0xFF
-
-# Aggravation Trap
-#G:T:35:0xFF/0xFF
-
-# Multiplication Trap
-#G:T:36:0xFF/0xFF
-
-# Steal Item Trap
-#G:T:37:0xFF/0xFF
-
-# Summon Fast Quylthulgs Trap
-#G:T:38:0xFF/0xFF
-
-# Trap of Sinking
-#G:T:39:0xFF/0xFF
-
-# Trap of Mana Drain
-#G:T:40:0xFF/0xFF
-
-# Trap of Missing Money
-#G:T:41:0xFF/0xFF
-
-# Trap of No Return
-#G:T:42:0xFF/0xFF
-
-# Trap of Silent Switching
-#G:T:43:0xFF/0xFF
-
-# Trap of Walls
-#G:T:44:0xFF/0xFF
-
-# Trap of Calling Out
-#G:T:45:0xFF/0xFF
-
-# Trap of Sliding
-#G:T:46:0xFF/0xFF
-
-# Trap of Charges Drain
-#G:T:47:0xFF/0xFF
-
-# Trap of Stair Movement
-#G:T:48:0xFF/0xFF
-
-# Trap of New Trap
-#G:T:49:0xFF/0xFF
-
-# Trap of Scatter Items
-#G:T:50:0xFF/0xFF
-
-# Trap of Decay
-#G:T:51:0xFF/0xFF
-
-# Trap of Wasting Wands
-#G:T:52:0xFF/0xFF
-
-# Trap of Filling
-#G:T:53:0xFF/0xFF
-
-# Trap of Drain Speed
-#G:T:54:0xFF/0xFF
-
-# Lightning Bolt Trap
-#G:T:60:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:61:0xFF/0xFF
-
-# Acid Bolt Trap
-#G:T:62:0xFF/0xFF
-
-# Cold Bolt Trap
-#G:T:63:0xFF/0xFF
-
-# Fire Bolt Trap
-#G:T:64:0xFF/0xFF
-
-# Plasma Bolt Trap
-#G:T:65:0xFF/0xFF
-
-# Water Bolt Trap
-#G:T:66:0xFF/0xFF
-
-# Lite Bolt Trap
-#G:T:67:0xFF/0xFF
-
-# Dark Bolt Trap
-#G:T:68:0xFF/0xFF
-
-# Shards Bolt Trap
-#G:T:69:0xFF/0xFF
-
-# Sound Bolt Trap
-#G:T:70:0xFF/0xFF
-
-# Confusion Bolt Trap
-#G:T:71:0xFF/0xFF
-
-# Force Bolt Trap
-#G:T:72:0xFF/0xFF
-
-# Inertia Bolt Trap
-#G:T:73:0xFF/0xFF
-
-# Mana Bolt Trap
-#G:T:74:0xFF/0xFF
-
-# Ice Bolt Trap
-#G:T:75:0xFF/0xFF
-
-# Chaos Bolt Trap
-#G:T:76:0xFF/0xFF
-
-# Nether Bolt Trap
-#G:T:77:0xFF/0xFF
-
-# Disenchantment Bolt Trap
-#G:T:78:0xFF/0xFF
-
-# Nexus Bolt Trap
-#G:T:79:0xFF/0xFF
-
-# Time Bolt Trap
-#G:T:80:0xFF/0xFF
-
-# Gravity Bolt Trap
-#G:T:81:0xFF/0xFF
-
-# Lightning Ball Trap
-#G:T:82:0xFF/0xFF
-
-# Poison Ball Trap
-#G:T:83:0xFF/0xFF
-
-# Acid Ball Trap
-#G:T:84:0xFF/0xFF
-
-# Cold Ball Trap
-#G:T:85:0xFF/0xFF
-
-# Fire Ball Trap
-#G:T:86:0xFF/0xFF
-
-# Plasma Ball Trap
-#G:T:87:0xFF/0xFF
-
-# Water Ball Trap
-#G:T:88:0xFF/0xFF
-
-# Light Ball Trap
-#G:T:89:0xFF/0xFF
-
-# Darkness Ball Trap
-#G:T:90:0xFF/0xFF
-
-# Shards Ball Trap
-#G:T:91:0xFF/0xFF
-
-# Sound Ball Trap
-#G:T:92:0xFF/0xFF
-
-# Confusion Ball Trap
-#G:T:93:0xFF/0xFF
-
-# Force Ball Trap
-#G:T:94:0xFF/0xFF
-
-# Inertia Ball Trap
-#G:T:95:0x82/0xBF
-
-# Mana Ball Trap
-#G:T:96:0xFF/0xFF
-
-# Ice Ball Trap
-#G:T:97:0xFF/0xFF
-
-# Chaos Ball Trap
-#G:T:98:0xFF/0xFF
-
-# Nether Ball Trap
-#G:T:99:0xFF/0xFF
-
-# Disenchantment Ball Trap
-#G:T:100:0xFF/0xFF
-
-# Nexus Ball Trap
-#G:T:101:0xFF/0xFF
-
-# Time Ball Trap
-#G:T:102:0xFF/0xFF
-
-# Gravity Ball Trap
-#G:T:103:0xFF/0xFF
-
-# Arrow Trap
-#G:T:110:0xFF/0xFF
-
-# Bolt Trap
-#G:T:111:0xFF/0xFF
-
-# Seeker Arrow Trap
-#G:T:112:0xFF/0xFF
-
-# Seeker Bolt Trap
-#G:T:113:0xFF/0xFF
-
-# Poison Arrow Trap
-#G:T:114:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:115:0xFF/0xFF
-
-# Poison Seeker Arrow Trap
-#G:T:116:0xFF/0xFF
-
-# Poison Seeker Bolt Trap
-#G:T:117:0xFF/0xFF
-
-# Broken Dagger Trap
-#G:T:118:0xFF/0xFF
-
-# Dagger Trap
-#G:T:119:0xFF/0xFF
-
-# Poison Broken Dagger Trap
-#G:T:120:0xFF/0xFF
-
-# Poison Dagger Trap
-#G:T:121:0xFF/0xFF
-
-# Arrows Trap
-#G:T:122:0xFF/0xFF
-
-# Bolts Trap
-#G:T:123:0xFF/0xFF
-
-# Seeker Arrow Trap
-#G:T:124:0xFF/0xFF
-
-# Seeker Bolt Trap
-#G:T:125:0xFF/0xFF
-
-# Poison Arrows Trap
-#G:T:126:0xFF/0xFF
-
-# Poison Bolt Trap
-#G:T:127:0xFF/0xFF
-
-# Poison Seeker Arrows Trap
-#G:T:128:0xFF/0xFF
-
-# Poison Seeker Bolts Trap
-#G:T:129:0xFF/0xFF
-
-# Broken Daggers Trap
-#G:T:130:0xFF/0xFF
-
-# Dagger Trap
-#G:T:131:0xFF/0xFF
-
-# Poison Broken Daggers Trap
-#G:T:132:0xFF/0xFF
-
-# Poison Daggers Trap
-#G:T:133:0xFF/0xFF
-
-# Trap of Drop Item
-#G:T:140:0xFF/0xFF
-
-# Trap of Drop Items
-#G:T:141:0xFF/0xFF
-
-# Trap of Drop Everything
-#G:T:142:0xFF/0xFF
-
-# Trap of Femininity
-#G:T:150:0xFF/0xFF
-
-# Trap of Masculinity
-#G:T:151:0xFF/0xFF
-
-# Trap of Neutrality
-#G:T:152:0xFF/0xFF
-
-# Trap of Aging
-#G:T:153:0xFF/0xFF
-
-# Trap of Growing
-#G:T:154:0xFF/0xFF
-
-# Trap of Shrinking
-#G:T:155:0xFF/0xFF
-
-# Trap of Tanker Drain
-#G:T:157:0xFF/0xFF
-
-# Trap of Divine Anger
-#G:T:158:0xFF/0xFF
-
-# Trap of Divine Wrath
-#G:T:159:0xFF/0xFF
-
-# Hallucination Trap
-#G:T:160:0xFF/0xFF
-
-# Greater Magic Missile Trap
-#G:T:161:0xFF/0xFF
-
-# Foulness Trap
-#G:T:162:0xFF/0xFF
-
-# Trap of Holy Fire
-#G:T:164:0xFF/0xFF
-
-# Trap of Hell Fire
-#G:T:165:0xFF/0xFF
-
-# Psi Bolt Trap
-#G:T:166:0xFF/0xFF
-
-# Psi Drain Trap
-#G:T:167:0xFF/0xFF
-
-# Plasma Ball Trap
-#G:T:168:0xFF/0xFF
-
-# Psi Ball Trap
-#G:T:169:0xFF/0xFF
-
-# Acquirement Trap
-#G:T:170:0xFF/0xFF
-
-# Greater Lightning Bolt Trap
-#G:T:171:0xFF/0xFF
-
-# Greater Poison Bolt Trap
-#G:T:172:0xFF/0xFF
-
-# Greater Acid Bolt Trap
-#G:T:173:0xFF/0xFF
-
-# Greater Cold Bolt Trap
-#G:T:174:0xFF/0xFF
-
-# Greater Fire Bolt Trap
-#G:T:175:0xFF/0xFF
-# non-defines encountered :
-# Load the special player pictures
-%:xtra-new.prf
diff --git a/lib/pref/graf-sdl.prf b/lib/pref/graf-sdl.prf
deleted file mode 100644
index 818f876a..00000000
--- a/lib/pref/graf-sdl.prf
+++ /dev/null
@@ -1,37 +0,0 @@
-# File: graf-x11.prf
-
-
-# Font stuff
-%:font-x11.prf
-
-
-# Color palette - Graphics
-
-#V:16:0x01:0x00:0x00:0x00
-#V:17:0x01:0xF0:0xE0:0xD0
-#V:18:0x01:0x80:0x80:0x80
-#V:19:0x01:0x50:0x50:0x50
-#V:20:0x01:0xE0:0xB0:0x00
-#V:21:0x01:0xC0:0xA0:0x70
-#V:22:0x01:0x80:0x60:0x40
-#V:23:0x01:0x50:0x3C:0x28
-#V:24:0x01:0x00:0xA0:0xF0
-#V:25:0x01:0x00:0x00:0xF0
-#V:26:0x01:0x00:0x00:0x70
-#V:27:0x01:0xF0:0x00:0x00
-#V:28:0x01:0x80:0x00:0x00
-#V:29:0x01:0x90:0x00:0xB0
-#V:30:0x01:0x00:0x60:0x10
-#V:31:0x01:0x60:0xF0:0x40
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
-
-?:1
-
diff --git a/lib/pref/graf-win.prf b/lib/pref/graf-win.prf
deleted file mode 100644
index f59edb35..00000000
--- a/lib/pref/graf-win.prf
+++ /dev/null
@@ -1,16 +0,0 @@
-# File: graf-win.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
diff --git a/lib/pref/graf-x11.prf b/lib/pref/graf-x11.prf
deleted file mode 100644
index 818f876a..00000000
--- a/lib/pref/graf-x11.prf
+++ /dev/null
@@ -1,37 +0,0 @@
-# File: graf-x11.prf
-
-
-# Font stuff
-%:font-x11.prf
-
-
-# Color palette - Graphics
-
-#V:16:0x01:0x00:0x00:0x00
-#V:17:0x01:0xF0:0xE0:0xD0
-#V:18:0x01:0x80:0x80:0x80
-#V:19:0x01:0x50:0x50:0x50
-#V:20:0x01:0xE0:0xB0:0x00
-#V:21:0x01:0xC0:0xA0:0x70
-#V:22:0x01:0x80:0x60:0x40
-#V:23:0x01:0x50:0x3C:0x28
-#V:24:0x01:0x00:0xA0:0xF0
-#V:25:0x01:0x00:0x00:0xF0
-#V:26:0x01:0x00:0x00:0x70
-#V:27:0x01:0xF0:0x00:0x00
-#V:28:0x01:0x80:0x00:0x00
-#V:29:0x01:0x90:0x00:0xB0
-#V:30:0x01:0x00:0x60:0x10
-#V:31:0x01:0x60:0xF0:0x40
-
-
-# Standard file
-?:[EQU $GRAF old]
-%:graf-xxx.prf
-
-# New tiles
-?:[EQU $GRAF new]
-%:graf-new.prf
-
-?:1
-
diff --git a/lib/pref/graf-xxx.prf b/lib/pref/graf-xxx.prf
deleted file mode 100644
index bea696d9..00000000
--- a/lib/pref/graf-xxx.prf
+++ /dev/null
@@ -1,6348 +0,0 @@
-# PRF file generated by Andreas Koch`s Tile Assigner
-# 23/06/2004 : Edited manually
-
-# 2185 items
-# 2185 probably mapped correctly
-# 0 imported but not yet defined
-# 0 defined to value(s) lower than 0x80
-# Old header :
-### 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
-
-# General Store
-B:0:0x81/0x91
-
-# Armoury
-B:1:0x81/0x92
-
-# Weapon Smiths
-B:2:0x81/0x93
-
-# Temple
-B:3:0x81/0x94
-
-# Alchemy Shop
-B:4:0x81/0x95
-
-# Magic Shop
-B:5:0x81/0x96
-
-# Black Market
-B:6:0x81/0x97
-
-# Home
-B:7:0x81/0x98
-
-# Bookstore
-B:8:0x82/0x93
-
-# Pet Shop
-B:9:0xCB/0x96
-
-# Mayor's Office
-B:10:0xCB/0x92
-
-# Inn
-B:11:0xCB/0x95
-
-# The Soothsayer
-B:12:0xD4/0x85
-
-# Library
-B:13:0xD4/0x89
-
-# Castle
-B:14:0xCB/0x92
-
-# Casino
-B:15:0xD5/0x81
-
-# Beastmaster Shanty
-B:16:0xD3/0x8B
-
-# Fighters Hall
-B:17:0xD3/0x8C
-
-# Tower of Magery
-B:18:0xD4/0x8B
-
-# Inner Temple
-B:19:0xD4/0x9D
-
-# Paladins Guild
-B:20:0xCB/0x8F
-
-# Rangers Guild
-B:21:0xD3/0x83
-
-# Weyr
-B:22:0xCB/0x93
-
-# The Mirror
-B:23:0xD4/0x89
-
-# Seat of Ruling
-B:24:0xCB/0x92
-
-# Wizards Spire
-B:25:0xD4/0x8A
-
-# Priests Circle
-B:26:0xD4/0x92
-
-# Tower of the King
-B:27:0xCB/0x92
-
-# Library
-B:28:0xD4/0x89
-
-# The White Tree
-B:29:0xCB/0x95
-
-# Craftsmaster
-B:30:0xCB/0x97
-
-# Earth-Dome (Nature)
-B:31:0xCB/0x9A
-
-# Minstrels Haven
-B:32:0xD3/0x9F
-
-# Star-Dome
-B:33:0xD4/0x8C
-
-# Valarin Temple
-B:34:0xD4/0x90
-
-# Sea-Dome
-B:35:0xD4/0x91
-
-# The Golden Flower
-B:36:0xD3/0x83
-
-# The Fountain
-B:37:0xD4/0x9D
-
-# Axe Smith
-B:38:0xCC/0x96
-
-# Hafted Smith
-B:39:0xCC/0x97
-
-# Polearm Smith
-B:40:0xCC/0x98
-
-# Sword Smith
-B:41:0xCC/0x80
-
-# Rare Jewelry Shop
-B:42:0xD3/0x96
-
-# Jewelry Shop
-B:43:0xD3/0x93
-
-# Footwear Shop
-B:44:0xD3/0x9D
-
-# Rare Footwear Shop
-B:45:0xD3/0x9E
-
-# Library
-B:46:0xD3/0x9C
-
-# Forbidden Library
-B:47:0xD4/0x8F
-
-# Expensive Black Market
-B:48:0xD4/0x95
-
-# Common Shop
-B:49:0xD4/0x93
-
-# Dragon Hunter
-B:50:0xCC/0x89
-
-# Speed Ring Market
-B:51:0xD3/0x97
-
-# Scribe
-B:52:0xD4/0x86
-
-# Potion Store
-B:53:0xD4/0x80
-
-# Recaller
-B:54:0xD4/0x88
-
-# Master Archer
-B:55:0xD3/0x85
-
-# Merchants Guild
-B:56:0xD4/0x9B
-
-# The Mathom-house
-B:57:0xCB/0x9B
-
-# The Prancing Pony
-B:58:0xCB/0x95
-
-# nothing
-F:0:0x81/0x80
-
-# open floor
-F:1:0x80/0x80
-
-# fountain - wet
-F:2:0xD1/0x83
-
-# glyph of warding
-F:3:0xA2/0x88
-
-# open door
-F:4:0x81/0x87
-
-# broken door
-F:5:0x81/0x87
-
-# up staircase
-F:6:0x81/0x9C
-
-# down staircase
-F:7:0x81/0x9E
-
-# quest entrance
-F:8:0x82/0x8E
-
-# quest exit
-F:9:0x82/0x8B
-
-# quest down level
-F:10:0x82/0x8F
-
-# quest up level
-F:11:0x82/0x8C
-
-# town exit
-F:12:0x82/0x91
-
-# shaft down
-F:13:0x82/0x90
-
-# shaft up
-F:14:0x82/0x8D
-
-# fountain
-F:15:0xD1/0x82
-
-# web
-F:16:0x82/0x92
-
-# Open pit
-F:17:0xA2/0x96
-
-# Spiked Pit
-F:18:0xA2/0x96
-
-# Poison Pit
-F:19:0xA2/0x96
-
-# Summon Rune
-F:20:0x8A/0x9C
-
-# Teleport Rune
-F:21:0x8A/0x9C
-
-# Fire spot
-F:22:0x8A/0x9B
-
-# Acid spot
-F:23:0x8A/0x9B
-
-# Slow dart trap
-F:24:0x82/0x9E
-
-# Lose str dart
-F:25:0xA2/0x89
-
-# Lose dex dart
-F:26:0xA2/0x8D
-
-# Lose con dart
-F:27:0xA2/0x92
-
-# gas trap - blind
-F:28:0xA2/0x8E
-
-# gas trap - confuse
-F:29:0xA2/0x8F
-
-# gas trap - poison
-F:30:0xA2/0x90
-
-# gas trap - sleep
-F:31:0xA2/0x91
-
-# door
-F:32:0x81/0x8B
-
-# locked door
-F:33:0x81/0x8B
-F:34:0x81/0x8B
-F:35:0x81/0x8B
-F:36:0x81/0x8B
-F:37:0x81/0x8B
-F:38:0x81/0x8B
-F:39:0x81/0x8B
-
-# jammed door
-F:40:0x81/0x8B
-F:41:0x81/0x8B
-F:42:0x81/0x8B
-F:43:0x81/0x8B
-F:44:0x81/0x8B
-F:45:0x81/0x8B
-F:46:0x81/0x8B
-F:47:0x81/0x8B
-
-# secret door
-F:48:0x80/0x82
-
-# pile of rubble
-F:49:0x81/0x9A
-
-# magma vein
-F:50:0x81/0x83
-
-# quartz vein
-F:51:0x80/0x83
-
-# magma vein
-F:52:0x81/0x83
-
-# quartz vein
-F:53:0x80/0x83
-
-# magma vein with treasure
-F:54:0x80/0x84
-
-# quartz vein with treasure
-F:55:0x80/0x84
-
-# granite wall
-F:56:0x80/0x82
-F:57:0x80/0x82
-F:58:0x80/0x82
-F:59:0x80/0x82
-
-# permanent wall
-F:60:0x80/0x95
-F:61:0x80/0x95
-F:62:0x80/0x95
-F:63:0x80/0x95
-
-# explosive rune
-F:64:0xA2/0x87
-
-# Straight Road startpoint
-F:65:0xA3/0x9D
-
-# section of the Straight Road
-F:66:0xA3/0x97
-F:67:0xA3/0x9C
-F:68:0xA3/0x9B
-F:69:0xA3/0x9A
-F:70:0xA3/0x98
-
-# section of the Straight Road (discharged)
-F:71:0xA3/0x98
-
-# Straight Road exit
-F:72:0xA3/0x9D
-
-# corrupted section of the Straight Road
-F:73:0xA3/0x99
-
-# Building
-F:74:0x81/0x91
-
-# permanent wall
-F:75:0x80/0x95
-F:76:0x80/0x95
-F:77:0x80/0x95
-F:78:0x80/0x95
-
-# Deep water
-F:83:0xD2/0x83
-
-# stream of shallow water
-F:84:0xD2/0x81
-
-# pool of deep lava
-F:85:0xCB/0x89
-
-# stream of shallow lava
-F:86:0xCB/0x88
-
-# dark pit
-F:87:0x81/0x80
-
-# dirt
-F:88:0xCB/0x84
-
-# patch of grass
-F:89:0xD0/0x8E
-
-# ice
-F:90:0xCF/0x81
-
-# sand
-F:91:0xCF/0x8E
-
-# dead tree
-F:92:0xCF/0x85
-
-# ash
-F:93:0xCF/0x95
-
-# mud
-F:94:0xCF/0x8D
-
-# ice wall
-F:95:0xD0/0x88
-
-# tree
-F:96:0xCB/0x86
-
-# mountain chain
-F:97:0xCB/0x87
-
-# sandwall
-F:98:0xD0/0x87
-F:99:0xD0/0x87
-
-# sandwall with treasure
-F:100:0xD0/0x8A
-
-# high mountain chain
-F:101:0xCB/0x87
-
-# nether mist
-F:102:0xC5/0x8C
-
-# molten glass wall
-F:103:0xD0/0x89
-
-# Between gate
-F:160:0x8A/0x9D
-
-# Altar of Forests
-F:161:0xD1/0x85
-
-# Altar of Water
-F:162:0xD1/0x86
-
-# Altar of Earth
-F:163:0xD1/0x8E
-
-# Altar of Darkness
-F:164:0xD1/0x88
-
-# Altar of Moon
-F:165:0xD1/0x89
-
-# Altar of Sun
-F:166:0xD1/0x8C
-
-# Altar of Rage
-F:167:0xD1/0x8A
-
-# Altar of Winds
-F:168:0xD1/0x8B
-
-# Altar of Stars
-F:169:0xD1/0x8D
-
-# Altar of Being
-F:170:0xD1/0x87
-
-# Altar of Randomness
-F:171:0xD1/0x8F
-
-# floor
-F:172:0x80/0x80
-
-# Underground Tunnel
-F:173:0xCF/0x97
-
-# stream of tainted water
-F:174:0xD2/0x82
-
-# monster trap
-F:175:0x82/0x94
-
-# Between gate
-F:176:0x8A/0x9D
-
-# lava wall
-F:177:0xD0/0x86
-
-# Great Fire
-F:178:0xD1/0x90
-
-# Path to next area
-F:179:0xCF/0x9C
-
-# Path to previous area
-F:180:0xCF/0x9B
-
-# field
-F:181:0xCF/0x8A
-
-# Ekkaia, the Encircling Sea
-F:182:0xD2/0x84
-
-# pool of deep water
-F:187:0xD2/0x80
-
-# glass wall
-F:188:0xD0/0x89
-
-# illusion wall
-F:189:0xD0/0x8C
-
-# Grass roof
-F:190:0xD0/0x8F
-
-# grass roof top
-F:191:0xD0/0x8F
-
-# grass roof chimney
-F:192:0xD0/0x8F
-
-# brick roof
-F:193:0xD0/0x90
-
-# brick roof top
-F:194:0xD0/0x90
-
-# brick roof chimney
-F:195:0xD0/0x90
-
-# window
-F:196:0xD0/0x91
-
-# small window
-F:197:0xD0/0x92
-
-# rain barrel
-F:198:0xD0/0x93
-
-# grass with flowers
-F:199:0xD0/0x8D
-
-# cobblestone road
-F:200:0x82/0x8A
-
-# cobblestone with outlet
-F:201:0x82/0x8A
-
-# small tree
-F:202:0xD0/0x8B
-
-# town
-F:203:0xD0/0x94
-
-# Underground Tunnel
-F:204:0xD0/0x95
-
-# a blazing fire
-F:205:0xD1/0x84
-
-# pile of rubble
-F:206:0x81/0x9A
-
-# ethereal wall
-F:214:0x80/0x80
-
-# glacial wall
-F:215:0xD0/0x88
-
-# something
-K:0:0x80/0x80
-
-# Blindness
-K:1:0xBA/0x81
-
-# Paranoia
-K:2:0xBA/0x81
-
-# Confusion
-K:3:0xBA/0x81
-
-# Hallucination
-K:4:0xBA/0x81
-
-# Cure Poison
-K:5:0xBA/0x81
-
-# Cure Blindness
-K:6:0xBA/0x81
-
-# Cure Paranoia
-K:7:0xBA/0x81
-
-# Cure Confusion
-K:8:0xBA/0x81
-
-# Weakness
-K:9:0xBA/0x81
-
-# Unhealth
-K:10:0xBA/0x81
-
-# Restore Constitution
-K:11:0xBA/0x81
-
-# Restoring
-K:12:0xBA/0x81
-
-# Stupidity
-K:13:0xBA/0x81
-
-# Naivety
-K:14:0xBA/0x81
-
-# Poison
-K:15:0xBA/0x81
-
-# Sickness
-K:16:0xBA/0x81
-
-# Paralysis
-K:17:0xBA/0x81
-
-# Restore Strength
-K:18:0xBA/0x81
-
-# Disease
-K:19:0xBA/0x81
-
-# Cure Serious Wounds
-K:20:0xBA/0x81
-
-# & Ration~ of Food
-K:21:0x8B/0x82
-
-# & Hard Biscuit~
-K:22:0x8B/0x82
-
-# & Strip~ of Venison
-K:23:0x8B/0x82
-
-# & Slime Mold~
-K:24:0x8A/0x9F
-
-# & Piece~ of Elvish Waybread
-K:25:0x8B/0x80
-
-# & Pint~ of Fine Ale
-K:26:0x8A/0x95
-
-# & Pint~ of Fine Wine
-K:27:0x8A/0x96
-
-# & Mattock~
-K:28:0xCD/0x80
-
-# The Blue Stone 'Toris Mejistos'
-K:29:0xB6/0x89
-
-# & Broken Dagger~
-K:30:0x89/0x83
-
-# & Bastard Sword~
-K:31:0x89/0x85
-
-# & Scimitar~
-K:32:0x89/0x85
-
-# & Tulwar~
-K:33:0x89/0x84
-
-# & Broad Sword~
-K:34:0x89/0x85
-
-# & Short Sword~
-K:35:0x89/0x84
-
-# & Blade~ of Chaos
-K:36:0x89/0x87
-
-# & Two-Handed Sword~
-K:37:0x89/0x85
-
-# & Main Gauche~
-K:38:0x89/0x83
-
-# & Cutlass~
-K:39:0x89/0x84
-
-# & Executioner's Sword~
-K:40:0x89/0x86
-
-# & Katana~
-K:41:0x89/0x85
-
-# & Long Sword~
-K:42:0x89/0x85
-
-# & Dagger~
-K:43:0x89/0x83
-
-# & Rapier~
-K:44:0x89/0x84
-
-# & Sabre~
-K:45:0x89/0x84
-
-# & Small Sword~
-K:46:0x89/0x84
-
-# & Broken Sword~
-K:47:0x89/0x83
-
-# & Ball-and-Chain~
-K:48:0x89/0x88
-
-# & Whip~
-K:49:0x89/0x89
-
-# & Flail~
-K:50:0x89/0x8B
-
-# & Two-Handed Flail~
-K:51:0x89/0x8B
-
-# & Morning Star~
-K:52:0x89/0x8B
-
-# & Mace~
-K:53:0x89/0x8C
-
-# & Quarterstaff~
-K:54:0x89/0x8E
-
-# & War Hammer~
-K:55:0x89/0x8F
-
-# & Lead-Filled Mace~
-K:56:0x89/0x8C
-
-# & Mace~ of Disruption
-K:57:0x89/0x8D
-
-# & Lucerne Hammer~
-K:58:0x89/0x90
-
-# & Beaked Axe~
-K:59:0x89/0x90
-
-# & Glaive~
-K:60:0x89/0x90
-
-# & Halberd~
-K:61:0x89/0x90
-
-# & Awl-Pike~
-K:62:0x89/0x91
-
-# & Pike~
-K:63:0x89/0x91
-
-# & Spear~
-K:64:0x89/0x91
-
-# & Trident~
-K:65:0x89/0x92
-
-# & Lance~
-K:66:0x89/0x93
-
-# & Great Axe~
-K:67:0x89/0x90
-
-# & Battle Axe~
-K:68:0x89/0x90
-
-# & Lochaber Axe~
-K:69:0x89/0x90
-
-# & Broad Axe~
-K:70:0x89/0x90
-
-# & Scythe~
-K:71:0x89/0x94
-
-# & Scythe~ of Slicing
-K:72:0x89/0x94
-
-# & Short Bow~
-K:73:0x89/0x95
-
-# & Long Bow~
-K:74:0x89/0x96
-
-# & Light Crossbow~
-K:75:0x89/0x97
-
-# & Heavy Crossbow~
-K:76:0x89/0x98
-
-# & Sling~
-K:77:0x89/0x99
-
-# & Arrow~
-K:78:0x89/0x9A
-
-# & Seeker Arrow~
-K:79:0x89/0x9B
-
-# & Bolt~
-K:80:0x89/0x9C
-
-# & Seeker Bolt~
-K:81:0x89/0x9D
-
-# & Rounded Pebble~
-K:82:0x89/0x9E
-
-# & Iron Shot~
-K:83:0x89/0x9F
-
-# & Shovel~
-K:84:0x8A/0x98
-
-# & Gnomish Shovel~
-K:85:0x8B/0x8F
-
-# & Dwarven Shovel~
-K:86:0x8B/0x90
-
-# & Pick~
-K:87:0x8A/0x97
-
-# & Orcish Pick~
-K:88:0x8B/0x8D
-
-# & Dwarven Pick~
-K:89:0x8B/0x8E
-
-# & Elven Cloak~
-K:90:0x88/0x81
-
-# & Pair~ of Soft Leather Boots
-K:91:0x88/0x89
-
-# & Pair~ of Hard Leather Boots
-K:92:0x88/0x8A
-
-# & Pair~ of Metal Shod Boots
-K:93:0x88/0x8B
-
-# & Hard Leather Cap~
-K:94:0x88/0x82
-
-# & Metal Cap~
-K:95:0x88/0x83
-
-# & Iron Helm~
-K:96:0x88/0x84
-
-# & Steel Helm~
-K:97:0x88/0x85
-
-# & Iron Crown~
-K:98:0x88/0x86
-
-# & Golden Crown~
-K:99:0x88/0x87
-
-# & Jewel Encrusted Crown~
-K:100:0x88/0x88
-
-# & Robe~
-K:101:0x88/0x95
-
-# & Filthy Rag~
-K:102:0x88/0x94
-
-# Soft Leather Armour~
-K:103:0x88/0x96
-
-# Soft Studded Leather~
-K:104:0x88/0x96
-
-# Hard Leather Armour~
-K:105:0x88/0x97
-
-# Hard Studded Leather~
-K:106:0x88/0x97
-
-# Leather Scale Mail~
-K:107:0x88/0x98
-
-# Metal Scale Mail~
-K:108:0x88/0x98
-
-# Chain Mail~
-K:109:0x88/0x99
-
-# Rusty Chain Mail~
-K:110:0x88/0x9A
-
-# Augmented Chain Mail~
-K:111:0x88/0x99
-
-# Bar Chain Mail~
-K:112:0x88/0x99
-
-# Metal Brigandine Armour~
-K:113:0x88/0x99
-
-# Partial Plate Armour~
-K:114:0x88/0x9B
-
-# Metal Lamellar Armour~
-K:115:0x88/0x9B
-
-# Full Plate Armour~
-K:116:0xCD/0x82
-
-# Ribbed Plate Armour~
-K:117:0x88/0x9B
-
-# Adamantite Plate Mail~
-K:118:0xA3/0x96
-
-# Mithril Plate Mail~
-K:119:0x88/0x9C
-
-# Mithril Chain Mail~
-K:120:0x88/0x9C
-
-# Double Chain Mail~
-K:121:0x88/0x99
-
-# & Shield~ of Deflection
-K:122:0x88/0x93
-
-# & Cloak~
-K:123:0x88/0x80
-
-# & Shadow Cloak~
-K:124:0x88/0x81
-
-# & Set~ of Leather Gloves
-K:125:0x88/0x8C
-
-# & Set~ of Gauntlets
-K:126:0x88/0x8D
-
-# & Set~ of Cesti
-K:127:0x88/0x8E
-
-# & Small Leather Shield~
-K:128:0x88/0x8F
-
-# & Large Leather Shield~
-K:129:0x88/0x90
-
-# & Small Metal Shield~
-K:130:0x88/0x91
-
-# & Large Metal Shield~
-K:131:0x88/0x92
-
-# Strength
-K:132:0xB5/0x81
-
-# Dexterity
-K:133:0xB5/0x81
-
-# Constitution
-K:134:0xB5/0x81
-
-# Intelligence
-K:135:0xB5/0x81
-
-# Speed
-K:136:0xB5/0x83
-
-# Searching
-K:137:0xB5/0x80
-
-# Teleportation
-K:138:0xB5/0x80
-
-# Slow Digestion
-K:139:0xB5/0x80
-
-# Fire Resistance
-K:140:0xB5/0x80
-
-# Cold Resistance
-K:141:0xB5/0x80
-
-# Levitation
-K:142:0xB5/0x80
-
-# Poison Resistance
-K:143:0xB5/0x82
-
-# Free Action
-K:144:0xB5/0x80
-
-# Weakness
-K:145:0xB5/0x80
-
-# Flames
-K:146:0xB5/0x82
-
-# Acid
-K:147:0xB5/0x82
-
-# Ice
-K:148:0xB5/0x82
-
-# Woe
-K:149:0xB5/0x82
-
-# Stupidity
-K:150:0xB5/0x80
-
-# Damage
-K:151:0xB5/0x81
-
-# Accuracy
-K:152:0xB5/0x81
-
-# Protection
-K:153:0xB5/0x80
-
-# Aggravate Monster
-K:154:0xB5/0x80
-
-# See Invisible
-K:155:0xB5/0x81
-
-# Sustain Strength
-K:156:0xB5/0x81
-
-# Sustain Intelligence
-K:157:0xB5/0x81
-
-# Sustain Wisdom
-K:158:0xB5/0x81
-
-# Sustain Constitution
-K:159:0xB5/0x81
-
-# Sustain Dexterity
-K:160:0xB5/0x81
-
-# Sustain Charisma
-K:161:0xB5/0x81
-
-# Slaying
-K:162:0xB5/0x81
-
-# Brilliance
-K:163:0xB6/0x9F
-
-# Charisma
-K:164:0xB6/0x9F
-
-# Searching
-K:165:0xB6/0x9E
-
-# Teleportation
-K:166:0xB6/0x9E
-
-# Slow Digestion
-K:167:0xB6/0x9E
-
-# Acid Resistance
-K:168:0xB6/0x9E
-
-# Adornment
-K:169:0xB6/0x9E
-
-# Double Ring Mail~
-K:170:0xCD/0x83
-
-# the Magi
-K:171:0xB6/0x80
-
-# Doom
-K:172:0xB6/0x80
-
-# Enchant Weapon To-Hit
-K:173:0x86/0x80
-
-# Enchant Weapon To-Dam
-K:174:0x86/0x80
-
-# Enchant Armor
-K:175:0x86/0x80
-
-# Identify
-K:176:0x86/0x80
-
-# *Identify*
-K:177:0x86/0x82
-
-# Rumour
-K:178:0x86/0x80
-
-# Chaos
-K:179:0x86/0x80
-
-# Remove Curse
-K:180:0x86/0x80
-
-# Light
-K:181:0x86/0x80
-
-# Fire
-K:182:0x86/0x80
-
-# Ice
-K:183:0x86/0x80
-
-# Summon Monster
-K:184:0x86/0x80
-
-# Phase Door
-K:185:0x86/0x80
-
-# Teleportation
-K:186:0x86/0x80
-
-# Teleport Level
-K:187:0x86/0x80
-
-# Monster Confusion
-K:188:0x86/0x80
-
-# Magic Mapping
-K:189:0x86/0x80
-
-# Rune of Protection
-K:190:0x86/0x82
-
-# *Remove Curse*
-K:191:0x86/0x82
-
-# Treasure Detection
-K:192:0x86/0x80
-
-# Object Detection
-K:193:0x86/0x80
-
-# Trap Detection
-K:194:0x86/0x80
-
-# & Sheaf Arrow~
-K:195:0xCD/0x84
-
-# & Mithril Shot~
-K:196:0xCD/0x85
-
-# Door
-K:197:0x86/0x80
-
-# Acquirement
-K:198:0x86/0x80
-
-# *Acquirement*
-K:199:0x86/0x82
-
-# Mass Genocide
-K:200:0x86/0x82
-
-# Detect Invisible
-K:201:0x86/0x80
-
-# Aggravate Monster
-K:202:0x86/0x80
-
-# Trap Creation
-K:203:0x86/0x80
-
-# Trap
-K:204:0x86/0x80
-
-# Artifact Creation
-K:205:0x86/0x82
-
-# Recharging
-K:206:0x86/0x81
-
-# Genocide
-K:207:0x86/0x81
-
-# Darkness
-K:208:0x86/0x80
-
-# Protection from Evil
-K:209:0x86/0x81
-
-# Satisfy Hunger
-K:210:0x86/0x80
-
-# Dispel Undead
-K:211:0x86/0x81
-
-# *Enchant Weapon*
-K:212:0x86/0x82
-
-# Curse Weapon
-K:213:0x86/0x82
-
-# *Enchant Armor*
-K:214:0x86/0x82
-
-# Curse Armor
-K:215:0x86/0x82
-
-# Summon Undead
-K:216:0x86/0x80
-
-# Blessing
-K:217:0x86/0x80
-
-# Holy Chant
-K:218:0x86/0x80
-
-# Holy Prayer
-K:219:0x86/0x81
-
-# Word of Recall
-K:220:0x86/0x80
-
-# *Destruction*
-K:221:0x86/0x82
-
-# Slime Mold Juice
-K:222:0xBC/0x85
-
-# Apple Juice
-K:223:0xBC/0x85
-
-# Water
-K:224:0xBC/0x85
-
-# Strength
-K:225:0xBC/0x86
-
-# Weakness
-K:226:0xBC/0x85
-
-# Restore Strength
-K:227:0xBC/0x86
-
-# Intelligence
-K:228:0xBC/0x86
-
-# Stupidity
-K:229:0xBC/0x85
-
-# Restore Intelligence
-K:230:0xBC/0x86
-
-# Wisdom
-K:231:0xBC/0x86
-
-# Naivety
-K:232:0xBC/0x85
-
-# Restore Wisdom
-K:233:0xBC/0x86
-
-# Charisma
-K:234:0xBC/0x86
-
-# Ugliness
-K:235:0xBC/0x86
-
-# Restore Charisma
-K:236:0xBC/0x86
-
-# Curing
-K:237:0xBC/0x86
-
-# Invulnerability
-K:238:0xBC/0x86
-
-# New Life
-K:239:0xBC/0x86
-
-# Cure Serious Wounds
-K:240:0xBC/0x85
-
-# Cure Critical Wounds
-K:241:0xBC/0x85
-
-# Healing
-K:242:0xBC/0x85
-
-# Constitution
-K:243:0xBC/0x86
-
-# Experience
-K:244:0xBC/0x87
-
-# Sleep
-K:245:0xBC/0x85
-
-# Blindness
-K:246:0xBC/0x85
-
-# Booze
-K:247:0xBC/0x85
-
-# Poison
-K:248:0xBC/0x85
-
-# Speed
-K:249:0xBC/0x85
-
-# Slowness
-K:250:0xBC/0x85
-
-# Dexterity
-K:251:0xBC/0x86
-
-# Restore Dexterity
-K:252:0xBC/0x86
-
-# Restore Constitution
-K:253:0xBC/0x86
-
-# Lose Memories
-K:254:0xBC/0x85
-
-# Salt Water
-K:255:0xBC/0x85
-
-# Enlightenment
-K:256:0xBC/0x85
-
-# Heroism
-K:257:0xBC/0x85
-
-# Berserk Strength
-K:258:0xBC/0x85
-
-# Boldness
-K:259:0xBC/0x85
-
-# Restore Life Levels
-K:260:0xBC/0x87
-
-# Resist Heat
-K:261:0xBC/0x85
-
-# Resist Cold
-K:262:0xBC/0x85
-
-# Detect Invisible
-K:263:0xBC/0x85
-
-# Slow Poison
-K:264:0xBC/0x85
-
-# Neutralise Poison
-K:265:0xBC/0x85
-
-# Restore Mana
-K:266:0xBC/0x86
-
-# Infra-vision
-K:267:0xBC/0x85
-
-# Resistance
-K:268:0xBC/0x85
-
-# Light
-K:269:0xB7/0x8F
-
-# Tame Monster
-K:270:0xB7/0x8F
-
-# Frost Bolts
-K:271:0xB7/0x8F
-
-# Fire Bolts
-K:272:0xB7/0x90
-
-# Stone to Mud
-K:273:0xB7/0x8F
-
-# Polymorph
-K:274:0xB7/0x8F
-
-# Heal Monster
-K:275:0xB7/0x8F
-
-# Haste Monster
-K:276:0xB7/0x8F
-
-# Slow Monster
-K:277:0xB7/0x8F
-
-# Confuse Monster
-K:278:0xB7/0x8F
-
-# Sleep Monster
-K:279:0xB7/0x8F
-
-# Drain Life
-K:280:0xB7/0x91
-
-# Trap
-K:281:0xB7/0x8F
-
-# Magic Missile
-K:282:0xB7/0x8F
-
-# Clone Monster
-K:283:0xB7/0x90
-
-# Scare Monster
-K:284:0xB7/0x90
-
-# Teleport Other
-K:285:0xB7/0x8F
-
-# Disarming
-K:286:0xB7/0x8F
-
-# Lightning Balls
-K:287:0xB7/0x90
-
-# Cold Balls
-K:288:0xB7/0x90
-
-# Fire Balls
-K:289:0xB7/0x91
-
-# Stinking Cloud
-K:290:0xB7/0x8F
-
-# Acid Balls
-K:291:0xB7/0x91
-
-# Wonder
-K:292:0xB7/0x8F
-
-# & Flight Arrow~
-K:293:0xCD/0x86
-
-# Acid Bolts
-K:294:0xB7/0x90
-
-# Dragon's Flame
-K:295:0xB7/0x91
-
-# Dragon's Frost
-K:296:0xB7/0x91
-
-# Dragon's Breath
-K:297:0xB7/0x91
-
-# Annihilation
-K:298:0xB7/0x91
-
-# Rockets
-K:299:0xB7/0x91
-
-# Trap Location
-K:300:0xB9/0x99
-
-# Treasure Location
-K:301:0xB9/0x99
-
-# Object Location
-K:302:0xB9/0x99
-
-# Teleportation
-K:303:0xB9/0x99
-
-# Earthquakes
-K:304:0xB9/0x9A
-
-# Summoning
-K:305:0xB9/0x99
-
-# Light
-K:306:0xB9/0x99
-
-# *Destruction*
-K:307:0xB9/0x9B
-
-# Starlight
-K:308:0xB9/0x99
-
-# Haste Monsters
-K:309:0xB9/0x99
-
-# Slow Monsters
-K:310:0xB9/0x99
-
-# Sleep Monsters
-K:311:0xB9/0x99
-
-# Cure Light Wounds
-K:312:0xB9/0x99
-
-# Detect Invisible
-K:313:0xB9/0x99
-
-# Speed
-K:314:0xB9/0x9A
-
-# Slowness
-K:315:0xB9/0x99
-
-# Door
-K:316:0xB9/0x99
-
-# Remove Curse
-K:317:0xB9/0x9A
-
-# Detect Evil
-K:318:0xB9/0x99
-
-# Curing
-K:319:0xB9/0x9A
-
-# Dispel Evil
-K:320:0xB9/0x9B
-
-# Probing
-K:321:0xB9/0x9A
-
-# Darkness
-K:322:0xB9/0x99
-
-# Genocide
-K:323:0xB9/0x9B
-
-# Power
-K:324:0xB9/0x9C
-
-# the Magi
-K:325:0xB9/0x9C
-
-# Perception
-K:326:0xB9/0x99
-
-# Holiness
-K:327:0xB9/0x9C
-
-# Enlightenment
-K:328:0xB9/0x9A
-
-# Healing
-K:329:0xB9/0x9C
-
-# [Call of the West]
-K:330:0xA3/0x8A
-
-# [Light of Valinor]
-K:331:0xA3/0x8A
-
-# [Divine Mastery]
-K:332:0xA3/0x8A
-
-# [Words of Power]
-K:333:0xA3/0x8A
-
-# [Apprentice Handbook]
-K:334:0xA3/0x8C
-
-# [Mystical Words]
-K:335:0xA3/0x8C
-
-# [Arcane Chants]
-K:336:0xA3/0x8C
-
-# [Locus of Force]
-K:337:0xA3/0x8C
-
-# & Small wooden chest~
-K:338:0x80/0x96
-
-# & Large wooden chest~
-K:339:0x80/0x97
-
-# & Small iron chest~
-K:340:0x80/0x98
-
-# & Large iron chest~
-K:341:0x80/0x99
-
-# & Small steel chest~
-K:342:0x80/0x9A
-
-# & Large steel chest~
-K:343:0x80/0x9B
-
-# & Ruined chest~
-K:344:0x80/0x9C
-
-# & Iron Spike~
-K:345:0x8B/0x84
-
-# & Wooden Torch~
-K:346:0x8B/0x86
-
-# & Brass Lantern~
-K:347:0x8B/0x85
-
-# & Flask~ of oil
-K:348:0xBC/0x90
-
-# & Empty Bottle~
-K:349:0x8A/0x99
-
-# Havoc
-K:350:0xB8/0x94
-
-# Door
-K:351:0xB8/0x94
-
-# Trap Location
-K:352:0xB8/0x94
-
-# Probing
-K:353:0xB8/0x97
-
-# Recall
-K:354:0xB8/0x96
-
-# Illumination
-K:355:0xB8/0x95
-
-# Light
-K:356:0xB8/0x94
-
-# Lightning Bolts
-K:357:0xB8/0x94
-
-# Frost Bolts
-K:358:0xB8/0x95
-
-# Fire Bolts
-K:359:0xB8/0x95
-
-# Polymorph
-K:360:0xB8/0x95
-
-# Slow Monster
-K:361:0xB8/0x95
-
-# Sleep Monster
-K:362:0xB8/0x95
-
-# Drain Life
-K:363:0xB8/0x97
-
-# Teleport Other
-K:364:0xB8/0x96
-
-# Disarming
-K:365:0xB8/0x95
-
-# Lightning Balls
-K:366:0xB8/0x96
-
-# Cold Balls
-K:367:0xB8/0x96
-
-# Fire Balls
-K:368:0xB8/0x97
-
-# Acid Balls
-K:369:0xB8/0x97
-
-# Acid Bolts
-K:370:0xB8/0x95
-
-# Enlightenment
-K:371:0xB8/0x97
-
-# Perception
-K:372:0xB8/0x96
-
-# Curing
-K:373:0xB8/0x97
-
-# Healing
-K:374:0xB8/0x97
-
-# Detection
-K:375:0xB8/0x95
-
-# Restoration
-K:376:0xB8/0x97
-
-# Speed
-K:377:0xB8/0x97
-
-# [Inner Void]
-K:378:0xA3/0x8E
-
-# [Lurkings of the Night]
-K:379:0xA3/0x8E
-
-# [Beings of Darkness]
-K:380:0xA3/0x8E
-
-# [Material Shadow]
-K:381:0xA3/0x8E
-
-# [Sign of Chaos]
-K:383:0xA3/0x90
-
-# [Chaos Mastery]
-K:384:0xA3/0x90
-
-# [Chaos Channels]
-K:385:0xA3/0x91
-
-# [Armageddon Tome]
-K:386:0xA3/0x91
-
-# [Nether Openings]
-K:387:0xA3/0x92
-
-# [Unholy Blessings]
-K:388:0xA3/0x92
-
-# & Firestone~
-K:389:0x8B/0x88
-
-# & Small Firestone~
-K:390:0x8B/0x89
-
-# & Broken Skull~
-K:391:0x8B/0x8A
-
-# & Broken Bone~
-K:392:0x8B/0x8B
-
-# & Canine Skeleton~
-K:393:0x8B/0x87
-
-# & Rodent Skeleton~
-K:394:0x8B/0x87
-
-# & Human Skeleton~
-K:395:0x8B/0x87
-
-# & Dwarf Skeleton~
-K:396:0x8B/0x87
-
-# & Elf Skeleton~
-K:397:0x8B/0x87
-
-# & Gnome Skeleton~
-K:398:0x8B/0x87
-
-# & Great Hammer~
-K:399:0xCD/0x87
-
-# Black Dragon Scale Mail~
-K:400:0x88/0x9F
-
-# Blue Dragon Scale Mail~
-K:401:0x88/0x9D
-
-# White Dragon Scale Mail~
-K:402:0x88/0x9E
-
-# Red Dragon Scale Mail~
-K:403:0x89/0x81
-
-# Green Dragon Scale Mail~
-K:404:0x89/0x80
-
-# Multi-Hued Dragon Scale Mail~
-K:405:0x89/0x82
-
-# Pseudo Dragon Scale Mail~
-K:406:0xBB/0x9C
-
-# Law Dragon Scale Mail~
-K:407:0x88/0x9F
-
-# Bronze Dragon Scale Mail~
-K:408:0x88/0x96
-
-# Gold Dragon Scale Mail~
-K:409:0x88/0x9C
-
-# Chaos Dragon Scale Mail~
-K:410:0x89/0x80
-
-# Balance Dragon Scale Mail~
-K:411:0x88/0x99
-
-# Power Dragon Scale Mail~
-K:412:0xA2/0x9E
-
-# & Dragon Helm~
-K:413:0xA2/0x9D
-
-# & Dragon Shield~
-K:414:0xA2/0x9C
-
-# Death
-K:415:0xBC/0x88
-
-# Ruination
-K:416:0xBC/0x87
-
-# Detonations
-K:417:0xBC/0x87
-
-# Augmentation
-K:418:0xBC/0x87
-
-# *Healing*
-K:419:0xBC/0x87
-
-# Life
-K:420:0xBC/0x88
-
-# Self Knowledge
-K:421:0xBC/0x87
-
-# *Enlightenment*
-K:422:0xBC/0x88
-
-# [Necromantic Incantations]
-K:423:0xA3/0x92
-
-# [Curses of Angmar]
-K:424:0xA3/0x92
-
-# Fear Resistance
-K:425:0xB5/0x81
-
-# Light and Darkness Resistance
-K:426:0xB5/0x81
-
-# Nether Resistance
-K:427:0xB5/0x81
-
-# Nexus Resistance
-K:428:0xB5/0x81
-
-# Sound Resistance
-K:429:0xB5/0x81
-
-# Confusion Resistance
-K:430:0xB5/0x81
-
-# Shard Resistance
-K:431:0xB5/0x81
-
-# Disenchantment Resistance
-K:432:0xB5/0x81
-
-# Chaos Resistance
-K:433:0xB5/0x81
-
-# Blindness Resistance
-K:434:0xB5/0x81
-
-# Lordly Protection
-K:435:0xB5/0x81
-
-# Extra Attacks
-K:436:0xB5/0x81
-
-# Cure Light Wounds
-K:437:0xBC/0x85
-
-# Clumsiness
-K:438:0xBC/0x85
-
-# Sickliness
-K:439:0xBC/0x85
-
-# Map of Bree
-K:440:0xD8/0x81
-
-# Map of Gondolin
-K:441:0xD8/0x81
-
-# Map of Lothlorien
-K:442:0xD8/0x81
-
-# Map of Minas Anor
-K:443:0xD8/0x81
-
-# & Silver Arrow~
-K:465:0xCE/0x91
-
-# & Silver Bolt~
-K:466:0xCE/0x92
-
-# Lightning Resistance
-K:467:0x87/0x80
-
-# Wisdom
-K:468:0x87/0x80
-
-# Regeneration
-K:469:0x87/0x80
-
-# Infravision
-K:470:0x87/0x80
-
-# Devotion
-K:471:0x87/0x80
-
-# Weaponmastery
-K:472:0x87/0x80
-
-# Trickery
-K:473:0x87/0x80
-
-# ESP
-K:474:0x87/0x80
-
-# Sustenance
-K:475:0x87/0x80
-
-# Palantir
-K:476:0xD8/0x8F
-
-# Elfstone 'Elessar'
-K:477:0xB6/0x8F
-
-# Jewel 'Evenstar'
-K:478:0xB6/0x90
-
-# Ring of Durin
-K:479:0xB5/0x8E
-
-# copper
-K:480:0x80/0x8B
-K:481:0x80/0x8B
-K:482:0x80/0x8B
-
-# silver
-K:483:0x80/0x8C
-K:484:0x80/0x8C
-K:485:0x80/0x8C
-
-# garnets
-K:486:0x80/0x8F
-K:487:0x80/0x8F
-
-# gold
-K:488:0x80/0x8D
-K:489:0x80/0x8D
-K:490:0x80/0x8D
-
-# opals
-K:491:0x80/0x90
-
-# sapphires
-K:492:0x80/0x91
-
-# rubies
-K:493:0x80/0x92
-
-# diamonds
-K:494:0x80/0x93
-
-# emeralds
-K:495:0x80/0x94
-
-# mithril
-K:496:0x80/0x8E
-
-# adamantite
-K:497:0xA3/0x95
-
-# & Mighty Hammer~
-K:498:0x87/0x9A
-
-# & Massive Iron Crown~
-K:499:0x87/0x9B
-
-# & Phial~
-K:500:0x87/0x9D
-
-# & Star~
-K:501:0x87/0x9E
-
-# & Arkenstone~
-K:502:0x87/0x9F
-
-# & Amulet~
-K:503:0xB6/0x82
-K:504:0xB6/0x83
-
-# & Necklace~
-K:505:0xB6/0x84
-
-# & Ring~
-K:506:0xB5/0x83
-K:507:0xB5/0x83
-K:508:0xB5/0x84
-K:509:0xB5/0x85
-K:510:0xB5/0x86
-K:511:0xB5/0x87
-
-# [Rites of Initiation]
-K:512:0xBC/0x91
-
-# [Ways of War]
-K:513:0xBC/0x91
-
-# [Divine Retribution]
-K:514:0xBC/0x92
-
-# [Essence of Fury]
-K:515:0xBC/0x92
-
-# [Novice Crafts]
-K:516:0xBC/0x95
-
-# [Arcane Channels]
-K:517:0xBC/0x95
-
-# [Sigils of Wizardry]
-K:518:0xBC/0x95
-
-# [Mana Focus]
-K:519:0xBC/0x95
-
-# Reflection
-K:520:0xB6/0x80
-
-# Anti-Magic
-K:521:0xB6/0x80
-
-# Anti-Teleportation
-K:522:0xB6/0x80
-
-# Resistance
-K:523:0xB6/0x80
-
-# & Zweihander~
-K:524:0xCD/0x88
-
-# & Dwarven Lantern~
-K:525:0xD8/0x86
-
-# Splint Mail~
-K:526:0xCD/0x8A
-
-# & Everburning Torch~
-K:527:0xD8/0x87
-
-# & Trifurcate Spear~
-K:528:0xCD/0x96
-
-# & Three Piece Rod~
-K:529:0xCD/0x8C
-
-# & Feanorian Lamp~
-K:530:0xD8/0x85
-
-# & Fur Cloak~
-K:531:0xCD/0x8E
-
-# Potion: Water Curing
-K:532:0xBC/0x84
-
-# & Hatchet~
-K:533:0xCD/0x90
-
-# Rhino Hide Armour~
-K:535:0xCD/0x91
-
-# Leather Jacket~
-K:536:0xCD/0x92
-
-# & Sickle~
-K:537:0xCD/0x93
-
-# [Psychoportation]
-K:538:0xA3/0x88
-
-# [Clairsentience]
-K:539:0xA3/0x88
-
-# [Telekinesis]
-K:540:0xA3/0x89
-
-# [Empathy]
-K:541:0xA3/0x89
-
-# & Club~
-K:542:0xCD/0x99
-
-# & Broad Spear~
-K:543:0xCD/0x9A
-
-# & Khopesh~
-K:544:0xCD/0x9B
-
-# & Flamberge~
-K:545:0xCD/0x9C
-
-# & Claymore~
-K:546:0xCD/0x9D
-
-# & Espadon~
-K:547:0xCD/0x9E
-
-# & Great Scimitar~
-K:548:0xCD/0x9F
-
-# Trapping Kit: Arrow
-K:549:0xD7/0x84
-
-# Trapping Kit: Bolt
-K:550:0xD7/0x83
-
-# & Fauchard~
-K:551:0xCE/0x82
-
-# & Guisarme~
-K:552:0xCE/0x83
-
-# & Heavy Lance~
-K:553:0xCE/0x84
-
-# & Basillard~
-K:554:0xCE/0x85
-
-# Trapping Kit: Catapult
-K:555:0xD7/0x82
-
-# Ring Mail~
-K:556:0xCE/0x87
-
-# Cord Armour~
-K:557:0xCE/0x88
-
-# Paper Armour~
-K:558:0xCE/0x89
-
-# Padded Armour~
-K:559:0xCE/0x8A
-
-# Trap Kit: Fumes
-K:560:0xD7/0x80
-
-# Stone and Hide Armour~
-K:561:0xCE/0x8C
-
-# Trap Kit: Magic
-K:562:0xD7/0x81
-
-# Trap Kit: Device
-K:563:0xD7/0x85
-
-# Scroll: Nothing
-K:564:0x86/0x80
-
-# Poison
-K:565:0xD9/0x82
-
-# Wand: Nothing
-K:566:0xB7/0x90
-
-# Ring: Nothing
-K:567:0xB5/0x80
-
-# Staff: Nothing
-K:568:0xB8/0x96
-
-# Rod Tip: Nothing
-K:569:0xB8/0x95
-
-# Explosion
-K:570:0xD9/0x82
-
-# Teleport
-K:571:0xD9/0x82
-
-# Amulet: Nothing
-K:572:0x87/0x80
-
-# & Blood~ of Life
-K:573:0x87/0x88
-
-# Cold
-K:574:0xD9/0x82
-
-# Fire
-K:575:0xD9/0x82
-
-# Acid
-K:576:0xD9/0x82
-
-# Mage Staff
-K:577:0xCE/0x97
-
-# Lightning
-K:578:0xB5/0x81
-
-# Life
-K:579:0xD9/0x82
-
-# Confusion
-K:580:0xD9/0x82
-
-# Light
-K:581:0xD9/0x82
-
-# Ring of F'Lar
-K:582:0xB5/0x8F
-
-# Invisibility
-K:583:0xB8/0x85
-
-# Chaos
-K:584:0xD9/0x82
-
-# Corruption
-K:585:0xB8/0x85
-
-# Invisibility
-K:586:0xB5/0x81
-
-# Time
-K:587:0xD9/0x82
-
-# Deep Thoughts
-K:588:0xD8/0x80
-
-# More Deep Thoughts
-K:589:0xD8/0x80
-
-# Compendium of Deep Thoughts
-K:590:0xD8/0x80
-
-# Artifact Lore Vol. I
-K:591:0xD8/0x80
-
-# Artifact Lore Vol. II
-K:592:0xD8/0x80
-
-# Artifact Lore Vol. III
-K:593:0xD8/0x80
-
-# Monstrous Compendium 1
-K:594:0xD8/0x80
-
-# Monstrous Compendium 2
-K:595:0xD8/0x80
-
-# Monstrous Compendium 3
-K:596:0xD8/0x80
-
-# Monstrous Compendium 4
-K:597:0xD8/0x80
-
-# Monstrous Compendium 5
-K:598:0xD8/0x80
-
-# Monstrous Compendium 6
-K:599:0xD8/0x80
-
-# Monstrous Compendium 7
-K:600:0xD8/0x80
-
-# Monstrous Compendium 8
-K:601:0xD8/0x80
-
-# Monstrous Compendium 9
-K:602:0xD8/0x80
-
-# Monstrous Compendium 10
-K:603:0xD8/0x80
-
-# Monstrous Compendium 11
-K:604:0xD8/0x80
-
-# Abomination
-K:605:0xBC/0x85
-
-# Shape of Wolf
-K:606:0xBC/0x85
-
-# Shape of Ape
-K:607:0xBC/0x85
-
-# Shape of Goat
-K:608:0xBC/0x85
-
-# Shape of Insect
-K:609:0xBC/0x85
-
-# Shape of Sparrow
-K:610:0xBC/0x85
-
-# Shape of Ent
-K:611:0xBC/0x85
-
-# Shape of Vampire
-K:612:0xBC/0x85
-
-# Shape of Spider
-K:613:0xBC/0x85
-
-# Shape of Mana ball
-K:614:0xBC/0x85
-
-# Shape of Fire cloud
-K:615:0xBC/0x85
-
-# Shape of Cold cloud
-K:616:0xBC/0x85
-
-# Shape of Chaos cloud
-K:617:0xBC/0x85
-
-# [Wolf]
-K:618:0xCE/0x93
-
-# [Ape]
-K:619:0xCE/0x93
-
-# [Goat]
-K:620:0xCE/0x93
-
-# [Insect]
-K:621:0xCE/0x93
-
-# [Sparrow]
-K:622:0xCE/0x93
-
-# [Ent]
-K:623:0xCE/0x93
-
-# [Vampire]
-K:624:0xCE/0x93
-
-# [Spider]
-K:625:0xCE/0x93
-
-# [Mana ball]
-K:626:0xCE/0x93
-
-# [Fire cloud]
-K:627:0xCE/0x93
-
-# [Cold cloud]
-K:628:0xCE/0x93
-
-# [Chaos Cloud]
-K:629:0xCE/0x93
-
-# [Ghost]
-K:630:0xCE/0x93
-
-# [Kobold]
-K:631:0xCE/0x93
-
-# [Dragon]
-K:632:0xCE/0x93
-
-# [Demon]
-K:633:0xCE/0x93
-
-# [Hound]
-K:634:0xCE/0x93
-
-# [Quylthulg]
-K:635:0xCE/0x93
-
-# [Maia]
-K:636:0xCE/0x93
-
-# [Serpent]
-K:637:0xCE/0x93
-
-# [Giant]
-K:638:0xCE/0x93
-
-# [Vala]
-K:639:0xCE/0x93
-
-# Magic
-K:640:0xD9/0x82
-
-# corpse
-K:641:0xB4/0x90
-
-# skeleton
-K:642:0xB4/0x8B
-
-# head
-K:643:0xB4/0x8E
-
-# skull
-K:644:0xB4/0x8F
-
-# raw meat
-K:645:0xB4/0x8C
-
-# Dragonrider Coat
-K:646:0xCE/0x98
-
-# Stone of Lore
-K:647:0xD8/0x90
-
-# small wooden boomerang
-K:648:0xCE/0x99
-
-# large wooden boomerang
-K:649:0xCE/0x9A
-
-# small metal boomerang
-K:650:0xCE/0x9B
-
-# large metal boomerang
-K:651:0xCE/0x9C
-
-# The Space-Time Anchor
-K:652:0xD8/0x91
-
-# Summon never-moving pet
-K:654:0x86/0x80
-
-# [Life in symbiosis]
-K:655:0xA3/0x84
-
-# [Perfect Symbiosis]
-K:656:0xA3/0x85
-
-# Cure Light Insanity
-K:657:0xBC/0x85
-
-# Cure Serious Insanity
-K:658:0xBC/0x85
-
-# Cure Critical Insanity
-K:659:0xBC/0x85
-
-# Cure Insanity
-K:660:0xBC/0x85
-
-# & Phial~
-K:661:0x87/0x9D
-
-# Craftmanship
-K:663:0x86/0x82
-
-# The One Ring
-K:664:0xD8/0x81
-
-# [Apprentice Handbook]
-K:665:0xA3/0x81
-
-# [Minstrel's Music]
-K:666:0xA3/0x81
-
-# [Harps of Rivendell]
-K:667:0x8A/0x90
-
-# [Lays of Beleriand]
-K:668:0x8A/0x90
-
-# & Flute~
-K:669:0xD8/0x88
-
-# & Drum~
-K:670:0xD8/0x89
-
-# & Harp~
-K:671:0xD8/0x8A
-
-# & Banjo~
-K:672:0xD8/0x8B
-
-# & Lute~
-K:673:0xD8/0x8C
-
-# & Mandolin~
-K:674:0xD8/0x8D
-
-# Palantir of Orthanc
-K:675:0xD8/0x8F
-
-# Egg
-K:676:0xD8/0x84
-
-# Reset Recall
-K:677:0x86/0x81
-
-# Divination
-K:678:0x86/0x81
-
-# Rune: Self
-K:679:0xDA/0x80
-
-# Rune: Ray
-K:680:0xDA/0x80
-
-# Rune: Sphere
-K:681:0xDA/0x80
-
-# Rune: Knowledge
-K:682:0xDA/0x80
-
-# Rune: Life
-K:683:0xDA/0x84
-
-# Rune: Fire
-K:684:0xDA/0x81
-
-# Rune: Cold
-K:685:0xDA/0x80
-
-# Rune: Lightning
-K:686:0xDA/0x85
-
-# Rune: Acid
-K:687:0xDA/0x88
-
-# Rune: Element
-K:688:0xDA/0x89
-
-# Rune: Chaos
-K:689:0xDA/0x83
-
-# Rune: Mind
-K:690:0xDA/0x84
-
-# Rune: Holding
-K:691:0xDA/0x84
-
-# Rune: Arrow
-K:692:0xDA/0x80
-
-# Rune: Power Surge
-K:693:0xDA/0x80
-
-# Rune: Armageddon
-K:694:0xDA/0x80
-
-# Rune: Gravity
-K:695:0xDA/0x82
-
-# Essence: Extra Life
-K:696:0xD9/0x82
-
-# Rune: Undeath
-K:697:0xDA/0x82
-
-# Rune: Protection
-K:698:0xDA/0x82
-
-# Horn
-K:699:0xD8/0x8E
-
-# The Ring of Precognition
-K:700:0xB5/0x8E
-
-# Sprig of Athelas
-K:701:0xCE/0x96
-
-# [Magic for Beginners]
-K:702:0x8A/0x80
-
-# [Conjurings and Tricks]
-K:703:0x8A/0x80
-
-# [Incantations and Illusions]
-K:704:0x8A/0x80
-
-# [Sorcery and Evocations]
-K:705:0x8A/0x80
-
-# [Beginners Handbook]
-K:706:0x8A/0x89
-
-# [Words of Wisdom]
-K:707:0x8A/0x89
-
-# [Chants and Blessings]
-K:708:0x8A/0x89
-
-# [Exorcism and Dispelling]
-K:709:0x8A/0x89
-
-# [Resistance of Scarabtarices]
-K:710:0x8A/0x88
-
-# [Mordenkainen's Escapes]
-K:711:0x8A/0x88
-
-# [Kelek's Grimoire of Power]
-K:712:0x8A/0x88
-
-# [Tenser's Transformations]
-K:713:0x8A/0x88
-
-# [Raal's Tome of Destruction]
-K:714:0x8A/0x88
-
-# [Ethereal Openings]
-K:715:0x8A/0x85
-
-# [Godly Insights]
-K:716:0x8A/0x85
-
-# [Purifications and Healing]
-K:717:0x8A/0x85
-
-# [Holy Infusions]
-K:718:0x8A/0x85
-
-# [Wrath of God]
-K:719:0x8A/0x85
-
-# & Old Scroll~ of Deincarnation
-K:720:0x85/0x80
-
-# Dark Sword
-K:721:0xCE/0x9D
-
-# Numenorean for beginners (I)
-K:722:0xD8/0x81
-
-# Numenorean for beginners (II)
-K:723:0xD8/0x81
-
-# Advanced lessons of Numenorean
-K:724:0xD8/0x81
-
-# Advanced lessons of Sindarin
-K:725:0xD8/0x81
-
-# & Shard~ of Pottery
-K:726:0x8B/0x88
-
-# & Broken Stick~
-K:727:0x8B/0x89
-
-# Wall Creation
-K:728:0xB5/0x80
-
-# [Illusions for Beginners]
-K:729:0xA3/0x86
-
-# [Tricks and Visions]
-K:730:0xA3/0x86
-
-# [Phantasms and Illusions]
-K:731:0xA3/0x86
-
-# [Shadows and Prisms]
-K:732:0xA3/0x86
-
-# [Serten's Immunities]
-K:733:0xA3/0x87
-
-# [Knowledge of Kenault]
-K:734:0xA3/0x87
-
-# [Otiluke's Spheres]
-K:735:0xA3/0x87
-
-# [Boccob's Book of Shadows]
-K:736:0xA3/0x87
-
-# [Bigby's Handbook]
-K:737:0xA3/0x87
-
-# [Hunt of Orome]
-K:738:0xA3/0x8B
-
-# [Holy Sanctifications]
-K:739:0xA3/0x8B
-
-# [Secrets of the Feanturi]
-K:740:0xA3/0x8B
-
-# [War of Wrath]
-K:741:0xA3/0x8B
-
-# [Gifts of Iluvatar]
-K:742:0xA3/0x8B
-
-# & Potion~ of Learning
-K:743:0x87/0x86
-
-# [Eye of Sauron]
-K:744:0xA3/0x93
-
-# [Flame of Udun]
-K:745:0xA3/0x93
-
-# [Corruptions of Melkor]
-K:746:0xA3/0x93
-
-# [Crescent of Morgul]
-K:747:0xA3/0x93
-
-# [Morgoth's Ring]
-K:748:0xA3/0x93
-
-# Scroll: Spell
-K:749:0x86/0x82
-
-# Staff: Wishing
-K:750:0xB9/0x9B
-
-# Khuzdul - The hidden tongue of the Dwarves
-K:751:0xD8/0x81
-
-# Nandorin for dummies
-K:752:0xD8/0x81
-
-# Advanced lessons of Orcish
-K:753:0xD8/0x81
-
-# Ring: Flying
-K:755:0xB5/0x80
-
-# [Powerful Sigils]
-K:756:0xA3/0x8D
-
-# [Disruptive Forces]
-K:758:0xA3/0x8D
-
-# [Forces of the Mind]
-K:759:0xA3/0x8D
-
-# [Power of Ancient Sorcerors]
-K:760:0xA3/0x8D
-
-# [Tricks of the Wild]
-K:761:0xBC/0x93
-
-# [Mastering the Rituals]
-K:762:0xBC/0x93
-
-# [Rites of Power]
-K:763:0xBC/0x94
-
-# [Tribal Power]
-K:764:0xBC/0x94
-
-# [Aiding Shades]
-K:765:0xA3/0x8F
-
-# [Morgoth's Space-Time Warpings]
-K:766:0xA3/0x8F
-
-# [Murazor's Tome of Conjuring & Dispelling]
-K:767:0xA3/0x8F
-
-# [Channeling the Void]
-K:768:0xA3/0x8F
-
-# [Sauron's Forgotten Tome]
-K:769:0xA3/0x8F
-
-# Ring of Phasing
-K:770:0xB5/0x8E
-
-# [Earth]
-K:771:0xD8/0x82
-
-# [Fire]
-K:772:0xD8/0x82
-
-# [Air]
-K:773:0xD8/0x83
-
-# [Water]
-K:774:0xD8/0x83
-
-# [Mana]
-K:775:0xD8/0x83
-
-# Rod Tip: Home Summoning
-K:776:0xB8/0x84
-
-# Shadow Blade
-K:777:0xCD/0x9C
-
-# Bluesteel Blade
-K:778:0xCE/0x9E
-
-# Amulet: of the Serpents
-K:779:0xB6/0x9F
-
-# Darkness
-K:780:0xD9/0x82
-
-# Knowledge
-K:781:0xD9/0x82
-
-# Force
-K:782:0xD9/0x82
-
-# Lightning
-K:783:0xD9/0x82
-
-# Mana
-K:784:0xD9/0x82
-
-# Nazgul Ring
-K:785:0xB5/0x85
-
-# Climbing Set
-K:786:0xD8/0x92
-
-# Adventurer's guide to Middle-earth
-K:787:0xD8/0x80
-
-# [Dark Incantations]
-K:788:0xCE/0x94
-
-# [Immortal Rituals]
-K:789:0xCE/0x94
-
-# [Minions of Azathoth]
-K:790:0xCE/0x95
-
-# [Demonthoughts]
-K:791:0xCE/0x95
-
-# [Hellfire Tome]
-K:792:0xCE/0x95
-
-# Rod: Wooden
-K:793:0xDB/0x80
-
-# Rod: Copper
-K:794:0xDB/0x81
-
-# Rod: Iron
-K:795:0xDB/0x82
-
-# Rod: Aluminium
-K:796:0xDB/0x83
-
-# Rod: Silver
-K:797:0xDB/0x84
-
-# Rod: Golden
-K:798:0xDB/0x85
-
-# Rod: Mithril
-K:799:0xDB/0x86
-
-# Rod: Adamantite
-K:800:0xDB/0x87
-
-# Greater Ration of Health
-K:801:0x8A/0x9E
-
-# Scroll of Mass Ressurrection
-K:802:0x86/0x82
-
-# Cleaver
-K:803:0xD8/0x93
-
-# Light War Axe
-K:804:0xD8/0x94
-
-# Slaughter Axe
-K:805:0xD8/0x95
-
-# Runestone
-K:806:0xDA/0x83
-
-# Fortune Cookie
-K:807:0x8A/0x93
-
-# Portable Hole
-K:808:0xD8/0x96
-
-# Ring: Critical Hits
-K:809:0xB5/0x82
-
-# Wand of Digging of Thrain
-K:810:0xB8/0x97
-
-# Gnarled Staff of Holy Fire of Mithrandir
-K:811:0xCE/0x9F
-
-# Partial Totem
-K:812:0xB4/0x82
-
-# True Totem
-K:813:0xB4/0x85
-
-# Player
-R:0:0x8C/0x81
-
-# Filthy street urchin
-R:1:0x9B/0x8A
-
-# Scrawny cat
-R:2:0x98/0x8B
-
-# Sparrow
-R:3:0xBD/0x87
-
-# Chaffinch
-R:4:0xBD/0x86
-
-# Wild rabbit
-R:5:0xBF/0x85
-
-# Woodsman
-R:6:0xBD/0x88
-
-# Scruffy little dog
-R:7:0x8E/0x9D
-
-# Farmer Maggot
-R:8:0x9B/0x8B
-
-# Blubbering idiot
-R:9:0x9B/0x8C
-
-# Boil-covered wretch
-R:10:0x9B/0x8D
-
-# Village idiot
-R:11:0x9B/0x8E
-
-# Pitiful-looking beggar
-R:12:0xBB/0x82
-
-# Mangy-looking leper
-R:13:0x9B/0x90
-
-# Agent of the black market
-R:14:0xA2/0x94
-
-# Singing, happy drunk
-R:15:0x9B/0x92
-
-# Aimless-looking merchant
-R:16:0x9B/0x93
-
-# Mean-looking mercenary
-R:17:0x9B/0x94
-
-# Battle-scarred veteran
-R:18:0x9B/0x95
-
-# Martti Ihrasaari
-R:19:0xA1/0x8D
-
-# Grey mold
-R:20:0x9A/0x88
-
-# Large white snake
-R:21:0x93/0x8A
-
-# Grey mushroom patch
-R:22:0x8E/0x85
-
-# Newt
-R:23:0xA0/0x86
-
-# Giant white centipede
-R:24:0x96/0x9E
-
-# White icky thing
-R:25:0x99/0x8C
-
-# Clear icky thing
-R:26:0x99/0x8D
-
-# Giant white mouse
-R:27:0x9D/0x8F
-
-# Large brown snake
-R:28:0x93/0x92
-
-# Small kobold
-R:29:0x9A/0x82
-
-# Kobold
-R:30:0x9A/0x83
-
-# White worm mass
-R:31:0x9E/0x88
-
-# Floating eye
-R:32:0x98/0x84
-
-# Rock lizard
-R:33:0x93/0x8B
-
-# Grid bug
-R:34:0xA2/0x9B
-
-# Jackal
-R:35:0x8E/0x9E
-
-# Soldier ant
-R:36:0x96/0x8F
-
-# Fruit bat
-R:37:0x96/0x98
-
-# Insect swarm
-R:38:0xBD/0x89
-
-# The Greater hell-beast
-R:39:0xA2/0x82
-
-# Shrieker mushroom patch
-R:40:0x8E/0x86
-
-# Blubbering icky thing
-R:41:0x99/0x8E
-
-# Metallic green centipede
-R:42:0x96/0x9F
-
-# Novice warrior
-R:43:0x9B/0x96
-
-# Novice rogue
-R:44:0x9B/0x97
-
-# Novice priest
-R:45:0x9B/0x98
-
-# Novice mage
-R:46:0x9B/0x99
-
-# Yellow mushroom patch
-R:47:0x8E/0x87
-
-# White jelly
-R:48:0x99/0x93
-
-# Giant black ant
-R:49:0x96/0x90
-
-# Salamander
-R:50:0x93/0x8D
-
-# White harpy
-R:51:0x91/0x8C
-
-# Blue yeek
-R:52:0x9E/0x92
-
-# Grip, Farmer Maggot's dog
-R:53:0x8E/0x9F
-
-# Wolf, Farmer Maggot's dog
-R:54:0xBD/0x8A
-
-# Fang, Farmer Maggot's dog
-R:55:0x8F/0x80
-
-# Giant green frog
-R:56:0x93/0x8C
-
-# Freesia
-R:57:0xBC/0x98
-
-# Green worm mass
-R:58:0x9E/0x89
-
-# Large yellow snake
-R:59:0x93/0x91
-
-# Cave spider
-R:60:0x94/0x82
-
-# Crow
-R:61:0xBD/0x8B
-
-# Wild cat
-R:62:0x98/0x8C
-
-# Smeagol
-R:63:0x9B/0x9A
-
-# Green ooze
-R:64:0x99/0x94
-
-# Poltergeist
-R:65:0x90/0x9D
-
-# Yellow jelly
-R:66:0x99/0x96
-
-# Metallic blue centipede
-R:67:0x97/0x80
-
-# Raven
-R:68:0xBD/0x8C
-
-# Giant white louse
-R:69:0x9A/0x86
-
-# Giant yellow centipede
-R:70:0x96/0x9D
-
-# Black naga
-R:71:0x9A/0x91
-
-# Spotted mushroom patch
-R:72:0x8E/0x88
-
-# Silver jelly
-R:73:0x99/0x95
-
-# Scruffy-looking hobbit
-R:74:0x98/0x9C
-
-# Giant white ant
-R:75:0x96/0x91
-
-# Yellow mold
-R:76:0x9A/0x89
-
-# Metallic red centipede
-R:77:0x97/0x81
-
-# Yellow worm mass
-R:78:0x9E/0x8A
-
-# Clear worm mass
-R:79:0x9E/0x8B
-
-# Radiation eye
-R:80:0x98/0x85
-
-# Yellow light
-R:81:0xBD/0x92
-
-# Cave lizard
-R:82:0x93/0x8F
-
-# Novice ranger
-R:83:0x9B/0x9B
-
-# Blue jelly
-R:84:0x99/0x97
-
-# Creeping copper coins
-R:85:0x8E/0x80
-
-# Giant white rat
-R:86:0x9D/0x90
-
-# Snotling
-R:87:0xBD/0x8D
-
-# Swordfish
-R:88:0xBE/0x81
-
-# Blue worm mass
-R:89:0x9E/0x8C
-
-# Large grey snake
-R:90:0x93/0x90
-
-# Skeleton kobold
-R:91:0x9D/0x93
-
-# Ewok
-R:92:0xBB/0x90
-
-# Novice mage
-R:93:0x9B/0x9D
-
-# Green naga
-R:94:0x9A/0x92
-
-# Giant leech
-R:95:0xBD/0x8E
-
-# Barracuda
-R:96:0xBE/0x82
-
-# Novice paladin
-R:97:0x9B/0x9C
-
-# Zog
-R:98:0xBD/0x8F
-
-# Blue ooze
-R:99:0x99/0x98
-
-# Green glutton ghost
-R:100:0x90/0x9E
-
-# Green jelly
-R:101:0x99/0x99
-
-# Large kobold
-R:102:0x9A/0x84
-
-# Grey icky thing
-R:103:0x99/0x8F
-
-# Disenchanter eye
-R:104:0x98/0x86
-
-# Red worm mass
-R:105:0x9E/0x8D
-
-# Copperhead snake
-R:106:0x93/0x91
-
-# Death sword
-R:107:0x89/0x85
-
-# Purple mushroom patch
-R:108:0x8E/0x89
-
-# Novice priest
-R:109:0x9B/0x9E
-
-# Novice warrior
-R:110:0x9B/0x9F
-
-# Nibelung
-R:111:0xBB/0x8E
-
-# The disembodied hand that strangled people
-R:112:0x9F/0x87
-
-# Brown mold
-R:113:0x9A/0x8A
-
-# Giant brown bat
-R:114:0x96/0x99
-
-# Rat-thing
-R:115:0xBD/0x90
-
-# Novice rogue
-R:116:0x9C/0x81
-
-# Creeping silver coins
-R:117:0x8E/0x81
-
-# Snaga
-R:118:0x9A/0x97
-
-# Rattlesnake
-R:119:0x93/0x92
-
-# Giant slug
-R:120:0xBD/0x93
-
-# Giant pink frog
-R:121:0x93/0x93
-
-# Dark elf
-R:122:0x98/0x9E
-
-# Zombified kobold
-R:123:0x9E/0x97
-
-# Crypt creep
-R:124:0x9F/0x93
-
-# Rotting corpse
-R:125:0xBB/0x8B
-
-# Cave orc
-R:126:0x9A/0x98
-
-# Wood spider
-R:127:0x94/0x83
-
-# Manes
-R:128:0x91/0x96
-
-# Bloodshot eye
-R:129:0x98/0x87
-
-# Red naga
-R:130:0x9A/0x93
-
-# Red jelly
-R:131:0x99/0x9A
-
-# Green icky thing
-R:132:0x99/0x90
-
-# Lost soul
-R:133:0x90/0x9F
-
-# Night lizard
-R:134:0x93/0x94
-
-# Mughash, the Kobold Lord
-R:135:0x9A/0x85
-
-# Skeleton orc
-R:136:0x9D/0x94
-
-# Wormtongue, Agent of Saruman
-R:137:0xBC/0x9A
-
-# Robin Hood, the Outlaw
-R:138:0xBB/0x88
-
-# Nurgling
-R:139:0xBD/0x94
-
-# Lagduf, the Snaga
-R:140:0x9A/0x99
-
-# Brown yeek
-R:141:0x9E/0x93
-
-# Novice ranger
-R:142:0x9B/0x9B
-
-# Giant salamander
-R:143:0x93/0x95
-
-# Space monster
-R:144:0x8A/0x9B
-
-# Carnivorous flying monkey
-R:145:0xBD/0x95
-
-# Green mold
-R:146:0x9A/0x8B
-
-# Novice paladin
-R:147:0x9B/0x9C
-
-# Lemure
-R:148:0x91/0x97
-
-# Hill orc
-R:149:0x9A/0x9A
-
-# Bandit
-R:150:0x9C/0x85
-
-# Hunting hawk
-R:151:0x96/0x99
-
-# Phantom warrior
-R:152:0xA0/0x83
-
-# Gremlin
-R:153:0xA1/0x86
-
-# Yeti
-R:154:0x95/0x99
-
-# Bloodshot icky thing
-R:155:0x99/0x91
-
-# Giant grey rat
-R:156:0x9D/0x91
-
-# Black harpy
-R:157:0x91/0x8D
-
-# Skaven
-R:158:0xBD/0x96
-
-# The wounded bear
-R:159:0xBD/0x98
-
-# Cave bear
-R:160:0xB0/0x82
-
-# Rock mole
-R:161:0xBD/0x99
-
-# Mindcrafter
-R:162:0xB0/0x85
-
-# Baby blue dragon
-R:163:0x97/0x86
-
-# Baby white dragon
-R:164:0x97/0x87
-
-# Baby green dragon
-R:165:0x97/0x88
-
-# Baby black dragon
-R:166:0x97/0x89
-
-# Baby red dragon
-R:167:0x97/0x8A
-
-# Giant red ant
-R:168:0x96/0x96
-
-# Brodda, the Easterling
-R:169:0x9C/0x86
-
-# Bloodfang, the Wolf
-R:170:0xBD/0x9A
-
-# King cobra
-R:171:0x93/0x96
-
-# Eagle
-R:172:0xBD/0x9B
-
-# War bear
-R:173:0x9F/0x9D
-
-# Killer bee
-R:174:0xA0/0x88
-
-# Giant spider
-R:175:0x94/0x87
-
-# Giant white tick
-R:176:0x9D/0x9C
-
-# The Borshin
-R:177:0xBD/0x9C
-
-# Dark elven mage
-R:178:0x98/0x9F
-
-# Kamikaze yeek
-R:179:0xBD/0x9D
-
-# Orfax, Son of Boldor
-R:180:0x9E/0x94
-
-# Servant of Glaaki
-R:181:0xBD/0x9E
-
-# Dark elven warrior
-R:182:0x99/0x80
-
-# Sand-dweller
-R:183:0xBF/0x80
-
-# Clear mushroom patch
-R:184:0x8E/0x8A
-
-# Quiver slot
-R:185:0x89/0x9A
-
-# Grishnakh, the Hill Orc
-R:186:0x9A/0x9C
-
-# Giant tan bat
-R:187:0x96/0x99
-
-# Owlbear
-R:188:0xBF/0x81
-
-# Blue horror
-R:189:0xBF/0x82
-
-# Hairy mold
-R:190:0x9A/0x8C
-
-# Grizzly bear
-R:191:0xBF/0x83
-
-# Disenchanter mold
-R:192:0x9A/0x8D
-
-# Pseudo dragon
-R:193:0xBB/0x9B
-
-# Tengu
-R:194:0x91/0x98
-
-# Creeping gold coins
-R:195:0x8E/0x82
-
-# Wolf
-R:196:0x8F/0x81
-
-# Giant fruit fly
-R:197:0x90/0x95
-
-# Panther
-R:198:0x98/0x8D
-
-# Brigand
-R:199:0x9C/0x87
-
-# Hobbes the Tiger
-R:200:0x98/0x8E
-
-# Shadow Creature of Fiona
-R:201:0xBB/0x8F
-
-# Undead mass
-R:202:0xA0/0x89
-
-# Chaos shapechanger
-R:203:0xA0/0x8E
-
-# Baby multi-hued dragon
-R:204:0x97/0x8C
-
-# Vorpal bunny
-R:205:0xBF/0x84
-
-# Old Man Willow
-R:206:0xBF/0x86
-
-# Hippocampus
-R:207:0xBE/0x85
-
-# Zombified orc
-R:208:0x9E/0x98
-
-# Hippogriff
-R:209:0x91/0x8E
-
-# Black mamba
-R:210:0x93/0x97
-
-# White wolf
-R:211:0x8F/0x82
-
-# Grape jelly
-R:212:0x99/0x9B
-
-# Nether worm mass
-R:213:0x9E/0x8E
-
-# Abyss worm mass
-R:214:0xA0/0x8C
-
-# Golfimbul, the Hill Orc Chief
-R:215:0x9A/0x9D
-
-# Swordsman
-R:216:0x9C/0x89
-
-# Skaven shaman
-R:217:0xBD/0x97
-
-# Baby bronze dragon
-R:218:0xB0/0x89
-
-# Baby gold dragon
-R:219:0xB0/0x8A
-
-# Evil eye
-R:220:0xB0/0x8B
-
-# Mine-dog
-R:221:0xBF/0x88
-
-# Hellcat
-R:222:0xBC/0x97
-
-# Moon beast
-R:223:0xBB/0x9E
-
-# Master yeek
-R:224:0x9E/0x95
-
-# Priest
-R:225:0x9C/0x88
-
-# Dark elven priest
-R:226:0x99/0x82
-
-# Air spirit
-R:227:0x90/0x83
-
-# Skeleton human
-R:228:0x9D/0x95
-
-# Zombified human
-R:229:0x9E/0x99
-
-# Tiger
-R:230:0x98/0x8E
-
-# Moaning spirit
-R:231:0x91/0x80
-
-# Stegocentipede
-R:232:0x97/0x82
-
-# Spotted jelly
-R:233:0x99/0x9C
-
-# Drider
-R:234:0x94/0x85
-
-# Mongbat
-R:235:0xC4/0x80
-
-# Killer brown beetle
-R:236:0x92/0x80
-
-# Boldor, King of the Yeeks
-R:237:0x9E/0x96
-
-# Ogre
-R:238:0x92/0x90
-
-# Creeping mithril coins
-R:239:0x8E/0x83
-
-# Illusionist
-R:240:0x9C/0x8A
-
-# Druid
-R:241:0x9C/0x8B
-
-# Pink horror
-R:242:0xBF/0x89
-
-# Cloaker
-R:243:0xBF/0x8A
-
-# Black orc
-R:244:0x9A/0x9E
-
-# Ochre jelly
-R:245:0x99/0x9D
-
-# Software bug
-R:246:0xA0/0x92
-
-# Lurker
-R:247:0x80/0x80
-
-# Tangleweed
-R:248:0xBE/0x9E
-
-# Vlasta
-R:249:0xBF/0x8C
-
-# Giant white dragon fly
-R:250:0x90/0x97
-
-# Snaga sapper
-R:251:0xBF/0x8D
-
-# Blue icky thing
-R:252:0x99/0x92
-
-# Gibbering mouther
-R:253:0xA0/0x8A
-
-# Wolfhound of Flora
-R:254:0xA0/0x91
-
-# Hill giant
-R:255:0x92/0x96
-
-# Flesh golem
-R:256:0x98/0x92
-
-# Warg
-R:257:0x8F/0x83
-
-# Cheerful leprechaun
-R:258:0xA0/0x93
-
-# Giant flea
-R:259:0x90/0x96
-
-# Ufthak of Cirith Ungol
-R:260:0x9A/0x9F
-
-# Clay golem
-R:261:0x98/0x93
-
-# Black ogre
-R:262:0x92/0x91
-
-# Dweller on the threshold
-R:263:0xC4/0x83
-
-# Half-orc
-R:264:0x9B/0x80
-
-# Dark naga
-R:265:0xBF/0x8E
-
-# Poison ivy
-R:266:0xBE/0x9C
-
-# Magic mushroom patch
-R:267:0x8E/0x8B
-
-# Plaguebearer of Nurgle
-R:268:0xBF/0x8F
-
-# Guardian naga
-R:269:0x9A/0x94
-
-# Wererat
-R:270:0x9D/0x92
-
-# Light hound
-R:271:0x95/0x9B
-
-# Dark hound
-R:272:0x95/0x9C
-
-# Flying skull
-R:273:0xA0/0x95
-
-# Mi-Go
-R:274:0x9F/0x9F
-
-# Giant tarantula
-R:275:0x94/0x86
-
-# Giant clear centipede
-R:276:0x97/0x83
-
-# Mirkwood spider
-R:277:0x94/0x84
-
-# Frost giant
-R:278:0x92/0x97
-
-# Griffon
-R:279:0x91/0x8F
-
-# Homunculus
-R:280:0x91/0x99
-
-# Gnome mage
-R:281:0x99/0x83
-
-# Clear hound
-R:282:0x95/0x9D
-
-# Umber hulk
-R:283:0x94/0x9E
-
-# Rust monster
-R:284:0xBF/0x90
-
-# Ogrillon
-R:285:0xB0/0x8C
-
-# Gelatinous cube
-R:286:0x99/0x9E
-
-# Giant green dragon fly
-R:287:0x90/0x98
-
-# Fire giant
-R:288:0x92/0x98
-
-# Hummerhorn
-R:289:0x90/0x99
-
-# Lizard man
-R:290:0xBF/0x91
-
-# Ulfast, Son of Ulfang
-R:291:0x9C/0x8C
-
-# Crebain
-R:292:0xC4/0x94
-
-# Berserker
-R:293:0xBF/0x92
-
-# Quasit
-R:294:0x91/0x9A
-
-# Sphinx
-R:295:0xBF/0x93
-
-# Imp
-R:296:0x91/0x9B
-
-# Forest troll
-R:297:0x94/0x8E
-
-# Freezing sphere
-R:298:0xBF/0x94
-
-# Jumping fireball
-R:299:0xBF/0x95
-
-# Ball lightning
-R:300:0xBF/0x96
-
-# 2-headed hydra
-R:301:0x93/0x98
-
-# Swamp thing
-R:302:0xBF/0x97
-
-# Water spirit
-R:303:0x90/0x84
-
-# Giant red scorpion
-R:304:0x94/0x8C
-
-# Earth spirit
-R:305:0x90/0x85
-
-# Fire spirit
-R:306:0x90/0x86
-
-# Fire hound
-R:307:0x95/0x9E
-
-# Cold hound
-R:308:0x95/0x9F
-
-# Energy hound
-R:309:0x96/0x80
-
-# Lesser Mimic
-R:310:0x8E/0x8F
-
-# Door mimic
-R:311:0xBF/0x98
-
-# Blink dog
-R:312:0x8F/0x84
-
-# Uruk
-R:313:0x9B/0x82
-
-# Shagrat, the Orc Captain
-R:314:0x9B/0x83
-
-# Gorbag, the Orc Captain
-R:315:0x9B/0x84
-
-# Shambling mound
-R:316:0x8E/0x8C
-
-# Giant Venus Flytrap
-R:317:0xBE/0x9D
-
-# Chaos beastman
-R:318:0xBF/0x99
-
-# Daemonette of Slaanesh
-R:319:0xBF/0x9A
-
-# Giant bronze dragon fly
-R:320:0x90/0x9C
-
-# Stone giant
-R:321:0x92/0x99
-
-# Giant black dragon fly
-R:322:0x90/0x9A
-
-# Stone golem
-R:323:0x98/0x94
-
-# Red mold
-R:324:0x9A/0x8E
-
-# Giant gold dragon fly
-R:325:0x90/0x9B
-
-# Stunwall
-R:326:0xBF/0x9B
-
-# Ghast
-R:327:0xBF/0x9C
-
-# Neekerbreeker
-R:328:0xBE/0x86
-
-# Huorn
-R:329:0xBF/0x9D
-
-# Bolg, Son of Azog
-R:330:0x9B/0x85
-
-# Phase spider
-R:331:0x94/0x89
-
-# Lizard king
-R:332:0xBF/0x9E
-
-# Landmine
-R:333:0xBF/0x9F
-
-# Wyvern
-R:334:0xA0/0x97
-
-# Great eagle
-R:335:0xC0/0x80
-
-# Livingstone
-R:336:0x80/0x82
-
-# Earth hound
-R:337:0x96/0x81
-
-# Air hound
-R:338:0x96/0x82
-
-# Sabre-tooth tiger
-R:339:0x98/0x8F
-
-# Acid hound
-R:340:0x96/0x83
-
-# Chimaera
-R:341:0x91/0x90
-
-# Quylthulg
-R:342:0x92/0x9F
-
-# Sasquatch
-R:343:0x95/0x9A
-
-# Weir
-R:344:0xA0/0x96
-
-# Ranger
-R:345:0x9C/0x83
-
-# Paladin
-R:346:0x8D/0x9C
-
-# Werewolf
-R:347:0x8F/0x85
-
-# Dark elven lord
-R:348:0x99/0x85
-
-# Cloud giant
-R:349:0x92/0x9A
-
-# Ugluk, the Uruk
-R:350:0x9B/0x86
-
-# Blue dragon bat
-R:351:0x96/0x9A
-
-# Mimic
-R:352:0x86/0x82
-
-# Ultimate Mimic
-R:353:0xC0/0x83
-
-# Fire vortex
-R:354:0x9D/0x9E
-
-# Acid vortex
-R:355:0x9D/0x9F
-
-# Lugdush, the Uruk
-R:356:0x9B/0x87
-
-# Arch-vile
-R:357:0xC0/0x84
-
-# Cold vortex
-R:358:0x9E/0x80
-
-# Energy vortex
-R:359:0x9E/0x81
-
-# Globefish
-R:360:0xBE/0x8D
-
-# Giant firefly
-R:361:0xB0/0x8D
-
-# Mummified orc
-R:362:0x92/0x8D
-
-# Wolf chieftain
-R:363:0xBE/0x8E
-
-# Serpent man
-R:364:0xC0/0x85
-
-# Vampiric mist
-R:365:0xC0/0x86
-
-# Killer stag beetle
-R:366:0x92/0x81
-
-# Iron golem
-R:367:0x98/0x95
-
-# Auto-roller
-R:368:0xA0/0x98
-
-# Giant yellow scorpion
-R:369:0x94/0x8A
-
-# Jade monk
-R:370:0xC0/0x87
-
-# Black ooze
-R:371:0x99/0x9F
-
-# Hardened warrior
-R:372:0x9C/0x8D
-
-# Azog, King of the Uruk-Hai
-R:373:0x9B/0x88
-
-# Fleshhound of Khorne
-R:374:0xC0/0x89
-
-# Dark elven warlock
-R:375:0xA0/0x81
-
-# Master rogue
-R:376:0x9C/0x8E
-
-# Red dragon bat
-R:377:0x96/0x9B
-
-# Killer white beetle
-R:378:0x96/0x91
-
-# Ice skeleton
-R:379:0xC0/0x8A
-
-# Angamaite of Umbar
-R:380:0x9C/0x90
-
-# Forest wight
-R:381:0x95/0x83
-
-# Khim, Son of Mim
-R:382:0x99/0x87
-
-# Ibun, Son of Mim
-R:383:0x99/0x86
-
-# Meneldor the Swift
-R:384:0xC0/0x8B
-
-# Phantom beast
-R:385:0xA0/0x84
-
-# Giant silver ant
-R:386:0xB0/0x87
-
-# 4-headed hydra
-R:387:0x93/0x9A
-
-# Lesser hell-beast
-R:388:0xC0/0x8C
-
-# Tyrannosaur
-R:389:0x9F/0x94
-
-# Mummified human
-R:390:0x92/0x8E
-
-# Vampire bat
-R:391:0x96/0x9C
-
-# Sangahyando of Umbar
-R:392:0x9C/0x8F
-
-# It
-R:393:0x80/0x80
-
-# Banshee
-R:394:0x91/0x81
-
-# Carrion crawler
-R:395:0x97/0x84
-
-# Xiclotlan
-R:396:0xC0/0x8D
-
-# Silent watcher
-R:397:0xA0/0x9A
-
-# Pukelman
-R:398:0x98/0x96
-
-# Disenchanter beast
-R:399:0xC0/0x8E
-
-# Dark elven druid
-R:400:0x99/0x88
-
-# Stone troll
-R:401:0x94/0x9A
-
-# Black
-R:402:0xC0/0x8F
-
-# Hill troll
-R:403:0xB0/0x8F
-
-# Wereworm
-R:404:0x9E/0x8F
-
-# Killer red beetle
-R:405:0x92/0x83
-
-# Disenchanter bat
-R:406:0xB0/0x9B
-
-# Gnoph-Keh
-R:407:0xC0/0x90
-
-# Giant grey ant
-R:408:0x96/0x95
-
-# Khufu, the Mummified King
-R:409:0xA0/0x9C
-
-# Gwaihir the Windlord
-R:410:0xC0/0x91
-
-# Giant fire tick
-R:411:0x9D/0x9D
-
-# Displacer beast
-R:412:0x98/0x90
-
-# Ulwarth, Son of Ulfang
-R:413:0x9C/0x91
-
-# Werebear
-R:414:0xB1/0x96
-
-# Cave ogre
-R:415:0x92/0x92
-
-# White wraith
-R:416:0x95/0x84
-
-# Angel
-R:417:0x8E/0x92
-
-# Ghoul
-R:418:0xBB/0x8C
-
-# Mim, Betrayer of Turin
-R:419:0x99/0x89
-
-# Hellblade
-R:420:0x89/0x87
-
-# Killer fire beetle
-R:421:0x92/0x84
-
-# Beast of Nurgle
-R:422:0xC0/0x92
-
-# Creeping adamantite coins
-R:423:0x8E/0x84
-
-# Algroth
-R:424:0x94/0x91
-
-# Flamer of Tzeentch
-R:425:0xC0/0x93
-
-# Roper
-R:426:0xC0/0x94
-
-# Headless
-R:427:0x9F/0x86
-
-# Vibration hound
-R:428:0x96/0x84
-
-# Nexus hound
-R:429:0x96/0x8A
-
-# Half-ogre
-R:430:0xB0/0x9E
-
-# Lokkak, the Ogre Chieftain
-R:431:0xA1/0x80
-
-# Vampire
-R:432:0x94/0x9F
-
-# Gorgimaera
-R:433:0x91/0x91
-
-# Shantak
-R:434:0xA0/0x9D
-
-# Colbran
-R:435:0x98/0x97
-
-# Spirit naga
-R:436:0x9A/0x95
-
-# Corpser
-R:437:0xC0/0x95
-
-# Fiend of Slaanesh
-R:438:0xC0/0x96
-
-# Stairway to Hell
-R:439:0x81/0x9E
-
-# 5-headed hydra
-R:440:0x93/0x9B
-
-# Barney the Dinosaur
-R:441:0x9F/0x96
-
-# Black knight
-R:442:0x9C/0x92
-
-# Seahorse
-R:443:0xBE/0x91
-
-# Cyclops
-R:444:0xC0/0x97
-
-# Clairvoyant
-R:445:0xC0/0x98
-
-# Purple worm
-R:446:0x9E/0x90
-
-# Catoblepas
-R:447:0x9D/0x8B
-
-# Lesser wall monster
-R:448:0x80/0x82
-
-# Mage
-R:449:0x9C/0x94
-
-# Mind flayer
-R:450:0x9C/0x95
-
-# The Ultimate Dungeon Cleaner
-R:451:0xA0/0x99
-
-# Deep one
-R:452:0xC0/0x99
-
-# Basilisk
-R:453:0xBB/0x9F
-
-# Ice troll
-R:454:0x94/0x92
-
-# Dhole
-R:455:0xA1/0x82
-
-# Archangel
-R:456:0x8E/0x93
-
-# Greater Mimic
-R:457:0x82/0x81
-
-# Chaos tile
-R:458:0xA2/0x86
-
-# Young blue dragon
-R:459:0x97/0x8D
-
-# Young white dragon
-R:460:0x97/0x8E
-
-# Young green dragon
-R:461:0x97/0x8F
-
-# Young bronze dragon
-R:462:0x97/0x90
-
-# Aklash
-R:463:0xC0/0x9A
-
-# Mithril golem
-R:464:0x98/0x98
-
-# Skeleton troll
-R:465:0x9D/0x96
-
-# Skeletal tyrannosaur
-R:466:0xC0/0x9B
-
-# Beorn, the Shape-Changer
-R:467:0xA1/0x92
-
-# Thorondor, Lord of Eagles
-R:468:0xC0/0x9C
-
-# Giant blue ant
-R:469:0x96/0x94
-
-# Grave wight
-R:470:0x95/0x85
-
-# Shadow drake
-R:471:0x97/0x91
-
-# Manticore
-R:472:0x91/0x92
-
-# Giant army ant
-R:473:0x96/0x95
-
-# Killer slicer beetle
-R:474:0x92/0x85
-
-# Gorgon
-R:475:0xC0/0x9D
-
-# Gug
-R:476:0xC0/0x9E
-
-# Ghost
-R:477:0x91/0x82
-
-# Death watch beetle
-R:478:0x92/0x86
-
-# Mountain ogre
-R:479:0x92/0x95
-
-# Nexus quylthulg
-R:480:0x93/0x80
-
-# Shelob, Spider of Darkness
-R:481:0x94/0x8B
-
-# Giant squid
-R:482:0xBE/0x87
-
-# Ghoulking
-R:483:0xC0/0x9F
-
-# Doombat
-R:484:0xC1/0x80
-
-# Ninja
-R:485:0x9C/0x96
-
-# Memory moss
-R:486:0x9A/0x8F
-
-# Storm giant
-R:487:0x92/0x9B
-
-# Spectator
-R:488:0xA0/0x85
-
-# Bokrug
-R:489:0xC1/0x81
-
-# Biclops
-R:490:0xC1/0x82
-
-# Half-troll
-R:491:0x94/0x94
-
-# Ivory monk
-R:492:0xC0/0x88
-
-# Bert the Stone Troll
-R:493:0x94/0x95
-
-# Bill the Stone Troll
-R:494:0x94/0x96
-
-# Tom the Stone Troll
-R:495:0x94/0x97
-
-# Cave troll
-R:496:0x94/0x93
-
-# Anti-paladin
-R:497:0xA1/0x84
-
-# Chaos master
-R:498:0xBB/0x84
-
-# Barrow wight
-R:499:0x95/0x86
-
-# Skeleton ettin
-R:500:0x9D/0x97
-
-# Chaos drake
-R:501:0xBB/0x9A
-
-# Law drake
-R:502:0x97/0x93
-
-# Balance drake
-R:503:0x97/0x94
-
-# Ethereal drake
-R:504:0x97/0x95
-
-# Groo, the Wanderer
-R:505:0xA1/0x81
-
-# Fasolt the Giant
-R:506:0xBB/0x83
-
-# Shade
-R:507:0x91/0x83
-
-# Spectre
-R:508:0xA2/0x85
-
-# Water troll
-R:509:0x94/0x98
-
-# Fire elemental
-R:510:0x90/0x87
-
-# Cherub
-R:511:0x8E/0x94
-
-# Water elemental
-R:512:0x90/0x88
-
-# Multi-hued hound
-R:513:0xA2/0x83
-
-# Invisible stalker
-R:514:0x90/0x89
-
-# Carrion crawler
-R:515:0x97/0x85
-
-# Master thief
-R:516:0x9C/0x98
-
-# The Watcher in the Water
-R:517:0xBB/0x87
-
-# Lich
-R:518:0x92/0x88
-
-# Gas spore
-R:519:0xC1/0x83
-
-# Master vampire
-R:520:0x95/0x80
-
-# Oriental vampire
-R:521:0xA1/0x88
-
-# Greater mummy
-R:522:0xC1/0x84
-
-# Bloodletter of Khorne
-R:523:0xC1/0x85
-
-# Giant grey scorpion
-R:524:0xBB/0x9D
-
-# Earth elemental
-R:525:0x90/0x8A
-
-# Air elemental
-R:526:0x90/0x8B
-
-# Shimmering mold
-R:527:0xA2/0x93
-
-# Gargoyle
-R:528:0xC1/0x86
-
-# Malicious leprechaun
-R:529:0xA0/0x94
-
-# Eog golem
-R:530:0x98/0x99
-
-# Little Boy
-R:531:0xC0/0x81
-
-# Dagashi
-R:532:0x9C/0x9A
-
-# Headless ghost
-R:533:0xC1/0x87
-
-# Dread
-R:534:0x91/0x85
-
-# Gauth
-R:536:0xC5/0x8D
-
-# Leng spider
-R:535:0xC1/0x88
-
-# Smoke elemental
-R:537:0x90/0x8D
-
-# Olog
-R:538:0x94/0x99
-
-# Halfling slinger
-R:539:0xBB/0x91
-
-# Gravity hound
-R:540:0x96/0x86
-
-# Acidic cytoplasm
-R:541:0x9A/0x80
-
-# Inertia hound
-R:542:0x96/0x87
-
-# Impact hound
-R:543:0x96/0x88
-
-# Shardstorm
-R:544:0xB0/0x9F
-
-# Ooze elemental
-R:545:0x90/0x8C
-
-# Young black dragon
-R:546:0x97/0x96
-
-# Mumak
-R:547:0x9D/0x8C
-
-# Giant fire ant
-R:548:0x96/0x96
-
-# Mature white dragon
-R:549:0x97/0x97
-
-# Xorn
-R:550:0x95/0x97
-
-# Rogrog the Black Troll
-R:551:0x94/0x9A
-
-# Mist giant
-R:552:0xC1/0x8A
-
-# Phantom
-R:553:0x91/0x87
-
-# Grey wraith
-R:554:0x95/0x87
-
-# Revenant
-R:555:0xC1/0x8B
-
-# Young multi-hued dragon
-R:556:0x97/0x98
-
-# Raal's Tome of Destruction
-R:557:0xA3/0x91
-
-# Colossus
-R:558:0xA0/0x80
-
-# Young gold dragon
-R:559:0x97/0x99
-
-# Mature blue dragon
-R:560:0x97/0x9A
-
-# Mature green dragon
-R:561:0x97/0x9B
-
-# Mature bronze dragon
-R:562:0x97/0x9C
-
-# Young red dragon
-R:563:0x97/0x9D
-
-# Nightblade
-R:564:0xBB/0x92
-
-# Trapper
-R:565:0x8E/0x8E
-
-# Bodak
-R:566:0x91/0x9D
-
-# Time bomb
-R:567:0xC1/0x8C
-
-# Mezzodaemon
-R:568:0xC1/0x8D
-
-# Elder thing
-R:569:0x9F/0x9E
-
-# Ice elemental
-R:570:0x90/0x8E
-
-# Necromancer
-R:571:0x9C/0x9B
-
-# The Greater hell magic mushroom were-quylthulg
-R:572:0xB1/0x97
-
-# Lorgan, Chief of the Easterlings
-R:573:0x9C/0x9C
-
-# Chaos spawn
-R:574:0x9F/0x85
-
-# Mummified troll
-R:575:0x92/0x8F
-
-# Storm of Unmagic
-R:576:0xB1/0x98
-
-# Crypt thing
-R:577:0xC1/0x90
-
-# Chaos butterfly
-R:578:0xC1/0x92
-
-# Time elemental
-R:579:0xA2/0x84
-
-# Flying polyp
-R:580:0xC1/0x93
-
-# The Queen Ant
-R:581:0x96/0x97
-
-# Will o' the wisp
-R:582:0x90/0x8F
-
-# Shan
-R:583:0xC1/0x94
-
-# Magma elemental
-R:584:0x90/0x90
-
-# Black pudding
-R:585:0x9A/0x81
-
-# Killer iridescent beetle
-R:586:0xA3/0x94
-
-# Nexus vortex
-R:587:0xA1/0x9D
-
-# Plasma vortex
-R:588:0x9E/0x83
-
-# Mature red dragon
-R:589:0x97/0x9E
-
-# Mature gold dragon
-R:590:0x97/0x9F
-
-# Crystal drake
-R:591:0xBB/0x99
-
-# Mature black dragon
-R:592:0x98/0x81
-
-# Mature multi-hued dragon
-R:593:0x98/0x82
-
-# Sky whale
-R:594:0xC1/0x95
-
-# Draebor, the Imp
-R:595:0x91/0x9C
-
-# Mother Hydra
-R:596:0xC1/0x97
-
-# Death knight
-R:597:0x9C/0x9E
-
-# Castamir the Usurper
-R:598:0x9C/0x9F
-
-# Time vortex
-R:599:0x9E/0x82
-
-# Shimmering vortex
-R:600:0x9E/0x85
-
-# Ancient blue dragon
-R:601:0x8F/0x8B
-
-# Ancient bronze dragon
-R:602:0x8F/0x8C
-
-# Beholder
-R:603:0x98/0x88
-
-# Emperor wight
-R:604:0x95/0x88
-
-# Seraph
-R:605:0x8E/0x95
-
-# Vargo, Tyrant of Fire
-R:606:0x90/0x91
-
-# Black wraith
-R:607:0x95/0x89
-
-# Nightgaunt
-R:608:0xA0/0x9E
-
-# Baron of hell
-R:609:0x9F/0x8F
-
-# Scylla
-R:610:0xC1/0x98
-
-# Monastic lich
-R:611:0xC1/0x91
-
-# Nether wraith
-R:612:0x95/0x8A
-
-# Hellhound
-R:613:0x8F/0x87
-
-# 7-headed hydra
-R:614:0x93/0x9D
-
-# Waldern, King of Water
-R:615:0x90/0x92
-
-# Kavlax the Many-Headed
-R:616:0x98/0x83
-
-# Ancient white dragon
-R:617:0x8F/0x8D
-
-# Ancient green dragon
-R:618:0x8F/0x8E
-
-# Chthonian
-R:619:0xA1/0x83
-
-# Eldrak
-R:620:0x94/0x9B
-
-# Ettin
-R:621:0x94/0x9C
-
-# Night mare
-R:622:0x9D/0x8D
-
-# Vampire lord
-R:623:0x95/0x81
-
-# Ancient black dragon
-R:624:0x8F/0x8F
-
-# Weird fume
-R:625:0xC1/0x9A
-
-# Spawn of Ubbo-Sathla
-R:626:0xC1/0x9B
-
-# Fat Man
-R:627:0xC0/0x82
-
-# Malekith the Accursed
-R:628:0xBD/0x91
-
-# Shadowfax, steed of Gandalf
-R:629:0xC1/0x9C
-
-# Spirit troll
-R:630:0xC4/0x84
-
-# War troll
-R:631:0xA1/0x8C
-
-# Disenchanter worm mass
-R:632:0x9E/0x91
-
-# Rotting quylthulg
-R:633:0x93/0x81
-
-# Lesser titan
-R:634:0x92/0x9C
-
-# 9-headed hydra
-R:635:0x93/0x9E
-
-# Enchantress
-R:636:0xBB/0x81
-
-# Ranger chieftain
-R:637:0xB1/0x99
-
-# Sorcerer
-R:638:0x9D/0x82
-
-# Xaren
-R:639:0x95/0x98
-
-# Giant roc
-R:640:0x8E/0x9A
-
-# Minotaur
-R:641:0x91/0x93
-
-# Medusa, the Gorgon
-R:642:0x9A/0x96
-
-# Death drake
-R:643:0xBB/0x98
-
-# Ancient red dragon
-R:644:0x8F/0x91
-
-# Ancient gold dragon
-R:645:0x8F/0x92
-
-# Great crystal drake
-R:646:0xBB/0x97
-
-# Wyrd sister
-R:647:0xC1/0x9D
-
-# Vrock
-R:648:0x9E/0x9D
-
-# Death quasit
-R:649:0x91/0x9E
-
-# Giganto, the Gargantuan
-R:650:0xBE/0x95
-
-# Strygalldwir
-R:651:0x8E/0x9C
-
-# Fallen angel
-R:652:0xC1/0x9E
-
-# Giant headless
-R:653:0xC1/0x9F
-
-# Judge Fire
-R:654:0xC2/0x80
-
-# Ubbo-Sathla, the Unbegotten Source
-R:655:0xC2/0x81
-
-# Judge Mortis
-R:656:0xC2/0x82
-
-# Dark elven sorcerer
-R:657:0x99/0x8A
-
-# Master lich
-R:658:0x92/0x89
-
-# Byakhee
-R:659:0xA0/0x9F
-
-# Eol, the Dark Elf
-R:660:0xB2/0x8A
-
-# Archon
-R:661:0x8E/0x96
-
-# Formless spawn of Tsathoggua
-R:662:0x9F/0x9C
-
-# Hunting horror
-R:663:0x9F/0x98
-
-# Undead beholder
-R:664:0x98/0x89
-
-# Shadow
-R:665:0x91/0x86
-
-# Iron lich
-R:666:0xA1/0x8B
-
-# Dread
-R:667:0x91/0x85
-
-# Greater basilisk
-R:668:0xC2/0x83
-
-# Charybdis
-R:669:0xBE/0x96
-
-# Jack of Shadows
-R:670:0xC2/0x84
-
-# Zephyr Lord
-R:671:0xC2/0x85
-
-# Juggernaut of Khorne
-R:672:0xC2/0x86
-
-# Mumak
-R:673:0x9D/0x8E
-
-# Judge Fear
-R:674:0xC2/0x87
-
-# Ancient multi-hued dragon
-R:675:0x8F/0x94
-
-# Ethereal dragon
-R:676:0x8F/0x95
-
-# Dark young of Shub-Niggurath
-R:677:0xA1/0x8F
-
-# Colour out of space
-R:678:0xC2/0x88
-
-# Quaker, Master of Earth
-R:679:0x90/0x93
-
-# Death leprechaun
-R:680:0xBD/0x82
-
-# Chaugnar Faugn, Horror from the Hills
-R:681:0xC2/0x89
-
-# Lloigor
-R:682:0xC2/0x8A
-
-# Utgard-Loke
-R:683:0xC2/0x8B
-
-# Quachil Uttaus, Treader of the Dust
-R:684:0xC2/0x8C
-
-# Shoggoth
-R:685:0xA1/0x8E
-
-# Judge Death
-R:686:0xC2/0x8D
-
-# Ariel, Queen of Air
-R:687:0x90/0x94
-
-# 11-headed hydra
-R:688:0x93/0x9F
-
-# Patriarch
-R:689:0x9D/0x84
-
-# Dreadmaster
-R:690:0x91/0x89
-
-# Drolem
-R:691:0x98/0x9B
-
-# Scatha the Worm
-R:692:0x8F/0x93
-
-# Warrior of the Dawn
-R:693:0xA1/0x8A
-
-# Lesser black reaver
-R:694:0xC2/0x8E
-
-# Zoth-Ommog
-R:695:0xC2/0x8F
-
-# Grand master thief
-R:696:0x9C/0x84
-
-# Smaug the Golden
-R:697:0xBB/0x96
-
-# The Stormbringer
-R:698:0xA0/0x9B
-
-# Knight Templar
-R:699:0xB1/0x9A
-
-# Leprechaun fanatic
-R:700:0xC2/0x90
-
-# Dracolich
-R:701:0x8F/0x98
-
-# Greater titan
-R:702:0x92/0x9D
-
-# Dracolisk
-R:703:0x8F/0x9E
-
-# Winged Horror
-R:704:0xC4/0x85
-
-# Spectral tyrannosaur
-R:705:0x9F/0x95
-
-# Yibb-Tstll, the Patient One
-R:706:0xC2/0x91
-
-# Ghatanothoa
-R:707:0xC2/0x92
-
-# Ent
-R:708:0xC2/0x93
-
-# Hru
-R:709:0xC2/0x94
-
-# Itangast the Fire Drake
-R:710:0x8F/0x99
-
-# Death mold
-R:711:0x9A/0x90
-
-# Fafner the Dragon
-R:712:0xA1/0x90
-
-# Charon, Boatman of the Styx
-R:713:0xB1/0x9B
-
-# Quickbeam, the Ent
-R:714:0xB1/0x9C
-
-# Glaurung, Father of the Dragons
-R:715:0x8F/0x99
-
-# Behemoth
-R:716:0xC2/0x97
-
-# Garm, Guardian of Hel
-R:717:0xC2/0x98
-
-# Greater wall monster
-R:718:0x80/0x82
-
-# Nycadaemon
-R:719:0xC2/0x99
-
-# Barbazu
-R:720:0xB2/0x9D
-
-# Goat of Mendes
-R:721:0x9F/0x8D
-
-# Nightwing
-R:722:0x95/0x91
-
-# Maulotaur
-R:723:0xA0/0x8B
-
-# Nether hound
-R:724:0x96/0x89
-
-# Time hound
-R:725:0x96/0x85
-
-# Plasma hound
-R:726:0x96/0x8B
-
-# Demonic quylthulg
-R:727:0x93/0x82
-
-# Great Storm Wyrm
-R:728:0x8F/0x9B
-
-# Ulik the Troll
-R:729:0xC2/0x9A
-
-# Baphomet the Minotaur Lord
-R:730:0x91/0x95
-
-# Hell knight
-R:731:0xC2/0x9B
-
-# Bull Gates
-R:732:0xBC/0x9B
-
-# Santa Claus
-R:733:0x9F/0x89
-
-# Eihort, the Thing in the Labyrinth
-R:734:0xC2/0x9C
-
-# The King in Yellow
-R:735:0xC2/0x9D
-
-# Great unclean one
-R:736:0xC2/0x9E
-
-# Lord of Chaos
-R:737:0xBB/0x85
-
-# Old Sorcerer
-R:738:0xB1/0x9E
-
-# Ethereal hound
-R:739:0x96/0x8C
-
-# Lesser kraken
-R:740:0xBE/0x98
-
-# Great Ice Wyrm
-R:741:0x8F/0x9C
-
-# Demilich
-R:742:0xC2/0x9F
-
-# The Phoenix
-R:743:0x8E/0x9B
-
-# Nightcrawler
-R:744:0x95/0x94
-
-# Lord of Change
-R:745:0xC3/0x80
-
-# Keeper of Secrets
-R:746:0xC3/0x81
-
-# Shudde M'ell
-R:747:0xC3/0x82
-
-# Hand druj
-R:748:0x9D/0x98
-
-# Eye druj
-R:749:0x9D/0x99
-
-# Skull druj
-R:750:0x9D/0x9A
-
-# Chaos vortex
-R:751:0xBB/0x93
-
-# Aether vortex
-R:752:0x9E/0x87
-
-# Nidhogg, the Hel-Drake
-R:753:0xC3/0x83
-
-# The Lernaean Hydra
-R:754:0x94/0x80
-
-# Thuringwethil, the Vampire Messenger
-R:755:0x95/0x82
-
-# Great Hell Wyrm
-R:756:0x8F/0x9D
-
-# Hastur the Unspeakable
-R:757:0x9F/0x8C
-
-# Bloodthirster
-R:758:0xC3/0x84
-
-# Draconic quylthulg
-R:759:0x93/0x83
-
-# Nyogtha, the Thing that Should not Be
-R:760:0xA1/0x91
-
-# Ahtu, Avatar of Nyarlathotep
-R:761:0xC3/0x85
-
-# Fundin Bluecloak
-R:762:0x99/0x8B
-
-# Bile Demon
-R:763:0xB1/0x9F
-
-# Uriel, Angel of Fire
-R:764:0x8E/0x97
-
-# Azriel, Angel of Death
-R:765:0x8E/0x98
-
-# Ancalagon the Black
-R:766:0x8F/0x90
-
-# Daoloth, the Render of the Veils
-R:767:0xC3/0x86
-
-# Nightwalker
-R:768:0x95/0x95
-
-# Gabriel, the Messenger
-R:769:0x8E/0x99
-
-# Artsi, the Champion of Chaos
-R:770:0xC3/0x87
-
-# Saruman of Many Colours
-R:771:0x9D/0x88
-
-# Harowen the Black Hand
-R:772:0x9D/0x86
-
-# Osyluth
-R:773:0xB2/0x8E
-
-# Dreadlord
-R:774:0x91/0x8A
-
-# Greater kraken
-R:775:0xBE/0x99
-
-# Archlich
-R:776:0xC3/0x89
-
-# The Cat Lord
-R:777:0x98/0x91
-
-# Jabberwock
-R:778:0x91/0x9F
-
-# Chaos hound
-R:779:0xBB/0x94
-
-# Vlad Dracula, Prince of Darkness
-R:780:0xC3/0x8B
-
-# Beholder hive-mother
-R:781:0xC3/0x8C
-
-# Leviathan
-R:782:0xBE/0x9A
-
-# Great Wyrm of Chaos
-R:783:0xBB/0x95
-
-# Great Wyrm of Law
-R:784:0x90/0x80
-
-# Great Wyrm of Balance
-R:785:0x90/0x81
-
-# Shambler
-R:786:0x9F/0x92
-
-# Gelugon
-R:787:0xB2/0x8B
-
-# Glaaki
-R:788:0xC3/0x8E
-
-# T'ron, the Rebel Dragonrider
-R:789:0xB2/0x88
-
-# Great Wyrm of Many Colours
-R:790:0xA2/0x95
-
-# Mardra, rider of the Gold Loranth
-R:791:0xB2/0x85
-
-# Tselakus, the Dreadlord
-R:792:0x91/0x8B
-
-# Sky Drake
-R:793:0xA2/0x80
-
-# Eilinel the Entrapped
-R:794:0xB2/0x80
-
-# Horned Reaper
-R:795:0xB2/0x81
-
-# The Norsa
-R:796:0xBB/0x80
-
-# Rhan-Tegoth
-R:797:0xC3/0x8F
-
-# Black reaver
-R:798:0x92/0x8A
-
-# Master mindcrafter
-R:799:0xB0/0x86
-
-# Greater demonic quylthulg
-R:800:0x93/0x87
-
-# Greater draconic quylthulg
-R:801:0x93/0x85
-
-# Greater rotting quylthulg
-R:802:0x93/0x86
-
-# Null, the Living Void
-R:803:0xC3/0x90
-
-# Feagwath, the Undead Sorcerer
-R:804:0x92/0x8C
-
-# Omarax the Eye Tyrant
-R:805:0x98/0x8A
-
-# Tsathoggua, the Sleeper of N'kai
-R:806:0xC3/0x91
-
-# Greater Balrog
-R:807:0xB2/0x9E
-
-# Ungoliant, the Unlight
-R:808:0x94/0x8D
-
-# Atlach-Nacha, the Spider God
-R:809:0x94/0x8D
-
-# Y'golonac
-R:810:0xC3/0x92
-
-# Aether hound
-R:811:0x96/0x8E
-
-# Pit Fiend
-R:812:0xB2/0x9F
-
-# The Serpent of Chaos
-R:813:0x9F/0x8E
-
-# Yig, Father of Serpents
-R:814:0xC3/0x94
-
-# Unmaker
-R:815:0xA1/0x9E
-
-# Cyberdemon
-R:816:0x9F/0x91
-
-# Hela, Queen of the Dead
-R:817:0xC3/0x95
-
-# The Mouth of Sauron
-R:818:0x9D/0x89
-
-# The Necromancer of Dol Guldur
-R:819:0xC5/0x8B
-
-# Lessa, rider of the Gold Ramoth
-R:820:0xB2/0x86
-
-# Master quylthulg
-R:821:0x93/0x84
-
-# Qlzqqlzuup, the Lord of Flesh
-R:822:0x93/0x88
-
-# Cthugha, the Living Flame
-R:823:0xC3/0x96
-
-# F'lar, rider of the Bronze Mnementh
-R:824:0xB2/0x87
-
-# Maeglin, the Traitor of Gondolin
-R:825:0xA1/0x9C
-
-# Cyaegha
-R:826:0xBD/0x81
-
-# Pazuzu, Lord of Air
-R:827:0x8E/0x9C
-
-# Ithaqua the Windwalker
-R:828:0xA0/0x82
-
-# Hellhound
-R:829:0x8F/0x87
-
-# Cantoras, the Skeletal Lord
-R:830:0x9D/0x9B
-
-# Mephistopheles, Lord of Hell
-R:831:0x9F/0x90
-
-# Godzilla
-R:832:0x9F/0x97
-
-# Abhoth, Source of Uncleanness
-R:833:0xC3/0x97
-
-# Ymir, the Ice Giant
-R:834:0xBD/0x84
-
-# Loki, the Trickster
-R:835:0xC3/0x98
-
-# Star-spawn of Cthulhu
-R:836:0x9F/0x8A
-
-# Surtur, the Fire Giant
-R:837:0xBD/0x85
-
-# The Tarrasque
-R:838:0x94/0x81
-
-# Lungorthin, the Balrog of White Fire
-R:839:0x9F/0x82
-
-# Draugluin, Sire of All Werewolves
-R:840:0x8F/0x88
-
-# Shuma-Gorath
-R:841:0xBD/0x80
-
-# Tulzscha, the Green Flame
-R:842:0xC3/0x99
-
-# Oremorj, the Cyberdemon Lord
-R:843:0xC3/0x9A
-
-# Vecna, the Emperor Lich
-R:844:0x92/0x8B
-
-# Yog-Sothoth, the All-in-One
-R:845:0x9F/0x8B
-
-# Fenris Wolf
-R:846:0xC3/0x9B
-
-# Great Wyrm of Power
-R:847:0xA2/0x81
-
-# Shub-Niggurath, Black Goat of the Woods
-R:848:0x9F/0x99
-
-# Nodens, Lord of the Great Abyss
-R:849:0xC3/0x9C
-
-# Carcharoth, the Jaws of Thirst
-R:850:0x8F/0x89
-
-# Nyarlathotep, the Crawling Chaos
-R:851:0x9F/0x9B
-
-# Azathoth, the Daemon Sultan
-R:852:0xC4/0x8C
-
-# Huan, Wolfhound of the Valar
-R:853:0xB2/0x83
-
-# Jormungand the Midgard Serpent
-R:854:0xBE/0x9B
-
-# The Destroyer
-R:855:0xBD/0x83
-
-# Gothmog, the High Captain of Balrogs
-R:856:0x9F/0x81
-
-# Great Cthulhu
-R:857:0x9F/0x84
-
-# Sorka, rider of the Gold Faranth
-R:858:0xB2/0x84
-
-# The Unicorn of Order
-R:859:0xC3/0x9D
-
-# Sauron, the Sorcerer
-R:860:0x9D/0x8A
-
-# DarkGod, the Mighty Coder of Hell
-R:861:0xA1/0x93
-
-# Morgoth, Lord of Darkness
-R:862:0x92/0x9E
-
-# Human Warrior
-R:863:0xB2/0x82
-
-# Elven archer
-R:864:0x9C/0x81
-
-# Dwarven warrior
-R:865:0xB2/0x89
-
-# Elite uruk
-R:866:0x9B/0x81
-
-# The Philosophy Teacher
-R:867:0xC4/0x82
-
-# The Variant Maintainer
-R:868:0xA1/0x99
-
-# Random Number Generator
-R:869:0xBD/0x9F
-
-# Rocket mine
-R:870:0xB2/0x8C
-
-# Bouncing mine
-R:871:0xB2/0x8D
-
-# The Balrog of Moria
-R:872:0xB2/0x8F
-
-# The Icky Queen
-R:873:0xB2/0x90
-
-# Rot jelly
-R:874:0xB1/0x91
-
-# Death
-R:875:0xB2/0x91
-
-# Famine
-R:876:0xB2/0x92
-
-# Pestilence
-R:877:0xB2/0x93
-
-# War
-R:878:0xB2/0x94
-
-# Pike
-R:879:0xB2/0x95
-
-# Electric eel
-R:880:0xBE/0x8C
-
-# Giant crayfish
-R:881:0xB2/0x96
-
-# Mermaid
-R:882:0xB1/0x9D
-
-# Box jellyfish
-R:883:0xBE/0x83
-
-# Giant piranha
-R:884:0xBE/0x84
-
-# Piranha
-R:885:0xBE/0x80
-
-# Bullywug
-R:886:0xB2/0x97
-
-# Bullywug warrior
-R:887:0xB2/0x98
-
-# Bullywug shaman
-R:888:0xB2/0x99
-
-# Whale
-R:889:0xBE/0x8B
-
-# Sand mite
-R:890:0xB0/0x9D
-
-# Octopus
-R:891:0xB2/0x9A
-
-# Giant octopus
-R:892:0xBE/0x93
-
-# Eye of the deep
-R:893:0xB2/0x9B
-
-# Murk dweller
-R:894:0xB2/0x9C
-
-# Drowned soul
-R:895:0xC5/0x8F
-
-# Tiger shark
-R:896:0xC5/0x8E
-
-# Hammerhead shark
-R:897:0xBE/0x88
-
-# Great white shark
-R:898:0xBE/0x8F
-
-# Aquatic golem
-R:899:0xC5/0x95
-
-# Aquatic kobold
-R:900:0xC5/0x96
-
-# White shark
-R:901:0xBE/0x89
-
-# Scrag
-R:902:0xC5/0x97
-
-# Jaws
-R:903:0xBE/0x92
-
-# Aquatic elf
-R:904:0xC5/0x98
-
-# Aquatic elven warrior
-R:905:0xC5/0x99
-
-# Aquatic elven shaman
-R:906:0xC5/0x9A
-
-# Stargazer
-R:907:0xC5/0x9E
-
-# Elder stargazer
-R:908:0xC5/0x9F
-
-# Flounder
-R:909:0xC6/0x81
-
-# Giant turtle
-R:910:0xC6/0x82
-
-# Baby dragon turtle
-R:911:0xC6/0x83
-
-# Young dragon turtle
-R:912:0xC6/0x84
-
-# Mature dragon turtle
-R:913:0xC6/0x85
-
-# Ancient dragon turtle
-R:914:0xC6/0x86
-
-# Fastitocalon
-R:915:0xBE/0x97
-
-# Undead stargazer
-R:916:0xC6/0x80
-
-# Killer whale
-R:917:0xBE/0x8E
-
-# Merrow
-R:918:0xC5/0x9D
-
-# Water naga
-R:919:0xC6/0x87
-
-# Devilfish
-R:920:0xC6/0x88
-
-# Undead devilfish
-R:921:0xC6/0x89
-
-# Moby Dick, the White Whale
-R:922:0xC5/0x9C
-
-# Aquatic hound
-R:923:0xC4/0x9E
-
-# Water demon
-R:924:0xC6/0x8B
-
-# Ixitxachitl
-R:925:0xBE/0x86
-
-# Ixitxachitl priest
-R:926:0xBE/0x8A
-
-# Vampiric ixitxachitl
-R:927:0xBE/0x90
-
-# Mathilde, the Science Student
-R:928:0x9D/0x80
-
-# Child spirit
-R:929:0xC5/0x90
-
-# Young spirit
-R:930:0xC5/0x91
-
-# Mature spirit
-R:931:0xC5/0x92
-
-# Experienced spirit
-R:932:0xC5/0x93
-
-# Wise spirit
-R:933:0xC5/0x94
-
-# Fangorn the Treebeard, Lord of the Ents
-R:934:0xC2/0x95
-
-# Gandalf the Grey
-R:935:0xC3/0x88
-
-# Nar, the Dwarf
-R:936:0x99/0x84
-
-# Novice mindcrafter
-R:937:0xB0/0x84
-
-# Great Swamp Wyrm
-R:938:0x8F/0x9A
-
-# Great Bile Wyrm
-R:939:0x8F/0x9F
-
-# Blue Firelizard
-R:940:0xB0/0x99
-
-# Green Firelizard
-R:941:0xB0/0x98
-
-# Brown Firelizard
-R:942:0xB0/0x97
-
-# Bronze Firelizard
-R:943:0xB0/0x96
-
-# Gold Firelizard
-R:944:0xB0/0x95
-
-# High-elven ranger
-R:945:0xC6/0x93
-
-# Uvatha the Horseman
-R:946:0x95/0x8B
-
-# Adunaphel the Quiet
-R:947:0x95/0x8C
-
-# Akhorahil the Blind
-R:948:0x95/0x8D
-
-# Ren the Unclean
-R:949:0x95/0x82
-
-# Ji Indur Dawndeath
-R:950:0x95/0x8F
-
-# Dwar, Dog Lord of Waw
-R:951:0x95/0x8F
-
-# Hoarmurath of Dir
-R:952:0x95/0x92
-
-# Khamul, the Black Easterling
-R:953:0x95/0x93
-
-# The Witch-King of Angmar
-R:954:0x95/0x96
-
-# Green Dragonrider
-R:955:0xB0/0x91
-
-# Blue Dragonrider
-R:956:0xB0/0x94
-
-# Brown Dragonrider
-R:957:0xB0/0x92
-
-# Bronze Dragonrider
-R:958:0xB0/0x93
-
-# Gold Dragonrider
-R:959:0xB0/0x90
-
-# Thread
-R:960:0xB0/0x9A
-
-# Gorlim, Betrayer of Barahir
-R:961:0x9D/0x83
-
-# The Blubbering idiot, agent of black market, Simon the weak
-R:962:0x9B/0x8F
-
-# Aranea
-R:963:0xB0/0x80
-
-# Elder aranea
-R:964:0xB0/0x81
-
-# Giant brown tick
-R:965:0xC5/0x9B
-
-# Dolphiner
-R:966:0xC6/0x98
-
-# Novice possessor (soul)
-R:967:0xC6/0x8E
-
-# Bat of Gorgoroth
-R:968:0xC6/0x94
-
-# The Princess
-R:969:0xA2/0x9F
-
-# Merton Proudfoot, the lost hobbit
-R:970:0xC6/0x9E
-
-# The Wight-King of the Barrow-downs
-R:971:0xC6/0x91
-
-# Adventurer
-R:972:0xA9/0x86
-
-# Experienced possessor (soul)
-R:973:0xC6/0x8F
-
-# Old possessor (soul)
-R:974:0xC6/0x90
-
-# Death orb
-R:975:0xC6/0x99
-
-# Bronze dragon worm
-R:976:0xB1/0x80
-
-# Gold dragon worm
-R:977:0xB1/0x81
-
-# Moldoux, the Defenceless Mold
-R:978:0xB1/0x8A
-
-# The Physics Teacher
-R:979:0xC6/0x9A
-
-# Ar-Pharazon the Golden
-R:980:0xA1/0x9B
-
-# Doppelganger
-R:981:0x8C/0x81
-
-# Marylene, Heartbreakeress of the Netherworld
-R:982:0xA3/0x9E
-
-# The Greater Lag Monster
-R:983:0xC6/0x96
-
-# Hrungnir, the Stone Giant
-R:984:0xB1/0x8B
-
-# Bullroarer the Hobbit
-R:985:0x98/0x9D
-
-# 3-headed hydra
-R:986:0x93/0x99
-
-# Uldor the Accursed
-R:987:0x9C/0x93
-
-# Mystic
-R:988:0x9C/0x97
-
-# Elder vampire
-R:989:0xA1/0x9F
-
-# Ulfang the Black
-R:990:0x9C/0x99
-
-# Demonologist
-R:991:0x9C/0x9D
-
-# Hezrou
-R:992:0x9E/0x9C
-
-# Glabrezu
-R:993:0x9E/0x9D
-
-# Nalfeshnee
-R:994:0x9E/0x9E
-
-# Marilith
-R:995:0x9E/0x9F
-
-# Lesser Balrog
-R:996:0x9F/0x80
-
-# Master mystic
-R:997:0x9D/0x85
-
-# Grand master mystic
-R:998:0x9D/0x87
-
-# Erinyes
-R:999:0x9E/0x9A
-
-# Novice mindcrafter
-R:1000:0xB0/0x84
-
-# Polyphemus, the Blind Cyclops
-R:1001:0xC6/0x92
-
-# Great Wyrm of Perplexity
-R:1002:0xB1/0x8C
-
-# Hound of Tindalos
-R:1003:0xB0/0x8E
-
-# Great Wyrm of Thunder
-R:1004:0xB1/0x8D
-
-# Silver mouse
-R:1005:0xB0/0x83
-
-# The Rat King
-R:1006:0xB1/0x8E
-
-# Vort the Kobold Queen
-R:1007:0xB0/0x88
-
-# Giant black louse
-R:1008:0x9A/0x87
-
-# Fire Phantom
-R:1009:0xB1/0x8F
-
-# The Insane Player
-R:1010:0xBC/0x99
-
-# Glaryssa, Succubus Queen
-R:1011:0xA3/0x9F
-
-# Vermicious Knid
-R:1012:0xB1/0x90
-
-# Bone golem
-R:1013:0xB1/0x92
-
-# Snake of Yig
-R:1014:0xC6/0x8A
-
-# Bronze golem
-R:1015:0xB1/0x93
-
-# Dimensional shambler
-R:1016:0xB0/0x9C
-
-# Cultist
-R:1017:0xC6/0x8C
-
-# Cult leader
-R:1018:0xC6/0x8D
-
-# Servitor of the outer gods
-R:1019:0xC6/0x95
-
-# Avatar of Nyarlathotep
-R:1020:0xC3/0x85
-
-# Thiazi, the Storm Giant
-R:1021:0xB1/0x94
-
-# Hypnos, Lord of Sleep
-R:1022:0xC3/0x8D
-
-# Blue dragon worm
-R:1023:0xB1/0x82
-
-# White dragon worm
-R:1024:0xB1/0x83
-
-# Green dragon worm
-R:1025:0xB1/0x84
-
-# Black dragon worm
-R:1026:0xB1/0x85
-
-# Red dragon worm
-R:1027:0xB1/0x86
-
-# Multi-hued dragon worm
-R:1028:0xB1/0x87
-
-# The Minotaur of the Labyrinth
-R:1029:0x91/0x95
-
-# The Sandworm Queen
-R:1030:0xB1/0x88
-
-# Sandworm
-R:1031:0xB1/0x89
-
-# Tik'srvzllat
-R:1032:0xC6/0x9B
-
-# The Glass Golem
-R:1033:0xB1/0x95
-
-# The White Balrog
-R:1034:0x9F/0x82
-
-# Golgarach, the Living Rock
-R:1035:0x80/0x95
-
-# Atlas, the Titan
-R:1036:0xC6/0x9C
-
-# Kronos, Lord of the Titans
-R:1037:0xC6/0x9D
-
-# Water hound
-R:1038:0x96/0x83
-
-# Improv, the mighty MoLD
-R:1039:0xB1/0x8A
-
-# Emperor Mimic
-R:1040:0xA3/0x8D
-
-# Melinda Proudfoot
-R:1041:0xC6/0x9F
-
-# Thrain, the King Under the Mountain
-R:1042:0xC6/0x97
-
-## Fire golem
-R:1043:0xBC/0x9C
-
-# Spells (*)
-S:0x30:0x85/0x93
-S:0x31:0x85/0x92
-S:0x32:0x85/0x92
-S:0x33:0x85/0x8D
-S:0x34:0x85/0x8C
-S:0x35:0x85/0x8F
-S:0x36:0x85/0x90
-S:0x37:0x85/0x95
-S:0x38:0x85/0x93
-S:0x39:0x85/0x92
-S:0x3A:0x85/0x91
-S:0x3B:0x85/0x8E
-S:0x3C:0x85/0x8D
-S:0x3D:0x85/0x8F
-S:0x3E:0x85/0x90
-S:0x3F:0x85/0x95
-
-# Spells (|)
-S:0x40:0x84/0x9C
-S:0x41:0x84/0x98
-S:0x42:0x84/0x98
-S:0x43:0x85/0x88
-S:0x44:0x84/0x80
-S:0x45:0x84/0x8C
-S:0x46:0x84/0x90
-S:0x47:0x85/0x84
-S:0x48:0x84/0x9C
-S:0x49:0x84/0x98
-S:0x4A:0x84/0x94
-S:0x4B:0x84/0x88
-S:0x4C:0x85/0x88
-S:0x4D:0x84/0x8C
-S:0x4E:0x84/0x90
-S:0x4F:0x85/0x84
-
-# Spells (-)
-S:0x50:0x84/0x9D
-S:0x51:0x84/0x99
-S:0x52:0x84/0x99
-S:0x53:0x85/0x89
-S:0x54:0x84/0x81
-S:0x55:0x84/0x8D
-S:0x56:0x84/0x91
-S:0x57:0x85/0x85
-S:0x58:0x84/0x9D
-S:0x59:0x84/0x99
-S:0x5A:0x84/0x95
-S:0x5B:0x84/0x89
-S:0x5C:0x85/0x89
-S:0x5D:0x84/0x8D
-S:0x5E:0x84/0x91
-S:0x5F:0x85/0x85
-
-# Spells (:)
-S:0x60:0x84/0x9E
-S:0x61:0x84/0x9A
-S:0x62:0x84/0x9A
-S:0x63:0x85/0x8A
-S:0x64:0x84/0x82
-S:0x65:0x84/0x8E
-S:0x66:0x84/0x92
-S:0x67:0x85/0x86
-S:0x68:0x84/0x9E
-S:0x69:0x84/0x9A
-S:0x6A:0x84/0x96
-S:0x6B:0x84/0x8A
-S:0x6C:0x85/0x8A
-S:0x6D:0x84/0x8E
-S:0x6E:0x84/0x92
-S:0x6F:0x85/0x86
-
-# Spells (\)
-S:0x70:0x84/0x9F
-S:0x71:0x84/0x9B
-S:0x72:0x84/0x9B
-S:0x73:0x85/0x8B
-S:0x74:0x84/0x83
-S:0x75:0x84/0x8F
-S:0x76:0x84/0x93
-S:0x77:0x85/0x87
-S:0x78:0x84/0x9F
-S:0x79:0x84/0x9B
-S:0x7A:0x84/0x97
-S:0x7B:0x84/0x8B
-S:0x7C:0x85/0x8B
-S:0x7D:0x84/0x8F
-S:0x7E:0x84/0x93
-S:0x7F:0x85/0x87
-
-# Amulets (")
-S:0x80:0xB6/0x87
-S:0x81:0xB6/0x88
-S:0x82:0xB6/0x85
-S:0x83:0xB6/0x86
-S:0x84:0xB6/0x81
-S:0x85:0xB6/0x82
-S:0x86:0xB6/0x83
-S:0x87:0xB6/0x84
-S:0x88:0xB6/0x87
-S:0x89:0xB6/0x88
-S:0x8A:0xB6/0x8E
-S:0x8B:0xB6/0x86
-S:0x8C:0xB6/0x81
-S:0x8D:0xB6/0x82
-S:0x8E:0xB6/0x8B
-S:0x8F:0xB6/0x8C
-
-# Rings (=)
-S:0x90:0xB5/0x8B
-S:0x91:0xB5/0x8C
-S:0x92:0xB5/0x89
-S:0x93:0xB5/0x8A
-S:0x94:0xB5/0x81
-S:0x95:0xB5/0x82
-S:0x96:0xB5/0x83
-S:0x97:0xB5/0x88
-S:0x98:0xB5/0x8B
-S:0x99:0xB5/0x8C
-S:0x9A:0xB5/0x80
-S:0x9B:0xB5/0x8A
-S:0x9C:0xB5/0x81
-S:0x9D:0xB5/0x82
-S:0x9E:0xB5/0x83
-S:0x9F:0xB5/0x88
-
-# Staffs (_)
-S:0xA0:0xB9/0x84
-S:0xA1:0xB9/0x85
-S:0xA2:0xB9/0x85
-S:0xA3:0xB9/0x81
-S:0xA4:0xB9/0x81
-S:0xA5:0xB9/0x82
-S:0xA6:0xB9/0x80
-S:0xA7:0xB9/0x87
-S:0xA8:0xB9/0x84
-S:0xA9:0xB9/0x85
-S:0xAA:0xB9/0x83
-S:0xAB:0xB9/0x87
-S:0xAC:0xB9/0x81
-S:0xAD:0xB9/0x82
-S:0xAE:0xB9/0x80
-S:0xAF:0xB9/0x87
-
-# Wands (-)
-S:0xB0:0xB7/0x84
-S:0xB1:0xB7/0x85
-S:0xB2:0xB7/0x85
-S:0xB3:0xB7/0x86
-S:0xB4:0xB7/0x81
-S:0xB5:0xB7/0x82
-S:0xB6:0xB7/0x80
-S:0xB7:0xB7/0x87
-S:0xB8:0xB7/0x84
-S:0xB9:0xB7/0x85
-S:0xBA:0xB7/0x83
-S:0xBB:0xB7/0x86
-S:0xBC:0xB7/0x81
-S:0xBD:0xB7/0x82
-S:0xBE:0xB7/0x80
-S:0xBF:0xB7/0x87
-
-# Rods (-)
-S:0xC0:0xB8/0x84
-S:0xC1:0xB8/0x85
-S:0xC2:0xB8/0x85
-S:0xC3:0xB8/0x86
-S:0xC4:0xB8/0x81
-S:0xC5:0xB8/0x82
-S:0xC6:0xB8/0x80
-S:0xC7:0xB8/0x87
-S:0xC8:0xB8/0x84
-S:0xC9:0xB8/0x85
-S:0xCA:0xB8/0x83
-S:0xCB:0xB8/0x86
-S:0xCC:0xB8/0x81
-S:0xCD:0xB8/0x82
-S:0xCE:0xB8/0x80
-S:0xCF:0xB8/0x87
-
-# 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:0xBC/0x84
-S:0xE1:0xBC/0x83
-S:0xE2:0xBC/0x8A
-S:0xE3:0xBC/0x8B
-S:0xE4:0xBC/0x87
-S:0xE5:0xBC/0x86
-S:0xE6:0xBC/0x85
-S:0xE7:0xBC/0x89
-S:0xE8:0xBC/0x84
-S:0xE9:0xBC/0x83
-S:0xEA:0xBC/0x8E
-S:0xEB:0xBC/0x88
-S:0xEC:0xBC/0x8B
-S:0xED:0xBC/0x8C
-S:0xEE:0xBC/0x8D
-S:0xEF:0xBC/0x89
-
-# Food (,)
-S:0xF0:0xBA/0x84
-S:0xF1:0xBA/0x85
-S:0xF2:0xBA/0x85
-S:0xF3:0xBA/0x86
-S:0xF4:0xBA/0x81
-S:0xF5:0xBA/0x82
-S:0xF6:0xBA/0x80
-S:0xF7:0xBA/0x87
-S:0xF8:0xBA/0x84
-S:0xF9:0xBA/0x85
-S:0xFA:0xBA/0x83
-S:0xFB:0xBA/0x86
-S:0xFC:0xBA/0x81
-S:0xFD:0xBA/0x82
-S:0xFE:0xBA/0x80
-S:0xFF:0xBA/0x87
-
-# Unknown Amulet
-U:40:0xB6/0x81
-
-# Unknown Ring
-U:45:0xB5/0x81
-
-# Unknown Staff
-U:55:0xB9/0x81
-
-# Unknown Wand
-U:65:0xB7/0x81
-
-# Unknown Rod
-U:66:0xB8/0x81
-
-# Unknown Scroll
-U:70:0x86/0x82
-
-# Unknown Potion
-U:75:0xBC/0x85
-
-# Unknown Food
-U:80:0x8B/0x81
-# non-defines encountered :
-# Load the special player pictures
-%:xtra-xxx.prf
-# Load the Trap image definitions
-%:trap-xxx.prf
diff --git a/lib/pref/graf.prf b/lib/pref/graf.prf
deleted file mode 100644
index a82ce364..00000000
--- a/lib/pref/graf.prf
+++ /dev/null
@@ -1,51 +0,0 @@
-# File: graf.prf
-
-#
-# This file defines special attr/char mappings for use in "graphics" mode
-#
-# This file includes, if appropriate, various "sub-files"
-#
-# See "lib/help/command.txt" and "src/files.c" for more information.
-#
-
-
-##### Standard font file #####
-
-%:font-xxx.prf
-
-
-##### System Specific Subfiles #####
-
-?:[IOR [EQU $SYS xaw] [EQU $SYS x11] [EQU $SYS gtk]]
-%:graf-x11.prf
-
-?:[EQU $SYS gcu]
-%:graf-gcu.prf
-
-?:[EQU $SYS ami]
-%:graf-ami.prf
-
-?:[EQU $SYS mac]
-%:graf-mac.prf
-
-?:[EQU $SYS dos]
-%:graf-dos.prf
-
-?:[EQU $SYS win]
-%:graf-win.prf
-
-?:[EQU $SYS ibm]
-%:graf-ibm.prf
-
-?:[EQU $SYS emx]
-%:graf-emx.prf
-
-?:[EQU $SYS acn]
-%:graf-acn.prf
-
-?:[EQU $SYS sdl]
-%:graf-sdl.prf
-
-?:1
-
-
diff --git a/lib/xtra/graf/16x16.bmp b/lib/xtra/graf/16x16.bmp
deleted file mode 100644
index 2e6b0ebf..00000000
--- a/lib/xtra/graf/16x16.bmp
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/graf/16x16.png b/lib/xtra/graf/16x16.png
deleted file mode 100644
index 9fc1681a..00000000
--- a/lib/xtra/graf/16x16.png
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/graf/8x8.bmp b/lib/xtra/graf/8x8.bmp
deleted file mode 100644
index 02d2d1a9..00000000
--- a/lib/xtra/graf/8x8.bmp
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/graf/8x8.png b/lib/xtra/graf/8x8.png
deleted file mode 100644
index d56e9d6a..00000000
--- a/lib/xtra/graf/8x8.png
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/graf/mask.bmp b/lib/xtra/graf/mask.bmp
deleted file mode 100644
index fced8b05..00000000
--- a/lib/xtra/graf/mask.bmp
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/graf/tome-128.png b/lib/xtra/graf/tome-128.png
deleted file mode 100644
index 31b79c31..00000000
--- a/lib/xtra/graf/tome-128.png
+++ /dev/null
Binary files differ
diff --git a/lib/xtra/sound/Sound.cfg b/lib/xtra/sound/Sound.cfg
deleted file mode 100644
index eb3a7f39..00000000
--- a/lib/xtra/sound/Sound.cfg
+++ /dev/null
@@ -1,79 +0,0 @@
-# sound.cfg
-#
-# Configuration file for the Angband sound events
-#
-# The format is:
-# name of the Angband event = list of the available sample-names seperated by spaces.
-#
-# Example:
-# hit = hit.wav hit1.wav
-#
-# Look at the definition of "angband_sound_name" in variable.c for a complete list of
-# all the available event names.
-
-[Sound]
-hit = hit.wav drop.wav hit1.wav
-miss = miss.wav miss1.wav
-flee = flee.wav
-drop = clunk.wav
-kill = kill.wav destroy.wav kill1.wav
-level = level.wav
-death = death.wav
-study =
-teleport =
-shoot =
-quaff =
-zap =
-walk =
-tpother =
-hitwall =
-eat = eat.wav
-store1 = money.wav
-store2 = money.wav
-store3 = money.wav
-store4 = money.wav
-dig = thump.wav
-opendoor = opendoor.wav
-shutdoor = shutdoor.wav
-tplevel = teleport.wav
-scroll =
-buy =
-sell =
-warn =
-rocket =
-n_kill =
-u_kill =
-quest =
-heal =
-x_heal =
-bite =
-claw =
-m_spell =
-summon =
-breath =
-ball =
-m_heal =
-atkspell =
-evil =
-touch =
-sting =
-crush =
-slime =
-wail =
-winner =
-fire =
-acid =
-elec =
-cold =
-illegal =
-fail =
-wakeup =
-invuln =
-fall =
-pain =
-destitem =
-moan =
-show =
-unused =
-explode =
-
diff --git a/lib/xtra/sound/readme.txt b/lib/xtra/sound/readme.txt
deleted file mode 100644
index 49bb86a1..00000000
--- a/lib/xtra/sound/readme.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-New Sound Effect For Angband 2.8.1 Windows 95 (beta release)
-
-Changes since Alpha release:
-
-Altered sounds: breath.wav
- death.wav
- flee.wav
- hit.wav
- kill.wav
-
-
-New sounds: None (no new events yet)
-
-
-Useage:
-
-Unzip files into your angband 2.8.1 sounds directory EG:
-
-C:\angband-281\lib\xtra\sound
-
-That's it!
-
-If you wish to use the sounds for any other purpose or wish to include them as the default sounds
-in your variant of Angband, contact me at either:
-
-tim.haywood@ocean.co.uk or timothy.haywood@virgin.net
-
-Legal Stuff:
-
-This is a patch for Angband 2.8.1 (Windows95 Version).
-Copyright @ 1997 Tim Haywood
-Not for resale.
-Not for release with original version of Angband without permission.
diff --git a/src/.gitignore b/src/.gitignore
index be576d7b..0799f693 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,3 +1,3 @@
-/tolua
+/harness
/tome
w_*.c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 03c1771b..dcd1e518 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,29 +1,136 @@
-SET(SRCS
- main-gcu.c main-x11.c main-xaw.c main-sdl.c main-gtk2.c
- z-rand.c z-util.c z-form.c z-virt.c z-term.c
- variable.c tables.c plots.c util.c cave.c dungeon.c
- melee1.c melee2.c messages.c modules.c
- q_god.c
- object1.c object2.c randart.c squeltch.c traps.c
- monster1.c monster2.c monster3.c
- xtra1.c xtra2.c skills.c powers.c gods.c
- spells1.c spells2.c spells3.c spells4.c spells5.c spells6.c
- spell_type.c
- corrupt.c joke.c mimic.c
- status.c files.c notes.c loadsave.c string_list.c
- cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c
- help.c hiscore.c range.c
- generate.c gen_maze.c gen_evol.c wild.c levels.c store.c bldg.c
- cmovie.c
- wizard2.c init2.c birth.c wizard1.c init1.c main.c
- quark.c
- # Lua bits:
- lua_bind.c script.c
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/bandit)
+
+# Add subdirectories
+ADD_SUBDIRECTORY (squelch)
+
+# Sources (common)
+SET(SRCS_COMMON
+ birth.cc
+ bldg.cc
+ cave.cc
+ cmd1.cc
+ cmd2.cc
+ cmd3.cc
+ cmd4.cc
+ cmd5.cc
+ cmd6.cc
+ cmd7.cc
+ corrupt.cc
+ device_allocation.cc
+ dice.cc
+ dungeon.cc
+ files.cc
+ gen_evol.cc
+ gen_maze.cc
+ generate.cc
+ gods.cc
+ help.cc
+ hiscore.cc
+ hooks.cc
+ init1.cc
+ init2.cc
+ joke.cc
+ levels.cc
+ loadsave.cc
+ lua_bind.cc
+ melee1.cc
+ melee2.cc
+ messages.cc
+ mimic.cc
+ modules.cc
+ monster1.cc
+ monster2.cc
+ monster3.cc
+ notes.cc
+ object1.cc
+ object2.cc
+ object_filter.cc
+ options.cc
+ powers.cc
+ q_betwen.cc
+ q_bounty.cc
+ q_dragons.cc
+ q_eol.cc
+ q_evil.cc
+ q_fireprof.cc
+ q_god.cc
+ q_god.cc
+ q_haunted.cc
+ q_hobbit.cc
+ q_invas.cc
+ q_library.cc
+ q_main.cc
+ q_narsil.cc
+ q_nazgul.cc
+ q_nirna.cc
+ q_one.cc
+ q_poison.cc
+ q_rand.cc
+ q_shroom.cc
+ q_spider.cc
+ q_thief.cc
+ q_thrain.cc
+ q_troll.cc
+ q_ultrae.cc
+ q_ultrag.cc
+ q_wight.cc
+ q_wolves.cc
+ quark.cc
+ quest.cc
+ randart.cc
+ range.cc
+ script.cc
+ skills.cc
+ spell_type.cc
+ spells1.cc
+ spells2.cc
+ spells3.cc
+ spells4.cc
+ spells5.cc
+ spells6.cc
+ squeltch.cc
+ status.cc
+ store.cc
+ tables.cc
+ traps.cc
+ util.cc
+ variable.cc
+ wild.cc
+ wizard1.cc
+ wizard2.cc
+ xtra1.cc
+ xtra2.cc
+ z-form.c
+ z-rand.c
+ z-term.c
+ z-util.c
+)
+
+# Sources (PROGRAM)
+SET(SRCS_PROGRAM
+ main-gcu.c
+ main-gtk2.c
+ main-sdl.c
+ main-x11.c
+ main.c
+)
+
+# Sources (TEST)
+SET(SRCS_TESTS
+ ../tests/get_level_device.cc
+ ../tests/harness.cc
+ ../tests/lua_get_level.cc
+)
+
+ADD_LIBRARY(game
+ ${SRCS_COMMON}
)
# Need a few additional source files for Windows.
if(WIN32)
- SET(SRCS ${SRCS} main-win.c readdib.c)
+ SET(SRCS ${SRCS} main-win.c)
# Resource files require a little workaround.
if(MINGW)
# Workaround for resource compilation for mingw on CMake.
@@ -38,12 +145,13 @@ if(WIN32)
endif(MINGW)
endif(WIN32)
-
# tome executable
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
-ADD_EXECUTABLE(tome ${EXECUTABLE_OPTIONS} ${SRCS})
-TARGET_LINK_LIBRARIES(tome ${LIBS})
+ADD_EXECUTABLE(tome ${EXECUTABLE_OPTIONS} ${SRCS_PROGRAM})
+TARGET_LINK_LIBRARIES(tome game squelch ${LIBS})
+
+# test harness executable
+ADD_EXECUTABLE(harness ${EXECUTABLE_OPTIONS} ${SRCS_TESTS})
+TARGET_LINK_LIBRARIES(harness game squelch ${LIBS})
# Installation
INSTALL(TARGETS tome
diff --git a/src/ability_type.hpp b/src/ability_type.hpp
new file mode 100644
index 00000000..ea8a921d
--- /dev/null
+++ b/src/ability_type.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Abilities.
+ */
+struct ability_type
+{
+ const char *name; /* Name */
+ char *desc; /* Description */
+
+ const char *action_desc; /* Action Description */
+
+ s16b action_mkey; /* Action do to */
+
+ s16b cost; /* Skill points cost */
+
+ bool_ acquired; /* Do the player actualylg ot it ? */
+
+ /* Prereqs */
+ s16b skills[10]; /* List of prereq skills(10 max) */
+ s16b skill_levels[10]; /* List of prereq skills(10 max) */
+ s16b stat[6]; /* List of prereq stats */
+ s16b need_abilities[10]; /* List of prereq abilities(10 max) */
+ s16b forbid_abilities[10]; /* List of forbidden abilities(10 max) */
+};
diff --git a/src/ability_type_fwd.hpp b/src/ability_type_fwd.hpp
new file mode 100644
index 00000000..bade8638
--- /dev/null
+++ b/src/ability_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct ability_type;
diff --git a/src/activation.hpp b/src/activation.hpp
new file mode 100644
index 00000000..adb9d8bc
--- /dev/null
+++ b/src/activation.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Activation descriptor.
+ */
+struct activation
+{
+ char desc[80]; /* Desc of the activation */
+ u32b cost; /* costs value */
+ s16b spell; /* Spell. */
+};
diff --git a/src/alchemist_recipe.hpp b/src/alchemist_recipe.hpp
new file mode 100644
index 00000000..e87531f6
--- /dev/null
+++ b/src/alchemist_recipe.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct alchemist_recipe
+{
+ int sval_essence;
+ byte tval;
+ byte sval;
+ byte qty;
+};
diff --git a/src/alchemist_recipe_fwd.hpp b/src/alchemist_recipe_fwd.hpp
new file mode 100644
index 00000000..d1a8bb77
--- /dev/null
+++ b/src/alchemist_recipe_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct alchemist_recipe;
diff --git a/src/alloc_entry.hpp b/src/alloc_entry.hpp
new file mode 100644
index 00000000..41ec3b66
--- /dev/null
+++ b/src/alloc_entry.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * An entry for the object/monster allocation functions
+ *
+ * Pass 1 is determined from allocation information
+ * Pass 2 is determined from allocation restriction
+ * Pass 3 is determined from allocation calculation
+ */
+struct alloc_entry
+{
+ s16b index; /* The actual index */
+
+ byte level; /* Base dungeon level */
+ byte prob1; /* Probability, pass 1 */
+ byte prob2; /* Probability, pass 2 */
+ byte prob3; /* Probability, pass 3 */
+};
diff --git a/src/alloc_entry_fwd.hpp b/src/alloc_entry_fwd.hpp
new file mode 100644
index 00000000..167af118
--- /dev/null
+++ b/src/alloc_entry_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct alloc_entry;
diff --git a/src/angband.h b/src/angband.h
index 6bfbb984..ccf5295a 100644
--- a/src/angband.h
+++ b/src/angband.h
@@ -1,9 +1,4 @@
-/* File: angband.h */
-
-/* Main "Angband" header file */
-
-#ifndef INCLUDED_ANGBAND_H
-#define INCLUDED_ANGBAND_H
+#pragma once
/*
* Copyright (c) 1989 James E. Wilson
@@ -13,7 +8,6 @@
* included in all such copies.
*/
-
/*
* C++ guard.
*/
@@ -32,7 +26,6 @@ extern "C" {
* Then, include the header files for the low-level code
*/
#include "z-util.h"
-#include "z-virt.h"
#include "z-form.h"
#include "z-rand.h"
#include "z-term.h"
@@ -45,19 +38,9 @@ extern "C" {
/*
- * SGLIB
- */
-#include "sglib.h"
-
-
-/*
- * Now, include the define's, the type's, and the extern's
+ * Now, include the defines and the types
*/
#include "defines.h"
-#include "types.h"
-#include "spell_type_fwd.h"
-#include "externs.h"
-#include "plots.h"
/***** Some copyright messages follow below *****/
@@ -110,8 +93,3 @@ extern "C" {
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif
-
-
-
diff --git a/src/angband.rc b/src/angband.rc
index 547d43a1..37856f4a 100644
--- a/src/angband.rc
+++ b/src/angband.rc
@@ -101,25 +101,10 @@ ANGBAND MENU
POPUP "&Options"
{
- POPUP "&Graphics"
- {
- MENUITEM "&Old tiles", 400
- MENUITEM "&New tiles", 401
- MENUITEM "ASCII &Text", 403
- MENUITEM "&Bigtile mode", 409
- }
-
- MENUITEM "&Sound", 402
- MENUITEM SEPARATOR
MENUITEM "Unused menu option", 410
MENUITEM "Activate Screensaver", 411
}
- POPUP "&Help"
- {
- MENUITEM "&General", 901
- MENUITEM "&Spoilers", 902
- }
}
ANGBAND ICON "angband.ico"
diff --git a/src/artifact_select_flag.hpp b/src/artifact_select_flag.hpp
new file mode 100644
index 00000000..313f3a19
--- /dev/null
+++ b/src/artifact_select_flag.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct artifact_select_flag {
+ byte group; /* Flag group to display it in */
+ int flag; /* item flag to set */
+ byte level; /* Player skill level to start at */
+ char *desc; /* Display this description to select flag */
+ u32b xp; /* xp cost for this flag */
+ bool_ pval; /* indicates this flag benifits from pval */
+ char *item_desc; /* Description of required item */
+ char *item_descp; /* Description of required item; plural */
+ byte rtval; /* Required items' tval */
+ byte rsval; /* Required items' sval */
+ int rpval; /* Required items' pval (zero for no req) */
+ int rflag[6]; /* Monster Race flags for required Corpses */
+};
diff --git a/src/artifact_select_flag_fwd.hpp b/src/artifact_select_flag_fwd.hpp
new file mode 100644
index 00000000..f56ec3c9
--- /dev/null
+++ b/src/artifact_select_flag_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct artifact_select_flag;
diff --git a/src/artifact_type.hpp b/src/artifact_type.hpp
new file mode 100644
index 00000000..7a4340aa
--- /dev/null
+++ b/src/artifact_type.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Artifact descriptor.
+ *
+ * Note that the save-file only writes "cur_num" to the savefile.
+ *
+ * Note that "max_num" is always "1" (if that artifact "exists")
+ */
+struct artifact_type
+{
+ char const *name; /* Artifact name */
+ char *text; /* Artifact description */
+
+ byte tval; /* Artifact type */
+ byte sval; /* Artifact sub type */
+
+ s16b pval; /* Artifact extra info */
+
+ s16b to_h; /* Bonus to hit */
+ s16b to_d; /* Bonus to damage */
+ s16b to_a; /* Bonus to armor */
+
+ s16b activate; /* Activation Number */
+
+ s16b ac; /* Base armor */
+
+ byte dd, ds; /* Damage when hits */
+
+ s16b weight; /* Weight */
+
+ s32b cost; /* Artifact "cost" */
+
+ u32b flags1; /* Artifact Flags, set 1 */
+ u32b flags2; /* Artifact Flags, set 2 */
+ u32b flags3; /* Artifact Flags, set 3 */
+ u32b flags4; /* Artifact Flags, set 4 */
+ u32b flags5; /* Artifact Flags, set 5 */
+
+ u32b oflags1; /* Obvious Flags, set 1 */
+ u32b oflags2; /* Obvious Flags, set 2 */
+ u32b oflags3; /* Obvious Flags, set 3 */
+ u32b oflags4; /* Obvious Flags, set 4 */
+ u32b oflags5; /* Obvious Flags, set 5 */
+
+ byte level; /* Artifact level */
+ byte rarity; /* Artifact rarity */
+
+ byte cur_num; /* Number created (0 or 1) */
+ byte max_num; /* Unused (should be "1") */
+
+ u32b esp; /* ESP flags */
+ u32b oesp; /* ESP flags */
+
+ s16b power; /* Power granted(if any) */
+
+ s16b set; /* Does it belongs to a set ?*/
+};
diff --git a/src/artifact_type_fwd.hpp b/src/artifact_type_fwd.hpp
new file mode 100644
index 00000000..f3862d5a
--- /dev/null
+++ b/src/artifact_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct artifact_type;
diff --git a/src/between_exit.hpp b/src/between_exit.hpp
new file mode 100644
index 00000000..7ea686d7
--- /dev/null
+++ b/src/between_exit.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Surface-level void gates descriptor.
+ */
+struct between_exit
+{
+ s16b corresp; /* Corresponding between gate */
+ bool_ dungeon; /* Do we exit in a dungeon or in the wild ? */
+
+ s16b wild_x, wild_y; /* Wilderness spot to land onto */
+ s16b px, py; /* Location of the map */
+
+ s16b d_idx; /* Dungeon to land onto */
+ s16b level;
+};
diff --git a/src/birth.c b/src/birth.cc
index 85939b8e..9716cc8b 100644
--- a/src/birth.c
+++ b/src/birth.cc
@@ -1,7 +1,3 @@
-/* File: birth.c */
-
-/* Purpose: create a player character */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -9,10 +5,57 @@
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
-
-#include "angband.h"
-
-#include "messages.h"
+#include "birth.hpp"
+#include "birth.h"
+
+#include "ability_type.hpp"
+#include "artifact_type.hpp"
+#include "corrupt.hpp"
+#include "cmd4.hpp"
+#include "cmd5.hpp"
+#include "dungeon_info_type.hpp"
+#include "files.h"
+#include "files.hpp"
+#include "gods.hpp"
+#include "help.hpp"
+#include "hist_type.hpp"
+#include "hooks.hpp"
+#include "init2.hpp"
+#include "mimic.hpp"
+#include "messages.hpp"
+#include "meta_class_type.hpp"
+#include "modules.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "q_rand.hpp"
+#include "skill_type.hpp"
+#include "skills.hpp"
+#include "spells2.hpp"
+#include "spells3.hpp"
+#include "spells5.hpp"
+#include "stats.hpp"
+#include "store.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <string>
/*
* How often the autoroller will update the display and pause
@@ -57,7 +100,7 @@ static s32b auto_round;
static s32b last_round;
/* Human */
-static char *human_syllable1[] =
+static const char *human_syllable1[] =
{
"Ab", "Ac", "Ad", "Af", "Agr", "Ast", "As", "Al", "Adw", "Adr", "Ar",
"B", "Br", "C", "Cr", "Ch", "Cad", "D", "Dr", "Dw", "Ed", "Eth", "Et",
@@ -67,7 +110,7 @@ static char *human_syllable1[] =
"Tr", "Th", "V", "Y", "Z", "W", "Wic",
};
-static char *human_syllable2[] =
+static const char *human_syllable2[] =
{
"a", "ae", "au", "ao", "are", "ale", "ali", "ay", "ardo", "e", "ei",
"ea", "eri", "era", "ela", "eli", "enda", "erra", "i", "ia", "ie",
@@ -75,7 +118,7 @@ static char *human_syllable2[] =
"ore", "u", "y",
};
-static char *human_syllable3[] =
+static const char *human_syllable3[] =
{
"a", "and", "b", "bwyn", "baen", "bard", "c", "ctred", "cred", "ch",
"can", "d", "dan", "don", "der", "dric", "dfrid", "dus", "f", "g",
@@ -94,7 +137,7 @@ static char *human_syllable3[] =
*/
static void create_random_name(int race, char *name)
{
- char *syl1, *syl2, *syl3;
+ const char *syl1, *syl2, *syl3;
int idx;
@@ -185,9 +228,6 @@ static void save_prev_data(void)
}
previous_char.luck = p_ptr->luck_base;
- /* Save the weapon specialty */
- previous_char.weapon = 0;
-
/* Save the history */
for (i = 0; i < 4; i++)
{
@@ -222,9 +262,6 @@ static void load_prev_data(bool_ save)
}
temp.luck = p_ptr->luck_base;
- /* Save the weapon specialty */
- temp.weapon = 0;
-
/* Save the history */
for (i = 0; i < 4; i++)
{
@@ -274,12 +311,6 @@ static void load_prev_data(bool_ save)
}
previous_char.luck = temp.luck;
- /* Save the chaos patron */
- previous_char.chaos_patron = temp.chaos_patron;
-
- /* Save the weapon specialty */
- previous_char.weapon = temp.weapon;
-
/* Save the history */
for (i = 0; i < 4; i++)
{
@@ -334,22 +365,10 @@ static int adjust_stat(int value, int amount, int auto_roll)
{
value++;
}
- else if (p_ptr->maximize)
+ else
{
value += 10;
}
- else if (value < 18 + 70)
- {
- value += ((auto_roll ? 15 : randint(15)) + 5);
- }
- else if (value < 18 + 90)
- {
- value += ((auto_roll ? 6 : randint(6)) + 2);
- }
- else if (value < 18 + 100)
- {
- value++;
- }
}
}
@@ -418,25 +437,11 @@ static void get_stats(void)
/* Obtain a "bonus" for "race" and "class" */
bonus = rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i];
- /* Variable stat maxes */
- if (p_ptr->maximize)
- {
- /* Start fully healed */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i];
+ /* Start fully healed */
+ p_ptr->stat_cur[i] = p_ptr->stat_max[i];
- /* Efficiency -- Apply the racial/class bonuses */
- stat_use[i] = modify_stat_value(p_ptr->stat_max[i], bonus);
- }
-
- /* Fixed stat maxes */
- else
- {
- /* Apply the bonus to the stat (somewhat randomly) */
- stat_use[i] = adjust_stat(p_ptr->stat_max[i], bonus, FALSE);
-
- /* Save the resulting stat maximum */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stat_use[i];
- }
+ /* Efficiency -- Apply the racial/class bonuses */
+ stat_use[i] = modify_stat_value(p_ptr->stat_max[i], bonus);
/* No temporary drain (yet...) */
p_ptr->stat_cnt[i] = 0;
@@ -463,11 +468,8 @@ static void get_extra(void)
/* Experience factor */
p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp;
- /* Initialize arena and rewards information -KMW- */
- p_ptr->arena_number = 0;
- p_ptr->inside_arena = 0;
+ /* Initialize quest */
p_ptr->inside_quest = 0;
- p_ptr->exit_bldg = TRUE; /* only used for arena now -KMW- */
/* Hitdice */
p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp;
@@ -549,7 +551,7 @@ static void get_history(void)
while ((chart != bg[i].chart) || (roll > bg[i].roll)) i++;
/* Acquire the textual history */
- (void)strcat(buf, bg[i].info + rp_text);
+ (void)strcat(buf, bg[i].info);
/* Add in the social class */
social_class += (int)(bg[i].bonus) - 50;
@@ -618,7 +620,7 @@ static void get_history(void)
/*
* Fill the random_artifacts array with relevant info.
*/
-errr init_randart(void)
+static errr init_randart(void)
{
int i;
@@ -804,7 +806,11 @@ static void player_wipe(void)
wipe_saved();
/* Hack -- zero the struct */
- p_ptr = WIPE(p_ptr, player_type);
+ static_assert(std::is_pod<player_type>::value, "Cannot memset non-POD type");
+ memset(p_ptr, 0, sizeof(player_type));
+
+ /* Level 1 is the first level */
+ p_ptr->lev = 1;
/* Not dead yet */
p_ptr->lives = 0;
@@ -838,9 +844,9 @@ static void player_wipe(void)
for (i = 0; i < MAX_Q_IDX; i++)
{
quest[i].status = QUEST_STATUS_UNTAKEN;
- for (j = 0; j < sizeof(quest[i].data)/sizeof(quest[i].data[0]); j++)
+ for (auto &quest_data : quest[i].data)
{
- quest[i].data[j] = 0;
+ quest_data = 0;
}
}
@@ -964,12 +970,6 @@ static void player_wipe(void)
p_ptr->body_monster = 0;
p_ptr->disembodied = FALSE;
- /* Wipe the bounties */
- total_bounties = 0;
-
- /* Wipe spells */
- p_ptr->xtra_spells = 0;
-
/* Wipe xtra hp */
p_ptr->hp_mod = 0;
@@ -1005,8 +1005,6 @@ static void player_wipe(void)
/* Initialize allow_one_death */
p_ptr->allow_one_death = 0;
- p_ptr->loan = p_ptr->loan_time = 0;
-
/* Wipe the power list */
for (i = 0; i < POWER_MAX; i++)
{
@@ -1088,8 +1086,8 @@ static void player_outfit_spellbook(cptr spell_name)
static void player_outfit(void)
{
int i;
- cptr class_name = spp_ptr->title + c_name;
- cptr subrace_name = rmp_ptr->title + rmp_name;
+ cptr class_name = spp_ptr->title;
+ cptr subrace_name = rmp_ptr->title;
/*
* Get an adventurer guide describing a bit of the
@@ -1223,14 +1221,14 @@ static void player_outfit(void)
identify_pack_fully();
}
- if (streq(rmp_ptr->title + rmp_name, "Vampire"))
+ if (streq(rmp_ptr->title, "Vampire"))
{
player_gain_corruption(CORRUPT_VAMPIRE_TEETH);
player_gain_corruption(CORRUPT_VAMPIRE_STRENGTH);
player_gain_corruption(CORRUPT_VAMPIRE_VAMPIRE);
}
- process_hooks(HOOK_BIRTH_OBJECTS, "()");
+ process_hooks_new(HOOK_BIRTH_OBJECTS, NULL, NULL);
meta_inertia_control_hook_birth_objects();
{
@@ -1287,169 +1285,11 @@ static void player_outfit(void)
}
-/* Possible number(and layout) or random quests */
-#define MAX_RANDOM_QUESTS_TYPES ((8 * 3) + (8 * 1))
-int random_quests_types[MAX_RANDOM_QUESTS_TYPES] =
-{
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 20, 13, 15, 16, 9, 17, 18, 8, /* Hero Sword Quest */
-};
-
-/* Enforce OoD monsters until this level */
-#define RQ_LEVEL_CAP 49
-
-static void gen_random_quests(int n)
-{
- int step, lvl, i, k;
- int old_type = dungeon_type;
-
- /* Factor dlev value by 1000 to keep precision */
- step = (98 * 1000) / n;
-
- lvl = step / 2;
-
- quest[QUEST_RANDOM].status = QUEST_STATUS_TAKEN;
-
- for (i = 0; i < n; i++)
- {
- monster_race *r_ptr = &r_info[2];
-
- int rl = (lvl / 1000) + 1;
-
- int min_level;
-
- int tries = 5000;
-
- random_quest *q_ptr = &random_quests[rl];
-
- int j;
-
- /* Find the appropriate dungeon */
- for (j = 0; j < max_d_idx; j++)
- {
- dungeon_info_type *d_ptr = &d_info[j];
-
- if (!(d_ptr->flags1 & DF1_PRINCIPAL)) continue;
-
- if ((d_ptr->mindepth <= rl) && (rl <= d_ptr->maxdepth))
- {
- dungeon_type = j;
- break;
- }
- }
-
- q_ptr->type = random_quests_types[rand_int(MAX_RANDOM_QUESTS_TYPES)];
-
- /* XXX XXX XXX Try until valid choice is found */
- while (tries)
- {
- bool_ ok;
-
- tries--;
-
- /* Random monster 5 - 10 levels out of depth */
- q_ptr->r_idx = get_mon_num(rl + 4 + randint(6));
-
- if (!q_ptr->r_idx) continue;
-
- r_ptr = &r_info[q_ptr->r_idx];
-
- /* Accept only monsters that can be generated */
- if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue;
- if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
-
- /* Accept only monsters that are not breeders */
- if (r_ptr->flags4 & RF4_MULTIPLY) continue;
-
- /* Forbid joke monsters */
- if (r_ptr->flags8 & RF8_JOKEANGBAND) continue;
-
- /* Accept only monsters that are not friends */
- if (r_ptr->flags7 & RF7_PET) continue;
-
- /* Refuse nazguls */
- if (r_ptr->flags7 & RF7_NAZGUL) continue;
-
- /* Accept only monsters that are not good */
- if (r_ptr->flags3 & RF3_GOOD) continue;
-
- /* If module says a monster race is friendly, then skip */
- if (modules[game_module_idx].race_status != NULL)
- {
- s16b *status = (*modules[game_module_idx].race_status)(q_ptr->r_idx);
- if ((status != NULL) && (*status >= 0))
- {
- continue;
- }
- }
-
- /* Assume no explosion attacks */
- ok = TRUE;
-
- /* Reject monsters with exploding attacks */
- for (k = 0; k < 4; k++)
- {
- if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE;
- }
- if (!ok) continue;
-
- /* No mutliple uniques */
- if ((r_ptr->flags1 & RF1_UNIQUE) &&
- ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue;
-
- /* No single non uniques */
- if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue;
-
- /* Level restriction */
- min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl;
-
- /* Accept monsters matching the level restriction */
- if (r_ptr->level > min_level) break;
- }
-
- /* Arg could not find anything ??? */
- if (!tries)
- {
- if (wizard)
- {
- message_add(format("Could not find quest monster on lvl %d", rl), TERM_RED);
- }
- q_ptr->type = 0;
- }
- else
- {
- if (r_ptr->flags1 & RF1_UNIQUE)
- {
- r_ptr->max_num = -1;
- }
-
- q_ptr->done = FALSE;
-
- if (wizard)
- {
- message_add(format("Quest for %d on lvl %d",
- q_ptr->r_idx, rl), TERM_RED);
- }
- }
-
- lvl += step;
- }
-
- dungeon_type = old_type;
-}
-
int dump_classes(s16b *classes, int sel, u32b *restrictions)
{
int n = 0;
char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, c_head->text_size, char);
/* Clean up */
clear_from(12);
@@ -1462,7 +1302,6 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions)
/* Analyze */
p_ptr->pclass = classes[n];
cp_ptr = &class_info[p_ptr->pclass];
- str = cp_ptr->title + c_name;
if (sel == n)
{
@@ -1472,14 +1311,20 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions)
/* Display */
strnfmt(buf, 80, "%c%c%c %s%s", p1,
- (n <= 25) ? I2A(n) : I2D(n - 26), p2, str, mod);
+ (n <= 25) ? I2A(n) : I2D(n - 26), p2, cp_ptr->title, mod);
/* Print some more info */
if (sel == n)
{
- strnfmt(desc, c_head->text_size, "%s%s", cp_ptr->desc + c_text,
- cp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
+ std::string desc;
+
+ desc += cp_ptr->desc;
+ if (cp_ptr->flags1 & PR1_EXPERIMENTAL)
+ {
+ desc += "\nEXPERIMENTAL";
+ }
+
+ print_desc(desc.c_str());
if (!(restrictions[classes[n] / 32] & BIT(classes[n])) ||
cp_ptr->flags1 & PR1_EXPERIMENTAL)
@@ -1498,8 +1343,6 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions)
n++;
}
- C_FREE(desc, c_head->text_size, char);
-
return (n);
}
@@ -1508,11 +1351,6 @@ int dump_specs(int sel)
int n = 0;
char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, c_head->text_size, char);
/* Clean up */
clear_from(12);
@@ -1527,7 +1365,6 @@ int dump_specs(int sel)
/* Analyze */
p_ptr->pspec = n;
spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
- str = spp_ptr->title + c_name;
if (sel == n)
{
@@ -1536,14 +1373,20 @@ int dump_specs(int sel)
}
/* Display */
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
+ strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, spp_ptr->title);
/* Print some more info */
if (sel == n)
{
- strnfmt(desc, c_head->text_size, "%s%s", spp_ptr->desc + c_text,
- spp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
+ std::string desc;
+
+ desc += spp_ptr->desc;
+ if (spp_ptr->flags1 & PR1_EXPERIMENTAL)
+ {
+ desc += "\nEXPERIMENTAL";
+ }
+
+ print_desc(desc.c_str());
if (spp_ptr->flags1 & PR1_EXPERIMENTAL)
c_put_str(TERM_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
@@ -1559,8 +1402,6 @@ int dump_specs(int sel)
}
}
- C_FREE(desc, c_head->text_size, char);
-
return (n);
}
@@ -1569,11 +1410,6 @@ int dump_races(int sel)
int n = 0;
char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, rp_head->text_size, char);
/* Clean up */
clear_from(12);
@@ -1585,7 +1421,6 @@ int dump_races(int sel)
/* Analyze */
p_ptr->prace = n;
rp_ptr = &race_info[p_ptr->prace];
- str = rp_ptr->title + rp_name;
if (sel == n)
{
@@ -1594,14 +1429,20 @@ int dump_races(int sel)
}
/* Display */
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
+ strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, rp_ptr->title);
/* Print some more info */
if (sel == n)
{
- strnfmt(desc, rp_head->text_size, "%s%s", rp_ptr->desc + rp_text,
- rp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
+ std::string desc;
+
+ desc += rp_ptr->desc;
+ if (rp_ptr->flags1 & PR1_EXPERIMENTAL)
+ {
+ desc += "\nEXPERIMENTAL";
+ }
+
+ print_desc(desc.c_str());
if (rp_ptr->flags1 & PR1_EXPERIMENTAL)
c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
@@ -1617,8 +1458,6 @@ int dump_races(int sel)
}
}
- C_FREE(desc, rp_head->text_size, char);
-
return (n);
}
@@ -1628,11 +1467,6 @@ int dump_rmods(int sel, int *racem, int max)
int n = 0;
char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, rmp_head->text_size, char);
/* Clean up */
clear_from(12);
@@ -1645,7 +1479,6 @@ int dump_rmods(int sel, int *racem, int max)
/* Analyze */
p_ptr->pracem = racem[n];
rmp_ptr = &race_mod_info[p_ptr->pracem];
- str = rmp_ptr->title + rmp_name;
if (sel == n)
{
@@ -1655,16 +1488,22 @@ int dump_rmods(int sel, int *racem, int max)
/* Display */
if (racem[n])
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
+ strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, rmp_ptr->title);
else
strnfmt(buf, 80, "%c%c%c Classical", p1, I2A(n), p2);
/* Print some more info */
if (sel == n)
{
- strnfmt(desc, rmp_head->text_size, "%s%s", rmp_ptr->desc + rmp_text,
- rmp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
+ std::string desc;
+
+ desc += rmp_ptr->desc;
+ if (rmp_ptr->flags1 & PR1_EXPERIMENTAL)
+ {
+ desc += "\nEXPERIMENTAL";
+ }
+
+ print_desc(desc.c_str());
if (rmp_ptr->flags1 & PR1_EXPERIMENTAL)
c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
@@ -1680,8 +1519,6 @@ int dump_rmods(int sel, int *racem, int max)
}
}
- C_FREE(desc, rmp_head->text_size, char);
-
return (n);
}
@@ -1754,8 +1591,6 @@ static bool_ player_birth_aux_ask()
u32b restrictions[2];
- cptr str;
-
char c;
char p2 = ')';
@@ -1842,10 +1677,9 @@ static bool_ player_birth_aux_ask()
/* Analyze */
p_ptr->psex = n;
sp_ptr = &sex_info[p_ptr->psex];
- str = sp_ptr->title;
/* Display */
- strnfmt(buf, 200, "%c%c %s", I2A(n), p2, str);
+ strnfmt(buf, 200, "%c%c %s", I2A(n), p2, sp_ptr->title);
put_str(buf, 21 + (n / 5), 2 + 15 * (n % 5));
}
@@ -1878,10 +1712,9 @@ static bool_ player_birth_aux_ask()
/* 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, 9);
+ c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
/* Clean up */
clear_from(15);
@@ -1927,7 +1760,7 @@ static bool_ player_birth_aux_ask()
if ((k >= 0) && (k < n)) break;
if (c == '?')
{
- help_race(race_info[sel].title + rp_name);
+ help_race(race_info[sel].title);
}
else if (c == '=')
{
@@ -1973,10 +1806,9 @@ static bool_ player_birth_aux_ask()
/* Set race */
p_ptr->prace = k;
rp_ptr = &race_info[p_ptr->prace];
- str = rp_ptr->title + rp_name;
/* Display */
- c_put_str(TERM_L_BLUE, str, 4, 9);
+ c_put_str(TERM_L_BLUE, rp_ptr->title, 4, 9);
/* Get a random name */
if (!do_quick_start) create_random_name(p_ptr->prace, player_name);
@@ -2053,7 +1885,7 @@ static bool_ player_birth_aux_ask()
}
else if (c == '?')
{
- help_subrace(race_mod_info[racem[sel]].title + rmp_name);
+ help_subrace(race_mod_info[racem[sel]].title);
}
k = (islower(c) ? A2I(c) : -1);
@@ -2199,7 +2031,7 @@ static bool_ player_birth_aux_ask()
if ((k >= 0) && (k < n)) break;
if (c == '?')
{
- help_class(class_info[class_types[sel]].title + c_name);
+ help_class(class_info[class_types[sel]].title);
}
else if (c == '=')
{
@@ -2281,7 +2113,7 @@ static bool_ player_birth_aux_ask()
if ((k >= 0) && (k < n)) break;
if (c == '?')
{
- help_class(class_info[p_ptr->pclass].spec[sel].title + c_name);
+ help_class(class_info[p_ptr->pclass].spec[sel].title);
}
else if (c == '=')
{
@@ -2327,10 +2159,9 @@ static bool_ player_birth_aux_ask()
}
cp_ptr = &class_info[p_ptr->pclass];
spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
- str = spp_ptr->title + c_name;
/* Display */
- c_put_str(TERM_L_BLUE, str, 5, 9);
+ c_put_str(TERM_L_BLUE, spp_ptr->title, 5, 9);
/* Clean up */
clear_from(15);
@@ -2342,7 +2173,7 @@ static bool_ player_birth_aux_ask()
p_ptr->pgod = k;
set_grace(previous_char.grace);
}
- else if (PRACE_FLAG(PR1_NO_GOD))
+ else if (race_flags1_p(PR1_NO_GOD))
{
p_ptr->pgod = GOD_NONE;
}
@@ -2449,7 +2280,7 @@ static bool_ player_birth_aux_ask()
}
/* A god that like us ? more grace ! */
- if (PRACE_FLAGS(PR1_GOD_FRIEND))
+ if (race_flags1_p(PR1_GOD_FRIEND))
{
set_grace(200);
}
@@ -2477,10 +2308,9 @@ static bool_ player_birth_aux_ask()
}
/* Set birth options: maximize, preserve, sepcial levels and astral */
- p_ptr->maximize = maximize;
p_ptr->preserve = preserve;
p_ptr->special = special_lvls;
- p_ptr->astral = (PRACE_FLAG2(PR2_ASTRAL)) ? TRUE : FALSE;
+ p_ptr->astral = (race_flags2_p(PR2_ASTRAL)) ? TRUE : FALSE;
/*
* A note by pelpel. (remove this please)
@@ -2571,9 +2401,8 @@ static bool_ player_birth_aux_ask()
/* Prepare allocation table */
get_mon_num_prep();
- /* Generate quests */
- for (i = 0; i < MAX_RANDOM_QUEST; i++) random_quests[i].type = 0;
- if (v) gen_random_quests(v);
+ /* Generate random quests */
+ initialize_random_quests(v);
max_quests = v;
p_ptr->inside_quest = 0;
@@ -2671,9 +2500,6 @@ static bool_ player_birth_aux_point(void)
/* Roll for social class */
get_history();
- /*** Generate ***/
- process_hooks(HOOK_BIRTH, "()");
-
/* Get luck */
p_ptr->luck_base = rp_ptr->luck + rmp_ptr->luck + rand_range( -5, 5);
p_ptr->luck_max = p_ptr->luck_base;
@@ -2687,24 +2513,8 @@ static bool_ player_birth_aux_point(void)
/* Process stats */
for (i = 0; i < 6; i++)
{
- /* Variable stat maxes */
- if (p_ptr->maximize)
- {
- /* Reset stats */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stats[i];
-
- }
-
- /* Fixed stat maxes */
- else
- {
- /* Obtain a "bonus" for "race" and "class" */
- int bonus = rp_ptr->r_adj[i] + cp_ptr->c_adj[i];
-
- /* Apply the racial/class bonuses */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] =
- modify_stat_value(stats[i], bonus);
- }
+ /* Reset stats */
+ p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stats[i];
/* Total cost */
cost += birth_stat_costs[stats[i] - 10];
@@ -2946,7 +2756,7 @@ static bool_ player_birth_aux_auto()
c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
strnfmt(buf, 80, "%s", get_player_race_name(p_ptr->prace, p_ptr->pracem));
c_put_str(TERM_L_BLUE, buf, 4, 9);
- c_put_str(TERM_L_BLUE, spp_ptr->title + c_name, 5, 9);
+ c_put_str(TERM_L_BLUE, spp_ptr->title, 5, 9);
/* Label stats */
put_str("STR:", 2 + A_STR, 61);
@@ -3021,11 +2831,8 @@ static bool_ player_birth_aux_auto()
/* Make sure they see everything */
Term_fresh();
- /* Do not wait for a key */
- inkey_scan = TRUE;
-
/* Check for a keypress */
- if (inkey()) break;
+ if (inkey_scan()) break;
}
}
@@ -3050,9 +2857,6 @@ static bool_ player_birth_aux_auto()
/* Roll for gold */
get_money();
- /*** Generate ***/
- process_hooks(HOOK_BIRTH, "()");
-
/* Input loop */
while (TRUE)
{
@@ -3574,9 +3378,6 @@ void player_birth(void)
wild_map[j][i].known = FALSE;
}
}
-
- /* Select bounty monsters. */
- select_bounties();
}
@@ -3732,7 +3533,7 @@ void save_savefile_names()
fprintf(fff, "%s@%c%s@%s, the %s %s is %s\n", game_module,
(death) ? '0' : '1', player_base, player_name,
get_player_race_name(p_ptr->prace, p_ptr->pracem),
- spp_ptr->title + c_name,
+ spp_ptr->title,
(!death) ? "alive" : "dead");
for (i = 0; i < max; i++)
diff --git a/src/birth.h b/src/birth.h
new file mode 100644
index 00000000..41620bfa
--- /dev/null
+++ b/src/birth.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bool_ no_begin_screen;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/birth.hpp b/src/birth.hpp
new file mode 100644
index 00000000..fb036ecc
--- /dev/null
+++ b/src/birth.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void print_desc_aux(cptr txt, int y, int x);
+extern void save_savefile_names(void);
+extern bool_ begin_screen(void);
+extern void get_height_weight(void);
+extern void player_birth(void);
diff --git a/src/birther.hpp b/src/birther.hpp
new file mode 100644
index 00000000..f517fb9d
--- /dev/null
+++ b/src/birther.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Player information during the birth process.
+ */
+struct birther
+{
+ s16b sex;
+ s16b race;
+ s16b rmod;
+ s16b pclass;
+ s16b spec;
+
+ byte quests;
+
+ byte god;
+ s32b grace;
+ s32b god_favor;
+
+ s16b age;
+ s16b wt;
+ s16b ht;
+ s16b sc;
+
+ s32b au;
+
+ s16b stat[6];
+ s16b luck;
+
+ char history[4][60];
+
+ bool_ quick_ok;
+};
diff --git a/src/bldg.c b/src/bldg.cc
index 6b785d2a..dd433323 100644
--- a/src/bldg.c
+++ b/src/bldg.cc
@@ -13,10 +13,33 @@
* Heavily modified for ToME by DarkGod
*/
-#include "angband.h"
-
-/* hack as in leave_store in store.c */
-static bool_ leave_bldg = FALSE;
+#include "cave_type.hpp"
+#include "cmd3.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hook_quest_fail_in.hpp"
+#include "hook_init_quest_in.hpp"
+#include "mimic.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "owner_type.hpp"
+#include "player_type.hpp"
+#include "q_library.hpp"
+#include "q_fireprof.hpp"
+#include "q_bounty.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "store.hpp"
+#include "store_action_type.hpp"
+#include "store_info_type.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
/* remember building location */
static int building_loc = 0;
@@ -25,7 +48,7 @@ static int building_loc = 0;
/*
* A helper function for is_state
*/
-bool_ is_state_aux(store_type *s_ptr, int state)
+static bool_ is_state_aux(store_type *s_ptr, int state)
{
owner_type *ow_ptr = &ow_info[s_ptr->owner];
@@ -96,12 +119,10 @@ void show_building(store_type *s_ptr)
store_info_type *st_ptr = &st_info[s_ptr->st_idx];
- store_action_type *ba_ptr;
-
for (i = 0; i < 6; i++)
{
- ba_ptr = &ba_info[st_ptr->actions[i]];
+ store_action_type *ba_ptr = &ba_info[st_ptr->actions[i]];
if (ba_ptr->letter != '.')
{
@@ -176,130 +197,13 @@ void show_building(store_type *s_ptr)
strnfmt(tmp_str, 80, " %c", ba_ptr->letter);
c_put_str(TERM_YELLOW, tmp_str, 21 + (i / 2), 17 + (30 * (i % 2)));
- strnfmt(tmp_str, 80, ") %s %s", ba_ptr->name + ba_name, buff);
+ strnfmt(tmp_str, 80, ") %s %s", ba_ptr->name, buff);
c_put_str(action_color, tmp_str, 21 + (i / 2), 2 + 17 + (30 * (i % 2)));
}
}
}
-/* reset timed flags */
-static void reset_tim_flags()
-{
- p_ptr->fast = 0; /* Timed -- Fast */
- p_ptr->slow = 0; /* Timed -- Slow */
- p_ptr->blind = 0; /* Timed -- Blindness */
- p_ptr->paralyzed = 0; /* Timed -- Paralysis */
- p_ptr->confused = 0; /* Timed -- Confusion */
- p_ptr->afraid = 0; /* Timed -- Fear */
- p_ptr->image = 0; /* Timed -- Hallucination */
- p_ptr->poisoned = 0; /* Timed -- Poisoned */
- p_ptr->cut = 0; /* Timed -- Cut */
- p_ptr->stun = 0; /* Timed -- Stun */
-
- p_ptr->protevil = 0; /* Timed -- Protection */
- p_ptr->protgood = 0; /* Timed -- Protection */
- p_ptr->invuln = 0; /* Timed -- Invulnerable */
- p_ptr->hero = 0; /* Timed -- Heroism */
- p_ptr->shero = 0; /* Timed -- Super Heroism */
- p_ptr->shield = 0; /* Timed -- Shield Spell */
- p_ptr->blessed = 0; /* Timed -- Blessed */
- p_ptr->tim_invis = 0; /* Timed -- Invisibility */
- p_ptr->tim_infra = 0; /* Timed -- Infra Vision */
-
- p_ptr->oppose_acid = 0; /* Timed -- oppose acid */
- p_ptr->oppose_elec = 0; /* Timed -- oppose lightning */
- p_ptr->oppose_fire = 0; /* Timed -- oppose heat */
- p_ptr->oppose_cold = 0; /* Timed -- oppose cold */
- p_ptr->oppose_pois = 0; /* Timed -- oppose poison */
-
- p_ptr->confusing = 0; /* Touch of Confusion */
-}
-
-
-/*
- * arena commands
- */
-static void arena_comm(int cmd)
-{
- char tmp_str[80];
-
- monster_race *r_ptr;
-
- cptr name;
-
-
- switch (cmd)
- {
- case BACT_ARENA:
- {
- if (p_ptr->arena_number == MAX_ARENA_MONS)
- {
- clear_bldg(5, 19);
- prt(" Arena Victor!", 5, 0);
- prt("Congratulations! You have defeated all before you.", 7, 0);
- prt("For that, receive the prize: 10,000 gold pieces", 8, 0);
- prt("", 10, 0);
- prt("", 11, 0);
- p_ptr->au += 10000;
- msg_print("Press the space bar to continue");
- msg_print(NULL);
- p_ptr->arena_number++;
- }
- else if (p_ptr->arena_number > MAX_ARENA_MONS)
- {
- msg_print("You enter the arena briefly and bask in your glory.");
- msg_print(NULL);
- }
- else
- {
- p_ptr->inside_arena = TRUE;
- p_ptr->exit_bldg = FALSE;
- reset_tim_flags();
- p_ptr->leaving = TRUE;
- p_ptr->oldpx = p_ptr->px;
- p_ptr->oldpy = p_ptr->py;
- leave_bldg = TRUE;
- }
-
- break;
- }
-
- case BACT_POSTER:
- {
- if (p_ptr->arena_number == MAX_ARENA_MONS)
- msg_print("You are victorious. Enter the arena for the ceremony.");
- else if (p_ptr->arena_number > MAX_ARENA_MONS)
- msg_print("You have won against all foes.");
- else
- {
- r_ptr = &r_info[arena_monsters[p_ptr->arena_number]];
- name = (r_name + r_ptr->name);
- strnfmt(tmp_str, 80, "Do I hear any challenges against: %s", name);
- msg_print(tmp_str);
- msg_print(NULL);
- }
-
- break;
- }
-
- case BACT_ARENA_RULES:
- {
- /* Save screen */
- screen_save();
-
- /* Peruse the arena help file */
- (void)show_file("arena.txt", NULL, 0, 0);
-
- /* Load screen */
- screen_load();
-
- break;
- }
- }
-}
-
-
/*
* display fruit for dice slots
*/
@@ -541,40 +445,6 @@ static bool_ gamble_comm(int cmd)
break;
}
- case BACT_SPIN_WHEEL: /* Spin the Wheel Game */
- {
- win = FALSE;
- odds = 10;
- c_put_str(TERM_GREEN, "Wheel", 5, 2);
- prt("0 1 2 3 4 5 6 7 8 9", 7, 5);
- prt("--------------------------------", 8, 3);
- strcpy(out_val, "");
- get_string ("Pick a number (1-9): ", out_val, 32);
- for (p = out_val; *p == ' '; p++);
- choice = atol(p);
- if (choice < 0)
- {
- msg_print("I'll put you down for 0.");
- choice = 0;
- }
- else if (choice > 9)
- {
- msg_print("Ok, I'll put you down for 9.");
- choice = 9;
- }
- msg_print(NULL);
- roll1 = randint(10) - 1;
- strnfmt(tmp_str, 80, "The wheel spins to a stop and the winner is %d",
- roll1);
- prt(tmp_str, 13, 3);
- prt("", 9, 0);
- prt("*", 9, (3 * roll1 + 5));
- if (roll1 == choice)
- win = TRUE;
-
- break;
- }
-
case BACT_DICE_SLOTS: /* The Dice Slots */
{
c_put_str(TERM_GREEN, "Dice Slots", 5, 2);
@@ -670,7 +540,7 @@ static bool_ inn_comm(int cmd)
/* Extract race info */
- vampire = ((PRACE_FLAG(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")));
+ vampire = ((race_flags1_p(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")));
switch (cmd)
{
@@ -760,9 +630,6 @@ static bool_ inn_comm(int cmd)
p_ptr->oldpx = p_ptr->px;
p_ptr->oldpy = p_ptr->py;
- /* Select new bounties. */
- select_bounties();
-
break;
}
@@ -834,7 +701,8 @@ static bool_ castle_quest(int y, int x)
/* Rewarded quest */
q_ptr->status = QUEST_STATUS_FINISHED;
- process_hooks(HOOK_QUEST_FINISH, "(d)", plots[plot]);
+ struct hook_quest_finish_in in = { plots[plot] };
+ process_hooks_new(HOOK_QUEST_FINISH, &in, NULL);
return (TRUE);
}
@@ -854,14 +722,19 @@ static bool_ castle_quest(int y, int x)
/* Mark quest as done (but failed) */
q_ptr->status = QUEST_STATUS_FAILED_DONE;
- process_hooks(HOOK_QUEST_FAIL, "(d)", plots[plot]);
+ hook_quest_fail_in in = { plots[plot] };
+ process_hooks_new(HOOK_QUEST_FAIL, &in, NULL);
return (FALSE);
}
/* No quest yet */
else if (q_ptr->status == QUEST_STATUS_UNTAKEN)
{
- if (process_hooks(HOOK_INIT_QUEST, "(d)", plots[plot])) return (FALSE);
+ struct hook_init_quest_in in = { plots[plot] };
+ if (process_hooks_new(HOOK_INIT_QUEST, &in, NULL))
+ {
+ return (FALSE);
+ }
q_ptr->status = QUEST_STATUS_TAKEN;
@@ -896,7 +769,7 @@ static void town_history(void)
/*
* compare_weapon_aux2 -KMW-
*/
-static void compare_weapon_aux2(object_type *o_ptr, int numblows, int r, int c, int mult, char attr[80], u32b f1, u32b f2, u32b f3, byte color)
+static void compare_weapon_aux2(object_type *o_ptr, int numblows, int r, int c, int mult, const char *attr, u32b f1, u32b f2, u32b f3, byte color)
{
char tmp_str[80];
@@ -1023,7 +896,7 @@ static void list_weapon(object_type *o_ptr, int row, int col)
/*
* Select melee weapons
*/
-static bool_ item_tester_hook_melee_weapon(object_type *o_ptr)
+static bool item_tester_hook_melee_weapon(object_type const *o_ptr)
{
return (wield_slot(o_ptr) == INVEN_WIELD);
}
@@ -1033,34 +906,28 @@ static bool_ item_tester_hook_melee_weapon(object_type *o_ptr)
*/
static bool_ compare_weapons(void)
{
- int item, item2, i;
+ int item, i;
object_type *o1_ptr, *o2_ptr, *orig_ptr;
- object_type *i_ptr;
-
- cptr q, s;
-
-
clear_bldg(6, 18);
o1_ptr = NULL;
o2_ptr = NULL;
- i_ptr = NULL;
/* Store copy of original wielded weapon in pack slot */
- i_ptr = &p_ptr->inventory[INVEN_WIELD];
+ object_type *i_ptr = &p_ptr->inventory[INVEN_WIELD];
orig_ptr = &p_ptr->inventory[INVEN_PACK];
object_copy(orig_ptr, i_ptr);
i = 6;
- /* Get first weapon */
- /* Restrict choices to meele weapons */
- item_tester_hook = item_tester_hook_melee_weapon;
- q = "What is your first melee weapon? ";
- s = "You have nothing to compare.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN)))
+ /* Get first weapon */
+ if (!get_item(&item,
+ "What is your first melee weapon? ",
+ "You have nothing to compare.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
return (FALSE);
@@ -1071,12 +938,12 @@ static bool_ compare_weapons(void)
o1_ptr = &p_ptr->inventory[item];
/* Get second weapon */
- /* Restrict choices to melee weapons */
- item_tester_hook = item_tester_hook_melee_weapon;
-
- q = "What is your second melee weapon? ";
- s = "You have nothing to compare.";
- if (!get_item(&item2, q, s, (USE_EQUIP | USE_INVEN)))
+ int item2;
+ if (!get_item(&item2,
+ "What is your second melee weapon? ",
+ "You have nothing to compare.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
return (FALSE);
@@ -1223,380 +1090,6 @@ static bool_ research_item(void)
}
-/*
- * Show the current quest monster.
- */
-static void show_quest_monster(void)
-{
- monster_race* r_ptr = &r_info[bounties[0][0]];
-
-
- msg_format("Quest monster: %s. "
- "Need to turn in %d corpse%s to receive reward.",
- r_name + r_ptr->name, bounties[0][1],
- (bounties[0][1] > 1 ? "s" : ""));
- msg_print(NULL);
-}
-
-
-/*
- * Show the current bounties.
- */
-static void show_bounties(void)
-{
- int i, j = 6;
-
- monster_race* r_ptr;
-
- char buff[80];
-
-
- clear_bldg(7, 18);
-
- c_prt(TERM_YELLOW, "Currently active bounties:", 4, 2);
-
- for (i = 1; i < MAX_BOUNTIES; i++, j++)
- {
- r_ptr = &r_info[bounties[i][0]];
-
- strnfmt(buff, 80, "%-30s (%d gp)", r_name + r_ptr->name, bounties[i][1]);
-
- prt(buff, j, 2);
-
- if (j >= 17)
- {
- msg_print("Press space for more.");
- msg_print(NULL);
-
- clear_bldg(7, 18);
- j = 5;
- }
- }
-}
-
-
-/*
- * Filter for corpses that currently have a bounty on them.
- */
-static bool_ item_tester_hook_bounty(object_type* o_ptr)
-{
- int i;
-
-
- if (o_ptr->tval == TV_CORPSE)
- {
- for (i = 1; i < MAX_BOUNTIES; i++)
- {
- if (bounties[i][0] == o_ptr->pval2) return (TRUE);
- }
- }
-
- return (FALSE);
-}
-
-/* Filter to match the quest monster's corpse. */
-static bool_ item_tester_hook_quest_monster(object_type* o_ptr)
-{
- if ((o_ptr->tval == TV_CORPSE) &&
- (o_ptr->pval2 == bounties[0][0])) return (TRUE);
- return (FALSE);
-}
-
-
-/*
- * Return the boost in the corpse's value depending on how rare the body
- * part is.
- */
-static int corpse_value_boost(int sval)
-{
- switch (sval)
- {
- case SV_CORPSE_HEAD:
- case SV_CORPSE_SKULL:
- {
- return (1);
- }
-
- /* Default to no boost. */
- default:
- {
- return (0);
- }
- }
-}
-
-/*
- * Sell a corpse, if there's currently a bounty on it.
- */
-static void sell_corpses(void)
-{
- object_type* o_ptr;
-
- int i, boost = 0;
-
- s16b value;
-
- int item;
-
-
- /* Set the hook. */
- item_tester_hook = item_tester_hook_bounty;
-
- /* Select a corpse to sell. */
- if (!get_item(&item, "Sell which corpse",
- "You have no corpses you can sell.", USE_INVEN)) return;
-
- o_ptr = &p_ptr->inventory[item];
-
- /* Exotic body parts are worth more. */
- boost = corpse_value_boost(o_ptr->sval);
-
- /* Try to find a match. */
- for (i = 1; i < MAX_BOUNTIES; i++)
- {
- if (o_ptr->pval2 == bounties[i][0])
- {
- value = bounties[i][1] + boost * (r_info[o_ptr->pval2].level);
-
- msg_format("Sold for %ld gold pieces.", value);
- msg_print(NULL);
- p_ptr->au += value;
-
- /* Increase the number of collected bounties */
- total_bounties++;
-
- inc_stack_size(item, -1);
-
- return;
- }
- }
-
- msg_print("Sorry, but that monster does not have a bounty on it.");
- msg_print(NULL);
-}
-
-
-
-/*
- * Hook for bounty monster selection.
- */
-static bool_ mon_hook_bounty(int r_idx)
-{
- monster_race* r_ptr = &r_info[r_idx];
-
-
- /* Reject uniques */
- if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
-
- /* Reject those who cannot leave anything */
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE) &&
- !(r_ptr->flags9 & RF9_DROP_SKELETON)) return (FALSE);
-
- /* Reject pets */
- if (r_ptr->flags7 & RF7_PET) return (FALSE);
-
- /* Reject friendly creatures */
- if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE);
-
- /* The rest are acceptable */
- return (TRUE);
-}
-
-
-static void select_quest_monster(void)
-{
- monster_race* r_ptr;
-
- int amt;
-
-
- /*
- * Set up the hooks -- no bounties on uniques or monsters
- * with no corpses
- */
- get_mon_num_hook = mon_hook_bounty;
- get_mon_num_prep();
-
- /* Set up the quest monster. */
- bounties[0][0] = get_mon_num(p_ptr->lev);
-
- r_ptr = &r_info[bounties[0][0]];
-
- /*
- * Select the number of monsters needed to kill. Groups and
- * breeders require more
- */
- amt = randnor(5, 3);
-
- if (amt < 2) amt = 2;
-
- if (r_ptr->flags1 & RF1_FRIEND) amt *= 3; amt /= 2;
- if (r_ptr->flags1 & RF1_FRIENDS) amt *= 2;
- if (r_ptr->flags4 & RF4_MULTIPLY) amt *= 3;
-
- if (r_ptr->flags7 & RF7_AQUATIC) amt /= 2;
-
- bounties[0][1] = amt;
-
- /* Undo the filters */
- get_mon_num_hook = NULL;
- get_mon_num_prep();
-}
-
-
-
-/*
- * Sell a corpse for a reward.
- */
-static void sell_quest_monster(void)
-{
- object_type* o_ptr;
-
- int item;
-
-
- /* Set the hook. */
- item_tester_hook = item_tester_hook_quest_monster;
-
- /* Select a corpse to sell. */
- if (!get_item(&item, "Sell which corpse",
- "You have no corpses you can sell.", USE_INVEN)) return;
-
- o_ptr = &p_ptr->inventory[item];
-
- bounties[0][1] -= o_ptr->number;
-
- /* Completed the quest. */
- if (bounties[0][1] <= 0)
- {
- int m;
- monster_race *r_ptr;
-
- cmsg_print(TERM_YELLOW, "You have completed your quest!");
- msg_print(NULL);
-
- /* Give full knowledge */
-
- /* Hack -- Maximal info */
- r_ptr = &r_info[bounties[0][0]];
-
- msg_print(format("Well done! As a reward I'll teach you everything "
- "about the %s, (check your recall)",
- r_name + r_ptr->name));
-
- r_ptr->r_wake = r_ptr->r_ignore = MAX_UCHAR;
-
- /* Observe "maximal" attacks */
- for (m = 0; m < 4; m++)
- {
- /* Examine "actual" blows */
- if (r_ptr->blow[m].effect || r_ptr->blow[m].method)
- {
- /* Hack -- maximal observations */
- r_ptr->r_blows[m] = MAX_UCHAR;
- }
- }
-
- /* Hack -- maximal drops */
- r_ptr->r_drop_gold = r_ptr->r_drop_item =
- (((r_ptr->flags1 & (RF1_DROP_4D2)) ? 8 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_3D2)) ? 6 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_2D2)) ? 4 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_1D2)) ? 2 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_90)) ? 1 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_60)) ? 1 : 0));
-
- /* Hack -- but only "valid" drops */
- if (r_ptr->flags1 & (RF1_ONLY_GOLD)) r_ptr->r_drop_item = 0;
- if (r_ptr->flags1 & (RF1_ONLY_ITEM)) r_ptr->r_drop_gold = 0;
-
- /* Hack -- observe many spells */
- r_ptr->r_cast_inate = MAX_UCHAR;
- r_ptr->r_cast_spell = MAX_UCHAR;
-
- /* Hack -- know all the flags */
- r_ptr->r_flags1 = r_ptr->flags1;
- r_ptr->r_flags2 = r_ptr->flags2;
- r_ptr->r_flags3 = r_ptr->flags3;
- r_ptr->r_flags4 = r_ptr->flags4;
- r_ptr->r_flags5 = r_ptr->flags5;
- r_ptr->r_flags6 = r_ptr->flags6;
- r_ptr->r_flags4 = r_ptr->flags7;
- r_ptr->r_flags5 = r_ptr->flags8;
- r_ptr->r_flags6 = r_ptr->flags9;
-
- msg_print(NULL);
-
- select_quest_monster();
-
- }
- else
- {
- msg_format("Well done, only %d more to go.", bounties[0][1]);
- msg_print(NULL);
- }
-
- inc_stack_size(item, -1);
-}
-
-
-
-/*
- * Fill the bounty list with monsters.
- */
-void select_bounties(void)
-{
- int i, j;
-
-
- select_quest_monster();
-
- /*
- * Set up the hooks -- no bounties on uniques or monsters
- * with no corpses
- */
- get_mon_num_hook = mon_hook_bounty;
- get_mon_num_prep();
-
- for (i = 1; i < MAX_BOUNTIES; i++)
- {
- int lev = i * 5 + randnor(0, 2);
- monster_race* r_ptr;
- s16b r_idx;
- s16b val;
-
- if (lev < 1) lev = 1;
-
- if (lev >= MAX_DEPTH) lev = MAX_DEPTH - 1;
-
- /* We don't want to duplicate entries in the list */
- while (TRUE)
- {
- r_idx = get_mon_num(lev);
-
- for (j = 0; j < i; j++)
- {
- if (bounties[j][0] == r_idx) continue;
- }
-
- break;
- }
-
- bounties[i][0] = r_idx;
-
- r_ptr = &r_info[r_idx];
-
- val = r_ptr->mexp + r_ptr->level * 20 + randnor(0, r_ptr->level * 2);
-
- if (val < 1) val = 1;
-
- bounties[i][1] = val;
- }
-
- /* Undo the filters. */
- get_mon_num_hook = NULL;
- get_mon_num_prep();
-}
/*
* Execute a building command
@@ -1638,22 +1131,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
return FALSE;
}
- /* If player has loan and the time is out, few things work in stores */
- if (p_ptr->loan && !p_ptr->loan_time)
- {
- if ((bact != BACT_SELL) && (bact != BACT_VIEW_BOUNTIES) &&
- (bact != BACT_SELL_CORPSES) &&
- (bact != BACT_VIEW_QUEST_MON) &&
- (bact != BACT_SELL_QUEST_MON) &&
- (bact != BACT_EXAMINE) && (bact != BACT_STEAL) &&
- (bact != BACT_PAY_BACK_LOAN))
- {
- msg_print("You are not allowed to do that until you have paid back your loan.");
- msg_print(NULL);
- return FALSE;
- }
- }
-
/* check gold */
if (bcost > p_ptr->au)
{
@@ -1685,9 +1162,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
}
case BACT_QUEST1:
- case BACT_QUEST2:
- case BACT_QUEST3:
- case BACT_QUEST4:
{
int y = 1, x = 1;
bool_ ok = FALSE;
@@ -1721,24 +1195,13 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
}
case BACT_KING_LEGENDS:
- case BACT_ARENA_LEGENDS:
- case BACT_LEGENDS:
{
show_highclass(building_loc);
break;
}
- case BACT_POSTER:
- case BACT_ARENA_RULES:
- case BACT_ARENA:
- {
- arena_comm(bact);
- break;
- }
-
case BACT_IN_BETWEEN:
case BACT_CRAPS:
- case BACT_SPIN_WHEEL:
case BACT_DICE_SLOTS:
case BACT_GAMBLE_RULES:
{
@@ -1880,30 +1343,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
break;
}
- case BACT_VIEW_BOUNTIES:
- {
- show_bounties();
- break;
- }
-
- case BACT_VIEW_QUEST_MON:
- {
- show_quest_monster();
- break;
- }
-
- case BACT_SELL_QUEST_MON:
- {
- sell_quest_monster();
- break;
- }
-
- case BACT_SELL_CORPSES:
- {
- sell_corpses();
- break;
- }
-
case BACT_DIVINATION:
{
int i, count = 0;
@@ -1953,83 +1392,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
break;
}
- case BACT_REQUEST_ITEM:
- {
- store_request_item();
- paid = TRUE;
- break;
- }
-
- case BACT_GET_LOAN:
- {
- s32b i, req;
- char prompt[80];
-
- if (p_ptr->loan)
- {
- msg_print("You already have a loan!");
- break;
- }
-
- req = p_ptr->au;
-
- for (i = 0; i < INVEN_TOTAL; i++)
- req += object_value_real(&p_ptr->inventory[i]);
-
- if (req > 100000) req = 100000;
- if ((req + p_ptr->au) > PY_MAX_GOLD) req = PY_MAX_GOLD - p_ptr->au;
-
- strnfmt(prompt, sizeof (prompt),
- "How much would you like to get (0-%ld) ?", req);
-
- req = get_quantity(prompt, req);
-
- if (req)
- {
- p_ptr->loan += req;
- p_ptr->au += req;
- p_ptr->loan_time += req;
-
- msg_format("You receive %i gold pieces", req);
-
- paid = TRUE;
- }
- else
- msg_format("You did not request any money!");
-
- break;
- }
-
- case BACT_PAY_BACK_LOAN:
- {
- s32b req;
- char prompt[80];
-
- if (p_ptr->loan)
- {
- msg_format("You have nothing to payback!");
- break;
- }
-
- msg_format("You have a loan of %i.", p_ptr->loan);
-
- req = ((p_ptr->loan + bcost) > p_ptr->au) ? p_ptr->au - bcost : p_ptr->loan;
-
- strnfmt(prompt, sizeof (prompt),
- "How much would you like to pay back (0-%ld) ?", req);
-
- req = get_quantity(prompt, req);
-
- p_ptr->loan -= req;
- p_ptr->au -= req;
-
- if (!p_ptr->loan) p_ptr->loan_time = 0;
-
- msg_format("You pay back %i gold pieces", req);
- paid = TRUE;
- break;
- }
-
case BACT_DROP_ITEM:
{
quest_bounty_drop_item();
@@ -2063,14 +1425,8 @@ bool_ bldg_process_command(store_type *s_ptr, int i)
}
default:
- {
- if (process_hooks_ret(HOOK_BUILDING_ACTION, "dd", "(d)", bact))
- {
- paid = process_hooks_return[0].num;
- recreate = process_hooks_return[1].num;
- }
- break;
- }
+ printf("Unknown building action %d\n", static_cast<int>(bact));
+ break;
}
if (paid)
@@ -2110,121 +1466,3 @@ void enter_quest(void)
p_ptr->oldpy = p_ptr->py;
}
}
-
-
-/*
- * Do building commands
- */
-void do_cmd_bldg(void)
-{
- int i, which, x = p_ptr->px, y = p_ptr->py;
-
- char command;
-
- bool_ validcmd;
-
- store_type *s_ptr;
-
- store_action_type *ba_ptr;
-
-
- if (cave[p_ptr->py][p_ptr->px].feat != FEAT_SHOP)
- {
- msg_print("You see no building here.");
- return;
- }
-
- which = cave[p_ptr->py][p_ptr->px].special;
- building_loc = which;
-
- s_ptr = &town_info[p_ptr->town_num].store[which];
-
- p_ptr->oldpy = p_ptr->py;
- p_ptr->oldpx = p_ptr->px;
-
- /* Forget the lite */
- /* forget_lite(); */
-
- /* Forget the view */
- forget_view();
-
- /* Hack -- Increase "icky" depth */
- character_icky++;
-
- command_arg = 0;
- command_rep = 0;
- command_new = 0;
-
- show_building(s_ptr);
- leave_bldg = FALSE;
-
- while (!leave_bldg)
- {
- validcmd = FALSE;
- prt("", 1, 0);
- command = inkey();
-
- if (command == ESCAPE)
- {
- leave_bldg = TRUE;
- p_ptr->inside_arena = FALSE;
- break;
- }
-
- for (i = 0; i < 6; i++)
- {
- ba_ptr = &ba_info[st_info->actions[i]];
-
- if (ba_ptr->letter)
- {
- if (ba_ptr->letter == command)
- {
- validcmd = TRUE;
- break;
- }
- }
- if (ba_ptr->letter_aux)
- {
- if (ba_ptr->letter_aux == command)
- {
- validcmd = TRUE;
- break;
- }
- }
- }
-
- if (validcmd)
- bldg_process_command(s_ptr, i);
-
- /* Notice stuff */
- notice_stuff();
-
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Flush messages XXX XXX XXX */
- msg_print(NULL);
-
- /* Reinit wilderness to activate quests ... */
- wilderness_gen(TRUE);
- p_ptr->py = y;
- p_ptr->px = x;
-
- /* Hack -- Decrease "icky" depth */
- character_icky--;
-
- /* Clear the screen */
- Term_clear();
-
- /* Update the visuals */
- p_ptr->update |= (PU_VIEW | PU_MON_LITE | PU_MONSTERS | PU_BONUS);
-
- /* Redraw entire screen */
- p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-}
-
-
diff --git a/src/bldg.hpp b/src/bldg.hpp
new file mode 100644
index 00000000..0daebbee
--- /dev/null
+++ b/src/bldg.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+#include "store_type_fwd.hpp"
+
+extern bool_ bldg_process_command(store_type *s_ptr, int i);
+extern void show_building(store_type *s_ptr);
+extern bool_ is_state(store_type *s_ptr, int state);
+extern void enter_quest(void);
diff --git a/src/body.hpp b/src/body.hpp
new file mode 100644
index 00000000..dd0be282
--- /dev/null
+++ b/src/body.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+/*
+ * Body parts
+ */
+#define BODY_WEAPON 0
+#define BODY_TORSO 1
+#define BODY_ARMS 2
+#define BODY_FINGER 3
+#define BODY_HEAD 4
+#define BODY_LEGS 5
+#define BODY_MAX 6
diff --git a/src/cave.c b/src/cave.cc
index ab1ce56e..1dc5cbdb 100644
--- a/src/cave.c
+++ b/src/cave.cc
@@ -1,10 +1,29 @@
-/* File: cave.c */
-
-/* Purpose: low level dungeon routines -BEN- */
-
-
-#include "angband.h"
-
+#include "cave.hpp"
+
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_enter_dungeon_in.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "q_rand.hpp"
+#include "spells1.hpp"
+#include "store_info_type.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <cassert>
+#include <vector>
+#include <iterator>
+#include <algorithm>
/*
* Support for Adam Bolt's tileset, lighting and transparency effects
@@ -347,24 +366,16 @@ bool_ no_lite(void)
*/
bool_ cave_valid_bold(int y, int x)
{
- cave_type *c_ptr = &cave[y][x];
-
- s16b this_o_idx, next_o_idx = 0;
-
+ cave_type const *c_ptr = &cave[y][x];
/* Forbid perma-grids */
if (cave_perma_grid(c_ptr)) return (FALSE);
/* Check objects */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[o_idx];
/* Forbid artifact grids */
if ((o_ptr->art_name) || artifact_p(o_ptr)) return (FALSE);
@@ -376,106 +387,69 @@ bool_ cave_valid_bold(int y, int x)
-
/*
- * Hack -- Legal monster codes
- */
-static cptr image_monster_hack = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-/*
- * Hack -- Legal monster codes for IBM pseudo-graphics
- *
- * Dropped. Although this option has long left unmaintained, hardcoding
- * code points makes it impossible to update the font and prf files
- * flexibly. And the normal graphics code still works with it -- pelpel
- */
-
-/*
- * Mega-Hack -- Hallucinatory monster
+ * Generate visual for hallucinatory monster
*/
static void image_monster(byte *ap, char *cp)
{
- int n;
+ // Cached state which keeps a list of all the "live" monster race entries.
+ static std::vector<size_t> *instance = nullptr;
- switch (graphics_mode)
+ // First-time initialization
+ if (!instance)
{
- /* Text mode */
- case GRAPHICS_NONE:
- {
- n = strlen(image_monster_hack);
-
- /* Random symbol from set above */
- *cp = (image_monster_hack[rand_int(n)]);
-
- /* Random color */
- *ap = randint(15);
-
- break;
- }
-
- /* Normal graphics */
- default:
+ // Create the list of "live" indexes
+ instance = new std::vector<size_t>();
+ // Start at 1 to avoid 'player'
+ for (size_t i = 1; i < max_r_idx; i++)
{
- /* Avoid player ghost */
- n = randint(max_r_idx);
-
- *cp = r_info[n].x_char;
-
- *ap = r_info[n].x_attr;
-
- break;
+ if (r_info[i].name)
+ {
+ instance->push_back(i);
+ }
}
}
-}
+ // Sanity check
+ assert(instance != nullptr);
+ // Select a race at random
+ int n = rand_int(instance->size());
+ *cp = r_info[(*instance)[n]].x_char;
+ *ap = r_info[(*instance)[n]].x_attr;
+}
/*
- * Hack -- Legal object codes
- */
-static cptr image_object_hack = "?/|\\\"!$()_-=[]{},~";
-
-/*
- * Hardcoded IBM pseudo-graphics code points have been removed
- * for the same reason as stated above -- pelpel
- */
-
-/*
- * Mega-Hack -- Hallucinatory object
+ * Generate visual for hallucinatory object
*/
static void image_object(byte *ap, char *cp)
{
- int n;
+ // Cached state which keeps a list of the "live" object_kind entries.
+ static std::vector<size_t> *instance = nullptr;
- switch (graphics_mode)
+ // First-time initialization
+ if (!instance)
{
- /* Text mode */
- case GRAPHICS_NONE:
+ // Create the list of "live" indexes
+ instance = new std::vector<size_t>();
+ // Filter all the "live" entries
+ for (size_t i = 0; i < max_k_idx; i++)
{
- n = strlen(image_object_hack);
-
- /* Random symbol from set above */
- *cp = (image_object_hack[rand_int(n)]);
-
- /* Random color */
- *ap = randint(15);
-
- /* Done */
- break;
+ if (k_info[i].name)
+ {
+ instance->push_back(i);
+ }
}
+ }
- /* Normal graphics */
- default:
- {
- n = randint(max_k_idx - 1);
-
- *cp = k_info[n].x_char;
- *ap = k_info[n].x_attr;
+ // Sanity check
+ assert(instance != nullptr);
- break;
- }
- }
+ // Select an object kind at random
+ int n = rand_int(instance->size());
+ *cp = k_info[(*instance)[n]].x_char;
+ *ap = k_info[(*instance)[n]].x_attr;
}
@@ -498,16 +472,8 @@ static void image_random(byte *ap, char *cp)
}
-/*
- * The 16x16 tile of the terrain supports lighting
- */
-static bool_ feat_supports_lighting(byte feat)
-{
- return (f_info[feat].flags1 & FF1_SUPPORT_LIGHT) != 0;
-}
-
-char get_shimmer_color()
+static char get_shimmer_color()
{
switch (randint(7))
{
@@ -856,60 +822,25 @@ static byte darker_attrs[16] =
};
-void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
- byte *eap, char *ecp)
+static void map_info(int y, int x, byte *ap, char *cp)
{
- cave_type *c_ptr;
-
- feature_type *f_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
- u16b info;
-
- s16b t_idx;
-
- byte feat;
-
byte a;
byte c;
- /*
- * This means that a port supports graphics overlay as well as lighting
- * effects. See the step 3 below for the detailed information about
- * lighting. Basically, it requires "darker" tiles for those terrain
- * features with SUPPORT_LIGHT flag set, and they must be arranged
- * this way:
- * col col+1 col+2
- * row base darker brighter
- */
- bool_ graf_new = ((graphics_mode == GRAPHICS_ISO) ||
- (graphics_mode == GRAPHICS_NEW));
-
- /*
- * I never understand why some coders like shimmering so much.
- * It just serves to hurt my eyes, IMHO. If one feels like to show off,
- * go for better graphics support... Anyway this means a port allows
- * changing attr independently from its char -- pelpel
- */
- bool_ attr_mutable = (!use_graphics ||
- (graphics_mode == GRAPHICS_IBM));
-
-
/**** Preparation ****/
/* Access the grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Cache some frequently used values */
/* Grid info */
- info = c_ptr->info;
+ auto info = c_ptr->info;
/* Feature code */
- feat = c_ptr->feat;
+ auto feat = c_ptr->feat;
/* Apply "mimic" field */
if (c_ptr->mimic)
@@ -922,12 +853,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
}
/* Access floor */
- f_ptr = &f_info[feat];
-
-
- /* Reset attr/char */
- *eap = 0;
- *ecp = 0;
+ feature_type *f_ptr = &f_info[feat];
/**** Layer 1 -- Terrain feature ****/
@@ -955,8 +881,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
}
/* Mega-Hack 2 -- stair to dungeon branch are purple */
- if (c_ptr->special && attr_mutable &&
- ((feat == FEAT_MORE) || (feat == FEAT_LESS)))
+ if (c_ptr->special && ((feat == FEAT_MORE) || (feat == FEAT_LESS)))
{
a = TERM_VIOLET;
}
@@ -965,67 +890,39 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL))
{
/* Trap index */
- t_idx = c_ptr->t_idx;
+ auto t_idx = c_ptr->t_idx;
- if (use_graphics &&
- (t_info[t_idx].g_attr != 0) &&
- (t_info[t_idx].g_char != 0))
+ /*
+ * If trap is set on a floor grid that is not
+ * one of "interesting" features, use a special
+ * symbol to display it. Check for doors is no longer
+ * necessary because they have REMEMBER flag now.
+ *
+ * Cave macros cannot be used safely here, because of
+ * c_ptr->mimic XXX XXX
+ */
+ if ((f_ptr->flags1 & (FF1_FLOOR | FF1_REMEMBER)) == FF1_FLOOR)
{
-
- if (graf_new)
- {
- *eap = t_info[t_idx].g_attr;
- *ecp = t_info[t_idx].g_char;
- }
- else
- {
- a = t_info[t_idx].g_attr;
- c = t_info[t_idx].g_char;
- }
-
+ c = f_info[FEAT_TRAP].x_char;
}
- else
- {
- /*
- * If trap is set on a floor grid that is not
- * one of "interesting" features, use a special
- * symbol to display it. Check for doors is no longer
- * necessary because they have REMEMBER flag now.
- *
- * Cave macros cannot be used safely here, because of
- * c_ptr->mimic XXX XXX
- */
- if (!attr_mutable)
- {
- a = f_info[FEAT_TRAP].x_attr;
- c = f_info[FEAT_TRAP].x_char;
- }
- else
- {
- if ((f_ptr->flags1 & (FF1_FLOOR | FF1_REMEMBER)) == FF1_FLOOR)
- {
- c = f_info[FEAT_TRAP].x_char;
- }
- /* Add attr XXX XXX XXX */
- a = t_info[t_idx].color;
+ /* Add attr XXX XXX XXX */
+ a = t_info[t_idx].color;
- /* Get a new color with a strange formula :) XXX XXX XXX */
- if (t_info[t_idx].flags & FTRAP_CHANGE)
- {
- s32b tmp;
+ /* Get a new color with a strange formula :) XXX XXX XXX */
+ if (t_info[t_idx].flags & FTRAP_CHANGE)
+ {
+ s32b tmp;
- tmp = dun_level + dungeon_type + feat;
+ tmp = dun_level + dungeon_type + feat;
- a = tmp % 16;
- }
- }
+ a = tmp % 16;
}
}
/**** Step 2 -- Apply special random effects ****/
- if (!avoid_other && !avoid_shimmer && attr_mutable)
+ if (!avoid_other && !avoid_shimmer)
{
/* Special terrain effect */
if (c_ptr->effect)
@@ -1059,8 +956,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
if (view_special_lite &&
((f_ptr->flags1 & (FF1_FLOOR | FF1_REMEMBER)) == FF1_FLOOR))
{
- if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)) &&
- (attr_mutable || (graf_new && feat_supports_lighting(feat))))
+ if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)))
{
/* Handle "seen" grids */
if (info & (CAVE_SEEN))
@@ -1068,62 +964,30 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
/* Only lit by "torch" light */
if (view_yellow_lite && !(info & (CAVE_GLOW)))
{
- if (graf_new)
- {
- /* Use a brightly lit tile */
- c += 2;
- }
- else
- {
- /* Use "yellow" */
- a = TERM_YELLOW;
- }
+ /* Use "yellow" */
+ a = TERM_YELLOW;
}
}
/* Handle "blind" */
else if (p_ptr->blind)
{
- if (graf_new)
- {
- /* Use a dark tile */
- c++;
- }
- else
- {
- /* Use darker colour */
- a = darker_attrs[a & 0xF];
- }
+ /* Use darker colour */
+ a = darker_attrs[a & 0xF];
}
/* Handle "dark" grids */
else if (!(info & (CAVE_GLOW)))
{
- if (graf_new)
- {
- /* Use a dark tile */
- c++;
- }
- else
- {
- /* Use darkest colour */
- a = TERM_L_DARK;
- }
+ /* Use darkest colour */
+ a = TERM_L_DARK;
}
/* "Out-of-sight" glowing grids -- handle "view_bright_lite" */
else if (view_bright_lite)
{
- if (graf_new)
- {
- /* Use a dark tile */
- c++;
- }
- else
- {
- /* Use darker colour */
- a = dark_attrs[a & 0xF];
- }
+ /* Use darker colour */
+ a = dark_attrs[a & 0xF];
}
}
}
@@ -1132,8 +996,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
else if (view_granite_lite &&
(f_ptr->flags1 & (FF1_NO_VISION | FF1_DOOR)))
{
- if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)) &&
- (attr_mutable || (graf_new && feat_supports_lighting(feat))))
+ if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)))
{
/* Handle "seen" grids */
if (info & (CAVE_SEEN))
@@ -1144,44 +1007,20 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
/* Handle "blind" */
else if (p_ptr->blind)
{
- if (graf_new)
- {
- /* Use a dark tile */
- c++;
- }
- else
- {
- /* Use darker colour */
- a = darker_attrs[a & 0xF];
- }
+ /* Use darker colour */
+ a = darker_attrs[a & 0xF];
}
/* Handle "view_bright_lite" */
else if (view_bright_lite)
{
- if (graf_new)
- {
- /* Use a dark tile */
- c++;
- }
- else
- {
- /* Use darker colour */
- a = dark_attrs[a & 0xF];
- }
+ /* Use darker colour */
+ a = dark_attrs[a & 0xF];
}
else
{
- if (graf_new)
- {
- /* Use a brightly lit tile */
- c += 2;
- }
- else
- {
- /* Use normal colour */
- }
+ /* Use normal colour */
}
}
}
@@ -1211,10 +1050,6 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
image_random(ap, cp);
}
- /* Save the terrain info for the transparency effects */
- *tap = a;
- *tcp = c;
-
/* Save the info */
*ap = a;
*cp = c;
@@ -1224,15 +1059,10 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
if (feat != FEAT_MON_TRAP)
{
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[o_idx];
/* Memorized objects */
if (o_ptr->marked)
@@ -1244,8 +1074,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
*ap = object_attr(o_ptr);
/* Multi-hued attr */
- if (!avoid_other && attr_mutable &&
- (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
+ if (!avoid_other && (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
{
*ap = get_shimmer_color();
}
@@ -1269,10 +1098,8 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
if (r_ptr->flags9 & RF9_MIMIC)
{
- object_type *o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[m_ptr->hold_o_idx];
+ /* Acquire object being mimicked */
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
/* Memorized objects */
if (o_ptr->marked)
@@ -1284,8 +1111,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
*ap = object_attr(o_ptr);
/* Multi-hued attr */
- if (!avoid_other && attr_mutable &&
- (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
+ if (!avoid_other && (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
{
*ap = get_shimmer_color();
}
@@ -1301,28 +1127,6 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
{
monster_race *r_ptr = race_inf(m_ptr);
- /* Reset attr/char */
- *eap = 0;
- *ecp = 0;
-
- if (use_graphics)
- {
-
- if (graf_new)
- {
- monster_ego *re_ptr = &re_info[m_ptr->ego];
-
- /* Desired attr */
- *eap = re_ptr->g_attr;
-
- /* Desired char */
- *ecp = re_ptr->g_char;
- }
-
- /* Use base monster */
- r_ptr = &r_info[m_ptr->r_idx];
- }
-
/* Desired attr/char */
c = r_ptr->x_char;
a = r_ptr->x_attr;
@@ -1337,16 +1141,6 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
*ap = a;
}
- /* Special attr/char codes */
- else if (!attr_mutable)
- {
- /* Use char */
- *cp = c;
-
- /* Use attr */
- *ap = a;
- }
-
/* Multi-hued monster */
else if (r_ptr->flags1 & (RF1_ATTR_MULTI))
{
@@ -1426,12 +1220,8 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
{
monster_race *r_ptr = &r_info[p_ptr->body_monster];
- /* Reset attr/char */
- *eap = 0;
- *ecp = 0;
-
/* Get the "player" attr */
- if (!avoid_other && attr_mutable && (r_ptr->flags1 & RF1_ATTR_MULTI))
+ if (!avoid_other && (r_ptr->flags1 & RF1_ATTR_MULTI))
{
a = get_shimmer_color();
}
@@ -1443,67 +1233,16 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
/* Get the "player" char */
c = r_ptr->x_char;
-
- /* Mega-Hack -- Apply modifications to player graphics XXX XXX XXX */
- switch (graphics_mode)
+ /* Show player health char instead? */
+ if (player_char_health)
{
- case GRAPHICS_NONE:
- case GRAPHICS_IBM:
- {
- if (player_char_health)
- {
- int percent = p_ptr->chp * 10 / p_ptr->mhp;
+ int percent = p_ptr->chp * 10 / p_ptr->mhp;
- if (percent < 7)
- {
- c = I2D(percent);
- if (percent < 3) a = TERM_L_RED;
- }
- }
-
- break;
- }
-
- case GRAPHICS_OLD:
+ if (percent < 7)
{
- if (player_symbols)
- {
- a = BMP_FIRST_PC_CLASS + p_ptr->pclass;
- c = BMP_FIRST_PC_RACE + p_ptr->prace;
- }
-
- break;
+ c = I2D(percent);
+ if (percent < 3) a = TERM_L_RED;
}
-
- case GRAPHICS_ISO:
- case GRAPHICS_NEW:
- {
- if (p_ptr->pracem)
- {
- player_race_mod *rmp_ptr = &race_mod_info[p_ptr->pracem];
-
- /* Desired attr */
- *eap = rmp_ptr->g_attr;
-
- /* Desired char */
- *ecp = rmp_ptr->g_char;
- }
-
- /* +AKH 20020421 - Health dispay for graphics, too */
- if (player_char_health && (graphics_mode == GRAPHICS_NEW))
- {
- int percent = p_ptr->chp * 14 / p_ptr->mhp;
-
- if (percent < 10)
- {
- *eap = 10;
- *ecp = 32 + 14 - percent;
- }
- }
-
- break;
- }
-
}
/* Save the info */
@@ -1515,48 +1254,28 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp,
/*
- * Special version of map_info, for use by cmovie and HTML converter
+ * Special version of map_info, for use by HTML converter
* to obtain pure-ASCII image of dungeon map
*/
void map_info_default(int y, int x, byte *ap, char *cp)
{
- cave_type *c_ptr;
-
- feature_type *f_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
- u16b info;
-
- s16b t_idx;
-
- byte feat;
-
byte a;
byte c;
- bool_ use_graphics_hack = use_graphics;
- byte graphics_mode_hack = graphics_mode;
-
-
- /* Temporarily disable graphics mode -- for some random effects XXX */
- use_graphics = FALSE;
- graphics_mode = GRAPHICS_NONE;
-
/**** Preparation ****/
/* Access the grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Cache some frequently used values */
/* Grid info */
- info = c_ptr->info;
+ auto info = c_ptr->info;
/* Feature code */
- feat = c_ptr->feat;
+ auto feat = c_ptr->feat;
/* Apply "mimic" field */
if (c_ptr->mimic)
@@ -1569,7 +1288,7 @@ void map_info_default(int y, int x, byte *ap, char *cp)
}
/* Access floor */
- f_ptr = &f_info[feat];
+ feature_type *f_ptr = &f_info[feat];
/**** Layer 1 -- Terrain feature ****/
@@ -1607,7 +1326,7 @@ void map_info_default(int y, int x, byte *ap, char *cp)
if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL))
{
/* Trap index */
- t_idx = c_ptr->t_idx;
+ auto t_idx = c_ptr->t_idx;
/*
* If trap is set on a floor grid that is not
@@ -1771,15 +1490,10 @@ void map_info_default(int y, int x, byte *ap, char *cp)
if (feat != FEAT_MON_TRAP)
{
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Memorized objects */
if (o_ptr->marked)
@@ -1816,10 +1530,8 @@ void map_info_default(int y, int x, byte *ap, char *cp)
if (r_ptr->flags9 & RF9_MIMIC)
{
- object_type *o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[m_ptr->hold_o_idx];
+ /* Acquire object being mimicked */
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
/* Memorized objects */
if (o_ptr->marked)
@@ -1831,8 +1543,7 @@ void map_info_default(int y, int x, byte *ap, char *cp)
*ap = object_attr_default(o_ptr);
/* Multi-hued attr */
- if (!avoid_other && !use_graphics &&
- (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
+ if (!avoid_other && (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI))
{
*ap = get_shimmer_color();
}
@@ -1958,10 +1669,6 @@ void map_info_default(int y, int x, byte *ap, char *cp)
*cp = c;
}
-
- /* XXX Restore the graphics mode */
- use_graphics = use_graphics_hack;
- graphics_mode = graphics_mode_hack;
}
@@ -1971,7 +1678,6 @@ void map_info_default(int y, int x, byte *ap, char *cp)
static int panel_col_of(int col)
{
col -= panel_col_min;
- if (use_bigtile) col *= 2;
return col + COL_MAP;
}
@@ -2001,24 +1707,6 @@ void print_rel(char c, byte a, int y, int x)
/* Draw the char using the attr */
Term_draw(panel_col_of(x), y - panel_row_prt, a, c);
-
- if (use_bigtile)
- {
- char c2;
- byte a2;
-
- if (a & 0x80)
- {
- a2 = 255;
- c2 = 255;
- }
- else
- {
- a2 = TERM_WHITE;
- c2 = ' ';
- }
- Term_draw(panel_col_of(x) + 1, y - panel_row_prt, a2, c2);
- }
}
@@ -2070,20 +1758,15 @@ void note_spot(int y, int x)
u16b info = c_ptr->info;
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Require "seen" flag */
if (!(info & (CAVE_SEEN))) return;
/* Hack -- memorize objects */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ /* Acquire object */
+ object_type *o_ptr = &o_list[this_o_idx];
/* Memorize objects */
o_ptr->marked = TRUE;
@@ -2096,8 +1779,7 @@ void note_spot(int y, int x)
if (r_ptr->flags9 & RF9_MIMIC)
{
- object_type *o_ptr = &o_list[m_ptr->hold_o_idx];
-
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
o_ptr->marked = TRUE;
}
}
@@ -2136,39 +1818,17 @@ void note_spot(int y, int x)
*/
void lite_spot(int y, int x)
{
- byte a, a2;
- byte c, c2;
-
- byte ta;
- char tc;
-
- byte ea;
- char ec;
-
+ byte a;
+ char c;
/* Redraw if on screen */
if (panel_contains(y, x))
{
/* Examine the grid */
- map_info(y, x, &a, (char*)&c, &ta, &tc, &ea, &ec);
+ map_info(y, x, &a, &c);
/* Hack -- Queue it */
- Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c, ta, tc, ea, ec);
- if (use_bigtile)
- {
- if (a & 0x80)
- {
- a2 = 255;
- c2 = 255;
- }
- else
- {
- a2 = TERM_WHITE;
- c2 = ' ';
- }
- Term_queue_char(panel_col_of(x) + 1, y - panel_row_prt, a2, c2, 0, 0, 0, 0);
- }
-
+ Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c);
}
}
@@ -2200,33 +1860,14 @@ void prt_map(void)
/* Scan the columns of row "y" */
for (x = panel_col_min; x <= panel_col_max; x++)
{
- byte a, a2;
- char c, c2;
-
- byte ta;
- char tc;
- byte ea;
- char ec;
+ byte a;
+ char c;
/* Determine what is there */
- map_info(y, x, &a, &c, &ta, &tc, &ea, &ec);
+ map_info(y, x, &a, &c);
/* Efficiency -- Redraw that grid of the map */
- Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c, ta, tc, ea, ec);
- if (use_bigtile)
- {
- if (a & 0x80)
- {
- a2 = 255;
- c2 = 255;
- }
- else
- {
- a2 = TERM_WHITE;
- c2 = ' ';
- }
- Term_queue_char(panel_col_of(x) + 1, y - panel_row_prt, a2, c2, 0, 0, 0, 0);
- }
+ Term_queue_char(panel_col_of(x), y - panel_row_prt, a, c);
}
}
@@ -2382,11 +2023,6 @@ void display_map(int *cy, int *cx)
byte tp;
- byte **ma;
- char **mc;
-
- byte **mp;
-
bool_ old_view_special_lite;
bool_ old_view_granite_lite;
@@ -2396,9 +2032,6 @@ void display_map(int *cy, int *cx)
/* Obtain current size of the Angband window */
Term_get_size(&wid, &hgt);
- /* Use two characters as one tile in Bigtile mode */
- if (use_bigtile) wid /= 2;
-
/*
* Calculate the size of the dungeon map area
*/
@@ -2425,32 +2058,22 @@ void display_map(int *cy, int *cx)
view_granite_lite = FALSE;
- /* Allocate temporary memory for the maps */
- C_MAKE(ma, hgt + 2, byte *);
- C_MAKE(mc, hgt + 2, char *);
- C_MAKE(mp, hgt + 2, byte *);
-
- /* Allocate each line in the maps */
+ /* Set up initial maps */
+ std::vector<std::vector<byte>> ma;
+ std::vector<std::vector<char>> mc;
+ std::vector<std::vector<byte>> mp;
for (i = 0; i < hgt + 2; i++)
{
- C_MAKE(ma[i], wid + 2, byte);
- C_MAKE(mc[i], wid + 2, char);
- C_MAKE(mp[i], wid + 2, byte);
- }
-
- /* Clear the chars and attributes */
- for (y = 0; y < hgt + 2; ++y)
- {
- for (x = 0; x < wid + 2; ++x)
- {
- /* Nothing here */
- ma[y][x] = TERM_WHITE;
- mc[y][x] = ' ';
+ // Nothing there.
+ ma.push_back(std::vector<byte>(wid + 2, TERM_WHITE));
+ mc.push_back(std::vector<char>(wid + 2, ' '));
- /* No priority */
- mp[y][x] = 0;
- }
+ // No priority.
+ mp.push_back(std::vector<byte>(wid + 2, 0));
}
+ assert(static_cast<int>(ma.size()) == hgt + 2);
+ assert(static_cast<int>(mc.size()) == hgt + 2);
+ assert(static_cast<int>(mp.size()) == hgt + 2);
/* Calculate scaling factors */
yfactor = ((cur_hgt / hgt < 4) && (cur_hgt > hgt)) ? 10 : 1;
@@ -2469,7 +2092,7 @@ void display_map(int *cy, int *cx)
x = i * xfactor / xrat + 1;
/* Extract the current attr/char at that map location */
- map_info(j, i, &ta, &tc, &ta, &tc, &ta, &tc);
+ map_info(j, i, &ta, &tc);
/* Extract the priority of that attr/char */
tp = priority(ta, tc);
@@ -2521,54 +2144,12 @@ void display_map(int *cy, int *cx)
/* Add the character */
Term_addch(ta, tc);
-
- /* Double width tile mode requires filler */
- if (use_bigtile)
- {
- byte a2;
- char c2;
-
- if (ta & 0x80)
- {
- /* Mega-Hack */
- a2 = 255;
- c2 = 255;
- }
- else
- {
- a2 = TERM_WHITE;
- c2 = ' ';
- }
-
- Term_addch(a2, c2);
- }
}
}
/* Player location in dungeon */
*cy = p_ptr->py * yfactor / yrat + ROW_MAP;
- if (!use_bigtile)
- {
- *cx = p_ptr->px * xfactor / xrat + COL_MAP;
- }
- else
- {
- *cx = (p_ptr->px * xfactor / xrat + 1) * 2 - 1 + COL_MAP;
- }
-
- /* Free each line in the maps */
- for (i = 0; i < hgt + 2; i++)
- {
- C_FREE(ma[i], wid + 2, byte);
- C_FREE(mc[i], wid + 2, char);
- C_FREE(mp[i], wid + 2, byte);
- }
-
- /* Allocate temporary memory for the maps */
- C_FREE(ma, hgt + 2, byte *);
- C_FREE(mc, hgt + 2, char *);
- C_FREE(mp, hgt + 2, byte *);
-
+ *cx = p_ptr->px * xfactor / xrat + COL_MAP;
/* Restore lighting effects */
view_special_lite = old_view_special_lite;
@@ -3193,38 +2774,6 @@ struct vinfo_hack
/*
- * 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)
@@ -3282,8 +2831,6 @@ errr vinfo_init(void)
long m;
- vinfo_hack *hack;
-
int num_grids = 0;
int queue_head = 0;
@@ -3292,8 +2839,8 @@ errr vinfo_init(void)
/* Make hack */
- MAKE(hack, vinfo_hack);
-
+ vinfo_hack hack;
+ memset(&hack, 0, sizeof(vinfo_hack));
/* Analyze grids */
for (y = 0; y <= MAX_SIGHT; ++y)
@@ -3304,8 +2851,8 @@ errr vinfo_init(void)
if (distance(0, 0, y, x) > MAX_SIGHT) continue;
/* Default slope range */
- hack->slopes_min[y][x] = 999999999;
- hack->slopes_max[y][x] = 0;
+ hack.slopes_min[y][x] = 999999999;
+ hack.slopes_max[y][x] = 0;
/* Paranoia */
if (num_grids >= VINFO_MAX_GRIDS)
@@ -3321,25 +2868,25 @@ errr vinfo_init(void)
m = SCALE * (1000L * y - 500) / (1000L * x + 500);
/* Handle "legal" slopes */
- vinfo_init_aux(hack, y, x, m);
+ 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);
+ 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);
+ 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);
+ vinfo_init_aux(&hack, y, x, m);
}
}
@@ -3352,21 +2899,15 @@ errr vinfo_init(void)
}
/* Enforce maximal efficiency */
- if (hack->num_slopes < VINFO_MAX_SLOPES)
+ if (hack.num_slopes < VINFO_MAX_SLOPES)
{
quit_fmt("Too few slopes (%d < %d)!",
- hack->num_slopes, VINFO_MAX_SLOPES);
+ 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);
+ std::sort(std::begin(hack.slopes), std::end(hack.slopes));
@@ -3409,14 +2950,14 @@ errr vinfo_init(void)
/* Analyze slopes */
- for (i = 0; i < hack->num_slopes; ++i)
+ for (i = 0; i < hack.num_slopes; ++i)
{
- m = hack->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]))
+ (hack.slopes_min[y][x] < m) &&
+ (m < hack.slopes_max[y][x]))
{
switch (i / 32)
{
@@ -3497,10 +3038,6 @@ errr vinfo_init(void)
}
- /* Kill hack */
- KILL(hack, vinfo_hack);
-
-
/* Success */
return (0);
}
@@ -4258,32 +3795,6 @@ static int flow_n = 0;
/*
- * Hack -- forget the "flow" information
- */
-void forget_flow(void)
-{
- int x, y;
-
- /* Nothing to forget */
- if (!flow_n) return;
-
- /* Check the entire dungeon */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- /* Forget the old data */
- cave[y][x].cost = 0;
- cave[y][x].when = 0;
- }
- }
-
- /* Start over */
- flow_n = 0;
-}
-
-
-/*
* Hack -- Allow us to treat the "seen" array as a queue
*/
static int flow_head = 0;
@@ -4523,8 +4034,7 @@ void wiz_lite(void)
if (r_ptr->flags9 & RF9_MIMIC)
{
- object_type *o_ptr = &o_list[m_ptr->hold_o_idx];
-
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
o_ptr->marked = TRUE;
}
}
@@ -4859,7 +4369,7 @@ void health_track(int m_idx)
health_who = m_idx;
/* Redraw (later) */
- p_ptr->redraw |= (PR_HEALTH);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -4898,15 +4408,10 @@ void object_track(object_type *o_ptr)
*
* The first arg indicates a major disturbance, which affects search.
*
- * The second arg is currently unused, but could induce output flush.
- *
* All disturbance cancels repeated commands, resting, and running.
*/
-void disturb(int stop_search, int unused_flag)
+void disturb(int stop_search)
{
- /* Unused */
- unused_flag = unused_flag;
-
/* Cancel auto-commands */
/* command_new = 0; */
@@ -4917,7 +4422,7 @@ void disturb(int stop_search, int unused_flag)
command_rep = 0;
/* Redraw the state (later) */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Cancel Resting */
@@ -4927,7 +4432,7 @@ void disturb(int stop_search, int unused_flag)
resting = 0;
/* Redraw the state (later) */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Cancel running */
@@ -4950,7 +4455,7 @@ void disturb(int stop_search, int unused_flag)
p_ptr->update |= (PU_BONUS);
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Flush the input if requested */
@@ -4958,33 +4463,16 @@ void disturb(int stop_search, int unused_flag)
}
-/*
- * Hack -- Check if a level is a "quest" level
- */
-int is_quest(int level)
-{
- int i = random_quest_number();
-
- /* Check quests */
- if (p_ptr->inside_quest)
- return (p_ptr->inside_quest);
-
- if (i) return (QUEST_RANDOM);
-
- /* Nope */
- return (0);
-}
-
/*
* Return the index of the random quest on this level
* (or zero)
*/
-int random_quest_number()
+static int random_quest_number()
{
if ((dun_level >= 1) && (dun_level < MAX_RANDOM_QUEST) &&
- (dungeon_flags1 & DF1_PRINCIPAL) &&
- (random_quests[dun_level].type) &&
+ (dungeon_flags1 & DF1_PRINCIPAL) &&
+ (random_quests[dun_level].type) &&
(!random_quests[dun_level].done) &&
(!is_randhero(dun_level)))
{
@@ -4996,6 +4484,25 @@ int random_quest_number()
}
+
+/*
+ * Hack -- Check if a level is a "quest" level
+ */
+int is_quest(int level)
+{
+ int i = random_quest_number();
+
+ /* Check quests */
+ if (p_ptr->inside_quest)
+ return (p_ptr->inside_quest);
+
+ if (i) return (QUEST_RANDOM);
+
+ /* Nope */
+ return (0);
+}
+
+
/*
* handle spell effects
*/
@@ -5024,3 +4531,167 @@ int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags)
effects[i].rad = rad;
return i;
}
+
+/**
+ * Determine if a "legal" grid is a "floor" grid
+ *
+ * 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.
+ *
+ * Add in the fact that some new terrain (water & lava) do NOT block sight
+ * -KMW-
+ */
+bool cave_floor_bold(int y, int x)
+{
+ return cave_floor_grid(&cave[y][x]);
+}
+
+/**
+ * Grid based version of "cave_floor_bold()"
+ */
+bool cave_floor_grid(cave_type const *c)
+{
+ return (f_info[c->feat].flags1 & FF1_FLOOR) && (c->feat != FEAT_MON_TRAP);
+}
+
+
+
+/**
+ * Determine if a "legal" grid is floor without the REMEMBER flag set
+ * Sometimes called "boring" grid
+ */
+bool cave_plain_floor_bold(int y, int x)
+{
+ return cave_plain_floor_grid(&cave[y][x]);
+}
+
+/**
+ * Grid based version of "cave_plain_floor_bold()"
+ */
+bool cave_plain_floor_grid(cave_type const *c)
+{
+ return
+ (f_info[c->feat].flags1 & FF1_FLOOR) &&
+ !(f_info[c->feat].flags1 & FF1_REMEMBER);
+}
+
+
+
+/**
+ * Determine if a "legal" grid isn't a "blocking line of sight" grid
+ *
+ * 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.
+ *
+ * Add in the fact that some new terrain (water & lava) do NOT block sight
+ * -KMW-
+ */
+bool cave_sight_bold(int y, int x)
+{
+ return cave_sight_grid(&cave[y][x]);
+}
+
+bool cave_sight_grid(cave_type const *c)
+{
+ return !(f_info[c->feat].flags1 & FF1_NO_VISION);
+}
+
+
+/**
+ * Determine if a "legal" grid is a "clean" floor grid
+ *
+ * Line 1 -- forbid non-floors
+ * Line 2 -- forbid deep water -KMW-
+ * Line 3 -- forbid deep lava -KMW-
+ * Line 4 -- forbid normal objects
+ */
+bool cave_clean_bold(int y, int x)
+{
+ return
+ (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) &&
+ (cave[y][x].feat != FEAT_MON_TRAP) &&
+ (cave[y][x].o_idxs.empty()) &&
+ !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT);
+}
+
+/*
+ * Determine if a "legal" grid is an "empty" floor grid
+ *
+ * Line 1 -- forbid doors, rubble, seams, walls
+ * Line 2 -- forbid normal monsters
+ * Line 3 -- forbid the player
+ */
+bool cave_empty_bold(int y, int x)
+{
+ return
+ cave_floor_bold(y,x) &&
+ !(cave[y][x].m_idx) &&
+ !((y == p_ptr->py) && (x == p_ptr->px));
+}
+
+
+/*
+ * Determine if a "legal" grid is an "naked" floor grid
+ *
+ * Line 1 -- forbid non-floors, non-shallow water & lava -KMW-
+ * Line 2 -- forbid normal objects
+ * Line 3 -- forbid player/monsters
+ */
+bool cave_naked_bold(int y, int x)
+{
+ return
+ (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) &&
+ (cave[y][x].feat != FEAT_MON_TRAP) &&
+ !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT) &&
+ (cave[y][x].o_idxs.empty()) &&
+ (cave[y][x].m_idx == 0);
+}
+
+bool cave_naked_bold2(int y, int x)
+{
+ return
+ (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) &&
+ (cave[y][x].feat != FEAT_MON_TRAP) &&
+ (cave[y][x].o_idxs.empty()) &&
+ (cave[y][x].m_idx == 0);
+}
+
+
+/**
+ * Determine if a "legal" grid is "permanent"
+ */
+bool cave_perma_bold(int y, int x)
+{
+ return cave_perma_grid(&cave[y][x]);
+}
+
+bool cave_perma_grid(cave_type const *c)
+{
+ return f_info[c->feat].flags1 & FF1_PERMANENT;
+}
+
+/*
+ * Determine if a "legal" grid is within "los" of the player
+ *
+ * Note the use of comparison to zero to force a "boolean" result
+ */
+bool player_has_los_bold(int y, int x)
+{
+ return (cave[y][x].info & (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
+ */
+bool player_can_see_bold(int y, int x)
+{
+ return (cave[y][x].info & (CAVE_SEEN)) != 0;
+}
diff --git a/src/cave.hpp b/src/cave.hpp
new file mode 100644
index 00000000..64f67dba
--- /dev/null
+++ b/src/cave.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "h-basic.h"
+#include "cave_type_fwd.hpp"
+#include "object_type_fwd.hpp"
+
+extern int distance(int y1, int x1, int y2, int x2);
+extern bool_ los(int y1, int x1, int y2, int x2);
+extern bool_ cave_valid_bold(int y, int x);
+extern bool_ no_lite(void);
+extern void map_info_default(int y, int x, byte *ap, char *cp);
+extern void move_cursor_relative(int row, int col);
+extern void print_rel(char c, byte a, int y, int x);
+extern void note_spot(int y, int x);
+extern void lite_spot(int y, int x);
+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_mon_lite(void);
+extern void update_mon_lite(void);
+extern void update_flow(void);
+extern void map_area(void);
+extern void wiz_lite(void);
+extern void wiz_lite_extra(void);
+extern void wiz_dark(void);
+extern void cave_set_feat(int y, int x, int feat);
+extern void place_floor(int y, int x);
+extern void place_floor_convert_glass(int y, int x);
+extern void place_filler(int y, int x);
+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);
+extern void health_track(int m_idx);
+extern void monster_race_track(int r_idx, int ego);
+extern void object_track(object_type *o_ptr);
+extern void disturb(int stop_search);
+extern int is_quest(int level);
+extern int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags);
+extern bool cave_floor_bold(int y, int x);
+extern bool cave_floor_grid(cave_type const *c);
+extern bool cave_plain_floor_bold(int y, int x);
+extern bool cave_plain_floor_grid(cave_type const *c);
+extern bool cave_sight_bold(int y, int x);
+extern bool cave_sight_grid(cave_type const *c);
+extern bool cave_clean_bold(int y, int x);
+extern bool cave_empty_bold(int y, int x);
+extern bool cave_naked_bold(int y, int x);
+extern bool cave_naked_bold2(int y, int x);
+extern bool cave_perma_bold(int y, int x);
+extern bool cave_perma_grid(cave_type const *c);
+extern bool player_has_los_bold(int y, int x);
+extern bool player_can_see_bold(int y, int x);
diff --git a/src/cave_type.hpp b/src/cave_type.hpp
new file mode 100644
index 00000000..958ace1d
--- /dev/null
+++ b/src/cave_type.hpp
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "h-basic.h"
+
+#include <cassert>
+#include <vector>
+
+/**
+ * A single "grid" in a Cave.
+ *
+ * Note that several aspects of the code restrict the actual cave
+ * to a max size of 256 by 256. In partcular, locations are often
+ * saved as bytes, limiting each coordinate to the 0-255 range.
+ *
+ * The "o_idx" and "m_idx" fields are very interesting. There are
+ * many places in the code where we need quick access to the actual
+ * monster or object(s) in a given cave grid. The easiest way to
+ * do this is to simply keep the index of the monster and object
+ * (if any) with the grid, but this takes 198*66*4 bytes of memory.
+ * Several other methods come to mind, which require only half this
+ * amound of memory, but they all seem rather complicated, and would
+ * probably add enough code that the savings would be lost. So for
+ * these reasons, we simply store an index into the "o_list" and
+ * "m_list" arrays, using "zero" when no monster/object is present.
+ *
+ * Note that "o_idx" is the index of the top object in a stack of
+ * objects, using the "next_o_idx" field of objects to create the
+ * singly linked list of objects. If "o_idx" is zero then there
+ * are no objects in the grid.
+ */
+struct cave_type
+{
+ u16b info = 0; /* Hack -- cave flags */
+
+ byte feat = 0; /* Hack -- feature type */
+
+ std::vector<s16b> o_idxs { }; /* Indexes of objects in this grid */
+
+ s16b m_idx = 0; /* Monster in this grid */
+
+ s16b t_idx = 0; /* trap index (in t_list) or zero */
+
+ s16b special = 0; /* Special cave info */
+ s16b special2 = 0; /* Special cave info */
+
+ s16b inscription = 0; /* Inscription of the grid */
+
+ byte mana = 0; /* Magical energy of the grid */
+
+ byte mimic = 0; /* Feature to mimic */
+
+ byte cost = 0; /* Hack -- cost of flowing */
+ byte when = 0; /* Hack -- when cost was computed */
+
+ s16b effect = 0; /* The lasting effects */
+
+ /**
+ * @brief wipe the object's state
+ */
+ void wipe() {
+ /* Reset to defaults */
+ *this = cave_type();
+ }
+
+};
diff --git a/src/cave_type_fwd.hpp b/src/cave_type_fwd.hpp
new file mode 100644
index 00000000..f2569ea6
--- /dev/null
+++ b/src/cave_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct cave_type;
diff --git a/src/cli_comm.hpp b/src/cli_comm.hpp
new file mode 100644
index 00000000..6ae53edc
--- /dev/null
+++ b/src/cli_comm.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * A structure for CLI commands.
+ */
+struct cli_comm
+{
+ cptr comm; /* Extended name of the command. */
+ cptr descrip; /* Description of the command. */
+ s16b key; /* Key to convert command to. */
+};
diff --git a/src/cli_comm_fwd.hpp b/src/cli_comm_fwd.hpp
new file mode 100644
index 00000000..6d9b76a3
--- /dev/null
+++ b/src/cli_comm_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct cli_comm;
diff --git a/src/cmd1.c b/src/cmd1.cc
index a349ac12..02ad1fd8 100644
--- a/src/cmd1.c
+++ b/src/cmd1.cc
@@ -1,7 +1,3 @@
-/* File: cmd1.c */
-
-/* Purpose: Movement commands (part 1) */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,45 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "quark.h"
+#include "cmd1.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd4.hpp"
+#include "cmd5.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hooks.hpp"
+#include "hook_move_in.hpp"
+#include "lua_bind.hpp"
+#include "melee1.hpp"
+#include "melee2.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells3.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wild.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
#define MAX_VAMPIRIC_DRAIN 100
@@ -527,30 +559,23 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr,
*/
void search(void)
{
- int y, x, chance;
-
- s16b this_o_idx, next_o_idx = 0;
-
- cave_type *c_ptr;
-
-
/* Start with base search ability */
- chance = p_ptr->skill_srh;
+ int chance = p_ptr->skill_srh;
/* Penalize various conditions */
if (p_ptr->blind || no_lite()) chance = chance / 10;
if (p_ptr->confused || p_ptr->image) chance = chance / 10;
/* Search the nearby grids, which are always in bounds */
- for (y = (p_ptr->py - 1); y <= (p_ptr->py + 1); y++)
+ for (int y = (p_ptr->py - 1); y <= (p_ptr->py + 1); y++)
{
- for (x = (p_ptr->px - 1); x <= (p_ptr->px + 1); x++)
+ for (int x = (p_ptr->px - 1); x <= (p_ptr->px + 1); x++)
{
/* Sometimes, notice things */
if (rand_int(100) < chance)
{
/* Access the grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Invisible trap */
if ((c_ptr->t_idx != 0) && !(c_ptr->info & CAVE_TRDT))
@@ -562,7 +587,7 @@ void search(void)
msg_print("You have found a trap.");
/* Disturb */
- disturb(0, 0);
+ disturb(0);
}
/* Secret door */
@@ -577,20 +602,13 @@ void search(void)
lite_spot(y, x);
/* Disturb */
- disturb(0, 0);
+ disturb(0);
}
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx;
- this_o_idx = next_o_idx)
+ for (auto const o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[o_idx];
/* Skip non-chests */
if (o_ptr->tval != TV_CHEST) continue;
@@ -608,7 +626,7 @@ void search(void)
object_known(o_ptr);
/* Notice it */
- disturb(0, 0);
+ disturb(0);
}
}
}
@@ -644,7 +662,7 @@ static void hit_trap(void)
/* Disturb the player */
- disturb(0, 0);
+ disturb(0);
/* Get the cave grid */
c_ptr = &cave[p_ptr->py][p_ptr->px];
@@ -655,7 +673,7 @@ static void hit_trap(void)
{
t_info[c_ptr->t_idx].ident = TRUE;
msg_format("You identified the trap as %s.",
- t_name + t_info[c_ptr->t_idx].name);
+ t_info[c_ptr->t_idx].name);
}
}
}
@@ -814,7 +832,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
if (!effect || check_hit2(power, rlev, ac))
{
/* Always disturbing */
- disturb(1, 0);
+ disturb(1);
/* Describe the attack method */
switch (method)
@@ -1207,7 +1225,7 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_CHARGE:
{
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Message */
msg_format("%s misses %s.", sym_name, t_name);
@@ -1333,7 +1351,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
if (!effect || check_hit2(power, rlev, ac))
{
/* Always disturbing */
- disturb(1, 0);
+ disturb(1);
/* Describe the attack method */
switch (method)
@@ -1726,7 +1744,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath,
case RBM_CHARGE:
{
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Message */
msg_format("You miss %s.", t_name);
@@ -2186,7 +2204,7 @@ void py_attack(int y, int x, int max_blow)
int weap;
/* Disturb the player */
- disturb(0, 0);
+ disturb(0);
if (r_info[p_ptr->body_monster].flags1 & RF1_NEVER_BLOW)
{
@@ -2214,13 +2232,6 @@ void py_attack(int y, int x, int max_blow)
/* Extract monster name (or "it") */
monster_desc(m_name, m_ptr, 0);
- /* Dont even bother */
- if (r_ptr->flags7 & RF7_IM_MELEE)
- {
- msg_format("%^s is immune to melee attacks.");
- return;
- }
-
/* Auto-Recall if possible and visible */
if (m_ptr->ml) monster_race_track(m_ptr->r_idx, m_ptr->ego);
@@ -2440,7 +2451,7 @@ void py_attack(int y, int x, int max_blow)
while (randint(4) == 1);
}
- PRAY_GOD(GOD_TULKAS)
+ if (praying_to(GOD_TULKAS))
{
if (magik(wisdom_scale(130) - m_ptr->level) && (p_ptr->grace > 1000))
{
@@ -2467,9 +2478,9 @@ void py_attack(int y, int x, int max_blow)
}
/* Melkor can cast curse for you*/
- PRAY_GOD(GOD_MELKOR)
+ if (praying_to(GOD_MELKOR))
{
- int lv = get_level_s(MELKOR_CURSE, 100);
+ int lv = get_level(MELKOR_CURSE, 100, 1);
if (lv >= 10)
{
@@ -2865,7 +2876,7 @@ bool_ player_can_enter(byte feature)
/* Player can not walk through "walls" unless in Shadow Form */
- if (p_ptr->wraith_form || (PRACE_FLAG(PR1_SEMI_WRAITH)))
+ if (p_ptr->wraith_form || (race_flags1_p(PR1_SEMI_WRAITH)))
pass_wall = TRUE;
else
pass_wall = FALSE;
@@ -2903,7 +2914,7 @@ bool_ player_can_enter(byte feature)
pass_wall ||
(has_ability(AB_TREE_WALK)) ||
(p_ptr->mimic_form == resolve_mimic_name("Ent")) ||
- ((p_ptr->grace >= 9000) && (p_ptr->praying) && (p_ptr->pgod == GOD_YAVANNA)))
+ ((p_ptr->grace >= 9000) && praying_to(GOD_YAVANNA)))
return (TRUE);
}
@@ -2931,6 +2942,119 @@ bool_ player_can_enter(byte feature)
}
/*
+ * easy_open_door --
+ *
+ * If there is a jammed/closed/locked door at the given location,
+ * then attempt to unlock/open it. Return TRUE if an attempt was
+ * made (successful or not), otherwise return FALSE.
+ *
+ * The code here should be nearly identical to that in
+ * do_cmd_open_test() and do_cmd_open_aux().
+ */
+
+static bool_ easy_open_door(int y, int x)
+{
+ int i, j;
+
+ cave_type *c_ptr = &cave[y][x];
+
+ monster_race *r_ptr = &r_info[p_ptr->body_monster];
+
+
+ if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR))
+ {
+ msg_print("You cannot open doors.");
+
+ return (FALSE);
+ }
+
+ /* Must be a closed door */
+ if (!((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_DOOR_TAIL)))
+ {
+ /* Nope */
+ return (FALSE);
+ }
+
+ /* Jammed door */
+ if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x08)
+ {
+ /* Stuck */
+ msg_print("The door appears to be stuck.");
+ }
+
+ /* Locked door */
+ else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01)
+ {
+ /* Disarm factor */
+ i = p_ptr->skill_dis;
+
+ /* Penalize some conditions */
+ if (p_ptr->blind || no_lite()) i = i / 10;
+ if (p_ptr->confused || p_ptr->image) i = i / 10;
+
+ /* Extract the lock power */
+ j = c_ptr->feat - FEAT_DOOR_HEAD;
+
+ /* Extract the difficulty XXX XXX XXX */
+ j = i - (j * 4);
+
+ /* Always have a small chance of success */
+ if (j < 2) j = 2;
+
+ /* Success */
+ if (rand_int(100) < j)
+ {
+ /* Message */
+ msg_print("You have picked the lock.");
+
+ /* Set off trap */
+ if (c_ptr->t_idx != 0) player_activate_door_trap(y, x);
+
+ /* Open the door */
+ cave_set_feat(y, x, FEAT_OPEN);
+
+ /* Update some things */
+ p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
+
+ /* Sound */
+ sound(SOUND_OPENDOOR);
+
+ /* Experience */
+ gain_exp(1);
+ }
+
+ /* Failure */
+ else
+ {
+ /* Failure */
+ if (flush_failure) flush();
+
+ /* Message */
+ msg_print("You failed to pick the lock.");
+ }
+ }
+
+ /* Closed door */
+ else
+ {
+ /* Set off trap */
+ if (c_ptr->t_idx != 0) player_activate_door_trap(y, x);
+
+ /* Open the door */
+ cave_set_feat(y, x, FEAT_OPEN);
+
+ /* Update some things */
+ p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
+
+ /* Sound */
+ sound(SOUND_OPENDOOR);
+ }
+
+ /* Result */
+ return (TRUE);
+}
+
+/*
* Move player in the given direction, with the given "pickup" flag.
*
* This routine should (probably) always induce energy expenditure.
@@ -3099,8 +3223,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
}
/* Some hooks */
- if (process_hooks(HOOK_MOVE, "(d,d)", y, x)) return;
-
{
hook_move_in in = { y, x };
if (process_hooks_new(HOOK_MOVE, &in, NULL)) {
@@ -3188,13 +3310,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
oktomove = FALSE;
}
- /* Disarm a visible trap */
- else if (easy_disarm && disarm && (c_ptr->info & (CAVE_TRDT)))
- {
- (void)do_cmd_disarm_aux(y, x, tmp, do_pickup);
- return;
- }
-
/* Don't step on known traps. */
else if (disarm && (c_ptr->info & (CAVE_TRDT)) && !(p_ptr->confused || p_ptr->stun || p_ptr->image))
{
@@ -3209,7 +3324,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
oktomove = FALSE;
/* Disturb the player */
- disturb(0, 0);
+ disturb(0);
if (p_ptr->prob_travel)
{
@@ -3244,7 +3359,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
else
feat = f_info[c_ptr->feat].mimic;
- msg_format("You feel %s.", f_text + f_info[feat].block);
+ msg_format("You feel %s.", f_info[feat].block);
c_ptr->info |= (CAVE_MARK);
lite_spot(y, x);
}
@@ -3256,61 +3371,35 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
/* Rubble */
if (c_ptr->feat == FEAT_RUBBLE)
{
- if (!easy_tunnel)
- {
- msg_print("There is rubble blocking your way.");
+ msg_print("There is rubble blocking your way.");
- if (!(p_ptr->confused || p_ptr->stun || p_ptr->image))
- energy_use = 0;
- /*
- * Well, it makes sense that you lose time bumping into
- * a wall _if_ you are confused, stunned or blind; but
- * typing mistakes should not cost you a turn...
- */
- }
- else
- {
- do_cmd_tunnel_aux(y, x, dir);
- return;
- }
+ if (!(p_ptr->confused || p_ptr->stun || p_ptr->image))
+ energy_use = 0;
+ /*
+ * Well, it makes sense that you lose time bumping into
+ * a wall _if_ you are confused, stunned or blind; but
+ * typing mistakes should not cost you a turn...
+ */
}
/* Closed doors */
else if ((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_DOOR_TAIL))
{
- if (easy_open)
- {
- if (easy_open_door(y, x)) return;
- }
- else
- {
- msg_print("There is a closed door blocking your way.");
-
- if (!(p_ptr->confused || p_ptr->stun || p_ptr->image))
- energy_use = 0;
- }
+ if (easy_open_door(y, x)) return;
}
/* Wall (or secret door) */
else
{
- if (!easy_tunnel)
- {
- int feat;
+ int feat;
- if (c_ptr->mimic) feat = c_ptr->mimic;
- else
- feat = f_info[c_ptr->feat].mimic;
+ if (c_ptr->mimic) feat = c_ptr->mimic;
+ else
+ feat = f_info[c_ptr->feat].mimic;
- msg_format("There is %s.", f_text + f_info[feat].block);
+ msg_format("There is %s.", f_info[feat].block);
- if (!(p_ptr->confused || p_ptr->stun || p_ptr->image))
- energy_use = 0;
- }
- else
- {
- do_cmd_tunnel_aux(y, x, dir);
- return;
- }
+ if (!(p_ptr->confused || p_ptr->stun || p_ptr->image))
+ energy_use = 0;
}
}
@@ -3326,7 +3415,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
energy_use = 0;
}
- disturb(0, 0); /* To avoid a loop with running */
+ disturb(0); /* To avoid a loop with running */
oktomove = FALSE;
}
@@ -3349,7 +3438,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
if (old_dtrap && !new_dtrap)
{
/* Disturb player */
- disturb(0, 0);
+ disturb(0);
/* but don't take a turn */
energy_use = 0;
@@ -3384,9 +3473,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
else
feat = cave[p_ptr->py][p_ptr->px].feat;
- /* Some hooks */
- if (process_hooks(HOOK_MOVED, "(d,d)", oy, ox)) return;
-
/* Redraw new spot */
lite_spot(p_ptr->py, p_ptr->px);
@@ -3404,13 +3490,13 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
{
cmsg_print(TERM_VIOLET, "You leave a trap detected zone.");
if (running) msg_print(NULL);
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
}
else if (!old_dtrap && new_dtrap)
{
cmsg_print(TERM_L_BLUE, "You enter a trap detected zone.");
if (running) msg_print(NULL);
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Update stuff */
@@ -3423,16 +3509,16 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
if (!run) p_ptr->window |= (PW_OVERHEAD);
/* Some feature descs */
- if (f_info[cave[p_ptr->py][p_ptr->px].feat].text > 1)
+ if (f_info[cave[p_ptr->py][p_ptr->px].feat].text != DEFAULT_FEAT_TEXT)
{
/* Mega-hack for dungeon branches */
if ((feat == FEAT_MORE) && c_ptr->special)
{
- msg_format("There is %s", d_text + d_info[c_ptr->special].text);
+ msg_format("There is %s", d_info[c_ptr->special].text);
}
else
{
- msg_print(f_text + f_info[feat].text);
+ msg_print(f_info[feat].text);
}
/* Flush message while running */
@@ -3458,7 +3544,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
if (c_ptr->feat == FEAT_SHOP)
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Hack -- Enter store */
command_new = '_';
@@ -3467,7 +3553,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
else if (cave[y][x].feat >= FEAT_ALTAR_HEAD &&
cave[y][x].feat <= FEAT_ALTAR_TAIL)
{
- cptr name = f_name + f_info[cave[y][x].feat].name;
+ cptr name = f_info[cave[y][x].feat].name;
cptr pref = (is_a_vowel(name[0])) ? "an" : "a";
msg_format("You see %s %s.", pref, name);
@@ -3481,7 +3567,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
!(f_info[cave[y][x].feat].flags1 & FF1_DOOR))
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
if (!(c_ptr->info & (CAVE_TRDT)))
{
@@ -3500,7 +3586,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm)
else if (c_ptr->inscription)
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
msg_format("There is an inscription here: %s",
inscription_info[c_ptr->inscription].text);
@@ -3902,9 +3988,6 @@ static bool_ run_test(void)
int option = 0, option2 = 0;
- cave_type *c_ptr;
-
-
/* Where we came from */
prev_dir = find_prevdir;
@@ -3916,9 +3999,6 @@ static bool_ run_test(void)
/* Look at every newly adjacent square. */
for (i = -max; i <= max; i++)
{
- s16b this_o_idx, next_o_idx = 0;
-
-
/* New direction */
new_dir = cycle[chome[prev_dir] + i];
@@ -3927,7 +4007,7 @@ static bool_ run_test(void)
col = p_ptr->px + ddx[new_dir];
/* Access grid */
- c_ptr = &cave[row][col];
+ cave_type *c_ptr = &cave[row][col];
/* Visible monsters abort running */
@@ -3940,15 +4020,10 @@ static bool_ run_test(void)
}
/* Visible objects abort running */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[o_idx];
/* Visible object */
if (o_ptr->marked) return (TRUE);
@@ -4122,7 +4197,7 @@ static bool_ run_test(void)
col = p_ptr->px + ddx[new_dir];
/* Access grid */
- c_ptr = &cave[row][col];
+ cave_type *c_ptr = &cave[row][col];
/* Unknown grids or non-obstacle */
if (!see_obstacle_grid(c_ptr))
@@ -4154,7 +4229,7 @@ static bool_ run_test(void)
col = p_ptr->px + ddx[new_dir];
/* Access grid */
- c_ptr = &cave[row][col];
+ cave_type *c_ptr = &cave[row][col];
/* Unknown grid or non-obstacle */
if (!see_obstacle_grid(c_ptr))
@@ -4283,7 +4358,7 @@ void run_step(int dir)
msg_print("You cannot run in that direction.");
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Done */
return;
@@ -4303,7 +4378,7 @@ void run_step(int dir)
if (run_test())
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Done */
return;
@@ -4323,45 +4398,6 @@ void run_step(int dir)
/*
- * Take care of the various things that can happen when you step
- * into a space. (Objects, traps, and stores.)
- */
-void step_effects(int y, int x, int do_pickup)
-{
- /* Handle "objects" */
- py_pickup_floor(do_pickup);
-
- /* Handle "store doors" */
- if (cave[y][x].feat == FEAT_SHOP)
- {
- /* Disturb */
- disturb(0, 0);
-
- /* Hack -- Enter store */
- command_new = KTRL('V');
- }
-
- /* Discover/set off traps */
- else if (cave[y][x].t_idx != 0)
- {
- /* Disturb */
- disturb(0, 0);
-
- if (!(cave[y][x].info & CAVE_TRDT))
- {
- /* Message */
- msg_print("You found a trap!");
-
- /* Pick a trap */
- pick_trap(y, x);
- }
-
- /* Hit the trap */
- hit_trap();
- }
-}
-
-/*
* Issue a pet command
*/
void do_cmd_pet(void)
@@ -4374,7 +4410,7 @@ void do_cmd_pet(void)
char power_desc[36][80];
- bool_ flag, redraw;
+ bool_ flag;
int ask;
@@ -4453,80 +4489,55 @@ void do_cmd_pet(void)
/* Nothing chosen yet */
flag = FALSE;
- /* No redraw yet */
- redraw = FALSE;
-
/* Build a prompt (accept all spells) */
if (num <= 26)
{
/* Build a prompt (accept all spells) */
strnfmt(out_val, 78,
- "(Command %c-%c, *=List, ESC=exit) Select a command: ", I2A(0),
+ "(Command %c-%c, ESC=exit) Select a command: ", I2A(0),
I2A(num - 1));
}
else
{
strnfmt(out_val, 78,
- "(Command %c-%c, *=List, ESC=exit) Select a command: ", I2A(0),
+ "(Command %c-%c, ESC=exit) Select a command: ", I2A(0),
'0' + num - 27);
}
- /* Get a command from the user */
- while (!flag && get_com(out_val, &choice))
- {
- /* Request redraw */
- if ((choice == ' ') || (choice == '*') || (choice == '?'))
- {
- /* Show the list */
- if (!redraw)
- {
- byte y = 1, x = 0;
- int ctr = 0;
- char dummy[80];
-
- strcpy(dummy, "");
-
- /* Show list */
- redraw = TRUE;
-
- /* Save the screen */
- character_icky = TRUE;
- Term_save();
+ /* Save the screen */
+ character_icky = TRUE;
+ Term_save();
- prt("", y++, x);
-
- while (ctr < num)
- {
- strnfmt(dummy, 80, "%c) %s", I2A(ctr), power_desc[ctr]);
- prt(dummy, y + ctr, x);
- ctr++;
- }
+ /* Show the list */
+ {
+ byte y = 1, x = 0;
+ int ctr = 0;
+ char dummy[80];
- if (ctr < 17)
- {
- prt("", y + ctr, x);
- }
- else
- {
- prt("", y + 17, x);
- }
- }
+ strcpy(dummy, "");
- /* Hide the list */
- else
- {
- /* Hide list */
- redraw = FALSE;
+ prt("", y++, x);
- /* Restore the screen */
- Term_load();
- character_icky = FALSE;
- }
+ while (ctr < num)
+ {
+ strnfmt(dummy, 80, "%c) %s", I2A(ctr), power_desc[ctr]);
+ prt(dummy, y + ctr, x);
+ ctr++;
+ }
- /* Redo asking */
- continue;
+ if (ctr < 17)
+ {
+ prt("", y + ctr, x);
}
+ else
+ {
+ prt("", y + 17, x);
+ }
+ }
+ /* Get a command from the user */
+ while (!flag && get_com(out_val, &choice))
+ {
if (choice == '\r' && num == 1)
{
choice = 'a';
@@ -4574,11 +4585,8 @@ void do_cmd_pet(void)
}
/* Restore the screen */
- if (redraw)
- {
- Term_load();
- character_icky = FALSE;
- }
+ Term_load();
+ character_icky = FALSE;
/* Abort if needed */
if (!flag)
@@ -4809,35 +4817,31 @@ void do_cmd_pet(void)
/*
* Incarnate into a body
*/
-bool_ do_cmd_integrate_body()
+void do_cmd_integrate_body()
{
- cptr q, s;
-
- int item;
-
- object_type *o_ptr;
-
-
if (!p_ptr->disembodied)
{
msg_print("You are already in a body.");
- return FALSE;
+ return;
}
- /* Restrict choices to monsters */
- item_tester_tval = TV_CORPSE;
-
/* Get an item */
- q = "Incarnate in which body? ";
- s = "You have no corpse to incarnate in.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return FALSE;
+ int item;
+ if (!get_item(&item,
+ "Incarnate in which body? ",
+ "You have no corpse to incarnate in.",
+ (USE_FLOOR),
+ object_filter::TVal(TV_CORPSE)))
+ {
+ return;
+ }
- o_ptr = &o_list[0 - item];
+ object_type *o_ptr = &o_list[0 - item];
if (o_ptr->sval != SV_CORPSE_CORPSE)
{
msg_print("You must select a corpse.");
- return FALSE;
+ return;
}
p_ptr->body_monster = o_ptr->pval2;
@@ -4851,8 +4855,6 @@ bool_ do_cmd_integrate_body()
p_ptr->wraith_form = FALSE;
p_ptr->disembodied = FALSE;
do_cmd_redraw();
-
- return TRUE;
}
/*
@@ -4985,15 +4987,16 @@ bool_ execute_inscription(byte i, byte y, byte x)
{
monster_type *m_ptr;
monster_race *r_ptr;
- cave_type *c_ptr;
int ii = x, ij = y;
cave_set_feat(ij, ii, FEAT_DARK_PIT);
msg_print("A chasm appears in the floor!");
- if (cave[ij][ii].m_idx)
+ cave_type *c_ptr = &cave[ij][ii];
+
+ if (c_ptr->m_idx)
{
- m_ptr = &m_list[cave[ij][ii].m_idx];
+ m_ptr = &m_list[c_ptr->m_idx];
r_ptr = race_inf(m_ptr);
if (r_ptr->flags7 & RF7_CAN_FLY)
@@ -5005,34 +5008,28 @@ bool_ execute_inscription(byte i, byte y, byte x)
if (!(r_ptr->flags1 & RF1_UNIQUE))
{
msg_print("The monster falls in the chasm!");
- delete_monster_idx(cave[ij][ii].m_idx);
+ delete_monster_idx(c_ptr->m_idx);
}
}
}
- if (cave[ij][ii].o_idx)
+ if (!c_ptr->o_idxs.empty())
{
- s16b this_o_idx, next_o_idx = 0;
-
- c_ptr = &cave[ij][ii];
+ /* Copy list of objects since we're going to be manipulating the list */
+ auto const object_idxs(c_ptr->o_idxs);
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx;
- this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
bool_ plural = FALSE;
char o_name[80];
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
+ object_type * o_ptr = &o_list[this_o_idx];
if (o_ptr->number > 1) plural = TRUE;
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
/* Effect "observed" */
if (o_ptr->marked)
{
diff --git a/src/cmd1.hpp b/src/cmd1.hpp
new file mode 100644
index 00000000..3ae44ed2
--- /dev/null
+++ b/src/cmd1.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_type_fwd.hpp"
+#include "object_type_fwd.hpp"
+
+extern void attack_special(monster_type *m_ptr, s32b special, int dam);
+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, int skill);
+extern s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit);
+extern s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, s32b *special);
+extern void search(void);
+extern void carry(int pickup);
+extern void py_attack(int y, int x, int max_blow);
+extern bool_ player_can_enter(byte feature);
+extern void move_player(int dir, int do_pickup, bool_ disarm);
+extern void move_player_aux(int dir, int do_pickup, int run, bool_ disarm);
+extern void run_step(int dir);
+extern void do_cmd_pet(void);
+extern void do_cmd_integrate_body();
+extern bool_ do_cmd_leave_body(bool_ drop_body);
+extern bool_ execute_inscription(byte i, byte y, byte x);
+extern void do_cmd_engrave(void);
+extern void do_spin(void);
diff --git a/src/cmd2.c b/src/cmd2.cc
index 20ef50af..768e79c0 100644
--- a/src/cmd2.c
+++ b/src/cmd2.cc
@@ -1,7 +1,3 @@
-/* File: cmd2.c */
-
-/* Purpose: Movement commands (part 2) */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,7 +6,54 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "cmd2.hpp"
+
+#include "bldg.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hook_chat_in.hpp"
+#include "hook_enter_dungeon_in.hpp"
+#include "hook_give_in.hpp"
+#include "hook_stair_in.hpp"
+#include "hook_stair_out.hpp"
+#include "hooks.hpp"
+#include "levels.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells3.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <chrono>
+#include <thread>
+
+using std::this_thread::sleep_for;
+using std::chrono::milliseconds;
void do_cmd_immovable_special(void);
@@ -79,23 +122,10 @@ static bool_ do_cmd_bash_fountain(int y, int x)
*/
static bool_ stair_hooks(stairs_direction direction)
{
- cptr direction_s = (direction == STAIRS_UP) ? "up" : "down";
-
- /* Old-style hooks */
- if (process_hooks(HOOK_STAIR, "(s)", direction_s))
- {
- return TRUE; /* Prevent movement */
- }
-
- /* New-style hooks */
- {
- hook_stair_in in = { direction };
- hook_stair_out out = { TRUE }; /* Allow by default */
-
- process_hooks_new(HOOK_STAIR, &in, &out);
-
- return (!out.allow);
- }
+ hook_stair_in in = { direction };
+ hook_stair_out out = { TRUE }; /* Allow by default */
+ process_hooks_new(HOOK_STAIR, &in, &out);
+ return (!out.allow);
}
@@ -484,10 +514,13 @@ void do_cmd_go_down(void)
dungeon_info_type *d_ptr = &d_info[c_ptr->special];
/* Do the lua scripts refuse ? ;) */
- if (process_hooks(HOOK_ENTER_DUNGEON, "(d)", c_ptr->special))
{
- dun_level = old_dun;
- return;
+ struct hook_enter_dungeon_in in = { c_ptr->special };
+ if (process_hooks_new(HOOK_ENTER_DUNGEON, &in, NULL))
+ {
+ dun_level = old_dun;
+ return;
+ }
}
/* Ok go in the new dungeon */
@@ -509,8 +542,7 @@ void do_cmd_go_down(void)
dun_level = d_ptr->mindepth;
}
- msg_format("You go into %s",
- d_text + d_info[dungeon_type].text);
+ msg_format("You go into %s", d_info[dungeon_type].text);
}
else
{
@@ -549,7 +581,7 @@ void do_cmd_search(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -568,31 +600,9 @@ void do_cmd_search(void)
*/
void do_cmd_toggle_search(void)
{
- /* Stop searching */
- if (p_ptr->searching)
- {
- /* Clear the searching flag */
- p_ptr->searching = FALSE;
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
- }
-
- /* Start searching */
- else
- {
- /* Set the searching flag */
- p_ptr->searching = TRUE;
-
- /* Update stuff */
- p_ptr->update |= (PU_BONUS);
-
- /* Redraw stuff */
- p_ptr->redraw |= (PR_STATE | PR_SPEED);
- }
+ p_ptr->update |= (PU_BONUS);
+ p_ptr->redraw |= (PR_FRAME);
+ p_ptr->searching = !p_ptr->searching;
}
@@ -604,20 +614,14 @@ static s16b chest_check(int y, int x)
{
cave_type *c_ptr = &cave[y][x];
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
object_type * o_ptr;
/* Acquire object */
o_ptr = &o_list[this_o_idx];
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
/* Skip unknown chests XXX XXX */
/* if (!o_ptr->marked) continue; */
@@ -741,7 +745,7 @@ static void chest_trap(int y, int x, s16b o_idx)
{
t_info[o_ptr->pval].ident = TRUE;
msg_format("You identified the trap as %s.",
- t_name + t_info[trap].name);
+ t_info[trap].name);
}
}
@@ -1130,8 +1134,7 @@ void do_cmd_open(void)
return;
}
- /* Option: Pick a direction */
- if (easy_open)
+ /* Pick a direction if there's an obvious target */
{
int num_doors, num_chests;
@@ -1165,7 +1168,7 @@ void do_cmd_open(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -1220,11 +1223,8 @@ void do_cmd_open(void)
}
}
- /* Process the appropriate hooks */
- process_hooks(HOOK_OPEN, "(d)", is_quest(dun_level));
-
/* Cancel repeat unless we may continue */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
}
@@ -1300,8 +1300,7 @@ void do_cmd_close(void)
bool_ more = FALSE;
- /* Option: Pick a direction */
- if (easy_open)
+ /* Pick a direction if there's an obvious choice */
{
int num_doors;
@@ -1332,7 +1331,7 @@ void do_cmd_close(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -1377,7 +1376,7 @@ void do_cmd_close(void)
}
/* Cancel repeat unless we may continue */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
}
@@ -1410,7 +1409,7 @@ static bool_ do_cmd_tunnel_test(int y, int x)
if (!(f_info[cave[y][x].feat].flags1 & FF1_TUNNELABLE))
{
/* Message */
- msg_print(f_text + f_info[cave[y][x].feat].tunnel);
+ msg_print(f_info[cave[y][x].feat].tunnel);
/* Nope */
return (FALSE);
@@ -1464,7 +1463,7 @@ static bool_ twall(int y, int x, byte feat)
*
* Returns TRUE if repeated commands may continue
*/
-bool_ do_cmd_tunnel_aux(int y, int x, int dir)
+static bool_ do_cmd_tunnel_aux(int y, int x, int dir)
{
int skill_req = 0, skill_req_1pct = 0;
cave_type *c_ptr = &cave[y][x];
@@ -1501,7 +1500,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
/* Titanium */
if (f_ptr->flags1 & FF1_PERMANENT)
{
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
}
else if ((c_ptr->feat == FEAT_TREES) || (c_ptr->feat == FEAT_DEAD_TREE))
@@ -1518,7 +1517,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
else
{
/* We may continue chopping */
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
more = TRUE;
/* Occasional Search XXX XXX */
@@ -1543,7 +1542,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
else
{
/* We may continue tunelling */
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
more = TRUE;
}
}
@@ -1623,7 +1622,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
else
{
/* Message, continue digging */
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
more = TRUE;
}
}
@@ -1657,7 +1656,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
else
{
/* Message, keep digging */
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
more = TRUE;
}
}
@@ -1688,7 +1687,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
feat = c_ptr->feat;
/* We may continue tunelling */
- msg_print(f_text + f_info[feat].tunnel);
+ msg_print(f_info[feat].tunnel);
more = TRUE;
/* Occasional Search XXX XXX */
@@ -1711,7 +1710,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir)
else
{
/* We may continue tunelling */
- msg_print(f_text + f_ptr->tunnel);
+ msg_print(f_ptr->tunnel);
more = TRUE;
}
}
@@ -1768,7 +1767,7 @@ void do_cmd_tunnel(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -1821,124 +1820,7 @@ void do_cmd_tunnel(void)
}
/* Cancel repetition unless we can continue */
- if (!more) disturb(0, 0);
-}
-
-
-/*
- * easy_open_door --
- *
- * If there is a jammed/closed/locked door at the given location,
- * then attempt to unlock/open it. Return TRUE if an attempt was
- * made (successful or not), otherwise return FALSE.
- *
- * The code here should be nearly identical to that in
- * do_cmd_open_test() and do_cmd_open_aux().
- */
-
-bool_ easy_open_door(int y, int x)
-{
- int i, j;
-
- cave_type *c_ptr = &cave[y][x];
-
- monster_race *r_ptr = &r_info[p_ptr->body_monster];
-
-
- if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR))
- {
- msg_print("You cannot open doors.");
-
- return (FALSE);
- }
-
- /* Must be a closed door */
- if (!((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_DOOR_TAIL)))
- {
- /* Nope */
- return (FALSE);
- }
-
- /* Jammed door */
- if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x08)
- {
- /* Stuck */
- msg_print("The door appears to be stuck.");
- }
-
- /* Locked door */
- else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01)
- {
- /* Disarm factor */
- i = p_ptr->skill_dis;
-
- /* Penalize some conditions */
- if (p_ptr->blind || no_lite()) i = i / 10;
- if (p_ptr->confused || p_ptr->image) i = i / 10;
-
- /* Extract the lock power */
- j = c_ptr->feat - FEAT_DOOR_HEAD;
-
- /* Extract the difficulty XXX XXX XXX */
- j = i - (j * 4);
-
- /* Always have a small chance of success */
- if (j < 2) j = 2;
-
- /* Success */
- if (rand_int(100) < j)
- {
- /* Message */
- msg_print("You have picked the lock.");
-
- /* Set off trap */
- if (c_ptr->t_idx != 0) player_activate_door_trap(y, x);
-
- /* Open the door */
- cave_set_feat(y, x, FEAT_OPEN);
-
- /* Update some things */
- p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
-
- /* Sound */
- sound(SOUND_OPENDOOR);
-
- /* Process the appropriate hooks */
- process_hooks(HOOK_OPEN, "(d)", is_quest(dun_level));
-
- /* Experience */
- gain_exp(1);
- }
-
- /* Failure */
- else
- {
- /* Failure */
- if (flush_failure) flush();
-
- /* Message */
- msg_print("You failed to pick the lock.");
- }
- }
-
- /* Closed door */
- else
- {
- /* Set off trap */
- if (c_ptr->t_idx != 0) player_activate_door_trap(y, x);
-
- /* Open the door */
- cave_set_feat(y, x, FEAT_OPEN);
-
- /* Update some things */
- p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE);
-
- /* Sound */
- sound(SOUND_OPENDOOR);
- }
-
- /* Result */
- return (TRUE);
+ if (!more) disturb(0);
}
@@ -2029,7 +1911,7 @@ static bool_ do_cmd_disarm_chest(int y, int x, s16b o_idx)
*
* Returns TRUE if repeated commands may continue
*/
-bool_ do_cmd_disarm_aux(int y, int x, int dir, int do_pickup)
+static bool_ do_cmd_disarm_aux(int y, int x, int dir, int do_pickup)
{
int i, j, power;
@@ -2048,9 +1930,13 @@ bool_ do_cmd_disarm_aux(int y, int x, int dir, int do_pickup)
/* Access trap name */
if (t_info[c_ptr->t_idx].ident)
- name = (t_name + t_info[c_ptr->t_idx].name);
+ {
+ name = t_info[c_ptr->t_idx].name;
+ }
else
+ {
name = "unknown trap";
+ }
/* Get the "disarm" factor */
i = p_ptr->skill_dis;
@@ -2149,8 +2035,7 @@ void do_cmd_disarm(void)
bool_ more = FALSE;
- /* Option: Pick a direction */
- if (easy_disarm)
+ /* Pick a direction if there's an obvious choice */
{
int num_traps, num_chests;
@@ -2175,7 +2060,7 @@ void do_cmd_disarm(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -2234,7 +2119,7 @@ void do_cmd_disarm(void)
}
/* Cancel repeat unless told not to */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
}
@@ -2386,7 +2271,7 @@ void do_cmd_bash(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -2443,7 +2328,7 @@ void do_cmd_bash(void)
}
/* Unless valid action taken, cancel bash */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
}
@@ -2474,7 +2359,7 @@ void do_cmd_alter(void)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -2531,7 +2416,7 @@ void do_cmd_alter(void)
}
/* Cancel repetition unless we can continue */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
}
@@ -2656,7 +2541,7 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -2698,7 +2583,179 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm)
}
/* Cancel repeat unless we may continue */
- if (!more) disturb(0, 0);
+ if (!more) disturb(0);
+}
+
+
+/*
+ * Try to ``walk'' using phase door.
+ */
+static void do_cmd_unwalk()
+{
+ int dir, y, x, feat;
+
+ cave_type *c_ptr;
+
+ bool_ more = FALSE;
+
+
+ if (!get_rep_dir(&dir)) return;
+
+ y = p_ptr->py + ddy[dir];
+ x = p_ptr->px + ddx[dir];
+
+ c_ptr = &cave[y][x];
+ feat = c_ptr->feat;
+
+ /* Must have knowledge to know feature XXX XXX */
+ if (!(c_ptr->info & (CAVE_MARK))) feat = FEAT_NONE;
+
+ /* Take a turn */
+ energy_use = 100;
+ energy_use *= (p_ptr->wild_mode) ? (5 * (MAX_HGT + MAX_WID) / 2) : 1;
+
+
+ /* Allow repeated command */
+ if (command_arg)
+ {
+ /* Set repeat count */
+ command_rep = command_arg - 1;
+
+ /* Redraw the state */
+ p_ptr->redraw |= (PR_FRAME);
+
+ /* Cancel the arg */
+ command_arg = 0;
+ }
+
+
+ /* Attack monsters */
+ if (c_ptr->m_idx > 0)
+ {
+ /* Attack */
+ py_attack(y, x, -1);
+ }
+
+ /* Exit the area */
+ else if ((!dun_level) && (!p_ptr->wild_mode) &&
+ ((x == 0) || (x == cur_wid - 1) || (y == 0) || (y == cur_hgt - 1)))
+ {
+ /* Can the player enter the grid? */
+ if (player_can_enter(c_ptr->mimic))
+ {
+ /* Hack: move to new area */
+ if ((y == 0) && (x == 0))
+ {
+ p_ptr->wilderness_y--;
+ p_ptr->wilderness_x--;
+ p_ptr->oldpy = cur_hgt - 2;
+ p_ptr->oldpx = cur_wid - 2;
+ ambush_flag = FALSE;
+ }
+
+ else if ((y == 0) && (x == MAX_WID - 1))
+ {
+ p_ptr->wilderness_y--;
+ p_ptr->wilderness_x++;
+ p_ptr->oldpy = cur_hgt - 2;
+ p_ptr->oldpx = 1;
+ ambush_flag = FALSE;
+ }
+
+ else if ((y == MAX_HGT - 1) && (x == 0))
+ {
+ p_ptr->wilderness_y++;
+ p_ptr->wilderness_x--;
+ p_ptr->oldpy = 1;
+ p_ptr->oldpx = cur_wid - 2;
+ ambush_flag = FALSE;
+ }
+
+ else if ((y == MAX_HGT - 1) && (x == MAX_WID - 1))
+ {
+ p_ptr->wilderness_y++;
+ p_ptr->wilderness_x++;
+ p_ptr->oldpy = 1;
+ p_ptr->oldpx = 1;
+ ambush_flag = FALSE;
+ }
+
+ else if (y == 0)
+ {
+ p_ptr->wilderness_y--;
+ p_ptr->oldpy = cur_hgt - 2;
+ p_ptr->oldpx = x;
+ ambush_flag = FALSE;
+ }
+
+ else if (y == cur_hgt - 1)
+ {
+ p_ptr->wilderness_y++;
+ p_ptr->oldpy = 1;
+ p_ptr->oldpx = x;
+ ambush_flag = FALSE;
+ }
+
+ else if (x == 0)
+ {
+ p_ptr->wilderness_x--;
+ p_ptr->oldpx = cur_wid - 2;
+ p_ptr->oldpy = y;
+ ambush_flag = FALSE;
+ }
+
+ else if (x == cur_wid - 1)
+ {
+ p_ptr->wilderness_x++;
+ p_ptr->oldpx = 1;
+ p_ptr->oldpy = y;
+ ambush_flag = FALSE;
+ }
+
+ p_ptr->leaving = TRUE;
+
+ return;
+ }
+ }
+
+ /* Hack -- Ignore weird terrain types. */
+ else if (!cave_floor_grid(c_ptr))
+ {
+ teleport_player(10);
+ }
+
+ /* Enter quests */
+ else if (((feat >= FEAT_QUEST_ENTER) && (feat <= FEAT_QUEST_UP)) ||
+ ((feat >= FEAT_LESS) && (feat <= FEAT_MORE)))
+ {
+ move_player(dir, always_pickup, TRUE);
+ more = FALSE;
+ }
+
+ /* Hack -- Ignore wilderness mofe. */
+ else if (p_ptr->wild_mode)
+ {
+ /* Chance to not blink right */
+ if (magik(15))
+ {
+ do
+ {
+ dir = rand_range(1, 9);
+ }
+ while (dir == 5);
+ }
+
+ move_player(dir, always_pickup, TRUE);
+ }
+
+ /* Walking semantics */
+ else
+ {
+ teleport_player_directed(10, dir);
+ }
+
+ /* Cancel repetition unless we can continue */
+ if (!more) disturb(0);
}
@@ -2778,7 +2835,7 @@ void do_cmd_stay(int pickup)
command_rep = command_arg - 1;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Cancel the arg */
command_arg = 0;
@@ -2810,7 +2867,7 @@ void do_cmd_stay(int pickup)
if (c_ptr->feat == FEAT_SHOP)
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Hack -- enter store */
command_new = '_';
@@ -2830,7 +2887,7 @@ void do_cmd_rest(void)
/* Tell the player why */
msg_print(format("Resting on a %s is too dangerous!",
- f_name + f_info[cave[p_ptr->py][p_ptr->px].feat].name));
+ f_info[cave[p_ptr->py][p_ptr->px].feat].name));
/* Done */
return;
@@ -2900,7 +2957,7 @@ void do_cmd_rest(void)
p_ptr->update |= (PU_BONUS);
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -3082,8 +3139,6 @@ void do_cmd_fire(void)
char o_name[80];
- cptr q, s;
-
int msec = delay_factor * delay_factor * delay_factor;
@@ -3112,14 +3167,15 @@ void do_cmd_fire(void)
/* If nothing correct try to choose from the backpack */
if ((p_ptr->tval_ammo != o_ptr->tval) || (!o_ptr->k_idx))
{
- /* Require proper missile */
- item_tester_tval = p_ptr->tval_ammo;
-
/* Get an item */
- q = "Your quiver is empty. Fire which item? ";
- s = "You have nothing to fire.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
-
+ if (!get_item(&item,
+ "Your quiver is empty. Fire which item? ",
+ "You have nothing to fire.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(p_ptr->tval_ammo)))
+ {
+ return;
+ }
/* Access the item */
o_ptr = get_object(item);
@@ -3261,7 +3317,7 @@ void do_cmd_fire(void)
print_rel(missile_char, missile_attr, y, x);
move_cursor_relative(y, x);
Term_fresh();
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
lite_spot(y, x);
Term_fresh();
}
@@ -3270,7 +3326,7 @@ void do_cmd_fire(void)
else
{
/* Pause anyway, for consistancy */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
@@ -3491,7 +3547,7 @@ void do_cmd_fire(void)
*/
void do_cmd_throw(void)
{
- int dir, item;
+ int dir;
s32b special = 0;
@@ -3510,8 +3566,6 @@ void do_cmd_throw(void)
object_type *q_ptr;
- object_type *o_ptr;
-
bool_ hit_body = FALSE;
bool_ hit_wall = FALSE;
@@ -3524,20 +3578,20 @@ void do_cmd_throw(void)
int msec = delay_factor * delay_factor * delay_factor;
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
-
-
/* Get an item */
- q = "Throw which item? ";
- s = "You have nothing to throw.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Throw which item? ",
+ "You have nothing to throw.",
+ (USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Access the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Hack - Cannot throw away 'no drop' cursed items */
@@ -3677,7 +3731,7 @@ void do_cmd_throw(void)
print_rel(missile_char, missile_attr, y, x);
move_cursor_relative(y, x);
Term_fresh();
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
lite_spot(y, x);
Term_fresh();
}
@@ -3686,7 +3740,7 @@ void do_cmd_throw(void)
else
{
/* Pause anyway, for consistancy */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
@@ -4004,7 +4058,7 @@ void do_cmd_boomerang(void)
print_rel(missile_char, missile_attr, y, x);
move_cursor_relative(y, x);
Term_fresh();
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
lite_spot(y, x);
Term_fresh();
}
@@ -4013,7 +4067,7 @@ void do_cmd_boomerang(void)
else
{
/* Pause anyway, for consistancy */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
@@ -4180,7 +4234,7 @@ void do_cmd_boomerang(void)
print_rel(missile_char, missile_attr, y, x);
move_cursor_relative(y, x);
Term_fresh();
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
lite_spot(y, x);
Term_fresh();
}
@@ -4189,188 +4243,16 @@ void do_cmd_boomerang(void)
else
{
/* Pause anyway, for consistancy */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
}
}
-/*
- * Try to ``walk'' using phase door.
- */
-void do_cmd_unwalk()
-{
- int dir, y, x, feat;
-
- cave_type *c_ptr;
-
- bool_ more = FALSE;
-
-
- if (!get_rep_dir(&dir)) return;
-
- y = p_ptr->py + ddy[dir];
- x = p_ptr->px + ddx[dir];
-
- c_ptr = &cave[y][x];
- feat = c_ptr->feat;
-
- /* Must have knowledge to know feature XXX XXX */
- if (!(c_ptr->info & (CAVE_MARK))) feat = FEAT_NONE;
-
- /* Take a turn */
- energy_use = 100;
- energy_use *= (p_ptr->wild_mode) ? (5 * (MAX_HGT + MAX_WID) / 2) : 1;
-
-
- /* Allow repeated command */
- if (command_arg)
- {
- /* Set repeat count */
- command_rep = command_arg - 1;
-
- /* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
-
- /* Cancel the arg */
- command_arg = 0;
- }
-
-
- /* Attack monsters */
- if (c_ptr->m_idx > 0)
- {
- /* Attack */
- py_attack(y, x, -1);
- }
-
- /* Exit the area */
- else if ((!dun_level) && (!p_ptr->wild_mode) &&
- ((x == 0) || (x == cur_wid - 1) || (y == 0) || (y == cur_hgt - 1)))
- {
- /* Can the player enter the grid? */
- if (player_can_enter(c_ptr->mimic))
- {
- /* Hack: move to new area */
- if ((y == 0) && (x == 0))
- {
- p_ptr->wilderness_y--;
- p_ptr->wilderness_x--;
- p_ptr->oldpy = cur_hgt - 2;
- p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
- }
-
- else if ((y == 0) && (x == MAX_WID - 1))
- {
- p_ptr->wilderness_y--;
- p_ptr->wilderness_x++;
- p_ptr->oldpy = cur_hgt - 2;
- p_ptr->oldpx = 1;
- ambush_flag = FALSE;
- }
-
- else if ((y == MAX_HGT - 1) && (x == 0))
- {
- p_ptr->wilderness_y++;
- p_ptr->wilderness_x--;
- p_ptr->oldpy = 1;
- p_ptr->oldpx = cur_wid - 2;
- ambush_flag = FALSE;
- }
-
- else if ((y == MAX_HGT - 1) && (x == MAX_WID - 1))
- {
- p_ptr->wilderness_y++;
- p_ptr->wilderness_x++;
- p_ptr->oldpy = 1;
- p_ptr->oldpx = 1;
- ambush_flag = FALSE;
- }
-
- else if (y == 0)
- {
- p_ptr->wilderness_y--;
- p_ptr->oldpy = cur_hgt - 2;
- p_ptr->oldpx = x;
- ambush_flag = FALSE;
- }
-
- else if (y == cur_hgt - 1)
- {
- p_ptr->wilderness_y++;
- p_ptr->oldpy = 1;
- p_ptr->oldpx = x;
- ambush_flag = FALSE;
- }
-
- else if (x == 0)
- {
- p_ptr->wilderness_x--;
- p_ptr->oldpx = cur_wid - 2;
- p_ptr->oldpy = y;
- ambush_flag = FALSE;
- }
-
- else if (x == cur_wid - 1)
- {
- p_ptr->wilderness_x++;
- p_ptr->oldpx = 1;
- p_ptr->oldpy = y;
- ambush_flag = FALSE;
- }
-
- p_ptr->leaving = TRUE;
-
- return;
- }
- }
-
- /* Hack -- Ignore weird terrain types. */
- else if (!cave_floor_grid(c_ptr))
- {
- teleport_player(10);
- }
-
- /* Enter quests */
- else if (((feat >= FEAT_QUEST_ENTER) && (feat <= FEAT_QUEST_UP)) ||
- ((feat >= FEAT_LESS) && (feat <= FEAT_MORE)))
- {
- move_player(dir, always_pickup, TRUE);
- more = FALSE;
- }
-
- /* Hack -- Ignore wilderness mofe. */
- else if (p_ptr->wild_mode)
- {
- /* Chance to not blink right */
- if (magik(15))
- {
- do
- {
- dir = rand_range(1, 9);
- }
- while (dir == 5);
- }
-
- move_player(dir, always_pickup, TRUE);
- }
-
- /* Walking semantics */
- else
- {
- teleport_player_directed(10, dir);
- }
-
- /* Cancel repetition unless we can continue */
- if (!more) disturb(0, 0);
-}
-
-
static bool_ tport_vertically(bool_ how)
{
- /* arena or quest -KMW- */
- if ((p_ptr->inside_arena) || (p_ptr->inside_quest))
+ /* quest? */
+ if (p_ptr->inside_quest)
{
msg_print("There is no effect.");
return (FALSE);
@@ -4572,13 +4454,13 @@ void do_cmd_immovable_special(void)
if (lose_sp)
{
p_ptr->csp -= lose_sp;
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
if (lose_hp)
{
p_ptr->chp -= lose_hp;
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
}
energy_use = 100;
@@ -4586,9 +4468,9 @@ void do_cmd_immovable_special(void)
}
/* Can we sacrifice it ? */
-static bool_ item_tester_hook_sacrifiable(object_type *o_ptr)
+static bool item_tester_hook_sacrificable(object_type const *o_ptr)
{
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
/* Corpses are */
if (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE_CORPSE)
@@ -4608,7 +4490,7 @@ static bool_ item_tester_hook_sacrifiable(object_type *o_ptr)
/*
* Is item eligible for sacrifice to Aule?
*/
-static bool_ item_tester_hook_sacrifice_aule(object_type *o_ptr)
+static bool item_tester_hook_sacrifice_aule(object_type const *o_ptr)
{
/* perhaps restrict this only to metal armour and weapons */
return (o_ptr->found == OBJ_FOUND_SELFMADE);
@@ -4621,11 +4503,11 @@ static void do_cmd_sacrifice_aule()
{
int item;
- item_tester_hook = item_tester_hook_sacrifice_aule;
if (!get_item(&item,
"Sacrifice which item? ",
"You have nothing to sacrifice.",
- USE_INVEN))
+ USE_INVEN,
+ item_tester_hook_sacrifice_aule))
{
return;
}
@@ -4653,7 +4535,7 @@ void do_cmd_sacrifice(void)
/* Check valididty */
if ((on_what < FEAT_ALTAR_HEAD) || (on_what > FEAT_ALTAR_TAIL))
{
- show_god_info(FALSE);
+ show_god_info();
return;
}
else
@@ -4661,7 +4543,7 @@ void do_cmd_sacrifice(void)
int agod = on_what - FEAT_ALTAR_HEAD + 1;
/* Not worshipping a god ? ahhhh! */
- GOD(GOD_NONE)
+ if (p_ptr->pgod == GOD_NONE)
{
int i;
@@ -4679,7 +4561,7 @@ void do_cmd_sacrifice(void)
}
else if (p_ptr->pgod == agod)
{
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
/* One can sacrifice some HP for piety or damage */
if ((p_ptr->mhp > 10) && (p_ptr->chp > 10) && get_check("Do you want to sacrifice a part of yourself? "))
@@ -4707,15 +4589,18 @@ void do_cmd_sacrifice(void)
}
else
{
+ /* Get an item */
int item;
- object_type *o_ptr;
-
- /* Restrict choices to food */
- item_tester_hook = item_tester_hook_sacrifiable;
+ if (!get_item(&item,
+ "Sacrifice which item? ",
+ "You have nothing to sacrifice.",
+ (USE_INVEN),
+ item_tester_hook_sacrificable))
+ {
+ return;
+ }
- /* Get an item */
- if (!get_item(&item, "Sacrifice which item? ", "You have nothing to sacrifice.", (USE_INVEN))) return;
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Piety for corpses is based on monster level */
if (o_ptr->tval == TV_CORPSE)
@@ -4736,7 +4621,7 @@ void do_cmd_sacrifice(void)
}
}
- GOD(GOD_AULE)
+ if (p_ptr->pgod == GOD_AULE)
{
do_cmd_sacrifice_aule();
}
@@ -4751,147 +4636,114 @@ void do_cmd_sacrifice(void)
*
* Return a list of o_list[] indexes of items of the given monster
*/
-bool_ scan_monst(int *items, int *item_num, int m_idx)
+std::vector<s16b> scan_monst(int m_idx)
{
- int this_o_idx, next_o_idx;
-
- int num = 0;
-
+ constexpr std::size_t max_size = 23;
- (*item_num) = 0;
+ /* Create output vector. */
+ std::vector<s16b> objects;
+ objects.reserve(std::min(max_size, m_list[m_idx].hold_o_idxs.size()));
/* Scan all objects in the grid */
- for (this_o_idx = m_list[m_idx].hold_o_idx; this_o_idx;
- this_o_idx = next_o_idx)
+ for (auto const this_o_idx: m_list[m_idx].hold_o_idxs)
{
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Accept this item */
- items[num++] = this_o_idx;
-
- /* XXX Hack -- Enforce limit */
- if (num == 23) break;
+ objects.push_back(this_o_idx);
+ if (objects.size() == max_size) break;
}
- /* Number of items */
- (*item_num) = num;
-
/* Result */
- return (num != 0);
+ return objects;
}
/*
* Display a list of the items that the given monster carries.
+ * Returns the list of objects.
*/
-byte show_monster_inven(int m_idx, int *monst_list)
+std::vector<s16b> show_monster_inven(int m_idx)
{
- int i, j, k, l;
-
- int col, len, lim;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- char tmp_val[80];
-
- int out_index[23];
-
byte out_color[23];
-
char out_desc[23][80];
- int monst_num;
-
-
/* Default length */
- len = 79 - 50;
+ int len = 79 - 50;
/* Maximum space allowed for descriptions */
- lim = 79 - 3;
+ int lim = 79 - 3;
/* Require space for weight */
lim -= 9;
/* Scan for objects on the monster */
- (void)scan_monst(monst_list, &monst_num, m_idx);
+ std::vector<s16b> objects = scan_monst(m_idx);
+ assert(objects.size() <= 23);
- /* Display the p_ptr->inventory */
- for (k = 0, i = 0; i < monst_num; i++)
+ /* Calculate width of object names */
+ for (std::size_t i = 0; i < objects.size(); i++)
{
- o_ptr = &o_list[monst_list[i]];
+ object_type *o_ptr = &o_list[objects.at(i)];
/* Describe the object */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Hack -- enforce max length */
o_name[lim] = '\0';
- /* Save the index */
- out_index[k] = i;
-
/* Acquire p_ptr->inventory color */
- out_color[k] = tval_to_attr[o_ptr->tval & 0x7F];
+ out_color[i] = tval_to_attr[o_ptr->tval & 0x7F];
/* Save the object description */
- strcpy(out_desc[k], o_name);
+ strcpy(out_desc[i], o_name);
/* Find the predicted "line length" */
- l = strlen(out_desc[k]) + 5;
+ int l = strlen(out_desc[i]) + 5;
/* Account for the weight */
l += 9;
/* Maintain the maximum length */
if (l > len) len = l;
-
- /* Advance to next "line" */
- k++;
}
/* Find the column to start in */
- col = (len > 76) ? 0 : (79 - len);
+ int col = (len > 76) ? 0 : (79 - len);
/* Output each entry */
- for (j = 0; j < k; j++)
+ std::size_t i = 0;
+ for (i = 0; i < objects.size(); i++)
{
- /* Get the index */
- i = monst_list[out_index[j]];
-
/* Get the item */
- o_ptr = &o_list[i];
+ object_type *o_ptr = &o_list[objects.at(i)];
/* Clear the line */
- prt("", j + 1, col ? col - 2 : col);
+ prt("", i + 1, col ? col - 2 : col);
/* Prepare an index --(-- */
- strnfmt(tmp_val, 80, "%c)", index_to_label(j));
+ char tmp_val[80];
+ strnfmt(tmp_val, 80, "%c)", index_to_label(i));
/* Clear the line with the (possibly indented) index */
- put_str(tmp_val, j + 1, col);
+ put_str(tmp_val, i + 1, col);
/* Display the entry itself */
- c_put_str(out_color[j], out_desc[j], j + 1, col + 3);
+ c_put_str(out_color[i], out_desc[i], i + 1, col + 3);
/* Display the weight if needed */
{
int wgt = o_ptr->weight * o_ptr->number;
strnfmt(tmp_val, 80, "%3d.%1d lb", wgt / 10, wgt % 10);
- put_str(tmp_val, j + 1, 71);
+ put_str(tmp_val, i + 1, 71);
}
}
/* Make a "shadow" below the list (only if needed) */
- if (j && (j < 23)) prt("", j + 1, col ? col - 2 : col);
+ if (i && (i < 23))
+ {
+ prt("", i + 1, col ? col - 2 : col);
+ }
- return monst_num;
+ return objects;
}
@@ -4900,26 +4752,16 @@ byte show_monster_inven(int m_idx, int *monst_list)
*/
void do_cmd_steal()
{
- int x, y, dir = 0, item = -1, k = -1;
-
- cave_type *c_ptr;
-
- monster_type *m_ptr;
-
- object_type *o_ptr, forge;
-
- byte num = 0;
+ int dir = 0, item = -1, k = -1;
bool_ done = FALSE;
- int monst_list[23];
-
-
/* Only works on adjacent monsters */
if (!get_rep_dir(&dir)) return;
- y = p_ptr->py + ddy[dir];
- x = p_ptr->px + ddx[dir];
- c_ptr = &cave[y][x];
+ int y = p_ptr->py + ddy[dir];
+ int x = p_ptr->px + ddx[dir];
+
+ cave_type const *c_ptr = &cave[y][x];
if (!(c_ptr->m_idx))
{
@@ -4927,10 +4769,10 @@ void do_cmd_steal()
return;
}
- m_ptr = &m_list[c_ptr->m_idx];
+ monster_type *m_ptr = &m_list[c_ptr->m_idx];
/* There were no non-gold items */
- if (!m_ptr->hold_o_idx)
+ if (m_ptr->hold_o_idxs.empty())
{
msg_print("That monster has no objects!");
return;
@@ -4945,7 +4787,7 @@ void do_cmd_steal()
screen_save();
- num = show_monster_inven(c_ptr->m_idx, monst_list);
+ std::vector<s16b> objects = show_monster_inven(c_ptr->m_idx);
/* Repeat until done */
while (!done)
@@ -4955,7 +4797,7 @@ void do_cmd_steal()
/* Build the prompt */
strnfmt(tmp_val, 80, "Choose an item to steal (a-%c) or ESC:",
- 'a' - 1 + num);
+ 'a' - 1 + objects.size());
/* Show the prompt */
prt(tmp_val, 0, 0);
@@ -4982,7 +4824,7 @@ void do_cmd_steal()
which = tolower(which);
k = islower(which) ? A2I(which) : -1;
- if (k < 0 || k >= num)
+ if ((k < 0) || (static_cast<std::size_t>(k) >= objects.size()))
{
bell();
@@ -4990,7 +4832,7 @@ void do_cmd_steal()
}
/* Verify the item */
- if (ver && !verify("Try", 0 - monst_list[k]))
+ if (ver && !verify("Try", -objects[k]))
{
done = TRUE;
@@ -4998,7 +4840,7 @@ void do_cmd_steal()
}
/* Accept that choice */
- item = monst_list[k];
+ item = objects[k];
done = TRUE;
break;
@@ -5036,17 +4878,11 @@ void do_cmd_steal()
return;
}
- /* Reconnect the objects list */
- if (num == 1) m_ptr->hold_o_idx = 0;
- else
- {
- if (k > 0) o_list[monst_list[k - 1]].next_o_idx = monst_list[k + 1];
- if (k + 1 >= num) o_list[monst_list[k - 1]].next_o_idx = 0;
- if (k == 0) m_ptr->hold_o_idx = monst_list[k + 1];
- }
+ /* Remove from the monster's list of objects */
+ m_ptr->hold_o_idxs.erase(m_ptr->hold_o_idxs.begin() + k);
/* Rogues gain some xp */
- if (PRACE_FLAGS(PR1_EASE_STEAL))
+ if (race_flags1_p(PR1_EASE_STEAL))
{
s32b max_point;
@@ -5060,8 +4896,9 @@ void do_cmd_steal()
if (get_check("Phase door?")) teleport_player(10);
}
- /* Get the item */
- o_ptr = &forge;
+ /* Create the object we're going to copy into */
+ object_type forge;
+ object_type *o_ptr = &forge;
/* Special handling for gold */
if (o_list[item].tval == TV_GOLD)
@@ -5070,7 +4907,7 @@ void do_cmd_steal()
p_ptr->au += o_list[item].pval;
/* Redraw gold */
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -5082,7 +4919,7 @@ void do_cmd_steal()
inven_carry(o_ptr, FALSE);
}
- /* Delete it */
+ /* Delete source item */
o_list[item].k_idx = 0;
}
@@ -5098,24 +4935,16 @@ void do_cmd_steal()
*/
void do_cmd_give()
{
- int dir, x, y;
-
- cave_type *c_ptr;
-
- cptr q, s;
-
- int item;
-
-
/* Get a "repeated" direction */
+ int dir;
if (!get_rep_dir(&dir)) return;
/* Get requested location */
- y = p_ptr->py + ddy[dir];
- x = p_ptr->px + ddx[dir];
+ int y = p_ptr->py + ddy[dir];
+ int x = p_ptr->px + ddx[dir];
/* Get requested grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* No monster in the way */
if (c_ptr->m_idx == 0)
@@ -5125,18 +4954,20 @@ void do_cmd_give()
}
/* Get an item */
- q = "What item do you want to offer? ";
- s = "You have nothing to offer.";
- if (!get_item(&item, q, s, USE_INVEN)) return;
+ int item;
+ if (!get_item(&item,
+ "What item do you want to offer? ",
+ "You have nothing to offer.",
+ USE_INVEN))
+ {
+ return;
+ }
/* Process hooks if there are any */
- if (!process_hooks(HOOK_GIVE, "(d,d)", c_ptr->m_idx, item))
+ hook_give_in in = { c_ptr->m_idx, item };
+ if (!process_hooks_new(HOOK_GIVE, &in, NULL))
{
- hook_give_in in = { c_ptr->m_idx, item };
- if (!process_hooks_new(HOOK_GIVE, &in, NULL))
- {
- msg_print("The monster does not want your item.");
- }
+ msg_print("The monster does not want your item.");
}
/* Take a turn, even if the offer is declined */
@@ -5172,7 +5003,8 @@ void do_cmd_chat()
}
/* Process hook if there are any */
- if (!process_hooks(HOOK_CHAT, "(d)", c_ptr->m_idx))
+ struct hook_chat_in in = { c_ptr->m_idx };
+ if (!process_hooks_new(HOOK_CHAT, &in, NULL))
{
msg_print("The monster does not want to chat.");
}
diff --git a/src/cmd2.hpp b/src/cmd2.hpp
new file mode 100644
index 00000000..41030995
--- /dev/null
+++ b/src/cmd2.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+#include <vector>
+
+extern std::vector<s16b> show_monster_inven(int m_idx);
+extern int breakage_chance(object_type *o_ptr);
+extern void do_cmd_go_up(void);
+extern void do_cmd_go_down(void);
+extern void do_cmd_search(void);
+extern void do_cmd_toggle_search(void);
+extern void do_cmd_open(void);
+extern void do_cmd_close(void);
+extern void do_cmd_chat(void);
+extern void do_cmd_give(void);
+extern void do_cmd_tunnel(void);
+extern void do_cmd_disarm(void);
+extern void do_cmd_bash(void);
+extern void do_cmd_alter(void);
+extern void do_cmd_spike(void);
+extern void do_cmd_walk(int pickup, bool_ disarm);
+extern void do_cmd_stay(int pickup);
+extern void do_cmd_run(void);
+extern void do_cmd_rest(void);
+extern int get_shooter_mult(object_type *o_ptr);
+extern void do_cmd_fire(void);
+extern void do_cmd_throw(void);
+extern void do_cmd_boomerang(void);
+extern void do_cmd_immovable_special(void);
+extern void fetch(int dir, int wgt, bool_ require_los);
+extern void do_cmd_sacrifice(void);
+extern void do_cmd_create_artifact(object_type *q_ptr);
+extern void do_cmd_steal(void);
diff --git a/src/cmd3.c b/src/cmd3.cc
index 88c5346d..06300982 100644
--- a/src/cmd3.c
+++ b/src/cmd3.cc
@@ -1,7 +1,3 @@
-/* File: cmd3.c */
-
-/* Purpose: Inventory commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -9,10 +5,42 @@
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
-
-#include "angband.h"
-
-#include "quark.h"
+#include "cmd3.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cli_comm.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hook_drop_in.hpp"
+#include "hook_wield_in.hpp"
+#include "hooks.hpp"
+#include "monster1.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "squeltch.hpp"
+#include "store.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <cassert>
+#include <algorithm>
+#include <memory>
+#include <utility>
/*
* Display p_ptr->inventory
@@ -29,16 +57,10 @@ void do_cmd_inven(void)
character_icky = TRUE;
Term_save();
- /* Hack -- show empty slots */
- item_tester_full = TRUE;
-
- /* Display the p_ptr->inventory */
- show_inven();
-
- /* Hack -- hide empty slots */
- item_tester_full = FALSE;
-
+ /* Show the inventory */
+ show_inven_full();
+ /* Show prompt */
{
s32b total_weight = calc_total_weight();
@@ -90,16 +112,10 @@ void do_cmd_equip(void)
character_icky = TRUE;
Term_save();
- /* Hack -- show empty slots */
- item_tester_full = TRUE;
-
/* Display the equipment */
- show_equip();
+ show_equip_full();
- /* Hack -- undo the hack above */
- item_tester_full = FALSE;
-
- /* Build a prompt */
+ /* Show prompt */
{
s32b total_weight = calc_total_weight();
@@ -140,7 +156,7 @@ void do_cmd_equip(void)
/*
* The "wearable" tester
*/
-static bool_ item_tester_hook_wear(object_type *o_ptr)
+static bool item_tester_hook_wear(object_type const *o_ptr)
{
u32b f1, f2, f3, f4, f5, esp;
int slot = wield_slot(o_ptr);
@@ -202,27 +218,27 @@ void do_cmd_wield(void)
object_type *q_ptr;
- object_type *o_ptr, *i_ptr;
+ object_type *i_ptr;
cptr act;
char o_name[80];
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
- /* Restrict the choices */
- item_tester_hook = item_tester_hook_wear;
-
/* Get an item */
- q = "Wear/Wield which item? ";
- s = "You have nothing you can wear or wield.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Wear/Wield which item? ",
+ "You have nothing you can wear or wield.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_wear))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Check the slot */
slot = wield_slot(o_ptr);
@@ -255,7 +271,13 @@ void do_cmd_wield(void)
}
/* Can we wield */
- if (process_hooks(HOOK_WIELD, "(d)", item)) return;
+ {
+ struct hook_wield_in in = { o_ptr };
+ if (process_hooks_new(HOOK_WIELD, &in, NULL))
+ {
+ return;
+ }
+ }
/* Extract the flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -310,19 +332,6 @@ void do_cmd_wield(void)
}
}
- /* Can we take off existing item */
- if (slot != INVEN_AMMO)
- {
- if (p_ptr->inventory[slot].k_idx)
- if (process_hooks(HOOK_TAKEOFF, "(d)", slot)) return;
- }
- else
- {
- if (p_ptr->inventory[slot].k_idx)
- if (!object_similar(&p_ptr->inventory[slot], o_ptr))
- if (process_hooks(HOOK_TAKEOFF, "(d)", slot)) return;
- }
-
/* Take a turn */
energy_use = 100;
@@ -441,7 +450,7 @@ void do_cmd_wield(void)
p_ptr->update |= (PU_MANA | PU_SPELLS);
/* Redraw monster hitpoint */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
}
@@ -453,23 +462,18 @@ void do_cmd_wield(void)
*/
void do_cmd_takeoff(void)
{
- int item;
-
- object_type *o_ptr;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Take off which item? ";
- s = "You are not wearing anything to take off.";
- if (!get_item(&item, q, s, (USE_EQUIP))) return;
+ int item;
+ if (!get_item(&item,
+ "Take off which item? ",
+ "You are not wearing anything to take off.",
+ (USE_EQUIP)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
- /* Can we take it off */
- if (process_hooks(HOOK_TAKEOFF, "(d)", item)) return;
+ object_type *o_ptr = get_object(item);
/* Item is cursed */
if (cursed_p(o_ptr) && (!wizard))
@@ -491,7 +495,7 @@ void do_cmd_takeoff(void)
/* Recalculate hitpoint */
p_ptr->update |= (PU_HP);
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -500,27 +504,24 @@ void do_cmd_takeoff(void)
*/
void do_cmd_drop(void)
{
- int item, amt = 1;
-
- object_type *o_ptr;
-
- u32b f1, f2, f3, f4, f5, esp;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Drop which item? ";
- s = "You have nothing to drop.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+ int item;
+ if (!get_item(&item,
+ "Drop which item? ",
+ "You have nothing to drop.",
+ (USE_EQUIP | USE_INVEN)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Can we drop */
- if (process_hooks(HOOK_DROP, "(d)", item)) return;
+ struct hook_drop_in in = { item };
+ if (process_hooks_new(HOOK_DROP, &in, NULL)) return;
/* Hack -- Cannot remove cursed items */
if (cursed_p(o_ptr))
@@ -546,8 +547,8 @@ void do_cmd_drop(void)
}
}
-
/* See how many items */
+ int amt = 1;
if (o_ptr->number > 1)
{
/* Get a quantity */
@@ -570,37 +571,33 @@ void do_cmd_drop(void)
*/
void do_cmd_destroy(void)
{
- int item, amt = 1;
-
int old_number;
bool_ force = FALSE;
- object_type *o_ptr;
-
char o_name[80];
char out_val[160];
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
-
-
/* Hack -- force destruction */
if (command_arg > 0) force = TRUE;
/* Get an item */
- q = "Destroy which item? ";
- s = "You have nothing to destroy.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_AUTO))) return;
+ int item;
+ if (!get_item(&item,
+ "Destroy which item? ",
+ "You have nothing to destroy.",
+ (USE_INVEN | USE_FLOOR | USE_AUTO)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* See how many items */
+ int amt = 1;
if (o_ptr->number > 1)
{
/* Get a quantity */
@@ -620,17 +617,15 @@ void do_cmd_destroy(void)
/* Verify unless quantity given */
if (!force)
{
- if (!((auto_destroy) && (object_value(o_ptr) < 1)))
- {
- /* Make a verification */
- strnfmt(out_val, 160, "Really destroy %s? ", o_name);
- if (!get_check(out_val)) return;
- }
+ /* Make a verification */
+ strnfmt(out_val, 160, "Really destroy %s? ", o_name);
+ if (!get_check(out_val)) return;
}
/* Take no time, just like the automatizer */
energy_use = 0;
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
if ((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr))
@@ -679,7 +674,7 @@ void do_cmd_destroy(void)
/* Create an automatizer rule */
if (automatizer_create)
{
- automatizer_add_rule(o_ptr, TRUE);
+ automatizer_add_rule(o_ptr);
}
/*
@@ -706,24 +701,21 @@ void do_cmd_destroy(void)
*/
void do_cmd_observe(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- cptr q, s;
-
-
/* Get an item */
- q = "Examine which item? ";
- s = "You have nothing to examine.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Examine which item? ",
+ "You have nothing to examine.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -741,20 +733,18 @@ void do_cmd_observe(void)
*/
void do_cmd_uninscribe(void)
{
- int item;
-
- object_type *o_ptr;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Un-inscribe which item? ";
- s = "You have nothing to un-inscribe.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Un-inscribe which item? ",
+ "You have nothing to un-inscribe.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Nothing to remove */
if (!o_ptr->note)
@@ -782,26 +772,21 @@ void do_cmd_uninscribe(void)
*/
void do_cmd_inscribe(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- char out_val[80];
-
- cptr q, s;
-
-
/* Get an item */
- q = "Inscribe which item? ";
- s = "You have nothing to inscribe.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Inscribe which item? ",
+ "You have nothing to inscribe.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Describe the activity */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Message */
@@ -809,6 +794,7 @@ void do_cmd_inscribe(void)
msg_print(NULL);
/* Start with nothing */
+ char out_val[80];
strcpy(out_val, "");
/* Use old inscription */
@@ -837,17 +823,15 @@ void do_cmd_inscribe(void)
/*
* An "item_tester_hook" for refilling lanterns
*/
-static bool_ item_tester_refill_lantern(object_type *o_ptr)
+static object_filter_t const &item_tester_refill_lantern()
{
- /* Flasks of oil are okay */
- if (o_ptr->tval == TV_FLASK) return (TRUE);
-
- /* Lanterns are okay */
- if ((o_ptr->tval == TV_LITE) &&
- (o_ptr->sval == SV_LITE_LANTERN)) return (TRUE);
-
- /* Assume not okay */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_FLASK),
+ And(
+ TVal(TV_LITE),
+ SVal(SV_LITE_LANTERN)));
+ return instance;
}
@@ -856,30 +840,25 @@ static bool_ item_tester_refill_lantern(object_type *o_ptr)
*/
static void do_cmd_refill_lamp(void)
{
- int item;
-
- object_type *o_ptr;
- object_type *j_ptr;
-
- cptr q, s;
-
-
- /* Restrict the choices */
- item_tester_hook = item_tester_refill_lantern;
-
/* Get an item */
- q = "Refill with which flask? ";
- s = "You have no flasks of oil.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Refill with which flask? ",
+ "You have no flasks of oil.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_refill_lantern()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a partial turn */
energy_use = 50;
/* Access the lantern */
- j_ptr = &p_ptr->inventory[INVEN_LITE];
+ object_type *j_ptr = &p_ptr->inventory[INVEN_LITE];
/* Refuel */
if (o_ptr->tval == TV_FLASK)
@@ -908,14 +887,14 @@ static void do_cmd_refill_lamp(void)
/*
* An "item_tester_hook" for refilling torches
*/
-static bool_ item_tester_refill_torch(object_type *o_ptr)
+static object_filter_t const &item_tester_refill_torch()
{
- /* Torches are okay */
- if ((o_ptr->tval == TV_LITE) &&
- (o_ptr->sval == SV_LITE_TORCH)) return (TRUE);
-
- /* Assume not okay */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ And(
+ TVal(TV_LITE),
+ SVal(SV_LITE_TORCH));
+ return instance;
}
@@ -924,31 +903,25 @@ static bool_ item_tester_refill_torch(object_type *o_ptr)
*/
static void do_cmd_refill_torch(void)
{
- int item;
-
- object_type *o_ptr;
-
- object_type *j_ptr;
-
- cptr q, s;
-
-
- /* Restrict the choices */
- item_tester_hook = item_tester_refill_torch;
-
/* Get an item */
- q = "Refuel with which torch? ";
- s = "You have no extra torches.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Refuel with which torch? ",
+ "You have no extra torches.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_refill_torch()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a partial turn */
energy_use = 50;
/* Access the primary torch */
- j_ptr = &p_ptr->inventory[INVEN_LITE];
+ object_type *j_ptr = &p_ptr->inventory[INVEN_LITE];
/* Refuel */
j_ptr->timeout += o_ptr->timeout + 5;
@@ -1270,107 +1243,75 @@ static cptr ident_info[] =
};
-
-/*
- * Sorting hook -- Comp function -- see below
- *
- * We use "u" to point to array of monster indexes,
- * and "v" to select the type of sorting to perform on "u".
+/**
+ * Sort by monster experience.
*/
-static bool_ ang_sort_comp_hook(vptr u, vptr v, int a, int b)
+static bool compare_monster_experience(int w1, int w2)
{
- u16b *who = (u16b*)(u);
-
- u16b *why = (u16b*)(v);
-
- int w1 = who[a];
-
- int w2 = who[b];
-
- int z1, z2;
-
-
- /* Sort by player kills */
- if (*why >= 4)
- {
- /* Extract player kills */
- z1 = r_info[w1].r_pkills;
- z2 = r_info[w2].r_pkills;
-
- /* Compare player kills */
- if (z1 < z2) return (TRUE);
- if (z1 > z2) return (FALSE);
- }
-
-
- /* Sort by total kills */
- if (*why >= 3)
- {
- /* Extract total kills */
- z1 = r_info[w1].r_tkills;
- z2 = r_info[w2].r_tkills;
-
- /* Compare total kills */
- if (z1 < z2) return (TRUE);
- if (z1 > z2) return (FALSE);
- }
+ /* Extract experience */
+ s32b z1 = r_info[w1].mexp;
+ s32b z2 = r_info[w2].mexp;
+ /* Compare experience */
+ if (z1 < z2) return true;
+ if (z1 > z2) return false;
- /* Sort by monster level */
- if (*why >= 2)
- {
- /* Extract levels */
- z1 = r_info[w1].level;
- z2 = r_info[w2].level;
-
- /* Compare levels */
- if (z1 < z2) return (TRUE);
- if (z1 > z2) return (FALSE);
- }
-
+ /* Punt to index */
+ return w1 < w2;
+}
- /* Sort by monster experience */
- if (*why >= 1)
- {
- /* Extract experience */
- z1 = r_info[w1].mexp;
- z2 = r_info[w2].mexp;
+/**
+ * Sort by monster level.
+ */
+static bool compare_monster_level(int w1, int w2)
+{
+ /* Extract levels */
+ byte z1 = r_info[w1].level;
+ byte z2 = r_info[w2].level;
+
+ /* Compare levels */
+ if (z1 < z2) return true;
+ if (z1 > z2) return false;
+
+ /* Punt to monster experience. */
+ return compare_monster_experience(w1, w2);
+}
- /* Compare experience */
- if (z1 < z2) return (TRUE);
- if (z1 > z2) return (FALSE);
- }
+/**
+ * Sort by total number of kills
+ */
+static bool compare_total_kills(int w1, int w2)
+{
+ /* Extract total kills */
+ s16b z1 = r_info[w1].r_tkills;
+ s16b z2 = r_info[w2].r_tkills;
+ /* Compare total kills */
+ if (z1 < z2) return true;
+ if (z1 > z2) return false;
- /* Compare indexes */
- return (w1 <= w2);
+ /* Punt to monster level. */
+ return compare_monster_level(w1, w2);
}
-
/*
- * Sorting hook -- Swap function -- see below
- *
- * We use "u" to point to array of monster indexes,
- * and "v" to select the type of sorting to perform.
+ * Sort by player kills
*/
-static void ang_sort_swap_hook(vptr u, vptr v, int a, int b)
+static bool compare_player_kills(int w1, int w2)
{
- u16b *who = (u16b*)(u);
-
- u16b holder;
-
+ /* Extract player kills */
+ s16b z1 = r_info[w1].r_pkills;
+ s16b z2 = r_info[w2].r_pkills;
- /* XXX XXX */
- v = v ? v : 0;
+ /* Compare player kills */
+ if (z1 < z2) return true;
+ if (z1 > z2) return false;
- /* Swap */
- holder = who[a];
- who[a] = who[b];
- who[b] = holder;
+ /* Punt to total number of kills. */
+ return compare_total_kills(w1, w2);
}
-
/*
* Hack -- Display the "name" and "attr/chars" of a monster race
*/
@@ -1405,18 +1346,16 @@ static void roff_top(int r_idx)
}
/* Dump the name */
- Term_addstr( -1, TERM_WHITE, (r_name + r_ptr->name));
+ Term_addstr( -1, TERM_WHITE, r_ptr->name);
/* Append the "standard" attr/char info */
Term_addstr( -1, TERM_WHITE, " ('");
Term_addch(a1, c1);
- if (use_bigtile && (a1 & 0x80)) Term_addch(255, 255);
Term_addstr( -1, TERM_WHITE, "')");
/* Append the "optional" attr/char info */
Term_addstr( -1, TERM_WHITE, "/('");
Term_addch(a2, c2);
- if (use_bigtile && (a2 & 0x80)) Term_addch(255, 255);
Term_addstr( -1, TERM_WHITE, "'):");
}
@@ -1436,7 +1375,7 @@ static void roff_top(int r_idx)
*/
void do_cmd_query_symbol(void)
{
- int i, n, r_idx;
+ int i, r_idx;
char sym, query;
@@ -1457,11 +1396,7 @@ void do_cmd_query_symbol(void)
bool_ recall = FALSE;
-
- u16b why = 0;
-
- u16b *who;
-
+ bool (*sort_by)(int,int) = nullptr;
/* Get a character, or abort */
if (!get_com("Enter character to be identified, "
@@ -1508,11 +1443,9 @@ void do_cmd_query_symbol(void)
/* Display the result */
prt(buf, 0, 0);
- /* Allocate the "who" array */
- C_MAKE(who, max_r_idx, u16b);
-
/* Collect matching monsters */
- for (n = 0, i = 1; i < max_r_idx; i++)
+ std::vector<u16b> who;
+ for (i = 1; i < max_r_idx; i++)
{
monster_race *r_ptr = &r_info[i];
@@ -1530,22 +1463,21 @@ void do_cmd_query_symbol(void)
{
char mon_name[80];
- strcpy(mon_name, r_name + r_ptr->name);
+ strcpy(mon_name, r_ptr->name);
strlower(mon_name);
if (!strstr(mon_name, temp)) continue;
}
/* Collect "appropriate" monsters */
- if (all || (r_ptr->d_char == sym)) who[n++] = i;
+ if (all || (r_ptr->d_char == sym)) {
+ who.push_back(i);
+ }
}
/* Nothing to recall */
- if (!n)
+ if (who.empty())
{
- /* Free the "who" array */
- C_KILL(who, max_r_idx, u16b);
-
return;
}
@@ -1563,41 +1495,34 @@ void do_cmd_query_symbol(void)
/* Sort by kills (and level) */
if (query == 'k')
{
- why = 4;
+ sort_by = compare_player_kills;
query = 'y';
}
/* Sort by level */
if (query == 'p')
{
- why = 2;
+ sort_by = compare_monster_level;
query = 'y';
}
/* Catch "escape" */
if (query != 'y')
{
- /* Free the "who" array */
- C_KILL(who, max_r_idx, u16b);
-
return;
}
/* Sort if needed */
- if (why)
+ if (sort_by)
{
- /* Select the sort method */
- ang_sort_comp = ang_sort_comp_hook;
- ang_sort_swap = ang_sort_swap_hook;
-
/* Sort the array */
- ang_sort(who, &why, n);
+ std::sort(std::begin(who), std::end(who), sort_by);
}
/* Start at the end */
- i = n - 1;
+ i = who.size() - 1;
/* Scan the monster memory */
while (1)
@@ -1658,10 +1583,11 @@ void do_cmd_query_symbol(void)
/* Move to "prev" monster */
if (query == '-')
{
- if (++i == n)
+ i++;
+ assert(i >= 0);
+ if (static_cast<size_t>(i) == who.size())
{
i = 0;
- if (!expand_list) break;
}
}
@@ -1670,17 +1596,13 @@ void do_cmd_query_symbol(void)
{
if (i-- == 0)
{
- i = n - 1;
- if (!expand_list) break;
+ i = who.size() - 1;
}
}
}
/* Re-display the identity */
prt(buf, 0, 0);
-
- /* Free the "who" array */
- C_KILL(who, max_r_idx, u16b);
}
@@ -1690,7 +1612,7 @@ void do_cmd_query_symbol(void)
*/
bool_ research_mon()
{
- int i, n, r_idx;
+ int i, r_idx;
char sym, query;
@@ -1715,13 +1637,8 @@ bool_ research_mon()
bool_ recall = FALSE;
- u16b why = 0;
-
monster_race *r2_ptr;
- u16b *who;
-
-
/* Hack -- Remember "cheat_know" flag */
oldcheat = cheat_know;
@@ -1729,9 +1646,6 @@ bool_ research_mon()
/* Get a character, or abort */
if (!get_com("Enter character of monster: ", &sym)) return (TRUE);
- /* Allocate the "who" array */
- C_MAKE(who, max_r_idx, u16b);
-
/* Find that character info, and describe it */
for (i = 0; ident_info[i]; ++i)
{
@@ -1752,7 +1666,8 @@ bool_ research_mon()
/* Collect matching monsters */
- for (n = 0, i = 1; i < max_r_idx; i++)
+ std::vector<u16b> who;
+ for (i = 1; i < max_r_idx; i++)
{
monster_race *r_ptr = &r_info[i];
@@ -1769,15 +1684,14 @@ bool_ research_mon()
if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;
/* Collect "appropriate" monsters */
- if (all || (r_ptr->d_char == sym)) who[n++] = i;
+ if (all || (r_ptr->d_char == sym)) {
+ who.push_back(i);
+ }
}
/* Nothing to recall */
- if (!n)
+ if (who.empty())
{
- /* Free the "who" array */
- C_KILL(who, max_r_idx, u16b);
-
/* Restore the "cheat_know" flag */
cheat_know = oldcheat;
@@ -1785,24 +1699,14 @@ bool_ research_mon()
}
- /* Sort by level */
- why = 2;
query = 'y';
- /* Sort if needed */
- if (why)
- {
- /* Select the sort method */
- ang_sort_comp = ang_sort_comp_hook;
- ang_sort_swap = ang_sort_swap_hook;
-
- /* Sort the array */
- ang_sort(who, &why, n);
- }
+ /* Sort by level */
+ std::sort(std::begin(who), std::end(who), compare_monster_level);
/* Start at the end */
- i = n - 1;
+ i = who.size() - 1;
notpicked = TRUE;
@@ -1873,10 +1777,11 @@ bool_ research_mon()
/* Move to "prev" monster */
if (query == '-')
{
- if (++i == n)
+ i++;
+ assert(i >= 0);
+ if (static_cast<size_t>(i) == who.size())
{
i = 0;
- if (!expand_list) break;
}
}
@@ -1885,8 +1790,7 @@ bool_ research_mon()
{
if (i-- == 0)
{
- i = n - 1;
- if (!expand_list) break;
+ i = who.size() - 1;
}
}
}
@@ -1895,9 +1799,6 @@ bool_ research_mon()
/* Re-display the identity */
/* prt(buf, 5, 5);*/
- /* Free the "who" array */
- C_KILL(who, max_r_idx, u16b);
-
/* Restore the "cheat_know" flag */
cheat_know = oldcheat;
@@ -1958,131 +1859,6 @@ bool_ do_cmd_sense_grid_mana()
/*
- * Calculate the weight of the portable holes
- */
-s32b portable_hole_weight(void)
-{
- s32b weight, i;
-
- store_type *st_ptr = &town_info[TOWN_RANDOM].store[STORE_HOME];
-
-
- /* Sum the objects in the appropriate home */
- for (i = 0, weight = 0; i < st_ptr->stock_num; i++)
- {
- object_type *o_ptr = &st_ptr->stock[i];
-
- weight += (o_ptr->weight * o_ptr->number);
- }
-
- /* Multiply the sum with 1.5 */
- weight = (weight * 3) / 2 + 2;
-
- return (weight);
-}
-
-
-/*
- * Calculate and set the weight of the portable holes
- */
-void set_portable_hole_weight(void)
-{
- s32b weight, i, j;
-
- /* Calculate the weight of items in home */
- weight = portable_hole_weight();
-
- /* Set the weight of portable holes in the shops, ... */
- for (i = 1; i < max_towns; i++)
- {
- for (j = 0; j < max_st_idx; j++)
- {
- store_type *st_ptr = &town_info[i].store[j];
- int k;
-
- for (k = 0; k < st_ptr->stock_num; k++)
- {
- object_type *o_ptr = &st_ptr->stock[k];
-
- if ((o_ptr->tval == TV_TOOL) &&
- (o_ptr->sval == SV_PORTABLE_HOLE))
- o_ptr->weight = weight;
- }
- }
- }
-
- /* ... in the object list, ... */
- for (i = 1; i < o_max; i++)
- {
- object_type *o_ptr = &o_list[i];
-
- if ((o_ptr->tval == TV_TOOL) &&
- (o_ptr->sval == SV_PORTABLE_HOLE)) o_ptr->weight = weight;
- }
-
- /* ... and in the p_ptr->inventory to the appropriate value */
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- /* Skip non-objects */
- if ((o_ptr->tval == TV_TOOL) &&
- (o_ptr->sval == SV_PORTABLE_HOLE)) o_ptr->weight = weight;
- }
-}
-
-
-/*
- * Use a portable hole
- */
-void do_cmd_portable_hole(void)
-{
- cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px];
-
- int feat, special, town_num;
-
- /* Is it currently wielded? */
- if (!p_ptr->inventory[INVEN_TOOL].k_idx ||
- (p_ptr->inventory[INVEN_TOOL].tval != TV_TOOL) ||
- (p_ptr->inventory[INVEN_TOOL].sval != SV_PORTABLE_HOLE))
- {
- /* No, it isn't */
- msg_print("You have to wield a portable hole to use your abilities");
- return;
- }
-
- /* Mega-hack: Saving the old values, and then... */
- feat = c_ptr->feat;
- special = c_ptr->special;
- town_num = p_ptr->town_num;
-
- /* ... change the current grid to the home in town #1 */
- /* DG -- use the first random town, since random towns cannot have houses */
- /*
- * pelpel -- This doesn't affect LoS, so we can manipulate
- * terrain feature without calling cave_set_feat()
- */
- c_ptr->feat = FEAT_SHOP;
- c_ptr->special = STORE_HOME;
- p_ptr->town_num = TOWN_RANDOM;
-
- /* Now use the portable hole */
- do_cmd_store();
-
- /* Mega-hack part II: change the current grid to the original value */
- c_ptr->feat = feat;
- c_ptr->special = special;
- p_ptr->town_num = town_num;
-
- set_portable_hole_weight();
-
- /* Recalculate bonuses */
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- p_ptr->update |= (PU_BONUS);
-}
-
-
-/*
* Try to add a CLI action.
*/
void cli_add(cptr active, cptr trigger, cptr descr)
@@ -2137,16 +1913,19 @@ void cli_add(cptr active, cptr trigger, cptr descr)
}
if (*t == '\0') break;
}
- cli_ptr->comm = string_make(temp);
+ cli_ptr->comm = strdup(temp);
}
else
{
- cli_ptr->comm = string_make(trigger);
+ cli_ptr->comm = strdup(trigger);
}
/* First try copying everything across. */
cli_ptr->key = num;
- cli_ptr->descrip = string_make(descr);
+ cli_ptr->descrip = nullptr;
+ if (descr) {
+ cli_ptr->descrip = strdup(descr);
+ }
/* Take description for the previous record if appropriate. */
if ((cli_total > 0) && (old_ptr->key == cli_ptr->key) && (cli_ptr->descrip == 0))
diff --git a/src/cmd3.hpp b/src/cmd3.hpp
new file mode 100644
index 00000000..48677b77
--- /dev/null
+++ b/src/cmd3.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void do_cmd_html_dump(void);
+extern void cli_add(cptr active, cptr trigger, cptr descr);
+extern void do_cmd_cli(void);
+extern void do_cmd_cli_help(void);
+extern void do_cmd_inven(void);
+extern void do_cmd_equip(void);
+extern void do_cmd_wield(void);
+extern void do_cmd_takeoff(void);
+extern void do_cmd_drop(void);
+extern void do_cmd_destroy(void);
+extern void do_cmd_observe(void);
+extern void do_cmd_uninscribe(void);
+extern void do_cmd_inscribe(void);
+extern void do_cmd_refill(void);
+extern void do_cmd_target(void);
+extern void do_cmd_look(void);
+extern void do_cmd_locate(void);
+extern void do_cmd_query_symbol(void);
+extern bool_ do_cmd_sense_grid_mana(void);
+extern bool_ research_mon(void);
diff --git a/src/cmd4.c b/src/cmd4.cc
index da606cc6..c18718ae 100644
--- a/src/cmd4.c
+++ b/src/cmd4.cc
@@ -1,7 +1,3 @@
-/* File: cmd4.c */
-
-/* Purpose: Interface commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -9,10 +5,42 @@
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
-
-#include "angband.h"
-
-#include "messages.h"
+#include "cmd4.hpp"
+
+#include "artifact_type.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "levels.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "squeltch.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <vector>
+#include <algorithm>
/*
* Hack -- redraw the screen
@@ -60,7 +88,7 @@ void do_cmd_redraw(void)
p_ptr->update |= (PU_MONSTERS);
/* Redraw everything */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER | PW_M_LIST);
@@ -209,7 +237,7 @@ void do_cmd_change_name(void)
/* Redraw everything */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
handle_stuff();
}
@@ -449,63 +477,53 @@ void do_cmd_messages(void)
character_icky = FALSE;
}
+// File-local
+namespace {
+ /**
+ * Interaction mode for options
+ */
+ enum class interaction_mode_t {
+ READ_ONLY = 0,
+ READ_WRITE = 1
+ };
-/*
- * Number of cheating options
- */
-#define CHEAT_MAX 6
-
-/*
- * Cheating options
- */
-static option_type cheat_info[CHEAT_MAX] =
-{
- { &cheat_peek, FALSE, 0, 0, "cheat_peek", "Peek into object creation" },
- { &cheat_hear, FALSE, 0, 1, "cheat_hear", "Peek into monster creation" },
- { &cheat_room, FALSE, 0, 2, "cheat_room", "Peek into dungeon creation" },
- { &cheat_xtra, FALSE, 0, 3, "cheat_xtra", "Peek into something else" },
- { &cheat_know, FALSE, 0, 4, "cheat_know", "Know complete monster info" },
- { &cheat_live, FALSE, 0, 5, "cheat_live", "Allow player to avoid death" }
-};
+}
-/*
- * Interact with some options for cheating
+/**
+ * Interact with given vector of options.
*/
-static void do_cmd_options_cheat(cptr info)
+static void interact_with_options(std::vector<option_type *> const &options, char const *info, interaction_mode_t interaction_mode)
{
- char ch;
-
- int i, k = 0, n = CHEAT_MAX;
-
- int dir;
-
- char buf[80];
-
+ size_t n = options.size();
/* Clear screen */
Term_clear();
/* Interact with the player */
+ size_t k = 0; /* Currently selected option index */
while (TRUE)
{
/* Prompt XXX XXX XXX */
+ char buf[80];
strnfmt(buf, 80, "%s (RET to advance, y/n to set, ESC to accept) ", info);
prt(buf, 0, 0);
/* Display the options */
- for (i = 0; i < n; i++)
+ for (size_t i = 0; i < n; i++)
{
byte a = TERM_WHITE;
/* Color current option */
- if (i == k) a = TERM_L_BLUE;
+ if (i == k) {
+ a = TERM_L_BLUE;
+ }
/* Display the option text */
strnfmt(buf, 80, "%-48s: %s (%s)",
- cheat_info[i].o_desc,
- (*cheat_info[i].o_var ? "yes" : "no "),
- cheat_info[i].o_text);
+ options[i]->o_desc,
+ (*options[i]->o_var ? "yes" : "no "),
+ options[i]->o_text);
c_prt(a, buf, i + 2, 0);
}
@@ -513,15 +531,19 @@ static void do_cmd_options_cheat(cptr info)
move_cursor(k + 2, 50);
/* Get a key */
- ch = inkey();
+ int ch = inkey();
/*
* Hack -- Try to translate the key into a direction
* to allow the use of roguelike keys for navigation
*/
- dir = get_keymap_dir(ch);
- if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8)) ch = I2D(dir);
-
+ {
+ int dir = get_keymap_dir(ch);
+ if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
+ {
+ ch = I2D(dir);
+ }
+ }
/* Analyze */
switch (ch)
@@ -534,8 +556,9 @@ static void do_cmd_options_cheat(cptr info)
case '-':
case '8':
{
+ /* Adding n pre-modulo ensures that we don't
+ wrap around to the wrong (post-modulo) index. */
k = (n + k - 1) % n;
-
break;
}
@@ -545,7 +568,6 @@ static void do_cmd_options_cheat(cptr info)
case '2':
{
k = (k + 1) % n;
-
break;
}
@@ -553,10 +575,12 @@ static void do_cmd_options_cheat(cptr info)
case 'Y':
case '6':
{
- noscore |= (cheat_info[k].o_page * 256 + cheat_info[k].o_bit);
- (*cheat_info[k].o_var) = TRUE;
+ if (interaction_mode == interaction_mode_t::READ_ONLY)
+ {
+ break;
+ }
+ *(options[k]->o_var) = TRUE;
k = (k + 1) % n;
-
break;
}
@@ -564,9 +588,13 @@ static void do_cmd_options_cheat(cptr info)
case 'N':
case '4':
{
- (*cheat_info[k].o_var) = FALSE;
- k = (k + 1) % n;
+ if (interaction_mode == interaction_mode_t::READ_ONLY)
+ {
+ break;
+ }
+ *(options[k]->o_var) = FALSE;
+ k = (k + 1) % n;
break;
}
@@ -578,6 +606,54 @@ static void do_cmd_options_cheat(cptr info)
}
}
}
+
+
+}
+
+
+
+/*
+ * Cheating options
+ */
+static option_type cheat_info[6] =
+{
+ { &cheat_peek, FALSE, 0, 0, "cheat_peek", "Peek into object creation" },
+ { &cheat_hear, FALSE, 0, 1, "cheat_hear", "Peek into monster creation" },
+ { &cheat_room, FALSE, 0, 2, "cheat_room", "Peek into dungeon creation" },
+ { &cheat_xtra, FALSE, 0, 3, "cheat_xtra", "Peek into something else" },
+ { &cheat_know, FALSE, 0, 4, "cheat_know", "Know complete monster info" },
+ { &cheat_live, FALSE, 0, 5, "cheat_live", "Allow player to avoid death" }
+};
+
+/*
+ * Interact with some options for cheating
+ */
+static void do_cmd_options_cheat(cptr info)
+{
+ // Calculate number of cheat options
+ size_t n = std::distance(std::begin(cheat_info), std::end(cheat_info));
+
+ // Build the vector of options we're going to interact with
+ std::vector<option_type *> options;
+ options.reserve(n);
+ for (auto &option : cheat_info)
+ {
+ options.push_back(&option);
+ }
+
+ // Interact
+ interact_with_options(options, info, interaction_mode_t::READ_WRITE);
+
+ // If user toggled any of the options to TRUE, then we add those cheats
+ // to the player's "noscore" flags. Note that it doesn't matter what the
+ // previous value was -- we don't "unset" noscore flags anyway.
+ for (auto &option: options)
+ {
+ if (*option->o_var)
+ {
+ noscore |= (option->o_page * 256 + option->o_bit);
+ }
+ }
}
@@ -728,152 +804,27 @@ static void do_cmd_options_autosave(cptr info)
}
}
-/* Switch an option by only knowing its name */
-bool_ change_option(cptr name, bool_ value)
-{
- int i;
-
- /* Scan the options */
- for (i = 0; option_info[i].o_desc; i++)
- {
- if (!strcmp(option_info[i].o_text, name))
- {
- bool_ old = (*option_info[i].o_var);
-
- (*option_info[i].o_var) = value;
-
- return old;
- }
- }
-
- cmsg_format(TERM_VIOLET, "Warning, change_option couldn't find option '%s'.", name);
- return FALSE;
-}
-
/*
* Interact with some options
*/
void do_cmd_options_aux(int page, cptr info, bool_ read_only)
{
- char ch;
-
- int i, k = 0, n = 0;
-
- int dir;
-
- int opt[24];
-
- char buf[80];
-
-
- /* Lookup the options */
- for (i = 0; i < 24; i++) opt[i] = 0;
-
- /* Scan the options */
- for (i = 0; option_info[i].o_desc; i++)
- {
- /* Notice options on this "page" */
- if (option_info[i].o_page == page) opt[n++] = i;
- }
-
-
- /* Clear screen */
- Term_clear();
-
- /* Interact with the player */
- while (TRUE)
+ // Scrape together all the options from the relevant page.
+ std::vector<option_type *> options;
+ options.reserve(64); // Seems a reasonable number; anything more would be unusable anyway
+ for (size_t i = 0; option_info[i].o_desc; i++)
{
- /* Prompt XXX XXX XXX */
- strnfmt(buf, 80, "%s (RET to advance, y/n to set, ESC to accept) ", info);
- prt(buf, 0, 0);
-
- /* Display the options */
- for (i = 0; i < n; i++)
+ if (option_info[i].o_page == page)
{
- byte a = TERM_WHITE;
-
- /* Color current option */
- if (i == k) a = TERM_L_BLUE;
-
- /* Display the option text */
- strnfmt(buf, 80, "%-48s: %s (%s)",
- option_info[opt[i]].o_desc,
- (*option_info[opt[i]].o_var ? "yes" : "no "),
- option_info[opt[i]].o_text);
- c_prt(a, buf, i + 2, 0);
- }
-
- /* Hilite current option */
- move_cursor(k + 2, 50);
-
- /* Get a key */
- ch = inkey();
-
- /*
- * Hack -- Try to translate the key into a direction
- * to allow the use of roguelike keys for navigation
- */
- dir = get_keymap_dir(ch);
- if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8)) ch = I2D(dir);
-
- /* Analyze */
- switch (ch)
- {
- case ESCAPE:
- {
- return;
- }
-
- case '-':
- case '8':
- {
- k = (n + k - 1) % n;
-
- break;
- }
-
- case ' ':
- case '\n':
- case '\r':
- case '2':
- {
- k = (k + 1) % n;
-
- break;
- }
-
- case 'y':
- case 'Y':
- case '6':
- {
- if (read_only) break;
-
- (*option_info[opt[k]].o_var) = TRUE;
- k = (k + 1) % n;
-
- break;
- }
-
- case 'n':
- case 'N':
- case '4':
- {
- if (read_only) break;
-
- (*option_info[opt[k]].o_var) = FALSE;
- k = (k + 1) % n;
-
- break;
- }
-
- default:
- {
- bell();
-
- break;
- }
+ options.push_back(&option_info[i]);
}
}
+
+ // Interact with the options
+ interaction_mode_t interaction_mode = read_only
+ ? interaction_mode_t::READ_ONLY
+ : interaction_mode_t::READ_WRITE;
+ interact_with_options(options, info, interaction_mode);
}
@@ -1565,11 +1516,8 @@ static void do_cmd_macro_aux(char *buf, bool_ macro_screen)
/* Do not process macros */
inkey_base = TRUE;
- /* Do not wait for keys */
- inkey_scan = TRUE;
-
/* Attempt to read a key */
- i = inkey();
+ i = inkey_scan();
}
/* Terminate */
@@ -1998,11 +1946,9 @@ void do_cmd_macros(void)
/* Convert to ascii */
text_to_ascii(macro__buf, tmp);
- /* Free old keymap */
- string_free(keymap_act[mode][(byte)(buf[0])]);
-
/* Make new keymap */
- keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
+ free(keymap_act[mode][(byte)(buf[0])]);
+ keymap_act[mode][(byte)(buf[0])] = strdup(macro__buf);
/* Prompt */
msg_print("Added a keymap.");
@@ -2021,10 +1967,8 @@ void do_cmd_macros(void)
/* Get a keymap trigger */
do_cmd_macro_aux_keymap(buf);
- /* Free old keymap */
- string_free(keymap_act[mode][(byte)(buf[0])]);
-
/* Make new keymap */
+ free(keymap_act[mode][(byte)(buf[0])]);
keymap_act[mode][(byte)(buf[0])] = NULL;
/* Prompt */
@@ -2180,11 +2124,12 @@ void do_cmd_visuals(void)
if (!r_ptr->name) continue;
/* Dump a comment */
- fprintf(fff, "# %s\n", (r_name + r_ptr->name));
+ fprintf(fff, "# %s\n", r_ptr->name);
/* Dump the monster attr/char info */
fprintf(fff, "R:%d:0x%02X:0x%02X\n\n", i,
- (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
+ static_cast<unsigned int>(r_ptr->x_attr),
+ static_cast<unsigned int>(r_ptr->x_char));
}
/* All done */
@@ -2234,7 +2179,7 @@ void do_cmd_visuals(void)
if (!k_ptr->name) continue;
/* Dump a comment */
- fprintf(fff, "# %s\n", (k_name + k_ptr->name));
+ fprintf(fff, "# %s\n", k_ptr->name);
/* Dump the object attr/char info */
fprintf(fff, "K:%d:0x%02X:0x%02X\n\n", i,
@@ -2288,7 +2233,7 @@ void do_cmd_visuals(void)
if (!f_ptr->name) continue;
/* Dump a comment */
- fprintf(fff, "# %s\n", (f_name + f_ptr->name));
+ fprintf(fff, "# %s\n", f_ptr->name);
/* Dump the feature attr/char info */
fprintf(fff, "F:%d:0x%02X:0x%02X\n\n", i,
@@ -2326,33 +2271,19 @@ void do_cmd_visuals(void)
/* Label the object */
Term_putstr(5, 17, -1, TERM_WHITE,
format("Monster = %d, Name = %-40.40s",
- r, (r_name + r_ptr->name)));
+ r, r_ptr->name));
/* Label the Default values */
Term_putstr(10, 19, -1, TERM_WHITE,
format("Default attr/char = %3u / %3u", da, (dc & 0xFF)));
Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 19, da, dc);
- if (use_bigtile)
- {
- if (da & 0x80)
- Term_putch(44, 19, 255, 255);
- else
- Term_putch(44, 19, 0, ' ');
- }
/* Label the Current values */
Term_putstr(10, 20, -1, TERM_WHITE,
format("Current attr/char = %3u / %3u", ca, (cc & 0xFF)));
Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 20, ca, cc);
- if (use_bigtile)
- {
- if (ca & 0x80)
- Term_putch(44, 20, 255, 255);
- else
- Term_putch(44, 20, 0, ' ');
- }
/* Prompt */
Term_putstr(0, 22, -1, TERM_WHITE,
@@ -2367,10 +2298,10 @@ void do_cmd_visuals(void)
/* Analyze */
if (i == 'n') r = (r + max_r_idx + 1) % max_r_idx;
if (i == 'N') r = (r + max_r_idx - 1) % max_r_idx;
- if (i == 'a') r_ptr->x_attr = (byte)(ca + 1);
- if (i == 'A') r_ptr->x_attr = (byte)(ca - 1);
- if (i == 'c') r_ptr->x_char = (byte)(cc + 1);
- if (i == 'C') r_ptr->x_char = (byte)(cc - 1);
+ if (i == 'a') r_ptr->x_attr = (ca + 1);
+ if (i == 'A') r_ptr->x_attr = (ca - 1);
+ if (i == 'c') r_ptr->x_char = (cc + 1);
+ if (i == 'C') r_ptr->x_char = (cc - 1);
}
}
@@ -2387,41 +2318,27 @@ void do_cmd_visuals(void)
{
object_kind *k_ptr = &k_info[k];
- byte da = (byte)k_ptr->d_attr;
- char dc = (byte)k_ptr->d_char;
- byte ca = (byte)k_ptr->x_attr;
- char cc = (byte)k_ptr->x_char;
+ byte da = k_ptr->d_attr;
+ char dc = k_ptr->d_char;
+ byte ca = k_ptr->x_attr;
+ char cc = k_ptr->x_char;
/* Label the object */
Term_putstr(5, 17, -1, TERM_WHITE,
format("Object = %d, Name = %-40.40s",
- k, (k_name + k_ptr->name)));
+ k, k_ptr->name));
/* Label the Default values */
Term_putstr(10, 19, -1, TERM_WHITE,
format("Default attr/char = %3u / %3u", da, (dc & 0xFF)));
Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 19, da, dc);
- if (use_bigtile)
- {
- if (da & 0x80)
- Term_putch(44, 19, 255, 255);
- else
- Term_putch(44, 19, 0, ' ');
- }
/* Label the Current values */
Term_putstr(10, 20, -1, TERM_WHITE,
format("Current attr/char = %3u / %3u", ca, (cc & 0xFF)));
Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 20, ca, cc);
- if (use_bigtile)
- {
- if (ca & 0x80)
- Term_putch(44, 20, 255, 255);
- else
- Term_putch(44, 20, 0, ' ');
- }
/* Prompt */
Term_putstr(0, 22, -1, TERM_WHITE,
@@ -2436,10 +2353,10 @@ void do_cmd_visuals(void)
/* Analyze */
if (i == 'n') k = (k + max_k_idx + 1) % max_k_idx;
if (i == 'N') k = (k + max_k_idx - 1) % max_k_idx;
- if (i == 'a') k_info[k].x_attr = (byte)(ca + 1);
- if (i == 'A') k_info[k].x_attr = (byte)(ca - 1);
- if (i == 'c') k_info[k].x_char = (byte)(cc + 1);
- if (i == 'C') k_info[k].x_char = (byte)(cc - 1);
+ if (i == 'a') k_info[k].x_attr = (ca + 1);
+ if (i == 'A') k_info[k].x_attr = (ca - 1);
+ if (i == 'c') k_info[k].x_char = (cc + 1);
+ if (i == 'C') k_info[k].x_char = (cc - 1);
}
}
@@ -2456,41 +2373,27 @@ void do_cmd_visuals(void)
{
feature_type *f_ptr = &f_info[f];
- byte da = (byte)f_ptr->d_attr;
- char dc = (byte)f_ptr->d_char;
- byte ca = (byte)f_ptr->x_attr;
- char cc = (byte)f_ptr->x_char;
+ byte da = f_ptr->d_attr;
+ char dc = f_ptr->d_char;
+ byte ca = f_ptr->x_attr;
+ char cc = f_ptr->x_char;
/* Label the object */
Term_putstr(5, 17, -1, TERM_WHITE,
format("Terrain = %d, Name = %-40.40s",
- f, (f_name + f_ptr->name)));
+ f, f_ptr->name));
/* Label the Default values */
Term_putstr(10, 19, -1, TERM_WHITE,
format("Default attr/char = %3u / %3u", da, (dc & 0xFF)));
Term_putstr(40, 19, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 19, da, dc);
- if (use_bigtile)
- {
- if (da & 0x80)
- Term_putch(44, 19, 255, 255);
- else
- Term_putch(44, 19, 0, ' ');
- }
/* Label the Current values */
Term_putstr(10, 20, -1, TERM_WHITE,
format("Current attr/char = %3u / %3u", ca, (cc & 0xFF)));
Term_putstr(40, 20, -1, TERM_WHITE, "<< ? >>");
Term_putch(43, 20, ca, cc);
- if (use_bigtile)
- {
- if (ca & 0x80)
- Term_putch(44, 20, 255, 255);
- else
- Term_putch(44, 20, 0, ' ');
- }
/* Prompt */
Term_putstr(0, 22, -1, TERM_WHITE,
@@ -2505,10 +2408,10 @@ void do_cmd_visuals(void)
/* 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);
+ if (i == 'a') f_info[f].x_attr = (ca + 1);
+ if (i == 'A') f_info[f].x_attr = (ca - 1);
+ if (i == 'c') f_info[f].x_char = (cc + 1);
+ if (i == 'C') f_info[f].x_char = (cc - 1);
if (i == 'd')
{
f_info[f].x_char = f_ptr->d_char;
@@ -2733,16 +2636,16 @@ void do_cmd_colors(void)
if (i == ESCAPE) break;
/* Analyze */
- if (i == 'n') a = (byte)(a + 1);
- if (i == 'N') a = (byte)(a - 1);
- if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
- if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
- if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
- if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
- if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
- if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
- if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
- if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
+ if (i == 'n') a = (a + 1);
+ if (i == 'N') a = (a - 1);
+ if (i == 'k') angband_color_table[a][0] = (angband_color_table[a][0] + 1);
+ if (i == 'K') angband_color_table[a][0] = (angband_color_table[a][0] - 1);
+ if (i == 'r') angband_color_table[a][1] = (angband_color_table[a][1] + 1);
+ if (i == 'R') angband_color_table[a][1] = (angband_color_table[a][1] - 1);
+ if (i == 'g') angband_color_table[a][2] = (angband_color_table[a][2] + 1);
+ if (i == 'G') angband_color_table[a][2] = (angband_color_table[a][2] - 1);
+ if (i == 'b') angband_color_table[a][3] = (angband_color_table[a][3] + 1);
+ if (i == 'B') angband_color_table[a][3] = (angband_color_table[a][3] - 1);
/* Hack -- react to changes */
Term_xtra(TERM_XTRA_REACT, 0);
@@ -2843,7 +2746,7 @@ void do_cmd_feeling(void)
}
/* Hooked feelings ? */
- if (process_hooks(HOOK_FEELING, "(d)", is_quest(dun_level)))
+ if (process_hooks_new(HOOK_FEELING, NULL, NULL))
{
return;
}
@@ -3022,127 +2925,106 @@ void do_cmd_load_screen(void)
/*
- * Redefinable "save_screen" action
- */
-void (*screendump_aux)(void) = NULL;
-
-
-
-
-
-
-/*
* Hack -- save a screen dump to a file
*/
void do_cmd_save_screen(void)
{
- /* Do we use a special screendump function ? */
- if (screendump_aux)
- {
- /* Dump the screen to a graphics file */
- (*screendump_aux)();
- }
-
- /* Dump the screen as text */
- else
- {
- int y, x;
- int wid, hgt;
+ int y, x;
+ int wid, hgt;
- byte a = 0;
- char c = ' ';
+ byte a = 0;
+ char c = ' ';
- FILE *fff;
+ FILE *fff;
- char buf[1024];
+ char buf[1024];
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt");
+ /* Build the filename */
+ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt");
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
+ /* File type is "TEXT" */
+ FILE_TYPE(FILE_TYPE_TEXT);
- /* Append to the file */
- fff = my_fopen(buf, "w");
+ /* Append to the file */
+ fff = my_fopen(buf, "w");
- /* Oops */
- if (!fff) return;
+ /* Oops */
+ if (!fff) return;
- /* Retrieve the current screen size */
- Term_get_size(&wid, &hgt);
+ /* Retrieve the current screen size */
+ Term_get_size(&wid, &hgt);
- /* Enter "icky" mode */
- character_icky = TRUE;
+ /* Enter "icky" mode */
+ character_icky = TRUE;
- /* Save the screen */
- Term_save();
+ /* Save the screen */
+ Term_save();
- /* Dump the screen */
- for (y = 0; y < hgt; y++)
+ /* Dump the screen */
+ for (y = 0; y < hgt; y++)
+ {
+ /* Dump each row */
+ for (x = 0; x < wid; x++)
{
- /* Dump each row */
- for (x = 0; x < wid; x++)
- {
- /* Get the attr/char */
- (void)(Term_what(x, y, &a, &c));
+ /* Get the attr/char */
+ (void)(Term_what(x, y, &a, &c));
- /* Dump it */
- buf[x] = c;
- }
+ /* Dump it */
+ buf[x] = c;
+ }
- /* Terminate */
- buf[x] = '\0';
+ /* Terminate */
+ buf[x] = '\0';
- /* End the row */
- fprintf(fff, "%s\n", buf);
- }
+ /* End the row */
+ fprintf(fff, "%s\n", buf);
+ }
- /* Skip a line */
- fprintf(fff, "\n");
+ /* Skip a line */
+ fprintf(fff, "\n");
- /* Dump the screen */
- for (y = 0; y < hgt; y++)
+ /* Dump the screen */
+ for (y = 0; y < hgt; y++)
+ {
+ /* Dump each row */
+ for (x = 0; x < wid; x++)
{
- /* Dump each row */
- for (x = 0; x < wid; x++)
- {
- /* Get the attr/char */
- (void)(Term_what(x, y, &a, &c));
+ /* Get the attr/char */
+ (void)(Term_what(x, y, &a, &c));
- /* Dump it */
- buf[x] = hack[a & 0x0F];
- }
+ /* Dump it */
+ buf[x] = hack[a & 0x0F];
+ }
- /* Terminate */
- buf[x] = '\0';
+ /* Terminate */
+ buf[x] = '\0';
- /* End the row */
- fprintf(fff, "%s\n", buf);
- }
+ /* End the row */
+ fprintf(fff, "%s\n", buf);
+ }
- /* Skip a line */
- fprintf(fff, "\n");
+ /* Skip a line */
+ fprintf(fff, "\n");
- /* Close it */
- my_fclose(fff);
+ /* Close it */
+ my_fclose(fff);
- /* Message */
- msg_print("Screen dump saved.");
- msg_print(NULL);
+ /* Message */
+ msg_print("Screen dump saved.");
+ msg_print(NULL);
- /* Restore the screen */
- Term_load();
+ /* Restore the screen */
+ Term_load();
- /* Leave "icky" mode */
- character_icky = FALSE;
- }
+ /* Leave "icky" mode */
+ character_icky = FALSE;
}
@@ -3159,13 +3041,6 @@ void do_cmd_knowledge_artifacts(void)
char base_name[80];
- bool_ *okay, *okayk;
-
-
- /* Allocate the "okay" array */
- C_MAKE(okay, max_a_idx, bool_);
- C_MAKE(okayk, max_k_idx, bool_);
-
/* Temporary file */
if (path_temp(file_name, 1024)) return;
@@ -3173,6 +3048,7 @@ void do_cmd_knowledge_artifacts(void)
fff = my_fopen(file_name, "w");
/* Scan the artifacts */
+ std::unique_ptr<bool_[]> okay(new bool_[max_a_idx]);
for (k = 0; k < max_a_idx; k++)
{
artifact_type *a_ptr = &a_info[k];
@@ -3190,6 +3066,7 @@ void do_cmd_knowledge_artifacts(void)
okay[k] = TRUE;
}
+ std::unique_ptr<bool_[]> okayk(new bool_[max_k_idx]);
for (k = 0; k < max_k_idx; k++)
{
object_kind *k_ptr = &k_info[k];
@@ -3214,18 +3091,11 @@ void do_cmd_knowledge_artifacts(void)
{
cave_type *c_ptr = &cave[y][x];
- s16b this_o_idx, next_o_idx = 0;
-
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type const * o_ptr = &o_list[this_o_idx];
/* Ignore random artifacts */
if (o_ptr->tval == TV_RANDART) continue;
@@ -3252,21 +3122,14 @@ void do_cmd_knowledge_artifacts(void)
/* Check monsters in the dungeon */
for (i = 0; i < m_max; i++)
{
- monster_type *m_ptr = &m_list[i];
-
- s16b this_o_idx, next_o_idx = 0;
-
/* Scan all objects the monster carries */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: m_list[i].hold_o_idxs)
{
object_type * o_ptr;
/* Acquire object */
o_ptr = &o_list[this_o_idx];
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
/* Ignore random artifacts */
if (o_ptr->tval == TV_RANDART) continue;
@@ -3395,9 +3258,6 @@ void do_cmd_knowledge_artifacts(void)
/* Remove the file */
fd_kill(file_name);
-
- C_FREE(okay, max_a_idx, bool_);
- C_FREE(okayk, max_k_idx, bool_);
}
@@ -3434,7 +3294,7 @@ void do_cmd_knowledge_traps(void)
if (!t_ptr->ident) continue;
/* Hack -- Build the trap name */
- fprintf(fff, " %s\n", t_name + t_ptr->name);
+ fprintf(fff, " %s\n", t_ptr->name);
}
/* Close the file */
@@ -3448,54 +3308,28 @@ void do_cmd_knowledge_traps(void)
}
+static int monster_get_race_level(int r_idx) {
+ /* Hack -- Morgoth is always last */
+ if (r_idx == 862) {
+ return 20000;
+ }
+ /* Otherwise, we'll use the real level. */
+ return r_info[r_idx].level;
+}
+
+static bool compare_monster_level(int r_idx1, int r_idx2) {
+ return monster_get_race_level(r_idx1) < monster_get_race_level(r_idx2);
+}
+
/*
* Display known uniques
*
* Note that the player ghosts are ignored. XXX XXX XXX
*/
-static void insert_sort_unique(int *sort_uniques, int *num, int r_idx)
-{
- int i, j;
-
- monster_race *r_ptr = &r_info[r_idx];
-
- int level = r_ptr->level;
-
-
- /* Hack -- Morgoth is always at the bottom of the list */
- if (r_idx == 862) level = 20000;
-
- /* Find the place */
- for (i = 0; i < *num; i++)
- {
- monster_race *r2_ptr = &r_info[sort_uniques[i]];
- int level2 = r2_ptr->level;
-
- if (sort_uniques[i] == 862) level2 = 20000;
-
- if (level < level2) break;
- }
-
- /* Move the remaining items */
- for (j = *num - 1; j >= i; j--)
- {
- sort_uniques[j + 1] = sort_uniques[j];
- }
-
- /* Insert it */
- sort_uniques[i] = r_idx;
- (*num)++;
-}
-
-
static void do_cmd_knowledge_uniques(void)
{
int k;
- int *sort_uniques;
-
- int num = 0;
-
FILE *fff;
char file_name[1024];
@@ -3507,26 +3341,30 @@ static void do_cmd_knowledge_uniques(void)
/* Open a new file */
fff = my_fopen(file_name, "w");
- C_MAKE(sort_uniques, max_r_idx, int);
-
- /* Sort the monster races */
+ // Extract the unique race indexes.
+ std::vector<int> unique_r_idxs;
for (k = 1; k < max_r_idx; k++)
{
monster_race *r_ptr = &r_info[k];
/* Only print Uniques */
if (r_ptr->flags1 & (RF1_UNIQUE) &&
- !(r_ptr->flags7 & RF7_PET) &&
- !(r_ptr->flags7 & RF7_NEUTRAL))
+ !(r_ptr->flags7 & RF7_PET) &&
+ !(r_ptr->flags7 & RF7_NEUTRAL))
{
- insert_sort_unique(sort_uniques, &num, k);
+ unique_r_idxs.push_back(k);
}
}
- /* Scan the monster races -- sorted */
- for (k = 0; k < num; k++)
+ // Sort races by level.
+ std::sort(std::begin(unique_r_idxs),
+ std::end(unique_r_idxs),
+ compare_monster_level);
+
+ /* Scan the monster races */
+ for (int r_idx : unique_r_idxs)
{
- monster_race *r_ptr = &r_info[sort_uniques[k]];
+ monster_race *r_ptr = &r_info[r_idx];
/* Only print Uniques */
if (r_ptr->flags1 & (RF1_UNIQUE))
@@ -3539,44 +3377,22 @@ static void do_cmd_knowledge_uniques(void)
/* Print a message */
if (dead)
{
- /* Don't print the unique's ASCII symbol
- * if use_graphics is on. */
- if (use_graphics)
- {
- fprintf(fff, "[[[[[R%-70s is dead]\n",
- (r_name + r_ptr->name));
- }
- else
- {
- fprintf(fff, "[[[[[%c%c] [[[[[R%-68s is dead]\n",
- conv_color[r_ptr->d_attr],
- r_ptr->d_char,
- (r_name + r_ptr->name));
- }
+ fprintf(fff, "[[[[[%c%c] [[[[[R%-68s is dead]\n",
+ conv_color[r_ptr->d_attr],
+ r_ptr->d_char,
+ r_ptr->name);
}
else
{
- /* Don't print the unique's ASCII symbol
- * if use_graphics is on. */
- if (use_graphics)
- {
- fprintf(fff, "[[[[[w%-70s is alive]\n",
- (r_name + r_ptr->name));
- }
- else
- {
- fprintf(fff, "[[[[[%c%c] [[[[[w%-68s is alive]\n",
- conv_color[r_ptr->d_attr],
- r_ptr->d_char,
- (r_name + r_ptr->name));
- }
+ fprintf(fff, "[[[[[%c%c] [[[[[w%-68s is alive]\n",
+ conv_color[r_ptr->d_attr],
+ r_ptr->d_char,
+ r_ptr->name);
}
}
}
}
- C_FREE(sort_uniques, max_r_idx, int);
-
/* Close the file */
my_fclose(fff);
@@ -3588,7 +3404,7 @@ static void do_cmd_knowledge_uniques(void)
}
-void plural_aux(char *name)
+static void plural_aux(char *name)
{
int name_len = strlen(name);
@@ -3819,7 +3635,7 @@ static void do_cmd_knowledge_kill_count(void)
}
else
{
- fprintf(fff, "You have defeated %ld enemies.\n\n", (long int) Total);
+ fprintf(fff, "You have defeated " FMTs32b " enemies.\n\n", Total);
}
}
@@ -3837,8 +3653,7 @@ static void do_cmd_knowledge_kill_count(void)
if (dead)
{
/* Print a message */
- fprintf(fff, " %s\n",
- (r_name + r_ptr->name));
+ fprintf(fff, " %s\n", r_ptr->name);
Total++;
}
}
@@ -3850,19 +3665,19 @@ static void do_cmd_knowledge_kill_count(void)
{
if (This < 2)
{
- if (strstr(r_name + r_ptr->name, "coins"))
+ if (strstr(r_ptr->name, "coins"))
{
- fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
+ fprintf(fff, " 1 pile of %s\n", r_ptr->name);
}
else
{
- fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
+ fprintf(fff, " 1 %s\n", r_ptr->name);
}
}
else
{
char to_plural[80];
- strcpy(to_plural, (r_name + r_ptr->name));
+ strcpy(to_plural, r_ptr->name);
plural_aux(to_plural);
fprintf(fff, " %d %s\n", This, to_plural);
}
@@ -3873,7 +3688,7 @@ static void do_cmd_knowledge_kill_count(void)
}
fprintf(fff, "----------------------------------------------\n");
- fprintf(fff, " Total: %ld creature%s killed.\n", (long int) Total, (Total == 1 ? "" : "s"));
+ fprintf(fff, " Total: " FMTs32b " creature%s killed.\n", Total, (Total == 1 ? "" : "s"));
/* Close the file */
my_fclose(fff);
@@ -3972,7 +3787,7 @@ static void do_cmd_knowledge_dungeons(void)
/* Describe the recall depth */
fprintf(fff, " %c%s: Level %d (%d')\n",
(p_ptr->recall_dungeon == y) ? '*' : ' ',
- d_name + d_info[y].name,
+ d_info[y].name,
max_dlv[y], 50 * (max_dlv[y]));
}
}
@@ -4024,7 +3839,7 @@ void do_cmd_knowledge_towns(void)
/* Describe the dungeon town */
fprintf(fff, " %s: Level %d (%d')\n",
- d_name + d_ptr->name,
+ d_ptr->name,
d_ptr->t_level[j],
50 * d_ptr->t_level[j]);
}
@@ -4044,7 +3859,7 @@ void do_cmd_knowledge_towns(void)
/*
* List corruptions
*/
-void do_cmd_knowledge_corruptions(void)
+static void do_cmd_knowledge_corruptions(void)
{
FILE *fff;
@@ -4569,57 +4384,58 @@ void do_cmd_time()
* It records all keypresses and then put them in a macro
* Not as powerful as the macro screen, but much easier for newbies
*/
-char *macro_recorder_current = NULL;
+
+std::string *macro_recorder_current = nullptr;
+
void macro_recorder_start()
{
msg_print("Starting macro recording, press this key again to stop. Note that if the action you want to record accepts the @ key, use it; it will remove your the need to inscribe stuff.");
- C_MAKE(macro_recorder_current, 1, char);
- macro_recorder_current[0] = '\0';
+ assert (macro_recorder_current == nullptr);
+ macro_recorder_current = new std::string();
}
void macro_recorder_add(char c)
{
- char *old_macro_recorder_current = macro_recorder_current;
-
- if (macro_recorder_current == NULL) return;
-
- C_MAKE(macro_recorder_current, strlen(macro_recorder_current) + 1 + 1, char);
- sprintf(macro_recorder_current, "%s%c", old_macro_recorder_current, c);
- C_FREE(old_macro_recorder_current, strlen(old_macro_recorder_current) + 1, char);
+ // Gets called unconditionally for all input, so ignore unless
+ // we're actual recording.
+ if (macro_recorder_current) {
+ macro_recorder_current->push_back(c);
+ }
}
void macro_recorder_stop()
{
- char *str, *macro;
- char buf[1024];
+ assert(macro_recorder_current != nullptr);
+
+ // Remove the last key, because it is the key to stop recording
+ macro_recorder_current->pop_back();
- /* Ok we remove the last key, because it is the key to stop recording */
- macro_recorder_current[strlen(macro_recorder_current) - 1] = '\0';
+ // Copy out current macro text.
+ std::string macro(*macro_recorder_current);
- /* Stop the recording */
- macro = macro_recorder_current;
- macro_recorder_current = NULL;
+ // Stop recording.
+ delete macro_recorder_current;
+ macro_recorder_current = nullptr;
/* Add it */
if (get_check("Are you satisfied and want to create the macro? "))
{
+ char buf[1024];
+
prt("Trigger: ", 0, 0);
/* Get a macro trigger */
do_cmd_macro_aux(buf, FALSE);
/* Link the macro */
- macro_add(buf, macro);
+ macro_add(buf, macro.c_str());
/* Prompt */
- C_MAKE(str, (strlen(macro) + 1) * 3, char);
- ascii_to_text(str, macro);
- msg_format("Added a macro '%s'. If you want it to stay permanently, press @ now and dump macros to a file.", str);
- C_FREE(str, (strlen(macro) + 1) * 3, char);
+ std::unique_ptr<char[]> str(new char[(macro.length() + 1) * 3]);
+ str[0] = '\0';
+ ascii_to_text(str.get(), macro.c_str());
+ msg_format("Added a macro '%s'. If you want it to stay permanently, press @ now and dump macros to a file.", str.get());
}
-
- /* Ok now rid of useless stuff */
- C_FREE(macro, strlen(macro) + 1, char);
}
void do_cmd_macro_recorder()
diff --git a/src/cmd4.hpp b/src/cmd4.hpp
new file mode 100644
index 00000000..4470c94f
--- /dev/null
+++ b/src/cmd4.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void macro_recorder_start(void);
+extern void macro_recorder_add(char c);
+extern void macro_recorder_stop(void);
+extern void do_cmd_macro_recorder(void);
+extern void do_cmd_redraw(void);
+extern void do_cmd_change_name(void);
+extern void do_cmd_message_one(void);
+extern void do_cmd_messages(void);
+extern void do_cmd_options(void);
+extern void do_cmd_pref(void);
+extern void do_cmd_macros(void);
+extern void do_cmd_visuals(void);
+extern void do_cmd_colors(void);
+extern void do_cmd_note(void);
+extern void do_cmd_version(void);
+extern void do_cmd_feeling(void);
+extern void do_cmd_load_screen(void);
+extern void do_cmd_save_screen(void);
+extern void do_cmd_knowledge(void);
+extern void do_cmd_checkquest(void);
+extern void do_cmd_change_tactic(int i);
+extern void do_cmd_change_movement(int i);
+extern void do_cmd_time(void);
+extern void do_cmd_options_aux(int page, cptr info, bool_ read_only);
diff --git a/src/cmd5.c b/src/cmd5.cc
index 9571ce99..05483b91 100644
--- a/src/cmd5.c
+++ b/src/cmd5.cc
@@ -1,7 +1,3 @@
-/* File: cmd5.c */
-
-/* Purpose: Class commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,61 +6,80 @@
* included in all such copies.
*/
-
-#include "angband.h"
-
-#include <assert.h>
-
-#include "spell_type.h"
-#include "quark.h"
+#include "cmd5.hpp"
+
+#include "birth.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "lua_bind.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells4.hpp"
+#include "spells5.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "quark.hpp"
+#include "wizard2.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <boost/noncopyable.hpp>
+#include <boost/optional.hpp>
+#include <cassert>
/* Maximum number of tries for teleporting */
#define MAX_TRIES 300
-bool_ is_school_book(object_type *o_ptr)
+static object_filter_t const &is_school_book()
{
- if (o_ptr->tval == TV_BOOK)
- {
- return TRUE;
- }
- else if (o_ptr->tval == TV_DAEMON_BOOK)
- {
- return TRUE;
- }
- else if (o_ptr->tval == TV_INSTRUMENT)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_BOOK),
+ TVal(TV_DAEMON_BOOK),
+ TVal(TV_INSTRUMENT));
+ return instance;
}
/* Does it contains a schooled spell ? */
-static bool_ hook_school_spellable(object_type *o_ptr)
+static object_filter_t const &hook_school_spellable()
{
- if (is_school_book(o_ptr))
- return TRUE;
- else
- {
- u32b f1, f2, f3, f4, f5, esp;
-
- /* Extract object flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 != -1))
- return TRUE;
- }
- return FALSE;
+ using namespace object_filter;
+ static auto has_pval2 =
+ [=](object_type const *o_ptr) -> bool {
+ return (o_ptr->pval2 != -1);
+ };
+ static auto instance = Or(
+ is_school_book(),
+ And(
+ HasFlag5(TR5_SPELL_CONTAIN),
+ has_pval2));
+ return instance;
}
-/* Is it a book */
-bool_ item_tester_hook_browsable(object_type *o_ptr)
+/* Is it a browsable for spells? */
+static object_filter_t const &item_tester_hook_browsable()
{
- if (hook_school_spellable(o_ptr)) return TRUE;
- if (o_ptr->tval >= TV_BOOK) return TRUE;
- return FALSE;
+ using namespace object_filter;
+ static auto instance = Or(
+ hook_school_spellable(),
+ TVal(TV_BOOK));
+ return instance;
}
/*
@@ -95,6 +110,71 @@ bool_ is_magestaff()
return (FALSE);
}
+
+static void browse_school_spell(int book, int spell_idx, object_type *o_ptr)
+{
+ int i;
+ int num = 0, where = 1;
+ int ask;
+ char choice;
+ char out_val[160];
+
+ /* Show choices */
+ window_stuff();
+
+ num = school_book_length(book);
+
+ /* Build a prompt (accept all spells) */
+ strnfmt(out_val, 78, "(Spells %c-%c, ESC=exit) cast which spell? ",
+ I2A(0), I2A(num - 1));
+
+ /* Save the screen */
+ character_icky = TRUE;
+ Term_save();
+
+ /* Display a list of spells */
+ where = print_book(book, spell_idx, o_ptr);
+
+ /* Get a spell from the user */
+ while (get_com(out_val, &choice))
+ {
+ /* Display a list of spells */
+ where = print_book(book, spell_idx, o_ptr);
+
+ /* Note verify */
+ ask = (isupper(choice));
+
+ /* Lowercase */
+ if (ask) choice = tolower(choice);
+
+ /* Extract request */
+ i = (islower(choice) ? A2I(choice) : -1);
+
+ /* Totally Illegal */
+ if ((i < 0) || (i >= num))
+ {
+ bell();
+ continue;
+ }
+
+ /* Restore the screen */
+ Term_load();
+
+ /* Display a list of spells */
+ where = print_book(book, spell_idx, o_ptr);
+ print_spell_desc(spell_x(book, spell_idx, i), where);
+ }
+
+
+ /* Restore the screen */
+ Term_load();
+ character_icky = FALSE;
+
+ /* Show choices */
+ window_stuff();
+}
+
+
/*
* Peruse the spells/prayers in a book
*
@@ -109,35 +189,36 @@ extern void do_cmd_browse_aux(object_type *o_ptr)
u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
- if (is_school_book(o_ptr))
+ if (is_school_book()(o_ptr))
+ {
browse_school_spell(o_ptr->sval, o_ptr->pval, o_ptr);
+ }
else if (f5 & TR5_SPELL_CONTAIN && o_ptr->pval2 != -1)
+ {
browse_school_spell(255, o_ptr->pval2, o_ptr);
+ }
}
void do_cmd_browse(void)
{
- int item;
-
- cptr q, s;
-
- object_type *o_ptr;
-
- /* Restrict choices to "useful" books */
- item_tester_hook = item_tester_hook_browsable;
-
/* Get an item */
- q = "Browse which book? ";
- s = "You have no books that you can read.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Browse which book? ",
+ "You have no books that you can read.",
+ (USE_INVEN | USE_EQUIP | USE_FLOOR),
+ item_tester_hook_browsable()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
do_cmd_browse_aux(o_ptr);
}
-void do_poly_wounds(void)
+static void do_poly_wounds()
{
/* Changed to always provide at least _some_ healing */
s16b wounds = p_ptr->cut;
@@ -265,8 +346,8 @@ void do_poly_self(void)
if (effect_msg[0])
{
msg_format("You turn into a%s %s!",
- ((is_a_vowel(rp_name[race_info[new_race].title])) ? "n" : ""),
- race_info[new_race].title + rp_name);
+ ((is_a_vowel(*race_info[new_race].title)) ? "n" : ""),
+ race_info[new_race].title);
}
else
{
@@ -287,7 +368,7 @@ void do_poly_self(void)
check_experience();
p_ptr->max_plv = p_ptr->lev;
- p_ptr->redraw |= (PR_BASIC);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->update |= (PU_BONUS);
@@ -326,7 +407,7 @@ void do_poly_self(void)
while ((power > rand_int(15)) && (rand_int(3) == 0))
{
power -= 7;
- (void) gain_random_corruption(0);
+ gain_random_corruption();
}
if (power > rand_int(5))
@@ -343,138 +424,24 @@ void do_poly_self(void)
}
}
-
-/*
- * Brand the current weapon
- */
-void brand_weapon(int brand_type)
-{
- object_type *o_ptr;
-
- cptr act = NULL;
-
- char o_name[80];
-
-
- o_ptr = &p_ptr->inventory[INVEN_WIELD];
-
- /*
- * You can never modify artifacts / ego-items
- * You can never modify cursed items
- *
- * TY: You _can_ modify broken items (if you're silly enough)
- */
- if (!o_ptr->k_idx || artifact_p(o_ptr) || ego_item_p(o_ptr) ||
- o_ptr->art_name || cursed_p(o_ptr))
- {
- if (flush_failure) flush();
-
- msg_print("The Branding failed.");
-
- return;
- }
-
-
- /* Save the old name */
- object_desc(o_name, o_ptr, FALSE, 0);
-
- switch (brand_type)
- {
- case 6:
- {
- act = "glows with godly power.";
- o_ptr->name2 = EGO_BLESS_BLADE;
- o_ptr->pval = randint(4);
-
- break;
- }
- case 5:
- {
- act = "seems very powerful.";
- o_ptr->name2 = EGO_EARTHQUAKES;
- o_ptr->pval = randint(3);
-
- break;
- }
- case 4:
- {
- act = "seems very unstable now.";
- o_ptr->name2 = EGO_DRAGON;
- o_ptr->pval = randint(2);
-
- break;
- }
- case 3:
- {
- act = "thirsts for blood!";
- o_ptr->name2 = EGO_VAMPIRIC;
-
- break;
- }
- case 2:
- {
- act = "is coated with poison.";
- o_ptr->name2 = EGO_BRAND_POIS;
-
- break;
- }
- case 1:
- {
- act = "is engulfed in raw chaos!";
- o_ptr->name2 = EGO_CHAOTIC;
-
- break;
- }
- default:
- {
- if (rand_int(100) < 25)
- {
- act = "is covered in a fiery shield!";
- o_ptr->name2 = EGO_BRAND_FIRE;
- }
- else
- {
- act = "glows deep, icy blue!";
- o_ptr->name2 = EGO_BRAND_COLD;
- }
- }
- }
-
- /* Apply the ego */
- apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
- o_ptr->discount = 100;
-
- msg_format("Your %s %s", o_name, act);
-
- enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM);
-}
-
/*
* Fetch an item (teleport it right underneath the caster)
*/
void fetch(int dir, int wgt, bool_ require_los)
{
- int ty, tx, i;
-
- cave_type *c_ptr;
-
- object_type *o_ptr;
-
- char o_name[80];
-
-
/* Check to see if an object is already there */
- if (cave[p_ptr->py][p_ptr->px].o_idx)
+ if (!cave[p_ptr->py][p_ptr->px].o_idxs.empty())
{
msg_print("You can't fetch when you're already standing on something.");
return;
}
/* Use a target */
+ cave_type *c_ptr = nullptr;
if ((dir == 5) && target_okay())
{
- tx = target_col;
- ty = target_row;
+ int tx = target_col;
+ int ty = target_row;
if (distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE)
{
@@ -484,7 +451,7 @@ void fetch(int dir, int wgt, bool_ require_los)
c_ptr = &cave[ty][tx];
- if (!c_ptr->o_idx)
+ if (c_ptr->o_idxs.empty())
{
msg_print("There is no object at this place.");
return;
@@ -499,8 +466,8 @@ void fetch(int dir, int wgt, bool_ require_los)
else
{
/* Use a direction */
- ty = p_ptr->py; /* Where to drop the item */
- tx = p_ptr->px;
+ int ty = p_ptr->py; /* Where to drop the item */
+ int tx = p_ptr->px;
while (1)
{
@@ -511,12 +478,17 @@ void fetch(int dir, int wgt, bool_ require_los)
if ((distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) ||
!cave_floor_bold(ty, tx)) return;
- if (c_ptr->o_idx) break;
+ if (!c_ptr->o_idxs.empty()) break;
}
}
- o_ptr = &o_list[c_ptr->o_idx];
+ assert(c_ptr != nullptr);
+ assert(!c_ptr->o_idxs.empty());
+
+ /* Pick object from the list */
+ auto o_idx = c_ptr->o_idxs.front();
+ object_type *o_ptr = &o_list[o_idx];
if (o_ptr->weight > wgt)
{
/* Too heavy to 'fetch' */
@@ -524,13 +496,16 @@ void fetch(int dir, int wgt, bool_ require_los)
return;
}
- i = c_ptr->o_idx;
- c_ptr->o_idx = o_ptr->next_o_idx;
- cave[p_ptr->py][p_ptr->px].o_idx = i; /* 'move' it */
- o_ptr->next_o_idx = 0;
+ /* Move the object between the lists */
+ c_ptr->o_idxs.erase(c_ptr->o_idxs.begin()); // Remove
+ cave[p_ptr->py][p_ptr->px].o_idxs.push_back(o_idx); // Add
+
+ /* Update object's location */
o_ptr->iy = p_ptr->py;
o_ptr->ix = p_ptr->px;
+ /* Feedback */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 0);
msg_format("%^s flies through the air to your feet.", o_name);
@@ -582,225 +557,6 @@ void shriek_effect()
}
}
-
-/*
- * Like all the random effect codes, this is *ugly*,
- * and there is not a single line of comment, so I can't tell
- * some fall throughs are really intended. Well, I know it's
- * intended to be bizarre :) -- pelpel
- */
-void wild_magic(int spell)
-{
- int counter = 0;
- int type = SUMMON_BIZARRE1 - 1 + randint(6);
-
- if (type < SUMMON_BIZARRE1) type = SUMMON_BIZARRE1;
- else if (type > SUMMON_BIZARRE6) type = SUMMON_BIZARRE6;
-
- switch (randint(spell) + randint(8) + 1)
- {
- case 1:
- case 2:
- case 3:
- {
- teleport_player(10);
-
- break;
- }
-
- case 4:
- case 5:
- case 6:
- {
- teleport_player(100);
-
- break;
- }
-
- case 7:
- case 8:
- {
- teleport_player(200);
-
- break;
- }
-
- case 9:
- case 10:
- case 11:
- {
- unlite_area(10, 3);
-
- break;
- }
-
- case 12:
- case 13:
- case 14:
- {
- lite_area(damroll(2, 3), 2);
-
- break;
- }
-
- case 15:
- {
- destroy_doors_touch();
-
- break;
- }
-
- case 16:
- case 17:
- {
- wall_breaker();
-
- /* I don't think this is a fall through -- pelpel */
- break;
- }
-
- case 18:
- {
- sleep_monsters_touch();
-
- break;
- }
-
- case 19:
- case 20:
- {
- trap_creation();
-
- break;
- }
-
- case 21:
- case 22:
- {
- door_creation();
-
- break;
- }
-
- case 23:
- case 24:
- case 25:
- {
- aggravate_monsters(1);
-
- break;
- }
-
- case 26:
- {
- /* Prevent destruction of quest levels and town */
- if (!is_quest(dun_level) && dun_level)
- earthquake(p_ptr->py, p_ptr->px, 5);
-
- break;
- }
-
- case 27:
- case 28:
- {
- break;
- }
-
- case 29:
- case 30:
- {
- apply_disenchant(0);
-
- break;
- }
-
- case 31:
- {
- lose_all_info();
-
- break;
- }
-
- case 32:
- {
- fire_ball(GF_CHAOS, 0, spell + 5, 1 + (spell / 10));
-
- break;
- }
-
- case 33:
- {
- wall_stone(p_ptr->py, p_ptr->px);
-
- break;
- }
-
- case 34:
- case 35:
- {
- while (counter++ < 8)
- {
- (void) summon_specific(p_ptr->py, p_ptr->px, (dun_level * 3) / 2, type);
- }
-
- break;
- }
-
- case 36:
- case 37:
- {
- activate_hi_summon();
-
- break;
- }
-
- case 38:
- {
- summon_cyber();
-
- /* I don't think this is a fall through -- pelpel */
- break;
- }
-
- default:
- {
- activate_ty_curse();
- }
- }
-
- return;
-}
-
-
-/*
- * Hack -- Determine if the player is wearing an artefact ring
- * specified by art_type, that should be an index into a_info
- */
-bool_ check_ring(int art_type)
-{
- int i;
-
-
- /* We are only interested in ring slots */
- i = INVEN_RING;
-
- /* Scan the list of rings until we reach the end */
- while (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_RING)
- {
- /* Found the ring we were looking for */
- if (p_ptr->inventory[i].k_idx && (p_ptr->inventory[i].name1 == art_type))
- {
- return (TRUE);
- }
-
- /* Next item */
- i++;
- }
-
- /* Found nothing */
- return (FALSE);
-}
-
/*
* Return the symbiote's name or description.
*/
@@ -822,7 +578,7 @@ cptr symbiote_name(bool_ capitalize)
if (r_ptr->flags1 & RF1_UNIQUE)
{
/* Unique monster; no preceding "your", and ignore our name. */
- strncpy(buf, r_name + r_ptr->name, sizeof(buf));
+ strncpy(buf, r_ptr->name, sizeof(buf));
}
else if (o_ptr->note &&
(s = strstr(quark_str(o_ptr->note), "#named ")) != NULL)
@@ -834,7 +590,7 @@ cptr symbiote_name(bool_ capitalize)
{
/* No special cases, just return "Your <monster type>". */
strcpy(buf, "your ");
- strncpy(buf + 5, r_name + r_ptr->name, sizeof(buf) - 5);
+ strncpy(buf + 5, r_ptr->name, sizeof(buf) - 5);
}
}
@@ -2057,7 +1813,7 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2073,74 +1829,82 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost
* Find a spell in any books/objects
*/
static int hack_force_spell = -1;
-static object_type *hack_force_spell_obj = NULL;
-bool_ get_item_hook_find_spell(int *item)
+static s32b hack_force_spell_pval = -1;
+
+boost::optional<int> get_item_hook_find_spell(object_filter_t const &)
{
- int i, spell;
char buf[80];
-
strcpy(buf, "Manathrust");
if (!get_string("Spell name? ", buf, 79))
- return FALSE;
+ {
+ return boost::none;
+ }
- spell = find_spell(buf);
- if (spell == -1) return FALSE;
+ int const spell = find_spell(buf);
+ if (spell == -1)
+ {
+ return boost::none;
+ }
- for (i = 0; i < INVEN_TOTAL; i++)
+ for (int i = 0; i < INVEN_TOTAL; i++)
{
object_type *o_ptr = &p_ptr->inventory[i];
- u32b f1, f2, f3, f4, f5, esp;
- /* Must we wield it ? */
+ /* Extract object flags */
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
- if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) continue;
- /* Is it a non-book? */
- if (!is_school_book(o_ptr))
+ /* Must we wield it to cast from it? */
+ if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST))
{
- u32b f1, f2, f3, f4, f5, esp;
-
- /* Extract object flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ continue;
+ }
+ /* Is it a non-book? */
+ if (!is_school_book()(o_ptr))
+ {
+ /* Does it contain the appropriate spell? */
if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == spell))
{
- *item = i;
hack_force_spell = spell;
- hack_force_spell_obj = o_ptr;
- return TRUE;
+ hack_force_spell_pval = o_ptr->pval;
+ return i;
}
}
/* A random book ? */
else if (school_book_contains_spell(o_ptr->sval, spell))
{
- *item = i;
hack_force_spell = spell;
- hack_force_spell_obj = o_ptr;
- return TRUE;
+ hack_force_spell_pval = o_ptr->pval;
+ return i;
}
}
- return FALSE;
+
+ return boost::none;
}
/*
* Is the spell castable?
*/
-bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr)
+bool_ is_ok_spell(s32b spell_idx, s32b pval)
{
spell_type *spell = spell_at(spell_idx);
- assert(o_ptr != NULL);
- if (get_level(spell_idx, 50, 0) == 0)
+ // Calculate availability based on caster's skill level.
+ s32b level;
+ bool_ na;
+ get_level_school(spell, 50, 0, &level, &na);
+ if (na || (level == 0))
{
return FALSE;
}
-
- if (o_ptr->pval < spell_type_minimum_pval(spell))
+ // Are we permitted to cast based on item pval? Only music
+ // spells have non-zero minimum PVAL.
+ if (pval < spell_type_minimum_pval(spell))
{
return FALSE;
}
-
+ // OK, we're permitted to cast it.
return TRUE;
}
@@ -2157,24 +1921,31 @@ s32b get_school_spell(cptr do_what, s16b force_book)
int ask;
bool_ flag;
char out_val[160];
- char buf2[40];
- char buf3[40];
object_type *o_ptr, forge;
int tmp;
int sval, pval;
u32b f1, f2, f3, f4, f5, esp;
hack_force_spell = -1;
- hack_force_spell_obj = NULL;
+ hack_force_spell_pval = -1;
/* Ok do we need to ask for a book ? */
if (!force_book)
{
- get_item_extra_hook = get_item_hook_find_spell;
- item_tester_hook = hook_school_spellable;
+ char buf2[40];
+ char buf3[40];
sprintf(buf2, "You have no book to %s from", do_what);
sprintf(buf3, "%s from which book?", do_what);
- if (!get_item(&item, buf3, buf2, USE_INVEN | USE_EQUIP | USE_EXTRA )) return -1;
+
+ if (!get_item(&item,
+ buf3,
+ buf2,
+ USE_INVEN | USE_EQUIP,
+ hook_school_spellable(),
+ get_item_hook_find_spell))
+ {
+ return -1;
+ }
/* Get the item */
o_ptr = get_object(item);
@@ -2211,7 +1982,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
spell = -1;
/* Is it a random book, or something else ? */
- if (is_school_book(o_ptr))
+ if (is_school_book()(o_ptr))
{
sval = o_ptr->sval;
pval = o_ptr->pval;
@@ -2287,7 +2058,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
spell = spell_x(sval, pval, i);
/* Do we need to do some pre test */
- ok = is_ok_spell(spell, o_ptr);
+ ok = is_ok_spell(spell, o_ptr->pval);
/* Require "okay" spells */
if (!ok)
@@ -2308,7 +2079,7 @@ s32b get_school_spell(cptr do_what, s16b force_book)
bool_ ok;
/* Require "okay" spells */
- ok = is_ok_spell(hack_force_spell, hack_force_spell_obj);
+ ok = is_ok_spell(hack_force_spell, hack_force_spell_pval);
if (ok)
{
flag = TRUE;
@@ -2367,80 +2138,13 @@ void cast_school_spell()
}
}
-void browse_school_spell(int book, int pval, object_type *o_ptr)
-{
- int i;
- int num = 0, where = 1;
- int ask;
- char choice;
- char out_val[160];
-
- /* Show choices */
- window_stuff();
-
- num = school_book_length(book);
-
- /* Build a prompt (accept all spells) */
- strnfmt(out_val, 78, "(Spells %c-%c, ESC=exit) cast which spell? ",
- I2A(0), I2A(num - 1));
-
- /* Save the screen */
- character_icky = TRUE;
- Term_save();
-
- /* Display a list of spells */
- where = print_book(book, pval, o_ptr);
-
- /* Get a spell from the user */
- while (get_com(out_val, &choice))
- {
- /* Display a list of spells */
- where = print_book(book, pval, o_ptr);
-
- /* Note verify */
- ask = (isupper(choice));
-
- /* Lowercase */
- if (ask) choice = tolower(choice);
-
- /* Extract request */
- i = (islower(choice) ? A2I(choice) : -1);
-
- /* Totally Illegal */
- if ((i < 0) || (i >= num))
- {
- bell();
- continue;
- }
-
- /* Restore the screen */
- Term_load();
-
- /* Display a list of spells */
- where = print_book(book, pval, o_ptr);
- print_spell_desc(spell_x(book, pval, i), where);
- }
-
-
- /* Restore the screen */
- Term_load();
- character_icky = FALSE;
-
- /* Show choices */
- window_stuff();
-}
-
/* Can it contains a schooled spell ? */
-static bool_ hook_school_can_spellable(object_type *o_ptr)
+static bool hook_school_can_spellable(object_type const *o_ptr)
{
u32b f1, f2, f3, f4, f5, esp;
-
- /* Extract object flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
- if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1))
- return TRUE;
- return FALSE;
+ return ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1));
}
/*
@@ -2450,7 +2154,6 @@ void do_cmd_copy_spell()
{
int spell = get_school_spell("copy", 0);
int item;
- object_type *o_ptr;
if (spell == -1) return;
@@ -2461,9 +2164,12 @@ void do_cmd_copy_spell()
return;
}
- item_tester_hook = hook_school_can_spellable;
- if (!get_item(&item, "Copy to which object? ", "You have no object to copy to.", (USE_INVEN | USE_EQUIP))) return;
- o_ptr = get_object(item);
+ if (!get_item(&item,
+ "Copy to which object? ",
+ "You have no object to copy to.",
+ (USE_INVEN | USE_EQUIP),
+ hook_school_can_spellable)) return;
+ object_type *o_ptr = get_object(item);
msg_print("You copy the spell!");
o_ptr->pval2 = spell;
diff --git a/src/cmd5.hpp b/src/cmd5.hpp
new file mode 100644
index 00000000..1b3b062a
--- /dev/null
+++ b/src/cmd5.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+
+extern bool_ is_magestaff(void);
+extern void do_cmd_browse_aux(object_type *o_ptr);
+extern void do_cmd_browse(void);
+extern void fetch(int dir, int wgt, bool_ require_los);
+extern void do_poly_self(void);
+extern cptr symbiote_name(bool_ capitalize);
+extern int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost);
+extern bool_ is_ok_spell(s32b spell_idx, s32b pval);
+extern s32b get_school_spell(cptr do_what, s16b force_book);
+extern void do_cmd_copy_spell(void);
+extern void cast_school_spell(void);
diff --git a/src/cmd6.c b/src/cmd6.cc
index bfe364e5..97ee2cb0 100644
--- a/src/cmd6.c
+++ b/src/cmd6.cc
@@ -1,7 +1,3 @@
-/* File: cmd6.c */
-
-/* Purpose: Object commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,52 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "spell_type.h"
+#include "cmd6.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd7.hpp"
+#include "corrupt.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "files.hpp"
+#include "hook_eat_in.hpp"
+#include "hook_eat_out.hpp"
+#include "hooks.hpp"
+#include "lua_bind.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "randart.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells5.hpp"
+#include "stats.hpp"
+#include "store.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.h"
+#include "variable.hpp"
+#include "wild.hpp"
+#include "wizard2.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <cassert>
+
+using boost::algorithm::iequals;
/*
* Forward declare
@@ -23,31 +62,41 @@ static bool_ activate_spell(object_type * o_ptr, byte choice);
/*
* General function to find an item by its name
*/
-cptr get_item_hook_find_obj_what;
-bool_ get_item_hook_find_obj(int *item)
+static select_by_name_t select_object_by_name(std::string const &prompt)
{
- int i;
- char buf[80];
- char buf2[100];
-
- strcpy(buf, "");
- if (!get_string(get_item_hook_find_obj_what, buf, 79))
- return FALSE;
-
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- if (!item_tester_okay(o_ptr)) continue;
-
- object_desc(buf2, o_ptr, -1, 0);
- if (!strcmp(buf, buf2))
+ return [=](object_filter_t const &filter) -> boost::optional<int> {
+ // Ask for the name of the object we want to select
+ char buf[80] = "";
+ if (!get_string(prompt.c_str(), buf, 79))
{
- *item = i;
- return TRUE;
+ return boost::none;
}
- }
- return FALSE;
+ // Named objects must be in the inventory
+ for (size_t i = 0; i < INVEN_TOTAL; i++)
+ {
+ object_type *o_ptr = get_object(i);
+ // Must have an actual item in the slot
+ if (!o_ptr->k_idx)
+ {
+ continue;
+ }
+ // Must pass the filter
+ if (!filter(o_ptr))
+ {
+ continue;
+ }
+ // Check against the name of the object
+ // ignoring case.
+ char buf2[100];
+ object_desc(buf2, o_ptr, -1, 0);
+ if (iequals(buf, buf2))
+ {
+ return i;
+ }
+ }
+ // No match
+ return boost::none;
+ };
}
@@ -908,13 +957,14 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/*
* Hook to determine if an object is eatable
*/
-static bool_ item_tester_hook_eatable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_eatable()
{
- /* Foods and, well, corpses are edible */
- if ((o_ptr->tval == TV_FOOD) || (o_ptr->tval == TV_CORPSE)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_FOOD),
+ TVal(TV_CORPSE));
+ return instance;
}
@@ -923,32 +973,28 @@ static bool_ item_tester_hook_eatable(object_type *o_ptr)
*/
void do_cmd_eat_food(void)
{
- int item, ident, lev, fval = 0;
+ int ident, lev, fval = 0;
- object_type *o_ptr;
object_type *q_ptr, forge;
monster_race *r_ptr;
- cptr q, s;
-
bool_ destroy = TRUE;
-
- /* Restrict choices to food */
- item_tester_hook = item_tester_hook_eatable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Food full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Eat which item? ";
- s = "You have nothing to eat.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Eat which item? ",
+ "You have nothing to eat.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_eatable(),
+ select_object_by_name("Food full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Sound */
sound(SOUND_EAT);
@@ -966,12 +1012,7 @@ void do_cmd_eat_food(void)
/* Scripted foods */
hook_eat_in in = { o_ptr };
hook_eat_out out = { FALSE };
-
- if (process_hooks_ret(HOOK_EAT, "d", "(O)", o_ptr))
- {
- ident = process_hooks_return[0].num;
- }
- else if (process_hooks_new(HOOK_EAT, &in, &out))
+ if (process_hooks_new(HOOK_EAT, &in, &out))
{
ident = out.ident;
}
@@ -1254,7 +1295,7 @@ void do_cmd_eat_food(void)
/* 2% chance of getting the mold power */
if (magik(2))
{
- ADD_POWER(p_ptr->powers_mod, PWR_GROW_MOLD);
+ p_ptr->powers_mod[PWR_GROW_MOLD] = TRUE;
p_ptr->update |= PU_POWERS;
}
@@ -1449,7 +1490,7 @@ void do_cmd_eat_food(void)
/* Food can feed the player, in a different ways */
/* Vampires */
- if ((PRACE_FLAG(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")))
+ if ((race_flags1_p(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")))
{
/* Reduced nutritional benefit */
/* (void)set_food(p_ptr->food + (fval / 10)); -- No more */
@@ -1462,9 +1503,9 @@ void do_cmd_eat_food(void)
}
}
- else if (PRACE_FLAG(PR1_NO_FOOD))
+ else if (race_flags1_p(PR1_NO_FOOD))
{
- if (PRACE_FLAG(PR1_UNDEAD))
+ if (race_flags1_p(PR1_UNDEAD))
{
msg_print("The food of mortals is poor sustenance for you.");
}
@@ -1497,29 +1538,20 @@ void do_cmd_cut_corpse(void)
{
int item, meat = 0, not_meat = 0;
- object_type *o_ptr;
-
- object_type *i_ptr;
-
- object_type object_type_body;
-
- monster_race *r_ptr;
-
- cptr q, s;
-
-
- /* Restrict choices to corpses */
- item_tester_tval = TV_CORPSE;
-
/* Get an item */
- q = "Hack up which corpse? ";
- s = "You have no corpses.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Hack up which corpse? ",
+ "You have no corpses.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_CORPSE)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
- r_ptr = &r_info[o_ptr->pval2];
+ monster_race *r_ptr = &r_info[o_ptr->pval2];
if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_HEAD))
{
@@ -1573,7 +1605,8 @@ void do_cmd_cut_corpse(void)
corpse_effect(o_ptr, TRUE);
/* Get local object */
- i_ptr = &object_type_body;
+ object_type object_type_body;
+ object_type *i_ptr = &object_type_body;
/* Make some meat */
object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_MEAT));
@@ -1604,32 +1637,27 @@ void do_cmd_cure_meat(void)
{
int item, num, cure;
- object_type *o_ptr;
-
object_type *i_ptr;
- cptr q, s;
-
-
- /* Restrict choices to corpses */
- item_tester_tval = TV_CORPSE;
- item_tester_hook = item_tester_hook_eatable;
-
/* Get some meat */
- q = "Cure which meat? ";
- s = "You have no meat to cure.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Cure which meat? ",
+ "You have no meat to cure.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::And(item_tester_hook_eatable(), object_filter::TVal(TV_CORPSE))))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
- /* Restrict choices to potions */
- item_tester_tval = TV_POTION;
+ object_type *o_ptr = get_object(item);
/* Get a potion */
- q = "Use which potion? ";
- s = "You have no potions to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Use which potion? ",
+ "You have no potions to use.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_POTION))) return;
/* Get the item */
i_ptr = get_object(item);
@@ -1652,8 +1680,8 @@ void do_cmd_cure_meat(void)
/* Take a turn */
energy_use = 100;
- q = "You soak the meat.";
- s = "You soak the meat.";
+ cptr q = "You soak the meat.";
+ cptr s = "You soak the meat.";
switch (i_ptr->sval)
{
@@ -1715,8 +1743,14 @@ void do_cmd_cure_meat(void)
}
/* Message */
- if (object_known_p(i_ptr)) msg_print(q);
- else msg_print(s);
+ if (object_known_p(i_ptr))
+ {
+ msg_print(q);
+ }
+ else
+ {
+ msg_print(s);
+ }
/* The meat is already spoiling */
if (((o_ptr->sval == SV_CORPSE_MEAT) && (o_ptr->weight > o_ptr->pval)) ||
@@ -1738,12 +1772,13 @@ void do_cmd_cure_meat(void)
/*
* Hook to determine if an object is quaffable
*/
-static bool_ item_tester_hook_quaffable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_quaffable()
{
- if ((o_ptr->tval == TV_POTION) || (o_ptr->tval == TV_POTION2)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_POTION),
+ TVal(TV_POTION2));
+ return instance;
}
@@ -2126,7 +2161,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
p_ptr->csp = p_ptr->msp;
p_ptr->csp_frac = 0;
msg_print("Your feel your head clear.");
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_PLAYER);
ident = TRUE;
}
@@ -2345,7 +2380,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
potions of corruption. */
if (game_module_idx == MODULE_THEME)
{
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
msg_print("Your quaffing of this potion pleases Melkor!");
set_grace(p_ptr->grace + 2);
@@ -2400,7 +2435,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
set_mimic(time, pval2, (p_ptr->lev * 2) / 3);
/* Redraw title */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -2455,29 +2490,24 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
*/
void do_cmd_quaff_potion(void)
{
- int item, ident, lev;
-
- object_type *o_ptr;
+ int ident, lev;
object_type *q_ptr, forge;
- cptr q, s;
-
-
- /* Restrict choices to potions */
- item_tester_hook = item_tester_hook_quaffable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Potion full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Quaff which potion? ";
- s = "You have no potions to quaff.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Quaff which potion? ",
+ "You have no potions to quaff.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_quaffable(),
+ select_object_by_name("Potion full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Sound */
@@ -2548,6 +2578,92 @@ void do_cmd_quaff_potion(void)
/*
+ * Fill an empty bottle
+ */
+static void do_cmd_fill_bottle(void)
+{
+ cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px];
+
+ int tval, sval, item, amt = 1;
+
+ object_type *q_ptr, forge;
+
+ /* Is the fountain empty? */
+ /*
+ * This check is redundant as it is done in do_cmd_drink_fountain()
+ * but I keep this because someone might want to call this directly.
+ * -- Kusunose
+ */
+ if (c_ptr->special2 <= 0)
+ {
+ msg_print("The fountain has dried up.");
+ return;
+ }
+
+ /* Determine the tval/sval of the potion */
+ if (c_ptr->special <= SV_POTION_LAST)
+ {
+ tval = TV_POTION;
+ sval = c_ptr->special;
+ }
+ else
+ {
+ tval = TV_POTION2;
+ sval = c_ptr->special - SV_POTION_LAST;
+ }
+
+ /* Get an item */
+ if (!get_item(&item,
+ "Fill which bottle? ",
+ "You have no bottles to fill.",
+ (USE_INVEN),
+ object_filter::TVal(TV_BOTTLE)))
+ {
+ return;
+ }
+
+ object_type *o_ptr = &p_ptr->inventory[item];
+
+ /* Find out how many the player wants */
+ if (o_ptr->number > 1)
+ {
+ /* Get a quantity */
+ amt = get_quantity(NULL, o_ptr->number);
+
+ /* Allow user abort */
+ if (amt <= 0) return;
+ }
+
+ if (amt > c_ptr->special2) amt = c_ptr->special2;
+
+ /* Destroy bottles */
+ inc_stack_size(item, -amt);
+
+ /* Create the potion */
+ q_ptr = &forge;
+ object_prep(q_ptr, lookup_kind(tval, sval));
+ q_ptr->number = amt;
+
+ if (c_ptr->info & CAVE_IDNT)
+ {
+ object_aware(q_ptr);
+ object_known(q_ptr);
+ }
+
+ inven_carry(q_ptr, TRUE);
+
+ c_ptr->special2 -= amt;
+
+ if (c_ptr->special2 <= 0)
+ {
+ cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN);
+ }
+
+ return;
+}
+
+
+/*
* Drink from a fountain
*/
void do_cmd_drink_fountain(void)
@@ -2623,91 +2739,6 @@ void do_cmd_drink_fountain(void)
/*
- * Fill an empty bottle
- */
-void do_cmd_fill_bottle(void)
-{
- cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px];
-
- int tval, sval, item, amt = 1;
-
- object_type *q_ptr, *o_ptr, forge;
-
- cptr q, s;
-
- /* Is the fountain empty? */
- /*
- * This check is redundant as it is done in do_cmd_drink_fountain()
- * but I keep this because someone might want to call this directly.
- * -- Kusunose
- */
- if (c_ptr->special2 <= 0)
- {
- msg_print("The fountain has dried up.");
- return;
- }
-
- /* Determine the tval/sval of the potion */
- if (c_ptr->special <= SV_POTION_LAST)
- {
- tval = TV_POTION;
- sval = c_ptr->special;
- }
- else
- {
- tval = TV_POTION2;
- sval = c_ptr->special - SV_POTION_LAST;
- }
-
- /* Restrict choices to bottles */
- item_tester_tval = TV_BOTTLE;
-
- /* Get an item */
- q = "Fill which bottle? ";
- s = "You have no bottles to fill.";
- if (!get_item(&item, q, s, (USE_INVEN))) return;
- o_ptr = &p_ptr->inventory[item];
-
- /* Find out how many the player wants */
- if (o_ptr->number > 1)
- {
- /* Get a quantity */
- amt = get_quantity(NULL, o_ptr->number);
-
- /* Allow user abort */
- if (amt <= 0) return;
- }
-
- if (amt > c_ptr->special2) amt = c_ptr->special2;
-
- /* Destroy bottles */
- inc_stack_size(item, -amt);
-
- /* Create the potion */
- q_ptr = &forge;
- object_prep(q_ptr, lookup_kind(tval, sval));
- q_ptr->number = amt;
-
- if (c_ptr->info & CAVE_IDNT)
- {
- object_aware(q_ptr);
- object_known(q_ptr);
- }
-
- inven_carry(q_ptr, TRUE);
-
- c_ptr->special2 -= amt;
-
- if (c_ptr->special2 <= 0)
- {
- cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN);
- }
-
- return;
-}
-
-
-/*
* Curse the players armor
*/
bool_ curse_armor(void)
@@ -2842,12 +2873,14 @@ bool_ curse_weapon(void)
/*
* Hook to determine if an object is readable
*/
-static bool_ item_tester_hook_readable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_readable()
{
- if ((o_ptr->tval == TV_SCROLL) || (o_ptr->tval == TV_PARCHMENT)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_SCROLL),
+ TVal(TV_PARCHMENT));
+ return instance;
}
@@ -2860,15 +2893,6 @@ static bool_ item_tester_hook_readable(object_type *o_ptr)
*/
void do_cmd_read_scroll(void)
{
- int item, k, used_up, ident, lev;
-
- object_type *o_ptr;
-
- object_type *q_ptr, forge;
-
- cptr q, s;
-
-
/* Check some conditions */
if (p_ptr->blind)
{
@@ -2888,33 +2912,32 @@ void do_cmd_read_scroll(void)
return;
}
-
- /* Restrict choices to scrolls */
- item_tester_hook = item_tester_hook_readable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Scroll full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Read which scroll? ";
- s = "You have no scrolls to read.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Read which scroll? ",
+ "You have no scrolls to read.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_readable(),
+ select_object_by_name("Scroll full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a turn */
energy_use = 100;
/* Not identified yet */
- ident = FALSE;
+ int ident = FALSE;
/* Object level */
- lev = k_info[o_ptr->k_idx].level;
+ int lev = k_info[o_ptr->k_idx].level;
/* Assume the scroll will get used up */
- used_up = TRUE;
+ int used_up = TRUE;
/* Corruption */
if (player_has_corruption(CORRUPT_BALROG_AURA) && magik(5))
@@ -2932,13 +2955,11 @@ void do_cmd_read_scroll(void)
{
case SV_SCROLL_MASS_RESURECTION:
{
- int k;
-
ident = TRUE;
msg_print("You feel the souls of the dead coming back "
"from the Halls of Mandos.");
- for (k = 0; k < max_r_idx; k++)
+ for (int k = 0; k < max_r_idx; k++)
{
monster_race *r_ptr = &r_info[k];
@@ -2979,7 +3000,7 @@ void do_cmd_read_scroll(void)
}
msg_format("Recall reset to %s at level %d.",
- d_info[p_ptr->recall_dungeon].name + d_name,
+ d_info[p_ptr->recall_dungeon].name,
max_dlv[p_ptr->recall_dungeon]);
ident = TRUE;
@@ -3055,7 +3076,7 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_SUMMON_MONSTER:
{
- for (k = 0; k < randint(3); k++)
+ for (int k = 0; k < randint(3); k++)
{
if (summon_specific(p_ptr->py, p_ptr->px, dun_level, 0))
{
@@ -3078,7 +3099,7 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_SUMMON_UNDEAD:
{
- for (k = 0; k < randint(3); k++)
+ for (int k = 0; k < randint(3); k++)
{
if (summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD))
{
@@ -3335,8 +3356,11 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_PROTECTION_FROM_EVIL:
{
- k = 3 * p_ptr->lev;
- if (set_protevil(p_ptr->protevil + randint(25) + k)) ident = TRUE;
+ int k = 3 * p_ptr->lev;
+ if (set_protevil(p_ptr->protevil + randint(25) + k))
+ {
+ ident = TRUE;
+ }
break;
}
@@ -3362,7 +3386,7 @@ void do_cmd_read_scroll(void)
/* Prevent destruction of quest levels and town */
if (!is_quest(dun_level) && dun_level)
{
- destroy_area(p_ptr->py, p_ptr->px, 15, TRUE, FALSE);
+ destroy_area(p_ptr->py, p_ptr->px, 15);
}
else
{
@@ -3576,7 +3600,7 @@ void do_cmd_read_scroll(void)
screen_save();
/* Get the filename */
- q = format("book-%d.txt", o_ptr->sval);
+ cptr q = format("book-%d.txt", o_ptr->sval);
/* Peruse the help file */
(void)show_file(q, NULL, 0, 0);
@@ -3619,10 +3643,13 @@ void do_cmd_read_scroll(void)
/* Destroy scroll */
inc_stack_size(item, -1);
+ /* Alchemists end up with a "drained" scroll instead */
if (get_skill(SKILL_ALCHEMY))
{
if (item >= 0)
{
+ object_type *q_ptr, forge;
+
q_ptr = &forge;
object_prep(q_ptr, lookup_kind(TV_SCROLL, SV_SCROLL_NOTHING));
object_aware(q_ptr);
@@ -3642,7 +3669,9 @@ void set_stick_mode(object_type *o_ptr)
{
s32b bonus = o_ptr->pval3 & 0xFFFF;
s32b max = o_ptr->pval3 >> 16;
-
+ // Ensure that we're not assuming "reentrancy".
+ assert(get_level_use_stick < 0);
+ // Set up the casting mode
get_level_use_stick = bonus;
get_level_max_stick = max;
}
@@ -3650,6 +3679,9 @@ void set_stick_mode(object_type *o_ptr)
/* Remove 'stick mode' */
void unset_stick_mode()
{
+ // Ensure that we're not assuming "reentrancy".
+ assert(get_level_use_stick > 0);
+ // Unset the casting mode
get_level_use_stick = -1;
get_level_max_stick = -1;
}
@@ -3658,15 +3690,17 @@ void unset_stick_mode()
/*
* Activate a device
*/
-static void activate_stick(s16b s, bool_ *obvious, bool_ *use_charge)
+static void activate_stick(object_type *o_ptr, bool_ *obvious, bool_ *use_charge)
{
- spell_type *spell = spell_at(s);
+ spell_type *spell = spell_at(o_ptr->pval2);
casting_result ret;
assert(obvious != NULL);
assert(use_charge != NULL);
- ret = spell_type_produce_effect(spell, -1);
+ set_stick_mode(o_ptr);
+ ret = spell_type_produce_effect(spell);
+ unset_stick_mode();
switch (ret)
{
@@ -3697,16 +3731,10 @@ static void activate_stick(s16b s, bool_ *obvious, bool_ *use_charge)
*/
void do_cmd_use_staff(void)
{
- int item, ident, chance;
-
bool_ obvious, use_charge;
- object_type *o_ptr;
-
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
/* No magic */
if (p_ptr->antimagic)
{
@@ -3714,20 +3742,20 @@ void do_cmd_use_staff(void)
return;
}
- /* Restrict choices to wands */
- item_tester_tval = TV_STAFF;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Staff full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Use which staff? ";
- s = "You have no staff to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Use which staff? ",
+ "You have no staff to use.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_STAFF),
+ select_object_by_name("Staff full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Mega-Hack -- refuse to use a pile from the ground */
if ((item < 0) && (o_ptr->number > 1))
@@ -3736,17 +3764,21 @@ void do_cmd_use_staff(void)
return;
}
- /* Enter device mode */
- set_stick_mode(o_ptr);
-
/* Take a turn */
energy_use = 100;
- /* Not identified yet */
- ident = FALSE;
+ /* Enter device mode */
+ set_stick_mode(o_ptr);
/* get the chance */
- chance = spell_chance(o_ptr->pval2);
+ int chance;
+ {
+ auto spell = spell_at(o_ptr->pval2);
+ chance = spell_chance_device(spell);
+ }
+
+ /* Leave device mode */
+ unset_stick_mode();
/* Extract object flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -3769,9 +3801,6 @@ void do_cmd_use_staff(void)
if (flush_failure) flush();
msg_print("You failed to use the staff properly.");
sound(SOUND_FAIL);
-
- /* Leave device mode */
- unset_stick_mode();
return;
}
@@ -3781,9 +3810,6 @@ void do_cmd_use_staff(void)
if (flush_failure) flush();
msg_print("The staff has no charges left.");
o_ptr->ident |= (IDENT_EMPTY);
-
- /* Leave device mode */
- unset_stick_mode();
return;
}
@@ -3791,9 +3817,8 @@ void do_cmd_use_staff(void)
/* Sound */
sound(SOUND_ZAP);
-
/* Analyze the staff */
- activate_stick(o_ptr->pval2, &obvious, &use_charge);
+ activate_stick(o_ptr, &obvious, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
@@ -3809,9 +3834,6 @@ void do_cmd_use_staff(void)
/* Hack -- some uses are "free" */
if (!use_charge)
{
- /* Leave device mode */
- unset_stick_mode();
-
return;
}
@@ -3861,9 +3883,6 @@ void do_cmd_use_staff(void)
{
floor_item_charges(0 - item);
}
-
- /* Leave device mode */
- unset_stick_mode();
}
@@ -3891,12 +3910,6 @@ void do_cmd_aim_wand(void)
{
bool_ obvious, use_charge;
- int item, ident, chance;
-
- object_type *o_ptr;
-
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
@@ -3907,21 +3920,20 @@ void do_cmd_aim_wand(void)
return;
}
- /* Restrict choices to wands */
- item_tester_tval = TV_WAND;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Wand full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Aim which wand? ";
- s = "You have no wand to aim.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Aim which wand? ",
+ "You have no wand to aim.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_WAND),
+ select_object_by_name("Wand full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* Mega-Hack -- refuse to aim a pile from the ground */
if ((item < 0) && (o_ptr->number > 1))
@@ -3933,14 +3945,18 @@ void do_cmd_aim_wand(void)
/* Take a turn */
energy_use = 100;
- /* Not identified yet */
- ident = FALSE;
-
/* Enter device mode */
set_stick_mode(o_ptr);
/* get the chance */
- chance = spell_chance(o_ptr->pval2);
+ int chance;
+ {
+ auto spell = spell_at(o_ptr->pval2);
+ chance = spell_chance_device(spell);
+ }
+
+ /* Leave device mode */
+ unset_stick_mode();
/* Extract object flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -3957,9 +3973,6 @@ void do_cmd_aim_wand(void)
if (flush_failure) flush();
msg_print("You failed to use the wand properly.");
sound(SOUND_FAIL);
-
- /* Leave device mode */
- unset_stick_mode();
return;
}
@@ -3969,19 +3982,14 @@ void do_cmd_aim_wand(void)
if (flush_failure) flush();
msg_print("The wand has no charges left.");
o_ptr->ident |= (IDENT_EMPTY);
-
- /* Leave device mode */
- unset_stick_mode();
return;
}
-
/* Sound */
sound(SOUND_ZAP);
-
/* Analyze the wand */
- activate_stick(o_ptr->pval2, &obvious, &use_charge);
+ activate_stick(o_ptr, &obvious, &use_charge);
/* Combine / Reorder the pack (later) */
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
@@ -3992,9 +4000,6 @@ void do_cmd_aim_wand(void)
/* Hack -- some uses are "free" */
if (!use_charge)
{
- /* Leave device mode */
- unset_stick_mode();
-
return;
}
@@ -4022,9 +4027,6 @@ void do_cmd_aim_wand(void)
{
floor_item_charges(0 - item);
}
-
- /* Leave device mode */
- unset_stick_mode();
}
@@ -4045,25 +4047,24 @@ void do_cmd_aim_wand(void)
/*
* Hook to determine if an object is zapable
*/
-static bool_ item_tester_hook_zapable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_zapable()
{
- if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_ROD_MAIN)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_ROD),
+ TVal(TV_ROD_MAIN));
+ return instance;
}
/*
* Hook to determine if an object is attachable
*/
-static bool_ item_tester_hook_attachable(object_type *o_ptr)
+static bool item_tester_hook_attachable(object_type const *o_ptr)
{
- if ((o_ptr->tval == TV_ROD_MAIN) &&
- (o_ptr->pval == SV_ROD_NOTHING)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ return ((o_ptr->tval == TV_ROD_MAIN) &&
+ (o_ptr->pval == SV_ROD_NOTHING));
}
@@ -4074,10 +4075,6 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item)
{
int item;
- object_type *o_ptr;
-
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
s32b cost;
@@ -4089,16 +4086,18 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item)
return;
}
- /* Restrict choices to rods */
- item_tester_hook = item_tester_hook_attachable;
-
/* Get an item */
- q = "Attach the rod tip with which rod? ";
- s = "You have no rod to attach to.";
- if (!get_item(&item, q, s, (USE_INVEN))) return;
+ if (!get_item(&item,
+ "Attach the rod tip with which rod? ",
+ "You have no rod to attach to.",
+ (USE_INVEN),
+ item_tester_hook_attachable))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Examine the rod */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -4140,14 +4139,10 @@ void do_cmd_zap_rod(void)
bool_ require_dir;
- object_type *o_ptr;
-
object_kind *tip_ptr;
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
/* Hack -- let perception get aborted */
bool_ use_charge = TRUE;
@@ -4159,21 +4154,19 @@ void do_cmd_zap_rod(void)
return;
}
-
- /* Restrict choices to rods */
- item_tester_hook = item_tester_hook_zapable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Rod full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Zap which rod? ";
- s = "You have no rod to zap.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ if (!get_item(&item,
+ "Zap which rod? ",
+ "You have no rod to zap.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_zapable(),
+ select_object_by_name("Rod full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* "Zapping" a Rod Tip on rod of nothing will attach it */
@@ -4573,11 +4566,7 @@ void do_cmd_zap_rod(void)
}
default:
- {
- process_hooks(HOOK_ZAP, "(d,d)", o_ptr->tval, o_ptr->sval);
-
- break;
- }
+ break;
}
@@ -4612,26 +4601,16 @@ void do_cmd_zap_rod(void)
/*
* Hook to determine if an object is activable
*/
-static bool_ item_tester_hook_activate(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_activate()
{
- u32b f1, f2, f3, f4, f5, esp;
-
-
- /* Not known */
- if (!object_known_p(o_ptr)) return (FALSE);
-
- /* Extract the flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Check activation flag */
- if (f3 & (TR3_ACTIVATE)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = And(
+ IsKnown(),
+ HasFlag3(TR3_ACTIVATE));
+ return instance;
}
-
/*
* Hack -- activate the ring of power
*/
@@ -4676,7 +4655,7 @@ int ring_of_power()
/* Rewrite this -- pelpel */
if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
(plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD),
- (bool_)(((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
+ (((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
{
msg_print("Cold winds begin to blow around you, "
"carrying with them the stench of decay...");
@@ -4778,6 +4757,153 @@ bool_ brand_bolts(void)
/*
+ * Eternal flame activation
+ */
+
+static int get_eternal_artifact_idx(object_type const *o_ptr)
+{
+ if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_LONG_SWORD)) {
+ return 147;
+ } else if ((o_ptr->tval == TV_MSTAFF) && (o_ptr->sval == SV_MSTAFF)) {
+ return 127;
+ } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_HEAVY_XBOW)) {
+ return 152;
+ } else if ((o_ptr->tval == TV_DRAG_ARMOR) && (o_ptr->sval == SV_DRAGON_POWER)) {
+ return 17;
+ }
+
+ if (game_module_idx == MODULE_THEME)
+ {
+ if ((o_ptr->tval == TV_HAFTED) && (o_ptr->sval == SV_LUCERN_HAMMER)) {
+ return 241;
+ } else if ((o_ptr->tval == TV_POLEARM) && (o_ptr->sval == SV_TRIDENT)) {
+ return 242;
+ } else if ((o_ptr->tval == TV_AXE) && (o_ptr->sval == SV_BROAD_AXE)) {
+ return 243;
+ } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_LONG_BOW)) {
+ return 245;
+ } else if ((o_ptr->tval == TV_BOOMERANG) && (o_ptr->sval == SV_BOOM_METAL)) {
+ return 247;
+ } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_SLING)) {
+ return 246;
+ } else if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_RAPIER)) {
+ return 244;
+ } else if ((o_ptr->tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_SPELL)) {
+ return 248;
+ }
+ }
+
+ /* Not usable */
+ return -1;
+}
+
+static bool eternal_flame_item_tester_hook(object_type const *o_ptr)
+{
+ if ((o_ptr->name1 > 0) ||
+ (o_ptr->name2 > 0))
+ {
+ return FALSE;
+ }
+
+ return (get_eternal_artifact_idx(o_ptr) >= 0);
+}
+
+static bool activate_eternal_flame(int flame_item)
+{
+ int item;
+ int artifact_idx = -1;
+
+ if (!get_item(&item,
+ "Which object do you want to imbue?",
+ "You have no objects to imbue.",
+ USE_INVEN,
+ eternal_flame_item_tester_hook))
+ {
+ return false;
+ }
+
+ /* Get the artifact idx */
+ artifact_idx = get_eternal_artifact_idx(get_object(item));
+ assert(artifact_idx >= 0);
+
+ /* Forge the item */
+ object_type *o_ptr = get_object(item);
+ o_ptr->name1 = artifact_idx;
+
+ apply_magic(o_ptr, -1, TRUE, TRUE, TRUE);
+
+ o_ptr->found = OBJ_FOUND_SELFMADE;
+
+ inven_item_increase(flame_item, -1);
+ inven_item_describe(flame_item);
+ inven_item_optimize(flame_item);
+ return true;
+}
+
+
+/**
+ * Farmer Maggot's sling activation.
+ */
+static bool activate_maggot()
+{
+ int dir;
+ if (!get_aim_dir(&dir))
+ {
+ return false;
+ }
+
+ fire_ball(GF_TURN_ALL, dir, 40, 2);
+ return true;
+}
+
+
+/**
+ * 'Radagast' (Theme)
+ */
+static void activate_radagast()
+{
+ cmsg_print(TERM_GREEN, "The staff's power cleanses you completely!");
+ remove_all_curse();
+ do_res_stat(A_STR, TRUE);
+ do_res_stat(A_CON, TRUE);
+ do_res_stat(A_DEX, TRUE);
+ do_res_stat(A_WIS, TRUE);
+ do_res_stat(A_INT, TRUE);
+ do_res_stat(A_CHR, TRUE);
+ restore_level();
+ // clean_corruptions(); TODO: Do we want to implement this?
+ hp_player(5000);
+ heal_insanity(5000);
+ set_poisoned(0);
+ set_blind(0);
+ set_confused(0);
+ set_image(0);
+ set_stun(0);
+ set_cut(0);
+ set_parasite(0, 0);
+
+ if (p_ptr->black_breath)
+ {
+ msg_print("The hold of the Black Breath on you is broken!");
+ }
+ p_ptr->black_breath = FALSE;
+
+ p_ptr->update |= PU_BONUS;
+ p_ptr->window |= PW_PLAYER;
+}
+
+
+/**
+ * 'Valaroma' (Theme)
+ */
+static void activate_valaroma()
+{
+ int power = 5 * p_ptr->lev;
+ banish_evil(power);
+}
+
+
+/*
* Objects in the p_ptr->inventory can now be activated, and
* SOME of those may be able to stack (ego wands or something)
* in any case, we can't know that it's impossible. *BUT* we'll
@@ -4793,24 +4919,21 @@ void do_cmd_activate(void)
char ch, spell_choice;
- object_type *o_ptr;
-
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
-
- /* Prepare the hook */
- item_tester_hook = item_tester_hook_activate;
-
/* Get an item */
command_wrk = USE_EQUIP;
- q = "Activate which item? ";
- s = "You have nothing to activate.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+ if (!get_item(&item,
+ "Activate which item? ",
+ "You have nothing to activate.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_activate()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Extract object flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -4917,12 +5040,6 @@ void do_cmd_activate(void)
/* Sound */
sound(SOUND_ZAP);
- /* Lua hook ? -- go first to allow lua to override */
- if (process_hooks(HOOK_ACTIVATE, "(d)", item))
- {
- return;
- }
-
/* New mostly unified activation code
This has to be early to allow artifacts to override normal items -- neil */
@@ -5026,7 +5143,6 @@ void do_cmd_activate(void)
const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
{
- static char buf[256];
int plev = get_skill(SKILL_DEVICE);
int i = 0, ii = 0, ij = 0, k, dir, dummy = 0;
@@ -5063,2686 +5179,2742 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item)
if (!spell)
return "Unknown!";
- /* Negative means a unified spell index */
- if (spell < 0)
+ /* Activations always have positive numbers */
+ assert(spell > 0);
+
+ /* Activate for attack */
+ switch (spell)
{
- struct spell_type *spell_ptr = spell_at(-spell);
- if (doit)
+ case ACT_GILGALAD:
{
- spell_type_produce_effect(spell_ptr, item);
- o_ptr->timeout = spell_type_activation_roll_timeout(spell_ptr);
+ if (!doit) return "starlight (75) every 75+d75 turns";
+ for (k = 1; k < 10; k++)
+ {
+ if (k - 5) fire_beam(GF_LITE, k, 75);
+ }
+
+ o_ptr->timeout = rand_int(75) + 75;
+
+ break;
}
- else
+
+ case ACT_CELEBRIMBOR:
{
- spell_type_activation_description(spell_ptr, buf);
- return buf;
+ if (!doit) return "temporary ESP (dur 20+d20) every 20+d50 turns";
+ set_tim_esp(p_ptr->tim_esp + randint(20) + 20);
+
+ o_ptr->timeout = rand_int(50) + 20;
+
+ break;
}
- }
- else
- {
- /* Activate for attack */
- switch (spell)
+
+ case ACT_SKULLCLEAVER:
{
- case ACT_GILGALAD:
- {
- if (!doit) return "starlight (75) every 75+d75 turns";
- for (k = 1; k < 10; k++)
- {
- if (k - 5) fire_beam(GF_LITE, k, 75);
- }
+ if (!doit) return "destruction every 200+d200 turns";
+ destroy_area(p_ptr->py, p_ptr->px, 15);
- o_ptr->timeout = rand_int(75) + 75;
+ o_ptr->timeout = rand_int(200) + 200;
- break;
- }
+ break;
+ }
- case ACT_CELEBRIMBOR:
- {
- if (!doit) return "temporary ESP (dur 20+d20) every 20+d50 turns";
- set_tim_esp(p_ptr->tim_esp + randint(20) + 20);
+ case ACT_HARADRIM:
+ {
+ if (!doit) return "berserk strength every 50+d50 turns";
+ set_afraid(0);
+ set_shero(p_ptr->shero + randint(25) + 25);
+ hp_player(30);
- o_ptr->timeout = rand_int(50) + 20;
+ o_ptr->timeout = rand_int(50) + 50;
- break;
- }
+ break;
+ }
- case ACT_SKULLCLEAVER:
- {
- if (!doit) return "destruction every 200+d200 turns";
- destroy_area(p_ptr->py, p_ptr->px, 15, TRUE, FALSE);
+ case ACT_FUNDIN:
+ {
+ if (!doit) return "dispel evil (x4) every 100+d100 turns";
+ dispel_evil(p_ptr->lev * 4);
- o_ptr->timeout = rand_int(200) + 200;
+ o_ptr->timeout = rand_int(100) + 100;
- break;
- }
+ break;
+ }
- case ACT_HARADRIM:
- {
- if (!doit) return "berserk strength every 50+d50 turns";
- set_afraid(0);
- set_shero(p_ptr->shero + randint(25) + 25);
- hp_player(30);
+ case ACT_EOL:
+ {
+ if (!doit) return "mana bolt (9d8) every 7+d7 turns";
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_MANA, dir, damroll(9, 8));
- o_ptr->timeout = rand_int(50) + 50;
+ o_ptr->timeout = rand_int(7) + 7;
- break;
- }
+ break;
+ }
- case ACT_FUNDIN:
- {
- if (!doit) return "dispel evil (x4) every 100+d100 turns";
- dispel_evil(p_ptr->lev * 4);
+ case ACT_UMBAR:
+ {
+ if (!doit) return "magic arrow (10d10) every 20+d20 turns";
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_MISSILE, dir, damroll(10, 10));
- o_ptr->timeout = rand_int(100) + 100;
+ o_ptr->timeout = rand_int(20) + 20;
- break;
- }
+ break;
+ }
- case ACT_EOL:
- {
- if (!doit) return "mana bolt (9d8) 7+d7 turns";
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_MANA, dir, damroll(9, 8));
+ case ACT_NUMENOR:
+ {
+ /* Give full knowledge */
+ /* Hack -- Maximal info */
+ monster_race *r_ptr;
+ cave_type *c_ptr;
+ int x, y, m;
- o_ptr->timeout = rand_int(7) + 7;
+ if (!doit) return "analyze monster every 500+d200 turns";
- break;
- }
+ if (!tgt_pt(&x, &y)) break;
- case ACT_UMBAR:
- {
- if (!doit) return "magic arrow (10d10) every 20+d20 turns";
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_MISSILE, dir, damroll(10, 10));
+ c_ptr = &cave[y][x];
+ if (!c_ptr->m_idx) break;
- o_ptr->timeout = rand_int(20) + 20;
+ r_ptr = &r_info[c_ptr->m_idx];
- break;
+ /* Observe "maximal" attacks */
+ for (m = 0; m < 4; m++)
+ {
+ /* Examine "actual" blows */
+ if (r_ptr->blow[m].effect || r_ptr->blow[m].method)
+ {
+ /* Hack -- maximal observations */
+ r_ptr->r_blows[m] = MAX_UCHAR;
+ }
}
- case ACT_NUMENOR:
- {
- /* Give full knowledge */
- /* Hack -- Maximal info */
- monster_race *r_ptr;
- cave_type *c_ptr;
- int x, y, m;
+ /* Hack -- maximal drops */
+ r_ptr->r_drop_gold = r_ptr->r_drop_item =
+ (((r_ptr->flags1 & (RF1_DROP_4D2)) ? 8 : 0) +
+ ((r_ptr->flags1 & (RF1_DROP_3D2)) ? 6 : 0) +
+ ((r_ptr->flags1 & (RF1_DROP_2D2)) ? 4 : 0) +
+ ((r_ptr->flags1 & (RF1_DROP_1D2)) ? 2 : 0) +
+ ((r_ptr->flags1 & (RF1_DROP_90)) ? 1 : 0) +
+ ((r_ptr->flags1 & (RF1_DROP_60)) ? 1 : 0));
+
+ /* Hack -- but only "valid" drops */
+ if (r_ptr->flags1 & (RF1_ONLY_GOLD)) r_ptr->r_drop_item = 0;
+ if (r_ptr->flags1 & (RF1_ONLY_ITEM)) r_ptr->r_drop_gold = 0;
+
+ /* Hack -- observe many spells */
+ r_ptr->r_cast_inate = MAX_UCHAR;
+ r_ptr->r_cast_spell = MAX_UCHAR;
+
+ /* Hack -- know all the flags */
+ r_ptr->r_flags1 = r_ptr->flags1;
+ r_ptr->r_flags2 = r_ptr->flags2;
+ r_ptr->r_flags3 = r_ptr->flags3;
+ r_ptr->r_flags4 = r_ptr->flags4;
+ r_ptr->r_flags5 = r_ptr->flags5;
+ r_ptr->r_flags6 = r_ptr->flags6;
+ r_ptr->r_flags7 = r_ptr->flags7;
+ r_ptr->r_flags8 = r_ptr->flags8;
+ r_ptr->r_flags9 = r_ptr->flags9;
+
+ o_ptr->timeout = rand_int(200) + 500;
- if (!doit) return "analyze monster every 500+d200 turns";
+ break;
+ }
- if (!tgt_pt(&x, &y)) break;
+ case ACT_KNOWLEDGE:
+ {
+ if (!doit) return "whispers from beyond(sanity drain) every 100+d200 turns";
+ identify_fully();
+ take_sanity_hit(damroll(10, 7), "the sounds of the dead");
- c_ptr = &cave[y][x];
- if (!c_ptr->m_idx) break;
+ o_ptr->timeout = rand_int(200) + 100;
- r_ptr = &r_info[c_ptr->m_idx];
+ break;
+ }
- /* Observe "maximal" attacks */
- for (m = 0; m < 4; m++)
- {
- /* Examine "actual" blows */
- if (r_ptr->blow[m].effect || r_ptr->blow[m].method)
- {
- /* Hack -- maximal observations */
- r_ptr->r_blows[m] = MAX_UCHAR;
- }
- }
+ case ACT_UNDEATH:
+ {
+ if (!doit) return "ruination every 10+d10 turns";
+ msg_print("The phial wells with dark light...");
+ unlite_area(damroll(2, 15), 3);
+ take_hit(damroll(10, 10), "activating The Phial of Undeath");
+ (void)dec_stat(A_DEX, 25, STAT_DEC_PERMANENT);
+ (void)dec_stat(A_WIS, 25, STAT_DEC_PERMANENT);
+ (void)dec_stat(A_CON, 25, STAT_DEC_PERMANENT);
+ (void)dec_stat(A_STR, 25, STAT_DEC_PERMANENT);
+ (void)dec_stat(A_CHR, 25, STAT_DEC_PERMANENT);
+ (void)dec_stat(A_INT, 25, STAT_DEC_PERMANENT);
- /* Hack -- maximal drops */
- r_ptr->r_drop_gold = r_ptr->r_drop_item =
- (((r_ptr->flags1 & (RF1_DROP_4D2)) ? 8 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_3D2)) ? 6 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_2D2)) ? 4 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_1D2)) ? 2 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_90)) ? 1 : 0) +
- ((r_ptr->flags1 & (RF1_DROP_60)) ? 1 : 0));
+ o_ptr->timeout = rand_int(10) + 10;
- /* Hack -- but only "valid" drops */
- if (r_ptr->flags1 & (RF1_ONLY_GOLD)) r_ptr->r_drop_item = 0;
- if (r_ptr->flags1 & (RF1_ONLY_ITEM)) r_ptr->r_drop_gold = 0;
+ break;
+ }
- /* Hack -- observe many spells */
- r_ptr->r_cast_inate = MAX_UCHAR;
- r_ptr->r_cast_spell = MAX_UCHAR;
+ case ACT_THRAIN:
+ {
+ if (!doit) return "detection every 30+d30 turns";
+ msg_print("The stone glows a deep green...");
+ detect_all(DEFAULT_RADIUS);
- /* Hack -- know all the flags */
- r_ptr->r_flags1 = r_ptr->flags1;
- r_ptr->r_flags2 = r_ptr->flags2;
- r_ptr->r_flags3 = r_ptr->flags3;
- r_ptr->r_flags4 = r_ptr->flags4;
- r_ptr->r_flags5 = r_ptr->flags5;
- r_ptr->r_flags6 = r_ptr->flags6;
- r_ptr->r_flags7 = r_ptr->flags7;
- r_ptr->r_flags8 = r_ptr->flags8;
- r_ptr->r_flags9 = r_ptr->flags9;
+ o_ptr->timeout = rand_int(30) + 30;
- o_ptr->timeout = rand_int(200) + 500;
+ break;
+ }
- break;
- }
+ case ACT_BARAHIR:
+ {
+ if (!doit) return "dispel small life every 55+d55 turns";
+ msg_print("You exterminate small life.");
+ (void)dispel_monsters(4);
- case ACT_KNOWLEDGE:
- {
- if (!doit) return "whispers from beyond(sanity drain) 100+d200 turns";
- identify_fully();
- take_sanity_hit(damroll(10, 7), "the sounds of the dead");
+ o_ptr->timeout = rand_int(55) + 55;
- o_ptr->timeout = rand_int(200) + 100;
+ break;
+ }
- break;
+ case ACT_TULKAS:
+ {
+ if (!doit) return "haste self (75+d75 turns) every 150+d150 turns";
+ msg_print("The ring glows brightly...");
+ if (!p_ptr->fast)
+ {
+ (void)set_fast(randint(75) + 75, 10);
}
-
- case ACT_UNDEATH:
+ else
{
- if (!doit) return "ruination every 10+d10 turns";
- msg_print("The phial wells with dark light...");
- unlite_area(damroll(2, 15), 3);
- take_hit(damroll(10, 10), "activating The Phial of Undeath");
- (void)dec_stat(A_DEX, 25, STAT_DEC_PERMANENT);
- (void)dec_stat(A_WIS, 25, STAT_DEC_PERMANENT);
- (void)dec_stat(A_CON, 25, STAT_DEC_PERMANENT);
- (void)dec_stat(A_STR, 25, STAT_DEC_PERMANENT);
- (void)dec_stat(A_CHR, 25, STAT_DEC_PERMANENT);
- (void)dec_stat(A_INT, 25, STAT_DEC_PERMANENT);
-
- o_ptr->timeout = rand_int(10) + 10;
-
- break;
+ (void)set_fast(p_ptr->fast + 5, 10);
}
- case ACT_THRAIN:
- {
- if (!doit) return "detection every 30+d30 turns";
- msg_print("The stone glows a deep green...");
- detect_all(DEFAULT_RADIUS);
+ o_ptr->timeout = rand_int(150) + 150;
- o_ptr->timeout = rand_int(30) + 30;
+ break;
+ }
- break;
- }
+ case ACT_NARYA:
+ {
+ if (!doit) return "healing (500) every 200+d100 turns";
+ msg_print("The ring glows deep red...");
+ hp_player(500);
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
- case ACT_BARAHIR:
- {
- if (!doit) return "dispel small life every 55+d55 turns";
- msg_print("You exterminate small life.");
- (void)dispel_monsters(4);
+ o_ptr->timeout = rand_int(100) + 200;
- o_ptr->timeout = rand_int(55) + 55;
+ break;
+ }
- break;
- }
+ case ACT_NENYA:
+ {
+ if (!doit) return "healing (800) every 100+d200 turns";
+ msg_print("The ring glows bright white...");
+ hp_player(800);
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
- case ACT_TULKAS:
- {
- if (!doit) return "haste self (75+d75 turns) every 150+d150 turns";
- msg_print("The ring glows brightly...");
- if (!p_ptr->fast)
- {
- (void)set_fast(randint(75) + 75, 10);
- }
- else
- {
- (void)set_fast(p_ptr->fast + 5, 10);
- }
+ o_ptr->timeout = rand_int(200) + 100;
- o_ptr->timeout = rand_int(150) + 150;
+ break;
+ }
- break;
+ case ACT_VILYA:
+ {
+ if (!doit) return "greater healing (900) every 200+d200 turns";
+ msg_print("The ring glows deep blue...");
+ hp_player(900);
+ set_blind(0);
+ set_confused(0);
+ set_poisoned(0);
+ set_stun(0);
+ set_cut(0);
+ if (p_ptr->black_breath)
+ {
+ p_ptr->black_breath = FALSE;
+ msg_print("The hold of the Black Breath on you is broken!");
}
- case ACT_NARYA:
- {
- if (!doit) return "healing (500) every 200+d100 turns";
- msg_print("The ring glows deep red...");
- hp_player(500);
- set_blind(0);
- set_confused(0);
- set_poisoned(0);
- set_stun(0);
- set_cut(0);
+ o_ptr->timeout = rand_int(200) + 200;
- o_ptr->timeout = rand_int(100) + 200;
+ break;
+ }
- break;
- }
+ case ACT_POWER:
+ {
+ if (!doit) return "powerful things";
+ msg_print("The ring glows intensely black...");
- case ACT_NENYA:
- {
- if (!doit) return "healing (800) every 100+d200 turns";
- msg_print("The ring glows bright white...");
- hp_player(800);
- set_blind(0);
- set_confused(0);
- set_poisoned(0);
- set_stun(0);
- set_cut(0);
+ o_ptr->timeout = ring_of_power();
- o_ptr->timeout = rand_int(200) + 100;
+ break;
+ }
- break;
- }
- case ACT_VILYA:
+ /* The Stone of Lore is perilous, for the sake of game balance. */
+ case ACT_STONE_LORE:
+ {
+ if (!doit) return "perilous identify every turn";
+ msg_print("The stone reveals hidden mysteries...");
+ if (!ident_spell()) break;
+
+ if (has_ability(AB_PERFECT_CASTING))
{
- if (!doit) return "greater healing (900) every 200+d200 turns";
- msg_print("The ring glows deep blue...");
- hp_player(900);
- set_blind(0);
- set_confused(0);
- set_poisoned(0);
- set_stun(0);
- set_cut(0);
- if (p_ptr->black_breath)
+ /* Sufficient mana */
+ if (20 <= p_ptr->csp)
{
- p_ptr->black_breath = FALSE;
- msg_print("The hold of the Black Breath on you is broken!");
+ /* Use some mana */
+ p_ptr->csp -= 20;
}
- o_ptr->timeout = rand_int(200) + 200;
+ /* Over-exert the player */
+ else
+ {
+ int oops = 20 - p_ptr->csp;
- break;
- }
+ /* No mana left */
+ p_ptr->csp = 0;
+ p_ptr->csp_frac = 0;
- case ACT_POWER:
- {
- if (!doit) return "powerful things";
- msg_print("The ring glows intensely black...");
+ /* Message */
+ msg_print("You are too weak to control the stone!");
- o_ptr->timeout = ring_of_power();
+ /* Hack -- Bypass free action */
+ (void)set_paralyzed(randint(5 * oops + 1));
- break;
+ /* Confusing. */
+ (void)set_confused(p_ptr->confused +
+ randint(5 * oops + 1));
+ }
+
+ /* Redraw mana */
+ p_ptr->redraw |= (PR_FRAME);
}
+ take_hit(damroll(1, 12), "perilous secrets");
- /* The Stone of Lore is perilous, for the sake of game balance. */
- case ACT_STONE_LORE:
+ /* Confusing. */
+ if (rand_int(5) == 0)
{
- if (!doit) return "perilous identify every turn";
- msg_print("The stone reveals hidden mysteries...");
- if (!ident_spell()) break;
-
- if (has_ability(AB_PERFECT_CASTING))
- {
- /* Sufficient mana */
- if (20 <= p_ptr->csp)
- {
- /* Use some mana */
- p_ptr->csp -= 20;
- }
-
- /* Over-exert the player */
- else
- {
- int oops = 20 - p_ptr->csp;
+ (void)set_confused(p_ptr->confused + randint(10));
+ }
- /* No mana left */
- p_ptr->csp = 0;
- p_ptr->csp_frac = 0;
+ /* Exercise a little care... */
+ if (rand_int(20) == 0)
+ {
+ take_hit(damroll(4, 10), "perilous secrets");
+ }
- /* Message */
- msg_print("You are too weak to control the stone!");
+ o_ptr->timeout = 1;
- /* Hack -- Bypass free action */
- (void)set_paralyzed(randint(5 * oops + 1));
+ break;
+ }
- /* Confusing. */
- (void)set_confused(p_ptr->confused +
- randint(5 * oops + 1));
- }
+ case ACT_RAZORBACK:
+ {
+ if (!doit) return "star ball (150) every 1000 turns";
+ msg_print("Your armor is surrounded by lightning...");
+ for (i = 0; i < 8; i++) fire_ball(GF_ELEC, ddd[i], 150, 3);
- /* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
- }
+ o_ptr->timeout = 1000;
- take_hit(damroll(1, 12), "perilous secrets");
+ break;
+ }
- /* Confusing. */
- if (rand_int(5) == 0)
- {
- (void)set_confused(p_ptr->confused + randint(10));
- }
+ case ACT_BLADETURNER:
+ {
+ if (!doit) return "invulnerability (4+d8) every 800 turns";
+ set_invuln(p_ptr->invuln + randint(8) + 4);
- /* Exercise a little care... */
- if (rand_int(20) == 0)
- {
- take_hit(damroll(4, 10), "perilous secrets");
- }
+ o_ptr->timeout = 800;
- o_ptr->timeout = 1;
+ break;
+ }
- break;
- }
+ case ACT_MEDIATOR:
+ {
+ if (!doit) return "breathe elements (300), berserk rage, bless, and resistance every 400 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe the elements.");
+ fire_ball(GF_MISSILE, dir, 300, 4);
+ msg_print("Your armor glows many colours...");
+ (void)set_afraid(0);
+ (void)set_shero(p_ptr->shero + randint(50) + 50);
+ (void)hp_player(30);
+ (void)set_blessed(p_ptr->blessed + randint(50) + 50);
+ (void)set_oppose_acid(p_ptr->oppose_acid + randint(50) + 50);
+ (void)set_oppose_elec(p_ptr->oppose_elec + randint(50) + 50);
+ (void)set_oppose_fire(p_ptr->oppose_fire + randint(50) + 50);
+ (void)set_oppose_cold(p_ptr->oppose_cold + randint(50) + 50);
+ (void)set_oppose_pois(p_ptr->oppose_pois + randint(50) + 50);
- case ACT_RAZORBACK:
- {
- if (!doit) return "star ball (150) every 1000 turns";
- msg_print("Your armor is surrounded by lightning...");
- for (i = 0; i < 8; i++) fire_ball(GF_ELEC, ddd[i], 150, 3);
+ o_ptr->timeout = 400;
- o_ptr->timeout = 1000;
+ break;
+ }
- break;
- }
+ case ACT_BELEGENNON:
+ {
+ if (!doit) return ("heal (777), curing and heroism every 300 turns");
+ msg_print("A heavenly choir sings...");
+ (void)set_poisoned(0);
+ (void)set_cut(0);
+ (void)set_stun(0);
+ (void)set_confused(0);
+ (void)set_blind(0);
+ (void)set_hero(p_ptr->hero + randint(25) + 25);
+ (void)hp_player(777);
- case ACT_BLADETURNER:
- {
- if (!doit) return "invulnerability (4+d8) every 800 turns";
- set_invuln(p_ptr->invuln + randint(8) + 4);
+ o_ptr->timeout = 300;
- o_ptr->timeout = 800;
+ break;
+ }
- break;
- }
+ case ACT_GORLIM:
+ {
+ if (!doit) return "rays of fear in every direction";
+ turn_monsters(40 + p_ptr->lev);
- case ACT_MEDIATOR:
- {
- if (!doit) return "breathe elements (300), berserk rage, bless, and resistance every 400 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe the elements.");
- fire_ball(GF_MISSILE, dir, 300, 4);
- msg_print("Your armor glows many colours...");
- (void)set_afraid(0);
- (void)set_shero(p_ptr->shero + randint(50) + 50);
- (void)hp_player(30);
- (void)set_blessed(p_ptr->blessed + randint(50) + 50);
- (void)set_oppose_acid(p_ptr->oppose_acid + randint(50) + 50);
- (void)set_oppose_elec(p_ptr->oppose_elec + randint(50) + 50);
- (void)set_oppose_fire(p_ptr->oppose_fire + randint(50) + 50);
- (void)set_oppose_cold(p_ptr->oppose_cold + randint(50) + 50);
- (void)set_oppose_pois(p_ptr->oppose_pois + randint(50) + 50);
+ o_ptr->timeout = 3 * (p_ptr->lev + 10);
- o_ptr->timeout = 400;
+ break;
+ }
- break;
- }
+ case ACT_COLLUIN:
+ {
+ if (!doit) return "resistance (20+d20 turns) every 111 turns";
+ msg_print("Your cloak glows many colours...");
+ (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
+ (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
+ (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
+ (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
+ (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
- case ACT_BELEGENNON:
- {
- if (!doit) return ("heal (777), curing and heroism every 300 turns");
- msg_print("A heavenly choir sings...");
- (void)set_poisoned(0);
- (void)set_cut(0);
- (void)set_stun(0);
- (void)set_confused(0);
- (void)set_blind(0);
- (void)set_hero(p_ptr->hero + randint(25) + 25);
- (void)hp_player(777);
+ o_ptr->timeout = 111;
- o_ptr->timeout = 300;
+ break;
+ }
- break;
- }
- case ACT_GORLIM:
- {
- if (!doit) return "rays of fear in every direction";
- turn_monsters(40 + p_ptr->lev);
+ case ACT_BELANGIL:
+ {
+ if (!doit) return "frost ball (48) every 5+d5 turns";
+ msg_print("Your dagger is covered in frost...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_COLD, dir, 48, 2);
- o_ptr->timeout = 3 * (p_ptr->lev + 10);
+ o_ptr->timeout = rand_int(5) + 5;
- break;
- }
+ break;
+ }
- case ACT_COLLUIN:
+ case ACT_ANGUIREL:
+ {
+ if (!doit) return "a getaway every 35 turns";
+ switch (randint(13))
{
- if (!doit) return "resistance (20+d20 turns) every 111 turns";
- msg_print("Your cloak glows many colours...");
- (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
- (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
- (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
- (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
- (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20);
-
- o_ptr->timeout = 111;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ {
+ teleport_player(10);
- break;
- }
+ break;
+ }
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ {
+ teleport_player(222);
- case ACT_BELANGIL:
- {
- if (!doit) return "frost ball (48) every 5+d5 turns";
- msg_print("Your dagger is covered in frost...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_COLD, dir, 48, 2);
+ break;
+ }
- o_ptr->timeout = rand_int(5) + 5;
+ case 11:
+ case 12:
+ {
+ (void)stair_creation();
- break;
- }
+ break;
+ }
- case ACT_ANGUIREL:
- {
- if (!doit) return "a getaway every 35 turns";
- switch (randint(13))
+ default:
{
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
+ if (get_check("Leave this level? "))
{
- teleport_player(10);
+ autosave_checkpoint();
- break;
+ /* Leaving */
+ p_ptr->leaving = TRUE;
}
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- {
- teleport_player(222);
+ break;
+ }
+ }
- break;
- }
+ o_ptr->timeout = 35;
- case 11:
- case 12:
- {
- (void)stair_creation();
+ break;
+ }
- break;
- }
+ case ACT_ERU:
+ {
+ if (!doit) return "healing(7000), curing every 500 turns";
+ msg_print("Your sword glows an intense white...");
+ hp_player(7000);
+ heal_insanity(50);
+ set_blind(0);
+ set_poisoned(0);
+ set_confused(0);
+ set_stun(0);
+ set_cut(0);
+ set_image(0);
- default:
- {
- if (get_check("Leave this level? "))
- {
- autosave_checkpoint();
+ o_ptr->timeout = 500;
- /* Leaving */
- p_ptr->leaving = TRUE;
- }
+ break;
+ }
- break;
- }
- }
+ case ACT_DAWN:
+ {
+ if (!doit) return "summon the Legion of the Dawn every 500+d500 turns";
+ msg_print("You summon the Legion of the Dawn.");
+ (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE);
- o_ptr->timeout = 35;
+ o_ptr->timeout = 500 + randint(500);
- break;
- }
+ break;
+ }
- case ACT_ERU:
- {
- if (!doit) return "healing(7000), curing every 500 turns";
- msg_print("Your sword glows an intense white...");
- hp_player(7000);
- heal_insanity(50);
- set_blind(0);
- set_poisoned(0);
- set_confused(0);
- set_stun(0);
- set_cut(0);
- set_image(0);
+ case ACT_FIRESTAR:
+ {
+ if (!doit) return "large fire ball (72) every 100 turns";
+ msg_print("Your morning star rages in fire...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_FIRE, dir, 72, 3);
- o_ptr->timeout = 500;
+ o_ptr->timeout = 100;
- break;
- }
+ break;
+ }
- case ACT_DAWN:
- {
- if (!doit) return "summon the Legion of the Dawn every 500+d500 turns";
- msg_print("You summon the Legion of the Dawn.");
- (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE);
+ case ACT_TURMIL:
+ {
+ if (!doit) return "drain life (90) every 70 turns";
+ msg_print("Your hammer glows white...");
+ if (!get_aim_dir(&dir)) break;
+ drain_life(dir, 90);
- o_ptr->timeout = 500 + randint(500);
+ o_ptr->timeout = 70;
- break;
- }
+ break;
+ }
- case ACT_FIRESTAR:
- {
- if (!doit) return "large fire ball (72) every 100 turns";
- msg_print("Your morning star rages in fire...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_FIRE, dir, 72, 3);
+ case ACT_CUBRAGOL:
+ {
+ if (!doit) return "fire branding of bolts every 999 turns";
+ msg_print("Your crossbow glows deep red...");
+ (void)brand_bolts();
- o_ptr->timeout = 100;
+ o_ptr->timeout = 999;
- break;
- }
+ break;
+ }
- case ACT_TURMIL:
+ case ACT_ELESSAR:
+ {
+ if (!doit) return "heal and cure black breath every 200 turns";
+ if (p_ptr->black_breath)
{
- if (!doit) return "drain life (90) every 70 turns";
- msg_print("Your hammer glows white...");
- if (!get_aim_dir(&dir)) break;
- drain_life(dir, 90);
+ msg_print("The hold of the Black Breath on you is broken!");
+ }
+ p_ptr->black_breath = FALSE;
+ hp_player(100);
- o_ptr->timeout = 70;
+ o_ptr->timeout = 200;
- break;
- }
+ break;
+ }
- case ACT_CUBRAGOL:
+ case ACT_GANDALF:
+ {
+ if (!doit) return "restore mana every 666 turns";
+ msg_print("Your mage staff glows deep blue...");
+ if (p_ptr->csp < p_ptr->msp)
{
- if (!doit) return "fire branding of bolts every 999 turns";
- msg_print("Your crossbow glows deep red...");
- (void)brand_bolts();
+ p_ptr->csp = p_ptr->msp;
+ p_ptr->csp_frac = 0;
+ msg_print("Your feel your head clear.");
+ p_ptr->redraw |= (PR_FRAME);
+ p_ptr->window |= (PW_PLAYER);
+ }
- o_ptr->timeout = 999;
+ o_ptr->timeout = 666;
- break;
- }
+ break;
+ }
- case ACT_ELESSAR:
+ case ACT_MARDA:
+ {
+ if (!doit) return "summon a thunderlord every 1000 turns";
+ if (randint(3) == 1)
{
- if (!doit) return "heal and cure black breath every 200 turns";
- if (p_ptr->black_breath)
+ if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_THUNDERLORD))
{
- msg_print("The hold of the Black Breath on you is broken!");
+ msg_print("A Thunderlord comes from thin air!");
+ msg_print("'I will burn you!'");
}
- p_ptr->black_breath = FALSE;
- hp_player(100);
-
- o_ptr->timeout = 200;
-
- break;
}
-
- case ACT_GANDALF:
+ else
{
- if (!doit) return "restore mana every 666 turns";
- msg_print("Your mage staff glows deep blue...");
- if (p_ptr->csp < p_ptr->msp)
+ if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
+ SUMMON_THUNDERLORD, (plev == 50 ? TRUE : FALSE)))
{
- p_ptr->csp = p_ptr->msp;
- p_ptr->csp_frac = 0;
- msg_print("Your feel your head clear.");
- p_ptr->redraw |= (PR_MANA);
- p_ptr->window |= (PW_PLAYER);
+ msg_print("A Thunderlord comes from thin air!");
+ msg_print("'I will help you in your difficult task.'");
}
-
- o_ptr->timeout = 666;
-
- break;
}
- case ACT_MARDA:
- {
- if (!doit) return "summon a thunderlord every 1000 turns";
- if (randint(3) == 1)
- {
- if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_THUNDERLORD))
- {
- msg_print("A Thunderlord comes from thin air!");
- msg_print("'I will burn you!'");
- }
- }
- else
- {
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_THUNDERLORD, (bool_)(plev == 50 ? TRUE : FALSE)))
- {
- msg_print("A Thunderlord comes from thin air!");
- msg_print("'I will help you in your difficult task.'");
- }
- }
+ o_ptr->timeout = 1000;
- o_ptr->timeout = 1000;
+ break;
+ }
- break;
- }
+ case ACT_PALANTIR:
+ {
+ if (!doit) return "clairvoyance every 100+d100 turns";
+ msg_print("The stone glows a deep green...");
+ wiz_lite_extra();
+ (void)detect_traps(DEFAULT_RADIUS);
+ (void)detect_doors(DEFAULT_RADIUS);
+ (void)detect_stairs(DEFAULT_RADIUS);
- case ACT_PALANTIR:
- {
- if (!doit) return "clairvoyance every 100+d100 turns";
- msg_print("The stone glows a deep green...");
- wiz_lite_extra();
- (void)detect_traps(DEFAULT_RADIUS);
- (void)detect_doors(DEFAULT_RADIUS);
- (void)detect_stairs(DEFAULT_RADIUS);
+ o_ptr->timeout = rand_int(100) + 100;
- o_ptr->timeout = rand_int(100) + 100;
+ break;
+ }
- break;
- }
+ case ACT_EREBOR:
+ {
+ if (!doit) return "open a secret passage every 75 turns";
+ msg_print("Your pick twists in your hands.");
- case ACT_EREBOR:
+ if (!get_aim_dir(&dir)) break;
+ if (passwall(dir, TRUE))
+ {
+ msg_print("A passage opens, and you step through.");
+ }
+ else
{
- if (!doit) return "open a secret passage every 75 turns";
- msg_print("Your pick twists in your hands.");
+ msg_print("There is no wall there!");
+ }
- if (!get_aim_dir(&dir)) break;
- if (passwall(dir, TRUE))
- {
- msg_print("A passage opens, and you step through.");
- }
- else
- {
- msg_print("There is no wall there!");
- }
+ o_ptr->timeout = 75;
- o_ptr->timeout = 75;
+ break;
+ }
- break;
- }
+ case ACT_DRUEDAIN:
+ {
+ if (!doit) return "detection every 99 turns";
+ msg_print("Your drum shows you the world.");
+ detect_all(DEFAULT_RADIUS);
- case ACT_DRUEDAIN:
- {
- if (!doit) return "detection every 99 turns";
- msg_print("Your drum shows you the world.");
- detect_all(DEFAULT_RADIUS);
+ o_ptr->timeout = 99;
- o_ptr->timeout = 99;
+ break;
+ }
- break;
- }
+ case ACT_ROHAN:
+ {
+ if (!doit) return "heroism, berserker, and haste every 250 turns";
+ msg_print("Your horn glows deep red.");
+ set_afraid(0);
+ set_shero(p_ptr->shero + damroll(5, 10) + 30);
+ set_afraid(0);
+ set_hero(p_ptr->hero + damroll(5, 10) + 30);
+ set_fast(p_ptr->fast + damroll(5, 10) + 30, 10);
+ hp_player(30);
- case ACT_ROHAN:
- {
- if (!doit) return "heroism, berserker, and haste every 250 turns";
- msg_print("Your horn glows deep red.");
- set_afraid(0);
- set_shero(p_ptr->shero + damroll(5, 10) + 30);
- set_afraid(0);
- set_hero(p_ptr->hero + damroll(5, 10) + 30);
- set_fast(p_ptr->fast + damroll(5, 10) + 30, 10);
- hp_player(30);
+ o_ptr->timeout = 250;
- o_ptr->timeout = 250;
+ break;
+ }
- break;
- }
+ case ACT_HELM:
+ {
+ if (!doit) return "sound ball (300) every 300 turns";
+ msg_print("Your horn emits a loud sound.");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_SOUND, dir, 300, 6);
- case ACT_HELM:
- {
- if (!doit) return "sound ball (300) every 300 turns";
- msg_print("Your horn emits a loud sound.");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_SOUND, dir, 300, 6);
+ o_ptr->timeout = 300;
- o_ptr->timeout = 300;
+ break;
+ }
- break;
+ case ACT_BOROMIR:
+ {
+ if (!doit) return "mass human summoning every 1000 turns";
+ msg_print("Your horn calls for help.");
+ for (i = 0; i < 15; i++)
+ {
+ summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_HUMAN, TRUE);
}
- case ACT_BOROMIR:
- {
- if (!doit) return "mass human summoning every 1000 turns";
- msg_print("Your horn calls for help.");
- for (i = 0; i < 15; i++)
- {
- summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_HUMAN, TRUE);
- }
+ o_ptr->timeout = 1000;
- o_ptr->timeout = 1000;
+ break;
+ }
- break;
+ case ACT_HURIN:
+ {
+ if (!doit) return "berserker and +10 to speed (50) every 100+d200 turns";
+ if (!p_ptr->fast)
+ {
+ (void)set_fast(randint(50) + 50, 10);
}
-
- case ACT_HURIN:
+ else
{
- if (!doit) return "berserker and +10 to speed (50) every 100+d200 turns";
- if (!p_ptr->fast)
- {
- (void)set_fast(randint(50) + 50, 10);
- }
- else
- {
- (void)set_fast(p_ptr->fast + 5, 10);
- }
- hp_player(30);
- set_afraid(0);
- set_shero(p_ptr->shero + randint(50) + 50);
+ (void)set_fast(p_ptr->fast + 5, 10);
+ }
+ hp_player(30);
+ set_afraid(0);
+ set_shero(p_ptr->shero + randint(50) + 50);
- o_ptr->timeout = rand_int(200) + 100;
+ o_ptr->timeout = rand_int(200) + 100;
- break;
- }
+ break;
+ }
- case ACT_AXE_GOTHMOG:
- {
- if (!doit) return "fire ball (300) every 200+d200 turns";
- msg_print("Your lochaber axe erupts in fire...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_FIRE, dir, 300, 4);
+ case ACT_AXE_GOTHMOG:
+ {
+ if (!doit) return "fire ball (300) every 200+d200 turns";
+ msg_print("Your lochaber axe erupts in fire...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_FIRE, dir, 300, 4);
- o_ptr->timeout = 200 + rand_int(200);
+ o_ptr->timeout = 200 + rand_int(200);
- break;
- }
+ break;
+ }
- case ACT_MELKOR:
- {
- if (!doit) return "darkness ball (150) every 100 turns";
- msg_print("Your spear is covered of darkness...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_DARK, dir, 150, 3);
+ case ACT_MELKOR:
+ {
+ if (!doit) return "darkness ball (150) every 100 turns";
+ msg_print("Your spear is covered of darkness...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_DARK, dir, 150, 3);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- break;
- }
+ break;
+ }
- case ACT_GROND:
- {
- if (!doit) return "alter reality every 100 turns";
- msg_print("Your hammer hits the floor...");
- alter_reality();
+ case ACT_GROND:
+ {
+ if (!doit) return "alter reality every 100 turns";
+ msg_print("Your hammer hits the floor...");
+ alter_reality();
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- break;
- }
+ break;
+ }
- case ACT_NATUREBANE:
- {
- if (!doit) return "dispel monsters (300) every 200+d200 turns";
- msg_print("Your axe glows blood red...");
- dispel_monsters(300);
+ case ACT_NATUREBANE:
+ {
+ if (!doit) return "dispel monsters (300) every 200+d200 turns";
+ msg_print("Your axe glows blood red...");
+ dispel_monsters(300);
- o_ptr->timeout = 200 + randint(200);
+ o_ptr->timeout = 200 + randint(200);
- break;
- }
+ break;
+ }
- case ACT_NIGHT:
+ case ACT_NIGHT:
+ {
+ if (!doit) return "vampiric drain (3*100) every 250 turns";
+ msg_print("Your axe emits a black aura...");
+ if (!get_aim_dir(&dir)) break;
+ for (i = 0; i < 3; i++)
{
- if (!doit) return "vampiric drain (3*100) every 250 turns";
- msg_print("Your axe emits a black aura...");
- if (!get_aim_dir(&dir)) break;
- for (i = 0; i < 3; i++)
- {
- if (drain_life(dir, 100)) hp_player(100);
- }
+ if (drain_life(dir, 100)) hp_player(100);
+ }
- o_ptr->timeout = 250;
+ o_ptr->timeout = 250;
- break;
- }
+ break;
+ }
- case ACT_ORCHAST:
- {
- if (!doit) return "detect orcs every 10 turns";
- msg_print("Your weapon glows brightly...");
- (void)detect_monsters_xxx(RF3_ORC, DEFAULT_RADIUS);
+ case ACT_ORCHAST:
+ {
+ if (!doit) return "detect orcs every 10 turns";
+ msg_print("Your weapon glows brightly...");
+ (void)detect_monsters_xxx(RF3_ORC, DEFAULT_RADIUS);
- o_ptr->timeout = 10;
+ o_ptr->timeout = 10;
- break;
- }
- case ACT_SUNLIGHT:
- {
- if (!doit) return "beam of sunlight every 10 turns";
+ break;
+ }
+ case ACT_SUNLIGHT:
+ {
+ if (!doit) return "beam of sunlight every 10 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("A line of sunlight appears.");
- lite_line(dir);
+ if (!get_aim_dir(&dir)) break;
+ msg_print("A line of sunlight appears.");
+ lite_line(dir);
- o_ptr->timeout = 10;
+ o_ptr->timeout = 10;
- break;
- }
+ break;
+ }
- case ACT_BO_MISS_1:
- {
- if (!doit) return "magic missile (2d6) every 2 turns";
- msg_print("It glows extremely brightly...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_MISSILE, dir, damroll(2, 6));
+ case ACT_BO_MISS_1:
+ {
+ if (!doit) return "magic missile (2d6) every 2 turns";
+ msg_print("It glows extremely brightly...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_MISSILE, dir, damroll(2, 6));
- o_ptr->timeout = 2;
+ o_ptr->timeout = 2;
- break;
- }
+ break;
+ }
- case ACT_BA_POIS_1:
- {
- if (!doit) return "stinking cloud (12), rad. 3, every 4+d4 turns";
- msg_print("It throbs deep green...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_POIS, dir, 12, 3);
+ case ACT_BA_POIS_1:
+ {
+ if (!doit) return "stinking cloud (12), rad. 3, every 4+d4 turns";
+ msg_print("It throbs deep green...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_POIS, dir, 12, 3);
- o_ptr->timeout = rand_int(4) + 4;
+ o_ptr->timeout = rand_int(4) + 4;
- break;
- }
+ break;
+ }
- case ACT_BO_ELEC_1:
- {
- if (!doit) return "lightning bolt (4d8) every 6+d6 turns";
- msg_print("It is covered in sparks...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_ELEC, dir, damroll(4, 8));
+ case ACT_BO_ELEC_1:
+ {
+ if (!doit) return "lightning bolt (4d8) every 6+d6 turns";
+ msg_print("It is covered in sparks...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_ELEC, dir, damroll(4, 8));
- o_ptr->timeout = rand_int(6) + 6;
+ o_ptr->timeout = rand_int(6) + 6;
- break;
- }
+ break;
+ }
- case ACT_BO_ACID_1:
- {
- if (!doit) return "acid bolt (5d8) every 5+d5 turns";
- msg_print("It is covered in acid...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_ACID, dir, damroll(5, 8));
+ case ACT_BO_ACID_1:
+ {
+ if (!doit) return "acid bolt (5d8) every 5+d5 turns";
+ msg_print("It is covered in acid...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_ACID, dir, damroll(5, 8));
- o_ptr->timeout = rand_int(5) + 5;
+ o_ptr->timeout = rand_int(5) + 5;
- break;
- }
+ break;
+ }
- case ACT_BO_COLD_1:
- {
- if (!doit) return "frost bolt (6d8) every 7+d7 turns";
- msg_print("It is covered in frost...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_COLD, dir, damroll(6, 8));
+ case ACT_BO_COLD_1:
+ {
+ if (!doit) return "frost bolt (6d8) every 7+d7 turns";
+ msg_print("It is covered in frost...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_COLD, dir, damroll(6, 8));
- o_ptr->timeout = rand_int(7) + 7;
+ o_ptr->timeout = rand_int(7) + 7;
- break;
- }
+ break;
+ }
- case ACT_BO_FIRE_1:
- {
- if (!doit) return "fire bolt (9d8) every 8+d8 turns";
- msg_print("It is covered in fire...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_FIRE, dir, damroll(9, 8));
+ case ACT_BO_FIRE_1:
+ {
+ if (!doit) return "fire bolt (9d8) every 8+d8 turns";
+ msg_print("It is covered in fire...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_FIRE, dir, damroll(9, 8));
- o_ptr->timeout = rand_int(8) + 8;
+ o_ptr->timeout = rand_int(8) + 8;
- break;
- }
+ break;
+ }
- case ACT_BA_COLD_1:
- {
- if (!doit) return "ball of cold (48) every 400 turns";
- msg_print("It is covered in frost...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_COLD, dir, 48, 2);
+ case ACT_BA_COLD_1:
+ {
+ if (!doit) return "ball of cold (48) every 400 turns";
+ msg_print("It is covered in frost...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_COLD, dir, 48, 2);
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_BA_FIRE_1:
- {
- if (!doit) return "ball of fire (72) every 400 turns";
- msg_print("It glows an intense red...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_FIRE, dir, 72, 2);
+ case ACT_BA_FIRE_1:
+ {
+ if (!doit) return "ball of fire (72) every 400 turns";
+ msg_print("It glows an intense red...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_FIRE, dir, 72, 2);
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_DRAIN_1:
- {
- if (!doit) return "drain life (100) every 100+d100 turns";
- msg_print("It glows black...");
- if (!get_aim_dir(&dir)) break;
- if (drain_life(dir, 100))
+ case ACT_DRAIN_1:
+ {
+ if (!doit) return "drain life (100) every 100+d100 turns";
+ msg_print("It glows black...");
+ if (!get_aim_dir(&dir)) break;
+ if (drain_life(dir, 100))
- o_ptr->timeout = rand_int(100) + 100;
+ o_ptr->timeout = rand_int(100) + 100;
- break;
- }
+ break;
+ }
- case ACT_BA_COLD_2:
- {
- if (!doit) return "ball of cold (100) every 300 turns";
- msg_print("It glows an intense blue...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_COLD, dir, 100, 2);
+ case ACT_BA_COLD_2:
+ {
+ if (!doit) return "ball of cold (100) every 300 turns";
+ msg_print("It glows an intense blue...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_COLD, dir, 100, 2);
- o_ptr->timeout = 300;
+ o_ptr->timeout = 300;
- break;
- }
+ break;
+ }
- case ACT_BA_ELEC_2:
- {
- if (!doit) return "ball of lightning (100) every 500 turns";
- msg_print("It crackles with electricity...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_ELEC, dir, 100, 3);
+ case ACT_BA_ELEC_2:
+ {
+ if (!doit) return "ball of lightning (100) every 500 turns";
+ msg_print("It crackles with electricity...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_ELEC, dir, 100, 3);
- o_ptr->timeout = 500;
+ o_ptr->timeout = 500;
- break;
- }
+ break;
+ }
- case ACT_DRAIN_2:
- {
- if (!doit) return "drain life (120) every 400 turns";
- msg_print("It glows black...");
- if (!get_aim_dir(&dir)) break;
- drain_life(dir, 120);
+ case ACT_DRAIN_2:
+ {
+ if (!doit) return "drain life (120) every 400 turns";
+ msg_print("It glows black...");
+ if (!get_aim_dir(&dir)) break;
+ drain_life(dir, 120);
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_VAMPIRE_1:
+ case ACT_VAMPIRE_1:
+ {
+ if (!doit) return "vampiric drain (3*50) every 400 turns";
+ if (!get_aim_dir(&dir)) break;
+ for (dummy = 0; dummy < 3; dummy++)
{
- if (!doit) return "vampiric drain (3*50) every 400 turns";
- if (!get_aim_dir(&dir)) break;
- for (dummy = 0; dummy < 3; dummy++)
- {
- if (drain_life(dir, 50))
- hp_player(50);
- }
+ if (drain_life(dir, 50))
+ hp_player(50);
+ }
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_BO_MISS_2:
- {
- if (!doit) return "arrows (150) every 90+d90 turns";
- msg_print("It grows magical spikes...");
- if (!get_aim_dir(&dir)) break;
- fire_bolt(GF_ARROW, dir, 150);
+ case ACT_BO_MISS_2:
+ {
+ if (!doit) return "arrows (150) every 90+d90 turns";
+ msg_print("It grows magical spikes...");
+ if (!get_aim_dir(&dir)) break;
+ fire_bolt(GF_ARROW, dir, 150);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BA_FIRE_2:
- {
- if (!doit) return "fire ball (120) every 225+d225 turns";
- msg_print("It glows deep red...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_FIRE, dir, 120, 3);
+ case ACT_BA_FIRE_2:
+ {
+ if (!doit) return "fire ball (120) every 225+d225 turns";
+ msg_print("It glows deep red...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_FIRE, dir, 120, 3);
- o_ptr->timeout = rand_int(225) + 225;
+ o_ptr->timeout = rand_int(225) + 225;
- break;
- }
+ break;
+ }
- case ACT_BA_COLD_3:
- {
- if (!doit) return "ball of cold (200) every 325+d325 turns";
- msg_print("It glows bright white...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_COLD, dir, 200, 3);
+ case ACT_BA_COLD_3:
+ {
+ if (!doit) return "ball of cold (200) every 325+d325 turns";
+ msg_print("It glows bright white...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_COLD, dir, 200, 3);
- o_ptr->timeout = rand_int(325) + 325;
+ o_ptr->timeout = rand_int(325) + 325;
- break;
- }
+ break;
+ }
- case ACT_BA_ELEC_3:
- {
- if (!doit) return "Lightning Ball (250) every 425+d425 turns";
- msg_print("It glows deep blue...");
- if (!get_aim_dir(&dir)) break;
- fire_ball(GF_ELEC, dir, 250, 3);
+ case ACT_BA_ELEC_3:
+ {
+ if (!doit) return "Lightning Ball (250) every 425+d425 turns";
+ msg_print("It glows deep blue...");
+ if (!get_aim_dir(&dir)) break;
+ fire_ball(GF_ELEC, dir, 250, 3);
- o_ptr->timeout = rand_int(425) + 425;
+ o_ptr->timeout = rand_int(425) + 425;
- break;
- }
+ break;
+ }
- case ACT_WHIRLWIND:
- {
- int y = 0, x = 0;
- cave_type *c_ptr;
- monster_type *m_ptr;
- if (!doit) return "whirlwind attack every 250 turns";
+ case ACT_WHIRLWIND:
+ {
+ int y = 0, x = 0;
+ cave_type *c_ptr;
+ monster_type *m_ptr;
+ if (!doit) return "whirlwind attack every 250 turns";
- for (dir = 0; dir <= 9; dir++)
- {
- y = p_ptr->py + ddy[dir];
- x = p_ptr->px + ddx[dir];
- c_ptr = &cave[y][x];
+ for (dir = 0; dir <= 9; dir++)
+ {
+ y = p_ptr->py + ddy[dir];
+ x = p_ptr->px + ddx[dir];
+ c_ptr = &cave[y][x];
- /* Get the monster */
- m_ptr = &m_list[c_ptr->m_idx];
+ /* Get the monster */
+ m_ptr = &m_list[c_ptr->m_idx];
- /* Hack -- attack monsters */
- if (c_ptr->m_idx && (m_ptr->ml || cave_floor_bold(y, x)))
- {
- py_attack(y, x, -1);
- }
+ /* Hack -- attack monsters */
+ if (c_ptr->m_idx && (m_ptr->ml || cave_floor_bold(y, x)))
+ {
+ py_attack(y, x, -1);
}
+ }
- o_ptr->timeout = 250;
+ o_ptr->timeout = 250;
- break;
- }
+ break;
+ }
- case ACT_VAMPIRE_2:
+ case ACT_VAMPIRE_2:
+ {
+ if (!doit) return "vampiric drain (3*100) every 400 turns";
+ if (!get_aim_dir(&dir)) break;
+ for (dummy = 0; dummy < 3; dummy++)
{
- if (!doit) return "vampiric drain (3*100) every 400 turns";
- if (!get_aim_dir(&dir)) break;
- for (dummy = 0; dummy < 3; dummy++)
- {
- if (drain_life(dir, 100))
- hp_player(100);
- }
+ if (drain_life(dir, 100))
+ hp_player(100);
+ }
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_CALL_CHAOS:
- {
- if (!doit) return "call chaos every 350 turns";
- msg_print("It glows in scintillating colours...");
- call_chaos();
+ case ACT_CALL_CHAOS:
+ {
+ if (!doit) return "call chaos every 350 turns";
+ msg_print("It glows in scintillating colours...");
+ call_chaos();
- o_ptr->timeout = 350;
+ o_ptr->timeout = 350;
- break;
- }
+ break;
+ }
- case ACT_ROCKET:
- {
- if (!doit) return "launch rocket (120+level) every 400 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You launch a rocket!");
- fire_ball(GF_ROCKET, dir, 120 + (plev), 2);
+ case ACT_ROCKET:
+ {
+ if (!doit) return "launch rocket (120+level) every 400 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You launch a rocket!");
+ fire_ball(GF_ROCKET, dir, 120 + (plev), 2);
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_DISP_EVIL:
- {
- if (!doit) return "dispel evil (level*5) every 300+d300 turns";
- msg_print("It floods the area with goodness...");
- dispel_evil(p_ptr->lev * 5);
+ case ACT_DISP_EVIL:
+ {
+ if (!doit) return "dispel evil (level*5) every 300+d300 turns";
+ msg_print("It floods the area with goodness...");
+ dispel_evil(p_ptr->lev * 5);
- o_ptr->timeout = rand_int(300) + 300;
+ o_ptr->timeout = rand_int(300) + 300;
- break;
- }
+ break;
+ }
- case ACT_DISP_GOOD:
- {
- if (!doit) return "dispel good (level*5) every 300+d300 turns";
- msg_print("It floods the area with evil...");
- dispel_good(p_ptr->lev * 5);
+ case ACT_DISP_GOOD:
+ {
+ if (!doit) return "dispel good (level*5) every 300+d300 turns";
+ msg_print("It floods the area with evil...");
+ dispel_good(p_ptr->lev * 5);
- o_ptr->timeout = rand_int(300) + 300;
+ o_ptr->timeout = rand_int(300) + 300;
- break;
- }
+ break;
+ }
- case ACT_BA_MISS_3:
- {
- if (!doit) return "elemental breath (300) every 500 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe the elements.");
- fire_ball(GF_MISSILE, dir, 300, 4);
+ case ACT_BA_MISS_3:
+ {
+ if (!doit) return "elemental breath (300) every 500 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe the elements.");
+ fire_ball(GF_MISSILE, dir, 300, 4);
- o_ptr->timeout = 500;
+ o_ptr->timeout = 500;
- break;
- }
+ break;
+ }
- /* Activate for other offensive action */
+ /* Activate for other offensive action */
- case ACT_CONFUSE:
- {
- if (!doit) return "confuse monster every 15 turns";
- msg_print("It glows in scintillating colours...");
- if (!get_aim_dir(&dir)) break;
- confuse_monster(dir, 20);
+ case ACT_CONFUSE:
+ {
+ if (!doit) return "confuse monster every 15 turns";
+ msg_print("It glows in scintillating colours...");
+ if (!get_aim_dir(&dir)) break;
+ confuse_monster(dir, 20);
- o_ptr->timeout = 15;
+ o_ptr->timeout = 15;
- break;
- }
+ break;
+ }
- case ACT_SLEEP:
- {
- if (!doit) return "sleep nearby monsters every 55 turns";
- msg_print("It glows deep blue...");
- sleep_monsters_touch();
+ case ACT_SLEEP:
+ {
+ if (!doit) return "sleep nearby monsters every 55 turns";
+ msg_print("It glows deep blue...");
+ sleep_monsters_touch();
- o_ptr->timeout = 55;
+ o_ptr->timeout = 55;
- break;
- }
+ break;
+ }
- case ACT_QUAKE:
+ case ACT_QUAKE:
+ {
+ if (!doit) return "earthquake (rad 10) every 50 turns";
+ /* Prevent destruction of quest levels and town */
+ if (!is_quest(dun_level) && dun_level)
{
- if (!doit) return "earthquake (rad 10) every 50 turns";
- /* Prevent destruction of quest levels and town */
- if (!is_quest(dun_level) && dun_level)
- {
- earthquake(p_ptr->py, p_ptr->px, 10);
- o_ptr->timeout = 50;
- }
-
- break;
+ earthquake(p_ptr->py, p_ptr->px, 10);
+ o_ptr->timeout = 50;
}
- case ACT_TERROR:
- {
- if (!doit) return "terror every 3 * (level+10) turns";
- turn_monsters(40 + p_ptr->lev);
+ break;
+ }
- o_ptr->timeout = 3 * (p_ptr->lev + 10);
+ case ACT_TERROR:
+ {
+ if (!doit) return "terror every 3 * (level+10) turns";
+ turn_monsters(40 + p_ptr->lev);
- break;
- }
+ o_ptr->timeout = 3 * (p_ptr->lev + 10);
- case ACT_TELE_AWAY:
- {
- if (!doit) return "teleport away every 200 turns";
- if (!get_aim_dir(&dir)) break;
- (void)fire_beam(GF_AWAY_ALL, dir, plev);
+ break;
+ }
- o_ptr->timeout = 200;
+ case ACT_TELE_AWAY:
+ {
+ if (!doit) return "teleport away every 200 turns";
+ if (!get_aim_dir(&dir)) break;
+ (void)fire_beam(GF_AWAY_ALL, dir, plev);
- break;
- }
+ o_ptr->timeout = 200;
+
+ break;
+ }
- case ACT_BANISH_EVIL:
+ case ACT_BANISH_EVIL:
+ {
+ if (!doit) return "banish evil every 250+d250 turns";
+ if (banish_evil(100))
{
- if (!doit) return "banish evil every 250+d250 turns";
- if (banish_evil(100))
- {
- msg_print("The power of the artifact banishes evil!");
- }
+ msg_print("The power of the artifact banishes evil!");
+ }
- o_ptr->timeout = 250 + randint(250);
+ o_ptr->timeout = 250 + randint(250);
- break;
- }
+ break;
+ }
- case ACT_GENOCIDE:
- {
- if (!doit) return "genocide every 500 turns";
- msg_print("It glows deep blue...");
- (void)genocide(TRUE);
+ case ACT_GENOCIDE:
+ {
+ if (!doit) return "genocide every 500 turns";
+ msg_print("It glows deep blue...");
+ (void)genocide(TRUE);
- o_ptr->timeout = 500;
+ o_ptr->timeout = 500;
- break;
- }
+ break;
+ }
- case ACT_MASS_GENO:
- {
- if (!doit) return "mass genocide every 1000 turns";
- msg_print("It lets out a long, shrill note...");
- (void)mass_genocide(TRUE);
+ case ACT_MASS_GENO:
+ {
+ if (!doit) return "mass genocide every 1000 turns";
+ msg_print("It lets out a long, shrill note...");
+ (void)mass_genocide(TRUE);
- o_ptr->timeout = 1000;
+ o_ptr->timeout = 1000;
- break;
- }
+ break;
+ }
- /* Activate for summoning / charming */
+ /* Activate for summoning / charming */
- case ACT_CHARM_ANIMAL:
- {
- if (!doit) return "charm animal every 300 turns";
- if (!get_aim_dir(&dir)) break;
- (void) charm_animal(dir, plev);
+ case ACT_CHARM_ANIMAL:
+ {
+ if (!doit) return "charm animal every 300 turns";
+ if (!get_aim_dir(&dir)) break;
+ (void) charm_animal(dir, plev);
- o_ptr->timeout = 300;
+ o_ptr->timeout = 300;
- break;
- }
+ break;
+ }
- case ACT_CHARM_UNDEAD:
- {
- if (!doit) return "enslave undead every 333 turns";
- if (!get_aim_dir(&dir)) break;
- (void)control_one_undead(dir, plev);
+ case ACT_CHARM_UNDEAD:
+ {
+ if (!doit) return "enslave undead every 333 turns";
+ if (!get_aim_dir(&dir)) break;
+ (void)control_one_undead(dir, plev);
- o_ptr->timeout = 333;
+ o_ptr->timeout = 333;
- break;
- }
+ break;
+ }
- case ACT_CHARM_OTHER:
- {
- if (!doit) return "charm monster every 400 turns";
- if (!get_aim_dir(&dir)) break;
- (void) charm_monster(dir, plev);
+ case ACT_CHARM_OTHER:
+ {
+ if (!doit) return "charm monster every 400 turns";
+ if (!get_aim_dir(&dir)) break;
+ (void) charm_monster(dir, plev);
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_CHARM_ANIMALS:
- {
- if (!doit) return "animal friendship every 500 turns";
- (void) charm_animals(plev * 2);
+ case ACT_CHARM_ANIMALS:
+ {
+ if (!doit) return "animal friendship every 500 turns";
+ (void) charm_animals(plev * 2);
- o_ptr->timeout = 500;
+ o_ptr->timeout = 500;
- break;
- }
+ break;
+ }
- case ACT_CHARM_OTHERS:
- {
- if (!doit) return "mass charm every 750 turns";
- charm_monsters(plev * 2);
+ case ACT_CHARM_OTHERS:
+ {
+ if (!doit) return "mass charm every 750 turns";
+ charm_monsters(plev * 2);
- o_ptr->timeout = 750;
+ o_ptr->timeout = 750;
- break;
- }
+ break;
+ }
- case ACT_SUMMON_ANIMAL:
- {
- if (!doit) return "summon animal every 200+d300 turns";
- (void)summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE);
+ case ACT_SUMMON_ANIMAL:
+ {
+ if (!doit) return "summon animal every 200+d300 turns";
+ (void)summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE);
- o_ptr->timeout = 200 + randint(300);
+ o_ptr->timeout = 200 + randint(300);
- break;
- }
+ break;
+ }
- case ACT_SUMMON_PHANTOM:
- {
- if (!doit) return "summon phantasmal servant every 200+d200 turns";
- msg_print("You summon a phantasmal servant.");
- (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE);
+ case ACT_SUMMON_PHANTOM:
+ {
+ if (!doit) return "summon phantasmal servant every 200+d200 turns";
+ msg_print("You summon a phantasmal servant.");
+ (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE);
- o_ptr->timeout = 200 + randint(200);
+ o_ptr->timeout = 200 + randint(200);
- break;
- }
+ break;
+ }
- case ACT_SUMMON_ELEMENTAL:
+ case ACT_SUMMON_ELEMENTAL:
+ {
+ if (!doit) return "summon elemental every 750 turns";
+ if (randint(3) == 1)
{
- if (!doit) return "summon elemental every 750 turns";
- if (randint(3) == 1)
+ if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_ELEMENTAL))
{
- if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_ELEMENTAL))
- {
- msg_print("An elemental materialises...");
- msg_print("You fail to control it!");
- }
+ msg_print("An elemental materialises...");
+ msg_print("You fail to control it!");
}
- else
+ }
+ else
+ {
+ if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
+ SUMMON_ELEMENTAL, (plev == 50 ? TRUE : FALSE)))
{
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_ELEMENTAL, (bool_)(plev == 50 ? TRUE : FALSE)))
- {
- msg_print("An elemental materialises...");
- msg_print("It seems obedient to you.");
- }
+ msg_print("An elemental materialises...");
+ msg_print("It seems obedient to you.");
}
+ }
- o_ptr->timeout = 750;
+ o_ptr->timeout = 750;
- break;
- }
+ break;
+ }
- case ACT_SUMMON_DEMON:
+ case ACT_SUMMON_DEMON:
+ {
+ if (!doit) return "summon demon every 666+d333 turns";
+ if (randint(3) == 1)
{
- if (!doit) return "summon demon every 666+d333 turns";
- if (randint(3) == 1)
+ if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_DEMON))
{
- if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_DEMON))
- {
- msg_print("The area fills with a stench of sulphur and brimstone.");
- msg_print("'NON SERVIAM! Wretch! I shall feast on thy mortal soul!'");
- }
+ msg_print("The area fills with a stench of sulphur and brimstone.");
+ msg_print("'NON SERVIAM! Wretch! I shall feast on thy mortal soul!'");
}
- else
+ }
+ else
+ {
+ if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
+ SUMMON_DEMON, (plev == 50 ? TRUE : FALSE)))
{
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- SUMMON_DEMON, (bool_)(plev == 50 ? TRUE : FALSE)))
- {
- msg_print("The area fills with a stench of sulphur and brimstone.");
- msg_print("'What is thy bidding... Master?'");
- }
+ msg_print("The area fills with a stench of sulphur and brimstone.");
+ msg_print("'What is thy bidding... Master?'");
}
+ }
- o_ptr->timeout = 666 + randint(333);
+ o_ptr->timeout = 666 + randint(333);
- break;
- }
+ break;
+ }
- case ACT_SUMMON_UNDEAD:
+ case ACT_SUMMON_UNDEAD:
+ {
+ if (!doit) return "summon undead every 666+d333 turns";
+ if (randint(3) == 1)
{
- if (!doit) return "summon undead every 666+d333 turns";
- if (randint(3) == 1)
+ if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
+ (plev > 47 ? SUMMON_HI_UNDEAD : SUMMON_UNDEAD)))
{
- if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- (plev > 47 ? SUMMON_HI_UNDEAD : SUMMON_UNDEAD)))
- {
- msg_print("Cold winds begin to blow around you, carrying with them the stench of decay...");
- msg_print("'The dead arise... to punish you for disturbing them!'");
- }
+ msg_print("Cold winds begin to blow around you, carrying with them the stench of decay...");
+ msg_print("'The dead arise... to punish you for disturbing them!'");
}
- else
+ }
+ else
+ {
+ if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
+ (plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD),
+ (((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
{
- if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2),
- (plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD),
- (bool_)(((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE)))
- {
- msg_print("Cold winds begin to blow around you, carrying with them the stench of decay...");
- msg_print("Ancient, long-dead forms arise from the ground to serve you!");
- }
+ msg_print("Cold winds begin to blow around you, carrying with them the stench of decay...");
+ msg_print("Ancient, long-dead forms arise from the ground to serve you!");
}
+ }
- o_ptr->timeout = 666 + randint(333);
+ o_ptr->timeout = 666 + randint(333);
- break;
- }
+ break;
+ }
- /* Activate for healing */
+ /* Activate for healing */
- case ACT_CURE_LW:
- {
- if (!doit) return format("cure light wounds every %d turns", (is_junkart ? 50 : 10));
- (void)set_afraid(0);
- (void)hp_player(30);
+ case ACT_CURE_LW:
+ {
+ if (!doit) return format("cure light wounds every %d turns", (is_junkart ? 50 : 10));
+ (void)set_afraid(0);
+ (void)hp_player(30);
- o_ptr->timeout = 10;
+ o_ptr->timeout = 10;
- break;
- }
+ break;
+ }
- case ACT_CURE_MW:
- {
- if (!doit) return format("cure serious wounds every %s turns", (is_junkart? "75" : "3+d3"));
- msg_print("It radiates deep purple...");
- hp_player(damroll(4, 8));
- (void)set_cut((p_ptr->cut / 2) - 50);
+ case ACT_CURE_MW:
+ {
+ if (!doit) return format("cure serious wounds every %s turns", (is_junkart? "75" : "3+d3"));
+ msg_print("It radiates deep purple...");
+ hp_player(damroll(4, 8));
+ (void)set_cut((p_ptr->cut / 2) - 50);
- o_ptr->timeout = rand_int(3) + 3;
+ o_ptr->timeout = rand_int(3) + 3;
- break;
- }
+ break;
+ }
- case ACT_CURE_POISON:
- {
- if (!doit) return "remove fear and cure poison every 5 turns";
- msg_print("It glows deep blue...");
- (void)set_afraid(0);
- (void)set_poisoned(0);
+ case ACT_CURE_POISON:
+ {
+ if (!doit) return "remove fear and cure poison every 5 turns";
+ msg_print("It glows deep blue...");
+ (void)set_afraid(0);
+ (void)set_poisoned(0);
- o_ptr->timeout = 5;
+ o_ptr->timeout = 5;
- break;
- }
+ break;
+ }
- case ACT_REST_LIFE:
- {
- if (!doit) return "restore life levels every 450 turns";
- msg_print("It glows a deep red...");
- restore_level();
+ case ACT_REST_LIFE:
+ {
+ if (!doit) return "restore life levels every 450 turns";
+ msg_print("It glows a deep red...");
+ restore_level();
- o_ptr->timeout = 450;
+ o_ptr->timeout = 450;
- break;
- }
+ break;
+ }
- case ACT_REST_ALL:
- {
- if (!doit) return format("restore stats and life levels every %d turns", (is_junkart ? 200 : 750));
- msg_print("It glows a deep green...");
- (void)do_res_stat(A_STR, TRUE);
- (void)do_res_stat(A_INT, TRUE);
- (void)do_res_stat(A_WIS, TRUE);
- (void)do_res_stat(A_DEX, TRUE);
- (void)do_res_stat(A_CON, TRUE);
- (void)do_res_stat(A_CHR, TRUE);
- (void)restore_level();
+ case ACT_REST_ALL:
+ {
+ if (!doit) return format("restore stats and life levels every %d turns", (is_junkart ? 200 : 750));
+ msg_print("It glows a deep green...");
+ (void)do_res_stat(A_STR, TRUE);
+ (void)do_res_stat(A_INT, TRUE);
+ (void)do_res_stat(A_WIS, TRUE);
+ (void)do_res_stat(A_DEX, TRUE);
+ (void)do_res_stat(A_CON, TRUE);
+ (void)do_res_stat(A_CHR, TRUE);
+ (void)restore_level();
- o_ptr->timeout = 750;
+ o_ptr->timeout = 750;
- break;
- }
+ break;
+ }
- case ACT_CURE_700:
- {
- if (!doit) return format("heal 700 hit points every %d turns", (is_junkart ? 100 : 250));
- msg_print("It glows deep blue...");
- msg_print("You feel a warm tingling inside...");
- (void)hp_player(700);
- (void)set_cut(0);
+ case ACT_CURE_700:
+ {
+ if (!doit) return format("heal 700 hit points every %d turns", (is_junkart ? 100 : 250));
+ msg_print("It glows deep blue...");
+ msg_print("You feel a warm tingling inside...");
+ (void)hp_player(700);
+ (void)set_cut(0);
- o_ptr->timeout = 250;
+ o_ptr->timeout = 250;
- break;
- }
+ break;
+ }
- case ACT_CURE_1000:
- {
- if (!doit) return "heal 1000 hit points every 888 turns";
- msg_print("It glows a bright white...");
- msg_print("You feel much better...");
- (void)hp_player(1000);
- (void)set_cut(0);
+ case ACT_CURE_1000:
+ {
+ if (!doit) return "heal 1000 hit points every 888 turns";
+ msg_print("It glows a bright white...");
+ msg_print("You feel much better...");
+ (void)hp_player(1000);
+ (void)set_cut(0);
- o_ptr->timeout = 888;
+ o_ptr->timeout = 888;
- break;
- }
+ break;
+ }
- case ACT_ESP:
- {
- if (!doit) return "temporary ESP (dur 25+d30) every 200 turns";
- (void)set_tim_esp(p_ptr->tim_esp + randint(30) + 25);
+ case ACT_ESP:
+ {
+ if (!doit) return "temporary ESP (dur 25+d30) every 200 turns";
+ (void)set_tim_esp(p_ptr->tim_esp + randint(30) + 25);
- o_ptr->timeout = 200;
+ o_ptr->timeout = 200;
- break;
- }
+ break;
+ }
- case ACT_BERSERK:
- {
- if (!doit) return "heroism and berserk (dur 50+d50) every 100+d100 turns";
- (void)set_shero(p_ptr->shero + randint(50) + 50);
- (void)set_blessed(p_ptr->blessed + randint(50) + 50);
+ case ACT_BERSERK:
+ {
+ if (!doit) return "heroism and berserk (dur 50+d50) every 100+d100 turns";
+ (void)set_shero(p_ptr->shero + randint(50) + 50);
+ (void)set_blessed(p_ptr->blessed + randint(50) + 50);
- o_ptr->timeout = 100 + randint(100);
+ o_ptr->timeout = 100 + randint(100);
- break;
- }
+ break;
+ }
- case ACT_PROT_EVIL:
- {
- if (!doit) return "protection from evil (dur level*3 + d25) every 225+d225 turns";
- msg_print("It lets out a shrill wail...");
- k = 3 * p_ptr->lev;
- (void)set_protevil(p_ptr->protevil + randint(25) + k);
+ case ACT_PROT_EVIL:
+ {
+ if (!doit) return "protection from evil (dur level*3 + d25) every 225+d225 turns";
+ msg_print("It lets out a shrill wail...");
+ k = 3 * p_ptr->lev;
+ (void)set_protevil(p_ptr->protevil + randint(25) + k);
- o_ptr->timeout = rand_int(225) + 225;
+ o_ptr->timeout = rand_int(225) + 225;
- break;
- }
+ break;
+ }
- case ACT_RESIST_ALL:
- {
- if (!doit) return "resist elements (dur 40+d40) every 200 turns";
- msg_print("It glows many colours...");
- (void)set_oppose_acid(p_ptr->oppose_acid + randint(40) + 40);
- (void)set_oppose_elec(p_ptr->oppose_elec + randint(40) + 40);
- (void)set_oppose_fire(p_ptr->oppose_fire + randint(40) + 40);
- (void)set_oppose_cold(p_ptr->oppose_cold + randint(40) + 40);
- (void)set_oppose_pois(p_ptr->oppose_pois + randint(40) + 40);
+ case ACT_RESIST_ALL:
+ {
+ if (!doit) return "resist elements (dur 40+d40) every 200 turns";
+ msg_print("It glows many colours...");
+ (void)set_oppose_acid(p_ptr->oppose_acid + randint(40) + 40);
+ (void)set_oppose_elec(p_ptr->oppose_elec + randint(40) + 40);
+ (void)set_oppose_fire(p_ptr->oppose_fire + randint(40) + 40);
+ (void)set_oppose_cold(p_ptr->oppose_cold + randint(40) + 40);
+ (void)set_oppose_pois(p_ptr->oppose_pois + randint(40) + 40);
- o_ptr->timeout = 200;
+ o_ptr->timeout = 200;
- break;
- }
+ break;
+ }
- case ACT_SPEED:
+ case ACT_SPEED:
+ {
+ if (!doit) return "speed (dur 20+d20) every 250 turns";
+ msg_print("It glows bright green...");
+ if (!p_ptr->fast)
{
- if (!doit) return "speed (dur 20+d20) every 250 turns";
- msg_print("It glows bright green...");
- if (!p_ptr->fast)
- {
- (void)set_fast(randint(20) + 20, 10);
- }
- else
- {
- (void)set_fast(p_ptr->fast + 5, 10);
- }
+ (void)set_fast(randint(20) + 20, 10);
+ }
+ else
+ {
+ (void)set_fast(p_ptr->fast + 5, 10);
+ }
- o_ptr->timeout = 250;
+ o_ptr->timeout = 250;
- break;
- }
+ break;
+ }
- case ACT_XTRA_SPEED:
+ case ACT_XTRA_SPEED:
+ {
+ if (!doit) return "speed (dur 75+d75) every 200+d200 turns";
+ msg_print("It glows brightly...");
+ if (!p_ptr->fast)
{
- if (!doit) return "speed (dur 75+d75) every 200+d200 turns";
- msg_print("It glows brightly...");
- if (!p_ptr->fast)
- {
- (void)set_fast(randint(75) + 75, 10);
- }
- else
- {
- (void)set_fast(p_ptr->fast + 5, 10);
- }
+ (void)set_fast(randint(75) + 75, 10);
+ }
+ else
+ {
+ (void)set_fast(p_ptr->fast + 5, 10);
+ }
- o_ptr->timeout = rand_int(200) + 200;
+ o_ptr->timeout = rand_int(200) + 200;
- break;
- }
+ break;
+ }
- case ACT_WRAITH:
- {
- if (!doit) return "wraith form (level/2 + d(level/2)) every 1000 turns";
- set_shadow(p_ptr->tim_wraith + randint(plev / 2) + (plev / 2));
+ case ACT_WRAITH:
+ {
+ if (!doit) return "wraith form (level/2 + d(level/2)) every 1000 turns";
+ set_shadow(p_ptr->tim_wraith + randint(plev / 2) + (plev / 2));
- o_ptr->timeout = 1000;
+ o_ptr->timeout = 1000;
- break;
- }
+ break;
+ }
- case ACT_INVULN:
- {
- if (!doit) return "invulnerability (dur 8+d8) every 1000 turns";
- (void)set_invuln(p_ptr->invuln + randint(8) + 8);
+ case ACT_INVULN:
+ {
+ if (!doit) return "invulnerability (dur 8+d8) every 1000 turns";
+ (void)set_invuln(p_ptr->invuln + randint(8) + 8);
- o_ptr->timeout = 1000;
+ o_ptr->timeout = 1000;
- break;
- }
+ break;
+ }
- /* Activate for general purpose effect (detection etc.) */
+ /* Activate for general purpose effect (detection etc.) */
- case ACT_LIGHT:
- {
- if (!doit) return format("light area (dam 2d15) every %s turns", (is_junkart ? "100" : "10+d10"));
- msg_print("It wells with clear light...");
- lite_area(damroll(2, 15), 3);
+ case ACT_LIGHT:
+ {
+ if (!doit) return format("light area (dam 2d15) every %s turns", (is_junkart ? "100" : "10+d10"));
+ msg_print("It wells with clear light...");
+ lite_area(damroll(2, 15), 3);
- o_ptr->timeout = rand_int(10) + 10;
+ o_ptr->timeout = rand_int(10) + 10;
- break;
- }
+ break;
+ }
- case ACT_MAP_LIGHT:
- {
- if (!doit) return "light (dam 2d15) & map area every 50+d50 turns";
- msg_print("It shines brightly...");
- map_area();
- lite_area(damroll(2, 15), 3);
+ case ACT_MAP_LIGHT:
+ {
+ if (!doit) return "light (dam 2d15) & map area every 50+d50 turns";
+ msg_print("It shines brightly...");
+ map_area();
+ lite_area(damroll(2, 15), 3);
- o_ptr->timeout = rand_int(50) + 50;
+ o_ptr->timeout = rand_int(50) + 50;
- break;
- }
+ break;
+ }
- case ACT_DETECT_ALL:
- {
- if (!doit) return "detection every 55+d55 turns";
- msg_print("It glows bright white...");
- msg_print("An image forms in your mind...");
- detect_all(DEFAULT_RADIUS);
+ case ACT_DETECT_ALL:
+ {
+ if (!doit) return "detection every 55+d55 turns";
+ msg_print("It glows bright white...");
+ msg_print("An image forms in your mind...");
+ detect_all(DEFAULT_RADIUS);
- o_ptr->timeout = rand_int(55) + 55;
+ o_ptr->timeout = rand_int(55) + 55;
- break;
- }
+ break;
+ }
- case ACT_DETECT_XTRA:
- {
- if (!doit) return "detection, probing and identify true every 1000 turns";
- msg_print("It glows brightly...");
- detect_all(DEFAULT_RADIUS);
- probing();
- identify_fully();
+ case ACT_DETECT_XTRA:
+ {
+ if (!doit) return "detection, probing and identify true every 1000 turns";
+ msg_print("It glows brightly...");
+ detect_all(DEFAULT_RADIUS);
+ probing();
+ identify_fully();
- o_ptr->timeout = 1000;
+ o_ptr->timeout = 1000;
- break;
- }
+ break;
+ }
- case ACT_ID_FULL:
- {
- if (!doit) return "identify true every 750 turns";
- msg_print("It glows yellow...");
- identify_fully();
+ case ACT_ID_FULL:
+ {
+ if (!doit) return "identify true every 750 turns";
+ msg_print("It glows yellow...");
+ identify_fully();
- o_ptr->timeout = 750;
+ o_ptr->timeout = 750;
- break;
- }
+ break;
+ }
- case ACT_ID_PLAIN:
- {
- if (!doit) return "identify spell every 10 turns";
- if (!ident_spell()) break;
+ case ACT_ID_PLAIN:
+ {
+ if (!doit) return "identify spell every 10 turns";
+ if (!ident_spell()) break;
- o_ptr->timeout = 10;
+ o_ptr->timeout = 10;
- break;
- }
+ break;
+ }
- case ACT_RUNE_EXPLO:
- {
- if (!doit) return "explosive rune every 200 turns";
- msg_print("It glows bright red...");
- explosive_rune();
+ case ACT_RUNE_EXPLO:
+ {
+ if (!doit) return "explosive rune every 200 turns";
+ msg_print("It glows bright red...");
+ explosive_rune();
- o_ptr->timeout = 200;
+ o_ptr->timeout = 200;
- break;
- }
+ break;
+ }
- case ACT_RUNE_PROT:
- {
- if (!doit) return "rune of protection every 400 turns";
- msg_print("It glows light blue...");
- warding_glyph();
+ case ACT_RUNE_PROT:
+ {
+ if (!doit) return "rune of protection every 400 turns";
+ msg_print("It glows light blue...");
+ warding_glyph();
- o_ptr->timeout = 400;
+ o_ptr->timeout = 400;
- break;
- }
+ break;
+ }
- case ACT_SATIATE:
- {
- if (!doit) return "satisfy hunger every 200 turns";
- (void)set_food(PY_FOOD_MAX - 1);
+ case ACT_SATIATE:
+ {
+ if (!doit) return "satisfy hunger every 200 turns";
+ (void)set_food(PY_FOOD_MAX - 1);
- o_ptr->timeout = 200;
+ o_ptr->timeout = 200;
- break;
- }
+ break;
+ }
- case ACT_DEST_DOOR:
- {
- if (!doit) return "destroy doors and traps every 10 turns";
- msg_print("It glows bright red...");
- destroy_doors_touch();
+ case ACT_DEST_DOOR:
+ {
+ if (!doit) return "destroy doors and traps every 10 turns";
+ msg_print("It glows bright red...");
+ destroy_doors_touch();
- o_ptr->timeout = 10;
+ o_ptr->timeout = 10;
- break;
- }
+ break;
+ }
- case ACT_STONE_MUD:
- {
- if (!doit) return "stone to mud every 5 turns";
- msg_print("It pulsates...");
- if (!get_aim_dir(&dir)) break;
- wall_to_mud(dir);
+ case ACT_STONE_MUD:
+ {
+ if (!doit) return "stone to mud every 5 turns";
+ msg_print("It pulsates...");
+ if (!get_aim_dir(&dir)) break;
+ wall_to_mud(dir);
- o_ptr->timeout = 5;
+ o_ptr->timeout = 5;
- break;
- }
+ break;
+ }
- case ACT_RECHARGE:
- {
- if (!doit) return "recharging every 70 turns";
- recharge(60);
+ case ACT_RECHARGE:
+ {
+ if (!doit) return "recharging every 70 turns";
+ recharge(60);
- o_ptr->timeout = 70;
+ o_ptr->timeout = 70;
- break;
- }
+ break;
+ }
- case ACT_ALCHEMY:
- {
- if (!doit) return "alchemy every 500 turns";
- msg_print("It glows bright yellow...");
- (void) alchemy();
+ case ACT_ALCHEMY:
+ {
+ if (!doit) return "alchemy every 500 turns";
+ msg_print("It glows bright yellow...");
+ (void) alchemy();
+
+ o_ptr->timeout = 500;
- o_ptr->timeout = 500;
+ break;
+ }
+ case ACT_DIM_DOOR:
+ {
+ if (!doit) return "dimension door every 100 turns";
+ if (dungeon_flags2 & DF2_NO_TELEPORT)
+ {
+ msg_print("Not on special levels!");
break;
}
- case ACT_DIM_DOOR:
+ msg_print("You open a Void Jumpgate. Choose a destination.");
+ if (!tgt_pt(&ii, &ij)) break;
+
+ p_ptr->energy -= 60 - plev;
+
+ if (!cave_empty_bold(ij, ii) || (cave[ij][ii].info & CAVE_ICKY) ||
+ (distance(ij, ii, p_ptr->py, p_ptr->px) > plev + 2) ||
+ (!rand_int(plev * plev / 2)))
{
- if (!doit) return "dimension door every 100 turns";
- if (dungeon_flags2 & DF2_NO_TELEPORT)
- {
- msg_print("Not on special levels!");
- break;
- }
+ msg_print("You fail to exit the void correctly!");
+ p_ptr->energy -= 100;
+ get_pos_player(10, &ij, &ii);
+ }
- msg_print("You open a Void Jumpgate. Choose a destination.");
- if (!tgt_pt(&ii, &ij)) break;
+ cave_set_feat(p_ptr->py, p_ptr->px, FEAT_BETWEEN);
+ cave_set_feat(ij, ii, FEAT_BETWEEN);
+ cave[p_ptr->py][p_ptr->px].special = ii + (ij << 8);
+ cave[ij][ii].special = p_ptr->px + (p_ptr->py << 8);
- p_ptr->energy -= 60 - plev;
+ o_ptr->timeout = 100;
- if (!cave_empty_bold(ij, ii) || (cave[ij][ii].info & CAVE_ICKY) ||
- (distance(ij, ii, p_ptr->py, p_ptr->px) > plev + 2) ||
- (!rand_int(plev * plev / 2)))
- {
- msg_print("You fail to exit the void correctly!");
- p_ptr->energy -= 100;
- get_pos_player(10, &ij, &ii);
- }
+ break;
+ }
- cave_set_feat(p_ptr->py, p_ptr->px, FEAT_BETWEEN);
- cave_set_feat(ij, ii, FEAT_BETWEEN);
- cave[p_ptr->py][p_ptr->px].special = ii + (ij << 8);
- cave[ij][ii].special = p_ptr->px + (p_ptr->py << 8);
+ case ACT_TELEPORT:
+ {
+ if (!doit) return format("teleport (range 100) every %d turns", (is_junkart? 100 : 45));
+ msg_print("It twists space around you...");
+ teleport_player(100);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 45;
- break;
- }
+ break;
+ }
- case ACT_TELEPORT:
+ case ACT_RECALL:
+ {
+ if (!(dungeon_flags2 & DF2_ASK_LEAVE) || ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")))
{
- if (!doit) return format("teleport (range 100) every %d turns", (is_junkart? 100 : 45));
- msg_print("It twists space around you...");
- teleport_player(100);
-
- o_ptr->timeout = 45;
+ if (!doit) return "word of recall every 200 turns";
+ msg_print("It glows soft white...");
+ recall_player(20,15);
- break;
+ o_ptr->timeout = 200;
}
- case ACT_RECALL:
- {
- if (!(dungeon_flags2 & DF2_ASK_LEAVE) || ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")))
- {
- if (!doit) return "word of recall every 200 turns";
- msg_print("It glows soft white...");
- recall_player(20,15);
+ break;
+ }
- o_ptr->timeout = 200;
- }
+ case ACT_DEATH:
+ {
+ if (!doit) return "death";
+ take_hit(5000, "activating a death spell");
- break;
- }
+ /* Timeout is set before return */
- case ACT_DEATH:
- {
- if (!doit) return "death";
- take_hit(5000, "activating a death spell");
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_RUINATION:
+ {
+ if (!doit) return "Ruination";
+ msg_print("Your nerves and muscles feel weak and lifeless!");
- break;
- }
+ take_hit(damroll(10, 10), "activating Ruination");
+ (void)dec_stat(A_DEX, 25, TRUE);
+ (void)dec_stat(A_WIS, 25, TRUE);
+ (void)dec_stat(A_CON, 25, TRUE);
+ (void)dec_stat(A_STR, 25, TRUE);
+ (void)dec_stat(A_CHR, 25, TRUE);
+ (void)dec_stat(A_INT, 25, TRUE);
- case ACT_RUINATION:
- {
- if (!doit) return "Ruination";
- msg_print("Your nerves and muscles feel weak and lifeless!");
+ /* Timeout is set before return */
- take_hit(damroll(10, 10), "activating Ruination");
- (void)dec_stat(A_DEX, 25, TRUE);
- (void)dec_stat(A_WIS, 25, TRUE);
- (void)dec_stat(A_CON, 25, TRUE);
- (void)dec_stat(A_STR, 25, TRUE);
- (void)dec_stat(A_CHR, 25, TRUE);
- (void)dec_stat(A_INT, 25, TRUE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_DESTRUC:
+ {
+ if (!doit) return "Destruction every 100 turns";
+ earthquake(p_ptr->py, p_ptr->px, 12);
- break;
- }
+ /* Timeout is set before return */
- case ACT_DESTRUC:
- {
- if (!doit) return "Destruction every 100 turns";
- earthquake(p_ptr->py, p_ptr->px, 12);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNINT:
+ {
+ if (!doit) return "decreasing Intelligence";
+ (void)dec_stat(A_INT, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNINT:
- {
- if (!doit) return "decreasing Intelligence";
- (void)dec_stat(A_INT, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNSTR:
+ {
+ if (!doit) return "decreasing Strength";
+ (void)dec_stat(A_STR, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNSTR:
- {
- if (!doit) return "decreasing Strength";
- (void)dec_stat(A_STR, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNCON:
+ {
+ if (!doit) return "decreasing Constitution";
+ (void)dec_stat(A_CON, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNCON:
- {
- if (!doit) return "decreasing Constitution";
- (void)dec_stat(A_CON, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNCHR:
+ {
+ if (!doit) return "decreasing Charisma";
+ (void)dec_stat(A_CHR, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNCHR:
- {
- if (!doit) return "decreasing Charisma";
- (void)dec_stat(A_CHR, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNDEX:
+ {
+ if (!doit) return "decreasing Dexterity";
+ (void)dec_stat(A_DEX, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNDEX:
- {
- if (!doit) return "decreasing Dexterity";
- (void)dec_stat(A_DEX, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_UNWIS:
+ {
+ if (!doit) return "decreasing Wisdom";
+ (void)dec_stat(A_WIS, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_UNWIS:
- {
- if (!doit) return "decreasing Wisdom";
- (void)dec_stat(A_WIS, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_STATLOSS:
+ {
+ if (!doit) return "stat loss";
+ (void)dec_stat(A_STR, 15, FALSE);
+ (void)dec_stat(A_INT, 15, FALSE);
+ (void)dec_stat(A_WIS, 15, FALSE);
+ (void)dec_stat(A_DEX, 15, FALSE);
+ (void)dec_stat(A_CON, 15, FALSE);
+ (void)dec_stat(A_CHR, 15, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_STATLOSS:
- {
- if (!doit) return "stat loss";
- (void)dec_stat(A_STR, 15, FALSE);
- (void)dec_stat(A_INT, 15, FALSE);
- (void)dec_stat(A_WIS, 15, FALSE);
- (void)dec_stat(A_DEX, 15, FALSE);
- (void)dec_stat(A_CON, 15, FALSE);
- (void)dec_stat(A_CHR, 15, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_HISTATLOSS:
+ {
+ if (!doit) return "high stat loss";
+ (void)dec_stat(A_STR, 25, FALSE);
+ (void)dec_stat(A_INT, 25, FALSE);
+ (void)dec_stat(A_WIS, 25, FALSE);
+ (void)dec_stat(A_DEX, 25, FALSE);
+ (void)dec_stat(A_CON, 25, FALSE);
+ (void)dec_stat(A_CHR, 25, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_HISTATLOSS:
- {
- if (!doit) return "high stat loss";
- (void)dec_stat(A_STR, 25, FALSE);
- (void)dec_stat(A_INT, 25, FALSE);
- (void)dec_stat(A_WIS, 25, FALSE);
- (void)dec_stat(A_DEX, 25, FALSE);
- (void)dec_stat(A_CON, 25, FALSE);
- (void)dec_stat(A_CHR, 25, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_EXPLOSS:
+ {
+ if (!doit) return "experience loss";
+ lose_exp(p_ptr->exp / 20);
- break;
- }
+ /* Timeout is set before return */
- case ACT_EXPLOSS:
- {
- if (!doit) return "experience loss";
- lose_exp(p_ptr->exp / 20);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_HIEXPLOSS:
+ {
+ if (!doit) return "high experience loss";
+ lose_exp(p_ptr->exp / 10);
- break;
- }
+ /* Timeout is set before return */
- case ACT_HIEXPLOSS:
- {
- if (!doit) return "high experience loss";
- lose_exp(p_ptr->exp / 10);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_SUMMON_MONST:
+ {
+ if (!doit) return "summon monster";
+ summon_specific(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_SUMMON_MONST:
- {
- if (!doit) return "summon monster";
- summon_specific(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_PARALYZE:
+ {
+ if (!doit) return "paralyze";
+ set_paralyzed(20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_PARALYZE:
- {
- if (!doit) return "paralyze";
- set_paralyzed(20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_HALLU:
+ {
+ if (!doit) return "hallucination every 10 turns";
+ set_image(p_ptr->image + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_HALLU:
- {
- if (!doit) return "hallucination every 10 turns";
- set_image(p_ptr->image + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_POISON:
+ {
+ if (!doit) return "poison";
+ set_poisoned(p_ptr->poisoned + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_POISON:
- {
- if (!doit) return "poison";
- set_poisoned(p_ptr->poisoned + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_HUNGER:
+ {
+ if (!doit) return "create hunger";
+ (void)set_food(PY_FOOD_WEAK);
- break;
- }
+ /* Timeout is set before return */
- case ACT_HUNGER:
- {
- if (!doit) return "create hunger";
- (void)set_food(PY_FOOD_WEAK);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_STUN:
+ {
+ if (!doit) return "stun";
+ set_stun(p_ptr->stun + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_STUN:
- {
- if (!doit) return "stun";
- set_stun(p_ptr->stun + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CUTS:
+ {
+ if (!doit) return "cuts";
+ set_cut(p_ptr->cut + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_CUTS:
- {
- if (!doit) return "cuts";
- set_cut(p_ptr->cut + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_PARANO:
+ {
+ if (!doit) return "confusion";
+ set_confused(p_ptr->confused + 30 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_PARANO:
- {
- if (!doit) return "confusion";
- set_confused(p_ptr->confused + 30 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CONFUSION:
+ {
+ if (!doit) return "confusion";
+ set_confused(p_ptr->confused + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_CONFUSION:
- {
- if (!doit) return "confusion";
- set_confused(p_ptr->confused + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_BLIND:
+ {
+ if (!doit) return "blindness";
+ set_blind(p_ptr->blind + 20 + randint(10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_BLIND:
- {
- if (!doit) return "blindness";
- set_blind(p_ptr->blind + 20 + randint(10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_PET_SUMMON:
+ {
+ if (!doit) return "summon pet every 101 turns";
+ summon_specific_friendly(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0, FALSE);
- break;
- }
+ /* Timeout is set before return */
+ /*FINDME*/
- case ACT_PET_SUMMON:
- {
- if (!doit) return "summon pet every 101 turns";
- summon_specific_friendly(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0, FALSE);
+ break;
+ }
- /* Timeout is set before return */
- /*FINDME*/
+ case ACT_CURE_PARA:
+ {
+ if (!doit) return "cure confusion every 500 turns";
+ set_confused(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_PARA:
- {
- if (!doit) return "cure confusion every 500 turns";
- set_confused(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_HALLU:
+ {
+ if (!doit) return "cure hallucination every 100 turns";
+ set_image(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_HALLU:
- {
- if (!doit) return "cure hallucination every 100 turns";
- set_image(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_POIS:
+ {
+ if (!doit) return "cure poison every 100 turns";
+ set_poisoned(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_POIS:
- {
- if (!doit) return "cure poison every 100 turns";
- set_poisoned(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_HUNGER:
+ {
+ if (!doit) return "satisfy hunger every 100 turns";
+ (void)set_food(PY_FOOD_MAX - 1);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_HUNGER:
- {
- if (!doit) return "satisfy hunger every 100 turns";
- (void)set_food(PY_FOOD_MAX - 1);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_STUN:
+ {
+ if (!doit) return "cure stun every 100 turns";
+ set_stun(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_STUN:
- {
- if (!doit) return "cure stun every 100 turns";
- set_stun(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_CUTS:
+ {
+ if (!doit) return "cure cuts every 100 turns";
+ set_cut(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_CUTS:
- {
- if (!doit) return "cure cuts every 100 turns";
- set_cut(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_FEAR:
+ {
+ if (!doit) return "cure fear every 100 turns";
+ set_afraid(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_FEAR:
- {
- if (!doit) return "cure fear every 100 turns";
- set_afraid(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_CONF:
+ {
+ if (!doit) return "cure confusion every 100 turns";
+ set_confused(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_CONF:
- {
- if (!doit) return "cure confusion every 100 turns";
- set_confused(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_BLIND:
+ {
+ if (!doit) return "cure blindness every 100 turns";
+ set_blind(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_BLIND:
- {
- if (!doit) return "cure blindness every 100 turns";
- set_blind(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURING:
+ {
+ if (!doit) return "curing every 110 turns";
+ set_blind(0);
+ set_poisoned(0);
+ set_confused(0);
+ set_stun(0);
+ set_cut(0);
+ set_image(0);
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURING:
- {
- if (!doit) return "curing every 110 turns";
- set_blind(0);
- set_poisoned(0);
- set_confused(0);
- set_stun(0);
- set_cut(0);
- set_image(0);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_DARKNESS:
+ {
+ if (!doit) return "darkness";
+ unlite_area(damroll(2, 10), 10);
- break;
- }
+ /* Timeout is set before return */
- case ACT_DARKNESS:
- {
- if (!doit) return "darkness";
- unlite_area(damroll(2, 10), 10);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_LEV_TELE:
+ {
+ if (!doit) return "teleport level every 50 turns";
+ teleport_player_level();
- break;
- }
+ /* Timeout is set before return */
- case ACT_LEV_TELE:
- {
- if (!doit) return "teleport level every 50 turns";
- teleport_player_level();
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_ACQUIREMENT:
+ {
+ if (!doit) return "acquirement every 3000 turns";
+ acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE);
- break;
- }
+ /* Timeout is set before return */
- case ACT_ACQUIREMENT:
- {
- if (!doit) return "acquirement every 3000 turns";
- acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_WEIRD:
+ {
+ if (!doit) return "something weird every 5 turns";
+ /* It doesn't do anything */
- break;
- }
+ /* Timeout is set before return */
- case ACT_WEIRD:
- {
- if (!doit) return "something weird every 5 turns";
- /* It doesn't do anything */
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_AGGRAVATE:
+ {
+ if (!doit) return "aggravate";
+ aggravate_monsters(1);
- break;
- }
+ /* Timeout is set before return */
- case ACT_AGGRAVATE:
- {
- if (!doit) return "aggravate";
- aggravate_monsters(1);
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_MUT:
+ {
+ if (!doit) return "gain corruption every 10 turns";
+ gain_random_corruption();
+ /* Timeout is set before return */
- break;
- }
+ break;
+ }
- case ACT_MUT:
- {
- if (!doit) return "gain corruption every 10 turns";
- gain_random_corruption();
- /* Timeout is set before return */
+ case ACT_CURE_INSANITY:
+ {
+ if (!doit) return "cure insanity every 200 turns";
+ heal_insanity(damroll(10, 10));
- break;
- }
+ /* Timeout is set before return */
- case ACT_CURE_INSANITY:
- {
- if (!doit) return "cure insanity every 200 turns";
- heal_insanity(damroll(10, 10));
+ break;
+ }
- /* Timeout is set before return */
+ case ACT_CURE_MUT:
+ {
+ msg_print("Ahah, you wish.");
+ /* Timeout is set before return */
- break;
- }
+ break;
+ }
- case ACT_CURE_MUT:
- {
- msg_print("Ahah, you wish.");
- /* Timeout is set before return */
+ case ACT_LIGHT_ABSORBTION:
+ {
+ int y, x, light = 0, dir;
+ cave_type *c_ptr;
- break;
- }
+ if (!doit) return "light absorption every 80 turns";
- case ACT_LIGHT_ABSORBTION:
+ for (y = p_ptr->py - 6; y <= p_ptr->py + 6; y++)
{
- int y, x, light = 0, dir;
- cave_type *c_ptr;
+ for (x = p_ptr->px - 6; x <= p_ptr->px + 6; x++)
+ {
+ if (!in_bounds(y, x)) continue;
- if (!doit) return "light absorption every 80 turns";
+ c_ptr = &cave[y][x];
- for (y = p_ptr->py - 6; y <= p_ptr->py + 6; y++)
- {
- for (x = p_ptr->px - 6; x <= p_ptr->px + 6; x++)
+ if (distance(y, x, p_ptr->py, p_ptr->px) > 6) continue;
+
+ if (c_ptr->info & CAVE_GLOW)
{
- if (!in_bounds(y, x)) continue;
+ light++;
- c_ptr = &cave[y][x];
+ /* No longer in the array */
+ c_ptr->info &= ~(CAVE_TEMP);
- if (distance(y, x, p_ptr->py, p_ptr->px) > 6) continue;
+ /* Darken the grid */
+ c_ptr->info &= ~(CAVE_GLOW);
- if (c_ptr->info & CAVE_GLOW)
+ /* Hack -- Forget "boring" grids */
+ if (cave_plain_floor_grid(c_ptr) &&
+ !(c_ptr->info & (CAVE_TRDT)))
{
- light++;
-
- /* No longer in the array */
- c_ptr->info &= ~(CAVE_TEMP);
-
- /* Darken the grid */
- c_ptr->info &= ~(CAVE_GLOW);
-
- /* Hack -- Forget "boring" grids */
- if (cave_plain_floor_grid(c_ptr) &&
- !(c_ptr->info & (CAVE_TRDT)))
- {
- /* Forget the grid */
- c_ptr->info &= ~(CAVE_MARK);
-
- /* Notice */
- note_spot(y, x);
- }
-
- /* Process affected monsters */
- if (c_ptr->m_idx)
- {
- /* Update the monster */
- update_mon(c_ptr->m_idx, FALSE);
- }
-
- /* Redraw */
- lite_spot(y, x);
+ /* Forget the grid */
+ c_ptr->info &= ~(CAVE_MARK);
+
+ /* Notice */
+ note_spot(y, x);
+ }
+
+ /* Process affected monsters */
+ if (c_ptr->m_idx)
+ {
+ /* Update the monster */
+ update_mon(c_ptr->m_idx, FALSE);
}
+
+ /* Redraw */
+ lite_spot(y, x);
}
}
+ }
- if (!get_aim_dir(&dir)) return (FALSE);
+ if (!get_aim_dir(&dir)) return (FALSE);
- msg_print("The light around you is absorbed... "
- "and released in a powerful bolt!");
- fire_bolt(GF_LITE, dir, damroll(light, p_ptr->lev));
+ msg_print("The light around you is absorbed... "
+ "and released in a powerful bolt!");
+ fire_bolt(GF_LITE, dir, damroll(light, p_ptr->lev));
- /* Timeout is set before return */
+ /* Timeout is set before return */
- break;
- }
- /* Horns of DragonKind (Note that these are new egos)*/
- case ACT_BA_FIRE_H:
- {
- if (!doit) return "large fire ball (300) every 100 turns";
- fire_ball(GF_FIRE, 5, 300, 7);
+ break;
+ }
+ /* Horns of DragonKind (Note that these are new egos)*/
+ case ACT_BA_FIRE_H:
+ {
+ if (!doit) return "large fire ball (300) every 100 turns";
+ fire_ball(GF_FIRE, 5, 300, 7);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- break;
- }
- case ACT_BA_COLD_H:
- {
- if (!doit) return "large cold ball (300) every 100 turns";
- fire_ball(GF_COLD, 5, 300, 7);
+ break;
+ }
+ case ACT_BA_COLD_H:
+ {
+ if (!doit) return "large cold ball (300) every 100 turns";
+ fire_ball(GF_COLD, 5, 300, 7);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- break;
- }
- case ACT_BA_ELEC_H:
- {
- if (!doit) return "large lightning ball (300) every 100 turns";
- fire_ball(GF_ELEC, 5, 300, 7);
+ break;
+ }
+ case ACT_BA_ELEC_H:
+ {
+ if (!doit) return "large lightning ball (300) every 100 turns";
+ fire_ball(GF_ELEC, 5, 300, 7);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- break;
- }
- case ACT_BA_ACID_H:
- {
- if (!doit) return "large acid ball (300) every 100 turns";
- fire_ball(GF_ACID, 5, 300, 7);
+ break;
+ }
+ case ACT_BA_ACID_H:
+ {
+ if (!doit) return "large acid ball (300) every 100 turns";
+ fire_ball(GF_ACID, 5, 300, 7);
- o_ptr->timeout = 100;
+ o_ptr->timeout = 100;
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- break;
- }
+ break;
+ }
- case ACT_SPIN:
- {
- if (!doit) return "spinning around every 50+d25 turns";
- do_spin();
+ case ACT_SPIN:
+ {
+ if (!doit) return "spinning around every 50+d25 turns";
+ do_spin();
- o_ptr->timeout = 50 + randint(25);
+ o_ptr->timeout = 50 + randint(25);
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- /* Done */
- break;
- }
- case ACT_NOLDOR:
- {
- if (!doit) return "detect treasure every 10+d20 turns";
- detect_treasure(DEFAULT_RADIUS);
+ /* Done */
+ break;
+ }
+ case ACT_NOLDOR:
+ {
+ if (!doit) return "detect treasure every 10+d20 turns";
+ detect_treasure(DEFAULT_RADIUS);
- o_ptr->timeout = 10 + randint(20);
+ o_ptr->timeout = 10 + randint(20);
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
- /* Done */
- break;
+ /* Done */
+ break;
+ }
+ case ACT_SPECTRAL:
+ {
+ if (!doit) return "wraith-form every 50+d50 turns";
+ if (!p_ptr->wraith_form)
+ {
+ set_shadow(20 + randint(20));
}
- case ACT_SPECTRAL:
+ else
{
- if (!doit) return "wraith-form every 50+d50 turns";
- if (!p_ptr->wraith_form)
- {
- set_shadow(20 + randint(20));
- }
- else
- {
- set_shadow(p_ptr->tim_wraith + randint(20));
- }
+ set_shadow(p_ptr->tim_wraith + randint(20));
+ }
- o_ptr->timeout = 50 + randint(50);
+ o_ptr->timeout = 50 + randint(50);
- /* Window stuff */
- p_ptr->window |= PW_INVEN | PW_EQUIP;
+ /* Window stuff */
+ p_ptr->window |= PW_INVEN | PW_EQUIP;
- /* Done */
- break;
+ /* Done */
+ break;
+ }
+ case ACT_JUMP:
+ {
+ if (!doit) return "phasing every 10+d10 turns";
+ teleport_player(10);
+ o_ptr->timeout = 10 + randint(10);
+
+ /* Window stuff */
+ p_ptr->window |= (PW_INVEN | PW_EQUIP);
+
+ /* Done */
+ break;
+ }
+
+ case ACT_DEST_TELE:
+ {
+ if (!doit) return "teleportation and destruction of the ring";
+ if (!item)
+ {
+ msg_print("You can't activate this when it's there!");
}
- case ACT_JUMP:
+ if (get_check("This will destroy the ring. Do you wish to continue? "))
{
- if (!doit) return "phasing every 10+d10 turns";
- teleport_player(10);
- o_ptr->timeout = 10 + randint(10);
+ msg_print("The ring explodes into a space distortion.");
+ teleport_player(200);
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
+ /* It explodes, doesn't it ? */
+ take_hit(damroll(2, 10), "an exploding ring");
- /* Done */
- break;
+ inc_stack_size_ex(item, -255, OPTIMIZE, NO_DESCRIBE);
}
- case ACT_DEST_TELE:
- {
- if (!doit) return "teleportation and destruction of the ring";
- if (!item)
- {
- msg_print("You can't activate this when it's there!");
- }
- if (get_check("This will destroy the ring. Do you wish to continue? "))
- {
- msg_print("The ring explodes into a space distortion.");
- teleport_player(200);
+ break;
+ }
+ /*amulet of serpents dam 100, rad 2 timeout 40+d60 */
+ case ACT_BA_POIS_4:
+ {
+ if (!doit) return "venom breathing every 40+d60 turns";
+ /* Get a direction for breathing (or abort) */
+ if (!get_aim_dir(&dir)) break;
- /* It explodes, doesn't it ? */
- take_hit(damroll(2, 10), "an exploding ring");
+ msg_print("You breathe venom...");
+ fire_ball(GF_POIS, dir, 100, 2);
- inc_stack_size_ex(item, -255, OPTIMIZE, NO_DESCRIBE);
- }
+ o_ptr->timeout = rand_int(60) + 40;
- break;
- }
- /*amulet of serpents dam 100, rad 2 timeout 40+d60 */
- case ACT_BA_POIS_4:
- {
- if (!doit) return "venom breathing every 40+d60 turns";
- /* Get a direction for breathing (or abort) */
- if (!get_aim_dir(&dir)) break;
+ /* Window stuff */
+ p_ptr->window |= PW_INVEN | PW_EQUIP;
- msg_print("You breathe venom...");
- fire_ball(GF_POIS, dir, 100, 2);
+ /* Done */
+ break;
+ }
+ /*rings of X 50,50+d50 dur 20+d20 */
+ case ACT_BA_COLD_4:
+ {
+ if (!doit) return "ball of cold and resist cold every 50+d50 turns";
+ /* Get a direction for breathing (or abort) */
+ if (!get_aim_dir(&dir)) break;
- o_ptr->timeout = rand_int(60) + 40;
+ fire_ball(GF_COLD, dir, 50, 2);
+ (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
- /* Window stuff */
- p_ptr->window |= PW_INVEN | PW_EQUIP;
+ o_ptr->timeout = rand_int(50) + 50;
- /* Done */
- break;
- }
- /*rings of X 50,50+d50 dur 20+d20 */
- case ACT_BA_COLD_4:
- {
- if (!doit) return "ball of cold and resist cold every 50+d50 turns";
- /* Get a direction for breathing (or abort) */
- if (!get_aim_dir(&dir)) break;
+ break;
+ }
- fire_ball(GF_COLD, dir, 50, 2);
- (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20);
+ case ACT_BA_FIRE_4:
+ {
+ if (!doit) return "ball of fire and resist fire every 50+d50 turns";
+ /* Get a direction for breathing (or abort) */
+ if (!get_aim_dir(&dir)) break;
- o_ptr->timeout = rand_int(50) + 50;
+ fire_ball(GF_FIRE, dir, 50, 2);
+ (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
- break;
- }
+ o_ptr->timeout = rand_int(50) + 50;
- case ACT_BA_FIRE_4:
- {
- if (!doit) return "ball of fire and resist fire every 50+d50 turns";
- /* Get a direction for breathing (or abort) */
- if (!get_aim_dir(&dir)) break;
+ break;
+ }
+ case ACT_BA_ACID_4:
+ {
+ if (!doit) return "ball of acid and resist acid every 50+d50 turns";
+ /* Get a direction for breathing (or abort) */
+ if (!get_aim_dir(&dir)) break;
- fire_ball(GF_FIRE, dir, 50, 2);
- (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20);
+ fire_ball(GF_ACID, dir, 50, 2);
+ (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
- o_ptr->timeout = rand_int(50) + 50;
+ o_ptr->timeout = rand_int(50) + 50;
- break;
- }
- case ACT_BA_ACID_4:
- {
- if (!doit) return "ball of acid and resist acid every 50+d50 turns";
- /* Get a direction for breathing (or abort) */
- if (!get_aim_dir(&dir)) break;
+ break;
+ }
- fire_ball(GF_ACID, dir, 50, 2);
- (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20);
+ case ACT_BA_ELEC_4:
+ {
+ if (!doit) return "ball of lightning and resist lightning every 50+d50 turns";
+ /* Get a direction for breathing (or abort) */
+ if (!get_aim_dir(&dir)) break;
- o_ptr->timeout = rand_int(50) + 50;
+ fire_ball(GF_ELEC, dir, 50, 2);
+ (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
- break;
- }
+ o_ptr->timeout = rand_int(50) + 50;
- case ACT_BA_ELEC_4:
- {
- if (!doit) return "ball of lightning and resist lightning every 50+d50 turns";
- /* Get a direction for breathing (or abort) */
- if (!get_aim_dir(&dir)) break;
+ break;
+ }
- fire_ball(GF_ELEC, dir, 50, 2);
- (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20);
+ case ACT_BR_ELEC:
+ {
+ if (!doit) return "breathe lightning (100) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe lightning.");
+ fire_ball(GF_ELEC, dir, 100, 2);
- o_ptr->timeout = rand_int(50) + 50;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_ELEC:
- {
- if (!doit) return "breathe lightning (100) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe lightning.");
- fire_ball(GF_ELEC, dir, 100, 2);
+ case ACT_BR_COLD:
+ {
+ if (!doit) return "breathe frost (110) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe frost.");
+ fire_ball(GF_COLD, dir, 110, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_COLD:
- {
- if (!doit) return "breathe frost (110) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe frost.");
- fire_ball(GF_COLD, dir, 110, 2);
+ case ACT_BR_FIRE:
+ {
+ if (!doit) return "breathe fire (200) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe fire.");
+ fire_ball(GF_FIRE, dir, 200, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_FIRE:
- {
- if (!doit) return "breathe fire (200) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe fire.");
- fire_ball(GF_FIRE, dir, 200, 2);
+ case ACT_BR_ACID:
+ {
+ if (!doit) return "breathe acid (130) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe acid.");
+ fire_ball(GF_ACID, dir, 130, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_ACID:
- {
- if (!doit) return "breathe acid (130) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe acid.");
- fire_ball(GF_ACID, dir, 130, 2);
+ case ACT_BR_POIS:
+ {
+ if (!doit) return "breathe poison gas (150) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe poison gas.");
+ fire_ball(GF_POIS, dir, 150, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_POIS:
- {
- if (!doit) return "breathe poison gas (150) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe poison gas.");
- fire_ball(GF_POIS, dir, 150, 2);
+ case ACT_BR_MANY:
+ {
+ if (!doit) return "breathe multi-hued (250) every 60+d60 turns";
+ if (!get_aim_dir(&dir)) break;
+ chance = rand_int(5);
+ msg_format("You breathe %s.",
+ ((chance == 1) ? "lightning" :
+ ((chance == 2) ? "frost" :
+ ((chance == 3) ? "acid" :
+ ((chance == 4) ? "poison gas" : "fire")))));
+ fire_ball(((chance == 1) ? GF_ELEC :
+ ((chance == 2) ? GF_COLD :
+ ((chance == 3) ? GF_ACID :
+ ((chance == 4) ? GF_POIS : GF_FIRE)))),
+ dir, 250, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(60) + 60;
- break;
- }
+ break;
+ }
- case ACT_BR_MANY:
- {
- if (!doit) return "breathe multi-hued (250) every 60+d60 turns";
- if (!get_aim_dir(&dir)) break;
- chance = rand_int(5);
- msg_format("You breathe %s.",
- ((chance == 1) ? "lightning" :
- ((chance == 2) ? "frost" :
- ((chance == 3) ? "acid" :
- ((chance == 4) ? "poison gas" : "fire")))));
- fire_ball(((chance == 1) ? GF_ELEC :
- ((chance == 2) ? GF_COLD :
- ((chance == 3) ? GF_ACID :
- ((chance == 4) ? GF_POIS : GF_FIRE)))),
- dir, 250, 2);
+ case ACT_BR_CONF:
+ {
+ if (!doit) return "breathe confusion (120) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe confusion.");
+ fire_ball(GF_CONFUSION, dir, 120, 2);
- o_ptr->timeout = rand_int(60) + 60;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_CONF:
- {
- if (!doit) return "breathe confusion (120) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe confusion.");
- fire_ball(GF_CONFUSION, dir, 120, 2);
+ case ACT_BR_SOUND:
+ {
+ if (!doit) return "breathe sound (130) every 90+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe sound.");
+ fire_ball(GF_SOUND, dir, 130, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 90;
- break;
- }
+ break;
+ }
- case ACT_BR_SOUND:
- {
- if (!doit) return "breathe sound (130) every 90+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe sound.");
- fire_ball(GF_SOUND, dir, 130, 2);
+ case ACT_BR_CHAOS:
+ {
+ if (!doit) return "breathe chaos/disenchant (220) every 60+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ chance = rand_int(2);
+ msg_format("You breathe %s.",
+ ((chance == 1 ? "chaos" : "disenchantment")));
+ fire_ball((chance == 1 ? GF_CHAOS : GF_DISENCHANT),
+ dir, 220, 2);
- o_ptr->timeout = rand_int(90) + 90;
+ o_ptr->timeout = rand_int(90) + 60;
- break;
- }
+ break;
+ }
- case ACT_BR_CHAOS:
- {
- if (!doit) return "breathe chaos/disenchant (220) every 60+d90 turns";
- if (!get_aim_dir(&dir)) break;
- chance = rand_int(2);
- msg_format("You breathe %s.",
- ((chance == 1 ? "chaos" : "disenchantment")));
- fire_ball((chance == 1 ? GF_CHAOS : GF_DISENCHANT),
- dir, 220, 2);
+ case ACT_BR_SHARD:
+ {
+ if (!doit) return "breathe sound/shards (230) every 60+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ chance = rand_int(2);
+ msg_format("You breathe %s.",
+ ((chance == 1 ? "sound" : "shards")));
+ fire_ball((chance == 1 ? GF_SOUND : GF_SHARDS),
+ dir, 230, 2);
- o_ptr->timeout = rand_int(90) + 60;
+ o_ptr->timeout = rand_int(90) + 60;
- break;
- }
+ break;
+ }
- case ACT_BR_SHARD:
- {
- if (!doit) return "breathe sound/shards (230) every 60+d90 turns";
- if (!get_aim_dir(&dir)) break;
- chance = rand_int(2);
- msg_format("You breathe %s.",
- ((chance == 1 ? "sound" : "shards")));
- fire_ball((chance == 1 ? GF_SOUND : GF_SHARDS),
- dir, 230, 2);
+ case ACT_BR_BALANCE:
+ {
+ if (!doit) return "breathe balance (250) every 60+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ chance = rand_int(4);
+ msg_format("You breathe %s.",
+ ((chance == 1) ? "chaos" :
+ ((chance == 2) ? "disenchantment" :
+ ((chance == 3) ? "sound" : "shards"))));
+ fire_ball(((chance == 1) ? GF_CHAOS :
+ ((chance == 2) ? GF_DISENCHANT :
+ ((chance == 3) ? GF_SOUND : GF_SHARDS))),
+ dir, 250, 2);
- o_ptr->timeout = rand_int(90) + 60;
+ o_ptr->timeout = rand_int(90) + 60;
- break;
- }
+ break;
+ }
- case ACT_BR_BALANCE:
- {
- if (!doit) return "breathe balance (250) every 60+d90 turns";
- if (!get_aim_dir(&dir)) break;
- chance = rand_int(4);
- msg_format("You breathe %s.",
- ((chance == 1) ? "chaos" :
- ((chance == 2) ? "disenchantment" :
- ((chance == 3) ? "sound" : "shards"))));
- fire_ball(((chance == 1) ? GF_CHAOS :
- ((chance == 2) ? GF_DISENCHANT :
- ((chance == 3) ? GF_SOUND : GF_SHARDS))),
- dir, 250, 2);
+ case ACT_BR_LIGHT:
+ {
+ if (!doit) return "breathe light/darkness (200) every 60+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ chance = rand_int(2);
+ msg_format("You breathe %s.",
+ ((chance == 0 ? "light" : "darkness")));
+ fire_ball((chance == 0 ? GF_LITE : GF_DARK), dir, 200, 2);
- o_ptr->timeout = rand_int(90) + 60;
+ o_ptr->timeout = rand_int(90) + 60;
- break;
- }
+ break;
+ }
+ case ACT_BR_POWER:
+ {
+ if (!doit) return "breathe the elements (300) every 60+d90 turns";
+ if (!get_aim_dir(&dir)) break;
+ msg_print("You breathe the elements.");
+ fire_ball(GF_MISSILE, dir, 300, 3);
- case ACT_BR_LIGHT:
- {
- if (!doit) return "breathe light/darkness (200) every 60+d90 turns";
- if (!get_aim_dir(&dir)) break;
- chance = rand_int(2);
- msg_format("You breathe %s.",
- ((chance == 0 ? "light" : "darkness")));
- fire_ball((chance == 0 ? GF_LITE : GF_DARK), dir, 200, 2);
+ o_ptr->timeout = rand_int(90) + 60;
- o_ptr->timeout = rand_int(90) + 60;
+ break;
+ }
+ case ACT_GROW_MOLD:
+ {
+ if (!doit) return "grow mushrooms every 50+d50 turns";
+ msg_print("You twirl and spores fly everywhere!");
+ for (i = 0; i < 8; i++)
+ summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, FALSE);
- break;
- }
- case ACT_BR_POWER:
- {
- if (!doit) return "breathe the elements (300) every 60+d90 turns";
- if (!get_aim_dir(&dir)) break;
- msg_print("You breathe the elements.");
- fire_ball(GF_MISSILE, dir, 300, 3);
+ o_ptr->timeout = randint(50) + 50;
- o_ptr->timeout = rand_int(90) + 60;
+ break;
+ }
+ case ACT_MUSIC:
+ /* Should be handled specially by caller, so if we get here something's wrong. */
+ abort();
+ case ACT_ETERNAL_FLAME:
+ {
+ if (!doit) return "imbuing an object with the eternal fire";
- break;
- }
- case ACT_GROW_MOLD:
+ if (!activate_eternal_flame(item))
{
- if (!doit) return "grow mushrooms every 50+d50 turns";
- msg_print("You twirl and spores fly everywhere!");
- for (i = 0; i < 8; i++)
- summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, FALSE);
-
- o_ptr->timeout = randint(50) + 50;
-
- break;
+ // Eternal Flame object was NOT destroyed, so let's
+ // set the timeout.
+ o_ptr->timeout = 0;
}
- case ACT_MUSIC:
- /*
- fall through to unknown, as music should be
- handled by calling procedure.
- */
+ break;
+ }
+ case ACT_MAGGOT:
+ {
+ if (!doit) return "terrify every 10+d50 turns";
- default:
+ if (activate_maggot())
{
- msg_format("Unknown activation effect: %d.", spell);
- if ( !doit ) return "Unknown Activation";
- return NULL;
+ o_ptr->timeout = 10 + randint(50);
}
+ break;
+ }
+ case ACT_LEBOHAUM:
+ {
+ if (!doit) return "sing a cheerful song every turn";
+
+ msg_print("You hear a little song in your head in some unknown tongue:");
+ msg_print("'Avec le casque Lebohaum y a jamais d'anicroches, je parcours les dongeons,");
+ msg_print("j'en prend plein la caboche. Avec le casque Lebohaum, tout ces monstres a la");
+ msg_print("con, je leur met bien profond: c'est moi le maitre du dongeon!'");
+
+ o_ptr->timeout = 3;
+
+ break;
+ }
+ case ACT_DURANDIL:
+ {
+ if (!doit) return "sing a cheerful song every turn";
+
+ msg_print("You hear a little song in your head in some unknown tongue:");
+ msg_print("'Les epees Durandils sont forgees dans les mines par des nains.");
+ msg_print("Avec ca c'est facile de tuer un troll avec une seule main. Pas besoin");
+ msg_print("de super entrainement nis de niveau 28. Quand tu sors l'instrument");
+ msg_print("c'est l'ennemi qui prend la fuite! Avec ton epee Durandil quand tu");
+ msg_print("parcours les chemins, tu massacre sans peine les brigands et les gobelins,");
+ msg_print("les rats geants, les ogres mutants, les zombies et les liches, tu les");
+ msg_print("decoupe en tranches comme si c'etait des parts de quiches.");
+ msg_print("Les epees Durandil! Les epees Durandil!");
+ msg_print("Quand tu la sort dans un dongeon au moins t'as pas l'air debile.");
+ msg_print("C'est l'arme des bourins qui savent etre subtils.");
+ msg_print("Ne partez pas a l'aventure sans votre epee Durandil!'");
+
+ o_ptr->timeout = 3;
+
+ break;
+ }
+ case ACT_RADAGAST:
+ {
+ if (!doit) return "purity and health every 15000 turns";
+
+ activate_radagast();
+ o_ptr->timeout = 15000;
+
+ break;
+ }
+ case ACT_VALAROMA:
+ {
+ if (!doit) return "banish evil (level x5) every 250 turns";
+
+ activate_valaroma();
+ o_ptr->timeout = 250;
+
+ break;
+ }
+ default:
+ {
+ msg_format("Unknown activation effect: %d.", spell);
+ if ( !doit ) return "Unknown Activation";
+ return NULL;
}
}
diff --git a/src/cmd6.hpp b/src/cmd6.hpp
new file mode 100644
index 00000000..ad6619f6
--- /dev/null
+++ b/src/cmd6.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+
+extern void set_stick_mode(object_type *o_ptr);
+extern void unset_stick_mode(void);
+extern void do_cmd_eat_food(void);
+extern void do_cmd_quaff_potion(void);
+extern void do_cmd_read_scroll(void);
+extern void do_cmd_aim_wand(void);
+extern void do_cmd_use_staff(void);
+extern void do_cmd_zap_rod(void);
+extern const char *activation_aux(object_type *o_ptr, bool_ desc, int item);
+extern void do_cmd_activate(void);
+extern void do_cmd_cut_corpse(void);
+extern void do_cmd_cure_meat(void);
+extern void do_cmd_drink_fountain(void);
diff --git a/src/cmd7.c b/src/cmd7.cc
index 3d3b1bb2..4338cb52 100644
--- a/src/cmd7.c
+++ b/src/cmd7.cc
@@ -1,7 +1,3 @@
-/* File: cmd7.c */
-
-/* Purpose: More Class commands */
-
/*
* Copyright (c) 1999 Dark God
*
@@ -10,10 +6,39 @@
* included in all such copies.
*/
-
-#include "angband.h"
-
-#include "quark.h"
+#include "cmd7.hpp"
+
+#include "alchemist_recipe.hpp"
+#include "artifact_select_flag.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd5.hpp"
+#include "cmd6.hpp"
+#include "ego_item_type.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
/*
* Describe class powers of Mindcrafters
@@ -714,7 +739,7 @@ void do_cmd_mindcraft(void)
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -810,13 +835,13 @@ void do_cmd_mimic_lore()
/* Redraw title */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
}
-static bool_ mimic_forbid_travel(char *fmt)
+static bool_ mimic_forbid_travel(void *, void *, void *)
{
u32b value = p_ptr->mimic_extra >> 16;
u32b att = p_ptr->mimic_extra & 0xFFFF;
@@ -849,7 +874,7 @@ void do_cmd_mimic(void)
static bool_ added_hooks = FALSE;
if(!added_hooks)
{
- add_hook(HOOK_FORBID_TRAVEL, mimic_forbid_travel, "mimic_forbid_travel");
+ add_hook_new(HOOK_FORBID_TRAVEL, mimic_forbid_travel, "mimic_forbid_travel", NULL);
added_hooks = TRUE;
}
@@ -1123,7 +1148,7 @@ void do_cmd_mimic(void)
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1190,16 +1215,6 @@ void do_cmd_beastmaster(void)
int flags_select[32*5];
int activation_select;
-/* Return true if the player is wielding the philosopher's stone
- */
-bool_ alchemist_has_stone(void)
-{
- if (p_ptr->inventory[INVEN_LITE].name1 == 209)
- return TRUE;
- else
- return FALSE;
-}
-
/*
Display a group of flags from a_select flags, and return
the number of flags displayed (even invisible ones)
@@ -1226,12 +1241,14 @@ int show_flags(byte group, int pval)
{
sprintf(ttt, "%c) %s",
(items < 26) ? I2A(items) : ('0' + items - 26),
- al_name + a_select_flags[i].desc);
- if ( wizard || alchemist_has_stone())
- sprintf(ttt, "%c) %s (exp %ld)",
+ a_select_flags[i].desc);
+ if ( wizard )
+ {
+ sprintf(ttt, "%c) %s (exp " FMTu32b ")",
(items < 26) ? I2A(items) : ('0' + items - 26),
- al_name + a_select_flags[i].desc,
- (long int) a_select_flags[i].xp);
+ a_select_flags[i].desc,
+ a_select_flags[i].xp);
+ }
/* Note: Somebody is VERY clever, and it wasn't me. Text printed as
* TERM_DARK is actually printed as TERM_BLUE *SPACES* to prevent the
@@ -1265,9 +1282,11 @@ int show_flags(byte group, int pval)
break; /* Just in Case*/
}
}
- /* For alchemists who have the stone, at least show all the flags... */
- if ((alchemist_has_stone() || wizard) && color == TERM_DARK)
+
+ if (wizard && color == TERM_DARK)
+ {
color = TERM_BLUE;
+ }
if (items < 16) x = 5;
else x = 45;
@@ -1353,7 +1372,7 @@ s32b get_flags_exp(int pval, int oldpval)
}
}
}
- if ( alchemist_has_stone() ) exp = exp / 4;
+
return exp;
}
@@ -1400,7 +1419,7 @@ int calc_rqty(int i, int pval, int oldpval)
*/
-int check_artifact_items(int pval, int oldpval, int mode)
+static int check_artifact_items(int pval, int oldpval, int mode)
{
int i, j, k, row = 1 , col = 15, rqty, orqty, trqty;
bool_ good = TRUE;
@@ -1548,9 +1567,9 @@ int check_artifact_items(int pval, int oldpval, int mode)
*/
if ( mode == 0 )
{
- char *o_name = al_name + a_select_flags[i].item_desc;
+ char *o_name = a_select_flags[i].item_desc;
if (orqty > 1 && a_select_flags[i].pval && a_select_flags[i].item_descp)
- o_name = al_name + a_select_flags[i].item_descp;
+ o_name = a_select_flags[i].item_descp;
if ( rqty )
{
@@ -1679,12 +1698,12 @@ bool_ artifact_display_or_use(int pval, int oldpval, bool_ use)
if ( missing )
c_prt(TERM_RED, format("%d of the required %d essences of %s",
missing, essence[i],
- k_name + k_info[lookup_kind(TV_BATERIE, i + 1)].name ),
+ k_info[lookup_kind(TV_BATERIE, i + 1)].name ),
row++, col);
else
c_prt(TERM_GREEN, format("you have the needed %d essences of %s",
essence[i],
- k_name + k_info[lookup_kind(TV_BATERIE, i + 1)].name ),
+ k_info[lookup_kind(TV_BATERIE, i + 1)].name ),
row++, col);
}
@@ -1749,7 +1768,7 @@ void display_activation_info(int num)
c_prt(TERM_WHITE, " ", 5, 5);
c_prt(TERM_WHITE, format(" Level:%d ", a_select_flags[i].level), 6, 5);
c_prt(TERM_WHITE, format(" Exp :%d ", a_select_flags[i].xp), 7, 5);
- c_prt(TERM_WHITE, format(" Item :%s ", al_name + a_select_flags[i].item_desc), 8, 5);
+ c_prt(TERM_WHITE, format(" Item :%s ", a_select_flags[i].item_desc), 8, 5);
c_prt(TERM_WHITE, " ", 9, 5);
c_prt(TERM_WHITE, format(" %s ", activation_aux(&forge, 0, 0)), 9, 5);
c_prt(TERM_WHITE, " ", 10, 5);
@@ -1783,7 +1802,7 @@ void select_an_activation(void)
if (a_select_flags[i].group == 88 && a_select_flags[i].level <= lev )
{
act_ref[max] = -a_select_flags[i].flag; /* Activation number */
- act_list[max++] = al_name + a_select_flags[i].desc; /* Description */
+ act_list[max++] = a_select_flags[i].desc; /* Description */
}
/* Select from that list, using the util.c function display_list to display the scrolled list */
@@ -2330,7 +2349,7 @@ void do_cmd_create_artifact(object_type *q_ptr)
* recipes as a createable item. Used to determine if we
* should extract from it.
*/
-bool_ alchemist_exists(int tval, int sval, int ego, int artifact)
+static bool_ alchemist_exists(int tval, int sval, int ego, int artifact)
{
int al_idx;
@@ -2359,19 +2378,24 @@ bool_ alchemist_exists(int tval, int sval, int ego, int artifact)
/*
* Hook to determine if an object can have things extracted from it.
*/
-bool_ item_tester_hook_extractable(object_type *o_ptr)
+bool item_tester_hook_extractable(object_type const *o_ptr)
{
/* No artifacts */
- if (artifact_p(o_ptr)) return (FALSE);
+ if (artifact_p(o_ptr))
+ {
+ return false;
+ }
/* No cursed things */
- if (cursed_p(o_ptr)) return (FALSE);
+ if (cursed_p(o_ptr))
+ {
+ return false;
+ }
/* If we REALLY wanted to rebalance alchemists,
* we'd test for 'fully identified this object kind' here.
*/
-
return ((o_ptr->tval == TV_ROD_MAIN && o_ptr->pval != 0)
|| alchemist_exists(o_ptr->tval, o_ptr->sval, o_ptr->name2, o_ptr->name1));
}
@@ -2379,7 +2403,7 @@ bool_ item_tester_hook_extractable(object_type *o_ptr)
/*
* Hook to determine if an object is empowerable (NOT rechargeable)
*/
-bool_ item_tester_hook_empower(object_type *o_ptr)
+static bool item_tester_hook_empower(object_type const *o_ptr)
{
int sval = -1;
int lev = get_skill(SKILL_ALCHEMY);
@@ -2391,14 +2415,14 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Never Empower a cursed item */
if ( cursed_p(o_ptr))
{
- return FALSE;
+ return false;
}
/* Allow finalizing a self created artifact */
if (artifact_p(o_ptr)
&& (o_ptr->art_flags4 & TR4_ART_EXP)
&& !(o_ptr->art_flags4 & TR4_ULTIMATE))
- return TRUE;
+ return true;
switch ( o_ptr->tval)
{
@@ -2435,7 +2459,7 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Disallow ego dragon armour before you can create artifacts.*/
case TV_DRAG_ARMOR:
if ( lev < 25)
- return FALSE;
+ return false;
/* FALL THROUGH! no break here. */
/* weapons */
@@ -2471,24 +2495,24 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Disallow ANY creation of ego items below level 5*/
if ( lev < 5)
- return FALSE;
+ return false;
/* empowering an ego item creates an artifact or a
* double ego item, disallow below level 25 */
if ( lev < 25 && o_ptr->name2)
- return FALSE;
+ return false;
/* Disallow double-ego and artifact unless the character has
* the artifact creation ability. */
if (!has_ability(AB_CREATE_ART) &&
(artifact_p(o_ptr) || (o_ptr->name2 && o_ptr->name2b)))
- return FALSE;
+ return false;
/* Otherwise... */
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
/* Return to the traditional alchemist objects.
@@ -2501,7 +2525,7 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
if ((o_ptr->name2 || artifact_p(o_ptr)) &&
o_ptr->tval != TV_RING && o_ptr->tval != TV_AMULET)
- return FALSE;
+ return false;
/* return true if it's a 'of nothing' item;
* does nothing for TV_ROD_MAIN and TV_BOOK
@@ -2517,7 +2541,7 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
}
/* Extract a rod tip from a rod */
-void rod_tip_extract(object_type *o_ptr)
+static void rod_tip_extract(object_type *o_ptr)
{
object_type *q_ptr;
object_type forge;
@@ -2547,7 +2571,7 @@ void rod_tip_extract(object_type *o_ptr)
/* Begin & finish an art */
-void do_cmd_toggle_artifact(object_type *o_ptr)
+static void do_cmd_toggle_artifact(object_type *o_ptr)
{
char o_name[80];
@@ -2555,11 +2579,8 @@ void do_cmd_toggle_artifact(object_type *o_ptr)
{
bool_ okay = TRUE;
- if ( !alchemist_has_stone())
- {
- msg_print("Creating an artifact will result into a permanent loss of 10 hp.");
- if (!get_check("Are you sure you want to do that?")) return;
- }
+ msg_print("Creating an artifact will result into a permanent loss of 10 hp.");
+ if (!get_check("Are you sure you want to do that?")) return;
if (!magic_essence(get_skill(SKILL_ALCHEMY)))
{
@@ -2622,7 +2643,7 @@ void do_cmd_toggle_artifact(object_type *o_ptr)
* if tocreate=0, will return true if the player has enough
* in their p_ptr->inventory to empower that item.
*/
-bool_ alchemist_items_check(int tval, int sval, int ego, int tocreate, bool_ message)
+static bool_ alchemist_items_check(int tval, int sval, int ego, int tocreate, bool_ message)
{
int al_idx, j;
bool_ exists = FALSE;
@@ -2648,8 +2669,7 @@ bool_ alchemist_items_check(int tval, int sval, int ego, int tocreate, bool_ mes
/* Randomly decrease the number of essences created */
if ( randint(3) == 1
- && randint(52) > get_skill(SKILL_ALCHEMY)
- && !alchemist_has_stone())
+ && randint(52) > get_skill(SKILL_ALCHEMY))
o_ptr->number /= randint(2) + 1;
if ( o_ptr->number == 0)
continue;
@@ -2717,7 +2737,7 @@ bool_ alchemist_items_check(int tval, int sval, int ego, int tocreate, bool_ mes
/* This function lists all the ingredients
* needed to create something.
*/
-void alchemist_display_recipe(int tval, int sval, int ego)
+static void alchemist_display_recipe(int tval, int sval, int ego)
{
int al_idx;
int row = 1, col = 15;
@@ -2736,7 +2756,7 @@ void alchemist_display_recipe(int tval, int sval, int ego)
c_prt(TERM_GREEN,
format(" %d essence%s %s ", qty,
qty > 1 ? "s" : "",
- k_name + k_info[lookup_kind(TV_BATERIE, alchemist_recipes[al_idx].sval_essence)].name ),
+ k_info[lookup_kind(TV_BATERIE, alchemist_recipes[al_idx].sval_essence)].name),
row++, col);
}
@@ -2748,8 +2768,7 @@ void alchemist_display_recipe(int tval, int sval, int ego)
o_ptr = &forge;
object_prep(o_ptr, lookup_kind(tval, sval));
o_ptr->name2 = ego;
- hack_apply_magic_power = -99;
- apply_magic(o_ptr, get_skill(SKILL_ALCHEMY) * 2, FALSE, FALSE, FALSE);
+ apply_magic(o_ptr, get_skill(SKILL_ALCHEMY) * 2, FALSE, FALSE, FALSE, boost::make_optional(0));
object_aware(o_ptr);
object_known(o_ptr);
/* the 0 mode means only the text, leaving off any numbers */
@@ -2758,7 +2777,7 @@ void alchemist_display_recipe(int tval, int sval, int ego)
else
{
/* Display the ego item name */
- strcpy(o_name, e_name + e_info[ego].name);
+ strcpy(o_name, e_info[ego].name);
}
/* Display a short message about it, and wait for a key. */
@@ -2767,14 +2786,6 @@ void alchemist_display_recipe(int tval, int sval, int ego)
}
/*
- *
- * The alchemist_recipe_select was copied from
- * wiz_create_itemtype
- * and then changed quite a bit.
- *
- */
-
-/*
The select array is a simple array of 'use this char to select item x'
It has 88 items (three columns of 20 each)
selectitem is initilized with the reverse mappings:
@@ -2783,7 +2794,7 @@ void alchemist_display_recipe(int tval, int sval, int ego)
char selectchar[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*():;,.<=>[]{}/=?+'~";
byte selectitem[256];
-void strip_and_print(char *str, int color, int num)
+void strip_and_print(const char *str, int color, int num)
{
int row = 2 + (num % 20), col = 40 * (num / 20);
int ch, max_len = 0;
@@ -2830,11 +2841,235 @@ void strip_and_print(char *str, int color, int num)
c_prt(color, format("[%c] %s", ch, string), row, col);
}
+/* Display a list of known recipies that can be made with
+ * materials on hand (including the passed tval). Also
+ * calls the recipe_display function, if requested by the
+ * player or there aren't enough essences to make the
+ * requested object.
+ *
+ * Note: sval is ignored if !ego, tval is the only determinant
+ * of what recipies are available otherwise.
+ *
+ * This function needs to be able to scroll a list, because
+ * there are SO MANY potions. :)
+ */
+static int alchemist_recipe_select(int *tval, int sval, int ego, bool_ recipe)
+{
+ int i, mod40 = 0, num, max_num = 0;
+
+ cptr tval_desc2 = "";
+ char ch;
+ bool_ done = FALSE;
+
+ int choice[60];
+ int validc[60];
+
+ const char *string;
+
+
+ /* Save and clear the screen */
+ character_icky = TRUE;
+ Term_save();
+ Term_clear();
+
+ /* Base object type chosen, fill in tval */
+ for ( num = 0 ; num < 40 ; num ++)
+ if (tvals[num].tval == *tval)
+ {
+ tval_desc2 = tvals[num].desc;
+ }
+
+ while (!done)
+ {
+ Term_clear();
+ if (ego)
+ {
+ /* Find matching ego items */
+ for (num = 0, i = 1; (num < 40) && (i < max_e_idx) ; i++)
+ {
+ int j;
+ ego_item_type *e_ptr = &e_info[i];
+
+ /* Skip if unknown ego type */
+ if ( !(alchemist_known_egos[i / 32] & (1 << (i % 32))))
+ continue;
+
+ /* search in permitted tvals/svals for allowed egos */
+ for ( j = 0 ; j < 6 ; j ++ )
+ if ( e_ptr->tval[j] == *tval
+ && sval >= e_ptr->min_sval[j]
+ && sval <= e_ptr->max_sval[j])
+ {
+ int color = TERM_GREEN;
+
+ /*Reject if not opposite end of name
+ prefixes only on postfix egos,
+ postfixes only on prefix egos.
+ */
+ if (ego != -1 && e_ptr->before == e_info[ego].before)
+ continue;
+
+ /*Color it red of the alchemist doesn't have the essences to create it*/
+ if (!alchemist_items_check(*tval, 0, i, 0, TRUE))
+ color = TERM_RED;
+
+ /* add this ego to the list*/
+ strip_and_print(e_info[i].name, color, num);
+ validc[num] = color;
+ choice[num++] = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ char skipped = 0;
+ num = 0;
+ if (mod40 != 0)
+ {
+ strip_and_print("--MORE--", TERM_WHITE, num);
+ validc[num] = TERM_WHITE;
+ choice[num++] = -1;
+ }
+
+ for (i = 1; (num < 39) && (i < max_k_idx); i++)
+ {
+ object_kind *k_ptr = &k_info[i];
+
+ /* Analyze matching items */
+ if (k_ptr->tval == *tval || (k_ptr->tval == TV_POTION2 && *tval == TV_POTION))
+ {
+ char color = TERM_GREEN;
+ /* Hack -- Skip instant artifacts */
+ if (k_ptr->flags3 & (TR3_INSTA_ART)) continue;
+
+ /*Don't display recipes that the alchemist doesn't know about*/
+ if (!k_ptr->know && !wizard) continue;
+
+ /*Skip recipes that are somehow known, but don't exist*/
+ if (!alchemist_exists(k_ptr->tval, k_ptr->sval, 0, 0))
+ continue;
+
+ /* Skip the first 39 if they hit 'more' */
+ if (skipped++ < mod40*39)
+ continue;
+
+ /* Color 'unable to create' items different */
+ if (!alchemist_items_check(k_ptr->tval, k_ptr->sval, 0, 0, TRUE))
+ color = TERM_RED;
+
+ /* Acquire the "name" of object "i" */
+ /* and print it in it's place */
+ strip_and_print(k_ptr->name, color, num);
+
+ /* Remember the object index */
+ validc[num] = color;
+ choice[num++] = i;
+ }
+ }
+ if (num == 39)
+ {
+ strip_and_print("--MORE--", TERM_WHITE, num);
+ validc[num] = TERM_WHITE;
+ choice[num++] = -1;
+ }
+ }
+
+ /* We need to know the maximal possible remembered object_index */
+ max_num = num;
+ string = "What Kind of %s? (* to see recipe) [%c-%c,*]";
+ num = 0xff;
+
+ /* Pretend they're all undoable if we where called to display recipes */
+ if (recipe)
+ {
+ for ( num = 0 ; num < max_num ; num++)
+ if (validc[num] != TERM_WHITE) validc[num] = TERM_RED;
+ string = "show which %s recipe? [%c-%c]";
+ }
+
+ while (num == 0xff || num >= max_num)
+ {
+ ch = selectchar[max_num - 1];
+ /* Choose! */
+ if ( max_num == 0 || !get_com(format(string, tval_desc2, selectchar[0], ch), &ch))
+ {
+ break;
+ }
+
+ /* Extra breaks for recipe */
+ if (recipe && (ch == '\r' || ch == ' ' || ch == ESCAPE ))
+ break;
+
+ /* Analyze choice */
+ num = selectitem[(byte)ch];
+
+ /* Pretend that we don't have enough essences for anything */
+ if (ch == '*' )
+ {
+ for ( num = 0 ; num < max_num ; num++)
+ if (validc[num] != TERM_WHITE) validc[num] = TERM_RED;
+ string = "Show which %s recipe? [%c-%c]";
+ }
+ }
+ if ( num == 0xff || max_num == 0 || num >= max_num)
+ break;
+
+ if ( validc[num] == TERM_WHITE )
+ {
+ if (num == 0)
+ mod40--;
+ else
+ mod40++;
+ if ( mod40 < 0)
+ mod40 = 0;
+ continue;
+ }
+
+ /* If we don't have enough essences, or user asked for recipes */
+ if ( validc[num] != TERM_GREEN )
+ {
+ /* Display the recipe */
+ if (ego)
+ alchemist_display_recipe(*tval, sval, choice[num]);
+ else
+ alchemist_display_recipe(k_info[choice[num]].tval, k_info[choice[num]].sval, 0);
+ }
+ else
+ done = TRUE;
+
+ }/*while(!done)*/
+
+ /* Restore screen contents */
+ Term_load();
+ character_icky = FALSE;
+
+ /* User abort, or no choices */
+ if (max_num == 0 || num == 0xff || num >= max_num)
+ {
+ if (max_num == 0)
+ msg_print("You don't know of anything you can make using that.");
+ return ( -1);
+ }
+ if ( validc[num] != TERM_GREEN )
+ return ( -1);
+
+ /* And return successful */
+ if ( ego )
+ return choice[num];
+
+ /* Set the tval, should be the same unless they selected a potion2 */
+ if (*tval != k_info[choice[num]].tval && *tval != TV_POTION)
+ msg_print("Coding error: tval != TV_POTION");
+ *tval = k_info[choice[num]].tval;
+ return ( k_info[choice[num]].sval );
+}
+
/* Display a list of recipes that need a particular essence.
* Note that we display a list of essences first,
* so in effect, this is the alchemist's recipe book.
*/
-void alchemist_recipe_book(void)
+static void alchemist_recipe_book(void)
{
int num, max_num, i, al_idx, bat, kidx;
int choice[61], choice2[61];
@@ -2909,8 +3144,10 @@ void alchemist_recipe_book(void)
}
}
else
+ {
/* add this essence to the list*/
- strip_and_print(k_name + k_info[kidx].name, TERM_WHITE, num);
+ strip_and_print(k_info[kidx].name, TERM_WHITE, num);
+ }
choice[num++] = i;
}
@@ -3022,7 +3259,7 @@ void alchemist_recipe_book(void)
break;
}
}
- strcat(names, e_name + e_ptr->name);
+ strcat(names, e_ptr->name);
}
else
{
@@ -3039,7 +3276,7 @@ void alchemist_recipe_book(void)
break;
}
strcat(names, " of ");
- strcat(names, k_name + k_info[kidx].name);
+ strcat(names, k_info[kidx].name);
}
@@ -3108,230 +3345,6 @@ void alchemist_recipe_book(void)
character_icky = FALSE;
}
-/* Display a list of known recipies that can be made with
- * materials on hand (including the passed tval). Also
- * calls the recipe_display function, if requested by the
- * player or there aren't enough essences to make the
- * requested object.
- *
- * Note: sval is ignored if !ego, tval is the only determinant
- * of what recipies are available otherwise.
- *
- * This function needs to be able to scroll a list, because
- * there are SO MANY potions. :)
- */
-int alchemist_recipe_select(int *tval, int sval, int ego, bool_ recipe)
-{
- int i, mod40 = 0, num, max_num = 0;
-
- cptr tval_desc2 = "";
- char ch;
- bool_ done = FALSE;
-
- int choice[60];
- int validc[60];
-
- char *string;
-
-
- /* Save and clear the screen */
- character_icky = TRUE;
- Term_save();
- Term_clear();
-
- /* Base object type chosen, fill in tval */
- for ( num = 0 ; num < 40 ; num ++)
- if (tvals[num].tval == *tval)
- {
- tval_desc2 = tvals[num].desc;
- }
-
- while (!done)
- {
- Term_clear();
- if (ego)
- {
- /* Find matching ego items */
- for (num = 0, i = 1; (num < 40) && (i < max_e_idx) ; i++)
- {
- int j;
- ego_item_type *e_ptr = &e_info[i];
-
- /* Skip if unknown ego type */
- if ( !(alchemist_known_egos[i / 32] & (1 << (i % 32))))
- continue;
-
- /* search in permitted tvals/svals for allowed egos */
- for ( j = 0 ; j < 6 ; j ++ )
- if ( e_ptr->tval[j] == *tval
- && sval >= e_ptr->min_sval[j]
- && sval <= e_ptr->max_sval[j])
- {
- int color = TERM_GREEN;
-
- /*Reject if not opposite end of name
- prefixes only on postfix egos,
- postfixes only on prefix egos.
- */
- if (ego != -1 && e_ptr->before == e_info[ego].before)
- continue;
-
- /*Color it red of the alchemist doesn't have the essences to create it*/
- if (!alchemist_items_check(*tval, 0, i, 0, TRUE))
- color = TERM_RED;
-
- /* add this ego to the list*/
- strip_and_print(e_name + e_info[i].name, color, num);
- validc[num] = color;
- choice[num++] = i;
- break;
- }
- }
- }
- else
- {
- char skipped = 0;
- num = 0;
- if (mod40 != 0)
- {
- strip_and_print("--MORE--", TERM_WHITE, num);
- validc[num] = TERM_WHITE;
- choice[num++] = -1;
- }
-
- for (i = 1; (num < 39) && (i < max_k_idx); i++)
- {
- object_kind *k_ptr = &k_info[i];
-
- /* Analyze matching items */
- if (k_ptr->tval == *tval || (k_ptr->tval == TV_POTION2 && *tval == TV_POTION))
- {
- char color = TERM_GREEN;
- /* Hack -- Skip instant artifacts */
- if (k_ptr->flags3 & (TR3_INSTA_ART)) continue;
-
- /*Don't display recipes that the alchemist doesn't know about*/
- if (!k_ptr->know && !wizard) continue;
-
- /*Skip recipes that are somehow known, but don't exist*/
- if (!alchemist_exists(k_ptr->tval, k_ptr->sval, 0, 0))
- continue;
-
- /* Skip the first 39 if they hit 'more' */
- if (skipped++ < mod40*39)
- continue;
-
- /* Color 'unable to create' items different */
- if (!alchemist_items_check(k_ptr->tval, k_ptr->sval, 0, 0, TRUE))
- color = TERM_RED;
-
- /* Acquire the "name" of object "i" */
- /* and print it in it's place */
- strip_and_print(k_name + k_ptr->name, color, num);
-
- /* Remember the object index */
- validc[num] = color;
- choice[num++] = i;
- }
- }
- if (num == 39)
- {
- strip_and_print("--MORE--", TERM_WHITE, num);
- validc[num] = TERM_WHITE;
- choice[num++] = -1;
- }
- }
-
- /* We need to know the maximal possible remembered object_index */
- max_num = num;
- string = "What Kind of %s? (* to see recipe) [%c-%c,*]";
- num = 0xff;
-
- /* Pretend they're all undoable if we where called to display recipes */
- if (recipe)
- {
- for ( num = 0 ; num < max_num ; num++)
- if (validc[num] != TERM_WHITE) validc[num] = TERM_RED;
- string = "show which %s recipe? [%c-%c]";
- }
-
- while (num == 0xff || num >= max_num)
- {
- ch = selectchar[max_num - 1];
- /* Choose! */
- if ( max_num == 0 || !get_com(format(string, tval_desc2, selectchar[0], ch), &ch))
- {
- break;
- }
-
- /* Extra breaks for recipe */
- if (recipe && (ch == '\r' || ch == ' ' || ch == ESCAPE ))
- break;
-
- /* Analyze choice */
- num = selectitem[(byte)ch];
-
- /* Pretend that we don't have enough essences for anything */
- if (ch == '*' )
- {
- for ( num = 0 ; num < max_num ; num++)
- if (validc[num] != TERM_WHITE) validc[num] = TERM_RED;
- string = "Show which %s recipe? [%c-%c]";
- }
- }
- if ( num == 0xff || max_num == 0 || num >= max_num)
- break;
-
- if ( validc[num] == TERM_WHITE )
- {
- if (num == 0)
- mod40--;
- else
- mod40++;
- if ( mod40 < 0)
- mod40 = 0;
- continue;
- }
-
- /* If we don't have enough essences, or user asked for recipes */
- if ( validc[num] != TERM_GREEN )
- {
- /* Display the recipe */
- if (ego)
- alchemist_display_recipe(*tval, sval, choice[num]);
- else
- alchemist_display_recipe(k_info[choice[num]].tval, k_info[choice[num]].sval, 0);
- }
- else
- done = TRUE;
-
- }/*while(!done)*/
-
- /* Restore screen contents */
- Term_load();
- character_icky = FALSE;
-
- /* User abort, or no choices */
- if (max_num == 0 || num == 0xff || num >= max_num)
- {
- if (max_num == 0)
- msg_print("You don't know of anything you can make using that.");
- return ( -1);
- }
- if ( validc[num] != TERM_GREEN )
- return ( -1);
-
- /* And return successful */
- if ( ego )
- return choice[num];
-
- /* Set the tval, should be the same unless they selected a potion2 */
- if (*tval != k_info[choice[num]].tval && *tval != TV_POTION)
- msg_print("Coding error: tval != TV_POTION");
- *tval = k_info[choice[num]].tval;
- return ( k_info[choice[num]].sval );
-}
-
/* Set the 'known' flags for all objects with a level <= lev
* This lets the budding alchemist create basic items.
*/
@@ -3352,7 +3365,6 @@ void alchemist_learn_all(int lev)
void alchemist_learn_ego(int ego)
{
- char *name;
int i;
/* some Paranoia*/
@@ -3360,7 +3372,7 @@ void alchemist_learn_ego(int ego)
return;
/* Get the ego items name */
- name = e_name + e_info[ego].name;
+ const char *name = e_info[ego].name;
while (strchr(name, ' '))
name = strchr(name, ' ') + 1;
@@ -3369,7 +3381,6 @@ void alchemist_learn_ego(int ego)
if (alchemist_exists(0, 0, ego, 0))
{
alchemist_known_egos[ego / 32] |= (1 << (ego % 32));
- /* msg_format("You learn about '%s' ego items.",e_name+e_info[ego].name); */
}
else
{
@@ -3385,13 +3396,11 @@ void alchemist_learn_ego(int ego)
/* Look through all ego's for matching name */
/* Note that the original ego is marked here too */
for ( i = 0 ; i < max_e_idx ; i++ )
- if ( strstr(e_name + e_info[i].name, name) != NULL /*Last word of name exists in this ego's name*/
+ if ( strstr(e_info[i].name, name) != NULL /*Last word of name exists in this ego's name*/
&& alchemist_exists(0, 0, i, 0) /*There exists a recipe for this*/
&& !(alchemist_known_egos[i / 32] & (1 << (i % 32)) ) ) /*Not already known*/
- /*&& (e_name+e_info[i].name)[0])non-blank name*/
{
alchemist_known_egos[i / 32] |= (1 << (i % 32));
- /* msg_format("You learn about '%s' ego items.",e_name+e_info[i].name); */
}
return;
@@ -3443,7 +3452,7 @@ int alchemist_learn_object(object_type *o_ptr)
/* Alchemist has gained a level - set the ego flags
* for all egos <= lev/4.
*/
-void alchemist_gain_level(int lev)
+static void alchemist_gain_level(int lev)
{
object_type forge;
object_type *o_ptr = &forge;
@@ -3560,8 +3569,6 @@ void do_cmd_alchemist(void)
object_type forge, forge2;
byte carry_o_ptr = FALSE;
- cptr q, s;
-
/* With the new skill system, we can no longer depend on
* check_exp to handle the changes and learning involved in
* gaining levels.
@@ -3633,11 +3640,10 @@ void do_cmd_alchemist(void)
char o_name[200];
/* Get an item */
- q = "Empower which item? ";
- s = "You have no empowerable items.";
- item_tester_hook = item_tester_hook_empower;
-
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Empower which item? ",
+ "You have no empowerable items.",
+ (USE_INVEN | USE_FLOOR), item_tester_hook_empower)) return;
/* Get the item */
o_ptr = get_object(item);
@@ -3826,8 +3832,7 @@ void do_cmd_alchemist(void)
o_ptr = &forge;
object_wipe(o_ptr);
object_prep(o_ptr, lookup_kind(tval, sval));
- hack_apply_magic_power = -99;
- apply_magic(o_ptr, askill * 2, FALSE, FALSE, FALSE);
+ apply_magic(o_ptr, askill * 2, FALSE, FALSE, FALSE, boost::make_optional(0));
if ( o_ptr->tval == TV_WAND || o_ptr->tval == TV_STAFF)
o_ptr->pval = 0;
value = object_value_real(o_ptr);
@@ -3869,10 +3874,6 @@ void do_cmd_alchemist(void)
does the Philosopher's stone do?
Time*/
- /* 0% failure if you have the stone */
- if ( alchemist_has_stone())
- basechance = 0;
-
if (basechance > 0 && value)
{
char string[80];
@@ -3900,7 +3901,7 @@ void do_cmd_alchemist(void)
/* Redraw gold */
p_ptr->au -= i;
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Set fully identified
@@ -3936,7 +3937,7 @@ void do_cmd_alchemist(void)
msg_format("Your attempt backfires! Your %s explodes!", o_name);
take_hit(damroll(3, level - askill ) , "Alchemical Explosion");
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Combine / Reorder the pack (later) */
@@ -3963,12 +3964,12 @@ void do_cmd_alchemist(void)
object_type *s_ptr = NULL;
bool_ carry_s_ptr = FALSE;
- item_tester_hook = item_tester_hook_extractable;
-
/* Get an item */
- q = "Extract from which item? ";
- s = "You have no item to extract power from.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Extract from which item? ",
+ "You have no item to extract power from.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_extractable)) return;
/* Get the item */
o_ptr = get_object(item);
@@ -4130,8 +4131,7 @@ void do_cmd_alchemist(void)
s_ptr->number = 1;
/* Force creation of non ego non cursed */
- hack_apply_magic_power = -99;
- apply_magic(s_ptr, 0, FALSE, FALSE, FALSE);
+ apply_magic(s_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
/* Hack -- remove possible curse */
if (cursed_p(s_ptr))
@@ -4214,14 +4214,15 @@ void do_cmd_alchemist(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
- q = "Recharge which item? ";
- s = "You have no rechargable items.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR ))) return;
+ if (!get_item(&item,
+ "Recharge which item? ",
+ "You have no rechargable items.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_recharge()))
+ {
+ return;
+ }
/* Get the item */
o_ptr = get_object(item);
@@ -4298,7 +4299,7 @@ void do_cmd_pray(void)
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS |
PU_SANITY | PU_BODY);
- p_ptr->redraw |= PR_PIETY | PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP;
+ p_ptr->redraw |= PR_WIPE | PR_FRAME | PR_MAP;
energy_use = 100;
}
}
@@ -4404,7 +4405,7 @@ static random_spell* select_spell_from_batch(int batch)
mut_max = spell_num - batch * 10;
}
- strnfmt(tmp, 160, "(a-%c, A-%cto browse, / to rename, - to comment) Select a power: ",
+ strnfmt(tmp, 160, "(a-%c, A-%c to browse, / to rename, - to comment) Select a power: ",
I2A(mut_max - 1), I2A(mut_max - 1) - 'a' + 'A');
prt(tmp, 0, 0);
@@ -4686,7 +4687,7 @@ void do_cmd_powermage(void)
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
return;
}
@@ -4756,7 +4757,7 @@ void do_cmd_powermage(void)
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -4788,8 +4789,8 @@ void brand_ammo(int brand_type, int bolts_only)
if ((a < INVEN_PACK) && (rand_int(100) < 50))
{
object_type *o_ptr = &p_ptr->inventory[a];
- char *ammo_name;
- char *aura_name;
+ const char *ammo_name;
+ const char *aura_name;
char msg[48];
int aura_type, r;
@@ -4854,13 +4855,6 @@ void summon_monster(int sumtype)
/* Take a turn */
energy_use = 100;
- if (p_ptr->inside_arena)
- {
- msg_print("This place seems devoid of life.");
- msg_print(NULL);
- return;
- }
-
if (summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level + randint(5), sumtype, TRUE))
{
msg_print("You summon some help.");
@@ -4943,7 +4937,7 @@ void do_cmd_possessor()
p_ptr->chp = 1;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
}
}
}
@@ -4971,12 +4965,14 @@ void do_cmd_possessor()
/*
* Hook to determine if an object is contertible in an arrow/bolt
*/
-static bool_ item_tester_hook_convertible(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_convertible()
{
- if ((o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_SKELETON)) return TRUE;
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_JUNK),
+ TVal(TV_SKELETON));
+ return instance;
}
@@ -5091,14 +5087,12 @@ void do_cmd_archer(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_convertible;
-
/* Get an item */
- q = "Convert which item? ";
- s = "You have no item to convert.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Convert which item? ",
+ "You have no item to convert.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_convertible())) return;
/* Get local object */
q_ptr = &forge;
@@ -5129,14 +5123,12 @@ void do_cmd_archer(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_convertible;
-
/* Get an item */
- q = "Convert which item? ";
- s = "You have no item to convert.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Convert which item? ",
+ "You have no item to convert.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_convertible())) return;
/* Get local object */
q_ptr = &forge;
@@ -5337,7 +5329,7 @@ void do_cmd_necromancer(void)
p_ptr->chp_frac = 0;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -5471,7 +5463,7 @@ void do_cmd_necromancer(void)
p_ptr->chp_frac = 0;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -5529,72 +5521,29 @@ void do_cmd_necromancer(void)
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
}
-/* Runecrafters -- Move this into variable.c XXX XXX XXX */
-static s32b rune_combine = 0;
-
/*
* Hook to determine if an object is "runestone"
*/
-static bool_ item_tester_hook_runestone(object_type *o_ptr)
-{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval != RUNE_STONE) return (FALSE);
-
- if (o_ptr->pval != 0) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
-}
-
-
-static bool_ item_tester_hook_runestone_full(object_type *o_ptr)
-{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval != RUNE_STONE) return (FALSE);
-
- if (o_ptr->pval == 0) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
-}
-
-
-/*
- * Hook to determine if an object is "rune-able"
- */
-static bool_ item_tester_hook_runeable1(object_type *o_ptr)
+static bool item_tester_hook_runestone(object_type const *o_ptr)
{
- if (o_ptr->tval != TV_RUNE1) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval == RUNE_STONE) &&
+ (o_ptr->pval == 0));
}
-
-/*
- * Hook to determine if an object is "rune-able"
- */
-static bool_ item_tester_hook_runeable2(object_type *o_ptr)
+static bool item_tester_hook_runestone_full(object_type const *o_ptr)
{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval == RUNE_STONE) return (FALSE);
-
- if (rune_combine & BIT(o_ptr->sval)) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval == RUNE_STONE) &&
+ (o_ptr->pval != 0));
}
-
/*
* math.h(sqrt) is banned of angband so ... :)
*/
@@ -5761,7 +5710,7 @@ int rune_exec(rune_spell *spell, int cost)
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
return (mana_used);
}
@@ -5853,7 +5802,7 @@ int rune_exec(rune_spell *spell, int cost)
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
return (mana_used);
}
@@ -5902,44 +5851,43 @@ bool_ test_runespell(rune_spell *spell)
*/
bool_ get_runespell(rune_spell *spell)
{
- int item, power_rune = 0, rune2 = 0, plev = get_skill(SKILL_RUNECRAFT);
+ s32b rune_combine = 0;
- s32b power;
-
- int type = 0;
-
- object_type *o_ptr;
-
- cptr q, s;
+ /* Lambda to use for selecting the secondary rune(s) */
+ auto rune2_filter = [&](object_type const *o_ptr) -> bool {
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval != RUNE_STONE) &&
+ (!(rune_combine & BIT(o_ptr->sval))));
+ };
- bool_ OK = FALSE;
+ /* Prompt */
+ const char *const q = "Use which rune? ";
+ const char *const s = "You have no rune to use.";
+ /* Extract first rune for the base effect */
+ int type = 0;
+ {
+ int item;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), object_filter::TVal(TV_RUNE1)))
+ {
+ return FALSE;
+ }
- rune_combine = 0;
-
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runeable1;
-
- /* Get an item */
- q = "Use which rune? ";
- s = "You have no rune to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return FALSE;
-
- /* Get the item */
- o_ptr = get_object(item);
- type = o_ptr->sval;
+ object_type *o_ptr = get_object(item);
+ type = o_ptr->sval;
+ }
+ /* Choose secondary rune(s) */
+ int rune2 = 0;
while (1)
{
- /* Restrict choices to unused secondary runes */
- item_tester_hook = item_tester_hook_runeable2;
-
- OK = !get_item(&item, q, s, (USE_INVEN | USE_FLOOR));
-
- if (OK) break;
+ int item;
+ if (!get_item(&item, q, nullptr, (USE_INVEN | USE_FLOOR), rune2_filter))
+ {
+ break;
+ }
- /* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
rune_combine |= 1 << o_ptr->sval;
rune2 |= 1 << o_ptr->sval;
@@ -5951,9 +5899,14 @@ bool_ get_runespell(rune_spell *spell)
return (FALSE);
}
- power = get_quantity("Which amount of Mana?",
- p_ptr->csp - (power_rune * (plev / 5)));
- if (power < 1) power = 1;
+ int power_rune = 0;
+ int plev = get_skill(SKILL_RUNECRAFT);
+ s32b power = get_quantity("Which amount of Mana? ",
+ p_ptr->csp - (power_rune * (plev / 5)));
+ if (power < 1)
+ {
+ power = 1;
+ }
spell->mana = power;
spell->type = type;
@@ -6003,7 +5956,7 @@ void do_cmd_rune(void)
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6263,7 +6216,7 @@ void do_cmd_rune_cast()
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6274,10 +6227,6 @@ void do_cmd_runestone()
{
rune_spell s_ptr;
- object_type *o_ptr;
-
- cptr q, s;
-
int item;
@@ -6316,16 +6265,18 @@ void do_cmd_runestone()
return;
}
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runestone_full;
-
/* Get an item */
- q = "Cast from which runestone? ";
- s = "You have no runestone to cast from.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Cast from which runestone? ",
+ "You have no runestone to cast from.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_runestone_full))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
s_ptr.type = o_ptr->pval;
s_ptr.rune2 = o_ptr->pval2;
@@ -6342,7 +6293,7 @@ void do_cmd_runestone()
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6366,7 +6317,7 @@ void do_cmd_rune_add_mem()
if (rune_num >= MAX_RUNES)
{
- msg_print("You have already learn the maximun number of runespells!");
+ msg_print("You have already learned the maximum number of runespells!");
return;
}
@@ -6386,7 +6337,7 @@ void do_cmd_rune_add_mem()
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6397,10 +6348,6 @@ void do_cmd_rune_carve()
{
rune_spell s_ptr;
- object_type *o_ptr;
-
- cptr q, s;
-
int item, i;
char out_val[80];
@@ -6427,16 +6374,18 @@ void do_cmd_rune_carve()
if (!get_runespell(&s_ptr)) return;
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runestone;
-
/* Get an item */
- q = "Use which runestone? ";
- s = "You have no runestone to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Use which runestone? ",
+ "You have no runestone to use.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_runestone))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->pval = s_ptr.type;
o_ptr->pval2 = s_ptr.rune2;
@@ -6489,7 +6438,7 @@ void do_cmd_rune_carve()
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6531,7 +6480,7 @@ void do_cmd_rune_del()
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -6752,17 +6701,15 @@ void do_cmd_unbeliever()
/*
* Hook to determine if an object is totemable
*/
-static bool_ item_tester_hook_totemable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_totemable()
{
- /* Only full corpse */
- if ((o_ptr->tval == TV_CORPSE) &&
- ((o_ptr->sval == SV_CORPSE_CORPSE) || (o_ptr->sval == SV_CORPSE_SKELETON)))
- {
- return (TRUE);
- }
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = And(
+ TVal(TV_CORPSE),
+ Or(
+ SVal(SV_CORPSE_CORPSE),
+ SVal(SV_CORPSE_SKELETON)));
+ return instance;
}
@@ -6771,14 +6718,7 @@ static bool_ item_tester_hook_totemable(object_type *o_ptr)
*/
void do_cmd_summoner_extract()
{
- object_type *o_ptr, forge, *q_ptr;
-
- cptr q, s;
-
- int item, r;
-
- bool_ partial;
-
+ object_type forge, *q_ptr;
/* Not when confused */
if (p_ptr->confused)
@@ -6794,17 +6734,21 @@ void do_cmd_summoner_extract()
return;
}
- item_tester_hook = item_tester_hook_totemable;
-
/* Get an item */
- q = "Use which corpse? ";
- s = "You have no corpse to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Use which corpse? ",
+ "You have no corpse to use.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_totemable()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ bool_ partial;
if (r_info[o_ptr->pval2].flags1 & RF1_UNIQUE)
{
partial = FALSE;
@@ -6814,7 +6758,7 @@ void do_cmd_summoner_extract()
partial = get_check("Do you want to create a partial totem?");
}
- r = o_ptr->pval2;
+ int r = o_ptr->pval2;
inc_stack_size(item, -1);
@@ -6952,20 +6896,16 @@ void do_cmd_summoner_summon()
cptr q, s;
- object_type *o_ptr;
-
monster_type *m_ptr;
/* Which Totem? */
- item_tester_tval = TV_TOTEM;
-
q = "Summon from which Totem?";
s = "There are no totems to summon from!";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), object_filter::TVal(TV_TOTEM))) return;
/* Access the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a turn */
energy_use = 100;
@@ -7089,26 +7029,6 @@ void do_cmd_summoner(void)
/*
- * Fighters may invoke The Rush.
- */
-void do_cmd_blade(void)
-{
- /* Are we already Rushed? */
- if (p_ptr->rush)
- {
- msg_format("You have %d turns of The Rush remaining", p_ptr->rush);
- return;
- }
-
- /* Are you sure? */
- if (!get_check("Are you sure you want to invoke The Rush?")) return;
-
- /* Let's Rush! */
- set_rush(2 + p_ptr->lev / 2 + randint(p_ptr->lev / 2));
-}
-
-
-/*
* Dodge Chance Feedback.
*/
void use_ability_blade(void)
@@ -7327,19 +7247,18 @@ void do_cmd_symbiotic(void)
monster_type *m_ptr;
int m_idx;
int item, x, y, d;
- object_type *o_ptr;
-
- cptr q, s;
-
- /* Restrict choices to monsters */
- item_tester_tval = TV_HYPNOS;
/* Get an item */
- q = "Awaken which monster? ";
- s = "You have no monster to awaken.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Awaken which monster? ",
+ "You have no monster to awaken.",
+ (USE_FLOOR),
+ object_filter::TVal(TV_HYPNOS)))
+ {
+ return;
+ }
- o_ptr = &o_list[0 - item];
+ object_type *o_ptr = &o_list[0 - item];
d = 2;
while (d < 100)
@@ -7414,14 +7333,11 @@ void do_cmd_symbiotic(void)
p_ptr->chp = (percent1 * p_ptr->mhp) / 100;
o_ptr->pval2 = (percent1 * o_ptr->pval3) / 100;
- /* Redraw */
- p_ptr->redraw |= (PR_HP);
-
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
/* Display the monster hitpoints */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
break;
}
@@ -7459,7 +7375,7 @@ void do_cmd_symbiotic(void)
msg_format("%s is healed.", symbiote_name(TRUE));
/* Display the monster hitpoints */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
break;
}
@@ -7556,7 +7472,7 @@ void do_cmd_symbiotic(void)
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
diff --git a/src/cmd7.hpp b/src/cmd7.hpp
new file mode 100644
index 00000000..da96bb57
--- /dev/null
+++ b/src/cmd7.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "h-basic.h"
+#include "rune_spell_fwd.hpp"
+#include "object_type_fwd.hpp"
+
+extern void do_cmd_pray(void);
+extern void do_cmd_create_boulder(void);
+extern int rune_exec(rune_spell *spell, int cost);
+extern void necro_info(char *p, int power);
+extern void mindcraft_info(char *p, int power);
+extern void symbiotic_info(char *p, int power);
+extern void mimic_info(char *p, int power);
+extern void do_cmd_summoner(void);
+extern void do_cmd_mindcraft(void);
+extern void do_cmd_mimic(void);
+extern void use_ability_blade(void);
+extern int alchemist_learn_object(object_type *o_ptr);
+extern void do_cmd_alchemist(void);
+extern void do_cmd_beastmaster(void);
+extern void do_cmd_powermage(void);
+extern void do_cmd_possessor(void);
+extern void do_cmd_archer(void);
+extern void do_cmd_set_piercing(void);
+extern void do_cmd_necromancer(void);
+extern void do_cmd_unbeliever(void);
+extern void do_cmd_runecrafter(void);
+extern void do_cmd_symbiotic(void);
+extern s32b sroot(s32b n);
+extern int clamp_failure_chance(int chance, int minfail);
diff --git a/src/cmovie.c b/src/cmovie.c
deleted file mode 100644
index d1459e02..00000000
--- a/src/cmovie.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/* File: cmovie.c */
-
-/* Purpose: play cmovie files -DarkGod-Improv- */
-
-#include "angband.h"
-
-/*
- * Play a given cmovie
- */
-s16b do_play_cmovie(cptr cmov_file)
-{
- FILE *fff;
-
- int y, line = 0, x;
- int delay;
-
- char *s;
-
- char buf[1024];
- char cbuf[90];
- char ch;
-
- char mode = 0;
-
-
- /* Cmovie files are moved to the user directory on the multiuser systems */
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_CMOV, cmov_file);
-
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
-
- /* Read the file */
- fff = my_fopen(buf, "r");
-
- /* Failure */
- if (!fff) return ( -1);
-
- /* Save screen */
- character_icky = TRUE;
- Term_save();
- Term_clear();
-
- /* Give some usefull info */
- prt("While viewing the movie you can press Escape to exit, t/Space to switch between", 0, 0);
- prt("fluid more and step by step mode and any other key to step a frame in step by", 1, 0);
- prt("step mode.", 2, 0);
- prt("You can press D to do an html screenshot of the current frame.", 3, 0);
- prt("You can also use + and - to speed up/down the playing speed.", 5, 0);
- prt("Press any key when ready.", 8, 0);
-
- inkey();
-
- Term_clear();
-
- line = -1;
-
- delay = 1;
-
- /* Init to white */
- for (x = 0; x < 80; x++)
- {
- cbuf[x] = 'w';
- }
-
- /* Parse */
- while (0 == my_fgets(fff, buf, 1024))
- {
- /* Do not wait */
- inkey_scan = TRUE;
- ch = inkey();
-
- /* Stop */
- if (ch == ESCAPE) break;
-
- /* Change mode */
- else if (ch == 't')
- {
- mode = FALSE;
- }
- else if (ch == ' ')
- {
- mode = TRUE;
- }
-
- /* Change speed */
- else if (ch == '+')
- {
- delay--;
- if (delay < 0) delay = 0;
- }
- else if (ch == '-')
- {
- delay++;
- if (delay > 5) delay = 5;
- }
- else if (ch == 'D')
- {
- do_cmd_html_dump();
- }
-
- line++;
-
- /* Skip comments and blank lines */
- if (!buf[0] || (buf[0] == '#')) continue;
-
- /* Verify correct "colon" format */
- if (buf[1] != ':') break;
-
- /* Clean screen */
- if (buf[0] == 'C')
- {
- Term_clear();
-
- /* Next */
- continue;
- }
-
- /* Displays a textbox */
- if (buf[0] == 'B')
- {
- int len = strlen(buf + 2);
-
- /* Clear the line */
- Term_erase(0, 0, 255);
-
- /* Display the message */
- c_put_str(TERM_VIOLET, "###", 0, 0);
- c_put_str(TERM_ORANGE, buf + 2, 0, 3);
- c_put_str(TERM_VIOLET, "###", 0, 3 + len);
- c_put_str(TERM_WHITE, "(more)", 0, 6 + len);
-
- /* Next */
- continue;
- }
-
- /* Wait a key */
- if (buf[0] == 'W')
- {
- inkey();
-
- /* Next */
- continue;
- }
-
- /* Sleep */
- if (buf[0] == 'S')
- {
- long msec;
-
- /* Scan for the values */
- if (1 != sscanf(buf + 2, "%ld:", &msec))
- {
- return ( -2);
- }
-
- if (!mode)
- {
- Term_xtra(TERM_XTRA_DELAY, msec);
- }
- else
- {
- bool_ stop = FALSE;
-
- while (TRUE)
- {
- ch = inkey();
-
- /* Stop */
- if (ch == ESCAPE)
- {
- stop = TRUE;
- break;
- }
- /* Change mode */
- else if (ch == 't')
- {
- mode = FALSE;
- break;
- }
- /* Change mode */
- else if (ch == ' ')
- {
- if (mode) continue;
- mode = TRUE;
- break;
- }
- /* Change speed */
- else if (ch == '+')
- {
- delay--;
- if (delay < 0) delay = 0;
- }
- else if (ch == '-')
- {
- delay++;
- if (delay > 5) delay = 5;
- }
- else if (ch == 'D')
- {
- do_cmd_html_dump();
- }
- else break;
- }
- if (stop) break;
- }
-
- /* Next */
- continue;
- }
-
- /* Get color for the NEXT L line */
- if (buf[0] == 'E')
- {
- /* Find the colon before the name */
- s = strchr(buf + 2, ':');
-
- /* Verify that colon */
- if (!s) return ( -2);
-
- /* Nuke the colon, advance to the name */
- *s++ = '\0';
-
- /* Paranoia -- require a name */
- if (!*s) return ( -2);
-
- /* Get the index */
- y = atoi(buf + 2);
-
- C_COPY(cbuf, s, 80, char);
-
- /* Next... */
- continue;
- }
-
- /* Print a line */
- if (buf[0] == 'L')
- {
- /* Find the colon before the name */
- s = strchr(buf + 2, ':');
-
- /* Verify that colon */
- if (!s) return ( -2);
-
- /* Nuke the colon, advance to the name */
- *s++ = '\0';
-
- /* Paranoia -- require a name */
- if (!*s) return ( -2);
-
- /* Get the index */
- y = atoi(buf + 2);
-
- for (x = 0; x < 80; x++)
- {
- Term_putch(x, y, color_char_to_attr(cbuf[x]), s[x]);
-
- /* Reinit to white */
- cbuf[x] = 'w';
- }
- Term_redraw_section(0, y, 79, y);
-
- /* Next... */
- continue;
- }
-
- /* Update 1 char */
- if (buf[0] == 'P')
- {
- int x, y, a, c;
-
- /* Scan for the values */
- if (4 != sscanf(buf + 2, "%d:%d:%d:%d",
- &x, &y, &c, &a))
- {
- a = 'w';
- if (3 != sscanf(buf + 2, "%d:%d:%d",
- &x, &y, &c)) return ( -2);
- }
-
- Term_putch(x, y, color_char_to_attr(cbuf[x]), c);
- Term_redraw_section(x, y, x + 1, y + 1);
-
- /* Next... */
- continue;
- }
- }
-
- /* Load screen */
- Term_load();
- character_icky = FALSE;
-
- /* Close */
- my_fclose(fff);
-
- return (0);
-}
-
-
-/*
- * Start the recording of a cmovie
- */
-void do_record_cmovie(cptr cmovie)
-{
- char buf[1024];
- int fd = -1;
- int y;
-
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_CMOV, cmovie);
-
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
-
- /* Check for existing file */
- fd = fd_open(buf, O_RDONLY);
-
- /* Existing file */
- if (fd >= 0)
- {
- char out_val[160];
-
- /* Close the file */
- (void)fd_close(fd);
-
- /* Build query */
- (void)sprintf(out_val, "Replace existing file %s? ", cmovie);
-
- /* Ask */
- if (get_check(out_val)) fd = -1;
- }
-
- /* Be sure */
- if (!get_check("Ready to record(Press ctrl+D to enter a textual note while recording)?")) return;
-
- /* Open the non-existing file */
- if (fd < 0) movfile = my_fopen(buf, "w");
-
- /* Invalid file */
- if (movfile == NULL)
- {
- msg_format("Cmovie recording failed!");
-
- return;
- }
-
- /* First thing: Record clear screen then enable the recording */
- fprintf(movfile, "# Generated by %s\n",
- get_version_string());
- fprintf(movfile, "C:\n");
- last_paused = 0;
- do_movies = 1;
- cmovie_init_second();
-
- /* Mega Hack, get the screen */
- for (y = 0; y < Term->hgt; y++)
- {
- cmovie_record_line(y);
- }
-}
-
-
-/*
- * Stop the recording
- */
-void do_stop_cmovie()
-{
- if (do_movies == 1)
- {
- do_movies = 0;
- my_fclose(movfile);
- }
-}
-
-
-/*
- * Start a cmovie
- */
-void do_start_cmovie()
-{
- char name[90], rname[94];
-
-
- /* Should never happen */
- if (do_movies == 1) return;
-
- /* Default */
- sprintf(name, "%s", player_base);
-
- if (get_string("Cmovie name: ", name, 80))
- {
- if (name[0] && (name[0] != ' '))
- {
- sprintf(rname, "%s.cmv", name);
-
- if (get_check("Record(y), Play(n)?")) do_record_cmovie(rname);
- else do_play_cmovie(rname);
- }
- }
-}
-
-
-void cmovie_clean_line(int y, char *abuf, char *cbuf)
-{
- const byte *ap = Term->scr->a[y];
- const char *cp = Term->scr->c[y];
-
- byte a;
- char c;
-
- int x;
- int wid, hgt;
- int screen_wid, screen_hgt;
-
-
- /* Retrieve current screen size */
- Term_get_size(&wid, &hgt);
-
- /* Calculate the size of dungeon map area */
- screen_wid = wid - (COL_MAP + 1);
- screen_hgt = hgt - (ROW_MAP + 1);
-
- /* For the time being, assume 80 column display XXX XXX XXX */
- for (x = 0; x < wid; x++)
- {
- /* Convert dungeon map into default attr/chars */
- if (!character_icky &&
- ((x - COL_MAP) >= 0) &&
- ((x - COL_MAP) < screen_wid) &&
- ((y - ROW_MAP) >= 0) &&
- ((y - ROW_MAP) < screen_hgt))
- {
- /* Retrieve default attr/char */
- map_info_default(y + panel_row_prt, x + panel_col_prt, &a, &c);
-
- abuf[x] = conv_color[a & 0xf];
-
- if (c == '\0') cbuf[x] = ' ';
- else cbuf[x] = c;
- }
-
- else
- {
- abuf[x] = conv_color[ap[x] & 0xf];
- cbuf[x] = cp[x];
- }
- }
-
- /* Null-terminate the prepared strings */
- abuf[x] = '\0';
- cbuf[x] = '\0';
-}
-
-
-/*
- * Write a record of a screen row into a cmovie file
- */
-void cmovie_record_line(int y)
-{
- char abuf[256];
- char cbuf[256];
-
- cmovie_clean_line(y, abuf, cbuf);
-
- /* Write a colour record */
- fprintf(movfile, "E:%d:%.80s\n", y, abuf);
-
- /* Write a char record */
- fprintf(movfile, "L:%d:%.80s\n", y, cbuf);
-}
-
-
-/*
- * Record a "text box"
- */
-void do_cmovie_insert()
-{
- char buf[81] = "";
-
- /* Dont record */
- do_movies = 2;
-
- while (get_string("Textbox(ESC to end): ", buf, 80))
- {
- fprintf(movfile, "B:%s\nW:\n", buf);
- buf[0] = '\0';
- }
-
- /* We reinit the time as to not count the time the user needed ot enter the text */
- cmovie_init_second();
-
- /* Continue recording */
- do_movies = 1;
-}
diff --git a/src/config.h b/src/config.h
index cb258925..290ec624 100644
--- a/src/config.h
+++ b/src/config.h
@@ -30,16 +30,12 @@
* OPTION: See the Makefile(s), where several options may be declared.
*
* Some popular options include "USE_GCU" (allow use with Unix "curses"),
- * "USE_X11" (allow basic use with Unix X11) and "USE_XAW" (allow use with
- * Unix X11 plus the Athena Widget set).
+ * and "USE_X11" (allow basic use with Unix X11).
*
* The old "USE_NCU" option has been replaced with "USE_GCU".
*
* Several other such options are available for non-unix machines,
* such as "MACINTOSH", "WINDOWS".
- *
- * You may also need to specify the "system", using defines such as
- * "SOLARIS" (for Solaris), etc, see "h-config.h" for more info.
*/
@@ -60,53 +56,11 @@
/*
- * OPTION: Use "blocking getch() calls" in "main-gcu.c".
- * Hack -- Note that this option will NOT work on many BSD machines
- * Currently used whenever available, if you get a warning about
- * "nodelay()" undefined, then make sure to undefine this.
- */
-#if defined(SYS_V)
-# define USE_GETCH
-#endif
-
-
-/*
- * OPTION: Use the "curs_set()" call in "main-gcu.c".
- * Hack -- This option will not work on most BSD machines
- */
-#ifdef SYS_V
-# define USE_CURS_SET
-#endif
-
-
-/*
* OPTION: Include "ncurses.h" instead of "curses.h" in "main-gcu.c"
*/
/* #define USE_NCURSES */
-/*
- * OPTION: for multi-user machines running the game setuid to some other
- * user (like 'games') this SAFE_SETUID option allows the program to drop
- * its privileges when saving files that allow for user specified pathnames.
- * This lets the game be installed system wide without major security
- * concerns. There should not be any side effects on any machines.
- *
- * This will handle "gids" correctly once the permissions are set right.
- */
-#define SAFE_SETUID
-
-
-/*
- * This flag enables the "POSIX" methods for "SAFE_SETUID".
- */
-#if defined(_POSIX_SAVED_IDS) && !(defined(SUNOS) && !defined(SOLARIS)) && !defined(__APPLE__)
-# define SAFE_SETUID_POSIX
-#endif
-
-
-
-
/*
* OPTION: Maximum flow depth
@@ -117,18 +71,6 @@
/*
- * OPTION: Allow the use of "sound" in various places.
- */
-#define USE_SOUND
-
-/*
- * OPTION: Allow the use of "graphics" in various places
- */
-#define USE_GRAPHICS
-
-
-
-/*
* OPTION: Set the "default" path to the angband "lib" directory.
*
* See "main.c" for usage, and note that this value is only used on
@@ -157,13 +99,7 @@
/*
* Where to put the user's files.
*/
-#if defined(MACH_O_CARBON)
-#define PRIVATE_USER_PATH "~/Library/Application Support/ToME"
-#define PRIVATE_USER_PATH_DATA
-#define PRIVATE_USER_PATH_MODULES
-#else
#define PRIVATE_USER_PATH "~/.tome"
-#endif
/*
diff --git a/src/corrupt.c b/src/corrupt.cc
index a4c579d4..d1a7c530 100644
--- a/src/corrupt.c
+++ b/src/corrupt.cc
@@ -1,5 +1,35 @@
-#include "angband.h"
-#include <assert.h>
+#include "corrupt.hpp"
+
+#include "init1.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "stats.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <cassert>
+
+/**
+ * Corruptions
+ */
+typedef struct corruption_type corruption_type;
+struct corruption_type
+{
+ int modules[3]; /* Modules where this corruption is available; terminated with -1 entry */
+ byte color;
+ cptr group;
+ cptr name;
+ cptr get_text;
+ cptr lose_text; /* If NULL, the corruption is NOT removable by any means */
+ cptr desc;
+ s16b depends[5]; /* terminated by a -1 entry */
+ s16b opposes[5]; /* terminated by a -1 entry */
+ void (*gain_callback)(); /* callback to invoke when gained */
+ s16b power; /* index of granted power if >= 0, ignored otherwise */
+};
/**
* Vampire corruption helpers
@@ -57,18 +87,18 @@ static void player_gain_vampire()
player_race_mod *rmp_ptr = &race_mod_info[SUBRACE_SAVE];
/* Be a Vampire and be proud of it */
- cptr title = get_subrace_title(SUBRACE_SAVE);
- if (streq(title, " ") || streq(title, "Vampire"))
+ cptr title = rmp_ptr->title;
+ if (streq(title, "Vampire"))
{
title = "Vampire";
rmp_ptr->place = FALSE;
- set_subrace_title(SUBRACE_SAVE, title);
+ set_subrace_title(rmp_ptr, title);
}
else
{
char buf[512];
sprintf(buf, "Vampire %s", title);
- set_subrace_title(SUBRACE_SAVE, buf);
+ set_subrace_title(rmp_ptr, buf);
}
/* Bonus/and .. not bonus :) */
@@ -668,7 +698,6 @@ bool_ player_has_corruption(int corruption_idx)
static bool_ player_can_gain_corruption(int corruption_idx)
{
- cptr r_name = rp_ptr->title + rp_name;
bool_ allowed = TRUE; /* Allowed by default */
assert(corruption_idx >= 0);
@@ -676,7 +705,7 @@ static bool_ player_can_gain_corruption(int corruption_idx)
if (corruption_idx == CORRUPT_TROLL_BLOOD)
{
/* Ok trolls should not get this one. never. */
- if (streq(r_name, "Troll"))
+ if (streq(rp_ptr->title, "Troll"))
{
allowed = FALSE;
}
@@ -686,7 +715,7 @@ static bool_ player_can_gain_corruption(int corruption_idx)
if (game_module_idx == MODULE_THEME)
{
- if (streq(r_name, "Maia"))
+ if (streq(rp_ptr->title, "Maia"))
{
/* We use a whitelist of corruptions for Maiar */
bool_ allow = FALSE;
@@ -734,7 +763,7 @@ static bool_ player_allow_corruption(int corruption_idx)
/* Vampire teeth is special */
if (corruption_idx == CORRUPT_VAMPIRE_TEETH)
{
- if (PRACE_FLAG(PR1_NO_SUBRACE_CHANGE))
+ if (race_flags1_p(PR1_NO_SUBRACE_CHANGE))
{
return TRUE;
}
@@ -750,7 +779,7 @@ static bool_ player_allow_corruption(int corruption_idx)
static void player_set_corruption(int c, bool_ set)
{
p_ptr->corruptions[c] = set;
- p_ptr->redraw = p_ptr->redraw | PR_BASIC;
+ p_ptr->redraw = p_ptr->redraw | PR_FRAME;
p_ptr->update = p_ptr->update | PU_BONUS | PU_TORCH | PU_BODY | PU_POWERS;
}
diff --git a/src/corrupt.hpp b/src/corrupt.hpp
new file mode 100644
index 00000000..c200762e
--- /dev/null
+++ b/src/corrupt.hpp
@@ -0,0 +1,47 @@
+#include "h-basic.h"
+
+extern void gain_random_corruption();
+extern void dump_corruptions(FILE *OutFile, bool_ color, bool_ header);
+extern void lose_corruption();
+extern bool_ player_has_corruption(int corruption_idx);
+extern void player_gain_corruption(int corruption_idx);
+extern s16b get_corruption_power(int corruption_idx);
+
+/*
+ * Corruptions
+ */
+#define CORRUPT_BALROG_AURA 0
+#define CORRUPT_BALROG_WINGS 1
+#define CORRUPT_BALROG_STRENGTH 2
+#define CORRUPT_BALROG_FORM 3
+#define CORRUPT_DEMON_SPIRIT 4
+#define CORRUPT_DEMON_HIDE 5
+#define CORRUPT_DEMON_BREATH 6
+#define CORRUPT_DEMON_REALM 7
+#define CORRUPT_RANDOM_TELEPORT 8
+#define CORRUPT_ANTI_TELEPORT 9
+#define CORRUPT_TROLL_BLOOD 10
+#define CORRUPT_VAMPIRE_TEETH 11
+#define CORRUPT_VAMPIRE_STRENGTH 12
+#define CORRUPT_VAMPIRE_VAMPIRE 13
+#define MUT1_SPIT_ACID 14
+#define MUT1_BR_FIRE 15
+#define MUT1_HYPN_GAZE 16
+#define MUT1_TELEKINES 17
+#define MUT1_VTELEPORT 18
+#define MUT1_MIND_BLST 19
+#define MUT1_VAMPIRISM 20
+#define MUT1_SMELL_MET 21
+#define MUT1_SMELL_MON 22
+#define MUT1_BLINK 23
+#define MUT1_EAT_ROCK 24
+#define MUT1_SWAP_POS 25
+#define MUT1_SHRIEK 26
+#define MUT1_ILLUMINE 27
+#define MUT1_DET_CURSE 28
+#define MUT1_BERSERK 29
+#define MUT1_MIDAS_TCH 30
+#define MUT1_GROW_MOLD 31
+#define MUT1_RESIST 32
+#define MUT1_EARTHQUAKE 33
+#define CORRUPTIONS_MAX 34
diff --git a/src/defines.h b/src/defines.h
index d8a5d4f2..2c05acf5 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -46,11 +46,6 @@
#define SAVEFILE_VERSION 105
/*
- * This value is not currently used
- */
-#define VERSION_EXTRA 0
-
-/*
* Maximum amount of Angband windows.
*/
#define ANGBAND_TERM_MAX 8
@@ -126,17 +121,10 @@
#define CHANCE_TRAP_DOOR 500 /* in 10000 */
#define CHANCE_TRAP_FLOOR 4 /* in 10000 chance of placing a trap */
-#define MAX_BOUNTIES 24
-
#define MAX_SPELLS 100
#define MAX_RUNES 100
/*
- * Arena constants
- */
-#define MAX_ARENA_MONS 29 /* -KMW- */
-
-/*
* Total number of stores (see "store.c", etc)
*/
#define STORE_GENERAL 0
@@ -184,19 +172,6 @@
/*
- * Size of memory reserved for initialization of some arrays
- */
-#define FAKE_NAME_SIZE 40 * 1024L
-#define FAKE_TEXT_SIZE 120 * 1024L
-
-
-/*
- * Maximum number of high scores in the high score file
- */
-#define MAX_HISCORES 100
-
-
-/*
* Maximum dungeon level. The player can never reach this level
* in the dungeon, and this value is used for various calculations
* involving object and monster creation. It must be at least 100.
@@ -254,13 +229,6 @@
#define MACRO_MAX 256
/*
- * OPTION: Maximum number of "quarks" (see "io.c")
- * Default: assume at most 512 different inscriptions are used
- */
-#define QUARK_MAX 768
- /* Was 512... 256 quarks added for random artifacts */
-
-/*
* Maximum value storable in a "byte" (hard-coded)
*/
#define MAX_UCHAR 255
@@ -275,7 +243,6 @@
* Store constants
*/
#define STORE_INVEN_MAX 255 /* Max number of discrete objs in inven */
-#define STORE_CHOICES 56 /* Number of items to choose stock from */
#define STORE_OBJ_LEVEL 5 /* Magic Level for normal stores */
#define STORE_TURNOVER 9 /* Normal shop turnover, per day */
#define STORE_MIN_KEEP 6 /* Min slots to "always" keep full */
@@ -351,7 +318,6 @@
#define NASTY_MON 50 /* 1/chance of inflated monster level */
-
/*
* Refueling constants
*/
@@ -393,7 +359,6 @@
#define SUBRACE_SAVE 9 /* Ugly hack, should be in foo-info, the subrace saved to the savefile */
#define PY_MAX_EXP 99999999L /* Maximum exp */
#define PY_MAX_GOLD 999999999L /* Maximum gold */
-#define PY_MAX_LEVEL 50 /* Maximum level */
/*
* Player "food" crucial values
@@ -415,67 +380,11 @@
#define PY_REGEN_MNBASE 524 /* Min amount mana regen*2^16 */
/*
- * Maximum number of "normal" pack slots, and the index of the "overflow"
- * slot, which can hold an item, but only temporarily, since it causes the
- * pack to "overflow", dropping the "last" item onto the ground. Since this
- * value is used as an actual slot, it must be less than "INVEN_WIELD" (below).
- * Note that "INVEN_PACK" is probably hard-coded by its use in savefiles, and
- * by the fact that the screen can only show 23 items plus a one-line prompt.
- */
-#define INVEN_PACK 23
-
-/*
- * Body parts
- */
-#define BODY_WEAPON 0
-#define BODY_TORSO 1
-#define BODY_ARMS 2
-#define BODY_FINGER 3
-#define BODY_HEAD 4
-#define BODY_LEGS 5
-#define BODY_MAX 6
-
-/*
- * Indexes used for various "equipment" slots (hard-coded by savefiles, etc).
- */
-#define INVEN_WIELD 24 /* 3 weapons -- WEAPONS */
-#define INVEN_BOW 27 /* 1 bow -- WEAPON */
-#define INVEN_RING 28 /* 6 rings -- FINGER */
-#define INVEN_NECK 34 /* 2 amulets -- HEAD */
-#define INVEN_LITE 36 /* 1 lite -- TORSO */
-#define INVEN_BODY 37 /* 1 body -- TORSO */
-#define INVEN_OUTER 38 /* 1 cloak -- TORSO */
-#define INVEN_ARM 39 /* 3 arms -- ARMS */
-#define INVEN_HEAD 42 /* 2 heads -- HEAD */
-#define INVEN_HANDS 44 /* 3 hands -- ARMS */
-#define INVEN_FEET 47 /* 2 feets -- LEGS */
-#define INVEN_CARRY 49 /* 1 carried monster -- TORSO */
-#define INVEN_AMMO 50 /* 1 quiver -- TORSO */
-#define INVEN_TOOL 51 /* 1 tool -- ARMS */
-
-/*
- * Total number of inventory slots (hard-coded).
- */
-#define INVEN_TOTAL 52
-#define INVEN_EQ (INVEN_TOTAL - INVEN_WIELD)
-
-/*
* A "stack" of items is limited to less than 100 items (hard-coded).
*/
#define MAX_STACK_SIZE 100
-
-/*
- * Indexes of the various "stats" (hard-coded by savefiles, etc).
- */
-#define A_STR 0
-#define A_INT 1
-#define A_WIS 2
-#define A_DEX 3
-#define A_CON 4
-#define A_CHR 5
-
/*
* Player sex constants (hard-coded by save-files, arrays, etc)
*/
@@ -522,14 +431,9 @@
#define PR2_ASTRAL 0x00000002L /* Is it an astral being coming from th halls of mandos ? */
/* XXX */
-#define PRACE_FLAG2(f) ((rp_ptr->flags2 | rmp_ptr->flags2 | cp_ptr->flags2 | spp_ptr->flags2) & (f))
-#define PRACE_FLAG(f) ((rp_ptr->flags1 | rmp_ptr->flags1 | cp_ptr->flags1 | spp_ptr->flags1) & (f))
-#define PRACE_FLAGS(f) PRACE_FLAG(f)
-
/* XXX */
#define MKEY_MINDCRAFT 2
#define MKEY_ANTIMAGIC 3
-#define MKEY_BLADE 4
#define MKEY_ALCHEMY 5
#define MKEY_MIMIC 6
#define MKEY_NECRO 7
@@ -537,7 +441,6 @@
#define MKEY_RUNE 9
#define MKEY_FORGING 10
#define MKEY_INCARNATION 11
-#define MKEY_TELEKINESIS 12
#define MKEY_SUMMON 13
#define MKEY_TRAP 14
#define MKEY_STEAL 15
@@ -604,45 +507,6 @@
#define ROW_MH 19
#define COL_MH 0 /* "MH xxxxx/xxxxx" */
-#define ROW_INFO (Term->hgt - 4)
-#define COL_INFO 0 /* "xxxxxxxxxxxx" */
-
-#define ROW_CUT (Term->hgt - 3)
-#define COL_CUT 0 /* <cut> */
-
-#define ROW_STUN (Term->hgt - 2)
-#define COL_STUN 0 /* <stun> */
-
-#define ROW_HUNGRY (Term->hgt - 1)
-#define COL_HUNGRY 0 /* "Weak" / "Hungry" / "Full" / "Gorged" */
-
-#define ROW_BLIND (Term->hgt - 1)
-#define COL_BLIND 7 /* "Blind" */
-
-#define ROW_CONFUSED (Term->hgt - 1)
-#define COL_CONFUSED 13 /* "Conf" */
-
-#define ROW_AFRAID (Term->hgt - 1)
-#define COL_AFRAID 18 /* "Afraid" */
-
-#define ROW_POISONED (Term->hgt - 1)
-#define COL_POISONED 25 /* "Poison" */
-
-#define ROW_DTRAP (Term->hgt - 1)
-#define COL_DTRAP 32 /* "DTrap" */
-
-#define ROW_STATE (Term->hgt - 1)
-#define COL_STATE 38 /* <state> */
-
-#define ROW_SPEED (Term->hgt - 1)
-#define COL_SPEED 49 /* "Slow (-NN)" or "Fast (+NN)" */
-
-#define ROW_STUDY (Term->hgt - 1)
-#define COL_STUDY 60 /* "Study" */
-
-#define ROW_DEPTH (Term->hgt - 1)
-#define COL_DEPTH (Term->wid - 14) /* "Lev NNN" / "NNNN ft" */
-
/*** Terrain Feature Indexes (see "lib/edit/f_info.txt") ***/
@@ -724,9 +588,6 @@
/* Permanent walls for quests */
#define FEAT_QUEST1 0x4B
-#define FEAT_QUEST2 0x4C
-#define FEAT_QUEST3 0x4D
-#define FEAT_QUEST4 0x4E
/* Features 0x4F - 0x53 -- unused */
@@ -826,24 +687,6 @@
#define EFF_DIR8 0x00000200 /* Directed effect */
#define EFF_DIR9 0x00000400 /* Directed effect */
-/*
- * Wilderness terrains
- */
-#define TERRAIN_EDGE 0 /* Edge of the World */
-#define TERRAIN_TOWN 1 /* Town */
-#define TERRAIN_DEEP_WATER 2 /* Deep water */
-#define TERRAIN_SHALLOW_WATER 3 /* Shallow water */
-#define TERRAIN_SWAMP 4 /* Swamp */
-#define TERRAIN_DIRT 5 /* Dirt */
-#define TERRAIN_GRASS 6 /* Grass */
-#define TERRAIN_TREES 7 /* Trees */
-#define TERRAIN_DESERT 8 /* Desert */
-#define TERRAIN_SHALLOW_LAVA 9 /* Shallow lava */
-#define TERRAIN_DEEP_LAVA 10 /* Deep lava */
-#define TERRAIN_MOUNTAIN 11 /* Mountain */
-
-#define MAX_WILD_TERRAIN 18
-
/*** Artifact indexes (see "lib/edit/a_info.txt") ***/
@@ -1321,9 +1164,14 @@
#define ACT_BR_BALANCE 194
#define ACT_BR_LIGHT 195
#define ACT_BR_POWER 196
-#define ACT_GROW_MOLD 197
-#define ACT_MUSIC 200
-/* 170 -> unused */
+#define ACT_GROW_MOLD 197
+#define ACT_MUSIC 200
+#define ACT_ETERNAL_FLAME 201
+#define ACT_MAGGOT 202
+#define ACT_LEBOHAUM 203
+#define ACT_DURANDIL 204
+#define ACT_RADAGAST 205 /* Theme */
+#define ACT_VALAROMA 206 /* Theme */
/*** Object "tval" and "sval" codes ***/
@@ -1408,7 +1256,6 @@
/* The "sval" codes for TV_TOOL */
#define SV_TOOL_CLIMB 0
-#define SV_PORTABLE_HOLE 1
/* The "sval" codes for TV_MSTAFF */
#define SV_MSTAFF 1
@@ -2185,7 +2032,6 @@
#define USE_EQUIP 0x01 /* Allow equip items */
#define USE_INVEN 0x02 /* Allow inven items */
#define USE_FLOOR 0x04 /* Allow floor items */
-#define USE_EXTRA 0x08 /* Allow extra items */
#define USE_AUTO 0x10 /* Allow creation of automatizer rule */
/*
* Bit flags for the "p_ptr->notice" variable
@@ -2222,38 +2068,9 @@
/*
* Bit flags for the "p_ptr->redraw" variable
*/
-#define PR_MISC 0x00000001L /* Display Race/Class */
-#define PR_TITLE 0x00000002L /* Display Title */
-#define PR_LEV 0x00000004L /* Display Level */
-#define PR_EXP 0x00000008L /* Display Experience */
-#define PR_STATS 0x00000010L /* Display Stats */
-#define PR_ARMOR 0x00000020L /* Display Armor */
-#define PR_HP 0x00000040L /* Display Hitpoints */
-#define PR_MANA 0x00000080L /* Display Mana */
-#define PR_GOLD 0x00000100L /* Display Gold */
-#define PR_DEPTH 0x00000200L /* Display Depth */
-/****/
-#define PR_HEALTH 0x00000800L /* Display Health Bar */
-#define PR_CUT 0x00001000L /* Display Extra (Cut) */
-#define PR_STUN 0x00002000L /* Display Extra (Stun) */
-#define PR_HUNGER 0x00004000L /* Display Extra (Hunger) */
-#define PR_PIETY 0x00008000L /* Display Piety */
-#define PR_BLIND 0x00010000L /* Display Extra (Blind) */
-#define PR_CONFUSED 0x00020000L /* Display Extra (Confused) */
-#define PR_AFRAID 0x00040000L /* Display Extra (Afraid) */
-#define PR_POISONED 0x00080000L /* Display Extra (Poisoned) */
-#define PR_STATE 0x00100000L /* Display Extra (State) */
-#define PR_SPEED 0x00200000L /* Display Extra (Speed) */
-#define PR_STUDY 0x00400000L /* Display Extra (Study) */
-#define PR_SANITY 0x00800000L /* Display Sanity */
-#define PR_EXTRA 0x01000000L /* Display Extra Info */
-#define PR_BASIC 0x02000000L /* Display Basic Info */
+#define PR_FRAME 0x02000000L /* Display Basic Info */
#define PR_MAP 0x04000000L /* Display Map */
#define PR_WIPE 0x08000000L /* Hack -- Total Redraw */
-#define PR_MH 0x10000000L /* Display Monster hitpoints */
-#define PR_DTRAP 0x20000000L /* Display Extra (DTrap) */
-/* xxx */
-/* xxx */
/*
* Bit flags for the "p_ptr->window" variable (etc)
@@ -2862,9 +2679,6 @@
#define TR4_CHEAPNESS 0x00008000L /* Rod spells are cheaper(in mana cost) to cast */
#define TR4_FOUNTAIN 0x00010000L /* Available as fountain (for potions) */
#define TR4_ANTIMAGIC_50 0x00020000L /* Forbid magic */
-#define TR4_ANTIMAGIC_30 0x00040000L /* Forbid magic */
-#define TR4_ANTIMAGIC_20 0x00080000L /* Forbid magic */
-#define TR4_ANTIMAGIC_10 0x00100000L /* Forbid magic */
#define TR4_EASY_USE 0x00200000L /* Easily activable */
#define TR4_IM_NETHER 0x00400000L /* Immunity to nether */
#define TR4_RECHARGED 0x00800000L /* Object has been recharged once */
@@ -3042,11 +2856,6 @@
-/*** Monster blow constants ***/
-
-#define MODIFY_AUX(o, n) ((o) = modify_aux((o), (n) >> 2, (n) & 3))
-#define MODIFY(o, n, min) MODIFY_AUX(o, n); (o) = ((o) < (min))?(min):(o)
-
/*
* New monster blow methods
*/
@@ -3120,7 +2929,6 @@
/*** Monster flag values (hard-coded) ***/
#define MONSTER_LEVEL_MAX 150
-#define MONSTER_EXP(level) ((((level) > MONSTER_LEVEL_MAX)?MONSTER_LEVEL_MAX:(level)) * (((level) > MONSTER_LEVEL_MAX)?MONSTER_LEVEL_MAX:(level)) * (((level) > MONSTER_LEVEL_MAX)?MONSTER_LEVEL_MAX:(level)) * 6)
/*
* New monster race bit flags
@@ -3361,7 +3169,6 @@
#define RF7_AI_PLAYER 0x00020000 /* Controlled by the player */
#define RF7_NO_THEFT 0x00040000 /* Monster is immune to theft */
#define RF7_SPIRIT 0x00080000 /* This is a Spirit, coming from the Void */
-#define RF7_IM_MELEE 0x00100000 /* IM melee */
/*
@@ -3468,386 +3275,10 @@
#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)
-
-
-/*
- * Determine if a given inventory item is "known"
- * Test One -- Check for special "known" tag
- * 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) \
- (((T)->tval == TV_RANDART) ? \
- random_artifacts[(T)->sval].attr : \
- (k_info[(T)->k_idx].flavor) ? \
- misc_to_attr[k_info[(T)->k_idx].flavor] : \
- k_info[(T)->k_idx].x_attr)
-
-#define object_attr_default(T) \
- (((T)->tval == TV_RANDART) ? \
- random_artifacts[(T)->sval].attr : \
- (k_info[(T)->k_idx].flavor) ? \
- misc_to_attr[k_info[(T)->k_idx].flavor] : \
- k_info[(T)->k_idx].d_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)
-
-#define object_char_default(T) \
- ((k_info[(T)->k_idx].flavor) ? \
- misc_to_char[k_info[(T)->k_idx].flavor] : \
- k_info[(T)->k_idx].d_char)
-
-
-
-/*
- * Artifacts use the "name1" field
- */
-#define artifact_p(T) \
- ( \
- ((T)->tval == TV_RANDART || \
- ((T)->name1 ? TRUE : FALSE) || \
- ((T)->art_name ? TRUE : FALSE) || \
- ((k_info[(T)->k_idx].flags3 & TR3_NORM_ART)? TRUE : FALSE)) \
- )
-
-/*
- * Ego-Items use the "name2" field
- */
-#define ego_item_p(T) \
- ((T)->name2 || (T)->name2b ? TRUE : FALSE)
-
-/*
- * Ego-Items use the "name2" field
- */
-#define is_ego_p(T, e) \
- (((T)->name2 == (e)) || ((T)->name2b == (e)))
-
-
-
-/*
- * 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 fully inside the outer walls
- */
-#define in_bounds(Y,X) \
- (((Y) > 0) && ((X) > 0) && ((Y) < cur_hgt-1) && ((X) < cur_wid-1))
-
-/*
- * Determines if a map location is on or inside the outer walls
- */
-#define in_bounds2(Y,X) \
- (((Y) >= 0) && ((X) >= 0) && ((Y) < cur_hgt) && ((X) < cur_wid))
-
-
-/*
- * Determines if a map location is currently "on screen" -RAK-
- * Note that "panel_contains(Y,X)" always implies "in_bounds2(Y,X)".
- */
-#define panel_contains(Y,X) \
- (((Y) >= panel_row_min) && ((Y) <= panel_row_max) && \
- ((X) >= panel_col_min) && ((X) <= panel_col_max))
-
-
-
-/*
- * Determine if a "legal" grid is a "floor" grid
- *
- * 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.
- *
- * Add in the fact that some new terrain (water & lava) do NOT block sight
- * -KMW-
- */
-#define cave_floor_bold(Y,X) \
- ((f_info[cave[Y][X].feat].flags1 & FF1_FLOOR) && \
- (cave[Y][X].feat != FEAT_MON_TRAP))
-
-
-/*
- * Determine if a "legal" grid is floor without the REMEMBER flag set
- * Sometimes called "boring" grid
- */
-#define cave_plain_floor_bold(Y,X) \
- ((f_info[cave[Y][X].feat].flags1 & FF1_FLOOR) && \
- !(f_info[cave[Y][X].feat].flags1 & FF1_REMEMBER))
-
-
-/*
- * Determine if a "legal" grid isn't a "blocking line of sight" grid
- *
- * 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.
- *
- * Add in the fact that some new terrain (water & lava) do NOT block sight
- * -KMW-
- */
-#define cave_sight_bold(Y,X) \
- (!(f_info[cave[Y][X].feat].flags1 & FF1_NO_VISION))
-
-
-/*
- * Determine if a "legal" grid is a "clean" floor grid
- *
- * Line 1 -- forbid non-floors
- * Line 2 -- forbid deep water -KMW-
- * Line 3 -- forbid deep lava -KMW-
- * Line 4 -- forbid normal objects
- */
-#define cave_clean_bold(Y,X) \
- ((f_info[cave[Y][X].feat].flags1 & FF1_FLOOR) && \
- (cave[Y][X].feat != FEAT_MON_TRAP) && \
- (cave[Y][X].o_idx == 0) && \
- !(f_info[cave[Y][X].feat].flags1 & FF1_PERMANENT))
-
-
-/*
- * Determine if a "legal" grid is an "empty" floor grid
- *
- * Line 1 -- forbid doors, rubble, seams, walls
- * Line 2 -- forbid normal monsters
- * Line 3 -- forbid the player
- */
-#define cave_empty_bold(Y,X) \
- (cave_floor_bold(Y,X) && \
- !(cave[Y][X].m_idx) && \
- !(((Y) == p_ptr->py) && ((X) == p_ptr->px)))
-
-
-/*
- * Determine if a "legal" grid is an "naked" floor grid
- *
- * Line 1 -- forbid non-floors, non-shallow water & lava -KMW-
- * Line 2 -- forbid normal objects
- * Line 3 -- forbid player/monsters
- */
-#define cave_naked_bold(Y,X) \
- ((f_info[cave[Y][X].feat].flags1 & FF1_FLOOR) && \
- (cave[Y][X].feat != FEAT_MON_TRAP) && \
- !(f_info[cave[Y][X].feat].flags1 & FF1_PERMANENT) && \
- (cave[Y][X].o_idx == 0) && \
- (cave[Y][X].m_idx == 0))
-
-#define cave_naked_bold2(Y,X) \
- ((f_info[cave[Y][X].feat].flags1 & FF1_FLOOR) && \
- (cave[Y][X].feat != FEAT_MON_TRAP) && \
- (cave[Y][X].o_idx == 0) && \
- (cave[Y][X].m_idx == 0))
-
-
-
-/*
- * Determine if a "legal" grid is "permanent"
- *
- * Line 1 -- perma-walls
- * Line 2-3 -- stairs
- * Line 4-5 -- building doors -KMW-
- * Line 6-7 -- shop doors
- */
-#define cave_perma_bold(Y,X) \
- (f_info[cave[Y][X].feat].flags1 & FF1_PERMANENT)
-
-
-/*
- * Grid based version of "cave_floor_bold()"
- */
-#define cave_floor_grid(C) \
- ((f_info[(C)->feat].flags1 & FF1_FLOOR) && ((C)->feat != FEAT_MON_TRAP))
-
-
-/*
- * Grid based version of "cave_plain_floor_bold()"
- */
-#define cave_plain_floor_grid(C) \
- ((f_info[(C)->feat].flags1 & FF1_FLOOR) && \
- !(f_info[(C)->feat].flags1 & FF1_REMEMBER))
-
-
-/*
- * Grid based version of "cave_clean_bold()"
- */
-#define cave_clean_grid(C) \
- ((f_info[(C)->feat].flags1 & FF1_FLOOR) && ((C)->feat != FEAT_MON_TRAP) && \
- (!(C)->o_idx))
-
-/*
- * Grid based version of "cave_sight_bold()"
- */
-#define cave_sight_grid(C) \
- (!(f_info[(C)->feat].flags1 & FF1_NO_VISION))
-
-/*
- * Grid based version of "cave_empty_bold()"
- */
-#define cave_empty_grid(C) \
- (cave_floor_grid(C) && \
- !((C)->m_idx) && \
- !((C) == &cave[p_ptr->py][p_ptr->px]))
-
-/*
- * Grid based version of "cave_empty_bold()"
- */
-#define cave_naked_grid(C) \
- ((f_info[(C)->feat].flags1 & FF1_FLOOR) && ((C)->feat != FEAT_MON_TRAP) && \
- !((C)->o_idx) && \
- !((C)->m_idx) && \
- !((C) == &cave[p_ptr->py][p_ptr->px]))
-
-
-/*
- * Grid based version of "cave_perma_bold()"
- */
-#define cave_perma_grid(C) \
- (f_info[(C)->feat].flags1 & FF1_PERMANENT)
-
-
-
-/*
- * Determine if a "legal" grid is within "los" of the player
- *
- * Note the use of comparison to zero to force a "boolean" result
- */
-#define player_has_los_bold(Y,X) \
- ((cave[Y][X].info & (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[Y][X].info & (CAVE_SEEN)) != 0)
-
-
-
-/*** Color constants ***/
-
-
-/*
- * Angband "attributes" (with symbols, and base (R,G,B) codes)
- *
- * The "(R,G,B)" codes are given in "fourths" of the "maximal" value,
- * and should "gamma corrected" on most (non-Macintosh) machines.
- */
-#define TERM_DARK 0 /* 'd' */ /* 0,0,0 */
-#define TERM_WHITE 1 /* 'w' */ /* 4,4,4 */
-#define TERM_SLATE 2 /* 's' */ /* 2,2,2 */
-#define TERM_ORANGE 3 /* 'o' */ /* 4,2,0 */
-#define TERM_RED 4 /* 'r' */ /* 3,0,0 */
-#define TERM_GREEN 5 /* 'g' */ /* 0,2,1 */
-#define TERM_BLUE 6 /* 'b' */ /* 0,0,4 */
-#define TERM_UMBER 7 /* 'u' */ /* 2,1,0 */
-#define TERM_L_DARK 8 /* 'D' */ /* 1,1,1 */
-#define TERM_L_WHITE 9 /* 'W' */ /* 3,3,3 */
-#define TERM_VIOLET 10 /* 'v' */ /* 4,0,4 */
-#define TERM_YELLOW 11 /* 'y' */ /* 4,4,0 */
-#define TERM_L_RED 12 /* 'R' */ /* 4,0,0 */
-#define TERM_L_GREEN 13 /* 'G' */ /* 0,4,0 */
-#define TERM_L_BLUE 14 /* 'B' */ /* 0,4,4 */
-#define TERM_L_UMBER 15 /* 'U' */ /* 3,2,1 */
-
-
-/*** Graphics constants ***/
-
-/*
- * Possible values of graphics_mode
- * Good only when use_graphics is set to TRUE
- * Set by reset_visuals() and used by map_info()
- */
-#define GRAPHICS_NONE 0
-#define GRAPHICS_UNKNOWN 1
-#define GRAPHICS_IBM 2
-#define GRAPHICS_OLD 3
-#define GRAPHICS_NEW 4
-#define GRAPHICS_ISO 5
-
/*** Sound constants ***/
-/*
- * Mega-Hack -- some primitive sound support (see "main-win.c")
- *
- * Some "sound" constants for "Term_xtra(TERM_XTRA_SOUND, val)"
- */
#define SOUND_HIT 1
#define SOUND_MISS 2
#define SOUND_FLEE 3
@@ -3938,55 +3369,34 @@
#define BACT_RESEARCH_ITEM 1
#define BACT_TOWN_HISTORY 2
#define BACT_RACE_LEGENDS 3
-#define BACT_GREET_KING 4
#define BACT_KING_LEGENDS 5
#define BACT_QUEST1 6
-#define BACT_POSTER 8
-#define BACT_ARENA_RULES 9
-#define BACT_ARENA 10
-#define BACT_ARENA_LEGENDS 11
#define BACT_IN_BETWEEN 12
#define BACT_GAMBLE_RULES 13
#define BACT_CRAPS 14
-#define BACT_SPIN_WHEEL 15
#define BACT_DICE_SLOTS 16
#define BACT_REST 17
#define BACT_FOOD 18
#define BACT_RUMORS 19
#define BACT_RESEARCH_MONSTER 20
#define BACT_COMPARE_WEAPONS 21
-#define BACT_LEGENDS 22
#define BACT_ENCHANT_WEAPON 23
#define BACT_ENCHANT_ARMOR 24
#define BACT_RECHARGE 25
#define BACT_IDENTS 26
-#define BACT_LEARN 27
#define BACT_HEALING 28
#define BACT_RESTORE 29
#define BACT_ENCHANT_ARROWS 30
#define BACT_ENCHANT_BOW 31
-#define BACT_GREET 32
#define BACT_RECALL 33
#define BACT_TELEPORT_LEVEL 34
-/* XXX */
-/* XXX */
#define BACT_MIMIC_NORMAL 37
-#define BACT_VIEW_BOUNTIES 38
-#define BACT_SELL_CORPSES 39
-#define BACT_VIEW_QUEST_MON 40
-#define BACT_SELL_QUEST_MON 41
#define BACT_DIVINATION 42
#define BACT_SELL 43
#define BACT_BUY 44
#define BACT_EXAMINE 45
#define BACT_STEAL 46
-#define BACT_QUEST2 47
-#define BACT_QUEST3 48
-#define BACT_QUEST4 49
#define BACT_STAR_HEAL 50
-#define BACT_REQUEST_ITEM 51
-#define BACT_GET_LOAN 52
-#define BACT_PAY_BACK_LOAN 53
#define BACT_DROP_ITEM 54
#define BACT_GET_ITEM 55
#define BACT_FIREPROOF_QUEST 56
@@ -4114,13 +3524,7 @@
* Various class dependant defines
*/
#define CLASS_NONE 0
-#define CLASS_MANA_PATH 1
-#define CLASS_CANALIZE_MANA 2
-#define CLASS_WINDS_MANA 3
-#define CLASS_MANA_PATH_ERASE 0x0001
-#define CLASS_FLOOD_LEVEL 0x0002
-#define CLASS_CANALIZE_MANA_EXTRA 0x0004
#define CLASS_UNDEAD 0x0008
#define CLASS_ANTIMAGIC 0x0010
#define CLASS_LEGS 0x0020
@@ -4142,14 +3546,6 @@
#define NOTE_SAVE_GAME 3
#define NOTE_ENTER_DUNGEON 4
-/*
- * Player monsters & ghost defines
- * NO MORE USED but for savefile compatibility
- */
-#define GHOST_R_IDX_HEAD 967
-#define GHOST_R_IDX_TAIL 977
-#define MAX_GHOSTS (GHOST_R_IDX_TAIL - GHOST_R_IDX_HEAD)
-
/* Stores/buildings defines */
#define STORE_HATED 0
#define STORE_LIKED 1
@@ -4180,8 +3576,6 @@
#define MEGO_CHANCE 18 /* % chances of getting ego monsters */
-#define race_inf(m_ptr) (((m_ptr)->sr_ptr) ? (m_ptr)->sr_ptr : race_info_idx((m_ptr)->r_idx, (m_ptr)->ego))
-
/* Object generation */
#define OBJ_GENE_TREASURE 20
#define OBJ_GENE_COMBAT 20
@@ -4196,7 +3590,6 @@
/* Town defines */
#define TOWN_RANDOM 20 /* First random town */
-#define TOWN_DUNGEON 4 /* Maximun number of towns per dungeon */
#define TOWN_CHANCE 50 /* Chance of 1 town */
@@ -4216,80 +3609,6 @@
#define SF1_MUSEUM 0x00000400L
/*
- * Powers (mutation, activations, ...)
- */
-#define POWER_MAX 65
-
-#define PWR_SPIT_ACID 0
-#define PWR_BR_FIRE 1
-#define PWR_HYPN_GAZE 2
-#define PWR_TELEKINES 3
-#define PWR_VTELEPORT 4
-#define PWR_MIND_BLST 5
-#define PWR_RADIATION 6
-#define PWR_VAMPIRISM 7
-#define PWR_SMELL_MET 8
-#define PWR_SMELL_MON 9
-#define PWR_BLINK 10
-#define PWR_EAT_ROCK 11
-#define PWR_SWAP_POS 12
-#define PWR_SHRIEK 13
-#define PWR_ILLUMINE 14
-#define PWR_DET_CURSE 15
-#define PWR_BERSERK 16
-#define PWR_POLYMORPH 17
-#define PWR_MIDAS_TCH 18
-#define PWR_GROW_MOLD 19
-#define PWR_RESIST 20
-#define PWR_EARTHQUAKE 21
-#define PWR_EAT_MAGIC 22
-#define PWR_WEIGH_MAG 23
-#define PWR_STERILITY 24
-#define PWR_PANIC_HIT 25
-#define PWR_DAZZLE 26
-#define PWR_DARKRAY 27
-#define PWR_RECALL 28
-#define PWR_BANISH 29
-#define PWR_COLD_TOUCH 30
-#define PWR_LAUNCHER 31
-
-#define PWR_PASSWALL 32
-#define PWR_DETECT_TD 33
-#define PWR_COOK_FOOD 34
-#define PWR_UNFEAR 35
-#define PWR_EXPL_RUNE 36
-#define PWR_STM 37
-#define PWR_POIS_DART 38
-#define PWR_MAGIC_MISSILE 39
-#define PWR_GROW_TREE 40
-#define PWR_BR_COLD 41
-#define PWR_BR_CHAOS 42
-#define PWR_BR_ELEM 43
-#define PWR_WRECK_WORLD 44
-#define PWR_SCARE 45
-#define PWR_REST_LIFE 46
-#define PWR_SUMMON_MONSTER 47
-#define PWR_NECRO 48
-#define PWR_ROHAN 49
-#define PWR_THUNDER 50
-#define PWR_DEATHMOLD 51
-#define PWR_HYPNO 52
-#define PWR_UNHYPNO 53
-#define PWR_INCARNATE 54
-#define PWR_MAGIC_MAP 55
-#define PWR_LAY_TRAP 56
-#define PWR_MERCHANT 57
-#define PWR_COMPANION 58
-#define PWR_BEAR 59
-#define PWR_DODGE 60
-#define PWR_BALROG 61
-#define POWER_INVISIBILITY 62
-#define POWER_WEB 63
-#define POWER_COR_SPACE_TIME 64
-
-#define ADD_POWER(pow, p) ((pow)[(p)] = TRUE)
-
-/*
* Shield effect options
*/
#define SHIELD_NONE 0x0000
@@ -4355,45 +3674,6 @@
#define MAX_MODULES 2
/*
- * Corruptions
- */
-#define CORRUPT_BALROG_AURA 0
-#define CORRUPT_BALROG_WINGS 1
-#define CORRUPT_BALROG_STRENGTH 2
-#define CORRUPT_BALROG_FORM 3
-#define CORRUPT_DEMON_SPIRIT 4
-#define CORRUPT_DEMON_HIDE 5
-#define CORRUPT_DEMON_BREATH 6
-#define CORRUPT_DEMON_REALM 7
-#define CORRUPT_RANDOM_TELEPORT 8
-#define CORRUPT_ANTI_TELEPORT 9
-#define CORRUPT_TROLL_BLOOD 10
-#define CORRUPT_VAMPIRE_TEETH 11
-#define CORRUPT_VAMPIRE_STRENGTH 12
-#define CORRUPT_VAMPIRE_VAMPIRE 13
-#define MUT1_SPIT_ACID 14
-#define MUT1_BR_FIRE 15
-#define MUT1_HYPN_GAZE 16
-#define MUT1_TELEKINES 17
-#define MUT1_VTELEPORT 18
-#define MUT1_MIND_BLST 19
-#define MUT1_VAMPIRISM 20
-#define MUT1_SMELL_MET 21
-#define MUT1_SMELL_MON 22
-#define MUT1_BLINK 23
-#define MUT1_EAT_ROCK 24
-#define MUT1_SWAP_POS 25
-#define MUT1_SHRIEK 26
-#define MUT1_ILLUMINE 27
-#define MUT1_DET_CURSE 28
-#define MUT1_BERSERK 29
-#define MUT1_MIDAS_TCH 30
-#define MUT1_GROW_MOLD 31
-#define MUT1_RESIST 32
-#define MUT1_EARTHQUAKE 33
-#define CORRUPTIONS_MAX 34
-
-/*
* Races
*/
#define RACE_HUMAN 0
@@ -4428,7 +3708,6 @@
* Hooks
*/
#define HOOK_MONSTER_DEATH 0
-#define HOOK_OPEN 1
#define HOOK_GEN_QUEST 2
#define HOOK_END_TURN 3
#define HOOK_FEELING 4
@@ -4452,66 +3731,26 @@
#define HOOK_NEW_MONSTER_END 22
#define HOOK_AIM 24
#define HOOK_USE 25
-#define HOOK_ACTIVATE 26
-#define HOOK_ZAP 27
-#define HOOK_CALC_POWERS 30
-#define HOOK_KEYPRESS 31
#define HOOK_CHAT 32
#define HOOK_MON_SPEAK 33
#define HOOK_BIRTH_OBJECTS 35
-#define HOOK_ACTIVATE_DESC 36
-#define HOOK_INIT_GAME 37
-#define HOOK_ACTIVATE_POWER 38
-#define HOOK_ITEM_NAME 39
#define HOOK_SAVE_GAME 40
#define HOOK_LOAD_GAME 41
#define HOOK_LEVEL_REGEN 42
#define HOOK_LEVEL_END_GEN 43
-#define HOOK_BUILDING_ACTION 44
-#define HOOK_WIELD_SLOT 46
-#define HOOK_STORE_STOCK 47
#define HOOK_GEN_LEVEL_BEGIN 49
#define HOOK_GET 50
-#define HOOK_REDRAW 51
#define HOOK_RECALC_SKILLS 52
#define HOOK_ENTER_DUNGEON 53
-#define HOOK_FIRE 54
#define HOOK_EAT 55
#define HOOK_DIE 56
#define HOOK_CALC_HP 57
#define HOOK_CALC_MANA 60
-#define HOOK_LOAD_END 61
#define HOOK_RECALL 62
#define HOOK_BODY_PARTS 65
-#define HOOK_APPLY_MAGIC 66
-#define HOOK_PLAYER_EXP 67
-#define HOOK_BIRTH 68
#define HOOK_MON_ASK_HELP 69
-#define HOOK_LEARN_ABILITY 70
-#define HOOK_MOVED 71
#define HOOK_GAME_START 72
-#define HOOK_TAKEOFF 73
-#define HOOK_CALC_WEIGHT 74
#define HOOK_FORBID_TRAVEL 75
-#define HOOK_DEBUG_COMMAND 76
-#define MAX_HOOKS 77
-
-#define HOOK_TYPE_C 0
-#define HOOK_TYPE_NEW 2
-
-/*
- * Defines for loadsave.c
- * Why 3 and 7? So if it's uninitialized, the code will be able to catch it, as
- * 0 is an invalid flag. Also, having them apart means that it being accidentally
- * modified will also result in an invalid value -- Improv
- */
-#define LS_LOAD 3
-#define LS_SAVE 7
-
-/*
- * In game help
- */
-#define HELP_MAX 64
/*
* Special weapon effects
@@ -4540,69 +3779,6 @@
#define SKILL_EXCLUSIVE 9999 /* Flag to tell exclusive skills */
-#define SKILL_CONVEYANCE 1
-#define SKILL_MANA 2
-#define SKILL_FIRE 3
-#define SKILL_AIR 4
-#define SKILL_WATER 5
-#define SKILL_NATURE 6
-#define SKILL_EARTH 7
-#define SKILL_SYMBIOTIC 8
-#define SKILL_MUSIC 9
-#define SKILL_DIVINATION 10
-#define SKILL_TEMPORAL 11
-#define SKILL_DRUID 12
-#define SKILL_DAEMON 13
-#define SKILL_META 14
-#define SKILL_MAGIC 15
-#define SKILL_COMBAT 16
-#define SKILL_MASTERY 17
-#define SKILL_SWORD 18
-#define SKILL_AXE 19
-#define SKILL_POLEARM 20
-#define SKILL_HAFTED 21
-#define SKILL_BACKSTAB 22
-#define SKILL_ARCHERY 23
-#define SKILL_SLING 24
-#define SKILL_BOW 25
-#define SKILL_XBOW 26
-#define SKILL_BOOMERANG 27
-#define SKILL_SPIRITUALITY 28
-#define SKILL_MINDCRAFT 29
-#define SKILL_MISC 30
-#define SKILL_NECROMANCY 31
-#define SKILL_MIMICRY 32
-#define SKILL_ANTIMAGIC 33
-#define SKILL_RUNECRAFT 34
-#define SKILL_SNEAK 35
-#define SKILL_STEALTH 36
-#define SKILL_DISARMING 37
-/* XXX */
-#define SKILL_ALCHEMY 39
-#define SKILL_STEALING 40
-#define SKILL_SORCERY 41
-#define SKILL_HAND 42
-#define SKILL_THAUMATURGY 43
-#define SKILL_SUMMON 44
-#define SKILL_SPELL 45
-#define SKILL_DODGE 46
-#define SKILL_BEAR 47
-#define SKILL_LORE 48
-#define SKILL_PRESERVATION 49
-#define SKILL_POSSESSION 50
-#define SKILL_MIND 51
-#define SKILL_CRITS 52
-#define SKILL_PRAY 53
-#define SKILL_LEARN 54
-#define SKILL_UDUN 55
-#define SKILL_DEVICE 56
-#define SKILL_STUN 57
-#define SKILL_BOULDER 58
-#define SKILL_GEOMANCY 59
-
-/* Ugly but needed */
-#define MAX_SKILLS 200
-
/* Number of skill choices for Lost Sword quests. */
#define LOST_SWORD_NSKILLS 4
@@ -4613,11 +3789,6 @@
#define MAX_MELEE 3
-/*
- * Player specialities, should be external but ti would be a mess
- */
-#define MAX_SPEC 20
-
/*
* Spellbinder triggers
@@ -4642,10 +3813,6 @@
#define GOD_MANDOS 9
#define MAX_GODS 10
-#define GOD(g) if (p_ptr->pgod == (g))
-#define PRAY_GOD(g) if ((p_ptr->pgod == (g)) && (p_ptr->praying))
-#define NOT_PRAY_GOD(g) if ((p_ptr->pgod == (g)) && (!p_ptr->praying))
-
/*
* Command numbers for do_cmd_cli().
*
@@ -4728,3 +3895,21 @@
#define BOOK_RANDOM 255
#define SCHOOL_BOOKS_SIZE 256
+
+/**
+ * Macro to generate a memoizing named monster lookup function.
+ *
+ * This is meant as a stopgap measure until a better method
+ * can be implemented.
+ */
+#define GENERATE_MONSTER_LOOKUP_FN(fn, name) \
+ static int fn()\
+ {\
+ static int r_idx = -1;\
+ if (r_idx < 0)\
+ {\
+ r_idx = test_monster_name(name);\
+ assert(r_idx);\
+ }\
+ return r_idx;\
+ }
diff --git a/src/deity_type.hpp b/src/deity_type.hpp
new file mode 100644
index 00000000..0dcbb818
--- /dev/null
+++ b/src/deity_type.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+/**
+ * A structure for deity information.
+ */
+struct deity_type
+{
+ int modules[3]; /* terminated with -1 */
+ char const *name;
+ char desc[10][80];
+};
diff --git a/src/deity_type_fwd.hpp b/src/deity_type_fwd.hpp
new file mode 100644
index 00000000..492bf1fa
--- /dev/null
+++ b/src/deity_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct deity_type;
diff --git a/src/device_allocation.cc b/src/device_allocation.cc
new file mode 100644
index 00000000..ec2d208c
--- /dev/null
+++ b/src/device_allocation.cc
@@ -0,0 +1,20 @@
+#include "device_allocation.hpp"
+
+#include <cassert>
+
+static void device_allocation_init(device_allocation *device_allocation, byte tval)
+{
+ assert(device_allocation != NULL);
+
+ device_allocation->tval = tval;
+ device_allocation->rarity = 0;
+ range_init(&device_allocation->base_level, 0, 0);
+ range_init(&device_allocation->max_level, 0, 0);
+}
+
+device_allocation *device_allocation_new(byte tval)
+{
+ device_allocation *d = new device_allocation;
+ device_allocation_init(d, tval);
+ return d;
+}
diff --git a/src/device_allocation.hpp b/src/device_allocation.hpp
new file mode 100644
index 00000000..28854eac
--- /dev/null
+++ b/src/device_allocation.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "device_allocation_fwd.hpp"
+#include "range.hpp"
+
+/*
+ * Device allocation for skill
+ */
+struct device_allocation
+{
+ byte tval;
+ s32b rarity;
+ range_type base_level;
+ range_type max_level;
+};
+
+struct device_allocation *device_allocation_new(byte tval);
diff --git a/src/device_allocation_fwd.hpp b/src/device_allocation_fwd.hpp
new file mode 100644
index 00000000..70e53fca
--- /dev/null
+++ b/src/device_allocation_fwd.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+typedef struct device_allocation device_allocation;
+struct device_allocation;
+
+struct device_allocation *device_allocation_new(byte tval);
diff --git a/src/dice.cc b/src/dice.cc
new file mode 100644
index 00000000..637d2773
--- /dev/null
+++ b/src/dice.cc
@@ -0,0 +1,98 @@
+#include "dice.hpp"
+
+#include "z-rand.h"
+
+#include <cassert>
+
+void dice_init(dice_type *dice, long base, long num, long sides)
+{
+ assert(dice != NULL);
+
+ dice->base = base;
+ dice->num = num;
+ dice->sides = sides;
+}
+
+bool_ dice_parse(dice_type *dice, cptr s)
+{
+ long base, num, sides;
+
+ if (sscanf(s, "%ld+%ldd%ld", &base, &num, &sides) == 3)
+ {
+ dice_init(dice, base, num, sides);
+ return TRUE;
+ }
+
+ if (sscanf(s, "%ld+d%ld", &base, &sides) == 2)
+ {
+ dice_init(dice, base, 1, sides);
+ return TRUE;
+ }
+
+ if (sscanf(s, "d%ld", &sides) == 1)
+ {
+ dice_init(dice, 0, 1, sides);
+ return TRUE;
+ }
+
+ if (sscanf(s, "%ldd%ld", &num, &sides) == 2)
+ {
+ dice_init(dice, 0, num, sides);
+ return TRUE;
+ }
+
+ if (sscanf(s, "%ld", &base) == 1)
+ {
+ dice_init(dice, base, 0, 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void dice_parse_checked(dice_type *dice, cptr s)
+{
+ bool_ result = dice_parse(dice, s);
+ if (!result)
+ {
+ abort();
+ }
+}
+
+long dice_roll(dice_type *dice)
+{
+ assert(dice != NULL);
+ return dice->base + damroll(dice->num, dice->sides);
+}
+
+void dice_print(dice_type *dice, char *output)
+{
+ char buf[16];
+
+ output[0] = '\0';
+
+ if (dice->base > 0)
+ {
+ sprintf(buf, "%ld", dice->base);
+ strcat(output, buf);
+ }
+
+ if ((dice->num > 0) || (dice->sides > 0))
+ {
+ if (dice->base > 0)
+ {
+ strcat(output, "+");
+ }
+
+ if (dice->num > 1)
+ {
+ sprintf(buf, "%ld", dice->num);
+ strcat(output, buf);
+ }
+
+ strcat(output, "d");
+
+ sprintf(buf, "%ld", dice->sides);
+ strcat(output, buf);
+ }
+}
diff --git a/src/dice.hpp b/src/dice.hpp
new file mode 100644
index 00000000..40a49e37
--- /dev/null
+++ b/src/dice.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "dice_fwd.hpp"
+
+/**
+ * Dice
+ */
+struct dice_type
+{
+ long base; /* Base value to which roll is added. */
+ long num; /* Number of dice */
+ long sides; /* Sides per dice */
+};
diff --git a/src/dice_fwd.hpp b/src/dice_fwd.hpp
new file mode 100644
index 00000000..72b3b5ca
--- /dev/null
+++ b/src/dice_fwd.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "h-basic.h"
+
+typedef struct dice_type dice_type;
+struct dice_type;
+
+void dice_init(dice_type *dice, long base, long num, long sides);
+bool_ dice_parse(dice_type *dice, cptr s);
+void dice_parse_checked(dice_type *dice, cptr s);
+long dice_roll(dice_type *dice);
+void dice_print(dice_type *dice, char *buf);
diff --git a/src/dungeon.c b/src/dungeon.cc
index 8df85977..62eaf211 100644
--- a/src/dungeon.c
+++ b/src/dungeon.cc
@@ -1,7 +1,3 @@
-/* File: dungeon.c */
-
-/* Purpose: Angband game engine */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,23 +6,93 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include <assert.h>
-
-#include "quark.h"
-#include "spell_type.h"
+#include "dungeon.hpp"
+#include "dungeon.h"
+
+#include "birth.hpp"
+#include "birth.h"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd2.hpp"
+#include "cmd3.hpp"
+#include "cmd4.hpp"
+#include "cmd5.hpp"
+#include "cmd6.hpp"
+#include "cmd7.hpp"
+#include "corrupt.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.h"
+#include "files.hpp"
+#include "generate.hpp"
+#include "gen_evol.hpp"
+#include "gods.hpp"
+#include "help.hpp"
+#include "hooks.hpp"
+#include "init2.hpp"
+#include "levels.hpp"
+#include "loadsave.h"
+#include "loadsave.hpp"
+#include "lua_bind.hpp"
+#include "melee1.hpp"
+#include "melee2.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "modules.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_spec.hpp"
+#include "player_type.hpp"
+#include "powers.hpp"
+#include "quest.hpp"
+#include "quark.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells5.hpp"
+#include "squeltch.hpp"
+#include "stats.hpp"
+#include "store.hpp"
+#include "tables.hpp"
+#include "timer_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wild.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "wizard2.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <boost/filesystem.hpp>
+#include <cassert>
#define TY_CURSE_CHANCE 100
#define DG_CURSE_CHANCE 50
#define AUTO_CURSE_CHANCE 15
#define CHAINSWORD_NOISE 100
+/**
+ * Type of a "sense" function
+ */
+typedef byte (*sense_function_t)(object_type const *o_ptr);
/*
* Return a "feeling" (or NULL) about an item. Method 1 (Heavy).
*/
-byte value_check_aux1(object_type *o_ptr)
+static byte value_check_aux1(object_type const *o_ptr)
{
/* Artifacts */
if (artifact_p(o_ptr))
@@ -61,7 +127,7 @@ byte value_check_aux1(object_type *o_ptr)
return (SENSE_AVERAGE);
}
-byte value_check_aux1_magic(object_type *o_ptr)
+static byte value_check_aux1_magic(object_type const *o_ptr)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -128,7 +194,7 @@ byte value_check_aux1_magic(object_type *o_ptr)
/*
* Return a "feeling" (or NULL) about an item. Method 2 (Light).
*/
-byte value_check_aux2(object_type *o_ptr)
+static byte value_check_aux2(object_type const *o_ptr)
{
/* Cursed items (all of them) */
if (cursed_p(o_ptr)) return (SENSE_CURSED);
@@ -150,7 +216,7 @@ byte value_check_aux2(object_type *o_ptr)
}
-byte value_check_aux2_magic(object_type *o_ptr)
+static byte value_check_aux2_magic(object_type const *o_ptr)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -219,7 +285,7 @@ byte value_check_aux2_magic(object_type *o_ptr)
*/
static bool_ granted_resurrection(void)
{
- PRAY_GOD(GOD_ERU)
+ if (praying_to(GOD_ERU))
{
if (p_ptr->grace > 100000)
{
@@ -230,9 +296,8 @@ static bool_ granted_resurrection(void)
return (FALSE);
}
-static byte select_sense(object_type *o_ptr)
+static sense_function_t select_sense(object_type *o_ptr, sense_function_t combat, sense_function_t magic)
{
- /* Valid "tval" codes */
switch (o_ptr->tval)
{
case TV_SHOT:
@@ -257,8 +322,7 @@ static byte select_sense(object_type *o_ptr)
case TV_BOOMERANG:
case TV_TRAPKIT:
{
- return 1;
- break;
+ return combat;
}
case TV_POTION:
@@ -269,22 +333,21 @@ static byte select_sense(object_type *o_ptr)
case TV_ROD:
case TV_ROD_MAIN:
{
- return 2;
- break;
+ return magic;
}
/* Dual use? */
case TV_DAEMON_BOOK:
{
- return 1;
- break;
+ return combat;
}
}
- return 0;
+
+ return nullptr;
}
/*
- * Sense the inventory
+ * Sense quality of specific list of objects.
*
* Combat items (weapons and armour) - Fast, weak if combat skill < 10, strong
* otherwise.
@@ -296,21 +359,8 @@ static byte select_sense(object_type *o_ptr)
* they learn one form of ID or another, and because most magic items are
* easy_know.
*/
-void sense_inventory(void)
+void sense_objects(std::vector<int> const &object_idxs)
{
- int i, combat_lev, magic_lev;
-
- bool_ heavy_combat, heavy_magic;
-
- byte feel;
-
- object_type *o_ptr;
-
- char o_name[80];
-
-
- /*** Check for "sensing" ***/
-
/* No sensing when confused */
if (p_ptr->confused) return;
@@ -340,24 +390,21 @@ void sense_inventory(void)
*/
/* The combat skill affects weapon/armour pseudo-ID */
- combat_lev = get_skill(SKILL_COMBAT);
+ int combat_lev = get_skill(SKILL_COMBAT);
/* The magic skill affects magic item pseudo-ID */
- magic_lev = get_skill(SKILL_MAGIC);
+ int magic_lev = get_skill(SKILL_MAGIC);
/* Higher skill levels give the player better sense of items */
- heavy_combat = (combat_lev > 10) ? TRUE : FALSE;
- heavy_magic = (magic_lev > 10) ? TRUE : FALSE;
-
+ auto feel_combat = (combat_lev > 10) ? value_check_aux1 : value_check_aux2;
+ auto feel_magic = (magic_lev > 10) ? value_check_aux1_magic : value_check_aux2_magic;
/*** Sense everything ***/
/* Check everything */
- for (i = 0; i < INVEN_TOTAL; i++)
+ for (auto i : object_idxs)
{
- byte okay = 0;
-
- o_ptr = &p_ptr->inventory[i];
+ object_type *o_ptr = get_object(i);
/* Skip empty slots */
if (!o_ptr->k_idx) continue;
@@ -368,37 +415,39 @@ void sense_inventory(void)
/* It is fully known, no information needed */
if (object_known_p(o_ptr)) continue;
- /* Valid "tval" codes */
- okay = select_sense(o_ptr);
-
- /* Skip non-sense machines */
- if (!okay) continue;
+ /* Select appropriate sensing function, if any */
+ sense_function_t sense = select_sense(o_ptr, feel_combat, feel_magic);
- /* Check for a feeling */
- if (okay == 1)
- {
- feel = (heavy_combat ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
- }
- else
+ /* Skip non-sensed items */
+ if (!sense)
{
- feel = (heavy_magic ? value_check_aux1_magic(o_ptr) : value_check_aux2_magic(o_ptr));
+ continue;
}
+ /* Check for a feeling */
+ byte feel = sense(o_ptr);
+
/* Skip non-feelings */
- if (feel == SENSE_NONE) continue;
+ if (feel == SENSE_NONE)
+ {
+ continue;
+ }
/* Get an object description */
+ char o_name[80];
object_desc(o_name, o_ptr, FALSE, 0);
- /* Message (equipment) */
- if (i >= INVEN_WIELD)
+ /* Messages */
+ if (i < 0) {
+ // We get a message from the floor handling code, so
+ // it would be overkill to have a message here too.
+ }
+ else if (i >= INVEN_WIELD)
{
msg_format("You feel the %s (%c) you are %s %s %s...",
o_name, index_to_label(i), describe_use(i),
((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
}
-
- /* Message (inventory) */
else
{
msg_format("You feel the %s (%c) in your pack %s %s...",
@@ -423,6 +472,20 @@ void sense_inventory(void)
squeltch_inventory();
}
+void sense_inventory(void)
+{
+ static std::vector<int> idxs;
+ // Initialize static vector if necessary
+ if (idxs.empty())
+ {
+ idxs.reserve(INVEN_TOTAL);
+ for (int i = 0; i < INVEN_TOTAL; i++)
+ {
+ idxs.push_back(i);
+ }
+ }
+ sense_objects(idxs);
+}
/*
* Go to any level (ripped off from wiz_jump)
@@ -632,7 +695,7 @@ static void regenhp(int percent)
if (old_chp != p_ptr->chp)
{
/* Redraw */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -689,7 +752,7 @@ static void regenmana(int percent)
if (old_csp != p_ptr->csp)
{
/* Redraw */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -737,7 +800,7 @@ static void regen_monsters(void)
if (o_ptr->pval2 > o_ptr->pval3) o_ptr->pval2 = o_ptr->pval3;
/* Redraw (later) */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
}
}
@@ -774,7 +837,7 @@ static void regen_monsters(void)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == i) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == i) p_ptr->redraw |= (PR_FRAME);
}
}
}
@@ -785,7 +848,7 @@ static void regen_monsters(void)
*
* Should belong to object1.c, renamed to object_decays() -- pelpel
*/
-bool_ decays(object_type *o_ptr)
+static bool_ decays(object_type *o_ptr)
{
u32b f1, f2, f3, f4, f5, esp;
@@ -805,117 +868,6 @@ static int process_lasting_spell(s16b music)
return spell_type_produce_effect_lasting(spell);
}
-static void gere_class_special()
-{
- switch (p_ptr->druid_extra2)
- {
- /* Lay a path of mana on the floor */
- case CLASS_MANA_PATH:
- {
- /* Does the player have enought mana ? */
- if (p_ptr->csp < (s32b)(p_ptr->druid_extra & 255))
- {
- p_ptr->druid_extra = 0;
- p_ptr->druid_extra2 = CLASS_NONE;
- msg_print("You stop laying a mana path.");
- }
- else
- {
- /* Use some mana */
- p_ptr->csp -= (p_ptr->druid_extra & 255);
-
- if ((p_ptr->druid_extra >> 8) & CLASS_MANA_PATH_ERASE)
- {
- /* Absorb some of the mana of the grid */
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 50;
- if (p_ptr->csp > p_ptr->msp) p_ptr->csp = p_ptr->msp;
-
- /* Set the new grid mana */
- cave[p_ptr->py][p_ptr->px].mana = p_ptr->druid_extra & 255;
- }
- else
- {
- int m = cave[p_ptr->py][p_ptr->px].mana;
-
- if (m + (p_ptr->druid_extra & 255) > 255)
- {
- cave[p_ptr->py][p_ptr->px].mana = 255;
- }
- else
- {
- cave[p_ptr->py][p_ptr->px].mana += p_ptr->druid_extra & 255;
- }
- }
- }
-
- break;
- }
-
- /* Lay a path of mana on the floor */
- case CLASS_WINDS_MANA:
- {
- /* Does the player have enought mana ? */
- if (p_ptr->csp < (s32b)(p_ptr->druid_extra & 255))
- {
- p_ptr->druid_extra = CLASS_NONE;
- msg_print("You stop expulsing mana winds.");
- }
- else
- {
- int dam = 0;
-
- /* Use some mana */
- p_ptr->csp -= (p_ptr->druid_extra & 255);
-
- if ((p_ptr->druid_extra >> 8) & CLASS_MANA_PATH_ERASE)
- {
- dam = (p_ptr->druid_extra & 255) + 256;
- }
- else
- {
- dam = (p_ptr->druid_extra & 255);
- }
-
- fire_explosion(p_ptr->py, p_ptr->px, GF_WINDS_MANA, 2, dam);
- }
-
- break;
- }
-
- case CLASS_CANALIZE_MANA:
- {
- if (p_ptr->druid_extra & CLASS_CANALIZE_MANA_EXTRA)
- {
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 10;
- }
- else
- {
- p_ptr->csp += cave[p_ptr->py][p_ptr->px].mana / 20;
- }
-
- if (p_ptr->csp > p_ptr->msp) p_ptr->csp = p_ptr->msp;
-
- cave[p_ptr->py][p_ptr->px].mana = 0;
-
- break;
- }
-
- /* CLASS_NONE, possibly others? */
- default:
- {
- /* No mana update */
- return;
- }
- }
-
- /* Redraw mana */
- p_ptr->update |= (PU_BONUS);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-}
-
-
static void check_music()
{
int use_mana;
@@ -929,14 +881,13 @@ static void check_music()
{
msg_print("You stop your spell.");
p_ptr->music_extra = 0;
- p_ptr->music_extra2 = 0;
}
else
{
p_ptr->csp -= use_mana;
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -947,7 +898,7 @@ static void check_music()
/*
* Generate the feature effect
*/
-void apply_effect(int y, int x)
+static void apply_effect(int y, int x)
{
cave_type *c_ptr = &cave[y][x];
@@ -992,7 +943,7 @@ void apply_effect(int y, int x)
/* XXX XXX XXX */
-bool_ is_recall = FALSE;
+static bool_ is_recall = FALSE;
/*
@@ -1012,7 +963,7 @@ static void process_world_corruptions()
}
else
{
- disturb(0, 0);
+ disturb(0);
msg_print("Your corruption takes over you, you teleport!");
teleport_player(50);
}
@@ -1067,10 +1018,10 @@ static bool_ grace_delay_trigger()
*/
static void process_world_gods()
{
- const char *race_name = rp_ptr->title + rp_name;
- const char *subrace_name = rmp_ptr->title + rmp_name;
+ const char *race_name = rp_ptr->title;
+ const char *subrace_name = rmp_ptr->title;
- GOD(GOD_VARDA)
+ if (p_ptr->pgod == GOD_VARDA)
{
if (grace_delay_trigger())
{
@@ -1100,7 +1051,7 @@ static void process_world_gods()
}
}
- GOD(GOD_ULMO)
+ if (p_ptr->pgod == GOD_ULMO)
{
if (grace_delay_trigger())
{
@@ -1142,7 +1093,7 @@ static void process_world_gods()
}
}
- GOD(GOD_AULE)
+ if (p_ptr->pgod == GOD_AULE)
{
if (grace_delay_trigger())
{
@@ -1224,7 +1175,7 @@ static void process_world_gods()
}
}
- GOD(GOD_MANDOS)
+ if (p_ptr->pgod == GOD_MANDOS)
{
if (grace_delay_trigger())
{
@@ -1327,9 +1278,6 @@ static void process_world(void)
}
}
- /* Handle class special actions */
- gere_class_special();
-
/* Check the fate */
if (fate_option && (p_ptr->lev > 10))
{
@@ -1458,104 +1406,10 @@ static void process_world(void)
get_month_name(bst(DAY, turn), wizard, FALSE), buf);
}
- /* Set back the rewards once a day */
- if ((turn % (10L * STORE_TURNS)) == 0)
- {
- /* Select new bounties. */
- if (magik(20)) select_bounties();
- }
-
- /* Modify loan */
- if (p_ptr->loan)
- {
- if (p_ptr->loan_time) p_ptr->loan_time--;
-
- if (((turn % 5000) == 0) && !p_ptr->loan_time)
- {
- cmsg_print(TERM_RED, "You should pay your loan...");
-
- p_ptr->loan += p_ptr->loan / 12;
-
- if (p_ptr->loan > PY_MAX_GOLD) p_ptr->loan = PY_MAX_GOLD;
-
- /* Do a nasty stuff */
- if (p_ptr->wild_mode && rand_int(2))
- {
- /* Discount player items */
- int z = 0, tries = 200;
- object_type *o_ptr = NULL;
-
- while (tries--)
- {
- z = rand_int(INVEN_TOTAL);
- o_ptr = &p_ptr->inventory[z];
-
- if (!o_ptr->k_idx) continue;
-
- if (o_ptr->discount >= 100) continue;
-
- break;
- }
-
- if (tries)
- {
- o_ptr->discount += 70;
- if (o_ptr->discount >= 100) o_ptr->discount = 100;
-
- inven_item_optimize(z);
- inven_item_describe(z);
-
- p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
- }
- }
-
- else
- {
- int merc = test_monster_name("Mean-looking mercenary");
- int agent = test_monster_name("Agent of the black market");
- int num = 5 + (p_ptr->lev / 3), z;
-
- for (z = 0; z < num; z++)
- {
- int yy, xx, attempts = 200, m_idx;
-
- /* Summon */
- while (1)
- {
- scatter(&yy, &xx, p_ptr->py, p_ptr->px, 6);
-
- /* Accept an empty grid within the boundary */
- if (in_bounds(yy, xx) && cave_floor_bold(yy, xx)) break;
-
- /* Max number of retries reached */
- if (--attempts == 0) break;
- }
-
- /* All the attempts failed */
- if (attempts == 0) continue;
-
- /* Summon a monster */
- m_idx = place_monster_one(yy, xx, magik(80) ? merc : agent,
- 0, FALSE, MSTATUS_ENEMY);
-
- /* Level it */
- if (m_idx)
- {
- monster_type *m_ptr = &m_list[m_idx];
-
- m_ptr->exp = MONSTER_EXP(p_ptr->lev * 2);
- monster_check_experience(m_idx, TRUE);
- }
- }
- }
- }
- }
-
/*** Process the monsters ***/
/* Check for creature generation. */
if (!p_ptr->wild_mode &&
- !p_ptr->inside_arena &&
!p_ptr->inside_quest &&
(rand_int(d_info[(dun_level) ? dungeon_type : DUNGEON_WILDERNESS].max_m_alloc_chance) == 0))
{
@@ -1621,7 +1475,7 @@ static void process_world(void)
/* Drown in deep water unless the player have levitation, water walking
water breathing, or magic breathing.*/
- if (!p_ptr->ffall && !p_ptr->walk_water && !p_ptr->magical_breath &&
+ if (!p_ptr->ffall && !p_ptr->magical_breath &&
!p_ptr->water_breath &&
(cave[p_ptr->py][p_ptr->px].feat == FEAT_DEEP_WATER))
{
@@ -1657,7 +1511,7 @@ static void process_world(void)
{
/* Do nothing */
}
- else if (PRACE_FLAG(PR1_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_CAN_PASS))
+ else if (race_flags1_p(PR1_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_CAN_PASS))
{
int amt = 1 + ((p_ptr->lev) / 5);
@@ -1799,7 +1653,7 @@ static void process_world(void)
{
/* Message */
msg_print("You faint from the lack of food.");
- disturb(1, 0);
+ disturb(1);
/* Hack -- faint (bypass free action) */
(void)set_paralyzed(1 + rand_int(5));
@@ -1861,7 +1715,7 @@ static void process_world(void)
/* Eru piety incraese with time */
if (((turn % 100) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode))
{
- NOT_PRAY_GOD(GOD_ERU)
+ if ((p_ptr->pgod == GOD_ERU) && !p_ptr->praying)
{
int inc = wisdom_scale(10);
@@ -1873,47 +1727,65 @@ static void process_world(void)
/* Most gods piety decrease with time */
if (((turn % 300) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode) && (dun_level))
{
- GOD(GOD_MANWE)
+ if (p_ptr->pgod == GOD_MANWE)
{
int dec = 4 - wisdom_scale(3);
- PRAY_GOD(GOD_MANWE)
- dec++;
- if (PRACE_FLAG(PR1_ELF))
+ if (p_ptr->praying)
+ {
+ dec++;
+ }
+
+ if (race_flags1_p(PR1_ELF))
+ {
dec -= wisdom_scale(2);
- if (dec < 1) dec = 1;
+ }
+
+ dec = std::max(1, dec);
+
inc_piety(GOD_MANWE, -dec);
}
- GOD(GOD_MELKOR)
+
+ if (p_ptr->pgod == GOD_MELKOR)
{
int dec = 8 - wisdom_scale(6);
- PRAY_GOD(GOD_MELKOR)
- dec++;
- if (PRACE_FLAG(PR1_ELF))
+ if (p_ptr->praying)
+ {
+ dec++;
+ }
+
+ if (race_flags1_p(PR1_ELF))
+ {
dec += 5 - wisdom_scale(4);
- if (dec < 1) dec = 1;
+ }
+
+ dec = std::max(1, dec);
+
inc_piety(GOD_MELKOR, -dec);
}
- PRAY_GOD(GOD_TULKAS)
+
+ if (praying_to(GOD_TULKAS))
{
- int dec = 4 - wisdom_scale(3);
+ int dec = std::max(1, 4 - wisdom_scale(3));
- if (dec < 1) dec = 1;
inc_piety(GOD_TULKAS, -dec);
}
}
/* Yavanna piety decrease with time */
if (((turn % 400) == 0) && (!p_ptr->did_nothing) && (!p_ptr->wild_mode) && (dun_level))
{
- GOD(GOD_YAVANNA)
+ if (p_ptr->pgod == GOD_YAVANNA)
{
int dec = 5 - wisdom_scale(3);
/* Blech what an hideous hack */
- if (!strcmp(rp_ptr->title + rp_name, "Ent"))
+ if (!strcmp(rp_ptr->title, "Ent"))
+ {
dec -= wisdom_scale(2);
- if (dec < 1) dec = 1;
+ }
+
+ dec = std::max(1, dec);
inc_piety(GOD_YAVANNA, -dec);
}
}
@@ -1930,7 +1802,7 @@ static void process_world(void)
if (cave_no_regen) regen_amount = 0;
/* Being over grass allows Yavanna to regen you */
- PRAY_GOD(GOD_YAVANNA)
+ if (praying_to(GOD_YAVANNA))
{
if (cave[p_ptr->py][p_ptr->px].feat == FEAT_GRASS)
{
@@ -1997,7 +1869,7 @@ static void process_world(void)
p_ptr->chp--;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2063,24 +1935,12 @@ static void process_world(void)
}
}
- /* Walk water */
- if (p_ptr->walk_water)
- {
- (void)set_walk_water(p_ptr->walk_water - 1);
- }
-
/* True Strike */
if (p_ptr->strike)
{
(void)set_strike(p_ptr->strike - 1);
}
- /* Meditation */
- if (p_ptr->meditation)
- {
- (void)set_meditation(p_ptr->meditation - 1);
- }
-
/* Timed project */
if (p_ptr->tim_project)
{
@@ -2139,12 +1999,6 @@ static void process_world(void)
(void)set_prob_travel(p_ptr->prob_travel - 1);
}
- /* Timed Time Resistance */
- if (p_ptr->tim_res_time)
- {
- (void)set_tim_res_time(p_ptr->tim_res_time - 1);
- }
-
/* Timed Levitation */
if (p_ptr->tim_ffall)
{
@@ -2203,12 +2057,6 @@ static void process_world(void)
(void)set_poison(p_ptr->tim_poison - 1);
}
- /* Timed Fire Aura */
- if (p_ptr->tim_fire_aura)
- {
- (void)set_tim_fire_aura(p_ptr->tim_fire_aura - 1);
- }
-
/* Brightness */
if (p_ptr->tim_lite)
{
@@ -2407,19 +2255,6 @@ static void process_world(void)
(void)set_oppose_nex(p_ptr->oppose_nex - 1);
}
- /* Mental Barrier */
- if (p_ptr->tim_mental_barrier)
- {
- (void)set_mental_barrier(p_ptr->tim_mental_barrier - 1);
- }
-
- /* The rush */
- if (p_ptr->rush)
- {
- (void)set_rush(p_ptr->rush - 1);
- }
-
-
/* Timed mimicry */
if (get_skill(SKILL_MIMICRY))
{
@@ -2442,7 +2277,7 @@ static void process_world(void)
att &= ~(CLASS_LEGS);
att &= ~(CLASS_WALL);
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
}
p_ptr->update |= (PU_BODY);
@@ -2506,7 +2341,7 @@ static void process_world(void)
if (!(dungeon_flags1 & DF1_DAMAGE_FEAT))
{
/* If the grid is empty, skip it */
- if ((cave[j][k].o_idx == 0) &&
+ if ((cave[j][k].o_idxs.empty()) &&
((j != p_ptr->py) && (i != p_ptr->px))) continue;
}
@@ -2779,7 +2614,7 @@ static void process_world(void)
if (!be_silent)
{
cmsg_print(TERM_L_DARK, "The Black Breath saps your soul!");
- disturb(0, 0);
+ disturb(0);
}
}
@@ -2818,14 +2653,14 @@ static void process_world(void)
/* The light is now out */
else if (o_ptr->timeout < 1)
{
- disturb(0, 0);
+ disturb(0);
cmsg_print(TERM_YELLOW, "Your light has gone out!");
}
/* The light is getting dim */
else if ((o_ptr->timeout < 100) && (o_ptr->timeout % 10 == 0))
{
- if (disturb_minor) disturb(0, 0);
+ if (disturb_minor) disturb(0);
cmsg_print(TERM_YELLOW, "Your light is growing faint.");
}
}
@@ -2847,7 +2682,7 @@ static void process_world(void)
byte chance = 0;
int plev = p_ptr->lev;
- if (PRACE_FLAG(PR1_RESIST_BLACK_BREATH)) chance = 2;
+ if (race_flags1_p(PR1_RESIST_BLACK_BREATH)) chance = 2;
else chance = 5;
if ((rand_int(100) < chance) && (p_ptr->exp > 0))
@@ -2868,11 +2703,11 @@ static void process_world(void)
if (p_ptr->csp < 0)
{
p_ptr->csp = 0;
- disturb(0, 0);
+ disturb(0);
}
/* Redraw */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2887,7 +2722,7 @@ static void process_world(void)
if (p_ptr->csp < 0)
{
p_ptr->csp = 0;
- disturb(0, 0);
+ disturb(0);
p_ptr->maintain_sum = 0;
}
@@ -2898,7 +2733,7 @@ static void process_world(void)
}
/* Redraw */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2914,11 +2749,11 @@ static void process_world(void)
if (p_ptr->chp == 0)
{
- disturb(0, 0);
+ disturb(0);
}
/* Redraw */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2975,7 +2810,7 @@ static void process_world(void)
{
if ((o_ptr->ident & IDENT_CURSED) && !p_ptr->anti_tele)
{
- disturb(0, 0);
+ disturb(0);
/* Teleport player */
teleport_player(40);
@@ -2990,7 +2825,7 @@ static void process_world(void)
}
else if (get_check("Teleport? "))
{
- disturb(0, 0);
+ disturb(0);
teleport_player(50);
}
}
@@ -3150,8 +2985,7 @@ static void process_world(void)
if ((r_ptr->flags9 & RF9_IMPRESED) && can_create_companion())
{
- msg_format("And you have given the imprint to your %s!",
- r_name + r_ptr->name);
+ msg_format("And you have given the imprint to your %s!", r_ptr->name);
m_ptr->status = MSTATUS_COMPANION;
}
@@ -3275,7 +3109,7 @@ static void process_world(void)
if (p_ptr->word_recall)
{
/* Can we ? */
- if (process_hooks(HOOK_RECALL, "()", ""))
+ if (process_hooks_new(HOOK_RECALL, NULL, NULL))
{
p_ptr->word_recall = 0;
}
@@ -3329,7 +3163,7 @@ static void process_world(void)
if (p_ptr->word_recall == 0)
{
/* Disturbing! */
- disturb(0, 0);
+ disturb(0);
/* Determine the level */
if (p_ptr->inside_quest)
@@ -3434,12 +3268,6 @@ static bool_ enter_debug_mode(void)
/*
- * Hack -- Declare the Debug Routines
- */
-extern void do_cmd_debug(void);
-
-
-/*
* Parse and execute the current command
* Give "Warning" on illegal commands.
*
@@ -3452,9 +3280,6 @@ static void process_command(void)
/* Handle repeating the last command */
repeat_check();
- /* Process the appropriate hooks */
- if (process_hooks(HOOK_KEYPRESS, "(d)", command_cmd)) return;
-
/* Parse the command */
switch (command_cmd)
{
@@ -3494,7 +3319,7 @@ static void process_command(void)
p_ptr->update |= (PU_MONSTERS);
/* Redraw "title" */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
break;
}
@@ -3526,7 +3351,7 @@ static void process_command(void)
{
if (p_ptr->control) break;
if (!p_ptr->wild_mode) do_cmd_takeoff();
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
break;
}
@@ -3732,7 +3557,7 @@ static void process_command(void)
msg_print("To flee the ambush you have to reach the edge of the map.");
}
/* TODO: make the above stuff use this hook */
- else if (!process_hooks(HOOK_FORBID_TRAVEL, "()"))
+ else if (!process_hooks_new(HOOK_FORBID_TRAVEL, NULL, NULL))
{
p_ptr->oldpx = p_ptr->px;
p_ptr->oldpy = p_ptr->py;
@@ -3884,13 +3709,6 @@ static void process_command(void)
/* No magic in the overworld map */
if (p_ptr->wild_mode) break;
- /* Neither in the Arena */
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
-
- break;
- }
do_cmd_activate_skill();
squeltch_inventory();
squeltch_grid();
@@ -3969,13 +3787,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_activate();
squeltch_inventory();
squeltch_grid();
@@ -4006,18 +3817,8 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("You're in the arena now. This is hand-to-hand!");
- msg_print(NULL);
- break;
- }
-
j_ptr = &p_ptr->inventory[INVEN_BOW];
- if (process_hooks(HOOK_FIRE, "(O)", j_ptr))
- break;
-
if (j_ptr->tval == TV_BOOMERANG)
{
do_cmd_boomerang();
@@ -4036,13 +3837,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("You're in the arena now. This is hand-to-hand!");
- msg_print(NULL);
- break;
- }
-
do_cmd_throw();
break;
}
@@ -4053,13 +3847,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_aim_wand();
squeltch_inventory();
squeltch_grid();
@@ -4072,13 +3859,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_zap_rod();
squeltch_inventory();
squeltch_grid();
@@ -4091,13 +3871,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_quaff_potion();
squeltch_inventory();
squeltch_grid();
@@ -4131,13 +3904,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_read_scroll();
squeltch_inventory();
squeltch_grid();
@@ -4150,13 +3916,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_use_staff();
squeltch_inventory();
squeltch_grid();
@@ -4169,13 +3928,6 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (p_ptr->inside_arena)
- {
- msg_print("The arena absorbs all attempted magic!");
- msg_print(NULL);
- break;
- }
-
do_cmd_power();
squeltch_inventory();
squeltch_grid();
@@ -4188,7 +3940,7 @@ static void process_command(void)
if (p_ptr->control) break;
if (p_ptr->wild_mode) break;
- if (PRACE_FLAG(PR1_NO_GOD))
+ if (race_flags1_p(PR1_NO_GOD))
{
msg_print("You cannot worship gods.");
}
@@ -4271,13 +4023,6 @@ static void process_command(void)
/*** System Commands ***/
- /* Hack -- User interface */
- case '!':
- {
- (void)Term_user(0);
- break;
- }
-
/* Single line from a pref file */
case '"':
{
@@ -4399,22 +4144,6 @@ static void process_command(void)
break;
}
- /* Activate cmovie */
- case '|':
- {
- /* Stop ? */
- if (do_movies == 1)
- {
- do_stop_cmovie();
- msg_print("Cmovie recording stopped.");
- }
- else
- {
- do_start_cmovie();
- }
- break;
- }
-
/* Extended command */
case '#':
{
@@ -4511,7 +4240,7 @@ static void process_command(void)
* must come first just in case somebody manages to corrupt
* the savefiles by clever use of menu commands or something.
*/
-void process_player(void)
+static void process_player(void)
{
int i, j;
@@ -4553,7 +4282,7 @@ void process_player(void)
/* Stop resting */
if ((p_ptr->chp == p_ptr->mhp) && (p_ptr->csp >= p_ptr->msp))
{
- disturb(0, 0);
+ disturb(0);
}
}
@@ -4584,9 +4313,9 @@ void process_player(void)
if (stop)
{
- disturb(0, 0);
+ disturb(0);
}
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
}
}
@@ -4596,17 +4325,14 @@ void process_player(void)
/* Check for "player abort" (semi-efficiently for resting) */
if (running || command_rep || (resting && !(resting & 0x0F)))
{
- /* Do not wait */
- inkey_scan = TRUE;
-
/* Check for a key */
- if (inkey())
+ if (inkey_scan())
{
/* Flush input */
flush();
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Hack -- Show a Message */
msg_print("Cancelled.");
@@ -4656,7 +4382,7 @@ void process_player(void)
o_ptr = &p_ptr->inventory[item];
/* Disturbing */
- disturb(0, 0);
+ disturb(0);
/* Warning */
msg_print("Your pack overflows!");
@@ -4708,7 +4434,7 @@ void process_player(void)
resting--;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
}
p_ptr->did_nothing = TRUE;
@@ -4739,7 +4465,7 @@ void process_player(void)
command_rep--;
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Redraw stuff */
redraw_stuff();
@@ -4784,7 +4510,7 @@ void process_player(void)
/* Shimmer monsters if needed */
- if (!avoid_other && !use_graphics && shimmer_monsters)
+ if (!avoid_other && shimmer_monsters)
{
/* Clear the flag */
shimmer_monsters = FALSE;
@@ -4816,8 +4542,7 @@ void process_player(void)
}
/* Shimmer objects if needed and requested */
- if (!avoid_other && !avoid_shimmer && !use_graphics &&
- shimmer_objects)
+ if (!avoid_other && !avoid_shimmer && shimmer_objects)
{
/* Clear the flag */
shimmer_objects = FALSE;
@@ -4853,7 +4578,7 @@ void process_player(void)
* fast, and that's why shimmering has been limited to small
* number of monsters -- pelpel
*/
- if (!avoid_other && !avoid_shimmer && !use_graphics &&
+ if (!avoid_other && !avoid_shimmer &&
!resting && !running)
{
for (j = panel_row_min; j <= panel_row_max; j++)
@@ -4998,11 +4723,10 @@ static void dungeon(void)
shimmer_monsters = TRUE;
shimmer_objects = TRUE;
repair_monsters = TRUE;
- repair_objects = TRUE;
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Track maximum player level */
if (p_ptr->max_plv < p_ptr->lev)
@@ -5093,7 +4817,7 @@ static void dungeon(void)
p_ptr->window |= (PW_MONSTER);
/* Redraw dungeon */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME);
/* Redraw map */
p_ptr->redraw |= (PR_MAP);
@@ -5274,12 +4998,7 @@ static void dungeon(void)
process_world();
/* Process the appropriate hooks */
- process_hooks(HOOK_END_TURN, "(d)", is_quest(dun_level));
-
- {
- hook_end_turn_in in = { is_quest(dun_level) };
- process_hooks_new(HOOK_END_TURN, &in, NULL);
- }
+ process_hooks_new(HOOK_END_TURN, NULL, NULL);
/* Make it pulsate and live !!!! */
if ((dungeon_flags1 & DF1_EVOLVE) && dun_level)
@@ -5357,13 +5076,13 @@ static void load_all_pref_files(void)
/* Access the "race" pref file */
- sprintf(buf, "%s.prf", rp_ptr->title + rp_name);
+ sprintf(buf, "%s.prf", rp_ptr->title);
/* Process that file */
process_pref_file(buf);
/* Access the "class" pref file */
- sprintf(buf, "%s.prf", spp_ptr->title + c_name);
+ sprintf(buf, "%s.prf", spp_ptr->title);
/* Process that file */
process_pref_file(buf);
@@ -5374,12 +5093,20 @@ static void load_all_pref_files(void)
/* Process that file */
process_pref_file(buf);
- /* Process player specific automatizer sets */
- /* TODO: Disabled temporarily because it causes duplicate
- * rules on save and subsequent game load. */
- /* sprintf(buf2, "%s.atm", player_name); */
- /* path_build(buf, sizeof(buf), ANGBAND_DIR_USER, buf2); */
- /* automatizer_init(buf); */
+ /* Load automatizer settings. Character-specific automatizer
+ * file gets priority over the "template" file. We do not try
+ * to merge the two files since that would require tracking
+ * the providence of rules and such to avoid the same
+ * duplication problems as caused when saving macros/keymaps. */
+ boost::filesystem::path userDirectory(ANGBAND_DIR_USER);
+ if (automatizer_load(userDirectory / (std::string(player_name) + ".atm")))
+ {
+ // Done
+ }
+ else if (automatizer_load(userDirectory / "automat.atm"))
+ {
+ // Done
+ }
}
/*
@@ -5527,11 +5254,10 @@ void play_game(bool_ new_game)
if (p_ptr->astral) dun_level = 98;
else dun_level = 0;
p_ptr->inside_quest = 0;
- p_ptr->inside_arena = 0;
/* Hack -- enter the world */
/* Mega-hack Vampires and Spectres start in the dungeon */
- if (PRACE_FLAG(PR1_UNDEAD))
+ if (race_flags1_p(PR1_UNDEAD))
{
turn = (10L * DAY / 2) + (START_DAY * 10) + 1;
}
@@ -5582,7 +5308,7 @@ void play_game(bool_ new_game)
if (init_v_info()) quit("Cannot initialize vaults");
/* Initialize hooks */
- init_hooks();
+ init_hooks_quests();
init_hooks_help();
init_hooks_module();
@@ -5606,7 +5332,6 @@ void play_game(bool_ new_game)
if (!character_dungeon) generate_cave();
/* Ok tell the scripts that the game is about to start */
- process_hooks(HOOK_GAME_START, "()");
process_hooks_new(HOOK_GAME_START, NULL, NULL);
/* Character is now "complete" */
@@ -5723,7 +5448,7 @@ void play_game(bool_ new_game)
cheat_death = FALSE;
/* Can we die ? please let us die ! */
- if (process_hooks(HOOK_DIE, "()"))
+ if (process_hooks_new(HOOK_DIE, NULL, NULL))
{
cheat_death = TRUE;
}
@@ -5827,7 +5552,6 @@ void play_game(bool_ new_game)
/* New depth -KMW- */
/* dun_level = 0; */
- p_ptr->inside_arena = 0;
leaving_quest = 0;
p_ptr->inside_quest = 0;
@@ -5846,7 +5570,7 @@ void play_game(bool_ new_game)
if (dun_level) p_ptr->wild_mode = FALSE;
/* Make a new level */
- process_hooks(HOOK_NEW_LEVEL, "(d)", is_quest(dun_level));
+ process_hooks_new(HOOK_NEW_LEVEL, NULL, NULL);
generate_cave();
}
diff --git a/src/dungeon.h b/src/dungeon.h
new file mode 100644
index 00000000..1ce166d1
--- /dev/null
+++ b/src/dungeon.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void play_game(bool_ new_game);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/dungeon.hpp b/src/dungeon.hpp
new file mode 100644
index 00000000..bbe6da87
--- /dev/null
+++ b/src/dungeon.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+#include <vector>
+
+extern void sense_inventory();
+extern void sense_objects(std::vector<int> const &object_idxs);
diff --git a/src/dungeon_info_type.hpp b/src/dungeon_info_type.hpp
new file mode 100644
index 00000000..5f6fc9d0
--- /dev/null
+++ b/src/dungeon_info_type.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "h-basic.h"
+#include "rule_type.hpp"
+#include "obj_theme.hpp"
+
+/**
+ * Maximum number of towns per dungeon
+ */
+constexpr int TOWN_DUNGEON = 4;
+
+/* A structure for the != dungeon types */
+struct dungeon_info_type
+{
+ const char *name; /* Name */
+ char *text; /* Description */
+ char short_name[3]; /* Short name */
+
+ char generator[30]; /* Name of the level generator */
+
+ s16b floor1; /* Floor tile 1 */
+ byte floor_percent1[2]; /* Chance of type 1 */
+ s16b floor2; /* Floor tile 2 */
+ byte floor_percent2[2]; /* Chance of type 2 */
+ s16b floor3; /* Floor tile 3 */
+ byte floor_percent3[2]; /* Chance of type 3 */
+ s16b outer_wall; /* Outer wall tile */
+ s16b inner_wall; /* Inner wall tile */
+ s16b fill_type1; /* Cave tile 1 */
+ byte fill_percent1[2]; /* Chance of type 1 */
+ s16b fill_type2; /* Cave tile 2 */
+ byte fill_percent2[2]; /* Chance of type 2 */
+ s16b fill_type3; /* Cave tile 3 */
+ byte fill_percent3[2]; /* Chance of type 3 */
+ byte fill_method; /* Smoothing parameter for the above */
+
+ s16b mindepth; /* Minimal depth */
+ s16b maxdepth; /* Maximal depth */
+
+ bool_ principal; /* If it's a part of the main dungeon */
+ byte next; /* The next part of the main dungeon */
+ byte min_plev; /* Minimal plev needed to enter -- it's an anti-cheating mesure */
+
+ int min_m_alloc_level; /* Minimal number of monsters per level */
+ int max_m_alloc_chance; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */
+
+ u32b flags1; /* Flags 1 */
+ u32b flags2; /* Flags 1 */
+
+ int size_x, size_y; /* Desired numers of panels */
+
+ byte rule_percents[100]; /* Flat rule percents */
+ rule_type rules[5]; /* Monster generation rules */
+
+ int final_object; /* The object you'll find at the bottom */
+ int final_artifact; /* The artifact you'll find at the bottom */
+ int final_guardian; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */
+
+ int ix, iy, ox, oy; /* Wilderness coordinates of the entrance/output of the dungeon */
+
+ obj_theme objs; /* The drops type */
+
+ int d_dice[4]; /* Number of dices */
+ int d_side[4]; /* Number of sides */
+ int d_frequency[4]; /* Frequency of damage (1 is the minimum) */
+ int d_type[4]; /* Type of damage */
+
+ s16b t_idx[TOWN_DUNGEON]; /* The towns */
+ s16b t_level[TOWN_DUNGEON]; /* The towns levels */
+ s16b t_num; /* Number of towns */
+};
+
diff --git a/src/dungeon_info_type_fwd.hpp b/src/dungeon_info_type_fwd.hpp
new file mode 100644
index 00000000..26ed0289
--- /dev/null
+++ b/src/dungeon_info_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct dungeon_info_type;
diff --git a/src/effect_type.hpp b/src/effect_type.hpp
new file mode 100644
index 00000000..8cd638c6
--- /dev/null
+++ b/src/effect_type.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Lasting spell effects. (Clouds, etc.)
+ */
+struct effect_type
+{
+ s16b time; /* For how long */
+ s16b dam; /* How much damage */
+ s16b type; /* Of which type */
+ s16b cy; /* Center of the cast*/
+ s16b cx; /* Center of the cast*/
+ s16b rad; /* Radius -- if needed */
+ u32b flags; /* Flags */
+};
diff --git a/src/ego_item_type.hpp b/src/ego_item_type.hpp
new file mode 100644
index 00000000..f9b6970a
--- /dev/null
+++ b/src/ego_item_type.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "h-basic.h"
+
+/*
+ * Size of flag rarity tables
+ */
+constexpr int FLAG_RARITY_MAX = 6;
+
+/**
+ * Ego item descriptors.
+ */
+struct ego_item_type
+{
+ const char *name; /* Name (offset) */
+
+ bool_ before; /* Before or after the object name ? */
+
+ byte tval[10];
+ byte min_sval[10];
+ byte max_sval[10];
+
+ byte rating; /* Rating boost */
+
+ byte level; /* Minimum level */
+ byte rarity; /* Object rarity */
+ byte mrarity; /* Object rarity */
+
+ s16b max_to_h; /* Maximum to-hit bonus */
+ s16b max_to_d; /* Maximum to-dam bonus */
+ s16b max_to_a; /* Maximum to-ac bonus */
+
+ s16b activate; /* Activation Number */
+
+ s32b max_pval; /* Maximum pval */
+
+ s32b cost; /* Ego-item "cost" */
+
+ byte rar[FLAG_RARITY_MAX];
+ u32b flags1[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 1 */
+ u32b flags2[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 2 */
+ u32b flags3[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 3 */
+ u32b flags4[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 4 */
+ u32b flags5[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 5 */
+ u32b esp[FLAG_RARITY_MAX]; /* ESP flags */
+ u32b oflags1[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 1 */
+ u32b oflags2[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 2 */
+ u32b oflags3[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 3 */
+ u32b oflags4[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 4 */
+ u32b oflags5[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 5 */
+ u32b oesp[FLAG_RARITY_MAX]; /* Obvious ESP flags */
+ u32b fego[FLAG_RARITY_MAX]; /* ego flags */
+
+ u32b need_flags1; /* Ego-Item Flags, set 1 */
+ u32b need_flags2; /* Ego-Item Flags, set 2 */
+ u32b need_flags3; /* Ego-Item Flags, set 3 */
+ u32b need_flags4; /* Ego-Item Flags, set 4 */
+ u32b need_flags5; /* Ego-Item Flags, set 5 */
+ u32b need_esp; /* ESP flags */
+ u32b forbid_flags1; /* Ego-Item Flags, set 1 */
+ u32b forbid_flags2; /* Ego-Item Flags, set 2 */
+ u32b forbid_flags3; /* Ego-Item Flags, set 3 */
+ u32b forbid_flags4; /* Ego-Item Flags, set 4 */
+ u32b forbid_flags5; /* Ego-Item Flags, set 5 */
+ u32b forbid_esp; /* ESP flags */
+
+ s16b power; /* Power granted(if any) */
+};
diff --git a/src/ego_item_type_fwd.hpp b/src/ego_item_type_fwd.hpp
new file mode 100644
index 00000000..795f4403
--- /dev/null
+++ b/src/ego_item_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct ego_item_type;
diff --git a/src/externs.h b/src/externs.h
deleted file mode 100644
index 8fd9e5e5..00000000
--- a/src/externs.h
+++ /dev/null
@@ -1,2377 +0,0 @@
-/* File: externs.h */
-
-/* Purpose: extern declarations (variables and functions) */
-
-/*
- * Note that some files have their own header files
- * (z-virt.h, z-util.h, z-form.h, term.h, random.h)
- */
-
-/*
- * Options for inc_stack_size_ex
- */
-typedef enum { OPTIMIZE, NO_OPTIMIZE } optimize_flag;
-typedef enum { DESCRIBE, NO_DESCRIBE } describe_flag;
-
-
-/*
- * Automatically generated "variable" declarations
- */
-
-extern int max_macrotrigger;
-extern char *macro_template;
-extern char *macro_modifier_chr;
-extern char *macro_modifier_name[MAX_MACRO_MOD];
-extern char *macro_trigger_name[MAX_MACRO_TRIG];
-extern char *macro_trigger_keycode[2][MAX_MACRO_TRIG];
-
-/* tables.c */
-extern s16b ddd[9];
-extern s16b ddx[10];
-extern s16b ddy[10];
-extern s16b ddx_ddd[9];
-extern s16b ddy_ddd[9];
-extern char hexsym[16];
-extern byte adj_val_min[];
-extern byte adj_val_max[];
-extern byte adj_mag_study[];
-extern byte adj_mag_mana[];
-extern byte adj_mag_fail[];
-extern byte adj_mag_stat[];
-extern byte adj_chr_gold[];
-extern byte adj_int_dev[];
-extern byte adj_wis_sav[];
-extern byte adj_dex_dis[];
-extern byte adj_int_dis[];
-extern byte adj_dex_ta[];
-extern byte adj_str_td[];
-extern byte adj_dex_th[];
-extern byte adj_str_th[];
-extern byte adj_str_wgt[];
-extern byte adj_str_hold[];
-extern byte adj_str_dig[];
-extern byte adj_str_blow[];
-extern byte adj_dex_blow[];
-extern byte adj_dex_safe[];
-extern byte adj_con_fix[];
-extern byte adj_con_mhp[];
-extern byte blows_table[12][12];
-extern s16b arena_monsters[MAX_ARENA_MONS];
-extern byte extract_energy[300];
-extern s32b player_exp[PY_MAX_LEVEL];
-extern player_sex sex_info[MAX_SEXES];
-extern cptr color_names[16];
-extern cptr stat_names[6];
-extern cptr stat_names_reduced[6];
-extern cptr window_flag_desc[32];
-extern option_type option_info[];
-extern martial_arts bear_blows[MAX_BEAR];
-extern martial_arts ma_blows[MAX_MA];
-extern magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS];
-extern magic_power necro_powers[MAX_NECRO_POWERS];
-extern magic_power mimic_powers[MAX_MIMIC_POWERS];
-extern magic_power symbiotic_powers[MAX_SYMBIOTIC_POWERS];
-extern cptr deity_rarity[2];
-extern cptr deity_niceness[10];
-extern cptr deity_standing[11];
-extern move_info_type move_info[9];
-extern tactic_info_type tactic_info[9];
-extern activation activation_info[MAX_T_ACT];
-extern inscription_info_type inscription_info[MAX_INSCRIPTIONS];
-extern cptr sense_desc[];
-extern flags_group flags_groups[MAX_FLAG_GROUP];
-extern power_type powers_type[POWER_MAX];
-extern cptr artifact_names_list;
-extern monster_power monster_powers[96];
-extern tval_desc tval_descs[];
-extern between_exit between_exits[MAX_BETWEEN_EXITS];
-extern int month_day[9];
-extern cptr month_name[9];
-extern cli_comm *cli_info;
-extern int cli_total;
-extern quest_type quest[MAX_Q_IDX];
-extern int max_body_part[BODY_MAX];
-extern gf_name_type gf_names[];
-extern module_type modules[MAX_MODULES];
-
-
-/* variable.c */
-extern cptr copyright[5];
-extern byte version_major;
-extern byte version_minor;
-extern byte version_patch;
-extern byte version_extra;
-extern byte sf_major;
-extern byte sf_minor;
-extern byte sf_patch;
-extern byte sf_extra;
-extern u32b sf_xtra;
-extern u32b sf_when;
-extern u16b sf_lives;
-extern u16b sf_saves;
-extern u32b vernum; /* Version flag */
-extern bool_ arg_wizard;
-extern bool_ arg_sound;
-extern bool_ arg_graphics;
-extern bool_ arg_force_original;
-extern bool_ arg_force_roguelike;
-extern bool_ arg_bigtile;
-extern bool_ character_generated;
-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 s16b command_cmd;
-extern s16b command_arg;
-extern s16b command_rep;
-extern s16b command_dir;
-extern s16b command_wrk;
-extern s16b command_new;
-extern s32b energy_use;
-extern s16b choose_default;
-extern bool_ create_up_stair;
-extern bool_ create_down_stair;
-extern bool_ create_up_shaft;
-extern bool_ create_down_shaft;
-extern bool_ msg_flag;
-extern bool_ alive;
-extern bool_ death;
-extern s16b running;
-extern s16b resting;
-extern s16b cur_hgt;
-extern s16b cur_wid;
-extern s16b dun_level;
-extern s16b old_dun_level;
-extern s16b num_repro;
-extern s16b object_level;
-extern s16b monster_level;
-extern s32b turn;
-extern s32b old_turn;
-extern bool_ wizard;
-extern bool_ use_sound;
-extern bool_ use_graphics;
-extern bool_ use_bigtile;
-extern byte graphics_mode;
-extern u16b total_winner;
-extern u16b has_won;
-extern u16b noscore;
-extern bool_ inkey_base;
-extern bool_ inkey_xtra;
-extern bool_ inkey_scan;
-extern bool_ inkey_flag;
-extern s16b coin_type;
-extern bool_ opening_chest;
-extern bool_ shimmer_monsters;
-extern bool_ shimmer_objects;
-extern bool_ repair_monsters;
-extern bool_ repair_objects;
-extern s16b inven_cnt;
-extern s16b equip_cnt;
-extern s16b o_max;
-extern s16b o_cnt;
-extern s16b m_max;
-extern s16b m_cnt;
-extern s16b hack_m_idx;
-extern s16b hack_m_idx_ii;
-extern int total_friends;
-extern s32b total_friend_levels;
-extern int leaving_quest;
-extern char summon_kin_type;
-extern bool_ hack_mind;
-extern bool_ is_autosave;
-extern int artifact_bias;
-extern FILE *text_out_file;
-extern void (*text_out_hook)(byte a, cptr str);
-extern int text_out_indent;
-extern bool_ rogue_like_commands;
-extern bool_ quick_messages;
-extern bool_ carry_query_flag;
-extern bool_ always_pickup;
-extern bool_ prompt_pickup_heavy;
-extern bool_ always_repeat;
-extern bool_ use_old_target;
-extern bool_ depth_in_feet;
-extern bool_ hilite_player;
-extern bool_ ring_bell;
-extern bool_ find_ignore_stairs;
-extern bool_ find_ignore_doors;
-extern bool_ find_cut;
-extern bool_ find_examine;
-extern bool_ disturb_near;
-extern bool_ disturb_move;
-extern bool_ disturb_panel;
-extern bool_ disturb_detect;
-extern bool_ disturb_state;
-extern bool_ disturb_minor;
-extern bool_ disturb_other;
-extern bool_ avoid_abort;
-extern bool_ avoid_shimmer;
-extern bool_ avoid_other;
-extern bool_ flush_disturb;
-extern bool_ flush_failure;
-extern bool_ flush_command;
-extern bool_ fresh_before;
-extern bool_ fresh_after;
-extern bool_ fresh_message;
-extern bool_ alert_hitpoint;
-extern bool_ alert_failure;
-extern bool_ view_yellow_lite;
-extern bool_ view_bright_lite;
-extern bool_ view_granite_lite;
-extern bool_ view_special_lite;
-extern bool_ plain_descriptions;
-extern bool_ auto_destroy;
-extern bool_ wear_confirm;
-extern bool_ confirm_stairs;
-extern bool_ disturb_pets;
-extern bool_ view_perma_grids;
-extern bool_ view_torch_grids;
-extern bool_ monster_lite;
-extern bool_ flow_by_sound;
-extern bool_ track_follow;
-extern bool_ track_target;
-extern bool_ stack_allow_items;
-extern bool_ stack_allow_wands;
-extern bool_ stack_force_notes;
-extern bool_ stack_force_costs;
-extern bool_ view_reduce_lite;
-extern bool_ view_reduce_view;
-extern bool_ auto_scum;
-extern bool_ expand_look;
-extern bool_ expand_list;
-extern bool_ dungeon_align;
-extern bool_ dungeon_stair;
-extern bool_ smart_learn;
-extern bool_ smart_cheat;
-extern bool_ show_labels;
-extern bool_ show_weights;
-extern bool_ show_choices;
-extern bool_ show_details;
-extern bool_ testing_stack;
-extern bool_ testing_carry;
-extern bool_ cheat_peek;
-extern bool_ cheat_hear;
-extern bool_ cheat_room;
-extern bool_ cheat_xtra;
-extern bool_ cheat_know;
-extern bool_ cheat_live;
-extern bool_ last_words; /* Zangband options */
-extern bool_ speak_unique;
-extern bool_ small_levels;
-extern bool_ empty_levels;
-extern bool_ always_small_level;
-extern bool_ player_symbols;
-extern byte hitpoint_warn;
-extern byte delay_factor;
-extern s16b autosave_freq;
-extern bool_ autosave_t;
-extern bool_ autosave_l;
-extern s16b feeling;
-extern s16b rating;
-extern bool_ good_item_flag;
-extern bool_ closing_flag;
-extern s16b max_panel_rows, max_panel_cols;
-extern s16b panel_row_min, panel_row_max;
-extern s16b panel_col_min, panel_col_max;
-extern s16b panel_col_prt, panel_row_prt;
-extern byte feat_wall_outer;
-extern byte feat_wall_inner;
-extern s16b floor_type[100];
-extern s16b fill_type[100];
-extern s16b py;
-extern s16b px;
-extern s16b target_who;
-extern s16b target_col;
-extern s16b target_row;
-extern s16b health_who;
-extern s16b monster_race_idx;
-extern s16b monster_ego_idx;
-extern object_type *tracked_object;
-extern char player_name[32];
-extern char player_base[32];
-extern char died_from[80];
-extern char history[4][60];
-extern char savefile[1024];
-extern s16b lite_n;
-extern s16b lite_y[LITE_MAX];
-extern s16b 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 u32b option_flag[8];
-extern u32b option_mask[8];
-extern u32b window_flag[ANGBAND_TERM_MAX];
-extern u32b window_mask[ANGBAND_TERM_MAX];
-extern term *angband_term[ANGBAND_TERM_MAX];
-extern char angband_term_name[ANGBAND_TERM_MAX][80];
-extern byte angband_color_table[256][4];
-extern char angband_sound_name[SOUND_MAX][16];
-extern cave_type *cave[MAX_HGT];
-extern object_type *o_list;
-extern monster_type *m_list;
-extern monster_type *km_list;
-extern u16b max_real_towns;
-extern u16b max_towns;
-extern town_type *town_info;
-extern s16b alloc_kind_size;
-extern alloc_entry *alloc_kind_table;
-extern bool_ alloc_kind_table_valid;
-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 tval_to_char[128];
-extern cptr keymap_act[KEYMAP_MODES][256];
-extern player_type p_body;
-extern player_type *p_ptr;
-extern player_sex *sp_ptr;
-extern player_race *rp_ptr;
-extern player_race_mod *rmp_ptr;
-extern player_class *cp_ptr;
-extern player_spec *spp_ptr;
-extern u32b alchemist_known_egos[32];
-extern alchemist_recipe *alchemist_recipes;
-extern u32b alchemist_known_artifacts[6];
-extern u32b alchemist_gained;
-extern s16b player_hp[PY_MAX_LEVEL];
-extern header *al_head;
-extern char *al_name;
-extern artifact_select_flag *a_select_flags;
-
-extern header *ab_head;
-extern ability_type *ab_info;
-extern char *ab_name;
-extern char *ab_text;
-
-extern header *s_head;
-extern skill_type *s_info;
-extern char *s_name;
-extern char *s_text;
-
-extern header *v_head;
-extern vault_type *v_info;
-extern char *v_name;
-extern char *v_text;
-extern header *f_head;
-extern feature_type *f_info;
-extern char *f_name;
-extern char *f_text;
-extern header *k_head;
-extern object_kind *k_info;
-extern char *k_name;
-extern char *k_text;
-extern header *a_head;
-extern artifact_type *a_info;
-extern char *a_name;
-extern char *a_text;
-extern header *e_head;
-extern ego_item_type *e_info;
-extern char *e_name;
-extern char *e_text;
-extern header *ra_head;
-extern randart_part_type *ra_info;
-extern randart_gen_type ra_gen[30];
-extern header *r_head;
-extern monster_race *r_info;
-extern char *r_name;
-extern char *r_text;
-extern header *re_head;
-extern monster_ego *re_info;
-extern char *re_name;
-extern header *d_head;
-extern dungeon_info_type *d_info;
-extern char *d_name;
-extern char *d_text;
-extern header *c_head;
-extern player_class *class_info;
-extern char *c_name;
-extern char *c_text;
-extern meta_class_type *meta_class_info;
-extern header *rp_head;
-extern player_race *race_info;
-extern char *rp_name;
-extern char *rp_text;
-extern header *rmp_head;
-extern player_race_mod *race_mod_info;
-extern char *rmp_name;
-extern char *rmp_text;
-extern header *t_head;
-extern trap_type *t_info;
-extern char *t_name;
-extern char *t_text;
-extern header *wf_head;
-extern wilderness_type_info *wf_info;
-extern char *wf_name;
-extern char *wf_text;
-extern int wildc2i[256];
-extern header *st_head;
-extern store_info_type *st_info;
-extern char *st_name;
-extern header *ba_head;
-extern store_action_type *ba_info;
-extern char *ba_name;
-extern header *ow_head;
-extern owner_type *ow_info;
-extern char *ow_name;
-extern header *set_head;
-extern set_type *set_info;
-extern char *set_name;
-extern char *set_text;
-extern cptr ANGBAND_SYS;
-extern cptr ANGBAND_KEYBOARD;
-extern cptr ANGBAND_GRAF;
-extern cptr ANGBAND_DIR;
-extern cptr ANGBAND_DIR_CORE;
-extern cptr ANGBAND_DIR_DNGN;
-extern cptr ANGBAND_DIR_DATA;
-extern cptr ANGBAND_DIR_EDIT;
-extern cptr ANGBAND_DIR_FILE;
-extern cptr ANGBAND_DIR_HELP;
-extern cptr ANGBAND_DIR_INFO;
-extern cptr ANGBAND_DIR_MODULES;
-extern cptr ANGBAND_DIR_NOTE;
-extern cptr ANGBAND_DIR_SAVE;
-extern cptr ANGBAND_DIR_SCPT;
-extern cptr ANGBAND_DIR_PATCH;
-extern cptr ANGBAND_DIR_PREF;
-extern cptr ANGBAND_DIR_USER;
-extern cptr ANGBAND_DIR_XTRA;
-extern cptr ANGBAND_DIR_CMOV;
-extern char pref_tmp_value[8];
-extern bool_ item_tester_full;
-extern byte item_tester_tval;
-extern bool_ (*item_tester_hook)(object_type *o_ptr);
-extern bool_ (*ang_sort_comp)(vptr u, vptr v, int a, int b);
-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_mon_num2_hook)(int r_idx);
-extern bool_ (*get_obj_num_hook)(int k_idx);
-extern u16b max_wild_x;
-extern u16b max_wild_y;
-extern wilderness_map **wild_map;
-extern u16b old_max_s_idx;
-extern u16b max_ab_idx;
-extern u16b max_s_idx;
-extern u16b max_al_idx;
-extern u16b max_r_idx;
-extern u16b max_re_idx;
-extern u16b max_k_idx;
-extern u16b max_v_idx;
-extern u16b max_f_idx;
-extern u16b max_a_idx;
-extern u16b max_e_idx;
-extern u16b max_ra_idx;
-extern u16b max_d_idx;
-extern u16b max_o_idx;
-extern u16b max_m_idx;
-extern u16b max_t_idx;
-extern u16b max_rp_idx;
-extern u16b max_c_idx;
-extern u16b max_mc_idx;
-extern u16b max_rmp_idx;
-extern u16b max_st_idx;
-extern u16b max_ba_idx;
-extern u16b max_ow_idx;
-extern u16b max_wf_idx;
-extern s16b max_set_idx;
-extern int init_flags;
-extern bool_ ambush_flag;
-extern bool_ fate_flag;
-extern s16b no_breeds;
-extern bool_ carried_monster_hit;
-extern random_artifact random_artifacts[MAX_RANDARTS];
-extern s32b RANDART_WEAPON;
-extern s32b RANDART_ARMOR;
-extern s32b RANDART_JEWEL;
-extern s16b bounties[MAX_BOUNTIES][2];
-extern random_spell random_spells[MAX_SPELLS];
-extern s16b spell_num;
-extern rune_spell rune_spells[MAX_RUNES];
-extern s16b rune_num;
-extern fate fates[MAX_FATES];
-extern byte dungeon_type;
-extern s16b *max_dlv;
-extern u32b total_bounties;
-extern s16b doppleganger;
-extern bool_ generate_encounter;
-extern bool_ autoroll;
-extern bool_ point_based;
-extern bool_ maximize, preserve, special_lvls, ironman_rooms;
-extern bool_ inventory_no_move;
-extern bool_ *m_allow_special;
-extern bool_ *k_allow_special;
-extern bool_ *a_allow_special;
-extern bool_ rand_birth;
-extern bool_ joke_monsters;
-extern bool_ center_player;
-extern s16b plots[MAX_PLOTS];
-extern random_quest random_quests[MAX_RANDOM_QUEST];
-extern bool_ exp_need;
-extern bool_ fate_option;
-extern bool_ *special_lvl[MAX_DUNGEON_DEPTH];
-extern bool_ generate_special_feeling;
-extern bool_ auto_more;
-extern u32b dungeon_flags1;
-extern u32b dungeon_flags2;
-extern birther previous_char;
-extern hist_type *bg;
-extern int max_bg_idx;
-extern s32b extra_savefile_parts;
-extern bool_ player_char_health;
-extern s16b school_spells_count;
-extern spell_type *school_spells[SCHOOL_SPELLS_MAX];
-extern s16b schools_count;
-extern school_type schools[SCHOOLS_MAX];
-extern int project_time;
-extern s32b project_time_effect;
-extern effect_type effects[MAX_EFFECTS];
-extern char gen_skill_basem[MAX_SKILLS];
-extern u32b gen_skill_base[MAX_SKILLS];
-extern char gen_skill_modm[MAX_SKILLS];
-extern s16b gen_skill_mod[MAX_SKILLS];
-extern bool_ linear_stats;
-extern int max_bact;
-extern bool_ option_ingame_help;
-extern bool_ automatizer_enabled;
-extern s16b last_teleportation_y;
-extern s16b last_teleportation_x;
-extern cptr game_module;
-extern s32b game_module_idx;
-extern s32b VERSION_MAJOR;
-extern s32b VERSION_MINOR;
-extern s32b VERSION_PATCH;
-extern s32b max_plev;
-extern s32b DUNGEON_BASE;
-extern s32b DUNGEON_DEATH;
-extern s32b DUNGEON_ASTRAL;
-extern s32b DUNGEON_ASTRAL_WILD_X;
-extern s32b DUNGEON_ASTRAL_WILD_Y;
-extern deity_type deity_info[MAX_GODS];
-extern timer_type *gl_timers;
-extern const char *get_version_string();
-
-/* plots.c */
-extern FILE *hook_file;
-extern bool_ check_hook(int h_idx);
-extern void wipe_hooks(void);
-extern void dump_hooks(int h_idx);
-extern void init_hooks(void);
-extern hooks_chain* add_hook(int h_idx, hook_type hook, cptr name);
-extern void add_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *), cptr name, void *data);
-extern void add_hook_script(int h_idx, char *script, cptr name);
-extern void del_hook(int h_idx, hook_type hook);
-extern void del_hook_name(int h_idx, cptr name);
-extern s32b get_next_arg(char *fmt);
-extern int process_hooks_restart;
-extern hook_return process_hooks_return[20];
-extern bool_ process_hooks_ret(int h_idx, char *ret, char *fmt, ...);
-extern bool_ process_hooks(int h_idx, char *fmt, ...);
-extern bool_ process_hooks_new(int h_idx, void *in, void *out);
-
-extern void initialize_bookable_spells();
-
-/* help.c */
-extern void init_hooks_help();
-extern void help_race(cptr race);
-extern void help_subrace(cptr subrace);
-extern void help_class(cptr klass);
-extern void help_god(cptr god);
-extern void help_skill(cptr skill);
-extern void help_ability(cptr ability);
-
-/* birth.c */
-extern void print_desc_aux(cptr txt, int y, int x);
-extern void save_savefile_names(void);
-extern bool_ no_begin_screen;
-extern bool_ begin_screen(void);
-extern errr init_randart(void);
-extern void get_height_weight(void);
-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_ cave_valid_bold(int y, int x);
-extern bool_ no_lite(void);
-extern void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, byte *eap, char *ecp);
-extern void map_info_default(int y, int x, byte *ap, char *cp);
-extern void move_cursor_relative(int row, int col);
-extern void print_rel(char c, byte a, int y, int x);
-extern void note_spot(int y, int x);
-extern void lite_spot(int y, int x);
-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_mon_lite(void);
-extern void update_mon_lite(void);
-extern void forget_flow(void);
-extern void update_flow(void);
-extern void map_area(void);
-extern void wiz_lite(void);
-extern void wiz_lite_extra(void);
-extern void wiz_dark(void);
-extern void cave_set_feat(int y, int x, int feat);
-extern void place_floor(int y, int x);
-extern void place_floor_convert_glass(int y, int x);
-extern void place_filler(int y, int x);
-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);
-extern void health_track(int m_idx);
-extern void monster_race_track(int r_idx, int ego);
-extern void object_track(object_type *o_ptr);
-extern void disturb(int stop_search, int flush_output);
-extern int is_quest(int level);
-extern int random_quest_number(void);
-extern int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags);
-
-/* cmovie.c */
-extern void cmovie_init_second(void);
-extern s16b do_play_cmovie(cptr cmov_file);
-extern void do_record_cmovie(cptr cmovie);
-extern void do_stop_cmovie(void);
-extern void do_start_cmovie(void);
-extern void cmovie_clean_line(int y, char *abuf, char *cbuf);
-extern void cmovie_record_line(int y);
-extern void do_cmovie_insert(void);
-
-/* cmd1.c */
-extern void attack_special(monster_type *m_ptr, s32b special, int dam);
-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, int skill);
-extern s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit);
-extern s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, s32b *special);
-extern void search(void);
-extern void carry(int pickup);
-extern void py_attack(int y, int x, int max_blow);
-extern bool_ player_can_enter(byte feature);
-extern void move_player(int dir, int do_pickup, bool_ disarm);
-extern void move_player_aux(int dir, int do_pickup, int run, bool_ disarm);
-extern void run_step(int dir);
-extern void step_effects(int y, int x, int do_pickup);
-extern void do_cmd_pet(void);
-extern bool_ do_cmd_integrate_body(void);
-extern bool_ do_cmd_leave_body(bool_ drop_body);
-extern bool_ execute_inscription(byte i, byte y, byte x);
-extern void do_cmd_engrave(void);
-extern void do_spin(void);
-
-/* cmd2.c */
-extern byte show_monster_inven(int m_idx, int *monst_list);
-extern int breakage_chance(object_type *o_ptr);
-extern void do_cmd_go_up(void);
-extern void do_cmd_go_down(void);
-extern void do_cmd_search(void);
-extern void do_cmd_toggle_search(void);
-extern void do_cmd_open(void);
-extern void do_cmd_close(void);
-extern void do_cmd_chat(void);
-extern void do_cmd_give(void);
-extern bool_ do_cmd_tunnel_aux(int y, int x, int dir);
-extern void do_cmd_tunnel(void);
-extern void do_cmd_disarm(void);
-extern void do_cmd_disarm(void);
-extern void do_cmd_bash(void);
-extern void do_cmd_alter(void);
-extern void do_cmd_spike(void);
-extern void do_cmd_walk(int pickup, bool_ disarm);
-extern void do_cmd_stay(int pickup);
-extern void do_cmd_run(void);
-extern void do_cmd_rest(void);
-extern int get_shooter_mult(object_type *o_ptr);
-extern void do_cmd_fire(void);
-extern void do_cmd_throw(void);
-extern void do_cmd_boomerang(void);
-extern void do_cmd_unwalk(void);
-extern void do_cmd_immovable_special(void);
-extern void fetch(int dir, int wgt, bool_ require_los);
-extern void do_cmd_sacrifice(void);
-extern void do_cmd_create_artifact(object_type *q_ptr);
-extern void do_cmd_steal(void);
-extern void do_cmd_racial_power(void);
-
-/* cmd3.c */
-extern void do_cmd_html_dump(void);
-extern void cli_add(cptr active, cptr trigger, cptr descr);
-extern void do_cmd_cli(void);
-extern void do_cmd_cli_help(void);
-extern void do_cmd_inven(void);
-extern void do_cmd_equip(void);
-extern void do_cmd_wield(void);
-extern void do_cmd_takeoff(void);
-extern void do_cmd_drop(void);
-extern void do_cmd_destroy(void);
-extern void do_cmd_observe(void);
-extern void do_cmd_uninscribe(void);
-extern void do_cmd_inscribe(void);
-extern void do_cmd_refill(void);
-extern void do_cmd_target(void);
-extern void do_cmd_look(void);
-extern void do_cmd_locate(void);
-extern void do_cmd_query_symbol(void);
-extern bool_ do_cmd_sense_grid_mana(void);
-extern bool_ research_mon(void);
-extern s32b portable_hole_weight(void);
-extern void set_portable_hole_weight(void);
-extern void do_cmd_portable_hole(void);
-
-/* cmd4.c */
-extern bool_ change_option(cptr name, bool_ value);
-extern void macro_recorder_start(void);
-extern void macro_recorder_add(char c);
-extern void macro_recorder_stop(void);
-extern void do_cmd_macro_recorder(void);
-extern void do_cmd_redraw(void);
-extern void do_cmd_change_name(void);
-extern void do_cmd_message_one(void);
-extern void do_cmd_messages(void);
-extern void do_cmd_options(void);
-extern void do_cmd_pref(void);
-extern void do_cmd_macros(void);
-extern void do_cmd_visuals(void);
-extern void do_cmd_colors(void);
-extern void do_cmd_note(void);
-extern void do_cmd_version(void);
-extern void do_cmd_feeling(void);
-extern void do_cmd_load_screen(void);
-extern void do_cmd_save_screen(void);
-extern void do_cmd_knowledge(void);
-extern void plural_aux(char * Name);
-extern void do_cmd_checkquest(void);
-extern void do_cmd_change_tactic(int i);
-extern void do_cmd_change_movement(int i);
-extern void do_cmd_time(void);
-extern void do_cmd_options_aux(int page, cptr info, bool_ read_only);
-
-
-/* cmd5.c */
-extern bool_ is_magestaff(void);
-extern void calc_magic_bonus(void);
-extern void do_cmd_browse_aux(object_type *o_ptr);
-extern void do_cmd_browse(void);
-extern void do_cmd_cast(void);
-extern void do_cmd_pray(void);
-extern void do_cmd_rerate(void);
-extern void corrupt_player(void);
-extern bool_ item_tester_hook_armour(object_type *o_ptr);
-extern void fetch(int dir, int wgt, bool_ require_los);
-extern void do_poly_self(void);
-extern void brand_weapon(int brand_type);
-extern cptr symbiote_name(bool_ capitalize);
-extern int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost);
-extern bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr);
-extern s32b get_school_spell(cptr do_what, s16b force_book);
-extern void do_cmd_copy_spell(void);
-extern void cast_school_spell(void);
-extern void browse_school_spell(int book, int pval, object_type *o_ptr);
-extern int find_spell(const char *name);
-extern bool_ is_school_book(object_type *o_ptr);
-
-/* cmd6.c */
-extern void set_stick_mode(object_type *o_ptr);
-extern void unset_stick_mode(void);
-extern void do_cmd_eat_food(void);
-extern void do_cmd_quaff_potion(void);
-extern void do_cmd_read_scroll(void);
-extern void do_cmd_aim_wand(void);
-extern void do_cmd_use_staff(void);
-extern void do_cmd_zap_rod(void);
-extern const char *activation_aux(object_type *o_ptr, bool_ desc, int item);
-extern void do_cmd_activate(void);
-extern void do_cmd_rerate(void);
-extern void do_cmd_cut_corpse(void);
-extern void do_cmd_cure_meat(void);
-extern void do_cmd_drink_fountain(void);
-extern void do_cmd_fill_bottle(void);
-
-/* cmd7.c */
-extern void do_cmd_create_boulder(void);
-extern int rune_exec(rune_spell *spell, int cost);
-extern void necro_info(char *p, int power);
-extern void mindcraft_info(char *p, int power);
-extern void symbiotic_info(char *p, int power);
-extern void mimic_info(char *p, int power);
-extern void cast_magic_spell(int spell, byte level);
-extern void do_cmd_summoner(void);
-extern void do_cmd_mindcraft(void);
-extern void do_cmd_mimic(void);
-extern void do_cmd_blade(void);
-extern void use_ability_blade(void);
-extern bool_ alchemist_exists(int tval, int sval, int ego, int artifact);
-extern void rod_tip_extract(object_type *o_ptr);
-extern void do_cmd_toggle_artifact(object_type *o_ptr);
-extern bool_ alchemist_items_check(int tval, int sval, int ego, int tocreate, bool_ message);
-extern void alchemist_display_recipe(int tval, int sval, int ego);
-extern void alchemist_recipe_book(void);
-extern int alchemist_recipe_select(int *tval, int sval, int ego, bool_ recipe);
-extern int alchemist_learn_object(object_type *o_ptr);
-extern void alchemist_gain_level(int lev);
-extern void do_cmd_alchemist(void);
-extern void do_cmd_beastmaster(void);
-extern void do_cmd_powermage(void);
-extern void do_cmd_possessor(void);
-extern void do_cmd_archer(void);
-extern void do_cmd_set_piercing(void);
-extern void do_cmd_necromancer(void);
-extern void do_cmd_unbeliever(void);
-extern void cast_daemon_spell(int spell, byte level);
-extern void do_cmd_unbeliever(void);
-extern void do_cmd_runecrafter(void);
-extern void do_cmd_symbiotic(void);
-extern s32b sroot(s32b n);
-extern int clamp_failure_chance(int chance, int minfail);
-
-/* corrupt.c */
-extern void gain_random_corruption();
-extern void dump_corruptions(FILE *OutFile, bool_ color, bool_ header);
-extern void lose_corruption();
-extern bool_ player_has_corruption(int corruption_idx);
-extern void player_gain_corruption(int corruption_idx);
-extern s16b get_corruption_power(int corruption_idx);
-
-/* dungeon.c */
-extern byte value_check_aux1(object_type *o_ptr);
-extern byte value_check_aux1_magic(object_type *o_ptr);
-extern byte value_check_aux2(object_type *o_ptr);
-extern byte value_check_aux2_magic(object_type *o_ptr);
-extern void play_game(bool_ new_game);
-extern void sense_inventory();
-
-/* files.c */
-extern void html_screenshot(cptr name);
-extern void help_file_screenshot(cptr name);
-extern void player_flags(u32b* f1, u32b* f2, u32b* f3, u32b* f4, u32b* f5, u32b* esp);
-extern void wipe_saved(void);
-extern s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2);
-extern void display_player(int mode);
-extern cptr describe_player_location(void);
-extern errr file_character(cptr name, bool_ full);
-extern errr process_pref_file_aux(char *buf);
-extern errr process_pref_file(cptr name);
-extern void read_times(void);
-extern bool_ txt_to_html(cptr head, cptr food, cptr base, cptr ext, bool_ force, bool_ recur);
-extern bool_ show_file(cptr name, cptr what, int line, int mode);
-extern void do_cmd_help(void);
-extern void process_player_base(void);
-extern void process_player_name(bool_ sf);
-extern void get_name(void);
-extern void do_cmd_suicide(void);
-extern void do_cmd_save_game(void);
-extern void autosave_checkpoint();
-extern long total_points(void);
-extern void display_scores(int from, int to);
-extern errr predict_score(void);
-extern void predict_score_gui(bool_ *initialized, bool_ *game_in_progress);
-extern void close_game(void);
-extern errr get_rnd_line(char * file_name, char * output);
-extern char *get_line(char* fname, cptr fdir, char *linbuf, int line);
-extern void do_cmd_knowledge_corruptions(void);
-extern void race_legends(void);
-extern void show_highclass(int building);
-extern errr get_xtra_line(char * file_name, monster_type *m_ptr, char * output);
-
-/* gen_maze.c */
-extern bool_ level_generate_maze();
-
-/* gen_life.c */
-extern bool_ level_generate_life();
-extern void evolve_level(bool_ noise);
-
-/* generate.c */
-extern bool_ new_player_spot(int branch);
-extern void add_level_generator(cptr name, bool_ (*generator)(), bool_ stairs, bool_ monsters, bool_ objects, bool_ miscs);
-extern bool_ level_generate_dungeon();
-extern bool_ generate_fracave(int y0, int x0,int xsize,int ysize,int cutoff,bool_ light,bool_ room);
-extern void generate_hmap(int y0, int x0,int xsiz,int ysiz,int grd,int roug,int cutoff);
-extern bool_ room_alloc(int x,int y,bool_ crowded,int by0,int bx0,int *xx,int *yy);
-extern void generate_grid_mana(void);
-extern byte calc_dungeon_type(void);
-extern void generate_cave(void);
-extern void build_rectangle(int y1, int x1, int y2, int x2, int feat, int info);
-
-
-/* wild.c */
-extern int generate_area(int y, int x, bool_ border, bool_ corner, bool_ refresh);
-extern void wilderness_gen(int refresh);
-extern void wilderness_gen_small(void);
-extern void reveal_wilderness_around_player(int y, int x, int h, int w);
-extern void town_gen(int t_idx);
-
-
-/* init1.c */
-extern int color_char_to_attr(char c);
-extern byte conv_color[16];
-extern errr init_player_info_txt(FILE *fp, char *buf);
-extern errr init_ab_info_txt(FILE *fp, char *buf);
-extern errr init_s_info_txt(FILE *fp, char *buf);
-extern errr init_set_info_txt(FILE *fp, char *buf);
-extern errr init_v_info_txt(FILE *fp, char *buf, bool_ start);
-extern errr init_f_info_txt(FILE *fp, char *buf);
-extern errr init_k_info_txt(FILE *fp, char *buf);
-extern errr init_a_info_txt(FILE *fp, char *buf);
-extern errr init_al_info_txt(FILE *fp, char *buf);
-extern errr init_ra_info_txt(FILE *fp, char *buf);
-extern errr init_e_info_txt(FILE *fp, char *buf);
-extern errr init_r_info_txt(FILE *fp, char *buf);
-extern errr init_re_info_txt(FILE *fp, char *buf);
-extern errr grab_one_dungeon_flag(u32b *flags1, u32b *flags2, cptr what);
-extern errr init_d_info_txt(FILE *fp, char *buf);
-extern errr init_t_info_txt(FILE *fp, char *buf);
-extern errr init_ba_info_txt(FILE *fp, char *buf);
-extern errr init_st_info_txt(FILE *fp, char *buf);
-extern errr init_ow_info_txt(FILE *fp, char *buf);
-extern errr init_wf_info_txt(FILE *fp, char *buf);
-extern errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full);
-
-/* init2.c */
-extern void init_corruptions();
-extern void reinit_gods(s16b new_size);
-extern void reinit_quests(s16b new_size);
-extern void create_stores_stock(int t);
-extern errr init_v_info(void);
-extern void init_file_paths(char *path);
-extern void init_angband(void);
-extern errr init_buildings(void);
-extern s16b error_idx;
-extern s16b error_line;
-extern u32b fake_name_size;
-extern u32b fake_text_size;
-
-/* joke.c */
-extern bool_ gen_joke_monsters(void *data, void *in, void *out);
-
-/* loadsave.c */
-extern bool_ file_exist(cptr buf);
-extern s16b rd_variable(void);
-extern void wr_variable(s16b *var);
-extern void wr_scripts(void);
-extern bool_ load_dungeon(char *ext);
-extern void save_dungeon(void);
-extern bool_ save_player(void);
-extern bool_ load_player(void);
-extern errr rd_savefile_new(void);
-
-/* melee1.c */
-/* melee2.c */
-extern int monst_spell_monst_spell;
-extern bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note);
-extern void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear);
-extern int check_hit2(int power, int level, int ac);
-extern int get_attack_power(int effect);
-extern bool_ carried_make_attack_normal(int r_idx);
-extern bool_ make_attack_normal(int m_idx, byte divis);
-extern bool_ make_attack_spell(int m_idx);
-extern void process_monsters(void);
-extern void curse_equipment(int chance, int heavy_chance);
-extern void curse_equipment_dg(int chance, int heavy_chance);
-
-/* monster1.c */
-extern void screen_roff(int r_idx, int ego, int remember);
-extern void display_roff(int r_idx, int ego);
-extern void monster_description_out(int r_idx, int ego);
-
-/* monster2.c */
-extern void monster_set_level(int m_idx, int level);
-extern s32b modify_aux(s32b a, s32b b, char mod);
-extern void monster_msg(cptr fmt, ...);
-extern void cmonster_msg(char a, cptr fmt, ...);
-extern bool_ mego_ok(int r_idx, int ego);
-extern void monster_check_experience(int m_idx, bool_ silent);
-extern void monster_gain_exp(int m_idx, u32b exp, bool_ silent);
-extern monster_race* race_info_idx(int r_idx, int ego);
-extern int get_wilderness_flag(void);
-extern void sanity_blast(monster_type * m_ptr, bool_ necro);
-extern void delete_monster_idx(int i);
-extern void delete_monster(int y, int x);
-extern void compact_monsters(int size);
-extern void wipe_m_list(void);
-extern s16b m_pop(void);
-extern errr get_mon_num_prep(void);
-extern s16b get_mon_num(int level);
-extern void monster_desc(char *desc, monster_type *m_ptr, int mode);
-extern void monster_race_desc(char *desc, int r_idx, int ego);
-extern void lore_do_probe(int m_idx);
-extern void lore_treasure(int m_idx, int num_item, int num_gold);
-extern void update_mon(int m_idx, bool_ full);
-extern void update_monsters(bool_ full);
-extern void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr);
-extern bool_ bypass_r_ptr_max_num ;
-extern bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status);
-extern bool_ place_monster(int y, int x, bool_ slp, bool_ grp);
-extern bool_ alloc_horde(int y, int x);
-extern bool_ alloc_monster(int dis, bool_ slp);
-extern bool_ summon_specific_okay(int r_idx);
-extern int summon_specific_level;
-extern bool_ summon_specific(int y1, int x1, int lev, int type);
-extern void monster_swap(int y1, int x1, int y2, int x2);
-extern bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone);
-extern bool_ hack_message_pain_may_silent;
-extern void message_pain(int m_idx, int dam);
-extern void update_smart_learn(int m_idx, int what);
-extern bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok);
-extern bool_ place_monster_one_no_drop;
-extern monster_race *place_monster_one_race;
-extern s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status);
-extern s16b player_place(int y, int x);
-extern void monster_drop_carried_objects(monster_type *m_ptr);
-extern bool_ monster_dungeon(int r_idx);
-extern bool_ monster_quest(int r_idx);
-extern bool_ monster_ocean(int r_idx);
-extern bool_ monster_shore(int r_idx);
-extern bool_ monster_town(int r_idx);
-extern bool_ monster_wood(int r_idx);
-extern bool_ monster_volcano(int r_idx);
-extern bool_ monster_mountain(int r_idx);
-extern bool_ monster_grass(int r_idx);
-extern bool_ monster_deep_water(int r_idx);
-extern bool_ monster_shallow_water(int r_idx);
-extern bool_ monster_lava(int r_idx);
-extern void set_mon_num_hook(void);
-extern void set_mon_num2_hook(int y, int x);
-extern bool_ monster_can_cross_terrain(byte feat, monster_race *r_ptr);
-extern void corrupt_corrupted(void);
-
-/* monster3.c */
-extern void dump_companions(FILE *outfile);
-extern void do_cmd_companion(void);
-extern bool_ do_control_reconnect(void);
-extern bool_ do_control_drop(void);
-extern bool_ do_control_magic(void);
-extern bool_ do_control_pickup(void);
-extern bool_ do_control_inven(void);
-extern bool_ do_control_walk(void);
-extern bool_ can_create_companion(void);
-extern void ai_deincarnate(int m_idx);
-extern bool_ ai_possessor(int m_idx, int o_idx);
-extern bool_ ai_multiply(int m_idx);
-extern bool_ change_side(monster_type *m_ptr);
-extern int is_friend(monster_type *m_ptr);
-extern bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr);
-
-/* object1.c */
-/* object2.c */
-extern byte get_item_letter_color(object_type *o_ptr);
-extern void describe_device(object_type *o_ptr);
-extern void inc_stack_size(int item, int delta);
-extern void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag desc);
-extern void object_pickup(int this_o_idx);
-extern int get_slot(int slot);
-extern bool_ apply_flags_set(s16b a_idx, s16b set_idx, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
-extern bool_ apply_set(s16b a_idx, s16b set_idx);
-extern bool_ takeoff_set(s16b a_idx, s16b set_idx);
-extern bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent);
-extern object_type *get_object(int item);
-extern s32b calc_total_weight(void);
-extern void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows);
-extern bool_ info_spell;
-extern char spell_txt[50];
-extern bool_ grab_tval_desc(int tval);
-extern void init_match_theme(obj_theme theme);
-extern bool_ kind_is_artifactable(int k_idx);
-extern bool_ kind_is_good(int k_idx);
-extern int kind_is_legal_special;
-extern bool_ kind_is_legal(int k_idx);
-extern bool_ verify(cptr prompt, int item);
-extern void flavor_init(void);
-extern void reset_visuals(void);
-extern int object_power(object_type *o_ptr);
-extern bool_ object_flags_no_set;
-extern void object_flags(object_type *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
-extern void object_flags_known(object_type *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
-extern void object_desc(char *buf, object_type *o_ptr, int pref, int mode);
-extern void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode);
-extern bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it);
-extern char index_to_label(int i);
-extern s16b label_to_inven(int c);
-extern s16b label_to_equip(int c);
-extern s16b wield_slot_ideal(object_type *o_ptr, bool_ ideal);
-extern s16b wield_slot(object_type *o_ptr);
-extern cptr mention_use(int i);
-extern cptr describe_use(int i);
-extern void inven_item_charges(int item);
-extern void inven_item_describe(int item);
-extern void inven_item_increase(int item, int num);
-extern bool_ inven_item_optimize(int item);
-extern void floor_item_charges(int item);
-extern void floor_item_describe(int item);
-extern void floor_item_increase(int item, int num);
-extern void floor_item_optimize(int item);
-extern bool_ inven_carry_okay(object_type *o_ptr);
-extern s16b inven_carry(object_type *o_ptr, bool_ final);
-extern s16b inven_takeoff(int item, int amt, bool_ force_drop);
-extern void inven_drop(int item, int amt, int dy, int dx, bool_ silent);
-extern bool_ item_tester_okay(object_type *o_ptr);
-extern void display_inven(void);
-extern void display_equip(void);
-extern void show_inven();
-extern void show_equip();
-extern void toggle_inven_equip(void);
-extern bool_ (*get_item_extra_hook)(int *cp);
-extern bool_ get_item(int *cp, cptr pmt, cptr str, int mode);
-extern void excise_object_idx(int o_idx);
-extern void delete_object_idx(int o_idx);
-extern void delete_object(int y, int x);
-extern void compact_objects(int size);
-extern void wipe_o_list(void);
-extern s16b o_pop(void);
-extern errr get_obj_num_prep(void);
-extern s16b get_obj_num(int level);
-extern void object_known(object_type *o_ptr);
-extern void object_aware(object_type *o_ptr);
-extern void object_tried(object_type *o_ptr);
-extern s32b object_value(object_type *o_ptr);
-extern s32b object_value_real(object_type *o_ptr);
-extern bool_ object_similar(object_type *o_ptr, object_type *j_ptr);
-extern void object_absorb(object_type *o_ptr, object_type *j_ptr);
-extern s16b lookup_kind(int tval, int sval);
-extern void object_wipe(object_type *o_ptr);
-extern void object_prep(object_type *o_ptr, int k_idx);
-extern void object_copy(object_type *o_ptr, object_type *j_ptr);
-extern int hack_apply_magic_power;
-extern void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great);
-extern bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme theme);
-extern void place_object(int y, int x, bool_ good, bool_ great, int where);
-extern bool_ make_gold(object_type *j_ptr);
-extern void place_gold(int y, int x);
-extern void process_objects(void);
-extern s16b drop_near(object_type *o_ptr, int chance, int y, int x);
-extern void acquirement(int y1, int x1, int num, bool_ great, bool_ known);
-extern void pick_trap(int y, int x);
-extern cptr item_activation(object_type *o_ptr,byte num);
-extern void combine_pack(void);
-extern void reorder_pack(void);
-extern void display_koff(int k_idx);
-extern void random_artifact_resistance (object_type * o_ptr);
-extern void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific);
-extern s16b floor_carry(int y, int x, object_type *j_ptr);
-extern void pack_decay(int item);
-extern void floor_decay(int item);
-extern bool_ scan_floor(int *items, int *item_num, int y, int x, int mode);
-extern void show_floor(int y, int x);
-extern bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode);
-extern void py_pickup_floor(int pickup);
-extern s16b m_bonus(int max, int level);
-extern void object_gain_level(object_type *o_ptr);
-extern void gain_flag_group_flag(object_type *o_ptr, bool_ silent);
-extern void gain_flag_group(object_type *o_ptr, bool_ silent);
-extern void get_table_name(char * out_string);
-extern s32b flag_cost(object_type * o_ptr, int plusses);
-
-/* powers.c */
-extern void do_cmd_power(void);
-
-/* traps.c */
-extern bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item);
-extern void player_activate_door_trap(s16b y, s16b x);
-extern void place_trap(int y, int x);
-extern void place_trap_leveled(int y, int x, int lev);
-extern void place_trap_object(object_type *o_ptr);
-extern void wiz_place_trap(int y, int x, int idx);
-extern void do_cmd_set_trap(void);
-extern bool_ mon_hit_trap(int);
-
-/* spells1.c */
-extern byte spell_color(int type);
-extern s16b poly_r_idx(int r_idx);
-extern void get_pos_player(int dis, int *ny, int *nx);
-extern bool_ teleport_player_bypass;
-extern void teleport_to_player(int m_idx);
-extern void teleport_player_directed(int rad, int dir);
-extern void teleport_away(int m_idx, int dis);
-extern void teleport_player(int dis);
-extern void teleport_player_to(int ny, int nx);
-extern void teleport_monster_to(int m_idx, int ny, int nx);
-extern void teleport_player_level(void);
-extern void recall_player(int d, int f);
-extern void take_hit(int damage, cptr kb_str);
-extern void take_sanity_hit(int damage, cptr hit_from);
-extern void acid_dam(int dam, cptr kb_str);
-extern void elec_dam(int dam, cptr kb_str);
-extern void fire_dam(int dam, cptr kb_str);
-extern void cold_dam(int dam, cptr kb_str);
-extern bool_ inc_stat(int stat);
-extern bool_ dec_stat(int stat, int amount, int mode);
-extern bool_ res_stat(int stat, bool_ full);
-extern bool_ apply_disenchant(int mode);
-extern bool_ project_m(int who, int r, int y, int x, int dam, int typ);
-extern sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg);
-extern bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg);
-extern bool_ potion_smash_effect(int who, int y, int x, int o_sval);
-extern void do_poly_self(void);
-extern void corrupt_player(void);
-extern void generate_spell(int plev);
-extern bool_ unsafe;
-extern void describe_attack_fully(int type, char* r);
-extern s16b do_poly_monster(int y, int x);
-
-
-/* spells2.c */
-extern bool_ remove_curse_object(object_type *o_ptr, bool_ all);
-extern void curse_artifact(object_type * o_ptr);
-extern void grow_things(s16b type, int rad);
-extern void grow_grass(int rad);
-extern void grow_trees(int rad);
-extern bool_ hp_player(int num);
-extern bool_ heal_insanity(int val);
-extern void warding_glyph(void);
-extern void explosive_rune(void);
-extern bool_ do_dec_stat(int stat, int mode);
-extern bool_ do_res_stat(int stat, bool_ full);
-extern bool_ do_inc_stat(int stat);
-extern void identify_hooks(int i, object_type *o_ptr, identify_mode type);
-extern bool_ identify_pack(void);
-extern void identify_pack_fully(void);
-extern bool_ remove_curse(void);
-extern bool_ remove_all_curse(void);
-extern bool_ restore_level(void);
-extern void self_knowledge(FILE *fff);
-extern bool_ lose_all_info(void);
-extern bool_ detect_traps(int rad);
-extern bool_ detect_doors(int rad);
-extern bool_ detect_stairs(int rad);
-extern bool_ detect_treasure(int rad);
-extern bool_ hack_no_detect_message;
-extern bool_ detect_objects_gold(int rad);
-extern bool_ detect_objects_normal(int rad);
-extern bool_ detect_objects_magic(int rad);
-extern bool_ detect_monsters_normal(int rad);
-extern bool_ detect_monsters_invis(int rad);
-extern bool_ detect_monsters_evil(int rad);
-extern bool_ detect_monsters_good(int rad);
-extern bool_ detect_monsters_xxx(u32b match_flag, int rad);
-extern bool_ detect_monsters_string(cptr chars, int rad);
-extern bool_ detect_monsters_nonliving(int rad);
-extern bool_ detect_all(int rad);
-extern void stair_creation(void);
-extern bool_ wall_stone(int y, int x);
-extern bool_ enchant(object_type *o_ptr, int n, int eflag);
-extern bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval);
-extern bool_ ident_spell(void);
-extern bool_ ident_all(void);
-extern bool_ identify_fully(void);
-extern bool_ recharge(int num);
-extern bool_ speed_monsters(void);
-extern bool_ slow_monsters(void);
-extern bool_ sleep_monsters(void);
-extern bool_ conf_monsters(void);
-extern void aggravate_monsters(int who);
-extern bool_ genocide_aux(bool_ player_cast, char typ);
-extern bool_ genocide(bool_ player_cast);
-extern bool_ mass_genocide(bool_ player_cast);
-extern void do_probe(int m_idx);
-extern bool_ probing(void);
-extern void change_wild_mode(void);
-extern bool_ banish_evil(int dist);
-extern bool_ dispel_evil(int dam);
-extern bool_ dispel_good(int dam);
-extern bool_ dispel_undead(int dam);
-extern bool_ dispel_monsters(int dam);
-extern bool_ dispel_living(int dam);
-extern bool_ dispel_demons(int dam);
-extern bool_ turn_undead(void);
-extern void wipe(int y1, int x1, int r);
-extern void destroy_area(int y1, int x1, int r, bool_ full, bool_ bypass);
-extern void earthquake(int cy, int cx, int r);
-extern void lite_room(int y1, int x1);
-extern void unlite_room(int y1, int x1);
-extern bool_ lite_area(int dam, int rad);
-extern bool_ unlite_area(int dam, int rad);
-extern bool_ fire_ball_beam(int typ, int dir, int dam, int rad);
-extern bool_ fire_cloud(int typ, int dir, int dam, int rad, int time);
-extern bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff);
-extern bool_ fire_wall(int typ, int dir, int dam, int time);
-extern bool_ fire_ball(int typ, int dir, int dam, int rad);
-extern bool_ fire_bolt(int typ, int dir, int dam);
-extern bool_ fire_beam(int typ, int dir, int dam);
-extern bool_ fire_druid_ball(int typ, int dir, int dam, int rad);
-extern bool_ fire_druid_bolt(int typ, int dir, int dam);
-extern bool_ fire_druid_beam(int typ, int dir, int dam);
-extern void call_chaos(void);
-extern bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam);
-extern bool_ lite_line(int dir);
-extern bool_ drain_life(int dir, int dam);
-extern bool_ death_ray(int dir, int plev);
-extern bool_ wall_to_mud(int dir);
-extern bool_ destroy_door(int dir);
-extern bool_ disarm_trap(int dir);
-extern bool_ wizard_lock(int dir);
-extern bool_ heal_monster(int dir);
-extern bool_ speed_monster(int dir);
-extern bool_ slow_monster(int dir);
-extern bool_ sleep_monster(int dir);
-extern bool_ stasis_monster(int dir);
-extern bool_ confuse_monster(int dir, int plev);
-extern bool_ stun_monster(int dir, int plev);
-extern bool_ fear_monster(int dir, int plev);
-extern bool_ scare_monsters(void);
-extern bool_ poly_monster(int dir);
-extern bool_ clone_monster(int dir);
-extern bool_ teleport_monster(int dir);
-extern bool_ door_creation(void);
-extern bool_ trap_creation(void);
-extern bool_ glyph_creation(void);
-extern bool_ destroy_doors_touch(void);
-extern bool_ destroy_traps_touch(void);
-extern bool_ sleep_monsters_touch(void);
-extern bool_ alchemy(void);
-extern void activate_ty_curse(void);
-extern void activate_dg_curse(void);
-extern void activate_hi_summon(void);
-extern void summon_cyber(void);
-extern void wall_breaker(void);
-extern void bless_weapon(void);
-extern bool_ confuse_monsters(int dam);
-extern bool_ charm_monsters(int dam);
-extern bool_ charm_animals(int dam);
-extern bool_ charm_demons(int dam);
-extern bool_ stun_monsters(int dam);
-extern bool_ stasis_monsters(int dam);
-extern bool_ banish_monsters(int dist);
-extern bool_ turn_monsters(int dam);
-extern bool_ turn_evil(int dam);
-extern bool_ deathray_monsters(void);
-extern bool_ charm_monster(int dir, int plev);
-extern bool_ star_charm_monster(int dir, int plev);
-extern bool_ control_one_undead(int dir, int plev);
-extern bool_ charm_animal(int dir, int plev);
-extern bool_ mindblast_monsters(int dam);
-extern void alter_reality(void);
-extern void report_magics(void);
-extern void teleport_swap(int dir);
-extern void swap_position(int lty, int ltx);
-extern bool_ item_tester_hook_recharge(object_type *o_ptr);
-extern bool_ fire_explosion(int y, int x, int typ, int rad, int dam);
-extern bool_ fire_godly_wrath(int y, int x, int typ, int dir, int dam);
-extern bool_ invoke(int dam, int typ);
-extern bool_ project_hack(int typ, int dam);
-extern void project_meteor(int radius, int typ, int dam, u32b flg);
-extern bool_ item_tester_hook_artifactable(object_type *o_ptr);
-extern bool_ passwall(int dir, bool_ safe);
-extern bool_ project_hook(int typ, int dir, int dam, int flg);
-extern void random_misc (object_type * o_ptr, bool_ is_scroll);
-extern void random_plus(object_type * o_ptr, bool_ is_scroll);
-extern bool_ reset_recall(bool_ no_trepas_max_depth);
-extern void remove_dg_curse(void);
-extern void geomancy_random_wall(int y, int x);
-extern void geomancy_random_floor(int y, int x, bool_ kill_wall);
-extern void geomancy_dig(int oy, int ox, int dir, int length);
-extern void channel_the_elements(int y, int x, int level);
-
-/* spells3.c */
-s32b get_level_s(int sp, int max);
-
-extern s32b NOXIOUSCLOUD;
-extern s32b AIRWINGS;
-extern s32b INVISIBILITY;
-extern s32b POISONBLOOD;
-extern s32b THUNDERSTORM;
-extern s32b STERILIZE;
-
-casting_result air_noxious_cloud(int);
-char *air_noxious_cloud_info();
-casting_result air_wings_of_winds(int);
-char *air_wings_of_winds_info();
-casting_result air_invisibility(int);
-char *air_invisibility_info();
-casting_result air_poison_blood(int);
-char *air_poison_blood_info();
-casting_result air_thunderstorm(int);
-char *air_thunderstorm_info();
-casting_result air_sterilize(int);
-char *air_sterilize_info();
-
-extern s32b BLINK;
-extern s32b DISARM;
-extern s32b TELEPORT;
-extern s32b TELEAWAY;
-extern s32b RECALL;
-extern s32b PROBABILITY_TRAVEL;
-
-casting_result convey_blink(int);
-char *convey_blink_info();
-casting_result convey_disarm(int);
-char *convey_disarm_info();
-casting_result convey_teleport(int);
-char *convey_teleport_info();
-casting_result convey_teleport_away(int);
-char *convey_teleport_away_info();
-casting_result convey_recall(int);
-char *convey_recall_info();
-casting_result convey_probability_travel(int);
-char *convey_probability_travel_info();
-
-extern s32b DEMON_BLADE;
-extern s32b DEMON_MADNESS;
-extern s32b DEMON_FIELD;
-extern s32b DOOM_SHIELD;
-extern s32b UNHOLY_WORD;
-extern s32b DEMON_CLOAK;
-extern s32b DEMON_SUMMON;
-extern s32b DISCHARGE_MINION;
-extern s32b CONTROL_DEMON;
-
-casting_result demonology_demon_blade(int);
-char *demonology_demon_blade_info();
-casting_result demonology_demon_madness(int);
-char *demonology_demon_madness_info();
-casting_result demonology_demon_field(int);
-char *demonology_demon_field_info();
-casting_result demonology_doom_shield(int);
-char *demonology_doom_shield_info();
-casting_result demonology_unholy_word(int);
-char *demonology_unholy_word_info();
-casting_result demonology_demon_cloak(int);
-char *demonology_demon_cloak_info();
-casting_result demonology_summon_demon(int);
-char *demonology_summon_demon_info();
-casting_result demonology_discharge_minion(int);
-char *demonology_discharge_minion_info();
-casting_result demonology_control_demon(int);
-char *demonology_control_demon_info();
-
-extern s32b STARIDENTIFY;
-extern s32b IDENTIFY;
-extern s32b VISION;
-extern s32b SENSEHIDDEN;
-extern s32b REVEALWAYS;
-extern s32b SENSEMONSTERS;
-
-casting_result divination_greater_identify(int);
-char *divination_greater_identify_info();
-casting_result divination_identify(int);
-char *divination_identify_info();
-casting_result divination_vision(int);
-char *divination_vision_info();
-casting_result divination_sense_hidden(int);
-char *divination_sense_hidden_info();
-casting_result divination_reveal_ways(int);
-char *divination_reveal_ways_info();
-casting_result divination_sense_monsters(int);
-char *divination_sense_monsters_info();
-
-extern s32b STONESKIN;
-extern s32b DIG;
-extern s32b STONEPRISON;
-extern s32b STRIKE;
-extern s32b SHAKE;
-
-casting_result earth_stone_skin(int);
-char *earth_stone_skin_info();
-casting_result earth_dig(int);
-char *earth_dig_info();
-casting_result earth_stone_prison(int);
-char *earth_stone_prison_info();
-casting_result earth_strike(int);
-char *earth_strike_info();
-casting_result earth_shake(int);
-char *earth_shake_info();
-
-extern s32b ERU_SEE;
-extern s32b ERU_LISTEN;
-extern s32b ERU_UNDERSTAND;
-extern s32b ERU_PROT;
-
-casting_result eru_see_the_music(int);
-char *eru_see_the_music_info();
-casting_result eru_listen_to_the_music(int);
-char *eru_listen_to_the_music_info();
-casting_result eru_know_the_music(int);
-char *eru_know_the_music_info();
-casting_result eru_lay_of_protection(int);
-char *eru_lay_of_protection_info();
-
-extern s32b GLOBELIGHT;
-extern s32b FIREFLASH;
-extern s32b FIERYAURA;
-extern s32b FIREWALL;
-extern s32b FIREGOLEM;
-
-casting_result fire_globe_of_light(int);
-char *fire_globe_of_light_info();
-casting_result fire_fireflash(int);
-char *fire_fireflash_info();
-casting_result fire_fiery_shield(int);
-char *fire_fiery_shield_info();
-casting_result fire_firewall(int);
-char *fire_firewall_info();
-casting_result fire_golem(int);
-char *fire_golem_info();
-
-extern s32b CALL_THE_ELEMENTS;
-extern s32b CHANNEL_ELEMENTS;
-extern s32b ELEMENTAL_WAVE;
-extern s32b VAPORIZE;
-extern s32b GEOLYSIS;
-extern s32b DRIPPING_TREAD;
-extern s32b GROW_BARRIER;
-extern s32b ELEMENTAL_MINION;
-
-casting_result geomancy_call_the_elements(int);
-char *geomancy_call_the_elements_info();
-casting_result geomancy_channel_elements(int);
-char *geomancy_channel_elements_info();
-casting_result geomancy_elemental_wave(int);
-char *geomancy_elemental_wave_info();
-casting_result geomancy_vaporize(int);
-char *geomancy_vaporize_info();
-bool_ geomancy_vaporize_depends();
-casting_result geomancy_geolysis(int);
-char *geomancy_geolysis_info();
-bool_ geomancy_geolysis_depends();
-casting_result geomancy_dripping_tread(int);
-char *geomancy_dripping_tread_info();
-bool_ geomancy_dripping_tread_depends();
-casting_result geomancy_grow_barrier(int);
-char *geomancy_grow_barrier_info();
-bool_ geomancy_grow_barrier_depends();
-casting_result geomancy_elemental_minion(int);
-char *geomancy_elemental_minion_info();
-
-extern s32b MANATHRUST;
-extern s32b DELCURSES;
-extern s32b RESISTS;
-extern s32b MANASHIELD;
-
-casting_result mana_manathrust(int);
-char *mana_manathrust_info();
-casting_result mana_remove_curses(int);
-char *mana_remove_curses_info();
-casting_result mana_elemental_shield(int);
-char *mana_elemental_shield_info();
-casting_result mana_disruption_shield(int);
-char *mana_disruption_shield_info();
-
-extern s32b MANWE_SHIELD;
-extern s32b MANWE_AVATAR;
-extern s32b MANWE_BLESS;
-extern s32b MANWE_CALL;
-
-casting_result manwe_wind_shield(int);
-char *manwe_wind_shield_info();
-casting_result manwe_avatar(int);
-char *manwe_avatar_info();
-casting_result manwe_blessing(int);
-char *manwe_blessing_info();
-casting_result manwe_call(int);
-char *manwe_call_info();
-
-extern s32b MELKOR_CURSE;
-extern s32b MELKOR_CORPSE_EXPLOSION;
-extern s32b MELKOR_MIND_STEAL;
-
-void do_melkor_curse(int m_idx);
-
-casting_result melkor_curse(int);
-char *melkor_curse_info();
-casting_result melkor_corpse_explosion(int);
-char *melkor_corpse_explosion_info();
-casting_result melkor_mind_steal(int);
-char *melkor_mind_steal_info();
-
-extern s32b RECHARGE;
-extern s32b SPELLBINDER;
-extern s32b DISPERSEMAGIC;
-extern s32b TRACKER;
-extern s32b INERTIA_CONTROL;
-extern timer_type *TIMER_INERTIA_CONTROL;
-
-casting_result meta_recharge(int);
-char *meta_recharge_info();
-casting_result meta_spellbinder(int);
-char *meta_spellbinder_info();
-casting_result meta_disperse_magic(int);
-char *meta_disperse_magic_info();
-casting_result meta_tracker(int);
-char *meta_tracker_info();
-casting_result meta_inertia_control(int);
-char *meta_inertia_control_info();
-
-void meta_inertia_control_timer_callback();
-void meta_inertia_control_calc_mana(int *msp);
-void meta_inertia_control_hook_birth_objects();
-
-extern s32b CHARM;
-extern s32b CONFUSE;
-extern s32b ARMOROFFEAR;
-extern s32b STUN;
-
-casting_result mind_charm(int);
-char *mind_charm_info();
-casting_result mind_confuse(int);
-char *mind_confuse_info();
-casting_result mind_armor_of_fear(int);
-char *mind_armor_of_fear_info();
-casting_result mind_stun(int);
-char *mind_stun_info();
-
-extern s32b MAGELOCK;
-extern s32b SLOWMONSTER;
-extern s32b ESSENCESPEED;
-extern s32b BANISHMENT;
-
-casting_result tempo_magelock(int);
-char *tempo_magelock_info();
-casting_result tempo_slow_monster(int);
-char *tempo_slow_monster_info();
-casting_result tempo_essence_of_speed(int);
-char *tempo_essence_of_speed_info();
-casting_result tempo_banishment(int);
-char *tempo_banishment_info();
-
-extern s32b TULKAS_AIM;
-extern s32b TULKAS_WAVE;
-extern s32b TULKAS_SPIN;
-
-casting_result tulkas_divine_aim(int);
-char *tulkas_divine_aim_info();
-casting_result tulkas_wave_of_power(int);
-char *tulkas_wave_of_power_info();
-casting_result tulkas_whirlwind(int);
-char *tulkas_whirlwind_info();
-
-extern s32b DRAIN;
-extern s32b GENOCIDE;
-extern s32b WRAITHFORM;
-extern s32b FLAMEOFUDUN;
-
-int udun_in_book(s32b sval, s32b pval);
-int levels_in_book(s32b sval, s32b pval);
-
-casting_result udun_drain(int);
-char *udun_drain_info();
-casting_result udun_genocide(int);
-char *udun_genocide_info();
-casting_result udun_wraithform(int);
-char *udun_wraithform_info();
-casting_result udun_flame_of_udun(int);
-char *udun_flame_of_udun_info();
-
-extern s32b TIDALWAVE;
-extern s32b ICESTORM;
-extern s32b ENTPOTION;
-extern s32b VAPOR;
-extern s32b GEYSER;
-
-casting_result water_tidal_wave(int);
-char *water_tidal_wave_info();
-casting_result water_ice_storm(int);
-char *water_ice_storm_info();
-casting_result water_ent_potion(int);
-char *water_ent_potion_info();
-casting_result water_vapor(int);
-char *water_vapor_info();
-casting_result water_geyser(int);
-char *water_geyser_info();
-
-extern s32b YAVANNA_CHARM_ANIMAL;
-extern s32b YAVANNA_GROW_GRASS;
-extern s32b YAVANNA_TREE_ROOTS;
-extern s32b YAVANNA_WATER_BITE;
-extern s32b YAVANNA_UPROOT;
-
-casting_result yavanna_charm_animal(int);
-char *yavanna_charm_animal_info();
-casting_result yavanna_grow_grass(int);
-char *yavanna_grow_grass_info();
-casting_result yavanna_tree_roots(int);
-char *yavanna_tree_roots_info();
-casting_result yavanna_water_bite(int);
-char *yavanna_water_bite_info();
-casting_result yavanna_uproot(int);
-char *yavanna_uproot_info();
-
-extern s32b GROWTREE;
-extern s32b HEALING;
-extern s32b RECOVERY;
-extern s32b REGENERATION;
-extern s32b SUMMONANNIMAL;
-extern s32b GROW_ATHELAS;
-
-casting_result nature_grow_trees(int);
-char *nature_grow_trees_info();
-casting_result nature_healing(int);
-char *nature_healing_info();
-casting_result nature_recovery(int);
-char *nature_recovery_info();
-casting_result nature_regeneration(int);
-char *nature_regeneration_info();
-casting_result nature_summon_animal(int);
-char *nature_summon_animal_info();
-casting_result nature_grow_athelas(int);
-char *nature_grow_athelas_info();
-
-extern s32b DEVICE_HEAL_MONSTER;
-extern s32b DEVICE_SPEED_MONSTER;
-extern s32b DEVICE_WISH;
-extern s32b DEVICE_SUMMON;
-extern s32b DEVICE_MANA;
-extern s32b DEVICE_NOTHING;
-extern s32b DEVICE_LEBOHAUM;
-extern s32b DEVICE_MAGGOT;
-extern s32b DEVICE_HOLY_FIRE;
-extern s32b DEVICE_ETERNAL_FLAME;
-extern s32b DEVICE_DURANDIL;
-extern s32b DEVICE_THUNDERLORDS;
-extern s32b DEVICE_RADAGAST;
-extern s32b DEVICE_VALAROMA;
-
-casting_result device_heal_monster(int);
-char *device_heal_monster_info();
-casting_result device_haste_monster(int);
-char *device_haste_monster_info();
-casting_result device_wish(int);
-char *device_wish_info();
-casting_result device_summon_monster(int);
-char *device_summon_monster_info();
-casting_result device_mana(int);
-char *device_mana_info();
-casting_result device_nothing(int);
-char *device_nothing_info();
-casting_result device_lebohaum(int);
-char *device_lebohaum_info();
-casting_result device_maggot(int);
-char *device_maggot_info();
-casting_result device_holy_fire(int);
-char *device_holy_fire_info();
-casting_result device_eternal_flame(int);
-char *device_eternal_flame_info();
-casting_result device_durandil(int);
-char *device_durandil_info();
-casting_result device_thunderlords(int);
-char *device_thunderlords_info();
-casting_result device_radagast(int);
-char *device_radagast_info();
-casting_result device_valaroma(int);
-char *device_valaroma_info();
-
-extern s32b MUSIC_STOP;
-extern s32b MUSIC_HOLD;
-extern s32b MUSIC_CONF;
-extern s32b MUSIC_STUN;
-extern s32b MUSIC_LITE;
-extern s32b MUSIC_HEAL;
-extern s32b MUSIC_HERO;
-extern s32b MUSIC_TIME;
-extern s32b MUSIC_MIND;
-extern s32b MUSIC_BLOW;
-extern s32b MUSIC_WIND;
-extern s32b MUSIC_YLMIR;
-extern s32b MUSIC_AMBARKANTA;
-
-casting_result music_stop_singing_spell(int);
-char *music_stop_singing_info();
-
-int music_holding_pattern_lasting();
-casting_result music_holding_pattern_spell(int);
-char *music_holding_pattern_info();
-
-int music_illusion_pattern_lasting();
-casting_result music_illusion_pattern_spell(int);
-char *music_illusion_pattern_info();
-
-int music_stun_pattern_lasting();
-casting_result music_stun_pattern_spell(int);
-char *music_stun_pattern_info();
-
-int music_song_of_the_sun_lasting();
-casting_result music_song_of_the_sun_spell(int);
-char *music_song_of_the_sun_info();
-
-int music_flow_of_life_lasting();
-casting_result music_flow_of_life_spell(int);
-char *music_flow_of_life_info();
-
-int music_heroic_ballad_lasting();
-casting_result music_heroic_ballad_spell(int);
-char *music_heroic_ballad_info();
-
-int music_hobbit_melodies_lasting();
-casting_result music_hobbit_melodies_spell(int);
-char *music_hobbit_melodies_info();
-
-int music_clairaudience_lasting();
-casting_result music_clairaudience_spell(int);
-char *music_clairaudience_info();
-
-casting_result music_blow_spell(int);
-char *music_blow_info();
-
-casting_result music_gush_of_wind_spell(int);
-char *music_gush_of_wind_info();
-
-casting_result music_horns_of_ylmir_spell(int);
-char *music_horns_of_ylmir_info();
-
-casting_result music_ambarkanta_spell(int);
-char *music_ambarkanta_info();
-
-extern s32b AULE_FIREBRAND;
-extern s32b AULE_ENCHANT_WEAPON;
-extern s32b AULE_ENCHANT_ARMOUR;
-extern s32b AULE_CHILD;
-
-casting_result aule_firebrand_spell(int);
-char *aule_firebrand_info();
-casting_result aule_enchant_weapon_spell(int);
-char *aule_enchant_weapon_info();
-casting_result aule_enchant_armour_spell(int);
-char *aule_enchant_armour_info();
-casting_result aule_child_spell(int);
-char *aule_child_info();
-
-extern s32b MANDOS_TEARS_LUTHIEN;
-extern s32b MANDOS_SPIRIT_FEANTURI;
-extern s32b MANDOS_TALE_DOOM;
-extern s32b MANDOS_CALL_HALLS;
-
-casting_result mandos_tears_of_luthien_spell(int);
-char *mandos_tears_of_luthien_info();
-casting_result mandos_spirit_of_the_feanturi_spell(int);
-char *mandos_spirit_of_the_feanturi_info();
-casting_result mandos_tale_of_doom_spell(int);
-char *mandos_tale_of_doom_info();
-casting_result mandos_call_to_the_halls_spell(int);
-char *mandos_call_to_the_halls_info();
-
-extern s32b ULMO_BELEGAER;
-extern s32b ULMO_DRAUGHT_ULMONAN;
-extern s32b ULMO_CALL_ULUMURI;
-extern s32b ULMO_WRATH;
-
-casting_result ulmo_song_of_belegaer_spell(int);
-char *ulmo_song_of_belegaer_info();
-casting_result ulmo_draught_of_ulmonan_spell(int);
-char *ulmo_draught_of_ulmonan_info();
-casting_result ulmo_call_of_the_ulumuri_spell(int);
-char *ulmo_call_of_the_ulumuri_info();
-casting_result ulmo_wrath_of_ulmo_spell(int);
-char *ulmo_wrath_of_ulmo_info();
-
-extern s32b VARDA_LIGHT_VALINOR;
-extern s32b VARDA_CALL_ALMAREN;
-extern s32b VARDA_EVENSTAR;
-extern s32b VARDA_STARKINDLER;
-
-casting_result varda_light_of_valinor_spell(int);
-char *varda_light_of_valinor_info();
-casting_result varda_call_of_almaren_spell(int);
-char *varda_call_of_almaren_info();
-casting_result varda_evenstar_spell(int);
-char *varda_evenstar_info();
-casting_result varda_star_kindler_spell(int);
-char *varda_star_kindler_info();
-
-/* spells4.c */
-
-SGLIB_DEFINE_LIST_PROTOTYPES(spell_idx_list, compare_spell_idx, next);
-
-extern s32b SCHOOL_AIR;
-extern s32b SCHOOL_AULE;
-extern s32b SCHOOL_CONVEYANCE;
-extern s32b SCHOOL_DEMON;
-extern s32b SCHOOL_DEVICE;
-extern s32b SCHOOL_DIVINATION;
-extern s32b SCHOOL_EARTH;
-extern s32b SCHOOL_ERU;
-extern s32b SCHOOL_FIRE;
-extern s32b SCHOOL_GEOMANCY;
-extern s32b SCHOOL_MANA;
-extern s32b SCHOOL_MANDOS;
-extern s32b SCHOOL_MANWE;
-extern s32b SCHOOL_MELKOR;
-extern s32b SCHOOL_META;
-extern s32b SCHOOL_MIND;
-extern s32b SCHOOL_MUSIC;
-extern s32b SCHOOL_NATURE;
-extern s32b SCHOOL_TEMPORAL;
-extern s32b SCHOOL_TULKAS;
-extern s32b SCHOOL_UDUN;
-extern s32b SCHOOL_ULMO;
-extern s32b SCHOOL_VARDA;
-extern s32b SCHOOL_WATER;
-extern s32b SCHOOL_YAVANNA;
-
-void print_spell_desc(int s, int y);
-void init_school_books();
-school_book_type *school_books_at(int sval);
-void school_book_add_spell(school_book_type *school_book, s32b spell_idx);
-void random_book_setup(s16b sval, s32b spell_idx);
-int print_spell(cptr label, byte color, int y, s32b s);
-int print_book(s16b sval, s32b pval, object_type *obj);
-int school_book_length(int sval);
-int spell_x(int sval, int pval, int i);
-bool_ school_book_contains_spell(int sval, s32b spell_idx);
-void lua_cast_school_spell(s32b spell_idx, bool_ no_cost);
-
-void device_allocation_init(device_allocation *device_allocation, byte tval);
-device_allocation *device_allocation_new(byte tval);
-
-void dice_init(dice_type *dice, long base, long num, long sides);
-bool_ dice_parse(dice_type *dice, cptr s);
-void dice_parse_checked(dice_type *dice, cptr s);
-long dice_roll(dice_type *dice);
-void dice_print(dice_type *dice, char *buf);
-
-/* spells5.c */
-void school_spells_init();
-spell_type *spell_at(s32b index);
-s16b get_random_spell(s16b random_type, int lev);
-
-/* spells6.c */
-
-SGLIB_DEFINE_LIST_PROTOTYPES(school_provider, compare_school_provider, next);
-
-void schools_init();
-school_type *school_at(int index);
-
-void mana_school_calc_mana(int *msp);
-
-/* range.c */
-extern void range_init(range_type *range, s32b min, s32b max);
-
-/* randart.c */
-extern int get_activation_power(void);
-extern void build_prob(cptr learn);
-extern bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name);
-extern bool_ artifact_scroll(void);
-
-/* store.c */
-extern bool_ is_blessed(object_type *o_ptr);
-extern void do_cmd_store(void);
-extern void store_shuffle(int which);
-extern void store_maint(int town_num, int store_num);
-extern void store_init(int town_num, int store_num);
-extern void move_to_black_market(object_type * o_ptr);
-extern void do_cmd_home_trump(void);
-extern void store_sell(void);
-extern void store_purchase(void);
-extern void store_examine(void);
-extern void store_stole(void);
-extern void store_prt_gold(void);
-extern void store_request_item(void);
-
-/* bldg.c -KMW- */
-extern bool_ bldg_process_command(store_type *s_ptr, int i);
-extern void show_building(store_type *s_ptr);
-extern bool_ is_state(store_type *s_ptr, int state);
-extern void do_cmd_bldg(void);
-extern bool_ show_god_info(bool_ ext);
-extern void enter_quest(void);
-extern void select_bounties(void);
-
-/* util.c */
-extern void scansubdir(cptr dir);
-extern s32b rescale(s32b x, s32b max, s32b new_max);
-extern bool_ input_box(cptr text, int y, int x, char *buf, int max);
-extern void draw_box(int y, int x, int h, int w);
-extern void display_list(int y, int x, int h, int w, cptr title, cptr *list, int max, int begin, int sel, byte sel_color);
-extern int ask_menu(cptr ask, char **items, int max);
-extern cptr get_player_race_name(int pr, int ps);
-extern cptr get_month_name(int month, bool_ full, bool_ compact);
-extern cptr get_day(int day);
-extern s32b bst(s32b what, s32b t);
-extern errr path_parse(char *buf, int max, cptr file);
-extern errr path_temp(char *buf, int max);
-extern errr path_build(char *buf, int max, cptr path, cptr file);
-extern FILE *my_fopen(cptr file, cptr mode);
-extern errr my_fgets(FILE *fff, char *buf, huge n);
-extern errr my_fputs(FILE *fff, cptr buf, huge n);
-extern errr my_fclose(FILE *fff);
-extern errr fd_kill(cptr file);
-extern errr fd_move(cptr file, cptr what);
-extern errr fd_copy(cptr file, cptr what);
-extern int fd_make(cptr file, int mode);
-extern int fd_open(cptr file, int flags);
-extern errr fd_lock(int fd, int what);
-extern errr fd_seek(int fd, huge n);
-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 flush(void);
-extern void bell(void);
-extern void sound(int num);
-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 errr macro_add(cptr pat, cptr act);
-extern sint macro_find_exact(cptr pat);
-extern char inkey(void);
-extern void display_message(int x, int y, int split, byte color, cptr t);
-extern void cmsg_print(byte color, cptr msg);
-extern void msg_print(cptr msg);
-extern void cmsg_format(byte color, cptr fmt, ...);
-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);
-extern void prt(cptr str, int row, int col);
-extern void text_out_to_screen(byte a, cptr str);
-extern void text_out_to_file(byte a, cptr str);
-extern void text_out(cptr str);
-extern void text_out_c(byte a, cptr str);
-extern void clear_screen(void);
-extern void clear_from(int row);
-extern bool_ askfor_aux_complete;
-extern bool_ askfor_aux(char *buf, int len);
-extern bool_ get_string(cptr prompt, char *buf, int len);
-extern bool_ get_check(cptr prompt);
-extern bool_ get_com(cptr prompt, char *command);
-extern s32b get_quantity(cptr prompt, s32b max);
-extern void pause_line(int row);
-extern char request_command_ignore_keymaps[];
-extern bool_ request_command_inven_mode;
-extern void request_command(int shopping);
-extern bool_ is_a_vowel(int ch);
-extern int get_keymap_dir(char ch);
-extern byte count_bits(u32b array);
-extern void strlower(char *buf);
-extern int test_monster_name(cptr name);
-extern int test_mego_name(cptr name);
-extern int test_item_name(cptr name);
-extern char msg_box(cptr text, int y, int x);
-extern timer_type *new_timer(void (*callback)(), s32b delay);
-extern void del_timer(timer_type *t_ptr);
-extern int get_keymap_mode();
-
-/* main.c */
-extern bool_ private_check_user_directory(cptr dirpath);
-
-/* mimic.c */
-extern s16b resolve_mimic_name(cptr name);
-extern s16b find_random_mimic_shape(byte level, bool_ limit);
-extern cptr get_mimic_name(s16b mf_idx);
-extern cptr get_mimic_object_name(s16b mf_idx);
-extern byte get_mimic_level(s16b mf_idx);
-extern s32b get_mimic_random_duration(s16b mf_idx);
-extern byte calc_mimic();
-extern void calc_mimic_power();
-
-/* xtra1.c */
-extern void fix_message(void);
-extern void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a);
-extern int luck(int min, int max);
-extern int weight_limit(void);
-extern bool_ calc_powers_silent;
-extern void cnv_stat(int i, char *out_val);
-extern s16b modify_stat_value(int value, int amount);
-extern void calc_hitpoints(void);
-extern void notice_stuff(void);
-extern void update_stuff(void);
-extern void redraw_stuff(void);
-extern void window_stuff(void);
-extern void handle_stuff(void);
-extern bool_ monk_empty_hands(void);
-extern bool_ monk_heavy_armor(void);
-extern bool_ beastmaster_whip(void);
-extern void calc_bonuses(bool_ silent);
-extern void calc_sanity(void);
-extern void gain_fate(byte fate);
-extern void fate_desc(char *desc, int fate);
-extern void dump_fates(FILE *OutFile);
-
-/* xtra2.c */
-extern void do_rebirth(void);
-extern cptr get_subrace_title(int racem);
-extern void set_subrace_title(int racem, cptr name);
-extern void switch_subrace(int racem, bool_ copy_old);
-extern void drop_from_wild(void);
-extern void clean_wish_name(char *buf, char *name);
-extern bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, char *what);
-extern bool_ set_roots(int v, s16b ac, s16b dam);
-extern bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag);
-extern bool_ set_rush(int v);
-extern bool_ set_parasite(int v, int r);
-extern bool_ set_disrupt_shield(int v);
-extern bool_ set_prob_travel(int v);
-extern bool_ set_absorb_soul(int v);
-extern bool_ set_tim_breath(int v, bool_ magical);
-extern bool_ set_tim_precognition(int v);
-extern bool_ set_tim_deadly(int v);
-extern bool_ set_tim_res_time(int v);
-extern bool_ set_tim_reflect(int v);
-extern bool_ set_tim_thunder(int v, int p1, int p2);
-extern bool_ set_meditation(int v);
-extern bool_ set_strike(int v);
-extern bool_ set_walk_water(int v);
-extern bool_ set_tim_regen(int v, int p);
-extern bool_ set_tim_ffall(int v);
-extern bool_ set_tim_fly(int v);
-extern bool_ set_poison(int v);
-extern bool_ set_tim_fire_aura(int v);
-extern bool_ set_holy(int v);
-extern void set_grace(s32b v);
-extern bool_ set_mimic(int v, int p, int level);
-extern bool_ set_no_breeders(int v);
-extern bool_ set_invis(int v,int p);
-extern bool_ set_lite(int v);
-extern bool_ set_blind(int v);
-extern bool_ set_confused(int v);
-extern bool_ set_poisoned(int v);
-extern bool_ set_afraid(int v);
-extern bool_ set_paralyzed(int v);
-extern void dec_paralyzed();
-extern bool_ set_image(int v);
-extern bool_ set_fast(int v, int p);
-extern bool_ set_light_speed(int v);
-extern bool_ set_slow(int v);
-extern bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2);
-extern bool_ set_blessed(int v);
-extern bool_ set_hero(int v);
-extern bool_ set_shero(int v);
-extern bool_ set_protevil(int v);
-extern bool_ set_protgood(int v);
-extern bool_ set_protundead(int v);
-extern bool_ set_invuln(int v);
-extern bool_ set_tim_invis(int v);
-extern bool_ set_tim_infra(int v);
-extern bool_ set_mental_barrier(int v);
-extern bool_ set_oppose_acid(int v);
-extern bool_ set_oppose_elec(int v);
-extern bool_ set_oppose_fire(int v);
-extern bool_ set_oppose_cold(int v);
-extern bool_ set_oppose_pois(int v);
-extern bool_ set_oppose_ld(int v);
-extern bool_ set_oppose_cc(int v);
-extern bool_ set_oppose_ss(int v);
-extern bool_ set_oppose_nex(int v);
-extern bool_ set_stun(int v);
-extern bool_ set_cut(int v);
-extern bool_ set_food(int v);
-extern void check_experience(void);
-extern void check_experience_obj(object_type *o_ptr);
-extern void gain_exp(s32b amount);
-extern void lose_exp(s32b amount);
-extern int get_coin_type(monster_race *r_ptr);
-extern void monster_death(int m_idx);
-extern bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note);
-extern bool_ change_panel(int dy, int dx);
-extern void verify_panel(void);
-extern void resize_map(void);
-extern void resize_window(void);
-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_hack_dir(int *dp);
-extern bool_ get_rep_dir(int *dp);
-extern bool_ set_shadow(int v);
-extern bool_ set_tim_esp(int v);
-extern bool_ tgp_pt(int *x, int * y);
-extern bool_ tgt_pt (int *x, int *y);
-extern void do_poly_self(void);
-extern void do_poly_wounds(void);
-extern bool_ curse_weapon(void);
-extern bool_ curse_armor(void);
-extern void random_resistance(object_type * q_ptr, bool_ is_scroll, int specific);
-extern void great_side_effect(void);
-extern void nasty_side_effect(void);
-extern void deadly_side_effect(bool_ god);
-extern void godly_wrath_blast(void);
-extern int interpret_grace(void);
-extern int interpret_favor(void);
-extern void make_wish(void);
-extern bool_ set_sliding(s16b v);
-extern void create_between_gate(int dist, int y, int x);
-
-/* levels.c */
-extern bool_ get_dungeon_generator(char *buf);
-extern bool_ get_level_desc(char *buf);
-extern void get_level_flags(void);
-extern bool_ get_dungeon_name(char *buf);
-extern bool_ get_dungeon_special(char *buf);
-extern bool_ get_command(const char *file, char comm, char *param);
-extern int get_branch(void);
-extern int get_fbranch(void);
-extern int get_flevel(void);
-extern bool_ get_dungeon_save(char *buf);
-
-/* wizard2.c */
-extern void do_cmd_wiz_cure_all(void);
-extern void do_cmd_wiz_named_friendly(int r_idx, bool_ slp);
-extern tval_desc2 tvals[];
-
-/* notes.c */
-extern void show_notes_file(void);
-extern void output_note(char *final_note);
-extern void add_note(char *note, char code);
-extern void add_note_type(int note_number);
-
-/* squeltch.c */
-extern void squeltch_inventory(void);
-extern void squeltch_grid(void);
-extern void do_cmd_automatizer(void);
-extern void automatizer_add_rule(object_type *o_ptr, bool_ destroy);
-extern bool_ automatizer_create;
-extern void automatizer_init(cptr file_name);
-
-
-/*
- * Hack -- conditional (or "bizarre") externs
- */
-
-#ifdef SET_UID
-/* util.c */
-extern void user_name(char *buf, int id);
-#endif
-
-#ifndef HAS_MEMSET
-/* util.c */
-extern char *memset(char*, int, huge);
-#endif
-
-#ifndef HAS_STRICMP
-/* util.c */
-extern int stricmp(cptr a, cptr b);
-#endif
-
-#ifndef HAS_USLEEP
-/* util.c */
-extern int usleep(huge usecs);
-#endif
-
-#ifdef MACINTOSH
-/* main-mac.c */
-/* extern void main(void); */
-#endif
-
-#ifdef MACH_O_CARBON
-/* main-crb.c */
-extern int fsetfileinfo(char *path, u32b fcreator, u32b ftype);
-extern u32b _fcreator;
-extern u32b _ftype;
-#endif /* MACH_O_CARBON */
-
-#ifdef WINDOWS
-/* main-win.c */
-/* extern int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, ...); */
-#endif
-
-#if !defined(WINDOWS) && !defined(MACINTOSH)
-/* files.c */
-extern bool_ chg_to_txt(cptr base, cptr newname);
-#endif /* !WINDOWS && !MACINTOSH */
-
-/* util.c */
-extern void repeat_push(int what);
-extern bool_ repeat_pull(int *what);
-extern void repeat_check(void);
-extern void get_count(int number, int max);
-
-/* variable.c */
-extern bool_ easy_open;
-extern bool_ easy_tunnel;
-extern bool_ easy_disarm;
-
-/* cmd2.c */
-extern bool_ easy_open_door(int y, int x);
-
-/* cmd2.c */
-extern bool_ do_cmd_disarm_aux(int y, int x, int dir, int do_pickup);
-
-extern bool_ easy_floor;
-
-
-/* script.c */
-extern void init_lua_init(void);
-
-/* modules.c */
-extern void module_reset_dir(cptr dir, cptr new_path);
-extern cptr force_module;
-extern bool_ select_module(void);
-extern bool_ module_savefile_loadable(cptr savefile_mod);
-extern void tome_intro();
-extern void theme_intro();
-extern s16b *theme_race_status(int r_idx);
-extern void init_hooks_module();
-extern int find_module(cptr name);
-
-
-/* lua_bind.c */
-
-extern s16b add_new_power(cptr name, cptr desc, cptr gain, cptr lose, byte level, byte cost, byte stat, byte diff);
-
-extern void find_position(int y, int x, int *yy, int *xx);
-
-extern s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus);
-extern s32b get_level_device(s32b s, s32b max, s32b min);
-extern int get_mana(s32b s);
-extern s32b get_power(s32b s);
-extern s32b spell_chance(s32b s);
-extern s32b get_level(s32b s, s32b max, s32b min);
-extern void get_level_school(s32b s, s32b max, s32b min, s32b *level, bool_ *na);
-
-extern s32b get_level_max_stick;
-extern s32b get_level_use_stick;
-
-extern void set_target(int y, int x);
-extern void get_target(int dir, int *y, int *x);
-
-extern void get_map_size(char *name, int *ysize, int *xsize);
-extern void load_map(char *name, int *y, int *x);
-
-extern int lua_get_new_bounty_monster(int lev);
-
-extern char *lua_input_box(cptr title, int max);
-extern char lua_msg_box(cptr title);
-
-extern void increase_mana(int delta);
-
-extern timer_type *TIMER_AGGRAVATE_EVIL;
-
-void timer_aggravate_evil_enable();
-void timer_aggravate_evil_callback();
-
-/* skills.c */
-extern void dump_skills(FILE *fff);
-extern s16b find_skill(cptr name);
-extern s16b find_skill_i(cptr name);
-extern s16b get_skill(int skill);
-extern s16b get_skill_scale(int skill, u32b scale);
-extern void do_cmd_skill(void);
-extern void do_cmd_activate_skill(void);
-extern s16b melee_skills[MAX_MELEE];
-extern char *melee_names[MAX_MELEE];
-extern s16b get_melee_skills(void);
-extern s16b get_melee_skill(void);
-extern bool_ forbid_gloves(void);
-extern bool_ forbid_non_blessed(void);
-extern void compute_skills(s32b *v, s32b *m, int i);
-extern void select_default_melee(void);
-extern void do_get_new_skill(void);
-extern void init_skill(s32b value, s32b mod, int i);
-extern s16b find_ability(cptr name);
-extern void dump_abilities(FILE *fff);
-extern void do_cmd_ability(void);
-extern bool_ has_ability(int ab);
-extern void apply_level_abilities(int level);
-extern void recalc_skills(bool_ init);
-
-/* gods.c */
-extern void inc_piety(int god, s32b amt);
-extern void abandon_god(int god);
-extern int wisdom_scale(int max);
-extern int find_god(cptr name);
-extern void follow_god(int god, bool_ silent);
-extern bool_ god_enabled(struct deity_type *deity);
-extern deity_type *god_at(byte god_idx);
diff --git a/src/fate.hpp b/src/fate.hpp
new file mode 100644
index 00000000..906bc99d
--- /dev/null
+++ b/src/fate.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Fate descritpor.
+ */
+struct fate
+{
+ byte fate; /* Which fate */
+ byte level; /* On which level */
+ byte serious; /* Is it sure? */
+ s16b o_idx; /* Object to find */
+ s16b e_idx; /* Ego-Item to find */
+ s16b a_idx; /* Artifact to find */
+ s16b v_idx; /* Vault to find */
+ s16b r_idx; /* Monster to find */
+ s16b count; /* Number of things */
+ s16b time; /* Turn before */
+ bool_ know; /* Has it been predicted? */
+ bool_ icky; /* Hackish runtime-only flag */
+};
diff --git a/src/feature_type.hpp b/src/feature_type.hpp
new file mode 100644
index 00000000..1a79aeb3
--- /dev/null
+++ b/src/feature_type.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Terrain feature descriptor.
+ */
+struct feature_type
+{
+ char *name; /* Name */
+
+ const char *text; /* Text. May point to shared read-only memory, DO NOT FREE! */
+ const char *tunnel; /* Text for tunneling. May point to shared read-only memory, DO NOT FREE! */
+ const char *block; /* Text for blocking. May point to shared read-only memory, DO NOT FREE! */
+
+ byte mimic; /* Feature to mimic */
+
+ u32b flags1; /* First set of flags */
+
+ byte extra; /* Extra byte (unused) */
+
+ 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 */
+
+ byte shimmer[7]; /* Shimmer colors */
+
+ int d_dice[4]; /* Number of dices */
+ int d_side[4]; /* Number of sides */
+ int d_frequency[4]; /* Frequency of damage (1 is the minimum) */
+ int d_type[4]; /* Type of damage */
+};
diff --git a/src/feature_type_fwd.hpp b/src/feature_type_fwd.hpp
new file mode 100644
index 00000000..168ec6c7
--- /dev/null
+++ b/src/feature_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct feature_type;
diff --git a/src/files.c b/src/files.cc
index 664c96d7..2ff6a909 100644
--- a/src/files.c
+++ b/src/files.cc
@@ -1,7 +1,3 @@
-/* File: files.c */
-
-/* Purpose: code dealing with files (and death) */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,10 +6,55 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "hiscore.h"
-
+#include "files.hpp"
+#include "files.h"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "cmd3.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "hiscore.hpp"
+#include "hook_chardump_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "levels.hpp"
+#include "loadsave.h"
+#include "loadsave.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_spec.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spells2.hpp"
+#include "store_info_type.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "xtra1.hpp"
+
+#include <memory>
+#include <unordered_set>
/*
* Extract the first few "tokens" from a buffer
@@ -429,9 +470,9 @@ errr process_pref_file_aux(char *buf)
if (!tmp[0] || tmp[1]) return (1);
i = (byte)(tmp[0]);
- string_free(keymap_act[mode][i]);
+ free(keymap_act[mode][i]);
- keymap_act[mode][i] = string_make(macro__buf);
+ keymap_act[mode][i] = strdup(macro__buf);
return (0);
}
@@ -464,10 +505,14 @@ errr process_pref_file_aux(char *buf)
if (macro_template != NULL)
{
- free(macro_template);
+ delete[] macro_template;
macro_template = NULL;
+
for (i = 0; i < max_macrotrigger; i++)
- free(macro_trigger_name[i]);
+ {
+ delete[] macro_trigger_name[i];
+ macro_trigger_name[i] = nullptr;
+ }
max_macrotrigger = 0;
}
@@ -478,7 +523,7 @@ errr process_pref_file_aux(char *buf)
len = strlen(zz[0]) + 1 + num + 1;
for (i = 0; i < num; i++)
len += strlen(zz[2 + i]) + 1;
- macro_template = malloc(len);
+ macro_template = new char[len];
strcpy(macro_template, zz[0]);
macro_modifier_chr =
@@ -508,7 +553,7 @@ errr process_pref_file_aux(char *buf)
len = strlen(zz[0]) + 1 + strlen(zz[1]) + 1;
if (tok == 3)
len += strlen(zz[2]) + 1;
- macro_trigger_name[m] = malloc(len);
+ macro_trigger_name[m] = new char[len];
t = macro_trigger_name[m];
s = zz[0];
@@ -850,19 +895,19 @@ static cptr process_pref_file_expr(char **sp, char *fp)
/* Race */
else if (streq(b + 1, "RACE"))
{
- v = rp_ptr->title + rp_name;
+ v = rp_ptr->title;
}
/* Race */
else if (streq(b + 1, "RACEMOD"))
{
- v = rmp_ptr->title + rmp_name;
+ v = rmp_ptr->title;
}
/* Class */
else if (streq(b + 1, "CLASS"))
{
- v = spp_ptr->title + c_name;
+ v = spp_ptr->title;
}
/* Player */
@@ -1029,7 +1074,7 @@ static void prt_lnum(cptr header, s32b num, int row, int col, byte color)
* Print number with header at given row, column
*/
static void prt_num(cptr header, int num, int row, int col, byte color,
- char *space)
+ cptr space)
{
int len = strlen(header);
char out_val[32];
@@ -1562,28 +1607,28 @@ void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
if (get_skill(SKILL_WATER) >= 30) (*f5) |= TR5_WATER_BREATH;
/* Gods */
- GOD(GOD_ERU)
+ if (p_ptr->pgod == GOD_ERU)
{
if ((p_ptr->grace >= 100) || (p_ptr->grace <= -100)) (*f1) |= TR1_MANA;
if (p_ptr->grace > 10000) (*f1) |= TR1_WIS;
}
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
(*f2) |= TR2_RES_FIRE;
if (p_ptr->melkor_sacrifice > 0) (*f2) |= TR2_LIFE;
if (p_ptr->grace > 10000) (*f1) |= (TR1_STR | TR1_CON | TR1_INT | TR1_WIS | TR1_CHR);
- PRAY_GOD(GOD_MELKOR)
+ if (p_ptr->praying)
{
if (p_ptr->grace > 5000) (*f2) |= TR2_INVIS;
if (p_ptr->grace > 15000) (*f2) |= TR2_IM_FIRE;
}
}
- GOD(GOD_MANWE)
+ if (p_ptr->pgod == GOD_MANWE)
{
if (p_ptr->grace >= 2000) (*f3) |= TR3_FEATHER;
- PRAY_GOD(GOD_MANWE)
+ if (p_ptr->praying)
{
if (p_ptr->grace >= 7000) (*f2) |= TR2_FREE_ACT;
if (p_ptr->grace >= 15000) (*f4) |= TR4_FLY;
@@ -1591,13 +1636,13 @@ void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
}
}
- GOD(GOD_TULKAS)
+ if (p_ptr->pgod == GOD_TULKAS)
{
if (p_ptr->grace > 5000) (*f1) |= TR1_CON;
if (p_ptr->grace > 10000) (*f1) |= TR1_STR;
}
- GOD(GOD_AULE)
+ if (p_ptr->pgod == GOD_AULE)
{
if (p_ptr->grace > 5000)
{
@@ -1605,7 +1650,7 @@ void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
}
}
- GOD(GOD_MANDOS)
+ if (p_ptr->pgod == GOD_MANDOS)
{
(*f2) |= TR2_RES_NETHER;
@@ -1622,7 +1667,7 @@ void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
}
}
- GOD(GOD_ULMO)
+ if (p_ptr->pgod == GOD_ULMO)
{
(*f5) |= TR5_WATER_BREATH;
@@ -2175,8 +2220,8 @@ void display_player(int mode)
c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
sprintf(buf, "%s", get_player_race_name(p_ptr->prace, p_ptr->pracem));
c_put_str(TERM_L_BLUE, buf, 4, 9);
- c_put_str(TERM_L_BLUE, spp_ptr->title + c_name, 5, 9);
- c_put_str(TERM_L_BLUE, r_name + r_ptr->name, 6, 9);
+ c_put_str(TERM_L_BLUE, spp_ptr->title, 5, 9);
+ c_put_str(TERM_L_BLUE, r_ptr->name, 6, 9);
c_put_str(TERM_L_BLUE, deity_info[p_ptr->pgod].name, 7, 9);
/* Age, Height, Weight, Social */
@@ -2281,11 +2326,17 @@ cptr describe_player_location()
int feat = wild_map[pwy][pwx].feat;
if (dungeon_type != DUNGEON_WILDERNESS && dun_level > 0)
- sprintf(desc, "on level %d of %s", dun_level, d_info[dungeon_type].name + d_name);
+ {
+ sprintf(desc, "on level %d of %s", dun_level, d_info[dungeon_type].name);
+ }
else if (wf_info[feat].terrain_idx == TERRAIN_TOWN)
- sprintf(desc, "in the town of %s", wf_info[feat].name + wf_name);
+ {
+ sprintf(desc, "in the town of %s", wf_info[feat].name);
+ }
else if (wf_info[feat].entrance)
- sprintf(desc, "near %s", wf_info[feat].name + wf_name);
+ {
+ sprintf(desc, "near %s", wf_info[feat].name);
+ }
else
{
/*
@@ -2322,10 +2373,14 @@ cptr describe_player_location()
}
if (!landmark)
- sprintf(desc, "in %s", wf_info[feat].text + wf_text);
+ {
+ sprintf(desc, "in %s", wf_info[feat].text);
+ }
else if (pwx == lwx && pwy == lwy)
+ {
/* Paranoia; this should have been caught above */
- sprintf(desc, "near %s", wf_info[feat].name + wf_name);
+ sprintf(desc, "near %s", wf_info[feat].name);
+ }
else
{
/*
@@ -2347,8 +2402,10 @@ cptr describe_player_location()
if (dx * 81 < dy * 31) ew = "";
sprintf(desc, "in %s %s%s of %s",
- wf_info[feat].text + wf_text, ns, ew,
- wf_info[landmark].name + wf_name);
+ wf_info[feat].text,
+ ns,
+ ew,
+ wf_info[landmark].name);
}
}
@@ -2456,7 +2513,7 @@ void file_character_print_store(FILE *fff, wilderness_type_info *place, int stor
if (st_ptr->stock_num)
{
/* Header with name of the town */
- fprintf(fff, " [%s Inventory - %s]\n\n", st_name + st_info[store].name, wf_name + place->name);
+ fprintf(fff, " [%s Inventory - %s]\n\n", st_info[store].name, place->name);
/* Dump all available items */
for (i = 0; i < st_ptr->stock_num; i++)
@@ -2469,46 +2526,26 @@ void file_character_print_store(FILE *fff, wilderness_type_info *place, int stor
}
}
-/*
+/**
* Helper function for file_character
*
* Checks if the store hasn't been added to the list yet, and then adds it if it
* was not already there. XXX This is an ugly workaround for the double Gondolin
* problem.
- *
- * Beware of the ugly pointer gymnastics.
*/
-bool_ file_character_check_stores(store_type ***store_list, int *store_list_count, wilderness_type_info *place, int store)
+static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_stores, wilderness_type_info *place, int store)
{
town_type *town = &town_info[place->entrance];
store_type *st_ptr = &town->store[store];
- store_type **head = *store_list;
- int i;
-
- /* check the list for this store */
- for (i = 0; i < *store_list_count; ++i)
- {
- if (*head == st_ptr) return FALSE;
- ++head;
- }
- /* make room for the new one in the array */
- if (*store_list)
- {
- head = *store_list;
- *store_list = C_RNEW(*store_list_count + 1, store_type *);
- C_COPY(*store_list, head, *store_list_count, store_type *);
- C_FREE(head, *store_list_count, store_type *);
- }
- else
+ // Already seen store?
+ if (seen_stores->find(st_ptr) != seen_stores->end())
{
- *store_list = RNEW(store_type *);
+ return FALSE;
}
- /* update data */
- (*store_list)[*store_list_count] = st_ptr;
- ++*store_list_count;
-
+ // Add
+ seen_stores->insert(st_ptr);
return TRUE;
}
@@ -2526,8 +2563,6 @@ errr file_character(cptr name, bool_ full)
int fd = -1;
FILE *fff = NULL;
char buf[1024];
- store_type **store_list = NULL;
- int store_list_count = 0;
/* Build the filename */
path_build(buf, 1024, ANGBAND_DIR_USER, name);
@@ -2619,19 +2654,12 @@ errr file_character(cptr name, bool_ full)
}
/* List the patches */
- hook_file = fff;
-
fprintf(fff, "\n\n [Miscellaneous information]\n");
if (joke_monsters)
fprintf(fff, "\n Joke monsters: ON");
else
fprintf(fff, "\n Joke monsters: OFF");
- if (p_ptr->maximize)
- fprintf(fff, "\n Maximize mode: ON");
- else
- fprintf(fff, "\n Maximize mode: OFF");
-
if (p_ptr->preserve)
fprintf(fff, "\n Preserve Mode: ON");
else
@@ -2664,7 +2692,7 @@ errr file_character(cptr name, bool_ full)
{
if (max_dlv[y])
fprintf(fff, "\n %s: Level %d (%d')",
- d_name + d_info[y].name,
+ d_info[y].name,
max_dlv[y], 50 * (max_dlv[y]));
}
fprintf(fff, "\n");
@@ -2672,7 +2700,7 @@ errr file_character(cptr name, bool_ full)
if (noscore)
fprintf(fff, "\n You have done something illegal.");
- if (PRACE_FLAGS(PR1_EXPERIMENTAL))
+ if (race_flags1_p(PR1_EXPERIMENTAL))
fprintf(fff, "\n You have done something experimental.");
{
@@ -2727,8 +2755,8 @@ errr file_character(cptr name, bool_ full)
fprintf(fff, "\n You have defeated %ld enemies.", (long int) Total);
}
- hook_file = fff;
- process_hooks(HOOK_CHAR_DUMP, "()");
+ struct hook_chardump_in in = { fff };
+ process_hooks_new(HOOK_CHAR_DUMP, &in, NULL);
/* Date */
{
@@ -2830,24 +2858,30 @@ errr file_character(cptr name, bool_ full)
fprintf(fff, "\n\n");
/* Print all homes in the different towns */
- for (j = 0; j < max_wf_idx; j++)
{
- if (wf_info[j].feat == FEAT_TOWN &&
- file_character_check_stores(&store_list, &store_list_count, &wf_info[j], 7))
- file_character_print_store(fff, &wf_info[j], 7, full);
+ std::unordered_set<store_type *> seen_stores;
+ for (j = 0; j < max_wf_idx; j++)
+ {
+ if (wf_info[j].feat == FEAT_TOWN &&
+ file_character_check_stores(&seen_stores, &wf_info[j], 7))
+ {
+ file_character_print_store(fff, &wf_info[j], 7, full);
+ }
+ }
}
- store_list = C_FREE(store_list, store_list_count, store_type *);
- store_list_count = 0;
/* Print all Mathom-houses in the different towns */
- for (j = 0; j < max_wf_idx; j++)
{
- if (wf_info[j].feat == FEAT_TOWN &&
- file_character_check_stores(&store_list, &store_list_count, &wf_info[j], 57))
- file_character_print_store(fff, &wf_info[j], 57, full);
+ std::unordered_set<store_type *> seen_stores;
+ for (j = 0; j < max_wf_idx; j++)
+ {
+ if (wf_info[j].feat == FEAT_TOWN &&
+ file_character_check_stores(&seen_stores, &wf_info[j], 57))
+ {
+ file_character_print_store(fff, &wf_info[j], 57, full);
+ }
+ }
}
- store_list = C_FREE(store_list, store_list_count, store_type *);
- store_list_count = 0;
text_out_indent = 0;
@@ -2933,9 +2967,6 @@ bool_ show_file(cptr name, cptr what, int line, int mode)
/* Find this string (if any) */
cptr find = NULL;
- /* Char array type of hyperlink info */
- hyperlink_type *h_ptr;
-
/* Pointer to general buffer in the above */
char *buf;
@@ -2945,7 +2976,8 @@ bool_ show_file(cptr name, cptr what, int line, int mode)
int wid, hgt;
/* Allocate hyperlink data */
- MAKE(h_ptr, hyperlink_type);
+ std::unique_ptr<hyperlink_type> h_ptr(new hyperlink_type);
+ memset(h_ptr.get(), 0, sizeof(hyperlink_type));
/* Setup buffer pointer */
buf = h_ptr->rbuf;
@@ -3015,9 +3047,6 @@ bool_ show_file(cptr name, cptr what, int line, int mode)
msg_format("Cannot open '%s'.", name);
msg_print(NULL);
- /* Free hyperlink info */
- KILL(h_ptr, hyperlink_type);
-
/* Oops */
return (TRUE);
}
@@ -3145,9 +3174,6 @@ bool_ show_file(cptr name, cptr what, int line, int mode)
/* Oops */
if (!fff)
{
- /* Free hyperlink info */
- KILL(h_ptr, hyperlink_type);
-
return (FALSE);
}
@@ -3488,9 +3514,6 @@ bool_ show_file(cptr name, cptr what, int line, int mode)
/* Close the file */
my_fclose(fff);
- /* Free hyperlink buffers */
- KILL(h_ptr, hyperlink_type);
-
/* Escape */
if (k == ESCAPE) return (FALSE);
@@ -3519,9 +3542,6 @@ bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_
/* Current html file */
FILE *htm = NULL;
- /* Char array type of hyperlink info */
- hyperlink_type *h_ptr;
-
cptr file_ext = "html";
cptr link_prefix = "";
cptr link_suffix = "";
@@ -3530,7 +3550,8 @@ bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_
char *buf;
/* Allocate hyperlink data */
- MAKE(h_ptr, hyperlink_type);
+ std::unique_ptr<hyperlink_type> h_ptr(new hyperlink_type);
+ memset(h_ptr.get(), 0, sizeof(hyperlink_type));
/* Setup buffer pointer */
buf = h_ptr->rbuf;
@@ -3565,9 +3586,6 @@ bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_
/* Oops */
if (!fff || !htm)
{
- /* Free hyperlink info */
- KILL(h_ptr, hyperlink_type);
-
my_fclose(fff);
my_fclose(htm);
@@ -3811,13 +3829,61 @@ bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_
my_fclose(htm);
my_fclose(fff);
- /* Free hyperlink buffers */
- KILL(h_ptr, hyperlink_type);
-
/* Normal return */
return (TRUE);
}
+static void cmovie_clean_line(int y, char *abuf, char *cbuf)
+{
+ const byte *ap = Term->scr->a[y];
+ const char *cp = Term->scr->c[y];
+
+ byte a;
+ char c;
+
+ int x;
+ int wid, hgt;
+ int screen_wid, screen_hgt;
+
+
+ /* Retrieve current screen size */
+ Term_get_size(&wid, &hgt);
+
+ /* Calculate the size of dungeon map area */
+ screen_wid = wid - (COL_MAP + 1);
+ screen_hgt = hgt - (ROW_MAP + 1);
+
+ /* For the time being, assume 80 column display XXX XXX XXX */
+ for (x = 0; x < wid; x++)
+ {
+ /* Convert dungeon map into default attr/chars */
+ if (!character_icky &&
+ ((x - COL_MAP) >= 0) &&
+ ((x - COL_MAP) < screen_wid) &&
+ ((y - ROW_MAP) >= 0) &&
+ ((y - ROW_MAP) < screen_hgt))
+ {
+ /* Retrieve default attr/char */
+ map_info_default(y + panel_row_prt, x + panel_col_prt, &a, &c);
+
+ abuf[x] = conv_color[a & 0xf];
+
+ if (c == '\0') cbuf[x] = ' ';
+ else cbuf[x] = c;
+ }
+
+ else
+ {
+ abuf[x] = conv_color[ap[x] & 0xf];
+ cbuf[x] = cp[x];
+ }
+ }
+
+ /* Null-terminate the prepared strings */
+ abuf[x] = '\0';
+ cbuf[x] = '\0';
+}
+
/* Take an help file screenshot(yes yes I know..) */
void help_file_screenshot(cptr name)
{
@@ -4050,7 +4116,7 @@ void process_player_name(bool_ sf)
#endif
-#if defined(WINDOWS) || defined(MSDOS)
+#if defined(WINDOWS)
/* Hack -- max length */
if (k > 8) k = 8;
@@ -4215,7 +4281,7 @@ void do_cmd_save_game(void)
if (!is_autosave)
{
/* Disturb the player */
- disturb(1, 0);
+ disturb(1);
}
/* Clear messages */
@@ -4271,7 +4337,7 @@ void autosave_checkpoint()
/*
* Hack -- Calculates the total number of points earned -JWT-
*/
-long total_points(void)
+static long total_points(void)
{
s16b max_dl = 0, i, k;
long temp, Total = 0;
@@ -4281,12 +4347,11 @@ long total_points(void)
if (!comp_death) comp_death = 1;
if (p_ptr->preserve) mult -= 1; /* Penalize preserve, maximize modes */
- if (p_ptr->maximize) mult -= 1;
+ mult -= 1; /* maximize pentalty, always on */
if (auto_scum) mult -= 4;
if (small_levels) mult += ((always_small_level) ? 4 : 10);
if (empty_levels) mult += 2;
if (smart_learn) mult += 4;
- if (smart_cheat) mult += 4;
if (mult < 2) mult = 2; /* At least 10% of the original score */
/* mult is now between 2 and 40, i.e. 10% and 200% */
@@ -4368,8 +4433,6 @@ long total_points(void)
}
temp += Total * 50;
- temp += total_bounties * 100;
-
if (total_winner) temp += 1000000;
@@ -4429,7 +4492,7 @@ static void print_tomb(void)
FILE *fp;
- time_t ct = time((time_t)0);
+ time_t ct = time(nullptr);
/* Clear screen */
@@ -4467,7 +4530,7 @@ static void print_tomb(void)
/* Normal */
else
{
- p = cp_ptr->titles[(p_ptr->lev - 1) / 5] + c_text;
+ p = cp_ptr->titles[(p_ptr->lev - 1) / 5];
}
center_string(buf, player_name);
@@ -4480,7 +4543,7 @@ static void print_tomb(void)
put_str(buf, 8, 11);
- center_string(buf, spp_ptr->title + c_name);
+ center_string(buf, spp_ptr->title);
put_str(buf, 10, 11);
(void)sprintf(tmp, "Level: %d", (int)p_ptr->lev);
@@ -4623,8 +4686,7 @@ static void show_info(void)
if (equip_cnt)
{
Term_clear();
- item_tester_full = TRUE;
- show_equip();
+ show_equip_full();
prt("You are using: -more-", 0, 0);
if (inkey() == ESCAPE) return;
}
@@ -4633,8 +4695,7 @@ static void show_info(void)
if (inven_cnt)
{
Term_clear();
- item_tester_full = TRUE;
- show_inven();
+ show_inven_full();
prt("You are carrying: -more-", 0, 0);
if (inkey() == ESCAPE) return;
}
@@ -4750,7 +4811,7 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
cptr gold, when, aged;
- int in_arena, in_quest;
+ int in_quest;
/* Hack -- indicate death in yellow */
attr = (j == note) ? TERM_YELLOW : TERM_WHITE;
@@ -4786,7 +4847,6 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
cdun = atoi(the_score.cur_dun);
mdun = atoi(the_score.max_dun);
- in_arena = atoi(the_score.inside_arena);
in_quest = atoi(the_score.inside_quest);
/* Hack -- extract the gold and such */
@@ -4796,8 +4856,11 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
/* Dump some info */
sprintf(out_val, "%3d.%9s %s the %s %s, Level %d",
- place, the_score.pts, the_score.who,
- get_player_race_name(pr, ps), class_info[pc].spec[pcs].title + c_name,
+ place,
+ the_score.pts,
+ the_score.who,
+ get_player_race_name(pr, ps),
+ class_info[pc].spec[pcs].title,
clev);
/* Append a "maximum level" */
@@ -4807,12 +4870,7 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
c_put_str(attr, out_val, n*4 + 2, 0);
/* Another line of info */
- if (in_arena)
- {
- sprintf(out_val, " Killed by %s in the Arena",
- the_score.how);
- }
- else if (in_quest)
+ if (in_quest)
{
sprintf(out_val, " Killed by %s while questing",
the_score.how);
@@ -4855,48 +4913,14 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig
/*
- * Hack -- Display the scores in a given range and quit.
- *
- * This function is only called from "main.c" when the user asks
- * to see the "high scores".
- */
-void display_scores(int from, int to)
-{
- char buf[1024];
- int highscore_fd;
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw");
-
- /* 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(highscore_fd, from, to, -1, NULL);
-
- /* Shut the high score file */
- fd_close(highscore_fd);
-
- /* Quit */
- quit(NULL);
-}
-
-
-/*
* show_highclass - selectively list highscores based on class
* -KMW-
*/
void show_highclass(int building)
{
- register int i = 0, j, m = 0;
- int pr, pc, clev, al;
+ int i = 0, j, m = 0;
+ int pr, pc, clev;
high_score the_score;
char buf[1024], out_val[256];
int highscore_fd;
@@ -4964,13 +4988,11 @@ void show_highclass(int building)
pr = atoi(the_score.p_r);
pc = atoi(the_score.p_c);
clev = atoi(the_score.cur_lev);
- al = atoi(the_score.arena_number);
- if (((pc == (building - 10)) && (building != 1) && (building != 2)) ||
- ((building == 1) && (clev >= PY_MAX_LEVEL)) ||
- ((building == 2) && (al > MAX_ARENA_MONS)))
+ if (((pc == (building - 10)) && (building != 1)) ||
+ ((building == 1) && (clev >= PY_MAX_LEVEL)))
{
sprintf(out_val, "%3d) %s the %s (Level %2d)",
- (m + 1), the_score.who, rp_name + race_info[pr].title, clev);
+ (m + 1), the_score.who, race_info[pr].title, clev);
prt(out_val, (m + 7), 0);
m++;
}
@@ -4981,21 +5003,15 @@ void show_highclass(int building)
if ((building == 1) && (p_ptr->lev >= PY_MAX_LEVEL))
{
sprintf(out_val, "You) %s the %s (Level %2d)",
- player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev);
- prt(out_val, (m + 8), 0);
- }
- else if ((building == 2) && (p_ptr->arena_number > MAX_ARENA_MONS))
- {
- sprintf(out_val, "You) %s the %s (Level %2d)",
- player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev);
+ player_name, race_info[p_ptr->prace].title, p_ptr->lev);
prt(out_val, (m + 8), 0);
}
- else if ((building != 1) && (building != 2))
+ else if ((building != 1))
{
if ((p_ptr->lev > clev) && (p_ptr->pclass == (building - 10)))
{
sprintf(out_val, "You) %s the %s (Level %2d)",
- player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev);
+ player_name, race_info[p_ptr->prace].title, p_ptr->lev);
prt(out_val, (m + 8), 0);
}
}
@@ -5015,7 +5031,7 @@ void show_highclass(int building)
*/
void race_score(int race_num)
{
- register int i = 0, j, m = 0;
+ int i = 0, j, m = 0;
int pr, clev, lastlev;
high_score the_score;
char buf[1024], out_val[256], tmp_str[80];
@@ -5024,7 +5040,7 @@ void race_score(int race_num)
lastlev = 0;
/* rr9: TODO - pluralize the race */
- sprintf(tmp_str, "The Greatest of all the %s", rp_name + race_info[race_num].title);
+ sprintf(tmp_str, "The Greatest of all the %s", race_info[race_num].title);
prt(tmp_str, 5, 3);
/* Build the filename */
@@ -5060,7 +5076,7 @@ void race_score(int race_num)
{
sprintf(out_val, "%3d) %s the %s (Level %3d)",
(m + 1), the_score.who,
- rp_name + race_info[pr].title, clev);
+ race_info[pr].title, clev);
prt(out_val, (m + 7), 0);
m++;
lastlev = clev;
@@ -5072,7 +5088,7 @@ void race_score(int race_num)
if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev))
{
sprintf(out_val, "You) %s the %s (Level %3d)",
- player_name, rp_name + race_info[p_ptr->prace].title, p_ptr->lev);
+ player_name, race_info[p_ptr->prace].title, p_ptr->lev);
prt(out_val, (m + 8), 0);
}
@@ -5180,7 +5196,7 @@ static errr top_twenty(void)
/* Clear the record */
- WIPE(&the_score, high_score);
+ memset(&the_score, 0, sizeof(high_score));
/* Save the version */
sprintf(the_score.what, "%ld.%ld.%ld",
@@ -5217,10 +5233,7 @@ static errr top_twenty(void)
sprintf(the_score.max_lev, "%3d", p_ptr->max_plv);
sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]);
- sprintf(the_score.arena_number, "%3d", p_ptr->arena_number); /* -KMW- */
- sprintf(the_score.inside_arena, "%3d", p_ptr->inside_arena);
sprintf(the_score.inside_quest, "%3d", p_ptr->inside_quest);
- sprintf(the_score.exit_bldg, "%3d", p_ptr->exit_bldg); /* -KMW- */
/* Save the cause of death (31 chars) */
sprintf(the_score.how, "%-.31s", died_from);
@@ -5258,7 +5271,7 @@ out:
/*
* Predict the players location, and display it.
*/
-errr predict_score(void)
+static errr predict_score(void)
{
int j;
@@ -5282,7 +5295,9 @@ errr predict_score(void)
}
/* Clear the record */
- WIPE(&the_score, high_score);
+ static_assert(std::is_pod<high_score>::value,
+ "Cannot memset a non-POD type");
+ memset(&the_score, 0, sizeof(high_score));
/* Save the version */
sprintf(the_score.what, "%ld.%ld.%ld",
@@ -5319,10 +5334,7 @@ errr predict_score(void)
sprintf(the_score.max_lev, "%3d", p_ptr->max_plv);
sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]);
- sprintf(the_score.arena_number, "%3d", p_ptr->arena_number); /* -KMW- */
- sprintf(the_score.inside_arena, "%3d", p_ptr->inside_arena);
sprintf(the_score.inside_quest, "%3d", p_ptr->inside_quest);
- sprintf(the_score.exit_bldg, "%3d", p_ptr->exit_bldg); /* -KMW- */
/* Hack -- no cause of death */
strcpy(the_score.how, "nobody (yet!)");
@@ -5592,7 +5604,7 @@ void close_game(void)
/*
* Grab a randomly selected line in lib/file/file_name
*/
-errr get_rnd_line(char *file_name, char *output)
+errr get_rnd_line(const char *file_name, char *output)
{
FILE *fp;
@@ -5669,7 +5681,7 @@ errr get_rnd_line(char *file_name, char *output)
*
* Caution: 'linbuf' should be at least 80 byte long.
*/
-char *get_line(char* fname, cptr fdir, char *linbuf, int line)
+char *get_line(const char* fname, cptr fdir, char *linbuf, int line)
{
FILE* fp;
int i;
@@ -5717,7 +5729,7 @@ char *get_line(char* fname, cptr fdir, char *linbuf, int line)
* understand such complexities -- and added extra error checkings
* and made sure fd is always closed -- pelpel
*/
-errr get_xtra_line(char *file_name, monster_type *m_ptr, char *output)
+errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output)
{
FILE *fp;
char buf[1024];
diff --git a/src/files.h b/src/files.h
new file mode 100644
index 00000000..e3df5636
--- /dev/null
+++ b/src/files.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bool_ txt_to_html(cptr head, cptr food, cptr base, cptr ext, bool_ force, bool_ recur);
+extern void process_player_name(bool_ sf);
+extern void do_cmd_save_game(void);
+extern void predict_score_gui(bool_ *initialized, bool_ *game_in_progress);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/files.hpp b/src/files.hpp
new file mode 100644
index 00000000..52206d12
--- /dev/null
+++ b/src/files.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_type_fwd.hpp"
+
+extern void html_screenshot(cptr name);
+extern void help_file_screenshot(cptr name);
+extern void player_flags(u32b* f1, u32b* f2, u32b* f3, u32b* f4, u32b* f5, u32b* esp);
+extern void wipe_saved(void);
+extern s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2);
+extern void display_player(int mode);
+extern cptr describe_player_location(void);
+extern errr file_character(cptr name, bool_ full);
+extern errr process_pref_file_aux(char *buf);
+extern errr process_pref_file(cptr name);
+extern bool_ show_file(cptr name, cptr what, int line, int mode);
+extern void do_cmd_help(void);
+extern void process_player_base(void);
+extern void get_name(void);
+extern void do_cmd_suicide(void);
+extern void autosave_checkpoint();
+extern void close_game(void);
+extern errr get_rnd_line(const char * file_name, char * output);
+extern char *get_line(const char* fname, cptr fdir, char *linbuf, int line);
+extern void race_legends(void);
+extern void show_highclass(int building);
+extern errr get_xtra_line(const char * file_name, monster_type *m_ptr, char * output);
diff --git a/src/flags_group.hpp b/src/flags_group.hpp
new file mode 100644
index 00000000..f71e3704
--- /dev/null
+++ b/src/flags_group.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * For level gaining artifacts, artifact creation, ...
+ */
+struct flags_group
+{
+ char name[30]; /* Name */
+ byte color; /* Color */
+
+ byte price; /* Price to "buy" it */
+
+ u32b flags1; /* Flags set 1 */
+ u32b flags2; /* Flags set 2 */
+ u32b flags3; /* Flags set 3 */
+ u32b flags4; /* Flags set 4 */
+ u32b esp; /* ESP flags set */
+};
diff --git a/src/gen_evol.c b/src/gen_evol.cc
index bfdfbd68..f6cee5a7 100644
--- a/src/gen_evol.c
+++ b/src/gen_evol.cc
@@ -1,8 +1,4 @@
/*
- * Generate a game of life level and make it evolve
- */
-
-/*
* Copyright (c) 2003 DarkGod.
*
* This software may be copied and distributed for educational, research, and
@@ -10,8 +6,15 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "gen_evol.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "generate.hpp"
+#include "levels.hpp"
+#include "player_type.hpp"
+#include "variable.hpp"
/*
* Generate a game of life level :) and make it evolve
@@ -48,7 +51,7 @@ void evolve_level(bool_ noise)
if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue;
/* Avoid evolving grids with object or monster */
- if (c_ptr->o_idx || c_ptr->m_idx) continue;
+ if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue;
/* Avoid evolving player grid */
if ((j == p_ptr->py) && (i == p_ptr->px)) continue;
@@ -82,7 +85,7 @@ void evolve_level(bool_ noise)
if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue;
/* Avoid evolving grids with object or monster */
- if (c_ptr->o_idx || c_ptr->m_idx) continue;
+ if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue;
/* Avoid evolving player grid */
if ((j == p_ptr->py) && (i == p_ptr->px)) continue;
diff --git a/src/gen_evol.hpp b/src/gen_evol.hpp
new file mode 100644
index 00000000..65b1320d
--- /dev/null
+++ b/src/gen_evol.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ level_generate_life();
+extern void evolve_level(bool_ noise);
diff --git a/src/gen_maze.c b/src/gen_maze.cc
index 92cb482f..9a3706fa 100644
--- a/src/gen_maze.c
+++ b/src/gen_maze.cc
@@ -1,8 +1,4 @@
/*
- * Maze dungeon generator
- */
-
-/*
* Copyright (c) 2003 DarkGod. And somebody who posted the algorith on
* rec.games.roguelike.development. I can't remember teh name :( please mail me
*
@@ -11,7 +7,14 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "gen_evol.hpp"
+
+#include "cave.hpp"
+#include "generate.hpp"
+#include "levels.hpp"
+#include "variable.hpp"
+
+#include <memory>
/*
* If we wasted static memory for this, it would look like:
@@ -20,7 +23,7 @@
*/
typedef signed char maze_row[(MAX_WID / 2) + 2];
-void dig(maze_row *maze, int y, int x, int d)
+static void dig(maze_row *maze, int y, int x, int d)
{
int k;
int dy = 0, dx = 0;
@@ -145,10 +148,9 @@ bool_ level_generate_maze()
int y, dy = 0;
int x, dx = 0;
int m_1 = 0, m_2 = 0;
- maze_row *maze;
/* Allocate temporary memory */
- C_MAKE(maze, (MAX_HGT / 2) + 2, maze_row);
+ std::unique_ptr<maze_row[]> maze(new maze_row[(MAX_HGT / 2) + 2]);
/*
* the empty maze is:
@@ -209,7 +211,7 @@ bool_ level_generate_maze()
x = rand_range(1, (cur_wid / 2));
d = rand_range(0, 3);
- dig(maze, y, x, d);
+ dig(maze.get(), y, x, d);
maze[y][x] = 0;
@@ -283,9 +285,6 @@ bool_ level_generate_maze()
}
}
- /* Free temporary memory */
- C_FREE(maze, (MAX_HGT / 2) + 2, maze_row);
-
/* Determine the character location */
if (!new_player_spot(get_branch()))
return FALSE;
diff --git a/src/gen_maze.hpp b/src/gen_maze.hpp
new file mode 100644
index 00000000..28c092e3
--- /dev/null
+++ b/src/gen_maze.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ level_generate_maze();
diff --git a/src/generate.c b/src/generate.cc
index 44e331a6..0f24f7d2 100644
--- a/src/generate.c
+++ b/src/generate.cc
@@ -1,7 +1,3 @@
-/* File: generate.c */
-
-/* Purpose: Dungeon generation */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,7 +6,40 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "generate.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "hook_build_room1_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "levels.hpp"
+#include "loadsave.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "randart.hpp"
+#include "spells1.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "vault_type.hpp"
+#include "wild.hpp"
+#include "wilderness_map.hpp"
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
#define SAFE_MAX_ATTEMPTS 5000
/*
@@ -273,12 +302,7 @@ typedef struct level_generator_type level_generator_type;
struct level_generator_type
{
cptr name;
- bool_ (*generator)(cptr);
-
- bool_ default_stairs;
- bool_ default_monsters;
- bool_ default_objects;
- bool_ default_miscs;
+ bool_ (*generator)();
struct level_generator_type *next;
};
@@ -288,18 +312,14 @@ static level_generator_type *level_generators = NULL;
/*
* Add a new generator
*/
-void add_level_generator(cptr name, bool_ (*generator)(), bool_ stairs, bool_ monsters, bool_ objects, bool_ miscs)
+void add_level_generator(cptr name, bool_ (*generator)())
{
- level_generator_type *g;
+ assert(name != nullptr);
- MAKE(g, level_generator_type);
- g->name = string_make(name);
- g->generator = generator;
+ level_generator_type *g = new level_generator_type;
- g->default_stairs = stairs;
- g->default_monsters = monsters;
- g->default_objects = objects;
- g->default_miscs = miscs;
+ g->name = strdup(name);
+ g->generator = generator;
g->next = level_generators;
level_generators = g;
@@ -1004,7 +1024,7 @@ static void place_random_door(int y, int x)
else
{
/* Create jammed door */
- cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x08 + (byte)rand_int(8));
+ cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x08 + rand_int(8));
}
}
@@ -2731,8 +2751,7 @@ static bool_ vault_aux_chapel(int r_idx)
if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
/* Require "priest" or Angel */
- if (!((r_ptr->d_char == 'A') ||
- strstr((r_name + r_ptr->name), "riest")))
+ if (!((r_ptr->d_char == 'A') || strstr(r_ptr->name, "riest")))
{
return (FALSE);
}
@@ -3445,7 +3464,7 @@ static void build_type6(int by0, int bx0)
for (i = 0; i < 8; i++)
{
/* Message */
- msg_print(r_name + r_info[what[i]].name);
+ msg_print(r_info[what[i]].name);
}
}
}
@@ -3827,7 +3846,7 @@ static void build_type7(int by0, int bx0)
}
/* Hack -- Build the vault */
- build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text);
+ build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_ptr->data);
}
@@ -3883,7 +3902,7 @@ static void build_type8(int by0, int bx0)
}
/* Hack -- Build the vault */
- build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text);
+ build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_ptr->data);
}
/*
@@ -4721,7 +4740,7 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
* Thing added based on distance to center of vault
* Difficulty is 1-easy to 10-hard
*/
- value = (((s32b)distance(cx, cy, x, y) * 100) / size) +
+ value = ((static_cast<s32b>(distance(cx, cy, x, y)) * 100) / size) +
randint(10) - difficulty;
/* Hack -- Empty square part of the time */
@@ -5288,7 +5307,7 @@ static void build_maze_vault(int x0, int y0, int xsize, int ysize)
{
int y, x, dy, dx;
int y1, x1, y2, x2;
- int i, m, n, num_vertices, *visited;
+ int m, n, num_vertices;
bool_ light;
cave_type *c_ptr;
@@ -5335,22 +5354,13 @@ static void build_maze_vault(int x0, int y0, int xsize, int ysize)
num_vertices = m * n;
/* Allocate an array for visited vertices */
- C_MAKE(visited, num_vertices, int);
-
- /* Initialise array of visited vertices */
- for (i = 0; i < num_vertices; i++)
- {
- visited[i] = 0;
- }
+ std::vector<int> visited(num_vertices, 0);
/* Traverse the graph to create a spaning tree, pick a random root */
- r_visit(y1, x1, y2, x2, rand_int(num_vertices), 0, visited);
+ r_visit(y1, x1, y2, x2, rand_int(num_vertices), 0, visited.data());
/* Fill with monsters and treasure, low difficulty */
fill_treasure(x1, x2, y1, y2, randint(5));
-
- /* Free the array for visited vertices */
- C_FREE(visited, num_vertices, int);
}
@@ -5366,8 +5376,7 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
{
int dy, dx;
int y1, x1, y2, x2, y, x, total;
- int i, m, n, num_vertices;
- int *visited;
+ int m, n, num_vertices;
if (cheat_room) msg_print("Mini Checker Board Vault");
@@ -5400,16 +5409,10 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
num_vertices = m * n;
/* Allocate an array for visited vertices */
- C_MAKE(visited, num_vertices, int);
-
- /* Initialise array of visited vertices */
- for (i = 0; i < num_vertices; i++)
- {
- visited[i] = 0;
- }
+ std::vector<int> visited(num_vertices, 0);
/* Traverse the graph to create a spannng tree, pick a random root */
- r_visit(y1, x1, y2, x2, rand_int(num_vertices), 0, visited);
+ r_visit(y1, x1, y2, x2, rand_int(num_vertices), 0, visited.data());
/* Make it look like a checker board vault */
for (x = x1; x <= x2; x++)
@@ -5444,9 +5447,6 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize)
/* Fill with monsters and treasure, highest difficulty */
fill_treasure(x1, x2, y1, y2, 10);
-
- /* Free the array for visited vertices */
- C_FREE(visited, num_vertices, int);
}
@@ -6642,7 +6642,7 @@ static bool_ room_build(int y, int x, int typ)
/*
* Set level boundaries
*/
-void set_bounders(bool_ empty_level)
+static void set_bounders(bool_ empty_level)
{
int y, x;
@@ -6794,7 +6794,10 @@ bool_ level_generate_dungeon()
}
/* Ugly */
- process_hooks(HOOK_BUILD_ROOM1, "(d,d)", y, x);
+ {
+ struct hook_build_room1_in in = { y, x };
+ process_hooks_new(HOOK_BUILD_ROOM1, &in, NULL);
+ }
/* Build some rooms */
for (i = 0; i < DUN_ROOMS; i++)
@@ -7176,34 +7179,34 @@ bool_ level_generate_dungeon()
/*
* Bring the imprinted pets from the old level
*/
-void replace_all_friends()
+static void replace_all_friends()
{
- int i;
-
- if (p_ptr->wild_mode) return;
+ if (p_ptr->wild_mode)
+ {
+ return;
+ }
/* Scan every saved pet */
- for (i = 0; i < max_m_idx; i++)
+ for (int i = 0; i < max_m_idx; i++)
{
if ((km_list[i].r_idx) && (km_list[i].status == MSTATUS_COMPANION))
{
- int y = p_ptr->py, x = p_ptr->px;
- cave_type *c_ptr;
- monster_type *m_ptr;
+ int y = p_ptr->py;
+ int x = p_ptr->px;
/* Find a suitable location */
get_pos_player(5, &y, &x);
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Get a m_idx to use */
c_ptr->m_idx = m_pop();
- m_ptr = &m_list[c_ptr->m_idx];
+ monster_type *m_ptr = &m_list[c_ptr->m_idx];
/* Actualy place the monster */
m_list[c_ptr->m_idx] = km_list[i];
m_ptr->fy = y;
m_ptr->fx = x;
- m_ptr->hold_o_idx = 0;
+ m_ptr->hold_o_idxs.clear(); // Objects have been removed previously by caller
}
}
}
@@ -7211,34 +7214,17 @@ void replace_all_friends()
/*
* Save the imprinted pets from the old level
*/
-void save_all_friends()
+static void save_all_friends()
{
if (p_ptr->old_wild_mode) return;
- C_COPY(km_list, m_list, max_m_idx, monster_type);
-}
-
-
-
-/*
- * Return the dungeon type of the current level(it can only return the
- * principal dungeons)
- */
-byte calc_dungeon_type()
-{
- int i;
-
- for (i = 0; i < max_d_idx; i++)
- {
- if ((dun_level >= d_info[i].mindepth) &&
- (dun_level <= d_info[i].maxdepth) &&
- (d_info[i].flags1 & DF1_PRINCIPAL))
- return (i);
+ for (int i = 0; i < max_m_idx; i++) {
+ km_list[i] = m_list[i];
}
- return (0);
}
+
/*
* Build probability tables for walls and floors and set feat_wall_outer
* and feat_wall_inner according to the current information in d_info.txt
@@ -7518,6 +7504,87 @@ static void fill_level(bool_ use_floor, byte smooth)
}
+/**
+ * @brief double a grid tile. Used for the double-size dungeons
+ */
+static void supersize_grid_tile(int sy, int sx, int ty, int tx)
+{
+ /* Displacements for copied grid tiles */
+ constexpr std::size_t n_disp = 4;
+ int disp[n_disp][2] = {
+ { 0, 0 },
+ { 0, +1 },
+ { +1, 0 },
+ { +1, +1 }
+ };
+
+ /* Acquire the grid tile and monster */
+ cave_type *cc_ptr = &cave[sy][sx];
+ monster_type *m_ptr = &m_list[cc_ptr->m_idx];
+
+ /* Save the list of objects */
+ auto const object_idxs(cc_ptr->o_idxs);
+
+ /* Save the monster */
+ auto m_idx = cc_ptr->m_idx;
+
+ /* Create pointers to each of the target grid tiles */
+ cave_type *c_ptr[n_disp];
+ for (std::size_t i = 0; i < n_disp; i++)
+ {
+ c_ptr[i] = &cave[ty + disp[i][0]][tx + disp[i][1]];
+ }
+
+ /* Now we copy around the grid tiles. Objects and
+ monsters are "removed" for now. */
+ for (std::size_t i = 0; i < 4; i++)
+ {
+ c_ptr[i] = &cave[ty + disp[i][0]][tx + disp[i][1]];
+
+ /* Copy grid */
+ *c_ptr[i] = *cc_ptr;
+ c_ptr[i]->o_idxs.clear(); // ... except objects in the tile
+ c_ptr[i]->m_idx = 0; // ... except monsters in the tile
+
+ /* Void gates need special attention */
+ if (cc_ptr->feat == FEAT_BETWEEN)
+ {
+ int xxx = cc_ptr->special & 0xFF;
+ int yyy = cc_ptr->special >> 8;
+
+ xxx *= 2;
+ yyy *= 2;
+ xxx += disp[i][1];
+ yyy += disp[i][0];
+ c_ptr[i]->special = xxx + (yyy << 8);
+ }
+ }
+
+ /* Scatter objects randomly into the destination grid tiles */
+ for (auto const o_idx: object_idxs)
+ {
+ std::size_t i = static_cast<std::size_t>(rand_int(4));
+ /* Put object into grid tile */
+ c_ptr[i]->o_idxs.push_back(o_idx);
+ /* Give object its location */
+ object_type *o_ptr = &o_list[o_idx];
+ o_ptr->iy = ty + disp[i][0];
+ o_ptr->ix = tx + disp[i][1];
+ }
+
+ /* Scatter move monster randomly into one of the destination grid tiles */
+ if (m_idx != 0)
+ {
+ std::size_t i = static_cast<std::size_t>(rand_int(4));
+ /* Place monster into grid tile */
+ c_ptr[i]->m_idx = cc_ptr->m_idx;
+ /* Give the monster its location */
+ m_ptr->fy = ty + disp[i][0];
+ m_ptr->fx = tx + disp[i][1];
+ }
+}
+
+
/*
* Generate a new dungeon level
*
@@ -7525,7 +7592,6 @@ static void fill_level(bool_ use_floor, byte smooth)
*/
static bool_ cave_gen(void)
{
- int i, k, y, x, y1, x1, branch;
dungeon_info_type *d_ptr = &d_info[dungeon_type];
int max_vault_ok = 2;
@@ -7585,7 +7651,7 @@ static bool_ cave_gen(void)
{
if (!strcmp(generator->name, generator_name))
{
- if (!generator->generator(generator->name))
+ if (!generator->generator())
return FALSE;
break;
}
@@ -7593,18 +7659,17 @@ static bool_ cave_gen(void)
generator = generator->next;
}
- /* Only if requested */
- if (generator->default_stairs)
+ /* Generate stairs */
{
/* Is there a dungeon branch ? */
- if ((branch = get_branch()))
+ if (int branch = get_branch())
{
/* Place 5 down stair some walls */
alloc_stairs(FEAT_MORE, 5, 3, branch);
}
/* Is there a father dungeon branch ? */
- if ((branch = get_fbranch()))
+ if (int branch = get_fbranch())
{
/* Place 1 down stair some walls */
alloc_stairs(FEAT_LESS, 5, 3, branch);
@@ -7629,21 +7694,20 @@ static bool_ cave_gen(void)
}
}
- process_hooks(HOOK_GEN_LEVEL, "(d)", is_quest(dun_level));
+ process_hooks_new(HOOK_GEN_LEVEL, NULL, NULL);
/* Basic "amount" */
- k = (dun_level / 3);
+ int k = (dun_level / 3);
if (k > 10) k = 10;
if (k < 2) k = 2;
- /* Only if requested */
- if (generator->default_monsters)
+ /* Place monsters */
{
/*
* Pick a base number of monsters
*/
- i = d_ptr->min_m_alloc_level;
+ int i = d_ptr->min_m_alloc_level;
/* To make small levels a bit more playable */
if ((cur_hgt < MAX_HGT) || (cur_wid < MAX_WID))
@@ -7671,7 +7735,7 @@ static bool_ cave_gen(void)
}
/* Check fates */
- for (i = 0; i < MAX_FATES; i++)
+ for (std::size_t i = 0; i < MAX_FATES; i++)
{
/* Ignore empty slots */
if (fates[i].fate == FATE_NONE) continue;
@@ -7804,8 +7868,8 @@ static bool_ cave_gen(void)
}
}
- /* Re scan the list to eliminate the inutile fate */
- for (i = 0; i < MAX_FATES; i++)
+ /* Re-scan the list to eliminate the inutile fate */
+ for (std::size_t i = 0; i < MAX_FATES; i++)
{
switch (fates[i].fate)
{
@@ -7822,8 +7886,7 @@ static bool_ cave_gen(void)
}
}
- /* Only if requested */
- if (generator->default_miscs)
+ /* Place traps and rubble */
{
/* Place some traps in the dungeon */
alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint(k * 2));
@@ -7832,8 +7895,7 @@ static bool_ cave_gen(void)
alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k));
}
- /* Only if requested */
- if (generator->default_objects)
+ /* Place objects and treasure */
{
/* Put some objects in rooms */
if (dungeon_type != DUNGEON_DEATH) alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
@@ -7843,8 +7905,7 @@ static bool_ cave_gen(void)
if (dungeon_type != DUNGEON_DEATH) alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
}
- /* Only if requested */
- if (generator->default_miscs)
+ /* Place random features such as altars and void gates, etc. */
{
/* Put some altars */
alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_ALTAR, randnor(DUN_AMT_ALTAR, 3));
@@ -7940,13 +8001,11 @@ static bool_ cave_gen(void)
object_copy(o_ptr, q_ptr);
/* Build a stack */
- o_ptr->next_o_idx = m_list[m_idx].hold_o_idx;
-
o_ptr->held_m_idx = m_idx;
o_ptr->ix = 0;
o_ptr->iy = 0;
- m_list[m_idx].hold_o_idx = o_idx;
+ m_list[m_idx].hold_o_idxs.push_back(o_idx);
}
}
@@ -7992,13 +8051,11 @@ static bool_ cave_gen(void)
object_copy(o_ptr, q_ptr);
/* Build a stack */
- o_ptr->next_o_idx = m_list[m_idx].hold_o_idx;
-
o_ptr->held_m_idx = m_idx;
o_ptr->ix = 0;
o_ptr->iy = 0;
- m_list[m_idx].hold_o_idx = o_idx;
+ m_list[m_idx].hold_o_idxs.push_back(o_idx);
}
}
}
@@ -8009,64 +8066,24 @@ static bool_ cave_gen(void)
/* Now double the generated dungeon */
if (dungeon_flags1 & DF1_DOUBLE)
{
- /* We begin at the bottom-right corner and from there move
- * up/left (this way we don't need another array for the
- * dungeon data) */
- /* Note: we double the border permanent walls, too. It is
- * easier this way and I think it isn't too ugly */
- for (y = cur_hgt - 1, y1 = y * 2; y >= 0; y--, y1 -= 2)
- for (x = cur_wid - 1, x1 = x * 2; x >= 0; x--, x1 -= 2)
+ /*
+ * We begin at the bottom-right corner and move upwards
+ * to the left. This avoids the need for an extra copy of
+ * the cave array.
+ *
+ * We double the border permanent walls, too.
+ */
+ int y = cur_hgt - 1;
+ int y1 = y * 2;
+ for (; y >= 0; y--, y1 -= 2)
+ {
+ int x = cur_wid - 1;
+ int x1 = x * 2;
+ for (; x >= 0; x--, x1 -= 2)
{
- int disp[4][2] = {{0, 0}, {0, + 1}, { + 1, 0}, { + 1, + 1}};
-
- cave_type *c_ptr[4], *cc_ptr = &cave[y][x];
- object_type *o_ptr = &o_list[cc_ptr->o_idx];
- monster_type *m_ptr = &m_list[cc_ptr->m_idx];
-
- /*
- * Now we copy the generated data to the
- * appropriate grids
- */
- for (i = 0; i < 4; i++)
- {
- c_ptr[i] = &cave[y1 + disp[i][0]][x1 + disp[i][1]];
- *c_ptr[i] = *cc_ptr;
- c_ptr[i]->o_idx = 0;
- c_ptr[i]->m_idx = 0;
-
- if (cc_ptr->feat == FEAT_BETWEEN)
- {
- int xxx = cc_ptr->special & 0xFF;
- int yyy = cc_ptr->special >> 8;
-
- xxx *= 2;
- yyy *= 2;
- xxx += disp[i][1];
- yyy += disp[i][0];
- c_ptr[i]->special = xxx + (yyy << 8);
- }
- }
-
- /* Objects should be put only in 1 of the
- * new grids (otherwise we would segfault
- * a lot) ... */
- if (cc_ptr->o_idx != 0)
- {
- i = rand_int(4);
- c_ptr[i]->o_idx = cc_ptr->o_idx;
- o_ptr->iy = y1 + disp[i][0];
- o_ptr->ix = x1 + disp[i][1];
- }
-
- /* ..just like monsters */
- if (cc_ptr->m_idx != 0)
- {
- i = rand_int(4);
- c_ptr[i]->m_idx = cc_ptr->m_idx;
- m_ptr->fy = y1 + disp[i][0];
- m_ptr->fx = x1 + disp[i][1];
- }
+ supersize_grid_tile(y, x, y1, x1);
}
+ }
/* Set the width/height ... */
cur_wid *= 2;
@@ -8081,139 +8098,6 @@ static bool_ cave_gen(void)
}
-/*
- * Builds the arena after it is entered -KMW-
- */
-static void build_arena(void)
-{
- int yval, y_height, y_depth, xval, x_left, x_right;
- register int i, j;
-
- yval = SCREEN_HGT / 2;
- xval = SCREEN_WID / 2;
- y_height = yval - 10 + SCREEN_HGT;
- y_depth = yval + 10 + SCREEN_HGT;
- x_left = xval - 32 + SCREEN_WID;
- x_right = xval + 32 + SCREEN_WID;
-
- for (i = y_height; i <= y_height + 5; i++)
- {
- for (j = x_left; j <= x_right; j++)
- {
- cave_set_feat(i, j, FEAT_PERM_EXTRA);
- cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
- }
- }
- for (i = y_depth; i >= y_depth - 5; i--)
- {
- for (j = x_left; j <= x_right; j++)
- {
- cave_set_feat(i, j, FEAT_PERM_EXTRA);
- cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
- }
- }
- for (j = x_left; j <= x_left + 17; j++)
- {
- for (i = y_height; i <= y_depth; i++)
- {
- cave_set_feat(i, j, FEAT_PERM_EXTRA);
- cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
- }
- }
- for (j = x_right; j >= x_right - 17; j--)
- {
- for (i = y_height; i <= y_depth; i++)
- {
- cave_set_feat(i, j, FEAT_PERM_EXTRA);
- cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
- }
- }
-
- cave_set_feat(y_height + 6, x_left + 18, FEAT_PERM_EXTRA);
- cave[y_height + 6][x_left + 18].info |= (CAVE_GLOW | CAVE_MARK);
- cave_set_feat(y_depth - 6, x_left + 18, FEAT_PERM_EXTRA);
- cave[y_depth - 6][x_left + 18].info |= (CAVE_GLOW | CAVE_MARK);
- cave_set_feat(y_height + 6, x_right - 18, FEAT_PERM_EXTRA);
- cave[y_height + 6][x_right - 18].info |= (CAVE_GLOW | CAVE_MARK);
- cave_set_feat(y_depth - 6, x_right - 18, FEAT_PERM_EXTRA);
- cave[y_depth - 6][x_right - 18].info |= (CAVE_GLOW | CAVE_MARK);
-
- i = y_height + 5;
- j = xval + SCREEN_WID;
- cave_set_feat(i, j, FEAT_SHOP);
- cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
- player_place(i + 1, j);
-}
-
-
-/*
- * Town logic flow for generation of arena -KMW-
- */
-static void arena_gen(void)
-{
- int y, x;
- int qy = SCREEN_HGT;
- int qx = SCREEN_WID;
- bool_ daytime;
-
- /* Day time */
- if ((turn % (10L * DAY)) < ((10L * DAY) / 2))
- daytime = TRUE;
-
- /* Night time */
- else
- daytime = FALSE;
-
- /* Start with solid walls */
- for (y = 0; y < MAX_HGT; y++)
- {
- for (x = 0; x < MAX_WID; x++)
- {
- /* Create "solid" perma-wall */
- cave_set_feat(y, x, FEAT_PERM_SOLID);
-
- /* Illuminate and memorize the walls */
- cave[y][x].info |= (CAVE_GLOW | CAVE_MARK);
- }
- }
-
- /* Then place some floors */
- for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++)
- {
- for (x = qx + 1; x < qx + SCREEN_WID - 1; x++)
- {
- /* Create empty floor */
- cave_set_feat(y, x, FEAT_FLOOR);
-
- /* Darken and forget the floors */
- cave[y][x].info &= ~(CAVE_GLOW | CAVE_MARK);
-
- /* Day time */
- if (daytime)
- {
- /* Perma-Lite */
- cave[y][x].info |= (CAVE_GLOW);
-
- /* Memorize */
- if (view_perma_grids) cave[y][x].info |= (CAVE_MARK);
- }
- }
- }
-
- build_arena();
-
- place_monster_aux(p_ptr->py + 5, p_ptr->px, arena_monsters[p_ptr->arena_number],
- FALSE, FALSE, MSTATUS_ENEMY);
-}
-
-
-/*
- * Generate a quest level
- */
-static void quest_gen(void)
-{
- process_hooks(HOOK_GEN_QUEST, "(d)", is_quest(dun_level));
-}
/*
* Creates a special level
@@ -8291,7 +8175,7 @@ static void wipe_special_level(void)
/* No special levels on the surface */
if (!dun_level) return;
- process_hooks(HOOK_LEVEL_REGEN, "()");
+ process_hooks_new(HOOK_LEVEL_REGEN, NULL, NULL);
/* Calculate relative depth */
level = dun_level - d_info[dungeon_type].mindepth;
@@ -8317,7 +8201,6 @@ static void finalise_special_level(void)
/* No special levels on the surface */
if (!dun_level) return;
- process_hooks(HOOK_LEVEL_END_GEN, "()");
process_hooks_new(HOOK_LEVEL_END_GEN, NULL, NULL);
/* Calculate relative depth */
@@ -8336,7 +8219,7 @@ static void finalise_special_level(void)
/*
* Give some magical energy to the each grid of the level
*/
-void generate_grid_mana()
+static void generate_grid_mana()
{
int y, x, mana, mult;
bool_ xtra_magic = FALSE;
@@ -8422,7 +8305,7 @@ void generate_cave(void)
Rand_value = town_info[town_level].seed;
}
- process_hooks(HOOK_GEN_LEVEL_BEGIN, "");
+ process_hooks_new(HOOK_GEN_LEVEL_BEGIN, NULL, NULL);
/* Try to load a saved level */
if (get_dungeon_save(buf))
@@ -8438,33 +8321,11 @@ void generate_cave(void)
{
for (x = 0; x < MAX_WID; x++)
{
- /* No flags */
- cave[y][x].info = 0;
+ /* Wipe */
+ cave[y][x].wipe();
/* No features */
cave_set_feat(y, x, FEAT_PERM_INNER);
-
- /* No objects */
- cave[y][x].o_idx = 0;
-
- /* No monsters */
- cave[y][x].m_idx = 0;
-
- /* No traps */
- cave[y][x].t_idx = 0;
-
- /* No mimic */
- cave[y][x].mimic = 0;
-
- /* No effects */
- cave[y][x].effect = 0;
-
- /* No inscription */
- cave[y][x].inscription = 0;
-
- /* No flow */
- cave[y][x].cost = 0;
- cave[y][x].when = 0;
}
}
@@ -8498,33 +8359,11 @@ void generate_cave(void)
{
for (x = 0; x < MAX_WID; x++)
{
- /* No flags */
- cave[y][x].info = 0;
+ /* Wipe */
+ cave[y][x].wipe();
/* No features */
cave_set_feat(y, x, FEAT_PERM_INNER);
-
- /* No objects */
- cave[y][x].o_idx = 0;
-
- /* No monsters */
- cave[y][x].m_idx = 0;
-
- /* No traps */
- cave[y][x].t_idx = 0;
-
- /* No mimic */
- cave[y][x].mimic = 0;
-
- /* No effect */
- cave[y][x].effect = 0;
-
- /* No inscription */
- cave[y][x].inscription = 0;
-
- /* No flow */
- cave[y][x].cost = 0;
- cave[y][x].when = 0;
}
}
@@ -8563,17 +8402,10 @@ void generate_cave(void)
/* No fated level here yet */
fate_flag = FALSE;
- /* Build the arena -KMW- */
- if (p_ptr->inside_arena)
- {
- /* Small arena */
- arena_gen();
- }
-
/* Quest levels -KMW- */
- else if (p_ptr->inside_quest)
+ if (p_ptr->inside_quest)
{
- quest_gen();
+ process_hooks_new(HOOK_GEN_QUEST, NULL, NULL);
}
/* Special levels */
@@ -8601,7 +8433,7 @@ void generate_cave(void)
if (!p_ptr->wild_mode)
{
/* Make the wilderness */
- wilderness_gen(0);
+ wilderness_gen();
}
/* Small wilderness mode */
@@ -8814,7 +8646,10 @@ void generate_cave(void)
}
/* Put the kept monsters -- DG */
- if (!p_ptr->wild_mode) replace_all_friends();
+ if (!p_ptr->wild_mode)
+ {
+ replace_all_friends();
+ }
/* Hack -- Clear used up fates */
for (i = 0; i < MAX_FATES; i++)
diff --git a/src/generate.hpp b/src/generate.hpp
new file mode 100644
index 00000000..d09907b5
--- /dev/null
+++ b/src/generate.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ new_player_spot(int branch);
+extern void add_level_generator(cptr name, bool_ (*generator)());
+extern bool_ level_generate_dungeon();
+extern bool_ generate_fracave(int y0, int x0,int xsize,int ysize,int cutoff,bool_ light,bool_ room);
+extern void generate_hmap(int y0, int x0,int xsiz,int ysiz,int grd,int roug,int cutoff);
+extern bool_ room_alloc(int x,int y,bool_ crowded,int by0,int bx0,int *xx,int *yy);
+extern void generate_cave(void);
+extern void build_rectangle(int y1, int x1, int y2, int x2, int feat, int info);
diff --git a/src/gf_name_type.hpp b/src/gf_name_type.hpp
new file mode 100644
index 00000000..0b17bdbf
--- /dev/null
+++ b/src/gf_name_type.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+/**
+ * GF_XXX descriptor entry.
+ */
+struct gf_name_type
+{
+ int gf;
+ char const *name;
+};
diff --git a/src/gods.c b/src/gods.cc
index f940e21a..1163e9b6 100644
--- a/src/gods.c
+++ b/src/gods.cc
@@ -1,7 +1,3 @@
-/* File: gods.c */
-
-/* Purpose: Deities code */
-
/*
* Copyright (c) 2002 DarkGod
*
@@ -9,8 +5,19 @@
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
+#include "gods.hpp"
+
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "skill_type.hpp"
+#include "stats.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra2.hpp"
-#include "angband.h"
+#include <cassert>
/*
* Add amt piety is god is god
@@ -88,7 +95,7 @@ void follow_god(int god, bool_ silent)
p_ptr->pgod = god;
/* Melkor offer Udun magic */
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
s_info[SKILL_UDUN].hidden = FALSE;
if (!silent) msg_print("You feel the dark powers of Melkor in you. You can now use the Udun skill.");
@@ -99,7 +106,7 @@ void follow_god(int god, bool_ silent)
/*
* Show religious info.
*/
-bool_ show_god_info(bool_ ext)
+bool_ show_god_info()
{
int pgod = p_ptr->pgod;
@@ -198,3 +205,8 @@ int find_god(cptr name)
}
return -1;
}
+
+bool praying_to(int god)
+{
+ return (p_ptr->pgod == god) && p_ptr->praying;
+}
diff --git a/src/gods.hpp b/src/gods.hpp
new file mode 100644
index 00000000..7035dd14
--- /dev/null
+++ b/src/gods.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void inc_piety(int god, s32b amt);
+extern void abandon_god(int god);
+extern int wisdom_scale(int max);
+extern int find_god(cptr name);
+extern void follow_god(int god, bool_ silent);
+extern bool_ god_enabled(struct deity_type *deity);
+extern deity_type *god_at(byte god_idx);
+extern bool_ show_god_info();
+extern bool praying_to(int god);
diff --git a/src/h-basic.h b/src/h-basic.h
index b5ea5d87..a65780a5 100644
--- a/src/h-basic.h
+++ b/src/h-basic.h
@@ -1,7 +1,8 @@
-/* File: h-basic.h */
+#pragma once
-#ifndef INCLUDED_H_BASIC_H
-#define INCLUDED_H_BASIC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* The most basic "include" file.
@@ -21,5 +22,6 @@
/* Basic constants and macros */
#include "h-define.h"
+#ifdef __cplusplus
+} // extern "C"
#endif
-
diff --git a/src/h-config.h b/src/h-config.h
index 53670e8f..fc2721ef 100644
--- a/src/h-config.h
+++ b/src/h-config.h
@@ -1,7 +1,8 @@
-/* File: h-config.h */
+#pragma once
-#ifndef INCLUDED_H_CONFIG_H
-#define INCLUDED_H_CONFIG_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* Choose the hardware, operating system, and compiler.
@@ -32,102 +33,6 @@
/* #define WINDOWS */
#endif
-/*
- * OPTION: Compile on a SYS III version of UNIX
- */
-#ifndef SYS_III
-/* #define SYS_III */
-#endif
-
-/*
- * OPTION: Compile on a SYS V version of UNIX (not Solaris)
- */
-#ifndef SYS_V
-/* #define SYS_V */
-#endif
-
-/*
- * OPTION: Compile on a HPUX version of UNIX
- */
-#ifndef HPUX
-/* #define HPUX */
-#endif
-
-/*
- * OPTION: Compile on an SGI running IRIX
- */
-#ifndef SGI
-/* #define SGI */
-#endif
-
-/*
- * OPTION: Compile on a SunOS machine
- */
-#ifndef SUNOS
-/* #define SUNOS */
-#endif
-
-/*
- * OPTION: Compile on a Solaris machine
- */
-#ifndef SOLARIS
-/* #define SOLARIS */
-#endif
-
-/*
- * OPTION: Compile on an ultrix/4.2BSD/Dynix/etc. version of UNIX,
- * Do not define this if you are on any kind of SunOS.
- */
-#ifndef ULTRIX
-/* #define ULTRIX */
-#endif
-
-
-
-/*
- * Extract the "SUNOS" flag from the compiler
- */
-#if defined(sun)
-# ifndef SUNOS
-# define SUNOS
-# endif
-#endif
-
-/*
- * Extract the "ULTRIX" flag from the compiler
- */
-#if defined(ultrix) || defined(Pyramid)
-# ifndef ULTRIX
-# define ULTRIX
-# endif
-#endif
-
-/*
- * Extract the "ATARI" flag from the compiler [cjh]
- */
-#if defined(__atarist) || defined(__atarist__)
-# ifndef ATARI
-# define ATARI
-# endif
-#endif
-
-/*
- * Extract the "SGI" flag from the compiler
- */
-#ifdef sgi
-# ifndef SGI
-# define SGI
-# endif
-#endif
-
-/*
- * Extract the "MSDOS" flag from the compiler
- */
-#ifdef __MSDOS__
-# ifndef MSDOS
-# define MSDOS
-# endif
-#endif
/*
* Extract the "WINDOWS" flag from the compiler
@@ -147,7 +52,7 @@
* The only such platform that angband is ported to is currently
* DEC Alpha AXP running OSF/1 (OpenVMS uses 32-bit longs).
*/
-#if defined(__alpha) && defined(__osf__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__ia64) || defined(__ia64__) || defined(__mips64) || defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || defined(__64BIT__) || defined(__sparc64__) || defined(__LP64__)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__ia64) || defined(__ia64__) || defined(__mips64) || defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || defined(__64BIT__) || defined(__sparc64__) || defined(__LP64__)
# define L64
#endif
@@ -160,34 +65,14 @@
* and of the "umask()" call for various reasons, and to guess if
* the "kill()" function is available, and for permission to use
* functions to extract user names and expand "tildes" in filenames.
- * It is also used for "locking" and "unlocking" the score file.
- * Basically, SET_UID should *only* be set for "Unix" machines,
- * or for the "Atari" platform which is Unix-like, apparently
+ * Basically, SET_UID should *only* be set for "Unix" machines.
*/
-#if !defined(MACINTOSH) && !defined(WINDOWS) && \
- !defined(MSDOS)
+#if !defined(MACINTOSH) && !defined(WINDOWS)
# define SET_UID
#endif
/*
- * OPTION: Set "USG" for "System V" versions of Unix
- * This is used to choose a "lock()" function, and to choose
- * which header files ("string.h" vs "strings.h") to include.
- * It is also used to allow certain other options, such as options
- * involving userid's, or multiple users on a single machine, etc.
- */
-#ifdef SET_UID
-# if defined(SYS_III) || defined(SYS_V) || defined(SOLARIS) || \
- defined(HPUX) || defined(SGI) || defined(ATARI)
-# ifndef USG
-# define USG
-# endif
-# endif
-#endif
-
-
-/*
* Every system seems to use its own symbol as a path separator.
* Default to the standard Unix slash, but attempt to change this
* for various other systems. Note that any system that uses the
@@ -204,20 +89,12 @@
# undef PATH_SEP
# define PATH_SEP "\\"
#endif
-#if defined(MSDOS) || defined(OS2)
-# undef PATH_SEP
-# define PATH_SEP "\\"
-#endif
-#ifdef __GO32__
-# undef PATH_SEP
-# define PATH_SEP "/"
-#endif
/*
* The Macintosh allows the use of a "file type" when creating a file
*/
-#if defined(MACINTOSH) && !defined(applec) || defined(MACH_O_CARBON)
+#if defined(MACINTOSH) && !defined(applec)
# define FILE_TYPE_TEXT 'TEXT'
# define FILE_TYPE_DATA 'DATA'
# define FILE_TYPE_SAVE 'SAVE'
@@ -227,48 +104,6 @@
#endif
-/*
- * OPTION: Hack -- Make sure "strchr()" and "strrchr()" will work
- */
-#if defined(SYS_III) || defined(SYS_V) || defined(MSDOS)
-# if !defined(__TURBOC__) && !defined(__WATCOMC__)
-# define strchr index
-# define strrchr rindex
-# endif
-#endif
-
-
-/*
- * OPTION: Define "HAS_STRICMP" only if "stricmp()" exists.
- * Note that "stricmp()" is not actually used by Angband.
- */
-/* #define HAS_STRICMP */
-
-/*
- * Linux has "stricmp()" with a different name
- */
-#if defined(linux)
-# define HAS_STRICMP
-# define stricmp strcasecmp
-#endif
-
-
-/*
- * OPTION: Define "HAS_MEMSET" only if "memset()" exists.
- * Note that the "memset()" routines are used in "z-virt.h"
- */
-#define HAS_MEMSET
-
-
-/*
- * 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
-
+#ifdef __cplusplus
+} // extern "C"
#endif
diff --git a/src/h-define.h b/src/h-define.h
index cb36b189..76e7e339 100644
--- a/src/h-define.h
+++ b/src/h-define.h
@@ -33,19 +33,6 @@
# define SEEK_END 2
#endif
-/*
- * Hack -- force definitions -- see fd_lock() XXX XXX XXX
- */
-#ifndef F_UNLCK
-# define F_UNLCK 0
-#endif
-#ifndef F_RDLCK
-# define F_RDLCK 1
-#endif
-#ifndef F_WRLCK
-# define F_WRLCK 2
-#endif
-
/*
* The constants "TRUE" and "FALSE"
@@ -87,12 +74,6 @@
#undef ABS
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
-/*
- * Non-typed sign extractor macro
- */
-#undef SGN
-#define SGN(a) (((a) < 0) ? (-1) : ((a) != 0))
-
/*
* Note that all "index" values must be "lowercase letters", while
diff --git a/src/h-system.h b/src/h-system.h
index c1b17e1f..f7759668 100644
--- a/src/h-system.h
+++ b/src/h-system.h
@@ -25,16 +25,11 @@
# include <sys/types.h>
-# if defined(Pyramid) || defined(SUNOS) || \
- defined(NCR3K) || defined(SUNOS) || defined(ibm032) || \
- defined(__osf__) || defined(ISC) || defined(SGI) || \
- defined(linux)
+# if defined(linux)
# include <sys/time.h>
# endif
-# if !defined(SGI) && !defined(ULTRIX)
# include <sys/timeb.h>
-# endif
#endif
@@ -47,31 +42,22 @@
# include <unix.h>
#endif
-#if defined(WINDOWS) || defined(MSDOS)
+#if defined(WINDOWS)
# include <io.h>
#endif
-#if !defined(MACINTOSH) && \
- !defined(__MWERKS__)
-# if defined(__TURBOC__) || defined(__WATCOMC__)
-# include <mem.h>
-# else
+#if !defined(MACINTOSH)
# include <memory.h>
-# endif
#endif
-#if !defined(__MWERKS__)
# include <fcntl.h>
-#endif
#ifdef SET_UID
-# ifndef USG
# include <sys/param.h>
# include <sys/file.h>
-# endif
# ifdef linux
# include <sys/file.h>
@@ -83,32 +69,12 @@
# include <sys/stat.h>
-# if defined(SOLARIS)
-# include <netdb.h>
-# endif
#endif
-#ifdef __DJGPP__
-#include <unistd.h>
-#endif /* __DJGPP__ */
-
#ifdef SET_UID
-#ifdef USG
-# include <string.h>
-#else
# include <strings.h>
-# ifndef strstr
-extern char *strstr();
-# endif
-# ifndef strchr
-extern char *strchr();
-# endif
-# ifndef strrchr
-extern char *strrchr();
-# endif
-#endif
#else
@@ -118,10 +84,6 @@ extern char *strrchr();
-#if !defined(linux) && !defined(__MWERKS__)
-extern long atol();
-#endif
-
#include <stdarg.h>
diff --git a/src/h-type.h b/src/h-type.h
index 145d4729..bcf013bb 100644
--- a/src/h-type.h
+++ b/src/h-type.h
@@ -72,17 +72,11 @@ typedef int errr;
#define uint uint_hack
/*
- * Hack -- prevent problems with MSDOS and WINDOWS
+ * Hack -- prevent problems with WINDOWS
*/
#undef huge
#define huge huge_hack
-/*
- * Hack -- prevent problems with AMIGA
- */
-#undef byte
-#define byte byte_hack
-
/* Note that "signed char" is not always "defined" */
/* So always use "s16b" to hold small signed values */
/* A signed byte of memory */
diff --git a/src/help.c b/src/help.cc
index 7aae360e..29ebf033 100644
--- a/src/help.c
+++ b/src/help.cc
@@ -1,7 +1,3 @@
-/* File: help.c */
-
-/* Purpose: ingame help */
-
/*
* Copyright (c) 2001 DarkGod
* Copyright (c) 2012 Bardur Arantsson
@@ -11,7 +7,20 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "help.hpp"
+
+#include "cave_type.hpp"
+#include "files.hpp"
+#include "hook_get_in.hpp"
+#include "hook_identify_in.hpp"
+#include "hook_move_in.hpp"
+#include "hooks.hpp"
+#include "object1.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "util.hpp"
+#include "variable.hpp"
#define DESC_MAX 14
#define TRIGGERED_HELP_MAX 19
@@ -316,7 +325,7 @@ static bool_ trigger_fountain(void *in, void *out) {
static bool_ trigger_found_object(void *in, void *out) {
hook_move_in *p = (hook_move_in *) in;
- return cave[p->y][p->x].o_idx != 0;
+ return !cave[p->y][p->x].o_idxs.empty();
}
static bool_ trigger_found_altar(void *in, void *out) {
diff --git a/src/help.hpp b/src/help.hpp
new file mode 100644
index 00000000..7c057a01
--- /dev/null
+++ b/src/help.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void init_hooks_help();
+extern void help_race(cptr race);
+extern void help_subrace(cptr subrace);
+extern void help_class(cptr klass);
+extern void help_god(cptr god);
+extern void help_skill(cptr skill);
+extern void help_ability(cptr ability);
diff --git a/src/help_info.hpp b/src/help_info.hpp
new file mode 100644
index 00000000..ea440bb9
--- /dev/null
+++ b/src/help_info.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Maximum number of help items.
+ */
+constexpr int HELP_MAX = 64;
+
+/**
+ * Context help runtime data.
+ */
+struct help_info
+{
+ bool_ enabled; /* ingame help enabled */
+ bool_ activated[HELP_MAX]; /* help item #i activated? */
+};
diff --git a/src/hiscore.c b/src/hiscore.cc
index 357026da..971b84cd 100644
--- a/src/hiscore.c
+++ b/src/hiscore.cc
@@ -1,8 +1,8 @@
-#include "hiscore.h"
+#include "hiscore.hpp"
-#include <assert.h>
+#include "util.hpp"
-#include "angband.h"
+#include <cassert>
int highscore_seek(int highscore_fd, int i)
{
diff --git a/src/hiscore.h b/src/hiscore.hpp
index 0eed91b4..0b1b713d 100644
--- a/src/hiscore.h
+++ b/src/hiscore.hpp
@@ -1,11 +1,11 @@
-#ifndef H_267bf1c1_eada_4b18_9558_d96330fa7258
-#define H_267bf1c1_eada_4b18_9558_d96330fa7258
+#pragma once
-#include "h-type.h"
+#include "h-basic.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * Maximum number of high scores in the high score file
+ */
+constexpr int MAX_HISCORES = 100;
/*
* Semi-Portable High Score List Entry (128 bytes) -- BEN
@@ -47,10 +47,10 @@ struct high_score
char max_lev[4]; /* Max Player Level (number) */
char max_dun[4]; /* Max Dungeon Level (number) */
- char arena_number[4]; /* Arena level attained -KMW- */
- char inside_arena[4]; /* Did the player die in the arena? */
+ char unused_2[4]; /* Kept for compatibility only */
+ char unused_3[4]; /* Kept for compatibility only */
char inside_quest[4]; /* Did the player die in a quest? */
- char exit_bldg[4]; /* Can the player exit arena? Goal obtained? -KMW- */
+ char unused_4[4]; /* Kept for compatibility only */
char how[32]; /* Method of death (string) */
};
@@ -81,9 +81,3 @@ int highscore_where(int highscore_fd, high_score *score);
* best) or -1 on "failure"
*/
int highscore_add(int highscore_fd, high_score *score);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
diff --git a/src/hist_type.hpp b/src/hist_type.hpp
new file mode 100644
index 00000000..2da47b7c
--- /dev/null
+++ b/src/hist_type.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Player background descriptor.
+ */
+struct hist_type
+{
+ char *info; /* Textual History */
+
+ byte roll; /* Frequency of this entry */
+ s16b chart; /* Chart index */
+ s16b next; /* Next chart index */
+ byte bonus; /* Social Class Bonus + 50 */
+};
diff --git a/src/hist_type_fwd.hpp b/src/hist_type_fwd.hpp
new file mode 100644
index 00000000..d1cbce91
--- /dev/null
+++ b/src/hist_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct hist_type;
diff --git a/src/hook_build_room1_in.hpp b/src/hook_build_room1_in.hpp
new file mode 100644
index 00000000..e9a5d367
--- /dev/null
+++ b/src/hook_build_room1_in.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_build_room1_in {
+ s32b y;
+ s32b x;
+};
diff --git a/src/hook_calculate_hp_in.hpp b/src/hook_calculate_hp_in.hpp
new file mode 100644
index 00000000..924add45
--- /dev/null
+++ b/src/hook_calculate_hp_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_calculate_hp_in {
+ s32b mhp;
+};
diff --git a/src/hook_calculate_hp_out.hpp b/src/hook_calculate_hp_out.hpp
new file mode 100644
index 00000000..7923997f
--- /dev/null
+++ b/src/hook_calculate_hp_out.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_calculate_hp_out {
+ s32b mhp;
+};
diff --git a/src/hook_chardump_in.hpp b/src/hook_chardump_in.hpp
new file mode 100644
index 00000000..c8edea62
--- /dev/null
+++ b/src/hook_chardump_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_chardump_in {
+ FILE *file;
+};
diff --git a/src/hook_chat_in.hpp b/src/hook_chat_in.hpp
new file mode 100644
index 00000000..5062b0e6
--- /dev/null
+++ b/src/hook_chat_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_chat_in {
+ s32b m_idx;
+};
diff --git a/src/hook_drop_in.hpp b/src/hook_drop_in.hpp
new file mode 100644
index 00000000..acaa10ff
--- /dev/null
+++ b/src/hook_drop_in.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+struct hook_drop_in {
+ int o_idx;
+};
diff --git a/src/hook_eat_in.hpp b/src/hook_eat_in.hpp
new file mode 100644
index 00000000..075bb2bf
--- /dev/null
+++ b/src/hook_eat_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "object_type_fwd.hpp"
+
+struct hook_eat_in {
+ object_type *o_ptr;
+};
diff --git a/src/hook_eat_out.hpp b/src/hook_eat_out.hpp
new file mode 100644
index 00000000..70bb92a4
--- /dev/null
+++ b/src/hook_eat_out.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_eat_out {
+ bool_ ident;
+};
diff --git a/src/hook_enter_dungeon_in.hpp b/src/hook_enter_dungeon_in.hpp
new file mode 100644
index 00000000..2f667c78
--- /dev/null
+++ b/src/hook_enter_dungeon_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_enter_dungeon_in {
+ s32b d_idx;
+};
diff --git a/src/hook_get_in.hpp b/src/hook_get_in.hpp
new file mode 100644
index 00000000..9bc4b795
--- /dev/null
+++ b/src/hook_get_in.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "object_type_fwd.hpp"
+
+struct hook_get_in {
+ object_type *o_ptr;
+ int o_idx;
+};
diff --git a/src/hook_give_in.hpp b/src/hook_give_in.hpp
new file mode 100644
index 00000000..0ef5a11d
--- /dev/null
+++ b/src/hook_give_in.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+struct hook_give_in {
+ int m_idx;
+ int item;
+};
diff --git a/src/hook_identify_in.hpp b/src/hook_identify_in.hpp
new file mode 100644
index 00000000..40a8fc79
--- /dev/null
+++ b/src/hook_identify_in.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "object_type_fwd.hpp"
+#include "identify_mode.hpp"
+
+struct hook_identify_in {
+ object_type *o_ptr;
+ identify_mode mode;
+};
diff --git a/src/hook_init_quest_in.hpp b/src/hook_init_quest_in.hpp
new file mode 100644
index 00000000..5d4b274a
--- /dev/null
+++ b/src/hook_init_quest_in.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+struct hook_init_quest_in {
+ int q_idx;
+};
diff --git a/src/hook_mon_speak_in.hpp b/src/hook_mon_speak_in.hpp
new file mode 100644
index 00000000..f3a14338
--- /dev/null
+++ b/src/hook_mon_speak_in.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_mon_speak_in {
+ s32b m_idx;
+ cptr m_name;
+};
diff --git a/src/hook_monster_ai_in.hpp b/src/hook_monster_ai_in.hpp
new file mode 100644
index 00000000..492006aa
--- /dev/null
+++ b/src/hook_monster_ai_in.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_type_fwd.hpp"
+
+struct hook_monster_ai_in {
+ s32b m_idx;
+ monster_type *m_ptr;
+};
diff --git a/src/hook_monster_ai_out.hpp b/src/hook_monster_ai_out.hpp
new file mode 100644
index 00000000..4c5ef28f
--- /dev/null
+++ b/src/hook_monster_ai_out.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_monster_ai_out {
+ s32b y;
+ s32b x;
+};
diff --git a/src/hook_monster_death_in.hpp b/src/hook_monster_death_in.hpp
new file mode 100644
index 00000000..354c37d2
--- /dev/null
+++ b/src/hook_monster_death_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_monster_death_in {
+ s32b m_idx;
+};
diff --git a/src/hook_move_in.hpp b/src/hook_move_in.hpp
new file mode 100644
index 00000000..6e299e5b
--- /dev/null
+++ b/src/hook_move_in.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+struct hook_move_in {
+ int y;
+ int x;
+};
diff --git a/src/hook_new_monster_end_in.hpp b/src/hook_new_monster_end_in.hpp
new file mode 100644
index 00000000..3c5f835b
--- /dev/null
+++ b/src/hook_new_monster_end_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "monster_type_fwd.hpp"
+
+struct hook_new_monster_end_in {
+ monster_type *m_ptr;
+};
diff --git a/src/hook_new_monster_in.hpp b/src/hook_new_monster_in.hpp
new file mode 100644
index 00000000..10b0420c
--- /dev/null
+++ b/src/hook_new_monster_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_new_monster_in {
+ s32b r_idx;
+};
diff --git a/src/hook_player_level_in.hpp b/src/hook_player_level_in.hpp
new file mode 100644
index 00000000..90804e27
--- /dev/null
+++ b/src/hook_player_level_in.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+struct hook_player_level_in {
+ int gained_levels;
+};
diff --git a/src/hook_quest_fail_in.hpp b/src/hook_quest_fail_in.hpp
new file mode 100644
index 00000000..2edf86a3
--- /dev/null
+++ b/src/hook_quest_fail_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_quest_fail_in {
+ s16b q_idx;
+};
diff --git a/src/hook_quest_finish_in.hpp b/src/hook_quest_finish_in.hpp
new file mode 100644
index 00000000..55490be4
--- /dev/null
+++ b/src/hook_quest_finish_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_quest_finish_in {
+ s32b q_idx;
+};
diff --git a/src/hook_stair_in.hpp b/src/hook_stair_in.hpp
new file mode 100644
index 00000000..884a187c
--- /dev/null
+++ b/src/hook_stair_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "stairs_direction.hpp"
+
+struct hook_stair_in {
+ stairs_direction direction;
+};
diff --git a/src/hook_stair_out.hpp b/src/hook_stair_out.hpp
new file mode 100644
index 00000000..5e3d515a
--- /dev/null
+++ b/src/hook_stair_out.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_stair_out {
+ bool_ allow;
+};
diff --git a/src/hook_wield_in.hpp b/src/hook_wield_in.hpp
new file mode 100644
index 00000000..036e62da
--- /dev/null
+++ b/src/hook_wield_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "object_type_fwd.hpp"
+
+struct hook_wield_in {
+ object_type *o_ptr;
+};
diff --git a/src/hook_wild_gen_in.hpp b/src/hook_wild_gen_in.hpp
new file mode 100644
index 00000000..147a74db
--- /dev/null
+++ b/src/hook_wild_gen_in.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct hook_wild_gen_in {
+ bool_ small;
+};
diff --git a/src/hooks.cc b/src/hooks.cc
new file mode 100644
index 00000000..4fcc39d3
--- /dev/null
+++ b/src/hooks.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001 James E. Wilson, Robert A. Koeneke, DarkGod
+ *
+ * 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.
+ */
+#include "hooks.hpp"
+
+#include <algorithm>
+#include <assert.h>
+#include <unordered_map>
+#include <vector>
+
+/******** Hooks stuff *********/
+
+struct hook_data
+{
+private:
+ hook_func_t m_hook_func;
+ void *m_hook_data;
+public:
+ hook_data(hook_func_t hook_func, void *hook_data)
+ : m_hook_func(hook_func)
+ , m_hook_data(hook_data) {
+ }
+
+ hook_data() = delete;
+
+ /**
+ * Check if the given hook points to the given function.
+ */
+ bool is(hook_func_t hook_func) const {
+ return m_hook_func == hook_func;
+ }
+
+ /**
+ * Invoke the hook with the given input and output pointers.
+ */
+ bool_ invoke(void *in, void *out) const {
+ return m_hook_func(m_hook_data, in, out);
+ }
+};
+
+std::unordered_map<size_t, std::vector<hook_data>> &hooks_instance()
+{
+ static auto instance = new std::unordered_map<size_t, std::vector<hook_data>>();
+ return *instance;
+}
+
+
+int process_hooks_restart = FALSE;
+
+static std::vector<hook_data>::iterator find_hook(std::vector<hook_data> &hooks, hook_func_t hook_func)
+{
+ return std::find_if(hooks.begin(),
+ hooks.end(),
+ [&](const hook_data &hook_data) {
+ return hook_data.is(hook_func);
+ });
+}
+
+void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data)
+{
+ auto &hooks = hooks_instance()[h_idx];
+ // Only insert if not already present.
+ if (find_hook(hooks, hook_func) == hooks.end()) {
+ hooks.emplace_back(hook_func, data);
+ }
+}
+
+void del_hook_new(int h_idx, hook_func_t hook_func)
+{
+ auto &hooks = hooks_instance()[h_idx];
+
+ /* Find it */
+ auto found_it = find_hook(hooks, hook_func);
+ if (found_it != hooks.end())
+ {
+ hooks.erase(found_it);
+ }
+}
+
+bool_ process_hooks_new(int h_idx, void *in, void *out)
+{
+ auto const &hooks = hooks_instance()[h_idx];
+
+ auto hooks_it = hooks.begin();
+ while (hooks_it != hooks.end())
+ {
+ auto &hook_data = *hooks_it;
+
+ /* Invoke hook function; stop processing if the hook
+ returns TRUE */
+ if (hook_data.invoke(in, out))
+ {
+ return TRUE;
+ }
+
+ /* Should we restart processing at the beginning? */
+ if (process_hooks_restart)
+ {
+ hooks_it = hooks.begin();
+ process_hooks_restart = FALSE;
+ }
+ else
+ {
+ hooks_it++;
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/hooks.hpp b/src/hooks.hpp
new file mode 100644
index 00000000..b6124e6a
--- /dev/null
+++ b/src/hooks.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "h-basic.h"
+
+typedef bool_ (*hook_func_t)(void *, void *, void *);
+
+extern void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data);
+extern void del_hook_new(int h_idx, hook_func_t hook_func);
+extern int process_hooks_restart;
+extern bool_ process_hooks_new(int h_idx, void *in, void *out);
diff --git a/src/identify_mode.hpp b/src/identify_mode.hpp
new file mode 100644
index 00000000..687a1fae
--- /dev/null
+++ b/src/identify_mode.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+typedef enum { IDENT_NORMAL, IDENT_FULL } identify_mode;
diff --git a/src/include/sglib.h b/src/include/sglib.h
deleted file mode 100644
index 1a4780fa..00000000
--- a/src/include/sglib.h
+++ /dev/null
@@ -1,1952 +0,0 @@
-/*
-
- This is SGLIB version 1.0.3
-
- (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5
-
- License Conditions: You can use a verbatim copy (including this
- copyright notice) of sglib freely in any project, commercial or not.
- You can also use derivative forms freely under terms of Open Source
- Software license or under terms of GNU Public License. If you need
- to use a derivative form in a commercial project, or you need sglib
- under any other license conditions, contact the author.
-
-
-
-*/
-
-
-#ifndef _SGLIB__h_
-#define _SGLIB__h_
-
-/* the assert is used exclusively to write unexpected error messages */
-#include <assert.h>
-
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - LEVEL - 0 INTERFACE - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------------ STATIC ARRAYS ------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/*
-
- Basic algorithms for sorting arrays. Multiple depending arrays can
- be rearranged using user defined 'elem_exchangers'
-
-*/
-
-/* HEAP - SORT (level 0) */
-
-#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\
- SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\
- int _k_;\
- for(_k_=(max)/2; _k_>=0; _k_--) {\
- SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\
- }\
- for(_k_=(max)-1; _k_>=0; _k_--) {\
- elem_exchanger(type, a, 0, _k_);\
- SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\
- }\
-}
-
-#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\
- type _t_;\
- int _m_, _l_, _r_, _i_;\
- _i_ = (ind);\
- _m_ = _i_;\
- do {\
- _i_ = _m_; \
- _l_ = 2*_i_+1;\
- _r_ = _l_+1;\
- if (_l_ < (max)){\
- if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\
- if (_r_ < (max)) {\
- if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\
- }\
- }\
- if (_m_ != _i_) {\
- elem_exchanger(type, a, _i_, _m_);\
- }\
- } while (_m_ != _i_);\
-}
-
-
-/* QUICK - SORT (level 0) */
-
-#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\
- SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\
- int _i_, _j_, _p_, _stacki_, _start_, _end_;\
- /* can sort up to 2^64 elements */\
- int _startStack_[64]; \
- int _endStack_[64];\
- type _tmp_;\
- _startStack_[0] = 0;\
- _endStack_[0] = (max);\
- _stacki_ = 1;\
- while (_stacki_ > 0) {\
- _stacki_ --;\
- _start_ = _startStack_[_stacki_];\
- _end_ = _endStack_[_stacki_];\
- while (_end_ - _start_ > 2) {\
- _p_ = _start_;\
- _i_ = _start_ + 1;\
- _j_ = _end_ - 1;\
- while (_i_<_j_) {\
- for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\
- if (_i_ > _j_) {\
- /* all remaining elements lesseq than pivot */\
- elem_exchanger(type, a, _j_, _p_);\
- _i_ = _j_;\
- } else {\
- for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\
- if (_i_ > _j_) {\
- /* all remaining elements greater than pivot */\
- elem_exchanger(type, a, _j_, _p_);\
- _i_ = _j_;\
- } else if (_i_ < _j_) {\
- elem_exchanger(type, a, _i_, _j_);\
- if (_i_+2 < _j_) {_i_++; _j_--;}\
- else if (_i_+1 < _j_) _i_++;\
- }\
- }\
- }\
- /* O.K. i==j and pivot is on a[i] == a[j] */\
- /* handle recursive calls without recursion */\
- if (_i_-_start_ > 1 && _end_-_j_ > 1) {\
- /* two recursive calls, use array-stack */\
- if (_i_-_start_ < _end_-_j_-1) {\
- _startStack_[_stacki_] = _j_+1;\
- _endStack_[_stacki_] = _end_;\
- _stacki_ ++;\
- _end_ = _i_;\
- } else {\
- _startStack_[_stacki_] = _start_;\
- _endStack_[_stacki_] = _i_;\
- _stacki_ ++;\
- _start_ = _j_+1;\
- }\
- } else {\
- if (_i_-_start_ > 1) {\
- _end_ = _i_;\
- } else {\
- _start_ = _j_+1;\
- }\
- }\
- }\
- if (_end_ - _start_ == 2) {\
- if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\
- elem_exchanger(type, a, _start_, _end_-1);\
- }\
- }\
- }\
-}
-
-/* BINARY SEARCH (level 0) */
-
-#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\
- int _kk_, _cc_, _ii_, _jj_, _ff_;\
- _ii_ = (start_index); \
- _jj_ = (end_index);\
- _ff_ = 0;\
- while (_ii_ <= _jj_ && _ff_==0) {\
- _kk_ = (_jj_+_ii_)/2;\
- _cc_ = comparator(((a)[_kk_]), (key));\
- if (_cc_ == 0) {\
- (result_index) = _kk_; \
- _ff_ = 1;\
- } else if (_cc_ < 0) {\
- _ii_ = _kk_+1;\
- } else {\
- _jj_ = _kk_-1;\
- }\
- }\
- if (_ff_ == 0) {\
- /* not found, but set its resulting place in the array */\
- (result_index) = _jj_+1;\
- }\
- (found) = _ff_;\
-}
-
-/* -------------------------------- queue (in an array) ------------------ */
-/* queue is a quadruple (a,i,j,dim) such that: */
-/* a is the array storing values */
-/* i is the index of the first used element in the array */
-/* j is the index of the first free element in the array */
-/* dim is the size of the array a */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; }
-#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j))
-#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim))
-#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i])
-#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\
- if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\
- (j) = ((j)+1) % (dim);\
-}
-#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\
- a[j] = (elem);\
- SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\
-}
-#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\
- if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\
- (i) = ((i)+1) % (dim);\
-}
-#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\
- SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\
-}
-
-/* ----------------- priority queue (heap) (in an array) -------------------- */
-/* heap is a triple (a,i,dim) such that: */
-/* a is the array storing values */
-/* i is the index of the first free element in the array */
-/* dim is the size of the array a */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-#define SGLIB_HEAP_INIT(type, a, i) { i = 0; }
-#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0)
-#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim))
-#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0])
-#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\
- int _i_;\
- if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\
- _i_ = (i)++;\
- while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\
- elem_exchanger(type, a, (_i_/2), _i_);\
- _i_ = _i_/2;\
- }\
-}
-#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\
- if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\
- a[i] = (elem);\
- SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\
- if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\
- (i)--;\
- a[0] = a[i];\
- SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\
-}
-#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\
- SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-
-/* ----------------- hashed table of pointers (in an array) -------------------- */
-
-/*
-
- This hashed table is storing pointers to objects (not containers).
- In this table there is a one-to-one mapping between 'objects' stored
- in the table and indexes where they are placed. Each index is
- pointing to exactly one 'object' and each 'object' stored in the
- table occurs on exactly one index. Once an object is stored in the
- table, it can be represented via its index.
-
- In case of collision while adding an object the index shifted
- by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined)
-
- You can NOT delete an element from such hash table. The only
- justification (I can see) for this data structure is an exchange
- file format, having an index table at the beginning and then
- refering objects via indexes.
-
- !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!!
-
-*/
-
-#define SGLIB_HASH_TAB_INIT(type, table, dim) {\
- int _i_;\
- for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\
-}
-
-#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\
- unsigned _pos_;\
- type *_elem_;\
- SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\
- (member) = (table)[_pos_];\
- if (_elem_ == NULL) {\
- if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\
- (table)[_pos_] = (elem);\
- }\
-}
-
-#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\
- unsigned _i_;\
- int _count_;\
- type *_e_;\
- _count = 0;\
- _i_ = hash_function(elem);\
- _i_ %= (dim);\
- while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\
- _count_ ++;\
- _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\
- }\
- (resultIndex) = _i_;\
- if (_count_ < (dim)) (resultMember) = _e_;\
- else (resultMember) = NULL;\
-}
-
-#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\
- unsigned _i_;\
- int _c_;\
- type *_e_;\
- _count = 0;\
- _i_ = hash_function(elem);\
- _i_ %= (dim);\
- while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\
- _c_ ++;\
- _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\
- }\
- if (_e_==(elem)) (resultIndex) = _i_;\
- else (resultIndex) = -1;\
-}
-
-#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\
- unsigned iteratedIndex;\
- type *iteratedVariable;\
- for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\
- iteratedVariable = (table)[iteratedIndex];\
- if (iteratedVariable != NULL) {command;}\
- }\
-}
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/* ------------------------------------ lists (level 0) --------------------- */
-
-#define SGLIB_LIST_ADD(type, list, elem, next) {\
- (elem)->next = (list);\
- (list) = (elem);\
-}
-
-#define SGLIB_LIST_CONCAT(type, first, second, next) {\
- if ((first)==NULL) {\
- (first) = (second);\
- } else {\
- type *_p_;\
- for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\
- _p_->next = (second);\
- }\
-}
-
-#define SGLIB_LIST_DELETE(type, list, elem, next) {\
- type **_p_;\
- for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\
- assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\
- *_p_ = (*_p_)->next;\
-}
-
-#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\
- (member) = _p_;\
- if (_p_ == NULL) {\
- SGLIB_LIST_ADD(type, list, elem, next);\
- }\
-}
-
-#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\
- type **_p_;\
- for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\
- (member) = *_p_;\
- if (*_p_ != NULL) {\
- *_p_ = (*_p_)->next;\
- }\
-}
-
-#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\
- (result) = (_p_!=NULL);\
-}
-
-#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\
- (member) = _p_;\
-}
-
-#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\
- type *_ne_;\
- type *iteratedVariable;\
- (iteratedVariable) = (list); \
- while ((iteratedVariable)!=NULL) {\
- _ne_ = (iteratedVariable)->next;\
- {command;};\
- (iteratedVariable) = _ne_;\
- }\
-}
-
-#define SGLIB_LIST_LEN(type, list, next, result) {\
- type *_ce_;\
- (result) = 0;\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\
-}
-
-#define SGLIB_LIST_REVERSE(type, list, next) {\
- type *_list_,*_tmp_,*_res_;\
- _list_ = (list);\
- _res_ = NULL;\
- while (_list_!=NULL) {\
- _tmp_ = _list_->next; _list_->next = _res_;\
- _res_ = _list_; _list_ = _tmp_;\
- }\
- (list) = _res_;\
-}
-
-#define SGLIB_LIST_SORT(type, list, comparator, next) {\
- /* a non-recursive merge sort on lists */\
- type *_r_;\
- type *_a_, *_b_, *_todo_, *_t_, **_restail_;\
- int _i_, _n_, _contFlag_;\
- _r_ = (list);\
- _contFlag_ = 1;\
- for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\
- _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\
- while (_todo_!=NULL) {\
- _a_ = _todo_;\
- for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\
- if (_t_ ==NULL) {\
- *_restail_ = _a_;\
- break;\
- }\
- _b_ = _t_->next; _t_->next=NULL;\
- for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\
- if (_t_ ==NULL) {\
- _todo_ =NULL;\
- } else {\
- _todo_ = _t_->next; _t_->next=NULL;\
- }\
- /* merge */\
- while (_a_!=NULL && _b_!=NULL) {\
- if (comparator(_a_, _b_) < 0) {\
- *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\
- } else {\
- *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\
- }\
- }\
- if (_a_!=NULL) *_restail_ = _a_;\
- else *_restail_ = _b_;\
- while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\
- _contFlag_ =1;\
- }\
- }\
- (list) = _r_;\
-}
-
-/* --------------------------------- sorted list (level 0) --------------------- */
-/*
- All operations suppose that the list is sorted and they preserve
- this property.
-*/
-
-
-#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\
- type **_e_;\
- int _cmpres_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\
- (elem)->next = *_e_;\
- *_e_ = (elem);\
-}
-
-#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\
- type **_e_;\
- int _cmp_res_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\
- if (_cmp_res_ != 0) {\
- (elem)->next = *_e_;\
- *_e_ = (elem);\
- (member) = NULL;\
- } else {\
- (member) = *_e_;\
- }\
-}
-
-#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\
- SGLIB_LIST_DELETE(type, list, elem, next);\
-}
-
-#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\
- type **_e_;\
- int _cmp_res_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\
- if (_cmp_res_ == 0) {\
- (member) = *_e_;\
- *_e_ = (*_e_)->next;\
- } else {\
- (member) = NULL;\
- }\
-}
-
-#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- int _cmpres_ = 1;\
- for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\
- if (_cmpres_ != 0) (member) = NULL;\
- else (member) = _p_;\
-}
-
-#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\
- while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\
- (result) = (_p_ == (elem));\
-}
-
-#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\
- (comparator_result) = -1;\
- for((member_ptr) = &(list); \
- *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \
- (member_ptr) = &(*(member_ptr))->next) ;\
-}
-
-#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\
- SGLIB_LIST_LEN(type, list, next, result);\
-}
-
-#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\
-}
-
-
-/* ------------------------------- double linked list (level 0) ------------------------- */
-/*
- Lists with back pointer to previous element. Those lists implements deletion
- of an element in a constant time.
-*/
-
-#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\
- (list) = (elem);\
- (list)->next = (list)->previous = NULL;\
-}
-
-#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\
- if ((place) == NULL) {\
- SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\
- } else {\
- (elem)->next = (place)->next;\
- (elem)->previous = (place);\
- (place)->next = (elem);\
- if ((elem)->next != NULL) (elem)->next->previous = (elem);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\
- if ((place) == NULL) {\
- SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\
- } else {\
- (elem)->next = (place);\
- (elem)->previous = (place)->previous;\
- (place)->previous = (elem);\
- if ((elem)->previous != NULL) (elem)->previous->next = (elem);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\
- SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\
-}
-
-#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\
- type *_dlp_;\
- for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\
- if (_dlp_ == NULL && (list) != NULL) {\
- for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\
- }\
- (member) = _dlp_;\
- if (_dlp_ == NULL) {\
- the_add_operation(type, list, elem, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\
-}
-
-#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\
-}
-
-#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\
-}
-
-#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\
- if ((first)==NULL) {\
- (first) = (second);\
- } else if ((second)!=NULL) {\
- type *_dlp_;\
- for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\
- SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\
- type *_l_;\
- _l_ = (list);\
- if (_l_ == (elem)) {\
- if ((elem)->previous != NULL) _l_ = (elem)->previous;\
- else _l_ = (elem)->next;\
- }\
- if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\
- if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\
- (list) = _l_;\
-}
-
-#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\
- type *_dlp_;\
- for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\
- if (_dlp_ == NULL && (list) != NULL) {\
- for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\
- }\
- (member) = _dlp_;\
- if (_dlp_ != NULL) {\
- SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\
- type *_dlp_;\
- SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\
- if (result == 0 && (list) != NULL) {\
- _dlp_ = (list)->next;\
- SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\
- }\
-}
-
-#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\
- type *_dlp_;\
- SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\
- if ((member) == NULL && (list) != NULL) {\
- _dlp_ = (list)->next;\
- SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\
- }\
-}
-
-#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\
- type *_dl_;\
- type *iteratedVariable;\
- if ((list)!=NULL) {\
- _dl_ = (list)->next;\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\
- }\
-}
-
-#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\
- type *_dll_, *_dlp_, *_dlt_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\
- SGLIB_LIST_SORT(type, _dll_, comparator, next);\
- SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\
- (list) = _dll_;\
- }\
-}
-
-#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\
- type *_dll_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\
- }\
- (result) = _dll_;\
-}
-
-#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\
- type *_dll_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\
- }\
- (result) = _dll_;\
-}
-
-#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\
- type *_dl_;\
- int _r1_, _r2_;\
- if ((list)==NULL) {\
- (result) = 0;\
- } else {\
- SGLIB_LIST_LEN(type, list, previous, _r1_);\
- _dl_ = (list)->next;\
- SGLIB_LIST_LEN(type, _dl_, next, _r2_);\
- (result) = _r1_ + _r2_;\
- }\
-}
-
-#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\
- type *_list_,*_nlist_,*_dlp_,*_dln_;\
- _list_ = (list);\
- if (_list_!=NULL) {\
- _nlist_ = _list_->next;\
- while (_list_!=NULL) {\
- _dln_ = _list_->next; \
- _dlp_ = _list_->previous; \
- _list_->next = _dlp_;\
- _list_->previous = _dln_;\
- _list_ = _dlp_;\
- }\
- while (_nlist_!=NULL) {\
- _dln_ = _nlist_->next; \
- _dlp_ = _nlist_->previous; \
- _nlist_->next = _dlp_;\
- _nlist_->previous = _dln_;\
- _nlist_ = _dln_;\
- }\
- }\
-}
-
-#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\
- type *_dlp_, *_dlt_;\
- _dlp_ = NULL;\
- for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\
- _dlt_->previous = _dlp_;\
- _dlp_ = _dlt_;\
- }\
-}
-
-
-/* ------------------------------- binary tree traversal (level 0) -------------------- */
-
-
-#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\
- /* this is non-recursive implementation of tree traversal */\
- /* it maintains the path to the current node in the array '_path_' */\
- /* the _path_[0] contains the root of the tree; */\
- /* the _path_[_pathi_] contains the _current_element_ */\
- /* the macro does not use the _current_element_ after execution of command */\
- /* command can destroy it, it can free the element for example */\
- type *_path_[SGLIB_MAX_TREE_DEEP];\
- type *_right_[SGLIB_MAX_TREE_DEEP];\
- char _pass_[SGLIB_MAX_TREE_DEEP];\
- type *_cn_;\
- int _pathi_;\
- type *iteratedVariable;\
- _cn_ = (tree);\
- _pathi_ = 0;\
- while (_cn_!=NULL) {\
- /* push down to leftmost innermost element */\
- while(_cn_!=NULL) {\
- _path_[_pathi_] = _cn_;\
- _right_[_pathi_] = _cn_->right;\
- _pass_[_pathi_] = 0;\
- _cn_ = _cn_->left;\
- if (order == 0) {\
- iteratedVariable = _path_[_pathi_];\
- {command;}\
- }\
- _pathi_ ++;\
- if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\
- }\
- do {\
- _pathi_ --;\
- if ((order==1 && _pass_[_pathi_] == 0)\
- || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\
- iteratedVariable = _path_[_pathi_];\
- {command;}\
- }\
- _pass_[_pathi_] ++;\
- } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\
- _cn_ = _right_[_pathi_];\
- _right_[_pathi_] = NULL;\
- _pathi_ ++;\
- }\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\
-}
-
-#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\
- type *_s_;\
- int _c_;\
- _s_ = (tree);\
- while (_s_!=NULL) {\
- _c_ = comparator((elem), _s_);\
- if (_c_ < 0) _s_ = _s_->left;\
- else if (_c_ > 0) _s_ = _s_->right;\
- else break;\
- }\
- (res) = _s_;\
-}
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - LEVEL - 1 INTERFACE - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------------ STATIC ARRAYS ------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/* ----------------------------- array sorting (level 1) ---------------------- */
-
-#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \
- extern void sglib_##type##_array_quick_sort(type *a, int max);\
- extern void sglib_##type##_array_heap_sort(type *a, int max);\
-
-
-#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \
- void sglib_##type##_array_quick_sort(type *a, int max) {\
- SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\
- }\
- void sglib_##type##_array_heap_sort(type *a, int max) {\
- SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\
- }\
-
-
-/* ----------------------------- array queue (level 1) ------------------- */
-/* sglib's queue is stored in a fixed sized array */
-/* queue_type MUST be a structure containing fields: */
-/* afield is the array storing elem_type */
-/* ifield is the index of the first element in the queue */
-/* jfield is the index of the first free element after the queue */
-/* dim is the size of the array afield */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-
-#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \
- extern void sglib_##queue_type##_init(queue_type *q); \
- extern int sglib_##queue_type##_is_empty(queue_type *q); \
- extern int sglib_##queue_type##_is_full(queue_type *q); \
- extern elem_type sglib_##queue_type##_first_element(queue_type *q); \
- extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \
- extern void sglib_##queue_type##_add_next(queue_type *q); \
- extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \
- extern void sglib_##queue_type##_delete_first(queue_type *q); \
- extern void sglib_##queue_type##_delete(queue_type *q);
-
-
-#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \
- void sglib_##queue_type##_init(queue_type *q) {\
- SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\
- }\
- int sglib_##queue_type##_is_empty(queue_type *q) {\
- return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- int sglib_##queue_type##_is_full(queue_type *q) {\
- return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- elem_type sglib_##queue_type##_first_element(queue_type *q) {\
- return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\
- return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- void sglib_##queue_type##_add_next(queue_type *q) {\
- SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\
- SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_delete_first(queue_type *q) {\
- SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_delete(queue_type *q) {\
- SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }
-
-
-/* ------------------------ array heap (level 1) ------------------------- */
-/* sglib's heap is a priority queue implemented in a fixed sized array */
-/* heap_type MUST be a structure containing fields: */
-/* afield is the array of size dim storing elem_type */
-/* ifield is the index of the first free element after the queue */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-
-#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \
- extern void sglib_##heap_type##_init(heap_type *q); \
- extern int sglib_##heap_type##_is_empty(heap_type *q); \
- extern int sglib_##heap_type##_is_full(heap_type *q); \
- extern elem_type sglib_##heap_type##_first_element(heap_type *q); \
- extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \
- extern void sglib_##heap_type##_add_next(heap_type *q); \
- extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \
- extern void sglib_##heap_type##_delete_first(heap_type *q); \
- extern void sglib_##heap_type##_delete(heap_type *q)
-
-#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \
- void sglib_##heap_type##_init(heap_type *q) {\
- SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\
- }\
- int sglib_##heap_type##_is_empty(heap_type *q) {\
- return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\
- }\
- int sglib_##heap_type##_is_full(heap_type *q) {\
- return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\
- }\
- elem_type sglib_##heap_type##_first_element(heap_type *q) {\
- return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\
- }\
- elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\
- return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\
- }\
- void sglib_##heap_type##_add_next(heap_type *q) {\
- SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\
- SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_delete_first(heap_type *q) {\
- SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_delete(heap_type *q) {\
- SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }
-
-
-/* ------------------------ hashed table (level 1) ------------------------- */
-/*
-
- sglib's hash table is an array storing directly pointers to objects (not containers).
- In this table there is a one-to-one mapping between 'objects' stored
- in the table and indexes where they are placed. Each index is
- pointing to exactly one 'object' and each 'object' stored in the
- table occurs on exactly one index. Once an object is stored in the
- table, it can be represented via its index.
-
- type - is the type of elements
- dim - is the size of the hash array
- hash_function - is a hashing function mapping type* to unsigned
- comparator - is a comparator on elements
-
- !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!!
-*/
-
-#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \
- struct sglib_hashed_##type##_iterator {\
- int currentIndex;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_hashed_##type##_init(type *table[dim]);\
- extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\
- extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\
- extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\
- extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \
- extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \
- extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it);
-
-#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \
- struct sglib_hashed_##type##_iterator {\
- int currentIndex;\
- type **table;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- void sglib_hashed_##type##_init(type *table[dim]) {\
- SGLIB_HASH_TAB_INIT(type, table, dim);\
- }\
- int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\
- SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\
- }\
- int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\
- int ind;\
- SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\
- return(ind != -1);\
- }\
- type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\
- type *mmb;\
- int ind;\
- SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\
- return(mmb);\
- }\
- type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\
- int i;\
- it->table = table;\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- for(i=0; i<(dim) && table[i]==NULL; i++) ;\
- it->currentIndex = i;\
- if (i<(dim)) return(table[i]);\
- return(NULL);\
- }\
- type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\
- sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\
- }\
- type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\
- return(table[it->currentIndex]);\
- }\
- type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\
- i=it->currentIndex;\
- if (i<(dim)) {\
- for(i++; i<(dim) && table[i]==NULL; i++) ;\
- }\
- it->currentIndex = i;\
- if (i<(dim)) return(table[i]);\
- return(NULL);\
- }
-
-
-/* ------------------- hashed container (only for level 1) -------------------- */
-/*
- hashed container is a table of given fixed size containing another
- (dynamic) base container in each cell. Once an object should be
- inserted into the hashed container, a hash function is used to
- determine the cell where the object belongs and the object is
- inserted into the base container stored in this cell. Usually the
- base container is simply a list or a sorted list, but it can be a
- red-black tree as well.
-
- parameters:
- type - the type of the container stored in each cell.
- dim - the size of the hashed array
- hash_function - the hashing function hashing 'type *' to unsigned.
-
-*/
-
-#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \
- struct sglib_hashed_##type##_iterator {\
- struct sglib_##type##_iterator containerIt;\
- type **table;\
- int currentIndex;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_hashed_##type##_init(type *table[dim]);\
- extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\
- extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\
- extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\
- extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\
- extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\
- extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\
- extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \
- extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \
- extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it);
-
-#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \
- /*extern unsigned hash_function(type *elem);*/\
- void sglib_hashed_##type##_init(type *table[dim]) {\
- unsigned i;\
- for(i=0; i<(dim); i++) table[i] = NULL;\
- }\
- void sglib_hashed_##type##_add(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- sglib_##type##_add(&(table)[i], elem);\
- }\
- int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\
- }\
- void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- sglib_##type##_delete(&(table)[i], elem);\
- }\
- int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\
- }\
- int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_is_member((table)[i], elem));\
- }\
- type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_find_member((table)[i], elem));\
- }\
- type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\
- type *e;\
- it->table = table;\
- it->currentIndex = 0;\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\
- if (e==NULL) e = sglib_hashed_##type##_it_next(it);\
- return(e);\
- }\
- type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\
- return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\
- }\
- type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\
- return(sglib_##type##_it_current(&it->containerIt));\
- }\
- type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\
- type *e;\
- e = sglib_##type##_it_next(&it->containerIt);\
- while (e==NULL && (++(it->currentIndex))<(dim)) {\
- e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\
- }\
- return(e);\
- }
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-
-/* ------------------------------------ list (level 1) -------------------------------- */
-
-#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_concat(type **first, type *second);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern void sglib_##type##_sort(type **list);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_reverse(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_LIST_ADD(type, *list, elem, next);\
- }\
- void sglib_##type##_concat(type **first, type *second) {\
- SGLIB_LIST_CONCAT(type, *first, second, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_LIST_DELETE(type, *list, elem, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member!=NULL);\
- }\
- void sglib_##type##_sort(type **list) { \
- SGLIB_LIST_SORT(type, *list, comparator, next);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_LIST_LEN(type, list, next, res);\
- return(res);\
- }\
- void sglib_##type##_reverse(type **list) {\
- SGLIB_LIST_REVERSE(type, *list, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->nextelem = list;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\
- }\
- it->currentelem = ce;\
- if (ce != NULL) it->nextelem = ce->next;\
- return(ce);\
- }
-
-/* ----------------------------- sorted list (level 1) ----------------------------------- */
-
-
-#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_sort(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member!=NULL);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_SORTED_LIST_LEN(type, list, next, res);\
- return(res);\
- }\
- void sglib_##type##_sort(type **list) { \
- SGLIB_LIST_SORT(type, *list, comparator, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->nextelem = list;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- int c;\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\
- if (ce != NULL && c > 0) ce = NULL;\
- }\
- it->currentelem = ce;\
- if (ce != NULL) it->nextelem = ce->next;\
- return(ce);\
- }
-
-
-/* ----------------------------- double linked list (level 1) ------------------------------ */
-
-
-#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *prevelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern void sglib_##type##_add_before(type **list, type *elem);\
- extern void sglib_##type##_add_after(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_concat(type **first, type *second);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern type *sglib_##type##_get_first(type *list);\
- extern type *sglib_##type##_get_last(type *list);\
- extern void sglib_##type##_sort(type **list);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_reverse(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\
- }\
- void sglib_##type##_add_after(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\
- }\
- void sglib_##type##_add_before(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_concat(type **first, type *second) {\
- SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member!=NULL);\
- }\
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_get_first(type *list) {\
- type *result;\
- SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_get_last(type *list) {\
- type *result;\
- SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\
- return(result);\
- }\
- void sglib_##type##_sort(type **list) {\
- SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_DL_LIST_LEN(type, list, previous, next, res);\
- return(res);\
- }\
- void sglib_##type##_reverse(type **list) {\
- SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->prevelem = list;\
- it->nextelem = list;\
- if (list != NULL) it->nextelem = list->next;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- ce = it->prevelem;\
- it->prevelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\
- }\
- if (ce != NULL) {\
- it->prevelem = ce->previous;\
- } else {\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\
- }\
- if (ce != NULL) it->nextelem = ce->next;\
- }\
- it->currentelem = ce;\
- return(ce);\
- }
-
-
-/* --------------------------------- red-black trees (level 1) -------------------------------- */
-
-/*
-
-This implementation requires pointers to left and right sons (no
-parent pointer is needed) and one bit of additional information
-storing the color of the node. The implementation follows discrepancy
-fixing rules from:
-http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html
-
-*/
-
-#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\
- type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\
- t = *tree;\
- tl = t->leftt;\
- if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\
- if (SGLIB___GET_VALUE(tl->bits)==RED) {\
- if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \
- || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\
- SGLIB___SET_VALUE(t->leftt->bits,BLACK);\
- SGLIB___SET_VALUE(t->rightt->bits,BLACK);\
- SGLIB___SET_VALUE(t->bits,RED);\
- }\
- }\
- } else {\
- if (SGLIB___GET_VALUE(tl->bits)==RED) {\
- if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\
- a = t; b = tl; c = tl->leftt;\
- br = b->rightt;\
- a->leftt = br;\
- b->leftt = c; b->rightt = a;\
- SGLIB___SET_VALUE(a->bits,RED);\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- *tree = b;\
- } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\
- a = t; b = tl; ar=a->rightt;\
- bl=b->leftt; c=b->rightt;\
- cl=c->leftt; cr=c->rightt;\
- b->rightt = cl;\
- a->leftt = cr;\
- c->leftt = b;\
- c->rightt = a;\
- SGLIB___SET_VALUE(c->bits,BLACK);\
- SGLIB___SET_VALUE(a->bits,RED);\
- *tree = c;\
- }\
- }\
- }\
-}
-
-#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\
- type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\
- t = a = *tree;\
- assert(t!=NULL);\
- ar = a->rightt;\
- b = t->leftt;\
- if (b==NULL) {\
- assert(SGLIB___GET_VALUE(t->bits)==RED);\
- SGLIB___SET_VALUE(t->bits,BLACK);\
- res = 0;\
- } else {\
- bl = b->leftt;\
- br = b->rightt;\
- if (SGLIB___GET_VALUE(b->bits)==RED) {\
- if (br==NULL) {\
- *tree = b;\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- b->rightt = a;\
- a->leftt = br;\
- res = 0;\
- } else {\
- c = br;\
- assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\
- cl = c->leftt;\
- cr = c->rightt;\
- if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\
- *tree = b;\
- b->rightt = a;\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- a->leftt = c;\
- SGLIB___SET_VALUE(c->bits,RED);\
- res = 0;\
- } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\
- if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\
- d = cr;\
- dl = d->leftt;\
- dr = d->rightt;\
- *tree = d;\
- SGLIB___SET_VALUE(d->bits,BLACK);\
- d->leftt = b;\
- c->rightt = dl;\
- d->rightt = a;\
- a->leftt = dr;\
- res = 0;\
- } else {\
- *tree = c;\
- c->leftt = b;\
- c->rightt = a;\
- b->leftt = bl;\
- b->rightt = cl;\
- a->leftt = cr;\
- SGLIB___SET_VALUE(cl->bits,BLACK);\
- res = 0;\
- }\
- } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\
- assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\
- d = cr;\
- dl = d->leftt;\
- dr = d->rightt;\
- *tree = d;\
- SGLIB___SET_VALUE(d->bits,BLACK);\
- d->leftt = b;\
- c->rightt = dl;\
- d->rightt = a;\
- a->leftt = dr;\
- res = 0;\
- } else {\
- assert(0);\
- res = 0;\
- }\
- }\
- } else {\
- if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\
- res = (SGLIB___GET_VALUE(a->bits)==BLACK);\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- SGLIB___SET_VALUE(b->bits,RED);\
- } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\
- if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\
- *tree = b;\
- SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- b->rightt = a;\
- a->leftt = br;\
- SGLIB___SET_VALUE(bl->bits,BLACK);\
- res = 0;\
- } else {\
- assert(bl!=NULL);\
- assert(br!=NULL);\
- assert(SGLIB___GET_VALUE(bl->bits)==RED);\
- assert(SGLIB___GET_VALUE(br->bits)==RED);\
- c = br;\
- cl = c->leftt;\
- cr = c->rightt;\
- *tree = c;\
- SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- c->leftt = b;\
- c->rightt = a;\
- b->rightt = cl;\
- a->leftt = cr;\
- res = 0;\
- }\
- } else {\
- assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\
- c = br;\
- cl = c->leftt;\
- cr = c->rightt;\
- *tree = c;\
- SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- c->leftt = b;\
- c->rightt = a;\
- b->rightt = cl;\
- a->leftt = cr;\
- res = 0;\
- }\
- }\
- }\
-}
-
-
-#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \
-static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\
- SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\
-}\
-\
-static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\
- SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\
-}\
-\
-static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\
- int res;\
- SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\
- return(res);\
-}\
-\
-static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\
- int res;\
- SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\
- return(res);\
-}\
-\
-static void sglib___##type##_add_recursive(type **tree, type *elem) {\
- int cmp;\
- type *t;\
- t = *tree;\
- if (t == NULL) {\
- SGLIB___SET_VALUE(elem->bits,RED);\
- *tree =elem;\
- } else {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- sglib___##type##_add_recursive(&t->left, elem);\
- if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\
- } else {\
- sglib___##type##_add_recursive(&t->right, elem);\
- if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\
- }\
- }\
-}\
-\
-static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\
- type *t;\
- int res, deepDecreased;\
- t = *tree;\
- res = 0;\
- assert(t!=NULL);\
- if (t->right == NULL) {\
- *theLeaf = t;\
- if (t->left!=NULL) {\
- if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\
- SGLIB___SET_VALUE(t->left->bits,BLACK);\
- *tree = t->left;\
- } else {\
- *tree = NULL;\
- res = (SGLIB___GET_VALUE(t->bits)==BLACK);\
- }\
- } else {\
- deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\
- if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\
- }\
- return(res);\
-}\
-\
-int sglib___##type##_delete_recursive(type **tree, type *elem) {\
- type *t, *theLeaf;\
- int cmp, res, deepDecreased;\
- t = *tree;\
- res = 0;\
- if (t==NULL) {\
- assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\
- } else {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- deepDecreased = sglib___##type##_delete_recursive(&t->left, elem);\
- if (deepDecreased) {\
- res = sglib___##type##_fix_left_deletion_discrepancy(tree);\
- }\
- } else if (cmp > 0 || (cmp==0 && elem>t)) {\
- deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\
- if (deepDecreased) {\
- res = sglib___##type##_fix_right_deletion_discrepancy(tree);\
- }\
- } else {\
- assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\
- if (t->left == NULL) {\
- if (t->right == NULL) {\
- /* a leaf, delete, it; */\
- *tree = NULL;\
- res = (SGLIB___GET_VALUE(t->bits)==BLACK);\
- } else {\
- if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\
- SGLIB___SET_VALUE(t->right->bits,BLACK);\
- *tree = t->right;\
- }\
- } else {\
- /* propagate deletion until righmost leaf of left subtree */\
- deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\
- theLeaf->left = t->left;\
- theLeaf->right = t->right;\
- SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\
- *tree = theLeaf;\
- if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\
- }\
- }\
- }\
- return(res);\
-}\
-\
-void sglib_##type##_add(type **tree, type *elem) {\
- elem->left = elem->right = NULL;\
- sglib___##type##_add_recursive(tree, elem);\
- SGLIB___SET_VALUE((*tree)->bits,BLACK);\
-}\
-\
-void sglib_##type##_delete(type **tree, type *elem) {\
- sglib___##type##_delete_recursive(tree, elem);\
- if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\
-}\
-\
-type *sglib_##type##_find_member(type *t, type *elem) {\
- type *res;\
- SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\
- return(res);\
-}\
-\
-int sglib_##type##_is_member(type *t, type *elem) {\
- int cmp;\
- while (t!=NULL) {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- t = t->left;\
- } else if (cmp > 0 || (cmp==0 && elem>t)) {\
- t = t->right;\
- } else {\
- assert(t == elem);\
- return(1);\
- }\
- }\
- return(0);\
-}\
-\
-int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\
- if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\
- sglib_##type##_delete(tree, *memb);\
- return(1);\
- } else {\
- return(0);\
- }\
-}\
-int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\
- if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\
- sglib_##type##_add(tree, elem);\
- return(1);\
- } else {\
- return(0);\
- }\
-}\
-int sglib_##type##_len(type *t) {\
- int n;\
- type *e;\
- n = 0;\
- SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\
- return(n);\
-}\
-\
-void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\
- int i,j,cmp;\
- type *s, *eqt;\
- int (*subcomparator)(type *, type *);\
- eqt = it->equalto;\
- subcomparator = it->subcomparator;\
- it->currentelem = NULL;\
- while(it->pathi > 0 && it->currentelem==NULL) {\
- i = it->pathi-1;\
- if (i >= 0) {\
- if (it->pass[i] >= 2) {\
- /* goto up */\
- it->pathi --;\
- } else {\
- if (it->pass[i] == 0) {\
- /* goto left */\
- s = it->path[i]->left;\
- } else {\
- /* goto right */\
- s = it->path[i]->right;\
- }\
- if (eqt != NULL) {\
- if (subcomparator == NULL) {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\
- } else {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\
- }\
- }\
- if (s != NULL) {\
- j = i+1;\
- it->path[j] = s;\
- it->pass[j] = 0;\
- it->pathi ++;\
- }\
- it->pass[i] ++;\
- }\
- }\
- if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\
- it->currentelem = it->path[it->pathi-1];\
- }\
- }\
-}\
-type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\
- type *t;\
- assert(it!=NULL);\
- it->order = order;\
- it->equalto = equalto;\
- it->subcomparator = subcomparator;\
- if (equalto == NULL) { \
- t = tree;\
- } else {\
- if (subcomparator == NULL) {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\
- } else {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\
- }\
- }\
- if (t == NULL) {\
- it->pathi = 0;\
- it->currentelem = NULL;\
- } else {\
- it->pathi = 1;\
- it->pass[0] = 0;\
- it->path[0] = t;\
- if (order == 0) {\
- it->currentelem = t;\
- } else {\
- sglib__##type##_it_compute_current_elem(it);\
- }\
- }\
- return(it->currentelem);\
-}\
-type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\
- return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\
-}\
-type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
-}\
-type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- sglib__##type##_it_compute_current_elem(it);\
- return(it->currentelem);\
-}\
-\
-static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\
- if (t==NULL) {\
- if (*pathdeep < 0) *pathdeep = cdeep;\
- else assert(*pathdeep == cdeep);\
- } else {\
- if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\
- if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\
- if (SGLIB___GET_VALUE(t->bits) == RED) {\
- assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\
- assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\
- sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\
- sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\
- } else {\
- sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\
- sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\
- }\
- }\
-}\
-\
-void sglib___##type##_consistency_check(type *t) {\
- int pathDeep;\
- assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\
- pathDeep = -1;\
- sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\
-}
-
-
-#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- char pass[SGLIB_MAX_TREE_DEEP];\
- type *path[SGLIB_MAX_TREE_DEEP];\
- short int pathi;\
- short int order;\
- type *equalto;\
- int (*subcomparator)(type *, type *);\
- };\
- extern void sglib___##type##_consistency_check(type *t); \
- extern void sglib_##type##_add(type **tree, type *elem); \
- extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \
- extern void sglib_##type##_delete(type **tree, type *elem); \
- extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \
- extern int sglib_##type##_is_member(type *t, type *elem); \
- extern type *sglib_##type##_find_member(type *t, type *elem); \
- extern int sglib_##type##_len(type *t); \
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \
-
-
-#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \
- SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0)
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - SUPPLEMENTARY DEFINITIONS - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-#define SGLIB___GET_VALUE(x) (x)
-#define SGLIB___SET_VALUE(x, value) {(x) = (value);}
-#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;}
-
-
-#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0)))
-#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0)))
-#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y)))
-#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x)))
-#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y)
-#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y)
-
-#ifndef SGLIB_MAX_TREE_DEEP
-#define SGLIB_MAX_TREE_DEEP 128
-#endif
-
-#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT
-#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */
-/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */
-#endif
-
-#endif /* _SGLIB__h_ */
diff --git a/src/include/tome/enum_string_map.hpp b/src/include/tome/enum_string_map.hpp
new file mode 100644
index 00000000..8ae1e115
--- /dev/null
+++ b/src/include/tome/enum_string_map.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <boost/bimap.hpp>
+#include <boost/noncopyable.hpp>
+#include <string>
+#include <cassert>
+
+/**
+ * Bidirectional mapping between enumerated values
+ * and strings.
+ */
+template <class E>
+class EnumStringMap : boost::noncopyable {
+
+private:
+ typedef boost::bimap< E, std::string > bimap_type;
+ typedef typename bimap_type::value_type value_type;
+
+ bimap_type bimap;
+
+public:
+ explicit EnumStringMap(std::initializer_list< std::pair<E, const char *> > in) {
+ for (auto es : in)
+ {
+ bimap.insert(value_type(es.first, es.second));
+ }
+ // Sanity check that there were no
+ // duplicate mappings.
+ assert(bimap.size() == in.size());
+ }
+
+ const char *stringify(E e) {
+ auto i = bimap.left.find(e);
+ assert(i != bimap.left.end() && "Missing mapping for enumerated value");
+ return i->second.c_str();
+ }
+
+ E parse(const char *s) {
+ E e;
+ bool result = parse(s, &e);
+ assert(result && "Missing string->enum mapping");
+ return e;
+ }
+
+ bool parse(const char *s, E *e) {
+ auto i = bimap.right.find(s);
+ if (i == bimap.right.end())
+ {
+ return false;
+ }
+
+ *e = i->second;
+ return true;
+ }
+};
diff --git a/src/include/tome/make_array.hpp b/src/include/tome/make_array.hpp
new file mode 100644
index 00000000..23cb8ac0
--- /dev/null
+++ b/src/include/tome/make_array.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <type_traits>
+
+/*
+ * Make an array of a POD type.
+ */
+template <typename T> T *make_array(std::size_t n) {
+ static_assert(std::is_pod<T>::value, "Type parameter must be POD type");
+ T *array = new T[n];
+ memset(array, 0, n*sizeof(T));
+ return array;
+}
diff --git a/src/include/tome/squelch/automatizer.hpp b/src/include/tome/squelch/automatizer.hpp
new file mode 100644
index 00000000..786ca1ae
--- /dev/null
+++ b/src/include/tome/squelch/automatizer.hpp
@@ -0,0 +1,156 @@
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <memory>
+#include <vector>
+#include <jansson.h>
+
+#include "tome/squelch/rule_fwd.hpp"
+#include "tome/squelch/cursor_fwd.hpp"
+#include "tome/squelch/tree_printer_fwd.hpp"
+#include "tome/squelch/condition_fwd.hpp"
+#include "../object_type_fwd.hpp"
+
+namespace squelch {
+
+/**
+ * Automatizer
+ */
+class Automatizer : public boost::noncopyable
+{
+public:
+ Automatizer(std::shared_ptr<TreePrinter> tree_printer,
+ std::shared_ptr<Cursor> cursor)
+ : m_selected_rule(0)
+ , m_begin(0)
+ , m_tree_printer(tree_printer)
+ , m_cursor(cursor)
+ , m_rules() {
+ }
+
+ /**
+ * Append a rule
+ */
+ int append_rule(std::shared_ptr<Rule> rule);
+
+ /**
+ * Swap two rules
+ */
+ void swap_rules(int i, int j);
+
+ /**
+ * Apply all rules to the given object
+ */
+ bool apply_rules(object_type *o_ptr, int item_idx) const;
+
+ /**
+ * Build a JSON data structure to represent
+ * all the rules.
+ */
+ std::shared_ptr<json_t> to_json() const;
+
+ /**
+ * Load rules from a JSON data structure.
+ */
+ void load_json(json_t *json);
+
+ /**
+ * Remove currently selected condition or rule.
+ */
+ int remove_current_selection();
+
+ /**
+ * Reset view.
+ */
+ void reset_view();
+
+ /**
+ * Show current rule
+ */
+ void show_current() const;
+
+ /**
+ * Scroll view up
+ */
+ void scroll_up();
+
+ /**
+ * Scroll view down
+ */
+ void scroll_down();
+
+ /**
+ * Scroll view left
+ */
+ void scroll_left();
+
+ /**
+ * Scroll view right
+ */
+ void scroll_right();
+
+ /**
+ * Move selection up
+ */
+ void move_up();
+
+ /**
+ * Move selection down
+ */
+ void move_down();
+
+ /**
+ * Move selection left
+ */
+ void move_left();
+
+ /**
+ * Move selection right
+ */
+ void move_right();
+
+ /**
+ * Add new condition to selected rule
+ */
+ void add_new_condition(std::function<std::shared_ptr<Condition> ()> factory);
+
+ /**
+ * Get rule names. The names are not stable across multiple
+ * calls to methods on this class.
+ */
+ void get_rule_names(std::vector<const char *> *names) const;
+
+ /**
+ * Get current number of rules.
+ */
+ int rules_count() const;
+
+ /**
+ * Get the "beginning" rule.
+ */
+ int rules_begin() const;
+
+ /**
+ * Select a new rule.
+ */
+ void select_rule(int selected_rule);
+
+ /**
+ * Return selected rule index
+ */
+ int selected_rule() const;
+
+ /**
+ * Return selected rule
+ */
+ std::shared_ptr<Rule> current_rule();
+
+private:
+ int m_selected_rule;
+ int m_begin;
+ std::shared_ptr<TreePrinter> m_tree_printer;
+ std::shared_ptr<Cursor> m_cursor;
+ std::vector < std::shared_ptr < Rule > > m_rules;
+};
+
+} // namespace
diff --git a/src/include/tome/squelch/automatizer_fwd.hpp b/src/include/tome/squelch/automatizer_fwd.hpp
new file mode 100644
index 00000000..068f297a
--- /dev/null
+++ b/src/include/tome/squelch/automatizer_fwd.hpp
@@ -0,0 +1,10 @@
+#ifndef H_cbf79126_fd24_4f80_8f2d_9dd69cb7010f
+#define H_cbf79126_fd24_4f80_8f2d_9dd69cb7010f
+
+namespace squelch {
+
+class Automatizer;
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/condition.hpp b/src/include/tome/squelch/condition.hpp
new file mode 100644
index 00000000..5d1240f5
--- /dev/null
+++ b/src/include/tome/squelch/condition.hpp
@@ -0,0 +1,632 @@
+#pragma once
+
+#include "tome/squelch/condition_fwd.hpp"
+
+#include <boost/noncopyable.hpp>
+#include <functional>
+#include <memory>
+#include <cstdint>
+#include <jansson.h>
+
+#include "tome/squelch/cursor_fwd.hpp"
+#include "tome/squelch/tree_printer_fwd.hpp"
+#include "tome/squelch/object_status_fwd.hpp"
+#include "tome/enum_string_map.hpp"
+#include "../object_type_fwd.hpp"
+
+namespace squelch {
+
+/**
+ * Types of matches used for conditions.
+ */
+enum class match_type {
+ AND , OR , NOT , NAME , CONTAIN ,
+ INSCRIBED, DISCOUNT, SYMBOL , STATE , STATUS ,
+ TVAL , SVAL , RACE , SUBRACE , CLASS ,
+ LEVEL , SKILL , ABILITY, INVENTORY, EQUIPMENT };
+
+/**
+ * Bidirectional map between enumeration values and strings.
+ */
+EnumStringMap<match_type> &match_mapping();
+
+/**
+ * Identification states an object can have: identified or not
+ * identified.
+ */
+enum class identification_state {
+ IDENTIFIED, NOT_IDENTIFIED };
+
+/**
+ * Biredectional map between identification_state values and strings.
+ */
+EnumStringMap<identification_state> &identification_state_mapping();
+
+/**
+ * Condition represents a tree of checks which
+ * can be applied to objects, the player, etc.
+ */
+class Condition : public boost::noncopyable
+{
+public:
+ Condition(match_type match_) : match(match_) {
+ }
+
+ void display(TreePrinter *, Cursor *) const;
+
+ virtual bool is_match(object_type *) const = 0;
+
+ virtual ~Condition() {
+ }
+
+public:
+ json_t *to_json() const;
+
+ virtual void add_child(ConditionFactory const &factory) {
+ // Default is to not support children.
+ };
+
+ virtual void remove_child(Condition *c) {
+ // Nothing to do by default.
+ }
+
+ virtual std::shared_ptr<Condition> first_child() {
+ // No children.
+ return nullptr;
+ }
+
+ virtual std::shared_ptr<Condition> previous_child(Condition *) {
+ // Default no children, so no predecessor.
+ return nullptr;
+ }
+
+ virtual std::shared_ptr<Condition> next_child(Condition *) {
+ // Default no children, so no successor.
+ return nullptr;
+ }
+
+ /**
+ * Parse condition from JSON
+ */
+ static std::shared_ptr<Condition> parse_condition(json_t *);
+
+ /**
+ * Convert an (optional) condition to JSON.
+ */
+ static json_t *optional_to_json(std::shared_ptr<Condition> condition);
+
+protected:
+ virtual void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const = 0;
+ virtual void to_json(json_t *) const = 0;
+
+ // What do we want to match?
+ match_type match;
+};
+
+/**
+ * Check for a specific TVAL
+ */
+class TvalCondition : public Condition
+{
+public:
+ TvalCondition(uint8_t tval)
+ : Condition(match_type::TVAL)
+ , m_tval(tval) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ uint8_t m_tval;
+};
+
+/**
+ * Check for object name
+ */
+class NameCondition : public Condition
+{
+public:
+ NameCondition(std::string name) :
+ Condition(match_type::NAME),
+ m_name(name) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_name;
+};
+
+/**
+ * Check for infix of object name
+ */
+class ContainCondition : public Condition
+{
+public:
+ ContainCondition(std::string contain) :
+ Condition(match_type::CONTAIN),
+ m_contain(contain) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_contain;
+};
+
+/**
+ * Check for specific SVAL
+ */
+class SvalCondition : public Condition
+{
+public:
+ SvalCondition(uint8_t min, uint8_t max)
+ : Condition(match_type::SVAL)
+ , m_min(min)
+ , m_max(max) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ uint8_t m_min;
+ uint8_t m_max;
+};
+
+/**
+ * Groupings of subconditions
+ */
+class GroupingCondition : public Condition
+{
+public:
+ GroupingCondition(match_type match,
+ std::vector< std::shared_ptr<Condition> > conditions = std::vector< std::shared_ptr<Condition> >())
+ : Condition(match)
+ , m_conditions(conditions) {
+ }
+
+ virtual void add_condition(std::shared_ptr<Condition> condition) {
+ if (condition)
+ {
+ m_conditions.push_back(condition);
+ }
+ }
+
+ // Child manipulation
+ virtual void add_child(ConditionFactory const &factory) override;
+ virtual void remove_child(Condition *condition) override;
+ virtual std::shared_ptr<Condition> first_child() override;
+ virtual std::shared_ptr<Condition> previous_child(Condition *) override;
+ virtual std::shared_ptr<Condition> next_child(Condition *current) override;
+
+ // Parse a list of conditions from JSON property
+ static std::vector< std::shared_ptr<Condition> > parse_conditions(json_t *);
+
+protected:
+ void to_json(json_t *) const override;
+
+protected:
+ std::vector< std::shared_ptr<Condition> > m_conditions;
+};
+
+/**
+ * Conditions that are AND'ed together
+ */
+class AndCondition : public GroupingCondition
+{
+public:
+ AndCondition() : GroupingCondition(match_type::AND) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+};
+
+/**
+ * Conditions that are OR'ed together
+ */
+class OrCondition : public GroupingCondition
+{
+public:
+ OrCondition() : GroupingCondition(match_type::OR) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+};
+
+/**
+ * Check for object status
+ */
+class StatusCondition : public Condition
+{
+public:
+ StatusCondition(status_type status)
+ : Condition(match_type::STATUS)
+ , m_status(status) {
+ }
+
+public:
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ status_type m_status;
+};
+
+/**
+ * Check for player race
+ */
+class RaceCondition : public Condition
+{
+public:
+ RaceCondition(std::string race)
+ : Condition(match_type::RACE)
+ , m_race(race) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_race;
+};
+
+/**
+ * Check player subrace
+ */
+class SubraceCondition : public Condition
+{
+public:
+ SubraceCondition(std::string subrace)
+ : Condition(match_type::SUBRACE)
+ , m_subrace(subrace) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_subrace;
+};
+
+/**
+ * Check player class
+ */
+class ClassCondition : public Condition
+{
+public:
+ ClassCondition(std::string klass)
+ : Condition(match_type::CLASS)
+ , m_class(klass) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_class;
+};
+
+/**
+ * Check object inscription
+ */
+class InscriptionCondition : public Condition
+{
+public:
+ InscriptionCondition(std::string inscription)
+ : Condition(match_type::INSCRIBED)
+ , m_inscription(inscription) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ std::string m_inscription;
+};
+
+/**
+ * Check object discount
+ */
+class DiscountCondition : public Condition
+{
+public:
+ DiscountCondition(int min, int max)
+ : Condition(match_type::DISCOUNT)
+ , m_min(min)
+ , m_max(max) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ int m_min;
+ int m_max;
+};
+
+/**
+ * Check player level
+ */
+class LevelCondition : public Condition
+{
+public:
+ LevelCondition(int min, int max)
+ : Condition(match_type::LEVEL)
+ , m_min(min)
+ , m_max(max) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ int m_min;
+ int m_max;
+};
+
+/**
+ * Check player's skill level
+ */
+class SkillCondition : public Condition
+{
+public:
+ SkillCondition(uint16_t skill_idx, uint16_t min, uint16_t max)
+ : Condition(match_type::SKILL)
+ , m_skill_idx(skill_idx)
+ , m_min(min)
+ , m_max(max) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ uint16_t m_skill_idx;
+ uint16_t m_min;
+ uint16_t m_max;
+};
+
+/**
+ * Check identification state
+ */
+class StateCondition : public Condition
+{
+public:
+ StateCondition(identification_state state)
+ : Condition(match_type::STATE)
+ , m_state(state) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ identification_state m_state;
+};
+
+/**
+ * Check object symbol
+ */
+class SymbolCondition : public Condition
+{
+public:
+ SymbolCondition(char symbol)
+ : Condition(match_type::SYMBOL)
+ , m_symbol(symbol) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ char m_symbol;
+};
+
+/**
+ * Check if player has a particular ability
+ */
+class AbilityCondition : public Condition
+{
+public:
+ AbilityCondition(uint16_t ability_idx)
+ : Condition(match_type::ABILITY)
+ , m_ability_idx(ability_idx) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+
+ void to_json(json_t *) const override;
+
+private:
+ uint16_t m_ability_idx;
+};
+
+/**
+ * Condition with a single subcondition
+ */
+class SingleSubconditionCondition : public Condition
+{
+public:
+ SingleSubconditionCondition(match_type match,
+ std::shared_ptr<Condition> subcondition)
+ : Condition(match)
+ , m_subcondition(subcondition) {
+ }
+
+ virtual void add_child(std::function< std::shared_ptr<Condition> () > const &factory) override;
+
+ virtual void remove_child(Condition *c) override;
+
+ virtual std::shared_ptr<Condition> first_child() override;
+
+protected:
+ void to_json(json_t *) const override;
+
+ static std::shared_ptr<Condition> parse_single_subcondition(
+ json_t *condition_json);
+
+protected:
+ std::shared_ptr<Condition> m_subcondition;
+};
+
+/**
+ * Condition which negates another condition
+ */
+class NotCondition : public SingleSubconditionCondition
+{
+public:
+ NotCondition(std::shared_ptr<Condition> subcondition = nullptr)
+ : SingleSubconditionCondition(match_type::NOT, subcondition) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+};
+
+/**
+ * Condition which checks if player inventory contains object(s)
+ * satisfying another condition.
+ */
+class InventoryCondition : public SingleSubconditionCondition
+{
+public:
+ InventoryCondition(std::shared_ptr<Condition> subcondition = nullptr)
+ : SingleSubconditionCondition(match_type::INVENTORY, subcondition) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+};
+
+/**
+ * Condition which checks if player equipment contains object(s)
+ * satisfying another condition.
+ */
+class EquipmentCondition : public SingleSubconditionCondition
+{
+public:
+ EquipmentCondition(std::shared_ptr<Condition> subcondition = nullptr)
+ : SingleSubconditionCondition(match_type::EQUIPMENT, subcondition) {
+ }
+
+ bool is_match(object_type *) const override;
+
+ static std::shared_ptr<Condition> from_json(json_t *);
+
+protected:
+ void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
+};
+
+} // namespace
diff --git a/src/include/tome/squelch/condition_fwd.hpp b/src/include/tome/squelch/condition_fwd.hpp
new file mode 100644
index 00000000..744e7884
--- /dev/null
+++ b/src/include/tome/squelch/condition_fwd.hpp
@@ -0,0 +1,15 @@
+#ifndef H_1122f873_e83d_4af8_b6a8_a9e8db195473
+#define H_1122f873_e83d_4af8_b6a8_a9e8db195473
+
+#include <functional>
+#include <memory>
+
+namespace squelch {
+
+enum class match_type : int;
+class Condition;
+typedef std::function< std::shared_ptr<Condition> () > ConditionFactory;
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/condition_metadata.hpp b/src/include/tome/squelch/condition_metadata.hpp
new file mode 100644
index 00000000..fbb26bc3
--- /dev/null
+++ b/src/include/tome/squelch/condition_metadata.hpp
@@ -0,0 +1,12 @@
+#ifndef H_787198a1_aa3e_45c9_bc9f_fd7f490db78c
+#define H_787198a1_aa3e_45c9_bc9f_fd7f490db78c
+
+#include "tome/squelch/condition_metadata_fwd.hpp"
+
+namespace squelch {
+
+std::shared_ptr<Condition> new_condition_interactive();
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/condition_metadata_fwd.hpp b/src/include/tome/squelch/condition_metadata_fwd.hpp
new file mode 100644
index 00000000..1f57481b
--- /dev/null
+++ b/src/include/tome/squelch/condition_metadata_fwd.hpp
@@ -0,0 +1,14 @@
+#ifndef H_7922f591_bdfd_491d_8561_b11225285fea
+#define H_7922f591_bdfd_491d_8561_b11225285fea
+
+#include "tome/squelch/condition_fwd.hpp"
+
+#include <memory>
+
+namespace squelch {
+
+std::shared_ptr<Condition> new_condition_interactive();
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/cursor.hpp b/src/include/tome/squelch/cursor.hpp
new file mode 100644
index 00000000..8dbfc6bf
--- /dev/null
+++ b/src/include/tome/squelch/cursor.hpp
@@ -0,0 +1,50 @@
+#ifndef H_8a10111d_64a1_4af9_a85b_24ec8922d3fa
+#define H_8a10111d_64a1_4af9_a85b_24ec8922d3fa
+
+#include <boost/noncopyable.hpp>
+#include <deque>
+
+#include "tome/squelch/condition_fwd.hpp"
+
+namespace squelch {
+
+/**
+ * Cursor which maintains selected condition(s)
+ */
+class Cursor : public boost::noncopyable
+{
+public:
+ bool is_selected(Condition const *condition) const;
+
+ void push(Condition *condition) {
+ m_conditions.push_back(condition);
+ }
+
+ Condition *pop();
+
+ Condition *current();
+
+ void clear() {
+ m_conditions.clear();
+ }
+
+ bool empty() const {
+ return m_conditions.empty();
+ }
+
+ std::size_t size() const {
+ return m_conditions.size();
+ }
+
+ void move_left();
+ void move_right();
+ void move_up();
+ void move_down();
+
+private:
+ std::deque<Condition *> m_conditions;
+};
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/cursor_fwd.hpp b/src/include/tome/squelch/cursor_fwd.hpp
new file mode 100644
index 00000000..f07e9aa9
--- /dev/null
+++ b/src/include/tome/squelch/cursor_fwd.hpp
@@ -0,0 +1,10 @@
+#ifndef H_a4caa98a_1044_4192_b1af_27c2e8790cae
+#define H_a4caa98a_1044_4192_b1af_27c2e8790cae
+
+namespace squelch {
+
+class Cursor;
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/object_status.hpp b/src/include/tome/squelch/object_status.hpp
new file mode 100644
index 00000000..c52a35ea
--- /dev/null
+++ b/src/include/tome/squelch/object_status.hpp
@@ -0,0 +1,28 @@
+#ifndef H_e3f9ebbe_ff9a_4687_a847_6101f094b483
+#define H_e3f9ebbe_ff9a_4687_a847_6101f094b483
+
+#include "tome/enum_string_map.hpp"
+
+namespace squelch {
+
+/**
+ * Types of statuses for objects, e.g. "special" for artifacts and
+ * "average" for plain objects with no plusses.
+ */
+enum class status_type {
+ BAD , VERY_BAD, AVERAGE, GOOD, VERY_GOOD,
+ SPECIAL, TERRIBLE, NONE, CHEST_EMPTY, CHEST_DISARMED };
+
+/**
+ * Bidirectional map between status_type values and strings.
+ */
+EnumStringMap<status_type> &status_mapping();
+
+/**
+ * Find the status of an object
+ */
+status_type object_status(object_type *o_ptr);
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/object_status_fwd.hpp b/src/include/tome/squelch/object_status_fwd.hpp
new file mode 100644
index 00000000..361ea2fe
--- /dev/null
+++ b/src/include/tome/squelch/object_status_fwd.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "../object_type_fwd.hpp"
+#include "tome/enum_string_map.hpp"
+
+namespace squelch {
+
+enum class status_type;
+EnumStringMap<status_type> &status_mapping();
+status_type object_status(object_type *o_ptr);
+
+} // namespace
diff --git a/src/include/tome/squelch/rule.hpp b/src/include/tome/squelch/rule.hpp
new file mode 100644
index 00000000..63f1b6c0
--- /dev/null
+++ b/src/include/tome/squelch/rule.hpp
@@ -0,0 +1,162 @@
+#pragma once
+
+#include <jansson.h>
+#include <memory>
+
+#include "tome/squelch/condition_fwd.hpp"
+#include "tome/squelch/cursor_fwd.hpp"
+#include "tome/squelch/tree_printer_fwd.hpp"
+#include "tome/enum_string_map.hpp"
+#include "../object_type_fwd.hpp"
+
+namespace squelch {
+
+/**
+ * Types of automatizer actions: destroy, pick up, and inscribe.
+ */
+enum class action_type { AUTO_DESTROY, AUTO_PICKUP, AUTO_INSCRIBE };
+
+/**
+ * Bidirectional map between rule actions and strings.
+ */
+EnumStringMap<action_type> &action_mapping();
+
+/**
+ * Rules are the representation of "when condition X is true, do Y".
+ */
+class Rule : public boost::noncopyable
+{
+public:
+ Rule(std::string name,
+ action_type action,
+ int module_idx,
+ std::shared_ptr<Condition> condition)
+ : m_name(name)
+ , m_action(action)
+ , m_module_idx(module_idx)
+ , m_condition(condition) {
+ }
+
+ /**
+ * Set the name of the rule
+ */
+ void set_name(const char *new_name);
+
+ /**
+ * Get the name of the rule
+ */
+ const char *get_name() const;
+
+ /**
+ * Get condition
+ */
+ std::shared_ptr<Condition> get_condition() const;
+
+ /**
+ * Add new condition using a factory to instantiate the
+ * condition only if the rule permits adding a condition.
+ */
+ void add_new_condition(Cursor *cursor,
+ ConditionFactory const &factory);
+
+ /**
+ * Remove currently selected condition
+ */
+ void delete_selected_condition(Cursor *cursor);
+
+ /**
+ * Write out tree representing rule
+ */
+ void write_tree(TreePrinter *p, Cursor *cursor) const;
+
+ /**
+ * Apply rule to object
+ */
+ bool apply_rule(object_type *o_ptr, int item_idx) const;
+
+ /**
+ * Convert rule to JSON
+ */
+ virtual json_t *to_json() const;
+
+ /**
+ * Parse rule from JSON
+ */
+ static std::shared_ptr<Rule> parse_rule(json_t *);
+
+protected:
+ virtual bool do_apply_rule(object_type *, int) const = 0;
+ virtual void do_write_tree(TreePrinter *p) const = 0;
+
+protected:
+ // Rule name
+ std::string m_name;
+ // What does the rule do?
+ action_type m_action;
+ // Which module does this rule apply to?
+ int m_module_idx;
+ // Condition to check
+ std::shared_ptr<Condition> m_condition;
+};
+
+/**
+ * Rule for destroying matching objects
+ */
+class DestroyRule : public Rule
+{
+public:
+ DestroyRule(std::string name,
+ int module_idx,
+ std::shared_ptr<Condition> condition)
+ : Rule(name, action_type::AUTO_DESTROY, module_idx, condition) {
+ }
+
+protected:
+ virtual bool do_apply_rule(object_type *o_ptr, int item_idx) const override;
+ virtual void do_write_tree(TreePrinter *p) const override;
+};
+
+/**
+ * Rule for picking up matching objects
+ */
+class PickUpRule : public Rule
+{
+public:
+
+ PickUpRule(std::string name,
+ int module_idx,
+ std::shared_ptr<Condition> condition)
+ : Rule(name, action_type::AUTO_PICKUP, module_idx, condition) {
+ }
+
+protected:
+ virtual void do_write_tree(TreePrinter *p) const override;
+ virtual bool do_apply_rule(object_type *o_ptr, int item_idx) const override;
+};
+
+/**
+ * Rule for inscribing matching objects
+ */
+class InscribeRule : public Rule
+{
+public:
+ InscribeRule(std::string name,
+ int module_idx,
+ std::shared_ptr<Condition> condition,
+ std::string inscription)
+ : Rule(name, action_type::AUTO_INSCRIBE, module_idx, condition)
+ , m_inscription(inscription) {
+ }
+
+ json_t *to_json() const override;
+
+protected:
+ virtual void do_write_tree(TreePrinter *p) const override;
+ virtual bool do_apply_rule(object_type *o_ptr, int) const override;
+
+private:
+ // Inscription to use for inscription rules.
+ std::string m_inscription;
+};
+
+} // namespace
diff --git a/src/include/tome/squelch/rule_fwd.hpp b/src/include/tome/squelch/rule_fwd.hpp
new file mode 100644
index 00000000..091e77ef
--- /dev/null
+++ b/src/include/tome/squelch/rule_fwd.hpp
@@ -0,0 +1,16 @@
+#ifndef H_4a8d2cfb_182c_4138_983d_606a9ac70784
+#define H_4a8d2cfb_182c_4138_983d_606a9ac70784
+
+#include "tome/enum_string_map.hpp"
+
+namespace squelch {
+
+enum class action_type;
+
+EnumStringMap<action_type> &action_mapping();
+
+class Rule;
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/tree_printer.hpp b/src/include/tome/squelch/tree_printer.hpp
new file mode 100644
index 00000000..e8ee1e56
--- /dev/null
+++ b/src/include/tome/squelch/tree_printer.hpp
@@ -0,0 +1,49 @@
+#ifndef H_3d6cc652_c674_4a84_911d_e8ec35cc992a
+#define H_3d6cc652_c674_4a84_911d_e8ec35cc992a
+
+#include <boost/noncopyable.hpp>
+#include <cstdint>
+
+namespace squelch {
+
+/**
+ * Printing trees.
+ */
+class TreePrinter : boost::noncopyable
+{
+public:
+ TreePrinter();
+
+ void indent();
+
+ void dedent();
+
+ void reset();
+
+ void reset_scroll();
+
+ void scroll_up();
+
+ void scroll_down();
+
+ void scroll_left();
+
+ void scroll_right();
+
+ void write(uint8_t color, const char *line);
+
+private:
+ int m_indent;
+ int m_write_out_y;
+ int m_write_out_x;
+ int m_write_out_h;
+ int m_write_out_w;
+ int m_write_y;
+ int m_write_x;
+ int m_write_off_x;
+ int m_write_off_y;
+};
+
+} // namespace
+
+#endif
diff --git a/src/include/tome/squelch/tree_printer_fwd.hpp b/src/include/tome/squelch/tree_printer_fwd.hpp
new file mode 100644
index 00000000..d7d75453
--- /dev/null
+++ b/src/include/tome/squelch/tree_printer_fwd.hpp
@@ -0,0 +1,10 @@
+#ifndef H_4ce68eb3_c475_4fc4_8a70_0590c16dc684
+#define H_4ce68eb3_c475_4fc4_8a70_0590c16dc684
+
+namespace squelch {
+
+class TreePrinter;
+
+} // namespace
+
+#endif
diff --git a/src/init1.c b/src/init1.cc
index cc589bde..1f2023f0 100644
--- a/src/init1.c
+++ b/src/init1.cc
@@ -1,8 +1,56 @@
-/* File: init1.c */
-
-/* Purpose: Initialization (part 1) -BEN- */
-
-#include "angband.h"
+#include "init1.hpp"
+
+#include "ability_type.hpp"
+#include "alchemist_recipe.hpp"
+#include "artifact_type.hpp"
+#include "artifact_select_flag.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hist_type.hpp"
+#include "init2.hpp"
+#include "meta_class_type.hpp"
+#include "monster2.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "owner_type.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "randart_gen_type.hpp"
+#include "randart_part_type.hpp"
+#include "set_type.hpp"
+#include "skill_type.hpp"
+#include "skills.hpp"
+#include "spells5.hpp"
+#include "store_action_type.hpp"
+#include "store_info_type.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "trap_type.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "vault_type.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::iequals;
+using boost::algorithm::ends_with;
/*
@@ -363,7 +411,7 @@ static cptr r_info_flags7[] =
"AI_PLAYER",
"NO_THEFT",
"SPIRIT",
- "IM_MELEE",
+ "XXX7X20",
"XXX7X21",
"XXX7X22",
"XXX7X23",
@@ -637,9 +685,9 @@ cptr k_info_flags4[] =
"CHEAPNESS",
"FOUNTAIN",
"ANTIMAGIC_50",
- "ANTIMAGIC_30",
- "ANTIMAGIC_20",
- "ANTIMAGIC_10",
+ "XXX5",
+ "XXX5",
+ "XXX5",
"EASY_USE",
"IM_NETHER",
"RECHARGED",
@@ -1394,6 +1442,12 @@ static const char *activation_names[] =
"XXX198",
"XXX199",
"MUSIC", /* 200*/
+ "ETERNAL_FLAME", /* 201 */
+ "MAGGOT", /* 202 */
+ "LEBOHAUM", /* 203 */
+ "DURANDIL", /* 204 */
+ "RADAGAST", /* 205, Theme */
+ "VALAROMA", /* 206, Theme */
""
};
@@ -1488,76 +1542,47 @@ static byte monster_ego_modify(char c)
}
}
-/*
- * Implements fp stacks, for included files
+/**
+ * Version of strdup() which just aborts if an allocation
+ * error occurs.
*/
-static FILE *fp_stack[10];
-static int fp_stack_idx = 0;
-
-/*
- * Must be caleld before the main loop
- */
-static void fp_stack_init(FILE *fp)
-{
- fp_stack[0] = fp;
- fp_stack_idx = 0;
-}
-
-static void fp_stack_push(cptr name)
+static char *my_strdup(const char *s)
{
- if (fp_stack_idx < 9)
+ char *p = strdup(s);
+ if (!p)
{
- char buf[1024];
- FILE *fp;
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, name);
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit(format("Cannot open '%s' file.", name));
-
- printf("ibncluding %s\n", name);
-
- fp_stack[++fp_stack_idx] = fp;
+ abort();
}
+ return p;
}
-static bool_ fp_stack_pop()
-{
- if (fp_stack_idx > 0)
- {
- FILE *fp = fp_stack[fp_stack_idx--];
- my_fclose(fp);
- return TRUE;
- }
- else
- return FALSE;
-}
-/*
- * Must be used instead of my_fgets for teh main loop
+/**
+ * Append one string to the end of another, reallocating if
+ * necessary.
*/
-static int my_fgets_dostack(char *buf, int len)
+static void strappend(char **s, const char *t)
{
- // End of a file
- if (0 != my_fgets(fp_stack[fp_stack_idx], buf, len))
+ // Do we need to initialize the destination string?
+ if (*s == nullptr)
{
- // If any left, use them
- if (fp_stack_pop())
- return my_fgets_dostack(buf, len);
- // If not, this is the end
- else
- return 1;
+ // Costs an extra allocation which could be avoided
+ // but this leads to simpler code.
+ *s = my_strdup("");
}
- else
+ // We should really be preserving the original pointer and
+ // do something else in case of failure to realloc(), but
+ // instead we just do the lazy thing and call abort() if
+ // reallocation fails. In practice it won't.
+ *s = static_cast<char *>(realloc(*s, strlen(*s) + strlen(t) + 1));
+ if (*s == nullptr)
{
- return 0;
+ abort(); // Cannot handle failure to reallocate
}
-}
+ /* Append 't' to the destination string */
+ strcat(*s, t);
+}
/*** Initialize from ascii template files ***/
@@ -1571,7 +1596,7 @@ static errr grab_one_class_flag(u32b *choice, cptr what)
cptr s;
/* Scan classes flags */
- for (i = 0; i < max_c_idx && (s = class_info[i].title + c_name); i++)
+ for (i = 0; i < max_c_idx && (s = class_info[i].title); i++)
{
if (streq(what, s))
{
@@ -1592,7 +1617,7 @@ static errr grab_one_race_allow_flag(u32b *choice, cptr what)
cptr s;
/* Scan classes flags */
- for (i = 0; i < max_rp_idx && (s = race_info[i].title + rp_name); i++)
+ for (i = 0; i < max_rp_idx && (s = race_info[i].title); i++)
{
if (streq(what, s))
{
@@ -1666,14 +1691,18 @@ static errr grab_one_player_race_flag(u32b *f1, u32b *f2, cptr what)
}
/* Get an activation number (good for artifacts, recipes, egos, and object kinds) */
-int get_activation(char *activation)
+static int get_activation(char *activation)
{
int i;
for ( i = 0 ; activation_names[i][0] ; i++)
+ {
if (!strncmp(activation_names[i], activation, 19))
{
return i;
}
+ }
+
+ msg_format("Unknown activation '%s'.", activation);
return -1;
}
@@ -1764,7 +1793,7 @@ static errr grab_one_race_kind_flag(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b
/*
* Initialize the "player" arrays, by parsing an ascii "template" file
*/
-errr init_player_info_txt(FILE *fp, char *buf)
+errr init_player_info_txt(FILE *fp)
{
int i = 0, z;
int powers = 0;
@@ -1772,7 +1801,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
int tit_idx = 0;
int spec_idx = 0;
int cur_ab = -1;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -1792,15 +1821,6 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- rp_head->name_size = 0;
- rp_head->text_size = 0;
- rmp_head->name_size = 0;
- rmp_head->text_size = 0;
- c_head->name_size = 0;
- c_head->text_size = 0;
-
/* Init general skills */
for (z = 0; z < MAX_SKILLS; z++)
{
@@ -1811,8 +1831,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
}
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -1842,13 +1861,6 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Reinit error_idx */
if (buf[0] == 'I')
{
@@ -1871,13 +1883,9 @@ errr init_player_info_txt(FILE *fp, char *buf)
bg[idx].next = atoi(zz[3]);
bg[idx].bonus = atoi(zz[4]);
- bg[idx].info = ++rp_head->text_size;
-
- /* Append chars to the name */
- strcpy(rp_text + rp_head->text_size, zz[5]);
-
- /* Advance the index */
- rp_head->text_size += strlen(zz[5]);
+ /* Copy text */
+ assert(!bg[idx].info);
+ bg[idx].info = my_strdup(zz[5]);
/* Next... */
continue;
@@ -1925,7 +1933,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= rp_head->info_num) return (2);
+ if (i >= max_rp_idx) return (2);
/* Save the index */
error_idx = i;
@@ -1933,18 +1941,11 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
rp_ptr = &race_info[i];
- /* Hack -- Verify space */
- if (rp_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!rp_ptr->title) rp_ptr->title = ++rp_head->name_size;
-
- /* Append chars to the name */
- strcpy(rp_name + rp_head->name_size, s);
-
- /* Advance the index */
- rp_head->name_size += strlen(s);
+ /* Copy title */
+ assert(!rp_ptr->title);
+ rp_ptr->title = my_strdup(s);
+ /* Initialize */
rp_ptr->powers[0] = rp_ptr->powers[1] = rp_ptr->powers[2] = rp_ptr->powers[3] = -1;
powers = 0;
lev = 1;
@@ -1962,27 +1963,13 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 4;
- /* Hack -- Verify space */
- if (rp_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
if (!rp_ptr->desc)
{
- rp_ptr->desc = ++rp_head->text_size;
-
- /* Append chars to the name */
- strcpy(rp_text + rp_head->text_size, s);
-
- /* Advance the index */
- rp_head->text_size += strlen(s);
+ rp_ptr->desc = my_strdup(s);
}
else
{
- /* Append chars to the name */
- strcpy(rp_text + rp_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- rp_head->text_size += strlen(s) + 1;
+ strappend(&rp_ptr->desc, format("\n%s", s));
}
/* Next... */
@@ -2049,7 +2036,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -2299,7 +2286,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= rmp_head->info_num) return (2);
+ if (i >= max_rmp_idx) return (2);
/* Save the index */
error_idx = i;
@@ -2307,18 +2294,11 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
rmp_ptr = &race_mod_info[i];
- /* Hack -- Verify space */
- if (rmp_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!rmp_ptr->title) rmp_ptr->title = ++rmp_head->name_size;
-
- /* Append chars to the name */
- strcpy(rmp_name + rmp_head->name_size, s);
-
- /* Advance the index */
- rmp_head->name_size += strlen(s);
+ /* Copy title */
+ assert(!rmp_ptr->title);
+ rmp_ptr->title = my_strdup(s);
+ /* Initialize */
rmp_ptr->powers[0] = rmp_ptr->powers[1] = rmp_ptr->powers[2] = rmp_ptr->powers[3] = -1;
powers = 0;
lev = 1;
@@ -2336,30 +2316,25 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 6;
- if (buf[4] == 'A') rmp_ptr->place = TRUE;
- else rmp_ptr->place = FALSE;
-
- /* Hack -- Verify space */
- if (rmp_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
+ /* Place */
+ if (buf[4] == 'A')
+ {
+ rmp_ptr->place = TRUE;
+ }
+ else
+ {
+ rmp_ptr->place = FALSE;
+ }
- /* Advance and Save the text index */
+ /* Description */
if (!rmp_ptr->desc)
{
- rmp_ptr->desc = ++rmp_head->text_size;
-
- /* Append chars to the name */
- strcpy(rmp_text + rmp_head->text_size, s);
-
- /* Advance the index */
- rmp_head->text_size += strlen(s);
+ rmp_ptr->desc = my_strdup(s);
}
else
{
/* Append chars to the name */
- strcpy(rmp_text + rmp_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- rmp_head->text_size += strlen(s) + 1;
+ strappend(&rmp_ptr->desc, format("\n%s", s));
}
/* Next... */
@@ -2427,7 +2402,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -2713,7 +2688,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= c_head->info_num) return (2);
+ if (i >= max_c_idx) return (2);
/* Save the index */
error_idx = i;
@@ -2721,18 +2696,11 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
c_ptr = &class_info[i];
- /* Hack -- Verify space */
- if (c_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!c_ptr->title) c_ptr->title = ++c_head->name_size;
-
- /* Append chars to the name */
- strcpy(c_name + c_head->name_size, s);
-
- /* Advance the index */
- c_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!c_ptr->title);
+ c_ptr->title = my_strdup(s);
+ /* Initialize */
c_ptr->powers[0] = c_ptr->powers[1] = c_ptr->powers[2] = c_ptr->powers[3] = -1;
powers = 0;
lev = 1;
@@ -2755,43 +2723,31 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 6;
- /* Hack -- Verify space */
- if (c_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
switch (buf[4])
{
- case '0':
- /* Advance and Save the text index */
+ case '0': /* Class description */
if (!c_ptr->desc)
{
- c_ptr->desc = ++c_head->text_size;
- /* Append chars to the name */
- strcpy(c_text + c_head->text_size, s);
-
- /* Advance the index */
- c_head->text_size += strlen(s);
+ c_ptr->desc = my_strdup(s);
}
else
{
- /* Append chars to the name */
- strcpy(c_text + c_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- c_head->text_size += strlen(s) + 1;
+ strappend(&c_ptr->desc, format("\n%s", s));
}
break;
- case '1':
- /* Advance and Save the text index */
- c_ptr->titles[tit_idx++] = ++c_head->text_size;
- /* Append chars to the name */
- strcpy(c_text + c_head->text_size, s);
+ case '1': /* Class title */
+ /* Copy */
+ assert(!c_ptr->titles[tit_idx]);
+ c_ptr->titles[tit_idx] = my_strdup(s);
+
+ /* Go to next title in array */
+ tit_idx++;
- /* Advance the index */
- c_head->text_size += strlen(s);
break;
- default:
+
+ default: /* Unknown */
return (6);
break;
}
@@ -2950,7 +2906,7 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -3132,18 +3088,11 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
s_ptr = &c_ptr->spec[spec_idx];
- /* Hack -- Verify space */
- if (c_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!s_ptr->title) s_ptr->title = ++c_head->name_size;
-
- /* Append chars to the name */
- strcpy(c_name + c_head->name_size, s);
-
- /* Advance the index */
- c_head->name_size += strlen(s);
+ /* Copy title */
+ assert(!s_ptr->title);
+ s_ptr->title = my_strdup(s);
+ /* Initialize */
s_ptr->obj_num = 0;
cur_ab = 0;
for (z = 0; z < 10; z++)
@@ -3159,27 +3108,13 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 6;
- /* Hack -- Verify space */
- if (c_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
if (!s_ptr->desc)
{
- s_ptr->desc = ++c_head->text_size;
-
- /* Append chars to the name */
- strcpy(c_text + c_head->text_size, s);
-
- /* Advance the index */
- c_head->text_size += strlen(s);
+ s_ptr->desc = my_strdup(s);
}
else
{
- /* Append chars to the name */
- strcpy(c_text + c_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- c_head->text_size += strlen(s) + 1;
+ strappend(&s_ptr->desc, format("\n%s", s));
}
/* Next... */
@@ -3373,7 +3308,10 @@ errr init_player_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < max_c_idx; i++)
{
- if (!stricmp(s, class_info[i].title + c_name)) break;
+ if (class_info[i].title && iequals(s, class_info[i].title))
+ {
+ break;
+ }
}
if (i == max_c_idx) return (6);
@@ -3388,13 +3326,6 @@ errr init_player_info_txt(FILE *fp, char *buf)
return (6);
}
- /* Complete the "name" and "text" sizes */
- ++rp_head->name_size;
- ++rp_head->text_size;
- ++rmp_head->name_size;
- ++rmp_head->text_size;
- ++c_head->name_size;
- ++c_head->text_size;
/* No version yet */
if (!okay) return (2);
@@ -3406,9 +3337,10 @@ errr init_player_info_txt(FILE *fp, char *buf)
/*
* Initialize the "v_info" array, by parsing an ascii "template" file
*/
-errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
+errr init_v_info_txt(FILE *fp)
{
int i;
+ char buf[1024];
char *s;
/* Not ready yet */
@@ -3417,22 +3349,14 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
/* Current entry */
vault_type *v_ptr = NULL;
- if (start)
- {
- /* Just before the first record */
- error_idx = -1;
-
- /* Just before the first line */
- error_line = -1;
+ /* Just before the first record */
+ error_idx = -1;
- /* Prepare the "fake" stuff */
- v_head->name_size = 0;
- v_head->text_size = 0;
- }
+ /* Just before the first line */
+ error_line = -1;
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -3463,13 +3387,6 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -3492,7 +3409,7 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
if (i <= error_idx) return (4);
/* Verify information */
- if (i >= v_head->info_num) return (2);
+ if (i >= max_v_idx) return (2);
/* Save the index */
error_idx = i;
@@ -3500,17 +3417,9 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
/* Point at the "info" */
v_ptr = &v_info[i];
- /* Hack -- Verify space */
- if (v_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!v_ptr->name) v_ptr->name = ++v_head->name_size;
-
- /* Append chars to the name */
- strcpy(v_name + v_head->name_size, s);
-
- /* Advance the index */
- v_head->name_size += strlen(s);
+ /* Initialize data -- we ignore the name, it's not
+ * used for anything */
+ v_ptr->data = my_strdup("");
/* Next... */
continue;
@@ -3525,17 +3434,8 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (v_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!v_ptr->text) v_ptr->text = ++v_head->text_size;
-
- /* Append chars to the name */
- strcpy(v_text + v_head->text_size, s);
-
- /* Advance the index */
- v_head->text_size += strlen(s);
+ /* Append data */
+ strappend(&v_ptr->data, s);
/* Next... */
continue;
@@ -3602,14 +3502,6 @@ errr init_v_info_txt(FILE *fp, char *buf, bool_ start)
}
- /* Complete the "name" and "text" sizes */
- if (!start)
- {
- ++v_head->name_size;
- ++v_head->text_size;
- }
-
-
/* No version yet */
if (!okay) return (2);
@@ -3647,47 +3539,26 @@ static errr grab_one_feature_flag(feature_type *f_ptr, cptr what)
/*
* Initialize the "f_info" array, by parsing an ascii "template" file
*/
-errr init_f_info_txt(FILE *fp, char *buf)
+errr init_f_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
bool_ okay = FALSE;
- u32b default_desc = 0, default_tunnel = 0, default_block = 0;
/* Current entry */
feature_type *f_ptr = NULL;
-
/* Just before the first record */
error_idx = -1;
/* Just before the first line */
error_line = -1;
-
- /* Prepare the "fake" stuff */
- f_head->name_size = 0;
- f_head->text_size = 0;
-
- /* Add some fake descs */
- default_desc = ++f_head->text_size;
- strcpy(f_text + f_head->text_size, "a wall blocking your way");
- f_head->text_size += strlen("a wall blocking your way");
-
- default_tunnel = ++f_head->text_size;
- strcpy(f_text + f_head->text_size, "You cannot tunnel through that.");
- f_head->text_size += strlen("You cannot tunnel through that.");
-
- default_block = ++f_head->text_size;
- strcpy(f_text + f_head->text_size, "a wall blocking your way");
- f_head->text_size += strlen("a wall blocking your way");
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -3717,13 +3588,6 @@ errr init_f_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -3746,7 +3610,7 @@ errr init_f_info_txt(FILE *fp, char *buf)
if (i <= error_idx) return (4);
/* Verify information */
- if (i >= f_head->info_num) return (2);
+ if (i >= max_f_idx) return (2);
/* Save the index */
error_idx = i;
@@ -3754,24 +3618,15 @@ errr init_f_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
f_ptr = &f_info[i];
- /* Hack -- Verify space */
- if (f_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
+ /* Copy name */
+ assert(!f_ptr->name);
+ f_ptr->name = my_strdup(s);
- /* Advance and Save the name index */
- if (!f_ptr->name) f_ptr->name = ++f_head->name_size;
-
- /* Append chars to the name */
- strcpy(f_name + f_head->name_size, s);
-
- /* Advance the index */
- f_head->name_size += strlen(s);
-
- /* Default "mimic" */
+ /* Initialize */
f_ptr->mimic = i;
- f_ptr->text = default_desc;
- f_ptr->block = default_desc;
- f_ptr->tunnel = default_tunnel;
- f_ptr->block = default_block;
+ f_ptr->text = DEFAULT_FEAT_TEXT;
+ f_ptr->tunnel = DEFAULT_FEAT_TUNNEL;
+ f_ptr->block = DEFAULT_FEAT_BLOCK;
/* Next... */
continue;
@@ -3787,34 +3642,24 @@ errr init_f_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 4;
- /* Hack -- Verify space */
- if (f_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
switch (buf[2])
{
case '0':
- /* Advance and Save the text index */
- f_ptr->text = ++f_head->text_size;
+ assert(f_ptr->text == DEFAULT_FEAT_TEXT);
+ f_ptr->text = my_strdup(s);
break;
case '1':
- /* Advance and Save the text index */
- f_ptr->tunnel = ++f_head->text_size;
+ assert(f_ptr->tunnel == DEFAULT_FEAT_TUNNEL);
+ f_ptr->tunnel = my_strdup(s);
break;
case '2':
- /* Advance and Save the text index */
- f_ptr->block = ++f_head->text_size;
+ assert(f_ptr->block == DEFAULT_FEAT_BLOCK);
+ f_ptr->block = my_strdup(s);
break;
default:
return (6);
- break;
}
- /* Append chars to the name */
- strcpy(f_text + f_head->text_size, s);
-
- /* Advance the index */
- f_head->text_size += strlen(s);
-
/* Next... */
continue;
}
@@ -3971,16 +3816,9 @@ errr init_f_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++f_head->name_size;
- ++f_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
-
/* Success */
return (0);
}
@@ -4094,10 +3932,10 @@ static errr grab_one_kind_flag(object_kind *k_ptr, cptr what, bool_ obvious)
/*
* Initialize the "k_info" array, by parsing an ascii "template" file
*/
-errr init_k_info_txt(FILE *fp, char *buf)
+errr init_k_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -4114,13 +3952,8 @@ errr init_k_info_txt(FILE *fp, char *buf)
error_line = -1;
- /* Prepare the "fake" stuff */
- k_head->name_size = 0;
- k_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -4150,13 +3983,6 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -4179,7 +4005,7 @@ errr init_k_info_txt(FILE *fp, char *buf)
if (i <= error_idx) return (4);
/* Verify information */
- if (i >= k_head->info_num) return (2);
+ if (i >= max_k_idx) return (2);
/* Save the index */
error_idx = i;
@@ -4187,17 +4013,12 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
k_ptr = &k_info[i];
- /* Hack -- Verify space */
- if (k_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
/* Advance and Save the name index */
- if (!k_ptr->name) k_ptr->name = ++k_head->name_size;
+ assert(!k_ptr->name);
+ k_ptr->name = my_strdup(s);
- /* Append chars to the name */
- strcpy(k_name + k_head->name_size, s);
-
- /* Advance the index */
- k_head->name_size += strlen(s);
+ /* Ensure empty description */
+ k_ptr->text = my_strdup("");
/* Needed hack */
k_ptr->esp = 0;
@@ -4216,27 +4037,8 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (k_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!k_ptr->text) k_ptr->text = ++k_head->text_size;
-
- /* Append a space if needed */
- else if (k_text[k_head->text_size - 1] != ' ')
- {
- /* Append chars to the name */
- strcpy(k_text + k_head->text_size, " ");
-
- /* Advance the index */
- k_head->text_size += 1;
- }
-
- /* Append chars to the name */
- strcpy(k_text + k_head->text_size, s);
-
- /* Advance the index */
- k_head->text_size += strlen(s);
+ /* Append description */
+ strappend(&k_ptr->text, s);
/* Next... */
continue;
@@ -4354,7 +4156,7 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -4368,17 +4170,10 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* Process 'a' for Activation */
if ( buf[0] == 'a')
{
- if (prefix(buf + 2, "HARDCORE="))
- {
- k_ptr->activate = get_activation(buf + 11);
- if (k_ptr->activate == -1)
- return 1;
- }
- else if (prefix(buf + 2, "SPELL="))
+ k_ptr->activate = get_activation(buf + 2);
+ if (k_ptr->activate == -1)
{
- k_ptr->activate = -find_spell(buf + 8);
- if (k_ptr->activate == -( -1))
- return 1;
+ return 1;
}
/* Next... */
@@ -4393,6 +4188,11 @@ errr init_k_info_txt(FILE *fp, char *buf)
/* XXX XXX XXX Simply read each number following a colon */
for (i = 0, s = buf + 1; s && (s[0] == ':') && s[1]; ++i)
{
+ if (i >= ALLOCATION_MAX) {
+ msg_print("Too many allocation entries.");
+ return 1;
+ }
+
/* Default chance */
k_ptr->chance[i] = 1;
@@ -4409,7 +4209,9 @@ errr init_k_info_txt(FILE *fp, char *buf)
if (t && (!s || t < s))
{
int chance = atoi(t + 1);
- if (chance > 0) k_ptr->chance[i] = chance;
+ if (chance > 0) {
+ k_ptr->chance[i] = chance;
+ }
}
}
@@ -4497,11 +4299,6 @@ errr init_k_info_txt(FILE *fp, char *buf)
}
- /* Complete the "name" and "text" sizes */
- ++k_head->name_size;
- ++k_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
@@ -4592,11 +4389,12 @@ int init_al_info_essence(char *essence)
/*
* Initialize the "al_info" array, by parsing an ascii "template" file
*/
-errr init_al_info_txt(FILE *fp, char *buf)
+errr init_al_info_txt(FILE *fp)
{
int al_idx = 0, a_idx = 0;
char *s, *t;
struct artifact_select_flag *a_ptr = NULL;
+ char buf[1024];
/* Not ready yet */
bool_ okay = FALSE;
@@ -4607,13 +4405,8 @@ errr init_al_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
- /* Fun! */
- al_head->name_size = 0;
- *al_name = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -4642,13 +4435,6 @@ errr init_al_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'I' for "Info" (one line only) */
if (buf[0] == 'I')
{
@@ -4813,71 +4599,47 @@ errr init_al_info_txt(FILE *fp, char *buf)
if (buf[0] == 'p')
{
/* Reject if doesn't depend on pval */
-
if (!a_ptr->pval)
return (1);
/* Acquire the description */
s = buf + 2;
- /* Hack -- Verify space */
- if (al_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- a_ptr->item_descp = ++al_head->name_size;
-
- /* Append chars to the name */
- strcpy(al_name + al_head->name_size, s);
-
- /* Advance the index */
- al_head->name_size += strlen(s);
+ /* Copy plural description */
+ assert(!a_ptr->item_descp);
+ a_ptr->item_descp = my_strdup(s);
/* Next... */
continue;
}
- /* Process 'D' for "Description" */
+ /* Process 'D' for "Description" (one line only) */
if (buf[0] == 'D')
{
/* Acquire the description */
s = buf + 2;
- /* Hack -- Verify space */
- if (al_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- a_ptr->desc = ++al_head->name_size;
-
- /* Append chars to the name */
- strcpy(al_name + al_head->name_size, s);
-
- /* Advance the index */
- al_head->name_size += strlen(s);
+ /* Copy description */
+ assert(!a_ptr->desc);
+ a_ptr->desc = my_strdup(s);
/* Next... */
continue;
}
- /* Process 'd' for "Item Description" */
+ /* Process 'd' for "Item Description" (one line only) */
if (buf[0] == 'd')
{
/* Acquire the name */
s = buf + 2;
- /* Hack -- Verify space */
- if (al_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
+ /* Reject if we already have a description */
if (a_ptr->item_desc)
return (7);
- /* Advance and Save the name index */
- a_ptr->item_desc = ++al_head->name_size;
-
- /* Append chars to the name */
- strcpy(al_name + al_head->name_size, s);
-
- /* Advance the index */
- al_head->name_size += strlen(s);
+ /* Copy description */
+ assert(!a_ptr->item_desc);
+ a_ptr->item_desc = my_strdup(s);
/* Next... */
continue;
@@ -4890,9 +4652,6 @@ errr init_al_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Hack - set the al_head->text_size to byte size of array */
- al_head->text_size = (a_idx + 1) * sizeof(artifact_select_flag);
-
/* Success */
return (0);
}
@@ -5008,10 +4767,10 @@ static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what, bool_ obviou
/*
* Initialize the "a_info" array, by parsing an ascii "template" file
*/
-errr init_a_info_txt(FILE *fp, char *buf)
+errr init_a_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -5029,8 +4788,7 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -5060,13 +4818,6 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -5089,7 +4840,7 @@ errr init_a_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= a_head->info_num) return (2);
+ if (i >= max_a_idx) return (2);
/* Save the index */
error_idx = i;
@@ -5097,17 +4848,12 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
a_ptr = &a_info[i];
- /* Hack -- Verify space */
- if (a_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!a_ptr->name) a_ptr->name = ++a_head->name_size;
-
- /* Append chars to the name */
- strcpy(a_name + a_head->name_size, s);
+ /* Copy name */
+ assert(!a_ptr->name);
+ a_ptr->name = my_strdup(s);
- /* Advance the index */
- a_head->name_size += strlen(s);
+ /* Ensure empty description */
+ a_ptr->text = my_strdup("");
/* Ignore everything */
a_ptr->flags3 |= (TR3_IGNORE_ACID);
@@ -5139,27 +4885,13 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (a_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!a_ptr->text) a_ptr->text = ++a_head->text_size;
-
- /* Append a space at the end of the line, if needed */
- else if (a_text[a_head->text_size - 1] != ' ')
- {
- /* Append the space */
- strcpy(a_text + a_head->text_size, " ");
-
- /* Advance the index */
- a_head->text_size += 1;
+ /* Add separator if necessary */
+ if (*a_ptr->text != '\0' && !ends_with(a_ptr->text, " ")) {
+ strappend(&a_ptr->text, " ");
}
- /* Append chars to the name */
- strcpy(a_text + a_head->text_size, s);
-
- /* Advance the index */
- a_head->text_size += strlen(s);
+ /* Append to description */
+ strappend(&a_ptr->text, s);
/* Next... */
continue;
@@ -5240,7 +4972,7 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -5308,17 +5040,10 @@ errr init_a_info_txt(FILE *fp, char *buf)
/* Read activation type. */
if (buf[0] == 'a')
{
- if (prefix(buf + 2, "HARDCORE="))
+ a_ptr->activate = get_activation(buf + 2);
+ if (a_ptr->activate == -1)
{
- a_ptr->activate = get_activation(buf + 11);
- if (a_ptr->activate == -1)
- return 1;
- }
- else if (prefix(buf + 2, "SPELL="))
- {
- a_ptr->activate = -find_spell(buf + 8);
- if (a_ptr->activate == -( -1))
- return 1;
+ return 1;
}
/* Next... */
@@ -5331,11 +5056,6 @@ errr init_a_info_txt(FILE *fp, char *buf)
}
- /* Complete the "name" and "text" sizes */
- ++a_head->name_size;
- ++a_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
@@ -5347,10 +5067,11 @@ errr init_a_info_txt(FILE *fp, char *buf)
/*
* Initialize the "set_info" array, by parsing an ascii "template" file
*/
-errr init_set_info_txt(FILE *fp, char *buf)
+errr init_set_info_txt(FILE *fp)
{
int i;
int cur_art = 0, cur_num = 0;
+ char buf[1024];
char *s, *t;
@@ -5369,8 +5090,7 @@ errr init_set_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -5400,13 +5120,6 @@ errr init_set_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -5431,7 +5144,7 @@ errr init_set_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= set_head->info_num) return (2);
+ if (i >= max_set_idx) return (2);
/* Save the index */
error_idx = i;
@@ -5439,19 +5152,11 @@ errr init_set_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
set_ptr = &set_info[i];
- /* Hack -- Verify space */
- if (set_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!set_ptr->name) set_ptr->name = ++set_head->name_size;
-
- /* Append chars to the name */
- strcpy(set_name + set_head->name_size, s);
-
- /* Advance the index */
- set_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!set_ptr->name);
+ set_ptr->name = my_strdup(s);
- /* Needed hack */
+ /* Initialize */
set_ptr->num = 0;
set_ptr->num_use = 0;
for (z = 0; z < 6; z++)
@@ -5483,17 +5188,8 @@ errr init_set_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (set_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!set_ptr->desc) set_ptr->desc = ++set_head->text_size;
-
- /* Append chars to the name */
- strcpy(set_text + set_head->text_size, s);
-
- /* Advance the index */
- set_head->text_size += strlen(s);
+ /* Append chars to the description */
+ strappend(&set_ptr->desc, s);
/* Next... */
continue;
@@ -5567,16 +5263,9 @@ errr init_set_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++set_head->name_size;
- ++set_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
-
/* Success */
return (0);
}
@@ -5585,10 +5274,10 @@ errr init_set_info_txt(FILE *fp, char *buf)
/*
* Initialize the "s_info" array, by parsing an ascii "template" file
*/
-errr init_s_info_txt(FILE *fp, char *buf)
+errr init_s_info_txt(FILE *fp)
{
int i, z, order = 1;
-
+ char buf[1024];
char *s;
/* Not ready yet */
@@ -5606,8 +5295,7 @@ errr init_s_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -5637,13 +5325,6 @@ errr init_s_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'T' for "skill Tree" */
if (buf[0] == 'T')
{
@@ -5780,7 +5461,7 @@ errr init_s_info_txt(FILE *fp, char *buf)
i = atoi(buf + 2);
/* Verify information */
- if (i >= s_head->info_num) return (2);
+ if (i >= max_s_idx) return (2);
/* Save the index */
error_idx = i;
@@ -5788,17 +5469,9 @@ errr init_s_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
s_ptr = &s_info[i];
- /* Hack -- Verify space */
- if (s_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!s_ptr->name) s_ptr->name = ++s_head->name_size;
-
- /* Append chars to the name */
- strcpy(s_name + s_head->name_size, s);
-
- /* Advance the index */
- s_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!s_ptr->name);
+ s_ptr->name = my_strdup(s);
/* Init */
s_ptr->action_mkey = 0;
@@ -5822,34 +5495,21 @@ errr init_s_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (s_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
+ /* Description */
if (!s_ptr->desc)
{
- s_ptr->desc = ++s_head->text_size;
-
- /* Append chars to the name */
- strcpy(s_text + s_head->text_size, s);
-
- /* Advance the index */
- s_head->text_size += strlen(s);
+ s_ptr->desc = my_strdup(s);
}
else
{
- /* Append chars to the name */
- strcpy(s_text + s_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- s_head->text_size += strlen(s) + 1;
+ strappend(&s_ptr->desc, format("\n%s", s));
}
/* Next... */
continue;
}
- /* Process 'A' for "Activation Description" */
+ /* Process 'A' for "Activation Description" (one line only) */
if (buf[0] == 'A')
{
char *txt;
@@ -5861,19 +5521,13 @@ errr init_s_info_txt(FILE *fp, char *buf)
*txt = '\0';
txt++;
- /* Hack -- Verify space */
- if (s_head->text_size + strlen(txt) + 8 > fake_text_size) return (7);
+ /* Copy action description */
+ assert(!s_ptr->action_desc);
+ s_ptr->action_desc = my_strdup(txt);
- /* Advance and Save the text index */
- if (!s_ptr->action_desc) s_ptr->action_desc = ++s_head->text_size;
-
- /* Append chars to the name */
- strcpy(s_text + s_head->text_size, txt);
+ /* Copy mkey index */
s_ptr->action_mkey = atoi(s);
- /* Advance the index */
- s_head->text_size += strlen(txt);
-
/* Next... */
continue;
}
@@ -5947,16 +5601,9 @@ errr init_s_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++s_head->name_size;
- ++s_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
-
/* Success */
return (0);
}
@@ -5964,10 +5611,10 @@ errr init_s_info_txt(FILE *fp, char *buf)
/*
* Initialize the "ab_info" array, by parsing an ascii "template" file
*/
-errr init_ab_info_txt(FILE *fp, char *buf)
+errr init_ab_info_txt(FILE *fp)
{
int i, z;
-
+ char buf[1024];
char *s;
/* Not ready yet */
@@ -5985,8 +5632,7 @@ errr init_ab_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -6016,13 +5662,6 @@ errr init_ab_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -6042,7 +5681,7 @@ errr init_ab_info_txt(FILE *fp, char *buf)
i = atoi(buf + 2);
/* Verify information */
- if (i >= ab_head->info_num) return (2);
+ if (i >= max_ab_idx) return (2);
/* Save the index */
error_idx = i;
@@ -6050,17 +5689,9 @@ errr init_ab_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
ab_ptr = &ab_info[i];
- /* Hack -- Verify space */
- if (ab_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!ab_ptr->name) ab_ptr->name = ++ab_head->name_size;
-
- /* Append chars to the name */
- strcpy(ab_name + ab_head->name_size, s);
-
- /* Advance the index */
- ab_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!ab_ptr->name);
+ ab_ptr->name = my_strdup(s);
/* Init */
ab_ptr->action_mkey = 0;
@@ -6089,27 +5720,14 @@ errr init_ab_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (ab_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
+ /* Append description */
if (!ab_ptr->desc)
{
- ab_ptr->desc = ++ab_head->text_size;
-
- /* Append chars to the name */
- strcpy(ab_text + ab_head->text_size, s);
-
- /* Advance the index */
- ab_head->text_size += strlen(s);
+ ab_ptr->desc = my_strdup(s);
}
else
{
- /* Append chars to the name */
- strcpy(ab_text + ab_head->text_size, format("\n%s", s));
-
- /* Advance the index */
- ab_head->text_size += strlen(s) + 1;
+ strappend(&ab_ptr->desc, format("\n%s", s));
}
/* Next... */
@@ -6128,19 +5746,13 @@ errr init_ab_info_txt(FILE *fp, char *buf)
*txt = '\0';
txt++;
- /* Hack -- Verify space */
- if (ab_head->text_size + strlen(txt) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!ab_ptr->action_desc) ab_ptr->action_desc = ++ab_head->text_size;
+ /* Copy name */
+ assert(!ab_ptr->action_desc);
+ ab_ptr->action_desc = my_strdup(txt);
- /* Append chars to the name */
- strcpy(ab_text + ab_head->text_size, txt);
+ /* Set mkey */
ab_ptr->action_mkey = atoi(s);
- /* Advance the index */
- ab_head->text_size += strlen(txt);
-
/* Next... */
continue;
}
@@ -6288,16 +5900,9 @@ errr init_ab_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++ab_head->name_size;
- ++ab_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
-
/* Success */
return (0);
}
@@ -6309,6 +5914,7 @@ errr init_ab_info_txt(FILE *fp, char *buf)
static bool_ grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what, int n, bool_ obvious)
{
int i;
+ assert(n < FLAG_RARITY_MAX);
/* Check flags1 */
for (i = 0; i < 32; i++)
@@ -6526,10 +6132,10 @@ static bool_ grab_one_ego_item_flag_restrict(ego_item_type *e_ptr, cptr what, bo
/*
* Initialize the "e_info" array, by parsing an ascii "template" file
*/
-errr init_e_info_txt(FILE *fp, char *buf)
+errr init_e_info_txt(FILE *fp)
{
int i, cur_r = -1, cur_t = 0, j;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -6547,8 +6153,7 @@ errr init_e_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -6578,13 +6183,6 @@ errr init_e_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -6607,7 +6205,7 @@ errr init_e_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= e_head->info_num) return (2);
+ if (i >= max_e_idx) return (2);
/* Save the index */
error_idx = i;
@@ -6615,17 +6213,9 @@ errr init_e_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
e_ptr = &e_info[i];
- /* Hack -- Verify space */
- if (e_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!e_ptr->name) e_ptr->name = ++e_head->name_size;
-
- /* Append chars to the name */
- strcpy(e_name + e_head->name_size, s);
-
- /* Advance the index */
- e_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!e_ptr->name);
+ e_ptr->name = my_strdup(s);
/* Needed hack */
e_ptr->power = -1;
@@ -6636,7 +6226,7 @@ errr init_e_info_txt(FILE *fp, char *buf)
{
e_ptr->tval[j] = 255;
}
- for (j = 0; j < 5; j++)
+ for (j = 0; j < FLAG_RARITY_MAX; j++)
{
e_ptr->rar[j] = 0;
e_ptr->flags1[j] = 0;
@@ -6645,6 +6235,13 @@ errr init_e_info_txt(FILE *fp, char *buf)
e_ptr->flags4[j] = 0;
e_ptr->flags5[j] = 0;
e_ptr->esp[j] = 0;
+ e_ptr->oflags1[j] = 0;
+ e_ptr->oflags2[j] = 0;
+ e_ptr->oflags3[j] = 0;
+ e_ptr->oflags4[j] = 0;
+ e_ptr->oflags5[j] = 0;
+ e_ptr->oesp[j] = 0;
+ e_ptr->fego[j] = 0;
}
/* Next... */
@@ -6682,14 +6279,16 @@ errr init_e_info_txt(FILE *fp, char *buf)
{
int rar;
- if (cur_r == 5) return 1;
+ cur_r++;
+
+ if (cur_r >= FLAG_RARITY_MAX) {
+ return 1;
+ }
/* Scan for the values */
if (1 != sscanf(buf + 2, "%d",
&rar)) return (1);
- cur_r++;
-
/* Save the values */
e_ptr->rar[cur_r] = rar;
@@ -6765,7 +6364,7 @@ errr init_e_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -6778,16 +6377,9 @@ errr init_e_info_txt(FILE *fp, char *buf)
if (buf[0] == 'a')
{
- if (prefix(buf + 2, "HARDCORE="))
+ e_ptr->activate = get_activation(buf + 2);
+ if (e_ptr->activate == -1)
{
- e_ptr->activate = get_activation(buf + 11);
- if (e_ptr->activate == -1)
- return 1;
- }
- else if (prefix(buf + 2, "SPELL="))
- {
- e_ptr->activate = -find_spell(buf + 8);
- if (e_ptr->activate == -( -1))
return 1;
}
@@ -6912,11 +6504,6 @@ errr init_e_info_txt(FILE *fp, char *buf)
}
- /* Complete the "name" and "text" sizes */
- ++e_head->name_size;
- ++e_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
@@ -7048,10 +6635,10 @@ static bool_ grab_one_randart_item_flag(randart_part_type *ra_ptr, cptr what, ch
/*
* Initialize the "ra_info" array, by parsing an ascii "template" file
*/
-errr init_ra_info_txt(FILE *fp, char *buf)
+errr init_ra_info_txt(FILE *fp)
{
int i, cur_t = 0, j, cur_g = 0;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -7069,8 +6656,7 @@ errr init_ra_info_txt(FILE *fp, char *buf)
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -7100,13 +6686,6 @@ errr init_ra_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'G' for "General" (up to 30 lines) */
if (buf[0] == 'G')
{
@@ -7137,7 +6716,7 @@ errr init_ra_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= ra_head->info_num) return (2);
+ if (i >= max_ra_idx) return (2);
/* Save the index */
error_idx = i;
@@ -7254,7 +6833,7 @@ errr init_ra_info_txt(FILE *fp, char *buf)
/* Find it in the list */
for (i = 0; i < POWER_MAX; i++)
{
- if (!stricmp(s, powers_type[i].name)) break;
+ if (iequals(s, powers_type[i].name)) break;
}
if (i == POWER_MAX) return (6);
@@ -7455,10 +7034,10 @@ static errr grab_one_spell_flag(monster_race *r_ptr, cptr what)
/*
* Initialize the "r_info" array, by parsing an ascii "template" file
*/
-errr init_r_info_txt(FILE *fp, char *buf)
+errr init_r_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -7475,13 +7054,8 @@ errr init_r_info_txt(FILE *fp, char *buf)
error_line = -1;
- /* Start the "fake" stuff */
- r_head->name_size = 0;
- r_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -7511,13 +7085,6 @@ errr init_r_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -7540,7 +7107,7 @@ errr init_r_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= r_head->info_num) return (2);
+ if (i >= max_r_idx) return (2);
/* Save the index */
error_idx = i;
@@ -7548,17 +7115,12 @@ errr init_r_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
r_ptr = &r_info[i];
- /* Hack -- Verify space */
- if (r_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
+ /* Allocate name string. */
+ assert(!r_ptr->name); // Sanity check that we aren't overwriting anything
+ r_ptr->name = my_strdup(s);
- /* Advance and Save the name index */
- if (!r_ptr->name) r_ptr->name = ++r_head->name_size;
-
- /* Append chars to the name */
- strcpy(r_name + r_head->name_size, s);
-
- /* Advance the index */
- r_head->name_size += strlen(s);
+ /* Ensure empty description */
+ r_ptr->text = my_strdup("");
/* HACK -- Those ones HAVE to have a set default value */
r_ptr->drops.treasure = OBJ_GENE_TREASURE;
@@ -7581,17 +7143,8 @@ errr init_r_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (r_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!r_ptr->text) r_ptr->text = ++r_head->text_size;
-
- /* Append chars to the name */
- strcpy(r_text + r_head->text_size, s);
-
- /* Advance the index */
- r_head->text_size += strlen(s);
+ /* Append to description */
+ strappend(&r_ptr->text, s);
/* Next... */
continue;
@@ -7843,11 +7396,7 @@ errr init_r_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++r_head->name_size;
- ++r_head->text_size;
-
+ /* Postprocessing */
for (i = 1; i < max_r_idx; i++)
{
/* Invert flag WILD_ONLY <-> RF8_DUNGEON */
@@ -8095,10 +7644,10 @@ static errr grab_one_ego_flag(monster_ego *re_ptr, cptr what, bool_ must)
/*
* Initialize the "re_info" array, by parsing an ascii "template" file
*/
-errr init_re_info_txt(FILE *fp, char *buf)
+errr init_re_info_txt(FILE *fp)
{
int i, j;
-
+ char buf[1024];
byte blow_num = 0;
int r_char_number = 0, nr_char_number = 0;
@@ -8117,14 +7666,8 @@ errr init_re_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- re_head->name_size = 0;
- re_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -8154,13 +7697,6 @@ errr init_re_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -8183,7 +7719,7 @@ errr init_re_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= re_head->info_num) return (2);
+ if (i >= max_re_idx) return (2);
/* Save the index */
error_idx = i;
@@ -8191,17 +7727,9 @@ errr init_re_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
re_ptr = &re_info[i];
- /* Hack -- Verify space */
- if (re_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!re_ptr->name) re_ptr->name = ++re_head->name_size;
-
- /* Append chars to the name */
- strcpy(re_name + re_head->name_size, s);
-
- /* Advance the index */
- re_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!re_ptr->name);
+ re_ptr->name = my_strdup(s);
/* Some inits */
blow_num = 0;
@@ -8600,10 +8128,6 @@ errr init_re_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++re_head->name_size;
-
/* No version yet */
if (!okay) return (2);
@@ -8639,10 +8163,10 @@ static errr grab_one_trap_type_flag(trap_type *t_ptr, cptr what)
/*
* Initialize the "tr_info" array, by parsing an ascii "template" file
*/
-errr init_t_info_txt(FILE *fp, char *buf)
+errr init_t_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -8651,21 +8175,14 @@ errr init_t_info_txt(FILE *fp, char *buf)
/* Current entry */
trap_type *t_ptr = NULL;
-
/* Just before the first record */
error_idx = -1;
/* Just before the first line */
error_line = -1;
-
- /* Prepare the "fake" stuff */
- t_head->name_size = 0;
- t_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -8695,13 +8212,6 @@ errr init_t_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -8724,7 +8234,7 @@ errr init_t_info_txt(FILE *fp, char *buf)
if (i <= error_idx) return (4);
/* Verify information */
- if (i >= t_head->info_num) return (2);
+ if (i >= max_t_idx) return (2);
/* Save the index */
error_idx = i;
@@ -8732,17 +8242,11 @@ errr init_t_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
t_ptr = &t_info[i];
- /* Hack -- Verify space */
- if (t_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!t_ptr->name) t_ptr->name = ++t_head->name_size;
-
- /* Append chars to the name */
- strcpy(t_name + t_head->name_size, s);
+ /* Copy name */
+ t_ptr->name = my_strdup(s);
- /* Advance the index */
- t_head->name_size += strlen(s);
+ /* Initialize */
+ t_ptr->text = my_strdup("");
/* Next... */
continue;
@@ -8786,17 +8290,8 @@ errr init_t_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (t_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!t_ptr->text) t_ptr->text = ++t_head->text_size;
-
/* Append chars to the name */
- strcpy(t_text + t_head->text_size, s);
-
- /* Advance the index */
- t_head->text_size += strlen(s);
+ strappend(&t_ptr->text, s);
/* Next... */
continue;
@@ -8838,16 +8333,9 @@ errr init_t_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++t_head->name_size;
- ++t_head->text_size;
-
-
/* No version yet */
if (!okay) return (2);
-
/* Success */
return (0);
}
@@ -9008,9 +8496,10 @@ static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what, byt
/*
* Initialize the "d_info" array, by parsing an ascii "template" file
*/
-errr init_d_info_txt(FILE *fp, char *buf)
+errr init_d_info_txt(FILE *fp)
{
int i, j;
+ char buf[1024];
s16b rule_num = 0;
@@ -9031,14 +8520,8 @@ errr init_d_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- d_head->name_size = 0;
- d_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -9068,13 +8551,6 @@ errr init_d_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -9097,7 +8573,7 @@ errr init_d_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= d_head->info_num) return (2);
+ if (i >= max_d_idx) return (2);
/* Save the index */
error_idx = i;
@@ -9105,17 +8581,12 @@ errr init_d_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
d_ptr = &d_info[i];
- /* Hack -- Verify space */
- if (d_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
+ /* Copy name */
+ assert(!d_ptr->name);
+ d_ptr->name = my_strdup(s);
- /* Advance and Save the name index */
- if (!d_ptr->name) d_ptr->name = ++d_head->name_size;
-
- /* Append chars to the name */
- strcpy(d_name + d_head->name_size, s);
-
- /* Advance the index */
- d_head->name_size += strlen(s);
+ /* Initialize description */
+ d_ptr->text = my_strdup("");
/* HACK -- Those ones HAVE to have a set default value */
d_ptr->size_x = -1;
@@ -9164,17 +8635,8 @@ errr init_d_info_txt(FILE *fp, char *buf)
/* Acquire the text */
s = buf + 6;
- /* Hack -- Verify space */
- if (d_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!d_ptr->text) d_ptr->text = ++d_head->text_size;
-
- /* Append chars to the name */
- strcpy(d_text + d_head->text_size, s);
-
- /* Advance the index */
- d_head->text_size += strlen(s);
+ /* Append to description */
+ strappend(&d_ptr->text, s);
/* Next... */
continue;
@@ -9588,10 +9050,6 @@ errr init_d_info_txt(FILE *fp, char *buf)
}
- /* Complete the "name" and "text" sizes */
- ++d_head->name_size;
- ++d_head->text_size;
-
/* No version yet */
if (!okay) return (2);
@@ -9657,10 +9115,10 @@ static errr grab_one_store_flag(store_info_type *st_ptr, cptr what)
/*
* Initialize the "st_info" array, by parsing an ascii "template" file
*/
-errr init_st_info_txt(FILE *fp, char *buf)
+errr init_st_info_txt(FILE *fp)
{
int i = 0, item_idx = 0;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -9676,14 +9134,8 @@ errr init_st_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- st_head->name_size = 0;
- st_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -9713,13 +9165,6 @@ errr init_st_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -9742,7 +9187,7 @@ errr init_st_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= st_head->info_num) return (2);
+ if (i >= max_st_idx) return (2);
/* Save the index */
error_idx = i;
@@ -9750,17 +9195,9 @@ errr init_st_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
st_ptr = &st_info[i];
- /* Hack -- Verify space */
- if (st_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!st_ptr->name) st_ptr->name = ++st_head->name_size;
-
- /* Append chars to the name */
- strcpy(st_name + st_head->name_size, s);
-
- /* Advance the index */
- st_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!st_ptr->name);
+ st_ptr->name = my_strdup(s);
/* We are ready for a new set of objects */
item_idx = 0;
@@ -9794,6 +9231,7 @@ errr init_st_info_txt(FILE *fp, char *buf)
st_ptr->table[item_idx++][0] = test_item_name(s);
st_ptr->table_num = item_idx;
+ assert(st_ptr->table_num <= STORE_CHOICES);
/* Next... */
continue;
@@ -9931,11 +9369,6 @@ errr init_st_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++st_head->name_size;
- ++st_head->text_size;
-
/* No version yet */
if (!okay) return (2);
@@ -9946,10 +9379,10 @@ errr init_st_info_txt(FILE *fp, char *buf)
/*
* Initialize the "ba_info" array, by parsing an ascii "template" file
*/
-errr init_ba_info_txt(FILE *fp, char *buf)
+errr init_ba_info_txt(FILE *fp)
{
int i = 0;
-
+ char buf[1024];
char *s;
/* Not ready yet */
@@ -9965,14 +9398,8 @@ errr init_ba_info_txt(FILE *fp, char *buf)
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- ba_head->name_size = 0;
- ba_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -10002,13 +9429,6 @@ errr init_ba_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -10031,7 +9451,7 @@ errr init_ba_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= ba_head->info_num) return (2);
+ if (i >= max_ba_idx) return (2);
/* Save the index */
error_idx = i;
@@ -10039,17 +9459,9 @@ errr init_ba_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
ba_ptr = &ba_info[i];
- /* Hack -- Verify space */
- if (ba_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!ba_ptr->name) ba_ptr->name = ++ba_head->name_size;
-
- /* Append chars to the name */
- strcpy(ba_name + ba_head->name_size, s);
-
- /* Advance the index */
- ba_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!ba_ptr->name);
+ ba_ptr->name = my_strdup(s);
/* Next... */
continue;
@@ -10101,11 +9513,6 @@ errr init_ba_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++ba_head->name_size;
- ++ba_head->text_size;
-
/* No version yet */
if (!okay) return (2);
@@ -10116,10 +9523,10 @@ errr init_ba_info_txt(FILE *fp, char *buf)
/*
* Initialize the "ow_info" array, by parsing an ascii "template" file
*/
-errr init_ow_info_txt(FILE *fp, char *buf)
+errr init_ow_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -10128,21 +9535,14 @@ errr init_ow_info_txt(FILE *fp, char *buf)
/* Current entry */
owner_type *ow_ptr = NULL;
-
/* Just before the first record */
error_idx = -1;
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- ow_head->name_size = 0;
- ow_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -10172,13 +9572,6 @@ errr init_ow_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -10201,7 +9594,7 @@ errr init_ow_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= ow_head->info_num) return (2);
+ if (i >= max_ow_idx) return (2);
/* Save the index */
error_idx = i;
@@ -10209,17 +9602,9 @@ errr init_ow_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
ow_ptr = &ow_info[i];
- /* Hack -- Verify space */
- if (ow_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!ow_ptr->name) ow_ptr->name = ++ow_head->name_size;
-
- /* Append chars to the name */
- strcpy(ow_name + ow_head->name_size, s);
-
- /* Advance the index */
- ow_head->name_size += strlen(s);
+ /* Copy name */
+ assert(!ow_ptr->name);
+ ow_ptr->name = my_strdup(s);
/* Next... */
continue;
@@ -10321,11 +9706,6 @@ errr init_ow_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++ow_head->name_size;
- ++ow_head->text_size;
-
/* No version yet */
if (!okay) return (2);
@@ -10360,10 +9740,10 @@ static errr grab_one_wf_info_flag(wilderness_type_info *wf_ptr, cptr what)
/*
* Initialize the "wf_info" array, by parsing an ascii "template" file
*/
-errr init_wf_info_txt(FILE *fp, char *buf)
+errr init_wf_info_txt(FILE *fp)
{
int i;
-
+ char buf[1024];
char *s, *t;
/* Not ready yet */
@@ -10372,21 +9752,14 @@ errr init_wf_info_txt(FILE *fp, char *buf)
/* Current entry */
wilderness_type_info *wf_ptr = NULL;
-
/* Just before the first record */
error_idx = -1;
/* Just before the first line */
error_line = -1;
-
- /* Start the "fake" stuff */
- wf_head->name_size = 0;
- wf_head->text_size = 0;
-
/* Parse */
- fp_stack_init(fp);
- while (0 == my_fgets_dostack(buf, 1024))
+ while (0 == my_fgets(fp, buf, 1024))
{
/* Advance the line number */
error_line++;
@@ -10416,13 +9789,6 @@ errr init_wf_info_txt(FILE *fp, char *buf)
/* No version yet */
if (!okay) return (2);
- /* Included file */
- if (buf[0] == '<')
- {
- fp_stack_push(buf + 2);
- continue;
- }
-
/* Process 'N' for "New/Number/Name" */
if (buf[0] == 'N')
{
@@ -10445,7 +9811,7 @@ errr init_wf_info_txt(FILE *fp, char *buf)
if (i < error_idx) return (4);
/* Verify information */
- if (i >= wf_head->info_num) return (2);
+ if (i >= max_wf_idx) return (2);
/* Save the index */
error_idx = i;
@@ -10453,17 +9819,9 @@ errr init_wf_info_txt(FILE *fp, char *buf)
/* Point at the "info" */
wf_ptr = &wf_info[i];
- /* Hack -- Verify space */
- if (wf_head->name_size + strlen(s) + 8 > fake_name_size) return (7);
-
- /* Advance and Save the name index */
- if (!wf_ptr->name) wf_ptr->name = ++wf_head->name_size;
-
- /* Append chars to the name */
- strcpy(wf_name + wf_head->name_size, s);
-
- /* Advance the index */
- wf_head->name_size += strlen(s);
+ /* Copy the name */
+ assert(!wf_ptr->name);
+ wf_ptr->name = my_strdup(s);
/* Next... */
continue;
@@ -10472,23 +9830,15 @@ errr init_wf_info_txt(FILE *fp, char *buf)
/* There better be a current wf_ptr */
if (!wf_ptr) return (3);
- /* Process 'D' for "Description */
+ /* Process 'D' for "Description (one line only) */
if (buf[0] == 'D')
{
/* Acquire the text */
s = buf + 2;
- /* Hack -- Verify space */
- if (wf_head->text_size + strlen(s) + 8 > fake_text_size) return (7);
-
- /* Advance and Save the text index */
- if (!wf_ptr->text) wf_ptr->text = ++wf_head->text_size;
-
- /* Append chars to the name */
- strcpy(wf_text + wf_head->text_size, s);
-
- /* Advance the index */
- wf_head->text_size += strlen(s);
+ /* Copy description */
+ assert(!wf_ptr->text);
+ wf_ptr->text = my_strdup(s);
/* Next... */
continue;
@@ -10574,11 +9924,6 @@ errr init_wf_info_txt(FILE *fp, char *buf)
return (6);
}
-
- /* Complete the "name" and "text" sizes */
- ++wf_head->name_size;
- ++wf_head->text_size;
-
/* No version yet */
if (!okay) return (2);
@@ -11399,6 +10744,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst
*/
static cptr process_dungeon_file_expr(char **sp, char *fp)
{
+ static char pref_tmp_value[8];
cptr v;
char *b;
@@ -11580,19 +10926,19 @@ static cptr process_dungeon_file_expr(char **sp, char *fp)
/* Race */
else if (streq(b + 1, "RACE"))
{
- v = rp_ptr->title + rp_name;
+ v = rp_ptr->title;
}
/* Race Mod */
else if (streq(b + 1, "RACEMOD"))
{
- v = rmp_ptr->title + rmp_name;
+ v = rmp_ptr->title;
}
/* Class */
else if (streq(b + 1, "CLASS"))
{
- v = cp_ptr->title + c_name;
+ v = cp_ptr->title;
}
/* Player */
diff --git a/src/init1.hpp b/src/init1.hpp
new file mode 100644
index 00000000..69bcec9b
--- /dev/null
+++ b/src/init1.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern int color_char_to_attr(char c);
+extern byte conv_color[16];
+extern errr init_player_info_txt(FILE *fp);
+extern errr init_ab_info_txt(FILE *fp);
+extern errr init_s_info_txt(FILE *fp);
+extern errr init_set_info_txt(FILE *fp);
+extern errr init_v_info_txt(FILE *fp);
+extern errr init_f_info_txt(FILE *fp);
+extern errr init_k_info_txt(FILE *fp);
+extern errr init_a_info_txt(FILE *fp);
+extern errr init_al_info_txt(FILE *fp);
+extern errr init_ra_info_txt(FILE *fp);
+extern errr init_e_info_txt(FILE *fp);
+extern errr init_r_info_txt(FILE *fp);
+extern errr init_re_info_txt(FILE *fp);
+extern errr init_d_info_txt(FILE *fp);
+extern errr init_t_info_txt(FILE *fp);
+extern errr init_ba_info_txt(FILE *fp);
+extern errr init_st_info_txt(FILE *fp);
+extern errr init_ow_info_txt(FILE *fp);
+extern errr init_wf_info_txt(FILE *fp);
+extern errr grab_one_dungeon_flag(u32b *flags1, u32b *flags2, cptr what);
+extern errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full);
diff --git a/src/init2.c b/src/init2.c
deleted file mode 100644
index 9c1c2afa..00000000
--- a/src/init2.c
+++ /dev/null
@@ -1,2738 +0,0 @@
-/* File: init2.c */
-
-/* Purpose: Initialisation (part 2) -BEN- */
-
-#include "angband.h"
-
-#include <assert.h>
-
-#include "messages.h"
-#include "quark.h"
-
-/*
- * This file is used to initialise various variables and arrays for the
- * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass
- * the common limitation of "read()" and "write()" to only 32767 bytes
- * at a time.
- *
- * Several of the arrays for Angband are built from "template" files in
- * the "lib/file" directory, from which quick-load binary "image" files
- * are constructed whenever they are not present in the "lib/data"
- * directory, or if those files become obsolete, if we are allowed.
- *
- * Warning -- the "ascii" file parsers use a minor hack to collect the
- * name and text information in a single pass. Thus, the game will not
- * be able to load any template file with more than 20K of names or 60K
- * of text, even though technically, up to 64K should be legal.
- *
- * The "init1.c" file is used only to parse the ascii template files.
- */
-
-
-
-/*
- * Find the default paths to all of our important sub-directories.
- *
- * The purpose of each sub-directory is described in "variable.c".
- *
- * All of the sub-directories should, by default, be located inside
- * the main "lib" directory, whose location is very system dependant.
- *
- * This function takes a writable buffer, initially containing the
- * "path" to the "lib" directory, for example, "/pkg/lib/angband/",
- * or a system dependant string, for example, ":lib:". The buffer
- * must be large enough to contain at least 32 more characters.
- *
- * Various command line options may allow some of the important
- * directories to be changed to user-specified directories, most
- * importantly, the "info" and "user" and "save" directories,
- * but this is done after this function, see "main.c".
- *
- * In general, the initial path should end in the appropriate "PATH_SEP"
- * string. All of the "sub-directory" paths (created below or supplied
- * by the user) will NOT end in the "PATH_SEP" string, see the special
- * "path_build()" function in "util.c" for more information.
- *
- * Mega-Hack -- support fat raw files under NEXTSTEP, using special
- * "suffixed" directories for the "ANGBAND_DIR_DATA" directory, but
- * requiring the directories to be created by hand by the user.
- *
- * Hack -- first we free all the strings, since this is known
- * to succeed even if the strings have not been allocated yet,
- * as long as the variables start out as "NULL". This allows
- * this function to be called multiple times, for example, to
- * try several base "path" values until a good one is found.
- */
-void init_file_paths(char *path)
-{
- char *tail;
- int pathlen;
-
- /*** Free everything ***/
-
- /* Free the main path */
- string_free(ANGBAND_DIR);
-
- /* Free the sub-paths */
- string_free(ANGBAND_DIR_CORE);
- string_free(ANGBAND_DIR_DNGN);
- string_free(ANGBAND_DIR_DATA);
- string_free(ANGBAND_DIR_EDIT);
- string_free(ANGBAND_DIR_FILE);
- string_free(ANGBAND_DIR_HELP);
- string_free(ANGBAND_DIR_INFO);
- string_free(ANGBAND_DIR_MODULES);
- string_free(ANGBAND_DIR_NOTE);
- string_free(ANGBAND_DIR_SAVE);
- string_free(ANGBAND_DIR_SCPT);
- string_free(ANGBAND_DIR_PREF);
- string_free(ANGBAND_DIR_PATCH);
- string_free(ANGBAND_DIR_USER);
- string_free(ANGBAND_DIR_XTRA);
- string_free(ANGBAND_DIR_CMOV);
-
-
- /*** Prepare the "path" ***/
-
- pathlen = strlen(path);
-
- /* Hack -- save the main directory without trailing PATH_SEP if present */
- if (strlen(PATH_SEP) > 0 && pathlen > 0)
- {
- int seplen = strlen(PATH_SEP);
-
- if (strcmp(path + pathlen - seplen, PATH_SEP) == 0)
- {
- path[pathlen - seplen] = '\0';
- ANGBAND_DIR = string_make(path);
- path[pathlen - seplen] = *PATH_SEP;
- }
- else
- {
- ANGBAND_DIR = string_make(path);
- }
- }
- else
- {
- ANGBAND_DIR = string_make(path);
- }
-
- /* Prepare to append to the Base Path */
- tail = path + pathlen;
-
-
-
- /*** Build the sub-directory names ***/
-
- /* Build a path name */
- strcpy(tail, "core");
- ANGBAND_DIR_CORE = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "dngn");
- ANGBAND_DIR_DNGN = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "data");
- ANGBAND_DIR_DATA = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "edit");
- ANGBAND_DIR_EDIT = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "file");
- ANGBAND_DIR_FILE = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "help");
- ANGBAND_DIR_HELP = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "info");
- ANGBAND_DIR_INFO = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "mods");
- ANGBAND_DIR_MODULES = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "patch");
- ANGBAND_DIR_PATCH = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "scpt");
- ANGBAND_DIR_SCPT = string_make(path);
-
- /* Build a path name */
- strcpy(tail, "pref");
- ANGBAND_DIR_PREF = string_make(path);
-
- /* synchronize with module_reset_dir */
- {
- char user_path[1024];
-
- /* Get an absolute path from the file name */
- path_parse(user_path, 1024, PRIVATE_USER_PATH);
- strcat(user_path, USER_PATH_VERSION);
- ANGBAND_DIR_USER = string_make(user_path);
- ANGBAND_DIR_NOTE = string_make(user_path);
- ANGBAND_DIR_CMOV = string_make(user_path);
-#ifdef PRIVATE_USER_PATH_MODULES
- ANGBAND_DIR_MODULES = string_make(user_path);
-#endif
-#ifdef PRIVATE_USER_PATH_DATA
- {
- char user_path_data[1024];
- strcpy(user_path_data, user_path);
- strcat(user_path_data, "/data");
- ANGBAND_DIR_DATA = string_make(user_path_data);
- }
-#endif
-
- /* Savefiles are in user directory */
- strcat(user_path, "/save");
- ANGBAND_DIR_SAVE = string_make(user_path);
- }
-
- /* Build a path name */
- strcpy(tail, "xtra");
- ANGBAND_DIR_XTRA = string_make(path);
-}
-
-
-/**
- * Realloc the given character array.
- */
-static void z_realloc(char **p, size_t n) {
- /* realloc doesn't really support size 0, but we want to shrink the allocated area regardless. */
- if (n == 0) {
- n = 1;
- }
- /* do the reallocation */
- *p = realloc(*p, n);
- if (*p == NULL) {
- quit("Error during realloc.");
- }
-}
-
-/*
- * Hack -- help give useful error messages
- */
-s16b error_idx;
-s16b error_line;
-
-
-/*
- * Hack -- help initialise the fake "name" and "text" arrays when
- * parsing an "ascii" template file.
- */
-u32b fake_name_size;
-u32b fake_text_size;
-
-
-/*
- * Standard error message text
- */
-static cptr err_str[9] =
-{
- NULL,
- "parse error",
- "obsolete file",
- "missing record header",
- "non-sequential records",
- "invalid flag specification",
- "undefined directive",
- "out of memory",
- "invalid skill chart"
-};
-
-
-/*
- * Hack -- take notes on line 23
- */
-static void note(cptr str)
-{
- Term_erase(0, 23, 255);
- Term_putstr(20, 23, -1, TERM_WHITE, str);
- Term_fresh();
-}
-
-
-
-/*
- * Initialise the "f_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_f_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(f_head, header);
-
- /* Save the "record" information */
- f_head->info_num = max_f_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "f_name" and "f_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "f_info" array */
- C_MAKE(f_info, f_head->info_num, feature_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(f_name, fake_name_size, char);
- C_MAKE(f_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "f_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'f_info.txt' file.");
-
- /* Parse the file */
- err = init_f_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'f_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'f_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&f_name, f_head->name_size);
- z_realloc(&f_text, f_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise the "k_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_k_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(k_head, header);
-
- /* Save the "record" information */
- k_head->info_num = max_k_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "k_name" and "k_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "k_info" array */
- C_MAKE(k_info, k_head->info_num, object_kind);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(k_name, fake_name_size, char);
- C_MAKE(k_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "k_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'k_info.txt' file.");
-
- /* Parse the file */
- err = init_k_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'k_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'k_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&k_name, k_head->name_size);
- z_realloc(&k_text, k_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise the "set_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_set_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(set_head, header);
-
- /* Save the "record" information */
- set_head->info_num = max_set_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "set_name" and "set_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "set_info" array */
- C_MAKE(set_info, set_head->info_num, set_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(set_name, fake_name_size, char);
- C_MAKE(set_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "set_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'set_info.txt' file.");
-
- /* Parse the file */
- err = init_set_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'set_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'set_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&set_name, set_head->name_size);
- z_realloc(&set_text, set_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "a_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_a_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(a_head, header);
-
- /* Save the "record" information */
- a_head->info_num = max_a_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "a_name" and "a_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "a_info" array */
- C_MAKE(a_info, a_head->info_num, artifact_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(a_name, fake_name_size, char);
- C_MAKE(a_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "a_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'a_info.txt' file.");
-
- /* Parse the file */
- err = init_a_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'a_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'a_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&a_name, a_head->name_size);
- z_realloc(&a_text, a_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "s_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_s_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(s_head, header);
-
- /* Save the "record" information */
- s_head->info_num = max_s_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "a_name" and "a_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "s_info" array */
- C_MAKE(s_info, s_head->info_num, skill_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(s_name, fake_name_size, char);
- C_MAKE(s_text, fake_text_size, char);
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "s_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 's_info.txt' file.");
-
- /* Parse the file */
- err = init_s_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 's_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 's_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&s_name, s_head->name_size);
- z_realloc(&s_text, s_head->text_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialise the "ab_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_ab_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(ab_head, header);
-
- /* Save the "record" information */
- ab_head->info_num = max_ab_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "a_name" and "a_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "ab_info" array */
- C_MAKE(ab_info, ab_head->info_num, ability_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(ab_name, fake_name_size, char);
- C_MAKE(ab_text, fake_text_size, char);
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "ab_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'ab_info.txt' file.");
-
- /* Parse the file */
- err = init_ab_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'ab_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'ab_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&ab_name, ab_head->name_size);
- z_realloc(&ab_text, ab_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise the "e_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_e_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(e_head, header);
-
- /* Save the "record" information */
- e_head->info_num = max_e_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "e_name" and "e_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "e_info" array */
- C_MAKE(e_info, e_head->info_num, ego_item_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(e_name, fake_name_size, char);
- C_MAKE(e_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "e_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'e_info.txt' file.");
-
- /* Parse the file */
- err = init_e_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'e_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'e_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&e_name, e_head->name_size);
- z_realloc(&e_text, e_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise the "ra_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_ra_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
- /*** Make the "header" ***/
-
- /* Allocate the "header" */
- MAKE(ra_head, header);
-
- /* Save the "record" information */
- ra_head->info_num = max_ra_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "ra_name" and "ra_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "ra_info" array */
- C_MAKE(ra_info, ra_head->info_num, randart_part_type);
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "ra_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'ra_info.txt' file.");
-
- /* Parse the file */
- err = init_ra_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'ra_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'ra_info.txt' file.");
- }
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise the "r_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_r_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(r_head, header);
-
- /* Save the "record" information */
- r_head->info_num = max_r_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "r_name" and "r_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "r_info" array */
- C_MAKE(r_info, r_head->info_num, monster_race);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(r_name, fake_name_size, char);
- C_MAKE(r_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "r_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'r_info.txt' file.");
-
- /* Parse the file */
- err = init_r_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'r_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'r_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&r_name, r_head->name_size);
- z_realloc(&r_text, r_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "re_info" array
- *
- * Note that we let each entry have a unique "name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_re_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(re_head, header);
-
- /* Save the "record" information */
- re_head->info_num = max_re_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "re_name" */
- fake_name_size = FAKE_NAME_SIZE;
-
- /* Allocate the "re_info" array */
- C_MAKE(re_info, re_head->info_num, monster_ego);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(re_name, fake_name_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "re_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 're_info.txt' file.");
-
- /* Parse the file */
- err = init_re_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 're_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 're_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&re_name, re_head->name_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "d_info" array
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_d_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(d_head, header);
-
- /* Save the "record" information */
- d_head->info_num = max_d_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "d_name" and "d_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "d_info" array */
- C_MAKE(d_info, d_head->info_num, dungeon_info_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(d_name, fake_name_size, char);
- C_MAKE(d_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "d_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'd_info.txt' file.");
-
- /* Parse the file */
- err = init_d_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'd_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'd_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&d_name, d_head->name_size);
- z_realloc(&d_text, d_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "player" arrays
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_player_info(void)
-{
- int i;
-
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(rp_head, header);
-
- /* Save the "record" information */
- rp_head->info_num = max_rp_idx;
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(rmp_head, header);
-
- /* Save the "record" information */
- rmp_head->info_num = max_rmp_idx;
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(c_head, header);
-
- /* Save the "record" information */
- c_head->info_num = max_c_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "rp_name" and "rp_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "rp_info" array */
- C_MAKE(race_info, rp_head->info_num, player_race);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(rp_name, fake_name_size, char);
- C_MAKE(rp_text, fake_text_size, char);
-
- /* Allocate the "rmp_info" array */
- C_MAKE(race_mod_info, rmp_head->info_num, player_race_mod);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(rmp_name, fake_name_size, char);
- C_MAKE(rmp_text, fake_text_size, char);
-
- /* Allocate the "c_info" array */
- C_MAKE(class_info, c_head->info_num, player_class);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(c_name, fake_name_size, char);
- C_MAKE(c_text, fake_text_size, char);
-
- /* Allocate the "bg" array */
- C_MAKE(bg, max_bg_idx, hist_type);
-
- /* Allocate the "meta_class" array */
- C_MAKE(meta_class_info, max_mc_idx, meta_class_type);
- for (i = 0; i < max_mc_idx; i++)
- {
- C_MAKE(meta_class_info[i].classes, max_c_idx, s16b);
- }
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "p_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'p_info.txt' file.");
-
- /* Parse the file */
- err = init_player_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'p_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'p_info.txt' file.");
- }
-
- /* Reallocate arrays. */
- z_realloc(&rp_name, rp_head->name_size);
- z_realloc(&rp_text, rp_head->text_size);
- z_realloc(&rmp_name, rmp_head->name_size);
- z_realloc(&rmp_text, rmp_head->text_size);
- z_realloc(&c_name, c_head->name_size);
- z_realloc(&c_text, c_head->text_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialise the "st_info" array
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_st_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(st_head, header);
-
- /* Save the "record" information */
- st_head->info_num = max_st_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "st_name" and "st_text" */
- fake_name_size = FAKE_NAME_SIZE;
-
- /* Allocate the "st_info" array */
- C_MAKE(st_info, st_head->info_num, store_info_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(st_name, fake_name_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "st_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'st_info.txt' file.");
-
- /* Parse the file */
- err = init_st_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'st_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'st_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&st_name, st_head->name_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialise the "ow_info" array
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_ow_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(ow_head, header);
-
- /* Save the "record" information */
- ow_head->info_num = max_ow_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "ow_name" and "ow_text" */
- fake_name_size = FAKE_NAME_SIZE;
-
- /* Allocate the "ow_info" array */
- C_MAKE(ow_info, ow_head->info_num, owner_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(ow_name, fake_name_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "ow_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'ow_info.txt' file.");
-
- /* Parse the file */
- err = init_ow_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'ow_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'ow_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&ow_name, ow_head->name_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialise the "ba_info" array
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_ba_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(ba_head, header);
-
- /* Save the "record" information */
- ba_head->info_num = max_ba_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "ba_name" and "ba_text" */
- fake_name_size = FAKE_NAME_SIZE;
-
- /* Allocate the "ba_info" array */
- C_MAKE(ba_info, ba_head->info_num, store_action_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(ba_name, fake_name_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "ba_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'ba_info.txt' file.");
-
- /* Parse the file */
- err = init_ba_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'ba_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'ba_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&ba_name, ba_head->name_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialise the "wf_info" array
- *
- * Note that we let each entry have a unique "name" and "short name" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_wf_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(wf_head, header);
-
- /* Save the "record" information */
- wf_head->info_num = max_wf_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Assume the size of "wf_name" and "wf_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "r_info" array */
- C_MAKE(wf_info, wf_head->info_num, wilderness_type_info);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(wf_name, fake_name_size, char);
- C_MAKE(wf_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "wf_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'wf_info.txt' file.");
-
- /* Parse the file */
- err = init_wf_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d df 'wf_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'wf_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&wf_name, wf_head->name_size);
- z_realloc(&wf_text, wf_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "t_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-static errr init_t_info(void)
-{
- errr err = 0;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(t_head, header);
-
- /* Save the "record" information */
- t_head->info_num = max_t_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "t_name" and "t_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "t_info" array */
- C_MAKE(t_info, t_head->info_num, trap_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(t_name, fake_name_size, char);
- C_MAKE(t_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "tr_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'tr_info.txt' file.");
-
- /* Parse the file */
- err = init_t_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'tr_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'tr_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&t_name, t_head->name_size);
- z_realloc(&t_text, t_head->text_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "al_info" array
- *
- * Not a flat array, but an array none the less
- */
-errr init_al_info(void)
-{
- errr err;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(al_head, header);
-
- /* Save the "record" information */
- al_head->info_num = max_al_idx;
-
-
-
-
- fake_text_size = FAKE_TEXT_SIZE;
- fake_name_size = FAKE_NAME_SIZE;
-
- /* Allocate the "al_info" array */
- C_MAKE(alchemist_recipes, al_head->info_num, alchemist_recipe);
-
- /* Allocate the fake arrays */
- /* ok, so we fudge a bit, but
- fake text size will ALWAYS be larger
- than 32*5*sizeof(artifact_select_flag) = 10 int and 5 bytes
- which is the maximum size of the a_select_flags array
- */
- C_MAKE(al_name, fake_name_size, char);
-
- {
- char *hack;
- C_MAKE(hack, fake_text_size, char);
- a_select_flags = (artifact_select_flag *) hack;
- }
-
- /*** Load the ascii template file ***/
-
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "al_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'al_info.txt' file.");
-
- /* Parse the file */
- err = init_al_info_txt(fp, buf);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'al_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'al_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&al_name, al_head->name_size);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Initialise the "v_info" array
- *
- * Note that we let each entry have a unique "name" and "text" string,
- * even if the string happens to be empty (everyone has a unique '\0').
- */
-errr init_v_info(void)
-{
- errr err;
-
- FILE *fp;
-
- /* General buffer */
- char buf[1024];
-
-
- /*** Make the header ***/
-
- /* Allocate the "header" */
- MAKE(v_head, header);
-
- /* Save the "record" information */
- v_head->info_num = max_v_idx;
-
-
- /*** Make the fake arrays ***/
-
- /* Fake the size of "v_name" and "v_text" */
- fake_name_size = FAKE_NAME_SIZE;
- fake_text_size = FAKE_TEXT_SIZE;
-
- /* Allocate the "k_info" array */
- C_MAKE(v_info, v_head->info_num, vault_type);
-
- /* Hack -- make "fake" arrays */
- C_MAKE(v_name, fake_name_size, char);
- C_MAKE(v_text, fake_text_size, char);
-
-
- /*** Load the ascii template file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_EDIT, "v_info.txt");
-
- /* Open the file */
- fp = my_fopen(buf, "r");
-
- /* Parse it */
- if (!fp) quit("Cannot open 'v_info.txt' file.");
-
- /* Parse the file */
- err = init_v_info_txt(fp, buf, TRUE);
-
- /* Close it */
- my_fclose(fp);
-
- /* Errors */
- if (err)
- {
- cptr oops;
-
- /* Error string */
- oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
-
- /* Oops */
- msg_format("Error %d at line %d of 'v_info.txt'.", err, error_line);
- msg_format("Record %d contains a '%s' error.", error_idx, oops);
- msg_format("Parsing '%s'.", buf);
- msg_print(NULL);
-
- /* Quit */
- quit("Error in 'v_info.txt' file.");
- }
-
- /* Reduce sizes of the arrays */
- z_realloc(&v_name, v_head->name_size);
- z_realloc(&v_text, v_head->text_size);
-
- /* Success */
- return (0);
-}
-
-/*
- * Initialize the very basic arrays
- */
-static void init_basic()
-{
- int i;
-
- /* 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);
-
- /* Extended trigger macros */
- C_MAKE(cli_info, CLI_MAX, cli_comm);
-
- /* Wipe the directory list */
- for (i = 0; i < 255; i++)
- {
- scansubdir_result[i] = NULL;
- }
-}
-
-
-/*
- * Initialise misc. values
- */
-static errr init_misc(void)
-{
- int xstart = 0;
- int ystart = 0;
- int i;
-
- /*** Prepare the various "bizarre" arrays ***/
-
- /* Initialize quark subsystem */
- quark_init();
-
- /* Initialize messages subsystem */
- message_init();
-
- /* Initialize game */
- process_hooks(HOOK_INIT_GAME, "(s)", "begin");
-
- /* Initialise the values */
- process_dungeon_file("misc.txt", &ystart, &xstart, 0, 0, TRUE, FALSE);
-
- /* Init the spell effects */
- for (i = 0; i < MAX_EFFECTS; i++)
- effects[i].time = 0;
-
- /* Initialize timers */
- TIMER_INERTIA_CONTROL =
- new_timer(meta_inertia_control_timer_callback,
- 10);
- TIMER_AGGRAVATE_EVIL =
- new_timer(timer_aggravate_evil_callback,
- 10);
-
- return 0;
-}
-
-
-/*
- * Initialise town array
- */
-static errr init_towns(void)
-{
- int i = 0, j = 0;
-
- /*** Prepare the Towns ***/
-
- /* Allocate the towns */
- C_MAKE(town_info, max_towns, town_type);
-
- for (i = 1; i < max_towns; i++)
- {
- if (i <= max_real_towns) town_info[i].flags |= (TOWN_REAL);
-
- /* Allocate the stores */
- C_MAKE(town_info[i].store, max_st_idx, store_type);
-
- /* Fill in each store */
- for (j = 0; j < max_st_idx; j++)
- {
- /* Access the store */
- store_type *st_ptr = &town_info[i].store[j];
-
- /* Know who we are */
- st_ptr->st_idx = j;
-
- /* Assume full stock */
- st_ptr->stock_size = 0;
- }
- }
- return 0;
-}
-
-void create_stores_stock(int t)
-{
- int j;
- town_type *t_ptr = &town_info[t];
-
- if (t_ptr->stocked) return;
-
- for (j = 0; j < max_st_idx; j++)
- {
- store_type *st_ptr = &t_ptr->store[j];
-
- /* Assume full stock */
- st_ptr->stock_size = st_info[j].max_obj;
-
- /* Allocate the stock */
- C_MAKE(st_ptr->stock, st_ptr->stock_size, object_type);
- }
- t_ptr->stocked = TRUE;
-}
-
-/*
- * Pointer to wilderness_map
- */
-typedef wilderness_map *wilderness_map_ptr;
-
-/*
- * Initialise wilderness map array
- */
-static errr init_wilderness(void)
-{
- int i;
-
- /* Allocate the wilderness (two-dimension array) */
- C_MAKE(wild_map, max_wild_y, wilderness_map_ptr);
- C_MAKE(wild_map[0], max_wild_x * max_wild_y, wilderness_map);
-
- /* Init the other pointers */
- for (i = 1; i < max_wild_y; i++)
- wild_map[i] = wild_map[0] + i * max_wild_x;
-
- /* No encounter right now */
- generate_encounter = FALSE;
-
- return 0;
-}
-
-/*
- * Initialise some other arrays
- */
-static errr init_other(void)
-{
- int i, n;
-
- /*** Prepare the "dungeon" information ***/
-
- /* Allocate and Wipe the special gene flags */
- C_MAKE(m_allow_special, max_r_idx, bool_);
- C_MAKE(k_allow_special, max_k_idx, bool_);
- C_MAKE(a_allow_special, max_a_idx, bool_);
-
-
- /*** Prepare "vinfo" array ***/
-
- /* Used by "update_view()" */
- (void)vinfo_init();
-
-
- /* Allocate and Wipe the object list */
- C_MAKE(o_list, max_o_idx, object_type);
-
- /* Allocate and Wipe the monster list */
- C_MAKE(m_list, max_m_idx, monster_type);
-
- /* Allocate and Wipe the to keep monster list */
- C_MAKE(km_list, max_m_idx, monster_type);
-
- /* Allocate and Wipe the max dungeon level */
- C_MAKE(max_dlv, max_d_idx, s16b);
-
- /* Allocate and Wipe the special levels */
- for (i = 0; i < MAX_DUNGEON_DEPTH; i++)
- {
- C_MAKE(special_lvl[i], max_d_idx, bool_);
- }
-
- /* Allocate and wipe each line of the cave */
- for (i = 0; i < MAX_HGT; i++)
- {
- /* Allocate one row of the cave */
- C_MAKE(cave[i], MAX_WID, cave_type);
- }
-
- /*** Pre-allocate the basic "auto-inscriptions" ***/
-
- /* The "basic" feelings */
- (void)quark_add("cursed");
- (void)quark_add("broken");
- (void)quark_add("average");
- (void)quark_add("good");
-
- /* The "extra" feelings */
- (void)quark_add("excellent");
- (void)quark_add("worthless");
- (void)quark_add("special");
- (void)quark_add("terrible");
-
- /* Some extra strings */
- (void)quark_add("uncursed");
- (void)quark_add("on sale");
-
-
- /*** Prepare the options ***/
-
- /* Scan the options */
- for (i = 0; option_info[i].o_desc; i++)
- {
- int os = option_info[i].o_page;
- int ob = option_info[i].o_bit;
-
- /* Set the "default" options */
- if (option_info[i].o_var)
- {
- /* Accept */
- option_mask[os] |= (1L << ob);
-
- /* Set */
- if (option_info[i].o_norm)
- {
- /* Set */
- option_flag[os] |= (1L << ob);
- }
-
- /* Clear */
- else
- {
- /* Clear */
- option_flag[os] &= ~(1L << ob);
- }
- }
- }
-
- /* Analyze the windows */
- for (n = 0; n < 8; n++)
- {
- /* Analyze the options */
- for (i = 0; i < 32; i++)
- {
- /* Accept */
- if (window_flag_desc[i])
- {
- /* Accept */
- window_mask[n] |= (1L << i);
- }
- }
- }
-
-
- /*
- * Install the various level generators
- */
- add_level_generator("dungeon", level_generate_dungeon, TRUE, TRUE, TRUE, TRUE);
- add_level_generator("maze", level_generate_maze, TRUE, TRUE, TRUE, TRUE);
- add_level_generator("life", level_generate_life, TRUE, TRUE, TRUE, TRUE);
-
- /*** Pre-allocate space for the "format()" buffer ***/
-
- /* Hack -- Just call the "format()" function */
- (void)format("%s (%s).", "Dark God <darkgod@t-o-m-e.net>", MAINTAINER);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Initialise some other arrays
- */
-static errr init_alloc(void)
-{
- int i, j;
-
- object_kind *k_ptr;
-
- monster_race *r_ptr;
-
- alloc_entry *table;
-
- s16b num[MAX_DEPTH_MONSTER];
-
- s16b aux[MAX_DEPTH_MONSTER];
-
- /*** Analyze object allocation info ***/
-
- /* Clear the "aux" array */
- C_WIPE(&aux, MAX_DEPTH_MONSTER, s16b);
-
- /* Clear the "num" array */
- C_WIPE(&num, MAX_DEPTH_MONSTER, s16b);
-
- /* Size of "alloc_kind_table" */
- alloc_kind_size = 0;
-
- /* Scan the objects */
- for (i = 1; i < max_k_idx; i++)
- {
- k_ptr = &k_info[i];
-
- /* Scan allocation pairs */
- for (j = 0; j < 4; j++)
- {
- /* Count the "legal" entries */
- if (k_ptr->chance[j])
- {
- /* Count the entries */
- alloc_kind_size++;
-
- /* Group by level */
- num[k_ptr->locale[j]]++;
- }
- }
- }
-
- /* Collect the level indexes */
- for (i = 1; i < MAX_DEPTH_MONSTER; i++)
- {
- /* Group by level */
- num[i] += num[i - 1];
- }
-
- /* Paranoia */
- if (!num[0]) quit("No town objects!");
-
-
- /*** Initialise object allocation info ***/
-
- /* Allocate the alloc_kind_table */
- C_MAKE(alloc_kind_table, alloc_kind_size, alloc_entry);
-
- /* Access the table entry */
- table = alloc_kind_table;
-
- /* Scan the objects */
- for (i = 1; i < max_k_idx; i++)
- {
- k_ptr = &k_info[i];
-
- /* Scan allocation pairs */
- for (j = 0; j < 4; j++)
- {
- /* Count the "legal" entries */
- if (k_ptr->chance[j])
- {
- int p, x, y, z;
-
- /* Extract the base level */
- x = k_ptr->locale[j];
-
- /* Extract the base probability */
- p = (100 / k_ptr->chance[j]);
-
- /* Skip entries preceding our locale */
- y = (x > 0) ? num[x - 1] : 0;
-
- /* Skip previous entries at this locale */
- z = y + aux[x];
-
- /* Load the entry */
- table[z].index = i;
- table[z].level = x;
- table[z].prob1 = p;
- table[z].prob2 = p;
- table[z].prob3 = p;
-
- /* Another entry complete for this locale */
- aux[x]++;
- }
- }
- }
-
-
- /*** Analyze monster allocation info ***/
-
- /* Clear the "aux" array */
- C_WIPE(&aux, MAX_DEPTH_MONSTER, s16b);
-
- /* Clear the "num" array */
- C_WIPE(&num, MAX_DEPTH_MONSTER, s16b);
-
- /* Size of "alloc_race_table" */
- alloc_race_size = 0;
-
- /* Scan the monsters */
- for (i = 1; i < max_r_idx; i++)
- {
- /* Get the i'th race */
- r_ptr = &r_info[i];
-
- /* Legal monsters */
- if (r_ptr->rarity)
- {
- /* Count the entries */
- alloc_race_size++;
-
- /* Group by level */
- num[r_ptr->level]++;
- }
- }
-
- /* Collect the level indexes */
- for (i = 1; i < MAX_DEPTH_MONSTER; i++)
- {
- /* Group by level */
- num[i] += num[i - 1];
- }
-
- /* Paranoia */
- if (!num[0]) quit("No town monsters!");
-
-
- /*** Initialise monster allocation info ***/
-
- /* Allocate the alloc_race_table */
- C_MAKE(alloc_race_table, alloc_race_size, alloc_entry);
-
- /* Access the table entry */
- table = alloc_race_table;
-
- /* Scan the monsters */
- for (i = 1; i < max_r_idx; i++)
- {
- /* Get the i'th race */
- r_ptr = &r_info[i];
-
- /* Count valid pairs */
- if (r_ptr->rarity)
- {
- int p, x, y, z;
-
- /* Extract the base level */
- x = r_ptr->level;
-
- /* Extract the base probability */
- p = (100 / r_ptr->rarity);
-
- /* Skip entries preceding our locale */
- y = (x > 0) ? num[x - 1] : 0;
-
- /* Skip previous entries at this locale */
- z = y + aux[x];
-
- /* Load the entry */
- table[z].index = i;
- table[z].level = x;
- table[z].prob1 = p;
- table[z].prob2 = p;
- table[z].prob3 = p;
-
- /* Another entry complete for this locale */
- aux[x]++;
- }
- }
-
-
- /* Success */
- return (0);
-}
-
-/* Init the sets in a_info */
-void init_sets_aux()
-{
- int i, j;
-
- for (i = 0; i < max_a_idx; i++)
- a_info[i].set = -1;
- for (i = 0; i < max_set_idx; i++)
- {
- for (j = 0; j < set_info[i].num; j++)
- {
- a_info[set_info[i].arts[j].a_idx].set = i;
- }
- }
-}
-
-/*
- * Mark guardians and their artifacts with SPECIAL_GENE flag
- */
-static void init_guardians(void)
-{
- int i;
-
- /* Scan dungeons */
- for (i = 0; i < max_d_idx; i++)
- {
- dungeon_info_type *d_ptr = &d_info[i];
-
- /* Mark the guadian monster */
- if (d_ptr->final_guardian)
- {
- monster_race *r_ptr = &r_info[d_ptr->final_guardian];
-
- r_ptr->flags9 |= RF9_SPECIAL_GENE;
-
- /* Mark the final artifact */
- if (d_ptr->final_artifact)
- {
- artifact_type *a_ptr = &a_info[d_ptr->final_artifact];
-
- a_ptr->flags4 |= TR4_SPECIAL_GENE;
- }
-
- /* Mark the final object */
- if (d_ptr->final_object)
- {
- object_kind *k_ptr = &k_info[d_ptr->final_object];
-
- k_ptr->flags4 |= TR4_SPECIAL_GENE;
- }
-
- /* Give randart if there are no final artifacts */
- if (!(d_ptr->final_artifact) && !(d_ptr->final_object))
- {
- r_ptr->flags7 |= RF7_DROP_RANDART;
- }
- }
- }
-}
-
-/*
- * Hack -- Explain a broken "lib" folder and quit (see below).
- *
- * XXX XXX XXX This function is "messy" because various things
- * may or may not be initialised, but the "plog()" and "quit()"
- * functions are "supposed" to work under any conditions.
- */
-static void init_angband_aux(cptr why)
-{
- /* Why */
- plog(why);
-
- /* Explain */
- plog("The 'lib' directory is probably missing or broken.");
-
- /* More details */
- plog("Perhaps the archive was not extracted correctly.");
-
- /* Explain */
- plog("See the 'README' file for more information.");
-
- /* Quit with error */
- quit("Fatal Error.");
-}
-
-/*
- * Hack -- main Angband initialisation entry point
- *
- * Verify some files, display the "news.txt" file, create
- * the high score file, initialise all internal arrays, and
- * load the basic "user pref files".
- *
- * Note that we blindly assume that "news2.txt" exists. XXX
- *
- * Be very careful to keep track of the order in which things
- * are initialised, in particular, the only thing *known* to
- * be available when this function is called is the "z-term.c"
- * package, and that may not be fully initialised until the
- * end of this function, when the default "user pref files"
- * are loaded and "Term_xtra(TERM_XTRA_REACT,0)" is called.
- *
- * Note that this function attempts to verify the "news" file,
- * and the game aborts (cleanly) on failure, since without the
- * "news" file, it is likely that the "lib" folder has not been
- * correctly located. Otherwise, the news file is displayed for
- * the user.
- *
- * Note that this function attempts to verify (or create) the
- * "high score" file, and the game aborts (cleanly) on failure,
- * since one of the most common "extraction" failures involves
- * failing to extract all sub-directories (even empty ones), such
- * as by failing to use the "-d" option of "pkunzip", or failing
- * to use the "save empty directories" option with "Compact Pro".
- * This error will often be caught by the "high score" creation
- * code below, since the "lib/apex" directory, being empty in the
- * standard distributions, is most likely to be "lost", making it
- * impossible to create the high score file.
- *
- * Note that various things are initialised by this function,
- * including everything that was once done by "init_some_arrays".
- *
- * This initialisation involves the parsing of special files
- * in the "lib/data" and sometimes the "lib/edit" directories.
- *
- * Note that the "template" files are initialised first, since they
- * often contain errors. This means that macros and message recall
- * and things like that are not available until after they are done.
- *
- * We load the default "user pref files" here in case any "color"
- * changes are needed before character creation.
- *
- * Note that the "graf-xxx.prf" file must be loaded separately,
- * if needed, in the first (?) pass through "TERM_XTRA_REACT".
- */
-void init_angband(void)
-{
- int fd = -1;
-
- int mode = FILE_MODE;
-
- FILE *fp;
-
- char *news_file;
-
- char buf[1024];
-
- /* Init some VERY basic stuff, like macro arrays */
- init_basic();
-
- /* Select & init a module if needed */
- select_module();
-
- /*** Choose which news.txt file to use ***/
-
- /* Choose the news file */
- switch (time(NULL) % 2)
- {
- default:
- {
- news_file = "news.txt";
- break;
- }
-
- case 0:
- {
- news_file = "news2.txt";
- break;
- }
- }
-
- /*** Verify the "news" file ***/
-
- /* Build the filename */
- path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, news_file);
-
- /* Attempt to open the file */
- fd = fd_open(buf, O_RDONLY);
-
- /* Failure */
- if (fd < 0)
- {
- char why[1024];
-
- /* Message */
- sprintf(why, "Cannot access the '%s' file!", buf);
-
- /* Crash and burn */
- init_angband_aux(why);
- }
-
- /* Close it */
- (void)fd_close(fd);
-
-
- /*** Display the "news" file ***/
-
- /* Clear screen */
- Term_clear();
-
- /* Build the filename */
- path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, news_file);
-
- /* Open the News file */
- fp = my_fopen(buf, "r");
-
- /* Dump */
- if (fp)
- {
- int i = 0;
-
- /* Dump the file to the screen */
- while (0 == my_fgets(fp, buf, 1024))
- {
- /* Display and advance - we use display_message to parse colour codes XXX */
- display_message(0, i++, strlen(buf), TERM_WHITE, buf);
- }
-
- /* Close */
- my_fclose(fp);
- }
-
- /* Flush it */
- Term_fresh();
-
-
- /*** Verify (or create) the "high score" file ***/
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw");
-
- /* Attempt to open the high score file */
- fd = fd_open(buf, O_RDONLY);
-
- /* Failure */
- if (fd < 0)
- {
- /* File type is "DATA" */
- FILE_TYPE(FILE_TYPE_DATA);
-
- /* Create a new high score file */
- fd = fd_make(buf, mode);
-
- /* Failure */
- if (fd < 0)
- {
- char why[1024];
-
- /* Message */
- sprintf(why, "Cannot create the '%s' file!", buf);
-
- /* Crash and burn */
- init_angband_aux(why);
- }
- }
-
- /* Close it */
- (void)fd_close(fd);
-
-
- /*** Initialise some arrays ***/
-
- /* Initialise misc. values */
- note("[Initialising values... (misc)]");
- if (init_misc()) quit("Cannot initialise misc. values");
-
- wipe_hooks();
-
- /* Initialise some other arrays */
- note("[Initialising scripting... (script)]");
- init_lua_init();
-
- /* Initialise skills info */
- note("[Initialising arrays... (skills)]");
- if (init_s_info()) quit("Cannot initialise skills");
-
- /* Initialise abilities info */
- note("[Initialising arrays... (abilities)]");
- if (init_ab_info()) quit("Cannot initialise abilities");
-
- /* Initialise alchemy info */
- note("[Initialising arrays... (alchemy)]");
- if (init_al_info()) quit("Cannot initialise alchemy");
-
- /* Initialise player info */
- note("[Initialising arrays... (players)]");
- if (init_player_info()) quit("Cannot initialise players");
-
- /* Initialise feature info */
- note("[Initialising arrays... (features)]");
- if (init_f_info()) quit("Cannot initialise features");
-
- /* Initialise object info */
- note("[Initialising arrays... (objects)]");
- if (init_k_info()) quit("Cannot initialise objects");
-
- /* Initialise artifact info */
- note("[Initialising arrays... (artifacts)]");
- if (init_a_info()) quit("Cannot initialise artifacts");
-
- /* Initialise set info */
- note("[Initialising item sets... (sets)]");
- if (init_set_info()) quit("Cannot initialise item sets");
- init_sets_aux();
-
- /* Initialise ego-item info */
- note("[Initialising arrays... (ego-items)]");
- if (init_e_info()) quit("Cannot initialise ego-items");
-
- /* Initialise randart parts info */
- note("[Initialising arrays... (randarts)]");
- if (init_ra_info()) quit("Cannot initialise randarts");
-
- /* Initialise monster info */
- note("[Initialising arrays... (monsters)]");
- if (init_r_info()) quit("Cannot initialise monsters");
-
- /* Initialise ego monster info */
- note("[Initialising arrays... (ego monsters)]");
- if (init_re_info()) quit("Cannot initialise ego monsters");
-
- /* Initialise dungeon type info */
- note("[Initialising arrays... (dungeon types)]");
- if (init_d_info()) quit("Cannot initialise dungeon types");
- init_guardians();
-
- /* Initialise actions type info */
- note("[Initialising arrays... (action types)]");
- if (init_ba_info()) quit("Cannot initialise action types");
-
- /* Initialise owners type info */
- note("[Initialising arrays... (owners types)]");
- if (init_ow_info()) quit("Cannot initialise owners types");
-
- /* Initialise stores type info */
- note("[Initialising arrays... (stores types)]");
- if (init_st_info()) quit("Cannot initialise stores types");
-
- /* Initialise wilderness features array */
- note("[Initialising arrays... (wilderness features)]");
- if (init_wf_info()) quit("Cannot initialise wilderness features");
-
- /* Initialise wilderness map array */
- note("[Initialising arrays... (wilderness map)]");
- if (init_wilderness()) quit("Cannot initialise wilderness map");
-
- /* Initialise town array */
- note("[Initialising arrays... (towns)]");
- if (init_towns()) quit("Cannot initialise towns");
-
- /* Initialise trap info */
- note("[Initialising arrays... (traps)]");
- if (init_t_info()) quit("Cannot initialise traps");
-
- /* Initialise some other arrays */
- note("[Initialising arrays... (other)]");
- if (init_other()) quit("Cannot initialise other stuff");
-
- /* Initialise some other arrays */
- note("[Initialising arrays... (alloc)]");
- if (init_alloc()) quit("Cannot initialise alloc stuff");
-
- /* Init random artifact names */
- build_prob(artifact_names_list);
-
- /*** Load default user pref files ***/
-
- /* Initialise feature info */
- note("[Initialising user pref files...]");
-
- /* Access the "basic" pref file */
- strcpy(buf, "pref.prf");
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "basic" system pref file */
- sprintf(buf, "pref-%s.prf", ANGBAND_SYS);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "user" pref file */
- sprintf(buf, "user.prf");
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Access the "user" system pref file */
- sprintf(buf, "user-%s.prf", ANGBAND_SYS);
-
- /* Process that file */
- process_pref_file(buf);
-
- /* Initialise the automatizer */
- path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "automat.atm");
- automatizer_init(buf);
-
- /* Done */
- note("[Initialisation complete]");
-
- process_hooks(HOOK_INIT_GAME, "(s)", "end");
-}
diff --git a/src/init2.cc b/src/init2.cc
new file mode 100644
index 00000000..f80b832a
--- /dev/null
+++ b/src/init2.cc
@@ -0,0 +1,1525 @@
+#include "init2.hpp"
+#include "init2.h"
+
+#include "ability_type.hpp"
+#include "alchemist_recipe.hpp"
+#include "alloc_entry.hpp"
+#include "artifact_select_flag.hpp"
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cli_comm.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "files.hpp"
+#include "feature_type.hpp"
+#include "generate.hpp"
+#include "gen_evol.hpp"
+#include "gen_maze.hpp"
+#include "hist_type.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "lua_bind.hpp"
+#include "messages.hpp"
+#include "meta_class_type.hpp"
+#include "modules.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object_kind.hpp"
+#include "owner_type.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "quark.hpp"
+#include "randart.hpp"
+#include "randart_part_type.hpp"
+#include "script.h"
+#include "set_type.hpp"
+#include "skill_type.hpp"
+#include "spells3.hpp"
+#include "squeltch.hpp"
+#include "store_action_type.hpp"
+#include "store_info_type.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "tome/make_array.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "vault_type.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+
+#include <cassert>
+#include <type_traits>
+
+/*
+ * This file is used to initialise various variables and arrays for the
+ * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass
+ * the common limitation of "read()" and "write()" to only 32767 bytes
+ * at a time.
+ *
+ * Several of the arrays for Angband are built from "template" files in
+ * the "lib/file" directory, from which quick-load binary "image" files
+ * are constructed whenever they are not present in the "lib/data"
+ * directory, or if those files become obsolete, if we are allowed.
+ *
+ * Warning -- the "ascii" file parsers use a minor hack to collect the
+ * name and text information in a single pass. Thus, the game will not
+ * be able to load any template file with more than 20K of names or 60K
+ * of text, even though technically, up to 64K should be legal.
+ *
+ * The "init1.c" file is used only to parse the ascii template files.
+ */
+
+
+
+/*
+ * Find the default paths to all of our important sub-directories.
+ *
+ * The purpose of each sub-directory is described in "variable.c".
+ *
+ * All of the sub-directories should, by default, be located inside
+ * the main "lib" directory, whose location is very system dependant.
+ *
+ * This function takes a writable buffer, initially containing the
+ * "path" to the "lib" directory, for example, "/pkg/lib/angband/",
+ * or a system dependant string, for example, ":lib:". The buffer
+ * must be large enough to contain at least 32 more characters.
+ *
+ * Various command line options may allow some of the important
+ * directories to be changed to user-specified directories, most
+ * importantly, the "info" and "user" and "save" directories,
+ * but this is done after this function, see "main.c".
+ *
+ * In general, the initial path should end in the appropriate "PATH_SEP"
+ * string. All of the "sub-directory" paths (created below or supplied
+ * by the user) will NOT end in the "PATH_SEP" string, see the special
+ * "path_build()" function in "util.c" for more information.
+ *
+ * Mega-Hack -- support fat raw files under NEXTSTEP, using special
+ * "suffixed" directories for the "ANGBAND_DIR_DATA" directory, but
+ * requiring the directories to be created by hand by the user.
+ *
+ * Hack -- first we free all the strings, since this is known
+ * to succeed even if the strings have not been allocated yet,
+ * as long as the variables start out as "NULL". This allows
+ * this function to be called multiple times, for example, to
+ * try several base "path" values until a good one is found.
+ */
+void init_file_paths(char *path)
+{
+ char *tail;
+ int pathlen;
+
+ assert(path != nullptr);
+
+ /*** Free everything ***/
+
+ /* Free the main path */
+ free(ANGBAND_DIR);
+
+ /* Free the sub-paths */
+ free(ANGBAND_DIR_CORE);
+ free(ANGBAND_DIR_DNGN);
+ free(ANGBAND_DIR_DATA);
+ free(ANGBAND_DIR_EDIT);
+ free(ANGBAND_DIR_FILE);
+ free(ANGBAND_DIR_HELP);
+ free(ANGBAND_DIR_INFO);
+ free(ANGBAND_DIR_MODULES);
+ free(ANGBAND_DIR_NOTE);
+ free(ANGBAND_DIR_SAVE);
+ free(ANGBAND_DIR_PREF);
+ free(ANGBAND_DIR_USER);
+ free(ANGBAND_DIR_XTRA);
+
+
+ /*** Prepare the "path" ***/
+
+ pathlen = strlen(path);
+
+ /* Hack -- save the main directory without trailing PATH_SEP if present */
+ if (strlen(PATH_SEP) > 0 && pathlen > 0)
+ {
+ int seplen = strlen(PATH_SEP);
+
+ if (strcmp(path + pathlen - seplen, PATH_SEP) == 0)
+ {
+ path[pathlen - seplen] = '\0';
+ ANGBAND_DIR = strdup(path);
+ path[pathlen - seplen] = *PATH_SEP;
+ }
+ else
+ {
+ ANGBAND_DIR = strdup(path);
+ }
+ }
+ else
+ {
+ ANGBAND_DIR = strdup(path);
+ }
+
+ /* Prepare to append to the Base Path */
+ tail = path + pathlen;
+
+
+
+ /*** Build the sub-directory names ***/
+
+ /* Build a path name */
+ strcpy(tail, "core");
+ ANGBAND_DIR_CORE = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "dngn");
+ ANGBAND_DIR_DNGN = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "data");
+ ANGBAND_DIR_DATA = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "edit");
+ ANGBAND_DIR_EDIT = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "file");
+ ANGBAND_DIR_FILE = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "help");
+ ANGBAND_DIR_HELP = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "info");
+ ANGBAND_DIR_INFO = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "mods");
+ ANGBAND_DIR_MODULES = strdup(path);
+
+ /* Build a path name */
+ strcpy(tail, "pref");
+ ANGBAND_DIR_PREF = strdup(path);
+
+ /* synchronize with module_reset_dir */
+ {
+ char user_path[1024];
+
+ /* Get an absolute path from the file name */
+ path_parse(user_path, 1024, PRIVATE_USER_PATH);
+ strcat(user_path, USER_PATH_VERSION);
+ ANGBAND_DIR_USER = strdup(user_path);
+ ANGBAND_DIR_NOTE = strdup(user_path);
+
+ /* Savefiles are in user directory */
+ strcat(user_path, "/save");
+ ANGBAND_DIR_SAVE = strdup(user_path);
+ }
+
+ /* Build a path name */
+ strcpy(tail, "xtra");
+ ANGBAND_DIR_XTRA = strdup(path);
+}
+
+
+
+/*
+ * Initialize and verify the file paths, and the score file.
+ *
+ * Use the ANGBAND_PATH environment var if possible, else use
+ * DEFAULT_PATH, and in either case, branch off appropriately.
+ *
+ * First, we'll look for the ANGBAND_PATH environment variable,
+ * and then look for the files in there. If that doesn't work,
+ * we'll try the DEFAULT_PATH constant. So be sure that one of
+ * these two things works...
+ *
+ * We must ensure that the path ends with "PATH_SEP" if needed,
+ * since the "init_file_paths()" function will simply append the
+ * relevant "sub-directory names" to the given path.
+ */
+void init_file_paths_with_env()
+{
+ char path[1024];
+
+ cptr tail;
+
+ /* Get the environment variable */
+ tail = getenv("TOME_PATH");
+
+ /* Use the angband_path, or a default */
+ strcpy(path, tail ? tail : DEFAULT_PATH);
+
+ /* Hack -- Add a path separator (only if needed) */
+ if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
+
+ /* Initialize */
+ init_file_paths(path);
+}
+
+
+/*
+ * Hack -- help give useful error messages
+ */
+s16b error_idx;
+s16b error_line;
+
+
+/*
+ * Standard error message text
+ */
+static cptr err_str[9] =
+{
+ NULL,
+ "parse error",
+ "obsolete file",
+ "missing record header",
+ "non-sequential records",
+ "invalid flag specification",
+ "undefined directive",
+ "out of memory",
+ "invalid skill chart"
+};
+
+
+/*
+ * Hack -- take notes on line 23
+ */
+static void note(cptr str)
+{
+ Term_erase(0, 23, 255);
+ Term_putstr(20, 23, -1, TERM_WHITE, str);
+ Term_fresh();
+}
+
+
+/*
+ * Traits for data arrays
+ */
+namespace {
+
+ struct f_info_traits {
+
+ static constexpr char const *name = "f_info.txt";
+
+ static void allocate()
+ {
+ f_info = make_array<feature_type>(max_f_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_f_info_txt(fp);
+ }
+
+ };
+
+ struct k_info_traits {
+
+ static constexpr char const *name = "k_info.txt";
+
+ static void allocate()
+ {
+ k_info = make_array<object_kind>(max_k_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_k_info_txt(fp);
+ };
+
+ };
+
+ struct set_info_traits {
+
+ static constexpr char const *name = "set_info.txt";
+
+ static void allocate()
+ {
+ set_info = make_array<set_type>(max_set_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_set_info_txt(fp);
+ }
+
+ };
+
+ struct a_info_traits {
+
+ static constexpr char const *name = "a_info.txt";
+
+ static void allocate()
+ {
+ a_info = make_array<artifact_type>(max_a_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_a_info_txt(fp);
+ }
+
+ };
+
+ struct s_info_traits {
+
+ static constexpr char const *name = "s_info.txt";
+
+ static void allocate()
+ {
+ s_info = make_array<skill_type>(max_s_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_s_info_txt(fp);
+ }
+
+ };
+
+ struct ab_info_traits {
+
+ static constexpr char const *name = "ab_info.txt";
+
+ static void allocate()
+ {
+ ab_info = make_array<ability_type>(max_ab_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_ab_info_txt(fp);
+ }
+
+ };
+
+ struct e_info_traits {
+
+ static constexpr char const *name = "e_info.txt";
+
+ static void allocate()
+ {
+ e_info = make_array<ego_item_type>(max_e_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_e_info_txt(fp);
+ }
+
+ };
+
+ struct ra_info_traits {
+
+ static constexpr char const *name = "ra_info.txt";
+
+ static void allocate()
+ {
+ ra_info = make_array<randart_part_type>(max_ra_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_ra_info_txt(fp);
+ }
+
+ };
+
+ struct r_info_traits {
+
+ static constexpr char const *name = "r_info.txt";
+
+ static void allocate()
+ {
+ r_info = make_array<monster_race>(max_r_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_r_info_txt(fp);
+ }
+
+ };
+
+ struct re_info_traits {
+
+ static constexpr char const *name = "re_info.txt";
+
+ static void allocate()
+ {
+ re_info = make_array<monster_ego>(max_re_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_re_info_txt(fp);
+ }
+
+ };
+
+ struct d_info_traits {
+
+ static constexpr char const *name = "d_info.txt";
+
+ static void allocate()
+ {
+ d_info = make_array<dungeon_info_type>(max_d_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_d_info_txt(fp);
+ }
+
+ };
+
+ struct st_info_traits {
+
+ static constexpr char const *name = "st_info.txt";
+
+ static void allocate()
+ {
+ st_info = make_array<store_info_type>(max_st_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_st_info_txt(fp);
+ }
+
+ };
+
+ struct ow_info_traits {
+
+ static constexpr char const *name = "ow_info.txt";
+
+ static void allocate()
+ {
+ ow_info = make_array<owner_type>(max_ow_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_ow_info_txt(fp);
+ }
+
+ };
+
+ struct ba_info_traits {
+
+ static constexpr char const *name = "ba_info.txt";
+
+ static void allocate()
+ {
+ ba_info = make_array<store_action_type>(max_ba_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_ba_info_txt(fp);
+ }
+
+ };
+
+ struct wf_info_traits {
+
+ static constexpr char const *name = "wf_info.txt";
+
+ static void allocate()
+ {
+ wf_info = make_array<wilderness_type_info>(max_wf_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_wf_info_txt(fp);
+ }
+
+ };
+
+ struct tr_info_traits {
+
+ static constexpr char const *name = "tr_info.txt";
+
+ static void allocate()
+ {
+ t_info = make_array<trap_type>(max_t_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_t_info_txt(fp);
+ }
+
+ };
+
+ struct v_info_traits {
+
+ static constexpr char const *name = "v_info.txt";
+
+ static void allocate()
+ {
+ v_info = make_array<vault_type>(max_v_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_v_info_txt(fp);
+ }
+
+ };
+
+ struct p_info_traits {
+
+ static constexpr char const *name = "p_info.txt";
+
+ static void allocate()
+ {
+ race_info = make_array<player_race>(max_rp_idx);
+ race_mod_info = make_array<player_race_mod>(max_rmp_idx);
+ class_info = make_array<player_class>(max_c_idx);
+ bg = make_array<hist_type>(max_bg_idx);
+ meta_class_info = make_array<meta_class_type>(max_mc_idx);
+ for (std::size_t i = 0; i < max_mc_idx; i++)
+ {
+ meta_class_info[i].classes = make_array<s16b>(max_c_idx);
+ }
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_player_info_txt(fp);
+ }
+
+ };
+
+ struct al_info_traits {
+
+ static constexpr char const *name = "al_info.txt";
+
+ static void allocate()
+ {
+ alchemist_recipes = make_array<alchemist_recipe>(max_al_idx);
+ a_select_flags = make_array<artifact_select_flag>(max_al_idx);
+ }
+
+ static errr parse(FILE *fp)
+ {
+ return init_al_info_txt(fp);
+ }
+
+ };
+
+}
+
+template<typename T> static errr init_x_info() {
+
+ /* Allocate the data array */
+ T::allocate();
+
+ /* Build the filename */
+ boost::filesystem::path path(ANGBAND_DIR_EDIT);
+ path /= T::name;
+
+ /* Open the file */
+ FILE *fp = my_fopen(path.c_str(), "r");
+
+ /* Parse it */
+ if (!fp)
+ {
+ quit_fmt("Cannot open '%s' file.", T::name);
+ }
+
+ /* Parse the file */
+ errr err = T::parse(fp);
+
+ /* Close it */
+ my_fclose(fp);
+
+ /* Errors */
+ if (err)
+ {
+ /* Error string */
+ cptr oops = (((err > 0) && (err < 8)) ? err_str[err] : "unknown");
+
+ /* Oops */
+ msg_format("Error %d at line %d of '%s'.", err, error_line, T::name);
+ msg_format("Record %d contains a '%s' error.", error_idx, oops);
+ msg_print(NULL);
+
+ /* Quit */
+ quit_fmt("Error in '%s' file.", T::name);
+ }
+
+ /* Success */
+ return (0);
+}
+
+errr init_v_info()
+{
+ return init_x_info<v_info_traits>();
+}
+
+/*
+ * Initialize the very basic arrays
+ */
+static void init_basic()
+{
+ /* Macro variables */
+ macro__pat = make_array<char *>(MACRO_MAX);
+ macro__act = make_array<char *>(MACRO_MAX);
+ macro__cmd = make_array<bool_>(MACRO_MAX);
+
+ /* Macro action buffer */
+ macro__buf = make_array<char>(1024);
+
+ /* Extended trigger macros */
+ cli_info = make_array<cli_comm>(CLI_MAX);
+}
+
+
+/*
+ * Initialise misc. values
+ */
+static errr init_misc(void)
+{
+ int xstart = 0;
+ int ystart = 0;
+ int i;
+
+ /*** Prepare the various "bizarre" arrays ***/
+
+ /* Initialize quark subsystem */
+ quark_init();
+
+ /* Initialize messages subsystem */
+ message_init();
+
+ /* Initialise the values */
+ process_dungeon_file("misc.txt", &ystart, &xstart, 0, 0, TRUE, FALSE);
+
+ /* Init the spell effects */
+ for (i = 0; i < MAX_EFFECTS; i++)
+ effects[i].time = 0;
+
+ /* Initialize timers */
+ TIMER_INERTIA_CONTROL =
+ new_timer(meta_inertia_control_timer_callback,
+ 10);
+ TIMER_AGGRAVATE_EVIL =
+ new_timer(timer_aggravate_evil_callback,
+ 10);
+
+ return 0;
+}
+
+
+/*
+ * Initialise town array
+ */
+static errr init_towns(void)
+{
+ int i = 0, j = 0;
+
+ /*** Prepare the Towns ***/
+
+ /* Allocate the towns */
+ town_info = make_array<town_type>(max_towns);
+
+ for (i = 1; i < max_towns; i++)
+ {
+ if (i <= max_real_towns) town_info[i].flags |= (TOWN_REAL);
+
+ /* Allocate the stores */
+ town_info[i].store = make_array<store_type>(max_st_idx);
+
+ /* Fill in each store */
+ for (j = 0; j < max_st_idx; j++)
+ {
+ /* Access the store */
+ store_type *st_ptr = &town_info[i].store[j];
+
+ /* Know who we are */
+ st_ptr->st_idx = j;
+
+ /* Assume full stock */
+ st_ptr->stock_size = 0;
+ }
+ }
+ return 0;
+}
+
+void create_stores_stock(int t)
+{
+ int j;
+ town_type *t_ptr = &town_info[t];
+
+ if (t_ptr->stocked) return;
+
+ for (j = 0; j < max_st_idx; j++)
+ {
+ store_type *st_ptr = &t_ptr->store[j];
+
+ /* Assume full stock */
+ st_ptr->stock_size = st_info[j].max_obj;
+
+ /* Allocate the stock */
+ st_ptr->stock = make_array<object_type>(st_ptr->stock_size);
+ }
+ t_ptr->stocked = TRUE;
+}
+
+/*
+ * Pointer to wilderness_map
+ */
+typedef wilderness_map *wilderness_map_ptr;
+
+/*
+ * Initialise wilderness map array
+ */
+static errr init_wilderness(void)
+{
+ int i;
+
+ /* Allocate the wilderness (two-dimension array) */
+ wild_map = make_array<wilderness_map *>(max_wild_y);
+
+ /* Init the other pointers */
+ for (i = 0; i < max_wild_y; i++)
+ {
+ wild_map[i] = make_array<wilderness_map>(max_wild_x);
+ }
+
+ /* No encounter right now */
+ generate_encounter = FALSE;
+
+ return 0;
+}
+
+/*
+ * Initialise some other arrays
+ */
+static errr init_other(void)
+{
+ int i, n;
+
+ /*** Prepare the "dungeon" information ***/
+
+ /* Allocate and Wipe the special gene flags */
+ m_allow_special = make_array<bool_>(max_r_idx);
+ k_allow_special = make_array<bool_>(max_k_idx);
+ a_allow_special = make_array<bool_>(max_a_idx);
+
+
+ /*** Prepare "vinfo" array ***/
+
+ /* Used by "update_view()" */
+ (void)vinfo_init();
+
+
+ /* Allocate and Wipe the object list */
+ o_list = make_array<object_type>(max_o_idx);
+
+ /* Allocate and Wipe the monster list */
+ m_list = new monster_type[max_m_idx];
+
+ /* Allocate and Wipe the to keep monster list */
+ km_list = new monster_type[max_m_idx];
+
+ /* Allocate and Wipe the max dungeon level */
+ max_dlv = make_array<s16b>(max_d_idx);
+
+ /* Allocate and Wipe the special levels */
+ for (i = 0; i < MAX_DUNGEON_DEPTH; i++)
+ {
+ special_lvl[i] = make_array<bool_>(max_d_idx);
+ }
+
+ /* Allocate and wipe each line of the cave */
+ cave = new cave_type *[MAX_HGT];
+ for (i = 0; i < MAX_HGT; i++)
+ {
+ /* Allocate one row of the cave */
+ cave[i] = new cave_type[MAX_WID];
+ }
+
+ /*** Pre-allocate the basic "auto-inscriptions" ***/
+
+ /* The "basic" feelings */
+ (void)quark_add("cursed");
+ (void)quark_add("broken");
+ (void)quark_add("average");
+ (void)quark_add("good");
+
+ /* The "extra" feelings */
+ (void)quark_add("excellent");
+ (void)quark_add("worthless");
+ (void)quark_add("special");
+ (void)quark_add("terrible");
+
+ /* Some extra strings */
+ (void)quark_add("uncursed");
+ (void)quark_add("on sale");
+
+
+ /*** Prepare the options ***/
+
+ /* Scan the options */
+ for (i = 0; option_info[i].o_desc; i++)
+ {
+ int os = option_info[i].o_page;
+ int ob = option_info[i].o_bit;
+
+ /* Set the "default" options */
+ if (option_info[i].o_var)
+ {
+ /* Accept */
+ option_mask[os] |= (1L << ob);
+
+ /* Set */
+ if (option_info[i].o_norm)
+ {
+ /* Set */
+ option_flag[os] |= (1L << ob);
+ }
+
+ /* Clear */
+ else
+ {
+ /* Clear */
+ option_flag[os] &= ~(1L << ob);
+ }
+ }
+ }
+
+ /* Analyze the windows */
+ for (n = 0; n < 8; n++)
+ {
+ /* Analyze the options */
+ for (i = 0; i < 32; i++)
+ {
+ /* Accept */
+ if (window_flag_desc[i])
+ {
+ /* Accept */
+ window_mask[n] |= (1L << i);
+ }
+ }
+ }
+
+
+ /*
+ * Install the various level generators
+ */
+ add_level_generator("dungeon", level_generate_dungeon);
+ add_level_generator("maze", level_generate_maze);
+ add_level_generator("life", level_generate_life);
+
+ /*** Pre-allocate space for the "format()" buffer ***/
+
+ /* Hack -- Just call the "format()" function */
+ (void)format("%s (%s).", "Dark God <darkgod@t-o-m-e.net>", MAINTAINER);
+
+ /* Success */
+ return (0);
+}
+
+
+
+/*
+ * Initialise some other arrays
+ */
+static errr init_alloc(void)
+{
+ int i, j;
+
+ object_kind *k_ptr;
+
+ monster_race *r_ptr;
+
+ alloc_entry *table;
+
+ s16b num[MAX_DEPTH_MONSTER];
+
+ s16b aux[MAX_DEPTH_MONSTER];
+
+ /*** Analyze object allocation info ***/
+
+ /* Clear the "aux" array */
+ memset(aux, 0, MAX_DEPTH_MONSTER * sizeof(s16b));
+
+ /* Clear the "num" array */
+ memset(num, 0, MAX_DEPTH_MONSTER * sizeof(s16b));
+
+ /* Size of "alloc_kind_table" */
+ alloc_kind_size = 0;
+
+ /* Scan the objects */
+ for (i = 1; i < max_k_idx; i++)
+ {
+ k_ptr = &k_info[i];
+
+ /* Scan allocation pairs */
+ for (j = 0; j < ALLOCATION_MAX; j++)
+ {
+ /* Count the "legal" entries */
+ if (k_ptr->chance[j])
+ {
+ /* Count the entries */
+ alloc_kind_size++;
+
+ /* Group by level */
+ num[k_ptr->locale[j]]++;
+ }
+ }
+ }
+
+ /* Collect the level indexes */
+ for (i = 1; i < MAX_DEPTH_MONSTER; i++)
+ {
+ /* Group by level */
+ num[i] += num[i - 1];
+ }
+
+ /* Paranoia */
+ if (!num[0]) quit("No town objects!");
+
+
+ /*** Initialise object allocation info ***/
+
+ /* Allocate the alloc_kind_table */
+ alloc_kind_table = make_array<alloc_entry>(alloc_kind_size);
+
+ /* Access the table entry */
+ table = alloc_kind_table;
+
+ /* Scan the objects */
+ for (i = 1; i < max_k_idx; i++)
+ {
+ k_ptr = &k_info[i];
+
+ /* Scan allocation pairs */
+ for (j = 0; j < ALLOCATION_MAX; j++)
+ {
+ /* Count the "legal" entries */
+ if (k_ptr->chance[j])
+ {
+ int p, x, y, z;
+
+ /* Extract the base level */
+ x = k_ptr->locale[j];
+
+ /* Extract the base probability */
+ p = (100 / k_ptr->chance[j]);
+
+ /* Skip entries preceding our locale */
+ y = (x > 0) ? num[x - 1] : 0;
+
+ /* Skip previous entries at this locale */
+ z = y + aux[x];
+
+ /* Load the entry */
+ table[z].index = i;
+ table[z].level = x;
+ table[z].prob1 = p;
+ table[z].prob2 = p;
+ table[z].prob3 = p;
+
+ /* Another entry complete for this locale */
+ aux[x]++;
+ }
+ }
+ }
+
+
+ /*** Analyze monster allocation info ***/
+
+ /* Clear the "aux" array */
+ memset(aux, 0, MAX_DEPTH_MONSTER * sizeof(s16b));
+
+ /* Clear the "num" array */
+ memset(num, 0, MAX_DEPTH_MONSTER * sizeof(s16b));
+
+ /* Size of "alloc_race_table" */
+ alloc_race_size = 0;
+
+ /* Scan the monsters */
+ for (i = 1; i < max_r_idx; i++)
+ {
+ /* Get the i'th race */
+ r_ptr = &r_info[i];
+
+ /* Legal monsters */
+ if (r_ptr->rarity)
+ {
+ /* Count the entries */
+ alloc_race_size++;
+
+ /* Group by level */
+ num[r_ptr->level]++;
+ }
+ }
+
+ /* Collect the level indexes */
+ for (i = 1; i < MAX_DEPTH_MONSTER; i++)
+ {
+ /* Group by level */
+ num[i] += num[i - 1];
+ }
+
+ /* Paranoia */
+ if (!num[0]) quit("No town monsters!");
+
+
+ /*** Initialise monster allocation info ***/
+
+ /* Allocate the alloc_race_table */
+ alloc_race_table = make_array<alloc_entry>(alloc_race_size);
+
+ /* Access the table entry */
+ table = alloc_race_table;
+
+ /* Scan the monsters */
+ for (i = 1; i < max_r_idx; i++)
+ {
+ /* Get the i'th race */
+ r_ptr = &r_info[i];
+
+ /* Count valid pairs */
+ if (r_ptr->rarity)
+ {
+ int p, x, y, z;
+
+ /* Extract the base level */
+ x = r_ptr->level;
+
+ /* Extract the base probability */
+ p = (100 / r_ptr->rarity);
+
+ /* Skip entries preceding our locale */
+ y = (x > 0) ? num[x - 1] : 0;
+
+ /* Skip previous entries at this locale */
+ z = y + aux[x];
+
+ /* Load the entry */
+ table[z].index = i;
+ table[z].level = x;
+ table[z].prob1 = p;
+ table[z].prob2 = p;
+ table[z].prob3 = p;
+
+ /* Another entry complete for this locale */
+ aux[x]++;
+ }
+ }
+
+
+ /* Success */
+ return (0);
+}
+
+/* Init the sets in a_info */
+static void init_sets_aux()
+{
+ int i, j;
+
+ for (i = 0; i < max_a_idx; i++)
+ a_info[i].set = -1;
+ for (i = 0; i < max_set_idx; i++)
+ {
+ for (j = 0; j < set_info[i].num; j++)
+ {
+ a_info[set_info[i].arts[j].a_idx].set = i;
+ }
+ }
+}
+
+/*
+ * Mark guardians and their artifacts with SPECIAL_GENE flag
+ */
+static void init_guardians(void)
+{
+ int i;
+
+ /* Scan dungeons */
+ for (i = 0; i < max_d_idx; i++)
+ {
+ dungeon_info_type *d_ptr = &d_info[i];
+
+ /* Mark the guadian monster */
+ if (d_ptr->final_guardian)
+ {
+ monster_race *r_ptr = &r_info[d_ptr->final_guardian];
+
+ r_ptr->flags9 |= RF9_SPECIAL_GENE;
+
+ /* Mark the final artifact */
+ if (d_ptr->final_artifact)
+ {
+ artifact_type *a_ptr = &a_info[d_ptr->final_artifact];
+
+ a_ptr->flags4 |= TR4_SPECIAL_GENE;
+ }
+
+ /* Mark the final object */
+ if (d_ptr->final_object)
+ {
+ object_kind *k_ptr = &k_info[d_ptr->final_object];
+
+ k_ptr->flags4 |= TR4_SPECIAL_GENE;
+ }
+
+ /* Give randart if there are no final artifacts */
+ if (!(d_ptr->final_artifact) && !(d_ptr->final_object))
+ {
+ r_ptr->flags7 |= RF7_DROP_RANDART;
+ }
+ }
+ }
+}
+
+/*
+ * Hack -- Explain a broken "lib" folder and quit (see below).
+ *
+ * XXX XXX XXX This function is "messy" because various things
+ * may or may not be initialised, but the "plog()" and "quit()"
+ * functions are "supposed" to work under any conditions.
+ */
+static void init_angband_aux(cptr why)
+{
+ /* Why */
+ plog(why);
+
+ /* Explain */
+ plog("The 'lib' directory is probably missing or broken.");
+
+ /* More details */
+ plog("Perhaps the archive was not extracted correctly.");
+
+ /* Explain */
+ plog("See the 'README' file for more information.");
+
+ /* Quit with error */
+ quit("Fatal Error.");
+}
+
+/*
+ * Hack -- main Angband initialisation entry point
+ *
+ * Verify some files, display the "news.txt" file, create
+ * the high score file, initialise all internal arrays, and
+ * load the basic "user pref files".
+ *
+ * Note that we blindly assume that "news2.txt" exists. XXX
+ *
+ * Be very careful to keep track of the order in which things
+ * are initialised, in particular, the only thing *known* to
+ * be available when this function is called is the "z-term.c"
+ * package, and that may not be fully initialised until the
+ * end of this function, when the default "user pref files"
+ * are loaded and "Term_xtra(TERM_XTRA_REACT,0)" is called.
+ *
+ * Note that this function attempts to verify the "news" file,
+ * and the game aborts (cleanly) on failure, since without the
+ * "news" file, it is likely that the "lib" folder has not been
+ * correctly located. Otherwise, the news file is displayed for
+ * the user.
+ *
+ * Note that this function attempts to verify (or create) the
+ * "high score" file, and the game aborts (cleanly) on failure,
+ * since one of the most common "extraction" failures involves
+ * failing to extract all sub-directories (even empty ones), such
+ * as by failing to use the "-d" option of "pkunzip", or failing
+ * to use the "save empty directories" option with "Compact Pro".
+ * This error will often be caught by the "high score" creation
+ * code below, since the "lib/apex" directory, being empty in the
+ * standard distributions, is most likely to be "lost", making it
+ * impossible to create the high score file.
+ *
+ * Note that various things are initialised by this function,
+ * including everything that was once done by "init_some_arrays".
+ *
+ * This initialisation involves the parsing of special files
+ * in the "lib/data" and sometimes the "lib/edit" directories.
+ *
+ * Note that the "template" files are initialised first, since they
+ * often contain errors. This means that macros and message recall
+ * and things like that are not available until after they are done.
+ *
+ * We load the default "user pref files" here in case any "color"
+ * changes are needed before character creation.
+ *
+ * Note that the "graf-xxx.prf" file must be loaded separately,
+ * if needed, in the first (?) pass through "TERM_XTRA_REACT".
+ */
+void init_angband(void)
+{
+ int fd = -1;
+
+ int mode = FILE_MODE;
+
+ FILE *fp;
+
+ const char *news_file;
+
+ char buf[1024];
+
+ /* Init some VERY basic stuff, like macro arrays */
+ init_basic();
+
+ /* Select & init a module if needed */
+ select_module();
+
+ /*** Choose which news.txt file to use ***/
+
+ /* Choose the news file */
+ switch (time(NULL) % 2)
+ {
+ default:
+ {
+ news_file = "news.txt";
+ break;
+ }
+
+ case 0:
+ {
+ news_file = "news2.txt";
+ break;
+ }
+ }
+
+ /*** Verify the "news" file ***/
+
+ /* Build the filename */
+ path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, news_file);
+
+ /* Attempt to open the file */
+ fd = fd_open(buf, O_RDONLY);
+
+ /* Failure */
+ if (fd < 0)
+ {
+ char why[1024];
+
+ /* Message */
+ sprintf(why, "Cannot access the '%s' file!", buf);
+
+ /* Crash and burn */
+ init_angband_aux(why);
+ }
+
+ /* Close it */
+ (void)fd_close(fd);
+
+
+ /*** Display the "news" file ***/
+
+ /* Clear screen */
+ Term_clear();
+
+ /* Build the filename */
+ path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, news_file);
+
+ /* Open the News file */
+ fp = my_fopen(buf, "r");
+
+ /* Dump */
+ if (fp)
+ {
+ int i = 0;
+
+ /* Dump the file to the screen */
+ while (0 == my_fgets(fp, buf, 1024))
+ {
+ /* Display and advance - we use display_message to parse colour codes XXX */
+ display_message(0, i++, strlen(buf), TERM_WHITE, buf);
+ }
+
+ /* Close */
+ my_fclose(fp);
+ }
+
+ /* Flush it */
+ Term_fresh();
+
+
+ /*** Verify (or create) the "high score" file ***/
+
+ /* Build the filename */
+ path_build(buf, 1024, ANGBAND_DIR_USER, "scores.raw");
+
+ /* Attempt to open the high score file */
+ fd = fd_open(buf, O_RDONLY);
+
+ /* Failure */
+ if (fd < 0)
+ {
+ /* File type is "DATA" */
+ FILE_TYPE(FILE_TYPE_DATA);
+
+ /* Create a new high score file */
+ fd = fd_make(buf, mode);
+
+ /* Failure */
+ if (fd < 0)
+ {
+ char why[1024];
+
+ /* Message */
+ sprintf(why, "Cannot create the '%s' file!", buf);
+
+ /* Crash and burn */
+ init_angband_aux(why);
+ }
+ }
+
+ /* Close it */
+ (void)fd_close(fd);
+
+
+ /*** Initialise some arrays ***/
+
+ /* Initialise misc. values */
+ note("[Initialising values... (misc)]");
+ if (init_misc()) quit("Cannot initialise misc. values");
+
+ /* Initialise some other arrays */
+ note("[Initialising scripting... (script)]");
+ init_lua_init();
+
+ /* Initialise skills info */
+ note("[Initialising arrays... (skills)]");
+ if (init_x_info<s_info_traits>()) quit("Cannot initialise skills");
+
+ /* Initialise abilities info */
+ note("[Initialising arrays... (abilities)]");
+ if (init_x_info<ab_info_traits>()) quit("Cannot initialise abilities");
+
+ /* Initialise alchemy info */
+ note("[Initialising arrays... (alchemy)]");
+ if (init_x_info<al_info_traits>()) quit("Cannot initialise alchemy");
+
+ /* Initialise player info */
+ note("[Initialising arrays... (players)]");
+ if (init_x_info<p_info_traits>()) quit("Cannot initialise players");
+
+ /* Initialise feature info */
+ note("[Initialising arrays... (features)]");
+ if (init_x_info<f_info_traits>()) quit("Cannot initialise features");
+
+ /* Initialise object info */
+ note("[Initialising arrays... (objects)]");
+ if (init_x_info<k_info_traits>()) quit("Cannot initialise objects");
+
+ /* Initialise artifact info */
+ note("[Initialising arrays... (artifacts)]");
+ if (init_x_info<a_info_traits>()) quit("Cannot initialise artifacts");
+
+ /* Initialise set info */
+ note("[Initialising item sets... (sets)]");
+ if (init_x_info<set_info_traits>()) quit("Cannot initialise item sets");
+ init_sets_aux();
+
+ /* Initialise ego-item info */
+ note("[Initialising arrays... (ego-items)]");
+ if (init_x_info<e_info_traits>()) quit("Cannot initialise ego-items");
+
+ /* Initialise randart parts info */
+ note("[Initialising arrays... (randarts)]");
+ if (init_x_info<ra_info_traits>()) quit("Cannot initialise randarts");
+
+ /* Initialise monster info */
+ note("[Initialising arrays... (monsters)]");
+ if (init_x_info<r_info_traits>()) quit("Cannot initialise monsters");
+
+ /* Initialise ego monster info */
+ note("[Initialising arrays... (ego monsters)]");
+ if (init_x_info<re_info_traits>()) quit("Cannot initialise ego monsters");
+
+ /* Initialise dungeon type info */
+ note("[Initialising arrays... (dungeon types)]");
+ if (init_x_info<d_info_traits>()) quit("Cannot initialise dungeon types");
+ init_guardians();
+
+ /* Initialise actions type info */
+ note("[Initialising arrays... (action types)]");
+ if (init_x_info<ba_info_traits>()) quit("Cannot initialise action types");
+
+ /* Initialise owners type info */
+ note("[Initialising arrays... (owners types)]");
+ if (init_x_info<ow_info_traits>()) quit("Cannot initialise owners types");
+
+ /* Initialise stores type info */
+ note("[Initialising arrays... (stores types)]");
+ if (init_x_info<st_info_traits>()) quit("Cannot initialise stores types");
+
+ /* Initialise wilderness features array */
+ note("[Initialising arrays... (wilderness features)]");
+ if (init_x_info<wf_info_traits>()) quit("Cannot initialise wilderness features");
+
+ /* Initialise wilderness map array */
+ note("[Initialising arrays... (wilderness map)]");
+ if (init_wilderness()) quit("Cannot initialise wilderness map");
+
+ /* Initialise town array */
+ note("[Initialising arrays... (towns)]");
+ if (init_towns()) quit("Cannot initialise towns");
+
+ /* Initialise trap info */
+ note("[Initialising arrays... (traps)]");
+ if (init_x_info<tr_info_traits>()) quit("Cannot initialise traps");
+
+ /* Initialise some other arrays */
+ note("[Initialising arrays... (other)]");
+ if (init_other()) quit("Cannot initialise other stuff");
+
+ /* Initialise some other arrays */
+ note("[Initialising arrays... (alloc)]");
+ if (init_alloc()) quit("Cannot initialise alloc stuff");
+
+ /* Init random artifact names */
+ build_prob(artifact_names_list);
+
+ /* Initialize the automatizer */
+ automatizer_init();
+
+ /*** Load default user pref files ***/
+
+ /* Initialise feature info */
+ note("[Initialising user pref files...]");
+
+ /* Access the "basic" pref file */
+ strcpy(buf, "pref.prf");
+
+ /* Process that file */
+ process_pref_file(buf);
+
+ /* Access the "basic" system pref file */
+ sprintf(buf, "pref-%s.prf", ANGBAND_SYS);
+
+ /* Process that file */
+ process_pref_file(buf);
+
+ /* Access the "user" pref file */
+ sprintf(buf, "user.prf");
+
+ /* Process that file */
+ process_pref_file(buf);
+
+ /* Access the "user" system pref file */
+ sprintf(buf, "user-%s.prf", ANGBAND_SYS);
+
+ /* Process that file */
+ process_pref_file(buf);
+
+ /* Done */
+ note("[Initialisation complete]");
+}
diff --git a/src/init2.h b/src/init2.h
new file mode 100644
index 00000000..5697e4ef
--- /dev/null
+++ b/src/init2.h
@@ -0,0 +1,14 @@
+#pragma once
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void init_file_paths(char *path);
+extern void init_file_paths_with_env();
+extern void init_angband(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/init2.hpp b/src/init2.hpp
new file mode 100644
index 00000000..707a2706
--- /dev/null
+++ b/src/init2.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void init_corruptions();
+extern void create_stores_stock(int t);
+extern errr init_v_info(void);
+extern s16b error_idx;
+extern s16b error_line;
diff --git a/src/inscription_info_type.hpp b/src/inscription_info_type.hpp
new file mode 100644
index 00000000..6dbb67f1
--- /dev/null
+++ b/src/inscription_info_type.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Inscriptions
+ */
+struct inscription_info_type
+{
+ char text[40]; /* The inscription itself */
+ byte when; /* When it is executed */
+ bool_ know; /* Is the inscription know ? */
+ byte mana; /* Grid mana needed */
+};
diff --git a/src/inventory.hpp b/src/inventory.hpp
new file mode 100644
index 00000000..775f7a7e
--- /dev/null
+++ b/src/inventory.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+/*
+ * Maximum number of "normal" pack slots, and the index of the "overflow"
+ * slot, which can hold an item, but only temporarily, since it causes the
+ * pack to "overflow", dropping the "last" item onto the ground. Since this
+ * value is used as an actual slot, it must be less than "INVEN_WIELD" (below).
+ * Note that "INVEN_PACK" is probably hard-coded by its use in savefiles, and
+ * by the fact that the screen can only show 23 items plus a one-line prompt.
+ */
+#define INVEN_PACK 23
+
+/*
+ * Indexes used for various "equipment" slots (hard-coded by savefiles, etc).
+ */
+#define INVEN_WIELD 24 /* 3 weapons -- WEAPONS */
+#define INVEN_BOW 27 /* 1 bow -- WEAPON */
+#define INVEN_RING 28 /* 6 rings -- FINGER */
+#define INVEN_NECK 34 /* 2 amulets -- HEAD */
+#define INVEN_LITE 36 /* 1 lite -- TORSO */
+#define INVEN_BODY 37 /* 1 body -- TORSO */
+#define INVEN_OUTER 38 /* 1 cloak -- TORSO */
+#define INVEN_ARM 39 /* 3 arms -- ARMS */
+#define INVEN_HEAD 42 /* 2 heads -- HEAD */
+#define INVEN_HANDS 44 /* 3 hands -- ARMS */
+#define INVEN_FEET 47 /* 2 feets -- LEGS */
+#define INVEN_CARRY 49 /* 1 carried monster -- TORSO */
+#define INVEN_AMMO 50 /* 1 quiver -- TORSO */
+#define INVEN_TOOL 51 /* 1 tool -- ARMS */
+
+/*
+ * Total number of inventory slots (hard-coded).
+ */
+#define INVEN_TOTAL 52
+#define INVEN_EQ (INVEN_TOTAL - INVEN_WIELD)
diff --git a/src/joke.c b/src/joke.cc
index 0ff01557..fa660243 100644
--- a/src/joke.c
+++ b/src/joke.cc
@@ -1,10 +1,15 @@
-#include "angband.h"
+#include "joke.hpp"
-static void gen_joke_place_monster(r_idx)
+#include "monster2.hpp"
+#include "options.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+static void gen_joke_place_monster(int r_idx)
{
- int try;
+ int try_;
- for (try = 0; try < 1000; try++)
+ for (try_ = 0; try_ < 1000; try_++)
{
int x = randint(cur_hgt - 4) + 2;
int y = randint(cur_wid - 4) + 2;
@@ -24,9 +29,9 @@ bool_ gen_joke_monsters(void *data, void *in, void *out)
(dun_level == 72))
{
int r_idx = test_monster_name("Neil, the Sorceror");
- m_allow_special[r_idx + 1] = TRUE;
+ m_allow_special[r_idx] = TRUE;
gen_joke_place_monster(r_idx);
- m_allow_special[r_idx + 1] = FALSE;
+ m_allow_special[r_idx] = FALSE;
}
}
diff --git a/src/joke.hpp b/src/joke.hpp
new file mode 100644
index 00000000..05ac1843
--- /dev/null
+++ b/src/joke.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ gen_joke_monsters(void *data, void *in, void *out);
diff --git a/src/levels.c b/src/levels.cc
index 71148fc5..ac3aa3d3 100644
--- a/src/levels.c
+++ b/src/levels.cc
@@ -1,7 +1,3 @@
-/* File: levels.c */
-
-/* Purpose: Levels functions */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,14 +6,21 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "levels.hpp"
+
+#include "dungeon_info_type.hpp"
+#include "init1.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
/*
* Return the parameter of the given command in the given file
*/
static int start_line = 0;
-bool_ get_command(const char *file, char comm, char *param)
+static bool_ get_command(const char *file, char comm, char *param)
{
char buf[1024];
int i = -1;
diff --git a/src/levels.hpp b/src/levels.hpp
new file mode 100644
index 00000000..187092b1
--- /dev/null
+++ b/src/levels.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ get_dungeon_generator(char *buf);
+extern bool_ get_level_desc(char *buf);
+extern void get_level_flags(void);
+extern bool_ get_dungeon_name(char *buf);
+extern bool_ get_dungeon_special(char *buf);
+extern int get_branch(void);
+extern int get_fbranch(void);
+extern int get_flevel(void);
+extern bool_ get_dungeon_save(char *buf);
diff --git a/src/loadsave.c b/src/loadsave.cc
index 1b142e59..13e4911f 100644
--- a/src/loadsave.c
+++ b/src/loadsave.cc
@@ -1,48 +1,56 @@
-/* File: loadsave.c */
-
-/* Purpose: interact with savefiles. This file was made by
- unifying load2.c and save.c from the old codebase. Doing it
- this way makes maintenance easier and lets us share code. */
-
-#include "angband.h"
-
-#include "messages.h"
-#include "quark.h"
-
-static void do_byte(byte *, int);
-static void do_bool(bool_ *, int);
-static void do_u16b(u16b *, int);
-static void do_s16b(s16b *, int);
-static void do_u32b(u32b *, int);
-static void do_s32b(s32b *, int);
-static void do_string(char *, int, int);
-static void do_lore(int, int);
-static void do_monster(monster_type *, int);
-static void do_randomizer(int flag);
-static void do_spells(int, int);
-static void note(cptr);
-static void do_fate(int, int);
-static void do_item(object_type *, int);
-static void do_options(int);
-static bool_ do_store(store_type *, int);
-static void do_messages(int flag);
-static void do_xtra(int, int);
-static bool_ do_savefile_aux(int);
-static void junkinit(void);
-static void morejunk(void);
-static bool_ do_inventory(int);
-static bool_ do_dungeon(int, bool_);
-static void do_grid(int);
-static void my_sentinel(char *, u16b, int);
-
-static void do_ver_s16b(s16b *, u32b, s16b, int);
-
-static void skip_ver_byte(u32b, int);
-
-errr rd_savefile(void);
-
+#include "loadsave.hpp"
+#include "loadsave.h"
+
+#include "ability_type.hpp"
+#include "artifact_type.hpp"
+#include "birth.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "init1.hpp"
+#include "init2.hpp"
+#include "levels.hpp"
+#include "messages.hpp"
+#include "modules.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "hooks.hpp"
+#include "skill_type.hpp"
+#include "store_type.hpp"
+#include "tables.hpp"
+#include "timer_type.hpp"
+#include "town_type.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "wilderness_map.hpp"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra2.hpp"
+
+#include <cassert>
+#include <memory>
+
+static u32b vernum; /* Version flag */
static FILE *fff; /* Local savefile ptr */
+/**
+ * Load/save flag
+ */
+enum class ls_flag_t {
+ LOAD = 3,
+ SAVE = 7
+};
+
/*
* Basic byte-level reading from savefile. This provides a single point
* of interface to the pseudoencryption that ToME (and Angband)
@@ -76,14 +84,103 @@ static void sf_put(byte v)
}
/*
+ * Size-aware read/write routines for the savefile, do all their
+ * work through sf_get and sf_put.
+ */
+static void do_byte(byte *v, ls_flag_t flag)
+{
+ switch (flag)
+ {
+ case ls_flag_t::LOAD:
+ {
+ *v = sf_get();
+ return;
+ }
+ case ls_flag_t::SAVE:
+ {
+ byte val = *v;
+ sf_put(val);
+ return;
+ }
+ }
+}
+
+static void do_bool(bool_ *f, ls_flag_t flag)
+{
+ byte b = *f;
+ do_byte(&b, flag);
+ if (flag == ls_flag_t::LOAD)
+ {
+ *f = b;
+ }
+}
+
+static void do_u16b(u16b *v, ls_flag_t flag)
+{
+ switch (flag)
+ {
+ case ls_flag_t::LOAD:
+ {
+ (*v) = sf_get();
+ (*v) |= ((u16b)(sf_get()) << 8);
+ return;
+ }
+ case ls_flag_t::SAVE:
+ {
+ u16b val;
+ val = *v;
+ sf_put((byte)(val & 0xFF));
+ sf_put((byte)((val >> 8) & 0xFF));
+ return;
+ }
+ }
+}
+
+static void do_s16b(s16b *ip, ls_flag_t flag)
+{
+ do_u16b((u16b *)ip, flag);
+}
+
+static void do_u32b(u32b *ip, ls_flag_t flag)
+{
+ switch(flag)
+ {
+ case ls_flag_t::LOAD:
+ {
+ (*ip) = sf_get();
+ (*ip) |= ((u32b)(sf_get()) << 8);
+ (*ip) |= ((u32b)(sf_get()) << 16);
+ (*ip) |= ((u32b)(sf_get()) << 24);
+ return;
+ }
+ case ls_flag_t::SAVE:
+ {
+ u32b val = *ip;
+ sf_put((byte)(val & 0xFF));
+ sf_put((byte)((val >> 8) & 0xFF));
+ sf_put((byte)((val >> 16) & 0xFF));
+ sf_put((byte)((val >> 24) & 0xFF));
+ return;
+ }
+ }
+}
+
+static void do_s32b(s32b *ip, ls_flag_t flag)
+{
+ do_u32b((u32b *)ip, flag);
+}
+
+/*
* Do object memory and similar stuff
*/
-static void do_xtra(int k_idx, int flag)
+static void do_xtra(int k_idx, ls_flag_t flag)
{
byte tmp8u = 0;
object_kind *k_ptr = &k_info[k_idx];
- if (flag == LS_SAVE)
+ switch(flag)
+ {
+ case ls_flag_t::SAVE:
{
if (k_ptr->aware) tmp8u |= 0x01;
if (k_ptr->tried) tmp8u |= 0x02;
@@ -91,22 +188,76 @@ static void do_xtra(int k_idx, int flag)
if (k_ptr->artifact) tmp8u |= 0x80;
do_byte(&tmp8u, flag);
+ return;
}
- if (flag == LS_LOAD)
+ case ls_flag_t::LOAD:
{
do_byte(&tmp8u, flag);
k_ptr->aware = ((tmp8u & 0x01) ? TRUE : FALSE);
k_ptr->tried = ((tmp8u & 0x02) ? TRUE : FALSE);
k_ptr->know = ((tmp8u & 0x04) ? TRUE : FALSE);
k_ptr->artifact = ((tmp8u & 0x80) ? TRUE : FALSE);
+ return;
+ }
+ }
+}
+
+static void save_string(const char *str)
+{
+ while (*str)
+ {
+ do_byte((byte*)str, ls_flag_t::SAVE);
+ str++;
+ }
+ do_byte((byte*)str, ls_flag_t::SAVE);
+}
+
+static void load_string(char *str, int max)
+{
+ int i;
+
+ /* Read the string */
+ for (i = 0; TRUE; i++)
+ {
+ byte tmp8u;
+
+ /* Read a byte */
+ do_byte(&tmp8u, ls_flag_t::LOAD);
+
+ /* Collect string while legal */
+ if (i < max) str[i] = tmp8u;
+
+ /* End of string */
+ if (!tmp8u) break;
+ }
+ /* Terminate */
+ str[max - 1] = '\0';
+}
+
+static void do_string(char *str, int max, ls_flag_t flag)
+/* Max is ignored for writing */
+{
+ switch(flag) {
+ case ls_flag_t::LOAD:
+ {
+ load_string(str, max);
+ return;
+ }
+ case ls_flag_t::SAVE:
+ {
+ save_string(str);
+ return;
+ }
}
}
/*
* Load/Save quick start data
*/
-void do_quick_start(int flag)
+static void do_quick_start(ls_flag_t flag)
{
+ s16b tmp16s;
+ u32b tmp32u;
int i;
do_s16b(&previous_char.sex, flag);
@@ -126,8 +277,8 @@ void do_quick_start(int flag)
for (i = 0; i < 6; i++) do_s16b(&(previous_char.stat[i]), flag);
do_s16b(&previous_char.luck, flag);
- do_s16b(&previous_char.chaos_patron, flag);
- do_u32b(&previous_char.weapon, flag);
+ do_s16b(&tmp16s, flag);
+ do_u32b(&tmp32u, flag);
do_byte((byte*)&previous_char.quick_ok, flag);
for (i = 0; i < 4; i++) do_string(previous_char.history[i], 60, flag);
@@ -136,23 +287,33 @@ void do_quick_start(int flag)
/*
* The special saved subrace
*/
-static void do_subrace(int flag)
+static void do_subrace(ls_flag_t flag)
{
player_race_mod *sr_ptr = &race_mod_info[SUBRACE_SAVE];
int i;
char buf[81];
- if (flag == LS_SAVE)
- strncpy(buf, sr_ptr->title + rmp_name, 80);
+ buf[80] = '\0'; // Make sure string is always NUL terminated
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ strncpy(buf, sr_ptr->title, 80);
+ }
do_string(buf, 80, flag);
- if (flag == LS_LOAD)
- strncpy(sr_ptr->title + rmp_name, buf, 80);
+ if (flag == ls_flag_t::LOAD)
+ {
+ set_subrace_title(sr_ptr, buf);
+ }
- if (flag == LS_SAVE)
- strncpy(buf, sr_ptr->desc + rmp_text, 80);
+ if (flag == ls_flag_t::SAVE)
+ {
+ strncpy(buf, sr_ptr->desc, 80);
+ }
do_string(buf, 80, flag);
- if (flag == LS_LOAD)
- strncpy(sr_ptr->desc + rmp_text, buf, 80);
+ if (flag == ls_flag_t::LOAD)
+ {
+ set_subrace_description(sr_ptr, buf);
+ }
do_byte((byte*)&sr_ptr->place, flag);
@@ -221,17 +382,78 @@ static void do_subrace(int flag)
}
}
+
+/* Load/Save the random spells info */
+static void do_spells(int i, ls_flag_t flag)
+{
+ random_spell *s_ptr = &random_spells[i];
+ do_string(s_ptr->name, 30, flag);
+ do_string(s_ptr->desc, 30, flag);
+ do_s16b(&s_ptr->mana, flag);
+ do_s16b(&s_ptr->fail, flag);
+ do_u32b(&s_ptr->proj_flags, flag);
+ do_byte(&s_ptr->GF, flag);
+ do_byte(&s_ptr->radius, flag);
+ do_byte(&s_ptr->dam_sides, flag);
+ do_byte(&s_ptr->dam_dice, flag);
+ do_byte(&s_ptr->level, flag);
+ do_byte((byte*)&s_ptr->untried, flag);
+}
+
+
+/*
+ * Show information on the screen, one line at a time.
+ *
+ * Avoid the top two lines, to avoid interference with "msg_print()".
+ */
+static void note(cptr msg)
+{
+ static int y = 2;
+
+ /* Draw the message */
+ prt(msg, y, 0);
+
+ /* Advance one line (wrap if needed) */
+ if (++y >= 24) y = 2;
+
+ /* Flush it */
+ Term_fresh();
+}
+
+
+static void skip_ver_byte(u32b version, ls_flag_t flag)
+/* Reads and discards a byte if the savefile is as old as/older than version */
+{
+ if ((flag == ls_flag_t::LOAD) && (vernum <= version))
+ {
+ byte forget;
+ do_byte(&forget, flag);
+ }
+ return;
+}
+
+static void do_ver_s16b(s16b *v, u32b version, s16b defval, ls_flag_t flag)
+{
+ if ((flag == ls_flag_t::LOAD) && (vernum < version))
+ {
+ *v = defval;
+ return;
+ }
+ do_s16b(v, flag);
+}
+
/*
* Misc. other data
*/
static char loaded_game_module[80];
-static bool_ do_extra(int flag)
+static bool_ do_extra(ls_flag_t flag)
{
int i, j;
- byte tmp8u;
- s16b tmp16s;
- u32b tmp32u;
- u16b tmp16b;
+ byte tmp8u = 0;
+ s16b tmp16s = 0;
+ u32b tmp32u = 0;
+ s32b tmp32s = 0;
+ u16b tmp16b = 0;
u32b dummy32u = 0;
do_string(player_name, 32, flag);
@@ -244,14 +466,14 @@ static bool_ do_extra(int flag)
}
/* Handle the special levels info */
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
tmp8u = max_d_idx;
tmp16s = MAX_DUNGEON_DEPTH;
}
do_byte(&tmp8u, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
if (tmp8u > max_d_idx)
{
@@ -261,7 +483,7 @@ static bool_ do_extra(int flag)
do_s16b(&tmp16s, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
if (tmp16s > MAX_DUNGEON_DEPTH)
{
@@ -297,7 +519,7 @@ static bool_ do_extra(int flag)
do_u16b(&tmp16b, flag);
do_byte(&p_ptr->mimic_form, flag);
do_s16b(&p_ptr->mimic_level, flag);
- if (flag == LS_SAVE) tmp8u = 0;
+ if (flag == ls_flag_t::SAVE) tmp8u = 0;
do_byte(&p_ptr->hitdie, flag);
do_u16b(&p_ptr->expfact, flag);
@@ -321,12 +543,12 @@ static bool_ do_extra(int flag)
tmp16s = MAX_SKILLS;
do_s16b(&tmp16s, flag);
- if ((flag == LS_LOAD) && (tmp16s > MAX_SKILLS))
+ if ((flag == ls_flag_t::LOAD) && (tmp16s > MAX_SKILLS))
{
quit("Too many skills");
}
- if (flag == LS_SAVE) old_max_s_idx = max_s_idx;
+ if (flag == ls_flag_t::SAVE) old_max_s_idx = max_s_idx;
do_u16b(&old_max_s_idx, flag);
for (i = 0; i < tmp16s; ++i)
{
@@ -351,7 +573,7 @@ static bool_ do_extra(int flag)
tmp16s = max_ab_idx;
do_s16b(&tmp16s, flag);
- if ((flag == LS_LOAD) && (tmp16s > max_ab_idx))
+ if ((flag == ls_flag_t::LOAD) && (tmp16s > max_ab_idx))
{
quit("Too many abilities");
}
@@ -392,10 +614,10 @@ static bool_ do_extra(int flag)
do_s16b(&p_ptr->town_num, flag); /* -KMW- */
/* Write arena and rewards information -KMW- */
- do_s16b(&p_ptr->arena_number, flag);
- do_s16b(&p_ptr->inside_arena, flag);
+ do_s16b(&tmp16s, flag);
+ do_s16b(&tmp16s, flag);
do_s16b(&p_ptr->inside_quest, flag);
- do_byte((byte*)&p_ptr->exit_bldg, flag);
+ do_byte(&tmp8u, flag);
/* Save/load spellbinder */
@@ -407,10 +629,10 @@ static bool_ do_extra(int flag)
do_byte(&tmp8u, flag); /* tmp8u should be 0 at this point */
- if (flag == LS_SAVE) tmp8u = MAX_PLOTS;
+ if (flag == ls_flag_t::SAVE) tmp8u = MAX_PLOTS;
do_byte(&tmp8u, flag);
- if ((flag == LS_LOAD) && (tmp8u > MAX_PLOTS))
+ if ((flag == ls_flag_t::LOAD) && (tmp8u > MAX_PLOTS))
{
quit(format("Too many plots, %d %d", tmp8u, MAX_PLOTS));
}
@@ -420,13 +642,13 @@ static bool_ do_extra(int flag)
do_s16b(&plots[i], flag);
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
tmp8u = MAX_RANDOM_QUEST;
}
do_byte(&tmp8u, flag);
- if ((flag == LS_LOAD) &&
+ if ((flag == ls_flag_t::LOAD) &&
(tmp8u > MAX_RANDOM_QUEST)) quit("Too many random quests");
for (i = 0; i < tmp8u; i++)
{
@@ -470,19 +692,19 @@ static bool_ do_extra(int flag)
/* Max Player and Dungeon Levels */
do_s16b(&p_ptr->max_plv, flag);
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
tmp8u = max_d_idx;
do_byte(&tmp8u, flag);
for (i = 0; i < tmp8u; i++)
{
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
tmp16s = max_dlv[i];
do_s16b(&tmp16s, flag);
- if ((flag == LS_LOAD) && (i <= max_d_idx))
+ if ((flag == ls_flag_t::LOAD) && (i <= max_d_idx))
max_dlv[i] = tmp16s;
}
/* Repair max player level??? */
- if ((flag == LS_LOAD) && (p_ptr->max_plv < p_ptr->lev))
+ if ((flag == ls_flag_t::LOAD) && (p_ptr->max_plv < p_ptr->lev))
p_ptr->max_plv = p_ptr->lev;
do_byte((byte*)&(p_ptr->help.enabled), flag);
@@ -556,9 +778,9 @@ static bool_ do_extra(int flag)
do_s16b(&p_ptr->tim_wraith, flag);
do_s16b(&p_ptr->tim_ffall, flag);
do_ver_s16b(&p_ptr->tim_fly, SAVEFILE_VERSION, 0, flag);
- do_s16b(&p_ptr->tim_fire_aura, flag);
+ do_s16b(&tmp16s, flag);
do_ver_s16b(&p_ptr->tim_poison, SAVEFILE_VERSION, 0, flag);
- do_s16b(&p_ptr->resist_magic, flag);
+ do_s16b(&tmp16s, flag);
do_s16b(&p_ptr->tim_invisible, flag);
do_s16b(&p_ptr->tim_inv_pow, flag);
do_s16b(&p_ptr->tim_mimic, flag);
@@ -567,27 +789,27 @@ static bool_ do_extra(int flag)
do_ver_s16b(&p_ptr->tim_regen, SAVEFILE_VERSION, 0, flag);
do_ver_s16b(&p_ptr->tim_regen_pow, SAVEFILE_VERSION, 0, flag);
do_s16b(&p_ptr->holy, flag);
- do_s16b(&p_ptr->walk_water, flag);
- do_s16b(&p_ptr->tim_mental_barrier, flag);
+ do_s16b(&tmp16s, flag);
+ do_s16b(&tmp16s, flag);
do_s16b(&p_ptr->immov_cntr, flag);
do_s16b(&p_ptr->strike, flag);
- do_s16b(&p_ptr->meditation, flag);
+ do_s16b(&tmp16s, flag);
do_s16b(&p_ptr->tim_reflect, flag);
- do_s16b(&p_ptr->tim_res_time, flag);
+ do_s16b(&tmp16s, flag);
do_s16b(&p_ptr->tim_deadly, flag);
do_s16b(&p_ptr->prob_travel, flag);
do_s16b(&p_ptr->disrupt_shield, flag);
do_s16b(&p_ptr->parasite, flag);
do_s16b(&p_ptr->parasite_r_idx, flag);
- do_s32b(&p_ptr->loan, flag);
- do_s32b(&p_ptr->loan_time, flag);
+ do_s32b(&tmp32s, flag);
+ do_s32b(&tmp32s, flag);
do_s16b(&p_ptr->absorb_soul, flag);
do_s32b(&p_ptr->inertia_controlled_spell, flag);
do_s16b(&p_ptr->last_rewarded_level, flag);
do_s16b(&tmp16s, flag); /* compat */
- if (flag == LS_SAVE) { tmp16s = CORRUPTIONS_MAX; }
+ if (flag == ls_flag_t::SAVE) { tmp16s = CORRUPTIONS_MAX; }
do_s16b(&tmp16s, flag);
if (tmp16s > CORRUPTIONS_MAX) {
quit("Too many corruptions");
@@ -595,12 +817,12 @@ static bool_ do_extra(int flag)
for (i = 0; i < tmp16s; i++)
{
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
tmp8u = p_ptr->corruptions[i];
do_byte(&tmp8u, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
p_ptr->corruptions[i] = tmp8u;
}
@@ -610,12 +832,12 @@ static bool_ do_extra(int flag)
do_byte((byte*)&p_ptr->black_breath, flag);
do_byte((byte*)&fate_flag, flag);
do_byte(&p_ptr->searching, flag);
- do_byte(&p_ptr->maximize, flag);
+ do_byte(&tmp8u, flag);
do_byte(&p_ptr->preserve, flag);
do_byte(&p_ptr->special, flag);
do_byte((byte*)&ambush_flag, flag);
do_byte(&p_ptr->allow_one_death, flag);
- do_s16b(&p_ptr->xtra_spells, flag);
+ do_s16b(&tmp16s, flag);
do_byte(&tmp8u, flag);
@@ -625,21 +847,21 @@ static bool_ do_extra(int flag)
/* Auxilliary variables */
do_u32b(&p_ptr->mimic_extra, flag);
do_u32b(&p_ptr->antimagic_extra, flag);
- do_u32b(&p_ptr->druid_extra, flag);
- do_u32b(&p_ptr->druid_extra2, flag);
- do_u32b(&p_ptr->druid_extra3, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
do_u32b(&p_ptr->music_extra, flag);
- do_u32b(&p_ptr->music_extra2, flag);
+ do_u32b(&tmp32u, flag);
do_u32b(&p_ptr->necro_extra, flag);
do_u32b(&p_ptr->necro_extra2, flag);
- do_u32b(&p_ptr->race_extra1, flag);
- do_u32b(&p_ptr->race_extra2, flag);
- do_u32b(&p_ptr->race_extra3, flag);
- do_u32b(&p_ptr->race_extra4, flag);
- do_u32b(&p_ptr->race_extra5, flag);
- do_u32b(&p_ptr->race_extra6, flag);
- do_u32b(&p_ptr->race_extra7, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
+ do_u32b(&tmp32u, flag);
do_u16b(&p_ptr->body_monster, flag);
do_byte((byte*)&p_ptr->disembodied, flag);
@@ -647,9 +869,9 @@ static bool_ do_extra(int flag)
/* Are we in astral mode? */
do_byte((byte*)&p_ptr->astral, flag);
- if (flag == LS_SAVE) tmp16s = POWER_MAX;
+ if (flag == ls_flag_t::SAVE) tmp16s = POWER_MAX;
do_s16b(&tmp16s, flag);
- if ((flag == LS_LOAD) && (tmp16s > POWER_MAX))
+ if ((flag == ls_flag_t::LOAD) && (tmp16s > POWER_MAX))
note(format("Too many (%u) powers!", tmp16s));
for (i = 0; i < POWER_MAX; i++)
do_byte((byte*)&p_ptr->powers_mod[i], flag);
@@ -668,13 +890,14 @@ static bool_ do_extra(int flag)
/* The fate */
do_byte((byte*)&p_ptr->no_mortal, flag);
- /* The bounties */
- for (i = 0; i < MAX_BOUNTIES; i++)
- {
- do_s16b(&bounties[i][0], flag);
- do_s16b(&bounties[i][1], flag);
+ /* The bounties -- kept only for load-compatibility with old savefiles. */
+ for (i = 0; i < 24; i++) {
+ tmp16s = 0; do_s16b(&tmp16s, flag);
+ tmp16s = 0; do_s16b(&tmp16s, flag);
}
- do_u32b(&total_bounties, flag);
+ tmp32u = 0; do_u32b(&tmp32u, flag);
+
+ /* Spells */
do_s16b(&spell_num, flag);
for (i = 0; i < MAX_SPELLS; i++)
do_spells(i, flag);
@@ -699,12 +922,12 @@ static bool_ do_extra(int flag)
do_u16b(&noscore, flag);
/* Write death */
- if (flag == LS_SAVE) tmp8u = death;
+ if (flag == ls_flag_t::SAVE) tmp8u = death;
do_byte(&tmp8u, flag);
- if (flag == LS_LOAD) death = tmp8u;
+ if (flag == ls_flag_t::LOAD) death = tmp8u;
/* Incompatible module? */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
s32b ok;
@@ -719,9 +942,9 @@ static bool_ do_extra(int flag)
}
/* Write feeling */
- if (flag == LS_SAVE) tmp8u = feeling;
+ if (flag == ls_flag_t::SAVE) tmp8u = feeling;
do_byte(&tmp8u, flag);
- if (flag == LS_LOAD) feeling = tmp8u;
+ if (flag == ls_flag_t::LOAD) feeling = tmp8u;
/* Turn of last "feeling" */
do_s32b(&old_turn, flag);
@@ -732,489 +955,58 @@ static bool_ do_extra(int flag)
return TRUE;
}
-/* Save the current persistent dungeon -SC- */
-void save_dungeon(void)
-{
- char tmp[16];
- char name[1024], buf[5];
-
- /* Save only persistent dungeons */
- if (!get_dungeon_save(buf) || (!dun_level)) return;
-
- /* Construct filename */
- sprintf(tmp, "%s.%s", player_base, buf);
- path_build(name, 1024, ANGBAND_DIR_SAVE, tmp);
-
- /* Open the file */
- fff = my_fopen(name, "wb");
-
- /* Save the dungeon */
- do_dungeon(LS_SAVE, TRUE);
-
- my_fclose(fff);
-}
-
-/*
- * Medium level player saver
- */
-static bool_ save_player_aux(char *name)
-{
- bool_ ok = FALSE;
- int fd = -1;
- int mode = 0644;
-
- /* No file yet */
- fff = NULL;
-
- /* File type is "SAVE" */
- FILE_TYPE(FILE_TYPE_SAVE);
-
- /* Create the savefile */
- fd = fd_make(name, mode);
-
- /* File is okay */
- if (fd >= 0)
- {
- /* Close the "fd" */
- (void)fd_close(fd);
-
- /* Open the savefile */
- fff = my_fopen(name, "wb");
-
- /* Successful open */
- if (fff)
- {
- /* Write the savefile */
- if (do_savefile_aux(LS_SAVE)) ok = TRUE;
-
- /* Attempt to close it */
- if (my_fclose(fff)) ok = FALSE;
- }
-
- /* "broken" savefile */
- if (!ok)
- {
- /* Remove "broken" files */
- (void)fd_kill(name);
- }
- }
-
- /* Failure */
- if (!ok) return (FALSE);
-
- /* Successful save */
- character_saved = TRUE;
-
- /* Success */
- return (TRUE);
-}
-
-/*
- * Attempt to save the player in a savefile
- */
-bool_ save_player(void)
-{
- int result = FALSE;
- char safe[1024];
-
- /* New savefile */
- strcpy(safe, savefile);
- strcat(safe, ".new");
-
- /* Remove it */
- fd_kill(safe);
-
- /* Attempt to save the player */
- if (save_player_aux(safe))
- {
- char temp[1024];
-
- /* Old savefile */
- strcpy(temp, savefile);
- strcat(temp, ".old");
-
- /* Remove it */
- fd_kill(temp);
-
- /* Preserve old savefile */
- fd_move(savefile, temp);
-
- /* Activate new savefile */
- fd_move(safe, savefile);
-
- /* Remove preserved savefile */
- fd_kill(temp);
-
- /* Hack -- Pretend the character was loaded */
- character_loaded = TRUE;
-
- /* Success */
- result = TRUE;
- }
-
- save_savefile_names();
-
- /* Return the result */
- return (result);
-}
-
-bool_ file_exist(cptr buf)
-{
- int fd;
- bool_ result;
-
- /* Open savefile */
- fd = fd_open(buf, O_RDONLY);
-
- /* File exists */
- if (fd >= 0)
- {
- fd_close(fd);
- result = TRUE;
- }
- else
- result = FALSE;
-
- return result;
-}
-
-/*
- * Attempt to Load a "savefile"
- *
- * On multi-user systems, you may only "read" a savefile if you will be
- * allowed to "write" it later, this prevents painful situations in which
- * the player loads a savefile belonging to someone else, and then is not
- * allowed to save his game when he quits.
- *
- * We return "TRUE" if the savefile was usable, and we set the global
- * flag "character_loaded" if a real, living, character was loaded.
- *
- * Note that we always try to load the "current" savefile, even if
- * there is no such file, so we must check for "empty" savefile names.
- */
-bool_ load_player(void)
-{
- int fd = -1;
-
- errr err = 0;
-
- cptr what = "generic";
-
- /* Paranoia */
- turn = 0;
-
- /* Paranoia */
- death = FALSE;
-
-
- /* Allow empty savefile name */
- if (!savefile[0]) return (TRUE);
-
-
- /* XXX XXX XXX Fix this */
-
- /* Verify the existance of the savefile */
- if (!file_exist(savefile))
- {
- /* Give a message */
- msg_format("Savefile does not exist: %s", savefile);
- msg_print(NULL);
-
- /* Allow this */
- return (TRUE);
- }
-
- /* Okay */
- if (!err)
- {
- /* Open the savefile */
- fd = fd_open(savefile, O_RDONLY);
-
- /* No file */
- if (fd < 0) err = -1;
-
- /* Message (below) */
- if (err) what = "Cannot open savefile";
- }
-
- /* Process file */
- if (!err)
- {
- /* Open the file XXX XXX XXX XXX Should use Angband file interface */
- fff = my_fopen(savefile, "rb");
-/* fff = fdopen(fd, "r"); */
-
- /* Read the first four bytes */
- do_u32b(&vernum, LS_LOAD);
- do_byte(&sf_extra, LS_LOAD);
-
- /* XXX XXX XXX XXX Should use Angband file interface */
- my_fclose(fff);
- /* fclose(fff) */
-
- /* Close the file */
- fd_close(fd);
- }
-
- /* Process file */
- if (!err)
- {
-
- /* Extract version */
- sf_major = VERSION_MAJOR;
- sf_minor = VERSION_MINOR;
- sf_patch = VERSION_PATCH;
- sf_extra = VERSION_EXTRA;
-
- /* Clear screen */
- Term_clear();
-
- /* Attempt to load */
- err = rd_savefile();
-
- /* Message (below) */
- if (err) what = "Cannot parse savefile";
- }
-
- /* Paranoia */
- if (!err)
- {
- /* Invalid turn */
- if (!turn) err = -1;
-
- /* Message (below) */
- if (err) what = "Broken savefile";
- }
-
-
- /* Okay */
- if (!err)
- {
- /* Maybe the scripts want to resurrect char */
- if (process_hooks_ret(HOOK_LOAD_END, "d", "(d)", death))
- {
- character_loaded = process_hooks_return[0].num;
- death = process_hooks_return[1].num;
- return TRUE;
- }
-
- /* Player is dead */
- if (death)
- {
- /* Player is no longer "dead" */
- death = FALSE;
-
- /* Cheat death (unless the character retired) */
- if (arg_wizard && !total_winner)
- {
- /* A character was loaded */
- character_loaded = TRUE;
-
- /* Done */
- return (TRUE);
- }
-
- /* Count lives */
- sf_lives++;
-
- /* Forget turns */
- turn = old_turn = 0;
-
- /* Done */
- return (TRUE);
- }
-
- /* A character was loaded */
- character_loaded = TRUE;
-
- /* Still alive */
- if (p_ptr->chp >= 0)
- {
- /* Reset cause of death */
- (void)strcpy(died_from, "(alive and well)");
- }
-
- /* Success */
- return (TRUE);
- }
-
-
- /* Message */
- msg_format("Error (%s) reading %d.%d.%d savefile.",
- what, sf_major, sf_minor, sf_patch);
- msg_print(NULL);
-
- /* Oops */
- return (FALSE);
-}
-
/*
- * Size-aware read/write routines for the savefile, do all their
- * work through sf_get and sf_put.
+ * Read a monster
*/
-
-static void do_byte(byte *v, int flag)
+static void do_monster(monster_type *m_ptr, ls_flag_t flag)
{
- if (flag == LS_LOAD)
- {
- *v = sf_get();
- return;
- }
- if (flag == LS_SAVE)
- {
- byte val = *v;
- sf_put(val);
- return;
- }
- /* We should never reach here, so bail out */
- printf("FATAL: do_byte passed %d\n", flag);
- exit(0);
-}
-
-static void do_bool(bool_ *f, int flag)
-{
- byte b = *f;
- do_byte(&b, flag);
- if (flag == LS_LOAD)
- {
- *f = b;
- }
-}
-
-static void do_u16b(u16b *v, int flag)
-{
- if (flag == LS_LOAD)
- {
- (*v) = sf_get();
- (*v) |= ((u16b)(sf_get()) << 8);
- return;
- }
- if (flag == LS_SAVE)
- {
- u16b val;
- val = *v;
- sf_put((byte)(val & 0xFF));
- sf_put((byte)((val >> 8) & 0xFF));
- return;
- }
- /* Never should reach here, bail out */
- printf("FATAL: do_u16b passed %d\n", flag);
- exit(0);
-}
-
-static void do_s16b(s16b *ip, int flag)
-{
- do_u16b((u16b *)ip, flag);
-}
+ int i;
-static void do_u32b(u32b *ip, int flag)
-{
- if (flag == LS_LOAD)
- {
- (*ip) = sf_get();
- (*ip) |= ((u32b)(sf_get()) << 8);
- (*ip) |= ((u32b)(sf_get()) << 16);
- (*ip) |= ((u32b)(sf_get()) << 24);
- return;
- }
- if (flag == LS_SAVE)
- {
- u32b val = *ip;
- sf_put((byte)(val & 0xFF));
- sf_put((byte)((val >> 8) & 0xFF));
- sf_put((byte)((val >> 16) & 0xFF));
- sf_put((byte)((val >> 24) & 0xFF));
- return;
- }
- /* Bad news if you're here, because you're going down */
- printf("FATAL: do_u32b passed %d\n", flag);
- exit(0);
-}
+ /* Read the monster race */
+ do_s16b(&m_ptr->r_idx, flag);
-static void do_s32b(s32b *ip, int flag)
-{
- do_u32b((u32b *)ip, flag);
-}
+ do_u16b(&m_ptr->ego, flag);
-static void do_string(char *str, int max, int flag)
-/* Max is ignored for writing */
-{
- if (flag == LS_LOAD)
- {
- int i;
+ /* Read the other information */
+ do_byte(&m_ptr->fy, flag);
+ do_byte(&m_ptr->fx, flag);
- /* Read the string */
- for (i = 0; TRUE; i++)
- {
- byte tmp8u;
+ do_s32b(&m_ptr->hp, flag);
+ do_s32b(&m_ptr->maxhp, flag);
- /* Read a byte */
- do_byte(&tmp8u, LS_LOAD);
+ do_s16b(&m_ptr->csleep, flag);
+ do_byte(&m_ptr->mspeed, flag);
+ do_byte(&m_ptr->energy, flag);
+ do_byte(&m_ptr->stunned, flag);
+ do_byte(&m_ptr->confused, flag);
+ do_byte(&m_ptr->monfear, flag);
+ do_u32b(&m_ptr->smart, flag);
+ do_s16b(&m_ptr->status, flag);
+ do_s16b(&m_ptr->possessor, flag);
+ do_byte(&m_ptr->speed, flag);
+ do_byte(&m_ptr->level, flag);
+ do_s16b(&m_ptr->ac, flag);
+ do_s32b(&m_ptr->exp, flag);
+ do_s16b(&m_ptr->target, flag);
- /* Collect string while legal */
- if (i < max) str[i] = tmp8u;
+ do_s16b(&m_ptr->bleeding, flag);
+ do_s16b(&m_ptr->poisoned, flag);
- /* End of string */
- if (!tmp8u) break;
- }
- /* Terminate */
- str[max - 1] = '\0';
- return;
- }
- if (flag == LS_SAVE)
- {
- while (*str)
- {
- do_byte((byte*)str, flag);
- str++;
- }
- do_byte((byte*)str, flag); /* Output a terminator */
- return;
- }
- printf("FATAL: do_string passed flag %d\n", flag);
- exit(0);
-}
+ do_s32b(&m_ptr->mflag, flag);
-static void skip_ver_byte(u32b version, int flag)
-/* Reads and discards a byte if the savefile is as old as/older than version */
-{
- if ((flag == LS_LOAD) && (vernum <= version))
- {
- byte forget;
- do_byte(&forget, flag);
- }
- return;
-}
+ if (flag == ls_flag_t::LOAD) m_ptr->mflag &= PERM_MFLAG_MASK;
-static void do_ver_s16b(s16b *v, u32b version, s16b defval, int flag)
-{
- if ((flag == LS_LOAD) && (vernum < version))
+ /* Attacks */
+ for (i = 0; i < 4; i++)
{
- *v = defval;
- return;
+ do_byte(&m_ptr->blow[i].method, flag);
+ do_byte(&m_ptr->blow[i].effect, flag);
+ do_byte(&m_ptr->blow[i].d_dice, flag);
+ do_byte(&m_ptr->blow[i].d_side, flag);
}
- do_s16b(v, flag);
}
-/*
- * Show information on the screen, one line at a time.
- *
- * Avoid the top two lines, to avoid interference with "msg_print()".
- */
-static void note(cptr msg)
-{
- static int y = 2;
-
- /* Draw the message */
- prt(msg, y, 0);
-
- /* Advance one line (wrap if needed) */
- if (++y >= 24) y = 2;
-
- /* Flush it */
- Term_fresh();
-}
/*
@@ -1276,7 +1068,7 @@ static bool_ wearable_p(object_type *o_ptr)
* FIXME! This code probably has a lot of cruft from the old Z/V codebase.
*
*/
-static void do_item(object_type *o_ptr, int flag)
+static void do_item(object_type *o_ptr, ls_flag_t flag)
{
byte old_dd;
byte old_ds;
@@ -1321,15 +1113,15 @@ static void do_item(object_type *o_ptr, int flag)
do_s16b(&o_ptr->ac, flag);
/* We do special processing of this flag when reading */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
- do_byte(&old_dd, LS_LOAD);
- do_byte(&old_ds, LS_LOAD);
+ do_byte(&old_dd, ls_flag_t::LOAD);
+ do_byte(&old_ds, ls_flag_t::LOAD);
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
- do_byte(&o_ptr->dd, LS_SAVE);
- do_byte(&o_ptr->ds, LS_SAVE);
+ do_byte(&o_ptr->dd, ls_flag_t::SAVE);
+ do_byte(&o_ptr->ds, ls_flag_t::SAVE);
}
do_byte(&o_ptr->ident, flag);
@@ -1372,42 +1164,47 @@ static void do_item(object_type *o_ptr, int flag)
do_s16b(&o_ptr->found_aux3, flag);
do_s16b(&o_ptr->found_aux4, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
char buf[128];
/* Inscription */
- do_string(buf, 128, LS_LOAD);
- /* Save the inscription */
- if (buf[0]) o_ptr->note = quark_add(buf);
-
- do_string(buf, 128, LS_LOAD);
- if (buf[0]) o_ptr->art_name = quark_add(buf);
+ load_string(buf, 128);
+ if (buf[0])
+ {
+ o_ptr->note = quark_add(buf);
+ }
+ /* Artifact name */
+ load_string(buf, 128);
+ if (buf[0])
+ {
+ o_ptr->art_name = quark_add(buf);
+ }
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
/* Save the inscription (if any) */
if (o_ptr->note)
{
- do_string((char *)quark_str(o_ptr->note), 0, LS_SAVE);
+ save_string(quark_str(o_ptr->note));
}
else
{
- do_string("", 0, LS_SAVE);
+ save_string("");
}
if (o_ptr->art_name)
{
- do_string((char *)quark_str(o_ptr->art_name), 0, LS_SAVE);
+ save_string(quark_str(o_ptr->art_name));
}
else
{
- do_string("", 0, LS_SAVE);
+ save_string("");
}
}
- if (flag == LS_SAVE) return ; /* Stick any more shared code before this. The rest
- of this function is reserved for LS_LOAD's
+ if (flag == ls_flag_t::SAVE) return ; /* Stick any more shared code before this. The rest
+ of this function is reserved for ls_flag_t::LOAD's
cleanup functions */
- /*********** END OF LS_SAVE ***************/
+ /*********** END OF ls_flag_t::SAVE ***************/
/* Obtain the "kind" template */
k_ptr = &k_info[o_ptr->k_idx];
@@ -1499,143 +1296,389 @@ static void do_item(object_type *o_ptr, int flag)
}
}
+static void do_cave_type(cave_type *c_ptr, ls_flag_t flag)
+{
+ do_u16b(&c_ptr->info, flag);
+ do_byte(&c_ptr->feat, flag);
+ do_byte(&c_ptr->mimic, flag);
+ do_s16b(&c_ptr->special, flag);
+ do_s16b(&c_ptr->special2, flag);
+ do_s16b(&c_ptr->t_idx, flag);
+ do_s16b(&c_ptr->inscription, flag);
+ do_byte(&c_ptr->mana, flag);
+ do_s16b(&c_ptr->effect, flag);
+}
+
+static void do_grid(ls_flag_t flag)
+{
+ for (int y = 0; y < cur_hgt; y++)
+ {
+ for (int x = 0; x < cur_wid; x++)
+ {
+ do_cave_type(&cave[y][x], flag);
+ }
+ }
+}
+
+static void my_sentinel(const char *place, u16b value, ls_flag_t flag)
+/* This function lets us know exactly where a savefile is
+ broken by reading/writing conveniently a sentinel at this
+ spot */
+{
+ if (flag == ls_flag_t::SAVE)
+ {
+ do_u16b(&value, flag);
+ return;
+ }
+ if (flag == ls_flag_t::LOAD)
+ {
+ u16b found;
+ do_u16b(&found, flag);
+ if (found == value) /* All is good */
+ return;
+ /* All is bad */
+ note(format("Savefile broken %s", place));
+ return;
+ }
+ note(format("Impossible has occurred")); /* Programmer error */
+ exit(0);
+}
/*
- * Read a monster
+ * Handle dungeon
+ *
+ * The monsters/objects must be loaded in the same order
+ * that they were stored, since the actual indexes matter.
*/
-static void do_monster(monster_type *m_ptr, int flag)
+static bool_ do_dungeon(ls_flag_t flag, bool_ no_companions)
{
int i;
- bool_ tmp;
- /* Read the monster race */
- do_s16b(&m_ptr->r_idx, flag);
+ cave_type *c_ptr;
- do_u16b(&m_ptr->ego, flag);
+ /* Read specific */
+ u16b tmp16b = 0;
- /* Read the other information */
- do_byte(&m_ptr->fy, flag);
- do_byte(&m_ptr->fx, flag);
+ my_sentinel("Before do_dungeon", 324, flag);
- do_s32b(&m_ptr->hp, flag);
- do_s32b(&m_ptr->maxhp, flag);
+ /* Header info */
+ do_s16b(&dun_level, flag);
+ do_byte(&dungeon_type, flag);
+ do_s16b(&num_repro, flag);
+ do_s16b(&p_ptr->py, flag);
+ do_s16b(&p_ptr->px, flag);
+ do_s16b(&cur_hgt, flag);
+ do_s16b(&cur_wid, flag);
+ do_s16b(&max_panel_rows, flag);
+ do_s16b(&max_panel_cols, flag);
- do_s16b(&m_ptr->csleep, flag);
- do_byte(&m_ptr->mspeed, flag);
- do_byte(&m_ptr->energy, flag);
- do_byte(&m_ptr->stunned, flag);
- do_byte(&m_ptr->confused, flag);
- do_byte(&m_ptr->monfear, flag);
- do_u32b(&m_ptr->smart, flag);
- do_s16b(&m_ptr->status, flag);
- do_s16b(&m_ptr->possessor, flag);
- do_byte(&m_ptr->speed, flag);
- do_byte(&m_ptr->level, flag);
- do_s16b(&m_ptr->ac, flag);
- do_u32b(&m_ptr->exp, flag);
- do_s16b(&m_ptr->target, flag);
+ do_u32b(&dungeon_flags1, flag);
+ do_u32b(&dungeon_flags2, flag);
- do_s16b(&m_ptr->bleeding, flag);
- do_s16b(&m_ptr->poisoned, flag);
+ /* Last teleportation */
+ do_s16b(&last_teleportation_y, flag);
+ do_s16b(&last_teleportation_y, flag);
- do_s32b(&m_ptr->mflag, flag);
+ /* Spell effects */
+ tmp16b = MAX_EFFECTS;
+ do_u16b(&tmp16b, flag);
- if (flag == LS_LOAD) m_ptr->mflag &= PERM_MFLAG_MASK;
+ if ((flag == ls_flag_t::LOAD) && (tmp16b > MAX_EFFECTS))
+ {
+ quit("Too many spell effects");
+ }
- /* Attacks */
- for (i = 0; i < 4; i++)
+ for (i = 0; i < tmp16b; ++i)
{
- do_byte(&m_ptr->blow[i].method, flag);
- do_byte(&m_ptr->blow[i].effect, flag);
- do_byte(&m_ptr->blow[i].d_dice, flag);
- do_byte(&m_ptr->blow[i].d_side, flag);
+ do_s16b(&effects[i].type, flag);
+ do_s16b(&effects[i].dam, flag);
+ do_s16b(&effects[i].time, flag);
+ do_u32b(&effects[i].flags, flag);
+ do_s16b(&effects[i].cx, flag);
+ do_s16b(&effects[i].cy, flag);
+ do_s16b(&effects[i].rad, flag);
}
- /* Mind */
- tmp = (m_ptr->mind) ? TRUE : FALSE;
- do_byte((byte*)&tmp, flag);
- if (tmp)
+ /* TO prevent bugs with evolving dungeons */
+ for (i = 0; i < 100; i++)
{
- if (flag == LS_LOAD)
+ do_s16b(&floor_type[i], flag);
+ do_s16b(&fill_type[i], flag);
+ }
+
+ if ((flag == ls_flag_t::LOAD) && (!dun_level && !p_ptr->inside_quest))
+ {
+ int xstart = 0;
+ int ystart = 0;
+ /* Init the wilderness */
+ process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
+ TRUE, FALSE);
+
+ /* Init the town */
+ xstart = 0;
+ ystart = 0;
+ init_flags = 0;
+ process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
+ TRUE, FALSE);
+ }
+
+ do_grid(flag);
+
+ /*** Objects ***/
+
+ if (flag == ls_flag_t::SAVE) compact_objects(0);
+ if (flag == ls_flag_t::SAVE) compact_monsters(0);
+ if (flag == ls_flag_t::SAVE)
+ {
+ tmp16b = o_max;
+
+ if (no_companions)
{
- MAKE(m_ptr->mind, monster_mind);
+ for (i = 1; i < o_max; i++)
+ {
+ object_type *o_ptr = &o_list[i];
+
+ if (o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) tmp16b--;
+ }
}
+
+ /* Item count */
+ do_u16b(&tmp16b, flag);
+
+ tmp16b = o_max;
+ }
+ else
+ /* Read item count */
+ do_u16b(&tmp16b, flag);
+
+ /* Verify maximum */
+ if ((flag == ls_flag_t::LOAD) && (tmp16b > max_o_idx))
+ {
+ note(format("Too many (%d) object entries!", tmp16b));
+ return (FALSE);
}
- /* Special race */
- tmp = (m_ptr->sr_ptr) ? TRUE : FALSE;
- do_byte((byte*)&tmp, flag);
- if (tmp)
+ /* Dungeon items */
+ for (i = 1; i < tmp16b; i++)
{
- if (flag == LS_LOAD)
+ int o_idx;
+
+ object_type *o_ptr;
+
+ if (flag == ls_flag_t::SAVE)
{
- MAKE(m_ptr->sr_ptr, monster_race);
+ o_ptr = &o_list[i];
+ /* Don't save objects held by companions when no_companions is set */
+ if (no_companions && o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) continue;
+
+ do_item(o_ptr, ls_flag_t::SAVE);
+ continue; /* Saving is easy */
}
- do_u32b(&m_ptr->sr_ptr->name, flag);
- do_u32b(&m_ptr->sr_ptr->text, flag);
+ /* Until the end of the loop, this is all ls_flag_t::LOAD */
- do_u16b(&m_ptr->sr_ptr->hdice, flag);
- do_u16b(&m_ptr->sr_ptr->hside, flag);
+ /* Get a new record */
+ o_idx = o_pop();
- do_s16b(&m_ptr->sr_ptr->ac, flag);
+ /* Oops */
+ if (i != o_idx)
+ {
+ note(format("Object allocation error (%d <> %d)", i, o_idx));
+ return (FALSE);
+ }
- do_s16b(&m_ptr->sr_ptr->sleep, flag);
- do_byte(&m_ptr->sr_ptr->aaf, flag);
- do_byte(&m_ptr->sr_ptr->speed, flag);
- do_s32b(&m_ptr->sr_ptr->mexp, flag);
+ /* Acquire place */
+ o_ptr = &o_list[o_idx];
- do_s32b(&m_ptr->sr_ptr->weight, flag);
+ /* Read the item */
+ do_item(o_ptr, ls_flag_t::LOAD);
- do_byte(&m_ptr->sr_ptr->freq_inate, flag);
- do_byte(&m_ptr->sr_ptr->freq_spell, flag);
+ /* Monster */
+ if (o_ptr->held_m_idx)
+ {
+ /* Monster */
+ monster_type *m_ptr = &m_list[o_ptr->held_m_idx];
- do_u32b(&m_ptr->sr_ptr->flags1, flag);
- do_u32b(&m_ptr->sr_ptr->flags2, flag);
- do_u32b(&m_ptr->sr_ptr->flags3, flag);
- do_u32b(&m_ptr->sr_ptr->flags4, flag);
- do_u32b(&m_ptr->sr_ptr->flags5, flag);
- do_u32b(&m_ptr->sr_ptr->flags6, flag);
- do_u32b(&m_ptr->sr_ptr->flags7, flag);
- do_u32b(&m_ptr->sr_ptr->flags8, flag);
- do_u32b(&m_ptr->sr_ptr->flags9, flag);
+ /* Place the object */
+ m_ptr->hold_o_idxs.push_back(o_idx);
+ }
- /* Attacks */
- for (i = 0; i < 4; i++)
+ /* Dungeon */
+ else
{
- do_byte(&m_ptr->sr_ptr->blow[i].method, flag);
- do_byte(&m_ptr->sr_ptr->blow[i].effect, flag);
- do_byte(&m_ptr->sr_ptr->blow[i].d_dice, flag);
- do_byte(&m_ptr->sr_ptr->blow[i].d_side, flag);
+ /* Access the item location */
+ c_ptr = &cave[o_ptr->iy][o_ptr->ix];
+
+ /* Place the object */
+ c_ptr->o_idxs.push_back(o_idx);
}
+ }
- for (i = 0; i < BODY_MAX; i++)
- do_byte(&m_ptr->sr_ptr->body_parts[i], flag);
+ /*** Monsters ***/
- do_byte(&m_ptr->sr_ptr->level, flag);
- do_byte(&m_ptr->sr_ptr->rarity, flag);
+ if (flag == ls_flag_t::SAVE)
+ {
+ tmp16b = m_max;
+
+ if (no_companions)
+ {
+ for (i = 1; i < m_max; i++)
+ {
+ monster_type *m_ptr = &m_list[i];
- do_byte((byte*)&m_ptr->sr_ptr->d_char, flag);
- do_byte(&m_ptr->sr_ptr->d_attr, flag);
+ if (m_ptr->status == MSTATUS_COMPANION) tmp16b--;
+ }
+ }
+
+ /* Write the monster count */
+ do_u16b(&tmp16b, flag);
- do_byte((byte*)&m_ptr->sr_ptr->x_char, flag);
- do_byte(&m_ptr->sr_ptr->x_attr, flag);
+ tmp16b = m_max;
+ }
+ else
+ /* Read the monster count */
+ do_u16b(&tmp16b, flag);
- do_s16b(&m_ptr->sr_ptr->max_num, flag);
- do_byte(&m_ptr->sr_ptr->cur_num, flag);
+ /* Validate */
+ if ((flag == ls_flag_t::LOAD) && (tmp16b > max_m_idx))
+ {
+ note(format("Too many (%d) monster entries!", tmp16b));
+ return (FALSE);
}
+
+ /* Read the monsters */
+ for (i = 1; i < tmp16b; i++)
+ {
+ int m_idx;
+ monster_type *m_ptr;
+ monster_race *r_ptr;
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ m_ptr = &m_list[i];
+
+ /* Don't save companions when no_companions is set */
+ if (no_companions && m_ptr->status == MSTATUS_COMPANION) continue;
+
+ do_monster(m_ptr, ls_flag_t::SAVE);
+ continue; /* Easy to save a monster */
+ }
+ /* From here on, it's all ls_flag_t::LOAD */
+ /* Get a new record */
+ m_idx = m_pop();
+
+ /* Oops */
+ if (i != m_idx)
+ {
+ note(format("Monster allocation error (%d <> %d)", i, m_idx));
+ return (FALSE);
+ }
+
+ /* Acquire monster */
+ m_ptr = &m_list[m_idx];
+
+ /* Read the monster */
+ do_monster(m_ptr, ls_flag_t::LOAD);
+
+ /* Access grid */
+ c_ptr = &cave[m_ptr->fy][m_ptr->fx];
+
+ /* Mark the location */
+ c_ptr->m_idx = m_idx;
+
+ /* Controlled ? */
+ if (m_ptr->mflag & MFLAG_CONTROL)
+ p_ptr->control = m_idx;
+
+ /* Access race */
+ r_ptr = &r_info[m_ptr->r_idx];
+
+ /* Count XXX XXX XXX */
+ r_ptr->cur_num++;
+ }
+
+ /* Read the kept monsters */
+
+ tmp16b = (flag == ls_flag_t::SAVE && !no_companions) ? max_m_idx : 0;
+
+ /* Read the monster count */
+ do_u16b(&tmp16b, flag);
+
+ /* Hack -- verify */
+ if ((flag == ls_flag_t::LOAD) && (tmp16b > max_m_idx))
+ {
+ note(format("Too many (%d) monster entries!", tmp16b));
+ return (FALSE);
+ }
+ for (i = 1; i < tmp16b; i++)
+ {
+ monster_type *m_ptr;
+
+ /* Acquire monster */
+ m_ptr = &km_list[i];
+
+ /* Read the monster */
+ do_monster(m_ptr, flag);
+ }
+
+ /*** Success ***/
+
+ /* The dungeon is ready */
+ if (flag == ls_flag_t::LOAD) character_dungeon = TRUE;
+
+ /* Success */
+ return (TRUE);
}
+/* Save the current persistent dungeon -SC- */
+void save_dungeon(void)
+{
+ char tmp[16];
+ char name[1024], buf[5];
+ /* Save only persistent dungeons */
+ if (!get_dungeon_save(buf) || (!dun_level)) return;
+
+ /* Construct filename */
+ sprintf(tmp, "%s.%s", player_base, buf);
+ path_build(name, 1024, ANGBAND_DIR_SAVE, tmp);
+
+ /* Open the file */
+ fff = my_fopen(name, "wb");
+
+ /* Save the dungeon */
+ do_dungeon(ls_flag_t::SAVE, TRUE);
+
+ my_fclose(fff);
+}
+bool_ file_exist(cptr buf)
+{
+ int fd;
+ bool_ result;
+
+ /* Open savefile */
+ fd = fd_open(buf, O_RDONLY);
+
+ /* File exists */
+ if (fd >= 0)
+ {
+ fd_close(fd);
+ result = TRUE;
+ }
+ else
+ result = FALSE;
+
+ return result;
+}
/*
* Handle monster lore
*/
-static void do_lore(int r_idx, int flag)
+static void do_lore(int r_idx, ls_flag_t flag)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1683,7 +1726,7 @@ static void do_lore(int r_idx, int flag)
do_byte((byte*)&r_ptr->on_saved, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
/* Lore flag repair? */
r_ptr->r_flags1 &= r_ptr->flags1;
@@ -1701,38 +1744,33 @@ static void do_lore(int r_idx, int flag)
/*
* Read a store
*/
-static bool_ do_store(store_type *str, int flag)
-/* FIXME! Why does this return anything when
- it always returns the same thing? */
+static void do_store(store_type *str, ls_flag_t flag)
{
- int j;
-
- byte num;
-
byte store_inven_max = STORE_INVEN_MAX;
/* Some basic info */
do_s32b(&str->store_open, flag);
do_u16b(&str->owner, flag);
- if (flag == LS_SAVE) num = str->stock_num;
/* Could be cleaner, done this way for benefit of the for loop later on */
+ byte num;
+ if (flag == ls_flag_t::SAVE) num = str->stock_num;
do_byte(&num, flag);
/* Last visit */
do_s32b(&str->last_visit, flag);
/* Items */
- for (j = 0; j < num; j++)
+ for (int j = 0; j < num; j++)
{
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
/* Can't this be cleaner? */
{
object_type forge;
/* Wipe the object */
object_wipe(&forge);
/* Read the item */
- do_item(&forge, LS_LOAD);
+ do_item(&forge, ls_flag_t::LOAD);
/* Acquire valid items */
if ((str->stock_num < store_inven_max) && (str->stock_num < str->stock_size))
{
@@ -1742,17 +1780,14 @@ static bool_ do_store(store_type *str, int flag)
object_copy(&str->stock[k], &forge);
}
}
- if (flag == LS_SAVE) do_item(&str->stock[j], flag);
+ if (flag == ls_flag_t::SAVE) do_item(&str->stock[j], flag);
}
-
- /* Success */
- return (TRUE);
}
/*
* RNG state
*/
-static void do_randomizer(int flag)
+static void do_randomizer(ls_flag_t flag)
{
int i;
@@ -1771,7 +1806,7 @@ static void do_randomizer(int flag)
}
/* Accept */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
Rand_quick = FALSE;
}
@@ -1789,7 +1824,7 @@ static void do_randomizer(int flag)
* The window options are stored in the same way, but note that each
* window gets 32 options, and their order is fixed by certain defines.
*/
-static void do_options(int flag)
+static void do_options(ls_flag_t flag)
{
int i, n;
@@ -1805,10 +1840,10 @@ static void do_options(int flag)
do_byte(&hitpoint_warn, flag);
/*** Cheating options ***/
- if (flag == LS_LOAD) /* There *MUST* be some nice way to unify this! */
+ if (flag == ls_flag_t::LOAD) /* There *MUST* be some nice way to unify this! */
{
u16b c;
- do_u16b(&c, LS_LOAD);
+ do_u16b(&c, ls_flag_t::LOAD);
if (c & 0x0002) wizard = TRUE;
cheat_peek = (c & 0x0100) ? TRUE : FALSE;
cheat_hear = (c & 0x0200) ? TRUE : FALSE;
@@ -1817,7 +1852,7 @@ static void do_options(int flag)
cheat_know = (c & 0x1000) ? TRUE : FALSE;
cheat_live = (c & 0x2000) ? TRUE : FALSE;
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
u16b c = 0;
if (wizard) c |= 0x0002;
@@ -1827,14 +1862,14 @@ static void do_options(int flag)
if (cheat_xtra) c |= 0x0800;
if (cheat_know) c |= 0x1000;
if (cheat_live) c |= 0x2000;
- do_u16b(&c, LS_SAVE);
+ do_u16b(&c, ls_flag_t::SAVE);
}
do_byte((byte*)&autosave_l, flag);
do_byte((byte*)&autosave_t, flag);
do_s16b(&autosave_freq, flag);
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
/* Read the option flags */
for (n = 0; n < 8; n++) do_u32b(&oflag[n], flag);
@@ -1911,7 +1946,7 @@ static void do_options(int flag)
}
}
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
/* Analyze the options */
for (i = 0; option_info[i].o_desc; i++)
@@ -1958,33 +1993,15 @@ static void do_options(int flag)
}
-/* Load/Save the random spells info */
-static void do_spells(int i, int flag)
-{
- random_spell *s_ptr = &random_spells[i];
- do_string(s_ptr->name, 30, flag);
- do_string(s_ptr->desc, 30, flag);
- do_s16b(&s_ptr->mana, flag);
- do_s16b(&s_ptr->fail, flag);
- do_u32b(&s_ptr->proj_flags, flag);
- do_byte(&s_ptr->GF, flag);
- do_byte(&s_ptr->radius, flag);
- do_byte(&s_ptr->dam_sides, flag);
- do_byte(&s_ptr->dam_dice, flag);
- do_byte(&s_ptr->level, flag);
- do_byte((byte*)&s_ptr->untried, flag);
-}
-
-
/*
* Handle player inventory
*
* FIXME! This function probably could be unified better
* Note that the inventory is "re-sorted" later by "dungeon()".
*/
-static bool_ do_inventory(int flag)
+static bool_ do_inventory(ls_flag_t flag)
{
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
int slot = 0;
@@ -2001,7 +2018,7 @@ static bool_ do_inventory(int flag)
u16b n;
/* Get the next item index */
- do_u16b(&n, LS_LOAD);
+ do_u16b(&n, ls_flag_t::LOAD);
/* Nope, we reached the end */
if (n == 0xFFFF) break;
@@ -2013,7 +2030,7 @@ static bool_ do_inventory(int flag)
object_wipe(q_ptr);
/* Read the item */
- do_item(q_ptr, LS_LOAD);
+ do_item(q_ptr, ls_flag_t::LOAD);
/* Hack -- verify item */
if (!q_ptr->k_idx) return (FALSE);
@@ -2058,7 +2075,7 @@ static bool_ do_inventory(int flag)
}
}
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
u16b i;
u16b sent = 0xFFFF;
@@ -2069,7 +2086,7 @@ static bool_ do_inventory(int flag)
do_u16b(&i, flag);
do_item(o_ptr, flag);
}
- do_u16b(&sent, LS_SAVE); /* Sentinel */
+ do_u16b(&sent, ls_flag_t::SAVE); /* Sentinel */
}
/* Success */
return (TRUE);
@@ -2080,7 +2097,7 @@ static bool_ do_inventory(int flag)
/*
* Read the saved messages
*/
-static void do_messages(int flag) /* FIXME! We should be able to unify this better */
+static void do_messages(ls_flag_t flag) /* FIXME! We should be able to unify this better */
{
int i;
char buf[128];
@@ -2088,19 +2105,18 @@ static void do_messages(int flag) /* FIXME! We should be able to unify this be
s16b num;
- if (flag == LS_SAVE) num = message_num();
-
/* Total */
+ if (flag == ls_flag_t::SAVE) num = message_num();
do_s16b(&num, flag);
/* Read the messages */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
byte tmp8u = 0;
for (i = 0; i < num; i++)
{
/* Read the message */
- do_string(buf, 128, LS_LOAD);
+ do_string(buf, 128, ls_flag_t::LOAD);
do_byte(&color, flag);
do_byte(&tmp8u, flag);
@@ -2108,13 +2124,13 @@ static void do_messages(int flag) /* FIXME! We should be able to unify this be
message_add(buf, color);
}
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
byte holder;
byte zero = 0;
for (i = num - 1; i >= 0; i--)
{
- do_string((char *)message_str((s16b)i), 0, LS_SAVE);
+ do_string((char *)message_str((s16b)i), 0, ls_flag_t::SAVE);
holder = message_color((s16b)i);
do_byte(&holder, flag);
do_byte(&zero, flag);
@@ -2122,300 +2138,6 @@ static void do_messages(int flag) /* FIXME! We should be able to unify this be
}
}
-/*
- * Handle dungeon
- *
- * The monsters/objects must be loaded in the same order
- * that they were stored, since the actual indexes matter.
- */
-static bool_ do_dungeon(int flag, bool_ no_companions)
-{
- int i;
-
- cave_type *c_ptr;
-
- /* Read specific */
- u16b tmp16b = 0;
-
- my_sentinel("Before do_dungeon", 324, flag);
-
- /* Header info */
- do_s16b(&dun_level, flag);
- do_byte(&dungeon_type, flag);
- do_s16b(&num_repro, flag);
- do_s16b(&p_ptr->py, flag);
- do_s16b(&p_ptr->px, flag);
- do_s16b(&cur_hgt, flag);
- do_s16b(&cur_wid, flag);
- do_s16b(&max_panel_rows, flag);
- do_s16b(&max_panel_cols, flag);
-
- do_u32b(&dungeon_flags1, flag);
- do_u32b(&dungeon_flags2, flag);
-
- /* Last teleportation */
- do_s16b(&last_teleportation_y, flag);
- do_s16b(&last_teleportation_y, flag);
-
- /* Spell effects */
- tmp16b = MAX_EFFECTS;
- do_u16b(&tmp16b, flag);
-
- if ((flag == LS_LOAD) && (tmp16b > MAX_EFFECTS))
- {
- quit("Too many spell effects");
- }
-
- for (i = 0; i < tmp16b; ++i)
- {
- do_s16b(&effects[i].type, flag);
- do_s16b(&effects[i].dam, flag);
- do_s16b(&effects[i].time, flag);
- do_u32b(&effects[i].flags, flag);
- do_s16b(&effects[i].cx, flag);
- do_s16b(&effects[i].cy, flag);
- do_s16b(&effects[i].rad, flag);
- }
-
- /* TO prevent bugs with evolving dungeons */
- for (i = 0; i < 100; i++)
- {
- do_s16b(&floor_type[i], flag);
- do_s16b(&fill_type[i], flag);
- }
-
- if ((flag == LS_LOAD) && (!dun_level && !p_ptr->inside_quest))
- {
- int xstart = 0;
- int ystart = 0;
- /* Init the wilderness */
- process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
- TRUE, FALSE);
-
- /* Init the town */
- xstart = 0;
- ystart = 0;
- init_flags = 0;
- process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid,
- TRUE, FALSE);
- }
-
- do_grid(flag);
-
- /*** Objects ***/
-
- if (flag == LS_SAVE) compact_objects(0);
- if (flag == LS_SAVE) compact_monsters(0);
- if (flag == LS_SAVE)
- {
- tmp16b = o_max;
-
- if (no_companions)
- {
- for (i = 1; i < o_max; i++)
- {
- object_type *o_ptr = &o_list[i];
-
- if (o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) tmp16b--;
- }
- }
-
- /* Item count */
- do_u16b(&tmp16b, flag);
-
- tmp16b = o_max;
- }
- else
- /* Read item count */
- do_u16b(&tmp16b, flag);
-
- /* Verify maximum */
- if ((flag == LS_LOAD) && (tmp16b > max_o_idx))
- {
- note(format("Too many (%d) object entries!", tmp16b));
- return (FALSE);
- }
-
- /* Dungeon items */
- for (i = 1; i < tmp16b; i++)
- {
- int o_idx;
-
- object_type *o_ptr;
-
- if (flag == LS_SAVE)
- {
- o_ptr = &o_list[i];
- /* Don't save objects held by companions when no_companions is set */
- if (no_companions && o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) continue;
-
- do_item(o_ptr, LS_SAVE);
- continue; /* Saving is easy */
- }
- /* Until the end of the loop, this is all LS_LOAD */
-
- /* Get a new record */
- o_idx = o_pop();
-
- /* Oops */
- if (i != o_idx)
- {
- note(format("Object allocation error (%d <> %d)", i, o_idx));
- return (FALSE);
- }
-
-
- /* Acquire place */
- o_ptr = &o_list[o_idx];
-
- /* Read the item */
- do_item(o_ptr, LS_LOAD);
-
- /* Monster */
- if (o_ptr->held_m_idx)
- {
- monster_type *m_ptr;
-
- /* Monster */
- m_ptr = &m_list[o_ptr->held_m_idx];
-
- /* Build a stack */
- o_ptr->next_o_idx = m_ptr->hold_o_idx;
-
- /* Place the object */
- m_ptr->hold_o_idx = o_idx;
- }
-
- /* Dungeon */
- else
- {
- /* Access the item location */
- c_ptr = &cave[o_ptr->iy][o_ptr->ix];
-
- /* Build a stack */
- o_ptr->next_o_idx = c_ptr->o_idx;
-
- /* Place the object */
- c_ptr->o_idx = o_idx;
- }
- }
-
- /*** Monsters ***/
-
- if (flag == LS_SAVE)
- {
- tmp16b = m_max;
-
- if (no_companions)
- {
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr = &m_list[i];
-
- if (m_ptr->status == MSTATUS_COMPANION) tmp16b--;
- }
- }
-
- /* Write the monster count */
- do_u16b(&tmp16b, flag);
-
- tmp16b = m_max;
- }
- else
- /* Read the monster count */
- do_u16b(&tmp16b, flag);
-
- /* Validate */
- if ((flag == LS_LOAD) && (tmp16b > max_m_idx))
- {
- note(format("Too many (%d) monster entries!", tmp16b));
- return (FALSE);
- }
-
- /* Read the monsters */
- for (i = 1; i < tmp16b; i++)
- {
- int m_idx;
- monster_type *m_ptr;
- monster_race *r_ptr;
-
- if (flag == LS_SAVE)
- {
- m_ptr = &m_list[i];
-
- /* Don't save companions when no_companions is set */
- if (no_companions && m_ptr->status == MSTATUS_COMPANION) continue;
-
- do_monster(m_ptr, LS_SAVE);
- continue; /* Easy to save a monster */
- }
- /* From here on, it's all LS_LOAD */
- /* Get a new record */
- m_idx = m_pop();
-
- /* Oops */
- if (i != m_idx)
- {
- note(format("Monster allocation error (%d <> %d)", i, m_idx));
- return (FALSE);
- }
-
- /* Acquire monster */
- m_ptr = &m_list[m_idx];
-
- /* Read the monster */
- do_monster(m_ptr, LS_LOAD);
-
- /* Access grid */
- c_ptr = &cave[m_ptr->fy][m_ptr->fx];
-
- /* Mark the location */
- c_ptr->m_idx = m_idx;
-
- /* Controlled ? */
- if (m_ptr->mflag & MFLAG_CONTROL)
- p_ptr->control = m_idx;
-
- /* Access race */
- r_ptr = &r_info[m_ptr->r_idx];
-
- /* Count XXX XXX XXX */
- r_ptr->cur_num++;
- }
-
- /* Read the kept monsters */
-
- tmp16b = (flag == LS_SAVE && !no_companions) ? max_m_idx : 0;
-
- /* Read the monster count */
- do_u16b(&tmp16b, flag);
-
- /* Hack -- verify */
- if ((flag == LS_LOAD) && (tmp16b > max_m_idx))
- {
- note(format("Too many (%d) monster entries!", tmp16b));
- return (FALSE);
- }
- for (i = 1; i < tmp16b; i++)
- {
- monster_type *m_ptr;
-
- /* Acquire monster */
- m_ptr = &km_list[i];
-
- /* Read the monster */
- do_monster(m_ptr, flag);
- }
-
- /*** Success ***/
-
- /* The dungeon is ready */
- if (flag == LS_LOAD) character_dungeon = TRUE;
-
- /* Success */
- return (TRUE);
-}
-
/* Returns TRUE if we successfully load the dungeon */
bool_ load_dungeon(char *ext)
{
@@ -2441,7 +2163,7 @@ bool_ load_dungeon(char *ext)
}
/* Read the dungeon */
- if (!do_dungeon(LS_LOAD, FALSE))
+ if (!do_dungeon(ls_flag_t::LOAD, FALSE))
{
dun_level = old_dun;
dungeon_type = old_dungeon_type;
@@ -2458,26 +2180,9 @@ bool_ load_dungeon(char *ext)
return (TRUE);
}
-void do_blocks(int flag)
-/* Handle blocked-allocation stuff for quests and lua stuff
- This depends on a dyn_tosave array of s32b's. Adjust as needed
- if other data structures are desirable. This also is not hooked
- in yet. Ideally, plug it near the end of the savefile.
- */
-{
- s16b numblks, n_iter = 0; /* How many blocks do we have? */
- do_s16b(&numblks, flag);
- while (n_iter < numblks)
- {
- /* do_s32b(dyn_tosave[n_iter], flag); */
- n_iter++;
- }
- my_sentinel("In blocked-allocation area", 37, flag);
-}
-
-void do_fate(int i, int flag)
+void do_fate(int i, ls_flag_t flag)
{
- if ((flag == LS_LOAD) && (i >= MAX_FATES)) i = MAX_FATES - 1;
+ if ((flag == ls_flag_t::LOAD) && (i >= MAX_FATES)) i = MAX_FATES - 1;
do_byte(&fates[i].fate, flag);
do_byte(&fates[i].level, flag);
@@ -2495,7 +2200,7 @@ void do_fate(int i, int flag)
/*
* Load/save timers.
*/
-static void do_timers(int flag)
+static void do_timers(ls_flag_t flag)
{
timer_type *t_ptr;
@@ -2508,20 +2213,93 @@ static void do_timers(int flag)
}
/*
+ * Load/save stores.
+ */
+static void do_stores(ls_flag_t flag)
+{
+ u16b tmp16u;
+ u16b real_max = 0;
+
+ /* Note that this forbids max_towns from shrinking, but that is fine */
+ std::unique_ptr<byte[]> reals(new byte[max_towns]);
+
+ /* Find the real towns */
+ if (flag == ls_flag_t::SAVE)
+ {
+ for (int i = 1; i < max_towns; i++)
+ {
+ if (!(town_info[i].flags & (TOWN_REAL))) continue;
+ reals[real_max++] = i;
+ }
+ }
+ do_u16b(&real_max, flag);
+ for (int i = 0; i < real_max; i++)
+ {
+ do_byte((byte*)&reals[i], flag);
+ }
+
+ /* Read the stores */
+ if (flag == ls_flag_t::SAVE) tmp16u = max_st_idx;
+ do_u16b(&tmp16u, flag);
+ assert(tmp16u <= max_st_idx);
+
+ /* Ok now read the real towns */
+ for (int i = 0; i < real_max; i++)
+ {
+ int z = reals[i];
+
+ /* Ultra paranoia */
+ if (!town_info[z].stocked) create_stores_stock(z);
+
+ for (int j = 0; j < tmp16u; j++)
+ {
+ do_store(&town_info[z].store[j], flag);
+ }
+ }
+}
+
+/*
+ * Note that this function may not be needed at all.
+ * It was taken out of load_player_aux(). Do we need it?
+ */
+static void junkinit(void)
+{
+ int i, j;
+ p_ptr->inside_quest = 0;
+ p_ptr->town_num = 1;
+ p_ptr->wilderness_x = 4;
+ p_ptr->wilderness_y = 4;
+ for (i = 0; i < max_wild_x; i++)
+ {
+ for (j = 0; j < max_wild_y; j++)
+ {
+ wild_map[j][i].seed = rand_int(0x10000000);
+ }
+ }
+}
+
+static void morejunk(void)
+{
+ sp_ptr = &sex_info[p_ptr->psex]; /* Sex */
+ rp_ptr = &race_info[p_ptr->prace]; /* Raceclass */
+ rmp_ptr = &race_mod_info[p_ptr->pracem];
+ cp_ptr = &class_info[p_ptr->pclass];
+ spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
+}
+
+
+/*
* Actually read the savefile
*/
-static bool_ do_savefile_aux(int flag)
+static bool_ do_savefile_aux(ls_flag_t flag)
{
int i, j;
byte tmp8u;
u16b tmp16u;
- bool_ *reals;
- u16b real_max = 0;
-
/* Mention the savefile version */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
if (vernum < 100)
{
@@ -2533,15 +2311,14 @@ static bool_ do_savefile_aux(int flag)
note(format("Loading version %lu savefile... ", vernum));
}
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
sf_when = time((time_t *) 0); /* Note when file was saved */
- sf_xtra = 0L; /* What the hell is this? */
sf_saves++; /* Increment the saves ctr */
}
/* Handle version bytes. FIXME! DG wants me to change this all around */
- if (flag == LS_LOAD)
+ if (flag == ls_flag_t::LOAD)
{
u32b mt32b;
byte mtbyte;
@@ -2550,7 +2327,7 @@ static bool_ do_savefile_aux(int flag)
do_u32b(&mt32b, flag);
do_byte(&mtbyte, flag);
}
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
u32b saver;
saver = SAVEFILE_VERSION;
@@ -2559,8 +2336,11 @@ static bool_ do_savefile_aux(int flag)
do_byte(&tmp8u, flag); /* 'encryption' */
}
- /* Operating system info? Not really. This is just set to 0L */
- do_u32b(&sf_xtra, flag);
+ /* Kept only for compatibility; always set to 0 */
+ {
+ u32b tmp32u = 0;
+ do_u32b(&tmp32u, flag);
+ }
/* Time of last save */
do_u32b(&sf_when, flag);
@@ -2572,7 +2352,7 @@ static bool_ do_savefile_aux(int flag)
do_u16b(&sf_saves, flag);
/* Game module */
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
strcpy(loaded_game_module, game_module);
do_string(loaded_game_module, 80, flag);
@@ -2592,11 +2372,11 @@ static bool_ do_savefile_aux(int flag)
do_messages(flag);
/* Monster Memory */
- if (flag == LS_SAVE) tmp16u = max_r_idx;
+ if (flag == ls_flag_t::SAVE) tmp16u = max_r_idx;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > max_r_idx))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > max_r_idx))
{
note(format("Too many (%u) monster races!", tmp16u));
return (FALSE);
@@ -2610,11 +2390,11 @@ static bool_ do_savefile_aux(int flag)
}
/* Object Memory */
- if (flag == LS_SAVE) tmp16u = max_k_idx;
+ if (flag == ls_flag_t::SAVE) tmp16u = max_k_idx;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > max_k_idx))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > max_k_idx))
{
note(format("Too many (%u) object kinds!", tmp16u));
return (FALSE);
@@ -2622,25 +2402,25 @@ static bool_ do_savefile_aux(int flag)
/* Read the object memory */
for (i = 0; i < tmp16u; i++) do_xtra(i, flag);
- if (flag == LS_LOAD) junkinit();
+ if (flag == ls_flag_t::LOAD) junkinit();
{
u16b max_towns_ldsv;
u16b max_quests_ldsv;
- if (flag == LS_SAVE) max_towns_ldsv = max_towns;
+ if (flag == ls_flag_t::SAVE) max_towns_ldsv = max_towns;
/* Number of towns */
do_u16b(&max_towns_ldsv, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (max_towns_ldsv > max_towns))
+ if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > max_towns))
{
note(format("Too many (%u) towns!", max_towns_ldsv));
return (FALSE);
}
/* Min of random towns */
- if (flag == LS_SAVE) max_towns_ldsv = TOWN_RANDOM;
+ if (flag == ls_flag_t::SAVE) max_towns_ldsv = TOWN_RANDOM;
do_u16b(&max_towns_ldsv, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (max_towns_ldsv != TOWN_RANDOM))
+ if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv != TOWN_RANDOM))
{
note(format("Different random towns base (%u)!", max_towns_ldsv));
return (FALSE);
@@ -2657,7 +2437,7 @@ static bool_ do_savefile_aux(int flag)
do_byte(&town_info[i].flags, flag);
/* If the town is realy used create a sock */
- if ((town_info[i].flags & (TOWN_REAL)) && (flag == LS_LOAD))
+ if ((town_info[i].flags & (TOWN_REAL)) && (flag == ls_flag_t::LOAD))
{
create_stores_stock(i);
}
@@ -2665,21 +2445,21 @@ static bool_ do_savefile_aux(int flag)
}
/* Number of dungeon */
- if (flag == LS_SAVE) max_towns_ldsv = max_d_idx;
+ if (flag == ls_flag_t::SAVE) max_towns_ldsv = max_d_idx;
do_u16b(&max_towns_ldsv, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (max_towns_ldsv > max_d_idx))
+ if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > max_d_idx))
{
note(format("Too many dungeon types (%u)!", max_towns_ldsv));
return (FALSE);
}
/* Number of towns per dungeon */
- if (flag == LS_SAVE) max_quests_ldsv = TOWN_DUNGEON;
+ if (flag == ls_flag_t::SAVE) max_quests_ldsv = TOWN_DUNGEON;
do_u16b(&max_quests_ldsv, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (max_quests_ldsv > TOWN_DUNGEON))
+ if ((flag == ls_flag_t::LOAD) && (max_quests_ldsv > TOWN_DUNGEON))
{
note(format("Too many town per dungeons (%u)!", max_quests_ldsv));
return (FALSE);
@@ -2696,11 +2476,11 @@ static bool_ do_savefile_aux(int flag)
}
/* Sanity check number of quests */
- if (flag == LS_SAVE) max_quests_ldsv = MAX_Q_IDX;
+ if (flag == ls_flag_t::SAVE) max_quests_ldsv = MAX_Q_IDX;
do_u16b(&max_quests_ldsv, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (max_quests_ldsv != MAX_Q_IDX))
+ if ((flag == ls_flag_t::LOAD) && (max_quests_ldsv != MAX_Q_IDX))
{
note(format("Invalid number of quests (%u)!", max_quests_ldsv));
return (FALSE);
@@ -2709,13 +2489,13 @@ static bool_ do_savefile_aux(int flag)
for (i = 0; i < MAX_Q_IDX; i++)
{
do_s16b(&quest[i].status, flag);
- for (j = 0; j < sizeof(quest[i].data)/sizeof(quest[i].data[0]); j++)
+ for (auto &quest_data : quest[i].data)
{
- do_s32b(&(quest[i].data[j]), flag);
+ do_s32b(&quest_data, flag);
}
/* Init the hooks */
- if (flag == LS_LOAD)
+ if ((flag == ls_flag_t::LOAD) && (quest[i].init != NULL))
{
quest[i].init(i);
}
@@ -2729,7 +2509,7 @@ static bool_ do_savefile_aux(int flag)
{
s32b wild_x_size, wild_y_size;
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
wild_x_size = max_wild_x;
wild_y_size = max_wild_y;
@@ -2738,11 +2518,11 @@ static bool_ do_savefile_aux(int flag)
do_s32b(&wild_x_size, flag);
do_s32b(&wild_y_size, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) &&
- ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y)))
+ if ((flag == ls_flag_t::LOAD) &&
+ ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y)))
{
note(format("Wilderness is too big (%u/%u)!",
- wild_x_size, wild_y_size));
+ wild_x_size, wild_y_size));
return (FALSE);
}
/* Wilderness seeds */
@@ -2759,9 +2539,9 @@ static bool_ do_savefile_aux(int flag)
}
/* Load the random artifacts. */
- if (flag == LS_SAVE) tmp16u = MAX_RANDARTS;
+ if (flag == ls_flag_t::SAVE) tmp16u = MAX_RANDARTS;
do_u16b(&tmp16u, flag);
- if ((flag == LS_LOAD) && (tmp16u > MAX_RANDARTS))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_RANDARTS))
{
note(format("Too many (%u) random artifacts!", tmp16u));
return (FALSE);
@@ -2780,10 +2560,10 @@ static bool_ do_savefile_aux(int flag)
}
/* Load the Artifacts */
- if (flag == LS_SAVE) tmp16u = max_a_idx;
+ if (flag == ls_flag_t::SAVE) tmp16u = max_a_idx;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > max_a_idx))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > max_a_idx))
{
note(format("Too many (%u) artifacts!", tmp16u));
return (FALSE);
@@ -2796,11 +2576,11 @@ static bool_ do_savefile_aux(int flag)
}
/* Fates */
- if (flag == LS_SAVE) tmp16u = MAX_FATES;
+ if (flag == ls_flag_t::SAVE) tmp16u = MAX_FATES;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > MAX_FATES))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_FATES))
{
note(format("Too many (%u) fates!", tmp16u));
return (FALSE);
@@ -2813,11 +2593,11 @@ static bool_ do_savefile_aux(int flag)
}
/* Load the Traps */
- if (flag == LS_SAVE) tmp16u = max_t_idx;
+ if (flag == ls_flag_t::SAVE) tmp16u = max_t_idx;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > max_t_idx))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > max_t_idx))
{
note(format("Too many (%u) traps!", tmp16u));
return (FALSE);
@@ -2830,11 +2610,11 @@ static bool_ do_savefile_aux(int flag)
}
/* inscription knowledge */
- if (flag == LS_SAVE) tmp16u = MAX_INSCRIPTIONS;
+ if (flag == ls_flag_t::SAVE) tmp16u = MAX_INSCRIPTIONS;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > MAX_INSCRIPTIONS))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_INSCRIPTIONS))
{
note(format("Too many (%u) inscriptions!", tmp16u));
return (FALSE);
@@ -2851,10 +2631,10 @@ static bool_ do_savefile_aux(int flag)
/* player_hp array */
- if (flag == LS_SAVE) tmp16u = PY_MAX_LEVEL;
+ if (flag == ls_flag_t::SAVE) tmp16u = PY_MAX_LEVEL;
do_u16b(&tmp16u, flag);
/* Incompatible save files */
- if ((flag == LS_LOAD) && (tmp16u > PY_MAX_LEVEL))
+ if ((flag == ls_flag_t::LOAD) && (tmp16u > PY_MAX_LEVEL))
{
note(format("Too many (%u) hitpoint entries!", tmp16u));
return (FALSE);
@@ -2866,7 +2646,7 @@ static bool_ do_savefile_aux(int flag)
do_s16b(&player_hp[i], flag);
}
- if (flag == LS_LOAD) morejunk();
+ if (flag == ls_flag_t::LOAD) morejunk();
/* Read the pet command settings */
do_byte(&p_ptr->pet_follow_distance, flag);
@@ -2877,66 +2657,33 @@ static bool_ do_savefile_aux(int flag)
do_s16b(&p_ptr->dripping_tread, flag);
/* Read the inventory */
- if (!do_inventory(flag) && (flag == LS_LOAD)) /* do NOT reverse this ordering */
+ if (!do_inventory(flag) && (flag == ls_flag_t::LOAD)) /* do NOT reverse this ordering */
{
note("Unable to read inventory");
return (FALSE);
}
- /* Note that this forbids max_towns from shrinking, but that is fine */
- C_MAKE(reals, max_towns, bool_);
-
- /* Find the real towns */
- if (flag == LS_SAVE)
- {
- for (i = 1; i < max_towns; i++)
- {
- if (!(town_info[i].flags & (TOWN_REAL))) continue;
- reals[real_max++] = i;
- }
- }
- do_u16b(&real_max, flag);
- for (i = 0; i < real_max; i++)
- {
- do_byte((byte*)&reals[i], flag);
- }
-
- /* Read the stores */
- if (flag == LS_SAVE) tmp16u = max_st_idx;
- do_u16b(&tmp16u, flag);
-
- /* Ok now read the real towns */
- for (i = 0; i < real_max; i++)
- {
- int z = reals[i];
-
- /* Ultra paranoia */
- if (!town_info[z].stocked) create_stores_stock(z);
-
- for (j = 0; j < tmp16u; j++)
- do_store(&town_info[z].store[j], flag);
- }
-
- C_FREE(reals, max_towns, bool_);
+ /* Stores */
+ do_stores(flag);
/* I'm not dead yet... */
if (!death)
{
/* Dead players have no dungeon */
- if (flag == LS_LOAD) note("Restoring Dungeon...");
- if ((flag == LS_LOAD) && (!do_dungeon(LS_LOAD, FALSE)))
+ if (flag == ls_flag_t::LOAD) note("Restoring Dungeon...");
+ if ((flag == ls_flag_t::LOAD) && (!do_dungeon(ls_flag_t::LOAD, FALSE)))
{
note("Error reading dungeon data");
return (FALSE);
}
- if (flag == LS_SAVE) do_dungeon(LS_SAVE, FALSE);
+ if (flag == ls_flag_t::SAVE) do_dungeon(ls_flag_t::SAVE, FALSE);
my_sentinel("Before ghost data", 435, flag);
my_sentinel("After ghost data", 320, flag);
}
{
byte foo = 0;
- if (flag == LS_SAVE)
+ if (flag == ls_flag_t::SAVE)
{
/*
* Safety Padding. It's there
@@ -2946,7 +2693,7 @@ static bool_ do_savefile_aux(int flag)
* read it. Insert any new stuff before
* this position.
*/
- do_byte(&foo, LS_SAVE);
+ do_byte(&foo, ls_flag_t::SAVE);
}
}
@@ -2955,21 +2702,22 @@ static bool_ do_savefile_aux(int flag)
}
+
/*
* Actually read the savefile
*/
-errr rd_savefile(void)
+static errr rd_savefile(void)
{
errr err = 0;
/* The savefile is a binary file */
fff = my_fopen(savefile, "rb");
-
+
/* Paranoia */
if (!fff) return ( -1);
/* Call the sub-function */
- err = !do_savefile_aux(LS_LOAD);
+ err = !do_savefile_aux(ls_flag_t::LOAD);
/* Check for errors */
if (ferror(fff)) err = -1;
@@ -2981,256 +2729,269 @@ errr rd_savefile(void)
return (err);
}
+
/*
- * Note that this function may not be needed at all.
- * It was taken out of load_player_aux(). Do we need it?
+ * Attempt to Load a "savefile"
+ *
+ * On multi-user systems, you may only "read" a savefile if you will be
+ * allowed to "write" it later, this prevents painful situations in which
+ * the player loads a savefile belonging to someone else, and then is not
+ * allowed to save his game when he quits.
+ *
+ * We return "TRUE" if the savefile was usable, and we set the global
+ * flag "character_loaded" if a real, living, character was loaded.
+ *
+ * Note that we always try to load the "current" savefile, even if
+ * there is no such file, so we must check for "empty" savefile names.
*/
-static void junkinit(void)
+bool_ load_player(void)
{
- int i, j;
- p_ptr->arena_number = 0;
- p_ptr->inside_arena = 0;
- p_ptr->inside_quest = 0;
- p_ptr->exit_bldg = TRUE;
- p_ptr->exit_bldg = TRUE;
- p_ptr->town_num = 1;
- p_ptr->wilderness_x = 4;
- p_ptr->wilderness_y = 4;
- for (i = 0; i < max_wild_x; i++)
+ int fd = -1;
+
+ errr err = 0;
+
+ cptr what = "generic";
+
+ /* Paranoia */
+ turn = 0;
+
+ /* Paranoia */
+ death = FALSE;
+
+
+ /* Allow empty savefile name */
+ if (!savefile[0]) return (TRUE);
+
+
+ /* XXX XXX XXX Fix this */
+
+ /* Verify the existance of the savefile */
+ if (!file_exist(savefile))
{
- for (j = 0; j < max_wild_y; j++)
- {
- wild_map[j][i].seed = rand_int(0x10000000);
- }
+ /* Give a message */
+ msg_format("Savefile does not exist: %s", savefile);
+ msg_print(NULL);
+
+ /* Allow this */
+ return (TRUE);
}
-}
-static void morejunk(void)
-{
- sp_ptr = &sex_info[p_ptr->psex]; /* Sex */
- rp_ptr = &race_info[p_ptr->prace]; /* Raceclass */
- rmp_ptr = &race_mod_info[p_ptr->pracem];
- cp_ptr = &class_info[p_ptr->pclass];
- spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
-}
+ /* Okay */
+ if (!err)
+ {
+ /* Open the savefile */
+ fd = fd_open(savefile, O_RDONLY);
-static void do_grid(int flag)
-/* Does the grid, RLE, blahblah. RLE sucks. I hate it. */
-{
- int i = 0, y = 0, x = 0;
- byte count = 0;
- byte tmp8u = 0;
- s16b tmp16s = 0;
- cave_type *c_ptr;
- byte prev_char = 0;
- s16b prev_s16b = 0;
- int ymax = cur_hgt, xmax = cur_wid;
+ /* No file */
+ if (fd < 0) err = -1;
- int part; /* Which section of the grid we're on */
+ /* Message (below) */
+ if (err) what = "Cannot open savefile";
+ }
- for (part = 0; part < 9; part++) /* There are 8 fields to the grid, each stored
- in a seperate RLE data structure */
+ /* Process file */
+ if (!err)
{
- if (flag == LS_SAVE)
- {
- count = 0;
- prev_s16b = 0;
- prev_char = 0; /* Clear, prepare for RLE */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- c_ptr = &cave[y][x];
- switch (part)
- {
- case 0:
- tmp16s = c_ptr->info;
- break;
+ byte tmp8u = 0;
- case 1:
- tmp8u = c_ptr->feat;
- break;
+ /* Open the file XXX XXX XXX XXX Should use Angband file interface */
+ fff = my_fopen(savefile, "rb");
+/* fff = fdopen(fd, "r"); */
- case 2:
- tmp8u = c_ptr->mimic;
- break;
+ /* Read the first four bytes */
+ do_u32b(&vernum, ls_flag_t::LOAD);
+ do_byte(&tmp8u, ls_flag_t::LOAD); // For comatibility with old savefiles
- case 3:
- tmp16s = c_ptr->special;
- break;
+ /* XXX XXX XXX XXX Should use Angband file interface */
+ my_fclose(fff);
+ /* fclose(fff) */
- case 4:
- tmp16s = c_ptr->special2;
- break;
+ /* Close the file */
+ fd_close(fd);
+ }
- case 5:
- tmp16s = c_ptr->t_idx;
- break;
+ /* Process file */
+ if (!err)
+ {
- case 6:
- tmp16s = c_ptr->inscription;
- break;
+ /* Extract version */
+ sf_major = VERSION_MAJOR;
+ sf_minor = VERSION_MINOR;
+ sf_patch = VERSION_PATCH;
- case 7:
- tmp8u = c_ptr->mana;
- break;
+ /* Clear screen */
+ Term_clear();
- case 8:
- tmp16s = c_ptr->effect;
- break;
- }
- /* Flush a full run */
- if ((((part != 1) && (part != 2) && (part != 7)) &&
- (tmp16s != prev_s16b)) || (((part == 1) || (part == 2)
- || (part == 7)) &&
- (tmp8u != prev_char)) ||
- (count == MAX_UCHAR))
- {
- do_byte(&count, LS_SAVE);
- switch (part)
- {
- case 0:
- case 3:
- case 4:
- case 5:
- case 6:
- case 8:
- do_s16b(&prev_s16b, LS_SAVE);
- prev_s16b = tmp16s;
- break;
-
- case 1:
- case 2:
- case 7:
- do_byte(&prev_char, LS_SAVE);
- prev_char = tmp8u;
- break;
- }
- count = 1; /* Reset RLE */
- }
- else
- count++; /* Otherwise, keep going */
- }
- }
- /* Fallen off the end of the world, flush anything left */
- if (count)
+ /* Attempt to load */
+ err = rd_savefile();
+
+ /* Message (below) */
+ if (err) what = "Cannot parse savefile";
+ }
+
+ /* Paranoia */
+ if (!err)
+ {
+ /* Invalid turn */
+ if (!turn) err = -1;
+
+ /* Message (below) */
+ if (err) what = "Broken savefile";
+ }
+
+
+ /* Okay */
+ if (!err)
+ {
+ /* Player is dead */
+ if (death)
+ {
+ /* Player is no longer "dead" */
+ death = FALSE;
+
+ /* Cheat death (unless the character retired) */
+ if (arg_wizard && !total_winner)
{
- do_byte(&count, LS_SAVE);
- switch (part)
- {
- case 0:
- case 3:
- case 4:
- case 5:
- case 6:
- case 8:
- do_s16b(&prev_s16b, LS_SAVE);
- break;
-
- case 1:
- case 2:
- case 7:
- do_byte(&prev_char, LS_SAVE);
- break;
- }
+ /* A character was loaded */
+ character_loaded = TRUE;
+
+ /* Done */
+ return (TRUE);
}
+
+ /* Count lives */
+ sf_lives++;
+
+ /* Forget turns */
+ turn = old_turn = 0;
+
+ /* Done */
+ return (TRUE);
}
- if (flag == LS_LOAD)
+
+ /* A character was loaded */
+ character_loaded = TRUE;
+
+ /* Still alive */
+ if (p_ptr->chp >= 0)
{
- x = 0;
- for (y = 0; y < ymax; )
- {
- do_byte(&count, LS_LOAD);
- switch (part)
- {
- case 0:
- case 3:
- case 4:
- case 5:
- case 6:
- case 8:
- do_s16b(&tmp16s, LS_LOAD);
- break;
-
- case 1:
- case 2:
- case 7:
- do_byte(&tmp8u, LS_LOAD);
- break;
- }
- for (i = count; i > 0; i--) /* RLE */
- {
- c_ptr = &cave[y][x];
- switch (part)
- {
- case 0:
- c_ptr->info = tmp16s;
- break;
+ /* Reset cause of death */
+ (void)strcpy(died_from, "(alive and well)");
+ }
- case 1:
- c_ptr->feat = tmp8u;
- break;
+ /* Success */
+ return (TRUE);
+ }
- case 2:
- c_ptr->mimic = tmp8u;
- break;
- case 3:
- c_ptr->special = tmp16s;
- break;
+ /* Message */
+ msg_format("Error (%s) reading %d.%d.%d savefile.",
+ what, sf_major, sf_minor, sf_patch);
+ msg_print(NULL);
- case 4:
- c_ptr->special2 = tmp16s;
- break;
+ /* Oops */
+ return (FALSE);
+}
- case 5:
- c_ptr->t_idx = tmp16s;
- break;
- case 6:
- c_ptr->inscription = tmp16s;
- break;
- case 7:
- c_ptr->mana = tmp8u;
- break;
+/*
+ * Medium level player saver
+ */
+static bool_ save_player_aux(char *name)
+{
+ bool_ ok = FALSE;
+ int fd = -1;
+ int mode = 0644;
- case 8:
- c_ptr->effect = tmp16s;
- break;
- }
- if (++x >= xmax)
- {
- /* Wrap */
- x = 0;
- if ((++y) >= ymax) break;
- }
- }
- }
+ /* No file yet */
+ fff = NULL;
+
+ /* File type is "SAVE" */
+ FILE_TYPE(FILE_TYPE_SAVE);
+
+ /* Create the savefile */
+ fd = fd_make(name, mode);
+
+ /* File is okay */
+ if (fd >= 0)
+ {
+ /* Close the "fd" */
+ (void)fd_close(fd);
+
+ /* Open the savefile */
+ fff = my_fopen(name, "wb");
+
+ /* Successful open */
+ if (fff)
+ {
+ /* Write the savefile */
+ if (do_savefile_aux(ls_flag_t::SAVE)) ok = TRUE;
+
+ /* Attempt to close it */
+ if (my_fclose(fff)) ok = FALSE;
+ }
+
+ /* "broken" savefile */
+ if (!ok)
+ {
+ /* Remove "broken" files */
+ (void)fd_kill(name);
}
}
+
+ /* Failure */
+ if (!ok) return (FALSE);
+
+ /* Success */
+ return (TRUE);
}
-static void my_sentinel(char *place, u16b value, int flag)
-/* This function lets us know exactly where a savefile is
- broken by reading/writing conveniently a sentinel at this
- spot */
+/*
+ * Attempt to save the player in a savefile
+ */
+bool_ save_player(void)
{
- if (flag == LS_SAVE)
- {
- do_u16b(&value, flag);
- return;
- }
- if (flag == LS_LOAD)
+ int result = FALSE;
+ char safe[1024];
+
+ /* New savefile */
+ strcpy(safe, savefile);
+ strcat(safe, ".new");
+
+ /* Remove it */
+ fd_kill(safe);
+
+ /* Attempt to save the player */
+ if (save_player_aux(safe))
{
- u16b found;
- do_u16b(&found, flag);
- if (found == value) /* All is good */
- return;
- /* All is bad */
- note(format("Savefile broken %s", place));
- return;
+ char temp[1024];
+
+ /* Old savefile */
+ strcpy(temp, savefile);
+ strcat(temp, ".old");
+
+ /* Remove it */
+ fd_kill(temp);
+
+ /* Preserve old savefile */
+ fd_move(savefile, temp);
+
+ /* Activate new savefile */
+ fd_move(safe, savefile);
+
+ /* Remove preserved savefile */
+ fd_kill(temp);
+
+ /* Hack -- Pretend the character was loaded */
+ character_loaded = TRUE;
+
+ /* Success */
+ result = TRUE;
}
- note(format("Impossible has occurred")); /* Programmer error */
- exit(0);
+
+ save_savefile_names();
+
+ /* Return the result */
+ return (result);
}
diff --git a/src/loadsave.h b/src/loadsave.h
new file mode 100644
index 00000000..61bfced7
--- /dev/null
+++ b/src/loadsave.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* loadsave.c */
+extern void save_dungeon(void);
+extern bool_ save_player(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/loadsave.hpp b/src/loadsave.hpp
new file mode 100644
index 00000000..a9eb9dc8
--- /dev/null
+++ b/src/loadsave.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ file_exist(cptr buf);
+extern bool_ load_dungeon(char *ext);
+extern bool_ load_player(void);
diff --git a/src/lua_bind.c b/src/lua_bind.c
deleted file mode 100644
index a15e9eb8..00000000
--- a/src/lua_bind.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* File: lua_bind.c */
-
-/* Purpose: various lua bindings */
-
-/*
- * Copyright (c) 2001 DarkGod
- *
- * 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.
- */
-
-#include "angband.h"
-
-#include <assert.h>
-
-#include "spell_type.h"
-
-/*
- * Monsters
- */
-
-void find_position(int y, int x, int *yy, int *xx)
-{
- int attempts = 500;
-
- do
- {
- scatter(yy, xx, y, x, 6);
- }
- while (!(in_bounds(*yy, *xx) && cave_floor_bold(*yy, *xx)) && --attempts);
-}
-
-/*
- * Misc
- */
-
-/* Change this fct if I want to switch to learnable spells */
-s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus)
-{
- s32b tmp;
-
- tmp = lvl - ((spell_type_skill_level(spell) - 1) * (SKILL_STEP / 10));
-
- if (tmp >= (SKILL_STEP / 10)) /* We require at least one spell level */
- tmp += bonus;
-
- tmp = (tmp * (max * (SKILL_STEP / 10)) / (SKILL_MAX / 10));
-
- if (tmp < 0) /* Shift all negative values, so they map to appropriate integer */
- tmp -= SKILL_STEP / 10 - 1;
-
- /* Now, we can safely divide */
- lvl = tmp / (SKILL_STEP / 10);
-
- if (lvl < min)
- lvl = min;
-
- return lvl;
-}
-
-/** This is the function to use when casting through a stick */
-s32b get_level_device(s32b s, s32b max, s32b min)
-{
- int lvl;
- spell_type *spell = spell_at(s);
-
- /* No max specified ? assume 50 */
- if (max <= 0) {
- max = 50;
- }
- /* No min specified ? */
- if (min <= 0) {
- min = 1;
- }
-
- lvl = s_info[SKILL_DEVICE].value;
- lvl = lvl + (get_level_use_stick * SKILL_STEP);
-
- /* Sticks are limited */
- if (lvl - ((spell_type_skill_level(spell) + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP)
- {
- lvl = (get_level_max_stick + spell_type_skill_level(spell) - 1) * SKILL_STEP;
- }
-
- /* / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative
- -- The loss of information should be negligible since 1 skill = 1000 internally
- */
- lvl = lvl / 10;
- lvl = lua_get_level(spell, lvl, max, min, 0);
-
- return lvl;
-}
-
-int get_mana(s32b s)
-{
- spell_type *spell = spell_at(s);
- range_type mana_range;
- spell_type_mana_range(spell, &mana_range);
- return get_level(s, mana_range.max, mana_range.min);
-}
-
-/** Returns spell chance of failure for spell */
-s32b spell_chance(s32b s)
-{
- spell_type *s_ptr = spell_at(s);
- int level = get_level(s, 50, 1);
-
- /* Extract the base spell failure rate */
- if (get_level_use_stick > -1)
- {
- int minfail;
- s32b chance = spell_type_failure_rate(s_ptr);
-
- /* Reduce failure rate by "effective" level adjustment */
- chance -= (level - 1);
-
- /* Extract the minimum failure rate */
- minfail = 15 - get_skill_scale(SKILL_DEVICE, 25);
-
- /* Return the chance */
- return clamp_failure_chance(chance, minfail);
- }
- else
- {
- s32b chance = spell_type_failure_rate(s_ptr);
- int mana = get_mana(s);
- int cur_mana = get_power(s);
- int stat = spell_type_casting_stat(s_ptr);
- int stat_ind = p_ptr->stat_ind[stat];
- int minfail;
-
- /* Reduce failure rate by "effective" level adjustment */
- chance -= 3 * (level - 1);
-
- /* Reduce failure rate by INT/WIS adjustment */
- chance -= 3 * (adj_mag_stat[stat_ind] - 1);
-
- /* Not enough mana to cast */
- if (chance < 0) chance = 0;
- if (mana > cur_mana)
- {
- chance += 15 * (mana - cur_mana);
- }
-
- /* Extract the minimum failure rate */
- minfail = adj_mag_fail[stat_ind];
-
- /* Must have Perfect Casting to get below 5% */
- if (!(has_ability(AB_PERFECT_CASTING)))
- {
- if (minfail < 5) minfail = 5;
- }
-
- /* Hack -- Priest prayer penalty for "edged" weapons -DGK */
- if ((forbid_non_blessed()) && (p_ptr->icky_wield)) chance += 25;
-
- /* Return the chance */
- return clamp_failure_chance(chance, minfail);
- }
-}
-
-s32b get_level(s32b s, s32b max, s32b min)
-{
- /** Ahah shall we use Magic device instead ? */
- if (get_level_use_stick > -1) {
- return get_level_device(s, max, min);
- } else {
- s32b level;
- bool_ notused;
- get_level_school(s, max, min, &level, &notused);
- return level;
- }
-}
-
-void set_target(int y, int x)
-{
- target_who = -1;
- target_col = x;
- target_row = y;
-}
-
-void get_target(int dir, int *y, int *x)
-{
- int ty, tx;
-
- /* Use the given direction */
- tx = p_ptr->px + (ddx[dir] * 100);
- ty = p_ptr->py + (ddy[dir] * 100);
-
- /* Hack -- Use an actual "target" */
- if ((dir == 5) && target_okay())
- {
- tx = target_col;
- ty = target_row;
- }
- *y = ty;
- *x = tx;
-}
-
-/* Level gen */
-void get_map_size(char *name, int *ysize, int *xsize)
-{
- *xsize = 0;
- *ysize = 0;
- init_flags = INIT_GET_SIZE;
- process_dungeon_file(name, ysize, xsize, cur_hgt, cur_wid, TRUE, TRUE);
-}
-
-void load_map(char *name, int *y, int *x)
-{
- /* Set the correct monster hook */
- set_mon_num_hook();
-
- /* Prepare allocation table */
- get_mon_num_prep();
-
- init_flags = INIT_CREATE_DUNGEON;
- process_dungeon_file(name, y, x, cur_hgt, cur_wid, TRUE, TRUE);
-}
-
-/*
- * Finds a good random bounty monster
- * Im too lazy to write it in lua since the lua API for monsters is not very well yet
- */
-
-/*
- * Hook for bounty monster selection.
- */
-static bool_ lua_mon_hook_bounty(int r_idx)
-{
- monster_race* r_ptr = &r_info[r_idx];
-
-
- /* Reject uniques */
- if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
-
- /* Reject those who cannot leave anything */
- if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) return (FALSE);
-
- /* Accept only monsters that can be generated */
- if (r_ptr->flags9 & RF9_SPECIAL_GENE) return (FALSE);
- if (r_ptr->flags9 & RF9_NEVER_GENE) return (FALSE);
-
- /* Reject pets */
- if (r_ptr->flags7 & RF7_PET) return (FALSE);
-
- /* Reject friendly creatures */
- if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE);
-
- /* Accept only monsters that are not breeders */
- if (r_ptr->flags4 & RF4_MULTIPLY) return (FALSE);
-
- /* Forbid joke monsters */
- if (r_ptr->flags8 & RF8_JOKEANGBAND) return (FALSE);
-
- /* Accept only monsters that are not good */
- if (r_ptr->flags3 & RF3_GOOD) return (FALSE);
-
- /* The rest are acceptable */
- return (TRUE);
-}
-
-int lua_get_new_bounty_monster(int lev)
-{
- int r_idx;
-
- /*
- * Set up the hooks -- no bounties on uniques or monsters
- * with no corpses
- */
- get_mon_num_hook = lua_mon_hook_bounty;
- get_mon_num_prep();
-
- /* Set up the quest monster. */
- r_idx = get_mon_num(lev);
-
- /* Undo the filters */
- get_mon_num_hook = NULL;
- get_mon_num_prep();
-
- return r_idx;
-}
-
-/*
- * Some misc functions
- */
-char *lua_input_box(cptr title, int max)
-{
- static char buf[80];
- int wid, hgt;
-
- strcpy(buf, "");
- Term_get_size(&wid, &hgt);
- if (!input_box(title, hgt / 2, wid / 2, buf, (max > 79) ? 79 : max))
- return "";
- return buf;
-}
-
-char lua_msg_box(cptr title)
-{
- int wid, hgt;
-
- Term_get_size(&wid, &hgt);
- return msg_box(title, hgt / 2, wid / 2);
-}
-
-
-
-void increase_mana(int delta)
-{
- p_ptr->csp += delta;
- p_ptr->redraw |= PR_MANA;
-
- if (p_ptr->csp < 0)
- {
- p_ptr->csp = 0;
- }
- if (p_ptr->csp > p_ptr->msp)
- {
- p_ptr->csp = p_ptr->msp;
- }
-}
-
-timer_type *TIMER_AGGRAVATE_EVIL = 0;
-
-void timer_aggravate_evil_enable()
-{
- TIMER_AGGRAVATE_EVIL->enabled = TRUE;
-}
-
-void timer_aggravate_evil_callback()
-{
- if ((p_ptr->prace == RACE_MAIA) &&
- (!player_has_corruption(CORRUPT_BALROG_AURA)) &&
- (!player_has_corruption(CORRUPT_BALROG_WINGS)) &&
- (!player_has_corruption(CORRUPT_BALROG_STRENGTH)) &&
- (!player_has_corruption(CORRUPT_BALROG_FORM)))
- {
- dispel_evil(0);
- }
-}
diff --git a/src/lua_bind.cc b/src/lua_bind.cc
new file mode 100644
index 00000000..aa2c3a2a
--- /dev/null
+++ b/src/lua_bind.cc
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2001 DarkGod
+ *
+ * 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.
+ */
+
+#include "lua_bind.hpp"
+
+#include "cmd7.hpp"
+#include "corrupt.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "player_type.hpp"
+#include "range.hpp"
+#include "skills.hpp"
+#include "skill_type.hpp"
+#include "spell_type.hpp"
+#include "spells2.hpp"
+#include "spells5.hpp"
+#include "tables.hpp"
+#include "timer_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+#include <functional>
+
+/*
+ * Misc
+ */
+
+/* Change this fct if I want to switch to learnable spells */
+s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus)
+{
+ s32b tmp;
+
+ tmp = lvl - ((spell_type_skill_level(spell) - 1) * (SKILL_STEP / 10));
+
+ if (tmp >= (SKILL_STEP / 10)) /* We require at least one spell level */
+ tmp += bonus;
+
+ tmp = (tmp * (max * (SKILL_STEP / 10)) / (SKILL_MAX / 10));
+
+ if (tmp < 0) /* Shift all negative values, so they map to appropriate integer */
+ tmp -= SKILL_STEP / 10 - 1;
+
+ /* Now, we can safely divide */
+ lvl = tmp / (SKILL_STEP / 10);
+
+ if (lvl < min)
+ lvl = min;
+
+ return lvl;
+}
+
+/* static */ s32b get_level_device(spell_type *spell, s32b max, s32b min, s32b device_skill, std::function<s32b(spell_type *, s32b, s32b, s32b, s32b)> lua_get_level_ = lua_get_level)
+{
+ /* No max specified ? assume 50 */
+ if (max <= 0) {
+ max = 50;
+ }
+ /* No min specified ? */
+ if (min <= 0) {
+ min = 1;
+ }
+
+ int lvl = device_skill + (get_level_use_stick * SKILL_STEP);
+
+ /* Sticks are limited */
+ if (lvl - ((spell_type_skill_level(spell) + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP)
+ {
+ lvl = (get_level_max_stick + spell_type_skill_level(spell) - 1) * SKILL_STEP;
+ }
+
+ /* / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative
+ -- The loss of information should be negligible since 1 skill = 1000 internally
+ */
+ lvl = lvl / 10;
+ lvl = lua_get_level_(spell, lvl, max, min, 0);
+
+ return lvl;
+}
+
+static s32b get_level_device_1(spell_type *spell, s32b max, s32b min)
+{
+ // Must be in "device" mode.
+ assert(get_level_use_stick > -1);
+ // Delegate
+ auto device_skill = s_info[SKILL_DEVICE].value;
+ return get_level_device(spell, max, min, device_skill);
+}
+
+static s32b get_level_school_1(spell_type *spell, s32b max, s32b min)
+{
+ // Delegate
+ s32b level;
+ bool_ na;
+ get_level_school(spell, max, min, &level, &na);
+ // Note: It is tempting to add an assertion here for "na == FALSE" here,
+ // but there are cases where we haven't actually checked if the spell is
+ // really castable before calling this function (indirectly). Thus we
+ // MUST NOT assert anything about "na" as the code currently stands.
+ return level;
+}
+
+int get_mana(s32b s)
+{
+ // Does not make sense in "device" mode.
+ assert(get_level_use_stick == -1);
+ // Extract the spell's mana range.
+ spell_type *spell = spell_at(s);
+ range_type mana_range;
+ spell_type_mana_range(spell, &mana_range);
+ // Scale
+ return get_level_school_1(spell, mana_range.max, mana_range.min);
+}
+
+/** Returns spell chance of failure for a school spell. */
+static s32b spell_chance_school(s32b s)
+{
+ spell_type *s_ptr = spell_at(s);
+ int level = get_level_school_1(s_ptr, 50, 1);
+ s32b chance = spell_type_failure_rate(s_ptr);
+ int mana = get_mana(s);
+ int cur_mana = get_power(s);
+ int stat = spell_type_casting_stat(s_ptr);
+ int stat_ind = p_ptr->stat_ind[stat];
+ int minfail;
+
+ /* Reduce failure rate by "effective" level adjustment */
+ chance -= 3 * (level - 1);
+
+ /* Reduce failure rate by INT/WIS adjustment */
+ chance -= 3 * (adj_mag_stat[stat_ind] - 1);
+
+ /* Not enough mana to cast */
+ if (chance < 0) chance = 0;
+ if (mana > cur_mana)
+ {
+ chance += 15 * (mana - cur_mana);
+ }
+
+ /* Extract the minimum failure rate */
+ minfail = adj_mag_fail[stat_ind];
+
+ /* Must have Perfect Casting to get below 5% */
+ if (!(has_ability(AB_PERFECT_CASTING)))
+ {
+ if (minfail < 5) minfail = 5;
+ }
+
+ /* Hack -- Priest prayer penalty for "edged" weapons -DGK */
+ if ((forbid_non_blessed()) && (p_ptr->icky_wield)) chance += 25;
+
+ /* Return the chance */
+ return clamp_failure_chance(chance, minfail);
+}
+
+s32b spell_chance_device(spell_type *spell_ptr)
+{
+ // Device parameters initialized?
+ assert(get_level_use_stick > -1);
+
+ // Calculate the chance.
+ int level = get_level_device_1(spell_ptr, 50, 1);
+ s32b chance = spell_type_failure_rate(spell_ptr);
+
+ /* Reduce failure rate by "effective" level adjustment */
+ chance -= (level - 1);
+
+ /* Extract the minimum failure rate */
+ int minfail = 15 - get_skill_scale(SKILL_DEVICE, 25);
+
+ /* Return the chance */
+ return clamp_failure_chance(chance, minfail);
+}
+
+s32b spell_chance_book(s32b s)
+{
+ // Must NOT be a device!
+ assert(get_level_use_stick < 0);
+ // Delegate
+ return spell_chance_school(s);
+}
+
+s32b get_level(s32b s, s32b max, s32b min)
+{
+ auto spell = spell_at(s);
+ /** Ahah shall we use Magic device instead ? */
+ if (get_level_use_stick > -1) {
+ return get_level_device_1(spell, max, min);
+ } else {
+ return get_level_school_1(spell, max, min);
+ }
+}
+
+/* Level gen */
+void get_map_size(const char *name, int *ysize, int *xsize)
+{
+ *xsize = 0;
+ *ysize = 0;
+ init_flags = INIT_GET_SIZE;
+ process_dungeon_file(name, ysize, xsize, cur_hgt, cur_wid, TRUE, TRUE);
+}
+
+void load_map(const char *name, int *y, int *x)
+{
+ /* Set the correct monster hook */
+ set_mon_num_hook();
+
+ /* Prepare allocation table */
+ get_mon_num_prep();
+
+ init_flags = INIT_CREATE_DUNGEON;
+ process_dungeon_file(name, y, x, cur_hgt, cur_wid, TRUE, TRUE);
+}
+
+/*
+ * Some misc functions
+ */
+char *lua_input_box(cptr title, int max)
+{
+ static char buf[80];
+ int wid, hgt;
+
+ strcpy(buf, "");
+ Term_get_size(&wid, &hgt);
+ if (!input_box(title, hgt / 2, wid / 2, buf, (max > 79) ? 79 : max))
+ return buf;
+ return buf;
+}
+
+char lua_msg_box(cptr title)
+{
+ int wid, hgt;
+
+ Term_get_size(&wid, &hgt);
+ return msg_box(title, hgt / 2, wid / 2);
+}
+
+
+
+void increase_mana(int delta)
+{
+ p_ptr->csp += delta;
+ p_ptr->redraw |= PR_FRAME;
+
+ if (p_ptr->csp < 0)
+ {
+ p_ptr->csp = 0;
+ }
+ if (p_ptr->csp > p_ptr->msp)
+ {
+ p_ptr->csp = p_ptr->msp;
+ }
+}
+
+timer_type *TIMER_AGGRAVATE_EVIL = 0;
+
+void timer_aggravate_evil_enable()
+{
+ TIMER_AGGRAVATE_EVIL->enabled = TRUE;
+}
+
+void timer_aggravate_evil_callback()
+{
+ if ((p_ptr->prace == RACE_MAIA) &&
+ (!player_has_corruption(CORRUPT_BALROG_AURA)) &&
+ (!player_has_corruption(CORRUPT_BALROG_WINGS)) &&
+ (!player_has_corruption(CORRUPT_BALROG_STRENGTH)) &&
+ (!player_has_corruption(CORRUPT_BALROG_FORM)))
+ {
+ dispel_evil(0);
+ }
+}
diff --git a/src/lua_bind.hpp b/src/lua_bind.hpp
new file mode 100644
index 00000000..b2a6c9a7
--- /dev/null
+++ b/src/lua_bind.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "h-basic.h"
+#include "spell_type_fwd.hpp"
+#include "timer_type_fwd.hpp"
+
+/** Calculate spell failure rate for a device, i.e. a wand or staff. */
+extern s32b spell_chance_device(spell_type *spell_ptr);
+
+/** Calculate spell failure rate for a spell book. */
+extern s32b spell_chance_book(s32b s);
+
+
+extern s32b lua_get_level(struct spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus);
+extern int get_mana(s32b s);
+extern s32b get_power(s32b s);
+extern s32b get_level(s32b s, s32b max, s32b min);
+extern void get_level_school(struct spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na);
+
+extern s32b get_level_max_stick;
+extern s32b get_level_use_stick;
+
+extern void get_map_size(const char *name, int *ysize, int *xsize);
+extern void load_map(const char *name, int *y, int *x);
+
+extern char *lua_input_box(cptr title, int max);
+extern char lua_msg_box(cptr title);
+
+extern void increase_mana(int delta);
+
+extern timer_type *TIMER_AGGRAVATE_EVIL;
+
+void timer_aggravate_evil_enable();
+void timer_aggravate_evil_callback();
diff --git a/src/magic_power.hpp b/src/magic_power.hpp
new file mode 100644
index 00000000..b02c6c14
--- /dev/null
+++ b/src/magic_power.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Powers, used by Mindcrafters and Necromancers
+ */
+struct magic_power
+{
+ int min_lev;
+ int mana_cost;
+ int fail;
+ cptr name;
+ cptr desc;
+};
diff --git a/src/maid-x11.c b/src/maid-x11.c
deleted file mode 100644
index 86df2119..00000000
--- a/src/maid-x11.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/* File: maid-x11.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.
- */
-
-#if defined(USE_X11) || defined(USE_XAW)
-
-/*
- * This file defines some "XImage" manipulation functions for X11.
- *
- * Original code by Desvignes Sebastien (desvigne@solar12.eerie.fr).
- *
- * BMP format support by Denis Eropkin (denis@dream.homepage.ru).
- *
- * Major fixes and cleanup by Ben Harrison (benh@phial.com).
- *
- * This file is designed to be "included" by "main-x11.c" or "main-xaw.c",
- * which will have already "included" several relevant header files.
- */
-
-#ifndef IsModifierKey
-
-/*
- * 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) \
-(((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal))
-
-#define IsCursorKey(keysym) \
-(((unsigned)(keysym) >= XK_Home) && ((unsigned)(keysym) < XK_Select))
-
-#define IsPFKey(keysym) \
-(((unsigned)(keysym) >= XK_KP_F1) && ((unsigned)(keysym) <= XK_KP_F4))
-
-#define IsFunctionKey(keysym) \
-(((unsigned)(keysym) >= XK_F1) && ((unsigned)(keysym) <= XK_F35))
-
-#define IsMiscFunctionKey(keysym) \
-(((unsigned)(keysym) >= XK_Select) && ((unsigned)(keysym) < XK_KP_Space))
-
-#define IsModifierKey(keysym) \
-(((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R))
-
-#endif /* IsModifierKey */
-
-
-/*
- * 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)
-
-
-/*
- * Hack -- Convert an RGB value to an X11 Pixel, or die.
- */
-static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue)
-{
- Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy));
-
- char cname[8];
-
- XColor xcolour;
-
- /* Build the color */
-
- xcolour.red = red * 255 + red;
- xcolour.green = green * 255 + green;
- xcolour.blue = blue * 255 + blue;
- xcolour.flags = DoRed | DoGreen | DoBlue;
-
- /* Attempt to Allocate the Parsed color */
- if (!(XAllocColor(dpy, cmap, &xcolour)))
- {
- quit_fmt("Couldn't allocate bitmap color '%s'\n", cname);
- }
-
- return (xcolour.pixel);
-}
-
-
-
-#ifdef USE_GRAPHICS
-
-/*
- * The Win32 "BITMAPFILEHEADER" type.
- */
-typedef struct BITMAPFILEHEADER
-{
- u16b bfType;
- u32b bfSize;
- u16b bfReserved1;
- u16b bfReserved2;
- u32b bfOffBits;
-}
-BITMAPFILEHEADER;
-
-
-/*
- * The Win32 "BITMAPINFOHEADER" type.
- */
-typedef struct BITMAPINFOHEADER
-{
- u32b biSize;
- u32b biWidth;
- u32b biHeight;
- u16b biPlanes;
- u16b biBitCount;
- u32b biCompresion;
- u32b biSizeImage;
- u32b biXPelsPerMeter;
- u32b biYPelsPerMeter;
- u32b biClrUsed;
- u32b biClrImportand;
-}
-BITMAPINFOHEADER;
-
-/*
- * The Win32 "RGBQUAD" type.
- */
-typedef struct RGBQUAD
-{
- unsigned char b, g, r;
- unsigned char filler;
-}
-RGBQUAD;
-
-
-/*** Helper functions for system independent file loading. ***/
-
-static byte get_byte(FILE *fff)
-{
- /* Get a character, and return it */
- return (getc(fff) & 0xFF);
-}
-
-static void rd_byte(FILE *fff, byte *ip)
-{
- *ip = get_byte(fff);
-}
-
-static void rd_u16b(FILE *fff, u16b *ip)
-{
- (*ip) = get_byte(fff);
- (*ip) |= ((u16b)(get_byte(fff)) << 8);
-}
-
-static void rd_u32b(FILE *fff, u32b *ip)
-{
- (*ip) = get_byte(fff);
- (*ip) |= ((u32b)(get_byte(fff)) << 8);
- (*ip) |= ((u32b)(get_byte(fff)) << 16);
- (*ip) |= ((u32b)(get_byte(fff)) << 24);
-}
-
-
-/*
- * Read a Win32 BMP file.
- *
- * This function replaces the old ReadRaw and RemapColors functions.
- *
- * Assumes that the bitmap has a size such that no padding is needed in
- * various places. Currently only handles bitmaps with 3 to 256 colors.
- */
-static XImage *ReadBMP(Display *dpy, char *Name)
-{
- Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
-
- int depth = DefaultDepth(dpy, DefaultScreen(dpy));
-
- FILE *f;
-
- BITMAPFILEHEADER fileheader;
- BITMAPINFOHEADER infoheader;
-
- XImage *Res = NULL;
-
- char *Data;
-
- int ncol;
-
- int total;
-
- int i, j;
-
- u32b x, y;
-
- unsigned long clr_pixels[256];
-
-
- /* Open the BMP file */
- f = fopen(Name, "r");
-
- /* No such file */
- if (f == NULL)
- {
- return (NULL);
- }
-
- /* Read the "BITMAPFILEHEADER" */
- rd_u16b(f, &(fileheader.bfType));
- rd_u32b(f, &(fileheader.bfSize));
- rd_u16b(f, &(fileheader.bfReserved1));
- rd_u16b(f, &(fileheader.bfReserved2));
- rd_u32b(f, &(fileheader.bfOffBits));
-
- /* Read the "BITMAPINFOHEADER" */
- rd_u32b(f, &(infoheader.biSize));
- rd_u32b(f, &(infoheader.biWidth));
- rd_u32b(f, &(infoheader.biHeight));
- rd_u16b(f, &(infoheader.biPlanes));
- rd_u16b(f, &(infoheader.biBitCount));
- rd_u32b(f, &(infoheader.biCompresion));
- rd_u32b(f, &(infoheader.biSizeImage));
- rd_u32b(f, &(infoheader.biXPelsPerMeter));
- rd_u32b(f, &(infoheader.biYPelsPerMeter));
- rd_u32b(f, &(infoheader.biClrUsed));
- rd_u32b(f, &(infoheader.biClrImportand));
-
- /* Verify the header */
- if (feof(f) ||
- (fileheader.bfType != 19778) ||
- (infoheader.biSize != 40))
- {
- quit_fmt("Incorrect BMP file format %s", Name);
- }
-
- /* The two headers above occupy 54 bytes total */
- /* The "bfOffBits" field says where the data starts */
- /* The "biClrUsed" field does not seem to be reliable */
- /* Compute number of colors recorded */
- ncol = (fileheader.bfOffBits - 54) / 4;
-
- for (i = 0; i < ncol; i++)
- {
- RGBQUAD clrg;
-
- /* Read an "RGBQUAD" */
- rd_byte(f, &(clrg.b));
- rd_byte(f, &(clrg.g));
- rd_byte(f, &(clrg.r));
- rd_byte(f, &(clrg.filler));
-
- /* Analyze the color */
- clr_pixels[i] = create_pixel(dpy, clrg.r, clrg.g, clrg.b);
- }
-
- /* Determine total bytes needed for image */
- i = 1;
- j = (depth - 1) >> 2;
- while (j >>= 1) i <<= 1;
- total = infoheader.biWidth * infoheader.biHeight * i;
-
- /* Allocate image memory */
- C_MAKE(Data, total, char);
-
- Res = XCreateImage(dpy, visual, depth, ZPixmap, 0 /*offset*/,
- Data, infoheader.biWidth, infoheader.biHeight,
- 8 /*bitmap_pad*/, 0 /*bytes_per_line*/);
-
- /* Failure */
- if (Res == NULL)
- {
- C_KILL(Data, total, char);
- fclose(f);
- return (NULL);
- }
-
- for (y = 0; y < infoheader.biHeight; y++)
- {
- int y2 = infoheader.biHeight - y - 1;
-
- for (x = 0; x < infoheader.biWidth; x++)
- {
- int ch = getc(f);
-
- /* Verify not at end of file XXX XXX */
- if (feof(f)) quit_fmt("Unexpected end of file in %s", Name);
-
- if (infoheader.biBitCount == 24)
- {
- int c2 = getc(f);
- int c3 = getc(f);
-
- /* Verify not at end of file XXX XXX */
- if (feof(f)) quit_fmt("Unexpected end of file in %s", Name);
-
- XPutPixel(Res, x, y2, create_pixel(dpy, ch, c2, c3));
- }
- else if (infoheader.biBitCount == 8)
- {
- XPutPixel(Res, x, y2, clr_pixels[ch]);
- }
- else if (infoheader.biBitCount == 4)
- {
- XPutPixel(Res, x, y2, clr_pixels[ch / 16]);
- x++;
- XPutPixel(Res, x, y2, clr_pixels[ch % 16]);
- }
- else
- {
- /* Technically 1 bit is legal too */
- quit_fmt("Illegal biBitCount %d in %s",
- infoheader.biBitCount, Name);
- }
- }
- }
-
- fclose(f);
-
- return Res;
-}
-
-
-/* ========================================================*/
-/* Code for smooth icon rescaling from Uwe Siems, Jan 2000 */
-/* ========================================================*/
-
-/*
- * to save ourselves some labour, define a maximum expected icon width here:
- */
-#define MAX_ICON_WIDTH 32
-
-
-/* some static variables for composing and decomposing pixel values into
- * red, green and blue values
- */
-static unsigned long redMask, greenMask, blueMask;
-static int redShift, greenShift, blueShift;
-
-
-/*
- * Use smooth rescaling?
- */
-static bool_ smoothRescaling = TRUE;
-
-
-/*
- * GetScaledRow reads a scan from the given XImage, scales it smoothly
- * and returns the red, green and blue values in arrays.
- * The values in this arrays must be divided by a certain value that is
- * calculated in ScaleIcon.
- * x, y is the position, iw is the input width and ow the output width
- * redScan, greenScan and blueScan must be sufficiently sized
- */
-static void GetScaledRow(XImage *Im, int x, int y, int iw, int ow,
- unsigned long *redScan, unsigned long *greenScan,
- unsigned long *blueScan)
-{
- int xi, si, sifrac, ci, cifrac, addWhole, addFrac;
- unsigned long pix;
- int prevRed, prevGreen, prevBlue, nextRed, nextGreen, nextBlue;
- bool_ getNextPix;
-
- if (iw == ow)
- {
- /* unscaled */
- for (xi = 0; xi < ow; xi++)
- {
- pix = XGetPixel(Im, x + xi, y);
- redScan [xi] = (pix >> redShift) & redMask;
- greenScan [xi] = (pix >> greenShift) & greenMask;
- blueScan [xi] = (pix >> blueShift) & blueMask;
- }
- }
- else if (iw < ow)
- {
- /* scaling by subsampling (grow) */
- iw--;
- ow--;
- /* read first pixel: */
- pix = XGetPixel(Im, x, y);
- nextRed = (pix >> redShift) & redMask;
- nextGreen = (pix >> greenShift) & greenMask;
- nextBlue = (pix >> blueShift) & blueMask;
- prevRed = nextRed;
- prevGreen = nextGreen;
- prevBlue = nextBlue;
- /* si and sifrac give the subsampling position: */
- si = x;
- sifrac = 0;
- /* getNextPix tells us, that we need the next pixel */
- getNextPix = TRUE;
-
- for (xi = 0; xi <= ow; xi++)
- {
- if (getNextPix)
- {
- prevRed = nextRed;
- prevGreen = nextGreen;
- prevBlue = nextBlue;
- if (xi < ow)
- {
- /* only get next pixel if in same icon */
- pix = XGetPixel(Im, si + 1, y);
- nextRed = (pix >> redShift) & redMask;
- nextGreen = (pix >> greenShift) & greenMask;
- nextBlue = (pix >> blueShift) & blueMask;
- }
- }
-
- /* calculate subsampled color values: */
- /* division by ow occurs in ScaleIcon */
- redScan [xi] = prevRed * (ow - sifrac) + nextRed * sifrac;
- greenScan [xi] = prevGreen * (ow - sifrac) + nextGreen * sifrac;
- blueScan [xi] = prevBlue * (ow - sifrac) + nextBlue * sifrac;
-
- /* advance sampling position: */
- sifrac += iw;
- if (sifrac >= ow)
- {
- si++;
- sifrac -= ow;
- getNextPix = TRUE;
- }
- else
- {
- getNextPix = FALSE;
- }
-
- }
- }
- else
- {
- /* scaling by averaging (shrink) */
- /* width of an output pixel in input pixels: */
- addWhole = iw / ow;
- addFrac = iw % ow;
- /* start position of the first output pixel: */
- si = x;
- sifrac = 0;
- /* get first input pixel: */
- pix = XGetPixel(Im, x, y);
- nextRed = (pix >> redShift) & redMask;
- nextGreen = (pix >> greenShift) & greenMask;
- nextBlue = (pix >> blueShift) & blueMask;
- for (xi = 0; xi < ow; xi++)
- {
- /* find endpoint of the current output pixel: */
- ci = si + addWhole;
- cifrac = sifrac + addFrac;
- if (cifrac >= ow)
- {
- ci++;
- cifrac -= ow;
- }
- /* take fraction of current input pixel (starting segment): */
- redScan[xi] = nextRed * (ow - sifrac);
- greenScan[xi] = nextGreen * (ow - sifrac);
- blueScan[xi] = nextBlue * (ow - sifrac);
- si++;
- /* add values for whole pixels: */
- while (si < ci)
- {
- pix = XGetPixel(Im, si, y);
- redScan[xi] += ((pix >> redShift) & redMask) * ow;
- greenScan[xi] += ((pix >> greenShift) & greenMask) * ow;
- blueScan[xi] += ((pix >> blueShift) & blueMask) * ow;
- si++;
- }
- /* add fraction of current input pixel (ending segment): */
- if (xi < ow - 1)
- {
- /* only get next pixel if still in icon: */
- pix = XGetPixel(Im, si, y);
- nextRed = (pix >> redShift) & redMask;
- nextGreen = (pix >> greenShift) & greenMask;
- nextBlue = (pix >> blueShift) & blueMask;
- }
- sifrac = cifrac;
- if (sifrac > 0)
- {
- redScan[xi] += nextRed * sifrac;
- greenScan[xi] += nextGreen * sifrac;
- blueScan[xi] += nextBlue * sifrac;
- }
- }
- }
-}
-
-
-/*
- * PutRGBScan takes arrays for red, green and blue and writes pixel values
- * according to this values in the XImage-structure. w is the number of
- * pixels to write and div is the value by which all red/green/blue values
- * are divided first.
- */
-static void PutRGBScan(XImage *Im, int x, int y, int w, int div,
- unsigned long *redScan, unsigned long *greenScan,
- unsigned long *blueScan)
-{
- int xi;
- unsigned long pix;
- unsigned long adj = div / 2;
- for (xi = 0; xi < w; xi++)
- {
- pix = (((((redScan[xi] + adj) / div) & redMask) << redShift) +
- ((((greenScan[xi] + adj) / div) & greenMask) << greenShift) +
- ((((blueScan[xi] + adj) / div) & blueMask) << blueShift));
- XPutPixel(Im, x + xi, y, pix);
- }
-}
-
-
-/*
- * ScaleIcon transfers an area from XImage ImIn, locate (x1,y1) to ImOut,
- * locate (x2, y2).
- * Source size is (ix, iy) and destination size is (ox, oy).
- * It does this by getting icon scan line from GetScaledScan and handling
- * them the same way as pixels are handled in GetScaledScan.
- * This even allows icons to be scaled differently in horizontal and
- * vertical directions (eg. shrink horizontal, grow vertical).
- */
-static void ScaleIcon(XImage *ImIn, XImage *ImOut,
- int x1, int y1, int x2, int y2,
- int ix, int iy, int ox, int oy)
-{
- int div;
- int xi, yi, si, sifrac, ci, cifrac, addWhole, addFrac;
-
- /* buffers for pixel rows: */
- unsigned long prevRed [MAX_ICON_WIDTH];
- unsigned long prevGreen [MAX_ICON_WIDTH];
- unsigned long prevBlue [MAX_ICON_WIDTH];
- unsigned long nextRed [MAX_ICON_WIDTH];
- unsigned long nextGreen [MAX_ICON_WIDTH];
- unsigned long nextBlue [MAX_ICON_WIDTH];
- unsigned long tempRed [MAX_ICON_WIDTH];
- unsigned long tempGreen [MAX_ICON_WIDTH];
- unsigned long tempBlue [MAX_ICON_WIDTH];
-
- bool_ getNextRow;
-
- /* get divider value for the horizontal scaling: */
- if (ix == ox)
- div = 1;
- else if (ix < ox)
- div = ox - 1;
- else
- div = ix;
-
- if (iy == oy)
- {
- /* no scaling needed vertically: */
- for (yi = 0; yi < oy; yi++)
- {
- GetScaledRow(ImIn, x1, y1 + yi, ix, ox,
- tempRed, tempGreen, tempBlue);
- PutRGBScan(ImOut, x2, y2 + yi, ox, div,
- tempRed, tempGreen, tempBlue);
- }
- }
- else if (iy < oy)
- {
- /* scaling by subsampling (grow): */
- iy--;
- oy--;
- div *= oy;
- /* get first row: */
- GetScaledRow(ImIn, x1, y1, ix, ox, nextRed, nextGreen, nextBlue);
- /* si and sifrac give the subsampling position: */
- si = y1;
- sifrac = 0;
- /* getNextRow tells us, that we need the next row */
- getNextRow = TRUE;
- for (yi = 0; yi <= oy; yi++)
- {
- if (getNextRow)
- {
- for (xi = 0; xi < ox; xi++)
- {
- prevRed[xi] = nextRed[xi];
- prevGreen[xi] = nextGreen[xi];
- prevBlue[xi] = nextBlue[xi];
- }
- if (yi < oy)
- {
- /* only get next row if in same icon */
- GetScaledRow(ImIn, x1, si + 1, ix, ox,
- nextRed, nextGreen, nextBlue);
- }
- }
-
- /* calculate subsampled color values: */
- /* division by oy occurs in PutRGBScan */
- for (xi = 0; xi < ox; xi++)
- {
- tempRed[xi] = (prevRed[xi] * (oy - sifrac) +
- nextRed[xi] * sifrac);
- tempGreen[xi] = (prevGreen[xi] * (oy - sifrac) +
- nextGreen[xi] * sifrac);
- tempBlue[xi] = (prevBlue[xi] * (oy - sifrac) +
- nextBlue[xi] * sifrac);
- }
-
- /* write row to output image: */
- PutRGBScan(ImOut, x2, y2 + yi, ox, div,
- tempRed, tempGreen, tempBlue);
-
- /* advance sampling position: */
- sifrac += iy;
- if (sifrac >= oy)
- {
- si++;
- sifrac -= oy;
- getNextRow = TRUE;
- }
- else
- {
- getNextRow = FALSE;
- }
-
- }
- }
- else
- {
- /* scaling by averaging (shrink) */
- div *= iy;
- /* height of a output row in input rows: */
- addWhole = iy / oy;
- addFrac = iy % oy;
- /* start position of the first output row: */
- si = y1;
- sifrac = 0;
- /* get first input row: */
- GetScaledRow(ImIn, x1, y1, ix, ox, nextRed, nextGreen, nextBlue);
- for (yi = 0; yi < oy; yi++)
- {
- /* find endpoint of the current output row: */
- ci = si + addWhole;
- cifrac = sifrac + addFrac;
- if (cifrac >= oy)
- {
- ci++;
- cifrac -= oy;
- }
- /* take fraction of current input row (starting segment): */
- for (xi = 0; xi < ox; xi++)
- {
- tempRed[xi] = nextRed[xi] * (oy - sifrac);
- tempGreen[xi] = nextGreen[xi] * (oy - sifrac);
- tempBlue[xi] = nextBlue[xi] * (oy - sifrac);
- }
- si++;
- /* add values for whole pixels: */
- while (si < ci)
- {
- GetScaledRow(ImIn, x1, si, ix, ox,
- nextRed, nextGreen, nextBlue);
- for (xi = 0; xi < ox; xi++)
- {
- tempRed[xi] += nextRed[xi] * oy;
- tempGreen[xi] += nextGreen[xi] * oy;
- tempBlue[xi] += nextBlue[xi] * oy;
- }
- si++;
- }
- /* add fraction of current input row (ending segment): */
- if (yi < oy - 1)
- {
- /* only get next row if still in icon: */
- GetScaledRow(ImIn, x1, si, ix, ox,
- nextRed, nextGreen, nextBlue);
- }
- sifrac = cifrac;
- for (xi = 0; xi < ox; xi++)
- {
- tempRed[xi] += nextRed[xi] * sifrac;
- tempGreen[xi] += nextGreen[xi] * sifrac;
- tempBlue[xi] += nextBlue[xi] * sifrac;
- }
- /* write row to output image: */
- PutRGBScan(ImOut, x2, y2 + yi, ox, div,
- tempRed, tempGreen, tempBlue);
- }
- }
-}
-
-
-
-static XImage *ResizeImageSmooth(Display *dpy, XImage *Im,
- int ix, int iy, int ox, int oy)
-{
- Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
-
- int width1, height1, width2, height2;
- int x1, x2, y1, y2;
-
- XImage *Tmp;
-
- char *Data;
-
- width1 = Im->width;
- height1 = Im->height;
-
- width2 = ox * width1 / ix;
- height2 = oy * height1 / iy;
-
- Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8);
-
- Tmp = XCreateImage(dpy, visual,
- Im->depth, ZPixmap, 0, Data, width2, height2,
- 32, 0);
-
- /* compute values for decomposing pixel into color values: */
- redMask = Im->red_mask;
- redShift = 0;
- while ((redMask & 1) == 0)
- {
- redShift++;
- redMask >>= 1;
- }
- greenMask = Im->green_mask;
- greenShift = 0;
- while ((greenMask & 1) == 0)
- {
- greenShift++;
- greenMask >>= 1;
- }
- blueMask = Im->blue_mask;
- blueShift = 0;
- while ((blueMask & 1) == 0)
- {
- blueShift++;
- blueMask >>= 1;
- }
-
- /* scale each icon: */
- for (y1 = 0, y2 = 0; (y1 < height1) && (y2 < height2); y1 += iy, y2 += oy)
- {
- for (x1 = 0, x2 = 0; (x1 < width1) && (x2 < width2); x1 += ix, x2 += ox)
- {
- ScaleIcon(Im, Tmp, x1, y1, x2, y2,
- ix, iy, ox, oy);
- }
- }
-
- return Tmp;
-}
-
-/*
- * Resize an image. XXX XXX XXX
- *
- * Also appears in "main-xaw.c".
- */
-static XImage *ResizeImage(Display *dpy, XImage *Im,
- int ix, int iy, int ox, int oy)
-{
- Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
-
- int width1, height1, width2, height2;
- int x1, x2, y1, y2, Tx, Ty;
- int *px1, *px2, *dx1, *dx2;
- int *py1, *py2, *dy1, *dy2;
-
- XImage *Tmp;
-
- char *Data;
-
- if (smoothRescaling && (ix != ox || iy != oy) &&
- visual->class == TrueColor)
- {
- return ResizeImageSmooth(dpy, Im, ix, iy, ox, oy);
- }
-
- width1 = Im->width;
- height1 = Im->height;
-
- width2 = ox * width1 / ix;
- height2 = oy * height1 / iy;
-
- Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8);
-
- Tmp = XCreateImage(dpy, visual,
- 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 / 2;
-
- for (y1 = 0, y2 = 0; (y1 < height1) && (y2 < height2); )
- {
- Tx = *dx1 / 2;
-
- 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 */
-
-#endif /* USE_X11 || USE_XAW */
diff --git a/src/main-crb.c b/src/main-crb.c
deleted file mode 100644
index c6a3a412..00000000
--- a/src/main-crb.c
+++ /dev/null
@@ -1,5963 +0,0 @@
-/* File: main-crb.c */
-
-/*
- * Copyright (c) 1997 Ben Harrison, Keith Randall, Peter Ammon, Ron Anderson
- * 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 Macintosh computers running OS X,
- * or OS 8/9 with CarbonLib system extention.
- *
- * 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"
- * resources with id "1001", "1002", "1003" and "1004" with no dangerous
- * side effects.
- *
- *
- * This file assumes that you will be using a PPC Mac running OS X
- * or OS 8/9 (8.6 or greater) with CarbonLib system extention enabled.
- * In fact, the game will refuse to run unless these features are available.
- *
- * MACH_O_CARBON code pushes the system requirement a bit further, and
- * I don't think it works on System 8, even with CarbonLib, because it uses
- * the Bundle services, but I may be wrong.
- *
- * Note that the "preference" file is now a simple XML text file
- * called "<program name>.plist" in case of PEF Carbon, and "<Java-style
- * program id defined in Info.plist>.plist" for Mach-O Carbon, which contains
- * key-value paris, so it no longer has to check version stamp to validate
- * its contents.
- *
- *
- * 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 Apple Event 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.
- *
- * Carbon code adapted from works by Peter Ammon and Ron Anderson.
- *
- * (List of changes made by "pelpel" follow)
- * Some API calls are updated to OS 8.x-- ones.
- *
- * Pixmap locking code in Term_pict_map() follows Carbon Porting Guide
- * by Apple.
- *
- * The idle loop in TERM_XTRA_DELAY is rewritten to sleep on WaitNextEvent
- * for a couple of reasons.
- *
- * CheckEvent now really blocks whenever asked to wait.
- *
- * The unused buffer GWorld is completely removed. It has long been pure waste
- * of memory.
- *
- * The default font-size combination was changed because the old one, Monaco
- * at 12 points causes the redraw artefact problem on OS X.
- *
- * Characters in the ASCII mode are clipped by their bounding rects to reduce
- * redraw artefacts that were quite annoying in certain font-point combos.
- *
- * Transparency effect now avoids double bitblts whenever possible.
- *
- * Old tiles were drawn in a wrong fashion by the USE_TRANSPARENCY code.
- *
- * ASCII and the two graphics modes are now controlled by single graf_mode
- * variable. arg_* and use_* variables are set when requested mode is
- * successfully initialised.
- *
- * Most of the menus are now loaded from resources.
- *
- * Moved TileWidth and TileHeight menus into Special. There were too many menus.
- *
- * Added support for 32x32 tiles, now for [V] only.
- *
- * Related to the above, globe_init no longer loads tile images twice if
- * a tileset doesn't have corresponding masks.
- *
- * Added support for POSIX-style pathnames, for Mach-O Carbon (gcc, CW >= 7).
- * We can finally live without Pascal strings to handle files this way.
- *
- * (Mach-O Carbon) Graphics tiles are moved out of the resource fork into
- * bundle-based data fork files.
- *
- * Changed size-related menu code, because they no longer function because
- * some APIs have been changed to return Unicode in some cases.
- *
- * Changed the transparency code again, this time using Ron Anderson's code,
- * which makes more sound assumption about background colour and is more
- * efficient.
- *
- * The old asynchronous sound player could try to lock the same handle more
- * than once, load same sound resource already in use, or unlock and release
- * currently playing sound.
- *
- * hook_quit() now releases memory-related resources dynamically allocated by
- * the graphics and sound code.
- *
- * Important Resources in the resource file:
- *
- * FREF 130 = ANGBAND_CREATOR / 'APPL' (application)
- * FREF 129 = ANGBAND_CREATOR / 'SAVE' (save file)
- * FREF 130 = ANGBAND_CREATOR / 'TEXT' (generic text file)
- * FREF 131 = ANGBAND_CREATOR / 'DATA' (binary image file, score file)
- *
- * DLOG 128 = "About Angband..."
- *
- * ALRT 128 = unused (?)
- * ALRT 129 = "Warning..."
- *
- * DITL 128 = body for DLOG 128
- * DITL 129 = body for ALRT 129
- * DITL 130 = body for ALRT 130
- *
- * ICON 128 = "warning" icon
- *
- * MBAR 128 = array of MENU id's (128, 129, 130, 131, 132, 133, 134)
- * MENU 128 = apple (about, -, ...)
- * MENU 129 = File (close, save, -, score, quit)
- * MENU 130 = Edit (undo, -, cut, copy, paste, clear)
- * MENU 131 = Font (bold, wide, -)
- * MENU 132 = Size ()
- * MENU 133 = Windows ()
- * MENU 134 = Special (Sound, Graphics, TileWidth, TileHeight, -, Fiddle,
- * Wizard)
- * Graphics have following submenu attached:
- * MENU 144 = Graphics (None, 8x8, 16x16, 32x32, enlarge tiles)
- * TileWidth and TileHeight submenus are filled in by this program.
- * MENU 145 = TileWidth ()
- * MENU 146 = TileHeight ()
- *
- * On CFM(PEF) Carbon only:
- * PICT 1001 = Graphics tile set (8x8)
- * PICT 1002 = Graphics tile set (16x16 images)
- * PICT 1004 = Graphics tile set (32x32)
- *
- * Mach-O Carbon now uses data fork resources:
- * 8x8.png = Graphics tile set (8x8)
- * 16x16.png = Graphics tile set (16x16 images)
- * 32x32.png = Graphics tile set (32x32)
- * These files should go into the Resources subdirectory of an application
- * bundle.
- *
- * STR# 128 = "Please select the "lib" folder"
- *
- * plst 0 can be empty, but required for single binary Carbon apps on OS X
- * Isn't necessary for Mach-O Carbon.
- *
- *
- * File name patterns:
- * all 'APEX' files have a filename of the form "*:apex:*" (?)
- * all 'DATA' files have a filename of the form "*:data:*"
- * all 'SAVE' files have a filename of the form "*:save:*"
- * all 'USER' files have a filename of the form "*:user:*" (?)
- *
- * Perhaps we should attempt to set the "_ftype" flag inside this file,
- * 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
- *
- * Types.h = (included anyway)
- * Gestalt.h = gestalt code
- * QuickDraw.h = (included anyway)
- * OSUtils.h = (included anyway)
- * Files.h = file code
- * Fonts.h = font code
- * Menus.h = menu code
- * Dialogs.h = dialog code
- * Windows.h = (included anyway)
- * Palettes.h = palette code
- * ToolUtils.h = HiWord() / LoWord()
- * Events.h = event code
- * Resources.h = resource code
- * Controls.h = button code
- * SegLoad.h = ExitToShell(), AppFile, etc
- * Memory.h = NewPtr(), etc
- * QDOffscreen.h = GWorld code
- * Sound.h = Sound code
- * Navigation.h = save file / lib locating dialogues
- * CFPreferences.h = Preferences
- * CFNumber.h = read/write short values from/to preferences
- */
-
-/*
- * Yet another main-xxx.c for Carbon (pelpel) - revision 11d
- *
- * Since I'm using CodeWarrior, the traditional header files are
- * #include'd below.
- *
- * I also compiled Angband 3.0.2 successfully with OS X's gcc.
- * Please follow these instructions if you are interested.
- *
- * ---(developer CD gcc + makefile porting notes, for Angband 3.0.2)-------
- * 1. Compiling the binary
- *
- * If you try this on OS X + gcc, please use makefile.std, replacing
- * main.c and main.o with main-crb.c and main-crb.o, removing all main-xxx.c
- * and main-xxx.o from SRCS and OBJS, and, and use these settings:
- *
- * COPTS = -Wall -O1 -g -fpascal-strings
- * INCLUDES =
- * DEFINES = -DMACH_O_CARBON -DANGBAND30X
- * LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon
- *
- * Never, ever #define MACINTOSH. It'll wreck havoc in system interface
- * (mostly because of totally different pathname convention).
- *
- * You might wish to disable some SET_UID features for various reasons:
- * to have user folder within the lib folder, savefile names etc.
- *
- * For the best compatibility with the Classic ports and my PEF Carbon
- * ports, my_fopen, fd_make and fd_open [in util.c] should call
- * (void)fsetfileinfo(buf, _fcreator, _ftype);
- * when a file is successfully opened. Or you'll see odd icons for some files
- * in the lib folder. In order to do so, extern.h should contain these lines,
- * within #ifdef MACH_O_CARBON:
- * extern int fsetfileinfo(char *path, u32b fcreator, u32b ftype);
- * extern u32b _fcreator;
- * extern u32b _ftype;
- * And enable the four FILE_TYPE macros in h-config.h for defined(MACH_O_CARBON)
- * in addition to defined(MACINTOSH) && !defined(applec), i.e.
- * #if defined(MACINTOSH) && !defined(applec) || defined(MACH_O_CARBON)
- *
- * This is a very good way to spot bugs in use of these macros, btw.
- *
- * 2. Installation
- *
- * The "angband" binary must be arranged this way for it to work:
- *
- * lib/ <- the lib folder
- * Angband (OS X).app/
- * Contents/
- * MacOS/
- * angband <- the binary you've just compiled
- * Info.plist <- to be explained below
- * Resources/
- * Angband.icns
- * Data.icns
- * Edit.icns
- * Save.icns
- * 8x8.png <- 8x8 tiles
- * 16x16.png <- 16x16 tiles
- * angband.rsrc <- see below
- *
- * 3. Preparing Info.plist
- *
- * Info.plist is an XML file describing some attributes of an application,
- * and this is appropriate for Angband:
- *
- * <?xml version="1.0" encoding="UTF-8"?>
- * <plist version="1.0">
- * <dict>
- * <key>CFBundleName</key><string>Angband</string>
- * <key>CFBundleDisplayName</key><string>Angband (OS X)</string>
- * <key>CFBundleExecutable</key><string>angband</string>
- * <key>CFBundlePackageType</key><string>APPL</string>
- * <key>CFBundleSignature</key><string>A271</string>
- * <key>CFBundleVersion</key><string>3.0.2</string>
- * <key>CFBundleShortVersionString</key><string>3.0.2</string>
- * <key>CFBundleIconFile</key><string>Angband</string>
- * <key>CFBundleIdentifier</key><string>net.thangorodrim.Angband</string>
- * <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
- * <key>CFBundleDocumentTypes</key>
- * <array>
- * <dict>
- * <key>CFBundleTypeExtentions</key><array><string>*</string></array>
- * <key>CFBundleTypeIconFile</key><string>Save</string>
- * <key>CFBundleTypeName</key><string>Angband saved game</string>
- * <key>CFBundleTypeOSTypes</key><array><string>SAVE</string></array>
- * <key>CFBundleTypeRole</key><string>Editor</string>
- * </dict>
- * <dict>
- * <key>CFBundleTypeExtentions</key><array><string>*</string></array>
- * <key>CFBundleTypeIconFile</key><string>Edit</string>
- * <key>CFBundleTypeName</key><string>Angband game data</string>
- * <key>CFBundleTypeOSTypes</key><array><string>TEXT</string></array>
- * <key>CFBundleTypeRole</key><string>Editor</string>
- * </dict>
- * <dict>
- * <key>CFBundleTypeExtentions</key><array><string>raw</string></array>
- * <key>CFBundleTypeIconFile</key><string>Data</string>
- * <key>CFBundleTypeName</key><string>Angband game data</string>
- * <key>CFBundleTypeOSTypes</key><array><string>DATA</string></array>
- * <key>CFBundleTypeRole</key><string>Editor</string>
- * </dict>
- * </array>
- * </dict>
- * </plist>
- *
- * 4. Menu, diaglogue and gfx resources
- *
- * The binary assumes angband.rsrc should be in the traditional resource
- * mangager format. Please run this command to create it from its textual
- * description:
- *
- * Rez -i /Developer/Headers/FlatCarbon -d MACH_O -o angband.rsrc Angband.r
- *
- * The command is in /Developer/Tools. You might wish to include it in your
- * PATH.
- *
- * It's better to comment out the definitions of BNDL and plst resources
- * before you do that. I think you can DeRez the resulting tome.rsrc and
- * feed it to the Interface Builder to produce a set of compatible .nib files,
- * but this file also needs to be updated to understand .nib... On the other
- * hand, I really don't like to hardcode UI definitions in C.
- *
- * Graphics resources are moved out of the resource fork and become ordinary
- * PNG files. Make sure to set its resolution to 72 dpi (<- VERY important)
- * while keeping vertical and horizontal scaling factor to 100% (<- VERY
- * important), when you convert tiles in any formats to PNG. This means
- * that the real size of an image must shrink or grow when you change it's dpi.
- *
- * Sound resources are a bit more complicated.
- * The easiest way is:
- * 1) Grab recent Mac Angband binary.
- * 2) Run this command:
- * DeRez -only 'snd ' (Angband binary) > sound.r
- * 3) And specify sound.r files in addition to Angband.r when you run Rez.
- *
- * ---(end of OS X + gcc porting note)--------------------------------------
- *
- * Code adapted from Peter Ammon's work on 2.8.3 and some modifications
- * are made when Apple's Carbon Porting Guide says they are absolutely
- * necessary. Other arbirary changes are mostly because of my hatred
- * of deep nestings and indentations. The code for controlling graphics modes
- * have been thoroughly revised simply because I didn't like it (^ ^;).
- * A bonus of this is that graphics settings can be loaded from Preferences
- * quite easily.
- *
- * I also took Ron Anderson's (minimising the use of local-global coordinate
- * conversions). Some might say his QuickTime multimedia is the most
- * significant achievement... Play your favourite CD instead, if you really
- * miss that (^ ^;) I might consider incorporating it if it makes use of
- * event notification.
- *
- * I replaced some old API calls with new (OS 8.x--) ones, especially
- * when I felt Apple is strongly against their continued usage.
- *
- * Similarly, USE_SFL_CODE should be always active, so I removed ifdef's
- * just to prevent accidents, as well as to make the code a bit cleaner.
- *
- * On the contrary, I deliberately left traditional resource interfaces.
- * Whatever Apple might say, I abhor file name extentions. And keeping two
- * different sets of resources for Classic and Carbon is just too much for
- * a personal project XXX
- *
- * Because Carbon forbids the use of 68K code, ANGBAND_LITE_MAC sections
- * are removed.
- *
- * Because the default font-size combination causes redraw artefact problem
- * (some characters, even in monospace fonts, have negative left bearings),
- * I introduced rather crude hack to clip all character drawings within
- * their bounding rects. If you don't like this, please comment out the line
- * #define CLIP_HACK
- * below.
- *
- * The check for return values of AEProcessAppleEvent is removed,
- * because it results in annoying dialogues on OS X, also because
- * Apple says it isn't usually necessary.
- *
- * Because the always_pict code is *so* slow, I changed the graphics
- * mode selection a bit to use higher_pict when a user chooses a fixed
- * width font and doesn't changes tile width / height.
- *
- * Added support for David Gervais' 32x32 tiles.
- *
- * Replaced transparency effect code by Ron Anderson's.
- *
- * Added support for gcc & make compilation. They come free with OS X
- * (on the developer CD). This means that it can be compiled as a bundle.
- *
- * For Mach-O Carbon binary, moved graphics tiles out of the
- * resource fork and made them plain PNG files, to be stored in the application
- * bundle's "Resources" subdirectory.
- *
- * For Mach-O Carbon binary, provided a compile-time option (USE_QT_SOUND) to
- * move sound effect samples out of the resource fork and use *.wav files in
- * the bundle's "Resources" subdirectory. The "*" part must match the names in
- * angband_sound_name (variable.c) exactly. This doesn't hurt performance
- * a lot in [V] (it's got ~25 sound events), but problematic in [Z]-based
- * ones (they have somewhere around 70 sound events).
- *
- * You still can use the resource file that comes with the ext-mac archive
- * on the Angband FTP server, with these additions:
- * - MENUs 131--134 and 144--146, as described above
- * - MBAR 128: just a array of 128 through 134
- * - plst 0 : can be empty, although Apple recommends us to fill it in.
- * - STR# 128 : something like "Please select your lib folder"
- *
- * Since this involves considerable amount of work, I attached
- * a plain text resource definition (= Rez format) .
- * I heavily commented on the file, hoping it could be easily adapted
- * to future versions of Angband as well as variants.
- * I omitted sound effects and graphic tiles to make it reasonably small.
- * Please copy them from any recent Mac binaries - you can use, say ZAngband
- * ones for Vanilla or [V]-based variants quite safely. T.o.M.E. uses fairly
- * extended 16x16 tileset and it is maintained actively. IIRC Thangorodrim
- * compile page has an intruction explaining how to convert tiles for
- * use on the Mac... It can be tricky, depending on your choice of
- * graphics utility. Remember setting resolution to 72 pixels per inch,
- * while keeping vertical/horizontal scale factor to 100% and dump the
- * result as a PICT from resource.
- *
- * To build Carbonised Angband with CodeWarrior, copy your PPC project
- * and
- * - replace main-mac.c in the project with this file (in the link order tab)
- * - remove InterfaceLib and MathLib
- * - add CarbonLib (found in Carbon SDK or CW's UniversalInterfaces) --
- * if you have compiler/linker errors, you'll need Carbon SDK 1.1 or greater
- * - replace MSL C.PPC.Lib with MSL C.Carbon.Lib (both found in
- * MSL:MSL_C:MSL_MacOS:Lib:PPC)
- * - leave MSL RuntimePPC.Lib as it is
- * - don't forget to update resource file, as described above
- * - as in Classic targets, you may have to include <unistd.h> and
- * <fcntl.h>. The most convinient place for them is the first
- * #ifdef MACINTOSH in h-system.h
- * - check variant dependent ifdef's explained below, and add
- * appropriate one(s) in your A-mac-h.pch.
- */
-
-
-/*
- * Force Carbon-compatible APIs
- */
-#ifndef MACH_O_CARBON
-
-/* Can be CodeWarrior or MPW */
-# define TARGET_API_MAC_CARBON 1
-
-#else
-
-/*
-* Must be Mach-O Carbon target with OS X gcc.
-* No need to set TARGET_API_MAC_CARBON to 1 here, but I assume it should
-* be able to make efficient use of BSD functions, hence:
-*/
-# define USE_MALLOC
-/* Not yet */
-/* # define USE_NIB */
-
-#endif /* !MACH_O_CARBON */
-
-
-#include "angband.h"
-
-#if defined(MACINTOSH) || defined(MACH_O_CARBON)
-
-/*
- * Check and create if needed the directory dirpath
- */
-bool_ private_check_user_directory(cptr dirpath)
-{
- /* Is this used anywhere else in *bands? */
- struct stat stat_buf;
-
- int ret;
-
- /* See if it already exists */
- ret = stat(dirpath, &stat_buf);
-
- /* It does */
- if (ret == 0)
- {
- /* Now we see if it's a directory */
- if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);
-
- /*
- * Something prevents us from create a directory with
- * the same pathname
- */
- return (FALSE);
- }
-
- /* No - this maybe the first time. Try to create a directory */
- else
- {
- /* Create the ~/.ToME directory */
- ret = mkdir(dirpath, 0700);
-
- /* An error occured */
- if (ret == -1) return (FALSE);
-
- /* Success */
- return (TRUE);
- }
-}
-
-/*
- * Check existence of ".ToME/" directory in the user's
- * home directory or try to create it if it doesn't exist.
- * Returns FALSE if all the attempts fail.
- */
-static bool_ check_create_user_dir(void)
-{
- char dirpath[1024];
- char versionpath[1024];
- char savepath[1024];
-#ifdef PRIVATE_USER_PATH_DATA
- char datapath[1024];
-#endif
-
- /* Get an absolute path from the filename */
- path_parse(dirpath, 1024, PRIVATE_USER_PATH);
- strcpy(versionpath, dirpath);
- strcat(versionpath, USER_PATH_VERSION);
- strcpy(savepath, versionpath);
- strcat(savepath, "/save");
-#ifdef PRIVATE_USER_PATH_DATA
- strcpy(datapath, versionpath);
- strcat(datapath, "/data");
-#endif
-
- return /* don't forget, the dirpath muts come first */
- private_check_user_directory(dirpath) &&
- private_check_user_directory(versionpath) &&
-#ifdef PRIVATE_USER_PATH_DATA
- private_check_user_directory(datapath) &&
-#endif
- private_check_user_directory(savepath);
-}
-
-
-/*
- * Variant-dependent features:
- *
- * #define ALLOW_BIG_SCREEN (V, Ey, O, T.o.M.E., and Z. Dr's big screen needs
- * more work. New S one is too idiosyncratic...)
- * #define HAS_SCORE_MENU (V and T.o.M.E.)
- * #define ANGBAND_CREATOR four letter code for your variant, if any.
- * or use the default one.
- *
- * For [Z], you also have to say -- #define inkey_flag (p_ptr->inkey_flag)
- * but before that, please, please consider using main-mac-carbon.c in [Z],
- * that has some interesting features.
- */
-
-#define USE_DOUBLE_TILES
-#define ALLOW_BIG_SCREEN
-#define HAS_SCORE_MENU
-#define ANGBAND_CREATOR 'PrnA'
-
-/* Default creator signature */
-#ifndef ANGBAND_CREATOR
-# define ANGBAND_CREATOR 'A271'
-#endif
-
-
-/*
- * Use rewritten asynchronous sound player
- */
-#define USE_ASYNC_SOUND
-
-
-/*
- * A rather crude fix to reduce amount of redraw artefacts.
- * Some fixed width fonts (i.e. Monaco) has characters with negative
- * left bearings, so Term_wipe_mac or overwriting cannot completely
- * erase them. This could be introduced to Classic Mac OS ports too,
- * but since I've never heard any complaints and I don't like to
- * make 68K ports even slower, I won't do so there.
- */
-#define CLIP_HACK /* */
-
-/*
- * To cope with pref file related problems. It no longer has to be acculate,
- * because preferences are stored in plist.
- */
-#define PREF_VER_MAJOR VERSION_MAJOR
-#define PREF_VER_MINOR VERSION_MINOR
-#define PREF_VER_PATCH VERSION_PATCH
-#define PREF_VER_EXTRA VERSION_EXTRA
-
-
-/*
- * In OS X + gcc, use <Carbon/Carbon.h>, <CoreServices/CoreServices.h> and
- * <CoreFoundation/CoreFoundation.h> for ALL of these, including the Apple
- * Event ones. <QuickTime/QuickTime.h> is used by the tile loading code.
- */
-#ifdef MACH_O_CARBON
-
-#include <Carbon/Carbon.h>
-#include <QuickTime/QuickTime.h>
-#include <CoreServices/CoreServices.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-#else /* MACH_O_CARBON */
-
-#include <Types.h>
-#include <Gestalt.h>
-#include <QuickDraw.h>
-#include <Files.h>
-#include <Fonts.h>
-#include <Menus.h>
-#include <Dialogs.h>
-#include <Windows.h>
-#include <Palettes.h>
-#include <ToolUtils.h>
-#include <Events.h>
-#include <SegLoad.h>
-#include <Resources.h>
-#include <Controls.h>
-#include <Memory.h>
-#include <QDOffscreen.h>
-#include <Sound.h>
-#include <Navigation.h>
-#include <CFPreferences.h>
-#include <CFNumber.h>
-#include <AppleEvents.h>
-#include <EPPC.h>
-#include <Folders.h>
-
-#endif /* MACH_O_CARBON */
-
-/* MacOSX == Unix == Good */
-#ifdef USE_MACOSX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
-#endif
-
-
-/*
- * Use "malloc()" instead of "NewPtr()"
- */
-/* #define USE_MALLOC */
-
-
-/*
- * Information about each of the 256 available colors
- */
-static RGBColor color_info[256];
-
-
-#ifdef MACH_O_CARBON
-
-/*
- * Creator signature and file type - Didn't I say that I abhor file name
- * extentions? Names and metadata are entirely different set of notions.
- */
-OSType _fcreator;
-OSType _ftype;
-
-#endif /* MACH_O_CARBON */
-
-
-/*
- * Forward declare
- */
-typedef struct term_data term_data;
-
-/*
- * Extra "term" data
- */
-struct term_data
-{
- term *t;
-
- Rect r;
-
- WindowPtr w;
-
-
- short padding;
-
- short pixelDepth;
-
- GWorldPtr theGWorld; /* not used ... */
-
- GDHandle theGDH;
-
- GDHandle mainSWGDH; /* not used ... */
-
- Str15 title;
-
- s16b oops;
-
- s16b keys;
-
- s16b last;
-
- s16b mapped;
-
- s16b rows;
- s16b cols;
-
- s16b font_id;
- s16b font_size;
- s16b font_face;
- s16b font_mono;
-
- s16b font_o_x;
- s16b font_o_y;
- s16b font_wid;
- s16b font_hgt;
-
- s16b tile_o_x;
- s16b tile_o_y;
- s16b tile_wid;
- s16b tile_hgt;
-
- s16b size_wid;
- s16b size_hgt;
-
- s16b size_ow1;
- s16b size_oh1;
- s16b size_ow2;
- s16b size_oh2;
-};
-
-
-
-
-/*
- * Forward declare -- see below
- */
-static bool_ CheckEvents(bool_ wait);
-
-
-#ifndef MACH_O_CARBON
-
-/*
- * Hack -- location of the main directory
- */
-static short app_vol;
-static long app_dir;
-
-#endif /* !MACH_O_CARBON */
-
-
-/*
- * Delay handling of double-clicked savefiles
- */
-Boolean open_when_ready = FALSE;
-
-/*
- * Delay handling of pre-emptive "quit" event
- */
-Boolean quit_when_ready = FALSE;
-
-
-/*
- * Aqua automatically supplies the Quit menu.
- */
-static Boolean is_aqua = FALSE;
-
-/*
- * Version of Mac OS - for version specific bug workarounds (; ;)
- */
-static long mac_os_version;
-
-
-/*
- * Hack -- game in progress
- */
-static int game_in_progress = 0;
-
-
-/*
- * Only do "SetPort()" when needed
- */
-static WindowPtr active = NULL;
-
-
-/*
- * Maximum number of terms
- */
-#define MAX_TERM_DATA 8
-
-
-/*
- * An array of term_data's
- */
-static term_data data[MAX_TERM_DATA];
-
-
-/*
- * Note when "open"/"new" become valid
- */
-static bool_ initialized = FALSE;
-
-
-
-/*
- * Convert a C string to a pascal string in place
- *
- * This function may be defined elsewhere, but since it is so
- * small, it is not worth finding the proper function name for
- * all the different platforms.
- */
-static void ctopstr(StringPtr src)
-{
- int i;
- byte len;
-
- /* Hack -- pointer */
- char *s = (char*)(src);
-
- len = strlen(s);
-
- /* Hack -- convert the string */
- for (i = len; i > 1; i--) s[i] = s[i - 1];
-
- /* Hack -- terminate the string */
- s[0] = len;
-}
-
-
-#ifdef MACH_O_CARBON
-
-/* Carbon File Manager utilities by pelpel */
-
-/*
- * (Carbon)
- * Convert a pathname to a corresponding FSSpec.
- * Returns noErr on success.
- */
-static OSErr path_to_spec(const char *path, FSSpec *spec)
-{
- OSErr err;
- FSRef ref;
-
- /* Convert pathname to FSRef ... */
- err = FSPathMakeRef(path, &ref, NULL);
- if (err != noErr) return (err);
-
- /* ... then FSRef to FSSpec */
- err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
-
- /* Inform caller of success or failure */
- return (err);
-}
-
-
-/*
- * (Carbon)
- * Convert a FSSpec to a corresponding pathname.
- * Returns noErr on success.
- */
-static OSErr spec_to_path(const FSSpec *spec, char *buf, size_t size)
-{
- OSErr err;
- FSRef ref;
-
- /* Convert FSSpec to FSRef ... */
- err = FSpMakeFSRef(spec, &ref);
- if (err != noErr) return (err);
-
- /* ... then FSRef to pathname */
- err = FSRefMakePath(&ref, buf, size);
-
- /* Inform caller of success or failure */
- return (err);
-}
-
-
-/*
- * (Carbon) [via path_to_spec]
- * Set creator and filetype of a file specified by POSIX-style pathname.
- * Returns 0 on success, -1 in case of errors.
- */
-int fsetfileinfo(char *pathname, OSType fcreator, OSType ftype)
-{
- OSErr err;
- FSSpec spec;
- FInfo info;
-
- /* Convert pathname to FSSpec */
- if (path_to_spec(pathname, &spec) != noErr) return ( -1);
-
- /* Obtain current finder info of the file */
- if (FSpGetFInfo(&spec, &info) != noErr) return ( -1);
-
- /* Overwrite creator and type */
- info.fdCreator = fcreator;
- info.fdType = ftype;
- err = FSpSetFInfo(&spec, &info);
-
- /* Inform caller of success or failure */
- return ((err == noErr) ? 0 : -1);
-}
-
-
-#else /* MACH_O_CARBON */
-
-/*
-* Convert refnum+vrefnum+fname into a full file name
-* Store this filename in 'buf' (make sure it is long enough)
-* Note that 'fname' looks to be a "pascal" string
-*/
-static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
-{
- DirInfo pb;
- Str255 name;
- int err;
- int i, j;
-
- char res[1000];
-
- i = 999;
-
- res[i] = 0;
- i--;
- for (j = 1; j <= fname[0]; j++)
- {
- res[i - fname[0] + j] = fname[j];
- }
- i -= fname[0];
-
- pb.ioCompletion = NULL;
- pb.ioNamePtr = name;
- pb.ioVRefNum = vrefnum;
- pb.ioDrParID = refnum;
- pb.ioFDirIndex = -1;
-
- while (1)
- {
- pb.ioDrDirID = pb.ioDrParID;
- err = PBGetCatInfoSync((CInfoPBPtr) & pb);
- res[i] = ':';
- i--;
- for (j = 1; j <= name[0]; j++)
- {
- res[i - name[0] + j] = name[j];
- }
- i -= name[0];
-
- if (pb.ioDrDirID == fsRtDirID) break;
- }
-
- /* Extract the result */
- for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
- buf[j] = 0;
-}
-
-
-/*
-* Convert a pascal string in place
-*
-* This function may be defined elsewhere, but since it is so
-* small, it is not worth finding the proper function name for
-* all the different platforms.
-*/
-static void ptocstr(StringPtr src)
-{
- int i;
-
- /* Hack -- pointer */
- char *s = (char*)(src);
-
- /* Hack -- convert the string */
- for (i = s[0]; i; i--, s++) s[0] = s[1];
-
- /* Hack -- terminate the string */
- s[0] = '\0';
-}
-
-
-/*
-* Utility routines by Steve Linberg
-*
-* The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
-* were taken from the Think Reference section called "Getting a Full Pathname"
-* (under the File Manager section). We need PathNameFromDirID to get the
-* full pathname of the opened savefile, making no assumptions about where it
-* is.
-*
-* I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
-* nice.
-*/
-static void pstrcat(StringPtr dst, StringPtr src)
-{
- /* copy string in */
- BlockMove(src + 1, dst + *dst + 1, *src);
-
- /* adjust length byte */
- *dst += *src;
-}
-
-
-/*
-* pstrinsert - insert string 'src' at beginning of string 'dst'
-*/
-static void pstrinsert(StringPtr dst, StringPtr src)
-{
- /* make room for new string */
- BlockMove(dst + 1, dst + *src + 1, *dst);
-
- /* copy new string in */
- BlockMove(src + 1, dst + 1, *src);
-
- /* adjust length byte */
- *dst += *src;
-}
-
-
-static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
-{
- CInfoPBRec block;
- Str255 directoryName;
- OSErr err;
-
- fullPathName[0] = '\0';
-
- block.dirInfo.ioDrParID = dirID;
- block.dirInfo.ioNamePtr = directoryName;
-
- while (1)
- {
- block.dirInfo.ioVRefNum = vRefNum;
- block.dirInfo.ioFDirIndex = -1;
- block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
- err = PBGetCatInfoSync(&block);
- pstrcat(directoryName, (StringPtr)"\p:");
- pstrinsert(fullPathName, directoryName);
- if (block.dirInfo.ioDrDirID == 2) break;
- }
-}
-
-#endif /* MACH_O_CARBON */
-
-
-
-
-/*
- * Center a rectangle inside another rectangle
- *
- * Consider using RepositionWindow() whenever possible
- */
-static void center_rect(Rect *r, Rect *s)
-{
- int centerx = (s->left + s->right) / 2;
- int centery = (2 * s->top + s->bottom) / 3;
- int dx = centerx - (r->right - r->left) / 2 - r->left;
- int dy = centery - (r->bottom - r->top) / 2 - r->top;
- r->left += dx;
- r->right += dx;
- r->top += dy;
- r->bottom += dy;
-}
-
-
-/*
- * Activate a given window, if necessary
- */
-static void activate(WindowPtr w)
-{
- /* Activate */
- if (active != w)
- {
- /* Activate */
- if (w) SetPort(GetWindowPort(w));
-
- /* Remember */
- active = w;
- }
-}
-
-
-/*
- * Display a warning message
- */
-static void mac_warning(cptr warning)
-{
- Str255 text;
- int len, i;
-
- /* Limit of 250 chars */
- len = strlen(warning);
- if (len > 250) len = 250;
-
- /* Make a "Pascal" string */
- text[0] = len;
- for (i = 0; i < len; i++) text[i + 1] = warning[i];
-
- /* Prepare the dialog box values */
- ParamText(text, "\p", "\p", "\p");
-
- /* Display the Alert, wait for Okay */
- Alert(129, 0L);
-}
-
-
-
-/*** Some generic functions ***/
-
-/*
- * Hack -- activate a color (0 to 255)
- */
-static void term_data_color(term_data *td, int a)
-{
- /* Activate the color */
- if (td->last != a)
- {
- /* Activate the color */
- RGBForeColor(&color_info[a]);
-
- /* Memorize color */
- td->last = a;
- }
-}
-
-
-/*
- * Hack -- Apply and Verify the "font" info
- *
- * This should usually be followed by "term_data_check_size()"
- *
- * XXX XXX To force (re)initialisation of td->tile_wid and td->tile_hgt
- * you have to reset them to zero before this function is called.
- * XXX XXX This is automatic when the program starts because the term_data
- * array is WIPE'd by term_data_hack, but isn't in the other cases, i.e.
- * font, font style and size changes.
- */
-static void term_data_check_font(term_data *td)
-{
- int i;
-
- FontInfo info;
-
- WindowPtr old = active;
-
-
- /* Activate */
- activate(td->w);
-
- /* Instantiate font */
- TextFont(td->font_id);
- TextSize(td->font_size);
- TextFace(td->font_face);
-
- /* Extract the font info */
- GetFontInfo(&info);
-
- /* Assume monospaced */
- td->font_mono = TRUE;
-
- /* Extract the font sizing values XXX XXX XXX */
- td->font_wid = CharWidth('@'); /* info.widMax; */
- td->font_hgt = info.ascent + info.descent;
- td->font_o_x = 0;
- td->font_o_y = info.ascent;
-
- /* Check important characters */
- for (i = 33; i < 127; i++)
- {
- /* Hack -- notice non-mono-space */
- if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;
-
- /* Hack -- collect largest width */
- if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
- }
-
- /* Set default offsets */
- td->tile_o_x = td->font_o_x;
- td->tile_o_y = td->font_o_y;
-
- /* Set default tile size */
- if (td->tile_wid == 0) td->tile_wid = td->font_wid;
- if (td->tile_hgt == 0) td->tile_hgt = td->font_hgt;
-
- /* Re-activate the old window */
- activate(old);
-}
-
-
-/*
- * Hack -- Apply and Verify the "size" info
- */
-static void term_data_check_size(term_data *td)
-{
- if (td == &data[0])
- {
-#ifndef ALLOW_BIG_SCREEN
-
- /* Forbid resizing of the Angband window */
- td->cols = 80;
- td->rows = 24;
-
-#else
-
- /* Enforce minimal size */
- if (td->cols < 80) td->cols = 80;
- if (td->rows < 24) td->rows = 24;
-
-#endif /* !ALLOW_BIG_SCREEN */
- }
-
- /* Information windows can be much smaller */
- else
- {
- if (td->cols < 1) td->cols = 1;
- if (td->rows < 1) td->rows = 1;
- }
-
- /* Enforce maximal sizes */
- if (td->cols > 255) td->cols = 255;
- if (td->rows > 255) td->rows = 255;
-
- /* Minimal tile size */
- if (td->tile_wid < td->font_wid) td->tile_wid = td->font_wid;
- if (td->tile_hgt < td->font_hgt) td->tile_hgt = td->font_hgt;
-
- /* Default tile offsets */
- td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
- td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;
-
- /* Minimal tile offsets */
- if (td->tile_o_x < 0) td->tile_o_x = 0;
- if (td->tile_o_y < 0) td->tile_o_y = 0;
-
- /* Apply font offsets */
- td->tile_o_x += td->font_o_x;
- td->tile_o_y += td->font_o_y;
-
- /* Calculate full window size */
- td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
- td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;
-
- {
- BitMap tScreen;
-
- /* Get current screen */
- (void)GetQDGlobalsScreenBits(&tScreen);
-
- /* Verify the top */
- if (td->r.top > tScreen.bounds.bottom - td->size_hgt)
- {
- td->r.top = tScreen.bounds.bottom - td->size_hgt;
- }
-
- /* Verify the top */
- if (td->r.top < tScreen.bounds.top + GetMBarHeight())
- {
- td->r.top = tScreen.bounds.top + GetMBarHeight();
- }
-
- /* Verify the left */
- if (td->r.left > tScreen.bounds.right - td->size_wid)
- {
- td->r.left = tScreen.bounds.right - td->size_wid;
- }
-
- /* Verify the left */
- if (td->r.left < tScreen.bounds.left)
- {
- td->r.left = tScreen.bounds.left;
- }
- }
-
- /* Calculate bottom right corner */
- td->r.right = td->r.left + td->size_wid;
- td->r.bottom = td->r.top + td->size_hgt;
-
- /* Assume no graphics */
- td->t->higher_pict = FALSE;
- td->t->always_pict = FALSE;
-
-
- /* Handle graphics */
- if (use_graphics)
- {
- /* Use higher pict whenever possible */
- if (td->font_mono) td->t->higher_pict = TRUE;
-
- /* Use always_pict only when necessary */
- else td->t->always_pict = TRUE;
- }
-
- /* Fake mono-space */
- if (!td->font_mono ||
- (td->font_wid != td->tile_wid) ||
- (td->font_hgt != td->tile_hgt))
- {
- /*
- * Handle fake monospace
- *
- * pelpel: This is SLOW. Couldn't we use CharExtra
- * and SpaceExtra for monospaced fonts?
- */
- if (td->t->higher_pict) td->t->higher_pict = FALSE;
- td->t->always_pict = TRUE;
- }
-}
-
-
-/*
- * Hack -- resize a term_data
- *
- * This should normally be followed by "term_data_redraw()"
- */
-static void term_data_resize(term_data *td)
-{
- /*
- * Actually resize the window
- *
- * ResizeWindow is the preferred API call, but it cannot
- * be used here.
- */
- SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
-}
-
-
-
-/*
- * Hack -- redraw a term_data
- *
- * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
- */
-static void term_data_redraw(term_data *td)
-{
- term *old = Term;
- Rect tRect;
-
- /* Activate the term */
- Term_activate(td->t);
-
- /* Redraw the contents */
- Term_redraw();
-
- /* Flush the output */
- Term_fresh();
-
- /* Restore the old term */
- Term_activate(old);
-
- /* No need to redraw */
- ValidWindowRect(td->w, GetPortBounds(GetWindowPort(td->w), &tRect));
-}
-
-
-/*
- * Graphics support
- */
-
-/* Set by Term_xtra_mac_react */
-#ifdef MACH_O_CARBON
-static CFStringRef pict_id; /* PICT id of image tiles */
-#else
-static int pict_id; /* PICT id of image tiles */
-#endif /* MACH_O_CARBON */
-
-static int graf_width; /* Width of a tile in pixels */
-static int graf_height; /* Height of a tile in pixels */
-
-/* Calculated by PICT loading code */
-static int pict_cols; /* Number of columns in tiles */
-static int pict_rows; /* Number of rows in tiles */
-
-/* Available graphics modes */
-#define GRAF_MODE_NONE 0 /* plain ASCII */
-#define GRAF_MODE_8X8 1 /* 8x8 tiles */
-#define GRAF_MODE_16X16 2 /* 16x16 tiles */
-#define GRAF_MODE_32X32 3 /* 32x32 tiles */
-
-static int graf_mode = GRAF_MODE_NONE; /* current graphics mode */
-static int graf_mode_req = GRAF_MODE_NONE; /* requested graphics mode */
-
-#define TR_NONE 0 /* No transparency */
-#define TR_OVER 1 /* Overwriting with transparent black pixels */
-static int transparency_mode = TR_NONE; /* types of transparency effect */
-
-
-/*
- * Forward Declare
- */
-typedef struct FrameRec FrameRec;
-
-/*
- * Frame
- *
- * - GWorld for the frame image
- * - Handle to pix map (saved for unlocking/locking)
- * - Pointer to color pix map (valid only while locked)
- */
-struct FrameRec
-{
- GWorldPtr framePort;
- PixMapHandle framePixHndl;
- PixMapPtr framePix;
-};
-
-
-/*
- * The global picture data
- */
-static FrameRec *frameP = NULL;
-
-
-/*
- * Lock a frame
- */
-static void BenSWLockFrame(FrameRec *srcFrameP)
-{
- PixMapHandle pixMapH;
-
- pixMapH = GetGWorldPixMap(srcFrameP->framePort);
- (void)LockPixels(pixMapH);
- HLockHi((Handle)pixMapH);
- srcFrameP->framePixHndl = pixMapH;
- srcFrameP->framePix = (PixMapPtr)(*(Handle)pixMapH);
-}
-
-
-/*
- * Unlock a frame
- */
-static void BenSWUnlockFrame(FrameRec *srcFrameP)
-{
- if (srcFrameP->framePort != NULL)
- {
- HUnlock((Handle)srcFrameP->framePixHndl);
- UnlockPixels(srcFrameP->framePixHndl);
- }
-
- srcFrameP->framePix = NULL;
-}
-
-
-
-#ifdef MACH_O_CARBON
-
-/* Moving graphics resources into data fork -- pelpel */
-
-/*
- * (Carbon, Bundle)
- * Given base and type names of a resource, find a file in the
- * current application bundle and return its FSSpec in the third argument.
- * Returns true on success, false otherwise.
- * e.g. get_resource_spec(CFSTR("8x8"), CFSTR("png"), &spec);
- */
-static Boolean get_resource_spec(
- CFStringRef base_name, CFStringRef type_name, FSSpec *spec)
-{
- CFURLRef res_url;
- FSRef ref;
-
- /* Find the tile resource specified in the current bundle */
- res_url = CFBundleCopyResourceURL(
- CFBundleGetMainBundle(), base_name, type_name, NULL);
-
- /* Oops */
- if (res_url == NULL) return (false);
-
- /* Convert CFURL to FSRef */
- (void)CFURLGetFSRef(res_url, &ref);
-
- /* Convert FSRef to FSSpec */
- (void)FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
-
- /* Free allocated CF data */
- CFRelease(res_url);
-
- /* Success */
- return (true);
-}
-
-
-/*
- * (QuickTime)
- * Create a off-screen GWorld from contents of a file specified by a FSSpec.
- *
- * Globals referenced: data[0], graf_height, graf_width
- * Globals updated: pict_rows, pict_cols.
- */
-static OSErr create_gworld_from_spec(
- GWorldPtr *tile_gw, FSSpec *tile_spec)
-{
- OSErr err;
- GraphicsImportComponent gi;
- GWorldPtr gw, tmp_gw;
- GDHandle gdh, tmp_gdh;
- Rect r;
- SInt16 depth;
-
- /* See if QuickTime understands the file format */
- err = GetGraphicsImporterForFile(tile_spec, &gi);
-
- /* Oops */
- if (err != noErr) return (err);
-
- /* Get depth */
- depth = data[0].pixelDepth;
-
- /* Get GDH */
- gdh = data[0].theGDH;
-
- /* Retrieve the rect of the image */
- err = GraphicsImportGetNaturalBounds(gi, &r);
-
- /* Adjust it, so that the upper left corner becomes (0, 0) */
- OffsetRect(&r, -r.left, -r.top);
-
- /* Calculate and set numbers of rows and columns */
- pict_rows = r.bottom / graf_height;
- pict_cols = r.right / graf_width;
-
- /* Create a GWorld */
- err = NewGWorld(&gw, depth, &r, NULL, gdh, noNewDevice);
-
- /* Oops */
- if (err != noErr) return (err);
-
- /* Save the pointer to the GWorld */
- *tile_gw = gw;
-
- /* Save the current GWorld */
- GetGWorld(&tmp_gw, &tmp_gdh);
-
- /* Activate the newly created GWorld */
- (void)GraphicsImportSetGWorld(gi, gw, NULL);
-
- /* Prevent pixmap from moving while drawing */
- (void)LockPixels(GetGWorldPixMap(gw));
-
- /* Clear the pixels */
- EraseRect(&r);
-
- /* Draw the image into it */
- (void)GraphicsImportDraw(gi);
-
- /* Release the lock*/
- UnlockPixels(GetGWorldPixMap(gw));
-
- /* Restore GWorld */
- SetGWorld(tmp_gw, tmp_gdh);
-
- /* Close the image importer */
- CloseComponent(gi);
-
- /* Success */
- return (noErr);
-}
-
-#else /* MACH_O_CARBON */
-
-static OSErr BenSWCreateGWorldFromPict(
- GWorldPtr *pictGWorld, PicHandle pictH)
-{
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
- GWorldPtr tempGWorld;
- Rect pictRect;
- short depth;
- GDHandle theGDH;
-
- tempGWorld = NULL;
-
- /* Reset */
- *pictGWorld = NULL;
-
- /* Get depth */
- depth = data[0].pixelDepth;
-
- /* Get GDH */
- theGDH = data[0].theGDH;
-
- /* Obtain size rectangle */
- pictRect = (**pictH).picFrame;
- OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
-
- /* Calculate and set numbers of rows and columns */
- pict_rows = pictRect.bottom / graf_height;
- pict_cols = pictRect.right / graf_width;
-
- /* Create a GWorld */
- err = NewGWorld(&tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice);
-
- /* Oops */
- if (err != noErr) return (err);
-
- /* Save pointer */
- *pictGWorld = tempGWorld;
-
- /* Save GWorld */
- GetGWorld(&saveGWorld, &saveGDevice);
-
- /* Activate */
- SetGWorld(tempGWorld, nil);
-
- /* Dump the pict into the GWorld */
- (void)LockPixels(GetGWorldPixMap(tempGWorld));
- EraseRect(&pictRect);
- DrawPicture(pictH, &pictRect);
- UnlockPixels(GetGWorldPixMap(tempGWorld));
-
- /* Restore GWorld */
- SetGWorld(saveGWorld, saveGDevice);
-
- /* Success */
- return (0);
-}
-
-#endif /* MACH_O_CARBON */
-
-
-/*
- * Init the global "frameP"
- */
-static errr globe_init(void)
-{
- OSErr err;
-
- GWorldPtr tempPictGWorldP;
-
-#ifdef MACH_O_CARBON
- FSSpec pict_spec;
-#else
- PicHandle newPictH;
-#endif /* MACH_O_CARBON */
-
-
- /* Use window XXX XXX XXX */
- SetPort(GetWindowPort(data[0].w));
-
-
-#ifdef MACH_O_CARBON
-
- /* Get the tile resources */
- if (!get_resource_spec(pict_id, CFSTR("png"), &pict_spec)) return ( -1);
-
- /* Create GWorld */
- err = create_gworld_from_spec(&tempPictGWorldP, &pict_spec);
-
-#else /* MACH_O_CARBON */
-
- /* Get the pict resource */
- if ((newPictH = GetPicture(pict_id)) == 0) return ( -1);
-
- /* Create GWorld */
- err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);
-
- /* Release resource */
- ReleaseResource((Handle)newPictH);
-
-#endif /* MACH_O_CARBON */
-
- /* Error */
- if (err != noErr) return (err);
-
- /* Create the frame */
- frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));
-
- /* Analyze result */
- if (frameP == NULL) return ( -1);
-
- /* Save GWorld */
- frameP->framePort = tempPictGWorldP;
-
- /* Lock it */
- BenSWLockFrame(frameP);
-
- /* Success */
- return (noErr);
-}
-
-
-/*
- * Nuke the global "frameP"
- */
-static errr globe_nuke(void)
-{
- /* Dispose */
- if (frameP)
- {
- /* Unlock */
- BenSWUnlockFrame(frameP);
-
- /* Dispose of the GWorld */
- DisposeGWorld(frameP->framePort);
-
- /* Dispose of the memory */
- DisposePtr((Ptr)frameP);
-
- /* Forget */
- frameP = NULL;
- }
-
- /* Flush events */
- FlushEvents(everyEvent, 0);
-
- /* Success */
- return (0);
-}
-
-
-#ifdef USE_ASYNC_SOUND
-
-/*
- * Asynchronous sound player - completely revised (beta)
- */
-#if defined(USE_QT_SOUND) && !defined(MACH_O_CARBON)
-# undef USE_QT_SOUND
-#endif /* USE_QT_SOUND && !MACH_O_CARBON */
-
-/*
- * How many sound channels will be pooled
- *
- * Was: 20, but I don't think we need 20 sound effects playing
- * simultaneously :) -- pelpel
- */
-#define MAX_CHANNELS 8
-
-/*
- * A pool of sound channels
- */
-static SndChannelPtr channels[MAX_CHANNELS];
-
-/*
- * Status of the channel pool
- */
-static Boolean channel_initialised = FALSE;
-
-/*
- * Data handles containing sound samples
- */
-static SndListHandle samples[SOUND_MAX];
-
-/*
- * Reference counts of sound samples
- */
-static SInt16 sample_refs[SOUND_MAX];
-
-#define SOUND_VOLUME_MIN 0 /* Default minimum sound volume */
-#define SOUND_VOLUME_MAX 255 /* Default maximum sound volume */
-#define VOLUME_MIN 0 /* Minimum sound volume in % */
-#define VOLUME_MAX 100 /* Maximum sound volume in % */
-#define VOLUME_INC 5 /* Increment sound volume in % */
-
-/*
- * I'm just too lazy to write a panel for this XXX XXX
- */
-static int sound_volume = SOUND_VOLUME_MAX;
-
-
-#ifdef USE_QT_SOUND
-
-/*
- * QuickTime sound, by Ron Anderson
- *
- * I didn't choose to use Windows-style .ini files (Ron wrote a parser
- * for it, but...), nor did I use lib/xtra directory, hoping someone
- * would code plist-based configuration code in the future -- pelpel
- */
-
-/*
- * (QuickTime)
- * Load sound effects from data-fork resources. They are wav files
- * with the same names as angband_sound_name[] (variable.c)
- *
- * Globals referenced: angband_sound_name[]
- * Globals updated: samples[] (they can be *huge*)
- */
-static void load_sounds(void)
-{
- OSErr err;
- int i;
-
- /* Start QuickTime */
- err = EnterMovies();
-
- /* Error */
- if (err != noErr) return;
-
- /*
- * This loop may take a while depending on the count and size of samples
- * to load.
- *
- * We should use a progress dialog for this.
- */
- for (i = 1; i < SOUND_MAX; i++)
- {
- /* Apple APIs always give me headacke :( */
- CFStringRef name;
- FSSpec spec;
- SInt16 file_id;
- SInt16 res_id;
- Str255 movie_name;
- Movie movie;
- Track track;
- Handle h;
- Boolean res;
-
- /* Allocate CFString with the name of sound event to be processed */
- name = CFStringCreateWithCString(NULL, angband_sound_name[i],
- kTextEncodingUS_ASCII);
-
- /* Error */
- if (name == NULL) continue;
-
- /* Find sound sample resource with the same name */
- res = get_resource_spec(name, CFSTR("wav"), &spec);
-
- /* Free the reference to CFString */
- CFRelease(name);
-
- /* Error */
- if (!res) continue;
-
- /* Open the sound file */
- err = OpenMovieFile(&spec, &file_id, fsRdPerm);
-
- /* Error */
- if (err != noErr) continue;
-
- /* Create Movie from the file */
- err = NewMovieFromFile(&movie, file_id, &res_id, movie_name,
- newMovieActive, NULL);
-
- /* Error */
- if (err != noErr) goto close_file;
-
- /* Get the first track of the movie */
- track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic,
- movieTrackCharacteristic | movieTrackEnabledOnly );
-
- /* Error */
- if (track == NULL) goto close_movie;
-
- /* Allocate a handle to store sample */
- h = NewHandle(0);
-
- /* Error */
- if (h == NULL) goto close_track;
-
- /* Dump the sample into the handle */
- err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0,
- GetTrackDuration(track), 0L, NULL);
-
- /* Success */
- if (err == noErr)
- {
- /* Store the handle in the sample list */
- samples[i] = (SndListHandle)h;
- }
-
- /* Failure */
- else
- {
- /* Free unused handle */
- DisposeHandle(h);
- }
-
- /* Free the track */
-close_track:
- DisposeMovieTrack(track);
-
- /* Free the movie */
-close_movie:
- DisposeMovie(movie);
-
- /* Close the movie file */
-close_file:
- CloseMovieFile(file_id);
- }
-
- /* Stop QuickTime */
- ExitMovies();
-}
-
-#else /* USE_QT_SOUND */
-
-/*
-* Return a handle of 'snd ' resource given Angband sound event number,
-* or NULL if it isn't found.
-*
-* Globals referenced: angband_sound_name[] (variable.c)
-*/
-static SndListHandle find_sound(int num)
-{
-Str255 sound;
-
-/* Get the proper sound name */
-strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
-sound[0] = strlen((char*)sound + 1);
-
-/* Obtain resource XXX XXX XXX */
-return ((SndListHandle)GetNamedResource('snd ', sound));
-}
-
-#endif /* USE_QT_SOUND */
-
-
-/*
- * Clean up sound support - to be called when the game exits.
- *
- * Globals referenced: channels[], samples[], sample_refs[].
- */
-static void cleanup_sound(void)
-{
- int i;
-
- /* No need to clean it up */
- if (!channel_initialised) return;
-
- /* Dispose channels */
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- /* Drain sound commands and free the channel */
- SndDisposeChannel(channels[i], TRUE);
- }
-
- /* Free sound data */
- for (i = 1; i < SOUND_MAX; i++)
- {
- /* Still locked */
- if ((sample_refs[i] > 0) && (samples[i] != NULL))
- {
- /* Unlock it */
- HUnlock((Handle)samples[i]);
- }
-
-#ifndef USE_QT_SOUND
-
- /* Release it */
- if (samples[i]) ReleaseResource((Handle)samples[i]);
-
-#else
-/* Free handle */
- if (samples[i]) DisposeHandle((Handle)samples[i]);
-
-#endif /* !USE_QT_SOUND */
- }
-}
-
-
-/*
- * Play sound effects asynchronously -- pelpel
- *
- * I don't believe those who first started using the previous implementations
- * imagined this is *much* more complicated as it may seem. Anyway,
- * introduced round-robin scheduling of channels and made it much more
- * paranoid about HLock/HUnlock.
- *
- * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done
- * using channel's callback procedures, which set global flags, and
- * a procedure hooked into CheckEvents does housekeeping. On the other
- * hand, this lazy reclaiming strategy keeps things simple (no interrupt
- * time code) and provides a sort of cache for sound data.
- *
- * Globals referenced: channel_initialised, channels[], samples[],
- * sample_refs[].
- * Globals updated: channel_initialised, channels[], sample_refs[].
- * Only in !USE_QT_SOUND, samples[].
- */
-static void play_sound(int num, int vol)
-{
- OSErr err;
- int i;
- int prev_num;
- SndListHandle h;
- SndChannelPtr chan;
- SCStatus status;
-
- static int next_chan;
- static SInt16 channel_occupants[MAX_CHANNELS];
- static SndCommand volume_cmd, quiet_cmd;
-
-
- /* Initialise sound channels */
- if (!channel_initialised)
- {
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- /* Paranoia - Clear occupant table */
- /* channel_occupants[i] = 0; */
-
- /* Create sound channel for all sounds to play from */
- err = SndNewChannel(&channels[i], sampledSynth, initMono, NULL);
-
- /* Error */
- if (err != noErr)
- {
- /* Free channels */
- while (--i >= 0)
- {
- SndDisposeChannel(channels[i], TRUE);
- }
-
- /* Notify error */
- plog("Cannot initialise sound channels!");
-
- /* Cancel request */
- use_sound = arg_sound = FALSE;
-
- /* Failure */
- return;
- }
- }
-
- /* First channel to use */
- next_chan = 0;
-
- /* Prepare volume command */
- volume_cmd.cmd = volumeCmd;
- volume_cmd.param1 = 0;
- volume_cmd.param2 = 0;
-
- /* Prepare quiet command */
- quiet_cmd.cmd = quietCmd;
- quiet_cmd.param1 = 0;
- quiet_cmd.param2 = 0;
-
- /* Initialisation complete */
- channel_initialised = TRUE;
- }
-
- /* Paranoia */
- if ((num <= 0) || (num >= SOUND_MAX)) return;
-
- /* Prepare volume command */
- volume_cmd.param2 = (SInt16)((vol << 4) | vol);
-
- /* Channel to use (round robin) */
- chan = channels[next_chan];
-
- /* See if the resource is already in use */
- if (sample_refs[num] > 0)
- {
- /* Resource in use */
- h = samples[num];
-
- /* Increase the refcount */
- sample_refs[num]++;
- }
-
- /* Sound is not currently in use */
- else
- {
- /* Get handle for the sound */
-#ifdef USE_QT_SOUND
- h = samples[num];
-#else
- h = find_sound(num);
-#endif /* USE_QT_SOUND */
-
- /* Sample not available */
- if (h == NULL) return;
-
-#ifndef USE_QT_SOUND
-
- /* Load resource */
- LoadResource((Handle)h);
-
- /* Remember it */
- samples[num] = h;
-
-#endif /* !USE_QT_SOUND */
-
- /* Lock the handle */
- HLock((Handle)h);
-
- /* Initialise refcount */
- sample_refs[num] = 1;
- }
-
- /* Poll the channel */
- err = SndChannelStatus(chan, sizeof(SCStatus), &status);
-
- /* It isn't available */
- if ((err != noErr) || status.scChannelBusy)
- {
- /* Shut it down */
- SndDoImmediate(chan, &quiet_cmd);
- }
-
- /* Previously played sound on this channel */
- prev_num = channel_occupants[next_chan];
-
- /* Process previously played sound */
- if (prev_num != 0)
- {
- /* Decrease refcount */
- sample_refs[prev_num]--;
-
- /* We can free it now */
- if (sample_refs[prev_num] <= 0)
- {
- /* Unlock */
- HUnlock((Handle)samples[prev_num]);
-
-#ifndef USE_QT_SOUND
-
- /* Release */
- ReleaseResource((Handle)samples[prev_num]);
-
- /* Forget handle */
- samples[prev_num] = NULL;
-
-#endif /* !USE_QT_SOUND */
-
- /* Paranoia */
- sample_refs[prev_num] = 0;
- }
- }
-
- /* Remember this sound as the current occupant of the channel */
- channel_occupants[next_chan] = num;
-
- /* Set up volume for channel */
- SndDoImmediate(chan, &volume_cmd);
-
- /* Play new sound asynchronously */
- SndPlay(chan, h, TRUE);
-
- /* Schedule next channel (round robin) */
- next_chan++;
- if (next_chan >= MAX_CHANNELS) next_chan = 0;
-}
-
-#endif /* USE_ASYNC_SOUND */
-
-
-
-
-/*** Support for the "z-term.c" package ***/
-
-
-/*
- * Initialize a new Term
- *
- * Note also the "window type" called "noGrowDocProc", which might be more
- * appropriate for the main "screen" window.
- *
- * Note the use of "srcCopy" mode for optimized screen writes.
- */
-static void Term_init_mac(term *t)
-{
- term_data *td = (term_data*)(t->data);
- WindowAttributes wattrs;
- OSStatus err;
-
- static RGBColor black = {0x0000, 0x0000, 0x0000};
- static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
-
-#ifndef ALLOW_BIG_SCREEN
-
- /* Every window has close and collapse boxes */
- wattrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;
-
- /* Information windows are resizable */
- if (td != &data[0]) wattrs |= kWindowResizableAttribute;
-
-#else
-
- /* Big screen - every window has close, collapse and resize boxes */
- wattrs = kWindowCloseBoxAttribute |
- kWindowCollapseBoxAttribute |
- kWindowResizableAttribute;
-
-#endif /* !ALLOW_BIG_SCREEN */
-
- /* Make the window */
- err = CreateNewWindow(
- kDocumentWindowClass,
- wattrs,
- &td->r,
- &td->w);
-
- /*
- * XXX XXX Although the original main-mac.c doesn't perform error
- * checking, it should be done here.
- */
-
- /* Set window title */
- SetWTitle(td->w, td->title);
-
- /* Activate the window */
- activate(td->w);
-
- /* Erase behind words */
- TextMode(srcCopy);
-
- /* Apply and Verify */
- term_data_check_font(td);
- term_data_check_size(td);
-
- /* Resize the window */
- term_data_resize(td);
-
-
- /* Prepare the colors (real colors) */
- RGBBackColor(&black);
- RGBForeColor(&white);
-
- /* Block */
- {
- Rect globalRect;
- GDHandle mainGDH;
- GDHandle currentGDH;
- GWorldPtr windowGWorld;
- PixMapHandle basePixMap;
-
- /* Obtain the global rect */
- GetWindowBounds((WindowRef)td->w, kWindowContentRgn, &globalRect);
-
- /* Obtain the proper GDH */
- mainGDH = GetMaxDevice(&globalRect);
-
- /* Extract GWorld and GDH */
- GetGWorld(&windowGWorld, &currentGDH);
-
- /* Obtain base pixmap */
- basePixMap = (**mainGDH).gdPMap;
-
- /* Save pixel depth */
- td->pixelDepth = (**basePixMap).pixelSize;
-
- /* Save Window GWorld - unused */
- td->theGWorld = windowGWorld;
-
- /* Save Window GDH */
- td->theGDH = currentGDH;
-
- /* Save main GDH - unused */
- td->mainSWGDH = mainGDH;
- }
-
- {
- Rect portRect;
-
- /* Get current Rect */
- GetPortBounds(GetWindowPort(td->w), &portRect);
-
- /* Clip to the window */
- ClipRect(&portRect);
-
- /* Erase the window */
- EraseRect(&portRect);
-
- /* Invalidate the window */
- InvalWindowRect(td->w, &portRect);
- }
-
- /*
- * A certain release of OS X fails to display windows at proper
- * locations (_ _#)
- */
- if ((mac_os_version >= 0x1000) && (mac_os_version < 0x1010))
- {
- /* Hack - Make sure the window is displayed at (r.left,r.top) */
- MoveWindow(td->w, td->r.left, td->r.top, 1);
- }
-
- /* Display the window if needed */
- if (td->mapped)
- {
- TransitionWindow(td->w,
- kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL);
- }
-
- /* Hack -- set "mapped" flag */
- t->mapped_flag = td->mapped;
-
- /* Forget color */
- td->last = -1;
-}
-
-
-
-/*
- * Nuke an old Term
- */
-static void Term_nuke_mac(term *t)
-{
- /* XXX */
-}
-
-
-
-/*
- * Unused
- */
-static errr Term_user_mac(int n)
-{
- /* Success */
- return (0);
-}
-
-
-
-/*
- * React to changes
- */
-static errr Term_xtra_mac_react(void)
-{
- term_data *td = (term_data*)(Term->data);
-
- int i;
-
-
- /* Reset color */
- td->last = -1;
-
- /* Update colors */
- for (i = 0; i < 256; i++)
- {
- u16b rv, gv, bv;
-
- /* Extract the R,G,B data */
- rv = angband_color_table[i][1];
- gv = angband_color_table[i][2];
- bv = angband_color_table[i][3];
-
- /* Save the actual color */
- color_info[i].red = (rv | (rv << 8));
- color_info[i].green = (gv | (gv << 8));
- color_info[i].blue = (bv | (bv << 8));
- }
-
-
- /* Handle sound */
- if (use_sound != arg_sound)
- {
- /* Apply request */
- use_sound = arg_sound;
- }
-
-
- /* Handle graphics */
- if (graf_mode_req != graf_mode)
- {
- /* dispose old GWorld's if present */
- globe_nuke();
-
- /*
- * Setup parameters according to request
- *
- * In [Z], you have to set use_graphics and arg_graphics to
- * GRAPHICS_NONE, GRAPHICS_ORIGINAL or GRAPHICS_ADAM_BOLT, and
- * comment ANGBAND_GRAF out.
- */
- switch (graf_mode_req)
- {
- /* ASCII - no graphics whatsoever */
- case GRAF_MODE_NONE:
- {
- use_graphics = arg_graphics = FALSE;
- transparency_mode = TR_NONE;
- break;
- }
-
- /*
- * 8x8 tiles (PICT id 1001)
- * no transparency effect
- * "old" graphics definitions
- */
- case GRAF_MODE_8X8:
- {
- use_graphics = arg_graphics = TRUE;
- ANGBAND_GRAF = "old";
- transparency_mode = TR_NONE;
-#ifdef MACH_O_CARBON
- pict_id = CFSTR("8x8");
-#else
- pict_id = 1001;
-#endif /* MACH_O_CARBON */
- graf_width = graf_height = 8;
- break;
- }
-
- /*
- * 16x16 tiles (images: PICT id 1002, masks: PICT id 1003)
- * with transparency effect
- * "new" graphics definitions
- */
- case GRAF_MODE_16X16:
- {
- use_graphics = arg_graphics = TRUE;
- ANGBAND_GRAF = "new";
- transparency_mode = TR_OVER;
-#ifdef MACH_O_CARBON
- pict_id = CFSTR("16x16");
-#else
- pict_id = 1002;
-#endif /* MACH_O_CARBON */
- graf_width = graf_height = 16;
- break;
- }
-
- /*
- * 32x32 tiles (images: PICT id 1004)
- * with transparency effect
- * "david" graphics definitions
- * Vanilla-specific
- */
- case GRAF_MODE_32X32:
- {
- use_graphics = arg_graphics = TRUE;
- ANGBAND_GRAF = "david";
- transparency_mode = TR_OVER;
-#ifdef MACH_O_CARBON
- pict_id = CFSTR("32x32");
-#else
- pict_id = 1004;
-#endif /* MACH_O_CARBON */
- graf_width = graf_height = 32;
- break;
- }
- }
-
- /* load tiles and setup GWorlds if tiles are requested */
- if ((graf_mode_req != GRAF_MODE_NONE) && (globe_init() != 0))
- {
- /* Oops */
- plog("Cannot initialize graphics!");
-
- /* reject request */
- graf_mode_req = GRAF_MODE_NONE;
-
- /* reset graphics flags */
- use_graphics = arg_graphics = FALSE;
-
- /* reset transparency mode */
- transparency_mode = TR_NONE;
- }
-
- /* update current graphics mode */
- graf_mode = graf_mode_req;
-
- /* Apply and Verify */
- term_data_check_size(td);
-
- /* Resize the window */
- term_data_resize(td);
-
- /* Reset visuals */
- reset_visuals();
- }
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Do a "special thing"
- */
-static errr Term_xtra_mac(int n, int v)
-{
- term_data *td = (term_data*)(Term->data);
-
- Rect r;
-
- /* Analyze */
- switch (n)
- {
- /* Make a noise */
- case TERM_XTRA_NOISE:
- {
- /* Make a noise */
- SysBeep(1);
-
- /* Success */
- return (0);
- }
-
- /* Make a sound */
- case TERM_XTRA_SOUND:
- {
-#ifndef USE_ASYNC_SOUND
-
- /*
- * This may not be your choice, but much safer and much less
- * resource hungry. Existing implementations can quite easily
- * crash, by starting asynchronous playing and immediately
- * unlocking and releasing the sound data just started playing...
- * -- pelpel
- */
- Handle handle;
- Str255 sound;
-
- /* Get the proper sound name */
- strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[v]);
- sound[0] = strlen((char*)sound + 1);
-
- /* Obtain resource XXX XXX XXX */
- handle = GetNamedResource('snd ', sound);
-
- /* Oops -- it is a failure, but we return 0 anyway */
- if (handle == NULL) return (0);
-
- /* Load and Lock */
- LoadResource(handle);
- HLock(handle);
-
- /* Play sound (wait for completion) */
- SndPlay(NULL, (SndListHandle)handle, FALSE);
-
- /* Unlock and release */
- HUnlock(handle);
- ReleaseResource(handle);
-
-#else /* !USE_ASYNC_SOUND */
-
- /* Play sound */
- play_sound(v, sound_volume);
-
-#endif /* !USE_ASYNC_SOUND */
-
- /* Success */
- return (0);
- }
-
- /* Process random events */
- case TERM_XTRA_BORED:
- {
- /* Process an event */
- (void)CheckEvents(FALSE);
-
- /* Success */
- return (0);
- }
-
- /* Process pending events */
- case TERM_XTRA_EVENT:
- {
- /* Process an event */
- (void)CheckEvents(v);
-
- /* Success */
- return (0);
- }
-
- /* Flush all pending events (if any) */
- case TERM_XTRA_FLUSH:
- {
- /* Hack -- flush all events */
- while (CheckEvents(FALSE)) /* loop */;
-
- /* Success */
- return (0);
- }
-
- /* Hack -- Change the "soft level" */
- case TERM_XTRA_LEVEL:
- {
- /* Activate if requested */
- if (v) activate(td->w);
-
- /* Success */
- return (0);
- }
-
- /* Clear the screen */
- case TERM_XTRA_CLEAR:
- {
- Rect portRect;
-
- /* Get current Rect */
- GetPortBounds(GetWindowPort(td->w), &portRect);
-
- /* No clipping XXX XXX XXX */
- ClipRect(&portRect);
-
- /* Erase the window */
- EraseRect(&portRect);
-
- /* Set the color */
- term_data_color(td, TERM_WHITE);
-
- /* Frame the window in white */
- MoveTo(0, 0);
- LineTo(0, td->size_hgt - 1);
- LineTo(td->size_wid - 1, td->size_hgt - 1);
- LineTo(td->size_wid - 1, 0);
-
- /* Clip to the new size */
- r.left = portRect.left + td->size_ow1;
- r.top = portRect.top + td->size_oh1;
- r.right = portRect.right - td->size_ow2;
- r.bottom = portRect.bottom - td->size_oh2;
- ClipRect(&r);
-
- /* Success */
- return (0);
- }
-
- /* React to changes */
- case TERM_XTRA_REACT:
- {
- /* React to changes */
- return (Term_xtra_mac_react());
- }
-
- /* Delay (milliseconds) */
- case TERM_XTRA_DELAY:
- {
- /*
- * WaitNextEvent relinquishes CPU as well as
- * induces a screen refresh on OS X
- */
-
- /* If needed */
- if (v > 0)
- {
- EventRecord tmp;
- UInt32 ticks;
-
- /* Convert millisecs to ticks */
- ticks = (v * 60L) / 1000;
-
- /*
- * Hack? - Put the programme into sleep.
- * No events match ~everyEvent, so nothing
- * should be lost in Angband's event queue.
- * Even if ticks are 0, it's worth calling for
- * the above mentioned reasons.
- */
- WaitNextEvent((EventMask)~everyEvent, &tmp, ticks, nil);
- }
-
- /* Success */
- return (0);
- }
-
- /* Rename main window */
- case TERM_XTRA_RENAME_MAIN_WIN:
- {
- char *s = strdup(angband_term_name[0]);
-
- ctopstr((StringPtr)s);
- SetWTitle(data[0].w, (StringPtr)s);
-
- free(s);
- return (0);
- }
-
-/* MacOSX == Unix == Good */
-#ifdef USE_MACOSX
- /* Get Delay of some milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- int ret;
- struct timeval tv;
-
- ret = gettimeofday(&tv, NULL);
- Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- return ret;
- }
-
- /* Subdirectory scan */
- case TERM_XTRA_SCANSUBDIR:
- {
- DIR *directory;
- struct dirent *entry;
-
- scansubdir_max = 0;
-
- directory = opendir(scansubdir_dir);
- if (!directory)
- return 1;
-
- while ((entry = readdir(directory)))
- {
- char file[PATH_MAX + NAME_MAX + 2];
- struct stat filedata;
-
- file[PATH_MAX + NAME_MAX] = 0;
- strncpy(file, scansubdir_dir, PATH_MAX);
- strncat(file, "/", 2);
- strncat(file, entry->d_name, NAME_MAX);
- if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] = string_make(entry->d_name);
- ++scansubdir_max;
- }
- }
-
- closedir(directory);
- return 0;
- }
-#endif
- }
-
- /* Oops */
- return (1);
-}
-
-
-
-/*
- * Low level graphics (Assumes valid input).
- * Draw a "cursor" at (x,y), using a "yellow box".
- * We are allowed to use "Term_what()" to determine
- * the current screen contents (for inverting, etc).
- */
-static errr Term_curs_mac(int x, int y)
-{
- Rect r;
-
- term_data *td = (term_data*)(Term->data);
-
- /* Set the color */
- term_data_color(td, TERM_YELLOW);
-
- /* Frame the grid */
- r.left = x * td->tile_wid + td->size_ow1;
- r.right = r.left + td->tile_wid;
- r.top = y * td->tile_hgt + td->size_oh1;
- r.bottom = r.top + td->tile_hgt;
-
-#ifdef USE_DOUBLE_TILES
-
- /* Mogami's bigtile patch */
-
- /* Adjust it if double width tiles are requested */
- if (use_bigtile &&
- (x + 1 < Term->wid) &&
- (Term->old->a[y][x + 1] == 255))
- {
- r.right += td->tile_wid;
- }
-
-#endif /* USE_DOUBLE_TILES */
-
- FrameRect(&r);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Low level graphics (Assumes valid input)
- *
- * Erase "n" characters starting at (x,y)
- */
-static errr Term_wipe_mac(int x, int y, int n)
-{
- Rect r;
-
- term_data *td = (term_data*)(Term->data);
-
-
- /* Erase the block of characters */
- r.left = x * td->tile_wid + td->size_ow1;
- r.right = r.left + n * td->tile_wid;
- r.top = y * td->tile_hgt + td->size_oh1;
- r.bottom = r.top + td->tile_hgt;
- EraseRect(&r);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Low level graphics. Assumes valid input.
- *
- * Draw several ("n") chars, with an attr, at a given location.
- */
-static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
-{
- int xp, yp;
-
-#ifdef CLIP_HACK
- Rect r;
-#endif /* CLIP_HACK */
-
- term_data *td = (term_data*)(Term->data);
-
-
- /* Set the color */
- term_data_color(td, a);
-
-#ifdef CLIP_HACK
- /* Hack - only draw within the bounding rect */
- r.left = x * td->tile_wid + td->size_ow1;
- r.right = r.left + n * td->tile_wid;
- r.top = y * td->tile_hgt + td->size_oh1;
- r.bottom = r.top + td->tile_hgt;
- ClipRect(&r);
-
- /* Hack - clear the content of the bounding rect */
- EraseRect(&r);
-#endif /* CLIP_HACK */
-
- /* Starting pixel */
- xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
- yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;
-
- /* Move to the correct location */
- MoveTo(xp, yp);
-
- /* Draw the character */
- if (n == 1) DrawChar(*cp);
-
- /* Draw the string */
- else DrawText(cp, 0, n);
-
-#ifdef CLIP_HACK
- /* Obtain current window's rect */
- GetPortBounds(GetWindowPort(td->w), &r);
-
- /* Clip to the window again */
- ClipRect(&r);
-#endif /* CLIP_HACK */
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Low level graphics (Assumes valid input)
- *
- * Erase "n" characters starting at (x,y)
- */
-static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
- const byte *tap, const char *tcp,
- const byte *eap, const char *ecp)
-{
- int i;
- Rect dst_r;
- GrafPtr port;
- PixMapHandle pixmap_h;
-
-#ifdef CLIP_HACK
- Rect portRect;
-#endif /* CLIP_HACK */
-
- term_data *td = (term_data*)(Term->data);
-
- static RGBColor black = {0x0000, 0x0000, 0x0000};
- static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
-
-
-#ifdef CLIP_HACK
- /* Remember current window's rect */
- GetPortBounds(GetWindowPort(td->w), &portRect);
-#endif /* CLIP_HACK */
-
- /* Destination rectangle */
- dst_r.left = x * td->tile_wid + td->size_ow1;
-#ifndef USE_DOUBLE_TILES
- dst_r.right = dst_r.left + td->tile_wid;
-#endif /* !USE_DOUBLE_TILES */
- dst_r.top = y * td->tile_hgt + td->size_oh1;
- dst_r.bottom = dst_r.top + td->tile_hgt;
-
- /* Scan the input */
- for (i = 0; i < n; i++)
- {
- bool_ done = FALSE;
-
- byte a = *ap++;
- char c = *cp++;
-
- byte ta = *tap++;
- char tc = *tcp++;
- byte ea = *eap++;
- char ec = *ecp++;
- bool_ has_overlay = (ea && ec);
-
-
-#ifdef USE_DOUBLE_TILES
-
- /* Hack -- a filler for double-width tile */
- if (use_bigtile && (a == 255))
- {
- /* Advance */
- dst_r.left += td->tile_wid;
-
- /* Ignore */
- continue;
- }
-
- /* Prepare right side of rectagle now */
- dst_r.right = dst_r.left + td->tile_wid;
-
-#endif /* USE_DOUBLE_TILES */
-
- /* Graphics -- if Available and Needed */
- if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
- {
- int col, row;
- Rect src_r;
- int t_col, t_row;
- Rect terrain_r;
- int e_col, e_row;
- Rect ego_r;
-
- /* Row and Col */
- row = ((byte)a & 0x7F) % pict_rows;
- col = ((byte)c & 0x7F) % pict_cols;
-
- /* Source rectangle */
- src_r.left = col * graf_width;
- src_r.top = row * graf_height;
- src_r.right = src_r.left + graf_width;
- src_r.bottom = src_r.top + graf_height;
-
- /* Row and Col */
- t_row = ((byte)ta & 0x7F) % pict_rows;
- t_col = ((byte)tc & 0x7F) % pict_cols;
-
- /* Source rectangle */
- terrain_r.left = t_col * graf_width;
- terrain_r.top = t_row * graf_height;
- terrain_r.right = terrain_r.left + graf_width;
- terrain_r.bottom = terrain_r.top + graf_height;
-
- /* If there's an overlay */
- if (has_overlay)
- {
- /* Row and Col */
- e_row = ((byte)ea & 0x7F) % pict_rows;
- e_col = ((byte)ec & 0x7F) % pict_cols;
-
- /* Source rectangle */
- ego_r.left = e_col * graf_width;
- ego_r.top = e_row * graf_height;
- ego_r.right = ego_r.left + graf_width;
- ego_r.bottom = ego_r.top + graf_height;
- }
-
- /* Hardwire CopyBits */
- RGBBackColor(&white);
- RGBForeColor(&black);
-
-#ifdef USE_DOUBLE_TILES
-
- /* Double width tiles */
- if (use_bigtile) dst_r.right += td->tile_wid;
-
-#endif /* USE_DOUBLE_TILES */
-
- /*
- * OS X requires locking and unlocking of window port
- * when we draw directly to its pixmap.
- * The Lock/Unlock protocol is described in the Carbon
- * Porting Guide.
- */
-
- /* Obtain current window's graphic port */
- port = GetWindowPort(td->w);
-
- /* Lock pixels, so we can use handle safely */
- LockPortBits(port);
-
- /* Get Pixmap handle */
- pixmap_h = GetPortPixMap(port);
-
- /* Transparency effect */
- switch (transparency_mode)
- {
- /* No transparency effects */
- case TR_NONE:
- default:
- {
- /* Draw the picture */
- CopyBits((BitMap*)frameP->framePix,
- (BitMap*)*pixmap_h,
- &src_r, &dst_r, srcCopy, NULL);
-
- break;
- }
-
- /* Overwriting with transparent black pixels */
- case TR_OVER:
- {
- /* Draw the terrain */
- CopyBits((BitMap*)frameP->framePix,
- (BitMap*)*pixmap_h,
- &terrain_r, &dst_r, srcCopy, NULL);
-
- /* Make black pixels transparent */
- RGBBackColor(&black);
-
- /* Draw mon/obj if there's one */
- if ((row != t_row) || (col != t_col))
- CopyBits((BitMap*)frameP->framePix,
- (BitMap*)*pixmap_h,
- &src_r, &dst_r, transparent, NULL);
-
- /* Draw overlay if there's one */
- if (has_overlay)
- {
- CopyBits((BitMap*)frameP->framePix,
- (BitMap*)*pixmap_h,
- &ego_r, &dst_r, transparent, NULL);
- }
-
- break;
- }
- }
-
- /* Release the lock and dispose the PixMap handle */
- UnlockPortBits(port);
-
- /* Restore colors */
- RGBBackColor(&black);
- RGBForeColor(&white);
-
- /* Forget color */
- td->last = -1;
-
- /* Done */
- done = TRUE;
- }
-
- /* Normal */
- if (!done)
- {
- int xp, yp;
-
-#ifdef CLIP_HACK
- /* Hack - avoid writing outside of dst_r */
- ClipRect(&dst_r);
- /* Some characters do not match dst_r, therefore we have to... */
-#endif /* CLIP_HACK */
-
- /* Erase */
- EraseRect(&dst_r);
-
- /* Set the color */
- term_data_color(td, a);
-
- /* Starting pixel */
- xp = dst_r.left + td->tile_o_x;
- yp = dst_r.top + td->tile_o_y;
-
- /* Move to the correct location */
- MoveTo(xp, yp);
-
- /* Draw the character */
- DrawChar(c);
-
-#ifdef CLIP_HACK
- /* Clip to the window - inefficient (; ;) XXX XXX */
- ClipRect(&portRect);
-#endif /* CLIP_HACK */
- }
-
- /* Advance */
- dst_r.left += td->tile_wid;
-#ifndef USE_DOUBLE_TILES
- dst_r.right += td->tile_wid;
-#endif /* !USE_DOUBLE_TILES */
- }
-
- /* Success */
- return (0);
-}
-
-
-
-
-
-/*
- * Create and initialize window number "i"
- */
-static void term_data_link(int i)
-{
- term *old = Term;
-
- term_data *td = &data[i];
-
- /* Only once */
- if (td->t) return;
-
- /* Require mapped */
- if (!td->mapped) return;
-
- /* Allocate */
- MAKE(td->t, term);
-
- /* Initialize the term */
- term_init(td->t, td->cols, td->rows, td->keys);
-
- /* Use a "software" cursor */
- td->t->soft_cursor = TRUE;
-
- /* Erase with "white space" */
- td->t->attr_blank = TERM_WHITE;
- td->t->char_blank = ' ';
-
- /* Prepare the init/nuke hooks */
- td->t->init_hook = Term_init_mac;
- td->t->nuke_hook = Term_nuke_mac;
-
- /* Prepare the function hooks */
- td->t->user_hook = Term_user_mac;
- td->t->xtra_hook = Term_xtra_mac;
- td->t->wipe_hook = Term_wipe_mac;
- td->t->curs_hook = Term_curs_mac;
- td->t->text_hook = Term_text_mac;
- td->t->pict_hook = Term_pict_mac;
-
- /* Link the local structure */
- td->t->data = (void *)(td);
-
- /* Activate it */
- Term_activate(td->t);
-
- /* Global pointer */
- angband_term[i] = td->t;
-
- /* Activate old */
- Term_activate(old);
-}
-
-
-
-
-#ifdef MACH_O_CARBON
-
-/*
- * (Carbon, Bundle)
- * Return a POSIX pathname of the lib directory, or NULL if it can't be
- * located. Caller must supply a buffer along with its size in bytes,
- * where returned pathname will be stored.
- * I prefer use of goto's to several nested if's, if they involve error
- * handling. Sorry if you are offended by their presence. Modern
- * languages have neater constructs for this kind of jobs -- pelpel
- */
-static char *locate_lib(char *buf, size_t size)
-{
- CFURLRef main_url = NULL;
- CFStringRef main_str = NULL;
- char *p;
- char *res = NULL;
-
- /* Obtain the URL of the main bundle */
- main_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
-
- /* Oops */
- if (main_url == NULL) goto ret;
-
- /* Convert it to POSIX pathname */
- main_str = CFURLCopyFileSystemPath(main_url, kCFURLPOSIXPathStyle);
-
- /* Oops */
- if (main_str == NULL) goto ret;
-
- /* Convert it again from darn unisomething encoding to ASCII */
- if (CFStringGetCString(main_str, buf, size, kTextEncodingUS_ASCII) == FALSE)
- goto ret;
-
- /*
- * Paranoia - bounds check
- */
- if (strlen(buf) + 25 + 1 > size) goto ret;
-
- /* Location of the data */
- strcat(buf, "/Contents/Resources/");
-
- /* Set result */
- res = buf;
-
-ret:
-
- /* Release objects allocated and implicitly retained by the program */
- if (main_str) CFRelease(main_str);
- if (main_url) CFRelease(main_url);
-
- /* pathname of the lib folder or NULL */
- return (res);
-}
-
-
-#else /* MACH_O_CARBON */
-
-/*
-* Set the "current working directory" (also known as the "default"
-* volume/directory) to the location of the current application.
-*
-* Original code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
-*
-* Completely rewritten to use Carbon Process Manager. It retrieves the
-* volume and direcotry of the current application and simply stores it
-* in the (static) global variables app_vol and app_dir, but doesn't
-* mess with the "current working directory", because it has long been
-* an obsolete (and arcane!) feature.
-*/
-static void SetupAppDir(void)
-{
- OSErr err;
- ProcessSerialNumber curPSN;
- ProcessInfoRec procInfo;
- FSSpec cwdSpec;
-
- /* Initialise PSN info for the current process */
- curPSN.highLongOfPSN = 0;
- curPSN.lowLongOfPSN = kCurrentProcess;
-
- /* Fill in mandatory fields */
- procInfo.processInfoLength = sizeof(ProcessInfoRec);
- procInfo.processName = nil;
- procInfo.processAppSpec = &cwdSpec;
-
- /* Obtain current process information */
- err = GetProcessInformation(&curPSN, &procInfo);
-
- /* Oops */
- if (err != noErr)
- {
- mac_warning("Unable to get process information");
-
- /* Quit without writing anything */
- ExitToShell();
- }
-
- /* Extract and save the Vol and Dir */
- app_vol = cwdSpec.vRefNum;
- app_dir = cwdSpec.parID;
-}
-
-#endif /* MACH_O_CARBON */
-
-
-
-
-/*
- * Using Core Foundation's Preferences services -- pelpel
- *
- * Requires OS 8.6 or greater with CarbonLib 1.1 or greater. Or OS X,
- * of course.
- *
- * Without this, we can support older versions of OS 8 as well
- * (with CarbonLib 1.0.4).
- *
- * Frequent allocation/deallocation of small chunks of data is
- * far from my liking, but since this is only called at the
- * beginning and the end of a session, I hope this hardly matters.
- */
-
-
-/*
- * Store "value" as the value for preferences item name
- * pointed by key
- */
-static void save_pref_short(const char *key, short value)
-{
- CFStringRef cf_key;
- CFNumberRef cf_value;
-
- /* allocate and initialise the key */
- cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);
-
- /* allocate and initialise the value */
- cf_value = CFNumberCreate(NULL, kCFNumberShortType, &value);
-
- if ((cf_key != NULL) && (cf_value != NULL))
- {
- /* Store the key-value pair in the applications preferences */
- CFPreferencesSetAppValue(
- cf_key,
- cf_value,
- kCFPreferencesCurrentApplication);
- }
-
- /*
- * Free CF data - the reverse order is a vain attempt to
- * minimise memory fragmentation.
- */
- if (cf_value) CFRelease(cf_value);
- if (cf_key) CFRelease(cf_key);
-}
-
-
-/*
- * Load preference value for key, returns TRUE if it succeeds with
- * vptr updated appropriately, FALSE otherwise.
- */
-static bool_ query_load_pref_short(const char *key, short *vptr)
-{
- CFStringRef cf_key;
- CFNumberRef cf_value;
-
- /* allocate and initialise the key */
- cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);
-
- /* Oops */
- if (cf_key == NULL) return (FALSE);
-
- /* Retrieve value for the key */
- cf_value = CFPreferencesCopyAppValue(
- cf_key,
- kCFPreferencesCurrentApplication);
-
- /* Value not found */
- if (cf_value == NULL)
- {
- CFRelease(cf_key);
- return (FALSE);
- }
-
- /* Convert the value to short */
- CFNumberGetValue(
- cf_value,
- kCFNumberShortType,
- vptr);
-
- /* Free CF data */
- CFRelease(cf_value);
- CFRelease(cf_key);
-
- /* Success */
- return (TRUE);
-}
-
-
-/*
- * Update short data pointed by vptr only if preferences
- * value for key is located.
- */
-static void load_pref_short(const char *key, short *vptr)
-{
- short tmp;
-
- if (query_load_pref_short(key, &tmp)) *vptr = tmp;
- return;
-}
-
-
-/*
- * Save preferences to preferences file for current host+current user+
- * current application.
- */
-static void cf_save_prefs()
-{
- int i;
-
- /* Version stamp */
- save_pref_short("version.major", PREF_VER_MAJOR);
- save_pref_short("version.minor", PREF_VER_MINOR);
- save_pref_short("version.patch", PREF_VER_PATCH);
- save_pref_short("version.extra", PREF_VER_EXTRA);
-
- /* Gfx settings */
- save_pref_short("arg.arg_sound", arg_sound);
- save_pref_short("arg.graf_mode", graf_mode);
-#ifdef USE_DOUBLE_TILES
- save_pref_short("arg.big_tile", use_bigtile);
-#endif /* USE_DOUBLE_TILES */
-
- /* Windows */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- term_data *td = &data[i];
-
- save_pref_short(format("term%d.font_mono", i), td->font_mono);
- save_pref_short(format("term%d.font_o_x", i), td->font_o_x);
- save_pref_short(format("term%d.font_o_y", i), td->font_o_y);
- save_pref_short(format("term%d.font_wid", i), td->font_wid);
- save_pref_short(format("term%d.font_hgt", i), td->font_hgt);
- save_pref_short(format("term%d.tile_o_x", i), td->tile_o_x);
- save_pref_short(format("term%d.tile_o_y", i), td->tile_o_y);
- save_pref_short(format("term%d.right", i), td->r.right);
- save_pref_short(format("term%d.bottom", i), td->r.bottom);
- save_pref_short(format("term%d.ow1", i), td->size_ow1);
- save_pref_short(format("term%d.oh1", i), td->size_oh1);
- save_pref_short(format("term%d.ow2", i), td->size_ow2);
- save_pref_short(format("term%d.oh2", i), td->size_oh2);
-
- save_pref_short(format("term%d.mapped", i), td->mapped);
-
- save_pref_short(format("term%d.font_id", i), td->font_id);
- save_pref_short(format("term%d.font_size", i), td->font_size);
- save_pref_short(format("term%d.font_face", i), td->font_face);
-
- save_pref_short(format("term%d.tile_wid", i), td->tile_wid);
- save_pref_short(format("term%d.tile_hgt", i), td->tile_hgt);
-
- save_pref_short(format("term%d.cols", i), td->cols);
- save_pref_short(format("term%d.rows", i), td->rows);
- save_pref_short(format("term%d.left", i), td->r.left);
- save_pref_short(format("term%d.top", i), td->r.top);
- }
-
- /*
- * Make sure preferences are persistent
- */
- CFPreferencesAppSynchronize(
- kCFPreferencesCurrentApplication);
-}
-
-
-/*
- * Load preferences from preferences file for current host+current user+
- * current application.
- */
-static void cf_load_prefs()
-{
- bool_ ok;
- short pref_major, pref_minor, pref_patch, pref_extra;
- int i;
-
- /* Assume nothing is wrong, yet */
- ok = TRUE;
-
- /* Load version information */
- ok &= query_load_pref_short("version.major", &pref_major);
- ok &= query_load_pref_short("version.minor", &pref_minor);
- ok &= query_load_pref_short("version.patch", &pref_patch);
- ok &= query_load_pref_short("version.extra", &pref_extra);
-
- /* Any of the above failed */
- if (!ok)
- {
- /* This may be the first run */
- mac_warning("Preferences are not found.");
-
- /* Ignore the rest */
- return;
- }
-
- /* Gfx settings */
- {
- short pref_tmp;
-
- /* sound */
- if (query_load_pref_short("arg.arg_sound", &pref_tmp))
- arg_sound = pref_tmp;
-
- /* graphics */
- if (query_load_pref_short("arg.graf_mode", &pref_tmp))
- graf_mode_req = pref_tmp;
-
-#ifdef USE_DOUBLE_TILES
-
- /* double-width tiles */
- if (query_load_pref_short("arg.big_tile", &pref_tmp))
- {
- use_bigtile = pref_tmp;
- }
-
-#endif /* USE_DOUBLE_TILES */
-
- }
-
- /* Windows */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- term_data *td = &data[i];
-
- load_pref_short(format("term%d.mapped", i), &td->mapped);
-
- load_pref_short(format("term%d.font_id", i), &td->font_id);
- load_pref_short(format("term%d.font_size", i), &td->font_size);
- load_pref_short(format("term%d.font_face", i), &td->font_face);
-
- load_pref_short(format("term%d.tile_wid", i), &td->tile_wid);
- load_pref_short(format("term%d.tile_hgt", i), &td->tile_hgt);
-
- load_pref_short(format("term%d.cols", i), &td->cols);
- load_pref_short(format("term%d.rows", i), &td->rows);
- load_pref_short(format("term%d.left", i), &td->r.left);
- load_pref_short(format("term%d.top", i), &td->r.top);
-
- load_pref_short(format("term%d.font_mono", i), &td->font_mono);
- load_pref_short(format("term%d.font_o_x", i), &td->font_o_x);
- load_pref_short(format("term%d.font_o_y", i), &td->font_o_y);
- load_pref_short(format("term%d.font_wid", i), &td->font_wid);
- load_pref_short(format("term%d.font_hgt", i), &td->font_hgt);
- load_pref_short(format("term%d.tile_o_x", i), &td->tile_o_x);
- load_pref_short(format("term%d.tile_o_y", i), &td->tile_o_y);
- load_pref_short(format("term%d.right", i), &td->r.right);
- load_pref_short(format("term%d.bottom", i), &td->r.bottom);
- load_pref_short(format("term%d.ow1", i), &td->size_ow1);
- load_pref_short(format("term%d.oh1", i), &td->size_oh1);
- load_pref_short(format("term%d.ow2", i), &td->size_ow2);
- load_pref_short(format("term%d.oh2", i), &td->size_oh2);
- }
-}
-
-
-
-
-/*
- * Hack -- default data for a window
- */
-static void term_data_hack(term_data *td)
-{
- short fid;
-
- /* Default to Monaco font */
- GetFNum("\pmonaco", &fid);
-
- /* Wipe it */
- WIPE(td, term_data);
-
- /* No color */
- td->last = -1;
-
- /* Default borders */
- td->size_ow1 = 2;
- td->size_ow2 = 2;
- td->size_oh1 = 2;
- td->size_oh2 = 2;
-
- /* Start hidden */
- td->mapped = FALSE;
-
- /* Default font */
- td->font_id = fid;
-
- /* Default font size - was 12 */
- td->font_size = 14;
-
- /* Default font face */
- td->font_face = 0;
-
- /* Default size */
- td->rows = 24;
- td->cols = 80;
-
- /* Default position */
- td->r.left = 10;
- td->r.top = 40;
-
- /* Minimal keys */
- td->keys = 16;
-}
-
-
-/*
- * Read the preference file, Create the windows.
- *
- * We attempt to use "FindFolder()" to track down the preference file.
- */
-static void init_windows(void)
-{
- int i, b = 0;
-
- term_data *td;
-
-
- /*** Default values ***/
-
- /* Initialize (backwards) */
- for (i = MAX_TERM_DATA; i-- > 0; )
- {
- int n;
-
- cptr s;
-
- /* Obtain */
- td = &data[i];
-
- /* Defaults */
- term_data_hack(td);
-
- /* Obtain title */
- s = angband_term_name[i];
-
- /* Get length */
- n = strlen(s);
-
- /* Maximal length */
- if (n > 15) n = 15;
-
- /* Copy the title */
- strncpy((char*)(td->title) + 1, s, n);
-
- /* Save the length */
- td->title[0] = n;
-
- /* Tile the windows */
- td->r.left += (b * 30);
- td->r.top += (b * 30);
-
- /* Tile */
- b++;
- }
-
-
- /*** Load preferences ***/
-
- cf_load_prefs();
-
-
- /*** Instantiate ***/
-
- /* Main window */
- td = &data[0];
-
- /* Many keys */
- td->keys = 1024;
-
- /* Start visible */
- td->mapped = TRUE;
-
- /* Link (backwards, for stacking order) */
- for (i = MAX_TERM_DATA; i-- > 0; )
- {
- term_data_link(i);
- }
-
- /* Main window */
- td = &data[0];
-
- /* Main window */
- Term_activate(td->t);
-}
-
-
-/*
- * Save preferences
- */
-static void save_pref_file(void)
-{
- cf_save_prefs();
-}
-
-
-/*
- * Handle the "open_when_ready" flag
- */
-static void handle_open_when_ready(void)
-{
- /* Check the flag XXX XXX XXX make a function for this */
- if (open_when_ready && initialized && !game_in_progress)
- {
- /* Forget */
- open_when_ready = FALSE;
-
- /* Game is in progress */
- game_in_progress = 1;
-
- /* Wait for it */
- pause_line(23);
-
- /* Flush input */
- flush();
-
- /* User double-clicked savefile; no savefile screen */
- no_begin_screen = TRUE;
-
- /* Play a game */
- play_game(FALSE);
-
- /* Quit */
- quit(NULL);
- }
-}
-
-
-
-
-/*
- * Menus
- *
- * The standard menus are:
- *
- * Apple (128) = { About, -, ... }
- * File (129) = { Close,Save,-,Score,Quit }
- * Edit (130) = { Cut, Copy, Paste, Clear } (?)
- * Font (131) = { Bold, Extend, -, Monaco, ..., -, ... }
- * Size (132) = { ... }
- * Window (133) = { Angband, Term-1/Mirror, Term-2/Recall, Term-3/Choice,
- * Term-4, Term-5, Term-6, Term-7 }
- * Special (134) = { Sound, Graphics, TileWidth, TileHeight, -,
- * Fiddle, Wizard }
- */
-
-/* Apple menu */
-#define MENU_APPLE 128
-#define ITEM_ABOUT 1
-
-/* File menu */
-#define MENU_FILE 129
-#define ITEM_CLOSE 1
-#define ITEM_SAVE 2
-#ifdef HAS_SCORE_MENU
-#define ITEM_SCORE 4
-#define ITEM_QUIT 5
-#else
-#define ITEM_QUIT 4
-#endif /* HAS_SCORE_MENU */
-
-/* Edit menu */
-#define MENU_EDIT 130
-#define ITEM_UNDO 1
-#define ITEM_CUT 3
-#define ITEM_COPY 4
-#define ITEM_PASTE 5
-#define ITEM_CLEAR 6
-
-/* Font menu */
-#define MENU_FONT 131
-#define ITEM_BOLD 1
-#define ITEM_WIDE 2
-
-/* Size menu */
-#define MENU_SIZE 132
-
-/* Windows menu */
-#define MENU_WINDOWS 133
-
-/* Special menu */
-#define MENU_SPECIAL 134
-#define ITEM_SOUND 1
-#define ITEM_GRAPH 2
-# define SUBMENU_GRAPH 144
-# define ITEM_NONE 1
-# define ITEM_8X8 2
-# define ITEM_16X16 3
-# define ITEM_32X32 4
-# define ITEM_BIGTILE 6
-#define ITEM_TILEWIDTH 3
-# define SUBMENU_TILEWIDTH 145
-#define ITEM_TILEHEIGHT 4
-# define SUBMENU_TILEHEIGHT 146
-#define ITEM_WIZARD 7
-
-
-/*
- * I HATE UNICODE! We've never wanted it. Some multi-national companies
- * made it up as their internationalisation "solution". So I won't use
- * any such API's -- pelpel
- */
-#define NSIZES 32
-static byte menu_size_values[NSIZES];
-static byte menu_tilewidth_values[NSIZES];
-static byte menu_tileheight_values[NSIZES];
-
-/*
- * Initialize the menus
- *
- * Fixed top level menus are now loaded all at once by GetNewMBar().
- * Although this simplifies the function a bit, we have to make sure
- * that resources have all the expected entries defined XXX XXX
- */
-static void init_menubar(void)
-{
- int i, n;
-
- Rect r;
-
- WindowPtr tmpw;
-
- MenuRef m;
-
-#ifdef USE_NIB
-
- /* The new way - loading main menu using Interface Builder services */
- {
- IBNibRef nib;
- OSStatus err;
-
- /* Create a nib reference to the main nib file */
- err = CreateNibReference(CFSTR("main"), &nib);
-
- /* Fatal error - missing Main.nib */
- if (err != noErr) quit("Cannot find Main.nib in the bundle!");
-
- /* Unarchive the menu bar and make it ready to use */
- err = SetMenuBarFromNib(nib, CFSTR("MainMenu"));
-
- /* Fatal error - couldn't insert menu bar */
- if (err != noErr) quit("Cannot prepare menu bar!");
-
- /* Dispose of the nib reference because we don't need it any longer */
- DisposeNibReference(nib);
- }
-
-#else /* USE_NIB */
-
- /* The old way - loading main menu from Resource Manager resource */
- {
- Handle mbar;
-
- /* Load menubar from resources */
- mbar = GetNewMBar(128);
-
- /* Whoops! */
- if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!");
-
- /* Insert them into the current menu list */
- SetMenuBar(mbar);
-
- /* Free handle */
- DisposeHandle(mbar);
- }
-
-#endif /* USE_NIB */
-
-
- /* Apple menu (id 128) - we don't have to do anything */
-
-#ifndef USE_NIB
-
- /* File menu (id 129) - Aqua provides Quit menu for us */
- if (is_aqua)
- {
- /* Get a handle to the file menu */
- m = GetMenuHandle(MENU_FILE);
-
- /* Nuke the quit menu since Aqua does that for us */
- DeleteMenuItem(m, ITEM_QUIT);
-
-#ifndef HAS_SCORE_MENU
-
- /* Hack - because the above leaves a separator as the last item */
- DeleteMenuItem(m, ITEM_QUIT - 1);
-
-#endif /* !HAS_SCORE_MENU */
- }
-
-#endif /* !USE_NIB */
-
-
- /* Edit menu (id 130) - we don't have to do anything */
-
-
- /*
- * Font menu (id 131) - append names of mono-spaced fonts
- * followed by all available ones
- */
- m = GetMenuHandle(MENU_FONT);
-
- /* Fake window */
- r.left = r.right = r.top = r.bottom = 0;
-
- /* Make the fake window so that we can retrieve font info */
- (void)CreateNewWindow(
- kDocumentWindowClass,
- kWindowNoAttributes,
- &r,
- &tmpw);
-
- /* Activate the "fake" window */
- SetPort(GetWindowPort(tmpw));
-
- /* Default mode */
- TextMode(0);
-
- /* Default size */
- TextSize(12);
-
- /* Add the fonts to the menu */
- AppendResMenu(m, 'FONT');
-
- /* Size of menu */
- n = CountMenuItems(m);
-
- /* Scan the menu */
- for (i = n; i >= 4; i--)
- {
- Str255 tmpName;
- short fontNum;
-
- /* Acquire the font name */
- GetMenuItemText(m, i, tmpName);
-
- /* Acquire the font index */
- GetFNum(tmpName, &fontNum);
-
- /* Apply the font index */
- TextFont(fontNum);
-
- /* Remove non-mono-spaced fonts */
- if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
- {
- /* Delete the menu item */
- DeleteMenuItem(m, i);
- }
- }
-
- /* Destroy the fake window */
- DisposeWindow(tmpw);
-
- /* Add a separator */
- AppendMenu(m, "\p-");
-
- /* Add the fonts to the menu */
- AppendResMenu(m, 'FONT');
-
-
-#ifndef USE_NIB
-
- /* Size menu (id 132) */
- m = GetMenuHandle(MENU_SIZE);
-
- /* Add some sizes (stagger choices) */
- for (i = 8, n = 1; i <= 32; i += ((i / 16) + 1), n++)
- {
- Str15 buf;
-
- /* Textual size */
- strnfmt((char*)buf + 1, 15, "%d", i);
- buf[0] = strlen((char*)buf + 1);
-
- /* Add the item */
- AppendMenu(m, buf);
-
- /* Remember its value, for we can't be sure it's in ASCII */
- menu_size_values[n] = i;
- }
-
-#endif /* !USE_NIB */
-
-
- /* Windows menu (id 133) */
- m = GetMenuHandle(MENU_WINDOWS);
-
- /* Default choices */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- Str15 buf;
-
- /* Describe the item */
- strnfmt((char*)buf + 1, 15, "%.15s", angband_term_name[i]);
- buf[0] = strlen((char*)buf + 1);
-
- /* Add the item */
- AppendMenu(m, buf);
-
- /* Command-Key shortcuts */
- if (i < 8) SetItemCmd(m, i + 1, I2D(i));
- }
-
-
-#ifndef USE_NIB
-
- /* Special menu (id 134) */
- m = GetMenuHandle(MENU_SPECIAL);
-
- /* Insert Graphics submenu (id 144) */
- {
- MenuHandle submenu;
-
- /* Get the submenu */
- submenu = GetMenu(SUBMENU_GRAPH);
-
- /* Insert it */
- SetMenuItemHierarchicalMenu(m, ITEM_GRAPH, submenu);
- }
-
- /* Insert TileWidth submenu (id 145) */
- {
- MenuHandle submenu;
-
- /* Get the submenu */
- submenu = GetMenu(SUBMENU_TILEWIDTH);
-
- /* Add some sizes */
- for (i = 4, n = 1; i <= 32; i++, n++)
- {
- Str15 buf;
-
- /* Textual size */
- strnfmt((char*)buf + 1, 15, "%d", i);
- buf[0] = strlen((char*)buf + 1);
-
- /* Append item */
- AppendMenu(submenu, buf);
-
- /* Remember its value, for we can't be sure it's in ASCII */
- menu_tilewidth_values[n] = i;
- }
-
- /* Insert it */
- SetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, submenu);
- }
-
- /* Insert TileHeight submenu (id 146) */
- {
- MenuHandle submenu;
-
- /* Get the submenu */
- submenu = GetMenu(SUBMENU_TILEHEIGHT);
-
-
- /* Add some sizes */
- for (i = 4, n = 1; i <= 32; i++, n++)
- {
- Str15 buf;
-
- /* Textual size */
- strnfmt((char*)buf + 1, 15, "%d", i);
- buf[0] = strlen((char*)buf + 1);
-
- /* Append item */
- AppendMenu(submenu, buf);
-
- /* Remember its value, for we can't be sure it's in ASCII */
- menu_tileheight_values[n] = i;
- }
-
- /* Insert it */
- SetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, submenu);
- }
-
-#endif /* !USE_NIB */
-
- /* Update the menu bar */
- DrawMenuBar();
-}
-
-
-/*
- * 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)
-{
- int i, n;
-
- short value;
-
- Str255 s;
-
- MenuHandle m;
-
- term_data *td = NULL;
-
-
- /* Relevant "term_data" */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Unused */
- if (!data[i].t) continue;
-
- /* Notice the matching window */
- if (data[i].w == FrontWindow()) td = &data[i];
- }
-
-
- /* File menu */
- m = GetMenuHandle(MENU_FILE);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-
- /* Enable "close" */
- if (initialized)
- {
- EnableMenuItem(m, ITEM_CLOSE);
- }
-
- /* Enable "save" */
- if (initialized && character_generated && inkey_flag)
- {
- EnableMenuItem(m, ITEM_SAVE);
- }
-
-#ifdef HAS_SCORE_MENU
-
- /* Enable "score" */
- if (initialized && character_generated && !character_icky)
- {
- EnableMenuItem(m, ITEM_SCORE);
- }
-
-#endif /* HAS_SCORE_MENU */
-
- /* Enable "quit" */
- if (!is_aqua)
- {
- if (!initialized || !character_generated || inkey_flag)
- {
- EnableMenuItem(m, ITEM_QUIT);
- }
- }
-
-
- /* Edit menu */
- m = GetMenuHandle(MENU_EDIT);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-
- /* Enable "edit" options if "needed" */
- if (!td)
- {
- EnableMenuItem(m, ITEM_UNDO);
- EnableMenuItem(m, ITEM_CUT);
- EnableMenuItem(m, ITEM_COPY);
- EnableMenuItem(m, ITEM_PASTE);
- EnableMenuItem(m, ITEM_CLEAR);
- }
-
-
- /* Font menu */
- m = GetMenuHandle(MENU_FONT);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-
- /* Hack -- look cute XXX XXX */
- /* SetItemStyle(m, ITEM_BOLD, bold); */
-
- /* Hack -- look cute XXX XXX */
- /* SetItemStyle(m, ITEM_WIDE, extend); */
-
- /* Active window */
- if (initialized && td)
- {
- /* Enable "bold" */
- EnableMenuItem(m, ITEM_BOLD);
-
- /* Enable "extend" */
- EnableMenuItem(m, ITEM_WIDE);
-
- /* Check the appropriate "bold-ness" */
- if (td->font_face & bold) CheckMenuItem(m, ITEM_BOLD, TRUE);
-
- /* Check the appropriate "wide-ness" */
- if (td->font_face & extend) CheckMenuItem(m, ITEM_WIDE, TRUE);
-
- /* Analyze fonts */
- for (i = 4; i <= n; i++)
- {
- /* Enable it */
- EnableMenuItem(m, i);
-
- /* Analyze font */
- GetMenuItemText(m, i, s);
- GetFNum(s, &value);
-
- /* Check active font */
- if (td->font_id == value) CheckMenuItem(m, i, TRUE);
- }
- }
-
-
- /* Size menu */
- m = GetMenuHandle(MENU_SIZE);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-
- /* Active window */
- if (initialized && td)
- {
- /* Analyze sizes */
- for (i = 1; i <= n; i++)
- {
- /* Analyze size */
- value = menu_size_values[i];
-
- /* Enable the "real" sizes */
- if (RealFont(td->font_id, value)) EnableMenuItem(m, i);
-
- /* Check the current size */
- if (td->font_size == value) CheckMenuItem(m, i, TRUE);
- }
- }
-
-
- /* Windows menu */
- m = GetMenuHandle(MENU_WINDOWS);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Check active windows */
- for (i = 1; i <= n; i++)
- {
- /* Check if needed */
- CheckMenuItem(m, i, data[i - 1].mapped);
- }
-
-
- /* Special menu */
- m = GetMenuHandle(MENU_SPECIAL);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-
- /* Item "arg_sound" */
- EnableMenuItem(m, ITEM_SOUND);
- CheckMenuItem(m, ITEM_SOUND, arg_sound);
-
- /* Item "Graphics" */
- EnableMenuItem(m, ITEM_GRAPH);
- {
- MenuRef submenu;
-
- /* Graphics submenu */
- (void)GetMenuItemHierarchicalMenu(m, ITEM_GRAPH, &submenu);
-
- /* Get menu size */
- n = CountMenuItems(submenu);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(submenu, i);
- CheckMenuItem(submenu, i, FALSE);
- }
-
- /* Item "None" */
- EnableMenuItem(submenu, ITEM_NONE);
- CheckMenuItem(submenu, ITEM_NONE, (graf_mode == GRAF_MODE_NONE));
-
- /* Item "8x8" */
- EnableMenuItem(submenu, ITEM_8X8);
- CheckMenuItem(submenu, ITEM_8X8, (graf_mode == GRAF_MODE_8X8));
-
- /* Item "16x16" */
- EnableMenuItem(submenu, ITEM_16X16);
- CheckMenuItem(submenu, ITEM_16X16, (graf_mode == GRAF_MODE_16X16));
-
- /* Item "32x32" */
- /*EnableMenuItem(submenu, ITEM_32X32);
- CheckMenuItem(submenu, ITEM_32X32, (graf_mode == GRAF_MODE_32X32));*/
-
-#ifdef USE_DOUBLE_TILES
-
- /* Item "Big tiles" */
- if (inkey_flag) EnableMenuItem(submenu, ITEM_BIGTILE);
- CheckMenuItem(submenu, ITEM_BIGTILE, use_bigtile);
-
-#endif /* USE_DOUBLE_TILES */
-
- }
-
- /* Item "TileWidth" */
- EnableMenuItem(m, ITEM_TILEWIDTH);
- {
- MenuRef submenu;
-
- /* TileWidth submenu */
- (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, &submenu);
-
- /* Get menu size */
- n = CountMenuItems(submenu);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(submenu, i);
- CheckMenuItem(submenu, i, FALSE);
- }
-
- /* Active window */
- if (initialized && td)
- {
- /* Analyze sizes */
- for (i = 1; i <= n; i++)
- {
- /* Analyze size */
- value = menu_tilewidth_values[i];
-
- /* Enable */
- if (value >= td->font_wid) EnableMenuItem(submenu, i);
-
- /* Check the current size */
- if (td->tile_wid == value) CheckMenuItem(submenu, i, TRUE);
- }
- }
- }
-
- /* Item "TileHeight" */
- EnableMenuItem(m, ITEM_TILEHEIGHT);
- {
- MenuRef submenu;
-
- /* TileWidth submenu */
- (void)GetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, &submenu);
-
- /* Get menu size */
- n = CountMenuItems(submenu);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(submenu, i);
- CheckMenuItem(submenu, i, FALSE);
- }
-
- /* Active window */
- if (initialized && td)
- {
- /* Analyze sizes */
- for (i = 1; i <= n; i++)
- {
- /* Analyze size */
- value = menu_tileheight_values[i];
-
- /* Enable */
- if (value >= td->font_hgt) EnableMenuItem(submenu, i);
-
- /* Check the current size */
- if (td->tile_hgt == value) CheckMenuItem(submenu, i, TRUE);
- }
- }
- }
-
- /* Item "arg_wizard" */
- EnableMenuItem(m, ITEM_WIZARD);
- CheckMenuItem(m, ITEM_WIZARD, arg_wizard);
-
-
- /* TileHeight menu */
- m = GetMenuHandle(SUBMENU_TILEHEIGHT);
-
- /* Get menu size */
- n = CountMenuItems(m);
-
- /* Reset menu */
- for (i = 1; i <= n; i++)
- {
- /* Reset */
- DisableMenuItem(m, i);
- CheckMenuItem(m, i, FALSE);
- }
-}
-
-
-/*
- * Process a menu selection (see above)
- *
- * Hack -- assume that invalid menu selections are disabled above,
- * which I have been informed may not be reliable. XXX XXX XXX
- */
-static void menu(long mc)
-{
- int i;
-
- int menuid, selection;
-
- static unsigned char s[1000];
-
- short fid;
-
- term_data *td = NULL;
-
- WindowPtr old_win;
-
-
- /* Analyze the menu command */
- menuid = HiWord(mc);
- selection = LoWord(mc);
-
-
- /* Find the window */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Skip dead windows */
- if (!data[i].t) continue;
-
- /* Notice matches */
- if (data[i].w == FrontWindow()) td = &data[i];
- }
-
-
- /* Branch on the menu */
- switch (menuid)
- {
- /* Apple Menu */
- case MENU_APPLE:
- {
- /* About Angband... */
- if (selection == ITEM_ABOUT)
- {
- DialogPtr dialog;
- short item_hit;
-
- /* Get the about dialogue */
- dialog = GetNewDialog(128, 0, (WindowPtr) - 1);
-
- /* Move it to the middle of the screen */
- RepositionWindow(
- GetDialogWindow(dialog),
- NULL,
- kWindowCenterOnMainScreen);
-
- /* Show the dialog */
- TransitionWindow(GetDialogWindow(dialog),
- kWindowZoomTransitionEffect,
- kWindowShowTransitionAction,
- NULL);
-
- /* Wait for user to click on it */
- ModalDialog(0, &item_hit);
-
- /* Free the dialogue */
- DisposeDialog(dialog);
- break;
- }
-
- break;
- }
-
- /* File Menu */
- case MENU_FILE:
- {
- switch (selection)
- {
-
- /* Close */
- case ITEM_CLOSE:
- {
- /* No window */
- if (!td) break;
-
- /* Not Mapped */
- td->mapped = FALSE;
-
- /* Not Mapped */
- td->t->mapped_flag = FALSE;
-
- /* Hide the window */
- TransitionWindow(td->w,
- kWindowZoomTransitionEffect,
- kWindowHideTransitionAction,
- NULL);
-
- break;
- }
-
- /* Save */
- case ITEM_SAVE:
- {
- /* Hack -- Forget messages */
- msg_flag = FALSE;
-
- /* Hack -- Save the game */
- do_cmd_save_game();
-
- break;
- }
-
-#ifdef HAS_SCORE_MENU
-
- /* Show score */
- case ITEM_SCORE:
- {
- predict_score_gui(&initialized, &game_in_progress);
-
- /* Done */
- break;
- }
-
-#endif /* HAS_SCORE_MENU */
-
- /* Quit (with save) */
- case ITEM_QUIT:
- {
- /* Save the game (if necessary) */
- if (game_in_progress && character_generated)
- {
- /* Hack -- Forget messages */
- msg_flag = FALSE;
-
- /* Save the game */
- do_cmd_save_game();
- }
-
- /* Quit */
- quit(NULL);
- break;
- }
- }
- break;
- }
-
- /* Edit menu */
- case MENU_EDIT:
- {
- /* Unused */
- break;
- }
-
- /* Font menu */
- case MENU_FONT:
- {
- /* Require a window */
- if (!td) break;
-
- /* Memorize old */
- old_win = active;
-
- /* Activate */
- activate(td->w);
-
- /* Toggle the "bold" setting */
- if (selection == ITEM_BOLD)
- {
- /* Toggle the setting */
- if (td->font_face & bold)
- {
- td->font_face &= ~bold;
- }
- else
- {
- td->font_face |= bold;
- }
-
- /* Hack - clear tile size info XXX XXX */
- td->tile_wid = td->tile_hgt = 0;
-
- /* Apply and Verify */
- term_data_check_font(td);
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- break;
- }
-
- /* Toggle the "wide" setting */
- if (selection == ITEM_WIDE)
- {
- /* Toggle the setting */
- if (td->font_face & extend)
- {
- td->font_face &= ~extend;
- }
- else
- {
- td->font_face |= extend;
- }
-
- /* Hack - clear tile size info XXX XXX */
- td->tile_wid = td->tile_hgt = 0;
-
- /* Apply and Verify */
- term_data_check_font(td);
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- break;
- }
-
- /* Get a new font name */
- GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s);
- GetFNum(s, &fid);
-
- /* Save the new font id */
- td->font_id = fid;
-
- /* Current size is bad for new font */
- if (!RealFont(td->font_id, td->font_size))
- {
- /* Find similar size */
- for (i = 1; i <= 32; i++)
- {
- /* Adjust smaller */
- if (td->font_size - i >= 8)
- {
- if (RealFont(td->font_id, td->font_size - i))
- {
- td->font_size -= i;
- break;
- }
- }
-
- /* Adjust larger */
- if (td->font_size + i <= 128)
- {
- if (RealFont(td->font_id, td->font_size + i))
- {
- td->font_size += i;
- break;
- }
- }
- }
- }
-
- /* Hack - clear tile size info XXX XXX */
- td->tile_wid = td->tile_hgt = 0;
-
- /* Apply and Verify */
- term_data_check_font(td);
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- /* Restore the window */
- activate(old_win);
-
- break;
- }
-
- /* Size menu */
- case MENU_SIZE:
- {
- if (!td) break;
-
- /* Save old */
- old_win = active;
-
- /* Activate */
- activate(td->w);
-
- td->font_size = menu_size_values[selection];
-
- /* Hack - clear tile size info XXX XXX */
- td->tile_wid = td->tile_hgt = 0;
-
- /* Apply and Verify */
- term_data_check_font(td);
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- /* Restore */
- activate(old_win);
-
- break;
- }
-
- /* Window menu */
- case MENU_WINDOWS:
- {
- /* Parse */
- i = selection - 1;
-
- /* Check legality of choice */
- if ((i < 0) || (i >= MAX_TERM_DATA)) break;
-
- /* Obtain the window */
- td = &data[i];
-
- /* Mapped */
- td->mapped = TRUE;
-
- /* Link */
- term_data_link(i);
-
- /* Mapped (?) */
- td->t->mapped_flag = TRUE;
-
- /* Show the window */
- TransitionWindow(td->w,
- kWindowZoomTransitionEffect,
- kWindowShowTransitionAction,
- NULL);
-
- /* Bring to the front */
- SelectWindow(td->w);
-
- break;
- }
-
- /* Special menu */
- case MENU_SPECIAL:
- {
- switch (selection)
- {
- case ITEM_SOUND:
- {
- /* Toggle arg_sound */
- arg_sound = !arg_sound;
-
- /* React to changes */
- Term_xtra(TERM_XTRA_REACT, 0);
-
- break;
- }
-
- case ITEM_WIZARD:
- {
- arg_wizard = !arg_wizard;
-
- break;
- }
- }
-
- break;
- }
-
- /* Graphics submenu */
- case SUBMENU_GRAPH:
- {
- switch (selection)
- {
- case ITEM_NONE:
- {
- graf_mode_req = GRAF_MODE_NONE;
-
- break;
- }
-
- case ITEM_8X8:
- {
- graf_mode_req = GRAF_MODE_8X8;
-
- break;
- }
-
- case ITEM_16X16:
- {
- graf_mode_req = GRAF_MODE_16X16;
-
- break;
- }
-
- case ITEM_32X32:
- {
- graf_mode_req = GRAF_MODE_32X32;
-
- break;
- }
-
-#ifdef USE_DOUBLE_TILES
-
- case ITEM_BIGTILE:
- {
- term *old = Term;
- term_data *td = &data[0];
-
- /* Toggle "use_bigtile" */
- use_bigtile = !use_bigtile;
- arg_bigtile = use_bigtile;
-
- /* Activate */
- Term_activate(td->t);
-
- /* Resize the term */
- Term_resize(td->cols, td->rows);
-
- /* Activate old */
- Term_activate(old);
-
- break;
- }
-
-#endif /* USE_DOUBLE_TILES */
-
- }
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
-
- break;
- }
-
- /* TileWidth menu */
- case SUBMENU_TILEWIDTH:
- {
- if (!td) break;
-
- /* Save old */
- old_win = active;
-
- /* Activate */
- activate(td->w);
-
- /* Analyse value */
- td->tile_wid = menu_tilewidth_values[selection];
-
- /* Apply and Verify */
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- /* Restore */
- activate(old_win);
-
- break;
- }
-
- /* TileHeight menu */
- case SUBMENU_TILEHEIGHT:
- {
- if (!td) break;
-
- /* Save old */
- old_win = active;
-
- /* Activate */
- activate(td->w);
-
- /* Analyse value */
- td->tile_hgt = menu_tileheight_values[selection];
-
- /* Apply and Verify */
- term_data_check_size(td);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- /* Restore */
- activate(old_win);
-
- break;
- }
- }
-
-
- /* Clean the menu */
- HiliteMenu(0);
-}
-
-
-/*
- * Check for extra required parameters -- From "Maarten Hazewinkel"
- */
-static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
-{
- OSErr aeError;
- DescType returnedType;
- Size actualSize;
-
- aeError = AEGetAttributePtr(
- theAppleEvent, keyMissedKeywordAttr, typeWildCard,
- &returnedType, NULL, 0, &actualSize);
-
- if (aeError == errAEDescNotFound) return (noErr);
-
- if (aeError == noErr) return (errAEParamMissed);
-
- return (aeError);
-}
-
-
-/*
- * Apple Event Handler -- Open Application
- */
-static OSErr AEH_Start(const AppleEvent *theAppleEvent, AppleEvent *reply,
- SInt32 handlerRefCon)
-{
- return (CheckRequiredAEParams(theAppleEvent));
-}
-
-
-/*
- * Apple Event Handler -- Quit Application
- */
-static OSErr AEH_Quit(const AppleEvent *theAppleEvent, AppleEvent *reply,
- SInt32 handlerRefCon)
-{
- /* Quit later */
- quit_when_ready = TRUE;
-
- /* Check arguments */
- return (CheckRequiredAEParams(theAppleEvent));
-}
-
-
-/*
- * Apple Event Handler -- Print Documents
- */
-static OSErr AEH_Print(const AppleEvent *theAppleEvent, AppleEvent *reply,
- SInt32 handlerRefCon)
-{
- return (errAEEventNotHandled);
-}
-
-
-/*
- * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
- *
- * The old method of opening savefiles from the finder does not work
- * on the Power Macintosh, because CountAppFiles and GetAppFiles,
- * used to return information about the selected document files when
- * an application is launched, are part of the Segment Loader, which
- * is not present in the RISC OS due to the new memory architecture.
- *
- * The "correct" way to do this is with AppleEvents. The following
- * code is modeled on the "Getting Files Selected from the Finder"
- * snippet from Think Reference 2.0. (The prior sentence could read
- * "shamelessly swiped & hacked")
- */
-static OSErr AEH_Open(const AppleEvent *theAppleEvent, AppleEvent* reply,
- SInt32 handlerRefCon)
-{
- FSSpec myFSS;
- AEDescList docList;
- OSErr err;
- Size actualSize;
- AEKeyword keywd;
- DescType returnedType;
- char msg[128];
- FInfo myFileInfo;
-
- /* Put the direct parameter (a descriptor list) into a docList */
- err = AEGetParamDesc(
- theAppleEvent, keyDirectObject, typeAEList, &docList);
- if (err) return err;
-
- /*
- * We ignore the validity check, because we trust the FInder, and we only
- * allow one savefile to be opened, so we ignore the depth of the list.
- */
- err = AEGetNthPtr(
- &docList, 1L, typeFSS, &keywd, &returnedType,
- (Ptr) & myFSS, sizeof(myFSS), &actualSize);
- if (err) return err;
-
- /* Only needed to check savefile type below */
- err = FSpGetFInfo(&myFSS, &myFileInfo);
- if (err)
- {
- strnfmt(msg, 128, "Argh! FSpGetFInfo failed with code %d", err);
- mac_warning(msg);
- return err;
- }
-
- /* Ignore non 'SAVE' files */
- if (myFileInfo.fdType != 'SAVE') return noErr;
-
-#ifdef MACH_O_CARBON
-
- /* Extract a file name */
- (void)spec_to_path(&myFSS, savefile, sizeof(savefile));
-
-#else
-
- /* XXX XXX XXX Extract a file name */
- PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
- pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);
-
- /* Convert the string */
- ptocstr((StringPtr)savefile);
-
-#endif /* MACH_O_CARBON */
-
- /* Delay actual open */
- open_when_ready = TRUE;
-
- /* Dispose */
- err = AEDisposeDesc(&docList);
-
- /* Success */
- return noErr;
-}
-
-
-/*
- * Handle quit_when_ready, by Peter Ammon,
- * slightly modified to check inkey_flag.
- */
-static void quit_calmly(void)
-{
- /* Quit immediately if game's not started */
- if (!game_in_progress || !character_generated) quit(NULL);
-
- /* Save the game and Quit (if it's safe) */
- if (inkey_flag)
- {
- /* Hack -- Forget messages */
- msg_flag = FALSE;
-
- /* Save the game */
- do_cmd_save_game();
-
- /* Quit */
- quit(NULL);
- }
-
- /* Wait until inkey_flag is set */
-}
-
-
-/*
- * Macintosh modifiers (event.modifier & ccc):
- * cmdKey, optionKey, shiftKey, alphaLock, controlKey
- *
- *
- * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
- *
- * Return:36
- * Delete:51
- *
- * Period:65
- * Star:67
- * Plus:69
- * Clear:71
- * Slash:75
- * Enter:76
- * Minus:78
- * Equal:81
- * 0-7:82-89
- * 8-9:91-92
- *
- * backslash/vertical bar (Japanese keyboard):93
- *
- * F5: 96
- * F6: 97
- * F7: 98
- * F3:99
- * F8:100
- * F10:101
- * F11:103
- * F13:105
- * F14:107
- * F9:109
- * F12:111
- * F15:113
- * Help:114
- * Home:115
- * PgUp:116
- * Del:117
- * F4: 118
- * End:119
- * F2:120
- * PgDn:121
- * F1:122
- * Lt:123
- * Rt:124
- * Dn:125
- * Up:126
- */
-
-
-/*
- * Check for Events, return TRUE if we process any
- *
- * Now it really waits for events if wait set to true, to prevent
- * undesirable monopoly of CPU. The side-effect is that you cannot do
- * while (CheckEvents(TRUE)); without discretion.
- */
-static bool_ CheckEvents(bool_ wait)
-{
- EventRecord event;
-
- WindowPtr w;
-
- Rect r;
-
- UInt32 sleep_ticks;
-
- int ch, ck;
-
- int mc, ms, mo, mx;
-
- int i;
-
- term_data *td = NULL;
-
-
- /*
- * With the wait mode blocking for available event / timeout,
- * the non-wait mode should actually call WaitNextEvent,
- * because of those event draining loops. Or we had to
- * implement yet another mode.
- */
-
- /* Handles the quit_when_ready flag */
- if (quit_when_ready) quit_calmly();
-
- /* Blocking call to WaitNextEvent - should use MAX_INT XXX XXX */
- if (wait) sleep_ticks = 0x7FFFFFFFL;
-
- /* Non-blocking */
- else sleep_ticks = 0L;
-
- /* Get an event (or null) */
- WaitNextEvent(everyEvent, &event, sleep_ticks, nil);
-
- /* Hack -- Nothing is ready yet */
- if (event.what == nullEvent) return (FALSE);
-
-
- /* Analyze the event */
- switch (event.what)
- {
-
- case updateEvt:
- {
- /* Extract the window */
- w = (WindowPtr)event.message;
-
- /* Find the window */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Skip dead windows */
- if (!data[i].t) continue;
-
- /* Notice matches */
- if (data[i].w == w) td = &data[i];
- }
-
- /* Hack XXX XXX XXX */
- BeginUpdate(w);
- EndUpdate(w);
-
- /* Redraw the window */
- if (td) term_data_redraw(td);
-
- break;
- }
-
- case keyDown:
- case autoKey:
- {
- /* Extract some modifiers */
- mc = (event.modifiers & controlKey) ? TRUE : FALSE;
- ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
- mo = (event.modifiers & optionKey) ? TRUE : FALSE;
- mx = (event.modifiers & cmdKey) ? TRUE : FALSE;
-
- /* Keypress: (only "valid" if ck < 96) */
- ch = (event.message & charCodeMask) & 255;
-
- /* Keycode: see table above */
- ck = ((event.message & keyCodeMask) >> 8) & 255;
-
- /* Command + "normal key" -> menu action */
- if (mx && (ck < 64))
- {
-#ifdef MENU_SHORTCUTS
- /* Hack -- Prepare the menus */
- setup_menus();
-
- /* Run the Menu-Handler */
- menu(MenuKey(ch));
-
- /* Turn off the menus */
- HiliteMenu(0);
-
- /* Done */
- break;
-#else
- /* Begin special trigger */
- Term_keypress(31);
-
- /* Send some modifier keys */
- if (mc) Term_keypress('C');
- if (ms) Term_keypress('S');
- if (mo) Term_keypress('O');
- if (mx) Term_keypress('X');
-
- /* Enqueue the keypress */
- Term_keypress(ch);
-
- /* Terminate the trigger */
- Term_keypress(13);
-#endif
- }
-
- /* Hide the mouse pointer */
- ObscureCursor();
-
- /* Normal key -> simple keypress */
- if ((ck < 64) || (ck == 93))
- {
- /* Enqueue the keypress */
- 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');
-
- /* Send the "ascii" keypress */
- Term_keypress(ch);
-
- /* Terminate the trigger */
- Term_keypress(13);
- }
-
- /* Bizarre key -> encoded keypress */
- else if (ck <= 127)
- {
- /* Begin special trigger */
- Term_keypress(31);
-
- /* Send some modifier keys */
- if (mc) Term_keypress('C');
- if (ms) Term_keypress('S');
- 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);
- }
-
- break;
- }
-
- case mouseDown:
- {
- int code;
-
- /* Analyze click location */
- code = FindWindow(event.where, &w);
-
- /* Find the window */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Skip dead windows */
- if (!data[i].t) continue;
-
- /* Notice matches */
- if (data[i].w == w) td = &data[i];
- }
-
- /* Analyze */
- switch (code)
- {
- case inMenuBar:
- {
- setup_menus();
- menu(MenuSelect(event.where));
- HiliteMenu(0);
- break;
- }
-
- case inDrag:
- {
- WindowPtr old_win;
- BitMap tBitMap;
- Rect pRect;
-
- r = GetQDGlobalsScreenBits(&tBitMap)->bounds;
- r.top += 20; /* GetMBarHeight() XXX XXX XXX */
- InsetRect(&r, 4, 4);
- DragWindow(w, event.where, &r);
-
- /* Oops */
- if (!td) break;
-
- /* Save */
- old_win = active;
-
- /* Activate */
- activate(td->w);
-
- /* Analyze */
- GetWindowBounds(
- (WindowRef)td->w,
- kWindowContentRgn,
- &pRect);
- td->r.left = pRect.left;
- td->r.top = pRect.top;
-
- /* Apply and Verify */
- term_data_check_size(td);
-
- /* Restore */
- activate(old_win);
-
- break;
- }
-
- case inGoAway:
- {
- /* Oops */
- if (!td) break;
-
- /* Track the go-away box */
- if (TrackGoAway(w, event.where))
- {
- /* Not Mapped */
- td->mapped = FALSE;
-
- /* Not Mapped */
- td->t->mapped_flag = FALSE;
-
- /* Hide the window */
- TransitionWindow(td->w,
- kWindowZoomTransitionEffect,
- kWindowHideTransitionAction,
- NULL);
- }
-
- break;
- }
-
- case inGrow:
- {
- int x, y;
-
- Rect nr;
-
- term *old = Term;
-
- /* Oops */
- if (!td) break;
-
-#ifndef ALLOW_BIG_SCREEN
-
- /* Minimum and maximum sizes */
- r.left = 20 * td->tile_wid + td->size_ow1;
- r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1;
- r.top = 1 * td->tile_hgt + td->size_oh1;
- r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;
-
- /* Grow the rectangle */
- if (!ResizeWindow(w, event.where, &r, NULL)) break;
-#else
-
- /* Grow the rectangle */
- if (!ResizeWindow(w, event.where, NULL, NULL)) break;
-
-#endif /* !ALLOW_BIG_SCREEN */
-
-
- /* Obtain geometry of resized window */
- GetWindowBounds(w, kWindowContentRgn, &nr);
-
- /* Extract the new size in pixels */
- y = nr.bottom - nr.top - td->size_oh1 - td->size_oh2;
- x = nr.right - nr.left - td->size_ow1 - td->size_ow2;
-
- /* Extract a "close" approximation */
- td->rows = y / td->tile_hgt;
- td->cols = x / td->tile_wid;
-
- /* Apply and Verify */
- term_data_check_size(td);
-
- /* Activate */
- Term_activate(td->t);
-
- /* Hack -- Resize the term */
- Term_resize(td->cols, td->rows);
-
- /* Resize and Redraw */
- term_data_resize(td);
- term_data_redraw(td);
-
- /* Restore */
- Term_activate(old);
-
- break;
- }
-
- case inContent:
- {
- SelectWindow(w);
-
- break;
- }
- }
-
- break;
- }
-
- /* OS Event -- From "Maarten Hazewinkel" */
- case osEvt:
- {
- switch ((event.message >> 24) & 0x000000FF)
- {
- case suspendResumeMessage:
-
- /* Resuming: activate the front window */
- if (event.message & resumeFlag)
- {
- Cursor tempCursor;
- SetPort(GetWindowPort(FrontWindow()));
- SetCursor(GetQDGlobalsArrow(&tempCursor));
- }
-
- /* Suspend: deactivate the front window */
- else
- {
- /* Nothing */
- }
-
- break;
- }
-
- break;
- }
-
- /* From "Steve Linberg" and "Maarten Hazewinkel" */
- case kHighLevelEvent:
- {
- /* Process apple events */
- (void)AEProcessAppleEvent(&event);
-
- /* Handle "quit_when_ready" */
- if (quit_when_ready)
- {
- /* Turn off the menus */
- HiliteMenu(0);
- }
-
- /* Handle "open_when_ready" */
- else if (open_when_ready)
- {
- handle_open_when_ready();
- }
-
- break;
- }
-
- }
-
-
- /* Something happened */
- return (TRUE);
-}
-
-
-/*** Some Hooks for various routines ***/
-
-
-/*
- * Mega-Hack -- emergency lifeboat
- */
-static void *lifeboat = NULL;
-
-
-/*
- * Hook to "release" memory
- */
-static void *hook_rnfree(void *v, size_t size)
-{
-
-#ifdef USE_MALLOC
-
- /* Alternative method */
- free(v);
-
-#else
-
- /* Dispose */
- DisposePtr(v);
-
-#endif
-
- /* Success */
- return (NULL);
-}
-
-/*
- * Hook to "allocate" memory
- */
-static void *hook_ralloc(size_t size)
-{
-
-#ifdef USE_MALLOC
-
- /* Make a new pointer */
- return (malloc(size));
-
-#else
-
- /* Make a new pointer */
- return (NewPtr(size));
-
-#endif
-
-}
-
-/*
- * Hook to handle "out of memory" errors
- */
-static void *hook_rpanic(size_t size)
-{
- /* void *mem = NULL; */
-
- /* Free the lifeboat */
- if (lifeboat)
- {
- /* Free the lifeboat */
- DisposePtr(lifeboat);
-
- /* Forget the lifeboat */
- lifeboat = NULL;
-
- /* Mega-Hack -- Warning */
- mac_warning("Running out of Memory!\rAbort this process now!");
-
- /* Mega-Hack -- Never leave this function */
- while (TRUE) CheckEvents(TRUE);
- }
-
- /* Mega-Hack -- Crash */
- return (NULL);
-}
-
-
-/*
- * Hook to tell the user something important
- */
-static void hook_plog(cptr str)
-{
- /* Warning message */
- mac_warning(str);
-}
-
-
-/*
- * Hook to tell the user something, and then quit
- */
-static void hook_quit(cptr str)
-{
- /* Warning if needed */
- if (str) mac_warning(str);
-
-#ifdef USE_ASYNC_SOUND
-
- /* Clean up sound support */
- cleanup_sound();
-
-#endif /* USE_ASYNC_SOUND */
-
- /* Dispose of graphic tiles */
- if (frameP)
- {
- /* Unlock */
- BenSWUnlockFrame(frameP);
-
- /* Dispose of the GWorld */
- DisposeGWorld(frameP->framePort);
-
- /* Dispose of the memory */
- DisposePtr((Ptr)frameP);
- }
-
- /* Write a preference file */
- save_pref_file();
-
- /* All done */
- ExitToShell();
-}
-
-
-/*
- * Hook to tell the user something, and then crash
- */
-static void hook_core(cptr str)
-{
- /* XXX Use the debugger */
- /* DebugStr(str); */
-
- /* Warning */
- if (str) mac_warning(str);
-
- /* Warn, then save player */
- mac_warning("Fatal error.\rI will now attempt to save and quit.");
-
- /* Attempt to save */
- if (!save_player()) mac_warning("Warning -- save failed!");
-
- /* Quit */
- quit(NULL);
-}
-
-
-
-/*** Main program ***/
-
-
-/*
- * Init some stuff
- *
- * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
- * "Macintosh Save Bug" by using "absolute" path names, since on
- * System 7 machines anyway, the "current working directory" often
- * "changes" due to background processes, invalidating any "relative"
- * path names. Note that the Macintosh is limited to 255 character
- * path names, so be careful about deeply embedded directories...
- *
- * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
- * "missing lib folder bug" by allowing the user to help find the
- * "lib" folder by hand if the "application folder" code fails...
- *
- *
- * The problem description above no longer applies, but I left it here,
- * modified for Carbon, to allow the game proceeds when a user doesn't
- * placed the Angband binary and the lib folder in the same place for
- * whatever reasons. -- pelpel
- */
-static void init_stuff(void)
-{
- Rect r;
- BitMap tBitMap;
- Rect screenRect;
- Point topleft;
-
- char path[1024];
-
- OSErr err = noErr;
- NavDialogOptions dialogOptions;
- FSSpec theFolderSpec;
- NavReplyRecord theReply;
-
-
- /* Fake rectangle */
- r.left = 0;
- r.top = 0;
- r.right = 344;
- r.bottom = 188;
-
- /* Center it */
- screenRect = GetQDGlobalsScreenBits(&tBitMap)->bounds;
- center_rect(&r, &screenRect);
-
- /* Extract corner */
- topleft.v = r.top;
- topleft.h = r.left;
-
- /* Default to the "lib" folder with the application */
-#ifdef MACH_O_CARBON
- if (locate_lib(path, sizeof(path)) == NULL) quit(NULL);
-#else
- refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
-#endif
-
-
- /* Check until done */
- while (1)
- {
- /* Prepare the paths */
- init_file_paths(path);
-
- /* Build the filename */
- path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");
-
- /* Attempt to open and close that file */
- if (0 == fd_close(fd_open(path, O_RDONLY))) break;
-
- /* Warning */
- plog_fmt("Unable to open the '%s' file.", path);
-
- /* Warning */
- plog("The Angband 'lib' folder is probably missing or misplaced.");
-
- /* Ask the user to choose the lib folder */
- err = NavGetDefaultDialogOptions(&dialogOptions);
-
- /* Paranoia */
- if (err != noErr) quit(NULL);
-
- /* Set default location option */
- dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
-
- /* Clear preview option */
- dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);
-
- /* Forbit selection of multiple files */
- dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);
-
- /* Display location */
- dialogOptions.location = topleft;
-
- /* Set the message for the missing folder XXX XXX */
- strcpy(dialogOptions.message + 1, "Please select the \"lib\" folder");
- dialogOptions.message[0] = strlen(dialogOptions.message + 1);
-
- /* Wait for the user to choose a folder */
- err = NavChooseFolder(
- nil, &theReply, &dialogOptions, nil, nil, nil);
-
- /* Assume the player doesn't want to go on */
- if ((err != noErr) || !theReply.validRecord) quit(NULL);
-
- /* Retrieve FSSpec from the reply */
- {
- AEKeyword theKeyword;
- DescType actualType;
- Size actualSize;
-
- /* Get a pointer to selected folder */
- err = AEGetNthPtr(
- &(theReply.selection), 1, typeFSS, &theKeyword,
- &actualType, &theFolderSpec, sizeof(FSSpec), &actualSize);
-
- /* Paranoia */
- if (err != noErr) quit(NULL);
- }
-
- /* Free navitagor reply */
- err = NavDisposeReply(&theReply);
-
- /* Paranoia */
- if (err != noErr) quit(NULL);
-
- /* Extract textual file name for given file */
-#ifdef MACH_O_CARBON
- if (spec_to_path(&theFolderSpec, path, sizeof(path)) != noErr)
- {
- quit(NULL);
- }
-#else /* MACH_O_CARBON */
-refnum_to_name(
- path,
- theFolderSpec.parID,
- theFolderSpec.vRefNum,
- (char *)theFolderSpec.name);
-#endif /* MACH_O_CARBON */
- }
-}
-
-
-/*
- * Macintosh Main loop
- */
-int main(void)
-{
- int i;
- long response;
- OSStatus err;
- EventRecord tempEvent;
- UInt32 numberOfMasters = 10;
-
- /* Get more Masters -- it is not recommended by Apple, should go away */
- MoreMasterPointers(numberOfMasters);
-
- /* Check for existence of Carbon */
- err = Gestalt(gestaltCarbonVersion, &response);
-
- if (err != noErr) quit("This program requires Carbon API");
-
- /* See if we are running on Aqua */
- err = Gestalt(gestaltMenuMgrAttr, &response);
-
- /* Cache the result */
- if ((err == noErr) &&
- (response & gestaltMenuMgrAquaLayoutMask)) is_aqua = TRUE;
-
- /*
- * Remember Mac OS version, in case we have to cope with version-specific
- * problems
- */
- (void)Gestalt(gestaltSystemVersion, &mac_os_version);
-
-
- /* Set up the Macintosh */
- InitCursor();
-
- /* Flush events */
- FlushEvents(everyEvent, 0);
-
- /* Flush events some more (?) */
- if (EventAvail(everyEvent, &tempEvent)) FlushEvents(everyEvent, 0);
-
-
- /* Install the start event hook (ignore error codes) */
- AEInstallEventHandler(
- kCoreEventClass,
- kAEOpenApplication,
- NewAEEventHandlerUPP(AEH_Start),
- 0L,
- FALSE);
-
- /* Install the quit event hook (ignore error codes) */
- AEInstallEventHandler(
- kCoreEventClass,
- kAEQuitApplication,
- NewAEEventHandlerUPP(AEH_Quit),
- 0L,
- FALSE);
-
- /* Install the print event hook (ignore error codes) */
- AEInstallEventHandler(
- kCoreEventClass,
- kAEPrintDocuments,
- NewAEEventHandlerUPP(AEH_Print),
- 0L,
- FALSE);
-
- /* Install the open event hook (ignore error codes) */
- AEInstallEventHandler(
- kCoreEventClass,
- kAEOpenDocuments,
- NewAEEventHandlerUPP(AEH_Open),
- 0L,
- FALSE);
-
-
-#ifndef MACH_O_CARBON
-
- /* Find the current application */
- SetupAppDir();
-
-#endif /* !MACH_O_CARBON */
-
- /* Mark ourself as the file creator */
- _fcreator = ANGBAND_CREATOR;
-
- /* Default to saving a "text" file */
- _ftype = 'TEXT';
-
-
- /* Hook in some "z-virt.c" hooks */
- rnfree_aux = hook_rnfree;
- ralloc_aux = hook_ralloc;
- rpanic_aux = hook_rpanic;
-
- /* Hooks in some "z-util.c" hooks */
- plog_aux = hook_plog;
- quit_aux = hook_quit;
- core_aux = hook_core;
-
-
- /* Initialize colors */
- for (i = 0; i < 256; i++)
- {
- u16b rv, gv, bv;
-
- /* Extract the R,G,B data */
- rv = angband_color_table[i][1];
- gv = angband_color_table[i][2];
- bv = angband_color_table[i][3];
-
- /* Save the actual color */
- color_info[i].red = (rv | (rv << 8));
- color_info[i].green = (gv | (gv << 8));
- color_info[i].blue = (bv | (bv << 8));
- }
-
-
- /* Show the "watch" cursor */
- SetCursor(*(GetCursor(watchCursor)));
-
- /* Prepare the menubar */
- init_menubar();
-
- /* Prepare the windows */
- init_windows();
-
- /* Hack -- process all events */
- while (CheckEvents(FALSE)) /* loop */;
-
- /* Reset the cursor */
- {
- Cursor tempCursor;
-
- SetCursor(GetQDGlobalsArrow(&tempCursor));
- }
-
- /* Mega-Hack -- Allocate a "lifeboat" */
- lifeboat = NewPtr(16384);
-
-#ifdef USE_QT_SOUND
-
- /* Load sound effect resources */
- load_sounds();
-
-#endif /* USE_QT_SOUND */
-
- /* Note the "system" */
- ANGBAND_SYS = "mac";
-
- if (check_create_user_dir() == FALSE)
- quit("Cannot create directory " PRIVATE_USER_PATH);
-
- /* Initialize */
- init_stuff();
-
- /* Initialize */
- init_angband();
-
-
- /* Hack -- process all events */
- while (CheckEvents(FALSE)) /* loop */;
-
-
- /* We are now initialized */
- initialized = TRUE;
-
-
- /* Handle "open_when_ready" */
- handle_open_when_ready();
-
- /* Game is in progress */
- game_in_progress = 1;
-
- /* Wait for keypress */
- pause_line(23);
-
- /* flush input - Warning: without this, _system_ would hang */
- flush();
-
- /* Play the game - note the value of the argument */
- play_game(FALSE);
-
- /* Quit */
- quit(NULL);
-
- /* Since it's a int function */
- return (0);
-}
-
-#endif /* MACINTOSH || MACH_O_CARBON */
-
diff --git a/src/main-gcu.c b/src/main-gcu.c
index 4e259a65..3e1d1ff0 100644
--- a/src/main-gcu.c
+++ b/src/main-gcu.c
@@ -38,8 +38,8 @@
* Consider the use of "savetty()" and "resetty()". XXX XXX XXX
*/
-
-#include "angband.h"
+#include "util.h"
+#include "variable.h"
#ifdef USE_GCU
@@ -82,7 +82,7 @@
# if defined(_POSIX_VERSION)
# define USE_TPOSIX
# else
-# if defined(USG) || defined(linux) || defined(SOLARIS)
+# if defined(linux)
# define USE_TERMIO
# else
# define USE_TCHARS
@@ -122,11 +122,6 @@
#include <unistd.h>
#include <dirent.h>
-/* /me pffts Solaris */
-#ifndef NAME_MAX
-#define NAME_MAX _POSIX_NAME_MAX
-#endif
-
/*
@@ -561,60 +556,6 @@ static void Term_nuke_gcu(term *t)
}
-
-
-#ifdef USE_GETCH
-
-/*
- * Process events, with optional wait
- */
-static errr Term_xtra_gcu_event(int v)
-{
- int i, k;
-
- /* Wait */
- if (v)
- {
- /* Paranoia -- Wait for it */
- nodelay(stdscr, FALSE);
-
- /* Get a keypress */
- i = getch();
-
- /* Mega-Hack -- allow graceful "suspend" */
- for (k = 0; (k < 10) && (i == ERR); k++) i = getch();
-
- /* Broken input is special */
- if (i == ERR) abort();
- if (i == EOF) abort();
- }
-
- /* Do not wait */
- else
- {
- /* Do not wait for it */
- nodelay(stdscr, TRUE);
-
- /* Check for keypresses */
- i = getch();
-
- /* Wait for it next time */
- nodelay(stdscr, FALSE);
-
- /* None ready */
- if (i == ERR) return (1);
- if (i == EOF) return (1);
- }
-
- /* Enqueue the keypress */
- Term_keypress(i);
-
- /* Success */
- return (0);
-}
-
-#else /* USE_GETCH */
-
/*
* Process events (with optional wait)
*/
@@ -663,7 +604,6 @@ static errr Term_xtra_gcu_event(int v)
return (0);
}
-#endif /* USE_GETCH */
/*
* React to changes
@@ -721,14 +661,6 @@ static errr Term_xtra_gcu(int n, int v)
(void)wrefresh(td->win);
return (0);
-#ifdef USE_CURS_SET
-
- /* Change the cursor visibility */
- case TERM_XTRA_SHAPE:
- curs_set(v);
- return (0);
-
-#endif
/* Suspend/Resume curses */
case TERM_XTRA_ALIVE:
@@ -743,53 +675,6 @@ static errr Term_xtra_gcu(int n, int v)
while (!Term_xtra_gcu_event(FALSE));
return (0);
- /* Delay */
- case TERM_XTRA_DELAY:
- usleep(1000 * v);
- return (0);
-
- /* Get Delay of some milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- int ret;
- struct timeval tv;
-
- ret = gettimeofday(&tv, NULL);
- Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- return ret;
- }
-
- /* Subdirectory scan */
- case TERM_XTRA_SCANSUBDIR:
- {
- DIR *directory;
- struct dirent *entry;
-
- scansubdir_max = 0;
-
- directory = opendir(scansubdir_dir);
- if (!directory)
- return 1;
-
- while ((entry = readdir(directory)))
- {
- char file[PATH_MAX + NAME_MAX + 2];
- struct stat filedata;
-
- file[PATH_MAX + NAME_MAX] = 0;
- strncpy(file, scansubdir_dir, PATH_MAX);
- strncat(file, "/", 2);
- strncat(file, entry->d_name, NAME_MAX);
- if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] = string_make(entry->d_name);
- ++scansubdir_max;
- }
- }
- }
-
/* React to events */
case TERM_XTRA_REACT:
Term_xtra_gcu_react();
@@ -851,7 +736,7 @@ static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
{
term_data *td = (term_data *)(Term->data);
- int i, pic;
+ int i;
#ifdef A_COLOR
/* Set the color */
@@ -864,41 +749,6 @@ static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
/* Draw each character */
for (i = 0; i < n; i++)
{
-#ifdef USE_GRAPHICS
- /* Special character */
- if (use_graphics && (s[i] & 0x80))
- {
- /* Determine picture to use */
- switch (s[i] & 0x7F)
- {
-
-#ifdef ACS_CKBOARD
- /* Wall */
- case '#':
- pic = ACS_CKBOARD;
- break;
-#endif /* ACS_CKBOARD */
-
-#ifdef ACS_BOARD
- /* Mineral vein */
- case '%':
- pic = ACS_BOARD;
- break;
-#endif /* ACS_BOARD */
-
- /* XXX */
- default:
- pic = '?';
- break;
- }
-
- /* Draw the picture */
- waddch(td->win, pic);
-
- /* Next character */
- continue;
- }
-#endif
/* Draw a normal character */
waddch(td->win, (byte)s[i]);
@@ -995,7 +845,7 @@ errr init_gcu(int argc, char **argv)
continue;
}
- plog_fmt("Ignoring option: %s", argv[i]);
+ fprintf(stderr, "Ignoring option: %s", argv[i]);
}
@@ -1003,17 +853,11 @@ errr init_gcu(int argc, char **argv)
keymap_norm_prepare();
-#if defined(USG)
- /* Initialize for USG Unix */
- if (initscr() == NULL) return ( -1);
-#else
/* Initialize for other systems */
if (initscr() == (WINDOW*)ERR) return ( -1);
-#endif
/* Activate hooks */
quit_aux = hook_quit;
- core_aux = hook_quit;
/* Require standard size screen */
if ((LINES < 24) || (COLS < 80))
@@ -1022,12 +866,6 @@ errr init_gcu(int argc, char **argv)
}
-#ifdef USE_GRAPHICS
-
- /* Set graphics flag */
- use_graphics = arg_graphics;
-
-#endif
#ifdef A_COLOR
@@ -1106,12 +944,6 @@ errr init_gcu(int argc, char **argv)
/*** Low level preparation ***/
-#ifdef USE_GETCH
-
- /* Paranoia -- Assume no waiting */
- nodelay(stdscr, FALSE);
-
-#endif
/* Prepare */
raw();
diff --git a/src/main-gtk2.c b/src/main-gtk2.c
index 102a8b7b..bdf7f6a4 100644
--- a/src/main-gtk2.c
+++ b/src/main-gtk2.c
@@ -30,28 +30,15 @@
* and reorganised the file a bit.
*/
-#include "angband.h"
+#include "files.h"
+#include "util.h"
+#include "variable.h"
/*
* Activate variant-specific features
- *
- * Angband 2.9.3 and close variants don't require any.
- *
- * Angband 2.9.4 alpha and later removed the short-lived
- * can_save flag, so please #define can_save TRUE, or remove
- * all the references to it. They also changed long-lived
- * z-virt macro names. Find C_FREE/C_KILL and replace them
- * with FREE/KILL, which takes one pointer parameter.
- *
- * ZAngband has its own enhanced main-gtk.c as mentioned above, and
- * you *should* use it :-)
- *
*/
-#define USE_DOUBLE_TILES /* Mogami's bigtile patch */
-
-
#ifdef USE_GTK2
/* Force ANSI standard */
@@ -66,11 +53,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
-
-/* /me pffts Solaris */
-#ifndef NAME_MAX
-#define NAME_MAX _POSIX_NAME_MAX
-#endif
+#include <assert.h>
/*
@@ -93,22 +76,6 @@
* back to the term_data structure.
*/
-#ifdef USE_GRAPHICS
-
-/*
- * Since GdkRGB doesn't provide us some useful functions...
- */
-typedef struct GdkRGBImage GdkRGBImage;
-
-struct GdkRGBImage
-{
- gint width;
- gint height;
- gint ref_count;
- guchar *image;
-};
-
-#endif /* USE_GRAPHICS */
/*
@@ -135,18 +102,8 @@ struct term_data
int rows;
int cols;
-#ifdef USE_GRAPHICS
-
- int tile_wid;
- int tile_hgt;
- GdkRGBImage *tiles;
- guint32 bg_pixel;
- GdkRGBImage *trans_buf;
-
-#endif /* USE_GRAPHICS */
-
- cptr name;
+ char *name;
};
@@ -242,42 +199,6 @@ static cptr get_default_font(int term)
#define can_save TRUE
-/*
- * The standard game uses this to implement lighting effects
- * for 16x16 tiles in cave.c...
- *
- * Because of the way it is implemented in X11 ports,
- * we can set this to TRUE even if we are using the 8x8 tileset.
- */
-static bool_ use_transparency = TRUE;
-
-
-
-
-/**** Low level routines - memory allocation ****/
-
-/*
- * Hook to "release" memory
- */
-static vptr hook_rnfree(vptr v, huge size)
-{
- /* Dispose */
- g_free(v);
-
- /* Success */
- return (NULL);
-}
-
-
-/*
- * Hook to "allocate" memory
- */
-static vptr hook_ralloc(huge size)
-{
- /* Make a new pointer */
- return (g_malloc(size));
-}
-
/**** Low level routines - colours and graphics ****/
@@ -330,1799 +251,6 @@ static void term_data_set_fg(term_data *td, byte attr)
}
-#ifdef USE_GRAPHICS
-
-/*
- * Graphics mode selector - current setting and requested value
- */
-#define GRAF_MODE_NONE 0
-#define GRAF_MODE_OLD 1
-#define GRAF_MODE_NEW 2
-
-static int graf_mode = GRAF_MODE_NONE;
-static int graf_mode_request = GRAF_MODE_NONE;
-
-/*
- * Use smooth rescaling?
- */
-static bool_ smooth_rescaling = TRUE;
-static bool_ smooth_rescaling_request = TRUE;
-
-/*
- * Dithering
- */
-static GdkRgbDither dith_mode = GDK_RGB_DITHER_NORMAL;
-
-/*
- * Need to reload and resize tiles when fonts are changed.
- */
-static bool_ resize_request = FALSE;
-
-/*
- * Numbers of columns and rows in current tileset
- * calculated and set by the tile loading code in graf_init()
- * and used by Term_pict_gtk()
- */
-static int tile_rows;
-static int tile_cols;
-
-
-/*
- * Directory name(s)
- */
-static cptr ANGBAND_DIR_XTRA_GRAF;
-
-
-/*
- * Be nice to old graphics hardwares -- using GdkRGB.
- *
- * We don't have colour allocation failure any longer this way,
- * even with 8bpp X servers. Gimp *does* work with 8bpp, why not Angband?
- *
- * Initialisation (before any widgets are created)
- * gdk_rgb_init();
- * gtk_widget_set_default_colormap (gdk_rgb_get_cmap());
- * gtk_widget_set_default_visual (gdk_rgb_get_visual());
- *
- * Setting fg/bg colours
- * void gdk_rgb_gc_set_foreground(GdkGC *gc, guint32 rgb);
- * void gdk_rgb_gc_set_background(GdkGC *gc, guint32 rgb);
- * where rgb is 0xRRGGBB.
- *
- * Drawing rgb images
- * void gdk_draw_rgb_image(
- * GdkDrawable *drawable,
- * GdkGC *gc,
- * gint x, gint y,
- * gint width, gint height,
- * GdkRgbDither dith,
- * guchar *rgb_buf,
- * gint rowstride);
- *
- * dith:
- * GDK_RGB_DITHER_NORMAL : dither if 8bpp or below
- * GDK_RGB_DITHER_MAX : dither if 16bpp or below.
- *
- * for 0 <= i < width and 0 <= j < height,
- * the pixel (x + i, y + j) is colored with
- * red value rgb_buf[j * rowstride + i * 3],
- * green value rgb_buf[j * rowstride + i * 3 + 1], and
- * blue value rgb_buf[j * rowstride + i * 3 + 2].
- */
-
-/*
- * gdk_image compatibility functions - should be part of gdk, IMHO.
- */
-
-/*
- * Create GdkRGBImage of width * height and return pointer
- * to it. Returns NULL on failure
- */
-static GdkRGBImage *gdk_rgb_image_new(
- gint width,
- gint height)
-{
- GdkRGBImage *result;
-
- /* Allocate a struct */
- result = g_new(GdkRGBImage, 1);
-
- /* Oops */
- if (result == NULL) return (NULL);
-
- /* Allocate buffer */
- result->image = g_new0(guchar, width * height * 3);
-
- /* Oops */
- if (result->image == NULL)
- {
- g_free(result);
- return (NULL);
- }
-
- /* Initialise size fields */
- result->width = width;
- result->height = height;
-
- /* Initialise reference count */
- result->ref_count = 1;
-
- /* Success */
- return (result);
-}
-
-/*
- * Free a GdkRGBImage
- */
-static void gdk_rgb_image_destroy(
- GdkRGBImage *im)
-{
- /* Paranoia */
- if (im == NULL) return;
-
- /* Free the RGB buffer */
- g_free(im->image);
-
- /* Free the structure */
- g_free(im);
-}
-
-
-/*
- * Write RGB pixel of the format 0xRRGGBB to (x, y) in GdkRGBImage
- */
-static void gdk_rgb_image_put_pixel(
- GdkRGBImage *im,
- gint x,
- gint y,
- guint32 pixel)
-{
- guchar *rgbp;
-
- /* Paranoia */
- g_return_if_fail(im != NULL);
-
- /* Paranoia */
- if ((x < 0) || (x >= im->width)) return;
-
- /* Paranoia */
- if ((y < 0) || (y >= im->height)) return;
-
- /* Access RGB data */
- rgbp = &im->image[(y * im->width * 3) + (x * 3)];
-
- /* Red */
- *rgbp++ = (pixel >> 16) & 0xFF;
- /* Green */
- *rgbp++ = (pixel >> 8) & 0xFF;
- /* Blue */
- *rgbp = pixel & 0xFF;
-}
-
-
-/*
- * Returns RGB pixel (0xRRGGBB) at (x, y) in GdkRGBImage
- */
-static guint32 gdk_rgb_image_get_pixel(
- GdkRGBImage *im,
- gint x,
- gint y)
-{
- guchar *rgbp;
-
- /* Paranoia */
- if (im == NULL) return (0);
-
- /* Paranoia - returns black */
- if ((x < 0) || (x >= im->width)) return (0);
-
- /* Paranoia */
- if ((y < 0) || (y >= im->height)) return (0);
-
- /* Access RGB data */
- rgbp = &im->image[(y * im->width * 3) + (x * 3)];
-
- /* Return result */
- return ((rgbp[0] << 16) | (rgbp[1] << 8) | (rgbp[2]));
-}
-
-
-/*
- * Since gdk_draw_rgb_image is a bit harder to use than it's
- * GdkImage counterpart, I wrote a grue function that takes
- * exactly the same parameters as gdk_draw_image, with
- * the GdkImage parameter replaced with GdkRGBImage.
- */
-static void gdk_draw_rgb_image_2(
- GdkDrawable *drawable,
- GdkGC *gc,
- GdkRGBImage *image,
- gint xsrc,
- gint ysrc,
- gint xdest,
- gint ydest,
- gint width,
- gint height)
-{
- /* Paranoia */
- g_return_if_fail(drawable != NULL);
- g_return_if_fail(image != NULL);
-
- /* Paranoia */
- if (xsrc < 0 || (xsrc + width - 1) >= image->width) return;
- if (ysrc < 0 || (ysrc + height - 1) >= image->height) return;
-
- /* Draw the image at (xdest, ydest), with dithering if bpp <= 8/16 */
- gdk_draw_rgb_image(
- drawable,
- gc,
- xdest,
- ydest,
- width,
- height,
- dith_mode,
- &image->image[(ysrc * image->width * 3) + (xsrc * 3)],
- image->width * 3);
-}
-
-
-/*
- * Code for smooth icon rescaling from Uwe Siems, Jan 2000
- *
- * XXX XXX Duplication of maid-x11.c, again. It doesn't do any colour
- * allocation, either.
- */
-
-/*
- * to save ourselves some labour, define a maximum expected icon width here:
- */
-#define MAX_ICON_WIDTH 32
-
-
-/*
- * Each pixel is kept in this structure during smooth rescaling
- * calculations, to make things a bit easier
- */
-typedef struct rgb_type rgb_type;
-
-struct rgb_type
-{
- guint32 red;
- guint32 green;
- guint32 blue;
-};
-
-/*
- * Because there are many occurences of this, and because
- * it's logical to do so...
- */
-#define pixel_to_rgb(pix, rgb_buf) \
-(rgb_buf)->red = ((pix) >> 16) & 0xFF; \
-(rgb_buf)->green = ((pix) >> 8) & 0xFF; \
-(rgb_buf)->blue = (pix) & 0xFF
-
-
-/*
- * get_scaled_row reads a scan from the given GdkRGBImage, scales it smoothly
- * and returns the red, green and blue values in arrays.
- * The values in this arrays must be divided by a certain value that is
- * calculated in scale_icon.
- * x, y is the position, iw is the input width and ow the output width
- * scan must be sufficiently sized
- */
-static void get_scaled_row(
- GdkRGBImage *im,
- int x,
- int y,
- int iw,
- int ow,
- rgb_type *scan)
-{
- int xi, si, sifrac, ci, cifrac, add_whole, add_frac;
- guint32 pix;
- rgb_type prev;
- rgb_type next;
- bool_ get_next_pix;
-
- /* Unscaled */
- if (iw == ow)
- {
- for (xi = 0; xi < ow; xi++)
- {
- pix = gdk_rgb_image_get_pixel(im, x + xi, y);
- pixel_to_rgb(pix, &scan[xi]);
- }
- }
-
- /* Scaling by subsampling (grow) */
- else if (iw < ow)
- {
- iw--;
- ow--;
-
- /* read first pixel: */
- pix = gdk_rgb_image_get_pixel(im, x, y);
- pixel_to_rgb(pix, &next);
- prev = next;
-
- /* si and sifrac give the subsampling position: */
- si = x;
- sifrac = 0;
-
- /* get_next_pix tells us, that we need the next pixel */
- get_next_pix = TRUE;
-
- for (xi = 0; xi <= ow; xi++)
- {
- if (get_next_pix)
- {
- prev = next;
- if (xi < ow)
- {
- /* only get next pixel if in same icon */
- pix = gdk_rgb_image_get_pixel(im, si + 1, y);
- pixel_to_rgb(pix, &next);
- }
- }
-
- /* calculate subsampled color values: */
- /* division by ow occurs in scale_icon */
- scan[xi].red = prev.red * (ow - sifrac) + next.red * sifrac;
- scan[xi].green = prev.green * (ow - sifrac) + next.green * sifrac;
- scan[xi].blue = prev.blue * (ow - sifrac) + next.blue * sifrac;
-
- /* advance sampling position: */
- sifrac += iw;
- if (sifrac >= ow)
- {
- si++;
- sifrac -= ow;
- get_next_pix = TRUE;
- }
- else
- {
- get_next_pix = FALSE;
- }
-
- }
- }
-
- /* Scaling by averaging (shrink) */
- else
- {
- /* width of an output pixel in input pixels: */
- add_whole = iw / ow;
- add_frac = iw % ow;
-
- /* start position of the first output pixel: */
- si = x;
- sifrac = 0;
-
- /* get first input pixel: */
- pix = gdk_rgb_image_get_pixel(im, x, y);
- pixel_to_rgb(pix, &next);
-
- for (xi = 0; xi < ow; xi++)
- {
- /* find endpoint of the current output pixel: */
- ci = si + add_whole;
- cifrac = sifrac + add_frac;
- if (cifrac >= ow)
- {
- ci++;
- cifrac -= ow;
- }
-
- /* take fraction of current input pixel (starting segment): */
- scan[xi].red = next.red * (ow - sifrac);
- scan[xi].green = next.green * (ow - sifrac);
- scan[xi].blue = next.blue * (ow - sifrac);
- si++;
-
- /* add values for whole pixels: */
- while (si < ci)
- {
- rgb_type tmp_rgb;
-
- pix = gdk_rgb_image_get_pixel(im, si, y);
- pixel_to_rgb(pix, &tmp_rgb);
- scan[xi].red += tmp_rgb.red * ow;
- scan[xi].green += tmp_rgb.green * ow;
- scan[xi].blue += tmp_rgb.blue * ow;
- si++;
- }
-
- /* add fraction of current input pixel (ending segment): */
- if (xi < ow - 1)
- {
- /* only get next pixel if still in icon: */
- pix = gdk_rgb_image_get_pixel(im, si, y);
- pixel_to_rgb(pix, &next);
- }
-
- sifrac = cifrac;
- if (sifrac > 0)
- {
- scan[xi].red += next.red * sifrac;
- scan[xi].green += next.green * sifrac;
- scan[xi].blue += next.blue * sifrac;
- }
- }
- }
-}
-
-
-/*
- * put_rgb_scan takes arrays for red, green and blue and writes pixel values
- * according to this values in the GdkRGBImage-structure. w is the number of
- * pixels to write and div is the value by which all red/green/blue values
- * are divided first.
- */
-static void put_rgb_scan(
- GdkRGBImage *im,
- int x,
- int y,
- int w,
- int div,
- rgb_type *scan)
-{
- int xi;
- guint32 pix;
- guint32 adj = div / 2;
-
- for (xi = 0; xi < w; xi++)
- {
- byte r, g, b;
-
- /* un-factor the RGB values */
- r = (scan[xi].red + adj) / div;
- g = (scan[xi].green + adj) / div;
- b = (scan[xi].blue + adj) / div;
-
- /* Make a (virtual) 24-bit pixel */
- pix = (r << 16) | (g << 8) | (b);
-
- /* Draw it into image */
- gdk_rgb_image_put_pixel(im, x + xi, y, pix);
- }
-}
-
-
-/*
- * scale_icon transfers an area from GdkRGBImage im_in, locate (x1,y1) to
- * im_out, locate (x2, y2). Source size is (ix, iy) and destination size
- * is (ox, oy).
- *
- * It does this by getting icon scan line from get_scaled_scan and handling
- * them the same way as pixels are handled in get_scaled_scan.
- * This even allows icons to be scaled differently in horizontal and
- * vertical directions (eg. shrink horizontal, grow vertical).
- */
-static void scale_icon(
- GdkRGBImage *im_in,
- GdkRGBImage *im_out,
- int x1,
- int y1,
- int x2,
- int y2,
- int ix,
- int iy,
- int ox,
- int oy)
-{
- int div;
- int xi, yi, si, sifrac, ci, cifrac, add_whole, add_frac;
-
- /* buffers for pixel rows: */
- rgb_type prev[MAX_ICON_WIDTH];
- rgb_type next[MAX_ICON_WIDTH];
- rgb_type temp[MAX_ICON_WIDTH];
-
- bool_ get_next_row;
-
- /* get divider value for the horizontal scaling: */
- if (ix == ox)
- div = 1;
- else if (ix < ox)
- div = ox - 1;
- else
- div = ix;
-
- /* no scaling needed vertically: */
- if (iy == oy)
- {
- for (yi = 0; yi < oy; yi++)
- {
- get_scaled_row(im_in, x1, y1 + yi, ix, ox, temp);
- put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);
- }
- }
-
- /* scaling by subsampling (grow): */
- else if (iy < oy)
- {
- iy--;
- oy--;
- div *= oy;
-
- /* get first row: */
- get_scaled_row(im_in, x1, y1, ix, ox, next);
-
- /* si and sifrac give the subsampling position: */
- si = y1;
- sifrac = 0;
-
- /* get_next_row tells us, that we need the next row */
- get_next_row = TRUE;
- for (yi = 0; yi <= oy; yi++)
- {
- if (get_next_row)
- {
- for (xi = 0; xi < ox; xi++)
- {
- prev[xi] = next[xi];
- }
- if (yi < oy)
- {
- /* only get next row if in same icon */
- get_scaled_row(im_in, x1, si + 1, ix, ox, next);
- }
- }
-
- /* calculate subsampled color values: */
- /* division by oy occurs in put_rgb_scan */
- for (xi = 0; xi < ox; xi++)
- {
- temp[xi].red = (prev[xi].red * (oy - sifrac) +
- next[xi].red * sifrac);
- temp[xi].green = (prev[xi].green * (oy - sifrac) +
- next[xi].green * sifrac);
- temp[xi].blue = (prev[xi].blue * (oy - sifrac) +
- next[xi].blue * sifrac);
- }
-
- /* write row to output image: */
- put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);
-
- /* advance sampling position: */
- sifrac += iy;
- if (sifrac >= oy)
- {
- si++;
- sifrac -= oy;
- get_next_row = TRUE;
- }
- else
- {
- get_next_row = FALSE;
- }
-
- }
- }
-
- /* scaling by averaging (shrink) */
- else
- {
- div *= iy;
-
- /* height of a output row in input rows: */
- add_whole = iy / oy;
- add_frac = iy % oy;
-
- /* start position of the first output row: */
- si = y1;
- sifrac = 0;
-
- /* get first input row: */
- get_scaled_row(im_in, x1, y1, ix, ox, next);
- for (yi = 0; yi < oy; yi++)
- {
- /* find endpoint of the current output row: */
- ci = si + add_whole;
- cifrac = sifrac + add_frac;
- if (cifrac >= oy)
- {
- ci++;
- cifrac -= oy;
- }
-
- /* take fraction of current input row (starting segment): */
- for (xi = 0; xi < ox; xi++)
- {
- temp[xi].red = next[xi].red * (oy - sifrac);
- temp[xi].green = next[xi].green * (oy - sifrac);
- temp[xi].blue = next[xi].blue * (oy - sifrac);
- }
- si++;
-
- /* add values for whole pixels: */
- while (si < ci)
- {
- get_scaled_row(im_in, x1, si, ix, ox, next);
- for (xi = 0; xi < ox; xi++)
- {
- temp[xi].red += next[xi].red * oy;
- temp[xi].green += next[xi].green * oy;
- temp[xi].blue += next[xi].blue * oy;
- }
- si++;
- }
-
- /* add fraction of current input row (ending segment): */
- if (yi < oy - 1)
- {
- /* only get next row if still in icon: */
- get_scaled_row(im_in, x1, si, ix, ox, next);
- }
- sifrac = cifrac;
- for (xi = 0; xi < ox; xi++)
- {
- temp[xi].red += next[xi].red * sifrac;
- temp[xi].green += next[xi].green * sifrac;
- temp[xi].blue += next[xi].blue * sifrac;
- }
-
- /* write row to output image: */
- put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);
- }
- }
-}
-
-
-/*
- * Rescale icons using sort of anti-aliasing technique.
- */
-static GdkRGBImage *resize_tiles_smooth(
- GdkRGBImage *im,
- int ix,
- int iy,
- int ox,
- int oy)
-{
- int width1, height1, width2, height2;
- int x1, x2, y1, y2;
-
- GdkRGBImage *tmp;
-
- /* Original size */
- width1 = im->width;
- height1 = im->height;
-
- /* Rescaled size */
- width2 = ox * width1 / ix;
- height2 = oy * height1 / iy;
-
- /* Allocate GdkRGBImage for resized tiles */
- tmp = gdk_rgb_image_new(width2, height2);
-
- /* Oops */
- if (tmp == NULL) return (NULL);
-
- /* Scale each icon */
- for (y1 = 0, y2 = 0; (y1 < height1) && (y2 < height2); y1 += iy, y2 += oy)
- {
- for (x1 = 0, x2 = 0; (x1 < width1) && (x2 < width2); x1 += ix, x2 += ox)
- {
- scale_icon(im, tmp, x1, y1, x2, y2,
- ix, iy, ox, oy);
- }
- }
-
- return tmp;
-}
-
-
-/*
- * Steven Fuerst's tile resizing code
- * Taken from Z because I think the algorithm is cool.
- */
-
-/* 24-bit version - GdkRGB uses 24 bit RGB data internally */
-static void copy_pixels(
- int wid,
- int y,
- int offset,
- int *xoffsets,
- GdkRGBImage *old_image,
- GdkRGBImage *new_image)
-{
- int i;
-
- /* Get source and destination */
- byte *src = &old_image->image[offset * old_image->width * 3];
- byte *dst = &new_image->image[y * new_image->width * 3];
-
- /* Copy to the image */
- for (i = 0; i < wid; i++)
- {
- *dst++ = src[3 * xoffsets[i]];
- *dst++ = src[3 * xoffsets[i] + 1];
- *dst++ = src[3 * xoffsets[i] + 2];
- }
-}
-
-
-/*
- * Resize ix * iy pixel tiles in old to ox * oy pixels
- * and return a new GdkRGBImage containing the resized tiles
- */
-static GdkRGBImage *resize_tiles_fast(
- GdkRGBImage *old_image,
- int ix,
- int iy,
- int ox,
- int oy)
-{
- GdkRGBImage *new_image;
-
- int old_wid, old_hgt;
-
- int new_wid, new_hgt;
-
- int add, remainder, rem_tot, offset;
-
- int *xoffsets;
-
- int i;
-
-
- /* Get the size of the old image */
- old_wid = old_image->width;
- old_hgt = old_image->height;
-
- /* Calculate the size of the new image */
- new_wid = (old_wid / ix) * ox;
- new_hgt = (old_hgt / iy) * oy;
-
- /* Allocate a GdkRGBImage to store resized tiles */
- new_image = gdk_rgb_image_new(new_wid, new_hgt);
-
- /* Paranoia */
- if (new_image == NULL) return (NULL);
-
- /* now begins the cool part of SF's code */
-
- /*
- * Calculate an offsets table, so the transformation
- * is faster. This is much like the Bresenham algorithm
- */
-
- /* Set up x offset table */
- C_MAKE(xoffsets, new_wid, int);
-
- /* Initialize line parameters */
- add = old_wid / new_wid;
- remainder = old_wid % new_wid;
-
- /* Start at left */
- offset = 0;
-
- /* Half-tile offset so 'line' is centered correctly */
- rem_tot = new_wid / 2;
-
- for (i = 0; i < new_wid; i++)
- {
- /* Store into the table */
- xoffsets[i] = offset;
-
- /* Move to next entry */
- offset += add;
-
- /* Take care of fractional part */
- rem_tot += remainder;
- if (rem_tot >= new_wid)
- {
- rem_tot -= new_wid;
- offset++;
- }
- }
-
- /* Scan each row */
-
- /* Initialize line parameters */
- add = old_hgt / new_hgt;
- remainder = old_hgt % new_hgt;
-
- /* Start at left */
- offset = 0;
-
- /* Half-tile offset so 'line' is centered correctly */
- rem_tot = new_hgt / 2;
-
- for (i = 0; i < new_hgt; i++)
- {
- /* Copy pixels to new image */
- copy_pixels(new_wid, i, offset, xoffsets, old_image, new_image);
-
- /* Move to next entry */
- offset += add;
-
- /* Take care of fractional part */
- rem_tot += remainder;
- if (rem_tot >= new_hgt)
- {
- rem_tot -= new_hgt;
- offset++;
- }
- }
-
- /* Free offset table */
- C_FREE(xoffsets, new_wid, int);
-
- return (new_image);
-}
-
-
-/*
- * Resize an image of ix * iy pixels and return a newly allocated
- * image of ox * oy pixels.
- */
-static GdkRGBImage *resize_tiles(
- GdkRGBImage *im,
- int ix,
- int iy,
- int ox,
- int oy)
-{
- GdkRGBImage *result;
-
- /*
- * I hope we can always use this with GdkRGB, which uses a 5x5x5
- * colour cube (125 colours) by default, and resort to dithering
- * when it can't find good match there or expand the cube, so it
- * works with 8bpp X servers.
- */
- if (smooth_rescaling_request && (ix != ox || iy != oy))
- {
- result = resize_tiles_smooth(im, ix, iy, ox, oy);
- }
-
- /*
- * Unless smoothing is requested by user, we use the fast
- * resizing code.
- */
- else
- {
- result = resize_tiles_fast(im, ix, iy, ox, oy);
- }
-
- /* Return rescaled tiles, or NULL */
- return (result);
-}
-
-
-/*
- * Tile loaders - XPM and BMP
- */
-
-/*
- * A helper function for the XPM loader
- *
- * Read next string delimited by double quotes from
- * the input stream. Return TRUE on success, FALSE
- * if it finds EOF or buffer overflow.
- *
- * I never mean this to be generic, so its EOF and buffer
- * overflow behaviour is terribly stupid -- there are no
- * provisions for recovery.
- *
- * CAVEAT: treatment of backslash is not compatible with the standard
- * C usage XXX XXX XXX XXX
- */
-static bool_ read_str(char *buf, u32b len, FILE *f)
-{
- int c;
-
- /* Paranoia - Buffer too small */
- if (len <= 0) return (FALSE);
-
- /* Find " */
- while ((c = getc(f)) != '"')
- {
- /* Premature EOF */
- if (c == EOF) return (FALSE);
- }
-
- while (1)
- {
- /* Read next char */
- c = getc(f);
-
- /* Premature EOF */
- if (c == EOF) return (FALSE);
-
- /* Terminating " */
- if (c == '"') break;
-
- /* Escape */
- if (c == '\\')
- {
- /* Use next char */
- c = getc(f);
-
- /* Premature EOF */
- if (c == EOF) return (FALSE);
- }
-
- /* Store character in the buffer */
- *buf++ = c;
-
- /* Decrement count */
- len--;
-
- /* Buffer full - we have to place a NULL at the end */
- if (len <= 0) return (FALSE);
- }
-
- /* Make a C string if there's room left */
- if (len > 0) *buf = '\0';
-
- /* Success */
- return (TRUE);
-}
-
-
-/*
- * Remember pixel symbol to RGB colour mappings
- */
-
-/*
- * I've forgot the formula, but I remember prime number yields
- * good results
- */
-#define HASH_SIZE 19
-
-typedef struct pal_type pal_type;
-
-struct pal_type
-{
- u32b str;
- u32b rgb;
- pal_type *next;
-};
-
-
-/*
- * A simple, slow and stupid XPM loader
- */
-static GdkRGBImage *load_xpm(cptr filename)
-{
- FILE *f;
- GdkRGBImage *img = NULL;
- int width, height, colours, chars;
- int i, j, k;
- bool_ ret;
- pal_type *pal = NULL;
- pal_type *head[HASH_SIZE];
- u32b buflen = 0;
- char *lin = NULL;
- char buf[1024];
-
- /* Build path to the XPM file */
- path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, filename);
-
- /* Open it */
- f = my_fopen(buf, "r");
-
- /* Oops */
- if (f == NULL) return (NULL);
-
- /* Read header */
- ret = read_str(buf, 1024, f);
-
- /* Oops */
- if (!ret)
- {
- /* Notify error */
- plog("Cannot find XPM header");
-
- /* Failure */
- goto oops;
- }
-
- /* Parse header */
- if (4 != sscanf(buf, "%d %d %d %d", &width, &height, &colours, &chars))
- {
- /* Notify error */
- plog("Bad XPM header");
-
- /* Failure */
- goto oops;
- }
-
- /*
- * Paranoia - the code can handle upto four letters per pixel,
- * but such large number of colours certainly requires a smarter
- * symbol-to-colour mapping algorithm...
- */
- if ((width <= 0) || (height <= 0) || (colours <= 0) || (chars <= 0) ||
- (chars > 2))
- {
- /* Notify error */
- plog("Invalid width/height/depth");
-
- /* Failure */
- goto oops;
- }
-
- /* Allocate palette */
- C_MAKE(pal, colours, pal_type);
-
- /* Initialise hash table */
- for (i = 0; i < HASH_SIZE; i++) head[i] = NULL;
-
- /* Parse palette */
- for (i = 0; i < colours; i++)
- {
- u32b tmp;
- int h_idx;
-
- /* Read next string */
- ret = read_str(buf, 1024, f);
-
- /* Check I/O result */
- if (!ret)
- {
- /* Notify error */
- plog("EOF in palette");
-
- /* Failure */
- goto oops;
- }
-
- /* Clear symbol code */
- tmp = 0;
-
- /* Encode pixel symbol */
- for (j = 0; j < chars; j++)
- {
- tmp = (tmp << 8) | (buf[j] & 0xFF);
- }
-
- /* Remember it */
- pal[i].str = tmp;
-
- /* Skip spaces */
- while ((buf[j] == ' ') || (buf[j] == '\t')) j++;
-
- /* Verify 'c' */
- if (buf[j] != 'c')
- {
- /* Notify error */
- plog("No 'c' in palette definition");
-
- /* Failure */
- goto oops;
- }
-
- /* Advance cursor */
- j++;
-
- /* Skip spaces */
- while ((buf[j] == ' ') || (buf[j] == '\t')) j++;
-
- /* Hack - Assume 'None' */
- if (buf[j] == 'N')
- {
- /* Angband always uses black background */
- pal[i].rgb = 0x000000;
- }
-
- /* Read colour */
- else if ((1 != sscanf(&buf[j], "#%06lX", &tmp)) &&
- (1 != sscanf(&buf[j], "#%06lx", &tmp)))
- {
- /* Notify error */
- plog("Badly formatted colour");
-
- /* Failure */
- goto oops;
- }
-
- /* Remember it */
- pal[i].rgb = tmp;
-
- /* Store it in hash table as well */
- h_idx = pal[i].str % HASH_SIZE;
-
- /* Link the entry */
- pal[i].next = head[h_idx];
- head[h_idx] = &pal[i];
- }
-
- /* Allocate image */
- img = gdk_rgb_image_new(width, height);
-
- /* Oops */
- if (img == NULL)
- {
- /* Notify error */
- plog("Cannot allocate image");
-
- /* Failure */
- goto oops;
- }
-
- /* Calculate buffer length */
- buflen = width * chars + 1;
-
- /* Allocate line buffer */
- C_MAKE(lin, buflen, char);
-
- /* For each row */
- for (i = 0; i < height; i++)
- {
- /* Read a row of image data */
- ret = read_str(lin, buflen, f);
-
- /* Oops */
- if (!ret)
- {
- /* Notify error */
- plog("EOF in middle of image data");
-
- /* Failure */
- goto oops;
- }
-
- /* For each column */
- for (j = 0; j < width; j++)
- {
- u32b tmp;
- pal_type *h_ptr;
-
- /* Clear encoded pixel */
- tmp = 0;
-
- /* Encode pixel symbol */
- for (k = 0; k < chars; k++)
- {
- tmp = (tmp << 8) | (lin[j * chars + k] & 0xFF);
- }
-
- /* Find colour */
- for (h_ptr = head[tmp % HASH_SIZE];
- h_ptr != NULL;
- h_ptr = h_ptr->next)
- {
- /* Found a match */
- if (h_ptr->str == tmp) break;
- }
-
- /* No match found */
- if (h_ptr == NULL)
- {
- /* Notify error */
- plog("Invalid pixel symbol");
-
- /* Failure */
- goto oops;
- }
-
- /* Draw it */
- gdk_rgb_image_put_pixel(
- img,
- j,
- i,
- h_ptr->rgb);
- }
- }
-
- /* Close file */
- my_fclose(f);
-
- /* Free line buffer */
- C_FREE(lin, buflen, char);
-
- /* Free palette */
- C_FREE(pal, colours, pal_type);
-
- /* Return result */
- return (img);
-
-oops:
-
- /* Close file */
- my_fclose(f);
-
- /* Free image */
- if (img) gdk_rgb_image_destroy(img);
-
- /* Free line buffer */
- if (lin) C_FREE(lin, buflen, char);
-
- /* Free palette */
- if (pal) C_FREE(pal, colours, pal_type);
-
- /* Failure */
- return (NULL);
-}
-
-
-/*
- * A BMP loader, yet another duplication of maid-x11.c functions.
- *
- * Another duplication, again because of different image format and
- * avoidance of colour allocation.
- *
- * XXX XXX XXX XXX Should avoid using a propriatary and closed format.
- * Since it's much bigger than gif that was used before, why don't
- * we switch to XPM? NetHack does. Well, NH has always been much
- * closer to the GNU/Un*x camp and it's GPL'ed quite early...
- *
- * The names and naming convention are worse than the worst I've ever
- * seen, so I deliberately changed them to fit well with the rest of
- * the code. Or are they what xx calls them? If it's the case, there's
- * no reason to follow *their* words.
- */
-
-/*
- * BMP file header
- */
-typedef struct bmp_file_type bmp_file_type;
-
-struct bmp_file_type
-{
- u16b type;
- u32b size;
- u16b reserved1;
- u16b reserved2;
- u32b offset;
-};
-
-
-/*
- * BMP file information fields
- */
-typedef struct bmp_info_type bmp_info_type;
-
-struct bmp_info_type
-{
- u32b size;
- u32b width;
- u32b height;
- u16b planes;
- u16b bit_count;
- u32b compression;
- u32b size_image;
- u32b x_pels_per_meter;
- u32b y_pels_per_meter;
- u32b colors_used;
- u32b color_importand;
-};
-
-/*
- * "RGBQUAD" type.
- */
-typedef struct rgb_quad_type rgb_quad_type;
-
-struct rgb_quad_type
-{
- unsigned char b, g, r;
- unsigned char filler;
-};
-
-
-/*** Helper functions for system independent file loading. ***/
-
-static byte get_byte(FILE *fff)
-{
- /* Get a character, and return it */
- return (getc(fff) & 0xFF);
-}
-
-static void rd_byte(FILE *fff, byte *ip)
-{
- *ip = get_byte(fff);
-}
-
-static void rd_u16b(FILE *fff, u16b *ip)
-{
- (*ip) = get_byte(fff);
- (*ip) |= ((u16b)(get_byte(fff)) << 8);
-}
-
-static void rd_u32b(FILE *fff, u32b *ip)
-{
- (*ip) = get_byte(fff);
- (*ip) |= ((u32b)(get_byte(fff)) << 8);
- (*ip) |= ((u32b)(get_byte(fff)) << 16);
- (*ip) |= ((u32b)(get_byte(fff)) << 24);
-}
-
-
-/*
- * Read a BMP file (a certain trademark nuked)
- *
- * This function replaces the old ReadRaw and RemapColors functions.
- *
- * Assumes that the bitmap has a size such that no padding is needed in
- * various places. Currently only handles bitmaps with 3 to 256 colors.
- */
-GdkRGBImage *load_bmp(cptr filename)
-{
- FILE *f;
-
- char path[1024];
-
- bmp_file_type file_hdr;
- bmp_info_type info_hdr;
-
- GdkRGBImage *result = NULL;
-
- int ncol;
-
- int i;
-
- u32b x, y;
-
- guint32 colour_pixels[256];
-
-
- /* Build the path to the bmp file */
- path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, filename);
-
- /* Open the BMP file */
- f = fopen(path, "r");
-
- /* No such file */
- if (f == NULL)
- {
- return (NULL);
- }
-
- /* Read the "bmp_file_type" */
- rd_u16b(f, &file_hdr.type);
- rd_u32b(f, &file_hdr.size);
- rd_u16b(f, &file_hdr.reserved1);
- rd_u16b(f, &file_hdr.reserved2);
- rd_u32b(f, &file_hdr.offset);
-
- /* Read the "bmp_info_type" */
- rd_u32b(f, &info_hdr.size);
- rd_u32b(f, &info_hdr.width);
- rd_u32b(f, &info_hdr.height);
- rd_u16b(f, &info_hdr.planes);
- rd_u16b(f, &info_hdr.bit_count);
- rd_u32b(f, &info_hdr.compression);
- rd_u32b(f, &info_hdr.size_image);
- rd_u32b(f, &info_hdr.x_pels_per_meter);
- rd_u32b(f, &info_hdr.y_pels_per_meter);
- rd_u32b(f, &info_hdr.colors_used);
- rd_u32b(f, &info_hdr.color_importand);
-
- /* Verify the header */
- if (feof(f) ||
- (file_hdr.type != 19778) ||
- (info_hdr.size != 40))
- {
- plog(format("Incorrect BMP file format %s", filename));
- fclose(f);
- return (NULL);
- }
-
- /*
- * The two headers above occupy 54 bytes total
- * The "offset" field says where the data starts
- * The "colors_used" field does not seem to be reliable
- */
-
- /* Compute number of colors recorded */
- ncol = (file_hdr.offset - 54) / 4;
-
- for (i = 0; i < ncol; i++)
- {
- rgb_quad_type clr;
-
- /* Read an "rgb_quad_type" */
- rd_byte(f, &clr.b);
- rd_byte(f, &clr.g);
- rd_byte(f, &clr.r);
- rd_byte(f, &clr.filler);
-
- /* Remember the pixel */
- colour_pixels[i] = (clr.r << 16) | (clr.g << 8) | (clr.b);
- }
-
- /* Allocate GdkRGBImage large enough to store the image */
- result = gdk_rgb_image_new(info_hdr.width, info_hdr.height);
-
- /* Failure */
- if (result == NULL)
- {
- fclose(f);
- return (NULL);
- }
-
- for (y = 0; y < info_hdr.height; y++)
- {
- u32b y2 = info_hdr.height - y - 1;
-
- for (x = 0; x < info_hdr.width; x++)
- {
- int ch = getc(f);
-
- /* Verify not at end of file XXX XXX */
- if (feof(f))
- {
- plog(format("Unexpected end of file in %s", filename));
- gdk_rgb_image_destroy(result);
- fclose(f);
- return (NULL);
- }
-
- if (info_hdr.bit_count == 24)
- {
- int c3, c2 = getc(f);
-
- /* Verify not at end of file XXX XXX */
- if (feof(f))
- {
- plog(format("Unexpected end of file in %s", filename));
- gdk_rgb_image_destroy(result);
- fclose(f);
- return (NULL);
- }
-
- c3 = getc(f);
-
- /* Verify not at end of file XXX XXX */
- if (feof(f))
- {
- plog(format("Unexpected end of file in %s", filename));
- gdk_rgb_image_destroy(result);
- fclose(f);
- return (NULL);
- }
-
- /* Draw the pixel */
- gdk_rgb_image_put_pixel(
- result,
- x,
- y2,
- (ch << 16) | (c2 << 8) | (c3));
- }
- else if (info_hdr.bit_count == 8)
- {
- gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch]);
- }
- else if (info_hdr.bit_count == 4)
- {
- gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch / 16]);
- x++;
- gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch % 16]);
- }
- else
- {
- /* Technically 1 bit is legal too */
- plog(format("Illegal bit count %d in %s",
- info_hdr.bit_count, filename));
- gdk_rgb_image_destroy(result);
- fclose(f);
- return (NULL);
- }
- }
- }
-
- fclose(f);
-
- return result;
-}
-
-
-/*
- * Try to load an XPM file, or a BMP file if it fails
- *
- * Choice of file format may better be made yet another option XXX
- */
-static GdkRGBImage *load_tiles(cptr basename)
-{
- char buf[32];
- GdkRGBImage *img;
-
- /* build xpm file name */
- strnfmt(buf, 32, "%s.xpm", basename);
-
- /* Try to load it */
- img = load_xpm(buf);
-
- /* OK */
- if (img) return (img);
-
- /* Try again for a bmp file */
- strnfmt(buf, 32, "%s.bmp", basename);
-
- /* Try loading it */
- img = load_bmp(buf);
-
- /* Return result, success or failure */
- return (img);
-}
-
-
-/*
- * Free all tiles and graphics buffers associated with windows
- *
- * This is conspirator of graf_init() below, sharing its inefficiency
- */
-static void graf_nuke()
-{
- int i;
-
- term_data *td;
-
-
- /* Nuke all terms */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Access term_data structure */
- td = &data[i];
-
- /* Disable graphics */
- td->t.higher_pict = FALSE;
-
- /* Free previously allocated tiles */
- if (td->tiles) gdk_rgb_image_destroy(td->tiles);
-
- /* Forget pointer */
- td->tiles = NULL;
-
- /* Free previously allocated transparency buffer */
- if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);
-
- /* Forget stale pointer */
- td->trans_buf = NULL;
- }
-}
-
-
-/*
- * Load tiles, scale them to current font size, and store a pointer
- * to them in a term_data structure for each term.
- *
- * XXX XXX XXX This is a terribly stupid quick hack.
- *
- * XXX XXX XXX Windows using the same font should share resized tiles
- */
-static bool_ graf_init(
- cptr filename,
- int tile_wid,
- int tile_hgt)
-{
- term_data *td;
-
- bool_ result;
-
- GdkRGBImage *raw_tiles, *scaled_tiles;
-
- GdkRGBImage *buffer;
-
- int i;
-
-
- /* Paranoia */
- if (filename == NULL) return (FALSE);
-
- /* Load tiles */
- raw_tiles = load_tiles(filename);
-
- /* Oops */
- if (raw_tiles == NULL)
- {
- /* Clean up */
- graf_nuke();
-
- /* Failure */
- return (FALSE);
- }
-
- /* Calculate and remember numbers of rows and columns */
- tile_rows = raw_tiles->height / tile_hgt;
- tile_cols = raw_tiles->width / tile_wid;
-
- /* Be optimistic */
- result = TRUE;
-
-
- /*
- * (Re-)init each term
- * XXX It might help speeding this up to avoid doing so if a window
- * doesn't need graphics (e.g. inventory/equipment and message recall).
- */
- for (i = 0; i < MAX_TERM_DATA; i++)
- {
- /* Access term_data */
- td = &data[i];
-
- /* Shouldn't waste anything for unused terms */
- if (!td->shown) continue;
-
- /* Enable graphics */
- td->t.higher_pict = TRUE;
-
- /* See if we need rescaled tiles XXX */
- if ((td->tiles == NULL) ||
- (td->tiles->width != td->tile_wid * tile_cols) ||
- (td->tiles->height != td->tile_hgt * tile_rows))
- {
- /* Free old tiles if present */
- if (td->tiles) gdk_rgb_image_destroy(td->tiles);
-
- /* Forget pointer */
- td->tiles = NULL;
-
- /* Scale the tiles to current font bounding rect */
- scaled_tiles = resize_tiles(
- raw_tiles,
- tile_wid, tile_hgt,
- td->tile_wid, td->tile_hgt);
-
- /* Oops */
- if (scaled_tiles == NULL)
- {
- /* Failure */
- result = FALSE;
-
- break;
- }
-
- /* Store it */
- td->tiles = scaled_tiles;
- }
-
- /* See if we have to (re)allocate a new buffer XXX */
- if ((td->trans_buf == NULL) ||
- (td->trans_buf->width != td->tile_wid) ||
- (td->trans_buf->height != td->tile_hgt))
- {
- /* Free old buffer if present */
- if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);
-
- /* Forget pointer */
- td->trans_buf = NULL;
-
- /* Allocate a new buffer */
- buffer = gdk_rgb_image_new(td->tile_wid, td->tile_hgt);
-
- /* Oops */
- if (buffer == NULL)
- {
- /* Failure */
- result = FALSE;
-
- break;
- }
-
- /* Store it */
- td->trans_buf = buffer;
- }
-
- /*
- * Giga-Hack - assume top left corner of 0x86/0x80 should be
- * in the background colour XXX XXX XXX XXX
- */
- td->bg_pixel = gdk_rgb_image_get_pixel(
- raw_tiles,
- 0,
- tile_hgt * 6);
-
- }
-
-
- /* Alas, we need to free wasted images */
- if (result == FALSE) graf_nuke();
-
- /* We don't need the raw image any longer */
- gdk_rgb_image_destroy(raw_tiles);
-
- /* Report success or failure */
- return (result);
-}
-
-
-/*
- * React to various changes in graphics mode settings
- *
- * It is *not* a requirement for tiles to have same pixel width and height.
- * The program can work with any conbinations of graf_wid and graf_hgt
- * (oops, they must be representable by u16b), as long as they are lesser
- * or equal to 32 if you use smooth rescaling.
- */
-static void init_graphics(void)
-{
- cptr tile_name;
-
- u16b graf_wid = 0, graf_hgt = 0;
-
-
- /* No graphics requests are made - Can't this be simpler? XXX XXX */
- if ((graf_mode_request == graf_mode) &&
- (smooth_rescaling_request == smooth_rescaling) &&
- !resize_request) return;
-
- /* Prevent further unsolicited reaction */
- resize_request = FALSE;
-
-
- /* Dispose unusable old tiles - awkward... XXX XXX */
- if ((graf_mode_request == GRAF_MODE_NONE) ||
- (graf_mode_request != graf_mode) ||
- (smooth_rescaling_request != smooth_rescaling)) graf_nuke();
-
-
- /* Setup parameters according to request */
- switch (graf_mode_request)
- {
- /* ASCII - no graphics whatsoever */
- default:
- case GRAF_MODE_NONE:
- {
- tile_name = NULL;
- use_graphics = arg_graphics = FALSE;
-
- break;
- }
-
- /*
- * 8x8 tiles originally collected for the Amiga port
- * from several contributers by Lars Haugseth, converted
- * to 256 colours and expanded by the Z devteam
- *
- * Use the "old" tile assignments
- *
- * Dawnmist is working on it for ToME
- */
- case GRAF_MODE_OLD:
- {
- tile_name = "8x8";
- graf_wid = graf_hgt = 8;
- ANGBAND_GRAF = "old";
- use_graphics = arg_graphics = TRUE;
-
- break;
- }
-
- /*
- * Adam Bolt's 16x16 tiles
- * "new" tile assignments
- * It is updated for ToME by Andreas Koch
- */
- case GRAF_MODE_NEW:
- {
- tile_name = "16x16";
- graf_wid = graf_hgt = 16;
- ANGBAND_GRAF = "new";
- use_graphics = arg_graphics = TRUE;
-
- break;
- }
- }
-
-
- /* load tiles and set them up if tiles are requested */
- if ((graf_mode_request != GRAF_MODE_NONE) &&
- !graf_init(tile_name, graf_wid, graf_hgt))
- {
- /* Oops */
- plog("Cannot initialize graphics");
-
- /* reject requests */
- graf_mode_request = GRAF_MODE_NONE;
- smooth_rescaling_request = smooth_rescaling;
-
- /* reset graphics flags */
- use_graphics = arg_graphics = FALSE;
- }
-
- /* Update current graphics mode */
- graf_mode = graf_mode_request;
- smooth_rescaling = smooth_rescaling_request;
-
- /* Reset visuals */
- reset_visuals();
-}
-
-#endif /* USE_GRAPHICS */
@@ -2139,7 +267,7 @@ static void Term_nuke_gtk(term *t)
/* Free name */
- if (td->name) string_free(td->name);
+ if (td->name) free(td->name);
/* Forget it */
td->name = NULL;
@@ -2156,21 +284,6 @@ static void Term_nuke_gtk(term *t)
/* Forget it too */
td->backing_store = NULL;
-#ifdef USE_GRAPHICS
-
- /* Free tiles */
- if (td->tiles) gdk_rgb_image_destroy(td->tiles);
-
- /* Forget pointer */
- td->tiles = NULL;
-
- /* Free transparency buffer */
- if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);
-
- /* Amnesia */
- td->trans_buf = NULL;
-
-#endif /* USE_GRAPHICS */
}
@@ -2294,20 +407,6 @@ static errr Term_curs_gtk(int x, int y)
/* Set foreground colour */
term_data_set_fg(td, TERM_YELLOW);
-#ifdef USE_DOUBLE_TILES
-
- /* Mogami's bigtile patch */
-
- /* Adjust it if wide tiles are requested */
- if (use_bigtile &&
- (x + 1 < Term->wid) &&
- (Term->old->a[y][x + 1] == 255))
- {
- cells = 2;
- }
-
-#endif /* USE_DOUBLE_TILES */
-
/* Draw the software cursor */
gdk_draw_rectangle(
TERM_DATA_DRAWABLE(td),
@@ -2326,299 +425,6 @@ static errr Term_curs_gtk(int x, int y)
}
-#ifdef USE_GRAPHICS
-
-/*
- * XXX XXX Low level graphics helper
- * Draw a tile at (s_x, s_y) over one at (t_x, t_y) and store the
- * result in td->trans_buf
- *
- * XXX XXX Even if CPU's are faster than necessary these days,
- * this should be made inline. Or better, there should be an API
- * to take advantage of graphics hardware. They almost always have
- * assortment of builtin bitblt's...
- */
-static void overlay_tiles_2(
- term_data *td,
- int s_x, int s_y,
- int t_x, int t_y)
-{
- guint32 pix;
- int x, y;
-
-
- /* Process each row */
- for (y = 0; y < td->tile_hgt; y++)
- {
- /* Process each column */
- for (x = 0; x < td->tile_wid; x++)
- {
- /* Get an overlay pixel */
- pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y);
-
- /* If it's in background color, use terrain instead */
- if (pix == td->bg_pixel)
- pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y);
-
- /* Store the result in trans_buf */
- gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix);
- }
- }
-}
-
-
-/*
- * XXX XXX Low level graphics helper
- * Draw a tile at (e_x, e_y) over one at (s_x, s_y) over another one
- * at (t_x, t_y) and store the result in td->trans_buf
- *
- * XXX XXX The same comment applies as that for the above...
- */
-static void overlay_tiles_3(
- term_data *td,
- int e_x, int e_y,
- int s_x, int s_y,
- int t_x, int t_y)
-{
- guint32 pix;
- int x, y;
-
-
- /* Process each row */
- for (y = 0; y < td->tile_hgt; y++)
- {
- /* Process each column */
- for (x = 0; x < td->tile_wid; x++)
- {
- /* Get an overlay pixel */
- pix = gdk_rgb_image_get_pixel(td->tiles, e_x + x, e_y + y);
-
- /*
- * If it's background colour, try to use one from
- * the second layer
- */
- if (pix == td->bg_pixel)
- pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y);
-
- /*
- * If it's background colour again, fall back to
- * the terrain layer
- */
- if (pix == td->bg_pixel)
- pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y);
-
- /* Store the pixel in trans_buf */
- gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix);
- }
- }
-}
-
-
-
-/*
- * Low level graphics (Assumes valid input)
- *
- * Draw "n" tiles/characters starting at (x,y)
- */
-static errr Term_pict_gtk(
- int x, int y, int n,
- const byte *ap, const char *cp,
- const byte *tap, const char *tcp,
- const byte *eap, const char *ecp)
-{
- term_data *td = (term_data*)(Term->data);
-
- int i;
-
- int d_x, d_y;
-
-# ifdef USE_DOUBLE_TILES
-
- /* Hack - remember real number of columns affected XXX XXX XXX */
- int cols;
-
-# endif /* USE_DOUBLE_TILES */
-
-
- /* Don't draw to hidden windows */
- if (!td->shown) return (0);
-
- /* Paranoia */
- g_assert(td->drawing_area->window != 0);
-
- /* Top left corner of the destination rect */
- d_x = x * td->font_wid;
- d_y = y * td->font_hgt;
-
-
-# ifdef USE_DOUBLE_TILES
-
- /* Reset column counter */
- cols = 0;
-
-# endif /* USE_DOUBLE_TILES */
-
- /* Scan the input */
- for (i = 0; i < n; i++)
- {
- byte a;
- char c;
- int s_x, s_y;
-
- byte ta;
- char tc;
- int t_x, t_y;
-
- byte ea;
- char ec;
- int e_x = 0, e_y = 0;
- bool_ has_overlay;
-
-
- /* Grid attr/char */
- a = *ap++;
- c = *cp++;
-
- /* Terrain attr/char */
- ta = *tap++;
- tc = *tcp++;
-
- /* Overlay attr/char */
- ea = *eap++;
- ec = *ecp++;
- has_overlay = (ea && ec);
-
- /* Row and Col */
- s_y = (((byte)a & 0x7F) % tile_rows) * td->tile_hgt;
- s_x = (((byte)c & 0x7F) % tile_cols) * td->tile_wid;
-
- /* Terrain Row and Col */
- t_y = (((byte)ta & 0x7F) % tile_rows) * td->tile_hgt;
- t_x = (((byte)tc & 0x7F) % tile_cols) * td->tile_wid;
-
- /* Overlay Row and Col */
- if (has_overlay)
- {
- e_y = (((byte)ea & 0x7F) % tile_rows) * td->tile_hgt;
- e_x = (((byte)ec & 0x7F) % tile_cols) * td->tile_wid;
- }
-
-
-# ifdef USE_DOUBLE_TILES
-
- /* Mogami's bigtile patch */
-
- /* Hack -- a filler for wide tile */
- if (use_bigtile && (a == 255))
- {
- /* Advance */
- d_x += td->font_wid;
-
- /* Ignore */
- continue;
- }
-
-# endif /* USE_DOUBLE_TILES */
-
- /* Optimise the common case: terrain == obj/mons */
- if (!use_transparency ||
- ((s_x == t_x) && (s_y == t_y)))
- {
-
- /* The simplest possible case - no overlay */
- if (!has_overlay)
- {
- /* Draw the tile */
- gdk_draw_rgb_image_2(
- TERM_DATA_DRAWABLE(td), td->gc, td->tiles,
- s_x, s_y,
- d_x, d_y,
- td->tile_wid, td->tile_hgt);
- }
-
- /* We have to draw overlay... */
- else
- {
- /* Overlay */
- overlay_tiles_2(td, e_x, e_y, s_x, s_y);
-
- /* And draw the result */
- gdk_draw_rgb_image_2(
- TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf,
- 0, 0,
- d_x, d_y,
- td->tile_wid, td->tile_hgt);
-
- /* Hack -- Prevent potential display problem */
- gdk_flush();
- }
-
- }
-
- /*
- * Since there's no masking bitblt in X,
- * we have to do that manually...
- */
- else
- {
-
- /* No overlay */
- if (!has_overlay)
- {
- /* Build terrain + masked overlay image */
- overlay_tiles_2(td, s_x, s_y, t_x, t_y);
- }
-
- /* With overlay */
- else
- {
- /* Ego over mon/PC over terrain */
- overlay_tiles_3(td, e_x, e_y, s_x, s_y,
- t_x, t_y);
- }
-
- /* Draw it */
- gdk_draw_rgb_image_2(
- TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf,
- 0, 0,
- d_x, d_y,
- td->tile_wid, td->tile_hgt);
-
- /* Hack -- Prevent potential display problem */
- gdk_flush();
- }
-
- /*
- * Advance x-coordinate - wide font fillers are taken care of
- * before entering the tile drawing code.
- */
- d_x += td->font_wid;
-
-# ifdef USE_DOUBLE_TILES
-
- /* Add up *real* number of columns updated XXX XXX XXX */
- cols += use_bigtile ? 2 : 1;
-
-# endif /* USE_DOUBLE_TILES */
- }
-
-# ifndef USE_DOUBLE_TILES
-
- /* Copy image from backing store if present */
- TERM_DATA_REFRESH(td, x, y, n, 1);
-
-# else
-
- /* Copy image from backing store if present */
- TERM_DATA_REFRESH(td, x, y, cols, 1);
-
-# endif /* USE_DOUBLE_TILES */
-
- /* Success */
- return (0);
-}
-
-#endif /* USE_GRAPHICS */
/*
@@ -2708,58 +514,6 @@ static errr Term_xtra_gtk(int n, int v)
case TERM_XTRA_CLEAR:
return (Term_clear_gtk());
- /* Delay for some milliseconds */
- case TERM_XTRA_DELAY:
- {
- /* sleep for v milliseconds */
- usleep(v * 1000);
-
- /* Done */
- return (0);
- }
-
- /* Get Delay of some milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- int ret;
- struct timeval tv;
-
- ret = gettimeofday(&tv, NULL);
- Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- return ret;
- }
-
- /* Subdirectory scan */
- case TERM_XTRA_SCANSUBDIR:
- {
- DIR *directory;
- struct dirent *entry;
-
- scansubdir_max = 0;
-
- directory = opendir(scansubdir_dir);
- if (!directory) return (1);
-
- while ((entry = readdir(directory)) != NULL)
- {
- char file[PATH_MAX + NAME_MAX + 2];
- struct stat filedata;
-
- file[PATH_MAX + NAME_MAX] = 0;
- strncpy(file, scansubdir_dir, PATH_MAX);
- strncat(file, "/", 2);
- strncat(file, entry->d_name, NAME_MAX);
- if ((stat(file, &filedata) == 0) && S_ISDIR(filedata.st_mode))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] =
- string_make(entry->d_name);
- ++scansubdir_max;
- }
- }
- }
-
/* Rename main window */
case TERM_XTRA_RENAME_MAIN_WIN: gtk_window_set_title(GTK_WINDOW(data[0].window), angband_term_name[0]); return (0);
@@ -2769,12 +523,6 @@ static errr Term_xtra_gtk(int n, int v)
/* (re-)init colours */
init_colours();
-#ifdef USE_GRAPHICS
-
- /* Initialise graphics */
- init_graphics();
-
-#endif /* USE_GRAPHICS */
/* Success */
return (0);
@@ -3064,20 +812,6 @@ static void load_font(term_data *td, cptr fontname)
td->font_wid = gdk_char_width(td->font, '@');
td->font_hgt = td->font->ascent + td->font->descent;
-#ifndef USE_DOUBLE_TILES
-
- /* Use the current font size for tiles as well */
- td->tile_wid = td->font_wid;
- td->tile_hgt = td->font_hgt;
-
-#else /* !USE_DOUBLE_TILES */
-
- /* Calculate the size of tiles */
- if (use_bigtile && (td == &data[0])) td->tile_wid = td->font_wid * 2;
- else td->tile_wid = td->font_wid;
- td->tile_hgt = td->font_hgt;
-
-#endif /* !USE_DOUBLE_TILES */
}
@@ -3144,128 +878,6 @@ static void change_backing_store_event_handler(
}
-#ifdef USE_GRAPHICS
-
-/*
- * Set graf_mode_request according to user selection,
- * and let Term_xtra react to the change.
- */
-static void change_graf_mode_event_handler(
- gpointer user_data,
- guint user_action,
- GtkWidget *was_clicked)
-{
- /* Set request according to user selection */
- graf_mode_request = (int)user_action;
-
- /*
- * Hack - force redraw
- * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well
- */
- Term_key_push(KTRL('R'));
-}
-
-
-/*
- * Set dither_mode according to user selection
- */
-static void change_dith_mode_event_handler(
- gpointer user_data,
- guint user_action,
- GtkWidget *was_clicked)
-{
- /* Set request according to user selection */
- dith_mode = (int)user_action;
-
- /*
- * Hack - force redraw
- */
- Term_key_push(KTRL('R'));
-}
-
-
-/*
- * Toggles the graphics tile scaling mode (Fast/Smooth)
- */
-static void change_smooth_mode_event_handler(
- gpointer user_data,
- guint user_action,
- GtkWidget *was_clicked)
-{
- /* (Try to) toggle the smooth rescaling mode */
- smooth_rescaling_request = !smooth_rescaling;
-
- /*
- * Hack - force redraw
- * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well
- */
- Term_key_push(KTRL('R'));
-}
-
-
-# ifdef USE_DOUBLE_TILES
-
-static void change_wide_tile_mode_event_handler(
- gpointer user_data,
- guint user_action,
- GtkWidget *was_clicked)
-{
- term *old = Term;
- term_data *td = &data[0];
-
- /* Toggle "use_bigtile" */
- use_bigtile = !use_bigtile;
-
- /* T.o.M.E. requires this as well */
- arg_bigtile = use_bigtile;
-
- /* Double the width of tiles (only for the main window) */
- if (use_bigtile)
- {
- td->tile_wid = td->font_wid * 2;
- }
-
- /* Use the width of current font */
- else
- {
- td->tile_wid = td->font_wid;
- }
-
- /* Need to resize the tiles */
- resize_request = TRUE;
-
- /* Activate the main window */
- Term_activate(&td->t);
-
- /* Resize the term */
- Term_resize(td->cols, td->rows);
-
- /* Activate the old term */
- Term_activate(old);
-
- /* Hack - force redraw XXX ??? XXX */
- Term_key_push(KTRL('R'));
-}
-
-# endif /* USE_DOUBLE_TILES */
-
-
-/*
- * Toggles the boolean value of use_transparency
- */
-static void change_trans_mode_event_handler(
- gpointer user_data,
- guint user_aciton,
- GtkWidget *was_clicked)
-{
- /* Toggle the transparency mode */
- use_transparency = !use_transparency;
-
- /* Hack - force redraw */
- Term_key_push(KTRL('R'));
-}
-
-#endif /* USE_GRAPHICS */
/*
@@ -3650,7 +1262,8 @@ static errr term_data_init(term_data *td, int i)
term_init(t, td->cols, td->rows, 1024);
/* Store the name of the term */
- td->name = string_make(angband_term_name[i]);
+ assert(angband_term_name[i] != NULL);
+ td->name = strdup(angband_term_name[i]);
/* Instance names should start with a lowercase letter XXX */
for (p = (char *)td->name; *p; p++) *p = tolower(*p);
@@ -3666,9 +1279,6 @@ static errr term_data_init(term_data *td, int i)
t->text_hook = Term_text_gtk;
t->wipe_hook = Term_wipe_gtk;
t->curs_hook = Term_curs_gtk;
-#ifdef USE_GRAPHICS
- t->pict_hook = Term_pict_gtk;
-#endif /* USE_GRAPHICS */
t->nuke_hook = Term_nuke_gtk;
/* Save the data */
@@ -3752,37 +1362,6 @@ static GtkItemFactoryEntry main_menu_items[] =
{ NULL, NULL,
change_font_event_handler, 7, NULL, NULL },
-#ifdef USE_GRAPHICS
-
- /* "Graphics" submenu */
- { "/Options/Graphics", NULL,
- NULL, 0, "<Branch>", NULL },
- { "/Options/Graphics/None", NULL,
- change_graf_mode_event_handler, GRAF_MODE_NONE, "<CheckItem>", NULL },
- { "/Options/Graphics/Old", NULL,
- change_graf_mode_event_handler, GRAF_MODE_OLD, "<CheckItem>", NULL },
- { "/Options/Graphics/New", NULL,
- change_graf_mode_event_handler, GRAF_MODE_NEW, "<CheckItem>", NULL },
-# ifdef USE_DOUBLE_TILES
- { "/Options/Graphics/sep3", NULL,
- NULL, 0, "<Separator>", NULL },
- { "/Options/Graphics/Wide tiles", NULL,
- change_wide_tile_mode_event_handler, 0, "<CheckItem>", NULL },
-# endif /* USE_DOUBLE_TILES */
- { "/Options/Graphics/sep1", NULL,
- NULL, 0, "<Separator>", NULL },
- { "/Options/Graphics/Dither if <= 8bpp", NULL,
- change_dith_mode_event_handler, GDK_RGB_DITHER_NORMAL, "<CheckItem>", NULL },
- { "/Options/Graphics/Dither if <= 16bpp", NULL,
- change_dith_mode_event_handler, GDK_RGB_DITHER_MAX, "<CheckItem>", NULL },
- { "/Options/Graphics/sep2", NULL,
- NULL, 0, "<Separator>", NULL },
- { "/Options/Graphics/Smoothing", NULL,
- change_smooth_mode_event_handler, 0, "<CheckItem>", NULL },
- { "/Options/Graphics/Transparency", NULL,
- change_trans_mode_event_handler, 0, "<CheckItem>", NULL },
-
-#endif /* USE_GRAPHICS */
/* "Misc" submenu */
{ "/Options/Misc", NULL,
@@ -3838,13 +1417,13 @@ static void setup_menu_paths(void)
strnfmt(buf, 64, "/Terms/%s", angband_term_name[i]);
/* XXX XXX Store it in the menu definition */
- term_entry[i].path = (gchar*)string_make(buf);
+ term_entry[i].path = (gchar*) strdup(buf);
/* XXX XXX Build the real path name to the entry */
strnfmt(buf, 64, "/Options/Font/%s", angband_term_name[i]);
/* XXX XXX Store it in the menu definition */
- font_entry[i].path = (gchar*)string_make(buf);
+ font_entry[i].path = (gchar*) strdup(buf);
}
}
@@ -3890,10 +1469,10 @@ static void free_menu_paths(void)
for (i = 0; i < MAX_TERM_DATA; i++)
{
/* XXX XXX Free Term menu path */
- if (term_entry[i].path) string_free((cptr)term_entry[i].path);
+ if (term_entry[i].path) free(term_entry[i].path);
/* XXX XXX Free Font menu path */
- if (font_entry[i].path) string_free((cptr)font_entry[i].path);
+ if (font_entry[i].path) free(font_entry[i].path);
}
}
@@ -4058,51 +1637,6 @@ static void misc_menu_update_handler(
}
-#ifdef USE_GRAPHICS
-
-/*
- * Update the "Graphics" submenu
- */
-static void graf_menu_update_handler(
- GtkWidget *widget,
- gpointer user_data)
-{
- /* Update menu items */
- check_menu_item(
- "<Angband>/Options/Graphics/None",
- (graf_mode == GRAF_MODE_NONE));
- check_menu_item(
- "<Angband>/Options/Graphics/Old",
- (graf_mode == GRAF_MODE_OLD));
- check_menu_item(
- "<Angband>/Options/Graphics/New",
- (graf_mode == GRAF_MODE_NEW));
-
-#ifdef USE_DOUBLE_TILES
-
- check_menu_item(
- "<Angband>/Options/Graphics/Wide tiles",
- use_bigtile);
-
-#endif /* USE_DOUBLE_TILES */
-
- check_menu_item(
- "<Angband>/Options/Graphics/Dither if <= 8bpp",
- (dith_mode == GDK_RGB_DITHER_NORMAL));
- check_menu_item(
- "<Angband>/Options/Graphics/Dither if <= 16bpp",
- (dith_mode == GDK_RGB_DITHER_MAX));
-
- check_menu_item(
- "<Angband>/Options/Graphics/Smoothing",
- smooth_rescaling);
-
- check_menu_item(
- "<Angband>/Options/Graphics/Transparency",
- use_transparency);
-}
-
-#endif /* USE_GRAPHICS */
/*
@@ -4211,23 +1745,6 @@ static void add_menu_update_callbacks()
GTK_SIGNAL_FUNC(misc_menu_update_handler),
NULL);
-#ifdef USE_GRAPHICS
-
- /* Access Graphics menu */
- widget = get_widget_from_path("<Angband>/Options/Graphics");
-
- /* Paranoia */
- g_assert(widget != NULL);
- g_assert(GTK_IS_MENU(widget));
-
- /* Assign callback */
- gtk_signal_connect(
- GTK_OBJECT(widget),
- "show",
- GTK_SIGNAL_FUNC(graf_menu_update_handler),
- NULL);
-
-#endif /* USE_GRAPHICS */
}
@@ -4375,12 +1892,6 @@ static void hook_quit(cptr str)
/* Free menu paths dynamically allocated */
free_menu_paths();
-# ifdef USE_GRAPHICS
-
- /* Free pathname string */
- if (ANGBAND_DIR_XTRA_GRAF) string_free(ANGBAND_DIR_XTRA_GRAF);
-
-# endif /* USE_GRAPHICS */
/* Terminate the program */
gtk_exit(0);
@@ -4399,10 +1910,7 @@ errr init_gtk2(int argc, char **argv)
gtk_init(&argc, &argv);
/* Activate hooks - Use gtk/glib interface throughout */
- ralloc_aux = hook_ralloc;
- rnfree_aux = hook_rnfree;
quit_aux = hook_quit;
- core_aux = hook_quit;
/* Parse args */
for (i = 1; i < argc; i++)
@@ -4423,68 +1931,11 @@ errr init_gtk2(int argc, char **argv)
continue;
}
-#ifdef USE_GRAPHICS
-
- /* Requests "old" graphics */
- if (streq(argv[i], "-o"))
- {
- graf_mode_request = GRAF_MODE_OLD;
- continue;
- }
-
- /* Requests "new" graphics */
- if (streq(argv[i], "-g"))
- {
- graf_mode_request = GRAF_MODE_NEW;
- continue;
- }
-
-# ifdef USE_DOUBLE_TILES
-
- /* Requests wide tile mode */
- if (streq(argv[i], "-w"))
- {
- use_bigtile = TRUE;
- arg_bigtile = TRUE;
- continue;
- }
-
-# endif /* USE_DOUBLE_TILES */
-
-
- /* Enable transparency effect */
- if (streq(argv[i], "-t"))
- {
- use_transparency = TRUE;
- continue;
- }
-
- /* Disable smooth rescaling of tiles */
- if (streq(argv[i], "-s"))
- {
- smooth_rescaling_request = FALSE;
- continue;
- }
-
-#endif /* USE_GRAPHICS */
/* None of the above */
- plog_fmt("Ignoring option: %s", argv[i]);
- }
-
-#ifdef USE_GRAPHICS
-
- {
- char path[1024];
-
- /* Build the "graf" path */
- path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");
-
- /* Allocate the path */
- ANGBAND_DIR_XTRA_GRAF = string_make(path);
+ fprintf(stderr, "Ignoring option: %s", argv[i]);
}
-#endif /* USE_GRAPHICS */
/* Initialise colours */
gdk_rgb_init();
diff --git a/src/main-sdl.c b/src/main-sdl.c
index 840859e9..7a534ad5 100644
--- a/src/main-sdl.c
+++ b/src/main-sdl.c
@@ -25,11 +25,15 @@
#ifdef USE_SDL
-#include "angband.h"
+#include "loadsave.h"
+#include "util.h"
+#include "variable.h"
+
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
+#include <assert.h>
#include <math.h>
/*************************************************
@@ -64,21 +68,6 @@ static char arg_font_name[64] = DEF_FONT_FILE;
/**************/
-/* Graphics setting - signifies what graphics to use. Valid ints
-are available with given defines */
-
-/* No graphics - use only colored text */
-#define NO_GRAPHICS 0
-/* "Old" graphics - use 8x8.bmp to extract graphics tiles */
-#define GRAPHICS_8x8 8
-/* "New" graphics - use 16x16.bmp as tiles and apply mask.bmp for transparency*/
-#define GRAPHICS_16x16 16
-
-static int arg_graphics_type = NO_GRAPHICS;
-
-
-/**************/
-
/* The number of term_data structures to set aside mem for */
#define MAX_CONSOLE_COUNT 8
@@ -95,10 +84,6 @@ border */
/**************/
-/* some miscellaneous settings which have not been dealt
-with yet */
-static bool_ arg_double_width = FALSE;
-
/* flag signifying whether the game is in full screen */
static bool_ arg_full_screen = FALSE;
@@ -115,7 +100,7 @@ static bool_ window_properties_set = FALSE;
static SDL_Surface *screen;
/* the video settings for the system */
-static SDL_VideoInfo *videoInfo;
+static const SDL_VideoInfo *videoInfo;
/* a flag to suspend updating of the screen;
this is in place so that when a large area is being
@@ -581,23 +566,6 @@ static errr Term_xtra_sdl(int n, int v)
return (0);
}
- case TERM_XTRA_FROSH:
- {
- /*
- * Flush a row of output XXX XXX XXX
- *
- * This action should make sure that row "v" of the "output"
- * to the window will actually appear on the window.
- *
- * This action is optional, assuming that "Term_text_xxx()"
- * (and similar functions) draw directly to the screen, or
- * that the "TERM_XTRA_FRESH" entry below takes care of any
- * necessary flushing issues.
- */
-
- return (1);
- }
-
case TERM_XTRA_FRESH:
{
/*
@@ -607,9 +575,7 @@ static errr Term_xtra_sdl(int n, int v)
* window will actually appear on the window.
*
* This action is optional, assuming that "Term_text_xxx()"
- * (and similar functions) draw directly to the screen, or
- * that the "TERM_XTRA_FROSH" entry above takes care of any
- * necessary flushing issues.
+ * (and similar functions) draw directly to the screen.
*/
/* If terminal display has been held for any reason,
@@ -638,21 +604,6 @@ static errr Term_xtra_sdl(int n, int v)
return (1);
}
- case TERM_XTRA_SOUND:
- {
- /*
- * Make a sound XXX XXX XXX
- *
- * This action should produce sound number "v", where the
- * "name" of that sound is "sound_names[v]". This method
- * is still under construction.
- *
- * This action is optional, and not very important.
- */
-
- return (1);
- }
-
case TERM_XTRA_BORED:
{
/* Perform event checking without blocking */
@@ -718,40 +669,6 @@ static errr Term_xtra_sdl(int n, int v)
return (1);
}
- case TERM_XTRA_DELAY:
- {
- /*
- * Delay for some milliseconds XXX XXX XXX
- *
- * This action is useful for proper "timing" of certain
- * visual effects, such as breath attacks.
- *
- * This action is optional, but may be required by this file,
- * especially if special "macro sequences" must be supported.
- */
-
- /* I think that this command is system independent... */
- /*sleep(v/1000);*/
- /* main-x11 uses usleep(1000*v); */
- /* main-win uses Sleep(v); */
- return (1);
- }
-
- case TERM_XTRA_GET_DELAY:
- {
- /*
- * Get Delay of some milliseconds XXX XXX XXX
- * place the result in Term_xtra_long
- *
- * This action is useful for proper "timing" of certain
- * visual effects, such as recording cmovies.
- *
- * This action is optional, but cmovies wont perform
- * good without it
- */
-
- return (1);
- }
}
/* Unknown or Unhandled action */
@@ -1190,7 +1107,8 @@ static errr Term_text_sdl(int x, int y, int n, byte a, const char *cp)
SDL_BlitSurface(worksurf,NULL,td->surf,&base);
} else {
/* copy the desired character onto working surface */
- SDL_BlitSurface(text[*cp],NULL,worksurf,NULL);
+ assert(*cp >= 0); // Make sure cast is valid
+ SDL_BlitSurface(text[(size_t)(*cp)],NULL,worksurf,NULL);
/* color our crayon surface with the desired color */
SDL_FillRect(crayon,NULL,color_data[a&0x0f]);
/* apply the color to the character on the working surface */
@@ -1380,7 +1298,6 @@ void moveTerminal(int x, int y)
void bringToTop(int current)
{
term_data *td;
- term_data *tc;
int n = 0;
int i;
@@ -1555,8 +1472,7 @@ void manipulationMode(void)
int mouse_x, mouse_y;
int value = 0, delta_x = 0, delta_y = 0;
int current_term;
- SDL_Surface backup;
-
+
/* Begin by redrawing the main terminal with its
purple border to signify that it is being edited*/
@@ -1849,8 +1765,6 @@ static errr term_data_init(term_data *td, int i)
t->soft_cursor = TRUE;
/* Picture routine flags */
- t->always_pict = FALSE;
- t->higher_pict = FALSE;
t->always_text = FALSE;
/* Erase with "white space" */
@@ -1950,7 +1864,7 @@ This routine processes arguments, opens the SDL
window, loads fonts, etc. */
errr init_sdl(int argc, char **argv)
{
- int i, surface_type;
+ int i;
char filename[PATH_MAX + 1];
const char file_sep = '.';
/* Flags to pass to SDL_SetVideoMode */
@@ -2053,25 +1967,6 @@ errr init_sdl(int argc, char **argv)
return -1;
}
}
- /* see if new graphics are requested...*/
- else if (0 == strcmp(argv[i], "-g"))
- {
- printf("New graphics (16x16) enabled!\n");
- arg_graphics_type = GRAPHICS_16x16;
- }
- /* see if old graphics are requested...*/
- else if (0 == strcmp(argv[i], "-o"))
- {
- printf("Old graphics (8x8) enabled!\n");
- arg_graphics_type = GRAPHICS_8x8;
- }
-
- /* see if double width tiles are requested */
- else if (0 == strcmp(argv[i], "-b"))
- {
- /* do nothing for now */
- /* arg_double_width = TRUE; */
- }
/* switch into full-screen at startup */
else if (0 == strcmp(argv[i], "-fs"))
{
@@ -2168,13 +2063,6 @@ errr init_sdl(int argc, char **argv)
/* load and render the font */
loadAndRenderFont(arg_font_name,arg_font_size);
- /* Graphics! ----
- If graphics are selected, then load graphical tiles! */
- if (arg_graphics_type != NO_GRAPHICS)
- {
- /* load graphics tiles */
- }
-
/* Initialize the working surface and crayon surface used for rendering
text in different colors. */
diff --git a/src/main-win.c b/src/main-win.c
index 2d740034..05742c86 100644
--- a/src/main-win.c
+++ b/src/main-win.c
@@ -36,14 +36,8 @@
*
* Compiling this file, and using the resulting executable, requires
* several extra files not distributed with the standard Angband code.
- * If "USE_GRAPHICS" is defined, then "readdib.h" and "readdib.c" must
- * be placed into "src/", and the "8X8.BMP" bitmap file must be placed
- * into "lib/xtra/graf". In any case, some "*.fon" files (including
- * "8X13.FON" if nothing else) must be placed into "lib/xtra/font/".
- * If "USE_SOUND" is defined, then some special library (for example,
- * "winmm.lib") may need to be linked in, and desired "*.WAV" sound
- * files must be placed into "lib/xtra/sound/". All of these extra
- * files can be found in the "ext-win" archive.
+ * In any case, some "*.fon" files (including "8X13.FON" if nothing
+ * else) must be placed into "lib/xtra/font/".
*
*
* The "Term_xtra_win_clear()" function should probably do a low-level
@@ -74,7 +68,11 @@
#include "angband.h"
-
+#include "dungeon.h"
+#include "files.h"
+#include "init2.h"
+#include "util.h"
+#include "variable.h"
#ifdef WINDOWS
@@ -167,17 +165,9 @@
#define IDM_WINDOW_D_HGT_6 276
#define IDM_WINDOW_D_HGT_7 277
-#define IDM_OPTIONS_OLD_GRAPHICS 400
-#define IDM_OPTIONS_NEW_GRAPHICS 401
-#define IDM_OPTIONS_ASCII_GRAPHICS 403
-#define IDM_OPTIONS_SOUND 402
-#define IDM_OPTIONS_BIGTILE 409
#define IDM_OPTIONS_UNUSED 410
#define IDM_OPTIONS_SAVER 411
-#define IDM_HELP_GENERAL 901
-#define IDM_HELP_SPOILERS 902
-
/*
* This may need to be removed for some compilers XXX XXX XXX
@@ -250,9 +240,6 @@
/*
* Include the support for loading bitmaps
*/
-#ifdef USE_GRAPHICS
-# include "readdib.h"
-#endif
/*
* Hack -- Fake declarations from "dos.h" XXX XXX XXX
@@ -443,40 +430,9 @@ static HWND hwndSaver;
#endif /* USE_SAVER */
-#ifdef USE_GRAPHICS
-
-/*
- * Flag set once "graphics" has been initialized
- */
-static bool_ can_use_graphics = FALSE;
-
-/*
- * The global bitmap
- */
-static DIBINIT infGraph;
-
-/*
- * The global bitmap mask
- */
-static DIBINIT infMask;
-#endif /* USE_GRAPHICS */
-#ifdef USE_SOUND
-
-/*
- * Flag set once "sound" has been initialized
- */
-static bool_ can_use_sound = FALSE;
-
-/*
- * An array of sound file names
- */
-static cptr sound_file[SOUND_MAX];
-
-#endif /* USE_SOUND */
-
/*
* Full path to ANGBAND.INI
@@ -498,7 +454,6 @@ static cptr AngList = "AngList";
*/
static cptr ANGBAND_DIR_XTRA_FONT;
static cptr ANGBAND_DIR_XTRA_GRAF;
-static cptr ANGBAND_DIR_XTRA_SOUND;
static cptr ANGBAND_DIR_XTRA_HELP;
@@ -893,18 +848,6 @@ static void save_prefs(void)
char buf[128];
- /* Save the "arg_graphics" flag */
- sprintf(buf, "%d", arg_graphics);
- WritePrivateProfileString("Angband", "Graphics", buf, ini_file);
-
- /* Save the "arg_bigtile" flag */
- strcpy(buf, arg_bigtile ? "1" : "0");
- WritePrivateProfileString("Angband", "Bigtile", buf, ini_file);
-
- /* Save the "arg_sound" flag */
- strcpy(buf, arg_sound ? "1" : "0");
- WritePrivateProfileString("Angband", "Sound", buf, ini_file);
-
/* Save window prefs */
for (i = 0; i < MAX_TERM_DATA; ++i)
{
@@ -936,7 +879,7 @@ static void load_prefs_aux(term_data *td, cptr sec_name)
td->bizarre = (GetPrivateProfileInt(sec_name, "Bizarre", td->bizarre, ini_file) != 0);
/* Analyze font, save desired font name */
- td->font_want = string_make(analyze_font(tmp, &wid, &hgt));
+ td->font_want = strdup(analyze_font(tmp, &wid, &hgt));
/* Tile size */
td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", wid, ini_file);
@@ -961,16 +904,6 @@ static void load_prefs(void)
char buf[1024];
- /* Extract the "arg_graphics" flag */
- arg_graphics = GetPrivateProfileInt("Angband", "Graphics", 0, ini_file);
-
- /* Extract the "arg_bigtile" flag */
- arg_bigtile = GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file);
- use_bigtile = arg_bigtile;
-
- /* Extract the "arg_sound" flag */
- arg_sound = (GetPrivateProfileInt("Angband", "Sound", 0, ini_file) != 0);
-
/* Load window prefs */
for (i = 0; i < MAX_TERM_DATA; ++i)
{
@@ -1021,37 +954,16 @@ static int new_palette(void)
lppe = NULL;
nEntries = 0;
-#ifdef USE_GRAPHICS
-
- /* Check the bitmap palette */
- hBmPal = infGraph.hPalette;
-
- /* Use the bitmap */
- if (hBmPal)
- {
- lppeSize = 256 * sizeof(PALETTEENTRY);
- lppe = (LPPALETTEENTRY)ralloc(lppeSize);
- nEntries = GetPaletteEntries(hBmPal, 0, 255, lppe);
- if ((nEntries == 0) || (nEntries > 220))
- {
- /* Warn the user */
- plog_fmt("Unusable bitmap palette (%d entries)", nEntries);
-
- /* Cleanup */
- rnfree(lppe, lppeSize);
-
- /* Fail */
- return (FALSE);
- }
- }
-
-#endif
/* Size of palette */
pLogPalSize = sizeof(LOGPALETTE) + (nEntries + 16) * sizeof(PALETTEENTRY);
/* Allocate palette */
- pLogPal = (LPLOGPALETTE)ralloc(pLogPalSize);
+ pLogPal = (LPLOGPALETTE) calloc(1, pLogPalSize);
+ if (pLogPal == NULL)
+ {
+ abort();
+ }
/* Version */
pLogPal->palVersion = 0x300;
@@ -1083,14 +995,19 @@ static int new_palette(void)
}
/* Free something */
- if (lppe) rnfree(lppe, lppeSize);
+ if (lppe)
+ {
+ free(lppe);
+ lppe = NULL;
+ }
/* Create a new palette, or fail */
hNewPal = CreatePalette(pLogPal);
if (!hNewPal) quit("Cannot create palette!");
/* Free the palette */
- rnfree(pLogPal, pLogPalSize);
+ free(pLogPal);
+ pLogPal = NULL;
/* Main window */
td = &data[0];
@@ -1123,120 +1040,6 @@ static int new_palette(void)
}
-/*
- * Initialize graphics
- */
-static bool_ init_graphics()
-{
- /* Initialize once */
- /*if (can_use_graphics != arg_graphics) */
- {
- char buf[1024];
- int wid, hgt;
- cptr name;
-
- /* Unused */
- PALETTEENTRY entry =
- {
- 0, 0, 0, 0
- };
- (void)entry;
-
- if (arg_graphics == 2)
- {
- wid = 16;
- hgt = 16;
-
- name = "16X16.BMP";
-
- ANGBAND_GRAF = "new";
- }
- else
- {
- wid = 8;
- hgt = 8;
-
- name = "8X8.BMP";
- ANGBAND_GRAF = "old";
- }
-
- /* Access the bitmap file */
- path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, name);
-
- /* Load the bitmap or quit */
- if (!ReadDIB(data[0].w, buf, &infGraph))
- {
- plog_fmt("Cannot read bitmap file '%s'", name);
- return (FALSE);
- }
-
- /* Save the new sizes */
- infGraph.CellWidth = wid;
- infGraph.CellHeight = hgt;
-
-
- path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, "mask.bmp");
- /* Load the bitmap or quit */
- if (!ReadDIB(data[0].w, buf, &infMask))
- {
- plog_fmt("Cannot read bitmap file '%s'", name);
- return (FALSE);
- }
-
- /* Activate a palette */
- if (!new_palette())
- {
- /* Free bitmap XXX XXX XXX */
-
- /* Oops */
- plog("Cannot activate palette!");
- return (FALSE);
- }
-
- /* Graphics available */
- can_use_graphics = arg_graphics;
- }
-
- /* Result */
- return (can_use_graphics);
-}
-
-
-/*
- * Initialize sound
- */
-static bool_ init_sound()
-{
- /* Initialize once */
- if (!can_use_sound)
- {
- int i;
-
- char wav[128];
- char buf[1024];
-
- /* Prepare the sounds */
- for (i = 1; i < SOUND_MAX; i++)
- {
- /* Extract name of sound file */
- sprintf(wav, "%s.wav", angband_sound_name[i]);
-
- /* Access the sound */
- path_build(buf, 1024, ANGBAND_DIR_XTRA_SOUND, wav);
-
- /* Save the sound filename, if it exists */
- if (check_file(buf)) sound_file[i] = string_make(buf);
- }
-
- /* Sound available */
- can_use_sound = TRUE;
- }
-
- /* Result */
- return (can_use_sound);
-}
-
-
/*
* Resize a window
@@ -1301,9 +1104,7 @@ static errr term_force_font(term_data *td, cptr path)
if (!used) RemoveFontResource(td->font_file);
/* Free the old name */
- string_free(td->font_file);
-
- /* Forget it */
+ free(td->font_file);
td->font_file = NULL;
}
@@ -1328,7 +1129,7 @@ static errr term_force_font(term_data *td, cptr path)
if (!AddFontResource(buf)) return (1);
/* Save new font name */
- td->font_file = string_make(base);
+ td->font_file = strdup(base);
/* Remove the "suffix" */
base[strlen(base) - 4] = '\0';
@@ -1445,16 +1246,6 @@ static void term_data_redraw(term_data *td)
/*
- * Interact with the User
- */
-static errr Term_user_win(int n)
-{
- /* Success */
- return (0);
-}
-
-
-/*
* React to global changes
*/
static errr Term_xtra_win_react(void)
@@ -1509,52 +1300,9 @@ static errr Term_xtra_win_react(void)
}
-#ifdef USE_SOUND
- /* Handle "arg_sound" */
- if (use_sound != arg_sound)
- {
- /* Initialize (if needed) */
- if (arg_sound && !init_sound())
- {
- /* Warning */
- plog("Cannot initialize sound!");
-
- /* Cannot enable */
- arg_sound = FALSE;
- }
-
- /* Change setting */
- use_sound = arg_sound;
- }
-
-#endif
-#ifdef USE_GRAPHICS
-
- /* Handle "arg_graphics" */
- if (use_graphics != arg_graphics)
- {
- /* Initialize (if needed) */
- if (arg_graphics && !init_graphics())
- {
- /* Warning */
- plog("Cannot initialize graphics!");
-
- /* Cannot enable */
- arg_graphics = FALSE;
- }
-
- /* Change setting */
- use_graphics = arg_graphics;
-
- /* Reset visuals */
- reset_visuals();
- }
-
-#endif /* USE_GRAPHICS */
-
/* Clean up windows */
for (i = 0; i < MAX_TERM_DATA; i++)
@@ -1680,41 +1428,6 @@ static errr Term_xtra_win_noise(void)
/*
- * Hack -- make a sound
- */
-static errr Term_xtra_win_sound(int v)
-{
- /* Sound disabled */
- if (!use_sound) return (1);
-
- /* Illegal sound */
- if ((v < 0) || (v >= SOUND_MAX)) return (1);
-
- /* Unknown sound */
- if (!sound_file[v]) return (1);
-
-#ifdef USE_SOUND
-
-#ifdef WIN32
-
- /* Play the sound, catch errors */
- return (PlaySound(sound_file[v], 0, SND_FILENAME | SND_ASYNC));
-
-#else /* WIN32 */
-
-/* Play the sound, catch errors */
- return (sndPlaySound(sound_file[v], SND_ASYNC));
-
-#endif /* WIN32 */
-
-#endif /* USE_SOUND */
-
- /* Oops */
- return (1);
-}
-
-
-/*
* Delay for "x" milliseconds
*/
static int Term_xtra_win_delay(int v)
@@ -1772,12 +1485,6 @@ static errr Term_xtra_win(int n, int v)
return (Term_xtra_win_noise());
}
- /* Make a special sound */
- case TERM_XTRA_SOUND:
- {
- return (Term_xtra_win_sound(v));
- }
-
/* Process random events */
case TERM_XTRA_BORED:
{
@@ -1814,40 +1521,6 @@ static errr Term_xtra_win(int n, int v)
return (Term_xtra_win_delay(v));
}
- /* Get the current time in milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- DWORD t;
-
- t = GetTickCount();
- Term_xtra_long = t;
- return 0;
- }
-
- /*
- * Scans for subdirectories in a directory "scansubdir_dir"
- * and place teh result in "scansubdir_result/scansubdir_max"
- */
- case TERM_XTRA_SCANSUBDIR:
- {
- BOOL ok;
- HANDLE h;
- WIN32_FIND_DATA fd;
- for (h = FindFirstFile(format("%s\\*", scansubdir_dir), &fd), ok = 1;
- h != INVALID_HANDLE_VALUE && ok;
- ok = FindNextFile(h, &fd))
- {
- if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(fd.cFileName, ".")) && (strcmp(fd.cFileName, "..")))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] = string_make(fd.cFileName);
- scansubdir_max++;
- }
- }
-
- return 0;
- }
-
/* Rename main window */
case TERM_XTRA_RENAME_MAIN_WIN:
SetWindowText(get_main_hwnd(), angband_term_name[0]); return (0);
@@ -1877,9 +1550,6 @@ static errr Term_curs_win(int x, int y)
rc.top = y * td->tile_hgt + td->size_oh1;
rc.bottom = rc.top + td->tile_hgt;
- if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x + 1] == 255)
- rc.right += td->tile_wid;
-
/* Cursor is done as a yellow "box" */
hdc = GetDC(data[0].w);
FrameRect(hdc, &rc, hbrYellow);
@@ -2010,197 +1680,6 @@ static errr Term_text_win(int x, int y, int n, byte a, const char *s)
}
-/*
- * Low level graphics. Assumes valid input.
- *
- * Draw an array of "special" attr/char pairs at the given location.
- *
- * We use the "Term_pict_win()" function for "graphic" data, which are
- * encoded by setting the "high-bits" of both the "attr" and the "char"
- * data. We use the "attr" to represent the "row" of the main bitmap,
- * and the "char" to represent the "col" of the main bitmap. The use
- * of this function is induced by the "higher_pict" flag.
- *
- * If "graphics" is not available, we simply "wipe" the given grids.
- */
-static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp)
-{
- term_data *td = (term_data*)(Term->data);
-
-#ifdef USE_GRAPHICS
-
- int i;
- int x1, y1, w1, h1;
- int x2, y2, w2, h2, tw2;
-
- int x3, y3;
-
- HDC hdcMask = NULL;
-
- int x4, y4;
-
- HDC hdc;
- HDC hdcSrc;
- HBITMAP hbmSrcOld;
-
- /* Paranoia */
- if (!use_graphics)
- {
- /* Erase the grids */
- return (Term_wipe_win(x, y, n));
- }
-
- /* Size of bitmap cell */
- w1 = infGraph.CellWidth;
- h1 = infGraph.CellHeight;
-
- /* Size of window cell */
- w2 = td->tile_wid;
- h2 = td->tile_hgt;
- tw2 = w2;
-
- /* big tile mode */
- if (use_bigtile) tw2 *= 2;
-
- /* Location of window cell */
- x2 = x * w2 + td->size_ow1;
- y2 = y * h2 + td->size_oh1;
-
- /* Info */
- hdc = GetDC(td->w);
-
- /* More info */
- hdcSrc = CreateCompatibleDC(hdc);
- hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);
-
- if (arg_graphics == 2)
- {
- hdcMask = CreateCompatibleDC(hdc);
- SelectObject(hdcMask, infMask.hBitmap);
- }
-
- /* Draw attr/char pairs */
- for (i = 0; i < n; i++, x2 += w2)
- {
- byte a = ap[i];
- char c = cp[i];
-
- /* Extract picture */
- int row = (a & 0x7F);
- int col = (c & 0x7F);
-
- /* Location of bitmap cell */
- x1 = col * w1;
- y1 = row * h1;
-
- if (arg_graphics == 2)
- {
- x3 = (tcp[i] & 0x7F) * w1;
- y3 = (tap[i] & 0x7F) * h1;
-
- /* Perfect size */
- if ((w1 == tw2) && (h1 == h2))
- {
- /* Copy the terrain picture from the bitmap to the window */
- BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, SRCCOPY);
-
- /* Mask out the tile */
- BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, SRCAND);
-
- /* Draw the tile */
- BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCPAINT);
-
- if (ecp[i] != 0 && eap[i] != 0)
- {
- x4 = (ecp[i] & 0x7F) * w1;
- y4 = (eap[i] & 0x7F) * h1;
-
- /* Mask out the tile */
- BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x4, y4, SRCAND);
-
- /* Draw the tile */
- BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x4, y4, SRCPAINT);
- }
- }
-
- /* Need to stretch */
- else
- {
- /* Set the correct mode for stretching the tiles */
- SetStretchBltMode(hdc, COLORONCOLOR);
-
- /* Copy the terrain picture from the bitmap to the window */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, w1, h1, SRCCOPY);
-
- /* Only draw if terrain and overlay are different */
- if ((x1 != x3) || (y1 != y3))
- {
- /* Mask out the tile */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, w1, h1, SRCAND);
-
- /* Draw the tile */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
- }
-
- if (ecp[i] != 0 && eap[i] != 0)
- {
- x4 = (ecp[i] & 0x7F) * w1;
- y4 = (eap[i] & 0x7F) * h1;
-
- /* Mask out the tile */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x4, y4, w1, h1, SRCAND);
-
- /* Draw the tile */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x4, y4, w1, h1, SRCPAINT);
- }
- }
- }
- else
- {
- /* Perfect size */
- if ((w1 == tw2) && (h1 == h2))
- {
- /* Copy the picture from the bitmap to the window */
- BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCCOPY);
- }
-
- /* Need to stretch */
- else
- {
- /* Set the correct mode for stretching the tiles */
- SetStretchBltMode(hdc, COLORONCOLOR);
-
- /* Copy the picture from the bitmap to the window */
- StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
- }
- }
- }
-
- /* Release */
- SelectObject(hdcSrc, hbmSrcOld);
- DeleteDC(hdcSrc);
-
- if (arg_graphics == 2)
- {
- /* Release */
- SelectObject(hdcMask, hbmSrcOld);
- DeleteDC(hdcMask);
- }
-
- /* Release */
- ReleaseDC(td->w, hdc);
-
-#else /* USE_GRAPHICS */
-
- /* Just erase this grid */
- return (Term_wipe_win(x, y, n));
-
-#endif /* USE_GRAPHICS */
-
- /* Success */
- return 0;
-}
-
/*** Other routines ***/
@@ -2218,20 +1697,15 @@ static void term_data_link(term_data *td)
/* Use a "software" cursor */
t->soft_cursor = TRUE;
- /* Use "Term_pict" for "graphic" data */
- t->higher_pict = TRUE;
-
/* Erase with "white space" */
t->attr_blank = TERM_WHITE;
t->char_blank = ' ';
/* Prepare the template hooks */
- t->user_hook = Term_user_win;
t->xtra_hook = Term_xtra_win;
t->curs_hook = Term_curs_win;
t->wipe_hook = Term_wipe_win;
t->text_hook = Term_text_win;
- t->pict_hook = Term_pict_win;
/* Remember where we came from */
t->data = (vptr)(td);
@@ -2258,7 +1732,7 @@ static void init_windows(void)
/* Main window */
td = &data[0];
- WIPE(td, term_data);
+ memset(td, 0, sizeof(term_data));
td->s = angband_term_name[0];
td->keys = 1024;
td->rows = 24;
@@ -2275,7 +1749,7 @@ static void init_windows(void)
for (i = 1; i < MAX_TERM_DATA; i++)
{
td = &data[i];
- WIPE(td, term_data);
+ memset(td, 0, sizeof(term_data));
td->s = angband_term_name[i];
td->keys = 16;
td->rows = 24;
@@ -2570,52 +2044,18 @@ static void setup_menus(void)
}
/* Menu "Options", disable all */
- EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
- MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
- MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS,
- MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hm, IDM_OPTIONS_BIGTILE,
- MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hm, IDM_OPTIONS_SOUND,
- MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
EnableMenuItem(hm, IDM_OPTIONS_UNUSED,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
EnableMenuItem(hm, IDM_OPTIONS_SAVER,
MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
/* Menu "Options", update all */
- CheckMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
- (arg_graphics == 1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
- (arg_graphics == 2 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS,
- (arg_graphics == 0 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(hm, IDM_OPTIONS_BIGTILE,
- (arg_bigtile ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(hm, IDM_OPTIONS_SOUND,
- (arg_sound ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(hm, IDM_OPTIONS_UNUSED,
(0 ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(hm, IDM_OPTIONS_SAVER,
(hwndSaver ? MF_CHECKED : MF_UNCHECKED));
-#ifdef USE_GRAPHICS
- /* Menu "Options", Item "Graphics" */
- EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS, MF_ENABLED);
- /* Menu "Options", Item "Graphics" */
- EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS, MF_ENABLED);
- /* Menu "Options", Item "Graphics" */
- EnableMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS, MF_ENABLED);
- /* Menu "Options", Item "Graphics" */
- EnableMenuItem(hm, IDM_OPTIONS_BIGTILE, MF_ENABLED);
-#endif
-#ifdef USE_SOUND
- /* Menu "Options", Item "Sound" */
- EnableMenuItem(hm, IDM_OPTIONS_SOUND, MF_ENABLED);
-#endif
#ifdef USE_SAVER
/* Menu "Options", Item "ScreenSaver" */
@@ -2977,114 +2417,6 @@ ofn.lStructSize = sizeof(OPENFILENAME);
break;
}
- case IDM_OPTIONS_OLD_GRAPHICS:
- {
- /* Paranoia */
- if (!inkey_flag)
- {
- plog("You may not do that right now.");
- break;
- }
-
- /* Set "arg_graphics" */
- arg_graphics = 1;
-
- /* React to changes */
- Term_xtra_win_react();
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
-
- break;
- }
-
- case IDM_OPTIONS_NEW_GRAPHICS:
- {
- /* Paranoia */
- if (!inkey_flag)
- {
- plog("You may not do that right now.");
- break;
- }
-
- /* Set "arg_graphics" */
- arg_graphics = 2;
-
- /* React to changes */
- Term_xtra_win_react();
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
-
- break;
- }
- case IDM_OPTIONS_ASCII_GRAPHICS:
- {
- /* Paranoia */
- if (!inkey_flag)
- {
- plog("You may not do that right now.");
- break;
- }
-
- /* Set "ASCII Graphics" */
- arg_graphics = 0;
- /* React to Changes */
- Term_xtra_win_react();
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
-
- break;
- }
-
- case IDM_OPTIONS_BIGTILE:
- {
- term_data *td = &data[0];
-
- /* Paranoia */
- if (!inkey_flag)
- {
- plog("You may not do that right now.");
- break;
- }
-
- /* Toggle "arg_sound" */
- arg_bigtile = !arg_bigtile;
-
- /* Activate */
- Term_activate(&td->t);
-
- /* Resize the term */
- Term_resize(td->cols, td->rows);
-
- /* Redraw later */
- InvalidateRect(td->w, NULL, TRUE);
-
- break;
- }
-
- case IDM_OPTIONS_SOUND:
- {
- /* Paranoia */
- if (!inkey_flag)
- {
- plog("You may not do that right now.");
- break;
- }
-
- /* Toggle "arg_sound" */
- arg_sound = !arg_sound;
-
- /* React to changes */
- Term_xtra_win_react();
-
- /* Hack -- Force redraw */
- Term_key_push(KTRL('R'));
-
- break;
- }
-
case IDM_OPTIONS_UNUSED:
{
/* Unused for now XXX XXX XXX */
@@ -3126,55 +2458,12 @@ ofn.lStructSize = sizeof(OPENFILENAME);
#endif
- case IDM_HELP_GENERAL:
- {
- char buf[1024];
- char tmp[1024];
- path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "angband.hlp");
- if (check_file(tmp))
- {
- sprintf(buf, "winhelp.exe %s", tmp);
- WinExec(buf, SW_NORMAL);
- }
- else
- {
- plog_fmt("Cannot find help file: %s", tmp);
- plog("Use the online help files instead.");
- }
- break;
- }
-
- case IDM_HELP_SPOILERS:
- {
- char buf[1024];
- char tmp[1024];
- path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "spoilers.hlp");
- if (check_file(tmp))
- {
- sprintf(buf, "winhelp.exe %s", tmp);
- WinExec(buf, SW_NORMAL);
- }
- else
- {
- plog_fmt("Cannot find help file: %s", tmp);
- plog("Use the online help files instead.");
- }
- break;
- }
- }
}
-#ifdef __MWERKS__
-LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
-#else /* __MWERKS__ */
-LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam)
-#endif /* __MWERKS__ */
{
PAINTSTRUCT ps;
HDC hdc;
@@ -3454,15 +2743,8 @@ LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
}
-#ifdef __MWERKS__
-LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
-#else /* __MWERKS__ */
-LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam)
-#endif /* __MWERKS__ */
{
term_data *td;
MINMAXINFO FAR *lpmmi;
@@ -3666,15 +2948,8 @@ LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
#define MOUSE_SENS 40
-#ifdef __MWERKS__
-LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam);
-LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
- WPARAM wParam, LPARAM lParam)
-#else /* __MWERKS__ */
LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
-#endif /* __MWERKS__ */
{
static int iMouse = 0;
static WORD xMouse = 0;
@@ -3833,7 +3108,11 @@ static void hook_quit(cptr str)
for (i = MAX_TERM_DATA - 1; i >= 0; --i)
{
term_force_font(&data[i], NULL);
- if (data[i].font_want) string_free(data[i].font_want);
+ if (data[i].font_want)
+ {
+ free(data[i].font_want);
+ data[i].font_want = NULL;
+ }
if (data[i].w) DestroyWindow(data[i].w);
data[i].w = 0;
}
@@ -3872,7 +3151,7 @@ static void init_stuff(void)
strcpy(path + strlen(path) - 4, ".INI");
/* Save the the name of the ini-file */
- ini_file = string_make(path);
+ ini_file = strdup(path);
/* Validate the ini-file */
validate_file(ini_file);
@@ -3905,7 +3184,7 @@ static void init_stuff(void)
path_build(path, 1024, ANGBAND_DIR_XTRA, "font");
/* Allocate the path */
- ANGBAND_DIR_XTRA_FONT = string_make(path);
+ ANGBAND_DIR_XTRA_FONT = strdup(path);
/*** Validate the paths to ensure we have a working install ***/
@@ -3930,45 +3209,15 @@ static void init_stuff(void)
validate_file(path);
-#ifdef USE_GRAPHICS
-
- /* Build the "graf" path */
- path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");
-
- /* Allocate the path */
- ANGBAND_DIR_XTRA_GRAF = string_make(path);
-
- /* Validate the "graf" directory */
- validate_dir(ANGBAND_DIR_XTRA_GRAF);
-
- /* Build the filename */
- path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, "8X8.BMP");
-
- /* Hack -- Validate the basic graf */
- validate_file(path);
-
-#endif
-
-#ifdef USE_SOUND
- /* Build the "sound" path */
- path_build(path, 1024, ANGBAND_DIR_XTRA, "sound");
-
- /* Allocate the path */
- ANGBAND_DIR_XTRA_SOUND = string_make(path);
-
- /* Validate the "sound" directory */
- validate_dir(ANGBAND_DIR_XTRA_SOUND);
-
-#endif
/* Build the "help" path */
path_build(path, 1024, ANGBAND_DIR_XTRA, "help");
/* Allocate the path */
- ANGBAND_DIR_XTRA_HELP = string_make(path);
+ ANGBAND_DIR_XTRA_HELP = strdup(path);
/* Validate the "help" directory */
/* validate_dir(ANGBAND_DIR_XTRA_HELP); */
@@ -4025,7 +3274,6 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
/* Temporary hooks */
plog_aux = hack_plog;
quit_aux = hack_quit;
- core_aux = hack_quit;
/* Prepare the filepaths */
init_stuff();
diff --git a/src/main-x11.c b/src/main-x11.c
index 9a106bd6..6d122744 100644
--- a/src/main-x11.c
+++ b/src/main-x11.c
@@ -92,7 +92,9 @@
*
*/
-#include "angband.h"
+#include "loadsave.h"
+#include "util.h"
+#include "variable.h"
#ifdef USE_X11
@@ -112,15 +114,86 @@
#include <sys/time.h>
-/* /me pffts Solaris */
-#ifndef NAME_MAX
-#define NAME_MAX _POSIX_NAME_MAX
-#endif
/*
- * Include some helpful X11 code.
+ * This file is designed to be "included" by "main-x11.c" or "main-xaw.c",
+ * which will have already "included" several relevant header files.
*/
-#include "maid-x11.c"
+
+#ifndef IsModifierKey
+
+/*
+ * 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) \
+(((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal))
+
+#define IsCursorKey(keysym) \
+(((unsigned)(keysym) >= XK_Home) && ((unsigned)(keysym) < XK_Select))
+
+#define IsPFKey(keysym) \
+(((unsigned)(keysym) >= XK_KP_F1) && ((unsigned)(keysym) <= XK_KP_F4))
+
+#define IsFunctionKey(keysym) \
+(((unsigned)(keysym) >= XK_F1) && ((unsigned)(keysym) <= XK_F35))
+
+#define IsMiscFunctionKey(keysym) \
+(((unsigned)(keysym) >= XK_Select) && ((unsigned)(keysym) < XK_KP_Space))
+
+#define IsModifierKey(keysym) \
+(((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R))
+
+#endif /* IsModifierKey */
+
+
+/*
+ * 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)
+
+
+/*
+ * Hack -- Convert an RGB value to an X11 Pixel, or die.
+ *
+ * Original code by Desvignes Sebastien (desvigne@solar12.eerie.fr).
+ *
+ * BMP format support by Denis Eropkin (denis@dream.homepage.ru).
+ *
+ * Major fixes and cleanup by Ben Harrison (benh@phial.com).
+ */
+static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue)
+{
+ Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy));
+
+ char cname[8];
+
+ XColor xcolour;
+
+ /* Build the color */
+
+ xcolour.red = red * 255 + red;
+ xcolour.green = green * 255 + green;
+ xcolour.blue = blue * 255 + blue;
+ xcolour.flags = DoRed | DoGreen | DoBlue;
+
+ /* Attempt to Allocate the Parsed color */
+ if (!(XAllocColor(dpy, cmap, &xcolour)))
+ {
+ quit_fmt("Couldn't allocate bitmap color '%s'\n", cname);
+ }
+
+ return (xcolour.pixel);
+}
+
+
/*
@@ -707,7 +780,7 @@ static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
Window xid;
/* Wipe it clean */
- (void)WIPE(Infowin, infowin);
+ memset(Infowin, 0, sizeof(struct infowin));
/*** Error Check XXX ***/
@@ -942,7 +1015,7 @@ static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
/*** Initialize ***/
/* Wipe the iclr clean */
- (void)WIPE(iclr, infoclr);
+ memset(iclr, 0, sizeof(struct infoclr));
/* Assign the GC */
iclr->gc = gc;
@@ -1009,11 +1082,7 @@ static errr Infofnt_prepare(XFontStruct *info)
ifnt->asc = info->ascent;
ifnt->hgt = info->ascent + info->descent;
ifnt->wid = cs->width;
- if (use_bigtile)
- ifnt->twid = 2 * ifnt->wid;
- else
- ifnt->twid = ifnt->wid;
-
+ ifnt->twid = ifnt->wid;
/* Success */
return (0);
@@ -1046,7 +1115,7 @@ static errr Infofnt_init_data(cptr name)
/*** Init the font ***/
/* Wipe the thing */
- (void)WIPE(Infofnt, infofnt);
+ memset(Infofnt, 0, sizeof(struct infofnt));
/* Attempt to prepare it */
if (Infofnt_prepare(info))
@@ -1059,7 +1128,7 @@ static errr Infofnt_init_data(cptr name)
}
/* Save a copy of the font name */
- Infofnt->name = string_make(name);
+ Infofnt->name = strdup(name);
/* Mark it as nukable */
Infofnt->nuke = 1;
@@ -1214,14 +1283,6 @@ struct term_data
infowin *win;
-#ifdef USE_GRAPHICS
-
- XImage *tiles;
-
- /* Tempory storage for overlaying tiles. */
- XImage *TmpImage;
-
-#endif
};
@@ -2104,56 +2165,6 @@ static errr Term_xtra_x11(int n, int v)
/* Clear the screen, and redraw any selection later. */
case TERM_XTRA_CLEAR: Infowin_wipe(); s_ptr->drawn = FALSE; return (0);
- /* Delay for some milliseconds */
- case TERM_XTRA_DELAY:
- usleep(1000 * v);
- return (0);
-
- /* Get Delay of some milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- int ret;
- struct timeval tv;
-
- ret = gettimeofday(&tv, NULL);
- Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- return ret;
- }
-
- /* Subdirectory scan */
- case TERM_XTRA_SCANSUBDIR:
- {
- DIR *directory;
- struct dirent *entry;
-
- scansubdir_max = 0;
-
- directory = opendir(scansubdir_dir);
- if (!directory)
- return 1;
-
- while ((entry = readdir(directory)))
- {
- char file[PATH_MAX + NAME_MAX + 2];
- struct stat filedata;
-
- file[PATH_MAX + NAME_MAX] = 0;
- strncpy(file, scansubdir_dir, PATH_MAX);
- strncat(file, "/", 2);
- strncat(file, entry->d_name, NAME_MAX);
- if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] = string_make(entry->d_name);
- ++scansubdir_max;
- }
- }
-
- closedir(directory);
- return 0;
- }
-
/* React to changes */
case TERM_XTRA_REACT: return (Term_xtra_x11_react());
@@ -2176,11 +2187,8 @@ static errr Term_curs_x11(int x, int y)
/* Draw the cursor */
Infoclr_set(xor);
- if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x + 1] == 255)
- Infofnt_text_non(x, y, " ", 2);
- else
- /* Hilite the cursor character */
- Infofnt_text_non(x, y, " ", 1);
+ /* Hilite the cursor character */
+ Infofnt_text_non(x, y, " ", 1);
/* Redraw the selection if any, as it may have been obscured. (later) */
s_ptr->drawn = FALSE;
@@ -2225,170 +2233,6 @@ static errr Term_text_x11(int x, int y, int n, byte a, cptr s)
}
-#ifdef USE_GRAPHICS
-
-/*
- * Draw some graphical characters.
- */
-static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp,
- const byte *tap, const char *tcp, const byte *eap, const char *ecp)
-{
- int i, x1, y1;
-
- byte a;
- char c;
-
- byte ta;
- char tc;
- int x2, y2;
-
- byte ea;
- char ec;
- int x3, y3;
- bool_ has_overlay;
-
- int k, l;
-
- unsigned long pixel, blank;
-
- term_data *td = (term_data*)(Term->data);
-
- y *= Infofnt->hgt;
- x *= Infofnt->wid;
-
- /* Add in affect of window boundaries */
- y += Infowin->oy;
- x += Infowin->ox;
-
- for (i = 0; i < n; ++i, x += td->fnt->wid)
- {
- a = *ap++;
- c = *cp++;
-
- /* For extra speed - cache these values */
- x1 = (c & 0x7F) * td->fnt->twid;
- y1 = (a & 0x7F) * td->fnt->hgt;
-
- ta = *tap++;
- tc = *tcp++;
-
- /* For extra speed - cache these values */
- x2 = (tc & 0x7F) * td->fnt->twid;
- y2 = (ta & 0x7F) * td->fnt->hgt;
-
- ea = *eap++;
- ec = *ecp++;
- has_overlay = (ea && ec);
-
- /* For extra speed - cache these values too */
- x3 = (ec & 0x7F) * td->fnt->twid;
- y3 = (ea & 0x7F) * td->fnt->hgt;
-
- /* Optimise the common case */
- if ((x1 == x2) && (y1 == y2))
- {
- /* Draw object / terrain */
- if (!has_overlay)
- {
- XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->tiles,
- x1, y1,
- x, y,
- td->fnt->twid, td->fnt->hgt);
- }
-
- /* There's a terrain overlay */
- else
- {
- /* Mega Hack^2 - assume the top left corner is "black" */
- blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6);
- for (k = 0; k < td->fnt->twid; k++)
- {
- for (l = 0; l < td->fnt->hgt; l++)
- {
- /* If mask set in overlay... */
- if ((pixel = XGetPixel(td->tiles, x3 + k, y3 + l)) == blank)
- {
- /* Output from the terrain */
- pixel = XGetPixel(td->tiles, x1 + k, y1 + l);
- }
-
- /* Store into the temp storage. */
- XPutPixel(td->TmpImage, k, l, pixel);
- }
- }
-
- /* Draw to screen */
- XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->TmpImage,
- 0, 0, x, y,
- td->fnt->twid, td->fnt->hgt);
- }
-
- }
- else
- {
-
- /* Mega Hack^2 - assume the top left corner is "black" */
- blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6);
-
- for (k = 0; k < td->fnt->twid; k++)
- {
- for (l = 0; l < td->fnt->hgt; l++)
- {
- /* Overlay */
- if (has_overlay)
- {
- pixel = XGetPixel(td->tiles, x3 + k, y3 + l);
- }
-
- /* Hack -- No overlay */
- else
- {
- pixel = blank;
- }
-
- /* If it's blank... */
- if (pixel == blank)
- {
- /* Look at mon/obj */
- pixel = XGetPixel(td->tiles, x1 + k, y1 + l);
- }
-
- /* If it's blank too, use terrain */
- if (pixel == blank)
- {
- pixel = XGetPixel(td->tiles, x2 + k, y2 + l);
- }
-
- /* Store into the temp storage. */
- XPutPixel(td->TmpImage, k, l, pixel);
- }
- }
-
-
-
- /* Draw to screen */
- XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->TmpImage,
- 0, 0, x, y,
- td->fnt->twid, td->fnt->hgt);
- }
-
- x += td->fnt->wid;
- }
-
- /* Redraw the selection if any, as it may have been obscured. (later) */
- s_ptr->drawn = FALSE;
-
- /* Success */
- return (0);
-}
-
-#endif /* USE_GRAPHICS */
@@ -2527,7 +2371,11 @@ static errr term_data_init(term_data *td, int i)
/* Prepare the standard font */
- MAKE(td->fnt, infofnt);
+ td->fnt = calloc(1, sizeof(struct infofnt));
+ if (td->fnt == NULL)
+ {
+ abort();
+ }
Infofnt_set(td->fnt);
Infofnt_init_data(font);
@@ -2539,7 +2387,11 @@ static errr term_data_init(term_data *td, int i)
hgt = rows * td->fnt->hgt + (oy + oy);
/* Create a top-window */
- MAKE(td->win, infowin);
+ td->win = calloc(1, sizeof(struct infowin));
+ if (td->win == NULL)
+ {
+ abort();
+ }
Infowin_set(td->win);
Infowin_init_top(x, y, wid, hgt, 0,
Metadpy->fg, Metadpy->bg);
@@ -2656,17 +2508,6 @@ errr init_x11(int argc, char *argv[])
int num_term = 1;
-#ifdef USE_GRAPHICS
-
- char filename[1024];
-
- int pict_wid = 0;
- int pict_hgt = 0;
- bool_ force_old_graphics = FALSE;
-
- char *TmpData;
-
-#endif /* USE_GRAPHICS */
/* Parse args */
@@ -2678,27 +2519,6 @@ errr init_x11(int argc, char *argv[])
continue;
}
-#ifdef USE_GRAPHICS
-
- if (prefix(argv[i], "-s"))
- {
- smoothRescaling = FALSE;
- continue;
- }
-
- if (prefix(argv[i], "-o"))
- {
- force_old_graphics = TRUE;
- continue;
- }
-
- if (prefix(argv[i], "-b"))
- {
- arg_bigtile = use_bigtile = TRUE;
- continue;
- }
-
-#endif /* USE_GRAPHICS */
if (prefix(argv[i], "-n"))
{
@@ -2708,7 +2528,7 @@ errr init_x11(int argc, char *argv[])
continue;
}
- plog_fmt("Ignoring option: %s", argv[i]);
+ fprintf(stderr, "Ignoring option: %s", argv[i]);
}
@@ -2717,7 +2537,11 @@ errr init_x11(int argc, char *argv[])
/* Prepare cursor color */
- MAKE(xor, infoclr);
+ xor = calloc(1, sizeof(struct infoclr));
+ if (xor == NULL)
+ {
+ abort();
+ }
Infoclr_set(xor);
Infoclr_init_ppn(Metadpy->fg, Metadpy->bg, "xor", 0);
@@ -2727,8 +2551,11 @@ errr init_x11(int argc, char *argv[])
{
Pixell pixel;
- MAKE(clr[i], infoclr);
-
+ clr[i] = calloc(1, sizeof(struct infoclr));
+ if (clr[i] == NULL)
+ {
+ abort();
+ }
Infoclr_set(clr[i]);
/* Acquire Angband colors */
@@ -2775,102 +2602,6 @@ errr init_x11(int argc, char *argv[])
Term_activate(&data[0].t);
-#ifdef USE_GRAPHICS
-
- /* Try graphics */
- if (arg_graphics)
- {
- /* Try the "16x16.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");
-
- /* Use the "16x16.bmp" file if it exists */
- if (!force_old_graphics &&
- (0 == fd_close(fd_open(filename, O_RDONLY))))
- {
- /* Use graphics */
- use_graphics = TRUE;
-
- pict_wid = pict_hgt = 16;
-
- ANGBAND_GRAF = "new";
- }
- else
- {
- /* Try the "8x8.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");
-
- /* Use the "8x8.bmp" file if it exists */
- if (0 == fd_close(fd_open(filename, O_RDONLY)))
- {
- /* Use graphics */
- use_graphics = TRUE;
-
- pict_wid = pict_hgt = 8;
-
- ANGBAND_GRAF = "old";
- }
- }
- }
-
- /* Load graphics */
- if (use_graphics)
- {
- Display *dpy = Metadpy->dpy;
-
- XImage *tiles_raw;
-
- /* Load the graphical tiles */
- tiles_raw = ReadBMP(dpy, filename);
-
- /* Initialize the windows */
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
-
- term *t = &td->t;
-
- /* Graphics hook */
- t->pict_hook = Term_pict_x11;
-
- /* Use graphics sometimes */
- t->higher_pict = TRUE;
-
- /* Resize tiles */
- td->tiles =
- ResizeImage(dpy, tiles_raw,
- pict_wid, pict_hgt,
- td->fnt->twid, td->fnt->hgt);
- }
-
- /* Initialize the transparency masks */
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
- int ii, jj;
- int depth = DefaultDepth(dpy, DefaultScreen(dpy));
- Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
- int total;
-
-
- /* Determine total bytes needed for image */
- ii = 1;
- jj = (depth - 1) >> 2;
- while (jj >>= 1) ii <<= 1;
- total = td->fnt->twid * td->fnt->hgt * ii;
-
-
- TmpData = (char *)malloc(total);
-
- td->TmpImage = XCreateImage(dpy, visual, depth,
- ZPixmap, 0, TmpData,
- td->fnt->twid, td->fnt->hgt, 8, 0);
-
- }
-
- /* Free tiles_raw? XXX XXX */
- }
-
-#endif /* USE_GRAPHICS */
/* Success */
diff --git a/src/main-xaw.c b/src/main-xaw.c
deleted file mode 100644
index 8de36a95..00000000
--- a/src/main-xaw.c
+++ /dev/null
@@ -1,1880 +0,0 @@
-/* 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, compile with "USE_XAW" defined, and link against all
- * the various "X11" libraries which may be needed.
- *
- * 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).
- *
- * Initial framework (and some code) by Ben Harrison (benh@phial.com).
- *
- * Most of this file is by Torbjorn Lindgren (tl@cd.chalmers.se).
- *
- * Major modifications by Ben Harrison (benh@phial.com).
- */
-
-
-#include "angband.h"
-
-
-#ifdef USE_XAW
-
-
-#ifndef __MAKEDEPEND__
-#include <X11/Xlib.h>
-#include <X11/StringDefs.h>
-#include <X11/Xutil.h>
-#include <X11/Intrinsic.h>
-#include <X11/Shell.h>
-#include <X11/keysym.h>
-#include <X11/keysymdef.h>
-#include <X11/IntrinsicP.h>
-#include <X11/CoreP.h>
-#include <X11/ShellP.h>
-#include <X11/StringDefs.h>
-#include <X11/Xaw/SimpleP.h>
-#include <X11/Xaw/Simple.h>
-#include <X11/Xaw/XawInit.h>
-#endif /* __MAKEDEPEND__ */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
-
-/* /me pffts Solaris */
-#ifndef NAME_MAX
-#define NAME_MAX _POSIX_NAME_MAX
-#endif
-
-
-/*
- * Include some helpful X11 code.
- */
-#include "maid-x11.c"
-
-
-
-/**** Resources ****/
-
-
-/*
-
-Name Class RepType Default Value
----- ----- ------- -------------
-background Background Pixel XtDefaultBackground
-border BorderColor Pixel XtDefaultForeground
-borderWidth BorderWidth Dimension 1
-cursor Cursor Cursor None
-cursorName Cursor String NULL
-destroyCallback Callback Pointer NULL
-height Height Dimension 0
-insensitiveBorder Insensitive Pixmap Gray
-mappedWhenManaged MappedWhenManaged Boolean True
-pointerColor Foreground Pixel XtDefaultForeground
-pointerColorBackground Background Pixel XtDefaultBackground
-sensitive Sensitive Boolean True
-width Width Dimension 0
-x Position Position 0
-y Position Position 0
-
-
-The colors can be changed using the standard Angband user pref files,
-which can also be used to provide black text on a white background,
-by setting color zero to "#FFFFFF" and color one to "#000000", since
-the other colors are unused.
-
-*/
-
-
-/*
- * New resource names
- */
-#define XtNstartRows "startRows"
-#define XtNstartColumns "startColumns"
-#define XtNminRows "minRows"
-#define XtNminColumns "minColumns"
-#define XtNmaxRows "maxRows"
-#define XtNmaxColumns "maxColumns"
-#define XtNinternalBorder "internalBorder"
-#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;
-
-typedef struct term_data term_data;
-
-
-/*
- * A structure for each "term"
- */
-struct term_data
-{
- term t;
-
- AngbandWidget widget;
-};
-
-
-/*
- * Maximum number of windows
- */
-#define MAX_TERM_DATA 8
-
-
-/*
- * An array of term_data's
- */
-static term_data data[MAX_TERM_DATA];
-
-
-/*
- * Current number of windows open
- */
-static int num_term = MAX_TERM_DATA;
-
-
-/*
- * New fields for the Angband widget record
- */
-struct AngbandPart
-{
- /* Settable resources */
- int start_rows;
- int start_columns;
- int min_rows;
- int min_columns;
- int max_rows;
- int max_columns;
- int internal_border;
- String font;
-
- XtCallbackList redraw_callbacks;
-
-#ifdef USE_GRAPHICS
-
- /* Tiles */
- XImage *tiles;
-
- /* Tempory storage for overlaying tiles. */
- XImage *TmpImage;
-
-#endif /* USE_GRAPHICS */
-
- /* Private state */
- XFontStruct *fnt;
- Dimension fontheight;
- Dimension fontwidth;
- Dimension fontascent;
-
- /* Color info for GC's */
- byte color[NUM_COLORS][4];
-
- /* GC's (including "xor") */
- GC gc[NUM_COLORS + 1];
-};
-
-
-/*
- * Full instance record declaration
- */
-struct AngbandRec
-{
- CorePart core;
- SimplePart simple;
- AngbandPart angband;
-};
-
-
-/*
- * New fields for the Angband widget class record
- */
-struct AngbandClassPart
-{
- int dummy;
-};
-
-
-/*
- * Full class record declaration
- */
-struct AngbandClassRec
-{
- CoreClassPart core_class;
- SimpleClassPart simple_class;
- AngbandClassPart angband_class;
-};
-
-
-
-/*
- * Hack -- see below
- */
-#define offset(field) XtOffsetOf(AngbandRec, angband.field)
-
-
-/*
- * Fallback resources for Angband widget
- */
-static XtResource resources[] =
-{
- { XtNstartRows, XtCValue, XtRInt, sizeof(int),
- offset(start_rows), XtRImmediate, (XtPointer) 24 },
- { XtNstartColumns, XtCValue, XtRInt, sizeof(int),
- offset(start_columns), XtRImmediate, (XtPointer) 80 },
- { XtNminRows, XtCValue, XtRInt, sizeof(int),
- offset(min_rows), XtRImmediate, (XtPointer) 1 },
- { XtNminColumns, XtCValue, XtRInt, sizeof(int),
- offset(min_columns), XtRImmediate, (XtPointer) 1 },
- { XtNmaxRows, XtCValue, XtRInt, sizeof(int),
- offset(max_rows), XtRImmediate, (XtPointer) 255 },
- { XtNmaxColumns, XtCValue, XtRInt, sizeof(int),
- offset(max_columns), XtRImmediate, (XtPointer) 255 },
- { XtNinternalBorder, XtCValue, XtRInt, sizeof(int),
- offset(internal_border), XtRImmediate, (XtPointer) 2 },
- { XtNfont, XtCFont, XtRString, sizeof(char *),
- offset(font), XtRString, DEFAULT_X11_FONT },
- { 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);
-static void Resize_term(AngbandWidget wnew);
-
-/*
- * 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),
- /* class_initialize */ NULL,
- /* class_part_initialize*/ NULL,
- /* class_inited */ FALSE,
- /* initialize */ (XtInitProc) Initialize,
- /* initialize_hook */ NULL,
- /* realize */ XtInheritRealize,
- /* actions */ NULL,
- /* num_actions */ 0,
- /* resources */ resources,
- /* num_resources */ XtNumber(resources),
- /* xrm_class */ NULLQUARK,
- /* compress_motion */ TRUE,
- /* compress_exposure */ XtExposeCompressMultiple,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ (XtWidgetProc) Destroy,
- /* resize */ (XtWidgetProc) Resize_term,
- /* expose */ (XtExposeProc) Redisplay,
- /* set_values */ (XtSetValuesFunc) SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback_private */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ NULL,
- /* display_accelerator */ XtInheritDisplayAccelerator,
- /* extension */ NULL
- },
- /* Simple class fields initialization */
- {
- /* change_sensitive */ XtInheritChangeSensitive
-#ifndef OLDXAW
- , NULL
-#endif
- },
- /* Angband class fields initialization */
- {
- /* nothing */ 0
- }
-};
-
-/*
- * Hack -- see above
- */
-#undef superclass
-
-
-/*
- * Class record pointer
- */
-WidgetClass angbandWidgetClass = (WidgetClass) &angbandClassRec;
-
-
-/*
- * Public procedures
- */
-
-/*
- * Simple routine to save the state of the game when the display connection
- * is broken. Remember, you cannot do anything in this function that will
- * generate X protocol requests.
- */
-static int x_io_error_handler(Display *d)
-{
- /* We have nothing to save */
- if (!character_generated) return 0;
-
- save_dungeon();
- save_player();
-
- return 0;
-}
-
-
-/*
- * Clear an area
- */
-static void AngbandClearArea(AngbandWidget widget,
- int x, int y, int w, int h, int a)
-{
- /* Figure out which area to clear */
- y = y * widget->angband.fontheight + widget->angband.internal_border;
- x = x * widget->angband.fontwidth + widget->angband.internal_border;
-
- /* Clear the area */
- XFillRectangle(XtDisplay(widget), XtWindow(widget),
- widget->angband.gc[a],
- x, y,
- widget->angband.fontwidth * w,
- widget->angband.fontheight * h);
-}
-
-
-
-/*
- * Output some text
- */
-static void AngbandOutputText(AngbandWidget widget, int x, int y,
- String txt, int len, int a)
-{
- /* 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[a], 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, const byte *tap, const char *tcp,
- const byte *eap, const char *ecp)
-{
- int i, x1, y1;
-
- byte a;
- char c;
-
- byte ta;
- char tc;
-
- int x2, y2;
-
- byte ea;
- char ec;
-
- int x3, y3;
- bool_ has_overlay;
-
- int k, l;
- unsigned long pixel, blank;
-
- /* 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++;
-
- /* For extra speed - cache these values */
- x1 = (c & 0x7F) * widget->angband.fontwidth;
- y1 = (a & 0x7F) * widget->angband.fontheight;
-
- ta = *tap++;
- tc = *tcp++;
-
- /* For extra speed - cache these values */
- x2 = (tc & 0x7F) * widget->angband.fontwidth;
- y2 = (ta & 0x7F) * widget->angband.fontheight;
-
- ea = *eap++;
- ec = *ecp++;
- has_overlay = (ea && ec);
-
- /* For extra speed -- cache these values */
- x3 = (ec & 0x7F) * widget->angband.fontwidth;
- y3 = (ea & 0x7F) * widget->angband.fontheight;
-
- /* Optimise the common case */
- if ((x1 == x2) && (y1 == y2))
- {
-
- /* No overlay */
- if (!has_overlay)
- {
- /* Draw object / terrain */
- XPutImage(XtDisplay(widget), XtWindow(widget),
- widget->angband.gc[0],
- widget->angband.tiles,
- x1, y1,
- x, y,
- widget->angband.fontwidth,
- widget->angband.fontheight);
- }
-
- /* Terrain overlay */
- else
- {
- /* Mega Hack^2 - assume the top left corner is "black" */
- blank = XGetPixel(widget->angband.tiles,
- 0, widget->angband.fontheight * 6);
-
- for (k = 0; k < widget->angband.fontwidth; k++)
- {
- for (l = 0; l < widget->angband.fontheight; l++)
- {
- /* If mask set... */
- if ((pixel = XGetPixel(widget->angband.tiles,
- x3 + k, y3 + l)) == blank)
- {
- /* Output from the terrain */
- pixel = XGetPixel(widget->angband.tiles,
- x1 + k, y1 + l);
- }
-
- /* Store into the temp storage */
- XPutPixel(widget->angband.TmpImage,
- k, l, pixel);
- }
- }
-
- /* Draw terrain + overlay */
- XPutImage(XtDisplay(widget), XtWindow(widget),
- widget->angband.gc[0],
- widget->angband.TmpImage,
- 0, 0,
- x, y,
- widget->angband.fontwidth,
- widget->angband.fontheight);
- }
-
- }
- else
- {
- /* Mega Hack^2 - assume the top left corner is "black" */
- blank = XGetPixel(widget->angband.tiles,
- 0, widget->angband.fontheight * 6);
-
- for (k = 0; k < widget->angband.fontwidth; k++)
- {
- for (l = 0; l < widget->angband.fontheight; l++)
- {
- /* Get overlay pixel */
- if (has_overlay)
- {
- pixel = XGetPixel(widget->angband.tiles,
- x3 + k, y3 + l);
- }
-
- /* Hack -- no overlay */
- else
- {
- pixel = blank;
- }
-
- /* If it's blank */
- if (pixel == blank)
- {
- /* Use obj/mon */
- pixel = XGetPixel(widget->angband.tiles,
- x1 + k, y1 + l);
- }
-
- /* Use terrain if it's blank too */
- if (pixel == blank)
- {
- pixel = XGetPixel(widget->angband.tiles,
- x2 + k, y2 + l);
- }
-
- /* Store into the temp storage. */
- XPutPixel(widget->angband.TmpImage,
- k, l, pixel);
- }
- }
-
- /* Draw to screen */
-
- /* Draw object / terrain */
- XPutImage(XtDisplay(widget), XtWindow(widget),
- widget->angband.gc[0],
- widget->angband.TmpImage,
- 0, 0,
- 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)
-{
- Display *dpy = XtDisplay(wnew);
-
- int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));
-
- XGCValues gcv;
- TopLevelShellWidget parent =
- (TopLevelShellWidget)XtParent((Widget) wnew);
- int i;
-
- /* Default background pixel */
- unsigned long bg = create_pixel(dpy,
- angband_color_table[0][1],
- angband_color_table[0][2],
- angband_color_table[0][3]);
-
- /* Default foreground pixel */
- unsigned long fg = create_pixel(dpy,
- angband_color_table[1][1],
- angband_color_table[1][2],
- angband_color_table[1][3]);
-
- /* Fix the background color */
- wnew->core.background_pixel = bg;
-
- /* 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 = bg;
-
- for (i = 0; i < NUM_COLORS; i++)
- {
- unsigned long pixel;
-
- /* Acquire Angband colors */
- wnew->angband.color[i][0] = angband_color_table[i][0];
- wnew->angband.color[i][1] = angband_color_table[i][1];
- wnew->angband.color[i][2] = angband_color_table[i][2];
- wnew->angband.color[i][3] = angband_color_table[i][3];
-
- if (depth > 1)
- {
- /* Create pixel */
- pixel = create_pixel(dpy,
- wnew->angband.color[i][1],
- wnew->angband.color[i][2],
- wnew->angband.color[i][3]);
- }
- else
- {
- /* Use background or foreground */
- pixel = ((i == 0) ? bg : fg);
- }
-
- gcv.foreground = pixel;
-
- /* Copy */
- gcv.function = 3;
-
- wnew->angband.gc[i] = XtGetGC((Widget)wnew,
- (GCFont | GCForeground | GCFunction |
- GCBackground | GCGraphicsExposures),
- &gcv);
- }
-
- /* Create a special GC for highlighting */
- gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)wnew)) ^
- WhitePixelOfScreen(XtScreen((Widget)wnew)));
- gcv.background = 0;
-
- gcv.function = GXxor;
- wnew->angband.gc[COLOR_XOR] = XtGetGC((Widget)wnew,
- (GCFunction | GCForeground | GCBackground |
- GCGraphicsExposures),
- &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 wants 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
- * fonts.
- */
-static void Destroy(AngbandWidget widget)
-{
- int n;
-
- /* Free all GC's */
- for (n = 0; n < NUM_COLORS + 1; n++)
- {
- XtReleaseGC((Widget)widget, widget->angband.gc[n]);
- }
-
- /* Free the font */
- XFreeFont(XtDisplay((Widget)widget), widget->angband.fnt);
-}
-
-
-static void Resize_term(AngbandWidget wnew)
-{
- int cols, rows, wid, hgt;
-
- int ox = wnew->angband.internal_border;
- int oy = wnew->angband.internal_border;
-
- int i;
- term_data *old_td;
- term_data *td = &data[0];
-
-
- /*
- * Mega-Hack -- avoid calling this before the terms package is
- * initialised
- */
- if (!Term) return;
-
- old_td = (term_data*)(Term->data);
-
- /* Hack - Find the term to activate */
- for (i = 0; i < num_term; i++)
- {
- td = &data[i];
-
- /* Paranoia: none of the widgets matched */
- if (!td) return;
-
- /* Have we found it? */
- if (td->widget == wnew) break;
- }
-
- /* Paranoia -- No matches */
- if (i == num_term) return;
-
- /* Activate the proper Term */
- Term_activate(&td->t);
-
- /* Determine "proper" number of rows/cols */
- cols = ((wnew->core.width - (ox + ox)) / wnew->angband.fontwidth);
- rows = ((wnew->core.height - (oy + oy)) / wnew->angband.fontheight);
-
- /* Hack -- minimal size */
- if (cols < 1) cols = 1;
- if (rows < 1) rows = 1;
-
- if (i == 0)
- {
- /* Hack the main window must be at least 80x24 */
- if (cols < 80) cols = 80;
- if (rows < 24) rows = 24;
- }
-
- /* Desired size of window */
- wid = cols * wnew->angband.fontwidth + (ox + ox);
- hgt = rows * wnew->angband.fontheight + (oy + oy);
-
- /* Resize the Term (if needed) */
- (void) Term_resize(cols, rows);
-
- /* Activate the old term */
- Term_activate(&old_td->t);
-}
-
-/*
- * Procedure Redisplay() is called as the result of an Expose event.
- * Use the redraw callback to do a full redraw
- */
-static void Redisplay(AngbandWidget wnew, XEvent *xev, Region region)
-{
- int x1, x2, y1, y2;
-
- int i;
-
- term_data *old_td = (term_data*)(Term->data);
- term_data *td = &data[0];
-
- /* Hack - Find the term to activate */
- for (i = 0; i < num_term; i++)
- {
- td = &data[i];
-
- /* Have we found it? */
- if (td->widget == wnew) break;
-
- /* Paranoia: none of the widgets matched */
- if (!td) return;
- }
-
- /* Activate the proper Term */
- Term_activate(&td->t);
-
- /* Find the bounds of the exposed region */
-
- /*
- * This probably could be obtained from the Region parameter -
- * but I don't know anything about XAW.
- */
- x1 = (xev->xexpose.x - wnew->angband.internal_border)
- / wnew->angband.fontwidth;
- x2 = (xev->xexpose.x + xev->xexpose.width -
- wnew->angband.internal_border) / wnew->angband.fontwidth;
-
- y1 = (xev->xexpose.y - wnew->angband.internal_border)
- / wnew->angband.fontheight;
- y2 = (xev->xexpose.y + xev->xexpose.height -
- wnew->angband.internal_border) / wnew->angband.fontheight;
-
- Term_redraw_section(x1, y1, x2, y2);
-
- /* Activate the old term */
- Term_activate(&old_td->t);
-}
-
-
-/*
- * Font 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).
- *
- * Color changes are handled elsewhere.
- *
- * This function is very underspecified, in terms of how these changes can
- * occur, and what is true about the various AngbandWidget's passed in. It
- * is very likely that this code no longer works.
- */
-static Boolean SetValues(AngbandWidget current, AngbandWidget request,
- AngbandWidget wnew, ArgList args,
- Cardinal *num_args)
-{
- Display *dpy = XtDisplay(wnew);
-
- Boolean font_changed = FALSE;
- Boolean border_changed = FALSE;
- int height, width;
- int i;
-
-
- /* Handle font change */
- if (wnew->angband.font != current->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 requested 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;
- }
- }
-
- /* Handle font change */
- if (font_changed)
- {
- /* Update all GC's */
- for (i = 0; i < NUM_COLORS; i++)
- {
- /* Steal the old GC */
- wnew->angband.gc[i] = current->angband.gc[i];
- current->angband.gc[i] = NULL;
-
- /* Be sure the correct font is ready */
- XSetFont(dpy, wnew->angband.gc[i], wnew->angband.fnt->fid);
- }
-
- /* Steal the old GC */
- wnew->angband.gc[NUM_COLORS] = current->angband.gc[NUM_COLORS];
- current->angband.gc[NUM_COLORS] = NULL;
- }
-
-
- /* 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 */
- /* has to be recalculated */
- 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 */
- XtWarning("Size change denied!");
- }
- else
- {
- /* Recalculate size hints */
- calculateSizeHints(wnew);
- }
- }
-
- /* Tell it to redraw the widget if anything has changed */
- return (font_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
- */
-static XFontStruct *getFont(AngbandWidget widget,
- String font, Boolean fallback)
-{
- Display *dpy = XtDisplay((Widget) widget);
- char buf[256];
- XFontStruct *fnt = NULL;
-
- if (!(fnt = XLoadQueryFont(dpy, font)) && fallback)
- {
- sprintf(buf, "Can't find the font \"%s\", trying fixed\n", font);
- XtWarning(buf);
- if (!(fnt = XLoadQueryFont(dpy, "fixed")))
- {
- XtError("Can't fint the font \"fixed\"!, bailing out\n");
- }
- }
-
- return fnt;
-}
-
-
-
-/*** The Angband code ****/
-
-
-
-
-
-/*
- * Number of fallback resources per window
- */
-#define TERM_FALLBACKS 6
-
-
-
-/*
- * The names of the term_data's
- */
-char *termNames[MAX_TERM_DATA] =
-{
- "angband",
- "mirror",
- "recall",
- "choice",
- "term-4",
- "term-5",
- "term-6",
- "term-7"
-};
-
-
-/*
- * The special Arg's
- */
-Arg specialArgs[TERM_FALLBACKS] =
-{
- { XtNstartRows, 24},
- { XtNstartColumns, 80},
- { XtNminRows, 24},
- { XtNminColumns, 80},
- { XtNmaxRows, 255},
- { XtNmaxColumns, 255}
-};
-
-
-/*
- * The default Arg's
- */
-Arg defaultArgs[TERM_FALLBACKS] =
-{
- { XtNstartRows, 24},
- { XtNstartColumns, 80},
- { XtNminRows, 1},
- { XtNminColumns, 1},
- { XtNmaxRows, 255},
- { XtNmaxColumns, 255}
-};
-
-
-/*
- * The application context
- */
-XtAppContext appcon;
-
-
-/*
- * User changable information about widgets
- */
-static String fallback[] =
-{
- "Angband.angband.iconName: ToME",
- "Angband.angband.title: ToME",
- "Angband.term-1.iconName: Mirror",
- "Angband.term-1.title: Mirror",
- "Angband.term-2.iconName: Recall",
- "Angband.term-2.title: Recall",
- "Angband.term-3.iconName: Choice",
- "Angband.term-3.title: Choice",
- "Angband.term-4.iconName: Term 4",
- "Angband.term-4.title: Term 4",
- "Angband.term-5.iconName: Term 5",
- "Angband.term-5.title: Term 5",
- "Angband.term-6.iconName: Term 6",
- "Angband.term-6.title: Term 6",
- "Angband.term-7.iconName: Term 7",
- "Angband.term-7.title: Term 7",
- NULL
-};
-
-
-
-/*
- * Do a redraw
- */
-static void react_redraw(Widget widget,
- XtPointer client_data, XtPointer call_data)
-{
- term_data *old_td = (term_data*)(Term->data);
- term_data *td = (term_data*)client_data;
-
- /* Activate the proper Term */
- Term_activate(&td->t);
-
- /* Request a redraw */
- Term_redraw();
-
- /* Activate the old Term */
- 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];
- char msg[128];
-
-
- /* Check for "normal" keypresses */
- n = XLookupString(ev, buf, 125, &ks, NULL);
-
- /* 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))
- {
- /* Enqueue the normal key(s) */
- for (i = 0; buf[i]; i++) Term_keypress(buf[i]);
-
- /* All done */
- 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)
- {
- sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
- mc ? "N" : "", ms ? "S" : "",
- mo ? "O" : "", mx ? "M" : "",
- (unsigned long)(ks), 13);
- }
-
- /* Hack -- Use the Keycode */
- else
- {
- sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
- mc ? "N" : "", ms ? "S" : "",
- mo ? "O" : "", mx ? "M" : "",
- 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;
-
- /* Continue to process the event by default */
- *continue_to_dispatch = TRUE;
-
- /* Activate the Term */
- Term_activate(&td->t);
-
- 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 */
- Term_activate(&old_td->t);
-
- return;
-}
-
-
-/*
- * Process an event (or just check for one)
- */
-errr CheckEvent(bool_ wait)
-{
- XEvent event;
-
- /* No events ready, and told to just check */
- if (!wait && !XtAppPending(appcon)) return 1;
-
- /* Process */
- while (1)
- {
- XtAppNextEvent(appcon, &event);
- XtDispatchEvent(&event);
- if (!XtAppPending(appcon)) break;
- }
-
- return (0);
-}
-
-
-/*
- * Monstrous hack.
- */
-static void Term_xtra_xaw_react_aux(term_data *td)
-{
- AngbandWidget wnew = td->widget;
-
- Display *dpy = XtDisplay((Widget) wnew);
-
- int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));
-
- int i;
-
- /* See if any colors need to be changed */
- for (i = 0; i < NUM_COLORS; i++)
- {
- if (depth > 1)
- {
- if ((wnew->angband.color[i][0] != angband_color_table[i][0]) ||
- (wnew->angband.color[i][1] != angband_color_table[i][1]) ||
- (wnew->angband.color[i][2] != angband_color_table[i][2]) ||
- (wnew->angband.color[i][3] != angband_color_table[i][3]))
- {
- unsigned long pixel;
-
- /* Save new values */
- wnew->angband.color[i][0] = angband_color_table[i][0];
- wnew->angband.color[i][1] = angband_color_table[i][1];
- wnew->angband.color[i][2] = angband_color_table[i][2];
- wnew->angband.color[i][3] = angband_color_table[i][3];
-
- /* Create pixel */
- pixel = create_pixel(dpy,
- wnew->angband.color[i][1],
- wnew->angband.color[i][2],
- wnew->angband.color[i][3]);
-
-
- /* Change */
- XSetForeground(dpy, wnew->angband.gc[i], pixel);
- }
- }
- }
-}
-
-
-/*
- * Monstrous hack.
- */
-static errr Term_xtra_xaw_react(void)
-{
- int i;
-
- /* Initialize the windows */
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
-
- if (!td) break;
-
- Term_xtra_xaw_react_aux(td);
- }
-
- return (0);
-}
-
-
-/*
- * Handle a "special request"
- */
-static errr Term_xtra_xaw(int n, int v)
-{
- term_data *td = (term_data*)(Term->data);
-
- Widget widget = (Widget)(td->widget);
-
- Display *dpy = XtDisplay(widget);
-
- /* Handle a subset of the legal requests */
- switch (n)
- {
- /* Make a noise */
- case TERM_XTRA_NOISE:
- XBell(dpy, 100);
- return (0);
-
- /* Flush the output */
- case TERM_XTRA_FRESH:
- XFlush(dpy);
- /* Allow flushed events to be showed */
- CheckEvent(FALSE);
- return (0);
-
- /* Process random events */
- case TERM_XTRA_BORED:
- return (CheckEvent(0));
-
- /* Process events */
- case TERM_XTRA_EVENT:
- return (CheckEvent(v));
-
- /* Flush events */
- case TERM_XTRA_FLUSH:
- while (!CheckEvent(FALSE));
- return (0);
-
- /* Clear the window */
- case TERM_XTRA_CLEAR:
- XClearWindow(dpy, XtWindow(widget));
- return (0);
-
- /* Delay */
- case TERM_XTRA_DELAY:
- usleep(1000 * v);
- return (0);
-
- /* Get Delay of some milliseconds */
- case TERM_XTRA_GET_DELAY:
- {
- int ret;
- struct timeval tv;
-
- ret = gettimeofday(&tv, NULL);
- Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- return ret;
- }
-
- /* Subdirectory scan */
- case TERM_XTRA_SCANSUBDIR:
- {
- DIR *directory;
- struct dirent *entry;
-
- scansubdir_max = 0;
-
- directory = opendir(scansubdir_dir);
- if (!directory)
- return 1;
-
- while (entry = readdir(directory))
- {
- char file[PATH_MAX + NAME_MAX + 2];
- struct stat filedata;
-
- file[PATH_MAX + NAME_MAX] = 0;
- strncpy(file, scansubdir_dir, PATH_MAX);
- strncat(file, "/", 2);
- strncat(file, entry->d_name, NAME_MAX);
- if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
- {
- string_free(scansubdir_result[scansubdir_max]);
- scansubdir_result[scansubdir_max] = string_make(entry->d_name);
- ++scansubdir_max;
- }
- }
- }
-
- case TERM_XTRA_REACT:
- return (Term_xtra_xaw_react());
- }
-
- /* Unknown */
- return (1);
-}
-
-
-
-/*
- * Erase a number of characters
- */
-static errr Term_wipe_xaw(int x, int y, int n)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Erase using color 0 */
- AngbandClearArea(td->widget, x, y, n, 1, 0);
-
- /* Success */
- return (0);
-}
-
-
-
-/*
- * Draw the cursor, by hiliting with XOR
- *
- * Should perhaps use rectangle outline, ala "main-mac.c". XXX XXX XXX
- */
-static errr Term_curs_xaw(int x, int y)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Hilite the cursor character */
- AngbandClearArea(td->widget, x, y, 1, 1, COLOR_XOR);
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Draw a number of characters
- */
-static errr Term_text_xaw(int x, int y, int n, byte a, cptr s)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Draw the text */
- AngbandOutputText(td->widget, x, y, (String)s, n, a);
-
- /* Success */
- return (0);
-}
-
-
-#ifdef USE_GRAPHICS
-
-/*
- * Draw some graphical characters.
- */
-static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp,
- const byte *tap, const char *tcp, const byte *eap, const char *ecp)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Draw the pictures */
- AngbandOutputPict(td->widget, x, y, n, ap, cp, tap, tcp, eap, ecp);
-
- /* Success */
- return (0);
-}
-
-#endif /* USE_GRAPHICS */
-
-
-/*
- * Raise a term
- */
-static void term_raise(term_data *td)
-{
- Widget widget = (Widget)(td->widget);
-
- XRaiseWindow(XtDisplay(XtParent(widget)), XtWindow(XtParent(widget)));
-}
-
-
-/*
- * Initialize a term_data
- */
-static errr term_data_init(term_data *td, Widget topLevel,
- int key_buf, String name,
- ArgList widget_arg, Cardinal widget_arg_no, int i)
-{
- Widget parent;
- term *t = &td->t;
-
- int cols = 80;
- int rows = 24;
-
- char buf[80];
- cptr str;
-
- int val;
-
- /* Create the shell widget */
- parent = XtCreatePopupShell(name, topLevelShellWidgetClass, topLevel,
- NULL, 0);
-
- /* Window specific cols */
- sprintf(buf, "ANGBAND_X11_COLS_%d", i);
- str = getenv(buf);
- val = (str != NULL) ? atoi(str) : -1;
- if (val > 0) cols = val;
-
- /* Window specific rows */
- sprintf(buf, "ANGBAND_X11_ROWS_%d", i);
- str = getenv(buf);
- val = (str != NULL) ? atoi(str) : -1;
- if (val > 0) rows = val;
-
- /* Hack the main window must be at least 80x24 */
- if (i == 0)
- {
- if (cols < 80) cols = 80;
- if (rows < 24) rows = 24;
- }
-
- /* Reset the initial size */
- widget_arg[0].value = rows;
- widget_arg[1].value = cols;
-
- /* Create the interior widget */
- td->widget = (AngbandWidget)
- XtCreateManagedWidget(name, angbandWidgetClass,
- parent, widget_arg, widget_arg_no);
-
- /* Initialize the term (full size) */
- term_init(t, cols, rows, key_buf);
-
- /* Use a "soft" cursor */
- t->soft_cursor = TRUE;
-
- /* Erase with "white space" */
- t->attr_blank = TERM_WHITE;
- t->char_blank = ' ';
-
- /* Hooks */
- t->xtra_hook = Term_xtra_xaw;
- t->curs_hook = Term_curs_xaw;
- t->wipe_hook = Term_wipe_xaw;
- t->text_hook = Term_text_xaw;
-
- /* Save the data */
- t->data = td;
-
- /* Register the keypress event handler */
- XtAddEventHandler((Widget)td->widget, KeyPressMask,
- False, (XtEventHandler) handle_event, td);
-
- /* Redraw callback */
- XtAddCallback((Widget)td->widget, XtNredrawCallback,
- react_redraw, td);
-
- /* Realize the widget */
- XtRealizeWidget(parent);
-
- /* Make it visible */
- XtPopup(parent, XtGrabNone);
-
- /* Activate (important) */
- Term_activate(t);
-
- Resize_term(td->widget);
-
- return 0;
-}
-
-
-/*
- * Initialization function for an X Athena Widget module to Angband
- *
- * We should accept "-d<dpy>" requests in the "argv" array. XXX XXX XXX
- */
-errr init_xaw(int argc, char *argv[])
-{
- int i;
- Widget topLevel;
- Display *dpy;
-
- cptr dpy_name = "";
-
-
-#ifdef USE_GRAPHICS
-
- char filename[1024];
-
- int pict_wid = 0;
- int pict_hgt = 0;
- bool_ force_old_graphics = FALSE;
-
- char *TmpData;
-
-#endif /* USE_GRAPHICS */
-
- /* Parse args */
- for (i = 1; i < argc; i++)
- {
- if (prefix(argv[i], "-d"))
- {
- dpy_name = &argv[i][2];
- continue;
- }
-
-#ifdef USE_GRAPHICS
-
- if (prefix(argv[i], "-s"))
- {
- smoothRescaling = FALSE;
- continue;
- }
-
- if (prefix(argv[i], "-o"))
- {
- force_old_graphics = TRUE;
- continue;
- }
-
-#endif /* USE_GRAPHICS */
-
- if (prefix(argv[i], "-n"))
- {
- num_term = atoi(&argv[i][2]);
- if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
- else if (num_term < 1) num_term = 1;
- continue;
- }
-
- plog_fmt("Ignoring option: %s", argv[i]);
- }
-
-
- /* Attempt to open the local display */
- dpy = XOpenDisplay(dpy_name);
-
- /* Failure -- assume no X11 available */
- if (!dpy) return ( -1);
-
- /* Close the local display */
- XCloseDisplay(dpy);
-
-
-#ifdef USE_XAW_LANG
-
- /* Support locale processing */
- XtSetLanguageProc(NULL, NULL, NULL);
-
-#endif /* USE_XAW_LANG */
-
-
- /* Initialize the toolkit */
- topLevel = XtAppInitialize(&appcon, "Angband", NULL, 0, &argc, argv,
- fallback, NULL, 0);
-
- XSetIOErrorHandler(x_io_error_handler);
-
- /* Initialize the windows */
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
-
- term_data_init(td, topLevel, 1024, termNames[i],
- (i == 0) ? specialArgs : defaultArgs,
- TERM_FALLBACKS, i);
-
- angband_term[i] = Term;
- }
-
- /* Activate the "Angband" window screen */
- Term_activate(&data[0].t);
-
- /* Raise the "Angband" window */
- term_raise(&data[0]);
-
-
-#ifdef USE_GRAPHICS
-
- /* Try graphics */
- if (arg_graphics)
- {
- /* Try the "16x16.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");
-
- /* Use the "16x16.bmp" file if it exists */
- if (!force_old_graphics &&
- (0 == fd_close(fd_open(filename, O_RDONLY))))
- {
- /* Use graphics */
- use_graphics = TRUE;
-
- pict_wid = pict_hgt = 16;
-
- ANGBAND_GRAF = "new";
- }
- else
- {
- /* Try the "8x8.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");
-
- /* Use the "8x8.bmp" file if it exists */
- if (0 == fd_close(fd_open(filename, O_RDONLY)))
- {
- /* Use graphics */
- use_graphics = TRUE;
-
- pict_wid = pict_hgt = 8;
-
- ANGBAND_GRAF = "old";
- }
- }
- }
-
- /* Load graphics */
- if (use_graphics)
- {
- /* Hack -- Get the Display */
- term_data *td = &data[0];
- Widget widget = (Widget)(td->widget);
- Display *dpy = XtDisplay(widget);
-
- XImage *tiles_raw;
-
- /* Load the graphical tiles */
- tiles_raw = ReadBMP(dpy, filename);
-
- /* Initialize the windows */
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
-
- term *t = &td->t;
-
- t->pict_hook = Term_pict_xaw;
-
- t->higher_pict = TRUE;
-
- /* Resize tiles */
- td->widget->angband.tiles =
- ResizeImage(dpy, tiles_raw,
- pict_wid, pict_hgt,
- td->widget->angband.fontwidth,
- td->widget->angband.fontheight);
- }
-
- /* Initialize the transparency temp storage*/
- for (i = 0; i < num_term; i++)
- {
- term_data *td = &data[i];
- int ii, jj;
- int depth = DefaultDepth(dpy, DefaultScreen(dpy));
- Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
- int total;
-
-
- /* Determine total bytes needed for image */
- ii = 1;
- jj = (depth - 1) >> 2;
- while (jj >>= 1) ii <<= 1;
- total = td->widget->angband.fontwidth *
- td->widget->angband.fontheight * ii;
-
-
- TmpData = (char *)malloc(total);
-
- td->widget->angband.TmpImage = XCreateImage(dpy,
- visual, depth,
- ZPixmap, 0, TmpData,
- td->widget->angband.fontwidth,
- td->widget->angband.fontheight, 8, 0);
-
- }
-
-
- /* Free tiles_raw? XXX XXX */
- }
-
-#endif /* USE_GRAPHICS */
-
- /* Success */
- return (0);
-}
-
-#endif /* USE_XAW */
-
diff --git a/src/main-xxx.c b/src/main-xxx.c
deleted file mode 100644
index c80f01f0..00000000
--- a/src/main-xxx.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* File: main-xxx.c */
-
-/* Purpose: Sample visual module for Angband 2.8.1 */
-
-/*
- * This file written by "Ben Harrison (benh@phial.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
- * actually work, but if the code near "XXX XXX XXX" comments were
- * replaced with functional code, then it probably would.
- *
- * See "z-term.c" for info on the concept of the "generic terminal",
- * and for more comments about what this file must supply.
- *
- * There are two basic ways to port Angband to a new system. The
- * first involves modifying the "main-gcu.c" and/or "main-x11.c"
- * files to support some version of "curses" and/or "X11" on your
- * machine, and to compile with the "USE_GCU" and/or "USE_X11"
- * compilation flags defined. The second involves creating a
- * new "main-xxx.c" file, based on this sample file (or on any
- * existing "main-xxx.c" file), and comes in two flavors, based
- * on whether it contains a "main()" function (as in "main-mac.c"
- * and "main-win.c") or not (as in "main-gcu.c" or "main-x11.c").
- *
- * If the "main-xxx.c" file includes its own "main()" function,
- * then you should NOT link in the "main.c" file, and your "main()"
- * function must process any command line arguments, initialize the
- * "visual system", and call "play_game()" with appropriate arguments.
- *
- * If the "main-xxx.c" file does not include its own "main()"
- * function, then you must add some code to "main.c" which, if
- * the appropriate "USE_XXX" compilation flag is defined, will
- * attempt to call the "init_xxx()" function in the "main-xxx.c"
- * file, which should initialize the "visual system" and return
- * zero if it was successful. The "main()" function in "main.c"
- * will take care of processing command line arguments and then
- * calling "play_game()" with appropriate arguments.
- *
- * Note that the "util.c" file often contains functions which must
- * be modified in small ways for various platforms, even if you are
- * able to use the existing "main-gcu.c" and/or "main-x11.c" files,
- * in particular, the "file handling" functions may not work on all
- * systems.
- *
- * 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.
- *
- * Try to stick to a "three letter" naming scheme for "main-xxx.c"
- * and "Makefile.xxx" and such for consistency and simplicity.
- */
-
-
-#include "angband.h"
-
-
-#ifdef USE_XXX
-
-
-/*
- * Extra data to associate with each "window"
- *
- * Each "window" is represented by a "term_data" structure, which
- * contains a "term" structure, which contains a pointer (t->data)
- * back to the term_data structure.
- */
-
-typedef struct term_data term_data;
-
-struct term_data
-{
- term t;
-
- /* Other fields if needed XXX XXX XXX */
-};
-
-
-
-/*
- * Number of "term_data" structures to support XXX XXX XXX
- *
- * You MUST support at least one "term_data" structure, and the
- * game will currently use up to eight "term_data" structures if
- * they are available.
- *
- * If only one "term_data" structure is supported, then a lot of
- * the things that would normally go into a "term_data" structure
- * could be made into global variables instead.
- */
-#define MAX_TERM_DATA 1
-
-
-/*
- * An array of "term_data" structures, one for each "sub-window"
- */
-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
-
-
-
-/*** Function hooks needed by "Term" ***/
-
-
-/*
- * Init a new "term"
- *
- * This function should do whatever is necessary to prepare a new "term"
- * for use by the "term.c" package. This may include clearing the window,
- * preparing the cursor, setting the font/colors, etc. Usually, this
- * function does nothing, and the "init_xxx()" function does it all.
- */
-static void Term_init_xxx(term *t)
-{
- term_data *td = (term_data*)(t->data);
-
- /* XXX XXX XXX */
-}
-
-
-
-/*
- * Nuke an old "term"
- *
- * This function is called when an old "term" is no longer needed. It should
- * do whatever is needed to clean up before the program exits, such as wiping
- * the screen, restoring the cursor, fixing the font, etc. Often this function
- * does nothing and lets the operating system clean up when the program quits.
- */
-static void Term_nuke_xxx(term *t)
-{
- term_data *td = (term_data*)(t->data);
-
- /* XXX XXX XXX */
-}
-
-
-
-/*
- * Do a "user action" on the current "term"
- *
- * This function allows the visual module to do implementation defined
- * things when the user activates the "system defined command" command.
- *
- * This function is normally not used.
- *
- * In general, this function should return zero if the action is successfully
- * handled, and non-zero if the action is unknown or incorrectly handled.
- */
-static errr Term_user_xxx(int n)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* XXX XXX XXX */
-
- /* Unknown */
- return (1);
-}
-
-
-/*
- * Do a "special thing" to the current "term"
- *
- * This function must react to a large number of possible arguments, each
- * corresponding to a different "action request" by the "z-term.c" package,
- * or by the application itself.
- *
- * The "action type" is specified by the first argument, which must be a
- * constant of the form "TERM_XTRA_*" as given in "term.h", and the second
- * argument specifies the "information" for that argument, if any, and will
- * vary according to the first argument.
- *
- * In general, this function should return zero if the action is successfully
- * handled, and non-zero if the action is unknown or incorrectly handled.
- */
-static errr Term_xtra_xxx(int n, int v)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* Analyze */
- switch (n)
- {
- case TERM_XTRA_EVENT:
- {
- /*
- * Process some pending events XXX XXX XXX
- *
- * Wait for at least one event if "v" is non-zero
- * otherwise, if no events are ready, return at once.
- * When "keypress" events are encountered, the "ascii"
- * value corresponding to the key should be sent to the
- * "Term_keypress()" function. Certain "bizarre" keys,
- * such as function keys or arrow keys, may send special
- * sequences of characters, such as control-underscore,
- * plus letters corresponding to modifier keys, plus an
- * underscore, plus carriage return, which can be used by
- * the main program for "macro" triggers. This action
- * should handle as many events as is efficiently possible
- * but is only required to handle a single event, and then
- * only if one is ready or "v" is true.
- *
- * This action is required.
- */
-
- return (0);
- }
-
- case TERM_XTRA_FLUSH:
- {
- /*
- * Flush all pending events XXX XXX XXX
- *
- * This action should handle all events waiting on the
- * queue, optionally discarding all "keypress" events,
- * since they will be discarded anyway in "z-term.c".
- *
- * This action is required, but may not be "essential".
- */
-
- return (0);
- }
-
- case TERM_XTRA_CLEAR:
- {
- /*
- * Clear the entire window XXX XXX XXX
- *
- * This action should clear the entire window, and redraw
- * any "borders" or other "graphic" aspects of the window.
- *
- * This action is required.
- */
-
- return (0);
- }
-
- case TERM_XTRA_SHAPE:
- {
- /*
- * Set the cursor visibility XXX XXX XXX
- *
- * This action should change the visibility of the cursor,
- * if possible, to the requested value (0=off, 1=on)
- *
- * This action is optional, but can improve both the
- * efficiency (and attractiveness) of the program.
- */
-
- return (0);
- }
-
- case TERM_XTRA_FROSH:
- {
- /*
- * Flush a row of output XXX XXX XXX
- *
- * This action should make sure that row "v" of the "output"
- * to the window will actually appear on the window.
- *
- * This action is optional, assuming that "Term_text_xxx()"
- * (and similar functions) draw directly to the screen, or
- * that the "TERM_XTRA_FRESH" entry below takes care of any
- * necessary flushing issues.
- */
-
- return (0);
- }
-
- case TERM_XTRA_FRESH:
- {
- /*
- * Flush output XXX XXX XXX
- *
- * This action should make sure that all "output" to the
- * window will actually appear on the window.
- *
- * This action is optional, assuming that "Term_text_xxx()"
- * (and similar functions) draw directly to the screen, or
- * that the "TERM_XTRA_FROSH" entry above takes care of any
- * necessary flushing issues.
- */
-
- return (0);
- }
-
- case TERM_XTRA_NOISE:
- {
- /*
- * Make a noise XXX XXX XXX
- *
- * This action should produce a "beep" noise.
- *
- * This action is optional, but convenient.
- */
-
- return (0);
- }
-
- case TERM_XTRA_SOUND:
- {
- /*
- * Make a sound XXX XXX XXX
- *
- * This action should produce sound number "v", where the
- * "name" of that sound is "sound_names[v]". This method
- * is still under construction.
- *
- * This action is optional, and not very important.
- */
-
- return (0);
- }
-
- case TERM_XTRA_BORED:
- {
- /*
- * Handle random events when bored XXX XXX XXX
- *
- * This action is optional, and normally not important
- */
-
- return (0);
- }
-
- case TERM_XTRA_REACT:
- {
- /*
- * 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
- * "arg_graphics" options.
- */
-
- return (0);
- }
-
- case TERM_XTRA_ALIVE:
- {
- /*
- * Change the "hard" level XXX XXX XXX
- *
- * This action is used if the program changes "aliveness"
- * by being either "suspended" (v=0) or "resumed" (v=1)
- * This action is optional, unless the computer uses the
- * same "physical screen" for multiple programs, in which
- * case this action should clean up to let other programs
- * use the screen, or resume from such a cleaned up state.
- *
- * This action is currently only used by "main-gcu.c",
- * on UNIX machines, to allow proper "suspending".
- */
-
- return (0);
- }
-
- case TERM_XTRA_LEVEL:
- {
- /*
- * Change the "soft" level XXX XXX XXX
- *
- * This action is used when the term window changes "activation"
- * either by becoming "inactive" (v=0) or "active" (v=1)
- *
- * This action can be used to do things like activate the proper
- * font / drawing mode for the newly active term window. This
- * action should NOT change which window has the "focus", which
- * window is "raised", or anything like that.
- *
- * This action is optional if all the other things which depend
- * on what term is active handle activation themself, or if only
- * one "term_data" structure is supported by this file.
- */
-
- return (0);
- }
-
- case TERM_XTRA_DELAY:
- {
- /*
- * Delay for some milliseconds XXX XXX XXX
- *
- * This action is useful for proper "timing" of certain
- * visual effects, such as breath attacks.
- *
- * This action is optional, but may be required by this file,
- * especially if special "macro sequences" must be supported.
- */
-
- return (0);
- }
-
- case TERM_XTRA_GET_DELAY:
- {
- /*
- * Get Delay of some milliseconds XXX XXX XXX
- * place the result in Term_xtra_long
- *
- * This action is useful for proper "timing" of certain
- * visual effects, such as recording cmovies.
- *
- * This action is optional, but cmovies wont perform
- * good without it
- */
-
- return (0);
- }
- }
-
- /* Unknown or Unhandled action */
- return (1);
-}
-
-
-/*
- * Display the cursor
- *
- * This routine should display the cursor at the given location
- * (x,y) in some manner. On some machines this involves actually
- * moving the physical cursor, on others it involves drawing a fake
- * cursor in some form of graphics mode. Note the "soft_cursor"
- * flag which tells "z-term.c" to treat the "cursor" as a "visual"
- * thing and not as a "hardware" cursor.
- *
- * You may assume "valid" input if the window is properly sized.
- *
- * You may use the "Term_grab(x, y, &a, &c)" function, if needed,
- * to determine what attr/char should be "under" the new cursor,
- * for "inverting" purposes or whatever.
- */
-static errr Term_curs_xxx(int x, int y)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* XXX XXX XXX */
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Erase some characters
- *
- * This function should erase "n" characters starting at (x,y).
- *
- * You may assume "valid" input if the window is properly sized.
- */
-static errr Term_wipe_xxx(int x, int y, int n)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* XXX XXX XXX */
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Draw some text on the screen
- *
- * This function should actually display an array of characters
- * starting at the given location, using the given "attribute",
- * and using the given string of characters, which contains
- * exactly "n" characters and which is NOT null-terminated.
- *
- * You may assume "valid" input if the window is properly sized.
- *
- * You must be sure that the string, when written, erases anything
- * (including any visual cursor) that used to be where the text is
- * drawn. On many machines this happens automatically, on others,
- * you must first call "Term_wipe_xxx()" to clear the area.
- *
- * In color environments, you should activate the color contained
- * in "color_data[a & 0x0F]", if needed, before drawing anything.
- *
- * You may ignore the "attribute" if you are only supporting a
- * monochrome environment, since this routine is normally never
- * called to display "black" (invisible) text, including the
- * default "spaces", and all other colors should be drawn in
- * the "normal" color in a monochrome environment.
- *
- * Note that if you have changed the "attr_blank" to something
- * which is not black, then this function must be able to draw
- * the resulting "blank" correctly.
- *
- * Note that this function must correctly handle "black" text if
- * the "always_text" flag is set, if this flag is not set, all the
- * "black" text will be handled by the "Term_wipe_xxx()" hook.
- */
-static errr Term_text_xxx(int x, int y, int n, byte a, const char *cp)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* XXX XXX XXX */
-
- /* Success */
- return (0);
-}
-
-
-/*
- * Draw some attr/char pairs on the screen
- *
- * This routine should display the given "n" attr/char pairs at
- * the given location (x,y). This function is only used if one
- * of the flags "always_pict" or "higher_pict" is defined.
- *
- * You must be sure that the attr/char pairs, when displayed, will
- * erase anything (including any visual cursor) that used to be at
- * the given location. On many machines this is automatic, but on
- * others, you must first call "Term_wipe_xxx(x, y, 1)".
- *
- * With the "higher_pict" flag, this function can be used to allow
- * the display of "pseudo-graphic" pictures, for example, by using
- * the attr/char pair as an encoded index into a pixmap of special
- * "pictures".
- *
- * With the "always_pict" flag, this function can be used to force
- * every attr/char pair to be drawn by this function, which can be
- * very useful if this file can optimize its own display calls.
- *
- * This function is often associated with the "arg_graphics" flag.
- *
- * This function is only used if one of the "higher_pict" and/or
- * "always_pict" flags are set.
- */
-static errr Term_pict_xxx(int x, int y, int n, const byte *ap, const char *cp)
-{
- term_data *td = (term_data*)(Term->data);
-
- /* XXX XXX XXX */
-
- /* Success */
- return (0);
-}
-
-
-
-/*** Internal Functions ***/
-
-
-/*
- * Instantiate a "term_data" structure
- *
- * This is one way to prepare the "term_data" structures and to
- * "link" the various informational pieces together.
- *
- * This function assumes that every window should be 80x24 in size
- * (the standard size) and should be able to queue 256 characters.
- * Technically, only the "main screen window" needs to queue any
- * characters, but this method is simple. One way to allow some
- * variation is to add fields to the "term_data" structure listing
- * parameters for that window, initialize them in the "init_xxx()"
- * function, and then use them in the code below.
- *
- * Note that "activation" calls the "Term_init_xxx()" hook for
- * the "term" structure, if needed.
- */
-static void term_data_link(int i)
-{
- term_data *td = &data[i];
-
- /* Initialize the term */
- term_init(td->t, 80, 24, 256);
-
- /* Choose "soft" or "hard" cursor XXX XXX XXX */
- /* A "soft" cursor must be explicitly "drawn" by the program */
- /* while a "hard" cursor has some "physical" existance and is */
- /* moved whenever text is drawn on the screen. See "term.c". */
- /* td->t->soft_cursor = TRUE; */
-
- /* Avoid the "corner" of the window XXX XXX XXX */
- /* td->t->icky_corner = TRUE; */
-
- /* Use "Term_pict()" for all attr/char pairs XXX XXX XXX */
- /* See the "Term_pict_xxx()" function above. */
- /* td->t->always_pict = TRUE; */
-
- /* Use "Term_pict()" for some attr/char pairs XXX XXX XXX */
- /* See the "Term_pict_xxx()" function above. */
- /* td->t->higher_pict = TRUE; */
-
- /* Use "Term_text()" even for "black" text XXX XXX XXX */
- /* See the "Term_text_xxx()" function above. */
- /* td->t->always_text = TRUE; */
-
- /* Ignore the "TERM_XTRA_BORED" action XXX XXX XXX */
- /* This may make things slightly more efficient. */
- /* td->t->never_bored = TRUE; */
-
- /* Ignore the "TERM_XTRA_FROSH" action XXX XXX XXX */
- /* This may make things slightly more efficient. */
- /* td->t->never_frosh = TRUE; */
-
- /* Erase with "white space" XXX XXX XXX */
- /* td->t->attr_blank = TERM_WHITE; */
- /* td->t->char_blank = ' '; */
-
- /* Prepare the init/nuke hooks */
- td->t->init_hook = Term_init_xxx;
- td->t->nuke_hook = Term_nuke_xxx;
-
- /* Prepare the template hooks */
- td->t->user_hook = Term_user_xxx;
- td->t->xtra_hook = Term_xtra_xxx;
- td->t->curs_hook = Term_curs_xxx;
- td->t->wipe_hook = Term_wipe_xxx;
- td->t->text_hook = Term_text_xxx;
- td->t->pict_hook = Term_pict_xxx;
-
- /* Remember where we came from */
- td->t->data = (vptr)(td);
-
- /* Activate it */
- Term_activate(td->t);
-
- /* Global pointer */
- ang_term[i] = td->t;
-}
-
-
-
-/*
- * Initialization function
- */
-errr init_xxx(void)
-{
- /* Initialize globals XXX XXX XXX */
-
- /* Initialize "term_data" structures XXX XXX XXX */
-
- /* Create windows (backwards!) */
- for (i = TERM_DATA_MAX - 1; i >= 0; i--)
- {
- /* Link */
- term_data_link(i);
- }
-
- /* Success */
- return (0);
-}
-
-
-#ifdef INTERNAL_MAIN
-
-
-/*
- * Some special machines need their own "main()" function, which they
- * can provide here, making sure NOT to compile the "main.c" file.
- *
- * These systems usually have some form of "event loop", run forever
- * as the last step of "main()", which handles things like menus and
- * window movement, and calls "play_game(FALSE)" to load a game after
- * initializing "savefile" to a filename, or "play_game(TRUE)" to make
- * a new game. The event loop would also be triggered by "Term_xtra()"
- * (the TERM_XTRA_EVENT action), in which case the event loop would not
- * actually "loop", but would run once and return.
- */
-
-
-/*
- * An event handler XXX XXX XXX
- *
- * You may need an event handler, which can be used by both
- * by the "TERM_XTRA_BORED" and "TERM_XTRA_EVENT" entries in
- * the "Term_xtra_xxx()" function, and also to wait for the
- * user to perform whatever user-interface operation is needed
- * to request the start of a new game or the loading of an old
- * game, both of which should launch the "play_game()" function.
- */
-static bool_ CheckEvents(bool_ wait)
-{
- /* XXX XXX XXX */
-
- return (0);
-}
-
-
-/*
- * Init some stuff
- *
- * This function is used to keep the "path" variable off the stack.
- */
-static void init_stuff(void)
-{
- char path[1024];
-
- /* Prepare the path XXX XXX XXX */
- /* This must in some way prepare the "path" variable */
- /* so that it points at the "lib" directory. Every */
- /* machine handles this in a different way... */
- strcpy(path, "XXX XXX XXX");
-
- /* Prepare the filepaths */
- init_file_paths(path);
-}
-
-
-/*
- * Main function
- *
- * This function must do a lot of stuff.
- */
-int main(int argc, char *argv[])
-{
- /* Initialize the machine itself XXX XXX XXX */
-
- /* Process command line arguments XXX XXX XXX */
-
- /* Initialize the windows */
- if (init_xxx()) quit("Oops!");
-
- /* XXX XXX XXX */
- ANGBAND_SYS = "xxx";
-
- /* Initialize some stuff */
- init_stuff();
-
- /* Initialize */
- init_angband * /
-
- /* Allow auto-startup XXX XXX XXX */
-
- /* Event loop forever XXX XXX XXX */
- while (TRUE) CheckEvents(TRUE);
-}
-
-
-#endif /* INTERNAL_MAIN */
-
-
-#endif /* USE_XXX */
diff --git a/src/main.c b/src/main.c
index 10500ab6..a20eb6b6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,7 +8,14 @@
* are included in all such copies.
*/
-#include "angband.h"
+#include "birth.h"
+#include "dungeon.h"
+#include "files.h"
+#include "init2.h"
+#include "modules.h"
+#include "script.h"
+#include "util.h"
+#include "variable.h"
@@ -44,51 +51,11 @@ static void quit_hook(cptr s)
/*
- * Check and create if needed the directory dirpath
- */
-bool_ private_check_user_directory(cptr dirpath)
-{
- /* Is this used anywhere else in *bands? */
- struct stat stat_buf;
-
- int ret;
-
- /* See if it already exists */
- ret = stat(dirpath, &stat_buf);
-
- /* It does */
- if (ret == 0)
- {
- /* Now we see if it's a directory */
- if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);
-
- /*
- * Something prevents us from create a directory with
- * the same pathname
- */
- return (FALSE);
- }
-
- /* No - this maybe the first time. Try to create a directory */
- else
- {
- /* Create the ~/.ToME directory */
- ret = mkdir(dirpath, 0700);
-
- /* An error occured */
- if (ret == -1) return (FALSE);
-
- /* Success */
- return (TRUE);
- }
-}
-
-/*
* Check existence of ".ToME/" directory in the user's
* home directory or try to create it if it doesn't exist.
* Returns FALSE if all the attempts fail.
*/
-static bool_ check_create_user_dir(void)
+static void init_save_dir(void)
{
char dirpath[1024];
char versionpath[1024];
@@ -101,132 +68,34 @@ static bool_ check_create_user_dir(void)
strcpy(savepath, versionpath);
strcat(savepath, "/save");
- return private_check_user_directory(dirpath) && private_check_user_directory(versionpath) && private_check_user_directory(savepath);
-}
-
-
-/*
- * Initialize and verify the file paths, and the score file.
- *
- * Use the ANGBAND_PATH environment var if possible, else use
- * DEFAULT_PATH, and in either case, branch off appropriately.
- *
- * First, we'll look for the ANGBAND_PATH environment variable,
- * and then look for the files in there. If that doesn't work,
- * we'll try the DEFAULT_PATH constant. So be sure that one of
- * these two things works...
- *
- * We must ensure that the path ends with "PATH_SEP" if needed,
- * since the "init_file_paths()" function will simply append the
- * relevant "sub-directory names" to the given path.
- */
-static void init_stuff(void)
-{
- char path[1024];
-
- cptr tail;
-
- /* Get the environment variable */
- tail = getenv("TOME_PATH");
-
- /* Use the angband_path, or a default */
- strcpy(path, tail ? tail : DEFAULT_PATH);
+ if (!private_check_user_directory(dirpath))
+ {
+ quit_fmt("Cannot create directory '%s'", dirpath);
+ }
- /* Hack -- Add a path separator (only if needed) */
- if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
+ if (!private_check_user_directory(versionpath))
+ {
+ quit_fmt("Cannot create directory '%s'", versionpath);
+ }
- /* Initialize */
- init_file_paths(path);
+ if (!private_check_user_directory(savepath))
+ {
+ quit_fmt("Cannot create directory '%s'", savepath);
+ }
}
-
-/*
- * Handle a "-d<what>=<path>" option
- *
- * The "<what>" can be any string starting with the same letter as the
- * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
- *
- * The "<path>" can be any legal path for the given system, and should
- * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
- */
-static void change_path(cptr info)
+static void init_player_name()
{
- cptr s;
-
- /* Find equal sign */
- s = strchr(info, '=');
-
- /* Verify equal sign */
- if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
-
- /* Analyze */
- switch (tolower(info[0]))
- {
- case 'f':
- {
- string_free(ANGBAND_DIR_FILE);
- ANGBAND_DIR_FILE = string_make(s + 1);
- break;
- }
-
- case 'h':
- {
- string_free(ANGBAND_DIR_HELP);
- ANGBAND_DIR_HELP = string_make(s + 1);
- break;
- }
-
- case 'i':
- {
- string_free(ANGBAND_DIR_INFO);
- ANGBAND_DIR_INFO = string_make(s + 1);
- break;
- }
-
- case 'u':
- {
- string_free(ANGBAND_DIR_USER);
- ANGBAND_DIR_USER = string_make(s + 1);
- break;
- }
-
- case 'x':
- {
- string_free(ANGBAND_DIR_XTRA);
- ANGBAND_DIR_XTRA = string_make(s + 1);
- break;
- }
-
- case 'd':
- {
- string_free(ANGBAND_DIR_DATA);
- ANGBAND_DIR_DATA = string_make(s + 1);
- break;
- }
-
- case 'e':
- {
- string_free(ANGBAND_DIR_EDIT);
- ANGBAND_DIR_EDIT = string_make(s + 1);
- break;
- }
-
- case 's':
- {
- string_free(ANGBAND_DIR_SAVE);
- ANGBAND_DIR_SAVE = string_make(s + 1);
- break;
- }
+ /* Get the user id (?) */
+ int player_uid = getuid();
- default:
- {
- quit_fmt("Bad semantics in '-d%s'", info);
- }
- }
+ /* Acquire the "user name" as a default player name */
+ user_name(player_name, player_uid);
}
+
/*
* Simple "main" function for multiple platforms.
*
@@ -242,50 +111,18 @@ int main(int argc, char *argv[])
bool_ new_game = FALSE;
- int show_score = 0;
-
cptr mstr = NULL;
bool_ args = TRUE;
- int player_uid;
-
-
-
- /* Save the "program name" XXX XXX XXX */
- argv0 = argv[0];
-
-
- /* Default permissions on files */
- (void)umask(022);
-
-
/* Get the file paths */
- init_stuff();
-
-
- /* Get the user id (?) */
- player_uid = getuid();
-
- /* Acquire the "user name" as a default player name */
- user_name(player_name, player_uid);
-
-
- /*
- * On multiuser systems, users' private directories are
- * used to store pref files, chardumps etc.
- */
- {
- bool_ ret;
-
- /* Create a directory for the user's files */
- ret = check_create_user_dir();
-
- /* Oops */
- if (ret == FALSE) quit("Cannot create directory " PRIVATE_USER_PATH);
- }
+ init_file_paths_with_env();
+ /* Initialize the player name */
+ init_player_name();
+ /* Make sure save directory exists */
+ init_save_dir();
/* Process the command line arguments */
@@ -311,20 +148,6 @@ int main(int argc, char *argv[])
break;
}
- case 'V':
- case 'v':
- {
- arg_sound = TRUE;
- break;
- }
-
- case 'G':
- case 'g':
- {
- arg_graphics = TRUE;
- break;
- }
-
case 'R':
case 'r':
{
@@ -339,14 +162,6 @@ int main(int argc, char *argv[])
break;
}
- case 'S':
- case 's':
- {
- show_score = atoi(&argv[i][2]);
- if (show_score <= 0) show_score = 10;
- break;
- }
-
case 'u':
case 'U':
{
@@ -367,7 +182,7 @@ int main(int argc, char *argv[])
case 'M':
{
if (!argv[i][2]) goto usage;
- force_module = string_make(&argv[i][2]);
+ force_module = &argv[i][2];
break;
}
@@ -397,13 +212,6 @@ int main(int argc, char *argv[])
return 0;
}
- case 'd':
- case 'D':
- {
- change_path(&argv[i][2]);
- break;
- }
-
case '-':
{
if (argv[i][2] == 'h' && !strcmp((argv[i] + 2), "help"))
@@ -430,51 +238,25 @@ usage:
puts(" -h This help");
puts(" -n Start a new character");
puts(" -w Request wizard mode");
- puts(" -v Request sound mode");
- puts(" -g Request graphics mode");
puts(" -o Request original keyset");
puts(" -r Request rogue-like keyset");
puts(" -H <list of files> Convert helpfile to html");
- puts(" -s<num> Show <num> high scores");
puts(" -u<who> Use your <who> savefile");
puts(" -M<which> Use the <which> module");
puts(" -m<sys> Force 'main-<sys>.c' usage");
- puts(" -d<def> Define a 'lib' dir sub-path");
#ifdef USE_GTK2
puts(" -mgtk2 To use GTK2");
puts(" -- Sub options");
puts(" -- -n# Number of terms to use");
puts(" -- -b Turn off software backing store");
-# ifdef USE_GRAPHICS
- puts(" -- -s Turn off smoothscaling graphics");
- puts(" -- -o Requests \"old\" graphics");
- puts(" -- -g Requests \"new\" graphics");
- puts(" -- -t Enable transparency effect");
-# endif /* USE_GRAPHICS */
#endif /* USE_GTK2 */
-#ifdef USE_XAW
- puts(" -mxaw To use XAW");
- puts(" -- Sub options");
- puts(" -- -n# Number of terms to use");
- puts(" -- -d<name> Display to use");
-# ifdef USE_GRAPHICS
- puts(" -- -s Turn off smoothscaling graphics");
- puts(" -- -o Requests \"old\" graphics");
-# endif /* USE_GRAPHICS */
-#endif /* USE_XAW */
-
#ifdef USE_X11
puts(" -mx11 To use X11");
puts(" -- Sub options");
puts(" -- -n# Number of terms to use");
puts(" -- -d<name> Display to use");
-# ifdef USE_GRAPHICS
- puts(" -- -s Turn off smoothscaling graphics");
- puts(" -- -o Requests \"old\" graphics");
- puts(" -- -b Requests double-width tiles");
-# endif /* USE_GRAPHICS */
#endif /* USE_X11 */
#ifdef USE_GCU
@@ -487,9 +269,6 @@ usage:
puts(" -msdl To use SDL");
puts(" -- Sub options");
puts(" -- -n # Number of virtual consoles to use");
- puts(" -- -g Request new graphics (16x16)");
- puts(" -- -o Request old graphics (8x8)");
- puts(" -- -b Requests double-width tiles");
puts(" -- -w # Request screen width in pixels");
puts(" -- -h # Request screen height in pixels");
puts(" -- -bpp # Request screen color depth in bits");
@@ -533,19 +312,6 @@ usage:
}
#endif
-#ifdef USE_XAW
- /* Attempt to use the "main-xaw.c" support */
- if (!done && (!mstr || (streq(mstr, "xaw"))))
- {
- extern errr init_xaw(int, char**);
- if (0 == init_xaw(argc, argv))
- {
- ANGBAND_SYS = "xaw";
- done = TRUE;
- }
- }
-#endif
-
#ifdef USE_X11
/* Attempt to use the "main-x11.c" support */
if (!done && (!mstr || (streq(mstr, "x11"))))
@@ -592,9 +358,6 @@ usage:
/* Initialize */
init_angband();
- /* Hack -- If requested, display scores and quit */
- if (show_score > 0) display_scores(0, show_score);
-
/* Wait for response */
pause_line(23);
diff --git a/src/martial_arts.hpp b/src/martial_arts.hpp
new file mode 100644
index 00000000..1f2f0cbe
--- /dev/null
+++ b/src/martial_arts.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Martial arts descriptors
+ */
+struct martial_arts
+{
+ cptr desc; /* A verbose attack description */
+ int min_level; /* Minimum level to use */
+ int chance; /* Chance of 'success' */
+ int dd; /* Damage dice */
+ int ds; /* Damage sides */
+ s16b effect; /* Special effects */
+ s16b power; /* Special effects power */
+};
+
diff --git a/src/melee1.c b/src/melee1.cc
index 157656a9..4eabe223 100644
--- a/src/melee1.c
+++ b/src/melee1.cc
@@ -1,7 +1,3 @@
-/* File: melee1.c */
-
-/* Purpose: Monster attacks */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,33 @@
* included in all such copies.
*/
-#include "angband.h"
-
-
+#include "melee1.hpp"
+
+#include "cave.hpp"
+#include "cmd5.hpp"
+#include "gods.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "store.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::iequals;
/*
* Critical blow. All hits that do 95% of total possible damage,
@@ -261,7 +281,7 @@ bool_ carried_make_attack_normal(int r_idx)
if (!effect || check_hit(power, rlev))
{
/* Always disturbing */
- disturb(1, 0);
+ disturb(1);
/* Hack -- Apply "protection from evil" */
if ((p_ptr->protevil > 0) &&
@@ -1280,7 +1300,7 @@ bool_ carried_make_attack_normal(int r_idx)
case RBM_CHARGE:
/* Disturbing */
- disturb(1, 0);
+ disturb(1);
/* Message */
msg_format("%s misses you.", sym_name);
@@ -1525,7 +1545,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
int chance = p_ptr->dodge_chance - ((rlev * 5) / 6);
/* Always disturbing */
- disturb(1, 0);
+ disturb(1);
if ((chance > 0) && magik(chance))
{
@@ -1536,7 +1556,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
}
/* Eru can help you */
- PRAY_GOD(GOD_ERU)
+ if (praying_to(GOD_ERU))
{
s32b chance = p_ptr->grace;
@@ -1648,7 +1668,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
{
act = "bites you.";
do_cut = 1;
- if (magik(5) && (strstr(r_name + r_ptr->name, "Vampire") || strstr(r_name + r_ptr->name, "vampire")))
+ if (magik(5) && iequals(r_ptr->name, "vampire"))
do_vampire = TRUE;
touched = TRUE;
sound(SOUND_BITE);
@@ -1774,7 +1794,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
case RBM_MOAN:
{
- if (strstr((r_name + r_ptr->name), "Mathilde, the Science Student"))
+ if (strstr(r_ptr->name, "Mathilde, the Science Student"))
act = desc_moan[rand_int(3) + 4];
else
act = desc_moan[rand_int(4)];
@@ -1955,7 +1975,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Uncharge */
o_ptr->pval = 0;
@@ -2036,7 +2056,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
}
/* Redraw gold */
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2094,8 +2114,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
((o_ptr->number > 1) ? "One of y" : "Y"),
o_name, index_to_label(i));
- /* Option */
- if (testing_carry)
+ /* Copy into inventory of monster */
{
s16b o_idx;
@@ -2133,43 +2152,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
j_ptr->held_m_idx = m_idx;
/* Build stack */
- j_ptr->next_o_idx = m_ptr->hold_o_idx;
-
- /* Build stack */
- m_ptr->hold_o_idx = o_idx;
- }
- }
- else
- {
- if (strstr((r_name + r_ptr->name), "black market")
- && randint(2) != 1)
- {
- s16b o_idx;
-
- /* Make an object */
- o_idx = o_pop();
-
- /* Success */
- if (o_idx)
- {
- object_type *j_ptr;
- if (cheat_xtra || cheat_peek)
- msg_print("Moving object to black market...");
-
- /* Get new object */
- j_ptr = &o_list[o_idx];
-
- /* Copy object */
- object_copy(j_ptr, o_ptr);
-
- /* Modify number */
- j_ptr->number = 1;
-
- /* Forget mark */
- j_ptr->marked = FALSE;
-
- move_to_black_market(j_ptr);
- }
+ m_ptr->hold_o_idxs.push_back(o_idx);
}
}
@@ -3011,7 +2994,7 @@ bool_ make_attack_normal(int m_idx, byte divis)
if (m_ptr->ml)
{
/* Disturbing */
- disturb(1, 0);
+ disturb(1);
/* Message */
msg_format("%^s misses you.", m_name);
diff --git a/src/melee1.hpp b/src/melee1.hpp
new file mode 100644
index 00000000..e84c8f03
--- /dev/null
+++ b/src/melee1.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern int get_attack_power(int effect);
+extern bool_ carried_make_attack_normal(int r_idx);
+extern bool_ make_attack_normal(int m_idx, byte divis);
diff --git a/src/melee2.c b/src/melee2.cc
index 4f63959d..05d91f3c 100644
--- a/src/melee2.c
+++ b/src/melee2.cc
@@ -1,30 +1,57 @@
-/* File: melee2.c */
-
-/* Purpose: Monster spells and movement */
-
/*
-* Copyright (c) 1989 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.
-*/
+ * Copyright (c) 1989 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.
+ */
/*
* This file has several additions to it by Keldon Jones (keldon@umr.edu)
* to improve the general quality of the AI (version 0.1.1).
*/
-#include "angband.h"
-
-#include "messages.h"
-#include "quark.h"
+#include "melee2.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "hook_mon_speak_in.hpp"
+#include "hook_monster_ai_in.hpp"
+#include "hook_monster_ai_out.hpp"
+#include "hooks.hpp"
+#include "melee1.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "xtra2.hpp"
+
+#include <cassert>
#define SPEAK_CHANCE 8
#define GRINDNOISE 20
#define FOLLOW_DISTANCE 6
+static void cmonster_msg(char a, cptr fmt, ...);
+
/*
* Based on mon_take_hit... all monster attacks on
* other monsters should use
@@ -38,7 +65,7 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note)
s32b div, new_exp, new_exp_frac;
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Some mosnters are immune to death */
if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE;
@@ -256,10 +283,7 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear)
*
* This has the added advantage that attacks and spells are related.
* The "smart_learn" option means that the monster "learns" the flags
-* that should be set, and "smart_cheat" means that he "knows" them.
-* So "smart_cheat" means that the "smart" field is always up to date,
-* while "smart_learn" means that the "smart" field is slowly learned.
-* Both of them have the same effect on the "choose spell" routine.
+* that should be set.
*/
@@ -298,61 +322,20 @@ static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p)
/* Must be cheating or learning */
- if (!smart_cheat && !smart_learn) return;
+ if (!smart_learn) return;
/* Update acquired knowledge */
if (smart_learn)
{
/* Hack -- Occasionally forget player status */
- if (m_ptr->smart && (rand_int(100) < 1)) m_ptr->smart = 0L;
+ if (m_ptr->smart && magik(1)) m_ptr->smart = 0L;
/* Use the memorized flags */
smart = m_ptr->smart;
}
- /* Cheat if requested */
- if (smart_cheat)
- {
- /* Know basic info */
- if (p_ptr->resist_acid) smart |= (SM_RES_ACID);
- if (p_ptr->oppose_acid) smart |= (SM_OPP_ACID);
- if (p_ptr->immune_acid) smart |= (SM_IMM_ACID);
- if (p_ptr->resist_elec) smart |= (SM_RES_ELEC);
- if (p_ptr->oppose_elec) smart |= (SM_OPP_ELEC);
- if (p_ptr->immune_elec) smart |= (SM_IMM_ELEC);
- if (p_ptr->resist_fire) smart |= (SM_RES_FIRE);
- if (p_ptr->oppose_fire) smart |= (SM_OPP_FIRE);
- if (p_ptr->immune_fire) smart |= (SM_IMM_FIRE);
- if (p_ptr->resist_cold) smart |= (SM_RES_COLD);
- if (p_ptr->oppose_cold) smart |= (SM_OPP_COLD);
- if (p_ptr->immune_cold) smart |= (SM_IMM_COLD);
-
- /* Know poison info */
- if (p_ptr->resist_pois) smart |= (SM_RES_POIS);
- if (p_ptr->oppose_pois) smart |= (SM_OPP_POIS);
-
- /* Know special resistances */
- if (p_ptr->resist_neth) smart |= (SM_RES_NETH);
- if (p_ptr->resist_lite) smart |= (SM_RES_LITE);
- if (p_ptr->resist_dark) smart |= (SM_RES_DARK);
- if (p_ptr->resist_fear) smart |= (SM_RES_FEAR);
- if (p_ptr->resist_conf) smart |= (SM_RES_CONF);
- if (p_ptr->resist_chaos) smart |= (SM_RES_CHAOS);
- if (p_ptr->resist_disen) smart |= (SM_RES_DISEN);
- if (p_ptr->resist_blind) smart |= (SM_RES_BLIND);
- if (p_ptr->resist_nexus) smart |= (SM_RES_NEXUS);
- if (p_ptr->resist_sound) smart |= (SM_RES_SOUND);
- if (p_ptr->resist_shard) smart |= (SM_RES_SHARD);
- if (p_ptr->reflect) smart |= (SM_IMM_REFLECT);
-
- /* Know bizarre "resistances" */
- if (p_ptr->free_act) smart |= (SM_IMM_FREE);
- if (!p_ptr->msp) smart |= (SM_IMM_MANA);
- }
-
-
/* Nothing known */
if (!smart) return;
@@ -946,7 +929,7 @@ static void monst_bolt_monst(int m_idx, int y, int x, int typ, int dam_hp)
}
-void monster_msg(cptr fmt, ...)
+static void monster_msg(cptr fmt, ...)
{
va_list vp;
@@ -961,12 +944,20 @@ void monster_msg(cptr fmt, ...)
/* End the Varargs Stuff */
va_end(vp);
+ /* Print */
+ monster_msg_simple(buf);
+}
+
+void monster_msg_simple(cptr s)
+{
/* Display */
if (disturb_other)
- msg_print(buf);
+ {
+ msg_print(s);
+ }
else
{
- message_add(buf, TERM_WHITE);
+ message_add(s, TERM_WHITE);
p_ptr->window |= PW_MESSAGE;
}
}
@@ -1155,7 +1146,7 @@ static bool_ monst_spell_monst(int m_idx)
case 96 + 0:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_m) monster_msg("You hear a shriek.");
else monster_msg("%^s shrieks at %s.", m_name, t_name);
wake_up = TRUE;
@@ -1171,7 +1162,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_S_ANIMAL */
case 96 + 2:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons an animal!", m_name);
for (k = 0; k < 1; k++)
@@ -1188,7 +1179,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_ROCKET */
case 96 + 3:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear an explosion!");
else if (blind) monster_msg("%^s shoots something.", m_name);
else monster_msg("%^s fires a rocket at %s.", m_name, t_name);
@@ -1200,7 +1191,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_ARROW_1 */
case 96 + 4:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear a strange noise.");
else if (blind) monster_msg("%^s makes a strange noise.", m_name);
else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
@@ -1212,7 +1203,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_ARROW_2 */
case 96 + 5:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear a strange noise.");
else if (blind) monster_msg("%^s makes a strange noise.", m_name);
else monster_msg("%^s fires an arrow at %s.", m_name, t_name);
@@ -1224,7 +1215,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_ARROW_3 */
case 96 + 6:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear a strange noise.");
else if (blind) monster_msg("%^s makes a strange noise.", m_name);
@@ -1238,7 +1229,7 @@ static bool_ monst_spell_monst(int m_idx)
case 96 + 7:
{
if (!see_either) monster_msg("You hear a strange noise.");
- else if (disturb_other) disturb(1, 0);
+ else if (disturb_other) disturb(1);
if (blind) monster_msg("%^s makes a strange noise.", m_name);
else monster_msg("%^s fires a missile at %s.", m_name, t_name);
sound(SOUND_SHOOT);
@@ -1249,7 +1240,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_ACID */
case 96 + 8:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes acid at %s.", m_name, t_name);
@@ -1262,7 +1253,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_ELEC */
case 96 + 9:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes lightning at %s.", m_name, t_name);
@@ -1275,7 +1266,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_FIRE */
case 96 + 10:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes fire at %s.", m_name, t_name);
@@ -1288,7 +1279,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_COLD */
case 96 + 11:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes frost at %s.", m_name, t_name);
@@ -1301,7 +1292,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_POIS */
case 96 + 12:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes gas at %s.", m_name, t_name);
@@ -1314,7 +1305,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_NETH */
case 96 + 13:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes nether at %s.", m_name, t_name);
@@ -1327,7 +1318,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_LITE */
case 96 + 14:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes light at %s.", m_name, t_name);
@@ -1340,7 +1331,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_DARK */
case 96 + 15:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes darkness at %s.", m_name, t_name);
@@ -1353,7 +1344,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_CONF */
case 96 + 16:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes confusion at %s.", m_name, t_name);
@@ -1366,7 +1357,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_SOUN */
case 96 + 17:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes sound at %s.", m_name, t_name);
@@ -1379,7 +1370,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_CHAO */
case 96 + 18:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes chaos at %s.", m_name, t_name);
@@ -1392,7 +1383,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_DISE */
case 96 + 19:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes disenchantment at %s.", m_name, t_name);
@@ -1405,7 +1396,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_NEXU */
case 96 + 20:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes nexus at %s.", m_name, t_name);
@@ -1418,7 +1409,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_TIME */
case 96 + 21:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes time at %s.", m_name, t_name);
@@ -1431,7 +1422,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_INER */
case 96 + 22:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes inertia at %s.", m_name, t_name);
@@ -1444,7 +1435,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_GRAV */
case 96 + 23:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes gravity at %s.", m_name, t_name);
@@ -1457,7 +1448,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_SHAR */
case 96 + 24:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes shards at %s.", m_name, t_name);
@@ -1470,7 +1461,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_PLAS */
case 96 + 25:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes plasma at %s.", m_name, t_name);
@@ -1483,7 +1474,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_WALL */
case 96 + 26:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes force at %s.", m_name, t_name);
@@ -1496,7 +1487,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_MANA */
case 96 + 27:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes magical energy at %s.", m_name, t_name);
@@ -1509,7 +1500,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BA_NUKE */
case 96 + 28:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear someone mumble.");
else if (blind) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a ball of radiation at %s.", m_name, t_name);
@@ -1522,7 +1513,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_NUKE */
case 96 + 29:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes toxic waste at %s.", m_name, t_name);
@@ -1535,7 +1526,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BA_CHAO */
case 96 + 30:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear someone mumble frighteningly.");
else if (blind) monster_msg("%^s mumbles frighteningly.", m_name);
else monster_msg("%^s invokes a raw Chaos upon %s.", m_name, t_name);
@@ -1548,7 +1539,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF4_BR_DISI -> Breathe Disintegration */
case 96 + 31:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg("You hear breathing noise.");
else if (blind) monster_msg("%^s breathes.", m_name);
else monster_msg("%^s breathes disintegration at %s.", m_name, t_name);
@@ -1561,7 +1552,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_ACID */
case 128 + 0:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else if (blind) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts an acid ball at %s.", m_name, t_name);
@@ -1572,7 +1563,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_ELEC */
case 128 + 1:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1584,7 +1575,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_FIRE */
case 128 + 2:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1596,7 +1587,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_COLD */
case 128 + 3:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1608,7 +1599,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_POIS */
case 128 + 4:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1620,7 +1611,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_NETH */
case 128 + 5:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1632,7 +1623,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_WATE */
case 128 + 6:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble.");
else
if (blind) monster_msg("%^s mumbles.", m_name);
@@ -1645,7 +1636,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_MANA */
case 128 + 7:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble powerfully.");
else
if (blind) monster_msg("%^s mumbles powerfully.", m_name);
@@ -1657,7 +1648,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BA_DARK */
case 128 + 8:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_either) monster_msg ("You hear someone mumble powerfully.");
else
if (blind) monster_msg("%^s mumbles powerfully.", m_name);
@@ -1693,7 +1684,7 @@ static bool_ monst_spell_monst(int m_idx)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Special message */
if (seen)
@@ -1712,7 +1703,7 @@ static bool_ monst_spell_monst(int m_idx)
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!seen)
{
@@ -1757,7 +1748,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 11:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!seen)
{
/* */
@@ -1803,7 +1794,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 12:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s points at %s and curses.", m_name, t_name);
if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
@@ -1824,7 +1815,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 13:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s points at %s and curses horribly.", m_name, t_name);
if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
@@ -1844,7 +1835,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 14:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s points at %s, incanting terribly!", m_name, t_name);
if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
@@ -1864,7 +1855,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 15:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s points at %s, screaming the word 'DIE!'", m_name, t_name);
if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)
@@ -1883,7 +1874,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_ACID */
case 128 + 16:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts an acid bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_ACID,
@@ -1894,7 +1885,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_ELEC */
case 128 + 17:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a lightning bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_ELEC,
@@ -1905,7 +1896,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_FIRE */
case 128 + 18:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a fire bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_FIRE,
@@ -1916,7 +1907,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_COLD */
case 128 + 19:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a frost bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_COLD,
@@ -1934,7 +1925,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_NETH */
case 128 + 21:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a nether bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_NETHER,
@@ -1945,7 +1936,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_WATE */
case 128 + 22:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a water bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_WATER,
@@ -1956,7 +1947,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_MANA */
case 128 + 23:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a mana bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_MANA,
@@ -1967,7 +1958,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_PLAS */
case 128 + 24:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a plasma bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_PLASMA,
@@ -1978,7 +1969,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_BO_ICEE */
case 128 + 25:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts an ice bolt at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_ICE,
@@ -1989,7 +1980,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF5_MISSILE */
case 128 + 26:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a magic missile at %s.", m_name, t_name);
monst_bolt_monst(m_idx, y, x, GF_MISSILE,
@@ -2001,7 +1992,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 27:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles, and you hear scary noises.", m_name);
else monster_msg("%^s casts a fearful illusion at %s.", m_name, t_name);
if (tr_ptr->flags3 & RF3_NO_FEAR)
@@ -2025,7 +2016,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 28:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s casts a spell, burning %s%s eyes.", m_name, t_name,
(!strcmp(t_name, "it") ? "s" : "'s"));
@@ -2051,7 +2042,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 29:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles, and you hear puzzling noises.", m_name);
else monster_msg("%^s creates a mesmerising illusion in front of %s.", m_name, t_name);
if (tr_ptr->flags3 & RF3_NO_CONF)
@@ -2075,7 +2066,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 30:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!blind && see_either) monster_msg("%^s drains power from %s%s muscles.", m_name, t_name,
(!strcmp(t_name, "it") ? "s" : "'s"));
if (tr_ptr->flags1 & RF1_UNIQUE)
@@ -2099,7 +2090,7 @@ static bool_ monst_spell_monst(int m_idx)
case 128 + 31:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!blind && see_m) monster_msg("%^s stares intently at %s.", m_name, t_name);
if ((tr_ptr->flags1 & RF1_UNIQUE) ||
(tr_ptr->flags3 & RF3_NO_STUN))
@@ -2123,7 +2114,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_HASTE */
case 160 + 0:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m)
{
monster_msg("%^s mumbles.", m_name);
@@ -2154,7 +2145,7 @@ static bool_ monst_spell_monst(int m_idx)
case 160 + 1:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (!see_m) monster_msg("You hear someone invoke the Hand of Doom!");
else if (!blind) monster_msg("%^s invokes the Hand of Doom on %s.", m_name, t_name);
else
@@ -2185,7 +2176,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_HEAL */
case 160 + 2:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
/* Message */
if (blind || !see_m)
@@ -2232,7 +2223,7 @@ static bool_ monst_spell_monst(int m_idx)
}
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Cancel fear */
if (m_ptr->monfear)
@@ -2250,7 +2241,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_ANIMALS */
case 160 + 3:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons some animals!", m_name);
for (k = 0; k < 4; k++)
@@ -2267,7 +2258,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_BLINK */
case 160 + 4:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (see_m) monster_msg("%^s blinks away.", m_name);
teleport_away(m_idx, 10);
break;
@@ -2279,7 +2270,7 @@ static bool_ monst_spell_monst(int m_idx)
if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */
else
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (see_m) monster_msg("%^s teleports away.", m_name);
teleport_away(m_idx, MAX_SIGHT * 2 + 5);
break;
@@ -2302,7 +2293,7 @@ static bool_ monst_spell_monst(int m_idx)
else
{
bool_ resists_tele = FALSE;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
monster_msg("%^s teleports %s away.", m_name, t_name);
@@ -2348,7 +2339,7 @@ static bool_ monst_spell_monst(int m_idx)
case 160 + 9:
{
if (!direct) break;
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s gestures in shadow.", m_name);
if (seen)
@@ -2382,7 +2373,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_BUG */
case 160 + 13:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically codes some software bugs.", m_name);
for (k = 0; k < 6; k++)
@@ -2399,7 +2390,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_RNG */
case 160 + 14:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically codes some RNGs.", m_name);
for (k = 0; k < 6; k++)
@@ -2417,7 +2408,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_THUNDERLORD */
case 160 + 15:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons a Thunderlord!", m_name);
for (k = 0; k < 1; k++)
@@ -2434,7 +2425,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_SUMMON_KIN */
case 160 + 16:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons %s %s.",
m_name, m_poss,
@@ -2457,7 +2448,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_HI_DEMON */
case 160 + 17:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons greater demons!", m_name);
if (blind && count) monster_msg("You hear heavy steps nearby.");
@@ -2471,7 +2462,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_MONSTER */
case 160 + 18:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons help!", m_name);
for (k = 0; k < 1; k++)
@@ -2488,7 +2479,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_MONSTERS */
case 160 + 19:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons monsters!", m_name);
for (k = 0; k < 8; k++)
@@ -2505,7 +2496,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_ANT */
case 160 + 20:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons ants.", m_name);
for (k = 0; k < 6; k++)
@@ -2522,7 +2513,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_SPIDER */
case 160 + 21:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons spiders.", m_name);
for (k = 0; k < 6; k++)
@@ -2539,7 +2530,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_HOUND */
case 160 + 22:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons hounds.", m_name);
for (k = 0; k < 6; k++)
@@ -2556,7 +2547,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_HYDRA */
case 160 + 23:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons hydras.", m_name);
for (k = 0; k < 6; k++)
@@ -2573,7 +2564,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_ANGEL */
case 160 + 24:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons an angel!", m_name);
for (k = 0; k < 1; k++)
@@ -2590,7 +2581,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_DEMON */
case 160 + 25:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons a demon!", m_name);
for (k = 0; k < 1; k++)
@@ -2607,7 +2598,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_UNDEAD */
case 160 + 26:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons an undead adversary!", m_name);
for (k = 0; k < 1; k++)
@@ -2624,7 +2615,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_DRAGON */
case 160 + 27:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons a dragon!", m_name);
for (k = 0; k < 1; k++)
@@ -2641,7 +2632,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_HI_UNDEAD */
case 160 + 28:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons greater undead!", m_name);
for (k = 0; k < 8; k++)
@@ -2661,7 +2652,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_HI_DRAGON */
case 160 + 29:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons ancient dragons!", m_name);
for (k = 0; k < 8; k++)
@@ -2681,7 +2672,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_WRAITH */
case 160 + 30:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons a wraith!", m_name);
@@ -2701,7 +2692,7 @@ static bool_ monst_spell_monst(int m_idx)
/* RF6_S_UNIQUE */
case 160 + 31:
{
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
if (blind || !see_m) monster_msg("%^s mumbles.", m_name);
else monster_msg("%^s magically summons special opponents!", m_name);
for (k = 0; k < 8; k++)
@@ -2905,14 +2896,6 @@ void curse_equipment_dg(int chance, int heavy_chance)
* 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
@@ -2926,12 +2909,6 @@ void curse_equipment_dg(int chance, int heavy_chance)
* could be left in a bizarre situation after the player ducked behind a
* pillar and then teleported away, for example.
*
- * 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
* them, or has spells but they will have no "useful" effect. Note that
@@ -2940,7 +2917,7 @@ void curse_equipment_dg(int chance, int heavy_chance)
* Note the special "MFLAG_NICE" flag, which prevents a monster from using
* any spell attacks until the player has had a single chance to move.
*/
-bool_ make_attack_spell(int m_idx)
+static bool_ make_attack_spell(int m_idx)
{
int k, chance, thrown_spell, rlev, failrate;
byte spell[96], num = 0;
@@ -2963,9 +2940,6 @@ bool_ make_attack_spell(int m_idx)
/* Assume "normal" target */
bool_ normal = TRUE;
- /* Assume "projectable" */
- bool_ direct = TRUE;
-
/* Target location */
if (m_ptr->target > -1)
{
@@ -3003,9 +2977,6 @@ bool_ make_attack_spell(int m_idx)
/* Sometimes forbid inate attacks (breaths) */
if (rand_int(100) >= (chance * 2)) no_inate = TRUE;
- /* XXX XXX XXX Handle "track_target" option (?) */
-
-
/* Hack -- require projectable player */
if (normal)
{
@@ -3152,8 +3123,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_SHRIEK */
case 96 + 0:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
msg_format("%^s makes a high pitched shriek.", m_name);
aggravate_monsters(m_idx);
break;
@@ -3168,7 +3138,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_S_ANIMAL */
case 96 + 2:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons an animal!", m_name);
for (k = 0; k < 1; k++)
@@ -3182,7 +3152,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_ROCKET */
case 96 + 3:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s shoots something.", m_name);
else msg_format("%^s fires a rocket.", m_name);
breath(m_idx, GF_ROCKET,
@@ -3194,7 +3164,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_ARROW_1 */
case 96 + 4:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
else msg_format("%^s fires an arrow.", m_name);
bolt(m_idx, GF_ARROW, damroll(1, 6));
@@ -3205,7 +3175,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_ARROW_2 */
case 96 + 5:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
else msg_format("%^s fires an arrow!", m_name);
bolt(m_idx, GF_ARROW, damroll(3, 6));
@@ -3216,7 +3186,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_ARROW_3 */
case 96 + 6:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
else msg_format("%^s fires a missile.", m_name);
bolt(m_idx, GF_ARROW, damroll(5, 6));
@@ -3227,7 +3197,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_ARROW_4 */
case 96 + 7:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s makes a strange noise.", m_name);
else msg_format("%^s fires a missile!", m_name);
bolt(m_idx, GF_ARROW, damroll(7, 6));
@@ -3238,7 +3208,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_ACID */
case 96 + 8:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes acid.", m_name);
breath(m_idx, GF_ACID,
@@ -3250,7 +3220,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_ELEC */
case 96 + 9:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes lightning.", m_name);
breath(m_idx, GF_ELEC,
@@ -3262,7 +3232,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_FIRE */
case 96 + 10:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes fire.", m_name);
breath(m_idx, GF_FIRE,
@@ -3274,7 +3244,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_COLD */
case 96 + 11:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes frost.", m_name);
breath(m_idx, GF_COLD,
@@ -3286,7 +3256,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_POIS */
case 96 + 12:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes gas.", m_name);
breath(m_idx, GF_POIS,
@@ -3299,7 +3269,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_NETH */
case 96 + 13:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes nether.", m_name);
breath(m_idx, GF_NETHER,
@@ -3311,7 +3281,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_LITE */
case 96 + 14:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes light.", m_name);
breath(m_idx, GF_LITE,
@@ -3323,7 +3293,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_DARK */
case 96 + 15:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes darkness.", m_name);
breath(m_idx, GF_DARK,
@@ -3335,7 +3305,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_CONF */
case 96 + 16:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes confusion.", m_name);
breath(m_idx, GF_CONFUSION,
@@ -3347,7 +3317,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_SOUN */
case 96 + 17:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes sound.", m_name);
breath(m_idx, GF_SOUND,
@@ -3359,7 +3329,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_CHAO */
case 96 + 18:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes chaos.", m_name);
breath(m_idx, GF_CHAOS,
@@ -3371,7 +3341,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_DISE */
case 96 + 19:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes disenchantment.", m_name);
breath(m_idx, GF_DISENCHANT,
@@ -3383,7 +3353,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_NEXU */
case 96 + 20:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes nexus.", m_name);
breath(m_idx, GF_NEXUS,
@@ -3395,7 +3365,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_TIME */
case 96 + 21:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes time.", m_name);
breath(m_idx, GF_TIME,
@@ -3406,7 +3376,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_INER */
case 96 + 22:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes inertia.", m_name);
breath(m_idx, GF_INERTIA,
@@ -3417,7 +3387,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_GRAV */
case 96 + 23:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes gravity.", m_name);
breath(m_idx, GF_GRAVITY,
@@ -3428,7 +3398,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_SHAR */
case 96 + 24:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes shards.", m_name);
breath(m_idx, GF_SHARDS,
@@ -3440,7 +3410,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_PLAS */
case 96 + 25:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes plasma.", m_name);
breath(m_idx, GF_PLASMA,
@@ -3451,7 +3421,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_WALL */
case 96 + 26:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes force.", m_name);
breath(m_idx, GF_FORCE,
@@ -3462,7 +3432,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_MANA */
case 96 + 27:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes magical energy.", m_name);
breath(m_idx, GF_MANA,
@@ -3473,7 +3443,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BA_NUKE */
case 96 + 28:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a ball of radiation.", m_name);
breath(m_idx, GF_NUKE, (rlev + damroll(10, 6)), 2);
@@ -3484,7 +3454,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_NUKE */
case 96 + 29:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes toxic waste.", m_name);
breath(m_idx, GF_NUKE,
@@ -3496,7 +3466,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BA_CHAO */
case 96 + 30:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles frighteningly.", m_name);
else msg_format("%^s invokes a raw chaos.", m_name);
breath(m_idx, GF_CHAOS, (rlev * 2) + damroll(10, 10), 4);
@@ -3507,7 +3477,7 @@ bool_ make_attack_spell(int m_idx)
/* RF4_BR_DISI -> Disintegration breath! */
case 96 + 31:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s breathes.", m_name);
else msg_format("%^s breathes disintegration.", m_name);
breath(m_idx, GF_DISINTEGRATE,
@@ -3520,7 +3490,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_ACID */
case 128 + 0:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts an acid ball.", m_name);
breath(m_idx, GF_ACID,
@@ -3532,7 +3502,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_ELEC */
case 128 + 1:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a lightning ball.", m_name);
breath(m_idx, GF_ELEC,
@@ -3544,7 +3514,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_FIRE */
case 128 + 2:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a fire ball.", m_name);
breath(m_idx, GF_FIRE,
@@ -3556,7 +3526,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_COLD */
case 128 + 3:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a frost ball.", m_name);
breath(m_idx, GF_COLD,
@@ -3568,7 +3538,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_POIS */
case 128 + 4:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a stinking cloud.", m_name);
breath(m_idx, GF_POIS,
@@ -3580,7 +3550,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_NETH */
case 128 + 5:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a nether ball.", m_name);
breath(m_idx, GF_NETHER,
@@ -3592,7 +3562,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_WATE */
case 128 + 6:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s gestures fluidly.", m_name);
msg_print("You are engulfed in a whirlpool.");
@@ -3604,7 +3574,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_MANA */
case 128 + 7:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles powerfully.", m_name);
else msg_format("%^s invokes a mana storm.", m_name);
breath(m_idx, GF_MANA,
@@ -3615,7 +3585,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BA_DARK */
case 128 + 8:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles powerfully.", m_name);
else msg_format("%^s invokes a darkness storm.", m_name);
breath(m_idx, GF_DARK,
@@ -3627,13 +3597,12 @@ bool_ make_attack_spell(int m_idx)
/* RF5_DRAIN_MANA */
case 128 + 9:
{
- if (!direct) break;
if (p_ptr->csp)
{
int r1;
/* Disturb if legal */
- disturb(1, 0);
+ disturb(1);
/* Basic message */
msg_format("%^s draws psychic energy from you!", m_name);
@@ -3656,7 +3625,7 @@ bool_ make_attack_spell(int m_idx)
}
/* Redraw mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -3669,7 +3638,7 @@ bool_ make_attack_spell(int m_idx)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Special message */
if (seen)
@@ -3685,8 +3654,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_MIND_BLAST */
case 128 + 10:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (!seen)
{
msg_print("You feel something focusing on your mind.");
@@ -3722,8 +3690,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BRAIN_SMASH */
case 128 + 11:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (!seen)
{
msg_print("You feel something focusing on your mind.");
@@ -3771,8 +3738,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_CAUSE_1 */
case 128 + 12:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s points at you and curses.", m_name);
if (rand_int(100) < p_ptr->skill_sav)
@@ -3790,8 +3756,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_CAUSE_2 */
case 128 + 13:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s points at you and curses horribly.", m_name);
if (rand_int(100) < p_ptr->skill_sav)
@@ -3809,8 +3774,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_CAUSE_3 */
case 128 + 14:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles loudly.", m_name);
else msg_format("%^s points at you, incanting terribly!", m_name);
if (rand_int(100) < p_ptr->skill_sav)
@@ -3828,8 +3792,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_CAUSE_4 */
case 128 + 15:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s screams the word 'DIE!'", m_name);
else msg_format("%^s points at you, screaming the word DIE!", m_name);
if (rand_int(100) < p_ptr->skill_sav)
@@ -3847,7 +3810,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_ACID */
case 128 + 16:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a acid bolt.", m_name);
bolt(m_idx, GF_ACID, damroll(7, 8) + (rlev / 3));
@@ -3859,7 +3822,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_ELEC */
case 128 + 17:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a lightning bolt.", m_name);
bolt(m_idx, GF_ELEC, damroll(4, 8) + (rlev / 3));
@@ -3871,7 +3834,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_FIRE */
case 128 + 18:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a fire bolt.", m_name);
bolt(m_idx, GF_FIRE, damroll(9, 8) + (rlev / 3));
@@ -3883,7 +3846,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_COLD */
case 128 + 19:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a frost bolt.", m_name);
bolt(m_idx, GF_COLD, damroll(6, 8) + (rlev / 3));
@@ -3902,7 +3865,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_NETH */
case 128 + 21:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a nether bolt.", m_name);
bolt(m_idx, GF_NETHER, 30 + damroll(5, 5) + (rlev * 3) / 2);
@@ -3914,7 +3877,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_WATE */
case 128 + 22:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a water bolt.", m_name);
bolt(m_idx, GF_WATER, damroll(10, 10) + (rlev));
@@ -3925,7 +3888,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_MANA */
case 128 + 23:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a mana bolt.", m_name);
bolt(m_idx, GF_MANA, randint(rlev * 7 / 2) + 50);
@@ -3936,7 +3899,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_PLAS */
case 128 + 24:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a plasma bolt.", m_name);
bolt(m_idx, GF_PLASMA, 10 + damroll(8, 7) + (rlev));
@@ -3947,7 +3910,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BO_ICEE */
case 128 + 25:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts an ice bolt.", m_name);
bolt(m_idx, GF_ICE, damroll(6, 6) + (rlev));
@@ -3959,7 +3922,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_MISSILE */
case 128 + 26:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a magic missile.", m_name);
bolt(m_idx, GF_MISSILE, damroll(2, 6) + (rlev / 3));
@@ -3970,8 +3933,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_SCARE */
case 128 + 27:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles, and you hear scary noises.", m_name);
else msg_format("%^s casts a fearful illusion.", m_name);
if (p_ptr->resist_fear)
@@ -3993,8 +3955,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_BLIND */
case 128 + 28:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s casts a spell, burning your eyes!", m_name);
if (p_ptr->resist_blind)
@@ -4016,8 +3977,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_CONF */
case 128 + 29:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles, and you hear puzzling noises.", m_name);
else msg_format("%^s creates a mesmerizing illusion.", m_name);
if (p_ptr->resist_conf)
@@ -4039,8 +3999,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_SLOW */
case 128 + 30:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
msg_format("%^s drains power from your muscles!", m_name);
if (p_ptr->free_act)
{
@@ -4061,8 +4020,7 @@ bool_ make_attack_spell(int m_idx)
/* RF5_HOLD */
case 128 + 31:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s stares deep into your eyes!", m_name);
if (p_ptr->free_act)
@@ -4086,7 +4044,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_HASTE */
case 160 + 0:
{
- disturb(1, 0);
+ disturb(1);
if (blind)
{
msg_format("%^s mumbles.", m_name);
@@ -4116,7 +4074,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_HAND_DOOM */
case 160 + 1:
{
- disturb(1, 0);
+ disturb(1);
msg_format("%^s invokes the Hand of Doom!", m_name);
if (rand_int(100) < p_ptr->skill_sav)
{
@@ -4137,7 +4095,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_HEAL */
case 160 + 2:
{
- disturb(1, 0);
+ disturb(1);
/* Message */
if (blind)
@@ -4184,7 +4142,7 @@ bool_ make_attack_spell(int m_idx)
}
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Cancel fear */
if (m_ptr->monfear)
@@ -4201,7 +4159,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_ANIMALS */
case 160 + 3:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons some animals!", m_name);
for (k = 0; k < 4; k++)
@@ -4215,7 +4173,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_BLINK */
case 160 + 4:
{
- disturb(1, 0);
+ disturb(1);
msg_format("%^s blinks away.", m_name);
teleport_away(m_idx, 10);
break;
@@ -4224,7 +4182,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_TPORT */
case 160 + 5:
{
- disturb(1, 0);
+ disturb(1);
msg_format("%^s teleports away.", m_name);
teleport_away(m_idx, MAX_SIGHT * 2 + 5);
break;
@@ -4233,8 +4191,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_TELE_TO */
case 160 + 6:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
msg_format("%^s commands you to return.", m_name);
teleport_player_to(m_ptr->fy, m_ptr->fx);
break;
@@ -4243,8 +4200,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_TELE_AWAY */
case 160 + 7:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
msg_format("%^s teleports you away.", m_name);
teleport_player(100);
break;
@@ -4253,8 +4209,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_TELE_LEVEL */
case 160 + 8:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles strangely.", m_name);
else msg_format("%^s gestures at your feet.", m_name);
if (p_ptr->resist_nexus)
@@ -4276,8 +4231,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_DARKNESS */
case 160 + 9:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s gestures in shadow.", m_name);
(void)unlite_area(0, 3);
@@ -4287,8 +4241,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_TRAPS */
case 160 + 10:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles, and then cackles evilly.", m_name);
else msg_format("%^s casts a spell and cackles evilly.", m_name);
(void)trap_creation();
@@ -4298,8 +4251,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_FORGET */
case 160 + 11:
{
- if (!direct) break;
- disturb(1, 0);
+ disturb(1);
msg_format("%^s tries to blank your mind.", m_name);
if (rand_int(100) < p_ptr->skill_sav)
@@ -4320,7 +4272,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_BUG */
case 160 + 13:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically codes some software bugs.", m_name);
for (k = 0; k < 6; k++)
@@ -4334,7 +4286,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_RNG */
case 160 + 14:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically codes some RNGs.", m_name);
for (k = 0; k < 6; k++)
@@ -4348,7 +4300,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_THUNDERLORD */
case 160 + 15:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons a Thunderlord!", m_name);
for (k = 0; k < 1; k++)
@@ -4362,7 +4314,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_SUMMON_KIN */
case 160 + 16:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons %s %s.",
m_name, m_poss,
@@ -4382,7 +4334,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_HI_DEMON */
case 160 + 17:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons greater demons!", m_name);
if (blind && count) msg_print("You hear heavy steps nearby.");
@@ -4393,7 +4345,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_MONSTER */
case 160 + 18:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons help!", m_name);
for (k = 0; k < 1; k++)
@@ -4407,7 +4359,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_MONSTERS */
case 160 + 19:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons monsters!", m_name);
for (k = 0; k < 8; k++)
@@ -4421,7 +4373,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_ANT */
case 160 + 20:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons ants.", m_name);
for (k = 0; k < 6; k++)
@@ -4435,7 +4387,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_SPIDER */
case 160 + 21:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons spiders.", m_name);
for (k = 0; k < 6; k++)
@@ -4449,7 +4401,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_HOUND */
case 160 + 22:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons hounds.", m_name);
for (k = 0; k < 6; k++)
@@ -4463,7 +4415,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_HYDRA */
case 160 + 23:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons hydras.", m_name);
for (k = 0; k < 6; k++)
@@ -4477,7 +4429,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_ANGEL */
case 160 + 24:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons an angel!", m_name);
for (k = 0; k < 1; k++)
@@ -4491,7 +4443,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_DEMON */
case 160 + 25:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons a demon!", m_name);
for (k = 0; k < 1; k++)
@@ -4505,7 +4457,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_UNDEAD */
case 160 + 26:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons an undead adversary!", m_name);
for (k = 0; k < 1; k++)
@@ -4519,7 +4471,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_DRAGON */
case 160 + 27:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons a dragon!", m_name);
for (k = 0; k < 1; k++)
@@ -4533,7 +4485,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_HI_UNDEAD */
case 160 + 28:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons greater undead!", m_name);
for (k = 0; k < 8; k++)
@@ -4550,7 +4502,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_HI_DRAGON */
case 160 + 29:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons ancient dragons!", m_name);
for (k = 0; k < 8; k++)
@@ -4567,7 +4519,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_WRAITH */
case 160 + 30:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons Wraith!", m_name);
@@ -4587,7 +4539,7 @@ bool_ make_attack_spell(int m_idx)
/* RF6_S_UNIQUE */
case 160 + 31:
{
- disturb(1, 0);
+ disturb(1);
if (blind) msg_format("%^s mumbles.", m_name);
else msg_format("%^s magically summons special opponents!", m_name);
for (k = 0; k < 8; k++)
@@ -5108,10 +5060,12 @@ static bool_ get_moves(int m_idx, int *mm)
/* Let quests redefine AI */
if (r_ptr->flags7 & RF7_AI_SPECIAL)
{
- if (process_hooks_ret(HOOK_MONSTER_AI, "dd", "(d)", m_idx))
+ struct hook_monster_ai_in in = { m_idx, &m_list[m_idx] };
+ struct hook_monster_ai_out out = { 0, 0 };
+ if (process_hooks_new(HOOK_MONSTER_AI, &in, &out))
{
- y2 = process_hooks_return[0].num;
- x2 = process_hooks_return[1].num;
+ y2 = out.y;
+ x2 = out.x;
}
}
@@ -5469,7 +5423,6 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
/* Not allowed to attack */
if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
- if (tr_ptr->flags7 & RF7_IM_MELEE) return FALSE;
/* Total armor */
ac = t_ptr->ac;
@@ -5541,7 +5494,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
if (!effect || check_hit2(power, rlev, ac))
{
/* Always disturbing */
- if (disturb_other) disturb(1, 0);
+ if (disturb_other) disturb(1);
/* Describe the attack method */
switch (method)
@@ -5946,7 +5899,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx)
if (m_ptr->ml)
{
/* Disturbing */
- disturb(1, 0);
+ disturb(1);
/* Message */
monster_msg("%^s misses %s.", m_name, t_name);
@@ -6137,7 +6090,7 @@ static void process_monster(int m_idx, bool_ is_frien)
msg_format("%^s is no longer bleeding.", m_name);
/* Hack -- Update the health bar */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
}
}
}
@@ -6176,7 +6129,7 @@ static void process_monster(int m_idx, bool_ is_frien)
msg_format("%^s is no longer poisoned.", m_name);
/* Hack -- Update the health bar */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
}
}
}
@@ -6392,41 +6345,39 @@ static void process_monster(int m_idx, bool_ is_frien)
if (ai_multiply(m_idx)) return;
}
- if (speak_unique)
+ if (randint(SPEAK_CHANCE) == 1)
{
- if (randint(SPEAK_CHANCE) == 1)
+ if (player_has_los_bold(oy, ox) && (r_ptr->flags2 & RF2_CAN_SPEAK))
{
- if (player_has_los_bold(oy, ox) && (r_ptr->flags2 & RF2_CAN_SPEAK))
- {
- char m_name[80];
- char monmessage[80];
+ char m_name[80];
+ char monmessage[80];
- /* Acquire the monster name/poss */
- if (m_ptr->ml)
- monster_desc(m_name, m_ptr, 0);
- else
- strcpy(m_name, "It");
+ /* Acquire the monster name/poss */
+ if (m_ptr->ml)
+ monster_desc(m_name, m_ptr, 0);
+ else
+ strcpy(m_name, "It");
- /* xtra_line function by Matt Graham--allow uniques to */
- /* say "unique" things based on their monster index. */
- /* Try for the unique's lines in "monspeak.txt" first. */
- /* 0 is SUCCESS, of course.... */
+ /* xtra_line function by Matt Graham--allow uniques to */
+ /* say "unique" things based on their monster index. */
+ /* Try for the unique's lines in "monspeak.txt" first. */
+ /* 0 is SUCCESS, of course.... */
- if (!process_hooks(HOOK_MON_SPEAK, "(d,s)", m_idx, m_name))
+ struct hook_mon_speak_in in = { m_idx, m_name };
+ if (!process_hooks_new(HOOK_MON_SPEAK, &in, NULL))
+ {
+ if (get_xtra_line("monspeak.txt", m_ptr, monmessage) != 0)
{
- if (get_xtra_line("monspeak.txt", m_ptr, monmessage) != 0)
- {
- /* Get a message from old defaults if new don't work */
+ /* Get a message from old defaults if new don't work */
- if (is_friend(m_ptr) > 0)
- get_rnd_line("speakpet.txt", monmessage);
- else if (m_ptr->monfear)
- get_rnd_line("monfear.txt", monmessage);
- else
- get_rnd_line("bravado.txt", monmessage);
- }
- msg_format("%^s %s", m_name, monmessage);
+ if (is_friend(m_ptr) > 0)
+ get_rnd_line("speakpet.txt", monmessage);
+ else if (m_ptr->monfear)
+ get_rnd_line("monfear.txt", monmessage);
+ else
+ get_rnd_line("bravado.txt", monmessage);
}
+ msg_format("%^s %s", m_name, monmessage);
}
}
}
@@ -6741,7 +6692,7 @@ static void process_monster(int m_idx, bool_ is_frien)
msg_print("You hear a door burst open!");
/* Disturb (sometimes) */
- if (disturb_minor) disturb(0, 0);
+ if (disturb_minor) disturb(0);
/* The door was bashed open */
did_bash_door = TRUE;
@@ -6982,8 +6933,6 @@ static void process_monster(int m_idx, bool_ is_frien)
/* Creature has been allowed move */
if (do_move)
{
- s16b this_o_idx, next_o_idx = 0;
-
/* Take a turn */
do_turn = TRUE;
@@ -7043,7 +6992,7 @@ static void process_monster(int m_idx, bool_ is_frien)
{
/* Disturb */
if ((is_friend(m_ptr) < 0) || disturb_pets)
- disturb(0, 0);
+ disturb(0);
}
/* Check for monster trap */
@@ -7053,16 +7002,14 @@ static void process_monster(int m_idx, bool_ is_frien)
}
else
{
+ /* Copy list of objects; we need a copy because we're mutating the list. */
+ auto const object_idxs(c_ptr->o_idxs);
+
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[this_o_idx];
/* Skip gold */
if (o_ptr->tval == TV_GOLD) continue;
@@ -7142,8 +7089,7 @@ static void process_monster(int m_idx, bool_ is_frien)
msg_format("%^s picks up %s.", m_name, o_name);
}
- /* Option */
- if (testing_carry)
+ /* Put into inventory of monster */
{
/* Excise the object */
excise_object_idx(this_o_idx);
@@ -7157,18 +7103,8 @@ static void process_monster(int m_idx, bool_ is_frien)
/* Memorize monster */
o_ptr->held_m_idx = m_idx;
- /* Build a stack */
- o_ptr->next_o_idx = m_ptr->hold_o_idx;
-
/* Carry object */
- m_ptr->hold_o_idx = this_o_idx;
- }
-
- /* Nope */
- else
- {
- /* Delete the object */
- delete_object_idx(this_o_idx);
+ m_ptr->hold_o_idxs.push_back(this_o_idx);
}
}
diff --git a/src/melee2.hpp b/src/melee2.hpp
new file mode 100644
index 00000000..fece0564
--- /dev/null
+++ b/src/melee2.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_type_fwd.hpp"
+
+extern int monst_spell_monst_spell;
+extern bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note);
+extern void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear);
+extern int check_hit2(int power, int level, int ac);
+extern void process_monsters(void);
+extern void curse_equipment(int chance, int heavy_chance);
+extern void curse_equipment_dg(int chance, int heavy_chance);
diff --git a/src/messages.c b/src/messages.cc
index e88cf58e..a4ce949d 100644
--- a/src/messages.c
+++ b/src/messages.cc
@@ -1,6 +1,10 @@
-#include "messages.h"
+#include "messages.hpp"
-#include "angband.h"
+#include "tome/make_array.hpp"
+
+#include "z-term.h"
+#include "z-form.h"
+#include "z-util.h"
/*
* OPTION: Maximum number of messages to remember (see "io.c")
@@ -83,10 +87,10 @@ static char *message__buf;
void message_init()
{
/* Message variables */
- C_MAKE(message__ptr, MESSAGE_MAX, u16b);
- C_MAKE(message__color, MESSAGE_MAX, byte);
- C_MAKE(message__count, MESSAGE_MAX, u16b);
- C_MAKE(message__buf, MESSAGE_BUF, char);
+ message__ptr = make_array<u16b>(MESSAGE_MAX);
+ message__color = make_array<byte>(MESSAGE_MAX);
+ message__count = make_array<u16b>(MESSAGE_MAX);
+ message__buf = make_array<char>(MESSAGE_BUF);
/* Hack -- No messages yet */
message__tail = MESSAGE_BUF;
diff --git a/src/messages.h b/src/messages.h
deleted file mode 100644
index 401c5727..00000000
--- a/src/messages.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef H_f6dac2dc_0449_4764_9942_1c1fe7a70bc4
-#define H_f6dac2dc_0449_4764_9942_1c1fe7a70bc4
-
-#include "h-type.h"
-
-void message_init();
-s16b message_num();
-cptr message_str(int age);
-byte message_color(int age);
-byte message_type(int age);
-void message_add(cptr msg, byte color);
-
-#endif
diff --git a/src/messages.hpp b/src/messages.hpp
new file mode 100644
index 00000000..22943ab9
--- /dev/null
+++ b/src/messages.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+
+void message_init();
+s16b message_num();
+cptr message_str(int age);
+byte message_color(int age);
+void message_add(cptr msg, byte color);
diff --git a/src/meta_class_type.hpp b/src/meta_class_type.hpp
new file mode 100644
index 00000000..e74e75b3
--- /dev/null
+++ b/src/meta_class_type.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct meta_class_type
+{
+ char name[80]; /* Name */
+ byte color;
+ s16b *classes; /* list of classes */
+};
diff --git a/src/meta_class_type_fwd.hpp b/src/meta_class_type_fwd.hpp
new file mode 100644
index 00000000..2d0e482a
--- /dev/null
+++ b/src/meta_class_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct meta_class_type;
diff --git a/src/mimic.c b/src/mimic.cc
index 90c8a62a..b888ec52 100644
--- a/src/mimic.c
+++ b/src/mimic.cc
@@ -1,5 +1,38 @@
-#include "angband.h"
-#include <assert.h>
+#include "mimic.hpp"
+
+#include "player_type.hpp"
+#include "skill_type.hpp"
+#include "stats.hpp"
+#include "variable.hpp"
+#include "xtra1.hpp"
+
+#include <cassert>
+
+/**
+ * Mimicry forms
+ */
+typedef struct mimic_duration_type mimic_duration_type;
+struct mimic_duration_type
+{
+ s16b min;
+ s16b max;
+};
+
+typedef struct mimic_form_type mimic_form_type;
+struct mimic_form_type
+{
+ int modules[3]; /* Modules where this mimicry form is available; terminated with a -1 entry */
+ cptr name; /* Name of mimicry form */
+ cptr obj_name; /* Object mimicry form name */
+ cptr desc; /* Description */
+ cptr realm; /* Realm of mimicry */
+ bool_ limit; /* If true, the form is not available except through special means */
+ byte level;
+ byte rarity;
+ mimic_duration_type duration;
+ s32b (*calc)(); /* Callback to calculate bonuses; return number of blows to add */
+ void (*power)(); /* Callback to calculate powers */
+};
static s32b abomination_calc()
{
@@ -371,7 +404,7 @@ static s32b fire_elemental_calc()
/*
* Mimicry forms
*/
-mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
+static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] =
{
{ /* 0 */
{ MODULE_TOME, MODULE_THEME, -1 },
diff --git a/src/mimic.hpp b/src/mimic.hpp
new file mode 100644
index 00000000..d9c8f3bd
--- /dev/null
+++ b/src/mimic.hpp
@@ -0,0 +1,10 @@
+#include "h-basic.h"
+
+extern s16b resolve_mimic_name(cptr name);
+extern s16b find_random_mimic_shape(byte level, bool_ limit);
+extern cptr get_mimic_name(s16b mf_idx);
+extern cptr get_mimic_object_name(s16b mf_idx);
+extern byte get_mimic_level(s16b mf_idx);
+extern s32b get_mimic_random_duration(s16b mf_idx);
+extern byte calc_mimic();
+extern void calc_mimic_power();
diff --git a/src/module_type.hpp b/src/module_type.hpp
new file mode 100644
index 00000000..96938856
--- /dev/null
+++ b/src/module_type.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Module descriptor.
+ */
+struct module_type
+{
+ /* Metadata about the module: author, description, etc. */
+ struct {
+ /* Module name */
+ cptr name;
+
+ /* Module version number */
+ struct {
+ s32b major;
+ s32b minor;
+ s32b patch;
+ } version;
+
+ /* Module author */
+ struct {
+ cptr name;
+ cptr email;
+ } author;
+
+ /* Module description */
+ cptr desc;
+
+ /* Save file tag */
+ cptr save_file_tag;
+
+ /* Module directory */
+ cptr module_dir;
+ } meta;
+
+ /* Random artifact generation chances */
+ struct {
+ s32b weapon_chance;
+ s32b armor_chance;
+ s32b jewelry_chance;
+ } randarts;
+
+ /* Max player level. */
+ int max_plev;
+
+ /* Skills */
+ struct {
+ /* Skill points per level */
+ s32b skill_per_level;
+ /* Maximum "overage" for skill points, i.e. how many skill
+ points you can go above your current level. */
+ s32b max_skill_overage;
+ } skills;
+
+ /* Function to show introduction to module */
+ void (*intro)();
+
+ /* Function to compute race status, i.e. whether monsters
+ are friendly/neutral towards the player. Returns NULL
+ to indicate that no override happens. */
+ s16b *(*race_status)(int r_idx);
+};
diff --git a/src/modules.c b/src/modules.cc
index 8376e3fb..611afe63 100644
--- a/src/modules.c
+++ b/src/modules.cc
@@ -1,7 +1,3 @@
-/* File: modules.c */
-
-/* Purpose: T-engine modules */
-
/*
* Copyright (c) 2003 DarkGod
*
@@ -10,26 +6,102 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "modules.hpp"
+#include "modules.h"
+
+#include "birth.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "files.hpp"
+#include "hook_eat_in.hpp"
+#include "hook_give_in.hpp"
+#include "hook_move_in.hpp"
+#include "hook_stair_in.hpp"
+#include "hook_stair_out.hpp"
+#include "hook_new_monster_end_in.hpp"
+#include "hooks.hpp"
+#include "joke.hpp"
+#include "lua_bind.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <cassert>
+#include <chrono>
+#include <thread>
+
+using std::this_thread::sleep_for;
+using std::chrono::milliseconds;
-static void module_reset_dir_aux(cptr *dir, cptr new_path)
+/*
+ * Check and create if needed the directory dirpath
+ */
+bool_ private_check_user_directory(cptr dirpath)
+{
+ /* Is this used anywhere else in *bands? */
+ struct stat stat_buf;
+
+ int ret;
+
+ /* See if it already exists */
+ ret = stat(dirpath, &stat_buf);
+
+ /* It does */
+ if (ret == 0)
+ {
+ /* Now we see if it's a directory */
+ if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);
+
+ /*
+ * Something prevents us from create a directory with
+ * the same pathname
+ */
+ return (FALSE);
+ }
+
+ /* No - this maybe the first time. Try to create a directory */
+ else
+ {
+ /* Create the ~/.ToME directory */
+ ret = mkdir(dirpath, 0700);
+
+ /* An error occured */
+ if (ret == -1) return (FALSE);
+
+ /* Success */
+ return (TRUE);
+ }
+}
+
+static void module_reset_dir_aux(char **dir, cptr new_path)
{
char buf[1024];
/* Build the new path */
strnfmt(buf, sizeof (buf), "%s%s%s", *dir, PATH_SEP, new_path);
- string_free(*dir);
- *dir = string_make(buf);
+ free(*dir);
+ *dir = strdup(buf);
/* Make it if needed */
if (!private_check_user_directory(*dir))
quit(format("Unable to create module dir %s\n", *dir));
}
-void module_reset_dir(cptr dir, cptr new_path)
+static void module_reset_dir(cptr dir, cptr new_path)
{
- cptr *d = 0;
+ char **d = 0;
char buf[1025];
if (!strcmp(dir, "core")) d = &ANGBAND_DIR_CORE;
@@ -39,37 +111,30 @@ void module_reset_dir(cptr dir, cptr new_path)
if (!strcmp(dir, "file")) d = &ANGBAND_DIR_FILE;
if (!strcmp(dir, "help")) d = &ANGBAND_DIR_HELP;
if (!strcmp(dir, "info")) d = &ANGBAND_DIR_INFO;
- if (!strcmp(dir, "scpt")) d = &ANGBAND_DIR_SCPT;
- if (!strcmp(dir, "patch")) d = &ANGBAND_DIR_PATCH;
if (!strcmp(dir, "pref")) d = &ANGBAND_DIR_PREF;
if (!strcmp(dir, "xtra")) d = &ANGBAND_DIR_XTRA;
if (!strcmp(dir, "user")) d = &ANGBAND_DIR_USER;
if (!strcmp(dir, "note")) d = &ANGBAND_DIR_NOTE;
- if (!strcmp(dir, "cmov")) d = &ANGBAND_DIR_CMOV;
+
if (
!strcmp(dir, "user") ||
- !strcmp(dir, "note") ||
- !strcmp(dir, "cmov"))
+ !strcmp(dir, "note"))
{
char user_path[1024];
/* copied from init_file_paths */
path_parse(user_path, 1024, PRIVATE_USER_PATH);
strcat(user_path, USER_PATH_VERSION);
strnfmt(buf, 1024, "%s%s%s", user_path, PATH_SEP, new_path);
- string_free(*d);
- *d = string_make(buf);
+
+ free(*d);
+ *d = strdup(buf);
+
// Make it if needed */
if (!private_check_user_directory(*d))
{
quit(format("Unable to create module dir %s\n", *d));
}
}
-#ifdef PRIVATE_USER_PATH_DATA
- else if (!strcmp(dir, "data"))
- {
- module_reset_dir_aux(&ANGBAND_DIR_DATA, new_path);
- }
-#endif
else if (!strcmp(dir, "save"))
{
module_reset_dir_aux(&ANGBAND_DIR_SAVE, new_path);
@@ -79,8 +144,8 @@ void module_reset_dir(cptr dir, cptr new_path)
/* Build the new path */
strnfmt(buf, 1024, "%s%s%s%s%s", ANGBAND_DIR_MODULES, PATH_SEP, new_path, PATH_SEP, dir);
- string_free(*d);
- *d = string_make(buf);
+ free(*d);
+ *d = strdup(buf);
}
}
@@ -167,7 +232,6 @@ static void init_module(module_type *module_ptr)
module_reset_dir("help", dir);
module_reset_dir("note", dir);
module_reset_dir("save", dir);
- module_reset_dir("scpt", dir);
module_reset_dir("user", dir);
module_reset_dir("pref", dir);
}
@@ -220,7 +284,8 @@ bool_ select_module()
{
/* Process the module */
init_module(&modules[sel]);
- game_module = string_make(modules[sel].meta.name);
+
+ game_module = modules[sel].meta.name;
activate_module(sel);
@@ -290,7 +355,8 @@ bool_ select_module()
/* Process the module */
init_module(&modules[x]);
- game_module = string_make(modules[x].meta.name);
+
+ game_module = modules[x].meta.name;
activate_module(x);
@@ -320,14 +386,13 @@ static bool_ dleft(byte c, cptr str, int y, int o)
time = time + 1;
if (time >= 4)
{
- Term_xtra(TERM_XTRA_DELAY, 1);
+ sleep_for(milliseconds(1));
time = 0;
}
Term_redraw_section(a - 1, y, a, y);
a = a + 1;
- inkey_scan = TRUE;
- if (inkey()) {
+ if (inkey_scan()) {
return TRUE;
}
}
@@ -340,9 +405,9 @@ static bool_ dleft(byte c, cptr str, int y, int o)
static bool_ dright(byte c, cptr str, int y, int o)
{
- int x = 39 - (strlen(str) / 2) + o;
- int i = 1;
- while (i <= strlen(str))
+ int n = strlen(str); // Conversion to int to avoid warnings
+ int x = 39 - (n / 2) + o;
+ for (int i = 1; i <= n; i++)
{
int a = 79;
int time = 0;
@@ -354,20 +419,17 @@ static bool_ dright(byte c, cptr str, int y, int o)
Term_putch(a, y, c, str[i-1]);
time = time + 1;
if (time >= 4) {
- Term_xtra(TERM_XTRA_DELAY, 1);
+ sleep_for(milliseconds(1));
time = 0;
}
Term_redraw_section(a, y, a + 1, y);
a = a - 1;
- inkey_scan = TRUE;
- if (inkey()) {
+ if (inkey_scan()) {
return TRUE;
}
}
}
-
- i = i + 1;
}
return FALSE;
}
@@ -403,7 +465,6 @@ static bool_ show_intro(intro_text intro_texts[])
/* Wait for key */
Term_putch(0, 0, TERM_DARK, 32);
- inkey_scan = FALSE;
inkey();
/* Continue */
@@ -419,7 +480,7 @@ void tome_intro()
{ dleft , TERM_L_BLUE, "to find the true nature of the legends beyond them?", 12, 0, },
{ dright, TERM_L_BLUE, "If this is so, then seeketh me.", 13, -1, },
{ dleft , TERM_WHITE , "[Press any key to continue]", 23, -1, },
- { NULL, }
+ { NULL , TERM_WHITE , NULL, 0, 0, }
};
intro_text intro2[] =
{
@@ -432,7 +493,7 @@ void tome_intro()
{ dleft , TERM_WHITE , "present", 15, 1, },
{ dright, TERM_YELLOW , "T.o.M.E.", 16, 0, },
{ dleft , TERM_WHITE , "[Press any key to continue]", 23, -1, },
- { NULL, }
+ { NULL , TERM_WHITE , NULL, 0, 0, }
};
screen_save();
@@ -467,7 +528,7 @@ void theme_intro()
{ dright, TERM_L_BLUE , "In the land of Mordor, where the Shadows lie.", 17, -1, },
{ dright, TERM_L_GREEN, "--J.R.R. Tolkien", 18, 0, },
{ dleft , TERM_WHITE , "[Press any key to continue]", 23, -1, },
- { NULL, },
+ { NULL , TERM_WHITE , NULL, 0, 0, },
};
struct intro_text intro2[] =
{
@@ -480,7 +541,7 @@ void theme_intro()
{ dleft , TERM_WHITE , "present", 15, 1, },
{ dright, TERM_YELLOW , "Theme (a module for ToME)", 16, 0, },
{ dleft , TERM_WHITE , "[Press any key to continue]", 23, -1, },
- { NULL, },
+ { NULL , TERM_WHITE , NULL, 0, 0, },
};
screen_save();
@@ -719,7 +780,7 @@ static bool_ theme_push_past(void *data, void *in_, void *out_)
if (m_ptr->status >= MSTATUS_NEUTRAL)
{
- if ((cave_floor_bold(p->y, p->x) == TRUE) ||
+ if (cave_floor_bold(p->y, p->x) ||
(mr_ptr->flags2 == RF2_PASS_WALL))
{
char buf[128];
diff --git a/src/modules.h b/src/modules.h
new file mode 100644
index 00000000..8a3b88b0
--- /dev/null
+++ b/src/modules.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bool_ private_check_user_directory(cptr dirpath);
+extern cptr force_module;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/modules.hpp b/src/modules.hpp
new file mode 100644
index 00000000..d83e3e2e
--- /dev/null
+++ b/src/modules.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ select_module(void);
+extern bool_ module_savefile_loadable(cptr savefile_mod);
+extern void tome_intro();
+extern void theme_intro();
+extern s16b *theme_race_status(int r_idx);
+extern void init_hooks_module();
+extern int find_module(cptr name);
diff --git a/src/monster1.c b/src/monster1.cc
index 68882d27..77f916a7 100644
--- a/src/monster1.c
+++ b/src/monster1.cc
@@ -1,7 +1,3 @@
-/* File: monster1.c */
-
-/* Purpose: describe monsters (using monster memory) */
-
/*
* Copyright (c) 1989 James E. Wilson, Christopher J. Stuart
*
@@ -10,8 +6,17 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "monster1.hpp"
+#include "cave_type.hpp"
+#include "monster2.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "player_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
/*
* Pronoun arrays, by gender.
@@ -337,7 +342,7 @@ static void roff_aux(int r_idx, int ego, int remem)
char buf[2048];
/* Simple method */
- strcpy(buf, r_text + r_ptr->text);
+ strcpy(buf, r_ptr->text);
/* Dump it */
text_out(buf);
@@ -373,31 +378,17 @@ static void roff_aux(int r_idx, int ego, int remem)
text_out(", ");
else
text_out(format("%^s ", wd_he[msex]));
- if (depth_in_feet)
+
+ text_out(format("is normally found on level ", wd_he[msex]));
+ if (dun_level < r_ptr->level) /* out of depth monster */
{
- text_out(format("is normally found at depths of ", wd_he[msex]));
- if (dun_level < r_ptr->level) /* out of depth monster */
- {
- text_out_c(TERM_L_RED, format("%d", r_ptr->level * 50));
- }
- else
- {
- text_out_c(TERM_L_GREEN, format("%d", r_ptr->level * 50));
- }
- text_out(" feet");
+ text_out_c(TERM_L_RED, format("%d", r_ptr->level));
}
else
{
- text_out(format("is normally found on level ", wd_he[msex]));
- if (dun_level < r_ptr->level) /* out of depth monster */
- {
- text_out_c(TERM_L_RED, format("%d", r_ptr->level));
- }
- else
- {
- text_out_c(TERM_L_GREEN, format("%d", r_ptr->level));
- }
+ text_out_c(TERM_L_GREEN, format("%d", r_ptr->level));
}
+
old = TRUE;
}
@@ -523,16 +514,16 @@ static void roff_aux(int r_idx, int ego, int remem)
long i, j;
/* calculate the integer exp part */
- i = (long)r_ptr->mexp * r_ptr->level / p_ptr->lev;
+ i = static_cast<long>(r_ptr->mexp) * r_ptr->level / p_ptr->lev;
/* calculate the fractional exp part scaled by 100, */
/* must use long arithmetic to avoid overflow */
- j = ((((long)r_ptr->mexp * r_ptr->level % p_ptr->lev) *
- (long)1000 / p_ptr->lev + 5) / 10);
+ j = (((static_cast<long>(r_ptr->mexp) * r_ptr->level % p_ptr->lev) *
+ 1000L / p_ptr->lev + 5) / 10);
/* Mention the experience */
text_out(" is worth ");
- text_out_c(TERM_ORANGE, format("%ld.%02ld", (long)i, (long)j));
+ text_out_c(TERM_ORANGE, format("%ld.%02ld", i, j));
text_out(" point");
text_out(((i == 1) && (j == 0)) ? "" : "s");
@@ -551,7 +542,7 @@ static void roff_aux(int r_idx, int ego, int remem)
/* Mention the dependance on the player's level */
text_out(format(" for a%s %lu%s level character. ",
- q, (long)i, p));
+ q, i, p));
}
}
@@ -1087,9 +1078,9 @@ static void roff_aux(int r_idx, int ego, int remem)
/* Do we know how aware it is? */
- if ((((int)r_ptr->r_wake * (int)r_ptr->r_wake) > r_ptr->sleep) ||
- (r_ptr->r_ignore == MAX_UCHAR) ||
- ((r_ptr->sleep == 0) && (r_ptr->r_tkills >= 10)))
+ if (((static_cast<int>(r_ptr->r_wake) * static_cast<int>(r_ptr->r_wake)) > r_ptr->sleep) ||
+ (r_ptr->r_ignore == MAX_UCHAR) ||
+ ((r_ptr->sleep == 0) && (r_ptr->r_tkills >= 10)))
{
cptr act;
@@ -1517,7 +1508,7 @@ static void roff_aux(int r_idx, int ego, int remem)
if ((cheat_know) && (remem == 0))
{
/* Hack -- restore memory */
- COPY(r_ptr, &save_mem, monster_race);
+ *r_ptr = save_mem;
}
}
@@ -1548,24 +1539,28 @@ static void roff_name(int r_idx, int ego)
/* Dump the name */
if (ego)
{
- if (re_info[ego].before) Term_addstr( -1, TERM_WHITE, format("%s %s", re_name + re_info[ego].name, r_name + r_ptr->name));
- else Term_addstr( -1, TERM_WHITE, format("%s %s", r_name + r_ptr->name, re_name + re_info[ego].name));
+ if (re_info[ego].before)
+ {
+ Term_addstr( -1, TERM_WHITE, format("%s %s", re_info[ego].name, r_ptr->name));
+ }
+ else
+ {
+ Term_addstr( -1, TERM_WHITE, format("%s %s", r_ptr->name, re_info[ego].name));
+ }
}
else
{
- Term_addstr( -1, TERM_WHITE, r_name + r_ptr->name);
+ Term_addstr( -1, TERM_WHITE, r_ptr->name);
}
/* Append the "standard" attr/char info */
Term_addstr( -1, TERM_WHITE, " ('");
Term_addch(a1, c1);
- if (use_bigtile && (a1 & 0x80)) Term_addch(255, 255);
Term_addstr( -1, TERM_WHITE, "')");
/* Append the "optional" attr/char info */
Term_addstr( -1, TERM_WHITE, "/('");
Term_addch(a2, c2);
- if (use_bigtile && (a2 & 0x80)) Term_addch(255, 255);
Term_addstr( -1, TERM_WHITE, "'):");
}
@@ -1616,9 +1611,11 @@ void monster_description_out(int r_idx, int ego)
void display_roff(int r_idx, int ego)
{
int y;
+ int hgt;
+ Term_get_size(nullptr, &hgt);
/* Erase the window */
- for (y = 0; y < Term->hgt; y++)
+ for (y = 0; y < hgt; y++)
{
/* Erase the line */
Term_erase(0, y, 255);
@@ -1663,7 +1660,7 @@ bool_ monster_dungeon(int r_idx)
}
-bool_ monster_ocean(int r_idx)
+static bool_ monster_ocean(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1674,7 +1671,7 @@ bool_ monster_ocean(int r_idx)
}
-bool_ monster_shore(int r_idx)
+static bool_ monster_shore(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1685,7 +1682,7 @@ bool_ monster_shore(int r_idx)
}
-bool_ monster_waste(int r_idx)
+static bool_ monster_waste(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1696,7 +1693,7 @@ bool_ monster_waste(int r_idx)
}
-bool_ monster_town(int r_idx)
+static bool_ monster_town(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1707,7 +1704,7 @@ bool_ monster_town(int r_idx)
}
-bool_ monster_wood(int r_idx)
+static bool_ monster_wood(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1718,7 +1715,7 @@ bool_ monster_wood(int r_idx)
}
-bool_ monster_volcano(int r_idx)
+static bool_ monster_volcano(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1729,7 +1726,7 @@ bool_ monster_volcano(int r_idx)
}
-bool_ monster_mountain(int r_idx)
+static bool_ monster_mountain(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1740,7 +1737,7 @@ bool_ monster_mountain(int r_idx)
}
-bool_ monster_grass(int r_idx)
+static bool_ monster_grass(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1751,7 +1748,7 @@ bool_ monster_grass(int r_idx)
}
-bool_ monster_deep_water(int r_idx)
+static bool_ monster_deep_water(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1764,7 +1761,7 @@ bool_ monster_deep_water(int r_idx)
}
-bool_ monster_shallow_water(int r_idx)
+static bool_ monster_shallow_water(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -1777,7 +1774,7 @@ bool_ monster_shallow_water(int r_idx)
}
-bool_ monster_lava(int r_idx)
+static bool_ monster_lava(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
diff --git a/src/monster1.hpp b/src/monster1.hpp
new file mode 100644
index 00000000..1d71fef1
--- /dev/null
+++ b/src/monster1.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+extern void screen_roff(int r_idx, int ego, int remember);
+extern void display_roff(int r_idx, int ego);
+extern void monster_description_out(int r_idx, int ego);
diff --git a/src/monster2.c b/src/monster2.cc
index 5ed4758a..513ebf03 100644
--- a/src/monster2.c
+++ b/src/monster2.cc
@@ -1,7 +1,3 @@
-/* File: monster2.c */
-
-/* Purpose: misc code for monsters */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -9,13 +5,56 @@
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
-
-#include "angband.h"
+#include "monster2.hpp"
+
+#include "alloc_entry.hpp"
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "files.hpp"
+#include "hook_new_monster_in.hpp"
+#include "hook_new_monster_end_in.hpp"
+#include "hooks.hpp"
+#include "levels.hpp"
+#include "mimic.hpp"
+#include "monster3.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "randart.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <algorithm>
+#include <string>
#define MAX_HORROR 20
#define MAX_FUNNY 22
#define MAX_COMMENT 5
+#define MODIFY_AUX(o, n) ((o) = modify_aux((o), (n) >> 2, (n) & 3))
+#define MODIFY(o, n, min) MODIFY_AUX(o, n); (o) = ((o) < (min))?(min):(o)
+
+s32b monster_exp(s16b level)
+{
+ s32b capped_level = std::min(level, static_cast<s16b>(MONSTER_LEVEL_MAX));
+ return (capped_level * capped_level * capped_level * 6);
+}
+
/* Monster gain a few levels ? */
void monster_check_experience(int m_idx, bool_ silent)
{
@@ -28,7 +67,7 @@ void monster_check_experience(int m_idx, bool_ silent)
/* Gain levels while possible */
while ((m_ptr->level < MONSTER_LEVEL_MAX) &&
- (m_ptr->exp >= (u32b)(MONSTER_EXP(m_ptr->level + 1))))
+ (m_ptr->exp >= monster_exp(m_ptr->level + 1)))
{
/* Gain a level */
m_ptr->level++;
@@ -95,7 +134,7 @@ void monster_set_level(int m_idx, int level)
if (m_ptr->level < level)
{
- m_ptr->exp = MONSTER_EXP(level);
+ m_ptr->exp = monster_exp(level);
monster_check_experience(m_idx, TRUE);
}
}
@@ -124,10 +163,9 @@ s32b modify_aux(s32b a, s32b b, char mod)
}
/* Is this ego ok for this monster ? */
-bool_ mego_ok(int r_idx, int ego)
+bool_ mego_ok(monster_race const *r_ptr, int ego)
{
monster_ego *re_ptr = &re_info[ego];
- monster_race *r_ptr = &r_info[r_idx];
bool_ ok = FALSE;
int i;
@@ -169,7 +207,7 @@ bool_ mego_ok(int r_idx, int ego)
}
/* Choose an ego type */
-int pick_ego_monster(int r_idx)
+static int pick_ego_monster(monster_race const *r_ptr)
{
/* Assume no ego */
int ego = 0, lvl;
@@ -179,7 +217,7 @@ int pick_ego_monster(int r_idx)
if ((!(dungeon_flags2 & DF2_ELVEN)) && (!(dungeon_flags2 & DF2_DWARVEN)))
{
/* No townspeople ego */
- if (!r_info[r_idx].level) return 0;
+ if (!r_ptr->level) return 0;
/* First are we allowed to find an ego */
if (!magik(MEGO_CHANCE)) return 0;
@@ -192,10 +230,10 @@ int pick_ego_monster(int r_idx)
re_ptr = &re_info[ego];
/* No hope so far */
- if (!mego_ok(r_idx, ego)) continue;
+ if (!mego_ok(r_ptr, ego)) continue;
/* Not too much OoD */
- lvl = r_info[r_idx].level;
+ lvl = r_ptr->level;
MODIFY(lvl, re_ptr->level, 0);
lvl -= ((dun_level / 2) + (rand_int(dun_level / 2)));
if (lvl < 1) lvl = 1;
@@ -216,7 +254,7 @@ int pick_ego_monster(int r_idx)
else if (dungeon_flags2 & DF2_DWARVEN)
ego = test_mego_name("Dwarven");
- if (mego_ok(r_idx, ego))
+ if (mego_ok(r_ptr, ego))
return ego;
}
@@ -239,7 +277,7 @@ monster_race* race_info_idx(int r_idx, int ego)
if (!ego) return r_ptr;
/* Copy the base monster */
- COPY(nr_ptr, r_ptr, monster_race);
+ *nr_ptr = *r_ptr;
/* Adjust the values */
for (i = 0; i < 4; i++)
@@ -316,6 +354,11 @@ monster_race* race_info_idx(int r_idx, int ego)
return nr_ptr;
}
+monster_race* race_inf(monster_type *m_ptr)
+{
+ return race_info_idx(m_ptr->r_idx, m_ptr->ego);
+}
+
static cptr horror_desc[MAX_HORROR] =
{
"abominable",
@@ -383,18 +426,6 @@ static cptr funny_comments[MAX_COMMENT] =
};
-int get_wilderness_flag(void)
-{
- int x = p_ptr->wilderness_x;
- int y = p_ptr->wilderness_y;
-
- if (dun_level)
- return (RF8_DUNGEON);
- else
- return (1L << wf_info[wild_map[y][x].feat].terrain_idx);
-}
-
-
/*
* Delete a monster by index.
*
@@ -402,21 +433,15 @@ int get_wilderness_flag(void)
*/
void delete_monster_idx(int i)
{
- int x, y, j;
-
monster_type *m_ptr = &m_list[i];
monster_race *r_ptr = race_inf(m_ptr);
- s16b this_o_idx, next_o_idx = 0;
-
bool_ had_lite = FALSE;
- ;
-
/* Get location */
- y = m_ptr->fy;
- x = m_ptr->fx;
+ int y = m_ptr->fy;
+ int x = m_ptr->fx;
/* Hack -- Reduce the racial counter */
r_ptr->cur_num--;
@@ -438,7 +463,8 @@ void delete_monster_idx(int i)
/* Hack -- remove tracked monster */
if (i == p_ptr->control) p_ptr->control = 0;
- for (j = m_max - 1; j >= 1; j--)
+
+ for (int j = m_max - 1; j >= 1; j--)
{
/* Access the monster */
monster_type *t_ptr = &m_list[j];
@@ -452,17 +478,15 @@ void delete_monster_idx(int i)
/* Monster is gone */
cave[y][x].m_idx = 0;
+ /* Copy list of objects; need a copy since we're
+ * manipulating the list itself below. */
+ auto const object_idxs(m_ptr->hold_o_idxs);
/* Delete objects */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Hack -- efficiency */
o_ptr->held_m_idx = 0;
@@ -487,18 +511,13 @@ void delete_monster_idx(int i)
}
}
}
+
/* Delete the object */
delete_object_idx(this_o_idx);
}
- /* Delete mind & special race if needed */
- if (m_ptr->sr_ptr)
- KILL(m_ptr->sr_ptr, monster_race);
- if (m_ptr->mind)
- KILL(m_ptr->mind, monster_mind);
-
/* Wipe the Monster */
- m_ptr = WIPE(m_ptr, monster_type);
+ m_ptr->wipe();
/* Count monsters */
m_cnt--;
@@ -548,42 +567,27 @@ void delete_monster(int y, int x)
*/
static void compact_monsters_aux(int i1, int i2)
{
- int y, x, j;
-
- cave_type *c_ptr;
-
- monster_type *m_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Do nothing */
if (i1 == i2) return;
-
/* Old monster */
- m_ptr = &m_list[i1];
+ monster_type *m_ptr = &m_list[i1];
/* Location */
- y = m_ptr->fy;
- x = m_ptr->fx;
+ int y = m_ptr->fy;
+ int x = m_ptr->fx;
/* Cave grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Update the cave */
c_ptr->m_idx = i2;
/* Repair objects being carried by monster */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: m_ptr->hold_o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Reset monster pointer */
o_ptr->held_m_idx = i2;
@@ -601,7 +605,7 @@ static void compact_monsters_aux(int i1, int i2)
/* Hack -- Update the health bar */
if (health_who == i1) health_track(i2);
- for (j = m_max - 1; j >= 1; j--)
+ for (int j = m_max - 1; j >= 1; j--)
{
/* Access the monster */
monster_type *t_ptr = &m_list[j];
@@ -613,16 +617,10 @@ static void compact_monsters_aux(int i1, int i2)
}
/* Structure copy */
- COPY(&m_list[i2], &m_list[i1], monster_type);
-
- /* Delete mind & special race if needed */
- if (m_list[i1].sr_ptr)
- KILL(m_list[i1].sr_ptr, monster_race);
- if (m_list[i1].mind)
- KILL(m_list[i1].mind, monster_mind);
+ m_list[i2] = m_list[i1];
/* Wipe the hole */
- m_ptr = WIPE(&m_list[i1], monster_type);
+ m_list[i1].wipe();
}
@@ -739,15 +737,8 @@ void wipe_m_list(void)
/* Monster is gone */
cave[m_ptr->fy][m_ptr->fx].m_idx = 0;
- /* Delete mind & special race if needed */
- if (m_ptr->sr_ptr)
- KILL(m_ptr->sr_ptr, monster_race);
- if (m_ptr->mind)
- KILL(m_ptr->mind, monster_mind);
-
-
/* Wipe the Monster */
- m_ptr = WIPE(m_ptr, monster_type);
+ m_ptr->wipe();
}
/* Reset "m_max" */
@@ -1226,19 +1217,24 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
{
cptr res;
monster_race *r_ptr = race_inf(m_ptr);
- cptr b_name = (r_name + r_ptr->name);
char silly_name[80], name[100];
bool_ seen, pron;
int insanity = (p_ptr->msane - p_ptr->csane) * 100 / p_ptr->msane;
if (m_ptr->ego)
{
- if (re_info[m_ptr->ego].before) sprintf(name, "%s %s", re_name + re_info[m_ptr->ego].name, b_name);
- else sprintf(name, "%s %s", b_name, re_name + re_info[m_ptr->ego].name);
+ if (re_info[m_ptr->ego].before)
+ {
+ sprintf(name, "%s %s", re_info[m_ptr->ego].name, r_ptr->name);
+ }
+ else
+ {
+ sprintf(name, "%s %s", r_ptr->name, re_info[m_ptr->ego].name);
+ }
}
else
{
- sprintf(name, "%s", b_name);
+ sprintf(name, "%s", r_ptr->name);
}
/*
@@ -1257,7 +1253,7 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
}
while (hallu_race->flags1 & RF1_UNIQUE);
- strcpy(silly_name, (r_name + hallu_race->name));
+ strcpy(silly_name, hallu_race->name);
}
else
{
@@ -1434,17 +1430,22 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
void monster_race_desc(char *desc, int r_idx, int ego)
{
monster_race *r_ptr = &r_info[r_idx];
- cptr b_name = (r_name + r_ptr->name);
char name[80];
if (ego)
{
- if (re_info[ego].before) sprintf(name, "%s %s", re_name + re_info[ego].name, b_name);
- else sprintf(name, "%s %s", b_name, re_name + re_info[ego].name);
+ if (re_info[ego].before)
+ {
+ sprintf(name, "%s %s", re_info[ego].name, r_ptr->name);
+ }
+ else
+ {
+ sprintf(name, "%s %s", r_ptr->name, re_info[ego].name);
+ }
}
else
{
- sprintf(name, "%s", b_name);
+ sprintf(name, "%s", r_ptr->name);
}
/* It could be a Unique */
@@ -1526,7 +1527,7 @@ void lore_treasure(int m_idx, int num_item, int num_gold)
-void sanity_blast(monster_type * m_ptr, bool_ necro)
+static void sanity_blast(monster_type * m_ptr, bool_ necro)
{
bool_ happened = FALSE;
int power = 100;
@@ -1595,7 +1596,7 @@ void sanity_blast(monster_type * m_ptr, bool_ necro)
}
/* Undead characters are 50% likely to be unaffected */
- if ((PRACE_FLAG(PR1_UNDEAD)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")))
+ if ((race_flags1_p(PR1_UNDEAD)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire")))
{
if (randint(100) < (25 + (p_ptr->lev))) return;
}
@@ -1878,7 +1879,7 @@ void update_mon(int m_idx, bool_ full)
lite_spot(fy, fx);
/* Update health bar as needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Update monster list window */
p_ptr->window |= (PW_M_LIST);
@@ -1889,7 +1890,7 @@ void update_mon(int m_idx, bool_ full)
/* Disturb on appearance */
if (disturb_move)
{
- if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1, 0);
+ if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1);
}
}
@@ -1921,7 +1922,7 @@ void update_mon(int m_idx, bool_ full)
lite_spot(fy, fx);
/* Update health bar as needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Update monster list window */
p_ptr->window |= (PW_M_LIST);
@@ -1929,7 +1930,7 @@ void update_mon(int m_idx, bool_ full)
/* Disturb on disappearance*/
if (disturb_move)
{
- if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1, 0);
+ if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1);
}
}
}
@@ -1956,7 +1957,7 @@ void update_mon(int m_idx, bool_ full)
/* Disturb on appearance */
if (disturb_near)
{
- if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1, 0);
+ if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1);
}
}
@@ -1977,7 +1978,7 @@ void update_mon(int m_idx, bool_ full)
/* Disturb on disappearance */
if (disturb_near)
{
- if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1, 0);
+ if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1);
}
}
}
@@ -2023,13 +2024,11 @@ void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr)
object_copy(o_ptr, q_ptr);
/* Build a stack */
- o_ptr->next_o_idx = m_ptr->hold_o_idx;
-
o_ptr->held_m_idx = m_idx;
o_ptr->ix = 0;
o_ptr->iy = 0;
- m_ptr->hold_o_idx = o_idx;
+ m_ptr->hold_o_idxs.push_back(o_idx);
}
else
@@ -2109,9 +2108,9 @@ bool_ kind_is_randart(int k_idx)
* except for the savefile loading code.
*/
bool_ bypass_r_ptr_max_num = FALSE;
-int place_monster_result = 0;
+static int place_monster_result = 0;
bool_ place_monster_one_no_drop = FALSE;
-monster_race *place_monster_one_race = NULL;
+static s16b hack_m_idx_ii = 0;
s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
{
int i;
@@ -2125,25 +2124,15 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
monster_race *r_ptr = &r_info[r_idx];
- cptr name = (r_name + r_ptr->name);
-
- /* Grab the special race if needed */
- if (place_monster_one_race)
- {
- r_ptr = place_monster_one_race;
- }
-
/* DO NOT PLACE A MONSTER IN THE SMALL SCALE WILDERNESS !!! */
if (p_ptr->wild_mode)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Verify location */
if (!in_bounds(y, x))
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2151,7 +2140,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (!cave_empty_bold(y, x))
{
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): EMPTY BOLD", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2159,26 +2147,22 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if ((cave[y][x].info & CAVE_FREE) && (!m_allow_special[r_idx]))
{
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): CAVE_FREE", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Hack -- no creation on glyph of warding */
if (cave[y][x].feat == FEAT_GLYPH)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
if (cave[y][x].feat == FEAT_MINOR_GLYPH)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Nor on the between */
if (cave[y][x].feat == FEAT_BETWEEN)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2186,7 +2170,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if ((cave[y][x].feat >= FEAT_ALTAR_HEAD)
&& (cave[y][x].feat <= FEAT_ALTAR_TAIL))
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2194,53 +2177,43 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if ((cave[y][x].feat >= FEAT_PATTERN_START)
&& (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Paranoia */
if (!r_idx)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Paranoia */
if (!r_ptr->name)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Are we allowed to continue ? */
- if (process_hooks(HOOK_NEW_MONSTER, "(d)", r_idx))
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
- return 0;
+ struct hook_new_monster_in in = { r_idx };
+ if (process_hooks_new(HOOK_NEW_MONSTER, &in, NULL))
+ {
+ return 0;
+ }
}
/* Ego Uniques are NOT to be created */
if ((r_ptr->flags1 & RF1_UNIQUE) && ego)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
/* Now could we generate an Ego Monster */
/* Grab the special race if needed */
- if (place_monster_one_race)
- {
- r_ptr = place_monster_one_race;
- }
- else
- {
- r_ptr = race_info_idx(r_idx, ego);
- }
+ r_ptr = race_info_idx(r_idx, ego);
if (!monster_can_cross_terrain(cave[y][x].feat, r_ptr))
{
if (wizard) cmsg_print(TERM_L_RED, "WARNING: Refused monster: cannot cross terrain");
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2248,7 +2221,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if ((r_ptr->flags9 & RF9_SPECIAL_GENE) && (!m_allow_special[r_idx]))
{
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): SPECIAL_GENE", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2256,7 +2228,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if ((r_ptr->flags7 & RF7_SPIRIT) && (dungeon_type != DUNGEON_VOID))
{
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): SPIRIT in non VOID", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2264,7 +2235,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (r_ptr->flags9 & RF9_NEVER_GENE)
{
if (wizard) cmsg_print(TERM_L_RED, "WARNING: Refused monster: NEVER_GENE");
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2273,7 +2243,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
{
/* Cannot create */
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster %d: unique not unique", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2281,7 +2250,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (r_ptr->on_saved)
{
if (wizard) cmsg_print(TERM_L_RED, "WARNING: Refused monster: unique already on saved level");
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2290,7 +2258,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
{
/* Cannot create */
if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster %d: cur_num >= max_num", r_idx);
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2299,7 +2266,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
{
/* Cannot create */
if (wizard) cmsg_print(TERM_L_RED, "WARNING: FORCE_DEPTH");
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2310,7 +2276,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
if (r_ptr->flags1 & (RF1_UNIQUE))
{
/* Message for cheaters */
- if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Unique (%s).", name);
+ if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Unique (%s).", r_ptr->name);
/* Boost rating by twice delta-depth */
rating += (r_ptr->level - dun_level) * 2;
@@ -2320,7 +2286,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
else
{
/* Message for cheaters */
- if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Monster (%s).", name);
+ if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Monster (%s).", r_ptr->name);
/* Boost rating by delta-depth */
rating += (r_ptr->level - dun_level);
@@ -2331,7 +2297,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
else if (r_ptr->flags1 & (RF1_UNIQUE))
{
/* Unique monsters induce message */
- if ((cheat_hear) || (p_ptr->precognition)) msg_format("Unique (%s).", name);
+ if ((cheat_hear) || (p_ptr->precognition)) msg_format("Unique (%s).", r_ptr->name);
}
@@ -2345,7 +2311,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
/* Mega-Hack -- catch "failure" */
if (!c_ptr->m_idx)
{
- if (place_monster_one_race) KILL(place_monster_one_race, monster_race);
return 0;
}
@@ -2357,10 +2322,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
m_ptr->r_idx = r_idx;
m_ptr->ego = ego;
- /* No special, no mind */
- m_ptr->sr_ptr = place_monster_one_race;
- m_ptr->mind = NULL;
-
/* Place the monster at the location */
m_ptr->fy = y;
m_ptr->fx = x;
@@ -2383,7 +2344,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
m_ptr->ml = FALSE;
/* No objects yet */
- m_ptr->hold_o_idx = 0;
+ m_ptr->hold_o_idxs.clear();
m_ptr->status = status;
@@ -2578,7 +2539,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
m_ptr->ac = r_ptr->ac;
m_ptr->level = r_ptr->level;
m_ptr->speed = r_ptr->speed;
- m_ptr->exp = MONSTER_EXP(m_ptr->level);
+ m_ptr->exp = monster_exp(m_ptr->level);
/* Extract the monster base speed */
m_ptr->mspeed = m_ptr->speed;
@@ -2655,8 +2616,6 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
r_ptr->on_saved = TRUE;
}
- place_monster_one_race = NULL;
-
/* Processs hooks */
{
hook_new_monster_end_in in = { m_ptr };
@@ -2745,7 +2704,7 @@ static bool_ place_monster_group(int y, int x, int r_idx, bool_ slp, int status)
if (!cave_empty_bold(my, mx)) continue;
/* Attempt to place another monster */
- if (place_monster_one(my, mx, r_idx, pick_ego_monster(r_idx), slp, status))
+ if (place_monster_one(my, mx, r_idx, pick_ego_monster(r_ptr), slp, status))
{
/* Add it to the "hack" set */
hack_y[hack_n] = my;
@@ -2824,7 +2783,7 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
/* Place one monster, or fail */
- if (!place_monster_one(y, x, r_idx, pick_ego_monster(r_idx), slp, status)) return (FALSE);
+ if (!place_monster_one(y, x, r_idx, pick_ego_monster(r_ptr), slp, status)) return (FALSE);
/* Require the "group" flag */
@@ -2882,7 +2841,7 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu
if (!z) break;
/* Place a single escort */
- place_monster_one(ny, nx, z, pick_ego_monster(z), slp, status);
+ place_monster_one(ny, nx, z, pick_ego_monster(&r_info[z]), slp, status);
/* Place a "group" of escorts if needed */
if ((r_info[z].flags1 & (RF1_FRIENDS)) ||
@@ -3068,7 +3027,7 @@ static int summon_specific_type = 0;
/*
* Hack -- help decide if a monster race is "okay" to summon
*/
-bool_ summon_specific_okay(int r_idx)
+static bool_ summon_specific_okay(int r_idx)
{
monster_race *r_ptr = &r_info[r_idx];
@@ -3233,7 +3192,7 @@ bool_ summon_specific_okay(int r_idx)
case SUMMON_DAWN:
{
- okay = ((strstr((r_name + r_ptr->name), "the Dawn")) &&
+ okay = ((strstr(r_ptr->name, "the Dawn")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
@@ -3282,14 +3241,14 @@ bool_ summon_specific_okay(int r_idx)
case SUMMON_PHANTOM:
{
- okay = ((strstr((r_name + r_ptr->name), "Phantom")) &&
+ okay = ((strstr(r_ptr->name, "Phantom")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
case SUMMON_ELEMENTAL:
{
- okay = ((strstr((r_name + r_ptr->name), "lemental")) &&
+ okay = ((strstr(r_ptr->name, "lemental")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
@@ -3302,21 +3261,21 @@ bool_ summon_specific_okay(int r_idx)
case SUMMON_BLUE_HORROR:
{
- okay = ((strstr((r_name + r_ptr->name), "lue horror")) &&
+ okay = ((strstr(r_ptr->name, "lue horror")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
case SUMMON_BUG:
{
- okay = ((strstr((r_name + r_ptr->name), "Software bug")) &&
+ okay = ((strstr(r_ptr->name, "Software bug")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
case SUMMON_RNG:
{
- okay = ((strstr((r_name + r_ptr->name), "Random Number Generator")) &&
+ okay = ((strstr(r_ptr->name, "Random Number Generator")) &&
!(r_ptr->flags1 & (RF1_UNIQUE)));
break;
}
@@ -3742,25 +3701,21 @@ bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone)
* Technically should attempt to treat "Beholder"'s as jelly's
*/
bool_ hack_message_pain_may_silent = FALSE;
-void message_pain_hook(cptr fmt, ...)
+void message_pain_hook(cptr message, cptr name)
{
- va_list vp;
-
- char buf[1024];
-
- /* Begin the Varargs Stuff */
- va_start(vp, fmt);
-
- /* Format the args, save the length */
- (void)vstrnfmt(buf, 1024, fmt, vp);
-
- /* End the Varargs Stuff */
- va_end(vp);
+ std::string buf;
+ buf += name;
+ buf += " ";
+ buf += message;
if (hack_message_pain_may_silent)
- monster_msg(buf);
+ {
+ monster_msg_simple(buf.c_str());
+ }
else
- msg_print(buf);
+ {
+ msg_print(buf.c_str());
+ }
}
void message_pain(int m_idx, int dam)
@@ -3773,11 +3728,12 @@ void message_pain(int m_idx, int dam)
/* Get the monster name */
monster_desc(m_name, m_ptr, 0);
+ capitalize(m_name);
/* Notice non-damage */
if (dam == 0)
{
- message_pain_hook("%^s is unharmed.", m_name);
+ message_pain_hook("is unharmed.", m_name);
return;
}
@@ -3792,76 +3748,76 @@ void message_pain(int m_idx, int dam)
if (strchr("jmvQ", r_ptr->d_char))
{
if (percentage > 95)
- message_pain_hook("%^s barely notices.", m_name);
+ message_pain_hook("barely notices.", m_name);
else if (percentage > 75)
- message_pain_hook("%^s flinches.", m_name);
+ message_pain_hook("flinches.", m_name);
else if (percentage > 50)
- message_pain_hook("%^s squelches.", m_name);
+ message_pain_hook("squelches.", m_name);
else if (percentage > 35)
- message_pain_hook("%^s quivers in pain.", m_name);
+ message_pain_hook("quivers in pain.", m_name);
else if (percentage > 20)
- message_pain_hook("%^s writhes about.", m_name);
+ message_pain_hook("writhes about.", m_name);
else if (percentage > 10)
- message_pain_hook("%^s writhes in agony.", m_name);
+ message_pain_hook("writhes in agony.", m_name);
else
- message_pain_hook("%^s jerks limply.", m_name);
+ message_pain_hook("jerks limply.", m_name);
}
/* Dogs and Hounds */
else if (strchr("CZ", r_ptr->d_char))
{
if (percentage > 95)
- message_pain_hook("%^s shrugs off the attack.", m_name);
+ message_pain_hook("shrugs off the attack.", m_name);
else if (percentage > 75)
- message_pain_hook("%^s snarls with pain.", m_name);
+ message_pain_hook("snarls with pain.", m_name);
else if (percentage > 50)
- message_pain_hook("%^s yelps in pain.", m_name);
+ message_pain_hook("yelps in pain.", m_name);
else if (percentage > 35)
- message_pain_hook("%^s howls in pain.", m_name);
+ message_pain_hook("howls in pain.", m_name);
else if (percentage > 20)
- message_pain_hook("%^s howls in agony.", m_name);
+ message_pain_hook("howls in agony.", m_name);
else if (percentage > 10)
- message_pain_hook("%^s writhes in agony.", m_name);
+ message_pain_hook("writhes in agony.", m_name);
else
- message_pain_hook("%^s yelps feebly.", m_name);
+ message_pain_hook("yelps feebly.", m_name);
}
/* One type of monsters (ignore,squeal,shriek) */
else if (strchr("FIKMRSXabclqrst", r_ptr->d_char))
{
if (percentage > 95)
- message_pain_hook("%^s ignores the attack.", m_name);
+ message_pain_hook("ignores the attack.", m_name);
else if (percentage > 75)
- message_pain_hook("%^s grunts with pain.", m_name);
+ message_pain_hook("grunts with pain.", m_name);
else if (percentage > 50)
- message_pain_hook("%^s squeals in pain.", m_name);
+ message_pain_hook("squeals in pain.", m_name);
else if (percentage > 35)
- message_pain_hook("%^s shrieks in pain.", m_name);
+ message_pain_hook("shrieks in pain.", m_name);
else if (percentage > 20)
- message_pain_hook("%^s shrieks in agony.", m_name);
+ message_pain_hook("shrieks in agony.", m_name);
else if (percentage > 10)
- message_pain_hook("%^s writhes in agony.", m_name);
+ message_pain_hook("writhes in agony.", m_name);
else
- message_pain_hook("%^s cries out feebly.", m_name);
+ message_pain_hook("cries out feebly.", m_name);
}
/* Another type of monsters (shrug,cry,scream) */
else
{
if (percentage > 95)
- message_pain_hook("%^s shrugs off the attack.", m_name);
+ message_pain_hook("shrugs off the attack.", m_name);
else if (percentage > 75)
- message_pain_hook("%^s grunts with pain.", m_name);
+ message_pain_hook("grunts with pain.", m_name);
else if (percentage > 50)
- message_pain_hook("%^s cries out in pain.", m_name);
+ message_pain_hook("cries out in pain.", m_name);
else if (percentage > 35)
- message_pain_hook("%^s screams in pain.", m_name);
+ message_pain_hook("screams in pain.", m_name);
else if (percentage > 20)
- message_pain_hook("%^s screams in agony.", m_name);
+ message_pain_hook("screams in agony.", m_name);
else if (percentage > 10)
- message_pain_hook("%^s writhes in agony.", m_name);
+ message_pain_hook("writhes in agony.", m_name);
else
- message_pain_hook("%^s cries out feebly.", m_name);
+ message_pain_hook("cries out feebly.", m_name);
}
}
@@ -3884,7 +3840,7 @@ void update_smart_learn(int m_idx, int what)
if (r_ptr->flags2 & (RF2_STUPID)) return;
/* Not intelligent, only learn sometimes */
- if (!(r_ptr->flags2 & (RF2_SMART)) && (rand_int(100) < 50)) return;
+ if (!(r_ptr->flags2 & (RF2_SMART)) && magik(50)) return;
/* XXX XXX XXX */
@@ -4003,26 +3959,22 @@ s16b player_place(int y, int x)
*/
void monster_drop_carried_objects(monster_type *m_ptr)
{
- s16b this_o_idx, next_o_idx = 0;
- object_type forge;
- object_type *o_ptr;
- object_type *q_ptr;
-
+ /* Copy list of objects; we need a copy since
+ we're manipulating the list itself below. */
+ auto const object_idxs(m_ptr->hold_o_idxs);
/* Drop objects being carried */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Paranoia */
o_ptr->held_m_idx = 0;
/* Get local object */
- q_ptr = &forge;
+ object_type forge;
+ object_type *q_ptr = &forge;
/* Copy the object */
object_copy(q_ptr, o_ptr);
@@ -4035,5 +3987,5 @@ void monster_drop_carried_objects(monster_type *m_ptr)
}
/* Forget objects */
- m_ptr->hold_o_idx = 0;
+ m_ptr->hold_o_idxs.clear();
}
diff --git a/src/monster2.hpp b/src/monster2.hpp
new file mode 100644
index 00000000..ffe7b3cd
--- /dev/null
+++ b/src/monster2.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_race_fwd.hpp"
+#include "monster_type_fwd.hpp"
+#include "object_type_fwd.hpp"
+
+extern s32b monster_exp(s16b level);
+extern void monster_set_level(int m_idx, int level);
+extern s32b modify_aux(s32b a, s32b b, char mod);
+extern void monster_msg_simple(cptr s);
+extern bool_ mego_ok(monster_race const *r_ptr, int ego);
+extern void monster_check_experience(int m_idx, bool_ silent);
+extern void monster_gain_exp(int m_idx, u32b exp, bool_ silent);
+extern monster_race* race_info_idx(int r_idx, int ego);
+extern monster_race* race_inf(monster_type *m_ptr);
+extern void delete_monster_idx(int i);
+extern void delete_monster(int y, int x);
+extern void compact_monsters(int size);
+extern void wipe_m_list(void);
+extern s16b m_pop(void);
+extern errr get_mon_num_prep(void);
+extern s16b get_mon_num(int level);
+extern void monster_desc(char *desc, monster_type *m_ptr, int mode);
+extern void monster_race_desc(char *desc, int r_idx, int ego);
+extern void lore_do_probe(int m_idx);
+extern void lore_treasure(int m_idx, int num_item, int num_gold);
+extern void update_mon(int m_idx, bool_ full);
+extern void update_monsters(bool_ full);
+extern void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr);
+extern bool_ bypass_r_ptr_max_num ;
+extern bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status);
+extern bool_ place_monster(int y, int x, bool_ slp, bool_ grp);
+extern bool_ alloc_horde(int y, int x);
+extern bool_ alloc_monster(int dis, bool_ slp);
+extern int summon_specific_level;
+extern bool_ summon_specific(int y1, int x1, int lev, int type);
+extern void monster_swap(int y1, int x1, int y2, int x2);
+extern bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone);
+extern bool_ hack_message_pain_may_silent;
+extern void message_pain(int m_idx, int dam);
+extern void update_smart_learn(int m_idx, int what);
+extern bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok);
+extern bool_ place_monster_one_no_drop;
+extern s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status);
+extern s16b player_place(int y, int x);
+extern void monster_drop_carried_objects(monster_type *m_ptr);
+extern bool_ monster_dungeon(int r_idx);
+extern bool_ monster_quest(int r_idx);
+extern void set_mon_num_hook(void);
+extern void set_mon_num2_hook(int y, int x);
+extern bool_ monster_can_cross_terrain(byte feat, monster_race *r_ptr);
diff --git a/src/monster3.c b/src/monster3.cc
index a2b5fb38..e7e8e6da 100644
--- a/src/monster3.c
+++ b/src/monster3.cc
@@ -1,7 +1,3 @@
-/* File: monster3.c */
-
-/* Purpose: Monsters AI */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,7 +6,24 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "monster3.hpp"
+
+#include "cave_type.hpp"
+#include "cmd2.hpp"
+#include "gods.hpp"
+#include "melee2.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra2.hpp"
/*
* Is the mon,ster in friendly state(pet, friend, ..)
@@ -189,7 +202,7 @@ bool_ ai_possessor(int m_idx, int o_idx)
m_ptr->ac = r_ptr->ac;
m_ptr->level = r_ptr->level;
m_ptr->speed = r_ptr->speed;
- m_ptr->exp = MONSTER_EXP(m_ptr->level);
+ m_ptr->exp = monster_exp(m_ptr->level);
/* Extract the monster base speed */
m_ptr->mspeed = m_ptr->speed;
@@ -264,7 +277,7 @@ void ai_deincarnate(int m_idx)
m_ptr->ac = r_ptr->ac;
m_ptr->level = r_ptr->level;
m_ptr->speed = r_ptr->speed;
- m_ptr->exp = MONSTER_EXP(m_ptr->level);
+ m_ptr->exp = monster_exp(m_ptr->level);
/* Extract the monster base speed */
m_ptr->mspeed = m_ptr->speed;
@@ -332,12 +345,10 @@ bool_ do_control_walk(void)
bool_ do_control_inven(void)
{
- int monst_list[23];
-
if (!p_ptr->control) return FALSE;
screen_save();
prt("Carried items", 0, 0);
- show_monster_inven(p_ptr->control, monst_list);
+ (void) show_monster_inven(p_ptr->control);
inkey();
screen_load();
return TRUE;
@@ -345,24 +356,23 @@ bool_ do_control_inven(void)
bool_ do_control_pickup(void)
{
- int this_o_idx, next_o_idx = 0;
+ if (!p_ptr->control) return FALSE;
+
monster_type *m_ptr = &m_list[p_ptr->control];
- cave_type *c_ptr;
- bool_ done = FALSE;
- if (!p_ptr->control) return FALSE;
+ cave_type *c_ptr = &cave[m_ptr->fy][m_ptr->fx];
+
+ /* Copy list of all objects in the grid; we need a
+ * copy since we're going to be excising objects
+ * from lists. */
+ auto const object_idxs(c_ptr->o_idxs);
/* Scan all objects in the grid */
- c_ptr = &cave[m_ptr->fy][m_ptr->fx];
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ bool done = false;
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Skip gold */
if (o_ptr->tval == TV_GOLD) continue;
@@ -379,14 +389,19 @@ bool_ do_control_pickup(void)
/* Memorize monster */
o_ptr->held_m_idx = p_ptr->control;
- /* Build a stack */
- o_ptr->next_o_idx = m_ptr->hold_o_idx;
-
/* Carry object */
- m_ptr->hold_o_idx = this_o_idx;
- done = TRUE;
+ m_ptr->hold_o_idxs.push_back(this_o_idx);
+
+ /* Picked up at least one object */
+ done = true;
}
- if (done) msg_print("You pick up all objects on the floor.");
+
+ /* Feedback */
+ if (done)
+ {
+ msg_print("You pick up all objects on the floor.");
+ }
+
return TRUE;
}
diff --git a/src/monster3.hpp b/src/monster3.hpp
new file mode 100644
index 00000000..7cf8ccd0
--- /dev/null
+++ b/src/monster3.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_type_fwd.hpp"
+
+extern void dump_companions(FILE *outfile);
+extern void do_cmd_companion(void);
+extern bool_ do_control_reconnect(void);
+extern bool_ do_control_drop(void);
+extern bool_ do_control_magic(void);
+extern bool_ do_control_pickup(void);
+extern bool_ do_control_inven(void);
+extern bool_ do_control_walk(void);
+extern bool_ can_create_companion(void);
+extern void ai_deincarnate(int m_idx);
+extern bool_ ai_possessor(int m_idx, int o_idx);
+extern bool_ ai_multiply(int m_idx);
+extern bool_ change_side(monster_type *m_ptr);
+extern int is_friend(monster_type *m_ptr);
+extern bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr);
diff --git a/src/monster_blow.hpp b/src/monster_blow.hpp
new file mode 100644
index 00000000..0f19f64c
--- /dev/null
+++ b/src/monster_blow.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Monster blow descriptor.
+ *
+ * - Method (RBM_*)
+ * - Effect (RBE_*)
+ * - Damage Dice
+ * - Damage Sides
+ */
+struct monster_blow
+{
+ byte method;
+ byte effect;
+ byte d_dice;
+ byte d_side;
+};
diff --git a/src/monster_ego.hpp b/src/monster_ego.hpp
new file mode 100644
index 00000000..00464c2e
--- /dev/null
+++ b/src/monster_ego.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_blow.hpp"
+
+/**
+ * Monster ego descriptors.
+ */
+struct monster_ego
+{
+ const char *name; /* Name */
+ bool_ before; /* Display ego before or after */
+
+ monster_blow blow[4]; /* Up to four blows per round */
+ byte blowm[4][2];
+
+ s16b hdice; /* Creatures hit dice count */
+ s16b hside; /* Creatures hit dice sides */
+
+ s16b ac; /* Armour Class */
+
+ s16b sleep; /* Inactive counter (base) */
+ s16b aaf; /* Area affect radius (1-100) */
+ s16b speed; /* Speed (normally 110) */
+
+ s32b mexp; /* Exp value for kill */
+
+ s32b weight; /* Weight of the monster */
+
+ byte freq_inate; /* Inate spell frequency */
+ byte freq_spell; /* Other spell frequency */
+
+ /* Ego flags */
+ u32b flags1; /* Flags 1 */
+ u32b flags2; /* Flags 1 */
+ u32b flags3; /* Flags 1 */
+ u32b flags7; /* Flags 1 */
+ u32b flags8; /* Flags 1 */
+ u32b flags9; /* Flags 1 */
+ u32b hflags1; /* Flags 1 */
+ u32b hflags2; /* Flags 1 */
+ u32b hflags3; /* Flags 1 */
+ u32b hflags7; /* Flags 1 */
+ u32b hflags8; /* Flags 1 */
+ u32b hflags9; /* Flags 1 */
+
+ /* Monster flags */
+ u32b mflags1; /* Flags 1 (general) */
+ u32b mflags2; /* Flags 2 (abilities) */
+ u32b mflags3; /* Flags 3 (race/resist) */
+ u32b mflags4; /* Flags 4 (inate/breath) */
+ u32b mflags5; /* Flags 5 (normal spells) */
+ u32b mflags6; /* Flags 6 (special spells) */
+ u32b mflags7; /* Flags 7 (movement related abilities) */
+ u32b mflags8; /* Flags 8 (wilderness info) */
+ u32b mflags9; /* Flags 9 (drops info) */
+
+ /* Negative Flags, to be removed from the monster flags */
+ u32b nflags1; /* Flags 1 (general) */
+ u32b nflags2; /* Flags 2 (abilities) */
+ u32b nflags3; /* Flags 3 (race/resist) */
+ u32b nflags4; /* Flags 4 (inate/breath) */
+ u32b nflags5; /* Flags 5 (normal spells) */
+ u32b nflags6; /* Flags 6 (special spells) */
+ u32b nflags7; /* Flags 7 (movement related abilities) */
+ u32b nflags8; /* Flags 8 (wilderness info) */
+ u32b nflags9; /* Flags 9 (drops info) */
+
+ s16b level; /* Level of creature */
+ s16b rarity; /* Rarity of creature */
+
+
+ byte d_attr; /* Default monster attribute */
+ char d_char; /* Default monster character */
+
+ byte g_attr; /* Overlay graphic attribute */
+ char g_char; /* Overlay graphic character */
+
+ char r_char[5]; /* Monster race allowed */
+ char nr_char[5]; /* Monster race not allowed */
+};
diff --git a/src/monster_ego_fwd.hpp b/src/monster_ego_fwd.hpp
new file mode 100644
index 00000000..5b47f3e9
--- /dev/null
+++ b/src/monster_ego_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct monster_ego;
diff --git a/src/monster_power.hpp b/src/monster_power.hpp
new file mode 100644
index 00000000..03d0f8a9
--- /dev/null
+++ b/src/monster_power.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Monster powers that players can use via e.g. Symbiosis.
+ */
+struct monster_power
+{
+ u32b power; /* Power RF?_xxx */
+ cptr name; /* Name of it */
+ int mana; /* Mana needed */
+ bool_ great; /* Need the use of great spells */
+};
diff --git a/src/monster_race.hpp b/src/monster_race.hpp
new file mode 100644
index 00000000..7e5d5082
--- /dev/null
+++ b/src/monster_race.hpp
@@ -0,0 +1,116 @@
+#pragma once
+
+#include "body.hpp"
+#include "h-basic.h"
+#include "monster_blow.hpp"
+#include "obj_theme.hpp"
+
+/**
+ * Monster race descriptors and runtime data, including racial memories.
+ *
+ * Note that "d_attr" and "d_char" are used for MORE than "visual" stuff.
+ *
+ * Note that "x_attr" and "x_char" are used ONLY for "visual" stuff.
+ *
+ * Note that "cur_num" (and "max_num") represent the number of monsters
+ * of the given race currently on (and allowed on) the current level.
+ * This information yields the "dead" flag for Unique monsters.
+ *
+ * Note that "max_num" is reset when a new player is created.
+ * Note that "cur_num" is reset when a new level is created.
+ *
+ * Note that several of these fields, related to "recall", can be
+ * scrapped if space becomes an issue, resulting in less "complete"
+ * monster recall (no knowledge of spells, etc). All of the "recall"
+ * fields have a special prefix to aid in searching for them.
+ */
+struct monster_race
+{
+ const char *name; /* Name */
+ char *text; /* Text */
+
+ u16b hdice; /* Creatures hit dice count */
+ u16b hside; /* Creatures hit dice sides */
+
+ s16b ac; /* Armour Class */
+
+ s16b sleep; /* Inactive counter (base) */
+ byte aaf; /* Area affect radius (1-100) */
+ byte speed; /* Speed (normally 110) */
+
+ s32b mexp; /* Exp value for kill */
+
+ s32b weight; /* Weight of the monster */
+
+ byte freq_inate; /* Inate spell frequency */
+ byte freq_spell; /* Other spell frequency */
+
+ u32b flags1; /* Flags 1 (general) */
+ u32b flags2; /* Flags 2 (abilities) */
+ u32b flags3; /* Flags 3 (race/resist) */
+ u32b flags4; /* Flags 4 (inate/breath) */
+ u32b flags5; /* Flags 5 (normal spells) */
+ u32b flags6; /* Flags 6 (special spells) */
+ u32b flags7; /* Flags 7 (movement related abilities) */
+ u32b flags8; /* Flags 8 (wilderness info) */
+ u32b flags9; /* Flags 9 (drops info) */
+
+ monster_blow blow[4]; /* Up to four blows per round */
+
+ byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
+
+ byte level; /* Level of creature */
+ byte rarity; /* Rarity of creature */
+
+
+ byte d_attr; /* Default monster attribute */
+ char d_char; /* Default monster character */
+
+
+ byte x_attr; /* Desired monster attribute */
+ char x_char; /* Desired monster character */
+
+
+ s16b max_num; /* Maximum population allowed per level */
+
+ byte cur_num; /* Monster population on current level */
+
+
+ s16b r_sights; /* Count sightings of this monster */
+ s16b r_deaths; /* Count deaths from this monster */
+
+ s16b r_pkills; /* Count monsters killed in this life */
+ s16b r_tkills; /* Count monsters killed in all lives */
+
+ byte r_wake; /* Number of times woken up (?) */
+ byte r_ignore; /* Number of times ignored (?) */
+
+ byte r_xtra1; /* Something (unused) */
+ byte r_xtra2; /* Something (unused) */
+
+ byte r_drop_gold; /* Max number of gold dropped at once */
+ byte r_drop_item; /* Max number of item dropped at once */
+
+ byte r_cast_inate; /* Max number of inate spells seen */
+ byte r_cast_spell; /* Max number of other spells seen */
+
+ byte r_blows[4]; /* Number of times each blow type was seen */
+
+ u32b r_flags1; /* Observed racial flags */
+ u32b r_flags2; /* Observed racial flags */
+ u32b r_flags3; /* Observed racial flags */
+ u32b r_flags4; /* Observed racial flags */
+ u32b r_flags5; /* Observed racial flags */
+ u32b r_flags6; /* Observed racial flags */
+ u32b r_flags7; /* Observed racial flags */
+ u32b r_flags8; /* Observed racial flags */
+ u32b r_flags9; /* Observed racial flags */
+
+ bool_ on_saved; /* Is the (unique) on a saved level ? */
+
+ byte total_visible; /* Amount of this race that are visible */
+
+ obj_theme drops; /* The drops type */
+};
+
+
diff --git a/src/monster_race_fwd.hpp b/src/monster_race_fwd.hpp
new file mode 100644
index 00000000..9ee9658a
--- /dev/null
+++ b/src/monster_race_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct monster_race;
diff --git a/src/monster_type.hpp b/src/monster_type.hpp
new file mode 100644
index 00000000..912c97d0
--- /dev/null
+++ b/src/monster_type.hpp
@@ -0,0 +1,90 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_blow.hpp"
+
+#include <cassert>
+#include <vector>
+
+/**
+ * Monster information for a specific monster.
+ *
+ * Note: fy, fx constrain dungeon size to 256x256
+ *
+ * The "hold_o_idx" field points to the first object of a stack
+ * of objects (if any) being carried by the monster (see above).
+ */
+struct monster_type
+{
+ s16b r_idx = 0; /* Monster race index */
+
+ u16b ego = 0; /* Ego monster type */
+
+ byte fy = 0; /* Y location on map */
+ byte fx = 0; /* X location on map */
+
+ s32b hp = 0; /* Current Hit points */
+ s32b maxhp = 0; /* Max Hit points */
+
+ monster_blow blow[4] = { /* Up to four blows per round */
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ };
+
+ byte speed = 0; /* Speed (normally 110) */
+ byte level = 0; /* Level of creature */
+ s16b ac = 0; /* Armour Class */
+ s32b exp = 0; /* Experience */
+
+ s16b csleep = 0; /* Inactive counter */
+
+ byte mspeed = 0; /* Monster "speed" */
+ byte energy = 0; /* Monster "energy" */
+
+ byte stunned = 0; /* Monster is stunned */
+ byte confused = 0; /* Monster is confused */
+ byte monfear = 0; /* Monster is afraid */
+
+ s16b bleeding = 0; /* Monster is bleeding */
+ s16b poisoned = 0; /* Monster is poisoned */
+
+ byte cdis = 0; /* Current dis from player */
+
+ s32b mflag = 0; /* Extra monster flags */
+
+ bool_ ml = FALSE; /* Monster is "visible" */
+
+ std::vector<s16b> hold_o_idxs { }; /* Objects being held */
+
+ u32b smart = 0; /* Field for "smart_learn" */
+
+ s16b status = 0; /* Status(friendly, pet, companion, ..) */
+
+ s16b target = 0; /* Monster target */
+
+ s16b possessor = 0; /* Is it under the control of a possessor ? */
+
+ /**
+ * @brief wipe the object's state
+ */
+ void wipe()
+ {
+ /* Reset to defaults */
+ *this = monster_type();
+ }
+
+ /**
+ * Get the o_idx of the object being mimicked
+ */
+ s16b mimic_o_idx() const
+ {
+ // We *should* also assert that the monster has flag RF9_MIMIC,
+ // but it's currently not safe since the functions we need for
+ // that are a) expensive, and b) side-effecting via statics.
+ assert(hold_o_idxs.size() == 1); // Mimics are defined by exactly one object
+ return hold_o_idxs.front();
+ }
+
+};
diff --git a/src/monster_type_fwd.hpp b/src/monster_type_fwd.hpp
new file mode 100644
index 00000000..a44baa9d
--- /dev/null
+++ b/src/monster_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct monster_type;
diff --git a/src/move_info_type.hpp b/src/move_info_type.hpp
new file mode 100644
index 00000000..5f8aa3d8
--- /dev/null
+++ b/src/move_info_type.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Movement typse
+ */
+struct move_info_type
+{
+ s16b to_speed;
+ s16b to_search;
+ s16b to_stealth;
+ s16b to_percep;
+ cptr name;
+};
diff --git a/src/music.hpp b/src/music.hpp
new file mode 100644
index 00000000..5f37c570
--- /dev/null
+++ b/src/music.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Music descriptor.
+ */
+struct music
+{
+ char desc[80]; /* Desc of the music */
+ s16b music; /* Music. */
+ s16b dur; /* Duration(if any) */
+ s16b init_recharge; /* Minimal recharge time */
+ s16b turn_recharge; /* Recharge time for each more turn */
+ byte min_inst; /* Minimum instrument for the music */
+ byte rarity; /* Rarity of the music(use 100 to unallow to be randomly generated) */
+};
diff --git a/src/notes.c b/src/notes.cc
index 3504f61c..26960073 100644
--- a/src/notes.c
+++ b/src/notes.cc
@@ -1,7 +1,3 @@
-/* File: notes.c */
-
-/* Purpose: Note taking to a file */
-
/*
* Copyright (c) 1989, 1999 James E. Wilson, Robert A. Koeneke,
* Robert Ruehlmann
@@ -11,7 +7,15 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "notes.hpp"
+
+#include "files.hpp"
+#include "player_class.hpp"
+#include "player_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
/*
* Show the notes file on the screen
@@ -89,7 +93,7 @@ void add_note(char *note, char code)
char depths[32];
/* Get the first 60 chars - so do not have an overflow */
- C_WIPE(buf, 100, char);
+ memset(buf, 0, sizeof(buf));
strncpy(buf, note, 60);
/* Get date and time */
@@ -99,7 +103,6 @@ void add_note(char *note, char code)
/* Get depth */
if (!dun_level) strcpy(depths, " Town");
- else if (depth_in_feet) sprintf(depths, "%4dft", dun_level * 50);
else sprintf(depths, "Lev%3d", dun_level);
/* Make note */
@@ -135,7 +138,10 @@ void add_note_type(int note_number)
char player[100];
/* Build the string containing the player information */
- sprintf(player, "the %s %s", get_player_race_name(p_ptr->prace, p_ptr->pracem), class_info[p_ptr->pclass].spec[p_ptr->pspec].title + c_name);
+ sprintf(player,
+ "the %s %s",
+ get_player_race_name(p_ptr->prace, p_ptr->pracem),
+ class_info[p_ptr->pclass].spec[p_ptr->pspec].title);
/* Add in "character start" information */
sprintf(buf,
diff --git a/src/notes.hpp b/src/notes.hpp
new file mode 100644
index 00000000..e8c22bb7
--- /dev/null
+++ b/src/notes.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+extern void show_notes_file(void);
+extern void output_note(char *final_note);
+extern void add_note(char *note, char code);
+extern void add_note_type(int note_number);
diff --git a/src/obj_theme.hpp b/src/obj_theme.hpp
new file mode 100644
index 00000000..13f185e8
--- /dev/null
+++ b/src/obj_theme.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Object theme. Probability in percent for each class of
+ * objects to be dropped.
+ */
+struct obj_theme
+{
+ byte treasure;
+ byte combat;
+ byte magic;
+ byte tools;
+};
diff --git a/src/obj_theme_fwd.hpp b/src/obj_theme_fwd.hpp
new file mode 100644
index 00000000..6c0d19a3
--- /dev/null
+++ b/src/obj_theme_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct obj_theme;
diff --git a/src/object1.c b/src/object1.cc
index dd27c27e..95cd0522 100644
--- a/src/object1.c
+++ b/src/object1.cc
@@ -1,7 +1,3 @@
-/* File: object1.c */
-
-/* Purpose: Object code, part 1 */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,10 +6,55 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "quark.h"
-#include "spell_type.h"
+#include "object1.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd2.hpp"
+#include "cmd6.hpp"
+#include "dungeon.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "hook_get_in.hpp"
+#include "hooks.hpp"
+#include "lua_bind.hpp"
+#include "mimic.hpp"
+#include "monster1.hpp"
+#include "monster2.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "set_type.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells5.hpp"
+#include "squeltch.hpp"
+#include "stats.hpp"
+#include "store_info_type.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_type_info.hpp"
+#include "xtra1.hpp"
+
+#include <cassert>
+
+static bool_ apply_flags_set(s16b a_idx, s16b set_idx,
+ u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
/*
* Hack -- note that "TERM_MULTI" is now just "TERM_VIOLET".
@@ -26,6 +67,12 @@
#define TERM_MULTI TERM_VIOLET
+/**
+ * Show all equipment/inventory slots, even when empty?
+ */
+static bool item_tester_full;
+
+
/*
* Max sizes of the following arrays
*/
@@ -278,7 +325,7 @@ static byte scroll_col[MAX_TITLES];
* Certain items have a flavor
* This function is used only by "flavor_init()"
*/
-static bool_ object_flavor(int k_idx)
+static byte object_flavor(int k_idx)
{
object_kind *k_ptr = &k_info[k_idx];
@@ -337,39 +384,6 @@ static bool_ object_flavor(int k_idx)
}
-void get_table_name(char *out_string)
-{
- int testcounter = (randint(3)) + 1;
-
- strcpy(out_string, "'");
-
- if (randint(3) == 2)
- {
- while (testcounter--)
- strcat(out_string, syllables[(randint(MAX_SYLLABLES)) - 1]);
- }
-
- else
- {
- char Syllable[80];
- testcounter = (randint(2)) + 1;
- while (testcounter--)
- {
- get_rnd_line("elvish.txt", Syllable);
- strcat(out_string, Syllable);
- }
- }
-
- out_string[1] = toupper(out_string[1]);
-
- strcat(out_string, "'");
-
- out_string[18] = '\0';
-
- return;
-}
-
-
/*
* Certain items, if aware, are known instantly
* This function is used only by "flavor_init()"
@@ -680,7 +694,7 @@ void flavor_init(void)
* 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
+ * relevant "font.pref". XXX XXX XXX
*
* The "prefs" parameter is no longer meaningful. XXX XXX XXX
*/
@@ -759,72 +773,15 @@ void reset_visuals(void)
}
- if (use_graphics)
- {
- /* Process "graf.prf" */
- process_pref_file("graf.prf");
-
- /*
- * Hack -- remember graphics mode as an integer value,
- * for faster processing of map_info()
- */
-
- /* IBM-PC pseudo-graphics -- not maintained, but the code is there */
- if (streq(ANGBAND_SYS, "ibm"))
- {
- graphics_mode = GRAPHICS_IBM;
- }
-
- /*
- * Isometric view. Also assumes all the attributes of the "new"
- * graphics.
- */
- else if (streq(ANGBAND_GRAF, "iso"))
- {
- graphics_mode = GRAPHICS_ISO;
- }
-
- /*
- * "New" graphics -- supports graphics overlay for traps, ego monsters
- * and player subraces, and has tiles for lighting effects (row + 1
- * and row + 2 for "darker" versions of terrain features)
- */
- else if (streq(ANGBAND_GRAF, "new"))
- {
- graphics_mode = GRAPHICS_NEW;
- }
-
- /*
- * "Old" graphics -- doesn't support graphics overlay and lighting
- * effects
- */
- else if (streq(ANGBAND_GRAF, "old"))
- {
- graphics_mode = GRAPHICS_OLD;
- }
-
- /* ??? */
- else
- {
- graphics_mode = GRAPHICS_UNKNOWN;
- }
- }
-
/* Normal symbols */
- else
- {
- /* Process "font.prf" */
- process_pref_file("font.prf");
-
- graphics_mode = GRAPHICS_NONE;
- }
+ process_pref_file("font.prf");
}
/*
* Extract "xtra" flags from object.
*/
-void object_flags_xtra(object_type *o_ptr, u32b *f2, u32b *f3, u32b *esp)
+static void object_flags_xtra(object_type const *o_ptr, u32b *f2, u32b *f3, u32b *esp)
{
switch (o_ptr->xtra1)
{
@@ -941,7 +898,7 @@ void object_flags_xtra(object_type *o_ptr, u32b *f2, u32b *f3, u32b *esp)
* Obtain the "flags" for an item
*/
bool_ object_flags_no_set = FALSE;
-void object_flags(object_type *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
+void object_flags(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -1027,7 +984,7 @@ int object_power(object_type *o_ptr)
/*
* Obtain the "flags" for an item which are known to the player
*/
-void object_flags_known(object_type *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
+void object_flags_known(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -1322,7 +1279,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
indexx = o_ptr->sval;
/* Extract default "base" string */
- basenm = (k_name + k_ptr->name);
+ basenm = k_ptr->name;
/* Assume no "modifier" string */
modstr = "";
@@ -1397,12 +1354,15 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
modstr = amulet_adj[indexx];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Amulet~";
else
basenm = aware ? "& # Amulet~" : "& # Amulet~";
- if (known && !o_ptr->art_name && artifact_p(o_ptr)) basenm = k_ptr->name + k_name;
+ if (known && !o_ptr->art_name && artifact_p(o_ptr))
+ {
+ basenm = k_ptr->name;
+ }
break;
}
@@ -1414,7 +1374,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
modstr = ring_adj[indexx];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Ring~";
else
basenm = aware ? "& # Ring~" : "& # Ring~";
@@ -1422,7 +1382,10 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Hack -- The One Ring */
if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold";
- if (known && !o_ptr->art_name && artifact_p(o_ptr)) basenm = k_ptr->name + k_name;
+ if (known && !o_ptr->art_name && artifact_p(o_ptr))
+ {
+ basenm = k_ptr->name;
+ }
break;
}
@@ -1432,7 +1395,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Color the object */
modstr = staff_adj[o_ptr->pval2 % MAX_WOODS];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Staff~";
else
basenm = "& # Staff~";
@@ -1444,7 +1407,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Color the object */
modstr = wand_adj[o_ptr->pval2 % MAX_METALS];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Wand~";
else
basenm = "& # Wand~";
@@ -1456,7 +1419,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Color the object */
modstr = rod_adj[indexx];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Rod Tip~";
else
basenm = aware ? "& # Rod Tip~" : "& # Rod Tip~";
@@ -1470,9 +1433,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
case TV_ROD_MAIN:
{
- object_kind *tip_ptr = &k_info[lookup_kind(TV_ROD, o_ptr->pval)];
-
- modstr = k_name + tip_ptr->name;
+ modstr = k_info[lookup_kind(TV_ROD, o_ptr->pval)].name;
break;
}
@@ -1481,7 +1442,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Color the object */
modstr = scroll_adj[indexx];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Scroll~";
else
basenm = aware ? "& Scroll~ titled \"#\"" : "& Scroll~ titled \"#\"";
@@ -1501,7 +1462,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
{
modstr = get_mimic_name(o_ptr->pval2);
}
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Potion~";
else
basenm = aware ? "& # Potion~" : "& # Potion~";
@@ -1516,7 +1477,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Color the object */
modstr = food_adj[indexx];
if (aware) append_name = TRUE;
- if (((plain_descriptions) && (aware)) || o_ptr->ident & IDENT_STOREB)
+ if (aware || o_ptr->ident & IDENT_STOREB)
basenm = "& Mushroom~";
else
basenm = aware ? "& # Mushroom~" : "& # Mushroom~";
@@ -1585,9 +1546,9 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
monster_race* r_ptr = &r_info[o_ptr->pval2];
modstr = basenm;
if (r_ptr->flags1 & RF1_UNIQUE)
- basenm = format("& %s's #~", r_name + r_ptr->name);
+ basenm = format("& %s's #~", r_ptr->name);
else
- basenm = format("& %s #~", r_name + r_ptr->name);
+ basenm = format("& %s #~", r_ptr->name);
break;
}
@@ -1596,7 +1557,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
monster_race* r_ptr = &r_info[o_ptr->pval2];
modstr = basenm;
- basenm = format("& %s #~", r_name + r_ptr->name);
+ basenm = format("& %s #~", r_ptr->name);
break;
}
@@ -1605,7 +1566,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* We print hit points further down. --dsb */
monster_race* r_ptr = &r_info[o_ptr->pval];
modstr = basenm;
- basenm = format("& %s~", r_name + r_ptr->name);
+ basenm = format("& %s~", r_ptr->name);
break;
}
@@ -1614,7 +1575,6 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
char name[80];
monster_type monster;
- monster.sr_ptr = 0;
monster.r_idx = o_ptr->pval;
monster.ego = o_ptr->pval2;
monster.ml = TRUE;
@@ -1662,7 +1622,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
case TV_DAEMON_BOOK:
case TV_BOOK:
{
- basenm = k_name + k_ptr->name;
+ basenm = k_ptr->name;
if (o_ptr->sval == 255)
{
modstr = spell_type_name(spell_at(o_ptr->pval));
@@ -1673,23 +1633,16 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Used in the "inventory" routine */
default:
{
- if (process_hooks_ret(HOOK_ITEM_NAME, "ss", "(O,s,s)",
- o_ptr, basenm, modstr))
- {
- basenm = process_hooks_return[0].str;
- modstr = process_hooks_return[1].str;
- break;
- }
- else
- {
- strcpy(buf, "(nothing)");
- return;
- }
+ strcpy(buf, "(nothing)");
+ return;
}
}
/* Mega Hack */
- if ((!hack_name) && known && (k_ptr->flags5 & TR5_FULL_NAME)) basenm = (k_name + k_ptr->name);
+ if ((!hack_name) && known && (k_ptr->flags5 & TR5_FULL_NAME))
+ {
+ basenm = k_ptr->name;
+ }
/* Start dumping the result */
@@ -1712,11 +1665,11 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (e_ptr->before)
{
- ego = e_ptr->name + e_name;
+ ego = e_ptr->name;
}
else if (e2_ptr->before)
{
- ego = e2_ptr->name + e_name;
+ ego = e2_ptr->name;
}
}
@@ -1793,12 +1746,12 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (e_ptr->before)
{
- t = object_desc_str(t, (e_name + e_ptr->name));
+ t = object_desc_str(t, e_ptr->name);
t = object_desc_chr(t, ' ');
}
if (e2_ptr->before)
{
- t = object_desc_str(t, (e_name + e2_ptr->name));
+ t = object_desc_str(t, e2_ptr->name);
t = object_desc_chr(t, ' ');
}
}
@@ -1871,12 +1824,12 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (e_ptr->before)
{
- t = object_desc_str(t, (e_name + e_ptr->name));
+ t = object_desc_str(t, e_ptr->name);
t = object_desc_chr(t, ' ');
}
if (e2_ptr->before)
{
- t = object_desc_str(t, (e_name + e2_ptr->name));
+ t = object_desc_str(t, e2_ptr->name);
t = object_desc_chr(t, ' ');
}
}
@@ -1917,8 +1870,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (known && o_ptr->name2)
{
ego_item_type *e_ptr = &e_info[o_ptr->name2];
-
- t = object_desc_str(t, (e_name + e_ptr->name));
+ t = object_desc_str(t, e_ptr->name);
}
}
@@ -1959,7 +1911,9 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
}
}
else
- t = object_desc_str(t, (k_name + k_ptr->name));
+ {
+ t = object_desc_str(t, k_ptr->name);
+ }
}
/* Hack -- Append "Artifact" or "Special" names */
@@ -1999,7 +1953,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (o_ptr->tval != TV_CORPSE)
{
t = object_desc_chr(t, ' ');
- t = object_desc_str(t, (a_name + a_ptr->name));
+ t = object_desc_str(t, a_ptr->name);
}
}
@@ -2012,12 +1966,12 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if (o_ptr->name2 && !e_ptr->before)
{
t = object_desc_chr(t, ' ');
- t = object_desc_str(t, (e_name + e_ptr->name));
+ t = object_desc_str(t, e_ptr->name);
}
if (o_ptr->name2b && !e2_ptr->before)
{
t = object_desc_chr(t, ' ');
- t = object_desc_str(t, (e_name + e2_ptr->name));
+ t = object_desc_str(t, e2_ptr->name);
}
}
}
@@ -2043,16 +1997,15 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
if ((f4 & TR4_LEVELS) && known)
{
t = object_desc_str(t, " (E:");
- if (exp_need)
+ if (o_ptr->elevel < PY_MAX_LEVEL)
{
- s32b need;
/* Formula from check_experience_obj(). */
- need = player_exp[o_ptr->elevel - 1] * 5 / 2;
+ s32b need = player_exp[o_ptr->elevel - 1] * 5 / 2;
t = object_desc_num(t, need - o_ptr->exp);
}
else
{
- t = object_desc_num(t, o_ptr->exp);
+ t = object_desc_str(t, "*****");
}
t = object_desc_str(t, ", L:");
t = object_desc_num(t, o_ptr->elevel);
@@ -2092,9 +2045,13 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode)
/* Describe the traps */
t = object_desc_str(t, " (");
if (t_info[o_ptr->pval].ident)
- t = object_desc_str(t, t_name + t_info[o_ptr->pval].name);
+ {
+ t = object_desc_str(t, t_info[o_ptr->pval].name);
+ }
else
+ {
t = object_desc_str(t, "trapped");
+ }
t = object_desc_str(t, ")");
}
}
@@ -2557,8 +2514,8 @@ cptr item_activation(object_type *o_ptr, byte num)
mana = o_ptr->pval2 >> 8;
}
sprintf(rspell[num], "runespell(%s, %s, %d) every %d turns",
- k_info[lookup_kind(TV_RUNE1, gf)].name + k_name,
- k_info[lookup_kind(TV_RUNE2, mod)].name + k_name,
+ k_info[lookup_kind(TV_RUNE1, gf)].name,
+ k_info[lookup_kind(TV_RUNE2, mod)].name,
mana, mana * 5);
return rspell[num];
}
@@ -2581,14 +2538,11 @@ cptr item_activation(object_type *o_ptr, byte num)
}
}
- if (process_hooks_ret(HOOK_ACTIVATE_DESC, "s", "(O)", o_ptr))
- return (process_hooks_return[0].str);
-
return activation_aux(o_ptr, FALSE, 0);
}
/* Grab the tval desc */
-bool_ grab_tval_desc(int tval)
+static bool_ grab_tval_desc(int tval)
{
int tv = 0;
@@ -2803,18 +2757,9 @@ void display_ammo_damage(object_type *o_ptr)
}
/*
- * Output spell description
- */
-static void print_device_desc_callback(void *data, cptr text)
-{
- text_out("\n");
- text_out(text);
-}
-
-/*
* Describe a magic stick powers
*/
-void describe_device(object_type *o_ptr)
+static void describe_device(object_type *o_ptr)
{
char buf[128];
@@ -2824,24 +2769,29 @@ void describe_device(object_type *o_ptr)
/* Enter device mode */
set_stick_mode(o_ptr);
+ // Spell reference
+ auto spell = spell_at(o_ptr->pval2);
+
text_out("\nSpell description:\n");
- spell_type_description_foreach(spell_at(o_ptr->pval2),
- print_device_desc_callback,
- NULL);
+ spell_type_description_foreach(spell,
+ [] (std::string const &text) -> void {
+ text_out("\n");
+ text_out(text.c_str());
+ });
text_out("\nSpell level: ");
sprintf(buf, FMTs32b, get_level(o_ptr->pval2, 50, 0));
text_out_c(TERM_L_BLUE, buf);
text_out("\nMinimum Magic Device level to increase spell level: ");
- text_out_c(TERM_L_BLUE, format("%d", spell_type_skill_level(spell_at(o_ptr->pval2))));
+ text_out_c(TERM_L_BLUE, format("%d", spell_type_skill_level(spell)));
text_out("\nSpell fail: ");
- sprintf(buf, FMTs32b, spell_chance(o_ptr->pval2));
+ sprintf(buf, FMTs32b, spell_chance_device(spell));
text_out_c(TERM_GREEN, buf);
text_out("\nSpell info: ");
- text_out_c(TERM_YELLOW, spell_type_info(spell_at(o_ptr->pval2)));
+ text_out_c(TERM_YELLOW, spell_type_info(spell));
/* Leave device mode */
unset_stick_mode();
@@ -2862,15 +2812,25 @@ static cptr object_out_desc_where_found(s16b level, s16b dungeon)
static char str[80];
if (dungeon == DUNGEON_WILDERNESS)
+ {
/* Taking care of older objects */
if (level == 0)
+ {
sprintf(str, "in the wilderness or in a town");
+ }
else if (wf_info[level].terrain_idx == TERRAIN_TOWN)
- sprintf(str, "in the town of %s", wf_info[level].name + wf_name);
+ {
+ sprintf(str, "in the town of %s", wf_info[level].name);
+ }
else
- sprintf(str, "in %s", wf_info[level].text + wf_text);
+ {
+ sprintf(str, "in %s", wf_info[level].text);
+ }
+ }
else
- sprintf(str, "on level %d of %s", level, d_info[dungeon].name + d_name);
+ {
+ sprintf(str, "on level %d of %s", level, d_info[dungeon].name);
+ }
return str;
}
@@ -2882,7 +2842,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
{
u32b f1, f2, f3, f4, f5, esp;
- char *txt;
+ const char *txt;
cptr vp[64];
byte vc[64];
@@ -2934,7 +2894,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
- text_out_c(TERM_ORANGE, k_text + k_ptr->text);
+ text_out_c(TERM_ORANGE, k_ptr->text);
text_out("\n");
}
@@ -2942,14 +2902,12 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
{
artifact_type *a_ptr = &a_info[o_ptr->name1];
- text_out_c(TERM_YELLOW, a_text + a_ptr->text);
+ text_out_c(TERM_YELLOW, a_ptr->text);
text_out("\n");
if (a_ptr->set != -1)
{
- set_type *set_ptr = &set_info[a_ptr->set];
-
- text_out_c(TERM_GREEN, set_text + set_ptr->desc);
+ text_out_c(TERM_GREEN, set_info[a_ptr->set].desc);
text_out("\n");
}
}
@@ -3041,7 +2999,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
text_out("It prevents the space-time continuum from being disrupted. ");
}
- if ((f4 & (TR4_ANTIMAGIC_50)) || (f4 & (TR4_ANTIMAGIC_30)) || (f4 & (TR4_ANTIMAGIC_20)) || (f4 & (TR4_ANTIMAGIC_10)))
+ if (f4 & TR4_ANTIMAGIC_50)
{
text_out("It generates an antimagic field. ");
}
@@ -3858,12 +3816,12 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait
else if (o_ptr->found == OBJ_FOUND_STORE)
{
text_out(format("\nYou bought it from the %s.",
- st_info[o_ptr->found_aux1].name + st_name));
+ st_info[o_ptr->found_aux1].name));
}
else if (o_ptr->found == OBJ_FOUND_STOLEN)
{
text_out(format("\nYou stole it from the %s.",
- st_info[o_ptr->found_aux1].name + st_name));
+ st_info[o_ptr->found_aux1].name));
}
else if (o_ptr->found == OBJ_FOUND_SELFMADE)
{
@@ -3923,7 +3881,7 @@ char index_to_label(int i)
* Convert a label into the index of an item in the "inven"
* Return "-1" if the label does not indicate a real item
*/
-s16b label_to_inven(int c)
+static s16b label_to_inven(int c)
{
int i;
@@ -3945,7 +3903,7 @@ s16b label_to_inven(int c)
* Convert a label into the index of a item in the "equip"
* Return "-1" if the label does not indicate a real item
*/
-s16b label_to_equip(int c)
+static s16b label_to_equip(int c)
{
int i;
@@ -3966,7 +3924,7 @@ s16b label_to_equip(int c)
* Returns the next free slot of the given "type", return the first
* if all are used
*/
-int get_slot(int slot)
+static int get_slot(int slot)
{
int i = 0;
@@ -3996,16 +3954,12 @@ int get_slot(int slot)
* Determine which equipment slot (if any) an item likes, ignoring the player's
* current body and stuff if ideal == TRUE
*/
-s16b wield_slot_ideal(object_type *o_ptr, bool_ ideal)
+s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal)
{
- /* Try for a script first */
- if (process_hooks_ret(HOOK_WIELD_SLOT, "d", "(O,d)", o_ptr, ideal))
- return process_hooks_return[0].num;
-
/* Theme has restrictions for winged races. */
if (game_module_idx == MODULE_THEME)
{
- cptr race_name = rp_ptr->title + rp_name;
+ cptr race_name = rp_ptr->title;
if (streq(race_name, "Dragon") ||
streq(race_name, "Eagle"))
@@ -4186,7 +4140,7 @@ s16b wield_slot_ideal(object_type *o_ptr, bool_ ideal)
* Determine which equipment slot (if any) an item likes for the player's
* current body and stuff
*/
-s16b wield_slot(object_type *o_ptr)
+s16b wield_slot(object_type const *o_ptr)
{
return wield_slot_ideal(o_ptr, FALSE);
}
@@ -4194,7 +4148,7 @@ s16b wield_slot(object_type *o_ptr)
/*
* Return a string mentioning how a given item is carried
*/
-cptr mention_use(int i)
+static cptr mention_use(int i)
{
cptr p;
@@ -4299,7 +4253,7 @@ cptr mention_use(int i)
*/
cptr describe_use(int i)
{
- cptr p;
+ cptr p = nullptr;
switch (i)
{
@@ -4397,45 +4351,42 @@ cptr describe_use(int i)
/*
* Check an item against the item tester info
*/
-bool_ item_tester_okay(object_type *o_ptr)
+static bool item_tester_okay(object_type const *o_ptr, object_filter_t const &filter)
{
/* Hack -- allow listing empty slots */
- if (item_tester_full) return (TRUE);
+ if (item_tester_full)
+ {
+ return true;
+ }
/* Require an item */
- if (!o_ptr->k_idx) return (FALSE);
-
- /* Hack -- ignore "gold" */
- if (o_ptr->tval == TV_GOLD) return (FALSE);
-
- /* Check the tval */
- if (item_tester_tval)
+ if (!o_ptr->k_idx)
{
- if (!(item_tester_tval == o_ptr->tval)) return (FALSE);
+ return false;
}
- /* Check the hook */
- if (item_tester_hook)
+ /* Hack -- ignore "gold" */
+ if (o_ptr->tval == TV_GOLD)
{
- if (!(*item_tester_hook)(o_ptr)) return (FALSE);
+ return false;
}
- /* Assume okay */
- return (TRUE);
+ /* Check against the filter */
+ return filter(o_ptr);
}
-void show_equip_aux(bool_ mirror, bool_ everything);
-void show_inven_aux(bool_ mirror, bool_ everything);
+static void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter);
+static void show_inven_aux(bool_ mirror, bool_ everything, object_filter_t const &filter);
/*
* Choice window "shadow" of the "show_inven()" function
*/
void display_inven(void)
{
- show_inven_aux(TRUE, inventory_no_move);
+ show_inven_aux(TRUE, inventory_no_move, object_filter::True());
}
@@ -4445,7 +4396,7 @@ void display_inven(void)
*/
void display_equip(void)
{
- show_equip_aux(TRUE, inventory_no_move);
+ show_equip_aux(TRUE, inventory_no_move, object_filter::True());
}
@@ -4472,7 +4423,7 @@ byte get_item_letter_color(object_type *o_ptr)
*
* Hack -- do not display "trailing" empty slots
*/
-void show_inven_aux(bool_ mirror, bool_ everything)
+void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filter)
{
int i, j, k, l, z = 0;
int row, col, len, lim;
@@ -4524,7 +4475,7 @@ void show_inven_aux(bool_ mirror, bool_ everything)
o_ptr = &p_ptr->inventory[i];
/* Is this item acceptable? */
- if (!item_tester_okay(o_ptr))
+ if (!item_tester_okay(o_ptr, filter))
{
if ( !everything )
continue;
@@ -4613,8 +4564,10 @@ void show_inven_aux(bool_ mirror, bool_ everything)
/* Shadow windows */
if (mirror)
{
+ int hgt;
+ Term_get_size(nullptr, &hgt);
/* Erase the rest of the window */
- for (j = row + k; j < Term->hgt; j++)
+ for (j = row + k; j < hgt; j++)
{
/* Erase the line */
Term_erase(0, j, 255);
@@ -4630,20 +4583,34 @@ void show_inven_aux(bool_ mirror, bool_ everything)
}
-void show_inven()
+static void show_inven(object_filter_t const &filter)
{
- show_inven_aux(FALSE, FALSE);
+ show_inven_aux(FALSE, FALSE, filter);
}
-void show_equip()
+void show_inven_full()
{
- show_equip_aux(FALSE, FALSE);
+ item_tester_full = true;
+ show_inven(object_filter::True());
+ item_tester_full = false;
+}
+
+static void show_equip(object_filter_t const &filter)
+{
+ show_equip_aux(FALSE, FALSE, filter);
+}
+
+void show_equip_full()
+{
+ item_tester_full = true;
+ show_equip(object_filter::True());
+ item_tester_full = false;
}
/*
* Display the equipment.
*/
-void show_equip_aux(bool_ mirror, bool_ everything)
+void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter)
{
int i, j, k, l;
int row, col, len, lim, idx;
@@ -4730,7 +4697,7 @@ void show_equip_aux(bool_ mirror, bool_ everything)
if ((p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD) &&
!o_ptr->k_idx)
{
- sprintf(o_name, "(%s)", melee_names[get_melee_skill()]);
+ sprintf(o_name, "(%s)", get_melee_name());
/* Truncate the description */
o_name[lim] = 0;
@@ -4754,7 +4721,7 @@ void show_equip_aux(bool_ mirror, bool_ everything)
/* Truncate the description */
o_name[lim] = 0;
/* Is this item acceptable? */
- if (!item_tester_okay(o_ptr))
+ if (!item_tester_okay(o_ptr, filter))
{
if (!everything) continue;
out_index[k] = -1;
@@ -4849,8 +4816,10 @@ void show_equip_aux(bool_ mirror, bool_ everything)
/* Shadow windows */
if (mirror)
{
+ int hgt;
+ Term_get_size(nullptr, &hgt);
/* Erase the rest of the window */
- for (j = row + k; j < Term->hgt; j++)
+ for (j = row + k; j < hgt; j++)
{
/* Erase the line */
Term_erase(0, j, 255);
@@ -4977,16 +4946,16 @@ static bool_ get_item_allow(int item)
/*
* Auxiliary function for "get_item()" -- test an index
*/
-static bool_ get_item_okay(int i)
+static bool get_item_okay(int i, object_filter_t const &filter)
{
/* Illegal items */
- if ((i < 0) || (i >= INVEN_TOTAL)) return (FALSE);
+ if ((i < 0) || (i >= INVEN_TOTAL))
+ {
+ return (FALSE);
+ }
/* Verify the item */
- if (!item_tester_okay(&p_ptr->inventory[i])) return (FALSE);
-
- /* Assume okay */
- return (TRUE);
+ return item_tester_okay(&p_ptr->inventory[i], filter);
}
@@ -5056,61 +5025,45 @@ static int get_tag(int *cp, char tag)
* scan_floor --
*
* Return a list of o_list[] indexes of items at the given cave
- * location. Valid flags are:
- *
- * mode & 0x01 -- Item tester
- * mode & 0x02 -- Marked items only
- * mode & 0x04 -- Stop after first
+ * location.
*/
-bool_ scan_floor(int *items, int *item_num, int y, int x, int mode)
+static std::vector<int> scan_floor(int y, int x, object_filter_t const &filter)
{
- int this_o_idx, next_o_idx;
-
- int num = 0;
-
- (*item_num) = 0;
+ std::vector<int> items;
/* Sanity */
- if (!in_bounds(y, x)) return (FALSE);
+ if (!in_bounds(y, x))
+ {
+ return items;
+ }
/* Scan all objects in the grid */
- for (this_o_idx = cave[y][x].o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: cave[y][x].o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[this_o_idx];
/* Item tester */
- if ((mode & 0x01) && !item_tester_okay(o_ptr)) continue;
-
- /* Marked */
- if ((mode & 0x02) && !o_ptr->marked) continue;
+ if (!item_tester_okay(o_ptr, filter))
+ {
+ continue;
+ }
/* Accept this item */
- items[num++] = this_o_idx;
-
- /* Only one */
- if (mode & 0x04) break;
+ items.push_back(this_o_idx);
/* XXX Hack -- Enforce limit */
- if (num == 23) break;
+ if (items.size() == 23) break;
}
- /* Number of items */
- (*item_num) = num;
-
/* Result */
- return (num != 0);
+ return items;
}
/*
* Display a list of the items on the floor at the given location.
*/
-void show_floor(int y, int x)
+static void show_floor(int y, int x, object_filter_t const &filter)
{
int i, j, k, l;
int col, len, lim;
@@ -5125,8 +5078,6 @@ void show_floor(int y, int x)
byte out_color[23];
char out_desc[23][80];
- int floor_list[23], floor_num;
-
/* Default length */
len = 79 - 50;
@@ -5137,7 +5088,9 @@ void show_floor(int y, int x)
lim -= 9;
/* Scan for objects in the grid, using item_tester_okay() */
- (void) scan_floor(floor_list, &floor_num, y, x, 0x01);
+ auto const floor_list = scan_floor(y, x, filter);
+ assert(floor_list.size() <= 23);
+ int const floor_num = floor_list.size(); // "int" for warning avoidance
/* Display the inventory */
for (k = 0, i = 0; i < floor_num; i++)
@@ -5212,8 +5165,7 @@ void show_floor(int y, int x)
* This version of get_item() is called by get_item() when
* the easy_floor is on.
*/
-bool_ (*get_item_extra_hook)(int *cp);
-bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
+static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
char n1 = 0, n2 = 0, which = ' ';
@@ -5226,7 +5178,6 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
bool_ equip = FALSE;
bool_ inven = FALSE;
bool_ floor = FALSE;
- bool_ extra = FALSE;
bool_ automat = FALSE;
bool_ allow_equip = FALSE;
@@ -5238,7 +5189,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
char tmp_val[160];
char out_val[160];
- int floor_num, floor_list[23], floor_top = 0;
+ int floor_top = 0;
k = 0;
@@ -5257,28 +5208,16 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
o_ptr = &o_list[k];
/* Validate the item */
- if (item_tester_okay(o_ptr))
+ if (item_tester_okay(o_ptr, filter))
{
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Success */
return (TRUE);
}
}
/* Verify the item */
- else if (get_item_okay(*cp))
+ else if (get_item_okay(*cp, filter))
{
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Success */
return (TRUE);
}
@@ -5289,7 +5228,6 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (mode & (USE_EQUIP)) equip = TRUE;
if (mode & (USE_INVEN)) inven = TRUE;
if (mode & (USE_FLOOR)) floor = TRUE;
- if (mode & (USE_EXTRA)) extra = TRUE;
if (mode & (USE_AUTO)) automat = TRUE;
@@ -5312,8 +5250,8 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (!inven) i2 = -1;
/* Restrict inventory indexes */
- while ((i1 <= i2) && (!get_item_okay(i1))) i1++;
- while ((i1 <= i2) && (!get_item_okay(i2))) i2--;
+ while ((i1 <= i2) && (!get_item_okay(i1, filter))) i1++;
+ while ((i1 <= i2) && (!get_item_okay(i2, filter))) i2--;
/* Full equipment */
@@ -5324,19 +5262,16 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (!equip) e2 = -1;
/* Restrict equipment indexes */
- while ((e1 <= e2) && (!get_item_okay(e1))) e1++;
- while ((e1 <= e2) && (!get_item_okay(e2))) e2--;
+ while ((e1 <= e2) && (!get_item_okay(e1, filter))) e1++;
+ while ((e1 <= e2) && (!get_item_okay(e2, filter))) e2--;
- /* Count "okay" floor items */
- floor_num = 0;
-
- /* Restrict floor usage */
- if (floor)
- {
- /* Scan all objects in the grid */
- (void) scan_floor(floor_list, &floor_num, p_ptr->py, p_ptr->px, 0x01);
- }
+ /* Floor items? */
+ auto const floor_list =
+ floor ? std::move(scan_floor(p_ptr->py, p_ptr->px, filter))
+ : std::vector<int>();
+ assert(floor_list.size() <= 23);
+ int const floor_num = floor_list.size(); // "int" for warning avoidance
/* Accept inventory */
if (i1 <= i2) allow_inven = TRUE;
@@ -5345,7 +5280,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (e1 <= e2) allow_equip = TRUE;
/* Accept floor */
- if (floor_num) allow_floor = TRUE;
+ if (!floor_list.empty()) allow_floor = TRUE;
/* Require at least one legal choice */
if (!allow_inven && !allow_equip && !allow_floor)
@@ -5435,7 +5370,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(i2);
/* Redraw */
- show_inven();
+ show_inven(filter);
}
/* Equipment screen */
@@ -5446,7 +5381,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(e2 - INVEN_WIELD);
/* Redraw */
- show_equip();
+ show_equip(filter);
}
/* Floor screen */
@@ -5460,7 +5395,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(k - floor_top);
/* Redraw */
- show_floor(p_ptr->py, p_ptr->px);
+ show_floor(p_ptr->py, p_ptr->px, filter);
}
/* Viewing inventory */
@@ -5526,8 +5461,8 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
}
- /* Extra? */
- if (extra)
+ /* Do we allow selection by name? */
+ if (select_by_name)
{
strcat(out_val, " @ for extra selection,");
}
@@ -5680,7 +5615,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if (!get_item_okay(k))
+ if (!get_item_okay(k, filter))
{
bell();
break;
@@ -5739,7 +5674,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if (!get_item_okay(k))
+ if (!get_item_okay(k, filter))
{
bell();
break;
@@ -5761,11 +5696,15 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
case '@':
{
- int i;
-
- if (extra && get_item_extra_hook(&i))
+ // Ignore if not "enabled"
+ if (!select_by_name)
+ {
+ break;
+ }
+ // Find by name
+ if (auto i = select_by_name(filter))
{
- (*cp) = i;
+ (*cp) = *i;
item = TRUE;
done = TRUE;
}
@@ -5822,7 +5761,7 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if ((k >= 0) && !get_item_okay(k))
+ if ((k >= 0) && !get_item_okay(k, filter))
{
bell();
break;
@@ -5854,12 +5793,6 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
/* Fix the screen */
screen_load();
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Track */
if (item && done)
{
@@ -5947,17 +5880,16 @@ bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
* We always erase the prompt when we are done, leaving a blank line,
* or a warning message, if appropriate, if no items are available.
*/
-bool_ get_item(int *cp, cptr pmt, cptr str, int mode)
+bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
automatizer_create = FALSE;
-
- return get_item_floor(cp, pmt, str, mode);
+ return get_item_floor(cp, pmt, str, mode, filter, select_by_name);
}
/*
* Hook to determine if an object is getable
*/
-static bool_ item_tester_hook_getable(object_type *o_ptr)
+static bool item_tester_hook_getable(object_type const *o_ptr)
{
if (!inven_carry_okay(o_ptr)) return (FALSE);
@@ -6029,7 +5961,7 @@ int wear_ammo(object_type *o_ptr)
p_ptr->update |= (PU_MANA);
/* Redraw monster hitpoint */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
@@ -6043,21 +5975,19 @@ int wear_ammo(object_type *o_ptr)
*/
void pickup_ammo()
{
- s16b this_o_idx, next_o_idx = 0, slot;
- char o_name[80];
+ /* Copy list of objects since we're manipulating the list */
+ auto const object_idxs(cave[p_ptr->py][p_ptr->px].o_idxs);
/* Scan the pile of objects */
- for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
+ object_type *o_ptr = &o_list[this_o_idx];
if (object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]))
{
msg_print("You add the ammo to your quiver.");
- slot = wear_ammo(o_ptr);
+ s16b slot = wear_ammo(o_ptr);
if (slot != -1)
{
@@ -6065,6 +5995,7 @@ void pickup_ammo()
o_ptr = &p_ptr->inventory[slot];
/* Describe the object */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Message */
@@ -6074,51 +6005,35 @@ void pickup_ammo()
delete_object_idx(this_o_idx);
}
}
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
}
}
-/*
- * Make the player carry everything in a grid
- *
- * If "pickup" is FALSE then only gold will be picked up
- *
- * This is called by py_pickup() when easy_floor is TRUE.
+/**
+ * Check for encumberance if player were to pick up
+ * given item.
*/
-bool_ can_carry_heavy(object_type *o_ptr)
+static bool can_carry_heavy(object_type const *o_ptr)
{
- /* Query if object is heavy */
- if (prompt_pickup_heavy)
- {
- int i, j;
- int old_enc = 0;
- int new_enc = 0;
-
- /* Extract the "weight limit" (in tenth pounds) */
- i = weight_limit();
+ /* Extract the "weight limit" (in tenth pounds) */
+ int i = weight_limit();
- /* Calculate current encumbarance */
- j = calc_total_weight();
+ /* Calculate current encumbarance */
+ int j = calc_total_weight();
- /* Apply encumbarance from weight */
- if (j > i / 2) old_enc = ((j - (i / 2)) / (i / 10));
+ /* Apply encumbarance from weight */
+ int old_enc = 0;
+ if (j > i / 2) old_enc = ((j - (i / 2)) / (i / 10));
- /* Increase the weight, recalculate encumbarance */
- j += (o_ptr->number * o_ptr->weight);
+ /* Increase the weight, recalculate encumbarance */
+ j += (o_ptr->number * o_ptr->weight);
- /* Apply encumbarance from weight */
- if (j > i / 2) new_enc = ((j - (i / 2)) / (i / 10));
+ /* Apply encumbarance from weight */
+ int new_enc = 0;
+ if (j > i / 2) new_enc = ((j - (i / 2)) / (i / 10));
- /* Should we query? */
- if (new_enc > old_enc)
- {
- return (FALSE);
- }
- }
- return (TRUE);
+ /* If the encumberance is the same, then we pick up without prompt */
+ return (new_enc <= old_enc);
}
/* Do the actuall picking up */
@@ -6149,10 +6064,6 @@ void object_pickup(int this_o_idx)
/* Pick up object */
else
{
- /* Tell the scripts */
- if (process_hooks(HOOK_GET, "(O,d)", o_ptr, this_o_idx))
- return;
-
/* Hooks */
{
hook_get_in in = { o_ptr, this_o_idx };
@@ -6199,60 +6110,19 @@ void object_pickup(int this_o_idx)
}
-void py_pickup_floor(int pickup)
+static void absorb_gold(cave_type const *c_ptr)
{
- s16b this_o_idx, next_o_idx = 0;
-
- char o_name[80] = "";
- object_type *o_ptr = 0;
-
- int floor_num = 0, floor_o_idx = 0;
-
- bool_ do_pickup = TRUE;
-
- bool_ do_ask = TRUE;
-
- /* Hack -- ignore monster traps */
- if (cave[p_ptr->py][p_ptr->px].feat == FEAT_MON_TRAP) return;
-
- /* Try to grab ammo */
- pickup_ammo();
+ /* Copy list of objects since we're going to manipulate the list itself */
+ auto const object_idxs(c_ptr->o_idxs);
- /* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching,
- * so that we don't have to walk over things twice to get them
- * squelched. --dsb */
- if (p_ptr->auto_id)
- {
- this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx;
-
- for (; this_o_idx; this_o_idx = next_o_idx)
- {
- /* Aquire the object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire the next object index */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Identify Object */
- object_aware(o_ptr);
- object_known(o_ptr);
- }
- }
-
- /* Squeltch the floor */
- squeltch_grid();
-
- /* Scan the pile of objects */
- for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx)
+ /* Go through everything */
+ for (auto const this_o_idx: object_idxs)
{
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Hack -- disturb */
- disturb(0, 0);
+ disturb(0);
/* Pick up gold */
if (o_ptr->tval == TV_GOLD)
@@ -6261,139 +6131,174 @@ void py_pickup_floor(int pickup)
object_desc(goldname, o_ptr, TRUE, 3);
/* Message */
msg_format("You have found %ld gold pieces worth of %s.",
- (long)o_ptr->pval, goldname);
+ (long)o_ptr->pval, goldname);
/* Collect the gold */
p_ptr->au += o_ptr->pval;
/* Redraw gold */
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
/* Delete the gold */
delete_object_idx(this_o_idx);
-
- continue;
}
+ }
+}
+static void sense_floor(cave_type const *c_ptr)
+{
+ /* Build a list of the floor objects. */
+ std::vector<int> floor_object_idxs;
+ {
+ /* Reserve the correct number of slots */
+ floor_object_idxs.reserve(c_ptr->o_idxs.size());
+ /* Fill in the indexes */
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- char testdesc[80];
+ // Note the "-"! We need it for get_object()
+ // lookups to function correctly.
+ floor_object_idxs.push_back(0 - this_o_idx);
+ }
+ }
- object_desc(testdesc, o_ptr, TRUE, 3);
- if (0 != strncmp(testdesc, "(nothing)", 80))
- {
- strncpy(o_name, testdesc, 80);
- }
+ /* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching,
+ * so that we don't have to walk over things twice to get them
+ * squelched. --dsb */
+ if (p_ptr->auto_id)
+ {
+ for (auto const o_idx: floor_object_idxs)
+ {
+ object_type *o_ptr = get_object(o_idx);
+ object_aware(o_ptr);
+ object_known(o_ptr);
}
+ }
- /* Count non-gold */
- floor_num++;
+ /* Sense floor tile */
+ sense_objects(floor_object_idxs);
+}
+
+void py_pickup_floor(int pickup)
+{
+ /* Get the tile */
+ auto c_ptr = &cave[p_ptr->py][p_ptr->px];
- /* Remember this index */
- floor_o_idx = this_o_idx;
+ /* Hack -- ignore monster traps */
+ if (c_ptr->feat == FEAT_MON_TRAP)
+ {
+ return;
}
- /* There were no non-gold items */
- if (!floor_num) return;
+ /* Try to grab ammo */
+ pickup_ammo();
+
+ /* Auto-ID and pseudo-ID */
+ sense_floor(c_ptr);
+
+ /* Squeltch the floor */
+ squeltch_grid();
+
+ /* Absorb gold on the tile */
+ absorb_gold(&cave[p_ptr->py][p_ptr->px]);
- /* Mention number of items */
- if (!pickup)
+ /* We handle 0, 1, or "many" items cases separately */
+ if (c_ptr->o_idxs.empty())
{
- /* One item */
- if (floor_num == 1)
+ /* Nothing to do */
+ }
+ else if (c_ptr->o_idxs.size() == 1)
+ {
+ /* Acquire object */
+ auto floor_o_idx = c_ptr->o_idxs.front();
+ auto o_ptr = &o_list[floor_o_idx];
+
+ /* Describe or pick up? */
+ if (!pickup)
{
- /* Acquire object */
- o_ptr = &o_list[floor_o_idx];
+ /* Describe */
+ char o_name[80] = "";
+ object_desc(o_name, o_ptr, TRUE, 3);
/* Message */
msg_format("You see %s.", o_name);
}
-
- /* Multiple items */
else
{
- /* Message */
- msg_format("You see a pile of %d items.", floor_num);
- }
+ /* Are we actually going to pick up? */
+ bool_ do_pickup = TRUE;
- /* Done */
- return;
- }
-
- /* One item */
- if (floor_num == 1)
- {
- /* Hack -- query every item */
- if (carry_query_flag || (!can_carry_heavy(&o_list[floor_o_idx])))
- {
- if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]))
+ /* Hack -- query every item */
+ if (carry_query_flag || (!can_carry_heavy(&o_list[floor_o_idx])))
{
+ char o_name[80] = "";
object_desc(o_name, o_ptr, TRUE, 3);
- msg_format("You have no room for %s.", o_name);
- do_pickup = FALSE;
+
+ if (!inven_carry_okay(o_ptr) && !object_similar(o_ptr, &p_ptr->inventory[INVEN_AMMO]))
+ {
+ msg_format("You have no room for %s.", o_name);
+ return; /* Done */
+ }
+ else
+ {
+ char out_val[160];
+ sprintf(out_val, "Pick up %s? ", o_name);
+ do_pickup = get_check(out_val);
+ }
}
- else
+
+ /* Just pick it up; unless it's a symbiote and we don't have Symbiosis */
+ if (do_pickup && ((o_list[floor_o_idx].tval != TV_HYPNOS) || (get_skill(SKILL_SYMBIOTIC))))
{
- char out_val[160];
- sprintf(out_val, "Pick up %s? ", o_name);
- do_pickup = get_check(out_val);
+ object_pickup(floor_o_idx);
}
}
-
- /* Don't ask */
- do_ask = FALSE;
-
- if ((o_list[floor_o_idx].tval == TV_HYPNOS) && (!get_skill(SKILL_SYMBIOTIC)))
- do_pickup = FALSE;
- else
- this_o_idx = floor_o_idx;
}
-
- /* Ask */
- if (do_ask)
+ else
{
- cptr q, s;
-
- int item;
-
- /* Get an item */
-
- item_tester_hook = item_tester_hook_getable;
-
- q = "Get which item? ";
- s = "You have no room in your pack for any of the items here.";
- if (get_item(&item, q, s, (USE_FLOOR)))
+ /* Describe or pick up? */
+ if (!pickup)
{
- this_o_idx = 0 - item;
-
- if (!can_carry_heavy(&o_list[this_o_idx]))
+ /* Message */
+ msg_format("You see a pile of %d items.", c_ptr->o_idxs.size());
+ }
+ else
+ {
+ /* Prompt for the item to pick up */
+ cptr q = "Get which item? ";
+ cptr s = "You have no room in your pack for any of the items here.";
+ int item;
+ if (get_item(&item, q, s, (USE_FLOOR), item_tester_hook_getable))
{
- char out_val[160];
+ s16b this_o_idx = 0 - item;
- /* Describe the object */
- object_desc(o_name, &o_list[this_o_idx], TRUE, 3);
+ bool_ do_pickup = TRUE;
+ if (!can_carry_heavy(&o_list[this_o_idx]))
+ {
+ /* Describe the object */
+ char o_name[80] = "";
+ object_desc(o_name, &o_list[this_o_idx], TRUE, 3);
+
+ /* Prompt */
+ char out_val[160];
+ sprintf(out_val, "Pick up %s? ", o_name);
+ do_pickup = get_check(out_val);
+ }
- sprintf(out_val, "Pick up %s? ", o_name);
- do_pickup = get_check(out_val);
+ /* Pick up the item */
+ if (do_pickup)
+ {
+ object_pickup(this_o_idx);
+ }
}
}
- else
- {
- do_pickup = FALSE;
- }
- }
-
- /* Pick up the item */
- if (do_pickup)
- {
- object_pickup(this_o_idx);
}
}
/* Add a flags group */
-void gain_flag_group(object_type *o_ptr, bool_ silent)
+static void gain_flag_group(object_type *o_ptr)
{
int grp = 0;
int tries = 1000;
@@ -6418,7 +6323,7 @@ void gain_flag_group(object_type *o_ptr, bool_ silent)
o_ptr->pval2 -= flags_groups[grp].price;
o_ptr->pval3 |= BIT(grp);
- if (!silent)
+ /* Message */
{
char o_name[80];
@@ -6427,7 +6332,7 @@ void gain_flag_group(object_type *o_ptr, bool_ silent)
}
}
-u32b get_flag(object_type *o_ptr, int grp, int k)
+static u32b get_flag(object_type *o_ptr, int grp, int k)
{
u32b f = 0, flag_set = 0;
int tries = 1000;
@@ -6488,7 +6393,7 @@ u32b get_flag(object_type *o_ptr, int grp, int k)
}
/* Add a flags from a flag group */
-void gain_flag_group_flag(object_type *o_ptr, bool_ silent)
+static void gain_flag_group_flag(object_type *o_ptr)
{
int grp = 0, k = 0;
u32b f = 0;
@@ -6535,7 +6440,7 @@ void gain_flag_group_flag(object_type *o_ptr, bool_ silent)
break;
}
- if (!silent)
+ /* Message */
{
char o_name[80];
@@ -6572,13 +6477,13 @@ void object_gain_level(object_type *o_ptr)
o_ptr->to_h += 1;
o_ptr->pval2++;
- if (magik(NEW_GROUP_CHANCE)) gain_flag_group(o_ptr, FALSE);
+ if (magik(NEW_GROUP_CHANCE)) gain_flag_group(o_ptr);
}
else
{
- if (!o_ptr->pval3) gain_flag_group(o_ptr, FALSE);
+ if (!o_ptr->pval3) gain_flag_group(o_ptr);
- gain_flag_group_flag(o_ptr, FALSE);
+ gain_flag_group_flag(o_ptr);
if (!o_ptr->pval) o_ptr->pval = 1;
else
@@ -6607,8 +6512,14 @@ bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent)
{
s_ptr->num_use++;
s_ptr->arts[i].present = TRUE;
- if (s_ptr->num_use > s_ptr->num) msg_print("ERROR!! s_ptr->num_use > s_ptr->use");
- else if ((s_ptr->num_use == s_ptr->num) && (!silent)) cmsg_format(TERM_GREEN, "%s item set completed.", s_ptr->name + set_name);
+ if (s_ptr->num_use > s_ptr->num)
+ {
+ msg_print("ERROR!! s_ptr->num_use > s_ptr->use");
+ }
+ else if ((s_ptr->num_use == s_ptr->num) && (!silent))
+ {
+ cmsg_format(TERM_GREEN, "%s item set completed.", s_ptr->name);
+ }
return (TRUE);
}
return (FALSE);
@@ -6626,10 +6537,15 @@ bool_ takeoff_set(s16b a_idx, s16b set_idx)
if (s_ptr->arts[i].present)
{
s_ptr->arts[i].present = FALSE;
+
+ assert(s_ptr->num_use > 0);
s_ptr->num_use--;
- if (s_ptr->num_use == 255) msg_print("ERROR!! s_ptr->num_use < 0");
- if (s_ptr->num_use == s_ptr->num - 1) cmsg_format(TERM_GREEN, "%s item set not complete anymore.", s_ptr->name + set_name);
+ if (s_ptr->num_use == s_ptr->num - 1)
+ {
+ cmsg_format(TERM_GREEN, "%s item set not complete anymore.", s_ptr->name);
+ }
+
return (TRUE);
}
return (FALSE);
@@ -6661,7 +6577,7 @@ bool_ apply_set(s16b a_idx, s16b set_idx)
return (FALSE);
}
-bool_ apply_flags_set(s16b a_idx, s16b set_idx,
+static bool_ apply_flags_set(s16b a_idx, s16b set_idx,
u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp)
{
set_type *s_ptr = &set_info[set_idx];
@@ -6690,7 +6606,106 @@ bool_ apply_flags_set(s16b a_idx, s16b set_idx,
return (FALSE);
}
+/*
+ * Return the "attr" for a given item.
+ * Use "flavor" if available.
+ * Default to user definitions.
+ */
+byte object_attr(object_type const *o_ptr)
+{
+ if (o_ptr->tval == TV_RANDART)
+ {
+ return random_artifacts[o_ptr->sval].attr;
+ }
+ else if (k_info[o_ptr->k_idx].flavor)
+ {
+ return misc_to_attr[k_info[o_ptr->k_idx].flavor];
+ }
+ else
+ {
+ return k_info[o_ptr->k_idx].x_attr;
+ }
+}
+byte object_attr_default(object_type *o_ptr)
+{
+ if (o_ptr->tval == TV_RANDART)
+ {
+ return random_artifacts[o_ptr->sval].attr;
+ }
+ else if (k_info[o_ptr->k_idx].flavor)
+ {
+ return misc_to_attr[k_info[o_ptr->k_idx].flavor];
+ }
+ else
+ {
+ return k_info[o_ptr->k_idx].d_attr;
+ }
+}
+
+/*
+ * Return the "char" for a given item.
+ * Use "flavor" if available.
+ * Default to user definitions.
+ */
+
+char object_char(object_type const *o_ptr)
+{
+ if (k_info[o_ptr->k_idx].flavor)
+ {
+ return misc_to_char[k_info[o_ptr->k_idx].flavor];
+ }
+ else
+ {
+ return k_info[o_ptr->k_idx].x_char;
+ }
+}
+
+char object_char_default(object_type const *o_ptr)
+{
+ if (k_info[o_ptr->k_idx].flavor)
+ {
+ return misc_to_char[k_info[o_ptr->k_idx].flavor];
+ }
+ else
+ {
+ return k_info[o_ptr->k_idx].d_char;
+ }
+}
+
+/**
+ * Is the given object an artifact?
+ */
+bool artifact_p(object_type const *o_ptr)
+{
+ return
+ (o_ptr->tval == TV_RANDART) ||
+ (o_ptr->name1 ? true : false) ||
+ (o_ptr->art_name ? true : false) ||
+ ((k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) ? true : false);
+}
+
+/**
+ * Is the given object an ego item?
+ */
+bool ego_item_p(object_type const *o_ptr)
+{
+ return o_ptr->name2 || (o_ptr->name2b ? TRUE : FALSE);
+}
+/*
+ * Is the given object an ego item of the given type?
+ */
+bool is_ego_p(object_type const *o_ptr, s16b ego)
+{
+ return (o_ptr->name2 == ego) || (o_ptr->name2b == ego);
+}
+/**
+ * Is the given object identified as cursed?
+ */
+bool cursed_p(object_type const *o_ptr)
+{
+ return o_ptr->ident & (IDENT_CURSED);
+}
diff --git a/src/object1.hpp b/src/object1.hpp
new file mode 100644
index 00000000..ec8f9367
--- /dev/null
+++ b/src/object1.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_filter.hpp"
+
+#include <boost/optional.hpp>
+#include <functional>
+
+typedef std::function<boost::optional<int>(object_filter_t const &filter)> select_by_name_t;
+
+extern byte get_item_letter_color(object_type *o_ptr);
+extern void object_pickup(int this_o_idx);
+extern bool_ apply_set(s16b a_idx, s16b set_idx);
+extern bool_ takeoff_set(s16b a_idx, s16b set_idx);
+extern bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent);
+extern bool_ verify(cptr prompt, int item);
+extern void flavor_init(void);
+extern void reset_visuals(void);
+extern int object_power(object_type *o_ptr);
+extern bool_ object_flags_no_set;
+extern void object_flags(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
+extern void object_flags_known(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp);
+extern void object_desc(char *buf, object_type *o_ptr, int pref, int mode);
+extern void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode);
+extern bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it);
+extern char index_to_label(int i);
+extern s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal);
+extern s16b wield_slot(object_type const *o_ptr);
+extern cptr describe_use(int i);
+extern void display_inven(void);
+extern void display_equip(void);
+extern void show_inven_full();
+extern void show_equip_full();
+extern void toggle_inven_equip(void);
+extern bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t());
+extern cptr item_activation(object_type *o_ptr,byte num);
+extern void py_pickup_floor(int pickup);
+extern void object_gain_level(object_type *o_ptr);
+extern byte object_attr(object_type const *o_ptr);
+extern byte object_attr_default(object_type *o_ptr);
+extern char object_char(object_type const *o_ptr);
+extern char object_char_default(object_type const *o_ptr);
+extern bool artifact_p(object_type const *o_ptr);
+extern bool ego_item_p(object_type const *o_ptr);
+extern bool is_ego_p(object_type const *o_ptr, s16b ego);
+extern bool cursed_p(object_type const *o_ptr);
diff --git a/src/object2.c b/src/object2.cc
index b82691ea..b0e33365 100644
--- a/src/object2.c
+++ b/src/object2.cc
@@ -1,7 +1,3 @@
-/* File: object2.c */
-
-/* Purpose: Object code, part 2 */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,44 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "spell_type.h"
+#include "object2.hpp"
+
+#include "alloc_entry.hpp"
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "spell_type.hpp"
+#include "device_allocation.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "feature_type.hpp"
+#include "hooks.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "randart.hpp"
+#include "randart_part_type.hpp"
+#include "skills.hpp"
+#include "spells2.hpp"
+#include "spells3.hpp"
+#include "spells5.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "xtra1.hpp"
+
+#include <algorithm>
+#include <cassert>
+#include <type_traits>
+#include <vector>
/*
* Calculate the player's total inventory weight.
@@ -35,123 +66,36 @@ s32b calc_total_weight(void)
*/
void excise_object_idx(int o_idx)
{
- object_type *j_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
- s16b prev_o_idx = 0;
-
+ /* Function to remove from list */
+ auto remove_it = [o_idx](std::vector<s16b> *v) -> void {
+ v->erase(
+ std::remove(
+ v->begin(),
+ v->end(),
+ o_idx),
+ v->end());
+ };
/* Object */
- j_ptr = &o_list[o_idx];
+ object_type *o_ptr = &o_list[o_idx];
/* Monster */
- if (j_ptr->held_m_idx)
+ if (o_ptr->held_m_idx)
{
- monster_type *m_ptr;
-
/* Monster */
- m_ptr = &m_list[j_ptr->held_m_idx];
-
- /* Scan all objects in the grid */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Done */
- if (this_o_idx == o_idx)
- {
- /* No previous */
- if (prev_o_idx == 0)
- {
- /* Remove from list */
- m_ptr->hold_o_idx = next_o_idx;
- }
-
- /* Real previous */
- else
- {
- object_type *k_ptr;
-
- /* Previous object */
- k_ptr = &o_list[prev_o_idx];
-
- /* Remove from list */
- k_ptr->next_o_idx = next_o_idx;
- }
+ monster_type *m_ptr = &m_list[o_ptr->held_m_idx];
- /* Forget next pointer */
- o_ptr->next_o_idx = 0;
-
- /* Done */
- break;
- }
-
- /* Save prev_o_idx */
- prev_o_idx = this_o_idx;
- }
+ /* Remove object from list of held objects, if present. */
+ remove_it(&m_ptr->hold_o_idxs);
}
-
/* Dungeon */
else
{
- cave_type *c_ptr;
-
- int y = j_ptr->iy;
- int x = j_ptr->ix;
-
/* Grid */
- c_ptr = &cave[y][x];
-
- /* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Done */
- if (this_o_idx == o_idx)
- {
- /* No previous */
- if (prev_o_idx == 0)
- {
- /* Remove from list */
- c_ptr->o_idx = next_o_idx;
- }
-
- /* Real previous */
- else
- {
- object_type *k_ptr;
-
- /* Previous object */
- k_ptr = &o_list[prev_o_idx];
-
- /* Remove from list */
- k_ptr->next_o_idx = next_o_idx;
- }
+ cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix];
- /* Forget next pointer */
- o_ptr->next_o_idx = 0;
-
- /* Done */
- break;
- }
-
- /* Save prev_o_idx */
- prev_o_idx = this_o_idx;
- }
+ /* Remove object from list of objects in the grid, if present. */
+ remove_it(&c_ptr->o_idxs);
}
}
@@ -197,28 +141,17 @@ void delete_object_idx(int o_idx)
*/
void delete_object(int y, int x)
{
- cave_type *c_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Refuse "illegal" locations */
if (!in_bounds(y, x)) return;
-
/* Grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Wipe the object */
object_wipe(o_ptr);
@@ -228,7 +161,7 @@ void delete_object(int y, int x)
}
/* Objects are gone */
- c_ptr->o_idx = 0;
+ c_ptr->o_idxs.clear();
/* Visual update */
lite_spot(y, x);
@@ -240,76 +173,44 @@ void delete_object(int y, int x)
*/
static void compact_objects_aux(int i1, int i2)
{
- int i;
-
- cave_type *c_ptr;
-
- object_type *o_ptr;
-
-
/* Do nothing */
if (i1 == i2) return;
-
- /* Repair objects */
- for (i = 1; i < o_max; i++)
- {
- /* Acquire object */
- o_ptr = &o_list[i];
-
- /* Skip "dead" objects */
- if (!o_ptr->k_idx) continue;
-
- /* Repair "next" pointers */
- if (o_ptr->next_o_idx == i1)
- {
- /* Repair */
- o_ptr->next_o_idx = i2;
- }
- }
-
-
/* Acquire object */
- o_ptr = &o_list[i1];
-
+ object_type *o_ptr = &o_list[i1];
/* Monster */
if (o_ptr->held_m_idx)
{
- monster_type *m_ptr;
-
/* Acquire monster */
- m_ptr = &m_list[o_ptr->held_m_idx];
+ monster_type *m_ptr = &m_list[o_ptr->held_m_idx];
/* Repair monster */
- if (m_ptr->hold_o_idx == i1)
+ for (auto &hold_o_idx: m_ptr->hold_o_idxs)
{
- /* Repair */
- m_ptr->hold_o_idx = i2;
+ if (hold_o_idx == i1)
+ {
+ hold_o_idx = i2;
+ }
}
}
/* Dungeon */
else
{
- int y, x;
-
- /* Acquire location */
- y = o_ptr->iy;
- x = o_ptr->ix;
-
/* Acquire grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix];
/* Repair grid */
- if (c_ptr->o_idx == i1)
+ for (auto &o_idx: c_ptr->o_idxs)
{
- /* Repair */
- c_ptr->o_idx = i2;
+ if (o_idx == i1)
+ {
+ o_idx = i2;
+ }
}
}
-
/* Structure copy */
o_list[i2] = o_list[i1];
@@ -504,13 +405,11 @@ void wipe_o_list(void)
/* Monster */
if (o_ptr->held_m_idx)
{
- monster_type *m_ptr;
-
/* Monster */
- m_ptr = &m_list[o_ptr->held_m_idx];
+ monster_type *m_ptr = &m_list[o_ptr->held_m_idx];
/* Hack -- see above */
- m_ptr->hold_o_idx = 0;
+ m_ptr->hold_o_idxs.clear();
}
/* Dungeon */
@@ -526,11 +425,11 @@ void wipe_o_list(void)
c_ptr = &cave[y][x];
/* Hack -- see above */
- c_ptr->o_idx = 0;
+ c_ptr->o_idxs.clear();
}
/* Wipe the object */
- o_ptr = WIPE(o_ptr, object_type);
+ object_wipe(o_ptr);
}
/* Reset "o_max" */
@@ -807,6 +706,17 @@ void object_known(object_type *o_ptr)
+/*
+ * Determine if a given inventory item is "known"
+ * Test One -- Check for special "known" tag
+ * Test Two -- Check for "Easy Know" + "Aware"
+ */
+bool object_known_p(object_type const *o_ptr)
+{
+ return ((o_ptr->ident & (IDENT_KNOWN)) ||
+ (k_info[o_ptr->k_idx].easy_know && k_info[o_ptr->k_idx].aware));
+}
+
/*
@@ -818,6 +728,13 @@ void object_aware(object_type *o_ptr)
k_info[o_ptr->k_idx].aware = TRUE;
}
+/**
+ * Is the player aware of the effects of the given object?
+ */
+bool object_aware_p(object_type const *o_ptr)
+{
+ return k_info[o_ptr->k_idx].aware;
+}
/*
@@ -830,12 +747,20 @@ void object_tried(object_type *o_ptr)
}
+/**
+ * Has the given object been "tried"?
+ */
+bool object_tried_p(object_type const *o_ptr)
+{
+ return k_info[o_ptr->k_idx].tried;
+}
+
/*
* Return the "value" of an "unknown" item
* Make a guess at the value of non-aware items
*/
-static s32b object_value_base(object_type *o_ptr)
+static s32b object_value_base(object_type const *o_ptr)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -899,7 +824,7 @@ static s32b object_value_base(object_type *o_ptr)
}
/* Return the value of the flags the object has... */
-s32b flag_cost(object_type * o_ptr, int plusses)
+s32b flag_cost(object_type const * o_ptr, int plusses)
{
s32b total = 0;
u32b f1, f2, f3, f4, f5, esp;
@@ -1135,7 +1060,7 @@ s32b flag_cost(object_type * o_ptr, int plusses)
*
* Every wearable item with a "pval" bonus is worth extra (see below).
*/
-s32b object_value_real(object_type *o_ptr)
+s32b object_value_real(object_type const *o_ptr)
{
s32b value;
@@ -1449,7 +1374,7 @@ s32b object_value_real(object_type *o_ptr)
* Note that discounted items stay discounted forever, even if
* the discount is "forgotten" by the player via memory loss.
*/
-s32b object_value(object_type *o_ptr)
+s32b object_value(object_type const *o_ptr)
{
s32b value;
@@ -1505,7 +1430,7 @@ s32b object_value(object_type *o_ptr)
*
* Chests, and activatable items, never stack (for various reasons).
*/
-bool_ object_similar(object_type *o_ptr, object_type *j_ptr)
+bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr)
{
int total = o_ptr->number + j_ptr->number;
u32b f1, f2, f3, f4, f5, esp, f11, f12, f13, f14, esp1, f15;
@@ -1710,9 +1635,6 @@ bool_ object_similar(object_type *o_ptr, object_type *j_ptr)
case TV_TRAPKIT:
case TV_DAEMON_BOOK:
{
- /* Require permission */
- if (!stack_allow_items) return (0);
-
/* Fall through */
}
@@ -1818,13 +1740,6 @@ bool_ object_similar(object_type *o_ptr, object_type *j_ptr)
/* Hack -- require semi-matching "inscriptions" */
if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)) return (0);
- /* Hack -- normally require matching "inscriptions" */
- if (!stack_force_notes && (o_ptr->note != j_ptr->note)) return (0);
-
- /* Hack -- normally require matching "discounts" */
- if (!stack_force_costs && (o_ptr->discount != j_ptr->discount)) return (0);
-
-
/* Maximal "stacking" limit */
if (total >= MAX_STACK_SIZE) return (0);
@@ -1904,7 +1819,8 @@ s16b lookup_kind(int tval, int sval)
void object_wipe(object_type *o_ptr)
{
/* Wipe the structure */
- o_ptr = WIPE(o_ptr, object_type);
+ static_assert(std::is_pod<object_type>::value, "object_type must be POD type for memset to work");
+ memset(o_ptr, 0, sizeof(object_type));
}
@@ -1914,7 +1830,7 @@ void object_wipe(object_type *o_ptr)
void object_copy(object_type *o_ptr, object_type *j_ptr)
{
/* Copy the structure */
- COPY(o_ptr, j_ptr, object_type);
+ *o_ptr = *j_ptr;
}
@@ -1926,7 +1842,7 @@ void object_prep(object_type *o_ptr, int k_idx)
object_kind *k_ptr = &k_info[k_idx];
/* Clear the record */
- o_ptr = WIPE(o_ptr, object_type);
+ object_wipe(o_ptr);
/* Save the kind index */
o_ptr->k_idx = k_idx;
@@ -2383,17 +2299,15 @@ static bool_ make_artifact(object_type *o_ptr)
*/
static bool_ make_ego_item(object_type *o_ptr, bool_ good)
{
- int i = 0, j;
- int *ok_ego, ok_num = 0;
bool_ ret = FALSE;
object_kind *k_ptr = &k_info[o_ptr->k_idx];
if (artifact_p(o_ptr) || o_ptr->name2) return (FALSE);
- C_MAKE(ok_ego, max_e_idx, int);
+ std::vector<size_t> ok_ego;
/* Grab the ok ego */
- for (i = 0; i < max_e_idx; i++)
+ for (size_t i = 0; i < max_e_idx; i++)
{
ego_item_type *e_ptr = &e_info[i];
bool_ ok = FALSE;
@@ -2402,7 +2316,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
if (!e_ptr->name) continue;
/* Must have the correct fields */
- for (j = 0; j < 6; j++)
+ for (size_t j = 0; j < 6; j++)
{
if (e_ptr->tval[j] == o_ptr->tval)
{
@@ -2438,16 +2352,14 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
continue;
/* ok */
- ok_ego[ok_num++] = i;
+ ok_ego.push_back(i);
}
/* Now test them a few times */
- for (i = 0; i < ok_num * 10; i++)
+ for (size_t i = 0; i < ok_ego.size() * 10; i++)
{
- ego_item_type *e_ptr;
-
- int j = ok_ego[rand_int(ok_num)];
- e_ptr = &e_info[j];
+ size_t j = ok_ego[rand_int(ok_ego.size())];
+ ego_item_type *e_ptr = &e_info[j];
/* XXX XXX Enforce minimum "depth" (loosely) */
if (e_ptr->level > dun_level)
@@ -2483,12 +2395,10 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
if (magik(7 + luck( -7, 7)) && (!o_ptr->name2b))
{
/* Now test them a few times */
- for (i = 0; i < ok_num * 10; i++)
+ for (size_t i = 0; i < ok_ego.size() * 10; i++)
{
- ego_item_type *e_ptr;
-
- int j = ok_ego[rand_int(ok_num)];
- e_ptr = &e_info[j];
+ int j = ok_ego[rand_int(ok_ego.size())]; // Explicit int conversion to avoid warning
+ ego_item_type *e_ptr = &e_info[j];
/* Cannot be a double ego of the same ego type */
if (j == o_ptr->name2) continue;
@@ -2525,8 +2435,6 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good)
}
}
- C_FREE(ok_ego, max_e_idx, int);
-
/* Return */
return (ret);
}
@@ -2607,8 +2515,6 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power)
}
/* Some special cases */
- if (process_hooks(HOOK_APPLY_MAGIC, "(O,d,d)", o_ptr, level, power))
- return;
switch (o_ptr->tval)
{
case TV_TRAPKIT:
@@ -2754,8 +2660,6 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power)
}
/* Analyze type */
- if (process_hooks(HOOK_APPLY_MAGIC, "(O,d,d)", o_ptr, level, power))
- return;
switch (o_ptr->tval)
{
case TV_CLOAK:
@@ -2837,8 +2741,6 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
}
/* Apply magic (good or bad) according to type */
- if (process_hooks(HOOK_APPLY_MAGIC, "(O,d,d)", o_ptr, level, power))
- return;
switch (o_ptr->tval)
{
case TV_RING:
@@ -3228,31 +3130,6 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power)
}
/*
- * Get a spell for a given stick(wand, staff, rod)
- */
-long get_random_stick(byte tval, int level)
-{
- int tries;
-
- for (tries = 0; tries < 1000; tries++)
- {
- long spell_idx = rand_int(school_spells_count);
- spell_type *spell = spell_at(spell_idx);
- device_allocation *device_allocation = spell_type_device_allocation(spell, tval);
-
- if ((device_allocation != NULL) &&
- (rand_int(spell_type_skill_level(spell) * 3) < level) &&
- (magik(100 - device_allocation->rarity)))
- {
- return spell_idx;
- }
- }
-
- return -1;
-}
-
-
-/*
* Randomized level
*/
static int randomized_level_in_range(range_type *range, int level)
@@ -3321,8 +3198,6 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
}
/* Apply magic (good or bad) according to type */
- if (process_hooks(HOOK_APPLY_MAGIC, "(O,d,d)", o_ptr, level, power))
- return;
switch (o_ptr->tval)
{
case TV_BOOK:
@@ -3434,8 +3309,7 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power)
/* Decide the spell, pval == -1 means to bypass spell selection */
if (o_ptr->pval != -1)
{
- int spl = get_random_stick(TV_WAND, dun_level);
-
+ auto spl = get_random_stick(TV_WAND, dun_level);
if (spl == -1)
{
spl = MANATHRUST;
@@ -4010,8 +3884,7 @@ void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows)
* "good" and "great" arguments are false. As a total hack, if "great" is
* true, then the item gets 3 extra "attempts" to become an artifact.
*/
-int hack_apply_magic_power = 0;
-void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great)
+void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power)
{
int i, rolls, f1, f2, power;
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -4112,15 +3985,11 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea
if (magik(f2)) power = -2;
}
- /* Mega hack */
- if (hack_apply_magic_power)
+ /* Override power with parameter? */
+ if (auto power_override = force_power)
{
- if (hack_apply_magic_power == -99)
- power = 0;
- else
- power = hack_apply_magic_power;
+ power = *power_override;
}
- hack_apply_magic_power = 0;
/* Assume no rolls */
rolls = 0;
@@ -4286,7 +4155,7 @@ try_an_other_ego:
e_ptr = &e_info[e_idx];
/* Hack -- extra powers */
- for (j = 0; j < 5; j++)
+ for (j = 0; j < FLAG_RARITY_MAX; j++)
{
/* Rarity check */
if (magik(e_ptr->rar[j]))
@@ -4419,7 +4288,7 @@ static obj_theme match_theme;
* XXX XXX XXX It relies on the fact that obj_theme is a four byte structure
* for its efficient operation. A horrendous hack, I'd say.
*/
-void init_match_theme(obj_theme theme)
+void init_match_theme(obj_theme const &theme)
{
/* Save the theme */
match_theme = theme;
@@ -4444,7 +4313,7 @@ static bool_ theme_changed(obj_theme theme)
/*
* Maga-Hack -- match certain types of object only.
*/
-bool_ kind_is_theme(int k_idx)
+static bool kind_is_theme(int k_idx)
{
object_kind *k_ptr = &k_info[k_idx];
@@ -4637,7 +4506,6 @@ bool_ kind_is_theme(int k_idx)
/*
* Determine if an object must not be generated.
*/
-int kind_is_legal_special = -1;
bool_ kind_is_legal(int k_idx)
{
object_kind *k_ptr = &k_info[k_idx];
@@ -4674,9 +4542,6 @@ bool_ kind_is_legal(int k_idx)
/* Used only for the Nazgul rings */
if ((k_ptr->tval == TV_RING) && (k_ptr->sval == SV_RING_SPECIAL)) return FALSE;
- /* Are we forced to one tval ? */
- if ((kind_is_legal_special != -1) && (kind_is_legal_special != k_ptr->tval)) return (FALSE);
-
/* Assume legal */
return TRUE;
}
@@ -4685,7 +4550,7 @@ bool_ kind_is_legal(int k_idx)
/*
* Hack -- determine if a template is "good"
*/
-bool_ kind_is_good(int k_idx)
+static bool_ kind_is_good(int k_idx)
{
object_kind *k_ptr = &k_info[k_idx];
@@ -4825,7 +4690,7 @@ bool_ kind_is_artifactable(int k_idx)
* through the forge--object_prep()--apply_magic() sequence and
* get_obj_num() should never be called for that purpose XXX XXX XXX
*/
-bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme theme)
+bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme)
{
int invprob, base;
@@ -4995,10 +4860,8 @@ void place_object(int y, int x, bool_ good, bool_ great, int where)
/* Success */
if (o_idx)
{
- object_type *o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[o_idx];
+ object_type *o_ptr = &o_list[o_idx];
/* Structure Copy */
object_copy(o_ptr, q_ptr);
@@ -5010,11 +4873,8 @@ void place_object(int y, int x, bool_ good, bool_ great, int where)
/* Acquire grid */
c_ptr = &cave[y][x];
- /* Build a stack */
- o_ptr->next_o_idx = c_ptr->o_idx;
-
/* Place the object */
- c_ptr->o_idx = o_idx;
+ c_ptr->o_idxs.push_back(o_idx);
/* Notice */
note_spot(y, x);
@@ -5084,6 +4944,10 @@ bool_ make_gold(object_type *j_ptr)
/* Determine how much the treasure is "worth" */
j_ptr->pval = (base + (8L * randint(base)) + randint(8));
+
+ /* Multiply value by 5 if selling is disabled */
+ if (no_selling)
+ j_ptr->pval *= 5;
/* Success */
return (TRUE);
@@ -5143,11 +5007,8 @@ void place_gold(int y, int x)
/* Acquire grid */
c_ptr = &cave[y][x];
- /* Build a stack */
- o_ptr->next_o_idx = c_ptr->o_idx;
-
/* Place the object */
- c_ptr->o_idx = o_idx;
+ c_ptr->o_idxs.push_back(o_idx);
/* Notice */
note_spot(y, x);
@@ -5183,10 +5044,6 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
int dy, dx;
int ty, tx;
- s16b o_idx = 0;
-
- s16b this_o_idx, next_o_idx = 0;
-
cave_type *c_ptr;
char o_name[80];
@@ -5266,15 +5123,10 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
k = 0;
/* Scan objects in that grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Check for possible combination */
if (object_similar(o_ptr, j_ptr)) comb = TRUE;
@@ -5286,9 +5138,6 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
/* Add new object */
if (!comb) k++;
- /* No stacking (allow combining) */
- if (!testing_stack && (k > 1)) continue;
-
/* Paranoia */
if (k > 23) continue;
@@ -5375,15 +5224,10 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
c_ptr = &cave[by][bx];
/* Scan objects in that grid for combination */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Check for combination */
if (object_similar(o_ptr, j_ptr))
@@ -5400,6 +5244,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
}
/* Get new object */
+ s16b o_idx = 0;
if (!done) o_idx = o_pop();
/* Failure */
@@ -5446,11 +5291,8 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x)
/* No monster */
j_ptr->held_m_idx = 0;
- /* Build a stack */
- j_ptr->next_o_idx = c_ptr->o_idx;
-
/* Place the object */
- c_ptr->o_idx = o_idx;
+ c_ptr->o_idxs.push_back(o_idx);
/* Success */
done = TRUE;
@@ -5817,7 +5659,7 @@ void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag des
/*
* Check if we have space for an item in the pack without overflow
*/
-bool_ inven_carry_okay(object_type *o_ptr)
+bool_ inven_carry_okay(object_type const *o_ptr)
{
int j;
@@ -5990,7 +5832,6 @@ s16b inven_carry(object_type *o_ptr, bool_ final)
/* Clean out unused fields */
o_ptr->iy = o_ptr->ix = 0;
- o_ptr->next_o_idx = 0;
o_ptr->held_m_idx = 0;
/* Count the items */
@@ -6374,72 +6215,17 @@ void reorder_pack(void)
if (flag) msg_print("You reorder some items in your pack.");
}
-/*
- * Hack -- display an object kind in the current window
- *
- * Include list of usable spells for readible books
- */
-void display_koff(int k_idx)
-{
- int y;
-
- object_type forge;
- object_type *q_ptr;
-
- char o_name[80];
-
-
- /* Erase the window */
- for (y = 0; y < Term->hgt; y++)
- {
- /* Erase the line */
- Term_erase(0, y, 255);
- }
-
- /* No info */
- if (!k_idx) return;
-
-
- /* Get local object */
- q_ptr = &forge;
-
- /* Prepare the object */
- object_wipe(q_ptr);
-
- /* Prepare the object */
- object_prep(q_ptr, k_idx);
-
-
- /* Describe */
- object_desc_store(o_name, q_ptr, FALSE, 0);
-
- /* Mention the object name */
- Term_putstr(0, 0, -1, TERM_WHITE, o_name);
-}
-
/*
* Let the floor carry an object
*/
s16b floor_carry(int y, int x, object_type *j_ptr)
{
- int n = 0;
-
- s16b o_idx;
-
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Scan objects in that grid for combination */
- for (this_o_idx = cave[y][x].o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: cave[y][x].o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Check for combination */
if (object_similar(o_ptr, j_ptr))
@@ -6447,27 +6233,25 @@ s16b floor_carry(int y, int x, object_type *j_ptr)
/* Combine the items */
object_absorb(o_ptr, j_ptr);
- /* Result */
- return (this_o_idx);
+ /* Done */
+ return this_o_idx;
}
-
- /* Count objects */
- n++;
}
/* The stack is already too large */
- if (n > 23) return (0);
+ if (cave[y][x].o_idxs.size() > 23)
+ {
+ return (0);
+ }
/* Make an object */
- o_idx = o_pop();
+ s16b o_idx = o_pop();
/* Success */
if (o_idx)
{
- object_type *o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[o_idx];
+ object_type *o_ptr = &o_list[o_idx];
/* Structure Copy */
object_copy(o_ptr, j_ptr);
@@ -6479,11 +6263,8 @@ s16b floor_carry(int y, int x, object_type *j_ptr)
/* Forget monster */
o_ptr->held_m_idx = 0;
- /* Build a stack */
- o_ptr->next_o_idx = cave[y][x].o_idx;
-
/* Place the object */
- cave[y][x].o_idx = o_idx;
+ cave[y][x].o_idxs.push_back(o_idx);
/* Notice */
note_spot(y, x);
@@ -6679,13 +6460,11 @@ void floor_decay(int item)
/* Return the item be it on the floor or in inven */
object_type *get_object(int item)
{
- /* Get the item (in the pack) */
if (item >= 0)
{
+ assert(item < INVEN_TOTAL);
return &p_ptr->inventory[item];
}
-
- /* Get the item (on the floor) */
else
{
return &o_list[0 - item];
diff --git a/src/object2.hpp b/src/object2.hpp
new file mode 100644
index 00000000..26d07b25
--- /dev/null
+++ b/src/object2.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+#include "obj_theme_fwd.hpp"
+
+#include <boost/optional.hpp>
+
+typedef enum { OPTIMIZE, NO_OPTIMIZE } optimize_flag;
+typedef enum { DESCRIBE, NO_DESCRIBE } describe_flag;
+
+extern void inc_stack_size(int item, int delta);
+extern void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag desc);
+extern object_type *get_object(int item);
+extern s32b calc_total_weight(void);
+extern void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows);
+extern void init_match_theme(obj_theme const &theme);
+extern bool_ kind_is_artifactable(int k_idx);
+extern bool_ kind_is_legal(int k_idx);
+extern void inven_item_charges(int item);
+extern void inven_item_describe(int item);
+extern void inven_item_increase(int item, int num);
+extern bool_ inven_item_optimize(int item);
+extern void floor_item_charges(int item);
+extern void floor_item_describe(int item);
+extern void floor_item_increase(int item, int num);
+extern void floor_item_optimize(int item);
+extern bool_ inven_carry_okay(object_type const *o_ptr);
+extern s16b inven_carry(object_type *o_ptr, bool_ final);
+extern s16b inven_takeoff(int item, int amt, bool_ force_drop);
+extern void inven_drop(int item, int amt, int dy, int dx, bool_ silent);
+extern void excise_object_idx(int o_idx);
+extern void delete_object_idx(int o_idx);
+extern void delete_object(int y, int x);
+extern void compact_objects(int size);
+extern void wipe_o_list(void);
+extern s16b o_pop(void);
+extern errr get_obj_num_prep(void);
+extern s16b get_obj_num(int level);
+extern void object_known(object_type *o_ptr);
+extern bool object_known_p(object_type const *o_ptr);
+extern void object_aware(object_type *o_ptr);
+extern bool object_aware_p(object_type const *o_ptr);
+extern void object_tried(object_type *o_ptr);
+extern bool object_tried_p(object_type const *o_ptr);
+extern s32b object_value(object_type const *o_ptr);
+extern s32b object_value_real(object_type const *o_ptr);
+extern bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr);
+extern void object_absorb(object_type *o_ptr, object_type *j_ptr);
+extern s16b lookup_kind(int tval, int sval);
+extern void object_wipe(object_type *o_ptr);
+extern void object_prep(object_type *o_ptr, int k_idx);
+extern void object_copy(object_type *o_ptr, object_type *j_ptr);
+extern void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power = boost::none);
+extern bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme);
+extern void place_object(int y, int x, bool_ good, bool_ great, int where);
+extern bool_ make_gold(object_type *j_ptr);
+extern void place_gold(int y, int x);
+extern s16b drop_near(object_type *o_ptr, int chance, int y, int x);
+extern void acquirement(int y1, int x1, int num, bool_ great, bool_ known);
+extern void pick_trap(int y, int x);
+extern void combine_pack(void);
+extern void reorder_pack(void);
+extern void random_artifact_resistance (object_type * o_ptr);
+extern s16b floor_carry(int y, int x, object_type *j_ptr);
+extern void pack_decay(int item);
+extern void floor_decay(int item);
+extern s16b m_bonus(int max, int level);
+extern s32b flag_cost(object_type const *o_ptr, int plusses);
diff --git a/src/object_filter.cc b/src/object_filter.cc
new file mode 100644
index 00000000..39961146
--- /dev/null
+++ b/src/object_filter.cc
@@ -0,0 +1,98 @@
+#include "object_filter.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+
+namespace object_filter {
+
+object_filter_t TVal(byte tval) {
+ return [=](object_type const *o_ptr) -> bool {
+ return o_ptr->tval == tval;
+ };
+}
+
+object_filter_t SVal(byte sval) {
+ return [=](object_type const *o_ptr) -> bool {
+ return o_ptr->sval == sval;
+ };
+}
+
+object_filter_t HasFlag3(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f3 & mask);
+ };
+}
+
+object_filter_t HasFlag4(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f4 & mask);
+ };
+}
+
+object_filter_t HasFlag5(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f5 & mask);
+ };
+}
+
+object_filter_t IsArtifact() {
+ return [](object_type const *o_ptr) -> bool {
+ return o_ptr->name1 > 0;
+ };
+}
+
+object_filter_t IsArtifactP() {
+ return [](object_type const *o_ptr) -> bool {
+ return artifact_p(o_ptr);
+ };
+}
+
+object_filter_t IsEgo() {
+ return [](object_type const *o_ptr) -> bool {
+ return ego_item_p(o_ptr);
+ };
+}
+
+object_filter_t IsKnown() {
+ return [](object_type const *o_ptr) -> bool {
+ return object_known_p(o_ptr);
+ };
+}
+
+object_filter_t True() {
+ return [](object_type const *o_ptr) -> bool {
+ return true;
+ };
+}
+
+object_filter_t Not(object_filter_t p) {
+ return [=](object_type const *o_ptr) -> bool {
+ return !p(o_ptr);
+ };
+}
+
+object_filter_t And() {
+ return [](object_type const *) -> bool {
+ return true;
+ };
+}
+
+object_filter_t Or() {
+ return [](object_type const *) -> bool {
+ return false;
+ };
+}
+
+}
diff --git a/src/object_filter.hpp b/src/object_filter.hpp
new file mode 100644
index 00000000..9a22090b
--- /dev/null
+++ b/src/object_filter.hpp
@@ -0,0 +1,99 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+
+#include <functional>
+#include <initializer_list>
+
+typedef std::function<bool (object_type const *)> object_filter_t;
+
+namespace object_filter {
+
+/**
+ * Is TVal equal to the given value?
+ */
+object_filter_t TVal(byte tval);
+
+/**
+ * Is SVal equal to the given value?
+ */
+object_filter_t SVal(byte sval);
+
+/**
+ * Has given bit mask in flag3 value.
+ */
+object_filter_t HasFlag3(u32b mask);
+
+/**
+ * Has given bit mask in flag4 value.
+ */
+object_filter_t HasFlag4(u32b mask);
+
+/**
+ * Has given bit mask in flag5 value.
+ */
+object_filter_t HasFlag5(u32b mask);
+
+/**
+ * Is the object an artifact?
+ */
+object_filter_t IsArtifact();
+
+/**
+ * Is the object an artifact as determined by artifact_p?
+ */
+object_filter_t IsArtifactP();
+
+/**
+ * Is the object an ego item?
+ */
+object_filter_t IsEgo();
+
+/**
+ * Is the object "known"?
+ */
+object_filter_t IsKnown();
+
+/**
+ * True always accepts all items.
+ */
+object_filter_t True();
+
+/**
+ * Invert an object filter.
+ */
+object_filter_t Not(object_filter_t p);
+
+/**
+ * Logical conjunction (AND)
+ */
+object_filter_t And();
+
+/**
+ * Logical conjunction (AND)
+ */
+template<typename Arg0, typename... Args> object_filter_t And(Arg0&& arg0, Args&&... args) {
+ auto argsFilter = And(args...);
+ return [=](object_type const *o_ptr) -> bool {
+ return arg0(o_ptr) && argsFilter(o_ptr);
+ };
+}
+
+/**
+ * Logical disjunction (OR)
+ */
+object_filter_t Or();
+
+/**
+ * Logical disjunction (OR)
+ */
+template<typename Arg0, typename... Args> object_filter_t Or(Arg0&& arg0, Args&&... args) {
+ auto argsFilter = Or(args...);
+ return [=](object_type const *o_ptr) -> bool {
+ auto x = arg0(o_ptr) || argsFilter(o_ptr);
+ return x;
+ };
+}
+
+}
diff --git a/src/object_kind.hpp b/src/object_kind.hpp
new file mode 100644
index 00000000..40a77589
--- /dev/null
+++ b/src/object_kind.hpp
@@ -0,0 +1,86 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Size of allocation table for objects
+ */
+constexpr int ALLOCATION_MAX = 8;
+
+/**
+ * Object "kind" descriptor. Includes player knowledge.
+ *
+ * Only "aware" and "tried" are saved in the savefile
+ */
+struct object_kind
+{
+ const char *name; /* Name */
+ char *text; /* Text */
+
+ byte tval; /* Object type */
+ byte sval; /* Object sub type */
+
+ s32b pval; /* Object extra info */
+ s32b pval2; /* Object extra info */
+
+ s16b to_h; /* Bonus to hit */
+ s16b to_d; /* Bonus to damage */
+ s16b to_a; /* Bonus to armor */
+
+ s16b activate; /* Activation number */
+
+ s16b ac; /* Base armor */
+
+ byte dd, ds; /* Damage dice/sides */
+
+ s32b weight; /* Weight */
+
+ s32b cost; /* Object "base cost" */
+
+ u32b flags1; /* Flags, set 1 */
+ u32b flags2; /* Flags, set 2 */
+ u32b flags3; /* Flags, set 3 */
+ u32b flags4; /* Flags, set 4 */
+ u32b flags5; /* Flags, set 5 */
+
+ u32b oflags1; /* Obvious Flags, set 1 */
+ u32b oflags2; /* Obvious Flags, set 2 */
+ u32b oflags3; /* Obvious Flags, set 3 */
+ u32b oflags4; /* Obvious Flags, set 4 */
+ u32b oflags5; /* Obvious Flags, set 5 */
+
+ byte locale[ALLOCATION_MAX]; /* Allocation level(s) */
+ byte chance[ALLOCATION_MAX]; /* Allocation chance(s) */
+
+ byte level; /* Level */
+ byte extra; /* Something */
+
+
+ byte d_attr; /* Default object attribute */
+ char d_char; /* Default object character */
+
+
+ byte x_attr; /* Desired object attribute */
+ char x_char; /* Desired object character */
+
+
+ byte flavor; /* Special object flavor (or zero) */
+
+ bool_ easy_know; /* This object is always known (if aware) */
+
+
+ bool_ aware; /* The player is "aware" of the item's effects */
+
+ bool_ tried; /* The player has "tried" one of the items */
+
+ bool_ know; /* extractable flag for the alchemist */
+
+ u32b esp; /* ESP flags */
+ u32b oesp; /* Obvious ESP flags */
+
+ byte btval; /* Become Object type */
+ byte bsval; /* Become Object sub type */
+ bool_ artifact; /* Is it a normal artifact(already generated) */
+
+ s16b power; /* Power granted(if any) */
+};
diff --git a/src/object_kind_fwd.hpp b/src/object_kind_fwd.hpp
new file mode 100644
index 00000000..6d26db9f
--- /dev/null
+++ b/src/object_kind_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct object_kind;
diff --git a/src/object_type.hpp b/src/object_type.hpp
new file mode 100644
index 00000000..d7f003e6
--- /dev/null
+++ b/src/object_type.hpp
@@ -0,0 +1,104 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Object information for a specific object.
+ *
+ * Note that a "discount" on an item is permanent and never goes away.
+ *
+ * Note that inscriptions are now handled via the "quark_str()" function
+ * applied to the "note" field, which will return NULL if "note" is zero.
+ *
+ * Note that "object" records are "copied" on a fairly regular basis,
+ * and care must be taken when handling such objects.
+ *
+ * Note that "object flags" must now be derived from the object kind,
+ * the artifact and ego-item indexes, and the two "xtra" fields.
+ *
+ * Each cave grid points to one (or zero) objects via the "o_idx"
+ * field (above). Each object then points to one (or zero) objects
+ * via the "next_o_idx" field, forming a singly linked list, which
+ * in game terms, represents a "stack" of objects in the same grid.
+ *
+ * Each monster points to one (or zero) objects via the "hold_o_idx"
+ * field (below). Each object then points to one (or zero) objects
+ * via the "next_o_idx" field, forming a singly linked list, which
+ * in game terms, represents a pile of objects held by the monster.
+ *
+ * The "held_m_idx" field is used to indicate which monster, if any,
+ * is holding the object. Objects being held have "ix=0" and "iy=0".
+ */
+struct object_type
+{
+ s16b k_idx; /* Kind index (zero if "dead") */
+
+ byte iy; /* Y-position on map, or zero */
+ byte ix; /* X-position on map, or zero */
+
+ byte tval; /* Item type (from kind) */
+ byte sval; /* Item sub-type (from kind) */
+
+ s32b pval; /* Item extra-parameter */
+ s16b pval2; /* Item extra-parameter for some special
+ items*/
+ s32b pval3; /* Item extra-parameter for some special
+ items*/
+
+ byte discount; /* Discount (if any) */
+
+ byte number; /* Number of items */
+
+ s32b weight; /* Item weight */
+
+ byte elevel; /* Item exp level */
+ s32b exp; /* Item exp */
+
+ byte name1; /* Artifact type, if any */
+ s16b name2; /* Ego-Item type, if any */
+ s16b name2b; /* Second Ego-Item type, if any */
+
+ byte xtra1; /* Extra info type */
+ s16b xtra2; /* Extra info index */
+
+ s16b to_h; /* Plusses to hit */
+ s16b to_d; /* Plusses to damage */
+ s16b to_a; /* Plusses to AC */
+
+ s16b ac; /* Normal AC */
+
+ byte dd, ds; /* Damage dice/sides */
+
+ s16b timeout; /* Timeout Counter */
+
+ byte ident; /* Special flags */
+
+ byte marked; /* Object is marked */
+
+ u16b note; /* Inscription index */
+ u16b art_name; /* Artifact name (random artifacts) */
+
+ u32b art_flags1; /* Flags, set 1 Alas, these were necessary */
+ u32b art_flags2; /* Flags, set 2 for the random artifacts of*/
+ u32b art_flags3; /* Flags, set 3 Zangband */
+ u32b art_flags4; /* Flags, set 4 PernAngband */
+ u32b art_flags5; /* Flags, set 5 PernAngband */
+ u32b art_esp; /* Flags, set esp PernAngband */
+
+ u32b art_oflags1; /* Obvious Flags, set 1 */
+ u32b art_oflags2; /* Obvious Flags, set 2 */
+ u32b art_oflags3; /* Obvious Flags, set 3 */
+ u32b art_oflags4; /* Obvious Flags, set 4 */
+ u32b art_oflags5; /* Obvious Flags, set 5 */
+ u32b art_oesp; /* Obvious Flags, set esp */
+
+ s16b held_m_idx; /* Monster holding us (if any) */
+
+ byte sense; /* Pseudo-id status */
+
+ byte found; /* How did we find it */
+ s16b found_aux1; /* Stores info for found */
+ s16b found_aux2; /* Stores info for found */
+ s16b found_aux3; /* Stores info for found */
+ s16b found_aux4; /* Stores info for found */
+};
diff --git a/src/object_type_fwd.hpp b/src/object_type_fwd.hpp
new file mode 100644
index 00000000..d99e60a6
--- /dev/null
+++ b/src/object_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct object_type;
diff --git a/src/option_type.hpp b/src/option_type.hpp
new file mode 100644
index 00000000..58834b79
--- /dev/null
+++ b/src/option_type.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Option descriptor.
+ */
+struct option_type
+{
+ /**
+ * Address of actual option variable. NULL signals the
+ * end of the table.
+ */
+ bool_ *o_var;
+
+ /**
+ * Default value.
+ */
+ byte o_norm;
+
+ /**
+ * Option page number.
+ */
+ byte o_page;
+
+ /**
+ * Savefile bit in the page-specific list of options.
+ */
+ byte o_bit;
+
+ /**
+ * Textual name.
+ */
+ cptr o_text;
+
+ /**
+ * Textual description
+ */
+ cptr o_desc;
+};
diff --git a/src/options.cc b/src/options.cc
new file mode 100644
index 00000000..5501ab52
--- /dev/null
+++ b/src/options.cc
@@ -0,0 +1,89 @@
+#include "options.hpp"
+
+//
+// Option Set 1 -- User Interface
+//
+bool_ rogue_like_commands; /* Rogue-like commands */
+bool_ quick_messages; /* Activate quick messages */
+bool_ carry_query_flag; /* Prompt before picking things up */
+bool_ use_old_target; /* Use old target by default */
+bool_ always_pickup; /* Pick things up by default */
+bool_ always_repeat; /* Repeat obvious commands */
+bool_ ring_bell; /* Ring the bell (on errors, etc) */
+
+//
+// Option Set 2 -- Disturbance
+//
+bool_ find_ignore_stairs; /* Run past stairs */
+bool_ find_ignore_doors; /* Run through open doors */
+bool_ find_cut; /* Run past known corners */
+bool_ find_examine; /* Run into potential corners */
+bool_ disturb_move; /* Disturb whenever any monster moves */
+bool_ disturb_near; /* Disturb whenever viewable monster moves */
+bool_ disturb_panel; /* Disturb whenever map panel changes */
+bool_ disturb_detect; /* Disturb whenever leaving trap-detected area */
+bool_ disturb_state; /* Disturn whenever player state changes */
+bool_ disturb_minor; /* Disturb whenever boring things happen */
+bool_ disturb_other; /* Disturb whenever various things happen */
+bool_ alert_hitpoint; /* Alert user to critical hitpoints */
+bool_ alert_failure; /* Alert user to various failures */
+bool_ last_words; /* Get last words upon dying */
+bool_ small_levels; /* Allow unusually small dungeon levels */
+bool_ empty_levels; /* Allow empty 'arena' levels */
+bool_ confirm_stairs; /* Prompt before staircases... */
+bool_ wear_confirm; /* Confirm before putting on known cursed items */
+bool_ disturb_pets; /* Pets moving nearby disturb us */
+
+//
+// Option Set 3 -- Game-Play
+//
+bool_ auto_scum; /* Auto-scum for good levels */
+bool_ view_perma_grids; /* Map remembers all perma-lit grids */
+bool_ view_torch_grids; /* Map remembers all torch-lit grids */
+bool_ dungeon_align; /* Generate dungeons with aligned rooms */
+bool_ dungeon_stair; /* Generate dungeons with connected stairs */
+bool_ flow_by_sound; /* Monsters track new player location */
+bool_ smart_learn; /* Monsters learn from their mistakes */
+
+//
+// Option Set 4 -- Efficiency
+//
+bool_ view_reduce_lite; /* Reduce lite-radius when running */
+bool_ avoid_abort; /* Avoid checking for user abort */
+bool_ avoid_shimmer; /* Avoid processing extra shimmering */
+bool_ avoid_other; /* Avoid processing special colors */
+bool_ flush_failure; /* Flush input on any failure */
+bool_ flush_disturb; /* Flush input on disturbance */
+bool_ flush_command; /* Flush input before every command */
+bool_ fresh_before; /* Flush output before normal commands */
+bool_ fresh_after; /* Flush output after normal commands */
+bool_ fresh_message; /* Flush output after all messages */
+bool_ hilite_player; /* Hilite the player with the cursor */
+bool_ view_yellow_lite; /* Use special colors for torch-lit grids */
+bool_ view_bright_lite; /* Use special colors for 'viewable' grids */
+bool_ view_granite_lite; /* Use special colors for wall grids (slow) */
+bool_ view_special_lite; /* Use special colors for floor grids (slow) */
+bool_ center_player; /* Center view on player */
+
+//
+// Option Set 5 - ToME options
+//
+bool_ linear_stats;
+bool_ player_char_health; /* Display the player as a special symbol when in bad health ? */
+bool_ option_ingame_help; /* Ingame contextual help */
+bool_ auto_more; /* Auto more */
+bool_ inventory_no_move; /* In inventory option window, just erase the letters,
+ * rather that displaying the list without the invalid
+ * selections */
+
+//
+// Option Set 6 - Birth options
+//
+bool_ always_small_level;
+bool_ autoroll;
+bool_ fate_option;
+bool_ ironman_rooms;
+bool_ joke_monsters;
+bool_ point_based;
+bool_ preserve;
+bool_ no_selling;
diff --git a/src/options.hpp b/src/options.hpp
new file mode 100644
index 00000000..45e19cf7
--- /dev/null
+++ b/src/options.hpp
@@ -0,0 +1,89 @@
+#pragma once
+
+#include "h-basic.h"
+
+//
+// Option Set 1 -- User Interface.
+//
+extern bool_ rogue_like_commands;
+extern bool_ quick_messages;
+extern bool_ carry_query_flag;
+extern bool_ use_old_target;
+extern bool_ always_pickup;
+extern bool_ always_repeat;
+extern bool_ ring_bell;
+
+//
+// Option Set 2 -- Disturbance
+//
+extern bool_ find_ignore_stairs;
+extern bool_ find_ignore_doors;
+extern bool_ find_cut;
+extern bool_ find_examine;
+extern bool_ disturb_move;
+extern bool_ disturb_near;
+extern bool_ disturb_panel;
+extern bool_ disturb_detect;
+extern bool_ disturb_state;
+extern bool_ disturb_minor;
+extern bool_ disturb_other;
+extern bool_ alert_hitpoint;
+extern bool_ alert_failure;
+extern bool_ last_words;
+extern bool_ small_levels;
+extern bool_ empty_levels;
+extern bool_ confirm_stairs;
+extern bool_ wear_confirm;
+extern bool_ disturb_pets;
+
+//
+// Option Set 3 -- Game-Play
+//
+extern bool_ auto_scum;
+extern bool_ view_perma_grids;
+extern bool_ view_torch_grids;
+extern bool_ dungeon_align;
+extern bool_ dungeon_stair;
+extern bool_ flow_by_sound;
+extern bool_ smart_learn;
+
+//
+// Option Set 4 -- Efficiency
+//
+extern bool_ view_reduce_lite;
+extern bool_ avoid_abort;
+extern bool_ avoid_shimmer;
+extern bool_ avoid_other;
+extern bool_ flush_failure;
+extern bool_ flush_disturb;
+extern bool_ flush_command;
+extern bool_ fresh_before;
+extern bool_ fresh_after;
+extern bool_ fresh_message;
+extern bool_ hilite_player;
+extern bool_ view_yellow_lite;
+extern bool_ view_bright_lite;
+extern bool_ view_granite_lite;
+extern bool_ view_special_lite;
+extern bool_ center_player;
+
+//
+// Option Set 5 - ToME options
+//
+extern bool_ linear_stats;
+extern bool_ player_char_health;
+extern bool_ option_ingame_help;
+extern bool_ auto_more;
+extern bool_ inventory_no_move;
+
+//
+// Option Set 6 - Birth options
+//
+extern bool_ always_small_level;
+extern bool_ autoroll;
+extern bool_ fate_option;
+extern bool_ ironman_rooms;
+extern bool_ joke_monsters;
+extern bool_ point_based;
+extern bool_ preserve;
+extern bool_ no_selling;
diff --git a/src/owner_type.hpp b/src/owner_type.hpp
new file mode 100644
index 00000000..703d3159
--- /dev/null
+++ b/src/owner_type.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "h-basic.h"
+
+/*
+ * Store owner descriptor.
+ */
+struct owner_type
+{
+ /**
+ * Name
+ */
+ const char *name;
+
+ /**
+ * Purse limit
+ */
+ s16b max_cost;
+
+ /**
+ * Inflation
+ */
+ s16b inflation;
+
+ /**
+ * Liked/hated races.
+ */
+ u32b races[2][2];
+
+ /**
+ * Liked/hated classes
+ */
+ u32b classes[2][2];
+
+ /**
+ * Costs for liked people
+ */
+ s16b costs[3];
+};
diff --git a/src/owner_type_fwd.hpp b/src/owner_type_fwd.hpp
new file mode 100644
index 00000000..20c25802
--- /dev/null
+++ b/src/owner_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct owner_type;
diff --git a/src/player_class.hpp b/src/player_class.hpp
new file mode 100644
index 00000000..d67d1d73
--- /dev/null
+++ b/src/player_class.hpp
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "body.hpp"
+#include "h-basic.h"
+#include "player_defs.hpp"
+#include "player_spec.hpp"
+
+/**
+ * Maximum number of specialties.
+ */
+constexpr int MAX_SPEC = 20;
+
+/**
+ * Player descriptor and runtime data.
+ */
+struct player_class
+{
+ const char *title; /* Type of class */
+ char *desc; /* Small desc of the class */
+ const char *titles[PY_MAX_LEVEL / 5];
+ /* Titles */
+
+ s16b c_adj[6]; /* Class stat modifier */
+
+ s16b c_dis; /* class disarming */
+ s16b c_dev; /* class magic devices */
+ s16b c_sav; /* class saving throws */
+ s16b c_stl; /* class stealth */
+ s16b c_srh; /* class searching ability */
+ s16b c_fos; /* class searching frequency */
+ s16b c_thn; /* class to hit (normal) */
+ s16b c_thb; /* class to hit (bows) */
+
+ s16b x_dis; /* extra disarming */
+ s16b x_dev; /* extra magic devices */
+ s16b x_sav; /* extra saving throws */
+ s16b x_stl; /* extra stealth */
+ s16b x_srh; /* extra searching ability */
+ s16b x_fos; /* extra searching frequency */
+ s16b x_thn; /* extra to hit (normal) */
+ s16b x_thb; /* extra to hit (bows) */
+
+ s16b c_mhp; /* Class hit-dice adjustment */
+ s16b c_exp; /* Class experience factor */
+
+ s16b powers[4]; /* Powers of the class */
+
+ s16b spell_book; /* Tval of spell books (if any) */
+ s16b spell_stat; /* Stat for spells (if any) */
+ s16b spell_lev; /* The higher it is the higher the spells level are */
+ s16b spell_fail; /* The higher it is the higher the spells failure are */
+ s16b spell_mana; /* The higher it is the higher the spells mana are */
+ s16b spell_first; /* Level of first spell */
+ s16b spell_weight; /* Weight that hurts spells */
+ byte max_spell_level; /* Maximun spell level */
+ byte magic_max_spell; /* Maximun numbner of spells one can learn by natural means */
+
+ u32b flags1; /* flags */
+ u32b flags2; /* flags */
+
+ s16b mana;
+ s16b blow_num;
+ s16b blow_wgt;
+ s16b blow_mul;
+ s16b extra_blows;
+
+ s32b sense_base;
+ s32b sense_pl;
+ s32b sense_plus;
+ byte sense_heavy;
+ byte sense_heavy_magic;
+
+ s16b obj_tval[5];
+ s16b obj_sval[5];
+ s16b obj_pval[5];
+ s16b obj_dd[5];
+ s16b obj_ds[5];
+ s16b obj_num;
+
+ char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
+
+ u32b oflags1[PY_MAX_LEVEL + 1];
+ u32b oflags2[PY_MAX_LEVEL + 1];
+ u32b oflags3[PY_MAX_LEVEL + 1];
+ u32b oflags4[PY_MAX_LEVEL + 1];
+ u32b oflags5[PY_MAX_LEVEL + 1];
+ u32b oesp[PY_MAX_LEVEL + 1];
+ s16b opval[PY_MAX_LEVEL + 1];
+
+ char skill_basem[MAX_SKILLS];
+ u32b skill_base[MAX_SKILLS];
+ char skill_modm[MAX_SKILLS];
+ s16b skill_mod[MAX_SKILLS];
+
+ u32b gods;
+
+ player_spec spec[MAX_SPEC];
+
+ struct
+ {
+ s16b ability;
+ s16b level;
+ } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
+};
+
diff --git a/src/player_class_fwd.hpp b/src/player_class_fwd.hpp
new file mode 100644
index 00000000..2402934d
--- /dev/null
+++ b/src/player_class_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_class;
diff --git a/src/player_defs.hpp b/src/player_defs.hpp
new file mode 100644
index 00000000..2f57409c
--- /dev/null
+++ b/src/player_defs.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+/**
+ * Maximum player level
+ */
+#define PY_MAX_LEVEL 50
diff --git a/src/player_race.hpp b/src/player_race.hpp
new file mode 100644
index 00000000..edb304f2
--- /dev/null
+++ b/src/player_race.hpp
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "h-basic.h"
+#include "body.hpp"
+#include "player_defs.hpp"
+#include "skills_defs.hpp"
+
+/**
+ * Player racial descriptior.
+ */
+struct player_race
+{
+ const char *title; /* Type of race */
+ char *desc;
+
+ s16b r_adj[6]; /* Racial stat bonuses */
+
+ char luck; /* Luck */
+
+ s16b r_dis; /* disarming */
+ s16b r_dev; /* magic devices */
+ s16b r_sav; /* saving throw */
+ s16b r_stl; /* stealth */
+ s16b r_srh; /* search ability */
+ s16b r_fos; /* search frequency */
+ s16b r_thn; /* combat (normal) */
+ s16b r_thb; /* combat (shooting) */
+
+ byte r_mhp; /* Race hit-dice modifier */
+ u16b r_exp; /* Race experience factor */
+
+ byte b_age; /* base age */
+ byte m_age; /* mod age */
+
+ byte m_b_ht; /* base height (males) */
+ byte m_m_ht; /* mod height (males) */
+ byte m_b_wt; /* base weight (males) */
+ byte m_m_wt; /* mod weight (males) */
+
+ byte f_b_ht; /* base height (females) */
+ byte f_m_ht; /* mod height (females) */
+ byte f_b_wt; /* base weight (females) */
+ byte f_m_wt; /* mod weight (females) */
+
+ byte infra; /* Infra-vision range */
+
+ u32b choice[2]; /* Legal class choices */
+
+ s16b powers[4]; /* Powers of the race */
+
+ byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
+
+ s16b chart; /* Chart history */
+
+ u32b flags1;
+ u32b flags2; /* flags */
+
+ u32b oflags1[PY_MAX_LEVEL + 1];
+ u32b oflags2[PY_MAX_LEVEL + 1];
+ u32b oflags3[PY_MAX_LEVEL + 1];
+ u32b oflags4[PY_MAX_LEVEL + 1];
+ u32b oflags5[PY_MAX_LEVEL + 1];
+ u32b oesp[PY_MAX_LEVEL + 1];
+ s16b opval[PY_MAX_LEVEL + 1];
+
+ char skill_basem[MAX_SKILLS];
+ u32b skill_base[MAX_SKILLS];
+ char skill_modm[MAX_SKILLS];
+ s16b skill_mod[MAX_SKILLS];
+
+ s16b obj_tval[5];
+ s16b obj_sval[5];
+ s16b obj_pval[5];
+ s16b obj_dd[5];
+ s16b obj_ds[5];
+ s16b obj_num;
+
+ struct
+ {
+ s16b ability;
+ s16b level;
+ } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
+};
diff --git a/src/player_race_fwd.hpp b/src/player_race_fwd.hpp
new file mode 100644
index 00000000..c3c3350b
--- /dev/null
+++ b/src/player_race_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_race;
diff --git a/src/player_race_mod.hpp b/src/player_race_mod.hpp
new file mode 100644
index 00000000..72f975ce
--- /dev/null
+++ b/src/player_race_mod.hpp
@@ -0,0 +1,87 @@
+#pragma once
+
+#include "body.hpp"
+#include "h-basic.h"
+#include "skills_defs.hpp"
+
+struct player_race_mod
+{
+ char *title; /* Type of race mod */
+ char *desc; /* Desc */
+
+ bool_ place; /* TRUE = race race modifier, FALSE = Race modifier race */
+
+ s16b r_adj[6]; /* (+) Racial stat bonuses */
+
+ char luck; /* Luck */
+ s16b mana; /* Mana % */
+
+ s16b r_dis; /* (+) disarming */
+ s16b r_dev; /* (+) magic devices */
+ s16b r_sav; /* (+) saving throw */
+ s16b r_stl; /* (+) stealth */
+ s16b r_srh; /* (+) search ability */
+ s16b r_fos; /* (+) search frequency */
+ s16b r_thn; /* (+) combat (normal) */
+ s16b r_thb; /* (+) combat (shooting) */
+
+ char r_mhp; /* (+) Race mod hit-dice modifier */
+ s16b r_exp; /* (+) Race mod experience factor */
+
+ char b_age; /* (+) base age */
+ char m_age; /* (+) mod age */
+
+ char m_b_ht; /* (+) base height (males) */
+ char m_m_ht; /* (+) mod height (males) */
+ char m_b_wt; /* (+) base weight (males) */
+ char m_m_wt; /* (+) mod weight (males) */
+
+ char f_b_ht; /* (+) base height (females) */
+ char f_m_ht; /* (+) mod height (females) */
+ char f_b_wt; /* (+) base weight (females) */
+ char f_m_wt; /* (+) mod weight (females) */
+
+ char infra; /* (+) Infra-vision range */
+
+ u32b choice[2]; /* Legal race choices */
+
+ u32b pclass[2]; /* Classes allowed */
+ u32b mclass[2]; /* Classes restricted */
+
+ s16b powers[4]; /* Powers of the subrace */
+
+ char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
+
+ u32b flags1;
+ u32b flags2; /* flags */
+
+ u32b oflags1[PY_MAX_LEVEL + 1];
+ u32b oflags2[PY_MAX_LEVEL + 1];
+ u32b oflags3[PY_MAX_LEVEL + 1];
+ u32b oflags4[PY_MAX_LEVEL + 1];
+ u32b oflags5[PY_MAX_LEVEL + 1];
+ u32b oesp[PY_MAX_LEVEL + 1];
+ s16b opval[PY_MAX_LEVEL + 1];
+
+ byte g_attr; /* Overlay graphic attribute */
+ char g_char; /* Overlay graphic character */
+
+ char skill_basem[MAX_SKILLS];
+ u32b skill_base[MAX_SKILLS];
+ char skill_modm[MAX_SKILLS];
+ s16b skill_mod[MAX_SKILLS];
+
+ s16b obj_tval[5];
+ s16b obj_sval[5];
+ s16b obj_pval[5];
+ s16b obj_dd[5];
+ s16b obj_ds[5];
+ s16b obj_num;
+
+ struct
+ {
+ s16b ability;
+ s16b level;
+ } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
+};
+
diff --git a/src/player_race_mod_fwd.hpp b/src/player_race_mod_fwd.hpp
new file mode 100644
index 00000000..12eb468a
--- /dev/null
+++ b/src/player_race_mod_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_race_mod;
diff --git a/src/player_sex.hpp b/src/player_sex.hpp
new file mode 100644
index 00000000..5722f1a4
--- /dev/null
+++ b/src/player_sex.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+/**
+ * Player sex descriptor.
+ */
+struct player_sex
+{
+ /**
+ * Type of sex.
+ */
+ char const *title;
+
+ /**
+ * Winner title.
+ */
+ char const *winner;
+};
diff --git a/src/player_sex_fwd.hpp b/src/player_sex_fwd.hpp
new file mode 100644
index 00000000..eabea488
--- /dev/null
+++ b/src/player_sex_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_sex;
diff --git a/src/player_spec.hpp b/src/player_spec.hpp
new file mode 100644
index 00000000..28b32830
--- /dev/null
+++ b/src/player_spec.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "h-basic.h"
+#include "skills_defs.hpp"
+
+/**
+ * Player class descriptor.
+ */
+struct player_spec
+{
+ const char *title; /* Type of class spec */
+ char *desc; /* Small desc of the class spec */
+
+ char skill_basem[MAX_SKILLS]; /* Mod for value */
+ u32b skill_base[MAX_SKILLS]; /* value */
+ char skill_modm[MAX_SKILLS]; /* mod for mod */
+ s16b skill_mod[MAX_SKILLS]; /* mod */
+
+ u32b skill_ideal[MAX_SKILLS]; /* Ideal skill levels at level 50 */
+
+ s16b obj_tval[5];
+ s16b obj_sval[5];
+ s16b obj_pval[5];
+ s16b obj_dd[5];
+ s16b obj_ds[5];
+ s16b obj_num;
+
+ u32b gods;
+
+ u32b flags1;
+ u32b flags2; /* flags */
+
+ struct
+ {
+ s16b ability;
+ s16b level;
+ } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
+};
diff --git a/src/player_spec_fwd.hpp b/src/player_spec_fwd.hpp
new file mode 100644
index 00000000..9083acd0
--- /dev/null
+++ b/src/player_spec_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_spec;
diff --git a/src/player_type.hpp b/src/player_type.hpp
new file mode 100644
index 00000000..d9410dcb
--- /dev/null
+++ b/src/player_type.hpp
@@ -0,0 +1,423 @@
+#pragma once
+
+#include "corrupt.hpp"
+#include "h-basic.h"
+#include "help_info.hpp"
+#include "inventory.hpp"
+#include "object_type.hpp"
+#include "powers.hpp"
+
+/*
+ * Most of the "player" information goes here.
+ *
+ * This stucture gives us a large collection of player variables.
+ *
+ * This structure contains several "blocks" of information.
+ * (1) the "permanent" info
+ * (2) the "variable" info
+ * (3) the "transient" info
+ *
+ * All of the "permanent" info, and most of the "variable" info,
+ * is saved in the savefile. The "transient" info is recomputed
+ * whenever anything important changes.
+ */
+
+struct player_type
+{
+ s32b lives; /* How many times we resurected */
+
+ s16b oldpy; /* Previous player location -KMW- */
+ s16b oldpx; /* Previous player location -KMW- */
+
+ s16b py; /* Player location */
+ s16b px; /* Player location */
+
+ byte psex; /* Sex index */
+ byte prace; /* Race index */
+ byte pracem; /* Race Mod index */
+ byte pclass; /* Class index */
+ byte pspec; /* Class spec index */
+ byte mimic_form; /* Actualy transformation */
+ s16b mimic_level; /* Level of the mimic effect */
+ byte oops; /* Unused */
+
+ object_type inventory[INVEN_TOTAL]; /* Player inventory */
+
+ byte hitdie; /* Hit dice (sides) */
+ u16b expfact; /* Experience factor */
+
+ byte preserve; /* Preserve artifacts */
+ byte special; /* Special levels */
+ byte allow_one_death; /* Blood of life */
+
+ s16b age; /* Characters age */
+ s16b ht; /* Height */
+ s16b wt; /* Weight */
+ s16b sc; /* Social Class */
+
+
+ s32b au; /* Current Gold */
+
+ s32b max_exp; /* Max experience */
+ s32b exp; /* Cur experience */
+ u16b exp_frac; /* Cur exp frac (times 2^16) */
+
+ s16b lev; /* Level */
+
+ s16b town_num; /* Current town number */
+ s16b inside_quest; /* Inside quest level */
+
+ s32b wilderness_x; /* Coordinates in the wilderness */
+ s32b wilderness_y;
+ bool_ wild_mode; /* TRUE = Small map, FLASE = Big map */
+ bool_ old_wild_mode; /* TRUE = Small map, FLASE = Big map */
+
+ s16b mhp; /* Max hit pts */
+ s16b chp; /* Cur hit pts */
+ u16b chp_frac; /* Cur hit frac (times 2^16) */
+ s16b hp_mod; /* A modificator(permanent) */
+
+ s16b msp; /* Max mana pts */
+ s16b csp; /* Cur mana pts */
+ u16b csp_frac; /* Cur mana frac (times 2^16) */
+
+ s16b msane; /* Max sanity */
+ s16b csane; /* Cur sanity */
+ u16b csane_frac; /* Cur sanity frac */
+
+ s32b grace; /* Your God's appreciation factor. */
+ s32b grace_delay; /* Delay factor for granting piety. */
+ byte pgod; /* Your God. */
+ bool_ praying; /* Praying to your god. */
+ s16b melkor_sacrifice; /* How much hp has been sacrified for damage */
+
+ s16b max_plv; /* Max Player Level */
+
+ s16b stat_max[6]; /* Current "maximal" stat values */
+ s16b stat_cur[6]; /* Current "natural" stat values */
+
+ s16b luck_cur; /* Current "natural" luck value (range -30 <> 30) */
+ s16b luck_max; /* Current "maximal base" luck value (range -30 <> 30) */
+ s16b luck_base; /* Current "base" luck value (range -30 <> 30) */
+
+ s16b speed_factor; /* Timed -- Fast */
+ s16b fast; /* Timed -- Fast */
+ s16b lightspeed; /* Timed -- Light Speed */
+ s16b slow; /* Timed -- Slow */
+ s16b blind; /* Timed -- Blindness */
+ s16b paralyzed; /* Timed -- Paralysis */
+ s16b confused; /* Timed -- Confusion */
+ s16b afraid; /* Timed -- Fear */
+ s16b image; /* Timed -- Hallucination */
+ s16b poisoned; /* Timed -- Poisoned */
+ s16b cut; /* Timed -- Cut */
+ s16b stun; /* Timed -- Stun */
+
+ s16b protevil; /* Timed -- Protection from Evil*/
+ s16b protgood; /* Timed -- Protection from Good*/
+ s16b protundead; /* Timed -- Protection from Undead*/
+ s16b invuln; /* Timed -- Invulnerable */
+ s16b hero; /* Timed -- Heroism */
+ s16b shero; /* Timed -- Super Heroism */
+ s16b shield; /* Timed -- Shield Spell */
+ s16b shield_power; /* Timed -- Shield Spell Power */
+ s16b shield_opt; /* Timed -- Shield Spell options */
+ s16b shield_power_opt; /* Timed -- Shield Spell Power */
+ s16b shield_power_opt2; /* Timed -- Shield Spell Power */
+ s16b blessed; /* Timed -- Blessed */
+ s16b tim_invis; /* Timed -- See Invisible */
+ s16b tim_infra; /* Timed -- Infra Vision */
+
+ s16b oppose_acid; /* Timed -- oppose acid */
+ s16b oppose_elec; /* Timed -- oppose lightning */
+ s16b oppose_fire; /* Timed -- oppose heat */
+ s16b oppose_cold; /* Timed -- oppose cold */
+ s16b oppose_pois; /* Timed -- oppose poison */
+ s16b oppose_ld; /* Timed -- oppose light & dark */
+ s16b oppose_cc; /* Timed -- oppose chaos & confusion */
+ s16b oppose_ss; /* Timed -- oppose sound & shards */
+ s16b oppose_nex; /* Timed -- oppose nexus */
+
+ s16b tim_esp; /* Timed ESP */
+ s16b tim_wraith; /* Timed wraithform */
+ s16b tim_ffall; /* Timed Levitation */
+ s16b tim_fly; /* Timed Levitation */
+ s16b tim_poison; /* Timed poison hands */
+ s16b tim_thunder; /* Timed thunderstorm */
+ s16b tim_thunder_p1; /* Timed thunderstorm */
+ s16b tim_thunder_p2; /* Timed thunderstorm */
+
+ s16b tim_project; /* Timed project upon melee blow */
+ s16b tim_project_dam;
+ s16b tim_project_gf;
+ s16b tim_project_rad;
+ s16b tim_project_flag;
+
+ s16b tim_roots; /* Timed roots */
+ s16b tim_roots_ac;
+ s16b tim_roots_dam;
+
+ s16b tim_invisible; /* Timed Invisibility */
+ s16b tim_inv_pow; /* Power of timed invisibility */
+ s16b tim_mimic; /* Timed Mimic */
+ s16b tim_lite; /* Timed Lite */
+ s16b tim_regen; /* Timed extra regen */
+ s16b tim_regen_pow; /* Timed extra regen power */
+ s16b holy; /* Holy Aura */
+ s16b strike; /* True Strike(+25 hit) */
+ s16b tim_reflect; /* Timed Reflection */
+ s16b tim_deadly; /* Timed deadly blow */
+ s16b prob_travel; /* Timed probability travel */
+ s16b disrupt_shield;/* Timed disruption shield */
+ s16b parasite; /* Timed parasite */
+ s16b parasite_r_idx;/* Timed parasite monster */
+ s16b absorb_soul; /* Timed soul absordtion */
+ s16b tim_magic_breath; /* Magical breathing -- can breath anywhere */
+ s16b tim_water_breath; /* Water breathing -- can breath underwater */
+ s16b tim_precognition; /* Timed precognition */
+
+ s16b immov_cntr; /* Timed -- Last ``immovable'' command. */
+
+ s16b recall_dungeon; /* Recall in which dungeon */
+ s16b word_recall; /* Word of recall counter */
+
+ s32b energy; /* Current energy */
+
+ s16b food; /* Current nutrition */
+
+ byte confusing; /* Glowing hands */
+ byte searching; /* Currently searching */
+
+ bool_ old_cumber_armor;
+ bool_ old_cumber_glove;
+ bool_ old_heavy_wield;
+ bool_ old_heavy_shoot;
+ bool_ old_icky_wield;
+
+ s16b old_lite; /* Old radius of lite (if any) */
+ s16b old_view; /* Old radius of view (if any) */
+
+ s16b old_food_aux; /* Old value of food */
+
+
+ bool_ cumber_armor; /* Mana draining armor */
+ bool_ cumber_glove; /* Mana draining gloves */
+ bool_ heavy_wield; /* Heavy weapon */
+ bool_ heavy_shoot; /* Heavy shooter */
+ bool_ icky_wield; /* Icky weapon */
+ bool_ immovable; /* Immovable character */
+
+ s16b cur_lite; /* Radius of lite (if any) */
+
+
+ u32b notice; /* Special Updates (bit flags) */
+ u32b update; /* Pending Updates (bit flags) */
+ u32b redraw; /* Normal Redraws (bit flags) */
+ u32b window; /* Window Redraws (bit flags) */
+
+ s16b stat_use[6]; /* Current modified stats */
+ s16b stat_top[6]; /* Maximal modified stats */
+
+ s16b stat_add[6]; /* Modifiers to stat values */
+ s16b stat_ind[6]; /* Indexes into stat tables */
+ s16b stat_cnt[6]; /* Counter for temporary drains */
+ s16b stat_los[6]; /* Amount of temporary drains */
+
+ bool_ immune_acid; /* Immunity to acid */
+ bool_ immune_elec; /* Immunity to lightning */
+ bool_ immune_fire; /* Immunity to fire */
+ bool_ immune_cold; /* Immunity to cold */
+ bool_ immune_neth; /* Immunity to nether */
+
+ bool_ resist_acid; /* Resist acid */
+ bool_ resist_elec; /* Resist lightning */
+ bool_ resist_fire; /* Resist fire */
+ bool_ resist_cold; /* Resist cold */
+ bool_ resist_pois; /* Resist poison */
+
+ bool_ resist_conf; /* Resist confusion */
+ bool_ resist_sound; /* Resist sound */
+ bool_ resist_lite; /* Resist light */
+ bool_ resist_dark; /* Resist darkness */
+ bool_ resist_chaos; /* Resist chaos */
+ bool_ resist_disen; /* Resist disenchant */
+ bool_ resist_shard; /* Resist shards */
+ bool_ resist_nexus; /* Resist nexus */
+ bool_ resist_blind; /* Resist blindness */
+ bool_ resist_neth; /* Resist nether */
+ bool_ resist_fear; /* Resist fear */
+ bool_ resist_continuum; /* Resist space-time continuum disruption */
+
+ bool_ sensible_fire; /* Fire does more damage on the player */
+ bool_ sensible_lite; /* Lite does more damage on the player and blinds her/him */
+
+ bool_ reflect; /* Reflect 'bolt' attacks */
+ bool_ sh_fire; /* Fiery 'immolation' effect */
+ bool_ sh_elec; /* Electric 'immolation' effect */
+ bool_ wraith_form; /* wraithform */
+
+ bool_ anti_magic; /* Anti-magic */
+ bool_ anti_tele; /* Prevent teleportation */
+
+ bool_ sustain_str; /* Keep strength */
+ bool_ sustain_int; /* Keep intelligence */
+ bool_ sustain_wis; /* Keep wisdom */
+ bool_ sustain_dex; /* Keep dexterity */
+ bool_ sustain_con; /* Keep constitution */
+ bool_ sustain_chr; /* Keep charisma */
+
+ bool_ aggravate; /* Aggravate monsters */
+ bool_ teleport; /* Random teleporting */
+
+ bool_ exp_drain; /* Experience draining */
+ byte drain_mana; /* mana draining */
+ byte drain_life; /* hp draining */
+
+ bool_ magical_breath; /* Magical breathing -- can breath anywhere */
+ bool_ water_breath; /* Water breathing -- can breath underwater */
+ bool_ climb; /* Can climb mountains */
+ bool_ fly; /* Can fly over some features */
+ bool_ ffall; /* No damage falling */
+ bool_ lite; /* Permanent light */
+ bool_ free_act; /* Never paralyzed */
+ bool_ see_inv; /* Can see invisible */
+ bool_ regenerate; /* Regenerate hit pts */
+ bool_ hold_life; /* Resist life draining */
+ u32b telepathy; /* Telepathy */
+ bool_ slow_digest; /* Slower digestion */
+ bool_ bless_blade; /* Blessed blade */
+ byte xtra_might; /* Extra might bow */
+ bool_ impact; /* Earthquake blows */
+ bool_ auto_id; /* Auto id items */
+
+ s16b invis; /* Invisibility */
+
+ s16b dis_to_h; /* Known bonus to hit */
+ s16b dis_to_d; /* Known bonus to dam */
+ s16b dis_to_a; /* Known bonus to ac */
+
+ s16b dis_ac; /* Known base ac */
+
+ s16b to_l; /* Bonus to life */
+ s16b to_m; /* Bonus to mana */
+ s16b to_s; /* Bonus to spell */
+ s16b to_h; /* Bonus to hit */
+ s16b to_d; /* Bonus to dam */
+ s16b to_h_melee; /* Bonus to hit for melee */
+ s16b to_d_melee; /* Bonus to dam for melee */
+ s16b to_h_ranged; /* Bonus to hit for ranged */
+ s16b to_d_ranged; /* Bonus to dam for ranged */
+ s16b to_a; /* Bonus to ac */
+
+ s16b ac; /* Base ac */
+
+ byte antimagic; /* Power of the anti magic field */
+ byte antimagic_dis; /* Radius of the anti magic field */
+
+ s16b see_infra; /* Infravision range */
+
+ s16b skill_dis; /* Skill: Disarming */
+ s16b skill_dev; /* Skill: Magic Devices */
+ s16b skill_sav; /* Skill: Saving throw */
+ s16b skill_stl; /* Skill: Stealth factor */
+ s16b skill_srh; /* Skill: Searching ability */
+ s16b skill_fos; /* Skill: Searching frequency */
+ s16b skill_thn; /* Skill: To hit (normal) */
+ s16b skill_thb; /* Skill: To hit (shooting) */
+ s16b skill_tht; /* Skill: To hit (throwing) */
+ s16b skill_dig; /* Skill: Digging */
+
+ s16b num_blow; /* Number of blows */
+ s16b num_fire; /* Number of shots */
+ s16b xtra_crit; /* % of increased crits */
+
+ byte throw_mult; /* Multiplier for throw damage */
+
+ byte tval_ammo; /* Correct ammo tval */
+
+ s16b pspeed; /* Current speed */
+
+ u32b mimic_extra; /* Mimicry powers use that */
+ u32b antimagic_extra; /* Antimagic powers */
+ u32b music_extra; /* Music songs */
+ u32b necro_extra; /* Necro powers */
+ u32b necro_extra2; /* Necro powers */
+
+ s16b dodge_chance; /* Dodging chance */
+
+ u32b maintain_sum; /* Do we have partial summons */
+
+ byte spellbinder_num; /* Number of spells bound */
+ u32b spellbinder[4]; /* Spell bounds */
+ byte spellbinder_trigger; /* Spellbinder trigger condition */
+
+ cptr mimic_name;
+
+ char tactic; /* from 128-4 extremely coward to */
+ /* 128+4 berserker */
+ char movement; /* base movement way */
+
+ s16b companion_killed; /* Number of companion death */
+
+ bool_ no_mortal; /* Fated to never die by the hand of a mortal being */
+
+ bool_ black_breath; /* The Tolkien's Black Breath */
+
+ bool_ precognition; /* Like the cheat mode */
+
+ /*** Extra flags -- used for lua and easying stuff ***/
+ u32b xtra_f1;
+ u32b xtra_f2;
+ u32b xtra_f3;
+ u32b xtra_f4;
+ u32b xtra_f5;
+ u32b xtra_esp;
+
+ /* Corruptions */
+ bool_ corruptions[CORRUPTIONS_MAX];
+ bool_ corrupt_anti_teleport_stopped;
+
+ /*** Pet commands ***/
+ byte pet_follow_distance; /* Length of the imaginary "leash" for pets */
+ byte pet_open_doors; /* flag - allow pets to open doors */
+ byte pet_pickup_items; /* flag - allow pets to pickup items */
+
+ s16b control; /* Controlled monster */
+ byte control_dir; /* Controlled monster */
+
+ /*** Body changing variables ***/
+ u16b body_monster; /* In which body is the player */
+ bool_ disembodied; /* Is the player in a body ? */
+ byte body_parts[INVEN_TOTAL - INVEN_WIELD]; /* Which body parts does he have ? */
+
+ /* Astral */
+ bool_ astral; /* We started at the bottom ? */
+
+ /* Powers */
+ bool_ powers[POWER_MAX]; /* Actual powers */
+ bool_ powers_mod[POWER_MAX]; /* Intrinsinc powers */
+
+ /* Skills */
+ s16b skill_points;
+ s16b skill_last_level; /* Prevents gaining skills by losing level and regaining them */
+ s16b melee_style; /* How are */
+ s16b use_piercing_shots; /* for archery */
+
+ /* Dripping Tread spell timer */
+ s16b dripping_tread;
+
+ /* Help */
+ help_info help;
+
+ /* Inertia control */
+ s32b inertia_controlled_spell;
+
+ /* For automatic stat-gain */
+ s16b last_rewarded_level;
+
+ /*** Temporary fields ***/
+
+ bool_ did_nothing; /* True if the last action wasnt a real action */
+ bool_ leaving; /* True if player is leaving */
+};
+
diff --git a/src/player_type_fwd.hpp b/src/player_type_fwd.hpp
new file mode 100644
index 00000000..45a4bbcf
--- /dev/null
+++ b/src/player_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct player_type;
diff --git a/src/plots.c b/src/plots.c
deleted file mode 100644
index afc59350..00000000
--- a/src/plots.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* File: plots.c */
-
-/* Purpose: plots & quests */
-
-/*
- * Copyright (c) 2001 James E. Wilson, Robert A. Koeneke, DarkGod
- *
- * 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.
- */
-
-#include "angband.h"
-
-#include <assert.h>
-
-#include "messages.h"
-#include "quark.h"
-
-/******** Hooks stuff *********/
-FILE *hook_file;
-
-#define MAX_ARGS 50
-
-static hooks_chain *hooks_heads[MAX_HOOKS];
-
-/* Wipe hooks and init them with quest hooks */
-void wipe_hooks()
-{
- int i;
-
- for (i = 0; i < MAX_HOOKS; i++)
- {
- hooks_heads[i] = NULL;
- }
-}
-void init_hooks()
-{
- int i;
-
- for (i = 0; i < MAX_Q_IDX; i++)
- {
- if (quest[i].init != NULL)
- {
- quest[i].init(i);
- }
- }
-}
-
-void dump_hooks(int h_idx)
-{
- int min = 0, max = MAX_HOOKS, i;
-
- if (h_idx != -1)
- {
- min = h_idx;
- max = h_idx + 1;
- }
-
- for (i = min; i < max; i++)
- {
- hooks_chain *c = hooks_heads[i];
-
- /* Find it */
- while (c != NULL)
- {
- msg_format("%s(%s)", c->name, (c->type == HOOK_TYPE_C) ? "C" : "Lua");
-
- c = c->next;
- }
- }
-}
-
-/* Check a hook */
-bool_ check_hook(int h_idx)
-{
- hooks_chain *c = hooks_heads[h_idx];
-
- return (c != NULL);
-}
-
-/* Add a hook */
-hooks_chain* add_hook(int h_idx, hook_type hook, cptr name)
-{
- hooks_chain *new_, *c = hooks_heads[h_idx];
-
- /* Find it */
- while ((c != NULL) && (strcmp(c->name, name)))
- {
- c = c->next;
- }
-
- /* If not already in the list, add it */
- if (c == NULL)
- {
- MAKE(new_, hooks_chain);
- new_->hook = hook;
- sprintf(new_->name, "%s", name);
- new_->next = hooks_heads[h_idx];
- hooks_heads[h_idx] = new_;
- return (new_);
- }
- else return (c);
-}
-
-void add_hook_new(int h_idx, bool_ (*hook_f)(void *, void *, void *), cptr name, void *data)
-{
- hooks_chain *c = add_hook(h_idx, NULL, name);
- c->hook_f = hook_f;
- c->hook_data = data;
- c->type = HOOK_TYPE_NEW;
-}
-
-/* Remove a hook */
-void del_hook(int h_idx, hook_type hook)
-{
- hooks_chain *c = hooks_heads[h_idx], *p = NULL;
-
- /* Find it */
- while ((c != NULL) && (c->hook != hook))
- {
- p = c;
- c = c->next;
- }
-
- /* Remove it */
- if (c != NULL)
- {
- if (p == NULL)
- {
- hooks_heads[h_idx] = c->next;
- FREE(c, hooks_chain);
- }
- else
- {
- p->next = c->next;
- FREE(c, hooks_chain);
- }
- }
-}
-
-void del_hook_name(int h_idx, cptr name)
-{
- hooks_chain *c = hooks_heads[h_idx], *p = NULL;
-
- /* Find it */
- while ((c != NULL) && (strcmp(c->name, name)))
- {
- p = c;
- c = c->next;
- }
-
- /* Remove it */
- if (c != NULL)
- {
- if (p == NULL)
- {
- hooks_heads[h_idx] = c->next;
- FREE(c, hooks_chain);
- }
- else
- {
- p->next = c->next;
- FREE(c, hooks_chain);
- }
- }
-}
-
-/* get the next argument */
-static hook_return param_pile[MAX_ARGS];
-static int get_next_arg_pos = 0;
-static int get_next_arg_pile_pos = 0;
-s32b get_next_arg(char *fmt)
-{
- while (TRUE)
- {
- switch (fmt[get_next_arg_pos++])
- {
- case 'd':
- case 'l':
- return (param_pile[get_next_arg_pile_pos++].num);
- case ')':
- get_next_arg_pos--;
- return 0;
- case '(':
- case ',':
- break;
- }
- }
-}
-char* get_next_arg_str(char *fmt)
-{
- while (TRUE)
- {
- switch (fmt[get_next_arg_pos++])
- {
- case 's':
- return (char*)(param_pile[get_next_arg_pile_pos++].str);
- case ')':
- get_next_arg_pos--;
- return 0;
- case '(':
- case ',':
- break;
- }
- }
-}
-
-/* Actually process the hooks */
-int process_hooks_restart = FALSE;
-hook_return process_hooks_return[20];
-static bool_ vprocess_hooks_return (int h_idx, char *ret, char *fmt, va_list *ap)
-{
- hooks_chain *c = hooks_heads[h_idx];
- va_list real_ap;
-
- while (c != NULL)
- {
- if (c->type == HOOK_TYPE_C)
- {
- int i = 0, nb = 0;
-
- /* Push all args in the pile */
- i = 0;
- COPY(&real_ap, ap, va_list);
- while (fmt[i])
- {
- switch (fmt[i])
- {
- case 'O':
- param_pile[nb++].o_ptr = va_arg(real_ap, object_type *);
- break;
- case 's':
- param_pile[nb++].str = va_arg(real_ap, char *);
- break;
- case 'd':
- case 'l':
- param_pile[nb++].num = va_arg(real_ap, s32b);
- break;
- case '(':
- case ')':
- case ',':
- break;
- }
- i++;
- }
-
- get_next_arg_pos = 0;
- get_next_arg_pile_pos = 0;
- if (c->hook(fmt))
- {
- return TRUE;
- }
-
- /* Should we restart ? */
- if (process_hooks_restart)
- {
- c = hooks_heads[h_idx];
- process_hooks_restart = FALSE;
- }
- else
- {
- c = c->next;
- }
- }
- else if (c->type == HOOK_TYPE_NEW)
- {
- /* Skip; handled in process_hooks_new */
- c = c->next;
- }
- else
- {
- msg_format("Unkown hook type %d, name %s", c->type, c->name);
- c = c->next;
- }
- }
-
- return FALSE;
-}
-
-bool_ process_hooks_ret(int h_idx, char *ret, char *fmt, ...)
-{
- va_list ap;
- bool_ r;
-
- va_start(ap, fmt);
- r = vprocess_hooks_return (h_idx, ret, fmt, &ap);
- va_end(ap);
- return (r);
-}
-
-bool_ process_hooks(int h_idx, char *fmt, ...)
-{
- va_list ap;
- bool_ ret;
-
- va_start(ap, fmt);
- ret = vprocess_hooks_return (h_idx, "", fmt, &ap);
- va_end(ap);
- return (ret);
-}
-
-bool_ process_hooks_new(int h_idx, void *in, void *out)
-{
- hooks_chain *c = hooks_heads[h_idx];
-
- while (c != NULL)
- {
- /* Only new-style hooks; skip the rest. */
- if (c->type != HOOK_TYPE_NEW)
- {
- c = c->next;
- continue;
- }
-
- /* Invoke hook function; stop processing if
- the hook returns TRUE */
- if (c->hook_f(c->hook_data, in, out))
- {
- return TRUE;
- }
-
- /* Should we restart processing at the beginning? */
- if (process_hooks_restart)
- {
- c = hooks_heads[h_idx];
- process_hooks_restart = FALSE;
- }
- else
- {
- c = c->next;
- }
- }
-
- return FALSE;
-}
-
-/******** Plots & Quest stuff ********/
-
-static void quest_describe(int q_idx)
-{
- int i = 0;
-
- while ((i < 10) && (quest[q_idx].desc[i][0] != '\0'))
- {
- cmsg_print(TERM_YELLOW, quest[q_idx].desc[i++]);
- }
-}
-
-/* Catch-all quest hook */
-bool_ quest_null_hook(int q)
-{
- /* Do nothing */
- return (FALSE);
-}
-
-/************************** Random Quests *************************/
-#include "q_rand.c"
-
-/**************************** Main plot ***************************/
-#include "q_main.c"
-#include "q_one.c"
-#include "q_ultrag.c"
-#include "q_ultrae.c"
-
-/**************************** Bree plot ***************************/
-#include "q_thief.c"
-#include "q_hobbit.c"
-#include "q_troll.c"
-#include "q_wight.c"
-#include "q_nazgul.c"
-#include "q_shroom.c"
-
-/*************************** Lorien plot **************************/
-#include "q_wolves.c"
-#include "q_spider.c"
-#include "q_poison.c"
-
-/************************** Gondolin plot *************************/
-#include "q_dragons.c"
-#include "q_eol.c"
-#include "q_nirna.c"
-#include "q_invas.c"
-
-/************************* Minas Anor plot ************************/
-#include "q_haunted.c"
-#include "q_betwen.c"
-
-/************************* Khazad-dum plot ************************/
-#include "q_evil.c"
-
-/*************************** Other plot ***************************/
-#include "q_narsil.c"
-#include "q_thrain.c"
-
-/*************************** Bounty Quest *************************/
-#include "q_bounty.c"
-
-/************************** Library Quest *************************/
-#include "q_library.c"
-
-/************************* Fireproofing Quest *********************/
-#include "q_fireprof.c"
diff --git a/src/plots.h b/src/plots.h
deleted file mode 100644
index 91115856..00000000
--- a/src/plots.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* File: plots.h */
-
-/* Purpose: extern plots declarations */
-
-extern bool_ quest_null_hook(int q);
-
-/******* Random Quests ********/
-extern bool_ is_randhero(int level);
-extern bool_ quest_random_init_hook(int q_idx);
-extern bool_ quest_random_describe(FILE *fff);
-
-/******* Plot main ********/
-extern bool_ quest_necro_init_hook(int q_idx);
-extern bool_ quest_one_init_hook(int q_idx);
-extern bool_ quest_sauron_init_hook(int q_idx);
-extern bool_ quest_morgoth_init_hook(int q_idx);
-extern bool_ quest_ultra_good_init_hook(int q_idx);
-extern bool_ quest_ultra_evil_init_hook(int q_idx);
-
-/******* Plot Bree *********/
-extern bool_ quest_thieves_init_hook(int q_idx);
-extern bool_ quest_hobbit_init_hook(int q_idx);
-extern bool_ quest_troll_init_hook(int q_idx);
-extern bool_ quest_wight_init_hook(int q_idx);
-extern bool_ quest_nazgul_init_hook(int q_idx);
-extern bool_ quest_shroom_init_hook(int q_idx);
-
-/******* Plot Lorien *********/
-extern bool_ quest_wolves_init_hook(int q_idx);
-extern bool_ quest_spider_init_hook(int q_idx);
-extern bool_ quest_poison_init_hook(int q_idx);
-
-/******* Plot Gondolin *********/
-extern bool_ quest_dragons_init_hook(int q_idx);
-extern bool_ quest_eol_init_hook(int q_idx);
-extern bool_ quest_nirnaeth_init_hook(int q_idx);
-extern bool_ quest_invasion_init_hook(int q_idx);
-
-/******* Plot Minas Anor *********/
-extern bool_ quest_haunted_init_hook(int q_idx);
-extern bool_ quest_between_init_hook(int q_idx);
-
-/******* Plot Khazad-dum *********/
-extern bool_ quest_evil_init_hook(int q_idx);
-
-/******* Plot Other *********/
-extern bool_ quest_narsil_init_hook(int q_idx);
-extern bool_ quest_thrain_init_hook(int q_idx);
-
-/******* Plot Bounty Quest ********/
-extern bool_ quest_bounty_init_hook(int q_idx);
-extern bool_ quest_bounty_drop_item();
-extern bool_ quest_bounty_get_item();
-extern bool_ quest_bounty_describe(FILE *fff);
-
-/******* Plot Library Quest *******/
-extern bool_ quest_library_init_hook(int q);
-extern bool_ quest_library_describe(FILE *fff);
-extern void quest_library_building(bool_ *paid, bool_ *recreate);
-
-/******* Plot Fireproof Quest *********/
-extern void quest_fireproof_building(bool_ *paid, bool_ *recreate);
-extern bool_ quest_fireproof_init_hook(int q);
-extern bool_ quest_fireproof_describe(FILE *fff);
-
-/******* Plot God Quest **************/
-extern bool_ quest_god_describe(FILE *);
-extern bool_ quest_god_init_hook(int q);
diff --git a/src/power_type.hpp b/src/power_type.hpp
new file mode 100644
index 00000000..6cf8c29b
--- /dev/null
+++ b/src/power_type.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Power descriptor. (Racial, class, mutation, artifacts, ...)
+ */
+struct power_type
+{
+ const char *name; /* Name */
+ const char *desc_text; /* Text describing power */
+ const char *gain_text; /* Text displayed on gaining the power */
+ const char *lose_text; /* Text displayed on losing the power */
+
+ byte level; /* Min level */
+ byte cost; /* Mana/Life cost */
+ byte stat; /* Stat used */
+ byte diff; /* Difficulty */
+};
diff --git a/src/powers.c b/src/powers.cc
index afc4a13a..ce715859 100644
--- a/src/powers.c
+++ b/src/powers.cc
@@ -1,7 +1,3 @@
-/* File: powers.c */
-
-/* Purpose: Powers */
-
/*
* Copyright (c) 2001 James E. Wilson, Robert A. Koeneke, DarkGod
*
@@ -10,14 +6,42 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "quark.h"
+#include "powers.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd2.hpp"
+#include "cmd7.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra2.hpp"
/*
* Note: return value indicates the amount of mana to use
*/
-bool_ power_chance(power_type *x_ptr)
+static bool_ power_chance(power_type *x_ptr)
{
bool_ use_hp = FALSE;
int diff = x_ptr->diff;
@@ -82,7 +106,7 @@ bool_ power_chance(power_type *x_ptr)
energy_use = 100;
/* Redraw mana and hp */
- p_ptr->redraw |= (PR_HP | PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -170,199 +194,6 @@ static void power_activate(int power)
}
}
break;
- case PWR_MERCHANT:
- /* Select power to use */
- while (TRUE)
- {
- if (!get_com("[A]ppraise item, [W]arp item or [I]dentify item? ", &ch))
- {
- amber_power = 0;
- break;
- }
-
- if (ch == 'A' || ch == 'a')
- {
- amber_power = 1;
- break;
- }
-
- if (ch == 'W' || ch == 'w')
- {
- amber_power = 2;
- break;
- }
-
- if (ch == 'I' || ch == 'i')
- {
- amber_power = 3;
- break;
- }
- }
-
- if (amber_power == 1)
- {
- x_ptr_foo.level = 5;
- x_ptr_foo.cost = 5;
- x_ptr_foo.stat = A_INT;
- x_ptr_foo.diff = 5;
- if (power_chance(&x_ptr_foo))
- {
- /* Appraise an object */
- int idx;
- cptr q, s;
-
- /* Get the item */
- q = "Appraise which item? ";
- s = "You have nothing to appraise.";
- if (get_item(&idx, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
- {
- object_type *o_ptr;
- char out_val[80], value[16];
-
- /* The item is in the pack */
- if (idx >= 0) o_ptr = &p_ptr->inventory[idx];
- /* The item is on the floor */
- else o_ptr = &o_list[0 - idx];
-
- /* Appraise it */
- sprintf(value, "%i au", (int)object_value(o_ptr));
-
- /* Inscribe the value */
- /* Get the original inscription */
- if (o_ptr->note)
- {
- strcpy(out_val, quark_str(o_ptr->note));
- strcat(out_val, " ");
- }
- else
- out_val[0] = '\0';
-
- strcat(out_val, value);
-
- /* Save the new inscription */
- o_ptr->note = quark_add(out_val);
-
- /* Combine the pack */
- p_ptr->notice |= (PN_COMBINE);
-
- /* Window stuff */
- p_ptr->window |= (PW_INVEN | PW_EQUIP);
- }
- }
- }
- if (amber_power == 2)
- {
- x_ptr_foo.level = 15;
- x_ptr_foo.cost = 10;
- x_ptr_foo.stat = A_INT;
- x_ptr_foo.diff = 7;
- if (power_chance(&x_ptr_foo))
- {
- int chest, item;
- cptr q1, s1, q2, s2;
- u32b flag = (USE_EQUIP | USE_INVEN | USE_FLOOR);
- object_type *o1_ptr = &p_ptr->inventory[0], *o2_ptr = &p_ptr->inventory[1];
- int ok = 0;
-
- q1 = "Select a chest! ";
- s1 = "You need a chest to warp items.";
-
- q2 = "Warp which item? ";
- s2 = "You have nothing to warp.";
-
- item_tester_tval = TV_CHEST;
-
- /* Get the chest */
- if (get_item(&chest, q1, s1, flag))
- {
- if (chest >= 0) o1_ptr = &p_ptr->inventory[chest];
- else o1_ptr = &o_list[0 - chest];
-
- /* Is the chest disarmed? */
- if (o1_ptr->pval > 0)
- msg_print("This chest may be trapped.");
-
- /* Is it ruined? */
- else if (k_info[o1_ptr->k_idx].level <= 0)
- msg_print("This chest is broken.");
-
- /* Is it empty? */
- else if (o1_ptr->pval2 >= (o1_ptr->sval % SV_CHEST_MIN_LARGE) * 2)
- msg_print("This chest is full.");
-
- else ok = 1;
- }
-
- /* Get the item */
- if (ok && get_item(&item, q2, s2, flag))
- {
- ok = 0;
-
- o2_ptr = get_object(item);
-
- /* Is the item cursed? */
- if ((item >= INVEN_WIELD) && cursed_p(o2_ptr))
- msg_print("Hmmm, it seems to be cursed.");
-
- /* Is it the same chest? */
- if (item == chest)
- msg_print("You can't put a chest into itself.");
-
- /* Is it another chest? */
- if (o2_ptr->tval == TV_CHEST)
- msg_print("You can't put a chest into another one.");
-
- /* Try to use the power */
- else ok = 1;
- }
-
- if (ok)
- {
- int tmp, level;
-
- /* Calculate the level of objects */
- tmp = o1_ptr->pval;
-
- /* Get the level of the current object */
- /* Cursed items/cheap items always break */
- if (k_info[o2_ptr->k_idx].cost < 20) level = 0;
- /* Not-so-cheap items break 90% of the time */
- else if (k_info[o2_ptr->k_idx].cost < 100) level = 1;
- else level = k_info[o2_ptr->k_idx].level;
-
- /* Break some items */
- if (randint(10) > level)
- msg_print("The item disappeared!");
- else
- {
- level /= (o1_ptr->sval % SV_CHEST_MIN_LARGE) * 2;
-
- /* Increase the number of objects in
- * the chest */
- o1_ptr->pval2++;
-
- /* Set the level of chest */
- tmp = tmp - level;
- o1_ptr->pval = tmp;
- }
-
- /* Destroy item */
- inc_stack_size(item, -1);
- }
- }
- }
- if (amber_power == 3)
- {
- x_ptr_foo.level = 30;
- x_ptr_foo.cost = 20;
- x_ptr_foo.stat = A_INT;
- x_ptr_foo.diff = 7;
- if (power_chance(&x_ptr_foo))
- {
- ident_spell();
- }
- }
- break;
case PWR_LAY_TRAP:
{
do_cmd_set_trap();
@@ -762,13 +593,10 @@ static void power_activate(int power)
cptr q, s;
- /* Restrict choices to monsters */
- item_tester_tval = TV_HYPNOS;
-
/* Get an item */
q = "Awaken which monster? ";
s = "You have no monster to awaken.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return;
+ if (!get_item(&item, q, s, (USE_FLOOR), object_filter::TVal(TV_HYPNOS))) return;
o_ptr = &o_list[0 - item];
@@ -1053,12 +881,10 @@ static void power_activate(int power)
object_type * o_ptr;
int lev, item;
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
q = "Drain which item? ";
s = "You have nothing to drain.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) break;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), item_tester_hook_recharge())) break;
o_ptr = get_object(item);
@@ -1248,16 +1074,11 @@ static void power_activate(int power)
break;
default:
-
- if (!process_hooks(HOOK_ACTIVATE_POWER, "(d)", power))
- {
- msg_format("Warning power_activate() called with invalid power(%d).", power);
- energy_use = 0;
- }
+ abort();
break;
}
- p_ptr->redraw |= (PR_HP | PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_PLAYER);
}
diff --git a/src/powers.hpp b/src/powers.hpp
new file mode 100644
index 00000000..35d317b0
--- /dev/null
+++ b/src/powers.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+extern void do_cmd_power();
+
+/*
+ * Powers (mutation, activations, ...)
+ */
+#define POWER_MAX 65
+
+#define PWR_SPIT_ACID 0
+#define PWR_BR_FIRE 1
+#define PWR_HYPN_GAZE 2
+#define PWR_TELEKINES 3
+#define PWR_VTELEPORT 4
+#define PWR_MIND_BLST 5
+#define PWR_RADIATION 6
+#define PWR_VAMPIRISM 7
+#define PWR_SMELL_MET 8
+#define PWR_SMELL_MON 9
+#define PWR_BLINK 10
+#define PWR_EAT_ROCK 11
+#define PWR_SWAP_POS 12
+#define PWR_SHRIEK 13
+#define PWR_ILLUMINE 14
+#define PWR_DET_CURSE 15
+#define PWR_BERSERK 16
+#define PWR_POLYMORPH 17
+#define PWR_MIDAS_TCH 18
+#define PWR_GROW_MOLD 19
+#define PWR_RESIST 20
+#define PWR_EARTHQUAKE 21
+#define PWR_EAT_MAGIC 22
+#define PWR_WEIGH_MAG 23
+#define PWR_STERILITY 24
+#define PWR_PANIC_HIT 25
+#define PWR_DAZZLE 26
+#define PWR_DARKRAY 27
+#define PWR_RECALL 28
+#define PWR_BANISH 29
+#define PWR_COLD_TOUCH 30
+#define PWR_LAUNCHER 31
+
+#define PWR_PASSWALL 32
+#define PWR_DETECT_TD 33
+#define PWR_COOK_FOOD 34
+#define PWR_UNFEAR 35
+#define PWR_EXPL_RUNE 36
+#define PWR_STM 37
+#define PWR_POIS_DART 38
+#define PWR_MAGIC_MISSILE 39
+#define PWR_GROW_TREE 40
+#define PWR_BR_COLD 41
+#define PWR_BR_CHAOS 42
+#define PWR_BR_ELEM 43
+#define PWR_WRECK_WORLD 44
+#define PWR_SCARE 45
+#define PWR_REST_LIFE 46
+#define PWR_SUMMON_MONSTER 47
+#define PWR_NECRO 48
+#define PWR_ROHAN 49
+#define PWR_THUNDER 50
+#define PWR_DEATHMOLD 51
+#define PWR_HYPNO 52
+#define PWR_UNHYPNO 53
+#define PWR_INCARNATE 54
+#define PWR_MAGIC_MAP 55
+#define PWR_LAY_TRAP 56
+#define PWR_COMPANION 58
+#define PWR_BEAR 59
+#define PWR_DODGE 60
+#define PWR_BALROG 61
+#define POWER_INVISIBILITY 62
+#define POWER_WEB 63
+#define POWER_COR_SPACE_TIME 64
diff --git a/src/q_betwen.c b/src/q_betwen.cc
index e6452dd9..2bebe452 100644
--- a/src/q_betwen.c
+++ b/src/q_betwen.cc
@@ -1,14 +1,30 @@
-#undef cquest
+#include "q_betwen.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_init_quest_in.hpp"
+#include "hook_move_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_BETWEEN])
-bool_ quest_between_move_hook(char *fmt)
+static bool_ quest_between_move_hook(void *, void *in_, void *)
{
- s32b y;
- s32b x;
+ struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
+ s32b y = in->y;
+ s32b x = in->x;
cave_type *c_ptr;
- y = get_next_arg(fmt);
- x = get_next_arg(fmt);
c_ptr = &cave[y][x];
if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
@@ -49,7 +65,8 @@ bool_ quest_between_move_hook(char *fmt)
return FALSE;
}
-bool_ quest_between_gen_hook(char *fmt)
+
+static bool_ quest_between_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -83,13 +100,13 @@ bool_ quest_between_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_between_finish_hook(char *fmt)
+
+static bool_ quest_between_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
object_type forge, *q_ptr;
- q_idx = get_next_arg(fmt);
-
if (q_idx != QUEST_BETWEEN) return FALSE;
c_put_str(TERM_YELLOW, "Ah you finally arrived, I hope your travel wasn't too hard.", 8, 0);
@@ -116,12 +133,13 @@ bool_ quest_between_finish_hook(char *fmt)
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
- del_hook(HOOK_QUEST_FINISH, quest_between_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_between_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_between_death_hook(char *fmt)
+
+static bool_ quest_between_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -150,19 +168,24 @@ bool_ quest_between_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_between_dump_hook(char *fmt)
+
+static bool_ quest_between_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status >= QUEST_STATUS_COMPLETED)
{
- fprintf(hook_file, "\n You established a permanent void jumpgates liaison between Minas Anor and Gondolin,");
- fprintf(hook_file, "\n thus allowing the last alliance to exist.");
+ fprintf(f, "\n You established a permanent void jumpgates liaison between Minas Anor and Gondolin,");
+ fprintf(f, "\n thus allowing the last alliance to exist.");
}
return (FALSE);
}
-bool_ quest_between_forbid_hook(char *fmt)
+
+static bool_ quest_between_forbid_hook(void *, void *in_, void *)
{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+ hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_BETWEEN) return (FALSE);
@@ -173,16 +196,17 @@ bool_ quest_between_forbid_hook(char *fmt)
}
return (FALSE);
}
+
bool_ quest_between_init_hook(int q)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MOVE, quest_between_move_hook, "between_move");
- add_hook(HOOK_GEN_QUEST, quest_between_gen_hook, "between_gen");
- add_hook(HOOK_QUEST_FINISH, quest_between_finish_hook, "between_finish");
- add_hook(HOOK_MONSTER_DEATH, quest_between_death_hook, "between_death");
+ add_hook_new(HOOK_MOVE, quest_between_move_hook, "between_move", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_between_gen_hook, "between_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_between_finish_hook, "between_finish", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_between_death_hook, "between_death", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_between_dump_hook, "between_dump");
- add_hook(HOOK_INIT_QUEST, quest_between_forbid_hook, "between_forbid");
+ add_hook_new(HOOK_CHAR_DUMP, quest_between_dump_hook, "between_dump", NULL);
+ add_hook_new(HOOK_INIT_QUEST, quest_between_forbid_hook, "between_forbid", NULL);
return (FALSE);
}
diff --git a/src/q_betwen.hpp b/src/q_betwen.hpp
new file mode 100644
index 00000000..d2fc08f0
--- /dev/null
+++ b/src/q_betwen.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_between_init_hook(int q_idx);
diff --git a/src/q_bounty.c b/src/q_bounty.cc
index 01b119be..bb84d48d 100644
--- a/src/q_bounty.c
+++ b/src/q_bounty.cc
@@ -1,18 +1,77 @@
-#undef cquest
+#include "q_bounty.hpp"
+
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "skill_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_BOUNTY])
#define bounty_quest_monster (cquest.data[0])
-static bool_ bounty_item_tester_hook(object_type *o_ptr)
+static bool_ lua_mon_hook_bounty(int r_idx)
{
- if ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval2 == bounty_quest_monster))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ monster_race* r_ptr = &r_info[r_idx];
+
+ /* Reject uniques */
+ if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
+
+ /* Reject those who cannot leave anything */
+ if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) return (FALSE);
+
+ /* Accept only monsters that can be generated */
+ if (r_ptr->flags9 & RF9_SPECIAL_GENE) return (FALSE);
+ if (r_ptr->flags9 & RF9_NEVER_GENE) return (FALSE);
+
+ /* Reject pets */
+ if (r_ptr->flags7 & RF7_PET) return (FALSE);
+
+ /* Reject friendly creatures */
+ if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE);
+
+ /* Accept only monsters that are not breeders */
+ if (r_ptr->flags4 & RF4_MULTIPLY) return (FALSE);
+
+ /* Forbid joke monsters */
+ if (r_ptr->flags8 & RF8_JOKEANGBAND) return (FALSE);
+
+ /* Accept only monsters that are not good */
+ if (r_ptr->flags3 & RF3_GOOD) return (FALSE);
+
+ /* The rest are acceptable */
+ return (TRUE);
+}
+
+static int get_new_bounty_monster(int lev)
+{
+ int r_idx;
+
+ /*
+ * Set up the hooks -- no bounties on uniques or monsters
+ * with no corpses
+ */
+ get_mon_num_hook = lua_mon_hook_bounty;
+ get_mon_num_prep();
+
+ /* Set up the quest monster. */
+ r_idx = get_mon_num(lev);
+
+ /* Undo the filters */
+ get_mon_num_hook = NULL;
+ get_mon_num_prep();
+
+ return r_idx;
+}
+
+static bool bounty_item_tester_hook(object_type const *o_ptr)
+{
+ return ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval2 == bounty_quest_monster));
}
bool_ quest_bounty_init_hook(int dummy)
@@ -28,7 +87,7 @@ bool_ quest_bounty_drop_item()
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
cquest.status = QUEST_STATUS_TAKEN;
- bounty_quest_monster = lua_get_new_bounty_monster(3 + (p_ptr->lev * 3) / 2);
+ bounty_quest_monster = get_new_bounty_monster(3 + (p_ptr->lev * 3) / 2);
monster_race_desc(mdesc, bounty_quest_monster, 0);
snprintf(msg, sizeof(msg), "You must bring me back %s corpse.", mdesc);
@@ -52,13 +111,13 @@ bool_ quest_bounty_get_item()
}
// Get the corpse.
- item_tester_hook = bounty_item_tester_hook;
int item = -1;
bool_ ret =
get_item(&item,
"What corpse to return?",
"You have no corpse to return.",
- USE_INVEN);
+ USE_INVEN,
+ bounty_item_tester_hook);
if (!ret) {
return FALSE;
}
diff --git a/src/q_bounty.hpp b/src/q_bounty.hpp
new file mode 100644
index 00000000..234c036d
--- /dev/null
+++ b/src/q_bounty.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ quest_bounty_init_hook(int q_idx);
+extern bool_ quest_bounty_drop_item();
+extern bool_ quest_bounty_get_item();
+extern bool_ quest_bounty_describe(FILE *fff);
diff --git a/src/q_dragons.c b/src/q_dragons.cc
index 025e8ecd..d6f5b1fb 100644
--- a/src/q_dragons.c
+++ b/src/q_dragons.cc
@@ -1,7 +1,21 @@
-#undef cquest
+#include "q_dragons.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_DRAGONS])
-bool_ quest_dragons_gen_hook(char *fmt)
+static bool_ quest_dragons_gen_hook(void *, void *, void *)
{
int x, y, i;
int xstart = 2;
@@ -89,7 +103,7 @@ bool_ quest_dragons_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_dragons_death_hook(char *fmt)
+static bool_ quest_dragons_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -111,8 +125,8 @@ bool_ quest_dragons_death_hook(char *fmt)
if (mcnt <= 1)
{
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_dragons_death_hook);
- del_hook(HOOK_GEN_QUEST, quest_dragons_gen_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_dragons_death_hook);
+ del_hook_new(HOOK_GEN_QUEST, quest_dragons_gen_hook);
process_hooks_restart = TRUE;
cmsg_print(TERM_YELLOW, "Gondolin is safer now.");
@@ -121,11 +135,10 @@ bool_ quest_dragons_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_dragons_finish_hook(char *fmt)
+static bool_ quest_dragons_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_DRAGONS) return FALSE;
@@ -142,9 +155,9 @@ bool_ quest_dragons_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_dragons_death_hook, "dragons_monster_death");
- add_hook(HOOK_QUEST_FINISH, quest_dragons_finish_hook, "dragons_finish");
- add_hook(HOOK_GEN_QUEST, quest_dragons_gen_hook, "dragons_geb");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_dragons_death_hook, "dragons_monster_death", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_dragons_finish_hook, "dragons_finish", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_dragons_gen_hook, "dragons_geb", NULL);
}
return (FALSE);
}
diff --git a/src/q_dragons.hpp b/src/q_dragons.hpp
new file mode 100644
index 00000000..f0aa50f2
--- /dev/null
+++ b/src/q_dragons.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_dragons_init_hook(int q_idx);
diff --git a/src/q_eol.c b/src/q_eol.cc
index 5b1cf78e..cfccd156 100644
--- a/src/q_eol.c
+++ b/src/q_eol.cc
@@ -1,7 +1,30 @@
-#undef cquest
+#include "q_eol.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "generate.hpp"
+#include "hook_stair_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hook_quest_fail_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hooks.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_EOL])
-bool_ quest_eol_gen_hook(char *fmt)
+GENERATE_MONSTER_LOOKUP_FN(get_eol, "Eol, the Dark Elf")
+
+static bool_ quest_eol_gen_hook(void *, void *, void *)
{
int x, y;
bool_ done = FALSE;
@@ -61,9 +84,13 @@ bool_ quest_eol_gen_hook(char *fmt)
/* Place eol at the other end */
if (!m_idx)
{
- m_allow_special[test_monster_name("Eol, the Dark Elf")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Eol, the Dark Elf"), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[test_monster_name("Eol, the Dark Elf")] = FALSE;
+ // Find Eol's r_info entry
+ int r_idx = get_eol();
+ // "Summon" Eol
+ m_allow_special[r_idx] = TRUE;
+ m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = FALSE;
+ // Mark with the QUEST flag
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
}
@@ -81,12 +108,12 @@ bool_ quest_eol_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_eol_finish_hook(char *fmt)
+
+static bool_ quest_eol_finish_hook(void *, void *in_, void *)
{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
object_type forge, *q_ptr;
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
if (q_idx != QUEST_EOL) return FALSE;
@@ -108,16 +135,16 @@ bool_ quest_eol_finish_hook(char *fmt)
*(quest[q_idx].plot) = QUEST_NIRNAETH;
quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));
- del_hook(HOOK_QUEST_FINISH, quest_eol_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_eol_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_eol_fail_hook(char *fmt)
-{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+static bool_ quest_eol_fail_hook(void *, void *in_, void *)
+{
+ struct hook_quest_fail_in *in = static_cast<struct hook_quest_fail_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_EOL) return FALSE;
@@ -126,37 +153,38 @@ bool_ quest_eol_fail_hook(char *fmt)
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
- del_hook(HOOK_QUEST_FAIL, quest_eol_fail_hook);
+ del_hook_new(HOOK_QUEST_FAIL, quest_eol_fail_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_eol_death_hook(char *fmt)
-{
- s32b r_idx, m_idx;
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
+static bool_ quest_eol_death_hook(void *, void *in_, void *)
+{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
if (p_ptr->inside_quest != QUEST_EOL) return FALSE;
- if (r_idx == test_monster_name("Eol, the Dark Elf"))
+ if (r_idx == get_eol())
{
cmsg_print(TERM_YELLOW, "Such a sad end...");
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_eol_death_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_eol_death_hook);
process_hooks_restart = TRUE;
+
return (FALSE);
}
return FALSE;
}
-bool_ quest_eol_stair_hook(char *fmt)
-{
- monster_race *r_ptr = &r_info[test_monster_name("Eol, the Dark Elf")];
- cptr down;
- down = get_next_arg_str(fmt);
+static bool_ quest_eol_stair_hook(void *, void *in_, void *)
+{
+ struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_);
+ monster_race *r_ptr = &r_info[get_eol()];
if (p_ptr->inside_quest != QUEST_EOL) return FALSE;
@@ -164,7 +192,7 @@ bool_ quest_eol_stair_hook(char *fmt)
if (r_ptr->max_num)
{
- if (!strcmp(down, "up"))
+ if (in->direction == STAIRS_UP)
{
/* Flush input */
flush();
@@ -173,7 +201,8 @@ bool_ quest_eol_stair_hook(char *fmt)
cmsg_print(TERM_YELLOW, "You flee away from Eol...");
cquest.status = QUEST_STATUS_FAILED;
- del_hook(HOOK_STAIR, quest_eol_stair_hook);
+
+ del_hook_new(HOOK_STAIR, quest_eol_stair_hook);
process_hooks_restart = TRUE;
return (FALSE);
}
@@ -181,15 +210,16 @@ bool_ quest_eol_stair_hook(char *fmt)
return FALSE;
}
+
bool_ quest_eol_init_hook(int q)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_eol_death_hook, "eol_death");
- add_hook(HOOK_GEN_QUEST, quest_eol_gen_hook, "eol_gen");
- add_hook(HOOK_STAIR, quest_eol_stair_hook, "eol_stair");
- add_hook(HOOK_QUEST_FAIL, quest_eol_fail_hook, "eol_fail");
- add_hook(HOOK_QUEST_FINISH, quest_eol_finish_hook, "eol_finish");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_eol_death_hook, "eol_death", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_eol_gen_hook, "eol_gen", NULL);
+ add_hook_new(HOOK_STAIR, quest_eol_stair_hook, "eol_stair", NULL);
+ add_hook_new(HOOK_QUEST_FAIL, quest_eol_fail_hook, "eol_fail", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_eol_finish_hook, "eol_finish", NULL);
}
return (FALSE);
}
diff --git a/src/q_eol.hpp b/src/q_eol.hpp
new file mode 100644
index 00000000..ab7f1274
--- /dev/null
+++ b/src/q_eol.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_eol_init_hook(int q_idx);
diff --git a/src/q_evil.c b/src/q_evil.cc
index a143f65c..511644a3 100644
--- a/src/q_evil.c
+++ b/src/q_evil.cc
@@ -1,7 +1,21 @@
-#undef cquest
+#include "q_evil.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_EVIL])
-bool_ quest_evil_gen_hook(char *fmt)
+static bool_ quest_evil_gen_hook(void *, void *, void *)
{
int x, y, i;
int xstart = 2;
@@ -54,7 +68,7 @@ bool_ quest_evil_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_evil_death_hook(char *fmt)
+static bool_ quest_evil_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -78,8 +92,9 @@ bool_ quest_evil_death_hook(char *fmt)
/* TODO: change to COMPLETED and remove NULL when mayor is added */
quest[p_ptr->inside_quest].status = QUEST_STATUS_FINISHED;
*(quest[p_ptr->inside_quest].plot) = QUEST_NULL;
- del_hook(HOOK_MONSTER_DEATH, quest_evil_death_hook);
- del_hook(HOOK_GEN_QUEST, quest_evil_gen_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_evil_death_hook);
+ del_hook_new(HOOK_GEN_QUEST, quest_evil_gen_hook);
process_hooks_restart = TRUE;
cmsg_print(TERM_YELLOW, "Khazad-Dum is safer now.");
@@ -88,11 +103,10 @@ bool_ quest_evil_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_evil_finish_hook(char *fmt)
+static bool_ quest_evil_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_EVIL) return FALSE;
@@ -109,9 +123,9 @@ bool_ quest_evil_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_evil_death_hook, "evil_monster_death");
- add_hook(HOOK_QUEST_FINISH, quest_evil_finish_hook, "evil_finish");
- add_hook(HOOK_GEN_QUEST, quest_evil_gen_hook, "evil_geb");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_evil_death_hook, "evil_monster_death", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_evil_finish_hook, "evil_finish", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_evil_gen_hook, "evil_geb", NULL);
}
return (FALSE);
}
diff --git a/src/q_evil.hpp b/src/q_evil.hpp
new file mode 100644
index 00000000..06fb17e1
--- /dev/null
+++ b/src/q_evil.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_evil_init_hook(int q_idx);
diff --git a/src/q_fireprof.c b/src/q_fireprof.cc
index 3afa348f..b11c9667 100644
--- a/src/q_fireprof.c
+++ b/src/q_fireprof.cc
@@ -1,4 +1,22 @@
-#undef cquest
+#include "q_fireprof.hpp"
+
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_get_in.hpp"
+#include "hooks.hpp"
+#include "lua_bind.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_FIREPROOF])
#define print_hook(fmt,...) do { fprintf(hook_file, fmt, ##__VA_ARGS__); } while (0)
@@ -65,38 +83,27 @@ static int fireproof_get_sval()
return cquest.data[1];
}
-static bool_ item_tester_hook_eligible(object_type *o_ptr)
+static bool item_tester_hook_eligible(object_type const *o_ptr)
{
/* check it's the 'marked' item */
- if ((o_ptr->tval == fireproof_get_settings()->tval) &&
+ return ((o_ptr->tval == fireproof_get_settings()->tval) &&
(o_ptr->sval == fireproof_get_sval()) &&
- (o_ptr->pval2 == fireproof_get_sval()))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ (o_ptr->pval2 == fireproof_get_sval()));
}
-static bool_ item_tester_hook_proofable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_proofable()
{
- u32b f1, f2, f3, f4, f5, esp;
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* is it a book/staff/scroll, is it already fireproof? */
- if (((o_ptr->tval == TV_BOOK) ||
- (o_ptr->tval == TV_SCROLL) ||
- (o_ptr->tval == TV_STAFF))
- && ((f3 & TR3_IGNORE_FIRE) == 0))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // Must be the correct item base type
+ Or(
+ TVal(TV_BOOK),
+ TVal(TV_SCROLL),
+ TVal(TV_STAFF)),
+ // Must NOT already be fireproof
+ Not(
+ HasFlag3(TR3_IGNORE_FIRE)));
+ return instance;
}
/*
@@ -157,30 +164,27 @@ static bool_ fireproof_enough_points(object_type *o_ptr, int *stack)
static bool_ fireproof()
{
- int ret, item, stack = 0;
- object_type *obj2 = NULL;
- bool_ ret2;
-
- item_tester_hook = item_tester_hook_proofable;
- ret = get_item(&item,
- "Which item shall I fireproof?",
- "You have no more items I can fireproof, come back when you have some.",
- USE_INVEN);
+ int item;
+ if (!get_item(&item,
+ "Which item shall I fireproof?",
+ "You have no more items I can fireproof, come back when you have some.",
+ USE_INVEN,
+ item_tester_hook_proofable()))
+ {
+ return FALSE;
+ }
/* get the object type from the number */
- obj2 = get_object(item);
+ object_type *obj2 = get_object(item);
/* check we have enough points (if we 'got' an item) */
- if (ret == TRUE) {
- ret2 = fireproof_enough_points(obj2, &stack);
- }
-
- /* did either routine fail? */
- if ((ret == FALSE) || (ret2 == FALSE))
+ int stack = 0;
+ if (!fireproof_enough_points(obj2, &stack))
{
return FALSE;
}
- else
+
+ /* Do the actual fireproofing */
{
bool_ carry_it;
object_type *obj3;
@@ -278,8 +282,7 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
snprintf(pni, sizeof(pni), "You have no %s to return", settings->tval_name_plural);
/* ask for item */
- item_tester_hook = item_tester_hook_eligible;
- ret = get_item(&item_idx, p, pni, USE_INVEN);
+ ret = get_item(&item_idx, p, pni, USE_INVEN, item_tester_hook_eligible);
/* didn't get the item? */
if (!ret)
@@ -377,10 +380,10 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
}
}
-static bool_ fireproof_get_hook(char *fmt)
+static bool_ fireproof_get_hook(void *, void *in_, void *)
{
- object_type *o_ptr = param_pile[0].o_ptr;
- assert(o_ptr != NULL);
+ struct hook_get_in *in = static_cast<struct hook_get_in *>(in_);
+ object_type *o_ptr = in->o_ptr;
/* check that player is in the quest, haven't picked up the
* item already, and check that it's the real item and not another one
@@ -397,7 +400,7 @@ static bool_ fireproof_get_hook(char *fmt)
return FALSE;
}
-static bool_ fireproof_stair_hook(char *fmt)
+static bool_ fireproof_stair_hook(void *, void *, void *)
{
/* only ask this if player about to go up stairs of quest and
* hasn't retrieved item */
@@ -479,7 +482,7 @@ bool_ quest_fireproof_describe(FILE *hook_file)
return TRUE;
}
-static bool_ fireproof_gen_hook(char *fmt)
+static bool_ fireproof_gen_hook(void *, void *, void *)
{
fireproof_settings const *settings = fireproof_get_settings();
@@ -575,9 +578,9 @@ bool_ quest_fireproof_init_hook(int q)
if ((cquest.status >= QUEST_STATUS_UNTAKEN) &&
(cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_GEN_QUEST, fireproof_gen_hook , "fireproof_gen_hook");
- add_hook(HOOK_GET , fireproof_get_hook , "fireproof_get_hook");
- add_hook(HOOK_STAIR , fireproof_stair_hook, "fireproof_stair_hook");
+ add_hook_new(HOOK_GEN_QUEST, fireproof_gen_hook , "fireproof_gen_hook", NULL);
+ add_hook_new(HOOK_GET , fireproof_get_hook , "fireproof_get_hook", NULL);
+ add_hook_new(HOOK_STAIR , fireproof_stair_hook, "fireproof_stair_hook", NULL);
}
return FALSE;
diff --git a/src/q_fireprof.hpp b/src/q_fireprof.hpp
new file mode 100644
index 00000000..53d368b0
--- /dev/null
+++ b/src/q_fireprof.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void quest_fireproof_building(bool_ *paid, bool_ *recreate);
+extern bool_ quest_fireproof_init_hook(int q);
+extern bool_ quest_fireproof_describe(FILE *fff);
diff --git a/src/q_god.c b/src/q_god.cc
index 82f90a25..754802fd 100644
--- a/src/q_god.c
+++ b/src/q_god.cc
@@ -1,9 +1,25 @@
-#include "angband.h"
+#include "q_god.hpp"
+
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_get_in.hpp"
+#include "hook_enter_dungeon_in.hpp"
+#include "hook_player_level_in.hpp"
+#include "hooks.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "skill_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
#include <assert.h>
-#include "quark.h"
-
#define cquest (quest[QUEST_GOD])
#define cquest_quests_given (cquest.data[0])
#define cquest_relics_found (cquest.data[1])
@@ -149,8 +165,8 @@ static byte get_relic_num()
assert(FALSE);
}
-static void get_home_coordinates(int *home1_y, int *home1_x, char **home1,
- int *home2_y, int *home2_x, char **home2)
+static void get_home_coordinates(int *home1_y, int *home1_x, const char **home1,
+ int *home2_y, int *home2_x, const char **home2)
{
/* Which are the waypoints? */
if (p_ptr->pgod != GOD_MELKOR)
@@ -223,8 +239,8 @@ static void print_directions(bool_ feel_it, void (*pfunc)(cptr, void *), void *p
{
int home1_y, home1_x;
int home2_y, home2_x;
- char *home1 = NULL;
- char *home2 = NULL;
+ const char *home1 = NULL;
+ const char *home2 = NULL;
char *home1_axis = NULL;
char *home2_axis = NULL;
cptr home1_distance = NULL;
@@ -865,7 +881,7 @@ static void quest_god_set_god_dungeon_attributes_mandos()
d_info[DUNGEON_GOD].rules[0].mflags3 = RF3_UNDEAD | RF3_EVIL;
}
-static bool_ quest_god_level_end_gen_hook(char *fmt)
+static bool_ quest_god_level_end_gen_hook(void *, void *, void *)
{
/* Check for dungeon */
if ((dungeon_type != DUNGEON_GOD) ||
@@ -922,9 +938,10 @@ static bool_ quest_god_level_end_gen_hook(char *fmt)
return FALSE;
}
-static bool_ quest_god_player_level_hook(char *fmt)
+static bool_ quest_god_player_level_hook(void *, void *in_, void *)
{
- s32b gained = get_next_arg(fmt);
+ struct hook_player_level_in *in = static_cast<struct hook_player_level_in *>(in_);
+ s32b gained = in->gained_levels;
if (gained <= 0)
{
@@ -982,16 +999,13 @@ static bool_ quest_god_player_level_hook(char *fmt)
return FALSE;
}
-static bool_ quest_god_get_hook(char *fmt)
+static bool_ quest_god_get_hook(void *, void *in_, void *)
{
- s32b item;
- object_type *o_ptr = NULL;
+ hook_get_in *in = static_cast<hook_get_in *>(in_);
- get_next_arg("d"); /* ignore first arg */
- item = get_next_arg("d");
+ s32b item = -in->o_idx; /* Note the negation */
- item = -item; /* Workaround */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* -- Is it the relic, and check to make sure the relic hasn't already been identified */
if ((cquest.status == QUEST_STATUS_TAKEN) &&
@@ -1040,8 +1054,11 @@ static bool_ quest_god_get_hook(char *fmt)
return FALSE;
}
-static bool_ quest_god_char_dump_hook(char *fmt)
+static bool_ quest_god_char_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest_quests_given > 0)
{
int relics = cquest_relics_found;
@@ -1067,9 +1084,7 @@ static bool_ quest_god_char_dump_hook(char *fmt)
}
}
- fprintf(hook_file, "\n You found %s of the relic pieces%s.",
- relics_text,
- append_text);
+ fprintf(f, "\n You found %s of the relic pieces%s.", relics_text, append_text);
}
return FALSE;
@@ -1141,26 +1156,26 @@ static void quest_god_dungeon_setup(int d_idx)
set_god_dungeon_attributes();
}
-static bool_ quest_god_enter_dungeon_hook(char *fmt)
+static bool_ quest_god_enter_dungeon_hook(void *, void *in_, void *)
{
- s32b d_idx = get_next_arg(fmt);
- quest_god_dungeon_setup(d_idx);
+ struct hook_enter_dungeon_in *in = static_cast<struct hook_enter_dungeon_in *>(in_);
+ quest_god_dungeon_setup(in->d_idx);
return FALSE;
}
-static bool_ quest_god_gen_level_begin_hook(char *fmt)
+static bool_ quest_god_gen_level_begin_hook(void *, void *, void *)
{
quest_god_dungeon_setup(dungeon_type);
return FALSE;
}
-static bool_ quest_god_stair_hook(char *fmt)
+static bool_ quest_god_stair_hook(void *, void *, void *)
{
quest_god_dungeon_setup(dungeon_type);
return FALSE;
}
-static bool_ quest_god_birth_objects_hook(char *fmt)
+static bool_ quest_god_birth_objects_hook(void *, void *, void *)
{
cquest_quests_given = 0;
cquest_relics_found = 0;
@@ -1179,18 +1194,18 @@ bool_ quest_god_init_hook(int q)
if ((cquest.status >= QUEST_STATUS_UNTAKEN) &&
(cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_LEVEL_END_GEN, quest_god_level_end_gen_hook, "q_god_level_end_gen");
- add_hook(HOOK_ENTER_DUNGEON, quest_god_enter_dungeon_hook, "q_god_enter_dungeon");
- add_hook(HOOK_GEN_LEVEL_BEGIN, quest_god_gen_level_begin_hook, "q_god_gen_level_begin");
- add_hook(HOOK_STAIR, quest_god_stair_hook, "q_god_hook_stair");
- add_hook(HOOK_GET, quest_god_get_hook, "q_god_get");
- add_hook(HOOK_CHAR_DUMP, quest_god_char_dump_hook, "q_god_char_dump");
- add_hook(HOOK_PLAYER_LEVEL, quest_god_player_level_hook, "q_god_player_level");
+ add_hook_new(HOOK_LEVEL_END_GEN, quest_god_level_end_gen_hook, "q_god_level_end_gen", NULL);
+ add_hook_new(HOOK_ENTER_DUNGEON, quest_god_enter_dungeon_hook, "q_god_enter_dungeon", NULL);
+ add_hook_new(HOOK_GEN_LEVEL_BEGIN, quest_god_gen_level_begin_hook, "q_god_gen_level_begin", NULL);
+ add_hook_new(HOOK_STAIR, quest_god_stair_hook, "q_god_hook_stair", NULL);
+ add_hook_new(HOOK_GET, quest_god_get_hook, "q_god_get", NULL);
+ add_hook_new(HOOK_CHAR_DUMP, quest_god_char_dump_hook, "q_god_char_dump", NULL);
+ add_hook_new(HOOK_PLAYER_LEVEL, quest_god_player_level_hook, "q_god_player_level", NULL);
}
/* Need this to re-initialize at birth; the quest data is
* zeroed which isn't quite right. */
- add_hook(HOOK_BIRTH_OBJECTS, quest_god_birth_objects_hook, "q_god_birth_objects");
+ add_hook_new(HOOK_BIRTH_OBJECTS, quest_god_birth_objects_hook, "q_god_birth_objects", NULL);
return FALSE;
}
diff --git a/src/q_god.hpp b/src/q_god.hpp
new file mode 100644
index 00000000..d9513bdb
--- /dev/null
+++ b/src/q_god.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_god_describe(FILE *);
+bool_ quest_god_init_hook(int q);
diff --git a/src/q_haunted.c b/src/q_haunted.cc
index db8992bc..cbfaa176 100644
--- a/src/q_haunted.c
+++ b/src/q_haunted.cc
@@ -1,7 +1,22 @@
-#undef cquest
+#include "q_haunted.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "traps.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_HAUNTED])
-bool_ quest_haunted_gen_hook(char *fmt)
+static bool_ quest_haunted_gen_hook(void *, void *, void *)
{
int x, y, i, m_idx;
int xstart = 2;
@@ -86,7 +101,7 @@ bool_ quest_haunted_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_haunted_death_hook(char *fmt)
+static bool_ quest_haunted_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -108,8 +123,9 @@ bool_ quest_haunted_death_hook(char *fmt)
if (mcnt <= 1)
{
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_haunted_death_hook);
- del_hook(HOOK_GEN_QUEST, quest_haunted_gen_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_haunted_death_hook);
+ del_hook_new(HOOK_GEN_QUEST, quest_haunted_gen_hook);
process_hooks_restart = TRUE;
cmsg_print(TERM_YELLOW, "Minas Anor is safer now.");
@@ -118,11 +134,10 @@ bool_ quest_haunted_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_haunted_finish_hook(char *fmt)
+static bool_ quest_haunted_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_HAUNTED) return FALSE;
@@ -139,9 +154,9 @@ bool_ quest_haunted_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_haunted_death_hook, "haunted_monster_death");
- add_hook(HOOK_QUEST_FINISH, quest_haunted_finish_hook, "haunted_finish");
- add_hook(HOOK_GEN_QUEST, quest_haunted_gen_hook, "haunted_geb");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_haunted_death_hook, "haunted_monster_death", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_haunted_finish_hook, "haunted_finish", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_haunted_gen_hook, "haunted_geb", NULL);
}
return (FALSE);
}
diff --git a/src/q_haunted.hpp b/src/q_haunted.hpp
new file mode 100644
index 00000000..4f51bce3
--- /dev/null
+++ b/src/q_haunted.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_haunted_init_hook(int q_idx);
diff --git a/src/q_hobbit.c b/src/q_hobbit.cc
index b80638ad..bc3659e9 100644
--- a/src/q_hobbit.c
+++ b/src/q_hobbit.cc
@@ -1,12 +1,34 @@
-#undef cquest
+#include "q_hobbit.hpp"
+
+#include "cave.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_chat_in.hpp"
+#include "hook_give_in.hpp"
+#include "hook_mon_speak_in.hpp"
+#include "hook_wild_gen_in.hpp"
+#include "hooks.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_HOBBIT])
-bool_ quest_hobbit_town_gen_hook(char *fmt)
+GENERATE_MONSTER_LOOKUP_FN(get_melinda_proudfoot, "Melinda Proudfoot")
+GENERATE_MONSTER_LOOKUP_FN(get_merton_proudfoot, "Merton Proudfoot, the lost hobbit")
+
+static bool_ quest_hobbit_town_gen_hook(void *, void *in_, void *)
{
+ struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
int x = 1, y = 1, tries = 10000;
- s32b small;
-
- small = get_next_arg(fmt);
+ bool_ small = in->small;
if ((turn < (cquest.data[1] + (DAY * 10L))) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) return (FALSE);
@@ -27,13 +49,15 @@ bool_ quest_hobbit_town_gen_hook(char *fmt)
}
/* Place Melinda */
- m_allow_special[test_monster_name("Melinda Proudfoot")] = TRUE;
- place_monster_one(y, x, test_monster_name("Melinda Proudfoot"), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[test_monster_name("Melinda Proudfoot")] = FALSE;
+ int r_idx = get_melinda_proudfoot();
+ m_allow_special[r_idx] = TRUE;
+ place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = FALSE;
return FALSE;
}
-bool_ quest_hobbit_gen_hook(char *fmt)
+
+static bool_ quest_hobbit_gen_hook(void *, void *, void *)
{
int x = 1, y = 1, tries = 10000;
@@ -54,25 +78,26 @@ bool_ quest_hobbit_gen_hook(char *fmt)
}
/* Place the hobbit */
- m_allow_special[test_monster_name("Merton Proudfoot, the lost hobbit")] = TRUE;
- place_monster_one(y, x, test_monster_name("Merton Proudfoot, the lost hobbit"), 0, FALSE, MSTATUS_FRIEND);
- m_allow_special[test_monster_name("Merton Proudfoot, the lost hobbit")] = FALSE;
+ int r_idx = get_merton_proudfoot();
+ m_allow_special[r_idx] = TRUE;
+ place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_allow_special[r_idx] = FALSE;
return FALSE;
}
-bool_ quest_hobbit_give_hook(char *fmt)
+
+static bool_ quest_hobbit_give_hook(void *, void *in_, void *)
{
+ struct hook_give_in *in = static_cast<struct hook_give_in *>(in_);
object_type *o_ptr;
monster_type *m_ptr;
- s32b m_idx, item;
-
- m_idx = get_next_arg(fmt);
- item = get_next_arg(fmt);
+ s32b m_idx = in->m_idx;
+ s32b item = in->item;
o_ptr = &p_ptr->inventory[item];
m_ptr = &m_list[m_idx];
- if (m_ptr->r_idx != test_monster_name("Merton Proudfoot, the lost hobbit")) return (FALSE);
+ if (m_ptr->r_idx != get_merton_proudfoot()) return (FALSE);
if ((o_ptr->tval != TV_SCROLL) || (o_ptr->sval != SV_SCROLL_WORD_OF_RECALL)) return (FALSE);
@@ -85,37 +110,38 @@ bool_ quest_hobbit_give_hook(char *fmt)
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_GIVE, quest_hobbit_give_hook);
+ del_hook_new(HOOK_GIVE, quest_hobbit_give_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_hobbit_speak_hook(char *fmt)
+
+static bool_ quest_hobbit_speak_hook(void *, void *in_, void *)
{
- s32b m_idx = get_next_arg(fmt);
+ struct hook_mon_speak_in *in = static_cast<struct hook_mon_speak_in *>(in_);
+ s32b m_idx = in->m_idx;
- if (m_list[m_idx].r_idx != test_monster_name("Melinda Proudfoot")) return (FALSE);
+ if (m_list[m_idx].r_idx != get_melinda_proudfoot())
+ {
+ return (FALSE);
+ }
if (cquest.status < QUEST_STATUS_COMPLETED)
{
- cptr m_name;
-
- m_name = get_next_arg_str(fmt);
-
- msg_format("%^s begs for your help.", m_name);
+ msg_format("%^s begs for your help.", in->m_name);
}
return (TRUE);
}
-bool_ quest_hobbit_chat_hook(char *fmt)
+
+static bool_ quest_hobbit_chat_hook(void *, void *in_, void *)
{
+ struct hook_chat_in *in = static_cast<struct hook_chat_in *>(in_);
+ s32b m_idx = in->m_idx;
monster_type *m_ptr;
- s32b m_idx;
-
- m_idx = get_next_arg(fmt);
m_ptr = &m_list[m_idx];
- if (m_ptr->r_idx != test_monster_name("Melinda Proudfoot")) return (FALSE);
+ if (m_ptr->r_idx != get_melinda_proudfoot()) return (FALSE);
if (cquest.status < QUEST_STATUS_COMPLETED)
{
@@ -145,7 +171,7 @@ bool_ quest_hobbit_chat_hook(char *fmt)
cquest.status = QUEST_STATUS_FINISHED;
- del_hook(HOOK_MON_SPEAK, quest_hobbit_speak_hook);
+ del_hook_new(HOOK_MON_SPEAK, quest_hobbit_speak_hook);
process_hooks_restart = TRUE;
delete_monster_idx(m_idx);
@@ -158,14 +184,19 @@ bool_ quest_hobbit_chat_hook(char *fmt)
return TRUE;
}
-bool_ quest_hobbit_dump_hook(char *fmt)
+
+static bool_ quest_hobbit_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status >= QUEST_STATUS_COMPLETED)
{
- fprintf(hook_file, "\n You saved a young hobbit from an horrible fate.");
+ fprintf(f, "\n You saved a young hobbit from an horrible fate.");
}
return (FALSE);
}
+
bool_ quest_hobbit_init_hook(int q_idx)
{
/* Get a level to place the hobbit */
@@ -181,18 +212,18 @@ bool_ quest_hobbit_init_hook(int q_idx)
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_GIVE, quest_hobbit_give_hook, "hobbit_give");
- add_hook(HOOK_GEN_LEVEL, quest_hobbit_gen_hook, "hobbit_gen");
- add_hook(HOOK_WILD_GEN, quest_hobbit_town_gen_hook, "hobbit_town_gen");
- add_hook(HOOK_CHAT, quest_hobbit_chat_hook, "hobbit_chat");
- add_hook(HOOK_MON_SPEAK, quest_hobbit_speak_hook, "hobbit_speak");
+ add_hook_new(HOOK_GIVE, quest_hobbit_give_hook, "hobbit_give", NULL);
+ add_hook_new(HOOK_GEN_LEVEL, quest_hobbit_gen_hook, "hobbit_gen", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_hobbit_town_gen_hook, "hobbit_town_gen", NULL);
+ add_hook_new(HOOK_CHAT, quest_hobbit_chat_hook, "hobbit_chat", NULL);
+ add_hook_new(HOOK_MON_SPEAK, quest_hobbit_speak_hook, "hobbit_speak", NULL);
}
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
- add_hook(HOOK_MON_SPEAK, quest_hobbit_speak_hook, "hobbit_speak");
- add_hook(HOOK_WILD_GEN, quest_hobbit_town_gen_hook, "hobbit_town_gen");
- add_hook(HOOK_CHAT, quest_hobbit_chat_hook, "hobbit_chat");
+ add_hook_new(HOOK_MON_SPEAK, quest_hobbit_speak_hook, "hobbit_speak", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_hobbit_town_gen_hook, "hobbit_town_gen", NULL);
+ add_hook_new(HOOK_CHAT, quest_hobbit_chat_hook, "hobbit_chat", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_hobbit_dump_hook, "hobbit_dump");
+ add_hook_new(HOOK_CHAR_DUMP, quest_hobbit_dump_hook, "hobbit_dump", NULL);
return (FALSE);
}
diff --git a/src/q_hobbit.hpp b/src/q_hobbit.hpp
new file mode 100644
index 00000000..b1878748
--- /dev/null
+++ b/src/q_hobbit.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_hobbit_init_hook(int q_idx);
diff --git a/src/q_invas.c b/src/q_invas.cc
index 985062af..64483d28 100644
--- a/src/q_invas.c
+++ b/src/q_invas.cc
@@ -1,7 +1,25 @@
-#undef cquest
+#include "q_invas.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_monster_ai_in.hpp"
+#include "hook_monster_ai_out.hpp"
+#include "hook_stair_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_INVASION])
-bool_ quest_invasion_gen_hook(char *fmt)
+static bool_ quest_invasion_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -43,13 +61,13 @@ bool_ quest_invasion_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_invasion_ai_hook(char *fmt)
-{
- monster_type *m_ptr;
- s32b m_idx;
- m_idx = get_next_arg(fmt);
- m_ptr = &m_list[m_idx];
+static bool_ quest_invasion_ai_hook(void *, void *in_, void *out_)
+{
+ struct hook_monster_ai_in *in = static_cast<struct hook_monster_ai_in *>(in_);
+ struct hook_monster_ai_out *out = static_cast<struct hook_monster_ai_out *>(out_);
+ monster_type *m_ptr = in->m_ptr;
+ s32b m_idx = in->m_idx;
if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;
@@ -74,15 +92,16 @@ bool_ quest_invasion_ai_hook(char *fmt)
}
else
{
- process_hooks_return[0].num = cquest.data[0];
- process_hooks_return[1].num = cquest.data[1];
+ out->y = cquest.data[0];
+ out->x = cquest.data[1];
return (TRUE);
}
}
return (FALSE);
}
-bool_ quest_invasion_turn_hook(char *fmt)
+
+static bool_ quest_invasion_turn_hook(void *, void *, void *)
{
if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE);
if (p_ptr->lev < 45) return (FALSE);
@@ -102,28 +121,33 @@ bool_ quest_invasion_turn_hook(char *fmt)
cquest.status = QUEST_STATUS_TAKEN;
quest_invasion_init_hook(QUEST_INVASION);
- del_hook(HOOK_END_TURN, quest_invasion_turn_hook);
+ del_hook_new(HOOK_END_TURN, quest_invasion_turn_hook);
process_hooks_restart = TRUE;
+
return (FALSE);
}
-bool_ quest_invasion_dump_hook(char *fmt)
+
+static bool_ quest_invasion_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status == QUEST_STATUS_FAILED)
{
- fprintf(hook_file, "\n You abandoned Gondolin when it most needed you, thus causing its destruction.");
+ fprintf(f, "\n You abandoned Gondolin when it most needed you, thus causing its destruction.");
}
if ((cquest.status == QUEST_STATUS_FINISHED) || (cquest.status == QUEST_STATUS_REWARDED) || (cquest.status == QUEST_STATUS_COMPLETED))
{
- fprintf(hook_file, "\n You saved Gondolin from destruction.");
+ fprintf(f, "\n You saved Gondolin from destruction.");
}
return (FALSE);
}
-bool_ quest_invasion_death_hook(char *fmt)
-{
- s32b r_idx, m_idx;
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
+static bool_ quest_invasion_death_hook(void *, void *in_, void *)
+{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;
@@ -131,24 +155,25 @@ bool_ quest_invasion_death_hook(char *fmt)
{
cmsg_print(TERM_YELLOW, "You did it! Gondolin will remain hidden.");
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_invasion_death_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_invasion_death_hook);
process_hooks_restart = TRUE;
+
return (FALSE);
}
return FALSE;
}
-bool_ quest_invasion_stair_hook(char *fmt)
-{
- cptr down;
- down = get_next_arg_str(fmt);
+static bool_ quest_invasion_stair_hook(void *, void *in_, void *)
+{
+ struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_);
if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;
if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return TRUE;
- if (!strcmp(down, "up"))
+ if (in->direction == STAIRS_UP)
{
if (cquest.status == QUEST_STATUS_FAILED)
{
@@ -174,23 +199,24 @@ bool_ quest_invasion_stair_hook(char *fmt)
cquest.status = QUEST_STATUS_FAILED;
town_info[2].destroyed = TRUE;
}
- del_hook(HOOK_STAIR, quest_invasion_stair_hook);
+ del_hook_new(HOOK_STAIR, quest_invasion_stair_hook);
process_hooks_restart = TRUE;
return (FALSE);
}
return TRUE;
}
+
bool_ quest_invasion_init_hook(int q_idx)
{
- add_hook(HOOK_END_TURN, quest_invasion_turn_hook, "invasion_turn");
- add_hook(HOOK_CHAR_DUMP, quest_invasion_dump_hook, "invasion_dump");
+ add_hook_new(HOOK_END_TURN, quest_invasion_turn_hook, "invasion_turn", NULL);
+ add_hook_new(HOOK_CHAR_DUMP, quest_invasion_dump_hook, "invasion_dump", NULL);
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_AI, quest_invasion_ai_hook, "invasion_ai");
- add_hook(HOOK_GEN_QUEST, quest_invasion_gen_hook, "invasion_gen");
- add_hook(HOOK_MONSTER_DEATH, quest_invasion_death_hook, "invasion_death");
- add_hook(HOOK_STAIR, quest_invasion_stair_hook, "invasion_stair");
+ add_hook_new(HOOK_MONSTER_AI, quest_invasion_ai_hook, "invasion_ai", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_invasion_gen_hook, "invasion_gen", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_invasion_death_hook, "invasion_death", NULL);
+ add_hook_new(HOOK_STAIR, quest_invasion_stair_hook, "invasion_stair", NULL);
}
return (FALSE);
}
diff --git a/src/q_invas.hpp b/src/q_invas.hpp
new file mode 100644
index 00000000..87b8fc77
--- /dev/null
+++ b/src/q_invas.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_invasion_init_hook(int q_idx);
diff --git a/src/q_library.c b/src/q_library.cc
index bbbcae4c..979fbb2f 100644
--- a/src/q_library.c
+++ b/src/q_library.cc
@@ -1,4 +1,23 @@
-#undef cquest
+#include "q_library.hpp"
+
+#include "cave_type.hpp"
+#include "hooks.hpp"
+#include "lua_bind.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "spells3.hpp"
+#include "spells4.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_LIBRARY])
#define print_hook(fmt,...) do { fprintf(hook_file, fmt, ##__VA_ARGS__); } while (0)
@@ -141,7 +160,7 @@ static void quest_library_finalize_book()
int i = 0;
for (i = 1; i <= 3; i++)
{
- school_book_type *school_book = school_books_at(BOOK_PLAYER);
+ school_book *school_book = school_books_at(BOOK_PLAYER);
school_book_add_spell(school_book, library_quest_book_get_slot(i));
}
}
@@ -243,7 +262,6 @@ static void library_quest_fill_book()
library_quest_print_spells(first, current);
- inkey_scan = FALSE;
ch = inkey();
dir = get_keymap_dir(ch);
@@ -294,7 +312,7 @@ static void library_quest_fill_book()
screen_load();
}
-static bool_ quest_library_gen_hook()
+static bool_ quest_library_gen_hook(void *, void *, void *)
{
/* Only if player doing this quest */
if (p_ptr->inside_quest != QUEST_LIBRARY)
@@ -337,7 +355,7 @@ static bool_ quest_library_gen_hook()
return TRUE;
}
-static bool_ quest_library_stair_hook()
+static bool_ quest_library_stair_hook(void *, void *, void *)
{
bool_ ret;
@@ -373,7 +391,7 @@ static bool_ quest_library_stair_hook()
}
}
-static bool_ quest_library_monster_death_hook(char *fmt)
+static bool_ quest_library_monster_death_hook(void *, void *, void *)
{
int i, count = -1;
@@ -490,9 +508,9 @@ bool_ quest_library_init_hook(int q)
if ((cquest.status >= QUEST_STATUS_UNTAKEN) &&
(cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_GEN_QUEST , quest_library_gen_hook , "library_gen_hook");
- add_hook(HOOK_STAIR , quest_library_stair_hook , "library_stair_hook");
- add_hook(HOOK_MONSTER_DEATH, quest_library_monster_death_hook, "library_monster_death_hook");
+ add_hook_new(HOOK_GEN_QUEST , quest_library_gen_hook , "library_gen_hook", NULL);
+ add_hook_new(HOOK_STAIR , quest_library_stair_hook , "library_stair_hook", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_library_monster_death_hook, "library_monster_death_hook", NULL);
}
/* If quest was rewarded we need to initialize the real player's spellbook. */
diff --git a/src/q_library.hpp b/src/q_library.hpp
new file mode 100644
index 00000000..8150893e
--- /dev/null
+++ b/src/q_library.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_library_init_hook(int q);
+bool_ quest_library_describe(FILE *fff);
+void quest_library_building(bool_ *paid, bool_ *recreate);
+void initialize_bookable_spells();
diff --git a/src/q_main.c b/src/q_main.cc
index a13b0790..ed11b9dc 100644
--- a/src/q_main.c
+++ b/src/q_main.cc
@@ -1,26 +1,55 @@
-bool_ quest_main_monsters_hook(char *fmt)
+#include "q_main.hpp"
+
+#include "hook_chardump_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_new_monster_in.hpp"
+#include "hooks.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
+GENERATE_MONSTER_LOOKUP_FN(get_necromancer, "The Necromancer of Dol Guldur")
+GENERATE_MONSTER_LOOKUP_FN(get_sauron, "Sauron, the Sorcerer")
+GENERATE_MONSTER_LOOKUP_FN(get_morgoth, "Morgoth, Lord of Darkness")
+
+static void quest_describe(int q_idx)
{
- s32b r_idx;
- r_idx = get_next_arg(fmt);
+ int i = 0;
+
+ while ((i < 10) && (quest[q_idx].desc[i][0] != '\0'))
+ {
+ cmsg_print(TERM_YELLOW, quest[q_idx].desc[i++]);
+ }
+}
+
+static bool_ quest_main_monsters_hook(void *, void *in_, void *)
+{
+ struct hook_new_monster_in *in = static_cast<struct hook_new_monster_in *>(in_);
+ s32b r_idx = in->r_idx;
/* Sauron */
- if (r_idx == 860)
+ if (r_idx == get_sauron())
{
/* No Sauron until Necromancer dies */
- if (r_info[819].max_num) return TRUE;
+ if (r_info[get_necromancer()].max_num) return TRUE;
}
/* Morgoth */
- else if (r_idx == 862)
+ else if (r_idx == get_morgoth())
{
/* No Morgoth until Sauron dies */
- if (r_info[860].max_num) return TRUE;
+ if (r_info[get_sauron()].max_num) return TRUE;
}
return FALSE;
}
-bool_ quest_morgoth_hook(char *fmt)
+
+static bool_ quest_morgoth_hook(void *, void *, void *)
{
- /* Using test_monster_name() here would be a lot less ugly, but would take much more time */
- monster_race *r_ptr = &r_info[862];
+ monster_race *r_ptr = &r_info[get_morgoth()];
/* Need to kill him */
if (!r_ptr->max_num)
@@ -31,7 +60,7 @@ bool_ quest_morgoth_hook(char *fmt)
quest[QUEST_MORGOTH].status = QUEST_STATUS_FINISHED;
/* Redraw the "title" */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Congratulations */
if (quest[QUEST_ONE].status == QUEST_STATUS_FINISHED)
@@ -55,7 +84,7 @@ bool_ quest_morgoth_hook(char *fmt)
}
/* Continue the plot(maybe) */
- del_hook(HOOK_MONSTER_DEATH, quest_morgoth_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_morgoth_hook);
process_hooks_restart = TRUE;
/* Either ultra good if the one Ring is destroyed, or ultra evil if used */
@@ -67,32 +96,36 @@ bool_ quest_morgoth_hook(char *fmt)
}
return (FALSE);
}
-bool_ quest_morgoth_dump_hook(char *fmt)
+
+static bool_ quest_morgoth_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (quest[QUEST_MORGOTH].status >= QUEST_STATUS_COMPLETED)
{
if (quest[QUEST_ONE].status == QUEST_STATUS_FINISHED)
- fprintf(hook_file, "\n You saved Arda and became a famed %s.", sp_ptr->winner);
+ fprintf(f, "\n You saved Arda and became a famed %s.", sp_ptr->winner);
else
- fprintf(hook_file, "\n You became a new force of darkness and enslaved all free people.");
+ fprintf(f, "\n You became a new force of darkness and enslaved all free people.");
}
return (FALSE);
}
+
bool_ quest_morgoth_init_hook(int q_idx)
{
if ((quest[QUEST_MORGOTH].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_MORGOTH].status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_morgoth_hook, "morgort_death");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_morgoth_hook, "morgoth_death", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_morgoth_dump_hook, "morgoth_dump");
- add_hook(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster");
+ add_hook_new(HOOK_CHAR_DUMP, quest_morgoth_dump_hook, "morgoth_dump", NULL);
+ add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL);
return (FALSE);
}
-bool_ quest_sauron_hook(char *fmt)
+static bool_ quest_sauron_hook(void *, void *, void *)
{
- /* Using test_monster_name() here would be a lot less ugly, but would take much more time */
- monster_race *r_ptr = &r_info[860];
+ monster_race *r_ptr = &r_info[get_sauron()];
/* Need to kill him */
if (!r_ptr->max_num)
@@ -103,8 +136,8 @@ bool_ quest_sauron_hook(char *fmt)
quest[QUEST_MORGOTH].status = QUEST_STATUS_TAKEN;
quest_describe(QUEST_MORGOTH);
- del_hook(HOOK_MONSTER_DEATH, quest_sauron_hook);
- add_hook(HOOK_MONSTER_DEATH, quest_morgoth_hook, "morgort_death");
+ del_hook_new(HOOK_MONSTER_DEATH, quest_sauron_hook);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_morgoth_hook, "morgort_death", NULL);
*(quest[QUEST_SAURON].plot) = QUEST_MORGOTH;
quest_morgoth_init_hook(QUEST_MORGOTH);
@@ -113,18 +146,19 @@ bool_ quest_sauron_hook(char *fmt)
return (FALSE);
}
-bool_ quest_sauron_resurect_hook(char *fmt)
+static bool_ quest_sauron_resurect_hook(void *, void *in_, void *)
{
- s32b m_idx = get_next_arg(fmt);
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
monster_type *m_ptr = &m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if ((r_ptr->flags7 & RF7_NAZGUL) && r_info[860].max_num)
+ if ((r_ptr->flags7 & RF7_NAZGUL) && r_info[get_sauron()].max_num)
{
msg_format("Somehow you feel %s is not totally destroyed...", (r_ptr->flags1 & RF1_FEMALE ? "she" : "he"));
r_ptr->max_num = 1;
}
- else if ((m_ptr->r_idx == 860) && (quest[QUEST_ONE].status < QUEST_STATUS_FINISHED))
+ else if ((m_ptr->r_idx == get_sauron()) && (quest[QUEST_ONE].status < QUEST_STATUS_FINISHED))
{
msg_print("Sauron will not be permanently defeated until the One Ring is either destroyed or used...");
r_ptr->max_num = 1;
@@ -136,17 +170,16 @@ bool_ quest_sauron_init_hook(int q_idx)
{
if ((quest[QUEST_SAURON].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_SAURON].status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_sauron_hook, "sauron_death");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_sauron_hook, "sauron_death", NULL);
}
- add_hook(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster");
- add_hook(HOOK_MONSTER_DEATH, quest_sauron_resurect_hook, "sauron_resurect_death");
+ add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_sauron_resurect_hook, "sauron_resurect_death", NULL);
return (FALSE);
}
-bool_ quest_necro_hook(char *fmt)
+static bool_ quest_necro_hook(void *, void *, void *)
{
- /* Using test_monster_name() here would be a lot less ugly, but would take much more time */
- monster_race *r_ptr = &r_info[819];
+ monster_race *r_ptr = &r_info[get_necromancer()];
/* Need to kill him */
if (!r_ptr->max_num)
@@ -160,17 +193,18 @@ bool_ quest_necro_hook(char *fmt)
*(quest[QUEST_NECRO].plot) = QUEST_ONE;
quest[*(quest[QUEST_NECRO].plot)].init(*(quest[QUEST_NECRO].plot));
- del_hook(HOOK_MONSTER_DEATH, quest_necro_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_necro_hook);
process_hooks_restart = TRUE;
}
return (FALSE);
}
+
bool_ quest_necro_init_hook(int q_idx)
{
if ((quest[QUEST_NECRO].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_NECRO].status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_necro_hook, "necro_death");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_necro_hook, "necro_death", NULL);
}
- add_hook(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster");
+ add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL);
return (FALSE);
}
diff --git a/src/q_main.hpp b/src/q_main.hpp
new file mode 100644
index 00000000..a88530fc
--- /dev/null
+++ b/src/q_main.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_necro_init_hook(int q_idx);
+bool_ quest_sauron_init_hook(int q_idx);
+bool_ quest_morgoth_init_hook(int q_idx);
diff --git a/src/q_narsil.c b/src/q_narsil.cc
index 27ec218e..a6c0eed3 100644
--- a/src/q_narsil.c
+++ b/src/q_narsil.cc
@@ -1,17 +1,28 @@
-#undef cquest
+#include "q_narsil.hpp"
+
+#include "cave_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_identify_in.hpp"
+#include "hook_move_in.hpp"
+#include "hooks.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_NARSIL])
-bool_ quest_narsil_move_hook(char *fmt)
+static bool_ quest_narsil_move_hook(void *, void *in_, void *)
{
- s32b y, x;
- cave_type *c_ptr;
+ struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
+ s32b y = in->y;
+ s32b x = in->x;
+ cave_type *c_ptr = &cave[y][x];
int i;
object_type *o_ptr;
- y = get_next_arg(fmt);
- x = get_next_arg(fmt);
- c_ptr = &cave[y][x];
-
if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
/* The castle of Aragorn */
@@ -51,36 +62,35 @@ bool_ quest_narsil_move_hook(char *fmt)
/* Continue the plot */
cquest.status = QUEST_STATUS_FINISHED;
- del_hook(HOOK_MOVE, quest_narsil_move_hook);
+ del_hook_new(HOOK_MOVE, quest_narsil_move_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_narsil_dump_hook(char *fmt)
+
+static bool_ quest_narsil_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status >= QUEST_STATUS_COMPLETED)
{
- fprintf(hook_file, "\n The sword that was broken is now reforged.");
+ fprintf(f, "\n The sword that was broken is now reforged.");
}
return (FALSE);
}
-bool_ quest_narsil_identify_hook(char *fmt)
+
+static bool_ quest_narsil_identify_hook(void *, void *in_, void *)
{
+ struct hook_identify_in *in = static_cast<struct hook_identify_in *>(in_);
+
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
- int i;
- object_type *o_ptr;
- s32b item;
-
- item = get_next_arg(fmt);
-
- o_ptr = get_object(item);
-
- if (o_ptr->name1 == ART_NARSIL)
+ if (in->o_ptr->name1 == ART_NARSIL)
{
cquest.status = QUEST_STATUS_TAKEN;
- for (i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++)
{
if (quest[QUEST_NARSIL].desc[i][0] != '\0')
{
@@ -88,21 +98,25 @@ bool_ quest_narsil_identify_hook(char *fmt)
}
}
- add_hook(HOOK_MOVE, quest_narsil_move_hook, "narsil_move");
- del_hook(HOOK_IDENTIFY, quest_narsil_identify_hook);
+ add_hook_new(HOOK_MOVE, quest_narsil_move_hook, "narsil_move", NULL);
+ del_hook_new(HOOK_IDENTIFY, quest_narsil_identify_hook);
process_hooks_restart = TRUE;
}
}
return (FALSE);
}
+
bool_ quest_narsil_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MOVE, quest_narsil_move_hook, "narsil_move");
+ add_hook_new(HOOK_MOVE, quest_narsil_move_hook, "narsil_move", NULL);
+ }
+ if (cquest.status == QUEST_STATUS_UNTAKEN)
+ {
+ add_hook_new(HOOK_IDENTIFY, quest_narsil_identify_hook, "narsil_id", NULL);
}
- if (cquest.status == QUEST_STATUS_UNTAKEN) add_hook(HOOK_IDENTIFY, quest_narsil_identify_hook, "narsil_id");
- add_hook(HOOK_CHAR_DUMP, quest_narsil_dump_hook, "narsil_dump");
+ add_hook_new(HOOK_CHAR_DUMP, quest_narsil_dump_hook, "narsil_dump", NULL);
return (FALSE);
}
diff --git a/src/q_narsil.hpp b/src/q_narsil.hpp
new file mode 100644
index 00000000..b83e63cf
--- /dev/null
+++ b/src/q_narsil.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_narsil_init_hook(int q_idx);
diff --git a/src/q_nazgul.c b/src/q_nazgul.c
deleted file mode 100644
index 66d3dc98..00000000
--- a/src/q_nazgul.c
+++ /dev/null
@@ -1,116 +0,0 @@
-#undef cquest
-#define cquest (quest[QUEST_NAZGUL])
-
-bool_ quest_nazgul_gen_hook(char *fmt)
-{
- int m_idx, x = 1, y = 1, tries = 10000;
- s32b small;
-
- small = get_next_arg(fmt);
-
- if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1)) return (FALSE);
-
- /* Find a good position */
- while (tries)
- {
- /* Get a random spot */
- y = randint(cur_hgt - 4) + 2;
- x = randint(cur_wid - 4) + 2;
-
- /* Is it a good spot ? */
- /* Not in player los */
- if ((!los(p_ptr->py, p_ptr->px, y, x)) && cave_empty_bold(y, x)) break;
-
- /* One less try */
- tries--;
- }
-
- /* Place the nazgul */
- m_allow_special[test_monster_name("Uvatha the Horseman")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Uvatha the Horseman"), 0, FALSE, MSTATUS_ENEMY);
- if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[test_monster_name("Uvatha the Horseman")] = FALSE;
-
- return FALSE;
-}
-bool_ quest_nazgul_finish_hook(char *fmt)
-{
- object_type forge, *q_ptr;
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
-
- if (q_idx != QUEST_NAZGUL) return FALSE;
-
- c_put_str(TERM_YELLOW, "I believe he will not come back! Thank you.", 8, 0);
- c_put_str(TERM_YELLOW, "Some time ago a ranger gave me this.", 9, 0);
- c_put_str(TERM_YELLOW, "I believe it will help you on your quest.", 10, 0);
-
- q_ptr = &forge;
- object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_ATHELAS));
- q_ptr->found = OBJ_FOUND_REWARD;
- q_ptr->number = 6;
- object_aware(q_ptr);
- object_known(q_ptr);
- q_ptr->ident |= IDENT_STOREB;
- (void)inven_carry(q_ptr, FALSE);
-
- /* End the plot */
- *(quest[q_idx].plot) = QUEST_NULL;
-
- del_hook(HOOK_QUEST_FINISH, quest_nazgul_finish_hook);
- process_hooks_restart = TRUE;
-
- return TRUE;
-}
-bool_ quest_nazgul_dump_hook(char *fmt)
-{
- if (cquest.status >= QUEST_STATUS_COMPLETED)
- {
- fprintf(hook_file, "\n You saved Bree from a dreadful Nazgul.");
- }
- return (FALSE);
-}
-bool_ quest_nazgul_forbid_hook(char *fmt)
-{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
-
- if (q_idx != QUEST_NAZGUL) return (FALSE);
-
- if (p_ptr->lev < 30)
- {
- c_put_str(TERM_WHITE, "I fear you are not ready for the next quest, come back later.", 8, 0);
- return (TRUE);
- }
- return (FALSE);
-}
-bool_ quest_nazgul_death_hook(char *fmt)
-{
- s32b r_idx, m_idx;
-
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
-
- if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE);
- if (r_idx != test_monster_name("Uvatha the Horseman")) return (FALSE);
-
- cquest.status = QUEST_STATUS_COMPLETED;
-
- del_hook(HOOK_MONSTER_DEATH, quest_nazgul_death_hook);
- process_hooks_restart = TRUE;
-
- return (FALSE);
-}
-bool_ quest_nazgul_init_hook(int q_idx)
-{
- if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
- {
- add_hook(HOOK_MONSTER_DEATH, quest_nazgul_death_hook, "nazgul_death");
- add_hook(HOOK_WILD_GEN, quest_nazgul_gen_hook, "nazgul_gen");
- add_hook(HOOK_QUEST_FINISH, quest_nazgul_finish_hook, "nazgul_finish");
- }
- add_hook(HOOK_CHAR_DUMP, quest_nazgul_dump_hook, "nazgul_dump");
- add_hook(HOOK_INIT_QUEST, quest_nazgul_forbid_hook, "nazgul_forbid");
- return (FALSE);
-}
diff --git a/src/q_nazgul.cc b/src/q_nazgul.cc
new file mode 100644
index 00000000..21bc95c9
--- /dev/null
+++ b/src/q_nazgul.cc
@@ -0,0 +1,144 @@
+#include "q_nazgul.hpp"
+
+#include "cave.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_init_quest_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hook_wild_gen_in.hpp"
+#include "hooks.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
+#define cquest (quest[QUEST_NAZGUL])
+
+GENERATE_MONSTER_LOOKUP_FN(get_uvatha, "Uvatha the Horseman")
+
+static bool_ quest_nazgul_gen_hook(void *, void *in_, void *)
+{
+ struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
+ int m_idx, x = 1, y = 1, tries = 10000;
+ bool_ small = in->small;
+
+ if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1)) return (FALSE);
+
+ /* Find a good position */
+ while (tries)
+ {
+ /* Get a random spot */
+ y = randint(cur_hgt - 4) + 2;
+ x = randint(cur_wid - 4) + 2;
+
+ /* Is it a good spot ? */
+ /* Not in player los */
+ if ((!los(p_ptr->py, p_ptr->px, y, x)) && cave_empty_bold(y, x)) break;
+
+ /* One less try */
+ tries--;
+ }
+
+ /* Place the nazgul */
+ int r_idx = get_uvatha();
+
+ m_allow_special[r_idx] = TRUE;
+ m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[r_idx] = FALSE;
+
+ if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
+
+ return FALSE;
+}
+
+static bool_ quest_nazgul_finish_hook(void *, void *in_, void *)
+{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
+ object_type forge, *q_ptr;
+
+ if (q_idx != QUEST_NAZGUL) return FALSE;
+
+ c_put_str(TERM_YELLOW, "I believe he will not come back! Thank you.", 8, 0);
+ c_put_str(TERM_YELLOW, "Some time ago a ranger gave me this.", 9, 0);
+ c_put_str(TERM_YELLOW, "I believe it will help you on your quest.", 10, 0);
+
+ q_ptr = &forge;
+ object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_ATHELAS));
+ q_ptr->found = OBJ_FOUND_REWARD;
+ q_ptr->number = 6;
+ object_aware(q_ptr);
+ object_known(q_ptr);
+ q_ptr->ident |= IDENT_STOREB;
+ (void)inven_carry(q_ptr, FALSE);
+
+ /* End the plot */
+ *(quest[q_idx].plot) = QUEST_NULL;
+
+ del_hook_new(HOOK_QUEST_FINISH, quest_nazgul_finish_hook);
+ process_hooks_restart = TRUE;
+
+ return TRUE;
+}
+
+static bool_ quest_nazgul_dump_hook(void *, void *in_, void *)
+{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
+ if (cquest.status >= QUEST_STATUS_COMPLETED)
+ {
+ fprintf(f, "\n You saved Bree from a dreadful Nazgul.");
+ }
+ return (FALSE);
+}
+
+static bool_ quest_nazgul_forbid_hook(void *, void *in_, void *)
+{
+ struct hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_);
+ s32b q_idx = in->q_idx;
+
+ if (q_idx != QUEST_NAZGUL) return (FALSE);
+
+ if (p_ptr->lev < 30)
+ {
+ c_put_str(TERM_WHITE, "I fear you are not ready for the next quest, come back later.", 8, 0);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+static bool_ quest_nazgul_death_hook(void *, void *in_, void *)
+{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
+
+ if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE);
+ if (r_idx != get_uvatha()) return (FALSE);
+
+ cquest.status = QUEST_STATUS_COMPLETED;
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_nazgul_death_hook);
+ process_hooks_restart = TRUE;
+
+ return (FALSE);
+}
+
+bool_ quest_nazgul_init_hook(int q_idx)
+{
+ if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
+ {
+ add_hook_new(HOOK_MONSTER_DEATH, quest_nazgul_death_hook, "nazgul_death", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_nazgul_gen_hook, "nazgul_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_nazgul_finish_hook, "nazgul_finish", NULL);
+ }
+ add_hook_new(HOOK_CHAR_DUMP, quest_nazgul_dump_hook, "nazgul_dump", NULL);
+ add_hook_new(HOOK_INIT_QUEST, quest_nazgul_forbid_hook, "nazgul_forbid", NULL);
+ return (FALSE);
+}
diff --git a/src/q_nazgul.hpp b/src/q_nazgul.hpp
new file mode 100644
index 00000000..32e3237c
--- /dev/null
+++ b/src/q_nazgul.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_nazgul_init_hook(int q_idx);
diff --git a/src/q_nirna.c b/src/q_nirna.cc
index be856d31..a92ba6e4 100644
--- a/src/q_nirna.c
+++ b/src/q_nirna.cc
@@ -1,7 +1,19 @@
-#undef cquest
+#include "q_nirna.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_NIRNAETH])
-bool_ quest_nirnaeth_gen_hook(char *fmt)
+static bool_ quest_nirnaeth_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -39,11 +51,11 @@ bool_ quest_nirnaeth_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_nirnaeth_finish_hook(char *fmt)
-{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+static bool_ quest_nirnaeth_finish_hook(void *, void *in_, void *)
+{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_NIRNAETH) return FALSE;
@@ -57,7 +69,7 @@ bool_ quest_nirnaeth_finish_hook(char *fmt)
p_ptr->au += 200000;
/* Redraw gold */
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -71,12 +83,13 @@ bool_ quest_nirnaeth_finish_hook(char *fmt)
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
- del_hook(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_nirnaeth_death_hook(char *fmt)
+
+static bool_ quest_nirnaeth_death_hook(void *, void *, void *)
{
if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE;
@@ -84,7 +97,8 @@ bool_ quest_nirnaeth_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_nirnaeth_stair_hook(char *fmt)
+
+static bool_ quest_nirnaeth_stair_hook(void *, void *, void *)
{
if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE;
@@ -92,18 +106,20 @@ bool_ quest_nirnaeth_stair_hook(char *fmt)
cmsg_print(TERM_YELLOW, "You found a way out!");
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_STAIR, quest_nirnaeth_stair_hook);
+
+ del_hook_new(HOOK_STAIR, quest_nirnaeth_stair_hook);
process_hooks_restart = TRUE;
return (FALSE);
}
+
bool_ quest_nirnaeth_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_nirnaeth_death_hook, "nirnaeth_death");
- add_hook(HOOK_GEN_QUEST, quest_nirnaeth_gen_hook, "nirnaeth_gen");
- add_hook(HOOK_STAIR, quest_nirnaeth_stair_hook, "nirnaeth_stair");
- add_hook(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook, "nirnaeth_finish");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_nirnaeth_death_hook, "nirnaeth_death", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_nirnaeth_gen_hook, "nirnaeth_gen", NULL);
+ add_hook_new(HOOK_STAIR, quest_nirnaeth_stair_hook, "nirnaeth_stair", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook, "nirnaeth_finish", NULL);
}
return (FALSE);
}
diff --git a/src/q_nirna.hpp b/src/q_nirna.hpp
new file mode 100644
index 00000000..24a8759f
--- /dev/null
+++ b/src/q_nirna.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_nirnaeth_init_hook(int q_idx);
diff --git a/src/q_one.c b/src/q_one.cc
index 4bfeaf3e..1aa77610 100644
--- a/src/q_one.c
+++ b/src/q_one.cc
@@ -1,14 +1,36 @@
-#undef cquest
+#include "q_one.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "gods.hpp"
+#include "hook_calculate_hp_in.hpp"
+#include "hook_calculate_hp_out.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_drop_in.hpp"
+#include "hook_identify_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_move_in.hpp"
+#include "hook_wield_in.hpp"
+#include "hooks.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_ONE])
-bool_ quest_one_move_hook(char *fmt)
+static bool_ quest_one_move_hook(void *, void *in_, void *)
{
- s32b y, x;
- cave_type *c_ptr;
-
- y = get_next_arg(fmt);
- x = get_next_arg(fmt);
- c_ptr = &cave[y][x];
+ struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
+ s32b y = in->y;
+ s32b x = in->x;
+ cave_type *c_ptr = &cave[y][x];
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
@@ -25,22 +47,22 @@ bool_ quest_one_move_hook(char *fmt)
cmsg_print(TERM_YELLOW, "'and destroy it. I know it will tempt you, but *NEVER* use it'");
cmsg_print(TERM_YELLOW, "'or it will corrupt you forever.'");
- GOD(GOD_ERU)
+ if (p_ptr->pgod == GOD_ERU)
{
cmsg_print(TERM_YELLOW, "'Also, Eru will abandon you if you wear it.'");
}
- GOD(GOD_MANWE)
+ if (p_ptr->pgod == GOD_MANWE)
{
cmsg_print(TERM_YELLOW, "'Also, Manwe will abandon you if you wear it.'");
}
- GOD(GOD_TULKAS)
+ if (p_ptr->pgod == GOD_TULKAS)
{
cmsg_print(TERM_YELLOW, "'Also, Tulkas will abandon you if you wear it.'");
}
- GOD(GOD_YAVANNA)
+ if (p_ptr->pgod == GOD_YAVANNA)
{
cmsg_print(TERM_YELLOW, "'Also, Yavanna will abandon you if you wear it.'");
}
@@ -52,7 +74,7 @@ bool_ quest_one_move_hook(char *fmt)
cmsg_print(TERM_YELLOW, "'are other people that might know.'");
cmsg_print(TERM_YELLOW, "'Do not forget: the Ring must be cast back into the fires of Mount Doom!'");
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
cmsg_print(TERM_YELLOW, "'Melkor will abandon you when you do, but you must do it anyway!'");
}
@@ -66,13 +88,12 @@ bool_ quest_one_move_hook(char *fmt)
return FALSE;
}
-bool_ quest_one_drop_hook(char *fmt)
-{
- s32b o_idx;
- object_type *o_ptr;
- o_idx = get_next_arg(fmt);
- o_ptr = &p_ptr->inventory[o_idx];
+static bool_ quest_one_drop_hook(void *, void *in_, void *)
+{
+ struct hook_drop_in *in = static_cast<struct hook_drop_in *>(in_);
+ s32b o_idx = in->o_idx;
+ object_type *o_ptr = &p_ptr->inventory[o_idx];
if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
@@ -96,13 +117,11 @@ bool_ quest_one_drop_hook(char *fmt)
return TRUE;
}
-bool_ quest_one_wield_hook(char *fmt)
-{
- s32b o_idx;
- object_type *o_ptr;
- o_idx = get_next_arg(fmt);
- o_ptr = &p_ptr->inventory[o_idx];
+static bool_ quest_one_wield_hook(void *, void *in_, void *)
+{
+ struct hook_wield_in *in = static_cast<struct hook_wield_in *>(in_);
+ object_type *o_ptr = in->o_ptr;
if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
@@ -153,24 +172,26 @@ bool_ quest_one_wield_hook(char *fmt)
return FALSE;
}
-bool_ quest_one_hp_hook(char *fmt)
+
+static bool_ quest_one_hp_hook(void *, void *in_, void *out_)
{
+ struct hook_calculate_hp_in *in = static_cast<struct hook_calculate_hp_in *>(in_);
+ struct hook_calculate_hp_out *out = static_cast<struct hook_calculate_hp_out *>(out_);
+
if (cquest.status == QUEST_STATUS_FAILED_DONE)
{
- s32b mhp;
- int i;
+ s32b mhp = in->mhp;
- mhp = get_next_arg(fmt);
-
- for (i = 0; i < p_ptr->lives + 1; i++)
+ for (int i = 0; i < p_ptr->lives + 1; i++)
mhp = (mhp * 2) / 3;
- process_hooks_return[0].num = mhp;
+ out->mhp = mhp;
return (TRUE);
}
return (FALSE);
}
-bool_ quest_one_die_hook(char *fmt)
+
+static bool_ quest_one_die_hook(void *, void *, void *)
{
if (cquest.status == QUEST_STATUS_FAILED_DONE)
{
@@ -189,18 +210,14 @@ bool_ quest_one_die_hook(char *fmt)
}
return (FALSE);
}
-bool_ quest_one_identify_hook(char *fmt)
-{
- s32b item;
- item = get_next_arg(fmt);
+static bool_ quest_one_identify_hook(void *, void *in_, void *)
+{
+ struct hook_identify_in *in = static_cast<struct hook_identify_in *>(in_);
+ object_type *o_ptr = in->o_ptr;
if (cquest.status == QUEST_STATUS_TAKEN)
{
- object_type *o_ptr;
-
- o_ptr = get_object(item);
-
if ((o_ptr->name1 == ART_POWER) && (!object_known_p(o_ptr)))
{
cmsg_print(TERM_YELLOW, "You finally found the One Ring, source of Sauron's power, and key to");
@@ -211,14 +228,14 @@ bool_ quest_one_identify_hook(char *fmt)
return (FALSE);
}
-bool_ quest_one_death_hook(char *fmt)
+
+static bool_ quest_one_death_hook(void *, void *in_, void *)
{
- s32b r_idx, m_idx;
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
bool_ ok = FALSE;
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
-
if (a_info[ART_POWER].cur_num) return FALSE;
/* Paranoia */
@@ -291,19 +308,24 @@ bool_ quest_one_death_hook(char *fmt)
return (FALSE);
}
-bool_ quest_one_dump_hook(char *fmt)
+
+static bool_ quest_one_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status == QUEST_STATUS_FINISHED)
{
- fprintf(hook_file, "\n You destroyed the One Ring, thus weakening Sauron.");
+ fprintf(f, "\n You destroyed the One Ring, thus weakening Sauron.");
}
if (cquest.status == QUEST_STATUS_FAILED_DONE)
{
- fprintf(hook_file, "\n You fell under the evil influence of the One Ring and decided to wear it.");
+ fprintf(f, "\n You fell under the evil influence of the One Ring and decided to wear it.");
}
return (FALSE);
}
-bool_ quest_one_gen_hook(char *fmt)
+
+static bool_ quest_one_gen_hook(void *, void *, void *)
{
s32b x, y, tries = 10000;
@@ -333,22 +355,23 @@ bool_ quest_one_gen_hook(char *fmt)
return (FALSE);
}
+
bool_ quest_one_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_LEVEL_END_GEN, quest_one_gen_hook, "one_gen");
- add_hook(HOOK_MONSTER_DEATH, quest_one_death_hook, "one_death");
- add_hook(HOOK_DROP, quest_one_drop_hook, "one_drop");
- add_hook(HOOK_WIELD, quest_one_wield_hook, "one_wield");
- add_hook(HOOK_IDENTIFY, quest_one_identify_hook, "one_id");
+ add_hook_new(HOOK_LEVEL_END_GEN, quest_one_gen_hook, "one_gen", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_one_death_hook, "one_death", NULL);
+ add_hook_new(HOOK_DROP, quest_one_drop_hook, "one_drop", NULL);
+ add_hook_new(HOOK_WIELD, quest_one_wield_hook, "one_wield", NULL);
+ add_hook_new(HOOK_IDENTIFY, quest_one_identify_hook, "one_id", NULL);
}
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
- add_hook(HOOK_MOVE, quest_one_move_hook, "one_move");
+ add_hook_new(HOOK_MOVE, quest_one_move_hook, "one_move", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_one_dump_hook, "one_dump");
- add_hook(HOOK_CALC_HP, quest_one_hp_hook, "one_hp");
- add_hook(HOOK_DIE, quest_one_die_hook, "one_die");
+ add_hook_new(HOOK_CHAR_DUMP, quest_one_dump_hook, "one_dump", NULL);
+ add_hook_new(HOOK_CALC_HP, quest_one_hp_hook, "one_hp", NULL);
+ add_hook_new(HOOK_DIE, quest_one_die_hook, "one_die", NULL);
return (FALSE);
}
diff --git a/src/q_one.hpp b/src/q_one.hpp
new file mode 100644
index 00000000..a85a5733
--- /dev/null
+++ b/src/q_one.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_one_init_hook(int q_idx);
diff --git a/src/q_poison.c b/src/q_poison.cc
index 0c3987df..d8ecf949 100644
--- a/src/q_poison.c
+++ b/src/q_poison.cc
@@ -1,4 +1,23 @@
-#undef cquest
+#include "q_poison.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_drop_in.hpp"
+#include "hook_init_quest_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_POISON])
static int wild_locs[4][2] =
@@ -21,7 +40,7 @@ static bool_ create_molds_hook(int r_idx)
else return FALSE;
}
-bool_ quest_poison_gen_hook(char *fmt)
+static bool_ quest_poison_gen_hook(void *, void *, void *)
{
int cy = 1, cx = 1, x, y, tries = 10000, r_idx;
bool_ (*old_get_mon_num_hook)(int r_idx);
@@ -83,7 +102,7 @@ bool_ quest_poison_gen_hook(char *fmt)
if (m_ptr->level < p_ptr->lev)
{
- m_ptr->exp = MONSTER_EXP(m_ptr->level + randint(p_ptr->lev - m_ptr->level));
+ m_ptr->exp = monster_exp(m_ptr->level + randint(p_ptr->lev - m_ptr->level));
monster_check_experience(m_idx, TRUE);
}
}
@@ -98,12 +117,12 @@ bool_ quest_poison_gen_hook(char *fmt)
return FALSE;
}
-bool_ quest_poison_finish_hook(char *fmt)
+
+static bool_ quest_poison_finish_hook(void *, void *in_, void *)
{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
object_type forge, *q_ptr;
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
if (q_idx != QUEST_POISON) return FALSE;
@@ -124,25 +143,29 @@ bool_ quest_poison_finish_hook(char *fmt)
/* Continue the plot */
*(quest[q_idx].plot) = QUEST_NULL;
- del_hook(HOOK_QUEST_FINISH, quest_poison_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_poison_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_poison_dump_hook(char *fmt)
+
+static bool_ quest_poison_dump_hook(void *, void *in_, void *)
{
+ hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (cquest.status >= QUEST_STATUS_COMPLETED)
{
- fprintf(hook_file, "\n You saved the beautiful Mallorns of Lothlorien.");
+ fprintf(f, "\n You saved the beautiful Mallorns of Lothlorien.");
}
return (FALSE);
}
-bool_ quest_poison_quest_hook(char *fmt)
+
+static bool_ quest_poison_quest_hook(void *, void *in_, void *)
{
+ struct hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_);
+ s32b q_idx = in->q_idx;
object_type forge, *q_ptr;
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
if (q_idx != QUEST_POISON) return FALSE;
@@ -155,18 +178,18 @@ bool_ quest_poison_quest_hook(char *fmt)
q_ptr->note = quark_add("quest");
(void)inven_carry(q_ptr, FALSE);
- del_hook(HOOK_INIT_QUEST, quest_poison_quest_hook);
+ del_hook_new(HOOK_INIT_QUEST, quest_poison_quest_hook);
process_hooks_restart = TRUE;
return FALSE;
}
-bool_ quest_poison_drop_hook(char *fmt)
-{
- s32b mcnt = 0, i, x, y, o_idx;
- object_type *o_ptr;
- o_idx = get_next_arg(fmt);
- o_ptr = &p_ptr->inventory[o_idx];
+static bool_ quest_poison_drop_hook(void *, void *in_, void *)
+{
+ struct hook_drop_in *in = static_cast<struct hook_drop_in *>(in_);
+ s32b mcnt = 0, i, x, y;
+ s32b o_idx = in->o_idx;
+ object_type *o_ptr = &p_ptr->inventory[o_idx];
if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE;
@@ -201,7 +224,7 @@ bool_ quest_poison_drop_hook(char *fmt)
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_DROP, quest_poison_drop_hook);
+ del_hook_new(HOOK_DROP, quest_poison_drop_hook);
process_hooks_restart = TRUE;
return FALSE;
@@ -213,6 +236,7 @@ bool_ quest_poison_drop_hook(char *fmt)
}
return FALSE;
}
+
bool_ quest_poison_init_hook(int q_idx)
{
/* Get a place to place the poison */
@@ -225,14 +249,14 @@ bool_ quest_poison_init_hook(int q_idx)
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_DROP, quest_poison_drop_hook, "poison_drop");
- add_hook(HOOK_WILD_GEN, quest_poison_gen_hook, "poison_gen");
- add_hook(HOOK_QUEST_FINISH, quest_poison_finish_hook, "poison_finish");
+ add_hook_new(HOOK_DROP, quest_poison_drop_hook, "poison_drop", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_poison_gen_hook, "poison_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_poison_finish_hook, "poison_finish", NULL);
}
if (cquest.status < QUEST_STATUS_COMPLETED)
{
- add_hook(HOOK_INIT_QUEST, quest_poison_quest_hook, "poison_iquest");
+ add_hook_new(HOOK_INIT_QUEST, quest_poison_quest_hook, "poison_iquest", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_poison_dump_hook, "poison_dump");
+ add_hook_new(HOOK_CHAR_DUMP, quest_poison_dump_hook, "poison_dump", NULL);
return (FALSE);
}
diff --git a/src/q_poison.hpp b/src/q_poison.hpp
new file mode 100644
index 00000000..f8d97ace
--- /dev/null
+++ b/src/q_poison.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_poison_init_hook(int q_idx);
diff --git a/src/q_rand.c b/src/q_rand.cc
index 0cc69a6d..5b265624 100644
--- a/src/q_rand.c
+++ b/src/q_rand.cc
@@ -1,5 +1,196 @@
+#include "q_rand.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "generate.hpp"
+#include "hook_build_room1_in.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "lua_bind.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_type.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
static int randquest_hero[] = { 20, 13, 15, 16, 9, 17, 18, 8, -1 };
+/* Possible number(and layout) or random quests */
+#define MAX_RANDOM_QUESTS_TYPES ((8 * 3) + (8 * 1))
+static int random_quests_types[MAX_RANDOM_QUESTS_TYPES] =
+{
+ 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
+ 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
+ 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
+ 20, 13, 15, 16, 9, 17, 18, 8, /* Hero Sword Quest */
+};
+
+/* Enforce OoD monsters until this level */
+#define RQ_LEVEL_CAP 49
+
+// Generate lookup function
+GENERATE_MONSTER_LOOKUP_FN(get_adventurer, "Adventurer")
+
+void initialize_random_quests(int n)
+{
+ int step, lvl, i, k;
+ int old_type = dungeon_type;
+
+ /* Zero out everything first */
+ for (i = 0; i < MAX_RANDOM_QUEST; i++) random_quests[i].type = 0;
+
+ if (n == 0) return;
+
+ /* Factor dlev value by 1000 to keep precision */
+ step = (98 * 1000) / n;
+
+ lvl = step / 2;
+
+ quest[QUEST_RANDOM].status = QUEST_STATUS_TAKEN;
+
+ for (i = 0; i < n; i++)
+ {
+ monster_race *r_ptr = nullptr;
+
+ int rl = (lvl / 1000) + 1;
+
+ int min_level;
+
+ int tries = 5000;
+
+ random_quest *q_ptr = &random_quests[rl];
+
+ int j;
+
+ /* Find the appropriate dungeon */
+ for (j = 0; j < max_d_idx; j++)
+ {
+ dungeon_info_type *d_ptr = &d_info[j];
+
+ if (!(d_ptr->flags1 & DF1_PRINCIPAL)) continue;
+
+ if ((d_ptr->mindepth <= rl) && (rl <= d_ptr->maxdepth))
+ {
+ dungeon_type = j;
+ break;
+ }
+ }
+
+ q_ptr->type = random_quests_types[rand_int(MAX_RANDOM_QUESTS_TYPES)];
+
+ /* XXX XXX XXX Try until valid choice is found */
+ while (tries)
+ {
+ bool_ ok;
+
+ tries--;
+
+ /* Random monster 5 - 10 levels out of depth */
+ q_ptr->r_idx = get_mon_num(rl + 4 + randint(6));
+
+ if (!q_ptr->r_idx) continue;
+
+ r_ptr = &r_info[q_ptr->r_idx];
+
+ /* Accept only monsters that can be generated */
+ if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue;
+ if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
+
+ /* Accept only monsters that are not breeders */
+ if (r_ptr->flags4 & RF4_MULTIPLY) continue;
+
+ /* Forbid joke monsters */
+ if (r_ptr->flags8 & RF8_JOKEANGBAND) continue;
+
+ /* Accept only monsters that are not friends */
+ if (r_ptr->flags7 & RF7_PET) continue;
+
+ /* Refuse nazguls */
+ if (r_ptr->flags7 & RF7_NAZGUL) continue;
+
+ /* Accept only monsters that are not good */
+ if (r_ptr->flags3 & RF3_GOOD) continue;
+
+ /* If module says a monster race is friendly, then skip */
+ if (modules[game_module_idx].race_status != NULL)
+ {
+ s16b *status = (*modules[game_module_idx].race_status)(q_ptr->r_idx);
+ if ((status != NULL) && (*status >= 0))
+ {
+ continue;
+ }
+ }
+
+ /* Assume no explosion attacks */
+ ok = TRUE;
+
+ /* Reject monsters with exploding attacks */
+ for (k = 0; k < 4; k++)
+ {
+ if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE;
+ }
+ if (!ok) continue;
+
+ /* No mutliple uniques */
+ if ((r_ptr->flags1 & RF1_UNIQUE) &&
+ ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue;
+
+ /* No single non uniques */
+ if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue;
+
+ /* Level restriction */
+ min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl;
+
+ /* Accept monsters matching the level restriction */
+ if (r_ptr->level > min_level) break;
+ }
+
+ /* Arg could not find anything ??? */
+ if (!tries)
+ {
+ if (wizard)
+ {
+ message_add(format("Could not find quest monster on lvl %d", rl), TERM_RED);
+ }
+ q_ptr->type = 0;
+ }
+ else
+ {
+ if (r_ptr->flags1 & RF1_UNIQUE)
+ {
+ r_ptr->max_num = -1;
+ }
+
+ q_ptr->done = FALSE;
+
+ if (wizard)
+ {
+ message_add(format("Quest for %d on lvl %d",
+ q_ptr->r_idx, rl), TERM_RED);
+ }
+ }
+
+ lvl += step;
+ }
+
+ dungeon_type = old_type;
+}
+
bool_ is_randhero(int level)
{
int i;
@@ -20,19 +211,18 @@ bool_ is_randhero(int level)
static void do_get_new_obj(int y, int x)
{
obj_theme theme;
- char *items[3];
object_type *q_ptr[3], forge[3];
- int max = 0, res, i;
+ int res, i;
- /* Create 3 ones */
- max = 0;
+ /* Create objects */
+ std::vector<std::string> items;
for (i = 0; i < 3; i++)
{
/* Get local object */
- q_ptr[max] = &forge[max];
+ q_ptr[i] = &forge[i];
/* Wipe the object */
- object_wipe(q_ptr[max]);
+ object_wipe(q_ptr[i]);
/* No themes */
theme.treasure = 100;
@@ -41,18 +231,18 @@ static void do_get_new_obj(int y, int x)
theme.tools = 100;
/* Make a great object */
- make_object(q_ptr[max], TRUE, TRUE, theme);
- q_ptr[max]->found = OBJ_FOUND_REWARD;
+ make_object(q_ptr[i], TRUE, TRUE, theme);
+ q_ptr[i]->found = OBJ_FOUND_REWARD;
- C_MAKE(items[max], 100, char);
- object_desc(items[max], q_ptr[max], 0, 0);
- max++;
+ char buf[100];
+ object_desc(buf, q_ptr[i], 0, 0);
+ items.push_back(buf);
}
while (TRUE)
{
- res = ask_menu("Choose a reward to get(a-c to choose, ESC to cancel)?", (char **)items, 3);
+ res = ask_menu("Choose a reward to get(a-c to choose, ESC to cancel)?", items);
/* Ok ? lets learn ! */
if (res > -1)
@@ -88,10 +278,6 @@ static void do_get_new_obj(int y, int x)
}
}
}
-
- for (i = 0; i < 3; i++)
- C_KILL(items[i], 100, char);
-
}
static void princess_death(s32b m_idx, s32b r_idx)
@@ -190,14 +376,15 @@ static void hero_death(s32b m_idx, s32b r_idx)
if (i < 20)
{
- int m_idx;
+ int r_idx = get_adventurer();
+
+ m_allow_special[r_idx] = TRUE;
+ int m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_COMPANION);
+ m_allow_special[r_idx] = FALSE;
- m_allow_special[test_monster_name("Adventurer")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Adventurer"), 0, FALSE, MSTATUS_COMPANION);
- m_allow_special[test_monster_name("Adventurer")] = FALSE;
if (m_idx)
{
- m_list[m_idx].exp = MONSTER_EXP(1 + (dun_level * 3 / 2));
+ m_list[m_idx].exp = monster_exp(1 + (dun_level * 3 / 2));
m_list[m_idx].status = MSTATUS_COMPANION;
monster_check_experience(m_idx, TRUE);
}
@@ -213,13 +400,11 @@ static void hero_death(s32b m_idx, s32b r_idx)
}
}
-static bool_ quest_random_death_hook(char *fmt)
+static bool_ quest_random_death_hook(void *, void *in_, void *)
{
- int r_idx;
- s32b m_idx;
-
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ int r_idx = m_list[m_idx].r_idx;
if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE);
if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE);
@@ -243,14 +428,14 @@ static bool_ quest_random_death_hook(char *fmt)
return (FALSE);
}
-static bool_ quest_random_turn_hook(char *fmt)
+static bool_ quest_random_turn_hook(void *, void *, void *)
{
quest[QUEST_RANDOM].data[0] = 0;
quest[QUEST_RANDOM].data[1] = 0;
return (FALSE);
}
-static bool_ quest_random_feeling_hook(char *fmt)
+static bool_ quest_random_feeling_hook(void *, void *, void *)
{
if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE);
if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE);
@@ -262,14 +447,14 @@ static bool_ quest_random_feeling_hook(char *fmt)
if (is_randhero(dun_level))
{
cmsg_format(TERM_YELLOW, "A strange man wrapped in a dark cloak steps out of the shadows:");
- cmsg_format(TERM_YELLOW, "'Oh, please help me! A horrible %s stole my sword! I'm nothing without it.'", r_info[random_quests[dun_level].r_idx].name + r_name);
+ cmsg_format(TERM_YELLOW, "'Oh, please help me! A horrible %s stole my sword! I'm nothing without it.'", r_info[random_quests[dun_level].r_idx].name);
}
else
- cmsg_format(TERM_YELLOW, "You hear someone shouting: 'Leave me alone, stupid %s'", r_info[random_quests[dun_level].r_idx].name + r_name);
+ cmsg_format(TERM_YELLOW, "You hear someone shouting: 'Leave me alone, stupid %s'", r_info[random_quests[dun_level].r_idx].name);
return (FALSE);
}
-static bool_ quest_random_gen_hero_hook(char *fmt)
+static bool_ quest_random_gen_hero_hook(void *, void *, void *)
{
int i;
@@ -300,9 +485,12 @@ static bool_ quest_random_gen_hero_hook(char *fmt)
return (FALSE);
}
-static bool_ quest_random_gen_hook(char *fmt)
+static bool_ quest_random_gen_hook(void *, void *in_, void *)
{
- s32b x, y, bx0, by0;
+ struct hook_build_room1_in *in = static_cast<struct hook_build_room1_in *>(in_);
+ s32b bx0 = in->x;
+ s32b by0 = in->y;
+ s32b x, y;
int xstart;
int ystart;
int y2, x2, yval, xval;
@@ -316,9 +504,6 @@ static bool_ quest_random_gen_hook(char *fmt)
if (quest[QUEST_RANDOM].data[1]) return (FALSE);
if (is_randhero(dun_level)) return (FALSE);
- by0 = get_next_arg(fmt);
- bx0 = get_next_arg(fmt);
-
/* Pick a room size */
get_map_size(format("qrand%d.map", random_quests[dun_level].type), &ysize, &xsize);
@@ -383,10 +568,11 @@ static bool_ quest_random_gen_hook(char *fmt)
return (TRUE);
}
-static bool_ quest_random_dump_hook(char *fmt)
+static bool_ quest_random_dump_hook(void *, void *in_, void *)
{
- static char *number[] =
- { "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
+ static const char *number[] = { "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
int i, valid = 0, lscnt = 0, pcnt = 0;
for (i = 0; i < MAX_RANDOM_QUEST; i++)
@@ -407,22 +593,22 @@ static bool_ quest_random_dump_hook(char *fmt)
if (valid)
{
if (pcnt > 10)
- fprintf(hook_file, "\n You have completed %d princess quests.", pcnt);
+ fprintf(f, "\n You have completed %d princess quests.", pcnt);
else if (pcnt > 1)
- fprintf(hook_file, "\n You have completed %s princess quests.", number[pcnt-2]);
+ fprintf(f, "\n You have completed %s princess quests.", number[pcnt-2]);
else if (pcnt == 1)
- fprintf(hook_file, "\n You have completed one princess quest.");
+ fprintf(f, "\n You have completed one princess quest.");
else
- fprintf(hook_file, "\n You haven't completed a single princess quest.");
+ fprintf(f, "\n You haven't completed a single princess quest.");
if (lscnt > 10)
- fprintf(hook_file, "\n You have completed %d lost sword quests.", lscnt);
+ fprintf(f, "\n You have completed %d lost sword quests.", lscnt);
else if (lscnt > 1)
- fprintf(hook_file, "\n You have completed %s lost sword quests.", number[lscnt-2]);
+ fprintf(f, "\n You have completed %s lost sword quests.", number[lscnt-2]);
else if (lscnt == 1)
- fprintf(hook_file, "\n You have completed one lost sword quest.");
+ fprintf(f, "\n You have completed one lost sword quest.");
else
- fprintf(hook_file, "\n You haven't completed a single lost sword quest.");
+ fprintf(f, "\n You haven't completed a single lost sword quest.");
}
return (FALSE);
@@ -441,14 +627,12 @@ bool_ quest_random_describe(FILE *fff)
{
fprintf(fff, "#####yCaptured princess!\n");
fprintf(fff, "A princess is being held prisoner and tortured here!\n");
- fprintf(fff, "Save her from the horrible %s.\n",
- r_info[random_quests[dun_level].r_idx].name + r_name);
+ fprintf(fff, "Save her from the horrible %s.\n", r_info[random_quests[dun_level].r_idx].name);
}
else
{
fprintf(fff, "#####yLost sword!\n");
- fprintf(fff, "An adventurer lost his sword to a bunch of %s!\n",
- r_info[random_quests[dun_level].r_idx].name + r_name);
+ fprintf(fff, "An adventurer lost his sword to a bunch of %s!\n", r_info[random_quests[dun_level].r_idx].name);
fprintf(fff, "Kill them all to get it back.\n");
}
fprintf(fff, "Number: %d, Killed: %ld.\n",
@@ -459,12 +643,12 @@ bool_ quest_random_describe(FILE *fff)
bool_ quest_random_init_hook(int q_idx)
{
- add_hook(HOOK_MONSTER_DEATH, quest_random_death_hook, "rand_death");
- add_hook(HOOK_NEW_LEVEL, quest_random_turn_hook, "rand_new_lvl");
- add_hook(HOOK_LEVEL_REGEN, quest_random_turn_hook, "rand_regen_lvl");
- add_hook(HOOK_LEVEL_END_GEN, quest_random_gen_hero_hook, "rand_gen_hero");
- add_hook(HOOK_BUILD_ROOM1, quest_random_gen_hook, "rand_gen");
- add_hook(HOOK_FEELING, quest_random_feeling_hook, "rand_feel");
- add_hook(HOOK_CHAR_DUMP, quest_random_dump_hook, "rand_dump");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_random_death_hook, "rand_death", NULL);
+ add_hook_new(HOOK_NEW_LEVEL, quest_random_turn_hook, "rand_new_lvl", NULL);
+ add_hook_new(HOOK_LEVEL_REGEN, quest_random_turn_hook, "rand_regen_lvl", NULL);
+ add_hook_new(HOOK_LEVEL_END_GEN, quest_random_gen_hero_hook, "rand_gen_hero", NULL);
+ add_hook_new(HOOK_BUILD_ROOM1, quest_random_gen_hook, "rand_gen", NULL);
+ add_hook_new(HOOK_FEELING, quest_random_feeling_hook, "rand_feel", NULL);
+ add_hook_new(HOOK_CHAR_DUMP, quest_random_dump_hook, "rand_dump", NULL);
return (FALSE);
}
diff --git a/src/q_rand.hpp b/src/q_rand.hpp
new file mode 100644
index 00000000..fe87289b
--- /dev/null
+++ b/src/q_rand.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+void initialize_random_quests(int n);
+bool_ is_randhero(int level);
+bool_ quest_random_init_hook(int q_idx);
+bool_ quest_random_describe(FILE *fff);
diff --git a/src/q_shroom.c b/src/q_shroom.cc
index c0133e74..f3a7dd12 100644
--- a/src/q_shroom.c
+++ b/src/q_shroom.cc
@@ -1,14 +1,39 @@
-#undef cquest
+#include "q_shroom.hpp"
+
+#include "cave.hpp"
+#include "hook_chat_in.hpp"
+#include "hook_give_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_mon_speak_in.hpp"
+#include "hook_wild_gen_in.hpp"
+#include "hooks.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_SHROOM])
-bool_ quest_shroom_speak_hook(char *fmt);
+static bool_ quest_shroom_speak_hook(void *, void *, void *);
+static bool_ quest_shroom_chat_hook(void *, void *, void *);
+
+GENERATE_MONSTER_LOOKUP_FN(get_grip, "Grip, Farmer Maggot's dog")
+GENERATE_MONSTER_LOOKUP_FN(get_wolf, "Wolf, Farmer Maggot's dog")
+GENERATE_MONSTER_LOOKUP_FN(get_fang, "Fang, Farmer Maggot's dog")
+GENERATE_MONSTER_LOOKUP_FN(get_farmer_maggot, "Farmer Maggot")
-bool_ quest_shroom_town_gen_hook(char *fmt)
+static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *)
{
+ struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_);
int m_idx, x = 1, y = 1, tries = 10000;
- s32b small;
-
- small = get_next_arg(fmt);
+ bool_ small = in->small;
/* Generate the shrooms field */
if ((!small) && (p_ptr->wilderness_y == 21) && (p_ptr->wilderness_x == 33))
@@ -33,24 +58,24 @@ bool_ quest_shroom_town_gen_hook(char *fmt)
/* Throw in some dogs ;) */
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[test_monster_name("Grip, Farmer Maggot's dog")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Grip, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_grip()] = TRUE;
+ m_idx = place_monster_one(y, x, get_grip(), 0, FALSE, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[test_monster_name("Grip, Farmer Maggot's dog")] = FALSE;
+ m_allow_special[get_grip()] = FALSE;
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[test_monster_name("Wolf, Farmer Maggot's dog")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Wolf, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_wolf()] = TRUE;
+ m_idx = place_monster_one(y, x, get_wolf(), 0, FALSE, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[test_monster_name("Wolf, Farmer Maggot's dog")] = FALSE;
+ m_allow_special[get_wolf()] = FALSE;
y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
- m_allow_special[test_monster_name("Fang, Farmer Maggot's dog")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Fang, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_fang()] = TRUE;
+ m_idx = place_monster_one(y, x, get_fang(), 0, FALSE, MSTATUS_ENEMY);
if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST;
- m_allow_special[test_monster_name("Fang, Farmer Maggot's dog")] = FALSE;
+ m_allow_special[get_fang()] = FALSE;
msg_print("You hear frenzied barking.");
}
@@ -75,57 +100,58 @@ bool_ quest_shroom_town_gen_hook(char *fmt)
}
/* Place Farmer Maggot */
- m_allow_special[test_monster_name("Farmer Maggot")] = TRUE;
- place_monster_one(y, x, test_monster_name("Farmer Maggot"), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[test_monster_name("Farmer Maggot")] = FALSE;
+ m_allow_special[get_farmer_maggot()] = TRUE;
+ place_monster_one(y, x, get_farmer_maggot(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_farmer_maggot()] = FALSE;
return FALSE;
}
-bool_ quest_shroom_death_hook(char *fmt)
-{
- s32b r_idx, m_idx;
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
+static bool_ quest_shroom_death_hook(void *, void *in_, void *)
+{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
if (cquest.status > QUEST_STATUS_COMPLETED) return FALSE;
- if ((r_idx == test_monster_name("Wolf, Farmer Maggot's dog")) ||
- (r_idx == test_monster_name("Grip, Farmer Maggot's dog")) ||
- (r_idx == test_monster_name("Fang, Farmer Maggot's dog")))
+ if ((r_idx == get_wolf()) ||
+ (r_idx == get_grip()) ||
+ (r_idx == get_fang()))
{
msg_print("The dog yells a last time and drops dead on the grass.");
}
return FALSE;
}
-bool_ quest_shroom_give_hook(char *fmt)
+
+static bool_ quest_shroom_give_hook(void *, void *in_, void *)
{
+ struct hook_give_in *in = static_cast<struct hook_give_in *>(in_);
object_type *o_ptr;
monster_type *m_ptr;
- s32b m_idx, item;
- m_idx = get_next_arg(fmt);
- item = get_next_arg(fmt);
+ s32b m_idx = in->m_idx;
+ s32b item = in->item;
o_ptr = &p_ptr->inventory[item];
m_ptr = &m_list[m_idx];
- if (m_ptr->r_idx != test_monster_name("Farmer Maggot")) return (FALSE);
+ if (m_ptr->r_idx != get_farmer_maggot()) return (FALSE);
/* If one is dead .. its bad */
- if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
+ if ((r_info[get_grip()].max_num == 0) ||
+ (r_info[get_wolf()].max_num == 0) ||
+ (r_info[get_fang()].max_num == 0))
{
cquest.status = QUEST_STATUS_FAILED_DONE;
msg_print("My puppy! My poor, defenceless puppy...");
msg_print("YOU MURDERER! Out of my sight!");
delete_monster_idx(m_idx);
- del_hook(HOOK_GIVE, quest_shroom_give_hook);
- del_hook(HOOK_CHAT, quest_shroom_speak_hook);
- del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
+ del_hook_new(HOOK_GIVE, quest_shroom_give_hook);
+ del_hook_new(HOOK_CHAT, quest_shroom_speak_hook);
+ del_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
process_hooks_restart = TRUE;
return TRUE;
}
@@ -175,7 +201,7 @@ bool_ quest_shroom_give_hook(char *fmt)
cquest.status = QUEST_STATUS_FINISHED;
- del_hook(HOOK_GIVE, quest_shroom_give_hook);
+ del_hook_new(HOOK_GIVE, quest_shroom_give_hook);
process_hooks_restart = TRUE;
}
else
@@ -183,53 +209,56 @@ bool_ quest_shroom_give_hook(char *fmt)
return TRUE;
}
-bool_ quest_shroom_speak_hook(char *fmt)
-{
- s32b m_idx = get_next_arg(fmt);
- if (m_list[m_idx].r_idx != test_monster_name("Farmer Maggot")) return (FALSE);
+static void check_dogs_alive(s32b m_idx)
+{
+ if ((r_info[get_grip()].max_num == 0) ||
+ (r_info[get_wolf()].max_num == 0) ||
+ (r_info[get_fang()].max_num == 0))
+ {
+ cquest.status = QUEST_STATUS_FAILED_DONE;
+ msg_print("My puppy! My poor, defenceless puppy...");
+ msg_print("YOU MURDERER! Out of my sight!");
+ delete_monster_idx(m_idx);
- if (cquest.status == QUEST_STATUS_UNTAKEN)
+ del_hook_new(HOOK_GIVE, quest_shroom_give_hook);
+ del_hook_new(HOOK_MON_SPEAK, quest_shroom_speak_hook);
+ del_hook_new(HOOK_CHAT, quest_shroom_chat_hook);
+ del_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
+ process_hooks_restart = TRUE;
+ }
+ else
{
- cptr m_name;
+ msg_format("You still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);
+ }
+}
- m_name = get_next_arg_str(fmt);
+static bool_ quest_shroom_speak_hook(void *, void *in_, void *)
+{
+ struct hook_mon_speak_in *in = static_cast<struct hook_mon_speak_in *>(in_);
+ s32b m_idx = in->m_idx;
- msg_format("%^s asks your help.", m_name);
+ if (m_list[m_idx].r_idx != get_farmer_maggot()) return (FALSE);
+
+ if (cquest.status == QUEST_STATUS_UNTAKEN)
+ {
+ msg_format("%^s asks your help.", in->m_name);
process_hooks_new(HOOK_MON_ASK_HELP, NULL, NULL);
}
else
{
- /* If one is dead .. its bad */
- if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
- {
- cquest.status = QUEST_STATUS_FAILED_DONE;
- msg_print("My puppy! My poor, defenceless puppy...");
- msg_print("YOU MURDERER! Out of my sight!");
- delete_monster_idx(m_idx);
-
- del_hook(HOOK_GIVE, quest_shroom_give_hook);
- del_hook(HOOK_CHAT, quest_shroom_speak_hook);
- del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
- process_hooks_restart = TRUE;
- return TRUE;
- }
- msg_format("You still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);
+ check_dogs_alive(m_idx);
}
return (TRUE);
}
-bool_ quest_shroom_chat_hook(char *fmt)
-{
- monster_type *m_ptr;
- s32b m_idx;
-
- m_idx = get_next_arg(fmt);
- m_ptr = &m_list[m_idx];
+static bool_ quest_shroom_chat_hook(void *, void *in_, void *)
+{
+ struct hook_chat_in *in = static_cast<struct hook_chat_in *>(in_);
+ s32b m_idx = in->m_idx;
+ monster_type *m_ptr = &m_list[m_idx];
- if (m_ptr->r_idx != test_monster_name("Farmer Maggot")) return (FALSE);
+ if (m_ptr->r_idx != get_farmer_maggot()) return (FALSE);
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
@@ -244,27 +273,12 @@ bool_ quest_shroom_chat_hook(char *fmt)
}
else
{
- /* If one is dead .. its bad */
- if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
- (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
- {
- cquest.status = QUEST_STATUS_FAILED_DONE;
- msg_print("My puppy! My poor, defenceless puppy...");
- msg_print("YOU MURDERER! Out of my sight!");
- delete_monster_idx(m_idx);
-
- del_hook(HOOK_GIVE, quest_shroom_give_hook);
- del_hook(HOOK_CHAT, quest_shroom_speak_hook);
- del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
- process_hooks_restart = TRUE;
- return TRUE;
- }
- msg_format("You still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);
+ check_dogs_alive(m_idx);
}
return TRUE;
}
+
bool_ quest_shroom_init_hook(int q_idx)
{
/* Get a number of 'shrooms */
@@ -280,17 +294,17 @@ bool_ quest_shroom_init_hook(int q_idx)
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_shroom_death_hook, "shroom_death");
- add_hook(HOOK_GIVE, quest_shroom_give_hook, "shroom_give");
- add_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen");
- add_hook(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat");
- add_hook(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_shroom_death_hook, "shroom_death", NULL);
+ add_hook_new(HOOK_GIVE, quest_shroom_give_hook, "shroom_give", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen", NULL);
+ add_hook_new(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat", NULL);
+ add_hook_new(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak", NULL);
}
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
- add_hook(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak");
- add_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen");
- add_hook(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat");
+ add_hook_new(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak", NULL);
+ add_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen", NULL);
+ add_hook_new(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat", NULL);
}
return (FALSE);
}
diff --git a/src/q_shroom.hpp b/src/q_shroom.hpp
new file mode 100644
index 00000000..6124775b
--- /dev/null
+++ b/src/q_shroom.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_shroom_init_hook(int q_idx);
diff --git a/src/q_spider.c b/src/q_spider.cc
index a739535b..07531b96 100644
--- a/src/q_spider.c
+++ b/src/q_spider.cc
@@ -1,7 +1,22 @@
-#undef cquest
+#include "q_spider.hpp"
+
+#include "cave.hpp"
+#include "gods.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_SPIDER])
-bool_ quest_spider_gen_hook(char *fmt)
+static bool_ quest_spider_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -30,7 +45,8 @@ bool_ quest_spider_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_spider_death_hook(char *fmt)
+
+static bool_ quest_spider_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -52,26 +68,28 @@ bool_ quest_spider_death_hook(char *fmt)
cmsg_print(TERM_YELLOW, "The forest is now safer, thanks to you.");
/* Yavanna LOVES saving forests */
- GOD(GOD_YAVANNA)
+ if (p_ptr->pgod == GOD_YAVANNA)
{
cmsg_print(TERM_L_GREEN, "You feel the gentle touch of Yavanna, as she smiles at you.");
inc_piety(GOD_YAVANNA, 6000);
}
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_spider_death_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_spider_death_hook);
process_hooks_restart = TRUE;
+
return (FALSE);
}
return (FALSE);
}
-bool_ quest_spider_finish_hook(char *fmt)
+
+static bool_ quest_spider_finish_hook(void *, void *in_, void *)
{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
object_type forge, *q_ptr;
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_SPIDER) return FALSE;
@@ -91,18 +109,19 @@ bool_ quest_spider_finish_hook(char *fmt)
*(quest[q_idx].plot) = QUEST_POISON;
quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));
- del_hook(HOOK_QUEST_FINISH, quest_spider_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_spider_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
+
bool_ quest_spider_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_spider_death_hook, "spider_death");
- add_hook(HOOK_GEN_QUEST, quest_spider_gen_hook, "spider_gen");
- add_hook(HOOK_QUEST_FINISH, quest_spider_finish_hook, "spider_finish");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_spider_death_hook, "spider_death", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_spider_gen_hook, "spider_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_spider_finish_hook, "spider_finish", NULL);
}
return (FALSE);
}
diff --git a/src/q_spider.hpp b/src/q_spider.hpp
new file mode 100644
index 00000000..e17cb523
--- /dev/null
+++ b/src/q_spider.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_spider_init_hook(int q_idx);
diff --git a/src/q_thief.c b/src/q_thief.cc
index 6b033f8c..5019d9d5 100644
--- a/src/q_thief.c
+++ b/src/q_thief.cc
@@ -1,7 +1,25 @@
-#undef cquest
+#include "q_thief.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "skill_type.hpp"
+#include "spells2.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_THIEVES])
-bool_ quest_thieves_gen_hook(char *fmt)
+static bool_ quest_thieves_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -56,12 +74,13 @@ bool_ quest_thieves_gen_hook(char *fmt)
}
}
- del_hook(HOOK_GEN_QUEST, quest_thieves_gen_hook);
+ del_hook_new(HOOK_GEN_QUEST, quest_thieves_gen_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_thieves_hook(char *fmt)
+
+static bool_ quest_thieves_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -105,7 +124,8 @@ bool_ quest_thieves_hook(char *fmt)
cave[23][4].special = 0;
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_END_TURN, quest_thieves_hook);
+
+ del_hook_new(HOOK_END_TURN, quest_thieves_hook);
process_hooks_restart = TRUE;
cmsg_print(TERM_YELLOW, "You stopped the thieves and saved Bree!");
@@ -113,11 +133,11 @@ bool_ quest_thieves_hook(char *fmt)
}
return FALSE;
}
-bool_ quest_thieves_finish_hook(char *fmt)
-{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+static bool_ quest_thieves_finish_hook(void *, void *in_, void *)
+{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_THIEVES) return FALSE;
@@ -140,20 +160,20 @@ bool_ quest_thieves_finish_hook(char *fmt)
}
quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));
- del_hook(HOOK_QUEST_FINISH, quest_thieves_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_thieves_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_thieves_feeling_hook(char *fmt)
+static bool_ quest_thieves_feeling_hook(void *, void *, void *)
{
if (p_ptr->inside_quest != QUEST_THIEVES) return FALSE;
msg_print("You wake up in a prison cell.");
msg_print("All your possessions have been stolen!");
- del_hook(HOOK_FEELING, quest_thieves_feeling_hook);
+ del_hook_new(HOOK_FEELING, quest_thieves_feeling_hook);
process_hooks_restart = TRUE;
return TRUE;
@@ -163,10 +183,10 @@ bool_ quest_thieves_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_END_TURN, quest_thieves_hook, "thieves_end_turn");
- add_hook(HOOK_QUEST_FINISH, quest_thieves_finish_hook, "thieves_finish");
- add_hook(HOOK_GEN_QUEST, quest_thieves_gen_hook, "thieves_geb");
- add_hook(HOOK_FEELING, quest_thieves_feeling_hook, "thieves_feel");
+ add_hook_new(HOOK_END_TURN, quest_thieves_hook, "thieves_end_turn", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_thieves_finish_hook, "thieves_finish", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_thieves_gen_hook, "thieves_geb", NULL);
+ add_hook_new(HOOK_FEELING, quest_thieves_feeling_hook, "thieves_feel", NULL);
}
return (FALSE);
}
diff --git a/src/q_thief.hpp b/src/q_thief.hpp
new file mode 100644
index 00000000..48e5dc8d
--- /dev/null
+++ b/src/q_thief.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_thieves_init_hook(int q_idx);
diff --git a/src/q_thrain.c b/src/q_thrain.cc
index 6180706c..4cdb8566 100644
--- a/src/q_thrain.c
+++ b/src/q_thrain.cc
@@ -1,17 +1,44 @@
-#undef cquest
+#include "q_thrain.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "dungeon_info_type.hpp"
+#include "generate.hpp"
+#include "hook_build_room1_in.hpp"
+#include "hook_move_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "lua_bind.hpp"
+#include "object_type.hpp"
+#include "quark.hpp"
+#include "randart.hpp"
+#include "messages.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_THRAIN])
-bool_ quest_thrain_death_hook(char *fmt)
+GENERATE_MONSTER_LOOKUP_FN(get_thrain, "Thrain, the King Under the Mountain")
+GENERATE_MONSTER_LOOKUP_FN(get_dwar, "Dwar, Dog Lord of Waw")
+GENERATE_MONSTER_LOOKUP_FN(get_hoarmurath, "Hoarmurath of Dir")
+
+static bool_ quest_thrain_death_hook(void *, void *in_, void *)
{
- s32b m_idx;
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
int r, x, y;
monster_type *m_ptr;
- m_idx = get_next_arg(fmt);
-
if ((cquest.status >= QUEST_STATUS_FINISHED) || (dun_level !=cquest.data[0]) || (dungeon_type != DUNGEON_DOL_GULDUR)) return (FALSE);
m_ptr = &m_list[m_idx];
- if ((m_ptr->r_idx != test_monster_name("Dwar, Dog Lord of Waw")) && (m_ptr->r_idx != test_monster_name("Hoarmurath of Dir"))) return (FALSE);
+ if ((m_ptr->r_idx != get_dwar()) && (m_ptr->r_idx != get_hoarmurath())) return (FALSE);
cquest.data[2]++;
@@ -47,7 +74,7 @@ bool_ quest_thrain_death_hook(char *fmt)
if (!m_ptr->r_idx) continue;
/* Is it the princess? */
- if (m_ptr->r_idx == test_monster_name("Thrain, the King Under the Mountain"))
+ if (m_ptr->r_idx == get_thrain())
{
int x = m_ptr->fx;
int y = m_ptr->fy;
@@ -81,15 +108,18 @@ bool_ quest_thrain_death_hook(char *fmt)
}
- del_hook(HOOK_MONSTER_DEATH, quest_thrain_death_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_thrain_death_hook);
process_hooks_restart = TRUE;
return (FALSE);
}
-bool_ quest_thrain_gen_hook(char *fmt)
+static bool_ quest_thrain_gen_hook(void *, void *in_, void *)
{
- s32b x, y, bx0, by0;
+ struct hook_build_room1_in *in = static_cast<struct hook_build_room1_in *>(in_);
+ s32b bx0 = in->x;
+ s32b by0 = in->y;
+ s32b x, y;
int xstart;
int ystart;
int y2, x2, yval, xval;
@@ -100,9 +130,6 @@ bool_ quest_thrain_gen_hook(char *fmt)
if (cquest.data[1]) return (FALSE);
if ((cquest.status < QUEST_STATUS_TAKEN) || (cquest.status >= QUEST_STATUS_FINISHED)) return (FALSE);
- by0 = get_next_arg(fmt);
- bx0 = get_next_arg(fmt);
-
/* Pick a room size */
get_map_size("thrain.map", &ysize, &xsize);
@@ -144,12 +171,11 @@ bool_ quest_thrain_gen_hook(char *fmt)
cave[y][x].info |= CAVE_ICKY | CAVE_ROOM | CAVE_FREE;
if (cave[y][x].feat == FEAT_MARKER)
{
- int i;
+ m_allow_special[get_thrain()] = TRUE;
+ int i = place_monster_one(y, x, get_thrain(), 0, FALSE, MSTATUS_NEUTRAL);
+ m_allow_special[get_thrain()] = FALSE;
- m_allow_special[test_monster_name("Thrain, the King Under the Mountain")] = TRUE;
- i = place_monster_one(y, x, test_monster_name("Thrain, the King Under the Mountain"), 0, FALSE, MSTATUS_NEUTRAL);
if (i) m_list[i].mflag |= MFLAG_QUEST;
- m_allow_special[test_monster_name("Thrain, the King Under the Mountain")] = FALSE;
}
}
@@ -158,7 +184,8 @@ bool_ quest_thrain_gen_hook(char *fmt)
return (TRUE);
}
-bool_ quest_thrain_feeling_hook(char *fmt)
+
+static bool_ quest_thrain_feeling_hook(void *, void *, void *)
{
if (dungeon_type != DUNGEON_DOL_GULDUR) return (FALSE);
if (cquest.data[0] != dun_level) return (FALSE);
@@ -170,15 +197,13 @@ bool_ quest_thrain_feeling_hook(char *fmt)
return (FALSE);
}
-bool_ quest_thrain_move_hook(char *fmt)
-{
- s32b y;
- s32b x;
- cave_type *c_ptr;
- y = get_next_arg(fmt);
- x = get_next_arg(fmt);
- c_ptr = &cave[y][x];
+static bool_ quest_thrain_move_hook(void *, void *in_, void *)
+{
+ struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
+ s32b y = in->y;
+ s32b x = in->x;
+ cave_type *c_ptr = &cave[y][x];
if (dungeon_type != DUNGEON_DOL_GULDUR) return (FALSE);
if (cquest.data[0] != dun_level) return (FALSE);
@@ -201,12 +226,14 @@ bool_ quest_thrain_move_hook(char *fmt)
return (FALSE);
}
-bool_ quest_thrain_turn_hook(char *fmt)
+
+static bool_ quest_thrain_turn_hook(void *, void *, void *)
{
cquest.data[1] = 0;
cquest.data[2] = 0;
return (FALSE);
}
+
bool_ quest_thrain_init_hook(int q)
{
if (!cquest.data[0])
@@ -219,15 +246,15 @@ bool_ quest_thrain_init_hook(int q)
}
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MOVE, quest_thrain_move_hook, "thrain_move");
+ add_hook_new(HOOK_MOVE, quest_thrain_move_hook, "thrain_move", NULL);
}
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_LEVEL_REGEN, quest_thrain_turn_hook, "thrain_regen_lvl");
- add_hook(HOOK_NEW_LEVEL, quest_thrain_turn_hook, "thrain_new_lvl");
- add_hook(HOOK_BUILD_ROOM1, quest_thrain_gen_hook, "thrain_gen");
- add_hook(HOOK_FEELING, quest_thrain_feeling_hook, "thrain_feel");
- add_hook(HOOK_MONSTER_DEATH, quest_thrain_death_hook, "thrain_death");
+ add_hook_new(HOOK_LEVEL_REGEN, quest_thrain_turn_hook, "thrain_regen_lvl", NULL);
+ add_hook_new(HOOK_NEW_LEVEL, quest_thrain_turn_hook, "thrain_new_lvl", NULL);
+ add_hook_new(HOOK_BUILD_ROOM1, quest_thrain_gen_hook, "thrain_gen", NULL);
+ add_hook_new(HOOK_FEELING, quest_thrain_feeling_hook, "thrain_feel", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_thrain_death_hook, "thrain_death", NULL);
}
return (FALSE);
}
diff --git a/src/q_thrain.hpp b/src/q_thrain.hpp
new file mode 100644
index 00000000..830da016
--- /dev/null
+++ b/src/q_thrain.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern bool_ quest_thrain_init_hook(int q_idx);
diff --git a/src/q_troll.c b/src/q_troll.cc
index c314d2a7..7227c1c3 100644
--- a/src/q_troll.c
+++ b/src/q_troll.cc
@@ -1,7 +1,30 @@
-#undef cquest
+#include "q_troll.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_TROLL])
-bool_ quest_troll_gen_hook(char *fmt)
+GENERATE_MONSTER_LOOKUP_FN(get_tom, "Tom the Stone Troll")
+GENERATE_MONSTER_LOOKUP_FN(get_stone_troll, "Stone troll")
+GENERATE_MONSTER_LOOKUP_FN(get_forest_troll, "Forest troll")
+
+static bool_ quest_troll_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -33,11 +56,9 @@ bool_ quest_troll_gen_hook(char *fmt)
{
if (cave[y][x].feat == FEAT_MARKER)
{
- int m_idx;
-
- m_allow_special[test_monster_name("Tom the Stone Troll")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("Tom the Stone Troll"), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[test_monster_name("Tom the Stone Troll")] = FALSE;
+ m_allow_special[get_tom()] = TRUE;
+ int m_idx = place_monster_one(y, x, get_tom(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_tom()] = FALSE;
if (m_idx)
{
@@ -72,14 +93,11 @@ bool_ quest_troll_gen_hook(char *fmt)
/* Structure copy */
object_copy(o_ptr, q_ptr);
- /* Build a stack */
- o_ptr->next_o_idx = m_list[m_idx].hold_o_idx;
-
+ /* Add to monster's inventory */
o_ptr->held_m_idx = m_idx;
o_ptr->ix = 0;
o_ptr->iy = 0;
-
- m_list[m_idx].hold_o_idx = o_idx;
+ m_list[m_idx].hold_o_idxs.push_back(o_idx);
}
else
{
@@ -93,11 +111,11 @@ bool_ quest_troll_gen_hook(char *fmt)
cquest.data[0] = FALSE;
return TRUE;
}
-bool_ quest_troll_finish_hook(char *fmt)
-{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+static bool_ quest_troll_finish_hook(void *, void *in_, void *)
+{
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_TROLL) return FALSE;
@@ -108,31 +126,29 @@ bool_ quest_troll_finish_hook(char *fmt)
*(quest[q_idx].plot) = QUEST_NAZGUL;
quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));
- del_hook(HOOK_QUEST_FINISH, quest_troll_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_troll_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
-bool_ quest_troll_death_hook(char *fmt)
+
+static bool_ quest_troll_death_hook(void *, void *in_, void *)
{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
int x, y, xstart = 2, ystart = 2;
- s32b r_idx, m_idx;
- ;
-
- m_idx = get_next_arg(fmt);
-
- r_idx = m_list[m_idx].r_idx;
if (p_ptr->inside_quest != QUEST_TROLL) return FALSE;
- if (r_idx == test_monster_name("Tom the Stone Troll"))
+ if (r_idx == get_tom())
{
cave_set_feat(3, 3, FEAT_LESS);
cave[3][3].special = 0;
cmsg_print(TERM_YELLOW, "Without Tom, the trolls won't be able to do much.");
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_troll_death_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_troll_death_hook);
process_hooks_restart = TRUE;
return (FALSE);
}
@@ -154,25 +170,24 @@ bool_ quest_troll_death_hook(char *fmt)
/* Ahah ! */
if (c_ptr->info & CAVE_SPEC)
{
- int r_idx;
-
cave_set_feat(y, x, FEAT_GRASS);
c_ptr->info &= ~CAVE_SPEC;
- r_idx = (rand_int(2) == 0) ? test_monster_name("Forest troll") : test_monster_name("Stone troll");
+ int r_idx = (rand_int(2) == 0) ? get_forest_troll() : get_stone_troll();
place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);
}
}
return FALSE;
}
+
bool_ quest_troll_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_troll_death_hook, "troll_death");
- add_hook(HOOK_GEN_QUEST, quest_troll_gen_hook, "troll_gen");
- add_hook(HOOK_QUEST_FINISH, quest_troll_finish_hook, "troll_finish");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_troll_death_hook, "troll_death", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_troll_gen_hook, "troll_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_troll_finish_hook, "troll_finish", NULL);
}
return (FALSE);
}
diff --git a/src/q_troll.hpp b/src/q_troll.hpp
new file mode 100644
index 00000000..140fe0b2
--- /dev/null
+++ b/src/q_troll.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_troll_init_hook(int q_idx);
diff --git a/src/q_ultrae.c b/src/q_ultrae.cc
index 78471df5..d42b9c6f 100644
--- a/src/q_ultrae.c
+++ b/src/q_ultrae.cc
@@ -1,8 +1,5 @@
-/*
- * Here takes place the Evil ultra ending
- */
+#include "q_ultrae.hpp"
-#undef cquest
#define cquest (quest[QUEST_ULTRA_EVIL])
bool_ quest_ultra_evil_init_hook(int q)
diff --git a/src/q_ultrae.hpp b/src/q_ultrae.hpp
new file mode 100644
index 00000000..5b08127b
--- /dev/null
+++ b/src/q_ultrae.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_ultra_evil_init_hook(int q_idx);
diff --git a/src/q_ultrag.c b/src/q_ultrag.cc
index a5a09f2d..c7c0312b 100644
--- a/src/q_ultrag.c
+++ b/src/q_ultrag.cc
@@ -1,18 +1,30 @@
-/*
- * Here takes place the Good ultra ending
- */
+#include "q_ultrag.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_chardump_in.hpp"
+#include "hook_move_in.hpp"
+#include "hook_stair_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hooks.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
-#undef cquest
#define cquest (quest[QUEST_ULTRA_GOOD])
-bool_ quest_ultra_good_move_hook(char *fmt)
+static bool_ quest_ultra_good_move_hook(void *, void *in_, void *)
{
- s32b y, x;
- cave_type *c_ptr;
-
- y = get_next_arg(fmt);
- x = get_next_arg(fmt);
- c_ptr = &cave[y][x];
+ struct hook_move_in *in = static_cast<struct hook_move_in *>(in_);
+ s32b y = in->y;
+ s32b x = in->x;
+ cave_type *c_ptr = &cave[y][x];
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
@@ -77,30 +89,29 @@ bool_ quest_ultra_good_move_hook(char *fmt)
return FALSE;
}
-bool_ quest_ultra_good_stair_hook(char *fmt)
+static bool_ quest_ultra_good_stair_hook(void *, void *in_, void *)
{
- cptr dir;
-
- dir = get_next_arg_str(fmt);
+ struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_);
+ stairs_direction dir = in->direction;
if (dungeon_type != DUNGEON_VOID)
return FALSE;
/* Cant leave */
- if ((!strcmp(dir, "up")) && (dun_level == 128))
+ if ((dir == STAIRS_UP) && (dun_level == 128))
{
cmsg_print(TERM_YELLOW, "The portal to Arda is now closed.");
return TRUE;
}
/* there is no coming back */
- if ((!strcmp(dir, "up")) && (dun_level == 150))
+ if ((dir == STAIRS_UP) && (dun_level == 150))
{
cmsg_print(TERM_YELLOW, "The barrier seems to be impenetrable from this side.");
cmsg_print(TERM_YELLOW, "You will have to move on.");
return TRUE;
}
/* Cant enter without the flame imperishable */
- if ((!strcmp(dir, "down")) && (dun_level == 149))
+ if ((dir == STAIRS_DOWN) && (dun_level == 149))
{
int i;
bool_ ultimate = FALSE;
@@ -140,7 +151,7 @@ bool_ quest_ultra_good_stair_hook(char *fmt)
return FALSE;
}
-bool_ quest_ultra_good_recall_hook(char *fmt)
+static bool_ quest_ultra_good_recall_hook(void *, void *, void *)
{
if ((dungeon_type != DUNGEON_VOID) && (dungeon_type != DUNGEON_NETHER_REALM))
return FALSE;
@@ -149,9 +160,10 @@ bool_ quest_ultra_good_recall_hook(char *fmt)
return TRUE;
}
-bool_ quest_ultra_good_death_hook(char *fmt)
+static bool_ quest_ultra_good_death_hook(void *, void *in_, void *)
{
- s32b m_idx = get_next_arg(fmt);
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
monster_type *m_ptr = &m_list[m_idx];
@@ -164,7 +176,7 @@ bool_ quest_ultra_good_death_hook(char *fmt)
quest[QUEST_ULTRA_GOOD].status = QUEST_STATUS_FINISHED;
/* Redraw the "title" */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Congratulations */
cmsg_print(TERM_L_GREEN, "****** CONGRATULATIONS ******");
@@ -180,7 +192,7 @@ bool_ quest_ultra_good_death_hook(char *fmt)
cave_set_feat(p_ptr->py, p_ptr->px, FEAT_MORE);
/* Remove now used hook */
- del_hook(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook);
+ del_hook_new(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook);
process_hooks_restart = TRUE;
/* End plot */
@@ -235,23 +247,27 @@ bool_ quest_ultra_good_death_hook(char *fmt)
}
return (FALSE);
}
-bool_ quest_ultra_good_dump_hook(char *fmt)
+
+static bool_ quest_ultra_good_dump_hook(void *, void *in_, void *)
{
+ struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_);
+ FILE *f = in->file;
+
if (quest[QUEST_ULTRA_GOOD].status >= QUEST_STATUS_TAKEN)
{
/* Ultra winner ! */
if (total_winner == WINNER_ULTRA)
{
- fprintf(hook_file, "\n You destroyed Melkor forever and have been elevated to the status of Vala by Eru Iluvatar.");
- fprintf(hook_file, "\n Arda will forever be free.");
+ fprintf(f, "\n You destroyed Melkor forever and have been elevated to the status of Vala by Eru Iluvatar.");
+ fprintf(f, "\n Arda will forever be free.");
}
else
{
/* Tried and failed */
if (death)
{
- fprintf(hook_file, "\n You tried to destroy Melkor forever, but died in the attempt.");
- fprintf(hook_file, "\n Arda will be quiet, but not free from evil.");
+ fprintf(f, "\n You tried to destroy Melkor forever, but died in the attempt.");
+ fprintf(f, "\n Arda will be quiet, but not free from evil.");
}
}
}
@@ -263,14 +279,14 @@ bool_ quest_ultra_good_init_hook(int q)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_STAIR, quest_ultra_good_stair_hook, "ultrag_stair");
- add_hook(HOOK_RECALL, quest_ultra_good_recall_hook, "ultrag_recall");
- add_hook(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook, "ultrag_death");
+ add_hook_new(HOOK_STAIR, quest_ultra_good_stair_hook, "ultrag_stair", NULL);
+ add_hook_new(HOOK_RECALL, quest_ultra_good_recall_hook, "ultrag_recall", NULL);
+ add_hook_new(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook, "ultrag_death", NULL);
}
if (cquest.status == QUEST_STATUS_UNTAKEN)
{
- add_hook(HOOK_MOVE, quest_ultra_good_move_hook, "ultrag_move");
+ add_hook_new(HOOK_MOVE, quest_ultra_good_move_hook, "ultrag_move", NULL);
}
- add_hook(HOOK_CHAR_DUMP, quest_ultra_good_dump_hook, "ultrag_dump");
+ add_hook_new(HOOK_CHAR_DUMP, quest_ultra_good_dump_hook, "ultrag_dump", NULL);
return (FALSE);
}
diff --git a/src/q_ultrag.hpp b/src/q_ultrag.hpp
new file mode 100644
index 00000000..0064b878
--- /dev/null
+++ b/src/q_ultrag.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_ultra_good_init_hook(int q_idx);
diff --git a/src/q_wight.c b/src/q_wight.cc
index 3f6b2c34..499535ca 100644
--- a/src/q_wight.c
+++ b/src/q_wight.cc
@@ -1,7 +1,27 @@
-#undef cquest
+#include "q_wight.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object2.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+
#define cquest (quest[QUEST_WIGHT])
-bool_ quest_wight_gen_hook(char *fmt)
+GENERATE_MONSTER_LOOKUP_FN(get_wight_king, "The Wight-King of the Barrow-downs")
+
+static bool_ quest_wight_gen_hook(void *, void *, void *)
{
int x, y;
int xstart = 2;
@@ -35,9 +55,9 @@ bool_ quest_wight_gen_hook(char *fmt)
{
int m_idx = 0;
- m_allow_special[test_monster_name("The Wight-King of the Barrow-downs")] = TRUE;
- m_idx = place_monster_one(y, x, test_monster_name("The Wight-King of the Barrow-downs"), 0, FALSE, MSTATUS_ENEMY);
- m_allow_special[test_monster_name("The Wight-King of the Barrow-downs")] = FALSE;
+ m_allow_special[get_wight_king()] = TRUE;
+ m_idx = place_monster_one(y, x, get_wight_king(), 0, FALSE, MSTATUS_ENEMY);
+ m_allow_special[get_wight_king()] = FALSE;
if (m_idx)
{
@@ -87,13 +107,11 @@ bool_ quest_wight_gen_hook(char *fmt)
object_copy(o_ptr, q_ptr);
/* Build a stack */
- o_ptr->next_o_idx = m_list[m_idx].hold_o_idx;
-
o_ptr->held_m_idx = m_idx;
o_ptr->ix = 0;
o_ptr->iy = 0;
- m_list[m_idx].hold_o_idx = o_idx;
+ m_list[m_idx].hold_o_idxs.push_back(o_idx);
}
}
}
@@ -101,16 +119,16 @@ bool_ quest_wight_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_wight_death_hook(char *fmt)
-{
- s32b r_idx, m_idx;
- m_idx = get_next_arg(fmt);
- r_idx = m_list[m_idx].r_idx;
+static bool_ quest_wight_death_hook(void *, void *in_, void *)
+{
+ struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_);
+ s32b m_idx = in->m_idx;
+ s32b r_idx = m_list[m_idx].r_idx;
if (p_ptr->inside_quest != QUEST_WIGHT) return FALSE;
- if (r_idx == test_monster_name("The Wight-King of the Barrow-downs"))
+ if (r_idx == get_wight_king())
{
cmsg_print(TERM_YELLOW, "Without their King the wights won't be able to do much.");
@@ -118,17 +136,20 @@ bool_ quest_wight_death_hook(char *fmt)
cave[p_ptr->py][p_ptr->px].special = 0;
cquest.status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_wight_death_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_wight_death_hook);
process_hooks_restart = TRUE;
+
return (FALSE);
}
return (FALSE);
}
-bool_ quest_wight_finish_hook(char *fmt)
+
+static bool_ quest_wight_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
- q_idx = get_next_arg(fmt);
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_WIGHT) return FALSE;
@@ -139,18 +160,19 @@ bool_ quest_wight_finish_hook(char *fmt)
*(quest[q_idx].plot) = QUEST_NAZGUL;
quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));
- del_hook(HOOK_QUEST_FINISH, quest_wight_finish_hook);
+ del_hook_new(HOOK_QUEST_FINISH, quest_wight_finish_hook);
process_hooks_restart = TRUE;
return TRUE;
}
+
bool_ quest_wight_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_wight_death_hook, "wight_death");
- add_hook(HOOK_GEN_QUEST, quest_wight_gen_hook, "wight_gen");
- add_hook(HOOK_QUEST_FINISH, quest_wight_finish_hook, "wight_finish");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_wight_death_hook, "wight_death", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_wight_gen_hook, "wight_gen", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_wight_finish_hook, "wight_finish", NULL);
}
return (FALSE);
}
diff --git a/src/q_wight.hpp b/src/q_wight.hpp
new file mode 100644
index 00000000..1252e4fa
--- /dev/null
+++ b/src/q_wight.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_wight_init_hook(int q_idx);
diff --git a/src/q_wolves.c b/src/q_wolves.cc
index 2ec14cc2..117e8d42 100644
--- a/src/q_wolves.c
+++ b/src/q_wolves.cc
@@ -1,7 +1,22 @@
-#undef cquest
+#include "q_wolves.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_quest_finish_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "player_type.hpp"
+#include "quest_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+
#define cquest (quest[QUEST_WOLVES])
-bool_ quest_wolves_gen_hook(char *fmt)
+static bool_ quest_wolves_gen_hook(void *, void *, void *)
{
int x, y, i;
int xstart = 2;
@@ -69,7 +84,7 @@ bool_ quest_wolves_gen_hook(char *fmt)
return TRUE;
}
-bool_ quest_wolves_death_hook(char *fmt)
+static bool_ quest_wolves_death_hook(void *, void *, void *)
{
int i, mcnt = 0;
@@ -91,8 +106,9 @@ bool_ quest_wolves_death_hook(char *fmt)
if (mcnt <= 1)
{
quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
- del_hook(HOOK_MONSTER_DEATH, quest_wolves_death_hook);
- del_hook(HOOK_GEN_QUEST, quest_wolves_gen_hook);
+
+ del_hook_new(HOOK_MONSTER_DEATH, quest_wolves_death_hook);
+ del_hook_new(HOOK_GEN_QUEST, quest_wolves_gen_hook);
process_hooks_restart = TRUE;
cmsg_print(TERM_YELLOW, "Lothlorien is safer now.");
@@ -101,11 +117,10 @@ bool_ quest_wolves_death_hook(char *fmt)
return FALSE;
}
-bool_ quest_wolves_finish_hook(char *fmt)
+static bool_ quest_wolves_finish_hook(void *, void *in_, void *)
{
- s32b q_idx;
-
- q_idx = get_next_arg(fmt);
+ struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_);
+ s32b q_idx = in->q_idx;
if (q_idx != QUEST_WOLVES) return FALSE;
@@ -122,9 +137,9 @@ bool_ quest_wolves_init_hook(int q_idx)
{
if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
{
- add_hook(HOOK_MONSTER_DEATH, quest_wolves_death_hook, "wolves_monster_death");
- add_hook(HOOK_QUEST_FINISH, quest_wolves_finish_hook, "wolves_finish");
- add_hook(HOOK_GEN_QUEST, quest_wolves_gen_hook, "wolves_geb");
+ add_hook_new(HOOK_MONSTER_DEATH, quest_wolves_death_hook, "wolves_monster_death", NULL);
+ add_hook_new(HOOK_QUEST_FINISH, quest_wolves_finish_hook, "wolves_finish", NULL);
+ add_hook_new(HOOK_GEN_QUEST, quest_wolves_gen_hook, "wolves_geb", NULL);
}
return (FALSE);
}
diff --git a/src/q_wolves.hpp b/src/q_wolves.hpp
new file mode 100644
index 00000000..59a83c56
--- /dev/null
+++ b/src/q_wolves.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "h-basic.h"
+
+bool_ quest_wolves_init_hook(int q_idx);
diff --git a/src/quark.c b/src/quark.cc
index 32efaaa0..45072ded 100644
--- a/src/quark.c
+++ b/src/quark.cc
@@ -1,6 +1,8 @@
-#include "quark.h"
+#include "quark.hpp"
-#include "angband.h"
+#include "z-util.h"
+
+#include <cassert>
/*
* The number of quarks
@@ -20,7 +22,11 @@ static cptr *quark__str = NULL;
void quark_init()
{
quark__num = 0;
- C_MAKE(quark__str, QUARK_MAX, cptr);
+ quark__str = new cptr[QUARK_MAX];
+
+ for (int i = 0; i < QUARK_MAX; i++) {
+ quark__str[i] = nullptr;
+ }
}
@@ -45,6 +51,8 @@ void quark_init()
*/
s16b quark_add(cptr str)
{
+ assert(str != nullptr);
+
int i;
/* Look for an existing quark */
@@ -61,7 +69,7 @@ s16b quark_add(cptr str)
quark__num = i + 1;
/* Add a new quark */
- quark__str[i] = string_make(str);
+ quark__str[i] = strdup(str);
/* Return the index */
return (i);
diff --git a/src/quark.h b/src/quark.h
deleted file mode 100644
index 9488b105..00000000
--- a/src/quark.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef H_eeb941c7_1a44_405a_8db3_ba14732c5b94
-#define H_eeb941c7_1a44_405a_8db3_ba14732c5b94
-
-#include "h-type.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void quark_init();
-cptr quark_str(s16b num);
-s16b quark_add(cptr str);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
diff --git a/src/quark.hpp b/src/quark.hpp
new file mode 100644
index 00000000..0fce3932
--- /dev/null
+++ b/src/quark.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Maximum number of quarks.
+ */
+constexpr int QUARK_MAX = 768;
+
+void quark_init();
+cptr quark_str(s16b num);
+s16b quark_add(cptr str);
diff --git a/src/quest.cc b/src/quest.cc
new file mode 100644
index 00000000..a1aee67f
--- /dev/null
+++ b/src/quest.cc
@@ -0,0 +1,17 @@
+#include "quest.hpp"
+
+#include "tables.hpp"
+
+#include <cstddef>
+
+void init_hooks_quests()
+{
+ for (std::size_t i = 0; i < MAX_Q_IDX; i++)
+ {
+ if (quest[i].init != NULL)
+ {
+ quest[i].init(i);
+ }
+ }
+}
+
diff --git a/src/quest.hpp b/src/quest.hpp
new file mode 100644
index 00000000..7ff3cd3c
--- /dev/null
+++ b/src/quest.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+extern void init_hooks_quests();
diff --git a/src/quest_type.hpp b/src/quest_type.hpp
new file mode 100644
index 00000000..aa99f40a
--- /dev/null
+++ b/src/quest_type.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Quest descriptor and runtime data.
+ */
+struct quest_type
+{
+ bool_ silent;
+
+ char name[40]; /* Quest name */
+
+ char desc[10][80]; /* Quest desc */
+
+ s16b status; /* Is the quest taken, completed, finished? */
+
+ s16b level; /* Dungeon level */
+
+ s16b *plot; /* Which plot does it belongs to? */
+
+ bool_ (*init)(int q); /* Function that takes care of generating hardcoded quests */
+
+ s32b data[9]; /* Various datas used by the quests */
+
+ bool_ (*gen_desc)(FILE *fff); /* Function for generating description. */
+};
diff --git a/src/randart.c b/src/randart.cc
index 10fd51b0..451bf948 100644
--- a/src/randart.c
+++ b/src/randart.cc
@@ -1,7 +1,3 @@
-/* File: randart.c */
-
-/* Purpose: Randart creation code */
-
/*
* Copyright (c) 2001 DarkGod
*
@@ -10,9 +6,23 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "quark.h"
+#include "randart.hpp"
+#include "mimic.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "randart_gen_type.hpp"
+#include "randart_part_type.hpp"
+#include "spells2.hpp"
+#include "util.hpp"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <memory>
+#include <vector>
/* Chance of using syllables to form the name instead of the "template" files */
#define TABLE_NAME 45
@@ -25,21 +35,19 @@
*/
static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *max_times)
{
- int i = 0, j;
- int *ok_ra, ok_num = 0;
bool_ ret = FALSE;
u32b f1, f2, f3, f4, f5, esp;
- C_MAKE(ok_ra, max_ra_idx, int);
+ std::vector<size_t> ok_ra;
/* Grab the ok randart */
- for (i = 0; i < max_ra_idx; i++)
+ for (size_t i = 0; i < max_ra_idx; i++)
{
randart_part_type *ra_ptr = &ra_info[i];
bool_ ok = FALSE;
/* Must have the correct fields */
- for (j = 0; j < 20; j++)
+ for (size_t j = 0; j < 20; j++)
{
if (ra_ptr->tval[j] == o_ptr->tval)
{
@@ -71,16 +79,14 @@ static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *m
if (esp & ra_ptr->aesp) continue;
/* ok */
- ok_ra[ok_num++] = i;
+ ok_ra.push_back(i);
}
/* Now test them a few times */
- for (i = 0; i < ok_num * 10; i++)
+ for (size_t count = 0; count < ok_ra.size() * 10; count++)
{
- randart_part_type *ra_ptr;
-
- i = ok_ra[rand_int(ok_num)];
- ra_ptr = &ra_info[i];
+ size_t i = ok_ra[rand_int(ok_ra.size())];
+ randart_part_type *ra_ptr = &ra_info[i];
/* XXX XXX Enforce minimum player level (loosely) */
if (ra_ptr->level > p_ptr->lev)
@@ -110,8 +116,6 @@ static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *m
break;
}
- C_FREE(ok_ra, max_ra_idx, int);
-
/* Return */
return (ret);
}
@@ -264,7 +268,6 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
s32b total_flags, total_power = 0;
bool_ a_cursed = FALSE;
u32b f1, f2, f3, f4, f5, esp;
- s16b *max_times;
s16b pval = 0;
bool_ limit_blows = FALSE;
@@ -283,7 +286,10 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
if (a_cursed) powers /= 2;
- C_MAKE(max_times, max_ra_idx, s16b);
+ std::unique_ptr<s16b[]> max_times(new s16b[max_ra_idx]);
+ for (int i = 0; i < max_ra_idx; i++) {
+ max_times[i] = 0;
+ }
/* Main loop */
while (powers)
@@ -293,7 +299,7 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
powers--;
- if (!grab_one_power(&ra_idx, o_ptr, TRUE, max_times)) continue;
+ if (!grab_one_power(&ra_idx, o_ptr, TRUE, max_times.get())) continue;
ra_ptr = &ra_info[ra_idx];
@@ -327,7 +333,6 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
/* Hack -- obtain pval */
if (((pval > ra_ptr->max_pval) && ra_ptr->max_pval) || (!pval)) pval = ra_ptr->max_pval;
};
- C_FREE(max_times, max_ra_idx, s16b);
if (pval > 0) o_ptr->pval = randint(pval);
if (pval < 0) o_ptr->pval = randint( -pval);
@@ -404,26 +409,24 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
bool_ artifact_scroll(void)
{
- int item;
bool_ okay = FALSE;
- object_type *o_ptr;
- char o_name[80];
-
- cptr q, s;
-
-
- /* Enchant weapon/armour */
- item_tester_hook = item_tester_hook_artifactable;
/* Get an item */
- q = "Enchant which item? ";
- s = "You have nothing to enchant.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Enchant which item? ",
+ "You have nothing to enchant.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ item_tester_hook_artifactable()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, FALSE, 0);
/* Describe */
diff --git a/src/randart.hpp b/src/randart.hpp
new file mode 100644
index 00000000..31b70f08
--- /dev/null
+++ b/src/randart.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+
+extern int get_activation_power(void);
+extern void build_prob(cptr learn);
+extern bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name);
+extern bool_ artifact_scroll(void);
diff --git a/src/randart_gen_type.hpp b/src/randart_gen_type.hpp
new file mode 100644
index 00000000..09aedcd9
--- /dev/null
+++ b/src/randart_gen_type.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+struct randart_gen_type
+{
+ int chance; /* Chance to have that number of powers */
+ int dd;
+ int ds;
+ int plus; /* xdy+plus power */
+};
diff --git a/src/randart_gen_type_fwd.hpp b/src/randart_gen_type_fwd.hpp
new file mode 100644
index 00000000..eba3e84e
--- /dev/null
+++ b/src/randart_gen_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct randart_gen_type;
diff --git a/src/randart_part_type.hpp b/src/randart_part_type.hpp
new file mode 100644
index 00000000..c2fa5386
--- /dev/null
+++ b/src/randart_part_type.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Random artifact part descriptor.
+ */
+struct randart_part_type
+{
+ byte tval[20];
+ byte min_sval[20];
+ byte max_sval[20];
+
+ byte level; /* Minimum level */
+ byte rarity; /* Object rarity */
+ byte mrarity; /* Object rarity */
+
+ s16b max_to_h; /* Maximum to-hit bonus */
+ s16b max_to_d; /* Maximum to-dam bonus */
+ s16b max_to_a; /* Maximum to-ac bonus */
+
+ s32b max_pval; /* Maximum pval */
+
+ s32b value; /* power value */
+ s16b max; /* Number of time it can appear on a single item */
+
+ u32b flags1; /* Ego-Item Flags, set 1 */
+ u32b flags2; /* Ego-Item Flags, set 2 */
+ u32b flags3; /* Ego-Item Flags, set 3 */
+ u32b flags4; /* Ego-Item Flags, set 4 */
+ u32b flags5; /* Ego-Item Flags, set 5 */
+ u32b esp; /* ESP flags */
+ u32b fego; /* ego flags */
+
+ u32b aflags1; /* Ego-Item Flags, set 1 */
+ u32b aflags2; /* Ego-Item Flags, set 2 */
+ u32b aflags3; /* Ego-Item Flags, set 3 */
+ u32b aflags4; /* Ego-Item Flags, set 4 */
+ u32b aflags5; /* Ego-Item Flags, set 5 */
+ u32b aesp; /* ESP flags */
+
+ s16b power; /* Power granted(if any) */
+};
diff --git a/src/randart_part_type_fwd.hpp b/src/randart_part_type_fwd.hpp
new file mode 100644
index 00000000..979fd72c
--- /dev/null
+++ b/src/randart_part_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct randart_part_type;
diff --git a/src/random_artifact.hpp b/src/random_artifact.hpp
new file mode 100644
index 00000000..a3fc1c66
--- /dev/null
+++ b/src/random_artifact.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Random artifact descriptor.
+ */
+struct random_artifact
+{
+ char name_full[80]; /* Full name for the artifact */
+ char name_short[80]; /* Un-Id'd name */
+ byte level; /* Level of the artifact */
+ byte attr; /* Color that is used on the screen */
+ u32b cost; /* Object's value */
+ byte activation; /* Activation. */
+ s16b timeout; /* Timeout. */
+ byte generated; /* Does it exist already? */
+};
diff --git a/src/random_quest.hpp b/src/random_quest.hpp
new file mode 100644
index 00000000..11ebe797
--- /dev/null
+++ b/src/random_quest.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "h-basic.h"
+
+struct random_quest
+{
+ byte type; /* Type/number of monsters to kill(0 = no quest) */
+ s16b r_idx; /* Monsters to crush */
+ bool_ done; /* Done ? */
+};
diff --git a/src/random_spell.hpp b/src/random_spell.hpp
new file mode 100644
index 00000000..01b5ba5e
--- /dev/null
+++ b/src/random_spell.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * A structure to describe the random spells of the Power Mages
+ */
+struct random_spell
+{
+ char desc[30]; /* Desc of the spell */
+ char name[30]; /* Name of the spell */
+ s16b mana; /* Mana cost */
+ s16b fail; /* Failure rate */
+ u32b proj_flags; /* Project function flags */
+ byte GF; /* Type of the projection */
+ byte radius;
+ byte dam_sides;
+ byte dam_dice;
+ byte level; /* Level needed */
+ bool_ untried; /* Is the spell was tried? */
+};
diff --git a/src/range.c b/src/range.cc
index 647f0576..7bd407c7 100644
--- a/src/range.c
+++ b/src/range.cc
@@ -1,4 +1,6 @@
-#include <angband.h>
+#include "range.hpp"
+
+#include <cassert>
void range_init(range_type *range, s32b min, s32b max)
{
diff --git a/src/range.hpp b/src/range.hpp
new file mode 100644
index 00000000..3c185ba6
--- /dev/null
+++ b/src/range.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "range_fwd.hpp"
+#include "h-basic.h"
+
+/*
+ * Range
+ */
+struct range_type
+{
+ s32b min;
+ s32b max;
+};
+
+void range_init(range_type *range, s32b min, s32b max);
diff --git a/src/range_fwd.hpp b/src/range_fwd.hpp
new file mode 100644
index 00000000..b5eef3fa
--- /dev/null
+++ b/src/range_fwd.hpp
@@ -0,0 +1,4 @@
+#pragma once
+
+typedef struct range_type range_type;
+struct range_type;
diff --git a/src/readdib.c b/src/readdib.c
deleted file mode 100644
index 294c2702..00000000
--- a/src/readdib.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* File: readbits.c */
-
-/*
- * This package provides a routine to read a DIB file and set up the
- * device dependent version of the image.
- *
- * This file has been modified for use with "Angband 2.8.2"
- *
- * COPYRIGHT:
- *
- * (C) Copyright Microsoft Corp. 1993. All rights reserved.
- *
- * You have a royalty-free right to use, modify, reproduce and
- * distribute the Sample Files (and/or any modified version) in
- * any way you find useful, provided that you agree that
- * Microsoft has no warranty obligations or liability for any
- * Sample Application Files which are modified.
- */
-
-#ifdef WINDOWS
-
-#include <windows.h>
-
-#include "readdib.h"
-
-
-/*
- * Extract the "WIN32" flag from the compiler
- */
-#if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-
-/*
- * Make sure "huge" is legal XXX XXX XXX
- */
-#undef huge
-#ifdef WIN32
-# define huge /* oops */
-#endif
-
-
-/*
- * Number of bytes to be read during each read operation
- */
-#define MAXREAD 32768
-
-/*
- * Private routine to read more than 64K at a time
- *
- * Reads data in steps of 32k till all the data has been read.
- *
- * Returns number of bytes requested, or zero if something went wrong.
- */
-static DWORD PASCAL lread(int fh, VOID far *pv, DWORD ul)
-{
- DWORD ulT = ul;
- BYTE huge *hp = pv;
-
- while (ul > (DWORD)MAXREAD)
- {
- if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
- return 0;
- ul -= MAXREAD;
- hp += MAXREAD;
- }
- if (_lread(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
- return 0;
- return ulT;
-}
-
-
-/*
- * Given a BITMAPINFOHEADER, create a palette based on the color table.
- *
- * Returns the handle of a palette, or zero if something went wrong.
- */
-static HPALETTE PASCAL NEAR MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
-{
- NPLOGPALETTE npPal;
- RGBQUAD far *lpRGB;
- HPALETTE hLogPal;
- WORD i;
-
- /*
- * since biClrUsed field was filled during the loading of the DIB,
- * we know it contains the number of colors in the color table.
- */
- if (lpInfo->biClrUsed)
- {
- npPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
- (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
- if (!npPal)
- return (FALSE);
-
- npPal->palVersion = 0x300;
- npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
-
- /* get pointer to the color table */
- lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
-
- /* copy colors from the color table to the LogPalette structure */
- for (i = 0; i < lpInfo->biClrUsed; i++, lpRGB++)
- {
- npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
- npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
- npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
- npPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
- }
-
- hLogPal = CreatePalette((LPLOGPALETTE)npPal);
- LocalFree((HANDLE)npPal);
- return (hLogPal);
- }
-
- /*
- * 24-bit DIB with no color table. return default palette. Another
- * option would be to create a 256 color "rainbow" palette to provide
- * some good color choices.
- */
- else
- {
- return (GetStockObject(DEFAULT_PALETTE));
- }
-}
-
-
-/*
- * Given a DIB, create a bitmap and corresponding palette to be used for a
- * device-dependent representation of the image.
- *
- * Returns TRUE on success (phPal and phBitmap are filled with appropriate
- * handles. Caller is responsible for freeing objects) and FALSE on failure
- * (unable to create objects, both pointer are invalid).
- */
-static BOOL NEAR PASCAL MakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
- HPALETTE * phPal, HBITMAP * phBitmap)
-{
- LPBITMAPINFOHEADER lpInfo;
- BOOL result = FALSE;
- HBITMAP hBitmap;
- HPALETTE hPalette, hOldPal;
- LPSTR lpBits;
-
- lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
- if ((hPalette = MakeDIBPalette(lpInfo)) != 0)
- {
- /* Need to realize palette for converting DIB to bitmap. */
- hOldPal = SelectPalette(hDC, hPalette, TRUE);
- RealizePalette(hDC);
-
- lpBits = ((LPSTR)lpInfo + (WORD)lpInfo->biSize +
- (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD));
- hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
- (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
-
- SelectPalette(hDC, hOldPal, TRUE);
- RealizePalette(hDC);
-
- if (!hBitmap)
- {
- DeleteObject(hPalette);
- }
- else
- {
- *phBitmap = hBitmap;
- *phPal = hPalette;
- result = TRUE;
- }
- }
- return (result);
-}
-
-
-
-/*
- * Reads a DIB from a file, obtains a handle to its BITMAPINFO struct, and
- * loads the DIB. Once the DIB is loaded, the function also creates a bitmap
- * and palette out of the DIB for a device-dependent form.
- *
- * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
- * case, the DIBINIT structure pointed to by pInfo is filled with the appropriate
- * handles, and FALSE if something went wrong.
- */
-BOOL ReadDIB(HWND hWnd, LPSTR lpFileName, DIBINIT *pInfo)
-{
- unsigned fh;
- LPBITMAPINFOHEADER lpbi;
- OFSTRUCT of;
- BITMAPFILEHEADER bf;
- WORD nNumColors;
- BOOL result = FALSE;
- char str[128];
- WORD offBits;
- HDC hDC;
- BOOL bCoreHead = FALSE;
-
- /* Open the file and get a handle to it's BITMAPINFO */
- fh = OpenFile(lpFileName, &of, OF_READ);
- if (fh == -1)
- {
- wsprintf(str, "Can't open file '%ls'", (LPSTR)lpFileName);
- MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
- return (FALSE);
- }
-
- pInfo->hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD)));
-
- if (!pInfo->hDIB)
- return (FALSE);
-
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
-
- /* read the BITMAPFILEHEADER */
- if (sizeof (bf) != _lread(fh, (LPSTR)&bf, sizeof(bf)))
- goto ErrExit;
-
- /* 'BM' */
- if (bf.bfType != 0x4d42)
- goto ErrExit;
-
- if (sizeof(BITMAPCOREHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
- goto ErrExit;
-
- if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- {
- lpbi->biSize = sizeof(BITMAPINFOHEADER);
- lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
- lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
- lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
- lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
- bCoreHead = TRUE;
- }
- else
- {
- /* get to the start of the header and read INFOHEADER */
- _llseek(fh, sizeof(BITMAPFILEHEADER), SEEK_SET);
- if (sizeof(BITMAPINFOHEADER) != _lread(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
- goto ErrExit;
- }
-
- if (!(nNumColors = (WORD)lpbi->biClrUsed))
- {
- /* no color table for 24-bit, default size otherwise */
- if (lpbi->biBitCount != 24)
- nNumColors = 1 << lpbi->biBitCount;
- }
-
- /* fill in some default values if they are zero */
- if (lpbi->biClrUsed == 0)
- lpbi->biClrUsed = nNumColors;
-
- if (lpbi->biSizeImage == 0)
- {
- lpbi->biSizeImage = (((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
- * lpbi->biHeight);
- }
-
- /* otherwise wouldn't work with 16 color bitmaps -- S.K. */
- else if ((nNumColors == 16) && (lpbi->biSizeImage > bf.bfSize))
- {
- lpbi->biSizeImage /= 2;
- }
-
- /* get a proper-sized buffer for header, color table and bits */
- GlobalUnlock(pInfo->hDIB);
- pInfo->hDIB = GlobalReAlloc(pInfo->hDIB, lpbi->biSize +
- nNumColors * sizeof(RGBQUAD) +
- lpbi->biSizeImage, 0);
-
- /* can't resize buffer for loading */
- if (!pInfo->hDIB)
- goto ErrExit2;
-
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(pInfo->hDIB);
-
- /* read the color table */
- if (!bCoreHead)
- {
- _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
- }
- else
- {
- signed int i;
- RGBQUAD FAR *pQuad;
- RGBTRIPLE FAR *pTriple;
-
- _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
-
- pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
- pTriple = (RGBTRIPLE FAR *) pQuad;
- for (i = nNumColors - 1; i >= 0; i--)
- {
- pQuad[i].rgbRed = pTriple[i].rgbtRed;
- pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
- pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
- pQuad[i].rgbReserved = 0;
- }
- }
-
- /* offset to the bits from start of DIB header */
- offBits = (WORD)lpbi->biSize + nNumColors * sizeof(RGBQUAD);
-
- if (bf.bfOffBits != 0L)
- {
- _llseek(fh, bf.bfOffBits, SEEK_SET);
- }
-
- /* Use local version of '_lread()' above */
- if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
- {
- GlobalUnlock(pInfo->hDIB);
-
- hDC = GetDC(hWnd);
- if (!MakeBitmapAndPalette(hDC, pInfo->hDIB, &(pInfo->hPalette),
- &(pInfo->hBitmap)))
- {
- ReleaseDC(hWnd, hDC);
- goto ErrExit2;
- }
- else
- {
- ReleaseDC(hWnd, hDC);
- result = TRUE;
- }
- }
- else
- {
-ErrExit:
- GlobalUnlock(pInfo->hDIB);
-ErrExit2:
- GlobalFree(pInfo->hDIB);
- }
-
- _lclose(fh);
- return (result);
-}
-
-#endif
diff --git a/src/readdib.h b/src/readdib.h
deleted file mode 100644
index c6402b50..00000000
--- a/src/readdib.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* File: readdib.h */
-
-/*
- * This file has been modified for use with "Angband 2.8.2"
- *
- * Copyright 1991 Microsoft Corporation. All rights reserved.
- */
-
-/*
- * Information about a bitmap
- */
-typedef struct {
- HANDLE hDIB;
- HANDLE hBitmap;
- HANDLE hPalette;
- BYTE CellWidth;
- BYTE CellHeight;
-} DIBINIT;
-
-/* Read a DIB from a file */
-BOOL ReadDIB(HWND, LPSTR, DIBINIT *);
diff --git a/src/rule_type.hpp b/src/rule_type.hpp
new file mode 100644
index 00000000..a8b35ffa
--- /dev/null
+++ b/src/rule_type.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "h-basic.h"
+
+/* Define monster generation rules */
+struct rule_type
+{
+ byte mode; /* Mode of combination of the monster flags */
+ byte percent; /* Percent of monsters affected by the rule */
+
+ u32b mflags1; /* The monster flags that are allowed */
+ u32b mflags2;
+ u32b mflags3;
+ u32b mflags4;
+ u32b mflags5;
+ u32b mflags6;
+ u32b mflags7;
+ u32b mflags8;
+ u32b mflags9;
+
+ char r_char[5]; /* Monster race allowed */
+};
diff --git a/src/rune_spell.hpp b/src/rune_spell.hpp
new file mode 100644
index 00000000..d04a8dc4
--- /dev/null
+++ b/src/rune_spell.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Runecrafter prefered spells
+ */
+struct rune_spell
+{
+ char name[30]; /* name */
+
+ s16b type; /* Type of the spell(GF) */
+ s16b rune2; /* Modifiers */
+ s16b mana; /* Mana involved */
+};
diff --git a/src/rune_spell_fwd.hpp b/src/rune_spell_fwd.hpp
new file mode 100644
index 00000000..eb540a2a
--- /dev/null
+++ b/src/rune_spell_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct rune_spell;
diff --git a/src/school_book.hpp b/src/school_book.hpp
new file mode 100644
index 00000000..51d3e6a7
--- /dev/null
+++ b/src/school_book.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+#include <vector>
+
+/**
+ * School book.
+ */
+struct school_book {
+ /**
+ * Indexes of all the spells in the book.
+ */
+ std::vector<s32b> spell_idxs;
+};
diff --git a/src/school_book_fwd.hpp b/src/school_book_fwd.hpp
new file mode 100644
index 00000000..46363da6
--- /dev/null
+++ b/src/school_book_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct school_book;
diff --git a/src/school_type.hpp b/src/school_type.hpp
new file mode 100644
index 00000000..7a5702b4
--- /dev/null
+++ b/src/school_type.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "h-basic.h"
+#include "deity_type_fwd.hpp"
+
+struct school_type
+{
+ cptr name; /* Name */
+ s16b skill; /* Skill used for that school */
+ bool_ spell_power; /* Does spell power affect spells in this school? */
+ bool_ sorcery; /* Does Sorcery affect this school? */
+
+ int deity_idx; /* Deity; if <=0, no deity required */
+ deity_type *deity; /* Direct pointer to deity */
+
+ int (*bonus_levels)(); /* Calculate number of bonus levels */
+
+ bool_ (*depends_satisfied)(); /* Are dependendies satisfied? */
+
+ struct school_provider_list *providers; /* List of secondary providers of this school */
+};
diff --git a/src/school_type_fwd.hpp b/src/school_type_fwd.hpp
new file mode 100644
index 00000000..dea0d3b4
--- /dev/null
+++ b/src/school_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct school_type;
diff --git a/src/script.c b/src/script.cc
index 40f43f95..84f7c3e4 100644
--- a/src/script.c
+++ b/src/script.cc
@@ -1,7 +1,3 @@
-/* File: script.c */
-
-/* Purpose: scripting in lua */
-
/*
* Copyright (c) 2001 Dark God
*
@@ -10,7 +6,13 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "script.h"
+
+#include "init2.hpp"
+#include "q_library.hpp"
+#include "spells4.hpp"
+#include "spells5.hpp"
+#include "spells6.hpp"
void init_lua_init()
diff --git a/src/script.h b/src/script.h
new file mode 100644
index 00000000..3d1a0840
--- /dev/null
+++ b/src/script.h
@@ -0,0 +1,12 @@
+#pragma once
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void init_lua_init(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/set_type.hpp b/src/set_type.hpp
new file mode 100644
index 00000000..827c23ac
--- /dev/null
+++ b/src/set_type.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Item set descriptor and runtime information.
+ */
+struct set_type
+{
+ const char *name; /* Name */
+ char *desc; /* Desc */
+
+ byte num; /* Number of artifacts used */
+ byte num_use; /* Number actually wore */
+
+ struct /* the various items */
+ {
+ bool_ present; /* Is it actually wore ? */
+ s16b a_idx; /* What artifact ? */
+ s16b pval[6]; /* Pval for each combination */
+ u32b flags1[6]; /* Flags */
+ u32b flags2[6]; /* Flags */
+ u32b flags3[6]; /* Flags */
+ u32b flags4[6]; /* Flags */
+ u32b flags5[6]; /* Flags */
+ u32b esp[6]; /* Flags */
+ } arts[6];
+};
diff --git a/src/set_type_fwd.hpp b/src/set_type_fwd.hpp
new file mode 100644
index 00000000..3b311808
--- /dev/null
+++ b/src/set_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct set_type;
diff --git a/src/skill_type.hpp b/src/skill_type.hpp
new file mode 100644
index 00000000..c6de1dc1
--- /dev/null
+++ b/src/skill_type.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "h-basic.h"
+#include "skills_defs.hpp"
+
+/**
+ * Skill descriptors and runtime data.
+ */
+struct skill_type
+{
+ const char *name; /* Name */
+ char *desc; /* Description */
+
+ const char *action_desc; /* Action Description */
+
+ s16b action_mkey; /* Action do to */
+
+ s32b i_value; /* Actual value */
+ s32b i_mod; /* Modifier(1 skill point = modifier skill) */
+
+ s32b value; /* Actual value */
+ s32b mod; /* Modifier(1 skill point = modifier skill) */
+ s16b rate; /* Modifier decreasing rate */
+
+ u32b uses; /* Number of times used */
+
+ s16b action[MAX_SKILLS]; /* List of actions against other skills */
+
+ s16b father; /* Father in the skill tree */
+ bool_ dev; /* Is the branch developped ? */
+ s16b order; /* Order in the tree */
+ bool_ hidden; /* Innactive */
+
+ byte random_gain_chance; /* random gain chance, still needs the flag */
+
+ u32b flags1; /* Skill flags */
+};
diff --git a/src/skill_type_fwd.hpp b/src/skill_type_fwd.hpp
new file mode 100644
index 00000000..0a06dadb
--- /dev/null
+++ b/src/skill_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct skill_type;
diff --git a/src/skills.c b/src/skills.cc
index 4df3c1b3..330aa9ba 100644
--- a/src/skills.c
+++ b/src/skills.cc
@@ -1,7 +1,3 @@
-/* File: skills.c */
-
-/* Purpose: player skills */
-
/*
* Copyright (c) 2001 DarkGod
*
@@ -10,15 +6,53 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include <math.h>
+#include "skills.hpp"
+
+#include "ability_type.hpp"
+#include "birth.hpp"
+#include "cmd2.hpp"
+#include "cmd3.hpp"
+#include "cmd5.hpp"
+#include "cmd7.hpp"
+#include "gods.hpp"
+#include "help.hpp"
+#include "hooks.hpp"
+#include "lua_bind.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_spec.hpp"
+#include "player_type.hpp"
+#include "skill_type.hpp"
+#include "spells1.hpp"
+#include "spells4.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra2.hpp"
+
+#include <algorithm>
+#include <boost/algorithm/string/predicate.hpp>
+#include <cassert>
+#include <cmath>
+#include <memory>
+#include <vector>
+#include <tuple>
+
+using boost::algorithm::iequals;
/*
* Advance the skill point of the skill specified by i and
* modify related skills
*/
-void increase_skill(int i, s16b *invest)
+static void increase_skill(int i, s16b *invest)
{
s32b max_skill_overage;
@@ -36,9 +70,14 @@ void increase_skill(int i, s16b *invest)
if (((s_info[i].value + s_info[i].mod) / SKILL_STEP) >= (p_ptr->lev + max_skill_overage + 1))
{
int hgt, wid;
+ char buf[256];
+
+ sprintf(buf,
+ "Cannot raise a skill value above " FMTs32b " + player level.",
+ max_skill_overage);
Term_get_size(&wid, &hgt);
- msg_box(format("Cannot raise a skill value above %i + player level.", max_skill_overage), (int)(hgt / 2), (int)(wid / 2));
+ msg_box(buf, hgt / 2, wid / 2);
return;
}
@@ -55,7 +94,7 @@ void increase_skill(int i, s16b *invest)
* Descrease the skill point of the skill specified by i and
* modify related skills
*/
-void decrease_skill(int i, s16b *invest)
+static void decrease_skill(int i, s16b *invest)
{
/* Cannot decrease more */
if (!invest[i]) return;
@@ -86,8 +125,10 @@ s16b find_skill(cptr name)
/* Scan skill list */
for (i = 1; i < max_s_idx; i++)
{
- /* The name matches */
- if (streq(s_info[i].name + s_name, name)) return (i);
+ if (s_info[i].name && streq(s_info[i].name, name))
+ {
+ return (i);
+ }
}
/* No match found */
@@ -101,7 +142,10 @@ s16b find_skill_i(cptr name)
for (i = 1; i < max_s_idx; i++)
{
/* The name matches */
- if (0 == stricmp(s_info[i].name + s_name, name)) return (i);
+ if (s_info[i].name && iequals(s_info[i].name, name))
+ {
+ return (i);
+ }
}
/* No match found */
@@ -141,15 +185,9 @@ s16b get_skill_scale(int skill, u32b scale)
return (temp / SKILL_MAX);
}
-
-/*
- *
- */
-int get_idx(int i)
+static int get_idx(int i)
{
- int j;
-
- for (j = 1; j < max_s_idx; j++)
+ for (int j = 1; j < max_s_idx; j++)
{
if (s_info[j].order == i)
return (j);
@@ -178,17 +216,11 @@ static bool_ is_known(int s_idx)
return FALSE;
}
-/*
- *
- */
-void init_table_aux(int table[MAX_SKILLS][2], int *idx, int father, int lev,
- bool_ full)
+static void init_table_aux(int table[MAX_SKILLS][2], int *idx, int father, int lev, bool_ full)
{
- int j, i;
-
- for (j = 1; j < max_s_idx; j++)
+ for (int j = 1; j < max_s_idx; j++)
{
- i = get_idx(j);
+ int i = get_idx(j);
if (s_info[i].father != father) continue;
if (s_info[i].hidden) continue;
if (!is_known(i)) continue;
@@ -200,15 +232,13 @@ void init_table_aux(int table[MAX_SKILLS][2], int *idx, int father, int lev,
}
}
-
-void init_table(int table[MAX_SKILLS][2], int *max, bool_ full)
+static void init_table(int table[MAX_SKILLS][2], int *max, bool_ full)
{
*max = 0;
init_table_aux(table, max, -1, 0, full);
}
-
-bool_ has_child(int sel)
+static bool_ has_child(int sel)
{
int i;
@@ -251,17 +281,17 @@ void dump_skills(FILE *fff)
if (!has_child(i))
{
- strcat(buf, format(" . %s", s_info[i].name + s_name));
+ strcat(buf, format(" . %s", s_info[i].name));
}
else
{
- strcat(buf, format(" - %s", s_info[i].name + s_name));
+ strcat(buf, format(" - %s", s_info[i].name));
}
fprintf(fff, "%-49s%s%06.3f [%05.3f]",
buf, s_info[i].value < 0 ? "-" : " ",
- ((double) ABS(s_info[i].value)) / SKILL_STEP,
- ((double) s_info[i].mod) / 1000);
+ static_cast<double>(ABS(s_info[i].value)) / SKILL_STEP,
+ static_cast<double>(s_info[i].mod) / 1000);
}
fprintf(fff, "\n");
@@ -285,7 +315,7 @@ void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start)
display_message(0, 1, strlen(keys), TERM_WHITE, keys);
c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED,
format("Skill points left: %d", p_ptr->skill_points), 2, 0);
- print_desc_aux(s_info[table[sel][0]].desc + s_text, 3, 0);
+ print_desc_aux(s_info[table[sel][0]].desc, 3, 0);
for (j = start; j < start + (hgt - 7); j++)
{
@@ -311,17 +341,17 @@ void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start)
}
if (!has_child(i))
{
- c_prt(color, format("%c.%c%s", deb, end, s_info[i].name + s_name),
+ c_prt(color, format("%c.%c%s", deb, end, s_info[i].name),
j + 7 - start, table[j][1] * 4);
}
else if (s_info[i].dev)
{
- c_prt(color, format("%c-%c%s", deb, end, s_info[i].name + s_name),
+ c_prt(color, format("%c-%c%s", deb, end, s_info[i].name),
j + 7 - start, table[j][1] * 4);
}
else
{
- c_prt(color, format("%c+%c%s", deb, end, s_info[i].name + s_name),
+ c_prt(color, format("%c+%c%s", deb, end, s_info[i].name),
j + 7 - start, table[j][1] * 4);
}
c_prt(color,
@@ -375,7 +405,6 @@ void recalc_skills(bool_ init)
abandon_god(GOD_ALL);
}
- process_hooks(HOOK_RECALC_SKILLS, "()");
process_hooks_new(HOOK_RECALC_SKILLS, NULL, NULL);
/* Update stuffs */
@@ -383,14 +412,14 @@ void recalc_skills(bool_ init)
PU_SANITY | PU_BODY);
/* Redraw various info */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
}
}
/*
* Recalc the skill value
*/
-void recalc_skills_theory(s16b *invest, s32b *base_val, s32b *base_mod, s32b *bonus)
+static void recalc_skills_theory(s16b *invest, s32b *base_val, s32b *base_mod, s32b *bonus)
{
int i, j;
@@ -448,11 +477,6 @@ void do_cmd_skill()
int i;
int wid, hgt;
s16b skill_points_save;
- s32b *skill_values_save;
- s32b *skill_mods_save;
- s16b *skill_rates_save;
- s16b *skill_invest;
- s32b *skill_bonus;
recalc_skills(TRUE);
@@ -460,11 +484,11 @@ void do_cmd_skill()
screen_save();
/* Allocate arrays to save skill values */
- C_MAKE(skill_values_save, MAX_SKILLS, s32b);
- C_MAKE(skill_mods_save, MAX_SKILLS, s32b);
- C_MAKE(skill_rates_save, MAX_SKILLS, s16b);
- C_MAKE(skill_invest, MAX_SKILLS, s16b);
- C_MAKE(skill_bonus, MAX_SKILLS, s32b);
+ std::unique_ptr<s32b[]> skill_values_save(new s32b[MAX_SKILLS]);
+ std::unique_ptr<s32b[]> skill_mods_save(new s32b[MAX_SKILLS]);
+ std::unique_ptr<s16b[]> skill_rates_save(new s16b[MAX_SKILLS]);
+ std::unique_ptr<s16b[]> skill_invest(new s16b[MAX_SKILLS]);
+ std::unique_ptr<s32b[]> skill_bonus(new s32b[MAX_SKILLS]);
/* Save skill points */
skill_points_save = p_ptr->skill_points;
@@ -478,6 +502,7 @@ void do_cmd_skill()
skill_mods_save[i] = s_ptr->mod;
skill_rates_save[i] = s_ptr->rate;
skill_invest[i] = 0;
+ skill_bonus[i] = 0;
}
/* Clear the screen */
@@ -491,7 +516,7 @@ void do_cmd_skill()
Term_get_size(&wid, &hgt);
/* Display list of skills */
- recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus);
+ recalc_skills_theory(skill_invest.get(), skill_values_save.get(), skill_mods_save.get(), skill_bonus.get());
print_skills(table, max, sel, start);
/* Wait for user input */
@@ -537,13 +562,13 @@ void do_cmd_skill()
if (dir == 8) sel--;
/* Miscellaneous skills cannot be increased/decreased as a group */
- if (table[sel][0] == SKILL_MISC) continue;
+ if ((sel >= 0) && (sel < max) && table[sel][0] == SKILL_MISC) continue;
/* Increase the current skill */
- if (dir == 6) increase_skill(table[sel][0], skill_invest);
+ if (dir == 6) increase_skill(table[sel][0], skill_invest.get());
/* Decrease the current skill */
- if (dir == 4) decrease_skill(table[sel][0], skill_invest);
+ if (dir == 4) decrease_skill(table[sel][0], skill_invest.get());
/* XXX XXX XXX Wizard mode commands outside of wizard2.c */
@@ -556,7 +581,7 @@ void do_cmd_skill()
/* Contextual help */
if (c == '?')
{
- help_skill(s_info[table[sel][0]].name + s_name);
+ help_skill(s_info[table[sel][0]].name);
}
/* Handle boundaries and scrolling */
@@ -575,7 +600,7 @@ void do_cmd_skill()
flush();
/* Ask we can commit the change */
- if (msg_box("Save and use these skill values? (y/n)", (int)(hgt / 2), (int)(wid / 2)) != 'y')
+ if (msg_box("Save and use these skill values? (y/n)", hgt / 2, wid / 2) != 'y')
{
/* User declines -- restore the skill values before exiting */
@@ -594,14 +619,6 @@ void do_cmd_skill()
}
}
-
- /* Free arrays to save skill values */
- C_FREE(skill_values_save, MAX_SKILLS, s32b);
- C_FREE(skill_mods_save, MAX_SKILLS, s32b);
- C_FREE(skill_rates_save, MAX_SKILLS, s16b);
- C_FREE(skill_invest, MAX_SKILLS, s16b);
- C_FREE(skill_bonus, MAX_SKILLS, s32b);
-
/* Load the screen */
screen_load();
@@ -613,13 +630,13 @@ void do_cmd_skill()
/*
* List of melee skills
*/
-s16b melee_skills[MAX_MELEE] =
+static s16b melee_skills[MAX_MELEE] =
{
SKILL_MASTERY,
SKILL_HAND,
SKILL_BEAR,
};
-char *melee_names[MAX_MELEE] =
+static const char *melee_names[MAX_MELEE] =
{
"Weapon combat",
"Barehanded combat",
@@ -640,6 +657,11 @@ s16b get_melee_skill()
return (0);
}
+cptr get_melee_name()
+{
+ return melee_names[get_melee_skill()];
+}
+
s16b get_melee_skills()
{
int i, j = 0;
@@ -725,7 +747,7 @@ static void choose_melee()
p_ptr->update |= (PU_HP);
/* Redraw monster hitpoint */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
Term_load();
character_icky = FALSE;
@@ -755,21 +777,23 @@ void select_default_melee()
/*
* Print a batch of skills.
*/
-static void print_skill_batch(int *p, cptr *p_desc, int start, int max)
+static void print_skill_batch(const std::vector<std::tuple<cptr, int>> &p, int start)
{
char buff[80];
- int i = start, j = 0;
+ int j = 0;
prt(format(" %-31s", "Name"), 1, 20);
- for (i = start; i < (start + 20); i++)
+ for (int i = start; i < (start + 20); i++)
{
- if (i >= max) break;
+ if (static_cast<size_t>(i) >= p.size())
+ {
+ break;
+ }
- if (p[i] > 0)
- sprintf(buff, " %c - %d) %-30s", I2A(j), p[i], p_desc[i]);
- else
- sprintf(buff, " %c - %d) %-30s", I2A(j), p[i], "Change melee style");
+ sprintf(buff, " %c - %d) %-30s", I2A(j),
+ std::get<1>(p[i]),
+ std::get<0>(p[i]));
prt(buff, 2 + j, 20);
j++;
@@ -778,37 +802,30 @@ static void print_skill_batch(int *p, cptr *p_desc, int start, int max)
prt(format("Select a skill (a-%c), @ to select by name, +/- to scroll:", I2A(j - 1)), 0, 0);
}
-int do_cmd_activate_skill_aux()
+static int do_cmd_activate_skill_aux()
{
char which;
- int max = 0, i, start = 0;
+ int start = 0;
int ret;
- int *p;
- cptr *p_desc;
-
- C_MAKE(p, max_s_idx + max_ab_idx, int);
- C_MAKE(p_desc, max_s_idx + max_ab_idx, cptr);
- /* Count the max */
+ std::vector<std::tuple<cptr,int>> p;
/* More than 1 melee skill ? */
if (get_melee_skills() > 1)
{
- p_desc[max] = "Change melee mode";
- p[max++] = 0;
+ p.push_back(std::make_tuple("Change melee mode", 0));
}
- for (i = 1; i < max_s_idx; i++)
+ for (size_t i = 1; i < max_s_idx; i++)
{
if (s_info[i].action_mkey && s_info[i].value && ((!s_info[i].hidden) || (i == SKILL_LEARN)))
{
- int j;
bool_ next = FALSE;
/* Already got it ? */
- for (j = 0; j < max; j++)
+ for (size_t j = 0; j < p.size(); j++)
{
- if (s_info[i].action_mkey == p[j])
+ if (s_info[i].action_mkey == std::get<1>(p[j]))
{
next = TRUE;
break;
@@ -816,22 +833,21 @@ int do_cmd_activate_skill_aux()
}
if (next) continue;
- p_desc[max] = s_text + s_info[i].action_desc;
- p[max++] = s_info[i].action_mkey;
+ p.push_back(std::make_tuple(s_info[i].action_desc,
+ s_info[i].action_mkey));
}
}
- for (i = 0; i < max_ab_idx; i++)
+ for (size_t i = 0; i < max_ab_idx; i++)
{
if (ab_info[i].action_mkey && ab_info[i].acquired)
{
- int j;
bool_ next = FALSE;
/* Already got it ? */
- for (j = 0; j < max; j++)
+ for (size_t j = 0; j < p.size(); j++)
{
- if (ab_info[i].action_mkey == p[j])
+ if (ab_info[i].action_mkey == std::get<1>(p[j]))
{
next = TRUE;
break;
@@ -839,12 +855,12 @@ int do_cmd_activate_skill_aux()
}
if (next) continue;
- p_desc[max] = ab_text + ab_info[i].action_desc;
- p[max++] = ab_info[i].action_mkey;
+ p.push_back(std::make_tuple(ab_info[i].action_desc,
+ ab_info[i].action_mkey));
}
}
- if (!max)
+ if (p.empty())
{
msg_print("You don't have any activable skills or abilities.");
return -1;
@@ -855,7 +871,7 @@ int do_cmd_activate_skill_aux()
while (1)
{
- print_skill_batch(p, p_desc, start, max);
+ print_skill_batch(p, start);
which = inkey();
if (which == ESCAPE)
@@ -866,14 +882,20 @@ int do_cmd_activate_skill_aux()
else if (which == '+')
{
start += 20;
- if (start >= max) start -= 20;
+ if (static_cast<size_t>(start) >= p.size())
+ {
+ start -= 20;
+ }
Term_load();
character_icky = FALSE;
}
else if (which == '-')
{
start -= 20;
- if (start < 0) start += 20;
+ if (start < 0)
+ {
+ start += 20;
+ }
Term_load();
character_icky = FALSE;
}
@@ -886,22 +908,23 @@ int do_cmd_activate_skill_aux()
return FALSE;
/* Find the skill it is related to */
- for (i = 0; i < max; i++)
+ size_t i = 0;
+ for (; i < p.size(); i++)
{
- if (!strcmp(buf, p_desc[i]))
+ if (!strcmp(buf, std::get<0>(p[i])))
break;
}
- if ((i < max))
+
+ if (i < p.size())
{
- ret = p[i];
+ ret = std::get<1>(p[i]);
break;
}
-
}
else
{
which = tolower(which);
- if (start + A2I(which) >= max)
+ if (start + A2I(which) >= static_cast<int>(p.size()))
{
bell();
continue;
@@ -912,16 +935,13 @@ int do_cmd_activate_skill_aux()
continue;
}
- ret = p[start + A2I(which)];
+ ret = std::get<1>(p[start + A2I(which)]);
break;
}
}
Term_load();
character_icky = FALSE;
- C_FREE(p, max_s_idx + max_ab_idx, int);
- C_FREE(p_desc, max_s_idx + max_ab_idx, cptr);
-
return ret;
}
@@ -1008,12 +1028,6 @@ void do_cmd_activate_skill()
case MKEY_INCARNATION:
do_cmd_possessor();
break;
- case MKEY_TELEKINESIS:
- do_cmd_portable_hole();
- break;
- case MKEY_BLADE:
- do_cmd_blade();
- break;
case MKEY_SUMMON:
do_cmd_summoner();
break;
@@ -1161,7 +1175,7 @@ bool_ forbid_gloves()
/* Which gods forbid edged weapons */
bool_ forbid_non_blessed()
{
- GOD(GOD_ERU) return (TRUE);
+ if (p_ptr->pgod == GOD_ERU) return (TRUE);
return (FALSE);
}
@@ -1240,104 +1254,69 @@ void init_skill(s32b value, s32b mod, int i)
}
/*
- * Perform weighted random selection without replacement according to
- * the algorithm given in "Weighted Random Sampling" (2005, Eframidis,
- * Spirakis)
+ * Perform weighted random shuffle according to the algorithm given in
+ * "Weighted Random Sampling" (2005, Efraimidis, Spirakis).
*
- * @param n is the total number of items to choose from.
- * @param k is the total number of items to choose.
- * @param weights is the array of weights.
- * @param indexes is the output array containing the chosen permutation.
- * The first k values will be set to a value in [0, n[ according to
- * which item was chosen.
+ * @param weights is the vector of weights.
+ * @return an output vector of the same size as the input weights vector containing,
+ * in order of selection, the indices to select. For example, if you
+ * need to choose two items, you would use v[0], v[1] as the indices
+ * to pick.
*/
-static void wrs_without_replacement(size_t n, size_t k, s32b unscaled_weights[], size_t indexes[])
+static std::vector<size_t> wrs(const std::vector<s32b> &unscaled_weights)
{
- size_t i;
- s32b scale;
- double *weights = NULL;
- double *keys = NULL;
- size_t *permutation = NULL;
-
- assert(k <= n);
-
- /* Allocate working memory */
- keys = C_RNEW(n, double);
- weights = C_RNEW(n, double);
- permutation = C_RNEW(n, double);
-
- /* Calculate the scale of the weights. */
- scale = 0;
- for (i = 0; i < n; i++)
- {
- scale += unscaled_weights[i];
- }
+ const size_t n = unscaled_weights.size();
/* Rescale weights into unit interval for numerical stability */
- for (i = 0; i < n; i++) {
- weights[i] =
- ((double) unscaled_weights[i]) /
- ((double) scale);
- }
+ std::vector<double> weights(unscaled_weights.size());
+ {
+ s32b scale = 0;
+ for (s32b weight: unscaled_weights)
+ {
+ scale += weight;
+ }
- /* Generate the keys to use for selection. This is where the
- magic happens. */
- for (i = 0; i < n; i++) {
- double u = ((double) rand_int(100000)) / ((double) 100000);
- keys[i] = pow(u, 1/weights[i]);
+ for (size_t i = 0; i < n; i++) {
+ weights[i] =
+ ((double) unscaled_weights[i]) /
+ ((double) scale);
+ }
}
- /* Generate the initial permutation */
- for (i = 0; i < n; i++) {
- permutation[i] = i;
+ /* Generate the keys and indexes to use for selection. This
+ is the only randomized portion of the algorithm. */
+ std::vector<std::tuple<double,size_t>> keys_and_indexes(unscaled_weights.size());
+ for (size_t i = 0; i < n; i++) {
+ /* Randomized keys according to the algorithm. */
+ double u = static_cast<double>(rand_int(100000)) / 100000;
+ double k = std::pow(u, 1/weights[i]);
+ /* Set up the key and index. We negate the k value
+ here so that keys will be sorted in descending
+ order rather than ascending order. */
+ keys_and_indexes[i] = std::make_tuple(-k, i);
}
- /* Select the k indexes with the largest keys */
- for (i = 0; i < k; i++) {
- /* Find maximal value and its index */
- int max_idx = i;
- double max_value = keys[max_idx];
- size_t j;
- for (j = i+1; j < n; j++) {
- if (keys[j] > max_value) {
- max_idx = j;
- max_value = keys[j];
- }
- }
+ /* Sort indexes according to keys. Since the keys have been
+ negated and we're using a lexicographical sort, we're
+ effectively sorting in descending order of key. */
+ std::sort(std::begin(keys_and_indexes),
+ std::end(keys_and_indexes));
- /* Swap into k'th position */
- if (max_idx != i) {
- double tmp_key;
- size_t tmp_idx;
- /* Swap keys */
- tmp_key = keys[i];
- keys[i] = keys[max_idx];
- keys[max_idx] = tmp_key;
- /* Swap indexes in permutation */
- tmp_idx = permutation[i];
- permutation[i] = permutation[max_idx];
- permutation[max_idx] = tmp_idx;
- }
-
- /* Output the k'th choice. */
- indexes[i] = permutation[i];
+ /* Produce the output vector consisting of indexes only. */
+ std::vector<size_t> indexes;
+ for (auto const &key_and_index: keys_and_indexes) {
+ indexes.push_back(std::get<1>(key_and_index));
}
-
- /* Clean up */
- C_FREE(keys, n, double);
- C_FREE(weights, n, double);
- C_FREE(permutation, n, size_t);
+ return indexes;
}
void do_get_new_skill()
{
- char *items[LOST_SWORD_NSKILLS];
+ std::vector<std::string> items;
int skl[LOST_SWORD_NSKILLS];
s32b val[LOST_SWORD_NSKILLS], mod[LOST_SWORD_NSKILLS];
int available_skills[MAX_SKILLS];
int max_a = 0, res, i;
- size_t indexes[LOST_SWORD_NSKILLS];
- s32b weights[MAX_SKILLS];
/* Check if some skills didn't influence other stuff */
recalc_skills(TRUE);
@@ -1353,11 +1332,13 @@ void do_get_new_skill()
}
/* Perform the selection */
+ std::vector<s32b> weights;
for (i = 0; i < max_a; i++) {
- weights[i] = s_info[available_skills[i]].random_gain_chance;
+ weights.push_back(s_info[available_skills[i]].random_gain_chance);
}
- wrs_without_replacement(max_a, LOST_SWORD_NSKILLS, weights, indexes);
+ std::vector<size_t> indexes = wrs(weights);
+ assert(indexes.size() >= LOST_SWORD_NSKILLS);
/* Extract the information needed from the skills */
for (i = 0; i < LOST_SWORD_NSKILLS; i++)
@@ -1396,7 +1377,12 @@ void do_get_new_skill()
}
skl[i] = s_idx;
- items[i] = (char *)string_make(format("%-40s: +%02ld.%03ld value, +%01d.%03d modifier", s_ptr->name + s_name, val[i] / SKILL_STEP, val[i] % SKILL_STEP, mod[i] / SKILL_STEP, mod[i] % SKILL_STEP));
+ items.push_back(format("%-40s: +%02ld.%03ld value, +%01d.%03d modifier",
+ s_ptr->name,
+ val[i] / SKILL_STEP,
+ val[i] % SKILL_STEP,
+ mod[i] / SKILL_STEP,
+ mod[i] % SKILL_STEP));
}
while (TRUE)
@@ -1404,7 +1390,7 @@ void do_get_new_skill()
char last = 'a' + (LOST_SWORD_NSKILLS-1);
char buf[80];
sprintf(buf, "Choose a skill to learn(a-%c to choose, ESC to cancel)?", last);
- res = ask_menu(buf, (char **)items, LOST_SWORD_NSKILLS);
+ res = ask_menu(buf, items);
/* Ok ? lets learn ! */
if (res > -1)
@@ -1439,7 +1425,7 @@ void do_get_new_skill()
/* Prepare prompt */
msg = format("This skill is mutually exclusive with "
"at least %s, continue?",
- s_info[oppose_skill].name + s_name);
+ s_info[oppose_skill].name);
/* The player rejected the choice */
if (!get_check(msg)) continue;
@@ -1451,23 +1437,17 @@ void do_get_new_skill()
if (mod[res])
{
msg_format("You can now learn the %s skill.",
- s_ptr->name + s_name);
+ s_ptr->name);
}
else
{
msg_format("Your knowledge of the %s skill increases.",
- s_ptr->name + s_name);
+ s_ptr->name);
}
break;
}
}
- /* Free them ! */
- for (i = 0; i < LOST_SWORD_NSKILLS; i++)
- {
- string_free(items[i]);
- }
-
/* Check if some skills didn't influence other stuff */
recalc_skills(FALSE);
}
@@ -1488,8 +1468,10 @@ s16b find_ability(cptr name)
/* Scan ability list */
for (i = 0; i < max_ab_idx; i++)
{
- /* The name matches */
- if (streq(ab_info[i].name + ab_name, name)) return (i);
+ if (ab_info[i].name && streq(ab_info[i].name, name))
+ {
+ return (i);
+ }
}
/* No match found */
@@ -1505,7 +1487,7 @@ bool_ has_ability(int ab)
}
/* Do we meet the requirements */
-bool_ can_learn_ability(int ab)
+static bool_ can_learn_ability(int ab)
{
ability_type *ab_ptr = &ab_info[ab];
int i;
@@ -1550,22 +1532,18 @@ bool_ can_learn_ability(int ab)
}
}
- /* Do the script allow us? */
- if (process_hooks(HOOK_LEARN_ABILITY, "(d)", ab))
- return FALSE;
-
return TRUE;
}
/* Learn an ability */
-void gain_ability(int ab)
+static void gain_ability(int ab)
{
int wid, hgt;
Term_get_size(&wid, &hgt);
if (!can_learn_ability(ab))
{
- msg_box("You cannot learn this ability.", (int)(hgt / 2), (int)(wid / 2));
+ msg_box("You cannot learn this ability.", hgt / 2, wid / 2);
return;
}
@@ -1573,7 +1551,7 @@ void gain_ability(int ab)
flush();
/* Ask we can commit the change */
- if (msg_box("Learn this ability(this is permanent)? (y/n)", (int)(hgt / 2), (int)(wid / 2)) != 'y')
+ if (msg_box("Learn this ability(this is permanent)? (y/n)", hgt / 2, wid / 2) != 'y')
{
return;
}
@@ -1582,28 +1560,9 @@ void gain_ability(int ab)
p_ptr->skill_points -= ab_info[ab].cost;
}
-/* helper function to generate a sorted table */
-static void add_sorted_ability(int *table, int *max, int ab)
+static bool compare_abilities(const int ab_idx1, const int ab_idx2)
{
- int i;
-
- for (i = 0; i < *max; i++)
- {
- if (strcmp(ab_name + ab_info[ab].name, ab_name + ab_info[table[i]].name) < 0)
- {
- int z;
-
- /* Move all indexes up */
- for (z = *max; z > i; z--)
- {
- table[z] = table[z - 1];
- }
- break;
- }
- }
- table[i] = ab;
-
- (*max)++;
+ return strcmp(ab_info[ab_idx1].name, ab_info[ab_idx2].name) < 0;
}
/*
@@ -1611,28 +1570,31 @@ static void add_sorted_ability(int *table, int *max, int ab)
*/
void dump_abilities(FILE *fff)
{
- int i, j;
- int *table;
- int max = 0;
-
- C_MAKE(table, max_ab_idx, int);
+ int i;
- /* Initialise the abilities list */
+ // Find all abilities that the player has.
+ std::vector<int> table;
for (i = 0; i < max_ab_idx; i++)
{
if (ab_info[i].name && has_ability(i))
- add_sorted_ability(table, &max, i);
+ {
+ table.push_back(i);
+ }
}
- if (max)
+ // Sort
+ std::sort(std::begin(table),
+ std::end(table),
+ compare_abilities);
+
+ // Show
+ if (!table.empty())
{
fprintf(fff, "\nAbilities");
- for (j = 0; j < max; j++)
+ for (int i : table)
{
- i = table[j];
-
- fprintf(fff, "\n * %s", ab_info[i].name + ab_name);
+ fprintf(fff, "\n * %s", ab_info[i].name);
}
fprintf(fff, "\n");
@@ -1642,7 +1604,7 @@ void dump_abilities(FILE *fff)
/*
* Draw the abilities list
*/
-void print_abilities(int table[], int max, int sel, int start)
+static void print_abilities(const std::vector<int> &table, int sel, int start)
{
int i, j;
int wid, hgt;
@@ -1657,14 +1619,18 @@ void print_abilities(int table[], int max, int sel, int start)
c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED,
format("Skill points left: %d", p_ptr->skill_points), 2, 0);
- print_desc_aux(ab_info[table[sel]].desc + ab_text, 3, 0);
+ print_desc_aux(ab_info[table[sel]].desc, 3, 0);
for (j = start; j < start + (hgt - 7); j++)
{
byte color = TERM_WHITE;
char deb = ' ', end = ' ';
- if (j >= max) break;
+ assert(j >= 0);
+ if (static_cast<size_t>(j) >= table.size())
+ {
+ break;
+ }
i = table[j];
@@ -1683,7 +1649,7 @@ void print_abilities(int table[], int max, int sel, int start)
end = ']';
}
- c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name + ab_name),
+ c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name),
j + 7 - start, 0);
if (!ab_info[i].acquired)
@@ -1702,14 +1668,11 @@ void print_abilities(int table[], int max, int sel, int start)
*/
void do_cmd_ability()
{
- int sel = 0, start = 0, max = 0;
+ int sel = 0, start = 0;
char c;
- int *table;
int i;
int wid, hgt;
- C_MAKE(table, max_ab_idx, int);
-
/* Save the screen */
screen_save();
@@ -1717,30 +1680,44 @@ void do_cmd_ability()
Term_clear();
/* Initialise the abilities list */
+ std::vector<int> table;
for (i = 0; i < max_ab_idx; i++)
{
-if (ab_info[i].name)
- add_sorted_ability(table, &max, i);
+ if (ab_info[i].name)
+ {
+ table.push_back(i);
+ }
}
+ std::sort(std::begin(table),
+ std::end(table),
+ compare_abilities);
+
while (TRUE)
{
Term_get_size(&wid, &hgt);
/* Display list of skills */
- print_abilities(table, max, sel, start);
+ print_abilities(table, sel, start);
/* Wait for user input */
c = inkey();
/* Leave the skill screen */
- if (c == ESCAPE) break;
+ if (c == ESCAPE)
+ {
+ break;
+ }
/* Next page */
else if (c == 'n')
{
sel += (hgt - 7);
- if (sel >= max) sel = max - 1;
+ assert(sel >= 0);
+ if (static_cast<size_t>(sel) >= table.size())
+ {
+ sel = table.size() - 1;
+ }
}
/* Previous page */
@@ -1775,28 +1752,38 @@ if (ab_info[i].name)
/* Contextual help */
if (c == '?')
{
- help_ability(ab_info[table[sel]].name + ab_name);
+ help_ability(ab_info[table[sel]].name);
}
/* Handle boundaries and scrolling */
- if (sel < 0) sel = max - 1;
- if (sel >= max) sel = 0;
- if (sel < start) start = sel;
- if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1;
+ if (sel < 0)
+ {
+ sel = table.size() - 1;
+ }
+ if (static_cast<size_t>(sel) >= table.size())
+ {
+ sel = 0;
+ }
+ if (sel < start)
+ {
+ start = sel;
+ }
+ if (sel >= start + (hgt - 7))
+ {
+ start = sel - (hgt - 7) + 1;
+ }
}
}
/* Load the screen */
screen_load();
- C_FREE(table, max_ab_idx, int);
-
/* Update stuffs */
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS |
PU_SANITY | PU_BODY);
/* Redraw various info */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
}
/*
@@ -1811,25 +1798,33 @@ void apply_level_abilities(int level)
if (cp_ptr->abilities[i].level == level)
{
if ((level > 1) && (!ab_info[cp_ptr->abilities[i].ability].acquired))
- cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_name + ab_info[cp_ptr->abilities[i].ability].name);
+ {
+ cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[cp_ptr->abilities[i].ability].name);
+ }
ab_info[cp_ptr->abilities[i].ability].acquired = TRUE;
}
if (spp_ptr->abilities[i].level == level)
{
if ((level > 1) && (!ab_info[spp_ptr->abilities[i].ability].acquired))
- cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_name + ab_info[spp_ptr->abilities[i].ability].name);
+ {
+ cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[spp_ptr->abilities[i].ability].name);
+ }
ab_info[spp_ptr->abilities[i].ability].acquired = TRUE;
}
if (rp_ptr->abilities[i].level == level)
{
if ((level > 1) && (!ab_info[rp_ptr->abilities[i].ability].acquired))
- cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_name + ab_info[rp_ptr->abilities[i].ability].name);
+ {
+ cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[rp_ptr->abilities[i].ability].name);
+ }
ab_info[rp_ptr->abilities[i].ability].acquired = TRUE;
}
if (rmp_ptr->abilities[i].level == level)
{
if ((level > 1) && (!ab_info[rmp_ptr->abilities[i].ability].acquired))
- cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_name + ab_info[rmp_ptr->abilities[i].ability].name);
+ {
+ cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[rmp_ptr->abilities[i].ability].name);
+ }
ab_info[rmp_ptr->abilities[i].ability].acquired = TRUE;
}
}
diff --git a/src/skills.hpp b/src/skills.hpp
new file mode 100644
index 00000000..6c1880a6
--- /dev/null
+++ b/src/skills.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "h-basic.h"
+
+/* Skill functions */
+extern void dump_skills(FILE *fff);
+extern s16b find_skill(cptr name);
+extern s16b find_skill_i(cptr name);
+extern s16b get_skill(int skill);
+extern s16b get_skill_scale(int skill, u32b scale);
+extern void do_cmd_skill(void);
+extern void do_cmd_activate_skill(void);
+extern cptr get_melee_name();
+extern s16b get_melee_skills(void);
+extern s16b get_melee_skill(void);
+extern bool_ forbid_gloves(void);
+extern bool_ forbid_non_blessed(void);
+extern void compute_skills(s32b *v, s32b *m, int i);
+extern void select_default_melee(void);
+extern void do_get_new_skill(void);
+extern void init_skill(s32b value, s32b mod, int i);
+extern s16b find_ability(cptr name);
+extern void dump_abilities(FILE *fff);
+extern void do_cmd_ability(void);
+extern bool_ has_ability(int ab);
+extern void apply_level_abilities(int level);
+extern void recalc_skills(bool_ init);
diff --git a/src/skills_defs.hpp b/src/skills_defs.hpp
new file mode 100644
index 00000000..59e1f059
--- /dev/null
+++ b/src/skills_defs.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+/*
+ * Skill constants
+ */
+#define SKILL_CONVEYANCE 1
+#define SKILL_MANA 2
+#define SKILL_FIRE 3
+#define SKILL_AIR 4
+#define SKILL_WATER 5
+#define SKILL_NATURE 6
+#define SKILL_EARTH 7
+#define SKILL_SYMBIOTIC 8
+#define SKILL_MUSIC 9
+#define SKILL_DIVINATION 10
+#define SKILL_TEMPORAL 11
+#define SKILL_DRUID 12
+#define SKILL_DAEMON 13
+#define SKILL_META 14
+#define SKILL_MAGIC 15
+#define SKILL_COMBAT 16
+#define SKILL_MASTERY 17
+#define SKILL_SWORD 18
+#define SKILL_AXE 19
+#define SKILL_POLEARM 20
+#define SKILL_HAFTED 21
+#define SKILL_BACKSTAB 22
+#define SKILL_ARCHERY 23
+#define SKILL_SLING 24
+#define SKILL_BOW 25
+#define SKILL_XBOW 26
+#define SKILL_BOOMERANG 27
+#define SKILL_SPIRITUALITY 28
+#define SKILL_MINDCRAFT 29
+#define SKILL_MISC 30
+#define SKILL_NECROMANCY 31
+#define SKILL_MIMICRY 32
+#define SKILL_ANTIMAGIC 33
+#define SKILL_RUNECRAFT 34
+#define SKILL_SNEAK 35
+#define SKILL_STEALTH 36
+#define SKILL_DISARMING 37
+#define SKILL_ALCHEMY 39
+#define SKILL_STEALING 40
+#define SKILL_SORCERY 41
+#define SKILL_HAND 42
+#define SKILL_THAUMATURGY 43
+#define SKILL_SUMMON 44
+#define SKILL_SPELL 45
+#define SKILL_DODGE 46
+#define SKILL_BEAR 47
+#define SKILL_LORE 48
+#define SKILL_PRESERVATION 49
+#define SKILL_POSSESSION 50
+#define SKILL_MIND 51
+#define SKILL_CRITS 52
+#define SKILL_PRAY 53
+#define SKILL_LEARN 54
+#define SKILL_UDUN 55
+#define SKILL_DEVICE 56
+#define SKILL_STUN 57
+#define SKILL_BOULDER 58
+#define SKILL_GEOMANCY 59
+#define MAX_SKILLS 200
diff --git a/src/spell_type.c b/src/spell_type.cc
index b8bec0cd..6cf6e35b 100644
--- a/src/spell_type.c
+++ b/src/spell_type.cc
@@ -1,6 +1,16 @@
-#include "spell_type.h"
+#include "spell_type.hpp"
-#include "angband.h"
+#include "range.hpp"
+#include "device_allocation.hpp"
+#include "dice.hpp"
+#include "skills_defs.hpp"
+#include "spells4.hpp"
+#include "stats.hpp"
+
+#include <cassert>
+#include <vector>
+#include <string>
+#include <type_traits>
#define SCHOOL_IDXS_MAX 3
@@ -11,23 +21,23 @@ struct spell_type
{
cptr name; /* Name */
byte skill_level; /* Required level (to learn) */
- string_list *description; /* List of strings */
+ std::vector<std::string> m_description; /* List of strings */
- casting_result (*effect_func)(int o_idx); /* Spell effect function */
- char* (*info_func)(); /* Information function */
+ casting_result (*effect_func)(); /* Spell effect function */
+ const char* (*info_func)(); /* Information function */
int (*lasting_func)(); /* Lasting effect function */
bool_ (*depend_func)(); /* Check dependencies */
s16b minimum_pval; /* Minimum required pval for item-based spells */
- casting_type casting_type; /* Type of casting required */
+ enum casting_type casting_type; /* Type of casting required */
s16b casting_stat; /* Stat used for casting */
bool_ castable_while_blind;
bool_ castable_while_confused;
dice_type device_charges; /* Number of charges for devices */
- device_allocation *device_allocation; /* Allocation table for devices */
+ std::vector<device_allocation *> m_device_allocation; /* Allocation table for devices */
s16b random_type; /* Type of random items in which skill may appear */
@@ -38,10 +48,36 @@ struct spell_type
range_type mana_range;
- dice_type activation_timeout; /* Timeout for activation (if any) */
-
- int school_idxs_count;
+ size_t school_idxs_count;
s32b school_idxs[3];
+
+public:
+
+ spell_type(cptr _name)
+ : name(_name)
+ , skill_level(0)
+ , m_description()
+ , effect_func(nullptr)
+ , info_func(nullptr)
+ , lasting_func(nullptr)
+ , depend_func(nullptr)
+ , minimum_pval(0)
+ , casting_type(USE_SPELL_POINTS)
+ , casting_stat(0)
+ , castable_while_blind(FALSE)
+ , castable_while_confused(FALSE)
+ , device_charges({ 0, 0, 0 })
+ , m_device_allocation()
+ , random_type(-1)
+ , failure_rate(0)
+ , inertia_difficulty(-1)
+ , inertia_delay(-1)
+ , mana_range({ -1, -1 })
+ , school_idxs_count(0)
+ , school_idxs{ -1, -1, -1 }
+ {
+ }
+
};
static void school_idx_add_new(spell_type *spell, s32b i)
@@ -53,31 +89,6 @@ static void school_idx_add_new(spell_type *spell, s32b i)
spell->school_idxs_count++;
}
-void spell_type_init(spell_type *spell, cptr name)
-{
- assert(spell != NULL);
-
- memset(spell, 0, sizeof(spell_type));
-
- spell->name = name;
- spell->description = NULL;
- spell->effect_func = NULL;
- spell->info_func = NULL;
- spell->lasting_func = NULL;
- spell->depend_func = NULL;
-
- spell->device_allocation = NULL;
-
- spell->school_idxs_count = 0;
-
- spell->random_type = -1;
-
- spell->castable_while_blind = FALSE;
- spell->castable_while_confused = FALSE;
-
- spell_type_set_inertia(spell, -1, -1);
-}
-
void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay)
{
assert(spell != NULL);
@@ -87,8 +98,8 @@ void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay)
void spell_type_init_music(spell_type *spell,
s16b minimum_pval,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx))
+ const char* (*info_func)(),
+ casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -107,8 +118,8 @@ void spell_type_init_music(spell_type *spell,
void spell_type_init_music_lasting(spell_type *spell,
s16b minimum_pval,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx),
+ const char* (*info_func)(),
+ casting_result (*effect_func)(),
int (*lasting_func)())
{
spell_type_init_music(
@@ -123,8 +134,8 @@ void spell_type_init_music_lasting(spell_type *spell,
void spell_type_init_mage(spell_type *spell,
random_type random_type,
s32b school_idx,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx))
+ const char* (*info_func)(),
+ casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -153,8 +164,8 @@ void spell_type_init_mage(spell_type *spell,
void spell_type_init_priest(spell_type *spell,
s32b school_idx,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx))
+ const char* (*info_func)(),
+ casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -169,8 +180,8 @@ void spell_type_init_priest(spell_type *spell,
}
void spell_type_init_device(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx))
+ const char* (*info_func)(),
+ casting_result (*effect_func)())
{
assert(spell != NULL);
@@ -182,8 +193,8 @@ void spell_type_init_device(spell_type *spell,
}
void spell_type_init_demonology(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx))
+ const char* (*info_func)(),
+ casting_result (*effect_func)())
{
spell_type_init_mage(spell,
NO_RANDOM,
@@ -193,8 +204,8 @@ void spell_type_init_demonology(spell_type *spell,
}
void spell_type_init_geomancy(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx),
+ const char* (*info_func)(),
+ casting_result (*effect_func)(),
bool_ (*depend_func)())
{
spell_type_init_mage(spell,
@@ -206,13 +217,6 @@ void spell_type_init_geomancy(spell_type *spell,
spell->depend_func = depend_func;
}
-void spell_type_set_activation_timeout(spell_type *spell, cptr timeout_s)
-{
- assert(spell != NULL);
-
- dice_parse_checked(&spell->activation_timeout, timeout_s);
-}
-
void spell_type_set_difficulty(spell_type *spell, byte skill_level, s32b failure_rate)
{
assert(spell != NULL);
@@ -246,7 +250,7 @@ void spell_type_describe(spell_type *spell, cptr line)
{
assert(spell != NULL);
- string_list_append(&spell->description, line);
+ spell->m_description.push_back(std::string(line));
}
void spell_type_add_school(spell_type *spell, s32b school_idx)
@@ -265,15 +269,13 @@ void spell_type_add_device_allocation(spell_type *spell, struct device_allocatio
{
assert(spell != NULL);
assert(a != NULL);
-
- sglib_device_allocation_add(&spell->device_allocation, a);
+ spell->m_device_allocation.push_back(a);
}
spell_type *spell_type_new(cptr name)
{
- spell_type *spell = malloc(sizeof(spell_type));
+ spell_type *spell = new spell_type(name);
assert(spell != NULL);
- spell_type_init(spell, name);
return spell;
}
@@ -283,10 +285,10 @@ int spell_type_produce_effect_lasting(spell_type *spell)
return spell->lasting_func();
}
-casting_result spell_type_produce_effect(spell_type *spell, int o_idx)
+casting_result spell_type_produce_effect(spell_type *spell)
{
assert(spell->effect_func != NULL);
- return spell->effect_func(o_idx);
+ return spell->effect_func();
}
cptr spell_type_name(spell_type *spell)
@@ -303,18 +305,11 @@ int spell_type_skill_level(spell_type *spell)
return spell->skill_level;
}
-void spell_type_description_foreach(spell_type *spell, void (*callback)(void *data, cptr text), void *data)
+void spell_type_description_foreach(spell_type *spell, std::function<void (std::string const &text)> callback)
{
- string_list *sl;
- struct sglib_string_list_iterator it;
-
- assert(callback != NULL);
-
- for (sl = sglib_string_list_it_init(&it, spell->description);
- sl != NULL;
- sl = sglib_string_list_it_next(&it))
+ for (auto line: spell->m_description)
{
- callback(data, sl->s);
+ callback(line);
}
}
@@ -323,35 +318,13 @@ long spell_type_roll_charges(spell_type *spell)
return dice_roll(&spell->device_charges);
}
-void spell_type_activation_description(spell_type *spell, char *buf)
-{
- char turns[32];
-
- dice_print(&spell->activation_timeout, turns);
-
- assert(spell->description != NULL);
- assert(spell->description->s != NULL);
-
- sprintf(buf, "%s every %s turns", spell->description->s, turns);
-}
-
-int spell_type_activation_roll_timeout(spell_type *spell)
-{
- return dice_roll(&spell->activation_timeout);
-}
-
device_allocation *spell_type_device_allocation(spell_type *spell, byte tval)
{
- struct sglib_device_allocation_iterator it;
- device_allocation *device_allocation;
-
- for (device_allocation = sglib_device_allocation_it_init(&it, spell->device_allocation);
- device_allocation != NULL;
- device_allocation = sglib_device_allocation_it_next(&it))
+ for (auto device_allocation_ptr: spell->m_device_allocation)
{
- if (device_allocation->tval == tval)
+ if (device_allocation_ptr->tval == tval)
{
- return device_allocation;
+ return device_allocation_ptr;
}
}
@@ -386,19 +359,14 @@ s16b spell_type_random_type(spell_type *spell)
return spell->random_type;
}
-bool_ spell_type_school_foreach(spell_type *spell, bool_ (*callback)(void *data, s32b school_idx), void *data)
+std::vector<s32b> const spell_type_get_schools(spell_type *spell)
{
- int i;
-
- for (i = 0; i < spell->school_idxs_count; i++)
+ std::vector<s32b> school_idxs;
+ for (size_t i = 0; i < spell->school_idxs_count; i++)
{
- if (!callback(data, spell->school_idxs[i]))
- {
- return FALSE;
- }
+ school_idxs.push_back(spell->school_idxs[i]);
}
-
- return TRUE;
+ return school_idxs;
}
bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay)
diff --git a/src/spell_type.h b/src/spell_type.hpp
index 32d6c7b6..43758103 100644
--- a/src/spell_type.h
+++ b/src/spell_type.hpp
@@ -1,65 +1,56 @@
-#ifndef H_e7e01ebf_e19f_439d_b88d_cad51446a7a0
-#define H_e7e01ebf_e19f_439d_b88d_cad51446a7a0
+#pragma once
-#include "spell_type_fwd.h"
-
-#include "h-type.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Forward declarations
- */
-struct device_allocation;
-struct range_type;
+#include "spell_type_fwd.hpp"
+#include <vector>
+#include <string>
+#include <functional>
+#include "h-basic.h"
+#include "device_allocation_fwd.hpp"
+#include "range_fwd.hpp"
/*
* Casting type
*/
-typedef enum { USE_SPELL_POINTS, USE_PIETY } casting_type;
+enum casting_type { USE_SPELL_POINTS, USE_PIETY };
/*
* Does the spell appear on spell random books?
*/
-typedef enum { RANDOM, NO_RANDOM } random_type;
+enum random_type { RANDOM, NO_RANDOM };
/*
* Spell functions
*/
-void spell_type_init(spell_type *spell, cptr name);
void spell_type_init_music(spell_type *spell,
s16b minimum_pval,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx));
+ const char* (*info_func)(),
+ casting_result (*effect_func)());
void spell_type_init_music_lasting(spell_type *spell,
s16b minimum_pval,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx),
+ const char* (*info_func)(),
+ casting_result (*effect_func)(),
int (*lasting_func)());
void spell_type_init_mage(spell_type *spell,
random_type random_type,
s32b school_idx,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx));
+ const char* (*info_func)(),
+ casting_result (*effect_func)());
void spell_type_init_priest(spell_type *spell,
s32b school_idx,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx));
+ const char* (*info_func)(),
+ casting_result (*effect_func)());
void spell_type_init_device(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx));
+ const char* (*info_func)(),
+ casting_result (*effect_func)());
void spell_type_init_demonology(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx));
+ const char* (*info_func)(),
+ casting_result (*effect_func)());
void spell_type_init_geomancy(spell_type *spell,
- char* (*info_func)(),
- casting_result (*effect_func)(int o_idx),
+ const char* (*info_func)(),
+ casting_result (*effect_func)(),
bool_ (*depend_func)());
-void spell_type_set_activation_timeout(spell_type *spell, cptr timeout_s);
void spell_type_set_inertia(spell_type *spell, s32b difficulty, s32b delay);
void spell_type_set_difficulty(spell_type *spell, byte skill_level, s32b failure_rate);
void spell_type_set_mana(spell_type *spell, s32b min, s32b max);
@@ -70,34 +61,26 @@ void spell_type_describe(spell_type *spell, cptr line);
void spell_type_add_school(spell_type *spell, s32b school_idx);
void spell_type_set_device_charges(spell_type *spell, cptr charges_s);
-void spell_type_add_device_allocation(spell_type *spell, struct device_allocation *a);
+void spell_type_add_device_allocation(spell_type *spell, device_allocation *a);
spell_type *spell_type_new(cptr name);
int spell_type_produce_effect_lasting(spell_type *spell);
-casting_result spell_type_produce_effect(spell_type *spell, int o_idx);
+casting_result spell_type_produce_effect(spell_type *spell);
cptr spell_type_name(spell_type *spell);
int spell_type_skill_level(spell_type *spell);
-void spell_type_description_foreach(spell_type *spell, void (*callback)(void *data, cptr text), void *data);
long spell_type_roll_charges(spell_type *spell);
-void spell_type_activation_description(spell_type *spell, char *buf);
-int spell_type_activation_roll_timeout(spell_type *spell);
struct device_allocation *spell_type_device_allocation(spell_type *spell, byte tval);
bool_ spell_type_uses_piety_to_cast(spell_type *spell);
bool_ spell_type_castable_while_blind(spell_type *spell);
bool_ spell_type_castable_while_confused(spell_type *spell);
s16b spell_type_minimum_pval(spell_type *spell);
s16b spell_type_random_type(spell_type *spell);
-bool_ spell_type_school_foreach(spell_type *spell, bool_ (*callback)(void *data, s32b school_idx), void *data);
+std::vector<s32b> const spell_type_get_schools(spell_type *spell);
bool_ spell_type_inertia(spell_type *spell, s32b *difficulty, s32b *delay);
s32b spell_type_failure_rate(spell_type *spell);
s16b spell_type_casting_stat(spell_type *spell);
cptr spell_type_info(spell_type *spell);
void spell_type_mana_range(spell_type *spell, struct range_type *range);
bool_ spell_type_dependencies_satisfied(spell_type *spell);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
+void spell_type_description_foreach(spell_type *spell, std::function<void (std::string const &text)>);
diff --git a/src/spell_type_fwd.h b/src/spell_type_fwd.hpp
index 4664592c..a3b27d27 100644
--- a/src/spell_type_fwd.h
+++ b/src/spell_type_fwd.hpp
@@ -1,9 +1,4 @@
-#ifndef H_ce003b12_cf58_444f_a927_5451f6dd8af1
-#define H_ce003b12_cf58_444f_a927_5451f6dd8af1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#pragma once
/*
* Spell effect function result
@@ -19,9 +14,3 @@ typedef enum {
*/
typedef struct spell_type spell_type;
struct spell_type;
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
diff --git a/src/spells1.c b/src/spells1.cc
index 5aec03bf..ccfb59a2 100644
--- a/src/spells1.c
+++ b/src/spells1.cc
@@ -1,7 +1,3 @@
-/* File: spells1.c */
-
-/* Purpose: Spell code (part 1) */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,49 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "spell_type.h"
+#include "spells1.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd3.hpp"
+#include "cmd5.hpp"
+#include "dungeon_info_type.hpp"
+#include "files.hpp"
+#include "feature_type.hpp"
+#include "gods.hpp"
+#include "melee2.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_type.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells2.hpp"
+#include "spells4.hpp"
+#include "spells5.hpp"
+#include "squeltch.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.hpp"
+#include "wizard2.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <chrono>
+#include <thread>
+
+using std::this_thread::sleep_for;
+using std::chrono::milliseconds;
/* 1/x chance of reducing stats (for elemental attacks) */
#define HURT_CHANCE 32
@@ -23,6 +59,24 @@
/* Maximum number of tries for teleporting */
#define MAX_TRIES 100
+/*
+ * 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)))
+
/*
* Helper function -- return a "nearby" race for polymorphing
@@ -175,7 +229,7 @@ void teleport_player_directed(int rad, int dir)
if (c_ptr->feat == FEAT_SHOP)
{
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Hack -- enter store */
command_new = '_';
@@ -251,7 +305,7 @@ void teleport_away(int m_idx, int dis)
(cave[ny][nx].feat <= FEAT_PATTERN_XTRA2)) continue;
/* No teleporting into vaults and such */
- if (!(p_ptr->inside_quest || p_ptr->inside_arena))
+ if (!(p_ptr->inside_quest))
if (cave[ny][nx].info & (CAVE_ICKY)) continue;
/* This grid looks good */
@@ -303,7 +357,7 @@ void teleport_away(int m_idx, int dis)
/*
* Teleport monster next to the player
*/
-void teleport_to_player(int m_idx)
+static void teleport_to_player(int m_idx)
{
int ny = 0, nx = 0, oy, ox, d, i, min;
int dis = 2;
@@ -571,7 +625,7 @@ void teleport_player(int dis)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -801,7 +855,7 @@ void teleport_player_to(int ny, int nx)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -818,7 +872,7 @@ void teleport_player_to(int ny, int nx)
void teleport_player_level(void)
{
/* No effect in arena or quest */
- if (p_ptr->inside_arena || p_ptr->inside_quest)
+ if (p_ptr->inside_quest)
{
msg_print("There is no effect.");
return;
@@ -937,7 +991,7 @@ void recall_player(int d, int f)
p_ptr->word_recall = 0;
msg_print("A tension leaves the air around you...");
}
- p_ptr->redraw |= (PR_DEPTH);
+ p_ptr->redraw |= (PR_FRAME);
}
@@ -1294,7 +1348,7 @@ void take_hit(int damage, cptr hit_from)
if (death) return;
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Apply "invulnerability" */
if (p_ptr->invuln && (damage < 9000))
@@ -1325,7 +1379,7 @@ void take_hit(int damage, cptr hit_from)
}
/* Display the mana */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Hurt the wielded monster if any */
@@ -1341,7 +1395,7 @@ void take_hit(int damage, cptr hit_from)
inc_stack_size_ex(INVEN_CARRY, -1, OPTIMIZE, NO_DESCRIBE);
damage -= o_ptr->pval2;
o_ptr->pval2 = 0;
- p_ptr->redraw |= PR_MH;
+ p_ptr->redraw |= PR_FRAME;
}
else
{
@@ -1353,14 +1407,14 @@ void take_hit(int damage, cptr hit_from)
carried_monster_hit = FALSE;
/* Display the monster hitpoints */
- p_ptr->redraw |= (PR_MH);
+ p_ptr->redraw |= (PR_FRAME);
}
/* Hurt the player */
if (!monster_take) p_ptr->chp -= damage;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1430,7 +1484,7 @@ void take_hit(int damage, cptr hit_from)
do_cmd_wiz_cure_all();
/* Display the hitpoints */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1479,7 +1533,7 @@ void take_hit(int damage, cptr hit_from)
/* Melkor acn summon to help you */
if (percent < 25)
{
- PRAY_GOD(GOD_MELKOR)
+ if (praying_to(GOD_MELKOR))
{
int chance = p_ptr->grace / 500; /* * 100 / 50000; */
@@ -1527,14 +1581,14 @@ void take_sanity_hit(int damage, cptr hit_from)
if (death) return;
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Hurt the player */
p_ptr->csane -= damage;
/* Display the hitpoints */
- p_ptr->redraw |= (PR_SANITY);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2103,75 +2157,6 @@ void cold_dam(int dam, cptr kb_str)
-
-
-/*
- * Increases a stat by one randomized level -RAK-
- *
- * Note that this function (used by stat potions) now restores
- * the stat BEFORE increasing it.
- */
-bool_ inc_stat(int stat)
-{
- int value, gain;
-
- /* Then augment the current/max stat */
- value = p_ptr->stat_cur[stat];
-
- /* Cannot go above 18/100 */
- if (value < 18 + 100)
- {
- /* Gain one (sometimes two) points */
- if (value < 18)
- {
- gain = ((rand_int(100) < 75) ? 1 : 2);
- value += gain;
- }
-
- /* Gain 1/6 to 1/3 of distance to 18/100 */
- else if (value < 18 + 98)
- {
- /* Approximate gain value */
- gain = (((18 + 100) - value) / 2 + 3) / 2;
-
- /* Paranoia */
- if (gain < 1) gain = 1;
-
- /* Apply the bonus */
- value += randint(gain) + gain / 2;
-
- /* Maximal value */
- if (value > 18 + 99) value = 18 + 99;
- }
-
- /* Gain one point at a time */
- else
- {
- value++;
- }
-
- /* Save the new value */
- p_ptr->stat_cur[stat] = value;
-
- /* Bring up the maximum too */
- if (value > p_ptr->stat_max[stat])
- {
- p_ptr->stat_max[stat] = value;
- }
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Success */
- return (TRUE);
- }
-
- /* Nothing to gain */
- return (FALSE);
-}
-
-
-
/*
* Decreases a stat by an amount indended to vary from 0 to 100 percent.
*
@@ -2669,13 +2654,14 @@ int get_mana_path_dir(int y, int x, int oy, int ox, int pdir, int mana)
* 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
+ * This function returns the coordinates of all the grids on the path.
+ * The returned vector will be empty if and only if (y1,x1) and (y2,x2) are
+ * equal. 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 size of the result of this function should never be
+ * compared directly to "range". Note that the initial grid (y1,x1) is
+ * never saved into the returned grid array, not even if the initial grid
+ * is also the final grid.
*
* The "flg" flags can be used to modify the behavior of this function.
*
@@ -2691,18 +2677,16 @@ int get_mana_path_dir(int y, int x, int oy, int ox, int pdir, int mana)
* 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)
+static std::vector<std::tuple<int, int>> project_path(unsigned int range, int y1, int x1, int y2, int x2, int flg)
{
int y, x, mana = 0, dir = 0;
- int n = 0;
- int k = 0;
+ /* Output grids */
+ std::vector<std::tuple<int, int>> gp;
+ gp.reserve(range + 10);
/* Absolute */
int ay, ax;
@@ -2721,7 +2705,10 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
/* No path necessary (or allowed) */
- if ((x1 == x2) && (y1 == y2)) return (0);
+ if ((x1 == x2) && (y1 == y2))
+ {
+ return gp;
+ }
/* Hack -- to make a bolt/beam/ball follow a mana path */
if (flg & PROJECT_MANA_PATH)
@@ -2740,23 +2727,33 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
while (1)
{
/* Save grid */
- gp[n++] = GRID(y, x);
+ gp.push_back(std::make_tuple(y, x));
/* Hack -- Check maximum range */
- if (n >= range + 10) return n;
+ if (gp.size() >= range + 10)
+ {
+ return gp;
+ }
/* Always stop at non-initial wall grids */
- if ((n > 0) && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x))) return n;
+ if ((!cave_sight_bold(y, x) || !cave_floor_bold(y, x)))
+ {
+ return gp;
+ }
/* Sometimes stop at non-initial monsters/players */
- if (flg & (PROJECT_STOP))
+ if ((flg & (PROJECT_STOP)) && (cave[y][x].m_idx != 0))
{
- if ((n > 0) && (cave[y][x].m_idx != 0)) return n;
+ return gp;
}
/* Get the new direction */
dir = get_mana_path_dir(y, x, oy, ox, pdir, mana);
- if (dir == 5) return n;
+ if (dir == 5)
+ {
+ return gp;
+ }
+
oy = y;
ox = x;
y += ddy[dir];
@@ -2809,28 +2806,37 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
y = y1 + sy;
x = x1;
+ /* Counter for distance calculation */
+ int k = 0;
+
/* Create the projection path */
while (1)
{
/* Save grid */
- gp[n++] = GRID(y, x);
+ gp.push_back(std::make_tuple(y, x));
/* Hack -- Check maximum range */
- if ((n + (k >> 1)) >= range) break;
+ if ((gp.size() + (k >> 1)) >= range)
+ {
+ break;
+ }
/* Sometimes stop at destination grid */
- if (!(flg & (PROJECT_THRU)))
+ if (!(flg & (PROJECT_THRU)) && (x == x2) && (y == y2))
{
- if ((x == x2) && (y == y2)) break;
+ break;
}
/* Always stop at non-initial wall grids */
- if ((n > 0) && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL)) break;
+ if ((!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL))
+ {
+ break;
+ }
/* Sometimes stop at non-initial monsters/players */
- if (flg & (PROJECT_STOP))
+ if ((flg & (PROJECT_STOP)) && (cave[y][x].m_idx != 0))
{
- if ((n > 0) && (cave[y][x].m_idx != 0)) break;
+ break;
}
/* Slant */
@@ -2871,28 +2877,37 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
y = y1;
x = x1 + sx;
+ /* Counter for distance calculation */
+ int k = 0;
+
/* Create the projection path */
while (1)
{
/* Save grid */
- gp[n++] = GRID(y, x);
+ gp.push_back(std::make_tuple(y, x));
/* Hack -- Check maximum range */
- if ((n + (k >> 1)) >= range) break;
+ if ((gp.size() + (k >> 1)) >= range)
+ {
+ break;
+ }
/* Sometimes stop at destination grid */
- if (!(flg & (PROJECT_THRU)))
+ if (!(flg & (PROJECT_THRU)) && (x == x2) && (y == y2))
{
- if ((x == x2) && (y == y2)) break;
+ break;
}
/* Always stop at non-initial wall grids */
- if ((n > 0) && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL)) break;
+ if ((!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL))
+ {
+ break;
+ }
/* Sometimes stop at non-initial monsters/players */
- if (flg & (PROJECT_STOP))
+ if ((flg & (PROJECT_STOP)) && (cave[y][x].m_idx != 0))
{
- if ((n > 0) && (cave[y][x].m_idx != 0)) break;
+ break;
}
/* Slant */
@@ -2931,24 +2946,30 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
while (1)
{
/* Save grid */
- gp[n++] = GRID(y, x);
+ gp.push_back(std::make_tuple(y, x));
/* Hack -- Check maximum range */
- if ((n + (n >> 1)) >= range) break;
+ if ((gp.size() + (gp.size() >> 1)) >= range)
+ {
+ break;
+ }
/* Sometimes stop at destination grid */
- if (!(flg & (PROJECT_THRU)))
+ if (!(flg & (PROJECT_THRU)) && (x == x2) && (y == y2))
{
- if ((x == x2) && (y == y2)) break;
+ break;
}
/* Always stop at non-initial wall grids */
- if ((n > 0) && (!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL)) break;
+ if ((!cave_sight_bold(y, x) || !cave_floor_bold(y, x)) && !(flg & PROJECT_WALL))
+ {
+ break;
+ }
/* Sometimes stop at non-initial monsters/players */
- if (flg & (PROJECT_STOP))
+ if ((flg & (PROJECT_STOP)) && (cave[y][x].m_idx != 0))
{
- if ((n > 0) && (cave[y][x].m_idx != 0)) break;
+ break;
}
/* Advance (Y) */
@@ -2959,9 +2980,8 @@ sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
}
}
-
- /* Length */
- return (n);
+ /* Done */
+ return gp;
}
@@ -3904,8 +3924,6 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
{
cave_type *c_ptr = &cave[y][x];
- s16b this_o_idx, next_o_idx = 0;
-
bool_ obvious = FALSE;
u32b f1, f2, f3, f4, f5, esp;
@@ -3925,11 +3943,12 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
/* Check new gods. */
project_check_gods(typ);
+ /* Copy list of objects since we may destroy during iteration */
+ auto const object_idxs(c_ptr->o_idxs);
+
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
bool_ is_art = FALSE;
bool_ ignore = FALSE;
bool_ plural = FALSE;
@@ -3938,10 +3957,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ)
cptr note_kill = NULL;
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[this_o_idx];
/* Extract the flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -4348,8 +4364,6 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
char killer [80];
- cptr name = (r_name + r_ptr->name);
-
/* Is the monster "seen"? */
bool_ seen;
@@ -4821,8 +4835,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
if (seen) obvious = TRUE;
if ((r_ptr->d_char == 'E') &&
- (prefix(name, "W") ||
- (strstr((r_name + r_ptr->name), "Unmaker"))))
+ (prefix(r_ptr->name, "W") ||
+ (strstr(r_ptr->name, "Unmaker"))))
{
note = " is immune.";
dam = 0;
@@ -4842,8 +4856,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
{
if (seen) obvious = TRUE;
if ((r_ptr->d_char == 'E') &&
- (prefix(name, "W") ||
- (strstr((r_name + r_ptr->name), "Unmaker"))))
+ (prefix(r_ptr->name, "W") ||
+ (strstr(r_ptr->name, "Unmaker"))))
{
note = " is immune.";
dam = 0;
@@ -5419,7 +5433,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
monster_desc(killer, m_ptr, 0x88);
msg_print("Your psychic energy is drained!");
p_ptr->csp = MAX(0, p_ptr->csp - damroll(5, dam) / 2);
- p_ptr->redraw |= PR_MANA;
+ p_ptr->redraw |= PR_FRAME;
take_hit(dam, killer); /* has already been /3 */
}
dam = 0;
@@ -5432,7 +5446,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
m_name, (seen ? "'s" : "s"));
b = MIN(p_ptr->msp, p_ptr->csp + b);
p_ptr->csp = b;
- p_ptr->redraw |= PR_MANA;
+ p_ptr->redraw |= PR_FRAME;
}
note_dies = " collapses, a mindless husk.";
@@ -5711,7 +5725,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_FRAME);
/* Message */
note = " looks healthier.";
@@ -6725,7 +6739,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ)
if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
/* Redraw (later) if needed */
- if (health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_FRAME);
/* Message */
note = " looks healthier.";
@@ -7216,7 +7230,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
project(0, 0, t_y, t_x, dam, typ, (PROJECT_STOP | PROJECT_KILL));
- disturb(1, 0);
+ disturb(1);
return TRUE;
}
@@ -7249,13 +7263,11 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
/* Did the dungeon do it? */
if (who == -100)
{
- sprintf(killer, "%s",
- d_name + d_info[dungeon_type].name);
+ sprintf(killer, "%s", d_info[dungeon_type].name);
}
if (who == -101)
{
- sprintf(killer, "%s",
- f_name + f_info[cave[p_ptr->py][p_ptr->px].feat].name);
+ sprintf(killer, "%s", f_info[cave[p_ptr->py][p_ptr->px].feat].name);
}
if (who >= -1)
@@ -7273,7 +7285,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
if (who == -2)
{
sprintf(killer, "%s",
- t_name + t_info[cave[p_ptr->py][p_ptr->px].t_idx].name);
+ t_info[cave[p_ptr->py][p_ptr->px].t_idx].name);
}
/* Analyze the damage */
@@ -8118,7 +8130,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
/* Disturb */
- disturb(1, 0);
+ disturb(1);
/* Return "Anything seen?" */
@@ -8272,7 +8284,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad
*/
bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
{
- int i, t, dist;
+ int t, dist;
int y1, x1;
int y2, x2;
@@ -8295,11 +8307,8 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* 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[1024];
+ std::vector<std::tuple<int, int>> path_g;
/* Number of grids in the "blast area" (including the "beam" path) */
int grids = 0;
@@ -8382,22 +8391,26 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Calculate the projection path */
if ((who == -101) || (who == -100))
- path_n = 0;
+ {
+ /* Leave path empty */
+ }
else
- path_n = project_path(path_g, MAX_RANGE, y1, x1, y2, x2, flg);
+ {
+ path_g = project_path(MAX_RANGE, y1, x1, y2, x2, flg);
+ }
/* Hack -- Handle stuff */
handle_stuff();
/* Project along the path */
- for (i = 0; i < path_n; ++i)
+ for (auto const &grid_yx: path_g)
{
int oy = y;
int ox = x;
- int ny = GRID_Y(path_g[i]);
- int nx = GRID_X(path_g[i]);
+ int ny = std::get<0>(grid_yx);
+ int nx = std::get<1>(grid_yx);
/* Hack -- Balls explode before reaching walls */
if (!cave_floor_bold(ny, nx) && (rad > 0)) break;
@@ -8436,7 +8449,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
print_rel(c, a, y, x);
move_cursor_relative(y, x);
if (fresh_before) Term_fresh();
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
lite_spot(y, x);
if (fresh_before) Term_fresh();
@@ -8462,7 +8475,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
else if (visual)
{
/* Delay for consistency */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
}
}
@@ -8543,7 +8556,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
for (t = 0; t <= rad; t++)
{
/* Dump everything with this radius */
- for (i = gm[t]; i < gm[t + 1]; i++)
+ for (int i = gm[t]; i < gm[t + 1]; i++)
{
/* Extract the location */
y = gy[i];
@@ -8580,7 +8593,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
/* Delay (efficiently) */
if (visual || drawn)
{
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
}
}
@@ -8588,7 +8601,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
if (drawn)
{
/* Erase the explosion drawn above */
- for (i = 0; i < grids; i++)
+ for (int i = 0; i < grids; i++)
{
/* Extract the location */
y = gy[i];
@@ -8625,7 +8638,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
}
/* Scan for features */
- for (i = 0; i < grids; i++)
+ for (int i = 0; i < grids; i++)
{
/* Hack -- Notice new "dist" values */
if (gm[dist + 1] == i) dist++;
@@ -8658,7 +8671,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
dist = 0;
/* Scan for objects */
- for (i = 0; i < grids; i++)
+ for (int i = 0; i < grids; i++)
{
/* Hack -- Notice new "dist" values */
if (gm[dist + 1] == i) dist++;
@@ -8685,7 +8698,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
dist = 0;
/* Scan for monsters */
- for (i = 0; i < grids; i++)
+ for (int i = 0; i < grids; i++)
{
/* Hack -- Notice new "dist" values */
if (gm[dist + 1] == i) dist++;
@@ -8770,7 +8783,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg)
dist = 0;
/* Scan for player */
- for (i = 0; i < grids; i++)
+ for (int i = 0; i < grids; i++)
{
/* Hack -- Notice new "dist" values */
if (gm[dist + 1] == i) dist++;
@@ -8950,6 +8963,10 @@ bool_ potion_smash_effect(int who, int y, int x, int o_sval)
(void) project(who, radius, y, x, dam, dt,
(PROJECT_JUMP | PROJECT_ITEM | PROJECT_KILL));
+ // Silence warning. We may want to introuce an actual implementation
+ // and I want to preserve the original "ident" values if we do so.
+ (void) ident;
+
/* XXX those potions that explode need to become "known" */
return angry;
}
@@ -9003,7 +9020,7 @@ static const int attack_types[25] =
* Describe the attack using normal names.
*/
-void describe_attack_fully(int type, char* r)
+static void describe_attack_fully(int type, char* r)
{
switch (type)
{
diff --git a/src/spells1.hpp b/src/spells1.hpp
new file mode 100644
index 00000000..5512063f
--- /dev/null
+++ b/src/spells1.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern byte spell_color(int type);
+extern s16b poly_r_idx(int r_idx);
+extern void get_pos_player(int dis, int *ny, int *nx);
+extern bool_ teleport_player_bypass;
+extern void teleport_player_directed(int rad, int dir);
+extern void teleport_away(int m_idx, int dis);
+extern void teleport_player(int dis);
+extern void teleport_player_to(int ny, int nx);
+extern void teleport_monster_to(int m_idx, int ny, int nx);
+extern void teleport_player_level(void);
+extern void recall_player(int d, int f);
+extern void take_hit(int damage, cptr kb_str);
+extern void take_sanity_hit(int damage, cptr hit_from);
+extern void acid_dam(int dam, cptr kb_str);
+extern void elec_dam(int dam, cptr kb_str);
+extern void fire_dam(int dam, cptr kb_str);
+extern void cold_dam(int dam, cptr kb_str);
+extern bool_ dec_stat(int stat, int amount, int mode);
+extern bool_ res_stat(int stat, bool_ full);
+extern bool_ apply_disenchant(int mode);
+extern bool_ project_m(int who, int r, int y, int x, int dam, int typ);
+extern bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg);
+extern bool_ potion_smash_effect(int who, int y, int x, int o_sval);
+extern void do_poly_self(void);
+extern void corrupt_player(void);
+extern void generate_spell(int plev);
+extern bool_ unsafe;
+extern s16b do_poly_monster(int y, int x);
diff --git a/src/spells2.c b/src/spells2.cc
index 8778e49f..631ff30e 100644
--- a/src/spells2.c
+++ b/src/spells2.cc
@@ -1,7 +1,3 @@
-/* File: spells2.c */
-
-/* Purpose: Spell code (part 2) */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,7 +6,51 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "spells2.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd7.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "hook_identify_in.hpp"
+#include "hooks.hpp"
+#include "melee2.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells3.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <cassert>
+#include <chrono>
+#include <sstream>
+#include <thread>
+#include <vector>
+
+using boost::algorithm::iequals;
+using std::this_thread::sleep_for;
+using std::chrono::milliseconds;
#define WEIRD_LUCK 12
#define BIAS_LUCK 20
@@ -19,7 +59,7 @@
* since it is usually tested several times...
*/
-void summon_dragon_riders();
+static void summon_dragon_riders();
/*
@@ -111,7 +151,7 @@ bool_ hp_player(int num)
}
/* Redraw */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -309,6 +349,72 @@ bool_ do_res_stat(int stat, bool_ full)
/*
+ * Increases a stat by one randomized level -RAK-
+ *
+ * Note that this function (used by stat potions) now restores
+ * the stat BEFORE increasing it.
+ */
+static bool_ inc_stat(int stat)
+{
+ int value, gain;
+
+ /* Then augment the current/max stat */
+ value = p_ptr->stat_cur[stat];
+
+ /* Cannot go above 18/100 */
+ if (value < 18 + 100)
+ {
+ /* Gain one (sometimes two) points */
+ if (value < 18)
+ {
+ gain = ((rand_int(100) < 75) ? 1 : 2);
+ value += gain;
+ }
+
+ /* Gain 1/6 to 1/3 of distance to 18/100 */
+ else if (value < 18 + 98)
+ {
+ /* Approximate gain value */
+ gain = (((18 + 100) - value) / 2 + 3) / 2;
+
+ /* Paranoia */
+ if (gain < 1) gain = 1;
+
+ /* Apply the bonus */
+ value += randint(gain) + gain / 2;
+
+ /* Maximal value */
+ if (value > 18 + 99) value = 18 + 99;
+ }
+
+ /* Gain one point at a time */
+ else
+ {
+ value++;
+ }
+
+ /* Save the new value */
+ p_ptr->stat_cur[stat] = value;
+
+ /* Bring up the maximum too */
+ if (value > p_ptr->stat_max[stat])
+ {
+ p_ptr->stat_max[stat] = value;
+ }
+
+ /* Recalculate bonuses */
+ p_ptr->update |= (PU_BONUS);
+
+ /* Success */
+ return (TRUE);
+ }
+
+ /* Nothing to gain */
+ return (FALSE);
+}
+
+
+/*
* Gain a "point" in a stat
*/
bool_ do_inc_stat(int stat)
@@ -348,27 +454,9 @@ bool_ do_inc_stat(int stat)
*/
void identify_hooks(int i, object_type *o_ptr, identify_mode mode)
{
- cptr mode_s = NULL;
-
- switch (mode)
- {
- case IDENT_NORMAL:
- mode_s = "normal";
- break;
- case IDENT_FULL:
- mode_s = "full";
- break;
- default:
- assert(FALSE);
- }
-
/* Process the appropriate hooks */
- process_hooks(HOOK_IDENTIFY, "(d,s)", i, mode_s);
-
- {
- hook_identify_in in = { o_ptr, mode };
- process_hooks_new(HOOK_IDENTIFY, &in, NULL);
- }
+ hook_identify_in in = { o_ptr, mode };
+ process_hooks_new(HOOK_IDENTIFY, &in, NULL);
}
@@ -456,7 +544,7 @@ static int enchant_table[16] =
1000
};
-bool_ remove_curse_object(object_type *o_ptr, bool_ all)
+static bool_ remove_curse_object(object_type *o_ptr, bool_ all)
{
u32b f1, f2, f3, f4, f5, esp;
@@ -595,23 +683,24 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh
int old_number;
long price;
bool_ force = FALSE;
- object_type *o_ptr;
char o_name[80];
char out_val[160];
- cptr q, s;
-
/* Hack -- force destruction */
if (command_arg > 0) force = TRUE;
/* Get an item */
- q = "Turn which item to gold? ";
- s = "You have nothing to turn to gold.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return (FALSE);
+ if (!get_item(&item,
+ "Turn which item to gold? ",
+ "You have nothing to turn to gold.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::True()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* See how many items */
if (o_ptr->number > 1)
@@ -633,12 +722,9 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh
/* Verify unless quantity given */
if (!force)
{
- if (!((auto_destroy) && (object_value(o_ptr) < 1)))
- {
- /* Make a verification */
- sprintf(out_val, "Really turn %s to gold? ", o_name);
- if (!get_check(out_val)) return FALSE;
- }
+ /* Make a verification */
+ sprintf(out_val, "Really turn %s to gold? ", o_name);
+ if (!get_check(out_val)) return FALSE;
}
/* Artifacts cannot be destroyed */
@@ -683,7 +769,7 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh
p_ptr->au += price;
/* Redraw gold */
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1202,10 +1288,6 @@ void self_knowledge(FILE *fff)
{
info[i++] = "You are looking around very carefully.";
}
- if (p_ptr->new_spells)
- {
- info[i++] = "You can learn some spells/prayers.";
- }
if (p_ptr->word_recall)
{
info[i++] = "You will soon be recalled.";
@@ -2013,7 +2095,7 @@ bool_ detect_traps(int rad)
* item is used and return FALSE there are none,
* followed by current implementation --pelpel
*/
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Result -- see my comment above -- pelpel */
/* return (detect); */
@@ -2209,83 +2291,75 @@ bool_ detect_treasure(int rad)
/*
- * Detect all "gold" objects on the current panel
+ * Detect all (string) monsters on current panel
*/
-bool_ hack_no_detect_message = FALSE;
-bool_ detect_objects_gold(int rad)
+static bool_ detect_monsters_string(cptr chars, int rad)
{
int i, y, x;
-
- bool_ detect = FALSE;
+ bool_ flag = FALSE;
- /* Scan objects */
- for (i = 1; i < o_max; i++)
+ /* Scan monsters */
+ for (i = 1; i < m_max; i++)
{
- object_type *o_ptr = &o_list[i];
+ monster_type *m_ptr = &m_list[i];
+ monster_race *r_ptr = race_inf(m_ptr);
- /* Skip dead objects */
- if (!o_ptr->k_idx) continue;
+ /* Skip dead monsters */
+ if (!m_ptr->r_idx) continue;
- /* Skip held objects */
- if (o_ptr->held_m_idx)
+ /* Location */
+ y = m_ptr->fy;
+ x = m_ptr->fx;
+
+ /* Only detect nearby monsters */
+ if (m_ptr->cdis > rad) continue;
+
+ /* Detect evil monsters */
+ if (strchr(chars, r_ptr->d_char))
{
- /* Access the monster */
- monster_type *m_ptr = &m_list[o_ptr->held_m_idx];
- monster_race *r_ptr = race_inf(m_ptr);
- if (!(r_ptr->flags9 & RF9_MIMIC)) continue;
- else
+ /* Update monster recall window */
+ if (monster_race_idx == m_ptr->r_idx)
{
- /* Location */
- y = m_ptr->fy;
- x = m_ptr->fx;
+ /* Window stuff */
+ p_ptr->window |= (PW_MONSTER);
}
- }
- else
- {
- /* Location */
- y = o_ptr->iy;
- x = o_ptr->ix;
- }
- /* Only detect nearby objects */
- if (distance(p_ptr->py, p_ptr->px, y, x) > rad) continue;
+ /* Repair visibility later */
+ repair_monsters = TRUE;
- /* Detect "gold" objects */
- if (o_ptr->tval == TV_GOLD)
- {
- /* Hack -- memorize it */
- o_ptr->marked = TRUE;
+ /* Hack -- Detect monster */
+ m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
+
+ /* Hack -- See monster */
+ m_ptr->ml = TRUE;
/* Redraw */
if (panel_contains(y, x)) lite_spot(y, x);
/* Detect */
- detect = TRUE;
+ flag = TRUE;
}
}
/* Describe */
- if (detect && (!hack_no_detect_message))
- {
- msg_print("You sense the presence of treasure!");
- }
-
- if (detect_monsters_string("$", rad))
+ if (flag)
{
- detect = TRUE;
+ /* Describe result */
+ msg_print("You sense the presence of monsters!");
}
/* Result */
- return (detect);
+ return (flag);
}
+
/*
- * Detect all "normal" objects on the current panel
+ * Detect all "gold" objects on the current panel
*/
-bool_ detect_objects_normal(int rad)
+bool_ detect_objects_gold(int rad)
{
int i, y, x;
@@ -2325,8 +2399,8 @@ bool_ detect_objects_normal(int rad)
/* Only detect nearby objects */
if (distance(p_ptr->py, p_ptr->px, y, x) > rad) continue;
- /* Detect "real" objects */
- if (o_ptr->tval != TV_GOLD)
+ /* Detect "gold" objects */
+ if (o_ptr->tval == TV_GOLD)
{
/* Hack -- memorize it */
o_ptr->marked = TRUE;
@@ -2340,12 +2414,12 @@ bool_ detect_objects_normal(int rad)
}
/* Describe */
- if (detect && (!hack_no_detect_message))
+ if (detect)
{
- msg_print("You sense the presence of objects!");
+ msg_print("You sense the presence of treasure!");
}
- if (detect_monsters_string("!=?|", rad))
+ if (detect_monsters_string("$", rad))
{
detect = TRUE;
}
@@ -2356,22 +2430,16 @@ bool_ detect_objects_normal(int rad)
/*
- * Detect all "magic" objects on the current panel.
- *
- * This will light up all spaces with "magic" items, including artifacts,
- * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
- * and "enchanted" items of the "good" variety.
- *
- * It can probably be argued that this function is now too powerful.
+ * Detect all "normal" objects on the current panel
*/
-bool_ detect_objects_magic(int rad)
+bool_ detect_objects_normal(int rad)
{
- int i, y, x, tv;
+ int i, y, x;
bool_ detect = FALSE;
- /* Scan all objects */
+ /* Scan objects */
for (i = 1; i < o_max; i++)
{
object_type *o_ptr = &o_list[i];
@@ -2404,19 +2472,10 @@ bool_ detect_objects_magic(int rad)
/* Only detect nearby objects */
if (distance(p_ptr->py, p_ptr->px, y, x) > rad) continue;
- /* Examine the tval */
- tv = o_ptr->tval;
-
- /* Artifacts, misc magic items, or enchanted wearables */
- if (artifact_p(o_ptr) || ego_item_p(o_ptr) || o_ptr->art_name ||
- (tv == TV_AMULET) || (tv == TV_RING) || (tv == TV_BATERIE) ||
- (tv == TV_STAFF) || (tv == TV_WAND) || (tv == TV_ROD) || (tv == TV_ROD_MAIN) ||
- (tv == TV_SCROLL) || (tv == TV_POTION) || (tv == TV_POTION2) ||
- (tv == TV_DAEMON_BOOK) ||
- (tv == TV_SYMBIOTIC_BOOK) || (tv == TV_MUSIC_BOOK) ||
- ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0)))
+ /* Detect "real" objects */
+ if (o_ptr->tval != TV_GOLD)
{
- /* Memorize the item */
+ /* Hack -- memorize it */
o_ptr->marked = TRUE;
/* Redraw */
@@ -2430,10 +2489,15 @@ bool_ detect_objects_magic(int rad)
/* Describe */
if (detect)
{
- msg_print("You sense the presence of magic objects!");
+ msg_print("You sense the presence of objects!");
+ }
+
+ if (detect_monsters_string("!=?|", rad))
+ {
+ detect = TRUE;
}
- /* Return result */
+ /* Result */
return (detect);
}
@@ -2565,140 +2629,6 @@ bool_ detect_monsters_invis(int rad)
/*
- * Detect all "evil" monsters on current panel
- */
-bool_ detect_monsters_evil(int rad)
-{
- int i, y, x;
- bool_ flag = FALSE;
-
-
- /* Scan monsters */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr = &m_list[i];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Location */
- y = m_ptr->fy;
- x = m_ptr->fx;
-
- /* Only detect nearby monsters */
- if (m_ptr->cdis > rad) continue;
-
- /* Detect evil monsters */
- if (r_ptr->flags3 & (RF3_EVIL))
- {
- /* Take note that they are evil */
- r_ptr->r_flags3 |= (RF3_EVIL);
-
- /* Update monster recall window */
- if (monster_race_idx == m_ptr->r_idx)
- {
- /* Window stuff */
- p_ptr->window |= (PW_MONSTER);
- }
-
- /* Repair visibility later */
- repair_monsters = TRUE;
-
- /* Hack -- Detect monster */
- m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
-
- /* Hack -- See monster */
- m_ptr->ml = TRUE;
-
- /* Redraw */
- if (panel_contains(y, x)) lite_spot(y, x);
-
- /* Detect */
- flag = TRUE;
- }
- }
-
- /* Describe */
- if (flag)
- {
- /* Describe result */
- msg_print("You sense the presence of evil creatures!");
- }
-
- /* Result */
- return (flag);
-}
-
-
-
-
-/*
- * Detect all (string) monsters on current panel
- */
-bool_ detect_monsters_string(cptr chars, int rad)
-{
- int i, y, x;
- bool_ flag = FALSE;
-
-
- /* Scan monsters */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr = &m_list[i];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Location */
- y = m_ptr->fy;
- x = m_ptr->fx;
-
- /* Only detect nearby monsters */
- if (m_ptr->cdis > rad) continue;
-
- /* Detect evil monsters */
- if (strchr(chars, r_ptr->d_char))
- {
-
- /* Update monster recall window */
- if (monster_race_idx == m_ptr->r_idx)
- {
- /* Window stuff */
- p_ptr->window |= (PW_MONSTER);
- }
-
- /* Repair visibility later */
- repair_monsters = TRUE;
-
- /* Hack -- Detect monster */
- m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
-
- /* Hack -- See monster */
- m_ptr->ml = TRUE;
-
- /* Redraw */
- if (panel_contains(y, x)) lite_spot(y, x);
-
- /* Detect */
- flag = TRUE;
- }
- }
-
- /* Describe */
- if (flag)
- {
- /* Describe result */
- msg_print("You sense the presence of monsters!");
- }
-
- /* Result */
- return (flag);
-}
-
-
-/*
* A "generic" detect monsters routine, tagged to flags3
*/
bool_ detect_monsters_xxx(u32b match_flag, int rad)
@@ -2779,11 +2709,6 @@ bool_ detect_monsters_xxx(u32b match_flag, int rad)
return (flag);
}
-/* Detect good monsters */
-bool_ detect_monsters_good(int rad)
-{
- return (detect_monsters_xxx(RF3_GOOD, rad));
-}
/*
@@ -2837,9 +2762,9 @@ void stair_creation(void)
delete_object(p_ptr->py, p_ptr->px);
/* Create a staircase */
- if (p_ptr->inside_arena || p_ptr->inside_quest)
+ if (p_ptr->inside_quest)
{
- /* arena or quest */
+ /* quest */
msg_print("There is no effect!");
}
else if (!dun_level)
@@ -2868,95 +2793,72 @@ void stair_creation(void)
/*
* Hook to specify "weapon"
*/
-static bool_ item_tester_hook_weapon(object_type *o_ptr)
-{
- switch (o_ptr->tval)
- {
- case TV_MSTAFF:
- case TV_BOOMERANG:
- case TV_SWORD:
- case TV_AXE:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_BOW:
- case TV_BOLT:
- case TV_ARROW:
- case TV_SHOT:
- {
- return (TRUE);
- }
- case TV_DAEMON_BOOK:
- {
- switch (o_ptr->sval)
- {
- case SV_DEMONBLADE:
- {
- return (TRUE);
- }
- }
- }
- }
-
- return (FALSE);
+static object_filter_t const &item_tester_hook_weapon()
+{
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_MSTAFF),
+ TVal(TV_BOOMERANG),
+ TVal(TV_SWORD),
+ TVal(TV_AXE),
+ TVal(TV_HAFTED),
+ TVal(TV_POLEARM),
+ TVal(TV_BOW),
+ TVal(TV_BOLT),
+ TVal(TV_ARROW),
+ TVal(TV_SHOT),
+ And(
+ TVal(TV_DAEMON_BOOK),
+ SVal(SV_DEMONBLADE)));
+ return instance;
}
/*
* Hook to specify "armour"
*/
-bool_ item_tester_hook_armour(object_type *o_ptr)
-{
- switch (o_ptr->tval)
- {
- case TV_DRAG_ARMOR:
- case TV_HARD_ARMOR:
- case TV_SOFT_ARMOR:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_CROWN:
- case TV_HELM:
- case TV_BOOTS:
- case TV_GLOVES:
- {
- return (TRUE);
- }
- case TV_DAEMON_BOOK:
- {
- switch (o_ptr->sval)
- {
- case SV_DEMONHORN:
- case SV_DEMONSHIELD:
- {
- return (TRUE);
- }
- }
- }
- }
-
- return (FALSE);
+static object_filter_t const &item_tester_hook_armour()
+{
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_DRAG_ARMOR),
+ TVal(TV_HARD_ARMOR),
+ TVal(TV_SOFT_ARMOR),
+ TVal(TV_SHIELD),
+ TVal(TV_CLOAK),
+ TVal(TV_CROWN),
+ TVal(TV_HELM),
+ TVal(TV_BOOTS),
+ TVal(TV_GLOVES),
+ And(
+ TVal(TV_DAEMON_BOOK),
+ Or(
+ SVal(SV_DEMONHORN),
+ SVal(SV_DEMONSHIELD))));
+ return instance;
}
/*
- * Check if an object is weapon or armour (but not arrow, bolt, or shot)
- */
-bool_ item_tester_hook_weapon_armour(object_type *o_ptr)
-{
- return (item_tester_hook_weapon(o_ptr) ||
- item_tester_hook_armour(o_ptr));
-}
-
-/*
* Check if an object is artifactable
*/
-bool_ item_tester_hook_artifactable(object_type *o_ptr)
+object_filter_t const &item_tester_hook_artifactable()
{
- return ((item_tester_hook_weapon(o_ptr) ||
- item_tester_hook_armour(o_ptr) ||
- (o_ptr->tval == TV_DIGGING) ||
- (o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET))
- /* be nice: allow only normal items */
- && (!artifact_p(o_ptr)) && (!ego_item_p(o_ptr)));
+ using namespace object_filter;
+ static auto instance = And(
+ // Check base item family
+ Or(
+ item_tester_hook_weapon(),
+ item_tester_hook_armour(),
+ TVal(TV_DIGGING),
+ TVal(TV_RING),
+ TVal(TV_AMULET)),
+ // Only unenchanted items
+ Not(IsArtifactP()),
+ Not(IsEgo()));
+ return instance;
}
@@ -3156,24 +3058,26 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
{
int item;
bool_ okay = FALSE;
- object_type *o_ptr;
char o_name[80];
cptr q, s;
/* Assume enchant weapon */
- item_tester_hook = item_tester_hook_weapon;
+ object_filter_t object_filter = item_tester_hook_weapon();
/* Enchant armor if requested */
- if (num_ac) item_tester_hook = item_tester_hook_armour;
+ if (num_ac)
+ {
+ object_filter = item_tester_hook_armour();
+ }
/* Get an item */
q = "Enchant which item? ";
s = "You have nothing to enchant.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR), object_filter)) return (FALSE);
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
object_desc(o_name, o_ptr, FALSE, 0);
@@ -3220,231 +3124,6 @@ void curse_artifact(object_type * o_ptr)
}
-/*
- * Should be merged with randart code.
- * looks like BASIC coder's work...
- */
-void random_plus(object_type * o_ptr, bool_ is_scroll)
-{
- int this_type = (o_ptr->tval < TV_BOOTS ? 23 : 19);
-
- if (artifact_bias == BIAS_WARRIOR)
- {
- if (!(o_ptr->art_flags1 & TR1_STR))
- {
- o_ptr->art_flags1 |= TR1_STR;
- if (randint(2) == 1) return ; /* 50% chance of being a "free" power */
- }
-
- if (!(o_ptr->art_flags1 & TR1_CON))
- {
- o_ptr->art_flags1 |= TR1_CON;
- if (randint(2) == 1) return;
- }
-
- if (!(o_ptr->art_flags1 & TR1_DEX))
- {
- o_ptr->art_flags1 |= TR1_DEX;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_MAGE)
- {
- if (!(o_ptr->art_flags1 & TR1_INT))
- {
- o_ptr->art_flags1 |= TR1_INT;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_PRIESTLY)
- {
- if (!(o_ptr->art_flags1 & TR1_WIS))
- {
- o_ptr->art_flags1 |= TR1_WIS;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_RANGER)
- {
- if (!(o_ptr->art_flags1 & TR1_CON))
- {
- o_ptr->art_flags1 |= TR1_CON;
- if (randint(2) == 1) return ; /* 50% chance of being a "free" power */
- }
-
- if (!(o_ptr->art_flags1 & TR1_DEX))
- {
- o_ptr->art_flags1 |= TR1_DEX;
- if (randint(2) == 1) return;
- }
-
- if (!(o_ptr->art_flags1 & TR1_STR))
- {
- o_ptr->art_flags1 |= TR1_STR;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_ROGUE)
- {
- if (!(o_ptr->art_flags1 & TR1_STEALTH))
- {
- o_ptr->art_flags1 |= TR1_STEALTH;
- if (randint(2) == 1) return;
- }
- if (!(o_ptr->art_flags1 & TR1_SEARCH))
- {
- o_ptr->art_flags1 |= TR1_SEARCH;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_STR)
- {
- if (!(o_ptr->art_flags1 & TR1_STR))
- {
- o_ptr->art_flags1 |= TR1_STR;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_WIS)
- {
- if (!(o_ptr->art_flags1 & TR1_WIS))
- {
- o_ptr->art_flags1 |= TR1_WIS;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_INT)
- {
- if (!(o_ptr->art_flags1 & TR1_INT))
- {
- o_ptr->art_flags1 |= TR1_INT;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_DEX)
- {
- if (!(o_ptr->art_flags1 & TR1_DEX))
- {
- o_ptr->art_flags1 |= TR1_DEX;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_CON)
- {
- if (!(o_ptr->art_flags1 & TR1_CON))
- {
- o_ptr->art_flags1 |= TR1_CON;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_CHR)
- {
- if (!(o_ptr->art_flags1 & TR1_CHR))
- {
- o_ptr->art_flags1 |= TR1_CHR;
- if (randint(2) == 1) return;
- }
- }
-
-
- switch (randint(this_type))
- {
- case 1:
- case 2:
- o_ptr->art_flags1 |= TR1_STR;
- /* if (is_scroll) msg_print("It makes you feel strong!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_STR;
- else if (!(artifact_bias) && randint(7) == 1)
- artifact_bias = BIAS_WARRIOR;
- break;
- case 3:
- case 4:
- o_ptr->art_flags1 |= TR1_INT;
- /* if (is_scroll) msg_print("It makes you feel smart!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_INT;
- else if (!(artifact_bias) && randint(7) == 1)
- artifact_bias = BIAS_MAGE;
- break;
- case 5:
- case 6:
- o_ptr->art_flags1 |= TR1_WIS;
- /* if (is_scroll) msg_print("It makes you feel wise!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_WIS;
- else if (!(artifact_bias) && randint(7) == 1)
- artifact_bias = BIAS_PRIESTLY;
- break;
- case 7:
- case 8:
- o_ptr->art_flags1 |= TR1_DEX;
- /* if (is_scroll) msg_print("It makes you feel nimble!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_DEX;
- else if (!(artifact_bias) && randint(7) == 1)
- artifact_bias = BIAS_ROGUE;
- break;
- case 9:
- case 10:
- o_ptr->art_flags1 |= TR1_CON;
- /* if (is_scroll) msg_print("It makes you feel healthy!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_CON;
- else if (!(artifact_bias) && randint(9) == 1)
- artifact_bias = BIAS_RANGER;
- break;
- case 11:
- case 12:
- o_ptr->art_flags1 |= TR1_CHR;
- /* if (is_scroll) msg_print("It makes you look great!"); */
- if (!(artifact_bias) && randint(13) != 1)
- artifact_bias = BIAS_CHR;
- break;
- case 13:
- case 14:
- o_ptr->art_flags1 |= TR1_STEALTH;
- /* if (is_scroll) msg_print("It looks muffled."); */
- if (!(artifact_bias) && randint(3) == 1)
- artifact_bias = BIAS_ROGUE;
- break;
- case 15:
- case 16:
- o_ptr->art_flags1 |= TR1_SEARCH;
- /* if (is_scroll) msg_print("It makes you see better."); */
- if (!(artifact_bias) && randint(9) == 1)
- artifact_bias = BIAS_RANGER;
- break;
- case 17:
- case 18:
- o_ptr->art_flags1 |= TR1_INFRA;
- /* if (is_scroll) msg_print("It makes you see tiny red animals.");*/
- break;
- case 19:
- o_ptr->art_flags1 |= TR1_SPEED;
- /* if (is_scroll) msg_print("It makes you move faster!"); */
- if (!(artifact_bias) && randint(11) == 1)
- artifact_bias = BIAS_ROGUE;
- break;
- case 20:
- case 21:
- o_ptr->art_flags1 |= TR1_TUNNEL;
- /* if (is_scroll) msg_print("Gravel flies from it!"); */
- break;
- case 22:
- case 23:
- if (o_ptr->tval == TV_BOW) random_plus(o_ptr, is_scroll);
- else
- {
- o_ptr->art_flags1 |= TR1_BLOWS;
- /* if (is_scroll) msg_print("It seems faster!"); */
- if (!(artifact_bias) && randint(11) == 1)
- artifact_bias = BIAS_WARRIOR;
- }
- break;
- }
-}
-
void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific)
{
@@ -3750,509 +3429,6 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific)
}
}
-void random_misc(object_type * o_ptr, bool_ is_scroll)
-{
-
- if (artifact_bias == BIAS_RANGER)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_CON))
- {
- o_ptr->art_flags2 |= TR2_SUST_CON;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_STR)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_STR))
- {
- o_ptr->art_flags2 |= TR2_SUST_STR;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_WIS)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_WIS))
- {
- o_ptr->art_flags2 |= TR2_SUST_WIS;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_INT)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_INT))
- {
- o_ptr->art_flags2 |= TR2_SUST_INT;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_DEX)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_DEX))
- {
- o_ptr->art_flags2 |= TR2_SUST_DEX;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_CON)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_CON))
- {
- o_ptr->art_flags2 |= TR2_SUST_CON;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_CHR)
- {
- if (!(o_ptr->art_flags2 & TR2_SUST_CHR))
- {
- o_ptr->art_flags2 |= TR2_SUST_CHR;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_CHAOS)
- {
- if (!(o_ptr->art_flags3 & TR3_TELEPORT))
- {
- o_ptr->art_flags3 |= TR3_TELEPORT;
- if (randint(2) == 1) return;
- }
- }
- else if (artifact_bias == BIAS_FIRE)
- {
- if (!(o_ptr->art_flags3 & TR3_LITE1))
- {
- o_ptr->art_flags3 |= TR3_LITE1; /* Freebie */
- }
- }
-
-
- switch (randint(31))
- {
- case 1:
- o_ptr->art_flags2 |= TR2_SUST_STR;
- /* if (is_scroll) msg_print("It makes you feel you cannot become weaker."); */
- if (!artifact_bias)
- artifact_bias = BIAS_STR;
- break;
-
- case 2:
- o_ptr->art_flags2 |= TR2_SUST_INT;
- /* if (is_scroll) msg_print("It makes you feel you cannot become more stupid.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_INT;
- break;
-
- case 3:
- o_ptr->art_flags2 |= TR2_SUST_WIS;
- /* if (is_scroll) msg_print("It makes you feel you cannot become simpler.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_WIS;
- break;
-
- case 4:
- o_ptr->art_flags2 |= TR2_SUST_DEX;
- /* if (is_scroll) msg_print("It makes you feel you cannot become clumsier.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_DEX;
- break;
-
- case 5:
- o_ptr->art_flags2 |= TR2_SUST_CON;
- /* if (is_scroll) msg_print("It makes you feel you cannot become less healthy.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_CON;
- break;
-
- case 6:
- o_ptr->art_flags2 |= TR2_SUST_CHR;
- /* if (is_scroll) msg_print("It makes you feel you cannot become uglier.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_CHR;
- break;
-
- case 7:
- case 8:
- case 14:
- o_ptr->art_flags2 |= TR2_FREE_ACT;
- /* if (is_scroll) msg_print("It makes you feel like a young rebel!");*/
- break;
-
- case 9:
- o_ptr->art_flags2 |= TR2_HOLD_LIFE;
- /* if (is_scroll) msg_print("It makes you feel immortal.");*/
- if (!artifact_bias && (randint(5) == 1))
- artifact_bias = BIAS_PRIESTLY;
- else if (!artifact_bias && (randint(6) == 1))
- artifact_bias = BIAS_NECROMANTIC;
- break;
-
- case 10:
- case 11:
- o_ptr->art_flags3 |= TR3_LITE1;
- /* if (is_scroll) msg_print("It starts shining.");*/
- break;
-
- case 12:
- case 13:
- o_ptr->art_flags3 |= TR3_FEATHER;
- /* if (is_scroll) msg_print("It feels lighter.");*/
- break;
-
- case 15:
- case 16:
- case 17:
- o_ptr->art_flags3 |= TR3_SEE_INVIS;
- /* if (is_scroll) msg_print("It makes you see the air!");*/
- break;
-
- case 18:
- o_ptr->art_esp |= 1 << (rand_int(32));
- /* if (is_scroll) msg_print("It makes you hear voices inside your head!");*/
- if (!artifact_bias && (randint(9) == 1))
- artifact_bias = BIAS_MAGE;
- break;
-
- case 19:
- case 20:
- o_ptr->art_flags3 |= TR3_SLOW_DIGEST;
- /* if (is_scroll) msg_print("It makes you feel less hungry.");*/
- break;
-
- case 21:
- case 22:
- o_ptr->art_flags3 |= TR3_REGEN;
- /* if (is_scroll) msg_print("It looks as good as new.");*/
- break;
-
- case 23:
- o_ptr->art_flags3 |= TR3_TELEPORT;
- /* if (is_scroll) msg_print("Its position feels uncertain!");*/
- break;
-
- case 24:
- case 25:
- case 26:
- if (o_ptr->tval >= TV_BOOTS) random_misc(o_ptr, is_scroll);
- else
- {
- o_ptr->art_flags3 |= TR3_SHOW_MODS;
- o_ptr->to_a = 4 + (randint(11));
- }
- break;
-
- case 27:
- case 28:
- case 29:
- o_ptr->art_flags3 |= TR3_SHOW_MODS;
- o_ptr->to_h += 4 + (randint(11));
- o_ptr->to_d += 4 + (randint(11));
- break;
-
- case 30:
- o_ptr->art_flags3 |= TR3_NO_MAGIC;
- break;
-
- case 31:
- o_ptr->art_flags3 |= TR3_NO_TELE;
- break;
- }
-
-
-}
-
-
-void random_slay (object_type * o_ptr, bool_ is_scroll)
-{
- if (artifact_bias == BIAS_CHAOS && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_CHAOTIC))
- {
- o_ptr->art_flags1 |= TR1_CHAOTIC;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_PRIESTLY &&
- (o_ptr->tval == TV_SWORD || o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_AXE) &&
- !(o_ptr->art_flags3 & TR3_BLESSED))
- {
- /* A free power for "priestly" random artifacts */
- o_ptr->art_flags3 |= TR3_BLESSED;
- }
-
- else if (artifact_bias == BIAS_NECROMANTIC && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_VAMPIRIC))
- {
- o_ptr->art_flags1 |= TR1_VAMPIRIC;
- if (randint(2) == 1) return;
- }
- if (!(o_ptr->art_flags1 & TR1_BRAND_POIS) && (randint(2) == 1))
- {
- o_ptr->art_flags1 |= TR1_BRAND_POIS;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_RANGER && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_SLAY_ANIMAL))
- {
- o_ptr->art_flags1 |= TR1_SLAY_ANIMAL;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_ROGUE && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_POIS))
- {
- o_ptr->art_flags1 |= TR1_BRAND_POIS;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_POIS && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_POIS))
- {
- o_ptr->art_flags1 |= TR1_BRAND_POIS;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_FIRE && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_FIRE))
- {
- o_ptr->art_flags1 |= TR1_BRAND_FIRE;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_COLD && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_COLD))
- {
- o_ptr->art_flags1 |= TR1_BRAND_COLD;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_ELEC && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_ELEC))
- {
- o_ptr->art_flags1 |= TR1_BRAND_ELEC;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_ACID && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_BRAND_ACID))
- {
- o_ptr->art_flags1 |= TR1_BRAND_ACID;
- if (randint(2) == 1) return;
- }
- }
-
- else if (artifact_bias == BIAS_LAW && !(o_ptr->tval == TV_BOW))
- {
- if (!(o_ptr->art_flags1 & TR1_SLAY_EVIL))
- {
- o_ptr->art_flags1 |= TR1_SLAY_EVIL;
- if (randint(2) == 1) return;
- }
- if (!(o_ptr->art_flags1 & TR1_SLAY_UNDEAD))
- {
- o_ptr->art_flags1 |= TR1_SLAY_UNDEAD;
- if (randint(2) == 1) return;
- }
- if (!(o_ptr->art_flags1 & TR1_SLAY_DEMON))
- {
- o_ptr->art_flags1 |= TR1_SLAY_DEMON;
- if (randint(2) == 1) return;
- }
- }
-
- if (!(o_ptr->tval == TV_BOW))
- {
- switch (randint(34))
- {
- case 1:
- case 2:
- o_ptr->art_flags1 |= TR1_SLAY_ANIMAL;
- /* if (is_scroll) msg_print("You start hating animals.");*/
- break;
-
- case 3:
- case 4:
- o_ptr->art_flags1 |= TR1_SLAY_EVIL;
- /* if (is_scroll) msg_print("You hate evil creatures.");*/
- if (!artifact_bias && (randint(2) == 1))
- artifact_bias = BIAS_LAW;
- else if (!artifact_bias && (randint(9) == 1))
- artifact_bias = BIAS_PRIESTLY;
- break;
-
- case 5:
- case 6:
- o_ptr->art_flags1 |= TR1_SLAY_UNDEAD;
- /* if (is_scroll) msg_print("You hate undead creatures.");*/
- if (!artifact_bias && (randint(9) == 1))
- artifact_bias = BIAS_PRIESTLY;
- break;
-
- case 7:
- case 8:
- o_ptr->art_flags1 |= TR1_SLAY_DEMON;
- /* if (is_scroll) msg_print("You hate demons.");*/
- if (!artifact_bias && (randint(9) == 1))
- artifact_bias = BIAS_PRIESTLY;
- break;
-
- case 9:
- case 10:
- o_ptr->art_flags1 |= TR1_SLAY_ORC;
- /* if (is_scroll) msg_print("You hate orcs.");*/
- break;
-
- case 11:
- case 12:
- o_ptr->art_flags1 |= TR1_SLAY_TROLL;
- /* if (is_scroll) msg_print("You hate trolls.");*/
- break;
-
- case 13:
- case 14:
- o_ptr->art_flags1 |= TR1_SLAY_GIANT;
- /* if (is_scroll) msg_print("You hate giants.");*/
- break;
-
- case 15:
- case 16:
- o_ptr->art_flags1 |= TR1_SLAY_DRAGON;
- /* if (is_scroll) msg_print("You hate dragons.");*/
- break;
-
- case 17:
- o_ptr->art_flags1 |= TR1_KILL_DRAGON;
- /* if (is_scroll) msg_print("You feel an intense hatred of dragons.");*/
- break;
-
- case 18:
- case 19:
- if (o_ptr->tval == TV_SWORD)
- {
- o_ptr->art_flags1 |= TR1_VORPAL;
- /* if (is_scroll) msg_print("It looks extremely sharp!");*/
- if (!artifact_bias && (randint(9) == 1))
- artifact_bias = BIAS_WARRIOR;
- }
- else random_slay(o_ptr, is_scroll);
- break;
-
- case 20:
- o_ptr->art_flags1 |= TR1_IMPACT;
- /* if (is_scroll) msg_print("The ground trembles beneath you.");*/
- break;
-
- case 21:
- case 22:
- o_ptr->art_flags1 |= TR1_BRAND_FIRE;
- /* if (is_scroll) msg_print("It feels hot!");*/
- if (!artifact_bias)
- artifact_bias = BIAS_FIRE;
- break;
-
- case 23:
- case 24:
- o_ptr->art_flags1 |= TR1_BRAND_COLD;
- /* if (is_scroll) msg_print("It feels cold!");*/
- if (!artifact_bias)
- artifact_bias = BIAS_COLD;
- break;
-
- case 25:
- case 26:
- o_ptr->art_flags1 |= TR1_BRAND_ELEC;
- /* if (is_scroll) msg_print("Ouch! You get zapped!");*/
- if (!artifact_bias)
- artifact_bias = BIAS_ELEC;
- break;
-
- case 27:
- case 28:
- o_ptr->art_flags1 |= TR1_BRAND_ACID;
- /* if (is_scroll) msg_print("Its smell makes you feel dizzy.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_ACID;
- break;
-
- case 29:
- case 30:
- o_ptr->art_flags1 |= TR1_BRAND_POIS;
- /* if (is_scroll) msg_print("It smells rotten.");*/
- if (!artifact_bias && (randint(3) != 1))
- artifact_bias = BIAS_POIS;
- else if (!artifact_bias && randint(6) == 1)
- artifact_bias = BIAS_NECROMANTIC;
- else if (!artifact_bias)
- artifact_bias = BIAS_ROGUE;
- break;
-
- case 31:
- case 32:
- o_ptr->art_flags1 |= TR1_VAMPIRIC;
- /* if (is_scroll) msg_print("You think it bit you!");*/
- if (!artifact_bias)
- artifact_bias = BIAS_NECROMANTIC;
- break;
-
- default:
- o_ptr->art_flags1 |= TR1_CHAOTIC;
- /* if (is_scroll) msg_print("It looks very confusing.");*/
- if (!artifact_bias)
- artifact_bias = BIAS_CHAOS;
- break;
- }
- }
- else
- {
- switch (randint(6))
- {
- case 1:
- case 2:
- case 3:
- o_ptr->art_flags3 |= TR3_XTRA_MIGHT;
- /* if (is_scroll) msg_print("It looks mightier than before."); */
- if (!artifact_bias && randint(9) == 1)
- artifact_bias = BIAS_RANGER;
- break;
-
- default:
- o_ptr->art_flags3 |= TR3_XTRA_SHOTS;
- /* if (is_scroll) msg_print("It seems faster!"); */
- if (!artifact_bias && randint(9) == 1)
- artifact_bias = BIAS_RANGER;
- break;
- }
- }
-}
-
-
-
-
-/*
- * Determines if an item is not identified
- */
-static bool_ item_tester_hook_unknown(object_type *o_ptr)
-{
- return (object_known_p(o_ptr) ? FALSE : TRUE);
-}
-
-
/*
@@ -4283,22 +3459,16 @@ static void note_found_object(object_type *o_ptr)
*/
bool_ ident_spell(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- cptr q, s;
-
/* Get an item */
- item_tester_hook = item_tester_hook_unknown;
- q = "Identify which item? ";
- s = "You have nothing to identify.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Identify which item? ",
+ "You have nothing to identify.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ object_filter::Not(object_known_p))) return (FALSE);
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Identify it fully */
object_aware(o_ptr);
@@ -4314,6 +3484,7 @@ bool_ ident_spell(void)
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -4377,9 +3548,9 @@ bool_ ident_all(void)
/*
* Determine if an object is not fully identified
*/
-static bool_ item_tester_hook_no_mental(object_type *o_ptr)
+static bool item_tester_hook_no_mental(object_type const *o_ptr)
{
- return ((o_ptr->ident & (IDENT_MENTAL)) ? FALSE : TRUE);
+ return ((o_ptr->ident & (IDENT_MENTAL)) ? false : true);
}
/*
@@ -4388,20 +3559,19 @@ static bool_ item_tester_hook_no_mental(object_type *o_ptr)
*/
bool_ identify_fully(void)
{
- int item;
- object_type *o_ptr;
- char o_name[80];
-
- cptr q, s;
-
/* Get an item */
- item_tester_hook = item_tester_hook_no_mental;
- q = "Identify which item? ";
- s = "You have nothing to identify.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Identify which item? ",
+ "You have nothing to identify.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ item_tester_hook_no_mental))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Do the identification */
make_item_fully_identified(o_ptr);
@@ -4416,6 +3586,7 @@ bool_ identify_fully(void)
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -4454,27 +3625,19 @@ bool_ identify_fully(void)
/*
* Hook for "get_item()". Determine if something is rechargable.
*/
-bool_ item_tester_hook_recharge(object_type *o_ptr)
+object_filter_t const &item_tester_hook_recharge()
{
- u32b f1, f2, f3, f4, f5, esp;
-
- /* Extract the flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Some objects cannot be recharged */
- if (f4 & TR4_NO_RECHARGE) return (FALSE);
-
- /* Recharge staffs */
- if (o_ptr->tval == TV_STAFF) return (TRUE);
-
- /* Recharge wands */
- if (o_ptr->tval == TV_WAND) return (TRUE);
-
- /* Hack -- Recharge rods */
- if (o_ptr->tval == TV_ROD_MAIN) return (TRUE);
-
- /* Nope */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ And(
+ // Must NOT have NO_RECHARGE flag.
+ Not(HasFlag4(TR4_NO_RECHARGE)),
+ // ... and must be a device.
+ Or(
+ TVal(TV_STAFF),
+ TVal(TV_WAND),
+ TVal(TV_ROD_MAIN)));
+ return instance;
}
@@ -4501,31 +3664,28 @@ bool_ item_tester_hook_recharge(object_type *o_ptr)
bool_ recharge(int power)
{
int recharge_strength, recharge_amount;
- int item, lev;
-
+ int lev;
bool_ fail = FALSE;
byte fail_type = 1;
-
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
char o_name[80];
- object_type *o_ptr;
-
- /* Only accept legal items */
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
- q = "Recharge which item? ";
- s = "You have nothing to recharge.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Recharge which item? ",
+ "You have nothing to recharge.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_recharge()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Extract the flags */
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Extract the object "level" */
@@ -4828,47 +3988,6 @@ void project_meteor(int radius, int typ, int dam, u32b flg)
/*
- * Speed monsters
- */
-bool_ speed_monsters(void)
-{
- return (project_hack(GF_OLD_SPEED, p_ptr->lev));
-}
-
-/*
- * Slow monsters
- */
-bool_ slow_monsters(void)
-{
- return (project_hack(GF_OLD_SLOW, p_ptr->lev));
-}
-
-/*
- * Paralyzation monsters
- */
-bool_ conf_monsters(void)
-{
- return (project_hack(GF_OLD_CONF, p_ptr->lev));
-}
-
-/*
- * Sleep monsters
- */
-bool_ sleep_monsters(void)
-{
- return (project_hack(GF_OLD_SLEEP, p_ptr->lev));
-}
-
-/*
- * Scare monsters
- */
-bool_ scare_monsters(void)
-{
- return (project_hack(GF_FEAR, p_ptr->lev));
-}
-
-
-/*
* Banish evil monsters
*/
bool_ banish_evil(int dist)
@@ -4877,14 +3996,6 @@ bool_ banish_evil(int dist)
}
-/*
- * Turn undead
- */
-bool_ turn_undead(void)
-{
- return (project_hack(GF_TURN_UNDEAD, p_ptr->lev));
-}
-
/*
* Dispel undead monsters
@@ -4918,22 +4029,6 @@ bool_ dispel_monsters(int dam)
return (project_hack(GF_DISP_ALL, dam));
}
-/*
- * Dispel 'living' monsters
- */
-bool_ dispel_living(int dam)
-{
- return (project_hack(GF_DISP_LIVING, dam));
-}
-
-/*
- * Dispel demons
- */
-bool_ dispel_demons(int dam)
-{
- return (project_hack(GF_DISP_DEMON, dam));
-}
-
/*
* Wake up all monsters, and speed up "los" monsters.
@@ -5022,70 +4117,6 @@ bool_ get_genocide_race(cptr msg, char *typ)
return FALSE;
}
-/*
- * Inflict dam damage of type typee to all monster of the given race
- */
-bool_ invoke(int dam, int typee)
-{
- int i;
- char typ;
- bool_ result = FALSE;
- int msec = delay_factor * delay_factor * delay_factor;
-
- if (dungeon_flags2 & DF2_NO_GENO) return (FALSE);
-
- /* Hack -- when you are fated to die, you cant cheat :) */
- if (dungeon_type == DUNGEON_DEATH)
- {
- msg_print("A mysterious force stops the genocide.");
- return FALSE;
- }
-
- /* Get a monster symbol */
- if (!get_genocide_race("Target a monster to select the race to invoke on.", &typ)) return FALSE;
-
- /* Delete the monsters of that "type" */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr = &m_list[i];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Paranoia -- Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Hack -- Skip Unique Monsters */
- if (r_ptr->flags1 & (RF1_UNIQUE)) continue;
-
- /* Hack -- Skip Quest Monsters */
- if (m_ptr->mflag & MFLAG_QUEST) continue;
-
- /* Skip "wrong" monsters */
- if (r_ptr->d_char != typ) continue;
-
- project_m(0, 0, m_ptr->fy, m_ptr->fx, dam, typee);
-
- /* Visual feedback */
- move_cursor_relative(p_ptr->py, p_ptr->px);
-
- /* Window stuff */
- p_ptr->window |= (PW_PLAYER);
-
- /* Handle */
- handle_stuff();
-
- /* Fresh */
- Term_fresh();
-
- /* Delay */
- Term_xtra(TERM_XTRA_DELAY, msec);
-
- /* Take note */
- result = TRUE;
- }
-
- return (result);
-}
-
/*
* Delete all non-unique/non-quest monsters of a given "type" from the level
@@ -5120,8 +4151,9 @@ bool_ genocide_aux(bool_ player_cast, char typ)
{
int wx, wy;
int attempts = 500;
+ char buf[256];
- monster_race_desc(r_name, m_ptr->r_idx, 0);
+ monster_race_desc(buf, m_ptr->r_idx, 0);
do
{
@@ -5131,7 +4163,7 @@ bool_ genocide_aux(bool_ player_cast, char typ)
if (place_monster_aux(wy, wx, m_ptr->r_idx, FALSE, TRUE, MSTATUS_ENEMY))
{
- cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", r_name);
+ cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", buf);
}
return TRUE;
@@ -5153,7 +4185,7 @@ bool_ genocide_aux(bool_ player_cast, char typ)
Term_fresh();
/* Delay */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
/* Take note */
result = TRUE;
@@ -5168,7 +4200,7 @@ bool_ genocide_aux(bool_ player_cast, char typ)
move_cursor_relative(p_ptr->py, p_ptr->px);
/* Redraw */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -5245,8 +4277,9 @@ bool_ mass_genocide(bool_ player_cast)
{
int wx, wy;
int attempts = 500;
+ char buf[256];
- monster_race_desc(r_name, m_ptr->r_idx, 0);
+ monster_race_desc(buf, m_ptr->r_idx, 0);
do
{
@@ -5256,7 +4289,7 @@ bool_ mass_genocide(bool_ player_cast)
if (place_monster_aux(wy, wx, m_ptr->r_idx, FALSE, TRUE, MSTATUS_ENEMY))
{
- cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", r_name);
+ cmsg_format(TERM_L_BLUE, "The spell seems to produce an ... interesting effect on the %s.", buf);
}
return TRUE;
@@ -5278,7 +4311,7 @@ bool_ mass_genocide(bool_ player_cast)
Term_fresh();
/* Delay */
- Term_xtra(TERM_XTRA_DELAY, msec);
+ sleep_for(milliseconds(msec));
/* Note effect */
result = TRUE;
@@ -5293,7 +4326,7 @@ bool_ mass_genocide(bool_ player_cast)
move_cursor_relative(p_ptr->py, p_ptr->px);
/* Redraw */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -5339,7 +4372,12 @@ void do_probe(int m_idx)
sprintf(t_name, "nothing");
msg_format("%^s target is %s.", m_name, t_name);
- msg_format("%^s has %ld exp and needs %ld.", m_name, m_ptr->exp, MONSTER_EXP(m_ptr->level + 1));
+ {
+ std::ostringstream buf;
+ buf << " has " << m_ptr->exp
+ << " exp and needs " << monster_exp(m_ptr->level + 1) << ".";
+ msg_format("%^s%s", m_name, buf.str().c_str());
+ }
}
/* Learn all of the non-spell, non-treasure flags */
@@ -5393,89 +4431,6 @@ bool_ probing(void)
/*
- * Wipe -- Empties a part of the dungeon
- */
-void wipe(int y1, int x1, int r)
-{
- int y, x, k;
-
- cave_type *c_ptr;
-
- bool_ flag = FALSE;
-
- if (dungeon_flags2 & DF2_NO_GENO)
- {
- msg_print("Not on special levels!");
- return;
- }
- if (p_ptr->inside_quest)
- {
- return;
- }
-
- /* Big area of affect */
- for (y = (y1 - r); y <= (y1 + r); y++)
- {
- for (x = (x1 - r); x <= (x1 + r); x++)
- {
- /* Skip illegal grids */
- if (!in_bounds(y, x)) continue;
-
- /* Extract the distance */
- k = distance(y1, x1, y, x);
-
- /* Stay in the circle of death */
- if (k > r) continue;
-
- /* Access the grid */
- c_ptr = &cave[y][x];
-
- /* Lose room and vault */
- c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
-
- /* Lose light and knowledge */
- c_ptr->info &= ~(CAVE_MARK | CAVE_GLOW);
-
- if (m_list[c_ptr->m_idx].status != MSTATUS_COMPANION) delete_monster(y, x);
- delete_object(y, x);
- place_floor_convert_glass(y, x);
- }
- }
-
-
- /* Hack -- Affect player */
- if (flag)
- {
- /* Message */
- msg_print("There is a searing blast of light!");
-
- /* Blind the player */
- if (!p_ptr->resist_blind && !p_ptr->resist_lite)
- {
- /* Become blind */
- (void)set_blind(p_ptr->blind + 10 + randint(10));
- }
- }
-
-
- /* Mega-Hack -- Forget the view */
- p_ptr->update |= (PU_UN_VIEW);
-
- /* Update stuff */
- p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE);
-
- /* Update the monsters */
- p_ptr->update |= (PU_MONSTERS);
-
- /* Redraw map */
- p_ptr->redraw |= (PR_MAP);
-
- /* Window stuff */
- p_ptr->window |= (PW_OVERHEAD);
-}
-
-
-/*
* The spell of destruction
*
* This spell "deletes" monsters (instead of "killing" them).
@@ -5483,7 +4438,7 @@ void wipe(int y1, int x1, int r)
* Later we may use one function for both "destruction" and
* "earthquake" by using the "full" to select "destruction".
*/
-void destroy_area(int y1, int x1, int r, bool_ full, bool_ bypass)
+void destroy_area(int y1, int x1, int r)
{
int y, x, k, t;
@@ -5492,15 +4447,12 @@ void destroy_area(int y1, int x1, int r, bool_ full, bool_ bypass)
bool_ flag = FALSE;
- /* XXX XXX */
- full = full ? full : 0;
-
if (dungeon_flags2 & DF2_NO_GENO)
{
msg_print("Not on special levels!");
return;
}
- if (p_ptr->inside_quest && (!bypass))
+ if (p_ptr->inside_quest)
{
return;
}
@@ -5807,7 +4759,7 @@ void earthquake(int cy, int cx, int r)
map[16 + p_ptr->py - cy][16 + p_ptr->px - cx] = FALSE;
/* Semi-wraiths have to be hurt *some*, says DG */
- if (PRACE_FLAG(PR1_SEMI_WRAITH))
+ if (race_flags1_p(PR1_SEMI_WRAITH))
damage /= 4;
/* Take some damage */
@@ -6011,7 +4963,7 @@ void earthquake(int cy, int cx, int r)
p_ptr->update |= (PU_DISTANCE);
/* Update the health bar */
- p_ptr->redraw |= (PR_HEALTH);
+ p_ptr->redraw |= (PR_FRAME);
/* Redraw map */
p_ptr->redraw |= (PR_MAP);
@@ -6416,62 +5368,6 @@ bool_ fire_wall(int typ, int dir, int dam, int time)
return (project_hook(typ, dir, dam, flg));
}
-/*
- * Cast a druidistic ball spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-bool_ fire_druid_ball(int typ, int dir, int dam, int rad)
-{
- int tx, ty;
-
- int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_MANA_PATH;
-
- /* Use the given direction */
- tx = p_ptr->px + 99 * ddx[dir];
- ty = p_ptr->py + 99 * ddy[dir];
-
- /* Hack -- Use an actual "target" */
- if ((dir == 5) && target_okay())
- {
- flg &= ~(PROJECT_STOP);
- tx = target_col;
- ty = target_row;
- }
-
- /* Analyze the "dir" and the "target". Hurt items on floor. */
- return (project(0, (rad > 16) ? 16 : rad, ty, tx, dam, typ, flg));
-}
-
-
-/*
- * Cast a ball-beamed spell
- * Stop if we hit a monster, act as a "ball"
- * Allow "target" mode to pass over monsters
- * Affect grids, objects, and monsters
- */
-bool_ fire_ball_beam(int typ, int dir, int dam, int rad)
-{
- int tx, ty;
-
- int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_BEAM;
-
- /* Use the given direction */
- tx = p_ptr->px + 99 * ddx[dir];
- ty = p_ptr->py + 99 * ddy[dir];
-
- /* Hack -- Use an actual "target" */
- if ((dir == 5) && target_okay())
- {
- flg &= ~(PROJECT_STOP);
- tx = target_col;
- ty = target_row;
- }
-
- /* Analyze the "dir" and the "target". Hurt items on floor. */
- return (project(0, (rad > 16) ? 16 : rad, ty, tx, dam, typ, flg));
-}
void teleport_swap(int dir)
@@ -6570,7 +5466,7 @@ void teleport_swap(int dir)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -6623,7 +5519,7 @@ void swap_position(int lty, int ltx)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -6672,7 +5568,7 @@ void swap_position(int lty, int ltx)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -6720,28 +5616,6 @@ bool_ fire_bolt(int typ, int dir, int dam)
return (project_hook(typ, dir, dam, flg));
}
-/*
- * Cast a druidistic bolt spell
- * Stop if we hit a monster, as a "bolt"
- * Affect monsters (not grids or objects)
- */
-bool_ fire_druid_bolt(int typ, int dir, int dam)
-{
- int flg = PROJECT_STOP | PROJECT_KILL | PROJECT_MANA_PATH;
- return (project_hook(typ, dir, dam, flg));
-}
-
-
-/*
- * Cast a druidistic beam spell
- * Pass through monsters, as a "beam"
- * Affect monsters (not grids or objects)
- */
-bool_ fire_druid_beam(int typ, int dir, int dam)
-{
- int flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_MANA_PATH;
- return (project_hook(typ, dir, dam, flg));
-}
/*
* Cast a beam spell
@@ -6770,19 +5644,6 @@ bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam)
}
}
-bool_ fire_godly_wrath(int y, int x, int typ, int rad, int dam)
-{
- int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
-
- return (project(0, rad, y, x, dam, typ, flg));
-}
-
-bool_ fire_explosion(int y, int x, int typ, int rad, int dam)
-{
- int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
-
- return (project(0, rad, y, x, dam, typ, flg));
-}
/*
* Some of the old functions
@@ -6815,13 +5676,6 @@ bool_ wizard_lock(int dir)
}
-bool_ destroy_door(int dir)
-{
- int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
- return (project_hook(GF_KILL_DOOR, dir, 0, flg));
-}
-
-
bool_ disarm_trap(int dir)
{
int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
@@ -6829,20 +5683,6 @@ bool_ disarm_trap(int dir)
}
-bool_ heal_monster(int dir)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_HEAL, dir, damroll(4, 6), flg));
-}
-
-
-bool_ speed_monster(int dir)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_SPEED, dir, p_ptr->lev, flg));
-}
-
-
bool_ slow_monster(int dir)
{
int flg = PROJECT_STOP | PROJECT_KILL;
@@ -6857,13 +5697,6 @@ bool_ sleep_monster(int dir)
}
-bool_ stasis_monster(int dir)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_STASIS, dir, p_ptr->lev, flg));
-}
-
-
bool_ confuse_monster(int dir, int plev)
{
int flg = PROJECT_STOP | PROJECT_KILL;
@@ -6871,13 +5704,6 @@ bool_ confuse_monster(int dir, int plev)
}
-bool_ stun_monster(int dir, int plev)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_STUN, dir, plev, flg));
-}
-
-
bool_ poly_monster(int dir)
{
int flg = PROJECT_STOP | PROJECT_KILL;
@@ -6885,13 +5711,6 @@ bool_ poly_monster(int dir)
}
-bool_ clone_monster(int dir)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_OLD_CLONE, dir, 0, flg));
-}
-
-
bool_ fear_monster(int dir, int plev)
{
int flg = PROJECT_STOP | PROJECT_KILL;
@@ -6899,13 +5718,6 @@ bool_ fear_monster(int dir, int plev)
}
-bool_ death_ray(int dir, int plev)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_DEATH_RAY, dir, plev, flg));
-}
-
-
bool_ teleport_monster(int dir)
{
int flg = PROJECT_BEAM | PROJECT_KILL;
@@ -6920,16 +5732,6 @@ bool_ teleport_monster(int dir)
}
-/*
- * Hooks -- affect adjacent grids (radius 1 ball attack)
- */
-bool_ door_creation(void)
-{
- int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
- return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_MAKE_DOOR, flg));
-}
-
-
bool_ trap_creation(void)
{
int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
@@ -6937,13 +5739,6 @@ bool_ trap_creation(void)
}
-bool_ glyph_creation(void)
-{
- int flg = PROJECT_GRID | PROJECT_ITEM;
- return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_MAKE_GLYPH, flg));
-}
-
-
bool_ wall_stone(int y, int x)
{
cave_type *c_ptr = &cave[y][x];
@@ -7039,6 +5834,72 @@ void call_chaos(void)
}
+static void activate_hi_summon(void)
+{
+ int i;
+
+ for (i = 0; i < (randint(9) + (dun_level / 40)); i++)
+ {
+ switch (randint(26) + (dun_level / 20) )
+ {
+ case 1:
+ case 2:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT);
+ break;
+ case 3:
+ case 4:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER);
+ break;
+ case 5:
+ case 6:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND);
+ break;
+ case 7:
+ case 8:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA);
+ break;
+ case 9:
+ case 10:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL);
+ break;
+ case 11:
+ case 12:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD);
+ break;
+ case 13:
+ case 14:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON);
+ break;
+ case 15:
+ case 16:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON);
+ break;
+ case 17:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH);
+ break;
+ case 18:
+ case 19:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE);
+ break;
+ case 20:
+ case 21:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD);
+ break;
+ case 22:
+ case 23:
+ (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON);
+ break;
+ case 24:
+ case 25:
+ (void) summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON);
+ break;
+ default:
+ (void) summon_specific(p_ptr->py, p_ptr->px, (((dun_level * 3) / 2) + 5), 0);
+ }
+ }
+}
+
+
/*
* Activate the evil Topi Ylinen curse
* rr9: Stop the nasty things when a Cyberdemon is summoned
@@ -7233,72 +6094,6 @@ case 27: case 28: case 29:
}
-void activate_hi_summon(void)
-{
- int i;
-
- for (i = 0; i < (randint(9) + (dun_level / 40)); i++)
- {
- switch (randint(26) + (dun_level / 20) )
- {
- case 1:
- case 2:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT);
- break;
- case 3:
- case 4:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER);
- break;
- case 5:
- case 6:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND);
- break;
- case 7:
- case 8:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA);
- break;
- case 9:
- case 10:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL);
- break;
- case 11:
- case 12:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD);
- break;
- case 13:
- case 14:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON);
- break;
- case 15:
- case 16:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON);
- break;
- case 17:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH);
- break;
- case 18:
- case 19:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE);
- break;
- case 20:
- case 21:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD);
- break;
- case 22:
- case 23:
- (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON);
- break;
- case 24:
- case 25:
- (void) summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON);
- break;
- default:
- (void) summon_specific(p_ptr->py, p_ptr->px, (((dun_level * 3) / 2) + 5), 0);
- }
- }
-}
-
-
void summon_cyber(void)
{
int i;
@@ -7310,7 +6105,7 @@ void summon_cyber(void)
}
}
-void summon_dragon_riders()
+static void summon_dragon_riders()
{
int i;
int max_dr = (dun_level / 50) + randint(6);
@@ -7322,230 +6117,6 @@ void summon_dragon_riders()
}
-void wall_breaker(void)
-{
- int dummy = 5;
-
- if (randint(80 + p_ptr->lev) < 70)
- {
- do
- {
- dummy = randint(9);
- }
- while ((dummy == 5) || (dummy == 0));
-
- wall_to_mud (dummy);
- }
- else if (randint(100) > 30)
- {
- /* Prevent destruction of quest levels and town */
- if (!is_quest(dun_level) && dun_level)
- earthquake(p_ptr->py, p_ptr->px, 1);
- }
- else
- {
- for (dummy = 1; dummy < 10; dummy++)
- {
- if (dummy - 5) wall_to_mud(dummy);
- }
- }
-}
-
-
-void bless_weapon(void)
-{
- int item;
- object_type *o_ptr;
- u32b f1, f2, f3, f4, f5, esp;
- char o_name[80];
- cptr q, s;
-
- /* Assume enchant weapon */
- item_tester_hook = item_tester_hook_weapon;
-
- /* Get an item */
- q = "Bless which weapon? ";
- s = "You have weapon to bless.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
-
- /* Get the item */
- o_ptr = get_object(item);
-
- /* Description */
- object_desc(o_name, o_ptr, FALSE, 0);
-
- /* Extract the flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if (o_ptr->ident & (IDENT_CURSED))
- {
-
- if (((f3 & (TR3_HEAVY_CURSE)) && (randint (100) < 33)) ||
- (f3 & (TR3_PERMA_CURSE)))
- {
-
- msg_format("The black aura on %s %s disrupts the blessing!",
- ((item >= 0) ? "your" : "the"), o_name);
- return;
- }
-
- msg_format("A malignant aura leaves %s %s.",
- ((item >= 0) ? "your" : "the"), o_name);
-
- /* Uncurse it */
- o_ptr->ident &= ~(IDENT_CURSED);
-
- /* Hack -- Assume felt */
- o_ptr->ident |= (IDENT_SENSE);
-
- /* Take note */
- o_ptr->sense = SENSE_UNCURSED;
-
- /* Recalculate the bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Window stuff */
- p_ptr->window |= (PW_EQUIP);
- }
-
- /*
- * Next, we try to bless it. Artifacts have a 1/3 chance of
- * being blessed, otherwise, the operation simply disenchants
- * them, godly power negating the magic. Ok, the explanation
- * is silly, but otherwise priests would always bless every
- * artifact weapon they find. Ego weapons and normal weapons
- * can be blessed automatically.
- */
- if (f3 & TR3_BLESSED)
- {
- msg_format("%s %s %s blessed already.",
- ((item >= 0) ? "Your" : "The"), o_name,
- ((o_ptr->number > 1) ? "were" : "was"));
- return;
- }
-
- if (!(o_ptr->art_name || o_ptr->name1) || (randint(3) == 1))
- {
- /* Describe */
- msg_format("%s %s shine%s!",
- ((item >= 0) ? "Your" : "The"), o_name,
- ((o_ptr->number > 1) ? "" : "s"));
- o_ptr->art_flags3 |= TR3_BLESSED;
- }
- else
- {
- bool_ dis_happened = FALSE;
-
- msg_print("The artifact resists your blessing!");
-
- /* Disenchant tohit */
- if (o_ptr->to_h > 0)
- {
- o_ptr->to_h--;
- dis_happened = TRUE;
- }
-
- if ((o_ptr->to_h > 5) && (rand_int(100) < 33)) o_ptr->to_h--;
-
- /* Disenchant todam */
- if (o_ptr->to_d > 0)
- {
- o_ptr->to_d--;
- dis_happened = TRUE;
- }
-
- if ((o_ptr->to_d > 5) && (rand_int(100) < 33)) o_ptr->to_d--;
-
- /* Disenchant toac */
- if (o_ptr->to_a > 0)
- {
- o_ptr->to_a--;
- dis_happened = TRUE;
- }
-
- if ((o_ptr->to_a > 5) && (rand_int(100) < 33)) o_ptr->to_a--;
-
- if (dis_happened)
- {
- msg_print("There is a static feeling in the air...");
- msg_format("%s %s %s disenchanted!",
- ((item >= 0) ? "Your" : "The"), o_name,
- ((o_ptr->number > 1) ? "were" : "was"));
- }
- }
-
- /* Recalculate bonuses */
- p_ptr->update |= (PU_BONUS);
-
- /* Window stuff */
- p_ptr->window |= (PW_EQUIP | PW_PLAYER);
-}
-
-
-/*
- * Detect all "nonliving", "undead" or "demonic" monsters on current panel
- */
-bool_ detect_monsters_nonliving(int rad)
-{
- int i, y, x;
- bool_ flag = FALSE;
-
- /* Scan monsters */
- for (i = 1; i < m_max; i++)
- {
- monster_type *m_ptr = &m_list[i];
- monster_race *r_ptr = race_inf(m_ptr);
-
- /* Skip dead monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Location */
- y = m_ptr->fy;
- x = m_ptr->fx;
-
- /* Only detect nearby monsters */
- if (m_ptr->cdis > rad) continue;
-
- /* Detect evil monsters */
- if ((r_ptr->flags3 & (RF3_NONLIVING)) ||
- (r_ptr->flags3 & (RF3_UNDEAD)) ||
- (r_ptr->flags3 & (RF3_DEMON)))
- {
- /* Update monster recall window */
- if (monster_race_idx == m_ptr->r_idx)
- {
- /* Window stuff */
- p_ptr->window |= (PW_MONSTER);
- }
-
- /* Repair visibility later */
- repair_monsters = TRUE;
-
- /* Hack -- Detect monster */
- m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
-
- /* Hack -- See monster */
- m_ptr->ml = TRUE;
-
- /* Redraw */
- if (panel_contains(y, x)) lite_spot(y, x);
-
- /* Detect */
- flag = TRUE;
- }
- }
-
- /* Describe */
- if (flag)
- {
- /* Describe result */
- msg_print("You sense the presence of unnatural beings!");
- }
-
- /* Result */
- return (flag);
-}
-
/*
* Confuse monsters
@@ -7573,14 +6144,6 @@ bool_ charm_animals(int dam)
return (project_hack(GF_CONTROL_ANIMAL, dam));
}
-/*
- * Charm demons
- */
-bool_ charm_demons(int dam)
-{
- return (project_hack(GF_CONTROL_DEMON, dam));
-}
-
/*
* Stun monsters
@@ -7592,15 +6155,6 @@ bool_ stun_monsters(int dam)
/*
- * Stasis monsters
- */
-bool_ stasis_monsters(int dam)
-{
- return (project_hack(GF_STASIS, dam));
-}
-
-
-/*
* Mindblast monsters
*/
bool_ mindblast_monsters(int dam)
@@ -7619,15 +6173,6 @@ bool_ banish_monsters(int dist)
/*
- * Turn evil
- */
-bool_ turn_evil(int dam)
-{
- return (project_hack(GF_TURN_EVIL, dam));
-}
-
-
-/*
* Turn everyone
*/
bool_ turn_monsters(int dam)
@@ -7636,28 +6181,12 @@ bool_ turn_monsters(int dam)
}
-/*
- * Death-ray all monsters (note: OBSCENELY powerful)
- */
-bool_ deathray_monsters(void)
-{
- return (project_hack(GF_DEATH_RAY, p_ptr->lev));
-}
-
-
bool_ charm_monster(int dir, int plev)
{
int flg = PROJECT_STOP | PROJECT_KILL;
return (project_hook(GF_CHARM, dir, plev, flg));
}
-bool_ star_charm_monster(int dir, int plev)
-{
- int flg = PROJECT_STOP | PROJECT_KILL;
- return (project_hook(GF_STAR_CHARM, dir, plev, flg));
-}
-
-
bool_ control_one_undead(int dir, int plev)
{
int flg = PROJECT_STOP | PROJECT_KILL;
@@ -7716,7 +6245,7 @@ bool_ heal_insanity(int val)
p_ptr->csane_frac = 0;
}
- p_ptr->redraw |= PR_SANITY;
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_PLAYER);
if (val < 5)
@@ -7826,7 +6355,7 @@ bool_ passwall(int dir, bool_ safe)
p_ptr->update |= (PU_DISTANCE);
/* Redraw trap detection status */
- p_ptr->redraw |= (PR_DTRAP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -7840,20 +6369,21 @@ bool_ passwall(int dir, bool_ safe)
/*
* Print a batch of dungeons.
*/
-static void print_dungeon_batch(int *p, int start, int max, bool_ mode)
+static void print_dungeon_batch(std::vector<int> const &dungeon_idxs,
+ int start,
+ bool_ mode)
{
char buf[80];
int i, j;
byte attr;
-
if (mode) prt(format(" %-31s", "Name"), 1, 20);
- for (i = 0, j = start; i < 20 && j < max; i++, j++)
+ for (i = 0, j = start; i < 20 && j < static_cast<int>(dungeon_idxs.size()); i++, j++)
{
- dungeon_info_type *d_ptr = &d_info[p[j]];
+ dungeon_info_type *d_ptr = &d_info[dungeon_idxs[j]];
- strnfmt(buf, 80, " %c) %-30s", I2A(i), d_name + d_ptr->name);
+ strnfmt(buf, 80, " %c) %-30s", I2A(i), d_ptr->name);
if (mode)
{
if (d_ptr->min_plev > p_ptr->lev)
@@ -7872,26 +6402,41 @@ static void print_dungeon_batch(int *p, int start, int max, bool_ mode)
prt(format("Select a dungeon (a-%c), * to list, @ to select by name, +/- to scroll:", I2A(i - 1)), 0, 0);
}
-int reset_recall_aux()
+static int find_dungeon_by_name(char const *name)
+{
+ /* Find the index corresponding to the name */
+ for (int i = 1; i < max_d_idx; i++)
+ {
+ /* Skip non-initialized entries. */
+ if (d_info[i].name == nullptr) {
+ continue;
+ }
+ if (iequals(name, d_info[i].name))
+ {
+ return i;
+ }
+ }
+ /* Not found */
+ return -1;
+}
+
+static int reset_recall_aux()
{
char which;
- int *p;
- int max = 0, i, start = 0;
+ int start = 0;
int ret;
bool_ mode = FALSE;
-
- C_MAKE(p, max_d_idx, int);
-
- /* Count the max */
- for (i = 1; i < max_d_idx; i++)
+ // Dungeons available for recall
+ std::vector<int> dungeons;
+ for (size_t i = 1; i < max_d_idx; i++)
{
/* skip "blocked" dungeons */
if (d_info[i].flags1 & DF1_NO_RECALL) continue;
if (max_dlv[i])
{
- p[max++] = i;
+ dungeons.push_back(i);
}
}
@@ -7900,7 +6445,7 @@ int reset_recall_aux()
while (1)
{
- print_dungeon_batch(p, start, max, mode);
+ print_dungeon_batch(dungeons, start, mode);
which = inkey();
if (which == ESCAPE)
@@ -7919,7 +6464,11 @@ int reset_recall_aux()
else if (which == '+')
{
start += 20;
- if (start >= max) start -= 20;
+ assert(start > 0);
+ if (static_cast<size_t>(start) >= dungeons.size())
+ {
+ start -= 20;
+ }
Term_load();
character_icky = FALSE;
}
@@ -7927,34 +6476,24 @@ int reset_recall_aux()
else if (which == '-')
{
start -= 20;
- if (start < 0) start += 20;
+ if (start < 0)
+ {
+ start += 20;
+ }
Term_load();
character_icky = FALSE;
}
else if (which == '@')
{
- char buf[80], buf2[80];
-
- strcpy(buf, (d_info[p_ptr->recall_dungeon].name + d_name));
+ char buf[80];
+ strcpy(buf, d_info[p_ptr->recall_dungeon].name);
if (!get_string("Which dungeon? ", buf, 79)) continue;
/* Find the index corresponding to the name */
- for (i = 1; i < max_d_idx; i++)
- {
- sprintf(buf2, "%s", d_info[i].name + d_name);
-
- /* Lowercase the name */
- strlower(buf);
- strlower(buf2);
- if (strstr(buf2, buf))
- {
- /* valid dungeon found */
- break;
- }
- }
+ int i = find_dungeon_by_name(buf);
- if (i >= max_d_idx)
+ if (i < 0)
{
msg_print("Never heard of that place!");
msg_print(NULL);
@@ -7979,26 +6518,29 @@ int reset_recall_aux()
else
{
which = tolower(which);
- if (start + A2I(which) >= max)
+ int i = start + A2I(which);
+
+ if (i < 0)
{
bell();
continue;
}
- if (start + A2I(which) < 0)
+ else if (static_cast<size_t>(i) >= dungeons.size()) // Cast to avoid compilation warning
{
bell();
continue;
}
- ret = p[start + A2I(which)];
- break;
+ else
+ {
+ ret = dungeons[i];
+ break;
+ }
}
}
Term_load();
character_icky = FALSE;
- C_FREE(p, max_d_idx, int);
-
return ret;
}
@@ -8017,7 +6559,7 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
else
max = max_dlv[dun];
depth = get_quantity(format("Which level in %s(%d-%d)? ",
- d_info[dun].name + d_name,
+ d_info[dun].name,
d_info[dun].mindepth, max),
max);
@@ -8035,26 +6577,6 @@ bool_ reset_recall(bool_ no_trepas_max_depth)
return TRUE;
}
-/* The only way to get rid of the dreaded DG_CURSE*/
-void remove_dg_curse()
-{
- int k;
-
- /* Parse all the items */
- for (k = INVEN_WIELD; k < INVEN_TOTAL; k++)
- {
- object_type *o_ptr = &p_ptr->inventory[k];
-
- if (o_ptr->k_idx && (o_ptr->art_flags4 & TR4_DG_CURSE))
- {
- o_ptr->art_flags3 &= ~TR3_HEAVY_CURSE;
- o_ptr->art_flags3 &= ~TR3_CURSED;
- o_ptr->art_flags4 &= ~TR4_DG_CURSE;
- msg_print("The Morgothian Curse withers away.");
- }
- }
-}
-
/*
* Creates a between gate
*/
@@ -8304,6 +6826,19 @@ void geomancy_dig(int oy, int ox, int dir, int length)
void channel_the_elements(int y, int x, int level)
{
+ // Type of water to use (if any)
+ auto water_type = []() -> int {
+ return (get_skill(SKILL_WATER) >= 18) ? GF_WAVE : GF_WATER;
+ };
+ // Do we use hellfire?
+ auto use_hellfire = []() -> bool {
+ return get_skill(SKILL_FIRE) >= 15;
+ };
+ // Type of fire to use (if any)
+ auto fire_type = [&use_hellfire]() -> int {
+ return use_hellfire() ? GF_HELL_FIRE : GF_FIRE;
+ };
+
switch (cave[y][x].feat)
{
case FEAT_GRASS:
@@ -8328,18 +6863,16 @@ void channel_the_elements(int y, int x, int level)
case FEAT_SHAL_WATER:
{
- int dir, type;
+ int dir;
if (!get_aim_dir(&dir)) break;
- type = (get_skill(SKILL_WATER) >= 18) ? GF_WAVE : GF_WATER;
-
if (get_skill(SKILL_WATER) >= 8)
{
- fire_beam(type, dir, damroll(3, get_skill(SKILL_WATER)));
+ fire_beam(water_type(), dir, damroll(3, get_skill(SKILL_WATER)));
}
else
{
- fire_bolt(type, dir, damroll(3, get_skill(SKILL_WATER)));
+ fire_bolt(water_type(), dir, damroll(3, get_skill(SKILL_WATER)));
}
break;
@@ -8347,18 +6880,16 @@ void channel_the_elements(int y, int x, int level)
case FEAT_DEEP_WATER:
{
- int dir, type;
+ int dir;
if (!get_aim_dir(&dir)) break;
- type = (get_skill(SKILL_WATER) >= 18) ? GF_WAVE : GF_WATER;
-
if (get_skill(SKILL_WATER) >= 8)
{
- fire_beam(type, dir, damroll(5, get_skill(SKILL_WATER)));
+ fire_beam(water_type(), dir, damroll(5, get_skill(SKILL_WATER)));
}
else
{
- fire_bolt(type, dir, damroll(5, get_skill(SKILL_WATER)));
+ fire_bolt(water_type(), dir, damroll(5, get_skill(SKILL_WATER)));
}
break;
@@ -8384,8 +6915,8 @@ void channel_the_elements(int y, int x, int level)
case FEAT_SAND:
{
int type, dur;
-
- type = (get_level(FIERYAURA, 50, 1) >= 8) ? SHIELD_GREAT_FIRE : SHIELD_FIRE;
+
+ type = use_hellfire() ? SHIELD_GREAT_FIRE : SHIELD_FIRE;
dur = randint(20) + level + get_skill(SKILL_AIR);
set_shield(dur, 0, type, 5 + get_skill_scale(SKILL_FIRE, 20), 5 + get_skill_scale(SKILL_FIRE, 14));
@@ -8399,15 +6930,7 @@ void channel_the_elements(int y, int x, int level)
int dir;
if (!get_aim_dir(&dir)) break;
- if (get_skill(SKILL_FIRE) >= 15)
- {
- fire_bolt(GF_HELL_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15));
- }
- else
- {
- fire_bolt(GF_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15));
- }
-
+ fire_bolt(fire_type(), dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15));
break;
}
@@ -8416,15 +6939,7 @@ void channel_the_elements(int y, int x, int level)
int dir;
if (!get_aim_dir(&dir)) break;
- if (get_skill(SKILL_FIRE) >= 15)
- {
- fire_ball(GF_HELL_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15), 3);
- }
- else
- {
- fire_ball(GF_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15), 3);
- }
-
+ fire_ball(fire_type(), dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15), 3);
break;
}
diff --git a/src/spells2.hpp b/src/spells2.hpp
new file mode 100644
index 00000000..1806e6b0
--- /dev/null
+++ b/src/spells2.hpp
@@ -0,0 +1,115 @@
+#pragma once
+
+#include "h-basic.h"
+#include "identify_mode.hpp"
+#include "object_filter.hpp"
+#include "object_type_fwd.hpp"
+
+extern void curse_artifact(object_type * o_ptr);
+extern void grow_things(s16b type, int rad);
+extern void grow_grass(int rad);
+extern void grow_trees(int rad);
+extern bool_ hp_player(int num);
+extern bool_ heal_insanity(int val);
+extern void warding_glyph(void);
+extern void explosive_rune(void);
+extern bool_ do_dec_stat(int stat, int mode);
+extern bool_ do_res_stat(int stat, bool_ full);
+extern bool_ do_inc_stat(int stat);
+extern void identify_hooks(int i, object_type *o_ptr, identify_mode type);
+extern bool_ identify_pack(void);
+extern void identify_pack_fully(void);
+extern bool_ remove_curse(void);
+extern bool_ remove_all_curse(void);
+extern bool_ restore_level(void);
+extern void self_knowledge(FILE *fff);
+extern bool_ lose_all_info(void);
+extern bool_ detect_traps(int rad);
+extern bool_ detect_doors(int rad);
+extern bool_ detect_stairs(int rad);
+extern bool_ detect_treasure(int rad);
+extern bool_ detect_objects_gold(int rad);
+extern bool_ detect_objects_normal(int rad);
+extern bool_ detect_monsters_normal(int rad);
+extern bool_ detect_monsters_invis(int rad);
+extern bool_ detect_monsters_xxx(u32b match_flag, int rad);
+extern bool_ detect_all(int rad);
+extern void stair_creation(void);
+extern bool_ wall_stone(int y, int x);
+extern bool_ enchant(object_type *o_ptr, int n, int eflag);
+extern bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval);
+extern bool_ ident_spell(void);
+extern bool_ ident_all(void);
+extern bool_ identify_fully(void);
+extern bool_ recharge(int num);
+extern void aggravate_monsters(int who);
+extern bool_ genocide_aux(bool_ player_cast, char typ);
+extern bool_ genocide(bool_ player_cast);
+extern bool_ mass_genocide(bool_ player_cast);
+extern void do_probe(int m_idx);
+extern bool_ probing(void);
+extern void change_wild_mode(void);
+extern bool_ banish_evil(int dist);
+extern bool_ dispel_evil(int dam);
+extern bool_ dispel_good(int dam);
+extern bool_ dispel_undead(int dam);
+extern bool_ dispel_monsters(int dam);
+extern void destroy_area(int y1, int x1, int r);
+extern void earthquake(int cy, int cx, int r);
+extern void lite_room(int y1, int x1);
+extern void unlite_room(int y1, int x1);
+extern bool_ lite_area(int dam, int rad);
+extern bool_ unlite_area(int dam, int rad);
+extern bool_ fire_cloud(int typ, int dir, int dam, int rad, int time);
+extern bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff);
+extern bool_ fire_wall(int typ, int dir, int dam, int time);
+extern bool_ fire_ball(int typ, int dir, int dam, int rad);
+extern bool_ fire_bolt(int typ, int dir, int dam);
+extern bool_ fire_beam(int typ, int dir, int dam);
+extern void call_chaos(void);
+extern bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam);
+extern bool_ lite_line(int dir);
+extern bool_ drain_life(int dir, int dam);
+extern bool_ wall_to_mud(int dir);
+extern bool_ disarm_trap(int dir);
+extern bool_ wizard_lock(int dir);
+extern bool_ slow_monster(int dir);
+extern bool_ sleep_monster(int dir);
+extern bool_ confuse_monster(int dir, int plev);
+extern bool_ fear_monster(int dir, int plev);
+extern bool_ poly_monster(int dir);
+extern bool_ teleport_monster(int dir);
+extern bool_ trap_creation(void);
+extern bool_ destroy_doors_touch(void);
+extern bool_ destroy_traps_touch(void);
+extern bool_ sleep_monsters_touch(void);
+extern bool_ alchemy(void);
+extern void activate_ty_curse(void);
+extern void activate_dg_curse(void);
+extern void summon_cyber(void);
+extern bool_ confuse_monsters(int dam);
+extern bool_ charm_monsters(int dam);
+extern bool_ charm_animals(int dam);
+extern bool_ stun_monsters(int dam);
+extern bool_ banish_monsters(int dist);
+extern bool_ turn_monsters(int dam);
+extern bool_ charm_monster(int dir, int plev);
+extern bool_ control_one_undead(int dir, int plev);
+extern bool_ charm_animal(int dir, int plev);
+extern bool_ mindblast_monsters(int dam);
+extern void alter_reality(void);
+extern void report_magics(void);
+extern void teleport_swap(int dir);
+extern void swap_position(int lty, int ltx);
+extern object_filter_t const &item_tester_hook_recharge();
+extern bool_ project_hack(int typ, int dam);
+extern void project_meteor(int radius, int typ, int dam, u32b flg);
+extern object_filter_t const &item_tester_hook_artifactable();
+extern bool_ passwall(int dir, bool_ safe);
+extern bool_ project_hook(int typ, int dir, int dam, int flg);
+extern bool_ reset_recall(bool_ no_trepas_max_depth);
+extern void geomancy_random_wall(int y, int x);
+extern void geomancy_random_floor(int y, int x, bool_ kill_wall);
+extern void geomancy_dig(int oy, int ox, int dir, int length);
+extern void channel_the_elements(int y, int x, int level);
+extern void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific);
diff --git a/src/spells3.c b/src/spells3.cc
index 269e861a..e209feb1 100644
--- a/src/spells3.c
+++ b/src/spells3.cc
@@ -1,8 +1,36 @@
-#include "angband.h"
-
-#include <assert.h>
-
-#include "spell_type.h"
+#include "spells3.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd5.hpp"
+#include "feature_type.hpp"
+#include "lua_bind.hpp"
+#include "mimic.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "player_type.hpp"
+#include "school_book.hpp"
+#include "skills.hpp"
+#include "spell_type.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "spells4.hpp"
+#include "spells5.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "timer_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "xtra2.hpp"
+
+#include <algorithm>
+#include <cassert>
+#include <vector>
s32b NOXIOUSCLOUD = -1; /* Identifier */
s32b AIRWINGS = -1; /* Identifier */
@@ -126,14 +154,8 @@ s32b DEVICE_WISH;
s32b DEVICE_SUMMON;
s32b DEVICE_MANA;
s32b DEVICE_NOTHING;
-s32b DEVICE_LEBOHAUM;
-s32b DEVICE_MAGGOT;
s32b DEVICE_HOLY_FIRE;
-s32b DEVICE_ETERNAL_FLAME;
-s32b DEVICE_DURANDIL;
s32b DEVICE_THUNDERLORDS;
-s32b DEVICE_RADAGAST = -1;
-s32b DEVICE_VALAROMA = -1;
s32b MUSIC_STOP;
s32b MUSIC_HOLD;
@@ -169,11 +191,22 @@ s32b VARDA_CALL_ALMAREN;
s32b VARDA_EVENSTAR;
s32b VARDA_STARKINDLER;
-s32b get_level_s(int sp, int max)
+static s32b get_level_s(int sp, int max)
{
return get_level(sp, max, 1);
}
+static void find_position(int y, int x, int *yy, int *xx)
+{
+ int attempts = 500;
+
+ do
+ {
+ scatter(yy, xx, y, x, 6);
+ }
+ while (!(in_bounds(*yy, *xx) && cave_floor_bold(*yy, *xx)) && --attempts);
+}
+
static casting_result cast(bool_ effect)
{
return effect ? CAST_OBVIOUS : CAST_HIDDEN;
@@ -197,7 +230,11 @@ static casting_result cplus(casting_result old, bool_ effect)
}
}
-casting_result air_noxious_cloud(int item)
+GENERATE_MONSTER_LOOKUP_FN(get_fire_golem, "Fire golem")
+
+// -------------------------------------------------------------
+
+casting_result air_noxious_cloud()
{
int dir, type;
@@ -219,7 +256,7 @@ casting_result air_noxious_cloud(int item)
return CAST_OBVIOUS;
}
-char *air_noxious_cloud_info()
+const char *air_noxious_cloud_info()
{
static char buf[128];
sprintf(buf,
@@ -229,7 +266,7 @@ char *air_noxious_cloud_info()
return buf;
}
-casting_result air_wings_of_winds(int item)
+casting_result air_wings_of_winds()
{
if (get_level_s(AIRWINGS, 50) >= 16)
{
@@ -249,14 +286,14 @@ casting_result air_wings_of_winds(int item)
return CAST_HIDDEN;
}
-char *air_wings_of_winds_info()
+const char *air_wings_of_winds_info()
{
static char buf[128];
sprintf(buf, "dur " FMTs32b "+d10", (5 + get_level_s(AIRWINGS, 25)));
return buf;
}
-casting_result air_invisibility(int item)
+casting_result air_invisibility()
{
if (p_ptr->tim_invisible == 0)
{
@@ -266,7 +303,7 @@ casting_result air_invisibility(int item)
return CAST_HIDDEN;
}
-char *air_invisibility_info()
+const char *air_invisibility_info()
{
static char buf[128];
sprintf(buf, "dur " FMTs32b "+d20 power " FMTs32b,
@@ -275,7 +312,7 @@ char *air_invisibility_info()
return buf;
}
-casting_result air_poison_blood(int item)
+casting_result air_poison_blood()
{
casting_result result = NO_CAST;
@@ -293,7 +330,7 @@ casting_result air_poison_blood(int item)
return result;
}
-char *air_poison_blood_info()
+const char *air_poison_blood_info()
{
static char buf[128];
sprintf(buf,
@@ -302,7 +339,7 @@ char *air_poison_blood_info()
return buf;
}
-casting_result air_thunderstorm(int item)
+casting_result air_thunderstorm()
{
if (p_ptr->tim_thunder == 0)
{
@@ -312,7 +349,7 @@ casting_result air_thunderstorm(int item)
return CAST_HIDDEN;
}
-char *air_thunderstorm_info()
+const char *air_thunderstorm_info()
{
static char buf[128];
sprintf(buf,
@@ -323,13 +360,13 @@ char *air_thunderstorm_info()
return buf;
}
-casting_result air_sterilize(int item)
+casting_result air_sterilize()
{
set_no_breeders((30) + 20 + get_level_s(STERILIZE, 70));
return CAST_OBVIOUS;
}
-char *air_sterilize_info()
+const char *air_sterilize_info()
{
static char buf[128];
sprintf(buf,
@@ -338,7 +375,7 @@ char *air_sterilize_info()
return buf;
}
-casting_result convey_blink(int item)
+casting_result convey_blink()
{
if (get_level_s(BLINK, 50) >= 30)
{
@@ -356,7 +393,7 @@ casting_result convey_blink(int item)
}
}
-char *convey_blink_info()
+const char *convey_blink_info()
{
static char buf[128];
sprintf(buf,
@@ -365,7 +402,7 @@ char *convey_blink_info()
return buf;
}
-casting_result convey_disarm(int item)
+casting_result convey_disarm()
{
casting_result result = NO_CAST;
@@ -378,19 +415,14 @@ casting_result convey_disarm(int item)
return result;
}
-char *convey_disarm_info()
-{
- return "";
-}
-
-casting_result convey_teleport(int item)
+casting_result convey_teleport()
{
p_ptr->energy -= (25 - get_level_s(TELEPORT, 50));
teleport_player(100 + get_level_s(TELEPORT, 100));
return CAST_OBVIOUS;
}
-char *convey_teleport_info()
+const char *convey_teleport_info()
{
static char buf[128];
sprintf(buf,
@@ -399,7 +431,7 @@ char *convey_teleport_info()
return buf;
}
-casting_result convey_teleport_away(int item)
+casting_result convey_teleport_away()
{
if (get_level_s(TELEAWAY, 50) >= 20)
{
@@ -426,11 +458,6 @@ casting_result convey_teleport_away(int item)
}
}
-char *convey_teleport_away_info()
-{
- return "";
-}
-
static int recall_get_d()
{
int d = 21 - get_level_s(RECALL, 15);
@@ -451,7 +478,7 @@ static int recall_get_f()
return f;
}
-casting_result convey_recall(int item)
+casting_result convey_recall()
{
int x,y;
cave_type *c_ptr;
@@ -476,9 +503,13 @@ casting_result convey_recall(int item)
swap_position(y, x);
return CAST_OBVIOUS;
}
- else if (c_ptr->o_idx > 0)
+ else if (!c_ptr->o_idxs.empty())
{
- set_target(y, x);
+ // Set the target
+ target_who = -1;
+ target_col = x;
+ target_row = y;
+ // Fetch item
if (get_level_s(RECALL, 50) >= 15)
{
fetch(5, 10 + get_level_s(RECALL, 150), FALSE);
@@ -495,7 +526,7 @@ casting_result convey_recall(int item)
}
}
-char *convey_recall_info()
+const char *convey_recall_info()
{
static char buf[128];
int d = recall_get_d();
@@ -507,12 +538,12 @@ char *convey_recall_info()
return buf;
}
-casting_result convey_probability_travel(int item)
+casting_result convey_probability_travel()
{
return cast(set_prob_travel(randint(20) + get_level_s(PROBABILITY_TRAVEL, 60)));
}
-char *convey_probability_travel_info()
+const char *convey_probability_travel_info()
{
static char buf[128];
sprintf(buf,
@@ -521,7 +552,7 @@ char *convey_probability_travel_info()
return buf;
}
-casting_result demonology_demon_blade(int item)
+casting_result demonology_demon_blade()
{
int rad, type;
@@ -544,7 +575,7 @@ casting_result demonology_demon_blade(int item)
PROJECT_STOP | PROJECT_KILL));
}
-char *demonology_demon_blade_info()
+const char *demonology_demon_blade_info()
{
static char buf[128];
sprintf(buf,
@@ -554,7 +585,7 @@ char *demonology_demon_blade_info()
return buf;
}
-casting_result demonology_demon_madness(int item)
+casting_result demonology_demon_madness()
{
casting_result result = NO_CAST;
int dir, type, y1, x1, y2, x2;
@@ -574,8 +605,24 @@ casting_result demonology_demon_madness(int item)
type = GF_CHARM;
}
- /* Calc the coordinates of arrival */
- get_target(dir, &y1, &x1);
+ // Calculate the coordinates of arrival
+ {
+ // Use the given direction
+ int tx = p_ptr->px + (ddx[dir] * 100);
+ int ty = p_ptr->py + (ddy[dir] * 100);
+
+ // Hack -- Use an actual "target"
+ if ((dir == 5) && target_okay())
+ {
+ tx = target_col;
+ ty = target_row;
+ }
+
+ y1 = ty;
+ x1 = tx;
+ }
+
+ // Calculate the appropriate place
y2 = p_ptr->py - (y1 - p_ptr->py);
x2 = p_ptr->px - (x1 - p_ptr->px);
@@ -595,7 +642,7 @@ casting_result demonology_demon_madness(int item)
return result;
}
-char *demonology_demon_madness_info()
+const char *demonology_demon_madness_info()
{
static char buf[128];
sprintf(buf,
@@ -605,7 +652,7 @@ char *demonology_demon_madness_info()
return buf;
}
-casting_result demonology_demon_field(int item)
+casting_result demonology_demon_field()
{
int dir;
@@ -621,7 +668,7 @@ casting_result demonology_demon_field(int item)
30 + get_level_s(DEMON_FIELD, 100)));
}
-char *demonology_demon_field_info()
+const char *demonology_demon_field_info()
{
static char buf[128];
sprintf(buf,
@@ -631,7 +678,7 @@ char *demonology_demon_field_info()
return buf;
}
-casting_result demonology_doom_shield(int item)
+casting_result demonology_doom_shield()
{
return cast(set_shield(randint(10) + 20 + get_level_s(DOOM_SHIELD, 100),
-300 + get_level_s(DOOM_SHIELD, 100),
@@ -640,7 +687,7 @@ casting_result demonology_doom_shield(int item)
10 + get_level_s(DOOM_SHIELD, 15)));
}
-char *demonology_doom_shield_info()
+const char *demonology_doom_shield_info()
{
static char buf[128];
sprintf(buf,
@@ -651,7 +698,7 @@ char *demonology_doom_shield_info()
return buf;
}
-casting_result demonology_unholy_word(int item)
+casting_result demonology_unholy_word()
{
int x, y;
cave_type *c_ptr = NULL;
@@ -708,7 +755,7 @@ casting_result demonology_unholy_word(int item)
}
}
-char *demonology_unholy_word_info()
+const char *demonology_unholy_word_info()
{
static char buf[128];
sprintf(buf,
@@ -717,12 +764,12 @@ char *demonology_unholy_word_info()
return buf;
}
-casting_result demonology_demon_cloak(int item)
+casting_result demonology_demon_cloak()
{
return cast(set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15, 0)));
}
-char *demonology_demon_cloak_info()
+const char *demonology_demon_cloak_info()
{
static char buf[128];
sprintf(buf,
@@ -731,7 +778,7 @@ char *demonology_demon_cloak_info()
return buf;
}
-casting_result demonology_summon_demon(int item)
+casting_result demonology_summon_demon()
{
int type, level, minlevel;
@@ -762,7 +809,7 @@ casting_result demonology_summon_demon(int item)
}
}
-char *demonology_summon_demon_info()
+const char *demonology_summon_demon_info()
{
static char buf[128];
sprintf(buf,
@@ -771,7 +818,7 @@ char *demonology_summon_demon_info()
return buf;
}
-casting_result demonology_discharge_minion(int item)
+casting_result demonology_discharge_minion()
{
cave_type *c_ptr;
int x, y;
@@ -813,7 +860,7 @@ casting_result demonology_discharge_minion(int item)
}
}
-char *demonology_discharge_minion_info()
+const char *demonology_discharge_minion_info()
{
static char buf[128];
sprintf(buf,
@@ -823,7 +870,7 @@ char *demonology_discharge_minion_info()
return buf;
}
-casting_result demonology_control_demon(int item)
+casting_result demonology_control_demon()
{
int dir;
if (!get_aim_dir(&dir))
@@ -834,7 +881,7 @@ casting_result demonology_control_demon(int item)
return cast(fire_ball(GF_CONTROL_DEMON, dir, 50 + get_level_s(CONTROL_DEMON, 250), 0));
}
-char *demonology_control_demon_info()
+const char *demonology_control_demon_info()
{
static char buf[128];
sprintf(buf,
@@ -843,7 +890,7 @@ char *demonology_control_demon_info()
return buf;
}
-casting_result divination_greater_identify(int item)
+casting_result divination_greater_identify()
{
if (get_check("Cast on yourself?"))
{
@@ -856,12 +903,7 @@ casting_result divination_greater_identify(int item)
return CAST_OBVIOUS;
}
-char *divination_greater_identify_info()
-{
- return "";
-}
-
-casting_result divination_identify(int item)
+casting_result divination_identify()
{
if (get_level_s(IDENTIFY, 50) >= 27)
{
@@ -887,7 +929,7 @@ casting_result divination_identify(int item)
}
}
-char *divination_identify_info()
+const char *divination_identify_info()
{
static char buf[128];
@@ -902,7 +944,7 @@ char *divination_identify_info()
}
}
-casting_result divination_vision(int item)
+casting_result divination_vision()
{
if (get_level_s(VISION, 50) >= 25)
{
@@ -916,12 +958,7 @@ casting_result divination_vision(int item)
}
-char *divination_vision_info()
-{
- return "";
-}
-
-casting_result divination_sense_hidden(int item)
+casting_result divination_sense_hidden()
{
casting_result result = NO_CAST;
@@ -934,7 +971,7 @@ casting_result divination_sense_hidden(int item)
return result;
}
-char *divination_sense_hidden_info()
+const char *divination_sense_hidden_info()
{
static char buf[128];
@@ -955,7 +992,7 @@ char *divination_sense_hidden_info()
return buf;
}
-casting_result divination_reveal_ways(int item)
+casting_result divination_reveal_ways()
{
casting_result result = NO_CAST;
result = cplus(result, detect_doors(10 + get_level(REVEALWAYS, 40, 0)));
@@ -963,7 +1000,7 @@ casting_result divination_reveal_ways(int item)
return result;
}
-char *divination_reveal_ways_info()
+const char *divination_reveal_ways_info()
{
static char buf[128];
sprintf(buf,
@@ -972,7 +1009,7 @@ char *divination_reveal_ways_info()
return buf;
}
-casting_result divination_sense_monsters(int item)
+casting_result divination_sense_monsters()
{
casting_result result = NO_CAST;
@@ -984,7 +1021,7 @@ casting_result divination_sense_monsters(int item)
return result;
}
-char *divination_sense_monsters_info()
+const char *divination_sense_monsters_info()
{
static char buf[128];
@@ -1005,7 +1042,7 @@ char *divination_sense_monsters_info()
return buf;
}
-casting_result earth_stone_skin(int item)
+casting_result earth_stone_skin()
{
int type;
@@ -1022,7 +1059,7 @@ casting_result earth_stone_skin(int item)
3 + get_level_s(STONESKIN, 5)));
}
-char *earth_stone_skin_info()
+const char *earth_stone_skin_info()
{
static char buf[128];
@@ -1046,7 +1083,7 @@ char *earth_stone_skin_info()
return buf;
}
-casting_result earth_dig(int item)
+casting_result earth_dig()
{
int dir;
if (!get_aim_dir(&dir))
@@ -1057,12 +1094,7 @@ casting_result earth_dig(int item)
return cast(wall_to_mud(dir));
}
-char *earth_dig_info()
-{
- return "";
-}
-
-casting_result earth_stone_prison(int item)
+casting_result earth_stone_prison()
{
int x,y;
@@ -1083,12 +1115,7 @@ casting_result earth_stone_prison(int item)
return CAST_OBVIOUS;
}
-char *earth_stone_prison_info()
-{
- return "";
-}
-
-casting_result earth_strike(int item)
+casting_result earth_strike()
{
int dir, dmg;
@@ -1108,7 +1135,7 @@ casting_result earth_strike(int item)
}
}
-char *earth_strike_info()
+const char *earth_strike_info()
{
static char buf[128];
int dmg = 50 + get_level_s(STRIKE, 50);
@@ -1125,7 +1152,7 @@ char *earth_strike_info()
return buf;
}
-casting_result earth_shake(int item)
+casting_result earth_shake()
{
int x,y;
@@ -1145,14 +1172,14 @@ casting_result earth_shake(int item)
return CAST_OBVIOUS;
}
-char *earth_shake_info()
+const char *earth_shake_info()
{
static char buf[128];
sprintf(buf, "rad " FMTs32b, (4 + get_level_s(SHAKE, 10)));
return buf;
}
-casting_result eru_see_the_music(int item)
+casting_result eru_see_the_music()
{
casting_result result = NO_CAST;
@@ -1177,7 +1204,7 @@ casting_result eru_see_the_music(int item)
return result;
}
-char *eru_see_the_music_info()
+const char *eru_see_the_music_info()
{
static char buf[128];
sprintf(buf,
@@ -1186,7 +1213,7 @@ char *eru_see_the_music_info()
return buf;
}
-casting_result eru_listen_to_the_music(int item)
+casting_result eru_listen_to_the_music()
{
casting_result result = NO_CAST;
@@ -1207,12 +1234,7 @@ casting_result eru_listen_to_the_music(int item)
return result;
}
-char *eru_listen_to_the_music_info()
-{
- return "";
-}
-
-casting_result eru_know_the_music(int item)
+casting_result eru_know_the_music()
{
if (get_level_s(ERU_UNDERSTAND, 50) >= 10)
{
@@ -1225,17 +1247,12 @@ casting_result eru_know_the_music(int item)
}
}
-char *eru_know_the_music_info()
-{
- return "";
-}
-
-casting_result eru_lay_of_protection(int item)
+casting_result eru_lay_of_protection()
{
return cast(fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2, 0)));
}
-char *eru_lay_of_protection_info()
+const char *eru_lay_of_protection_info()
{
static char buf[128];
sprintf(buf,
@@ -1244,7 +1261,7 @@ char *eru_lay_of_protection_info()
return buf;
}
-casting_result fire_globe_of_light(int item)
+casting_result fire_globe_of_light()
{
casting_result result = NO_CAST;
@@ -1271,7 +1288,7 @@ casting_result fire_globe_of_light(int item)
return result;
}
-char *fire_globe_of_light_info()
+const char *fire_globe_of_light_info()
{
static char buf[128];
@@ -1289,7 +1306,7 @@ char *fire_globe_of_light_info()
return buf;
}
-casting_result fire_fireflash(int item)
+casting_result fire_fireflash()
{
int dir;
int type = GF_FIRE;
@@ -1309,7 +1326,7 @@ casting_result fire_fireflash(int item)
2 + get_level_s(FIREFLASH, 5)));
}
-char *fire_fireflash_info()
+const char *fire_fireflash_info()
{
static char buf[128];
sprintf(buf,
@@ -1319,7 +1336,7 @@ char *fire_fireflash_info()
return buf;
}
-casting_result fire_fiery_shield(int item)
+casting_result fire_fiery_shield()
{
int type = SHIELD_FIRE;
if (get_level_s(FIERYAURA, 50) >= 8)
@@ -1334,7 +1351,7 @@ casting_result fire_fiery_shield(int item)
5 + get_level_s(FIERYAURA, 7)));
}
-char *fire_fiery_shield_info()
+const char *fire_fiery_shield_info()
{
static char buf[128];
sprintf(buf,
@@ -1345,7 +1362,7 @@ char *fire_fiery_shield_info()
return buf;
}
-casting_result fire_firewall(int item)
+casting_result fire_firewall()
{
int dir;
int type = GF_FIRE;
@@ -1365,7 +1382,7 @@ casting_result fire_firewall(int item)
return CAST_OBVIOUS;
}
-char *fire_firewall_info()
+const char *fire_firewall_info()
{
static char buf[128];
sprintf(buf,
@@ -1375,17 +1392,19 @@ char *fire_firewall_info()
return buf;
}
-bool_ item_tester_hook_fire_golem(object_type *o_ptr)
+object_filter_t const &item_tester_hook_fire_golem()
{
- return ((o_ptr->tval == TV_LITE) &&
- ((o_ptr->sval == SV_LITE_TORCH) ||
- (o_ptr->sval == SV_LITE_LANTERN)));
+ using namespace object_filter;
+ static auto instance = And(
+ TVal(TV_LITE),
+ Or(
+ SVal(SV_LITE_TORCH),
+ SVal(SV_LITE_LANTERN)));
+ return instance;
}
-casting_result fire_golem(int ignored)
+casting_result fire_golem()
{
- int item, x, y, m_idx;
-
/* Can we reconnect ? */
if (do_control_reconnect())
{
@@ -1393,11 +1412,12 @@ casting_result fire_golem(int ignored)
return NO_CAST;
}
- item_tester_hook = item_tester_hook_fire_golem;
+ int item;
if (!get_item(&item,
"Which light source do you want to use to create the golem?",
"You have no light source for the golem",
- USE_INVEN | USE_EQUIP))
+ USE_INVEN | USE_EQUIP,
+ item_tester_hook_fire_golem()))
{
return NO_CAST;
}
@@ -1405,11 +1425,15 @@ casting_result fire_golem(int ignored)
/* Destroy the source object */
inc_stack_size(item, -1);
- /* Summon it */
- m_allow_special[1043 + 1] = TRUE;
+ /* Find a place for it */
+ int x, y;
find_position(p_ptr->py, p_ptr->px, &y, &x);
- m_idx = place_monster_one(y, x, 1043, 0, FALSE, MSTATUS_FRIEND);
- m_allow_special[1043 + 1] = FALSE;
+
+ /* Summon it */
+ int r_idx = get_fire_golem();
+ m_allow_special[r_idx] = TRUE;
+ int m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND);
+ m_allow_special[r_idx] = FALSE;
/* level it */
if (m_idx != 0)
@@ -1422,7 +1446,7 @@ casting_result fire_golem(int ignored)
return CAST_OBVIOUS;
}
-char *fire_golem_info()
+const char *fire_golem_info()
{
static char buf[128];
sprintf(buf,
@@ -1431,7 +1455,7 @@ char *fire_golem_info()
return buf;
}
-casting_result geomancy_call_the_elements(int item)
+casting_result geomancy_call_the_elements()
{
int dir = 0;
@@ -1451,7 +1475,7 @@ casting_result geomancy_call_the_elements(int item)
return CAST_OBVIOUS;
}
-char *geomancy_call_the_elements_info()
+const char *geomancy_call_the_elements_info()
{
static char buf[128];
sprintf(buf,
@@ -1460,23 +1484,18 @@ char *geomancy_call_the_elements_info()
return buf;
}
-casting_result geomancy_channel_elements(int item)
+casting_result geomancy_channel_elements()
{
channel_the_elements(p_ptr->py, p_ptr->px, get_level_s(CHANNEL_ELEMENTS, 50));
return CAST_OBVIOUS;
}
-char *geomancy_channel_elements_info()
-{
- return "";
-}
-
typedef struct eff_type eff_type;
struct eff_type {
s16b feat;
s16b low_effect;
s16b high_effect;
- s16b damage;
+ int damage;
};
static eff_type *geomancy_find_effect(eff_type effs[], int feat)
@@ -1516,7 +1535,7 @@ static u32b dir_to_eff_flags(int dir)
return 0;
}
-casting_result geomancy_elemental_wave(int item)
+casting_result geomancy_elemental_wave()
{
int dir = 0, y = 0, x = 0;
eff_type *eff_ptr = NULL;
@@ -1576,12 +1595,7 @@ casting_result geomancy_elemental_wave(int item)
}
}
-char *geomancy_elemental_wave_info()
-{
- return "";
-}
-
-casting_result geomancy_vaporize(int item)
+casting_result geomancy_vaporize()
{
eff_type *eff_ptr = NULL;
eff_type t[] = {
@@ -1627,7 +1641,7 @@ casting_result geomancy_vaporize(int item)
}
}
-char *geomancy_vaporize_info()
+const char *geomancy_vaporize_info()
{
static char buf[128];
sprintf(buf,
@@ -1642,7 +1656,7 @@ bool_ geomancy_vaporize_depends()
return get_skill(SKILL_AIR) >= 4;
}
-casting_result geomancy_geolysis(int item)
+casting_result geomancy_geolysis()
{
int dir = 0;
@@ -1657,7 +1671,7 @@ casting_result geomancy_geolysis(int item)
return CAST_OBVIOUS;
}
-char *geomancy_geolysis_info()
+const char *geomancy_geolysis_info()
{
static char buf[128];
sprintf(buf,
@@ -1671,7 +1685,7 @@ bool_ geomancy_geolysis_depends()
return get_skill(SKILL_EARTH) >= 7;
}
-casting_result geomancy_dripping_tread(int item)
+casting_result geomancy_dripping_tread()
{
if (p_ptr->dripping_tread == 0)
{
@@ -1687,7 +1701,7 @@ casting_result geomancy_dripping_tread(int item)
return CAST_OBVIOUS;
}
-char *geomancy_dripping_tread_info()
+const char *geomancy_dripping_tread_info()
{
static char buf[128];
sprintf(buf,
@@ -1701,7 +1715,7 @@ bool_ geomancy_dripping_tread_depends()
return get_skill(SKILL_WATER) >= 10;
}
-casting_result geomancy_grow_barrier(int item)
+casting_result geomancy_grow_barrier()
{
int dir = 0;
@@ -1717,11 +1731,6 @@ casting_result geomancy_grow_barrier(int item)
return CAST_OBVIOUS;
}
-char *geomancy_grow_barrier_info()
-{
- return "";
-}
-
bool_ geomancy_grow_barrier_depends()
{
return get_skill(SKILL_EARTH) >= 12;
@@ -1757,7 +1766,7 @@ int geomancy_count_elements(cptr *elements)
return i;
}
-casting_result geomancy_elemental_minion(int item)
+casting_result geomancy_elemental_minion()
{
int dir = 0;
int x = 0, y = 0;
@@ -1852,7 +1861,7 @@ casting_result geomancy_elemental_minion(int item)
}
}
-char *geomancy_elemental_minion_info()
+const char *geomancy_elemental_minion_info()
{
static char buf[128];
sprintf(buf,
@@ -1867,7 +1876,7 @@ static void get_manathrust_dam(s16b *num, s16b *sides)
*sides = 1 + get_level_s(MANATHRUST, 20);
}
-casting_result mana_manathrust(int item)
+casting_result mana_manathrust()
{
int dir;
s16b num = 0;
@@ -1882,7 +1891,7 @@ casting_result mana_manathrust(int item)
return cast(fire_bolt(GF_MANA, dir, damroll(num, sides)));
}
-char *mana_manathrust_info()
+const char *mana_manathrust_info()
{
s16b num = 0;
s16b sides = 0;
@@ -1896,7 +1905,7 @@ char *mana_manathrust_info()
return buf;
}
-casting_result mana_remove_curses(int item)
+casting_result mana_remove_curses()
{
casting_result result = NO_CAST;
@@ -1917,12 +1926,7 @@ casting_result mana_remove_curses(int item)
return result;
}
-char *mana_remove_curses_info()
-{
- return "";
-}
-
-casting_result mana_elemental_shield(int item)
+casting_result mana_elemental_shield()
{
casting_result res = NO_CAST;
@@ -1949,7 +1953,7 @@ casting_result mana_elemental_shield(int item)
return res;
}
-char *mana_elemental_shield_info()
+const char *mana_elemental_shield_info()
{
static char buf[128];
sprintf(buf,
@@ -1958,7 +1962,7 @@ char *mana_elemental_shield_info()
return buf;
}
-casting_result mana_disruption_shield(int item)
+casting_result mana_disruption_shield()
{
if (get_level_s(MANASHIELD, 50) >= 5)
{
@@ -1975,7 +1979,7 @@ casting_result mana_disruption_shield(int item)
return NO_CAST;
}
-char *mana_disruption_shield_info()
+const char *mana_disruption_shield_info()
{
static char buf[128];
sprintf(buf,
@@ -1984,7 +1988,7 @@ char *mana_disruption_shield_info()
return buf;
}
-casting_result manwe_wind_shield(int item)
+casting_result manwe_wind_shield()
{
casting_result res = NO_CAST;
s32b dur = get_level_s(MANWE_SHIELD, 50) + 10 + randint(20);
@@ -2010,7 +2014,7 @@ casting_result manwe_wind_shield(int item)
return res;
}
-char *manwe_wind_shield_info()
+const char *manwe_wind_shield_info()
{
static char buf[128];
@@ -2037,7 +2041,7 @@ char *manwe_wind_shield_info()
return buf;
}
-casting_result manwe_avatar(int item)
+casting_result manwe_avatar()
{
s16b mimic_idx = resolve_mimic_name("Maia");
assert(mimic_idx >= 0);
@@ -2047,7 +2051,7 @@ casting_result manwe_avatar(int item)
p_ptr->lev));
}
-char *manwe_avatar_info()
+const char *manwe_avatar_info()
{
static char buf[128];
sprintf(buf,
@@ -2056,7 +2060,7 @@ char *manwe_avatar_info()
return buf;
}
-casting_result manwe_blessing(int item)
+casting_result manwe_blessing()
{
casting_result res = NO_CAST;
s32b dur = get_level_s(MANWE_BLESS, 70) + 30 + randint(40);
@@ -2081,7 +2085,7 @@ casting_result manwe_blessing(int item)
return res;
}
-char *manwe_blessing_info()
+const char *manwe_blessing_info()
{
static char buf[128];
sprintf(buf,
@@ -2090,7 +2094,7 @@ char *manwe_blessing_info()
return buf;
}
-casting_result manwe_call(int item)
+casting_result manwe_call()
{
int y = 0, x = 0, m_idx = -1, r_idx = -1;
@@ -2110,7 +2114,7 @@ casting_result manwe_call(int item)
return NO_CAST;
}
-char *manwe_call_info()
+const char *manwe_call_info()
{
static char buf[128];
sprintf(buf,
@@ -2140,7 +2144,7 @@ void do_melkor_curse(int m_idx)
m_ptr->hp = m_ptr->maxhp;
}
- p_ptr->redraw |= PR_HEALTH;
+ p_ptr->redraw |= PR_FRAME;
}
if (get_level_s(MELKOR_CURSE, 50) >= 25)
@@ -2209,7 +2213,7 @@ void do_melkor_curse(int m_idx)
m_ptr->csleep = 0;
}
-casting_result melkor_curse(int item)
+casting_result melkor_curse()
{
int dir = 0;
@@ -2230,12 +2234,7 @@ casting_result melkor_curse(int item)
}
}
-char *melkor_curse_info()
-{
- return "";
-}
-
-casting_result melkor_corpse_explosion(int item)
+casting_result melkor_corpse_explosion()
{
return cast(fire_ball(GF_CORPSE_EXPL,
0,
@@ -2243,7 +2242,7 @@ casting_result melkor_corpse_explosion(int item)
2 + get_level_s(MELKOR_CORPSE_EXPLOSION, 5)));
}
-char *melkor_corpse_explosion_info()
+const char *melkor_corpse_explosion_info()
{
static char buf[128];
sprintf(buf,
@@ -2252,7 +2251,7 @@ char *melkor_corpse_explosion_info()
return buf;
}
-casting_result melkor_mind_steal(int item)
+casting_result melkor_mind_steal()
{
int dir = 0;
@@ -2293,7 +2292,7 @@ casting_result melkor_mind_steal(int item)
}
}
-char *melkor_mind_steal_info()
+const char *melkor_mind_steal_info()
{
static char buf[128];
sprintf(buf,
@@ -2302,12 +2301,12 @@ char *melkor_mind_steal_info()
return buf;
}
-casting_result meta_recharge(int item)
+casting_result meta_recharge()
{
return cast(recharge(60 + get_level_s(RECHARGE, 140)));
}
-char *meta_recharge_info()
+const char *meta_recharge_info()
{
static char buf[128];
sprintf(buf,
@@ -2326,16 +2325,15 @@ static int get_spellbinder_max()
return i;
}
-casting_result meta_spellbinder(int item)
+casting_result meta_spellbinder()
{
if (p_ptr->spellbinder_num != 0)
{
- typedef struct trigger trigger;
struct trigger {
int idx;
cptr desc;
};
- trigger triggers[] = {
+ struct trigger triggers[] = {
{ SPELLBINDER_HP75, "75% HP", },
{ SPELLBINDER_HP50, "50% HP", },
{ SPELLBINDER_HP25, "25% HP", },
@@ -2419,7 +2417,7 @@ casting_result meta_spellbinder(int item)
}
}
-char *meta_spellbinder_info()
+const char *meta_spellbinder_info()
{
static char buf[128];
sprintf(buf,
@@ -2429,7 +2427,7 @@ char *meta_spellbinder_info()
return buf;
}
-casting_result meta_disperse_magic(int item)
+casting_result meta_disperse_magic()
{
casting_result res = NO_CAST;
@@ -2449,7 +2447,6 @@ casting_result meta_disperse_magic(int item)
if (get_level_s(DISPERSEMAGIC, 50) >= 15)
{
res = cplus(res, set_stun(0));
- res = cplus(res, set_meditation(0));
res = cplus(res, set_cut(0));
}
if (get_level_s(DISPERSEMAGIC, 50) >= 20)
@@ -2465,12 +2462,7 @@ casting_result meta_disperse_magic(int item)
return res;
}
-char *meta_disperse_magic_info()
-{
- return "";
-}
-
-casting_result meta_tracker(int item)
+casting_result meta_tracker()
{
if ((last_teleportation_y < 0) ||
(last_teleportation_x < 0))
@@ -2484,11 +2476,6 @@ casting_result meta_tracker(int item)
return CAST_OBVIOUS;
}
-char *meta_tracker_info()
-{
- return "";
-}
-
static void stop_inertia_controlled_spell()
{
assert(TIMER_INERTIA_CONTROL != NULL);
@@ -2503,7 +2490,7 @@ void meta_inertia_control_hook_birth_objects()
stop_inertia_controlled_spell();
}
-casting_result meta_inertia_control(int item)
+casting_result meta_inertia_control()
{
s32b s, difficulty, delay;
spell_type *spell;
@@ -2547,7 +2534,7 @@ casting_result meta_inertia_control(int item)
return CAST_OBVIOUS;
}
-char *meta_inertia_control_info()
+const char *meta_inertia_control_info()
{
static char buf[128];
sprintf(buf,
@@ -2591,7 +2578,7 @@ static int mind_charm_power()
return 10 + get_level_s(CHARM, 150);
}
-casting_result mind_charm(int item)
+casting_result mind_charm()
{
int pwr = mind_charm_power();
int level = get_level_s(CHARM, 50);
@@ -2619,7 +2606,7 @@ casting_result mind_charm(int item)
}
}
-char *mind_charm_info()
+const char *mind_charm_info()
{
static char buf[128];
sprintf(buf,
@@ -2633,7 +2620,7 @@ static int mind_confuse_power()
return 10 + get_level_s(CONFUSE, 150);
}
-casting_result mind_confuse(int item)
+casting_result mind_confuse()
{
int pwr = mind_confuse_power();
int level = get_level_s(CONFUSE, 50);
@@ -2661,7 +2648,7 @@ casting_result mind_confuse(int item)
}
}
-char *mind_confuse_info()
+const char *mind_confuse_info()
{
static char buf[128];
sprintf(buf,
@@ -2685,7 +2672,7 @@ static int mind_armor_of_fear_power_dice()
return 5 + get_level_s(ARMOROFFEAR, 20);
}
-casting_result mind_armor_of_fear(int item)
+casting_result mind_armor_of_fear()
{
return cast(set_shield(randint(10) + mind_armor_of_fear_base_duration(),
10,
@@ -2694,7 +2681,7 @@ casting_result mind_armor_of_fear(int item)
mind_armor_of_fear_power_dice()));
}
-char *mind_armor_of_fear_info()
+const char *mind_armor_of_fear_info()
{
static char buf[128];
sprintf(buf,
@@ -2710,7 +2697,7 @@ static int mind_stun_power()
return 10 + get_level_s(STUN, 150);
}
-casting_result mind_stun(int item)
+casting_result mind_stun()
{
int dir;
@@ -2729,7 +2716,7 @@ casting_result mind_stun(int item)
}
}
-char *mind_stun_info()
+const char *mind_stun_info()
{
static char buf[128];
sprintf(buf,
@@ -2738,7 +2725,7 @@ char *mind_stun_info()
return buf;
}
-casting_result tempo_magelock(int item)
+casting_result tempo_magelock()
{
if (get_level_s(MAGELOCK, 50) >= 30)
{
@@ -2778,17 +2765,12 @@ casting_result tempo_magelock(int item)
}
}
-char *tempo_magelock_info()
-{
- return "";
-}
-
static s32b tempo_slow_monster_power()
{
return 40 + get_level_s(SLOWMONSTER, 160);
}
-casting_result tempo_slow_monster(int item)
+casting_result tempo_slow_monster()
{
int dir;
s32b pwr;
@@ -2809,7 +2791,7 @@ casting_result tempo_slow_monster(int item)
}
}
-char *tempo_slow_monster_info()
+const char *tempo_slow_monster_info()
{
static char buf[128];
s32b pwr = tempo_slow_monster_power();
@@ -2835,7 +2817,7 @@ static s32b tempo_essence_of_speed_bonus()
return 5 + get_level_s(ESSENCESPEED, 20);
}
-casting_result tempo_essence_of_speed(int item)
+casting_result tempo_essence_of_speed()
{
if (p_ptr->fast == 0)
{
@@ -2845,7 +2827,7 @@ casting_result tempo_essence_of_speed(int item)
return NO_CAST;
}
-char *tempo_essence_of_speed_info()
+const char *tempo_essence_of_speed_info()
{
static char buf[128];
sprintf(buf,
@@ -2860,7 +2842,7 @@ static s32b tempo_banishment_power()
return 40 + get_level_s(BANISHMENT, 160);
}
-casting_result tempo_banishment(int item)
+casting_result tempo_banishment()
{
casting_result result = NO_CAST;
s32b pwr = tempo_banishment_power();
@@ -2876,7 +2858,7 @@ casting_result tempo_banishment(int item)
return result;
}
-char *tempo_banishment_info()
+const char *tempo_banishment_info()
{
static char buf[128];
sprintf(buf,
@@ -2885,7 +2867,7 @@ char *tempo_banishment_info()
return buf;
}
-casting_result tulkas_divine_aim(int item)
+casting_result tulkas_divine_aim()
{
casting_result result = NO_CAST;
s32b dur = get_level_s(TULKAS_AIM, 50) + randint(10);
@@ -2899,7 +2881,7 @@ casting_result tulkas_divine_aim(int item)
return result;
}
-char *tulkas_divine_aim_info()
+const char *tulkas_divine_aim_info()
{
static char buf[128];
sprintf(buf,
@@ -2908,7 +2890,7 @@ char *tulkas_divine_aim_info()
return buf;
}
-casting_result tulkas_wave_of_power(int item)
+casting_result tulkas_wave_of_power()
{
int dir;
@@ -2920,7 +2902,7 @@ casting_result tulkas_wave_of_power(int item)
return cast(fire_bolt(GF_ATTACK, dir, get_level_s(TULKAS_WAVE, p_ptr->num_blow)));
}
-char *tulkas_wave_of_power_info()
+const char *tulkas_wave_of_power_info()
{
static char buf[128];
sprintf(buf,
@@ -2929,50 +2911,32 @@ char *tulkas_wave_of_power_info()
return buf;
}
-casting_result tulkas_whirlwind(int item)
+casting_result tulkas_whirlwind()
{
return cast(fire_ball(GF_ATTACK, 0, 1, 1));
}
-char *tulkas_whirlwind_info()
-{
- return "";
-}
-
-static bool_ check_school_is_udun(void *data, s32b school_idx)
-{
- int *count = (int *) data;
-
- if ((school_idx == SCHOOL_UDUN) ||
- (school_idx == SCHOOL_MELKOR))
- {
- (*count)++;
- }
-
- /* Keep going */
- return TRUE;
-}
-
/* Return the number of Udun/Melkor spells in a given book */
int udun_in_book(s32b sval, s32b pval)
{
int count = 0;
- school_book_type *school_book;
- spell_idx_list *spell_idx = NULL;
- struct sglib_spell_idx_list_iterator it;
random_book_setup(sval, pval);
/* Get the school book */
- school_book = school_books_at(sval);
+ school_book *school_book = school_books_at(sval);
/* Go through spells */
- for (spell_idx = sglib_spell_idx_list_it_init(&it, school_book->spell_idx_list);
- spell_idx != NULL;
- spell_idx = sglib_spell_idx_list_it_next(&it))
- {
- spell_type *spell = spell_at(spell_idx->i);
- spell_type_school_foreach(spell, check_school_is_udun, &count);
+ for (auto spell_idx : school_book->spell_idxs) {
+ spell_type *spell = spell_at(spell_idx);
+ for (auto school_idx : spell_type_get_schools(spell))
+ {
+ if ((school_idx == SCHOOL_UDUN) ||
+ (school_idx == SCHOOL_MELKOR))
+ {
+ count++;
+ }
+ }
}
return count;
@@ -2981,55 +2945,47 @@ int udun_in_book(s32b sval, s32b pval)
int levels_in_book(s32b sval, s32b pval)
{
int levels = 0;
- school_book_type *school_book;
- spell_idx_list *spell_idx = NULL;
- struct sglib_spell_idx_list_iterator it;
random_book_setup(sval, pval);
/* Get the school book */
- school_book = school_books_at(sval);
+ school_book *school_book = school_books_at(sval);
/* Parse all spells */
- for (spell_idx = sglib_spell_idx_list_it_init(&it, school_book->spell_idx_list);
- spell_idx != NULL;
- spell_idx = sglib_spell_idx_list_it_next(&it))
+ for (auto spell_idx : school_book->spell_idxs)
{
- s32b s = spell_idx->i;
- spell_type *spell = spell_at(s);
-
+ spell_type *spell = spell_at(spell_idx);
levels += spell_type_skill_level(spell);
}
return levels;
}
-static bool_ udun_object_is_drainable(object_type *o_ptr)
+static object_filter_t const &udun_object_is_drainable()
{
- return ((o_ptr->tval == TV_WAND) ||
- (o_ptr->tval == TV_ROD_MAIN) ||
- (o_ptr->tval == TV_STAFF));
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_WAND),
+ TVal(TV_ROD_MAIN),
+ TVal(TV_STAFF));
+ return instance;
}
-casting_result udun_drain(int ignored)
+casting_result udun_drain()
{
- int item;
- object_type *o_ptr = NULL;
-
/* Ask for an item */
- item_tester_hook = udun_object_is_drainable;
+ int item;
if (!get_item(&item,
"What item to drain?",
"You have nothing you can drain",
- USE_INVEN))
+ USE_INVEN,
+ udun_object_is_drainable()))
{
return NO_CAST;
}
/* Drain */
-
- /* get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
switch (o_ptr->tval)
{
@@ -3068,12 +3024,7 @@ casting_result udun_drain(int ignored)
return CAST_OBVIOUS;
}
-char *udun_drain_info()
-{
- return "";
-}
-
-casting_result udun_genocide(int item)
+casting_result udun_genocide()
{
if (get_level_s(GENOCIDE, 50) < 10)
{
@@ -3094,22 +3045,17 @@ casting_result udun_genocide(int item)
return CAST_OBVIOUS;
}
-char *udun_genocide_info()
-{
- return "";
-}
-
static int udun_wraithform_base_duration()
{
return 20 + get_level_s(WRAITHFORM, 40);
}
-casting_result udun_wraithform(int item)
+casting_result udun_wraithform()
{
return cast(set_shadow(randint(30) + udun_wraithform_base_duration()));
}
-char *udun_wraithform_info()
+const char *udun_wraithform_info()
{
static char buf[128];
sprintf(buf,
@@ -3123,14 +3069,14 @@ static int udun_flame_of_udun_base_duration()
return 5 + get_level_s(FLAMEOFUDUN, 30);
}
-casting_result udun_flame_of_udun(int item)
+casting_result udun_flame_of_udun()
{
return cast(set_mimic(randint(15) + udun_flame_of_udun_base_duration(),
resolve_mimic_name("Balrog"),
get_level_s(FLAMEOFUDUN, 50)));
}
-char *udun_flame_of_udun_info()
+const char *udun_flame_of_udun_info()
{
static char buf[128];
sprintf(buf,
@@ -3149,7 +3095,7 @@ static int tidal_wave_duration()
return 6 + get_level_s(TIDALWAVE, 10);
}
-casting_result water_tidal_wave(int item)
+casting_result water_tidal_wave()
{
fire_wave(GF_WAVE,
0,
@@ -3160,7 +3106,7 @@ casting_result water_tidal_wave(int item)
return CAST_OBVIOUS;
}
-char *water_tidal_wave_info()
+const char *water_tidal_wave_info()
{
static char buf[128];
sprintf(buf,
@@ -3185,7 +3131,7 @@ static int water_ice_storm_duration()
return 20 + get_level_s(ICESTORM, 70);
}
-casting_result water_ice_storm(int item)
+casting_result water_ice_storm()
{
int type = GF_COLD;
@@ -3204,7 +3150,7 @@ casting_result water_ice_storm(int item)
return CAST_OBVIOUS;
}
-char *water_ice_storm_info()
+const char *water_ice_storm_info()
{
static char buf[128];
sprintf(buf,
@@ -3220,7 +3166,7 @@ static int water_ent_potion_base_duration()
return 25 + get_level_s(ENTPOTION, 40);;
}
-casting_result water_ent_potion(int item)
+casting_result water_ent_potion()
{
set_food(PY_FOOD_MAX - 1);
msg_print("The Ent's Potion fills your stomach.");
@@ -3237,7 +3183,7 @@ casting_result water_ent_potion(int item)
return CAST_OBVIOUS;
}
-char *water_ent_potion_info()
+const char *water_ent_potion_info()
{
if (get_level_s(ENTPOTION, 50) >= 12)
{
@@ -3268,7 +3214,7 @@ static int water_vapor_duration()
return 5;
}
-casting_result water_vapor(int item)
+casting_result water_vapor()
{
fire_cloud(GF_WATER,
0,
@@ -3278,7 +3224,7 @@ casting_result water_vapor(int item)
return CAST_OBVIOUS;
}
-char *water_vapor_info()
+const char *water_vapor_info()
{
static char buf[128];
sprintf(buf,
@@ -3298,7 +3244,7 @@ static void get_geyser_damage(int *dice, int *sides)
*sides = 3 + get_level_s(GEYSER, 35);
}
-casting_result water_geyser(int item)
+casting_result water_geyser()
{
int dir, dice, sides;
@@ -3314,7 +3260,7 @@ casting_result water_geyser(int item)
damroll(dice, sides)));
}
-char *water_geyser_info()
+const char *water_geyser_info()
{
static char buf[128];
int dice, sides;
@@ -3338,7 +3284,7 @@ static int charm_animal_radius()
return get_level_s(YAVANNA_CHARM_ANIMAL, 2);
}
-casting_result yavanna_charm_animal(int item)
+casting_result yavanna_charm_animal()
{
int dir;
@@ -3353,7 +3299,7 @@ casting_result yavanna_charm_animal(int item)
charm_animal_radius()));
}
-char *yavanna_charm_animal_info()
+const char *yavanna_charm_animal_info()
{
static char buf[128];
sprintf(buf,
@@ -3368,13 +3314,13 @@ static int yavanna_grow_grass_radius()
return get_level_s(YAVANNA_GROW_GRASS, 4);
}
-casting_result yavanna_grow_grass(int item)
+casting_result yavanna_grow_grass()
{
grow_grass(yavanna_grow_grass_radius());
return CAST_OBVIOUS;
}
-char *yavanna_grow_grass_info()
+const char *yavanna_grow_grass_info()
{
static char buf[128];
sprintf(buf,
@@ -3398,14 +3344,14 @@ static int tree_roots_damage()
return 10 + get_level_s(YAVANNA_TREE_ROOTS, 20);
}
-casting_result yavanna_tree_roots(int item)
+casting_result yavanna_tree_roots()
{
return cast(set_roots(tree_roots_duration(),
tree_roots_ac(),
tree_roots_damage()));
}
-char *yavanna_tree_roots_info()
+const char *yavanna_tree_roots_info()
{
static char buf[128];
sprintf(buf,
@@ -3426,7 +3372,7 @@ static int water_bite_damage()
return 10 + get_level_s(YAVANNA_WATER_BITE, 50);
}
-casting_result yavanna_water_bite(int item)
+casting_result yavanna_water_bite()
{
int rad = 0;
@@ -3442,7 +3388,7 @@ casting_result yavanna_water_bite(int item)
PROJECT_STOP | PROJECT_KILL));
}
-char *yavanna_water_bite_info()
+const char *yavanna_water_bite_info()
{
static char buf[128];
sprintf(buf,
@@ -3457,7 +3403,7 @@ static int uproot_mlevel()
return 30 + get_level_s(YAVANNA_UPROOT, 70);
}
-casting_result yavanna_uproot(int item)
+casting_result yavanna_uproot()
{
int dir, x, y;
cave_type *c_ptr;
@@ -3501,7 +3447,7 @@ casting_result yavanna_uproot(int item)
}
}
-char *yavanna_uproot_info()
+const char *yavanna_uproot_info()
{
static char buf[128];
sprintf(buf,
@@ -3515,13 +3461,13 @@ static int nature_grow_trees_radius()
return 2 + get_level_s(GROWTREE, 7);
}
-casting_result nature_grow_trees(int item)
+casting_result nature_grow_trees()
{
grow_trees(nature_grow_trees_radius());
return CAST_OBVIOUS;
}
-char *nature_grow_trees_info()
+const char *nature_grow_trees_info()
{
static char buf[128];
sprintf(buf,
@@ -3540,12 +3486,12 @@ static int nature_healing_hp()
return p_ptr->mhp * nature_healing_percentage() / 100;
}
-casting_result nature_healing(int item)
+casting_result nature_healing()
{
return cast(hp_player(nature_healing_hp()));
}
-char *nature_healing_info()
+const char *nature_healing_info()
{
static char buf[128];
sprintf(buf,
@@ -3555,7 +3501,7 @@ char *nature_healing_info()
return buf;
}
-casting_result nature_recovery(int item)
+casting_result nature_recovery()
{
casting_result result = NO_CAST;
@@ -3582,11 +3528,6 @@ casting_result nature_recovery(int item)
return result;
}
-char *nature_recovery_info()
-{
- return "";
-}
-
static int regeneration_base_duration()
{
return 5 + get_level_s(REGENERATION, 50);
@@ -3597,7 +3538,7 @@ static int regeneration_power()
return 300 + get_level_s(REGENERATION, 700);
}
-casting_result nature_regeneration(int item)
+casting_result nature_regeneration()
{
if (p_ptr->tim_regen == 0)
{
@@ -3607,7 +3548,7 @@ casting_result nature_regeneration(int item)
return NO_CAST;
}
-char *nature_regeneration_info()
+const char *nature_regeneration_info()
{
static char buf[128];
sprintf(buf,
@@ -3622,7 +3563,7 @@ static int summon_animal_level()
return 25 + get_level_s(SUMMONANNIMAL, 50);
}
-casting_result nature_summon_animal(int item)
+casting_result nature_summon_animal()
{
summon_specific_level = summon_animal_level();
return cast(summon_specific_friendly(p_ptr->py,
@@ -3632,7 +3573,7 @@ casting_result nature_summon_animal(int item)
TRUE));
}
-char *nature_summon_animal_info()
+const char *nature_summon_animal_info()
{
static char buf[128];
sprintf(buf,
@@ -3641,7 +3582,7 @@ char *nature_summon_animal_info()
return buf;
}
-casting_result nature_grow_athelas(int item)
+casting_result nature_grow_athelas()
{
if (p_ptr->black_breath)
{
@@ -3653,17 +3594,12 @@ casting_result nature_grow_athelas(int item)
return CAST_HIDDEN;
}
-char *nature_grow_athelas_info()
-{
- return "";
-}
-
static int device_heal_monster_hp()
{
return 20 + get_level_s(DEVICE_HEAL_MONSTER, 380);
}
-casting_result device_heal_monster(int item)
+casting_result device_heal_monster()
{
int dir;
@@ -3675,7 +3611,7 @@ casting_result device_heal_monster(int item)
return cast(fire_ball(GF_OLD_HEAL, dir, device_heal_monster_hp(), 0));
}
-char *device_heal_monster_info()
+const char *device_heal_monster_info()
{
static char buf[128];
sprintf(buf,
@@ -3684,7 +3620,7 @@ char *device_heal_monster_info()
return buf;
}
-casting_result device_haste_monster(int item)
+casting_result device_haste_monster()
{
int dir;
@@ -3696,23 +3632,18 @@ casting_result device_haste_monster(int item)
return cast(fire_ball(GF_OLD_SPEED, dir, 1, 0));
}
-char *device_haste_monster_info()
+const char *device_haste_monster_info()
{
return "speed +10";
}
-casting_result device_wish(int item)
+casting_result device_wish()
{
make_wish();
return CAST_OBVIOUS;
}
-char *device_wish_info()
-{
- return "";
-}
-
-casting_result device_summon_monster(int item)
+casting_result device_summon_monster()
{
casting_result result = NO_CAST;
int i;
@@ -3725,23 +3656,18 @@ casting_result device_summon_monster(int item)
return result;
}
-char *device_summon_monster_info()
-{
- return "";
-}
-
static int device_mana_pct()
{
return 20 + get_level_s(DEVICE_MANA, 50);
}
-casting_result device_mana(int item)
+casting_result device_mana()
{
increase_mana((p_ptr->msp * device_mana_pct()) / 100);
return CAST_OBVIOUS;
}
-char *device_mana_info()
+const char *device_mana_info()
{
static char buf[128];
sprintf(buf,
@@ -3750,58 +3676,22 @@ char *device_mana_info()
return buf;
}
-casting_result device_nothing(int item)
+casting_result device_nothing()
{
return CAST_HIDDEN;
}
-char *device_nothing_info()
-{
- return "";
-}
-
-casting_result device_lebohaum(int item)
-{
- msg_print("You hear a little song in your head in some unknown tongue:");
- msg_print("'Avec le casque Lebohaum y a jamais d'anicroches, je parcours les dongeons,");
- msg_print("j'en prend plein la caboche. Avec le casque Lebohaum, tout ces monstres a la");
- msg_print("con, je leur met bien profond: c'est moi le maitre du dongeon!'");
- return CAST_OBVIOUS;
-}
-
-char *device_lebohaum_info()
-{
- return "";
-}
-
-casting_result device_maggot(int item)
-{
- int dir;
-
- if (!get_aim_dir(&dir))
- {
- return NO_CAST;
- }
-
- return cast(fire_ball(GF_TURN_ALL, dir, 40, 2));
-}
-
-char *device_maggot_info()
-{
- return "power 40 rad 2";
-}
-
static int holy_fire_damage()
{
return 50 + get_level_s(DEVICE_HOLY_FIRE, 300);
}
-casting_result device_holy_fire(int item)
+casting_result device_holy_fire()
{
return cast(project_hack(GF_HOLY_FIRE, holy_fire_damage()));
}
-char *device_holy_fire_info()
+const char *device_holy_fire_info()
{
static char buf[128];
sprintf(buf,
@@ -3810,116 +3700,7 @@ char *device_holy_fire_info()
return buf;
}
-static int get_eternal_artifact_idx(object_type *o_ptr)
-{
- if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_LONG_SWORD)) {
- return 147;
- } else if ((o_ptr->tval == TV_MSTAFF) && (o_ptr->sval == SV_MSTAFF)) {
- return 127;
- } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_HEAVY_XBOW)) {
- return 152;
- } else if ((o_ptr->tval == TV_DRAG_ARMOR) && (o_ptr->sval == SV_DRAGON_POWER)) {
- return 17;
- }
-
- if (game_module_idx == MODULE_THEME)
- {
- if ((o_ptr->tval == TV_HAFTED) && (o_ptr->sval == SV_LUCERN_HAMMER)) {
- return 241;
- } else if ((o_ptr->tval == TV_POLEARM) && (o_ptr->sval == SV_TRIDENT)) {
- return 242;
- } else if ((o_ptr->tval == TV_AXE) && (o_ptr->sval == SV_BROAD_AXE)) {
- return 243;
- } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_LONG_BOW)) {
- return 245;
- } else if ((o_ptr->tval == TV_BOOMERANG) && (o_ptr->sval == SV_BOOM_METAL)) {
- return 247;
- } else if ((o_ptr->tval == TV_BOW) && (o_ptr->sval == SV_SLING)) {
- return 246;
- } else if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_RAPIER)) {
- return 244;
- } else if ((o_ptr->tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_SPELL)) {
- return 248;
- }
- }
-
- /* Not usable */
- return -1;
-}
-
-static bool_ eternal_flame_item_tester_hook(object_type *o_ptr)
-{
- if ((o_ptr->name1 > 0) ||
- (o_ptr->name2 > 0))
- {
- return FALSE;
- }
-
- return (get_eternal_artifact_idx(o_ptr) >= 0);
-}
-
-casting_result device_eternal_flame(int flame_item)
-{
- int item;
- object_type *o_ptr = NULL;
- int artifact_idx = -1;
-
- item_tester_hook = eternal_flame_item_tester_hook;
- if (!get_item(&item,
- "Which object do you want to imbue?",
- "You have no objects to imbue.",
- USE_INVEN))
- {
- return NO_CAST;
- }
-
- /* Get the artifact idx */
- artifact_idx = get_eternal_artifact_idx(o_ptr);
- assert(artifact_idx >= 0);
-
- /* Forge the item */
- o_ptr = get_object(item);
- o_ptr->name1 = artifact_idx;
-
- apply_magic(o_ptr, -1, TRUE, TRUE, TRUE);
-
- o_ptr->found = OBJ_FOUND_SELFMADE;
-
- inven_item_increase(flame_item, -1);
- inven_item_describe(flame_item);
- inven_item_optimize(flame_item);
-
- return CAST_OBVIOUS;
-}
-
-char *device_eternal_flame_info()
-{
- return "";
-}
-
-casting_result device_durandil(int item)
-{
- msg_print("You hear a little song in your head in some unknown tongue:");
- msg_print("'Les epees Durandils sont forgees dans les mines par des nains.");
- msg_print("Avec ca c'est facile de tuer un troll avec une seule main. Pas besoin");
- msg_print("de super entrainement nis de niveau 28. Quand tu sors l'instrument");
- msg_print("c'est l'ennemi qui prend la fuite! Avec ton epee Durandil quand tu");
- msg_print("parcours les chemins, tu massacre sans peine les brigands et les gobelins,");
- msg_print("les rats geants, les ogres mutants, les zombies et les liches, tu les");
- msg_print("decoupe en tranches comme si c'etait des parts de quiches.");
- msg_print("Les epees Durandil! Les epees Durandil!");
- msg_print("Quand tu la sort dans un dongeon au moins t'as pas l'air debile.");
- msg_print("C'est l'arme des bourins qui savent etre subtils.");
- msg_print("Ne partez pas a l'aventure sans votre epee Durandil!'");
- return CAST_OBVIOUS;
-}
-
-char *device_durandil_info()
-{
- return "";
-}
-
-casting_result device_thunderlords(int item)
+casting_result device_thunderlords()
{
switch (game_module_idx)
{
@@ -3957,78 +3738,17 @@ casting_result device_thunderlords(int item)
}
}
-char *device_thunderlords_info()
-{
- return "";
-}
-
-casting_result device_radagast(int item)
-{
- cmsg_print(TERM_GREEN, "The staff's power cleanses you completely!");
- remove_all_curse();
- do_res_stat(A_STR, TRUE);
- do_res_stat(A_CON, TRUE);
- do_res_stat(A_DEX, TRUE);
- do_res_stat(A_WIS, TRUE);
- do_res_stat(A_INT, TRUE);
- do_res_stat(A_CHR, TRUE);
- restore_level();
- // clean_corruptions(); TODO: Do we want to implement this?
- hp_player(5000);
- heal_insanity(5000);
- set_poisoned(0);
- set_blind(0);
- set_confused(0);
- set_image(0);
- set_stun(0);
- set_cut(0);
- set_parasite(0, 0);
-
- if (p_ptr->black_breath)
- {
- msg_print("The hold of the Black Breath on you is broken!");
- }
- p_ptr->black_breath = FALSE;
-
- p_ptr->update |= PU_BONUS;
- p_ptr->window |= PW_PLAYER;
-
- return CAST_OBVIOUS;
-}
-
-char *device_radagast_info()
-{
- return "";
-}
-
-casting_result device_valaroma(int item)
-{
- int power = 5 * p_ptr->lev;
- banish_evil(power);
- return CAST_HIDDEN;
-}
-
-char *device_valaroma_info()
-{
- return "";
-}
-
void static start_lasting_spell(int spl)
{
p_ptr->music_extra = -spl;
}
-casting_result music_stop_singing_spell(int item)
+casting_result music_stop_singing_spell()
{
start_lasting_spell(0);
return CAST_OBVIOUS;
}
-char *music_stop_singing_info()
-{
- return "";
-}
-
static int holding_pattern_power()
{
return 10 + get_level_s(MUSIC_HOLD, 100);
@@ -4040,13 +3760,13 @@ int music_holding_pattern_lasting()
return get_mana(MUSIC_HOLD);
}
-casting_result music_holding_pattern_spell(int item)
+casting_result music_holding_pattern_spell()
{
start_lasting_spell(MUSIC_HOLD);
return CAST_OBVIOUS;
}
-char *music_holding_pattern_info()
+const char *music_holding_pattern_info()
{
static char buf[128];
sprintf(buf,
@@ -4066,13 +3786,13 @@ int music_illusion_pattern_lasting()
return get_mana(MUSIC_CONF);
}
-casting_result music_illusion_pattern_spell(int item)
+casting_result music_illusion_pattern_spell()
{
start_lasting_spell(MUSIC_CONF);
return CAST_OBVIOUS;
}
-char *music_illusion_pattern_info()
+const char *music_illusion_pattern_info()
{
static char buf[128];
sprintf(buf,
@@ -4092,13 +3812,13 @@ int music_stun_pattern_lasting()
return get_mana(MUSIC_STUN);
}
-casting_result music_stun_pattern_spell(int item)
+casting_result music_stun_pattern_spell()
{
start_lasting_spell(MUSIC_STUN);
return CAST_OBVIOUS;
}
-char *music_stun_pattern_info()
+const char *music_stun_pattern_info()
{
static char buf[128];
sprintf(buf,
@@ -4113,17 +3833,12 @@ int music_song_of_the_sun_lasting()
return 1;
}
-casting_result music_song_of_the_sun_spell(int item)
+casting_result music_song_of_the_sun_spell()
{
start_lasting_spell(MUSIC_LITE);
return CAST_OBVIOUS;
}
-char *music_song_of_the_sun_info()
-{
- return "";
-}
-
int flow_of_life_hp()
{
return 7 + get_level_s(MUSIC_HEAL, 100);
@@ -4135,13 +3850,13 @@ int music_flow_of_life_lasting()
return get_mana(MUSIC_HEAL);
}
-casting_result music_flow_of_life_spell(int item)
+casting_result music_flow_of_life_spell()
{
start_lasting_spell(MUSIC_HEAL);
return CAST_OBVIOUS;
}
-char *music_flow_of_life_info()
+const char *music_flow_of_life_info()
{
static char buf[128];
sprintf(buf,
@@ -4168,17 +3883,12 @@ int music_heroic_ballad_lasting()
return get_mana(MUSIC_HERO);
}
-casting_result music_heroic_ballad_spell(int item)
+casting_result music_heroic_ballad_spell()
{
start_lasting_spell(MUSIC_HERO);
return CAST_OBVIOUS;
}
-char *music_heroic_ballad_info()
-{
- return "";
-}
-
int music_hobbit_melodies_lasting()
{
set_shield(5, 10 + get_level_s(MUSIC_TIME, 50), 0, 0, 0);
@@ -4189,13 +3899,13 @@ int music_hobbit_melodies_lasting()
return get_mana(MUSIC_TIME);
}
-casting_result music_hobbit_melodies_spell(int item)
+casting_result music_hobbit_melodies_spell()
{
start_lasting_spell(MUSIC_TIME);
return CAST_OBVIOUS;
}
-char *music_hobbit_melodies_info()
+const char *music_hobbit_melodies_info()
{
static char buf[128];
if (get_level_s(MUSIC_TIME, 50) >= 15)
@@ -4222,13 +3932,13 @@ int music_clairaudience_lasting()
return get_mana(MUSIC_MIND);
}
-casting_result music_clairaudience_spell(int item)
+casting_result music_clairaudience_spell()
{
start_lasting_spell(MUSIC_MIND);
return CAST_OBVIOUS;
}
-char *music_clairaudience_info()
+const char *music_clairaudience_info()
{
static char buf[128];
@@ -4244,7 +3954,7 @@ char *music_clairaudience_info()
}
}
-casting_result music_blow_spell(int item)
+casting_result music_blow_spell()
{
fire_ball(GF_SOUND,
0,
@@ -4253,7 +3963,7 @@ casting_result music_blow_spell(int item)
return CAST_OBVIOUS;
}
-char *music_blow_info()
+const char *music_blow_info()
{
static char buf[128];
sprintf(buf,
@@ -4264,7 +3974,7 @@ char *music_blow_info()
return buf;
}
-casting_result music_gush_of_wind_spell(int item)
+casting_result music_gush_of_wind_spell()
{
fire_ball(GF_AWAY_ALL,
0,
@@ -4273,7 +3983,7 @@ casting_result music_gush_of_wind_spell(int item)
return CAST_OBVIOUS;
}
-char *music_gush_of_wind_info()
+const char *music_gush_of_wind_info()
{
static char buf[128];
sprintf(buf,
@@ -4283,33 +3993,28 @@ char *music_gush_of_wind_info()
return buf;
}
-casting_result music_horns_of_ylmir_spell(int item)
+casting_result music_horns_of_ylmir_spell()
{
- earthquake(p_ptr->py, p_ptr->px, 2 + get_level_s(SHAKE, 10));
+ earthquake(p_ptr->py, p_ptr->px, 2 + get_level_s(MUSIC_YLMIR, 10));
return CAST_OBVIOUS;
}
-char *music_horns_of_ylmir_info()
+const char *music_horns_of_ylmir_info()
{
static char buf[128];
sprintf(buf,
"rad " FMTs32b,
- 2 + get_level_s(SHAKE, 10));
+ 2 + get_level_s(MUSIC_YLMIR, 10));
return buf;
}
-casting_result music_ambarkanta_spell(int item)
+casting_result music_ambarkanta_spell()
{
alter_reality();
return CAST_OBVIOUS;
}
-char *music_ambarkanta_info()
-{
- return "";
-}
-
-casting_result aule_firebrand_spell(int item)
+casting_result aule_firebrand_spell()
{
int rad = 0;
int type = GF_FIRE;
@@ -4332,7 +4037,7 @@ casting_result aule_firebrand_spell(int item)
PROJECT_STOP | PROJECT_KILL));
}
-char *aule_firebrand_info()
+const char *aule_firebrand_info()
{
s32b level = get_level_s(AULE_FIREBRAND, 50);
static char buf[128];
@@ -4344,34 +4049,27 @@ char *aule_firebrand_info()
return buf;
}
-static bool_ aule_enchant_weapon_item_tester(object_type *o_ptr)
+static object_filter_t const &aule_enchant_weapon_item_tester()
{
- if (o_ptr->name1 > 0)
- {
- return FALSE;
- }
-
- switch (o_ptr->tval)
- {
- case TV_MSTAFF:
- case TV_BOW:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_SWORD:
- case TV_AXE:
- return TRUE;
-
- default:
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // Cannot enchant artifacts, spell is probably already too overpowered.
+ Not(IsArtifact()),
+ // Only weapons which Aule likes
+ Or(
+ TVal(TV_MSTAFF),
+ TVal(TV_BOW),
+ TVal(TV_HAFTED),
+ TVal(TV_POLEARM),
+ TVal(TV_SWORD),
+ TVal(TV_AXE)));
+ return instance;
}
-casting_result aule_enchant_weapon_spell(int ignored)
+casting_result aule_enchant_weapon_spell()
{
s32b level = get_level_s(AULE_ENCHANT_WEAPON, 50);
s16b num_h, num_d, num_p;
- int item;
- object_type *o_ptr = NULL;
num_h = 1 + randint(level/12);
num_d = 0;
@@ -4386,16 +4084,17 @@ casting_result aule_enchant_weapon_spell(int ignored)
num_p = 1;
}
- item_tester_hook = aule_enchant_weapon_item_tester;
+ int item;
if (!get_item(&item,
"Which object do you want to enchant?",
"You have no objects to enchant.",
- USE_INVEN))
+ USE_INVEN,
+ aule_enchant_weapon_item_tester()))
{
return NO_CAST;
}
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->to_h = o_ptr->to_h + num_h;
o_ptr->to_d = o_ptr->to_d + num_d;
@@ -4404,7 +4103,7 @@ casting_result aule_enchant_weapon_spell(int ignored)
return CAST_OBVIOUS;
}
-char *aule_enchant_weapon_info()
+const char *aule_enchant_weapon_info()
{
static char buf[128];
sprintf(buf,
@@ -4413,37 +4112,32 @@ char *aule_enchant_weapon_info()
return buf;
}
-bool_ aule_enchant_armor_item_tester(object_type *o_ptr)
+static object_filter_t const &aule_enchant_armor_item_tester()
{
- if (o_ptr->name1 > 0)
- {
- return FALSE;
- }
-
- switch (o_ptr->tval)
- {
- case TV_BOOTS:
- case TV_GLOVES:
- case TV_HELM:
- case TV_CROWN:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- return TRUE;
-
- default:
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // No enchanting artifacts; the spell is already horribly
+ // overpowered.
+ Not(IsArtifact()),
+ // Only armor-like things can be enchanted
+ Or(
+ TVal(TV_BOOTS),
+ TVal(TV_GLOVES),
+ TVal(TV_HELM),
+ TVal(TV_CROWN),
+ TVal(TV_SHIELD),
+ TVal(TV_CLOAK),
+ TVal(TV_SOFT_ARMOR),
+ TVal(TV_HARD_ARMOR),
+ TVal(TV_DRAG_ARMOR)));
+ return instance;
}
-casting_result aule_enchant_armour_spell(int ignored)
+casting_result aule_enchant_armour_spell()
{
s32b level = get_level_s(AULE_ENCHANT_ARMOUR, 50);
s16b num_h, num_d, num_a, num_p;
int item;
- object_type *o_ptr = NULL;
num_a = 1 + randint(level/10);
num_h = 0;
@@ -4459,16 +4153,16 @@ casting_result aule_enchant_armour_spell(int ignored)
num_p = 1;
}
- item_tester_hook = aule_enchant_armor_item_tester;
if (!get_item(&item,
"Which object do you want to enchant?",
"You have no objects to enchant.",
- USE_INVEN))
+ USE_INVEN,
+ aule_enchant_armor_item_tester()))
{
return NO_CAST;
}
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->to_h = o_ptr->to_h + num_h;
o_ptr->to_d = o_ptr->to_d + num_d;
@@ -4478,7 +4172,7 @@ casting_result aule_enchant_armour_spell(int ignored)
return CAST_OBVIOUS;
}
-char *aule_enchant_armour_info()
+const char *aule_enchant_armour_info()
{
static char buf[128];
sprintf(buf,
@@ -4487,7 +4181,7 @@ char *aule_enchant_armour_info()
return buf;
}
-casting_result aule_child_spell(int item)
+casting_result aule_child_spell()
{
int y, x;
s16b m_idx;
@@ -4507,7 +4201,7 @@ casting_result aule_child_spell(int item)
}
}
-char *aule_child_info()
+const char *aule_child_info()
{
static char buf[128];
sprintf(buf,
@@ -4521,7 +4215,7 @@ static int tears_of_luthien_hp()
return 10 * get_level_s(MANDOS_TEARS_LUTHIEN, 30);
}
-casting_result mandos_tears_of_luthien_spell(int item)
+casting_result mandos_tears_of_luthien_spell()
{
casting_result result = NO_CAST;
@@ -4533,7 +4227,7 @@ casting_result mandos_tears_of_luthien_spell(int item)
return result;
}
-char *mandos_tears_of_luthien_info()
+const char *mandos_tears_of_luthien_info()
{
static char buf[128];
sprintf(buf,
@@ -4542,7 +4236,7 @@ char *mandos_tears_of_luthien_info()
return buf;
}
-casting_result mandos_spirit_of_the_feanturi_spell(int item)
+casting_result mandos_spirit_of_the_feanturi_spell()
{
casting_result result = NO_CAST;
s32b level = get_level_s(MANDOS_SPIRIT_FEANTURI, 50);
@@ -4565,7 +4259,7 @@ casting_result mandos_spirit_of_the_feanturi_spell(int item)
return result;
}
-char *mandos_spirit_of_the_feanturi_info()
+const char *mandos_spirit_of_the_feanturi_info()
{
static char buf[128];
s32b level = get_level_s(MANDOS_SPIRIT_FEANTURI, 50) ;
@@ -4585,12 +4279,12 @@ static int tale_of_doom_duration()
return 5 + get_level_s(MANDOS_TALE_DOOM,10);
}
-casting_result mandos_tale_of_doom_spell(int item)
+casting_result mandos_tale_of_doom_spell()
{
return cast(set_tim_precognition(tale_of_doom_duration()));
}
-char *mandos_tale_of_doom_info()
+const char *mandos_tale_of_doom_info()
{
static char buf[128];
sprintf(buf,
@@ -4604,17 +4298,16 @@ int call_to_the_halls_mlev()
return 20 + get_level(MANDOS_CALL_HALLS, 70, 0);
}
-casting_result mandos_call_to_the_halls_spell(int item)
+casting_result mandos_call_to_the_halls_spell()
{
-#define N_SUMMONS 2
int y, x;
- s16b m_idx, r_idx;
- s16b summons[N_SUMMONS] = {
+ s16b m_idx;
+ std::vector<int> summons {
test_monster_name("Experienced spirit"),
- test_monster_name("Wise spirit"),
+ test_monster_name("Wise spirit")
};
- r_idx = summons[rand_int(N_SUMMONS)];
+ int r_idx = summons[rand_int(summons.size())];
assert(r_idx >= 0);
find_position(p_ptr->py, p_ptr->px, &y, &x);
@@ -4625,10 +4318,9 @@ casting_result mandos_call_to_the_halls_spell(int item)
return CAST_OBVIOUS;
}
return NO_CAST;
-#undef N_SUMMONS
}
-char *mandos_call_to_the_halls_info()
+const char *mandos_call_to_the_halls_info()
{
static char buf[128];
sprintf(buf,
@@ -4643,7 +4335,7 @@ static void get_belegaer_damage(int *dice, int *sides)
*sides = 3 + get_level_s(ULMO_BELEGAER, 35);
}
-casting_result ulmo_song_of_belegaer_spell(int item)
+casting_result ulmo_song_of_belegaer_spell()
{
int dir, dice, sides;
@@ -4659,7 +4351,7 @@ casting_result ulmo_song_of_belegaer_spell(int item)
damroll(dice, sides)));
}
-char *ulmo_song_of_belegaer_info()
+const char *ulmo_song_of_belegaer_info()
{
static char buf[128];
int dice, sides;
@@ -4677,7 +4369,7 @@ int draught_of_ulmonan_hp()
return 5 * get_level_s(ULMO_DRAUGHT_ULMONAN, 50);
}
-casting_result ulmo_draught_of_ulmonan_spell(int item)
+casting_result ulmo_draught_of_ulmonan_spell()
{
casting_result result = NO_CAST;
s32b level = get_level_s(ULMO_DRAUGHT_ULMONAN, 50);
@@ -4705,7 +4397,7 @@ casting_result ulmo_draught_of_ulmonan_spell(int item)
return result;
}
-char *ulmo_draught_of_ulmonan_info()
+const char *ulmo_draught_of_ulmonan_info()
{
static char buf[128];
sprintf(buf,
@@ -4719,17 +4411,16 @@ static int call_of_the_ulumuri_mlev()
return 30 + get_level(ULMO_CALL_ULUMURI, 70, 0);
}
-casting_result ulmo_call_of_the_ulumuri_spell(int item)
+casting_result ulmo_call_of_the_ulumuri_spell()
{
-#define N_SUMMONS 2
int x,y;
- s16b m_idx, r_idx;
- s16b summons[N_SUMMONS] = {
+ s16b m_idx;
+ std::vector<int> summons {
test_monster_name("Water spirit"),
test_monster_name("Water elemental")
};
- r_idx = summons[rand_int(N_SUMMONS)];
+ int r_idx = summons[rand_int(summons.size())];
assert(r_idx >= 0);
find_position(p_ptr->py, p_ptr->px, &y, &x);
@@ -4742,10 +4433,9 @@ casting_result ulmo_call_of_the_ulumuri_spell(int item)
}
return NO_CAST;
-#undef N_SUMMONS
}
-char *ulmo_call_of_the_ulumuri_info()
+const char *ulmo_call_of_the_ulumuri_info()
{
static char buf[128];
sprintf(buf,
@@ -4764,7 +4454,7 @@ static int wrath_of_ulmo_duration()
return 10 + get_level_s(ULMO_WRATH, 14);
}
-casting_result ulmo_wrath_of_ulmo_spell(int item)
+casting_result ulmo_wrath_of_ulmo_spell()
{
int dir, type = GF_WATER;
@@ -4785,7 +4475,7 @@ casting_result ulmo_wrath_of_ulmo_spell(int item)
return CAST_OBVIOUS;
}
-char *ulmo_wrath_of_ulmo_info()
+const char *ulmo_wrath_of_ulmo_info()
{
static char buf[128];
sprintf(buf,
@@ -4805,7 +4495,7 @@ static int light_of_valinor_radius()
return 5 + get_level_s(VARDA_LIGHT_VALINOR, 6);
}
-casting_result varda_light_of_valinor_spell(int item)
+casting_result varda_light_of_valinor_spell()
{
casting_result result = NO_CAST;
@@ -4831,7 +4521,7 @@ casting_result varda_light_of_valinor_spell(int item)
return result;
}
-char *varda_light_of_valinor_info()
+const char *varda_light_of_valinor_info()
{
static char buf[128];
if (get_level_s(VARDA_LIGHT_VALINOR, 50) >= 15)
@@ -4848,7 +4538,7 @@ char *varda_light_of_valinor_info()
}
}
-casting_result varda_call_of_almaren_spell(int item)
+casting_result varda_call_of_almaren_spell()
{
int power = 5 * p_ptr->lev;
if (get_level_s(VARDA_CALL_ALMAREN, 50) >= 20)
@@ -4862,12 +4552,7 @@ casting_result varda_call_of_almaren_spell(int item)
return CAST_OBVIOUS;
}
-char *varda_call_of_almaren_info()
-{
- return "";
-}
-
-casting_result varda_evenstar_spell(int item)
+casting_result varda_evenstar_spell()
{
wiz_lite_extra();
if (get_level_s(VARDA_EVENSTAR, 50) >= 40)
@@ -4879,11 +4564,6 @@ casting_result varda_evenstar_spell(int item)
return CAST_OBVIOUS;
}
-char *varda_evenstar_info()
-{
- return "";
-}
-
static int star_kindler_bursts()
{
return p_ptr->lev / 5;
@@ -4894,7 +4574,7 @@ static int star_kindler_damage()
return 20 + get_level_s(VARDA_STARKINDLER, 100);
}
-casting_result varda_star_kindler_spell(int item)
+casting_result varda_star_kindler_spell()
{
int dir, i, n = star_kindler_bursts();
@@ -4914,7 +4594,7 @@ casting_result varda_star_kindler_spell(int item)
return CAST_OBVIOUS;
}
-char *varda_star_kindler_info()
+const char *varda_star_kindler_info()
{
static char buf[128];
sprintf(buf,
diff --git a/src/spells3.hpp b/src/spells3.hpp
new file mode 100644
index 00000000..3380203a
--- /dev/null
+++ b/src/spells3.hpp
@@ -0,0 +1,445 @@
+#pragma once
+
+#include "spell_type_fwd.hpp"
+#include "h-basic.h"
+#include "timer_type_fwd.hpp"
+
+extern s32b NOXIOUSCLOUD;
+extern s32b AIRWINGS;
+extern s32b INVISIBILITY;
+extern s32b POISONBLOOD;
+extern s32b THUNDERSTORM;
+extern s32b STERILIZE;
+
+casting_result air_noxious_cloud();
+const char *air_noxious_cloud_info();
+casting_result air_wings_of_winds();
+const char *air_wings_of_winds_info();
+casting_result air_invisibility();
+const char *air_invisibility_info();
+casting_result air_poison_blood();
+const char *air_poison_blood_info();
+casting_result air_thunderstorm();
+const char *air_thunderstorm_info();
+casting_result air_sterilize();
+const char *air_sterilize_info();
+
+extern s32b BLINK;
+extern s32b DISARM;
+extern s32b TELEPORT;
+extern s32b TELEAWAY;
+extern s32b RECALL;
+extern s32b PROBABILITY_TRAVEL;
+
+casting_result convey_blink();
+const char *convey_blink_info();
+casting_result convey_disarm();
+casting_result convey_teleport();
+const char *convey_teleport_info();
+casting_result convey_teleport_away();
+casting_result convey_recall();
+const char *convey_recall_info();
+casting_result convey_probability_travel();
+const char *convey_probability_travel_info();
+
+extern s32b DEMON_BLADE;
+extern s32b DEMON_MADNESS;
+extern s32b DEMON_FIELD;
+extern s32b DOOM_SHIELD;
+extern s32b UNHOLY_WORD;
+extern s32b DEMON_CLOAK;
+extern s32b DEMON_SUMMON;
+extern s32b DISCHARGE_MINION;
+extern s32b CONTROL_DEMON;
+
+casting_result demonology_demon_blade();
+const char *demonology_demon_blade_info();
+casting_result demonology_demon_madness();
+const char *demonology_demon_madness_info();
+casting_result demonology_demon_field();
+const char *demonology_demon_field_info();
+casting_result demonology_doom_shield();
+const char *demonology_doom_shield_info();
+casting_result demonology_unholy_word();
+const char *demonology_unholy_word_info();
+casting_result demonology_demon_cloak();
+const char *demonology_demon_cloak_info();
+casting_result demonology_summon_demon();
+const char *demonology_summon_demon_info();
+casting_result demonology_discharge_minion();
+const char *demonology_discharge_minion_info();
+casting_result demonology_control_demon();
+const char *demonology_control_demon_info();
+
+extern s32b STARIDENTIFY;
+extern s32b IDENTIFY;
+extern s32b VISION;
+extern s32b SENSEHIDDEN;
+extern s32b REVEALWAYS;
+extern s32b SENSEMONSTERS;
+
+casting_result divination_greater_identify();
+casting_result divination_identify();
+const char *divination_identify_info();
+casting_result divination_vision();
+casting_result divination_sense_hidden();
+const char *divination_sense_hidden_info();
+casting_result divination_reveal_ways();
+const char *divination_reveal_ways_info();
+casting_result divination_sense_monsters();
+const char *divination_sense_monsters_info();
+
+extern s32b STONESKIN;
+extern s32b DIG;
+extern s32b STONEPRISON;
+extern s32b STRIKE;
+extern s32b SHAKE;
+
+casting_result earth_stone_skin();
+const char *earth_stone_skin_info();
+casting_result earth_dig();
+casting_result earth_stone_prison();
+casting_result earth_strike();
+const char *earth_strike_info();
+casting_result earth_shake();
+const char *earth_shake_info();
+
+extern s32b ERU_SEE;
+extern s32b ERU_LISTEN;
+extern s32b ERU_UNDERSTAND;
+extern s32b ERU_PROT;
+
+casting_result eru_see_the_music();
+const char *eru_see_the_music_info();
+casting_result eru_listen_to_the_music();
+casting_result eru_know_the_music();
+casting_result eru_lay_of_protection();
+const char *eru_lay_of_protection_info();
+
+extern s32b GLOBELIGHT;
+extern s32b FIREFLASH;
+extern s32b FIERYAURA;
+extern s32b FIREWALL;
+extern s32b FIREGOLEM;
+
+casting_result fire_globe_of_light();
+const char *fire_globe_of_light_info();
+casting_result fire_fireflash();
+const char *fire_fireflash_info();
+casting_result fire_fiery_shield();
+const char *fire_fiery_shield_info();
+casting_result fire_firewall();
+const char *fire_firewall_info();
+casting_result fire_golem();
+const char *fire_golem_info();
+
+extern s32b CALL_THE_ELEMENTS;
+extern s32b CHANNEL_ELEMENTS;
+extern s32b ELEMENTAL_WAVE;
+extern s32b VAPORIZE;
+extern s32b GEOLYSIS;
+extern s32b DRIPPING_TREAD;
+extern s32b GROW_BARRIER;
+extern s32b ELEMENTAL_MINION;
+
+casting_result geomancy_call_the_elements();
+const char *geomancy_call_the_elements_info();
+casting_result geomancy_channel_elements();
+casting_result geomancy_elemental_wave();
+casting_result geomancy_vaporize();
+const char *geomancy_vaporize_info();
+bool_ geomancy_vaporize_depends();
+casting_result geomancy_geolysis();
+const char *geomancy_geolysis_info();
+bool_ geomancy_geolysis_depends();
+casting_result geomancy_dripping_tread();
+const char *geomancy_dripping_tread_info();
+bool_ geomancy_dripping_tread_depends();
+casting_result geomancy_grow_barrier();
+bool_ geomancy_grow_barrier_depends();
+casting_result geomancy_elemental_minion();
+const char *geomancy_elemental_minion_info();
+
+extern s32b MANATHRUST;
+extern s32b DELCURSES;
+extern s32b RESISTS;
+extern s32b MANASHIELD;
+
+casting_result mana_manathrust();
+const char *mana_manathrust_info();
+casting_result mana_remove_curses();
+casting_result mana_elemental_shield();
+const char *mana_elemental_shield_info();
+casting_result mana_disruption_shield();
+const char *mana_disruption_shield_info();
+
+extern s32b MANWE_SHIELD;
+extern s32b MANWE_AVATAR;
+extern s32b MANWE_BLESS;
+extern s32b MANWE_CALL;
+
+casting_result manwe_wind_shield();
+const char *manwe_wind_shield_info();
+casting_result manwe_avatar();
+const char *manwe_avatar_info();
+casting_result manwe_blessing();
+const char *manwe_blessing_info();
+casting_result manwe_call();
+const char *manwe_call_info();
+
+extern s32b MELKOR_CURSE;
+extern s32b MELKOR_CORPSE_EXPLOSION;
+extern s32b MELKOR_MIND_STEAL;
+
+void do_melkor_curse(int m_idx);
+
+casting_result melkor_curse();
+casting_result melkor_corpse_explosion();
+const char *melkor_corpse_explosion_info();
+casting_result melkor_mind_steal();
+const char *melkor_mind_steal_info();
+
+extern s32b RECHARGE;
+extern s32b SPELLBINDER;
+extern s32b DISPERSEMAGIC;
+extern s32b TRACKER;
+extern s32b INERTIA_CONTROL;
+extern timer_type *TIMER_INERTIA_CONTROL;
+
+casting_result meta_recharge();
+const char *meta_recharge_info();
+casting_result meta_spellbinder();
+const char *meta_spellbinder_info();
+casting_result meta_disperse_magic();
+casting_result meta_tracker();
+casting_result meta_inertia_control();
+const char *meta_inertia_control_info();
+
+void meta_inertia_control_timer_callback();
+void meta_inertia_control_calc_mana(int *msp);
+void meta_inertia_control_hook_birth_objects();
+
+extern s32b CHARM;
+extern s32b CONFUSE;
+extern s32b ARMOROFFEAR;
+extern s32b STUN;
+
+casting_result mind_charm();
+const char *mind_charm_info();
+casting_result mind_confuse();
+const char *mind_confuse_info();
+casting_result mind_armor_of_fear();
+const char *mind_armor_of_fear_info();
+casting_result mind_stun();
+const char *mind_stun_info();
+
+extern s32b MAGELOCK;
+extern s32b SLOWMONSTER;
+extern s32b ESSENCESPEED;
+extern s32b BANISHMENT;
+
+casting_result tempo_magelock();
+casting_result tempo_slow_monster();
+const char *tempo_slow_monster_info();
+casting_result tempo_essence_of_speed();
+const char *tempo_essence_of_speed_info();
+casting_result tempo_banishment();
+const char *tempo_banishment_info();
+
+extern s32b TULKAS_AIM;
+extern s32b TULKAS_WAVE;
+extern s32b TULKAS_SPIN;
+
+casting_result tulkas_divine_aim();
+const char *tulkas_divine_aim_info();
+casting_result tulkas_wave_of_power();
+const char *tulkas_wave_of_power_info();
+casting_result tulkas_whirlwind();
+
+extern s32b DRAIN;
+extern s32b GENOCIDE;
+extern s32b WRAITHFORM;
+extern s32b FLAMEOFUDUN;
+
+int udun_in_book(s32b sval, s32b pval);
+int levels_in_book(s32b sval, s32b pval);
+
+casting_result udun_drain();
+casting_result udun_genocide();
+casting_result udun_wraithform();
+const char *udun_wraithform_info();
+casting_result udun_flame_of_udun();
+const char *udun_flame_of_udun_info();
+
+extern s32b TIDALWAVE;
+extern s32b ICESTORM;
+extern s32b ENTPOTION;
+extern s32b VAPOR;
+extern s32b GEYSER;
+
+casting_result water_tidal_wave();
+const char *water_tidal_wave_info();
+casting_result water_ice_storm();
+const char *water_ice_storm_info();
+casting_result water_ent_potion();
+const char *water_ent_potion_info();
+casting_result water_vapor();
+const char *water_vapor_info();
+casting_result water_geyser();
+const char *water_geyser_info();
+
+extern s32b YAVANNA_CHARM_ANIMAL;
+extern s32b YAVANNA_GROW_GRASS;
+extern s32b YAVANNA_TREE_ROOTS;
+extern s32b YAVANNA_WATER_BITE;
+extern s32b YAVANNA_UPROOT;
+
+casting_result yavanna_charm_animal();
+const char *yavanna_charm_animal_info();
+casting_result yavanna_grow_grass();
+const char *yavanna_grow_grass_info();
+casting_result yavanna_tree_roots();
+const char *yavanna_tree_roots_info();
+casting_result yavanna_water_bite();
+const char *yavanna_water_bite_info();
+casting_result yavanna_uproot();
+const char *yavanna_uproot_info();
+
+extern s32b GROWTREE;
+extern s32b HEALING;
+extern s32b RECOVERY;
+extern s32b REGENERATION;
+extern s32b SUMMONANNIMAL;
+extern s32b GROW_ATHELAS;
+
+casting_result nature_grow_trees();
+const char *nature_grow_trees_info();
+casting_result nature_healing();
+const char *nature_healing_info();
+casting_result nature_recovery();
+casting_result nature_regeneration();
+const char *nature_regeneration_info();
+casting_result nature_summon_animal();
+const char *nature_summon_animal_info();
+casting_result nature_grow_athelas();
+
+extern s32b DEVICE_HEAL_MONSTER;
+extern s32b DEVICE_SPEED_MONSTER;
+extern s32b DEVICE_WISH;
+extern s32b DEVICE_SUMMON;
+extern s32b DEVICE_MANA;
+extern s32b DEVICE_NOTHING;
+extern s32b DEVICE_HOLY_FIRE;
+extern s32b DEVICE_THUNDERLORDS;
+
+casting_result device_heal_monster();
+const char *device_heal_monster_info();
+casting_result device_haste_monster();
+const char *device_haste_monster_info();
+casting_result device_wish();
+casting_result device_summon_monster();
+casting_result device_mana();
+const char *device_mana_info();
+casting_result device_nothing();
+casting_result device_holy_fire();
+const char *device_holy_fire_info();
+casting_result device_thunderlords();
+
+extern s32b MUSIC_STOP;
+extern s32b MUSIC_HOLD;
+extern s32b MUSIC_CONF;
+extern s32b MUSIC_STUN;
+extern s32b MUSIC_LITE;
+extern s32b MUSIC_HEAL;
+extern s32b MUSIC_HERO;
+extern s32b MUSIC_TIME;
+extern s32b MUSIC_MIND;
+extern s32b MUSIC_BLOW;
+extern s32b MUSIC_WIND;
+extern s32b MUSIC_YLMIR;
+extern s32b MUSIC_AMBARKANTA;
+
+casting_result music_stop_singing_spell();
+int music_holding_pattern_lasting();
+casting_result music_holding_pattern_spell();
+const char *music_holding_pattern_info();
+int music_illusion_pattern_lasting();
+casting_result music_illusion_pattern_spell();
+const char *music_illusion_pattern_info();
+int music_stun_pattern_lasting();
+casting_result music_stun_pattern_spell();
+const char *music_stun_pattern_info();
+int music_song_of_the_sun_lasting();
+casting_result music_song_of_the_sun_spell();
+int music_flow_of_life_lasting();
+casting_result music_flow_of_life_spell();
+const char *music_flow_of_life_info();
+int music_heroic_ballad_lasting();
+casting_result music_heroic_ballad_spell();
+int music_hobbit_melodies_lasting();
+casting_result music_hobbit_melodies_spell();
+const char *music_hobbit_melodies_info();
+int music_clairaudience_lasting();
+casting_result music_clairaudience_spell();
+const char *music_clairaudience_info();
+casting_result music_blow_spell();
+const char *music_blow_info();
+casting_result music_gush_of_wind_spell();
+const char *music_gush_of_wind_info();
+casting_result music_horns_of_ylmir_spell();
+const char *music_horns_of_ylmir_info();
+casting_result music_ambarkanta_spell();
+
+extern s32b AULE_FIREBRAND;
+extern s32b AULE_ENCHANT_WEAPON;
+extern s32b AULE_ENCHANT_ARMOUR;
+extern s32b AULE_CHILD;
+
+casting_result aule_firebrand_spell();
+const char *aule_firebrand_info();
+casting_result aule_enchant_weapon_spell();
+const char *aule_enchant_weapon_info();
+casting_result aule_enchant_armour_spell();
+const char *aule_enchant_armour_info();
+casting_result aule_child_spell();
+const char *aule_child_info();
+
+extern s32b MANDOS_TEARS_LUTHIEN;
+extern s32b MANDOS_SPIRIT_FEANTURI;
+extern s32b MANDOS_TALE_DOOM;
+extern s32b MANDOS_CALL_HALLS;
+
+casting_result mandos_tears_of_luthien_spell();
+const char *mandos_tears_of_luthien_info();
+casting_result mandos_spirit_of_the_feanturi_spell();
+const char *mandos_spirit_of_the_feanturi_info();
+casting_result mandos_tale_of_doom_spell();
+const char *mandos_tale_of_doom_info();
+casting_result mandos_call_to_the_halls_spell();
+const char *mandos_call_to_the_halls_info();
+
+extern s32b ULMO_BELEGAER;
+extern s32b ULMO_DRAUGHT_ULMONAN;
+extern s32b ULMO_CALL_ULUMURI;
+extern s32b ULMO_WRATH;
+
+casting_result ulmo_song_of_belegaer_spell();
+const char *ulmo_song_of_belegaer_info();
+casting_result ulmo_draught_of_ulmonan_spell();
+const char *ulmo_draught_of_ulmonan_info();
+casting_result ulmo_call_of_the_ulumuri_spell();
+const char *ulmo_call_of_the_ulumuri_info();
+casting_result ulmo_wrath_of_ulmo_spell();
+const char *ulmo_wrath_of_ulmo_info();
+
+extern s32b VARDA_LIGHT_VALINOR;
+extern s32b VARDA_CALL_ALMAREN;
+extern s32b VARDA_EVENSTAR;
+extern s32b VARDA_STARKINDLER;
+
+casting_result varda_light_of_valinor_spell();
+const char *varda_light_of_valinor_info();
+casting_result varda_call_of_almaren_spell();
+casting_result varda_evenstar_spell();
+casting_result varda_star_kindler_spell();
+const char *varda_star_kindler_info();
diff --git a/src/spells4.c b/src/spells4.cc
index c977742d..3c877bf2 100644
--- a/src/spells4.c
+++ b/src/spells4.cc
@@ -1,10 +1,29 @@
-#include "angband.h"
-
-#include <assert.h>
-
-#include "spell_type.h"
+#include "spells4.hpp"
+
+#include "cave.hpp"
+#include "cmd5.hpp"
+#include "gods.hpp"
+#include "lua_bind.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "school_book.hpp"
+#include "spell_type.hpp"
+#include "spells3.hpp"
+#include "spells5.hpp"
+#include "spells6.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.hpp"
+
+#include <algorithm>
+#include <cassert>
+#include <sstream>
+
+static std::array<school_book, SCHOOL_BOOKS_SIZE> &school_books() {
+ static std::array<school_book, SCHOOL_BOOKS_SIZE> *instance = new std::array<school_book, SCHOOL_BOOKS_SIZE>;
+ return *instance;
+}
-school_book_type school_books[SCHOOL_BOOKS_SIZE];
s32b SCHOOL_AIR;
s32b SCHOOL_AULE;
@@ -32,13 +51,6 @@ s32b SCHOOL_VARDA;
s32b SCHOOL_WATER;
s32b SCHOOL_YAVANNA;
-static int compare_spell_idx(spell_idx_list *a, spell_idx_list *b)
-{
- return SGLIB_NUMERIC_COMPARATOR(a->i, b->i);
-}
-
-SGLIB_DEFINE_LIST_FUNCTIONS(spell_idx_list, compare_spell_idx, next);
-
static bool_ uses_piety_to_cast(int s)
{
return spell_type_uses_piety_to_cast(spell_at(s));
@@ -69,22 +81,16 @@ s32b get_power(s32b s)
return uses_piety_to_cast(s) ? p_ptr->grace : p_ptr->csp;
}
-static void print_spell_desc_callback(void *data, cptr text)
-{
- int *y = (int *) data;
-
- c_prt(TERM_L_BLUE, text, *y, 0);
- (*y) += 1;
-}
-
/* Output the describtion when it is used as a spell */
void print_spell_desc(int s, int y)
{
spell_type *spell = spell_at(s);
spell_type_description_foreach(spell,
- print_spell_desc_callback,
- &y);
+ [&y] (std::string const &text) -> void {
+ c_prt(TERM_L_BLUE, text.c_str(), y, 0);
+ y += 1;
+ });
if (spell_type_uses_piety_to_cast(spell))
{
@@ -105,115 +111,59 @@ void print_spell_desc(int s, int y)
}
}
-school_book_type *school_books_at(int i)
+school_book *school_books_at(int i)
{
assert(i >= 0);
assert(i < SCHOOL_BOOKS_SIZE);
- return &school_books[i];
+ return &school_books()[i];
}
-static void school_book_init(school_book_type *school_book)
+void school_book_add_spell(school_book *school_book, s32b spell_idx)
{
- school_book->spell_idx_list = NULL;
-}
-
-static void spell_idx_init(spell_idx_list *p, s32b spell_idx)
-{
- assert(p != NULL);
-
- p->i = spell_idx;
- p->next = NULL;
-}
-
-static spell_idx_list *new_spell_idx(void *ctx, s32b spell_idx)
-{
- spell_idx_list *e = malloc(sizeof(spell_idx_list));
- spell_idx_init(e, spell_idx);
- return e;
-}
-
-void school_book_add_spell(school_book_type *school_book, s32b spell_idx)
-{
- spell_idx_list *e;
-
- assert(school_book != NULL);
-
- e = new_spell_idx(school_book, spell_idx);
- sglib_spell_idx_list_add(&school_book->spell_idx_list, e);
+ assert(school_book != nullptr);
+ school_book->spell_idxs.insert(std::begin(school_book->spell_idxs), spell_idx);
}
int school_book_length(int sval)
{
- school_book_type *school_book = school_books_at(sval);
-
- if (sval == BOOK_RANDOM)
- {
- return 1;
- }
-
- /* Parse all spells */
- return sglib_spell_idx_list_len(school_book->spell_idx_list);
+ school_book *school_book = school_books_at(sval);
+ return school_book->spell_idxs.size();
}
-int spell_x(int sval, int pval, int i)
+int spell_x(int sval, int spell_idx, int i)
{
assert(i >= 0);
if (sval == BOOK_RANDOM)
{
- return pval;
+ return spell_idx;
}
else
{
- school_book_type *school_book;
- spell_idx_list *spell_idx = NULL;
- struct sglib_spell_idx_list_iterator it;
-
- school_book = school_books_at(sval);
-
- for (spell_idx = sglib_spell_idx_list_it_init(&it, school_book->spell_idx_list);
- (spell_idx != NULL) && (i > 0);
- spell_idx = sglib_spell_idx_list_it_next(&it))
- {
- i--;
- }
-
- assert(spell_idx != NULL); /* Went off the end of the list? */
-
- return spell_idx->i;
+ school_book *school_book = school_books_at(sval);
+ return school_book->spell_idxs.at(i);
}
}
bool_ school_book_contains_spell(int sval, s32b spell_idx)
{
- school_book_type *school_book = NULL;
- spell_idx_list e;
-
random_book_setup(sval, spell_idx);
-
- school_book = school_books_at(sval);
-
- spell_idx_init(&e, spell_idx);
- return NULL != sglib_spell_idx_list_find_member(school_book->spell_idx_list, &e);
+ school_book *school_book = school_books_at(sval);
+ return (school_book->spell_idxs.end() !=
+ std::find(school_book->spell_idxs.begin(),
+ school_book->spell_idxs.end(),
+ spell_idx));
}
-void push_spell(int book_idx, s32b spell_idx)
+static void push_spell(int book_idx, s32b spell_idx)
{
- school_book_type *school_book = school_books_at(book_idx);
+ school_book *school_book = school_books_at(book_idx);
assert(school_book != NULL);
school_book_add_spell(school_book, spell_idx);
}
void init_school_books()
{
- int i;
-
- /* Initialize the new school books */
- for (i = 0; i<SCHOOL_BOOKS_SIZE; i++)
- {
- school_book_init(&school_books[i]);
- }
-
/* Note: We're adding the spells in the reverse order that
they appear in each book. This is because the list
operations insert at the front. */
@@ -435,37 +385,34 @@ void random_book_setup(s16b sval, s32b spell_idx)
{
if (sval == BOOK_RANDOM)
{
- school_book_type *school_book = school_books_at(sval);
-
- assert(school_book->spell_idx_list != NULL);
- school_book->spell_idx_list->i = spell_idx;
+ school_book *school_book = school_books_at(sval);
+ school_book->spell_idxs.clear();
+ school_book->spell_idxs.push_back(spell_idx);
}
}
-static bool_ spell_school_name_callback(void *data, s32b sch)
+static std::string spell_school_name(spell_type *spell)
{
- school_type *school = school_at(sch);
- char *buf = (char *) data;
+ std::ostringstream buf;
+ bool first = true;
- /* Add separator? */
- if (buf[0] != '\0')
+ for (s32b school_idx : spell_type_get_schools(spell))
{
- strcat(buf, "/");
+ school_type *school = school_at(school_idx);
+ // Add separator?
+ if (first)
+ {
+ first = false; // Skip separator
+ }
+ else
+ {
+ buf << "/";
+ }
+ // Put in the school's name
+ buf << school->name;
}
- /* Add school name */
- strcat(buf, school->name);
-
- /* Keep going */
- return TRUE;
-}
-
-static void spell_school_name(char *buf, spell_type *spell)
-{
- buf[0] = '\0';
- spell_type_school_foreach(spell,
- spell_school_name_callback,
- buf);
+ return buf.str();
}
int print_spell(cptr label_, byte color, int y, s32b s)
@@ -473,14 +420,14 @@ int print_spell(cptr label_, byte color, int y, s32b s)
s32b level;
bool_ na;
spell_type *spell = spell_at(s);
- char sch_str[128];
cptr spell_info = spell_type_info(spell);
cptr label = (label_ == NULL) ? "" : label_;
char level_str[8] = "n/a";
char buf[128];
- get_level_school(s, 50, -50, &level, &na);
- spell_school_name(sch_str, spell);
+ get_level_school(spell, 50, -50, &level, &na);
+
+ std::string sch_str(spell_school_name(spell));
if (!na)
{
@@ -490,48 +437,42 @@ int print_spell(cptr label_, byte color, int y, s32b s)
sprintf(buf, "%s%-20s%-16s %s %4d %3d%% %s",
label,
spell_type_name(spell_at(s)),
- sch_str,
+ sch_str.c_str(),
level_str,
get_mana(s),
- (int) spell_chance(s),
+ (int) spell_chance_book(s),
spell_info);
c_prt(color, buf, y, 0);
return y + 1;
}
-int print_book(s16b sval, s32b pval, object_type *obj)
+int print_book(s16b sval, s32b spell_idx, object_type *obj)
{
int y = 2;
int i;
- school_book_type *school_book;
- spell_idx_list *spell_idx;
- struct sglib_spell_idx_list_iterator it;
- random_book_setup(sval, pval);
+ random_book_setup(sval, spell_idx);
- school_book = school_books_at(sval);
+ school_book *school_book = school_books_at(sval);
/* Parse all spells */
i = 0;
- for (spell_idx = sglib_spell_idx_list_it_init(&it, school_book->spell_idx_list);
- spell_idx != NULL;
- spell_idx = sglib_spell_idx_list_it_next(&it))
+ for (auto spell_idx : school_book->spell_idxs)
{
- s32b s = spell_idx->i;
byte color = TERM_L_DARK;
bool_ is_ok;
char label[8];
- is_ok = is_ok_spell(s, obj);
+ is_ok = is_ok_spell(spell_idx, obj->pval);
if (is_ok)
{
- color = (get_mana(s) > get_power(s)) ? TERM_ORANGE : TERM_L_GREEN;
+ color = (get_mana(spell_idx) > get_power(spell_idx)) ? TERM_ORANGE : TERM_L_GREEN;
}
sprintf(label, "%c) ", 'a' + i);
- y = print_spell(label, color, y, s);
+ y = print_spell(label, color, y, spell_idx);
i++;
}
@@ -592,9 +533,9 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
/* Invoke the spell effect */
- if (!magik(spell_chance(s)))
+ if (!magik(spell_chance_book(s)))
{
- use = (spell_type_produce_effect(spell, -1) != NO_CAST);
+ use = (spell_type_produce_effect(spell) != NO_CAST);
}
else
{
@@ -612,7 +553,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
else
{
- spell_type_produce_effect(spell, -1);
+ spell_type_produce_effect(spell);
}
/* Use the mana/piety */
@@ -626,124 +567,6 @@ void lua_cast_school_spell(s32b s, bool_ no_cost)
}
/* Refresh player */
- p_ptr->redraw |= PR_MANA;
+ p_ptr->redraw |= PR_FRAME;
p_ptr->window |= PW_PLAYER;
}
-
-void device_allocation_init(device_allocation *device_allocation, byte tval)
-{
- assert(device_allocation != NULL);
-
- device_allocation->tval = tval;
- device_allocation->rarity = 0;
- range_init(&device_allocation->base_level, 0, 0);
- range_init(&device_allocation->max_level, 0, 0);
- device_allocation->next = NULL;
-}
-
-device_allocation *device_allocation_new(byte tval)
-{
- device_allocation *d = malloc(sizeof(device_allocation));
- device_allocation_init(d, tval);
- return d;
-}
-
-int compare_device_allocation(device_allocation *a, device_allocation *b)
-{
- return SGLIB_NUMERIC_COMPARATOR(a->tval, b->tval);
-}
-
-SGLIB_DEFINE_LIST_FUNCTIONS(device_allocation, compare_device_allocation, next);
-
-void dice_init(dice_type *dice, long base, long num, long sides)
-{
- assert(dice != NULL);
-
- dice->base = base;
- dice->num = num;
- dice->sides = sides;
-}
-
-bool_ dice_parse(dice_type *dice, cptr s)
-{
- long base, num, sides;
-
- if (sscanf(s, "%ld+%ldd%ld", &base, &num, &sides) == 3)
- {
- dice_init(dice, base, num, sides);
- return TRUE;
- }
-
- if (sscanf(s, "%ld+d%ld", &base, &sides) == 2)
- {
- dice_init(dice, base, 1, sides);
- return TRUE;
- }
-
- if (sscanf(s, "d%ld", &sides) == 1)
- {
- dice_init(dice, 0, 1, sides);
- return TRUE;
- }
-
- if (sscanf(s, "%ldd%ld", &num, &sides) == 2)
- {
- dice_init(dice, 0, num, sides);
- return TRUE;
- }
-
- if (sscanf(s, "%ld", &base) == 1)
- {
- dice_init(dice, base, 0, 0);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void dice_parse_checked(dice_type *dice, cptr s)
-{
- bool_ result = dice_parse(dice, s);
- if (!result)
- {
- abort();
- }
-}
-
-long dice_roll(dice_type *dice)
-{
- assert(dice != NULL);
- return dice->base + damroll(dice->num, dice->sides);
-}
-
-void dice_print(dice_type *dice, char *output)
-{
- char buf[16];
-
- output[0] = '\0';
-
- if (dice->base > 0)
- {
- sprintf(buf, "%ld", dice->base);
- strcat(output, buf);
- }
-
- if ((dice->num > 0) || (dice->sides > 0))
- {
- if (dice->base > 0)
- {
- strcat(output, "+");
- }
-
- if (dice->num > 1)
- {
- sprintf(buf, "%ld", dice->num);
- strcat(output, buf);
- }
-
- strcat(output, "d");
-
- sprintf(buf, "%ld", dice->sides);
- strcat(output, buf);
- }
-}
diff --git a/src/spells4.hpp b/src/spells4.hpp
new file mode 100644
index 00000000..99203ef8
--- /dev/null
+++ b/src/spells4.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+#include "school_book_fwd.hpp"
+
+extern s32b SCHOOL_AIR;
+extern s32b SCHOOL_AULE;
+extern s32b SCHOOL_CONVEYANCE;
+extern s32b SCHOOL_DEMON;
+extern s32b SCHOOL_DEVICE;
+extern s32b SCHOOL_DIVINATION;
+extern s32b SCHOOL_EARTH;
+extern s32b SCHOOL_ERU;
+extern s32b SCHOOL_FIRE;
+extern s32b SCHOOL_GEOMANCY;
+extern s32b SCHOOL_MANA;
+extern s32b SCHOOL_MANDOS;
+extern s32b SCHOOL_MANWE;
+extern s32b SCHOOL_MELKOR;
+extern s32b SCHOOL_META;
+extern s32b SCHOOL_MIND;
+extern s32b SCHOOL_MUSIC;
+extern s32b SCHOOL_NATURE;
+extern s32b SCHOOL_TEMPORAL;
+extern s32b SCHOOL_TULKAS;
+extern s32b SCHOOL_UDUN;
+extern s32b SCHOOL_ULMO;
+extern s32b SCHOOL_VARDA;
+extern s32b SCHOOL_WATER;
+extern s32b SCHOOL_YAVANNA;
+
+void print_spell_desc(int s, int y);
+void init_school_books();
+school_book *school_books_at(int sval);
+void school_book_add_spell(school_book *school_book, s32b spell_idx);
+void random_book_setup(s16b sval, s32b spell_idx);
+int print_spell(cptr label, byte color, int y, s32b s);
+int print_book(s16b sval, s32b spell_idx, object_type *obj);
+int school_book_length(int sval);
+int spell_x(int sval, int spell_idx, int i);
+bool_ school_book_contains_spell(int sval, s32b spell_idx);
+void lua_cast_school_spell(s32b spell_idx, bool_ no_cost);
diff --git a/src/spells5.c b/src/spells5.cc
index 7ad0d3b9..ca6351b6 100644
--- a/src/spells5.c
+++ b/src/spells5.cc
@@ -1,10 +1,17 @@
-#include <angband.h>
+#include "spells5.hpp"
-#include <assert.h>
+#include "spell_type.hpp"
+#include "device_allocation.hpp"
+#include "spells3.hpp"
+#include "spells4.hpp"
+#include "variable.hpp"
-#include "spell_type.h"
+#include <cassert>
-static spell_type *spell_new(s32b *index, cptr id, cptr name)
+static s16b school_spells_count = 0;
+static struct spell_type *school_spells[SCHOOL_SPELLS_MAX];
+
+static spell_type *spell_new(s32b *index, cptr name)
{
assert(school_spells_count < SCHOOL_SPELLS_MAX);
@@ -16,6 +23,11 @@ static spell_type *spell_new(s32b *index, cptr id, cptr name)
return spell;
}
+static cptr no_info()
+{
+ return "";
+}
+
spell_type *spell_at(s32b index)
{
assert(index >= 0);
@@ -59,37 +71,39 @@ s16b get_random_spell(s16b random_type, int level)
return -1;
}
-static void spells_init_tome()
+/*
+ * Get a spell for a device of a given tval (wand or staff).
+ */
+s16b get_random_stick(byte tval, int level)
{
- {
- spell_type *spell = spell_new(&DEVICE_LEBOHAUM, "DEVICE_LEBOHAUM", "Artifact Lebauhaum");
- spell_type_set_activation_timeout(spell, "3");
- spell_type_describe(spell, "sing a cheerful song");
- spell_type_set_mana(spell, 0, 0);
- spell_type_set_difficulty(spell, 1, 0);
- spell_type_init_device(spell,
- device_lebohaum_info,
- device_lebohaum);
- }
+ int tries;
+ for (tries = 0; tries < 1000; tries++)
{
- spell_type *spell = spell_new(&DEVICE_DURANDIL, "DEVICE_DURANDIL", "Artifact Durandil");
- spell_type_set_activation_timeout(spell, "3");
- spell_type_describe(spell, "sing a cheerful song");
- spell_type_set_mana(spell, 0, 0);
- spell_type_set_difficulty(spell, 1, 0);
- spell_type_init_device(spell,
- device_durandil_info,
- device_durandil);
+ long spell_idx = rand_int(school_spells_count);
+ spell_type *spell = spell_at(spell_idx);
+ device_allocation *device_allocation = spell_type_device_allocation(spell, tval);
+
+ if ((device_allocation != NULL) &&
+ (rand_int(spell_type_skill_level(spell) * 3) < level) &&
+ (magik(100 - device_allocation->rarity)))
+ {
+ return spell_idx;
+ }
}
+ return -1;
+}
+
+static void spells_init_tome()
+{
{
- spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "DEVICE_THUNDERLORDS", "Artifact Thunderlords");
+ spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "Artifact Thunderlords");
spell_type_describe(spell, "A thunderlord will appear to transport you quickly to the surface.");
spell_type_set_mana(spell, 1, 1);
spell_type_set_difficulty(spell, 1, 20);
spell_type_init_device(spell,
- device_thunderlords_info,
+ no_info,
device_thunderlords);
spell_type_set_device_charges(spell, "3+d3");
@@ -107,14 +121,14 @@ static void spells_init_tome()
static void spells_init_theme()
{
{
- spell_type *spell = spell_new(&GROW_ATHELAS, "GROW_ATHELAS", "Grow Athelas");
+ spell_type *spell = spell_new(&GROW_ATHELAS, "Grow Athelas");
spell_type_describe(spell, "Cures the Black Breath");
spell_type_set_mana(spell, 60, 100);
spell_type_set_difficulty(spell, 30, 95);
spell_type_init_mage(spell,
RANDOM,
SCHOOL_NATURE,
- nature_grow_athelas_info,
+ no_info,
nature_grow_athelas);
spell_type_set_device_charges(spell, "1+d3");
@@ -129,7 +143,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&AULE_FIREBRAND, "AULE_FIREBRAND", "Firebrand");
+ spell_type *spell = spell_new(&AULE_FIREBRAND, "Firebrand");
spell_type_describe(spell, "Imbues your melee weapon with fire to deal more damage");
spell_type_describe(spell, "At level 15 it spreads over a 1 radius zone around your target");
spell_type_describe(spell, "At level 30 it deals holy fire damage");
@@ -142,7 +156,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&AULE_ENCHANT_WEAPON, "AULE_ENCHANT_WEAPON", "Enchant Weapon");
+ spell_type *spell = spell_new(&AULE_ENCHANT_WEAPON, "Enchant Weapon");
spell_type_describe(spell, "Tries to enchant a weapon to-hit");
spell_type_describe(spell, "At level 5 it also enchants to-dam");
spell_type_describe(spell, "At level 45 it enhances the special powers of magical weapons");
@@ -156,7 +170,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&AULE_ENCHANT_ARMOUR, "AULE_ENCHANT_ARMOUR", "Enchant Armour");
+ spell_type *spell = spell_new(&AULE_ENCHANT_ARMOUR, "Enchant Armour");
spell_type_describe(spell, "Tries to enchant a piece of armour");
spell_type_describe(spell, "At level 20 it also enchants to-hit and to-dam");
spell_type_describe(spell, "At level 40 it enhances the special powers of magical armour");
@@ -170,7 +184,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&AULE_CHILD, "AULE_CHILD", "Child of Aule");
+ spell_type *spell = spell_new(&AULE_CHILD, "Child of Aule");
spell_type_describe(spell, "Summons a levelled Dwarven warrior to help you battle the forces");
spell_type_describe(spell, "of Morgoth");
spell_type_set_mana(spell, 200, 500);
@@ -182,7 +196,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&VARDA_LIGHT_VALINOR, "VARDA_LIGHT_VALINOR", "Light of Valinor");
+ spell_type *spell = spell_new(&VARDA_LIGHT_VALINOR, "Light of Valinor");
spell_type_describe(spell, "Lights a room");
spell_type_describe(spell, "At level 3 it starts damaging monsters");
spell_type_describe(spell, "At level 15 it starts creating a more powerful kind of light");
@@ -195,19 +209,19 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&VARDA_CALL_ALMAREN, "VARDA_CALL_ALMAREN", "Call of Almaren");
+ spell_type *spell = spell_new(&VARDA_CALL_ALMAREN, "Call of Almaren");
spell_type_describe(spell, "Banishes evil beings");
spell_type_describe(spell, "At level 20 it dispels evil beings");
spell_type_set_mana(spell, 5, 150);
spell_type_set_difficulty(spell, 10, 20);
spell_type_init_priest(spell,
SCHOOL_VARDA,
- varda_call_of_almaren_info,
+ no_info,
varda_call_of_almaren_spell);
}
{
- spell_type *spell = spell_new(&VARDA_EVENSTAR, "VARDA_EVENSTAR", "Evenstar");
+ spell_type *spell = spell_new(&VARDA_EVENSTAR, "Evenstar");
spell_type_describe(spell, "Maps and lights the whole level.");
spell_type_describe(spell, "At level 40 it maps and lights the whole level,");
spell_type_describe(spell, "in addition to letting you know yourself better");
@@ -216,12 +230,12 @@ static void spells_init_theme()
spell_type_set_difficulty(spell, 20, 20);
spell_type_init_priest(spell,
SCHOOL_VARDA,
- varda_evenstar_info,
+ no_info,
varda_evenstar_spell);
}
{
- spell_type *spell = spell_new(&VARDA_STARKINDLER, "VARDA_STARKINDLER", "Star Kindler");
+ spell_type *spell = spell_new(&VARDA_STARKINDLER, "Star Kindler");
spell_type_describe(spell, "Does multiple bursts of light damage.");
spell_type_describe(spell, "The damage increases with level.");
spell_type_set_mana(spell, 50, 250);
@@ -233,7 +247,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&ULMO_BELEGAER, "ULMO_BELEGAER", "Song of Belegaer");
+ spell_type *spell = spell_new(&ULMO_BELEGAER, "Song of Belegaer");
spell_type_describe(spell, "Channels the power of the Great Sea into your fingertips.");
spell_type_describe(spell, "Sometimes it can blast through its first target.");
spell_type_set_mana(spell, 1, 100);
@@ -245,7 +259,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&ULMO_DRAUGHT_ULMONAN, "ULMO_DRAUGHT_ULMONAN", "Draught of Ulmonan");
+ spell_type *spell = spell_new(&ULMO_DRAUGHT_ULMONAN, "Draught of Ulmonan");
spell_type_describe(spell, "Fills you with a draught with powerful curing effects,");
spell_type_describe(spell, "prepared by Ulmo himself.");
spell_type_describe(spell, "Level 1: blindness, poison, cuts and stunning");
@@ -260,7 +274,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&ULMO_CALL_ULUMURI, "ULMO_CALL_ULUMURI", "Call of the Ulumuri");
+ spell_type *spell = spell_new(&ULMO_CALL_ULUMURI, "Call of the Ulumuri");
spell_type_describe(spell, "Summons a leveled water spirit or elemental");
spell_type_describe(spell, "to fight for you");
spell_type_set_mana(spell, 50, 300);
@@ -272,7 +286,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&ULMO_WRATH, "ULMO_WRATH", "Wrath of Ulmo");
+ spell_type *spell = spell_new(&ULMO_WRATH, "Wrath of Ulmo");
spell_type_describe(spell, "Conjures up a sea storm.");
spell_type_describe(spell, "At level 30 it turns into a more forceful storm.");
spell_type_set_mana(spell, 100, 400);
@@ -284,7 +298,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&MANDOS_TEARS_LUTHIEN, "MANDOS_TEARS_LUTHIEN", "Tears of Luthien");
+ spell_type *spell = spell_new(&MANDOS_TEARS_LUTHIEN, "Tears of Luthien");
spell_type_describe(spell, "Calls upon the spirit of Luthien to ask Mandos for healing and succour.");
spell_type_set_mana(spell, 10, 100);
spell_type_set_difficulty(spell, 5, 25);
@@ -295,7 +309,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&MANDOS_SPIRIT_FEANTURI, "MANDOS_SPIRIT_FEANTURI", "Feanturi");
+ spell_type *spell = spell_new(&MANDOS_SPIRIT_FEANTURI, "Feanturi");
spell_type_describe(spell, "Channels the power of Mandos to cure fear and confusion.");
spell_type_describe(spell, "At level 20 it restores lost INT and WIS");
spell_type_describe(spell, "At level 30 it cures hallucinations and restores a percentage of lost sanity");
@@ -308,7 +322,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&MANDOS_TALE_DOOM, "MANDOS_TALE_DOOM", "Tale of Doom");
+ spell_type *spell = spell_new(&MANDOS_TALE_DOOM, "Tale of Doom");
spell_type_describe(spell, "Allows you to predict the future for a short time.");
spell_type_set_mana(spell, 60, 300);
spell_type_set_difficulty(spell, 25, 75);
@@ -319,7 +333,7 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&MANDOS_CALL_HALLS, "MANDOS_CALL_HALLS", "Call to the Halls");
+ spell_type *spell = spell_new(&MANDOS_CALL_HALLS, "Call to the Halls");
spell_type_describe(spell, "Summons a leveled spirit from the Halls of Mandos");
spell_type_describe(spell, "to fight for you.");
spell_type_set_mana(spell, 80, 400);
@@ -331,12 +345,12 @@ static void spells_init_theme()
}
{
- spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "DEVICE_THUNDERLORDS", "Artifact Thunderlords");
+ spell_type *spell = spell_new(&DEVICE_THUNDERLORDS, "Artifact Thunderlords");
spell_type_describe(spell, "An Eagle of Manwe will appear to transport you quickly to the town.");
spell_type_set_mana(spell, 1, 1);
spell_type_set_difficulty(spell, 1, 20);
spell_type_init_device(spell,
- device_thunderlords_info,
+ no_info,
device_thunderlords);
spell_type_set_device_charges(spell, "5+d5");
@@ -349,28 +363,6 @@ static void spells_init_theme()
spell_type_add_device_allocation(spell, device_allocation);
}
}
-
- {
- spell_type *spell = spell_new(&DEVICE_RADAGAST, "DEVICE_RADAGAST", "Artifact Radagast");
- spell_type_set_activation_timeout(spell, "15000");
- spell_type_describe(spell, "purity and health");
- spell_type_set_mana(spell, 0, 0);
- spell_type_set_difficulty(spell, 1, 10);
- spell_type_init_device(spell,
- device_radagast_info,
- device_radagast);
- }
-
- {
- spell_type *spell = spell_new(&DEVICE_VALAROMA, "DEVICE_VALAROMA", "Artifact Valaroma");
- spell_type_set_activation_timeout(spell, "250");
- spell_type_describe(spell, "banish evil (level x5)");
- spell_type_set_mana(spell, 0, 0);
- spell_type_set_difficulty(spell, 1, 25);
- spell_type_init_device(spell,
- device_valaroma_info,
- device_valaroma);
- }
}
void school_spells_init()
@@ -386,7 +378,7 @@ void school_spells_init()
/* Spells */
{
- spell_type *spell = spell_new(&GLOBELIGHT, "GLOBELIGHT", "Globe of Light");
+ spell_type *spell = spell_new(&GLOBELIGHT, "Globe of Light");
spell_type_describe(spell, "Creates a globe of pure light");
spell_type_describe(spell, "At level 3 it starts damaging monsters");
spell_type_describe(spell, "At level 15 it starts creating a more powerful kind of light");
@@ -411,7 +403,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&FIREFLASH, "FIREFLASH", "Fireflash");
+ spell_type *spell = spell_new(&FIREFLASH, "Fireflash");
spell_type_describe(spell, "Conjures a ball of fire to burn your foes to ashes");
spell_type_describe(spell, "At level 20 it turns into a ball of holy fire");
spell_type_set_mana(spell, 5, 70);
@@ -434,7 +426,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&FIERYAURA, "FIERYAURA", "Fiery Shield");
+ spell_type *spell = spell_new(&FIERYAURA, "Fiery Shield");
spell_type_describe(spell, "Creates a shield of fierce flames around you");
spell_type_describe(spell, "At level 8 it turns into a greater kind of flame that can not be resisted");
spell_type_set_mana(spell, 20, 60);
@@ -458,7 +450,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&FIREWALL, "FIREWALL", "Firewall");
+ spell_type *spell = spell_new(&FIREWALL, "Firewall");
spell_type_describe(spell, "Creates a fiery wall to incinerate monsters stupid enough to attack you");
spell_type_describe(spell, "At level 6 it turns into a wall of hell fire");
spell_type_set_mana(spell, 25, 100);
@@ -481,7 +473,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&FIREGOLEM, "FIREGOLEM", "Fire Golem");
+ spell_type *spell = spell_new(&FIREGOLEM, "Fire Golem");
spell_type_describe(spell, "Creates a fiery golem and controls it");
spell_type_describe(spell, "During the control the available keylist is:");
spell_type_describe(spell, "Movement keys: movement of the golem(depending on its speed");
@@ -505,7 +497,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANATHRUST, "MANATHRUST", "Manathrust");
+ spell_type *spell = spell_new(&MANATHRUST, "Manathrust");
spell_type_describe(spell, "Conjures up mana into a powerful bolt");
spell_type_describe(spell, "The damage is irresistible and will increase with level");
spell_type_set_mana(spell, 1, 25);
@@ -528,7 +520,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DELCURSES, "DELCURSES", "Remove Curses");
+ spell_type *spell = spell_new(&DELCURSES, "Remove Curses");
spell_type_describe(spell, "Remove curses of worn objects");
spell_type_describe(spell, "At level 20 switches to *remove curses*");
spell_type_set_mana(spell, 20, 40);
@@ -537,7 +529,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_MANA,
- mana_remove_curses_info,
+ no_info,
mana_remove_curses);
spell_type_set_device_charges(spell, "3+d8");
@@ -552,7 +544,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&RESISTS, "RESISTS", "Elemental Shield");
+ spell_type *spell = spell_new(&RESISTS, "Elemental Shield");
spell_type_describe(spell, "Provide resistances to the four basic elements");
spell_type_set_mana(spell, 17, 20);
spell_type_set_inertia(spell, 2, 25);
@@ -565,7 +557,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANASHIELD, "MANASHIELD", "Disruption Shield");
+ spell_type *spell = spell_new(&MANASHIELD, "Disruption Shield");
spell_type_describe(spell, "Uses mana instead of hp to take damage");
spell_type_describe(spell, "At level 5 switches to Globe of Invulnerability.");
spell_type_describe(spell, "The spell breaks as soon as a melee, shooting, throwing or magical");
@@ -581,7 +573,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TIDALWAVE, "TIDALWAVE", "Tidal Wave");
+ spell_type *spell = spell_new(&TIDALWAVE, "Tidal Wave");
spell_type_describe(spell, "Summons a monstrous tidal wave that will expand and crush the");
spell_type_describe(spell, "monsters under its mighty waves.");
spell_type_set_mana(spell, 16, 40);
@@ -605,7 +597,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ICESTORM, "ICESTORM", "Ice Storm");
+ spell_type *spell = spell_new(&ICESTORM, "Ice Storm");
spell_type_describe(spell, "Engulfs you in a storm of roaring cold that strikes your foes.");
spell_type_describe(spell, "At level 10 it turns into shards of ice.");
spell_type_set_mana(spell, 30, 60);
@@ -629,7 +621,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ENTPOTION, "ENTPOTION", "Ent's Potion");
+ spell_type *spell = spell_new(&ENTPOTION, "Ent's Potion");
spell_type_describe(spell, "Fills up your stomach.");
spell_type_describe(spell, "At level 5 it boldens your heart.");
spell_type_describe(spell, "At level 12 it makes you heroic.");
@@ -644,7 +636,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&VAPOR, "VAPOR", "Vapor");
+ spell_type *spell = spell_new(&VAPOR, "Vapor");
spell_type_describe(spell, "Fills the air with toxic moisture to eradicate annoying critters.");
spell_type_set_mana(spell, 2, 12);
spell_type_set_inertia(spell, 1, 30);
@@ -657,7 +649,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&GEYSER, "GEYSER", "Geyser");
+ spell_type *spell = spell_new(&GEYSER, "Geyser");
spell_type_describe(spell, "Shoots a geyser of water from your fingertips.");
spell_type_describe(spell, "Sometimes it can blast through its first target.");
spell_type_set_mana(spell, 1, 35);
@@ -670,7 +662,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&NOXIOUSCLOUD, "NOXIOUSCLOUD", "Noxious Cloud");
+ spell_type *spell = spell_new(&NOXIOUSCLOUD, "Noxious Cloud");
spell_type_describe(spell, "Creates a cloud of poison");
spell_type_describe(spell, "The cloud will persist for some turns, damaging all monsters passing by");
spell_type_describe(spell, "At spell level 30 it turns into a thick gas attacking all living beings");
@@ -694,7 +686,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&AIRWINGS, "AIRWINGS", "Wings of Winds");
+ spell_type *spell = spell_new(&AIRWINGS, "Wings of Winds");
spell_type_describe(spell, "Grants the power of levitation");
spell_type_describe(spell, "At level 16 it grants the power of controlled flight");
spell_type_add_school(spell, SCHOOL_CONVEYANCE);
@@ -719,7 +711,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&INVISIBILITY, "INVISIBILITY", "Invisibility");
+ spell_type *spell = spell_new(&INVISIBILITY, "Invisibility");
spell_type_describe(spell, "Grants invisibility");
spell_type_set_mana(spell, 10, 20);
spell_type_set_inertia(spell, 1, 30);
@@ -732,7 +724,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&POISONBLOOD, "POISONBLOOD", "Poison Blood");
+ spell_type *spell = spell_new(&POISONBLOOD, "Poison Blood");
spell_type_describe(spell, "Grants resist poison");
spell_type_describe(spell, "At level 15 it provides poison branding to wielded weapon");
spell_type_set_mana(spell, 10, 20);
@@ -756,7 +748,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&THUNDERSTORM, "THUNDERSTORM", "Thunderstorm");
+ spell_type *spell = spell_new(&THUNDERSTORM, "Thunderstorm");
spell_type_describe(spell, "Charges up the air around you with electricity");
spell_type_describe(spell, "Each turn it will throw a thunder bolt at a random monster in sight");
spell_type_describe(spell, "The thunder does 3 types of damage, one third of lightning");
@@ -783,7 +775,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STERILIZE, "STERILIZE", "Sterilize");
+ spell_type *spell = spell_new(&STERILIZE, "Sterilize");
spell_type_describe(spell, "Prevents explosive breeding for a while.");
spell_type_set_mana(spell, 10, 100);
spell_type_set_difficulty(spell, 20, 50);
@@ -805,7 +797,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STONESKIN, "STONESKIN", "Stone Skin");
+ spell_type *spell = spell_new(&STONESKIN, "Stone Skin");
spell_type_describe(spell, "Creates a shield of earth around you to protect you");
spell_type_describe(spell, "At level 25 it starts dealing damage to attackers");
spell_type_set_mana(spell, 1, 50);
@@ -819,14 +811,14 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DIG, "DIG", "Dig");
+ spell_type *spell = spell_new(&DIG, "Dig");
spell_type_describe(spell, "Digs a hole in a wall much faster than any shovels");
spell_type_set_mana(spell, 14, 14);
spell_type_set_difficulty(spell, 12, 20);
spell_type_init_mage(spell,
RANDOM,
SCHOOL_EARTH,
- earth_dig_info,
+ no_info,
earth_dig);
spell_type_set_device_charges(spell, "15+d5");
@@ -841,7 +833,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STONEPRISON, "STONEPRISON", "Stone Prison");
+ spell_type *spell = spell_new(&STONEPRISON, "Stone Prison");
spell_type_describe(spell, "Creates a prison of walls around you");
spell_type_describe(spell, "At level 10 it allows you to target a monster");
spell_type_set_mana(spell, 30, 50);
@@ -849,7 +841,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_EARTH,
- earth_stone_prison_info,
+ no_info,
earth_stone_prison);
spell_type_set_device_charges(spell, "5+d3");
@@ -864,7 +856,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STRIKE, "STRIKE", "Strike");
+ spell_type *spell = spell_new(&STRIKE, "Strike");
spell_type_describe(spell, "Creates a micro-ball of force that will push monsters backwards");
spell_type_describe(spell, "If the monster is caught near a wall, it'll be crushed against it");
spell_type_describe(spell, "At level 12 it turns into a ball of radius 1");
@@ -888,7 +880,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SHAKE, "SHAKE", "Shake");
+ spell_type *spell = spell_new(&SHAKE, "Shake");
spell_type_describe(spell, "Creates a localised earthquake");
spell_type_describe(spell, "At level 10 it can be targeted at any location");
spell_type_set_mana(spell, 25, 30);
@@ -912,7 +904,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&BLINK, "BLINK", "Phase Door");
+ spell_type *spell = spell_new(&BLINK, "Phase Door");
spell_type_describe(spell, "Teleports you on a small scale range");
spell_type_describe(spell, "At level 30 it creates void jumpgates");
spell_type_set_mana(spell, 1, 3);
@@ -926,7 +918,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DISARM, "DISARM", "Disarm");
+ spell_type *spell = spell_new(&DISARM, "Disarm");
spell_type_describe(spell, "Destroys doors and traps");
spell_type_describe(spell, "At level 10 it destroys doors and traps, then reveals and unlocks any secret");
spell_type_describe(spell, "doors");
@@ -935,7 +927,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_CONVEYANCE,
- convey_disarm_info,
+ no_info,
convey_disarm);
spell_type_set_device_charges(spell, "10+d15");
@@ -950,7 +942,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TELEPORT, "TELEPORT", "Teleportation");
+ spell_type *spell = spell_new(&TELEPORT, "Teleportation");
spell_type_describe(spell, "Teleports you around the level. The casting time decreases with level");
spell_type_set_mana(spell, 8, 14);
spell_type_set_inertia(spell, 1, 10);
@@ -973,7 +965,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TELEAWAY, "TELEAWAY", "Teleport Away");
+ spell_type *spell = spell_new(&TELEAWAY, "Teleport Away");
spell_type_describe(spell, "Teleports a line of monsters away");
spell_type_describe(spell, "At level 10 it turns into a ball");
spell_type_describe(spell, "At level 20 it teleports all monsters in sight");
@@ -982,7 +974,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_CONVEYANCE,
- convey_teleport_away_info,
+ no_info,
convey_teleport_away);
spell_type_set_device_charges(spell, "3+d5");
@@ -997,7 +989,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&RECALL, "RECALL", "Recall");
+ spell_type *spell = spell_new(&RECALL, "Recall");
spell_type_describe(spell, "Cast on yourself it will recall you to the surface/dungeon.");
spell_type_describe(spell, "Cast at a monster you will swap positions with the monster.");
spell_type_describe(spell, "Cast at an object it will fetch the object to you.");
@@ -1011,7 +1003,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&PROBABILITY_TRAVEL, "PROBABILITY_TRAVEL", "Probability Travel");
+ spell_type *spell = spell_new(&PROBABILITY_TRAVEL, "Probability Travel");
spell_type_describe(spell, "Renders you immaterial, when you hit a wall you travel through it and");
spell_type_describe(spell, "instantly appear on the other side of it. You can also float up and down");
spell_type_describe(spell, "at will");
@@ -1036,7 +1028,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&GROWTREE, "GROWTREE", "Grow Trees");
+ spell_type *spell = spell_new(&GROWTREE, "Grow Trees");
spell_type_describe(spell, "Makes trees grow extremely quickly around you");
spell_type_add_school(spell, SCHOOL_TEMPORAL);
spell_type_set_mana(spell, 6, 30);
@@ -1050,7 +1042,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&HEALING, "HEALING", "Healing");
+ spell_type *spell = spell_new(&HEALING, "Healing");
spell_type_describe(spell, "Heals a percent of hitpoints");
spell_type_set_mana(spell, 15, 50);
spell_type_set_difficulty(spell, 10, 45);
@@ -1072,7 +1064,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&RECOVERY, "RECOVERY", "Recovery");
+ spell_type *spell = spell_new(&RECOVERY, "Recovery");
spell_type_describe(spell, "Reduces the length of time that you are poisoned");
spell_type_describe(spell, "At level 5 it cures poison and cuts");
spell_type_describe(spell, "At level 10 it restores drained stats");
@@ -1083,7 +1075,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_NATURE,
- nature_recovery_info,
+ no_info,
nature_recovery);
spell_type_set_device_charges(spell, "5+d10");
@@ -1098,7 +1090,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&REGENERATION, "REGENERATION", "Regeneration");
+ spell_type *spell = spell_new(&REGENERATION, "Regeneration");
spell_type_describe(spell, "Increases your body's regeneration rate");
spell_type_set_mana(spell, 30, 55);
spell_type_set_inertia(spell, 4, 40);
@@ -1111,7 +1103,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SUMMONANNIMAL, "SUMMONANNIMAL", "Summon Animal");
+ spell_type *spell = spell_new(&SUMMONANNIMAL, "Summon Animal");
spell_type_describe(spell, "Summons a leveled animal to your aid");
spell_type_set_mana(spell, 25, 50);
spell_type_set_difficulty(spell, 25, 90);
@@ -1133,7 +1125,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STARIDENTIFY, "STARIDENTIFY", "Greater Identify");
+ spell_type *spell = spell_new(&STARIDENTIFY, "Greater Identify");
spell_type_describe(spell, "Asks for an object and fully identify it, providing the full list of powers");
spell_type_describe(spell, "Cast at yourself it will reveal your powers");
spell_type_set_mana(spell, 30, 30);
@@ -1141,12 +1133,12 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_DIVINATION,
- divination_greater_identify_info,
+ no_info,
divination_greater_identify);
}
{
- spell_type *spell = spell_new(&IDENTIFY, "IDENTIFY", "Identify");
+ spell_type *spell = spell_new(&IDENTIFY, "Identify");
spell_type_describe(spell, "Asks for an object and identifies it");
spell_type_describe(spell, "At level 17 it identifies all objects in the inventory");
spell_type_describe(spell, "At level 27 it identifies all objects in the inventory and in a");
@@ -1171,7 +1163,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&VISION, "VISION", "Vision");
+ spell_type *spell = spell_new(&VISION, "Vision");
spell_type_describe(spell, "Detects the layout of the surrounding area");
spell_type_describe(spell, "At level 25 it maps and lights the whole level");
spell_type_set_mana(spell, 7, 55);
@@ -1180,7 +1172,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_DIVINATION,
- divination_vision_info,
+ no_info,
divination_vision);
spell_type_set_device_charges(spell, "4+d6");
@@ -1195,7 +1187,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SENSEHIDDEN, "SENSEHIDDEN", "Sense Hidden");
+ spell_type *spell = spell_new(&SENSEHIDDEN, "Sense Hidden");
spell_type_describe(spell, "Detects the traps in a certain radius around you");
spell_type_describe(spell, "At level 15 it allows you to sense invisible for a while");
spell_type_set_mana(spell, 2, 10);
@@ -1219,7 +1211,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&REVEALWAYS, "REVEALWAYS", "Reveal Ways");
+ spell_type *spell = spell_new(&REVEALWAYS, "Reveal Ways");
spell_type_describe(spell, "Detects the doors/stairs/ways in a certain radius around you");
spell_type_set_mana(spell, 3, 15);
spell_type_set_inertia(spell, 1, 10);
@@ -1242,7 +1234,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SENSEMONSTERS, "SENSEMONSTERS", "Sense Monsters");
+ spell_type *spell = spell_new(&SENSEMONSTERS, "Sense Monsters");
spell_type_describe(spell, "Detects all monsters near you");
spell_type_describe(spell, "At level 30 it allows you to sense monster minds for a while");
spell_type_set_mana(spell, 1, 20);
@@ -1266,7 +1258,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MAGELOCK, "MAGELOCK", "Magelock");
+ spell_type *spell = spell_new(&MAGELOCK, "Magelock");
spell_type_describe(spell, "Magically locks a door");
spell_type_describe(spell, "At level 30 it creates a glyph of warding");
spell_type_describe(spell, "At level 40 the glyph can be placed anywhere in the field of vision");
@@ -1275,7 +1267,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_TEMPORAL,
- tempo_magelock_info,
+ no_info,
tempo_magelock);
spell_type_set_device_charges(spell, "7+d5");
@@ -1290,7 +1282,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SLOWMONSTER, "SLOWMONSTER", "Slow Monster");
+ spell_type *spell = spell_new(&SLOWMONSTER, "Slow Monster");
spell_type_describe(spell, "Magically slows down the passing of time around a monster");
spell_type_describe(spell, "At level 20 it affects a zone");
spell_type_set_mana(spell, 10, 15);
@@ -1313,7 +1305,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ESSENCESPEED, "ESSENCESPEED", "Essence of Speed");
+ spell_type *spell = spell_new(&ESSENCESPEED, "Essence of Speed");
spell_type_describe(spell, "Magically decreases the passing of time around you, making you move faster with");
spell_type_describe(spell, "respect to the rest of the universe.");
spell_type_set_mana(spell, 20, 40);
@@ -1337,7 +1329,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&BANISHMENT, "BANISHMENT", "Banishment");
+ spell_type *spell = spell_new(&BANISHMENT, "Banishment");
spell_type_describe(spell, "Disrupts the space/time continuum in your area and teleports all monsters away.");
spell_type_describe(spell, "At level 15 it may also lock them in a time bubble for a while.");
spell_type_add_school(spell, SCHOOL_CONVEYANCE);
@@ -1362,7 +1354,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&RECHARGE, "RECHARGE", "Recharge");
+ spell_type *spell = spell_new(&RECHARGE, "Recharge");
spell_type_describe(spell, "Taps on the ambient mana to recharge an object's power (charges or mana)");
spell_type_set_mana(spell, 10, 100);
spell_type_set_difficulty(spell, 5, 20);
@@ -1374,7 +1366,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&SPELLBINDER, "SPELLBINDER", "Spellbinder");
+ spell_type *spell = spell_new(&SPELLBINDER, "Spellbinder");
spell_type_describe(spell, "Stores spells in a trigger.");
spell_type_describe(spell, "When the condition is met all spells fire off at the same time");
spell_type_describe(spell, "This spell takes a long time to cast so you are advised to prepare it");
@@ -1391,7 +1383,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DISPERSEMAGIC, "DISPERSEMAGIC", "Disperse Magic");
+ spell_type *spell = spell_new(&DISPERSEMAGIC, "Disperse Magic");
spell_type_describe(spell, "Dispels a lot of magic that can affect you, be it good or bad");
spell_type_describe(spell, "Level 1: blindness and light");
spell_type_describe(spell, "Level 5: confusion and hallucination");
@@ -1406,7 +1398,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_META,
- meta_disperse_magic_info,
+ no_info,
meta_disperse_magic);
spell_type_set_device_charges(spell, "5+d5");
@@ -1421,7 +1413,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TRACKER, "TRACKER", "Tracker");
+ spell_type *spell = spell_new(&TRACKER, "Tracker");
spell_type_describe(spell, "Tracks down the last teleportation that happened on the level and teleports");
spell_type_describe(spell, "you to it");
spell_type_add_school(spell, SCHOOL_CONVEYANCE);
@@ -1430,12 +1422,12 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_META,
- meta_tracker_info,
+ no_info,
meta_tracker);
}
{
- spell_type *spell = spell_new(&INERTIA_CONTROL, "INERTIA_CONTROL", "Inertia Control");
+ spell_type *spell = spell_new(&INERTIA_CONTROL, "Inertia Control");
spell_type_describe(spell, "Changes the energy flow of a spell to be continuously recasted");
spell_type_describe(spell, "at a given interval. The inertia controlled spell reduces your");
spell_type_describe(spell, "maximum mana by four times its cost.");
@@ -1449,7 +1441,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&CHARM, "CHARM", "Charm");
+ spell_type *spell = spell_new(&CHARM, "Charm");
spell_type_describe(spell, "Tries to manipulate the mind of a monster to make it friendly");
spell_type_describe(spell, "At level 15 it turns into a ball");
spell_type_describe(spell, "At level 35 it affects all monsters in sight");
@@ -1473,7 +1465,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&CONFUSE, "CONFUSE", "Confuse");
+ spell_type *spell = spell_new(&CONFUSE, "Confuse");
spell_type_describe(spell, "Tries to manipulate the mind of a monster to confuse it");
spell_type_describe(spell, "At level 15 it turns into a ball");
spell_type_describe(spell, "At level 35 it affects all monsters in sight");
@@ -1497,7 +1489,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ARMOROFFEAR, "ARMOROFFEAR", "Armor of Fear");
+ spell_type *spell = spell_new(&ARMOROFFEAR, "Armor of Fear");
spell_type_describe(spell, "Creates a shield of pure fear around you. Any monster attempting to hit you");
spell_type_describe(spell, "must save or flee");
spell_type_set_mana(spell, 10, 50);
@@ -1511,7 +1503,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&STUN, "STUN", "Stun");
+ spell_type *spell = spell_new(&STUN, "Stun");
spell_type_describe(spell, "Tries to manipulate the mind of a monster to stun it");
spell_type_describe(spell, "At level 20 it turns into a ball");
spell_type_set_mana(spell, 10, 90);
@@ -1524,7 +1516,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DRAIN, "DRAIN", "Drain");
+ spell_type *spell = spell_new(&DRAIN, "Drain");
spell_type_describe(spell, "Drains the mana contained in wands, staves and rods to increase yours");
spell_type_add_school(spell, SCHOOL_MANA);
spell_type_set_mana(spell, 0, 0);
@@ -1532,12 +1524,12 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_UDUN,
- udun_drain_info,
+ no_info,
udun_drain);
}
{
- spell_type *spell = spell_new(&GENOCIDE, "GENOCIDE", "Genocide");
+ spell_type *spell = spell_new(&GENOCIDE, "Genocide");
spell_type_describe(spell, "Genocides all monsters of a race on the level");
spell_type_describe(spell, "At level 10 it can genocide all monsters near you");
spell_type_add_school(spell, SCHOOL_NATURE);
@@ -1546,7 +1538,7 @@ void school_spells_init()
spell_type_init_mage(spell,
RANDOM,
SCHOOL_UDUN,
- udun_genocide_info,
+ no_info,
udun_genocide);
spell_type_set_device_charges(spell, "2+d2");
@@ -1561,7 +1553,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&WRAITHFORM, "WRAITHFORM", "Wraithform");
+ spell_type *spell = spell_new(&WRAITHFORM, "Wraithform");
spell_type_describe(spell, "Turns you into an immaterial being");
spell_type_add_school(spell, SCHOOL_CONVEYANCE);
spell_type_set_mana(spell, 20, 40);
@@ -1575,7 +1567,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&FLAMEOFUDUN, "FLAMEOFUDUN", "Flame of Udun");
+ spell_type *spell = spell_new(&FLAMEOFUDUN, "Flame of Udun");
spell_type_describe(spell, "Turns you into a powerful Balrog");
spell_type_add_school(spell, SCHOOL_FIRE);
spell_type_set_mana(spell, 70, 100);
@@ -1589,7 +1581,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&CALL_THE_ELEMENTS, "CALL_THE_ELEMENTS", "Call the Elements");
+ spell_type *spell = spell_new(&CALL_THE_ELEMENTS, "Call the Elements");
spell_type_describe(spell, "Randomly creates various elements around you");
spell_type_describe(spell, "Each type of element chance is controlled by your level");
spell_type_describe(spell, "in the corresponding skill");
@@ -1605,7 +1597,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&CHANNEL_ELEMENTS, "CHANNEL_ELEMENTS", "Channel Elements");
+ spell_type *spell = spell_new(&CHANNEL_ELEMENTS, "Channel Elements");
spell_type_describe(spell, "Draws on the caster's immediate environs to form an attack or other effect.");
spell_type_describe(spell, "Grass/Flower heals.");
spell_type_describe(spell, "Water creates water bolt attacks.");
@@ -1625,12 +1617,12 @@ void school_spells_init()
spell_type_init_mage(spell,
NO_RANDOM,
SCHOOL_GEOMANCY,
- geomancy_channel_elements_info,
+ no_info,
geomancy_channel_elements);
}
{
- spell_type *spell = spell_new(&ELEMENTAL_WAVE, "ELEMENTAL_WAVE", "Elemental Wave");
+ spell_type *spell = spell_new(&ELEMENTAL_WAVE, "Elemental Wave");
spell_type_describe(spell, "Draws on an adjacent special square to project a slow-moving");
spell_type_describe(spell, "wave of that element in that direction");
spell_type_describe(spell, "Abyss squares cannot be channeled into a wave.");
@@ -1640,12 +1632,12 @@ void school_spells_init()
spell_type_init_mage(spell,
NO_RANDOM,
SCHOOL_GEOMANCY,
- geomancy_elemental_wave_info,
+ no_info,
geomancy_elemental_wave);
}
{
- spell_type *spell = spell_new(&VAPORIZE, "VAPORIZE", "Vaporize");
+ spell_type *spell = spell_new(&VAPORIZE, "Vaporize");
spell_type_describe(spell, "Draws upon your immediate environs to form a cloud of damaging vapors");
spell_type_set_mana(spell, 3, 30);
spell_type_set_difficulty(spell, 4, 15);
@@ -1658,7 +1650,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&GEOLYSIS, "GEOLYSIS", "Geolysis");
+ spell_type *spell = spell_new(&GEOLYSIS, "Geolysis");
spell_type_describe(spell, "Burrows deeply and slightly at random into a wall,");
spell_type_describe(spell, "leaving behind tailings of various different sorts of walls in the passage.");
spell_type_set_mana(spell, 15, 40);
@@ -1672,7 +1664,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DRIPPING_TREAD, "DRIPPING_TREAD", "Dripping Tread");
+ spell_type *spell = spell_new(&DRIPPING_TREAD, "Dripping Tread");
spell_type_describe(spell, "Causes you to leave random elemental forms behind as you walk");
spell_type_set_mana(spell, 15, 25);
spell_type_set_difficulty(spell, 10, 15);
@@ -1685,7 +1677,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&GROW_BARRIER, "GROW_BARRIER", "Grow Barrier");
+ spell_type *spell = spell_new(&GROW_BARRIER, "Grow Barrier");
spell_type_describe(spell, "Creates impassable terrain (walls, trees, etc.) around you.");
spell_type_describe(spell, "At level 20 it can be projected around another area.");
spell_type_set_mana(spell, 30, 40);
@@ -1693,13 +1685,13 @@ void school_spells_init()
spell_type_set_castable_while_blind(spell, TRUE);
spell_type_init_geomancy(
spell,
- geomancy_grow_barrier_info,
+ no_info,
geomancy_grow_barrier,
geomancy_grow_barrier_depends);
}
{
- spell_type *spell = spell_new(&ELEMENTAL_MINION, "ELEMENTAL_MINION", "Elemental Minion");
+ spell_type *spell = spell_new(&ELEMENTAL_MINION, "Elemental Minion");
spell_type_describe(spell, "Summons a minion from a nearby element.");
spell_type_describe(spell, "Walls can summon Earth elmentals, Xorns and Xarens");
spell_type_describe(spell, "Dark Pits can summon Air elementals, Ancient blue dragons, Great Storm Wyrms");
@@ -1716,7 +1708,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ERU_SEE, "ERU_SEE", "See the Music");
+ spell_type *spell = spell_new(&ERU_SEE, "See the Music");
spell_type_describe(spell, "Allows you to 'see' the Great Music from which the world");
spell_type_describe(spell, "originates, allowing you to see unseen things");
spell_type_describe(spell, "At level 10 it allows you to see your surroundings");
@@ -1732,7 +1724,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&ERU_LISTEN, "ERU_LISTEN", "Listen to the Music");
+ spell_type *spell = spell_new(&ERU_LISTEN, "Listen to the Music");
spell_type_describe(spell, "Allows you to listen to the Great Music from which the world");
spell_type_describe(spell, "originates, allowing you to understand the meaning of things");
spell_type_describe(spell, "At level 14 it allows you to identify all your pack");
@@ -1741,12 +1733,12 @@ void school_spells_init()
spell_type_set_difficulty(spell, 7, 25);
spell_type_init_priest(spell,
SCHOOL_ERU,
- eru_listen_to_the_music_info,
+ no_info,
eru_listen_to_the_music);
}
{
- spell_type *spell = spell_new(&ERU_UNDERSTAND, "ERU_UNDERSTAND", "Know the Music");
+ spell_type *spell = spell_new(&ERU_UNDERSTAND, "Know the Music");
spell_type_describe(spell, "Allows you to understand the Great Music from which the world");
spell_type_describe(spell, "originates, allowing you to know the full abilities of things");
spell_type_describe(spell, "At level 10 it allows you to *identify* all your pack");
@@ -1754,12 +1746,12 @@ void school_spells_init()
spell_type_set_difficulty(spell, 30, 50);
spell_type_init_priest(spell,
SCHOOL_ERU,
- eru_know_the_music_info,
+ no_info,
eru_know_the_music);
}
{
- spell_type *spell = spell_new(&ERU_PROT, "ERU_PROT", "Lay of Protection");
+ spell_type *spell = spell_new(&ERU_PROT, "Lay of Protection");
spell_type_describe(spell, "Creates a circle of safety around you");
spell_type_set_mana(spell, 400, 400);
spell_type_set_difficulty(spell, 35, 80);
@@ -1770,7 +1762,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANWE_SHIELD, "MANWE_SHIELD", "Wind Shield");
+ spell_type *spell = spell_new(&MANWE_SHIELD, "Wind Shield");
spell_type_describe(spell, "It surrounds you with a shield of wind that deflects blows from evil monsters");
spell_type_describe(spell, "At level 10 it increases your armour rating");
spell_type_describe(spell, "At level 20 it retaliates against monsters that melee you");
@@ -1783,7 +1775,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANWE_AVATAR, "MANWE_AVATAR", "Avatar");
+ spell_type *spell = spell_new(&MANWE_AVATAR, "Avatar");
spell_type_describe(spell, "It turns you into a full grown Maia");
spell_type_set_mana(spell, 1000, 1000);
spell_type_set_difficulty(spell, 35, 80);
@@ -1794,7 +1786,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANWE_BLESS, "MANWE_BLESS", "Manwe's Blessing");
+ spell_type *spell = spell_new(&MANWE_BLESS, "Manwe's Blessing");
spell_type_describe(spell, "Manwe's Blessing removes your fears, blesses you and surrounds you with");
spell_type_describe(spell, "holy light");
spell_type_describe(spell, "At level 10 it also grants heroism");
@@ -1809,7 +1801,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MANWE_CALL, "MANWE_CALL", "Manwe's Call");
+ spell_type *spell = spell_new(&MANWE_CALL, "Manwe's Call");
spell_type_describe(spell, "Manwe's Call summons a Great Eagle to help you battle the forces");
spell_type_describe(spell, "of Morgoth");
spell_type_set_mana(spell, 200, 500);
@@ -1821,7 +1813,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TULKAS_AIM, "TULKAS_AIM", "Divine Aim");
+ spell_type *spell = spell_new(&TULKAS_AIM, "Divine Aim");
spell_type_describe(spell, "It makes you more accurate in combat");
spell_type_describe(spell, "At level 20 all your blows are critical hits");
spell_type_set_mana(spell, 30, 500);
@@ -1833,7 +1825,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TULKAS_WAVE, "TULKAS_WAVE", "Wave of Power");
+ spell_type *spell = spell_new(&TULKAS_WAVE, "Wave of Power");
spell_type_describe(spell, "It allows you to project a number of melee blows across a distance");
spell_type_set_mana(spell, 200, 200);
spell_type_set_difficulty(spell, 20, 75);
@@ -1844,18 +1836,18 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&TULKAS_SPIN, "TULKAS_SPIN", "Whirlwind");
+ spell_type *spell = spell_new(&TULKAS_SPIN, "Whirlwind");
spell_type_describe(spell, "It allows you to spin around and hit all monsters nearby");
spell_type_set_mana(spell, 100, 100);
spell_type_set_difficulty(spell, 10, 45);
spell_type_init_priest(spell,
SCHOOL_TULKAS,
- tulkas_whirlwind_info,
+ no_info,
tulkas_whirlwind);
}
{
- spell_type *spell = spell_new(&MELKOR_CURSE, "MELKOR_CURSE", "Curse");
+ spell_type *spell = spell_new(&MELKOR_CURSE, "Curse");
spell_type_describe(spell, "It curses a monster, reducing its melee power");
spell_type_describe(spell, "At level 5 it can be auto-casted (with no piety cost) while fighting");
spell_type_describe(spell, "At level 15 it also reduces armor");
@@ -1865,12 +1857,12 @@ void school_spells_init()
spell_type_set_difficulty(spell, 1, 20);
spell_type_init_priest(spell,
SCHOOL_MELKOR,
- melkor_curse_info,
+ no_info,
melkor_curse);
}
{
- spell_type *spell = spell_new(&MELKOR_CORPSE_EXPLOSION, "MELKOR_CORPSE_EXPLOSION", "Corpse Explosion");
+ spell_type *spell = spell_new(&MELKOR_CORPSE_EXPLOSION, "Corpse Explosion");
spell_type_describe(spell, "It makes corpses in an area around you explode for a percent of their");
spell_type_describe(spell, "hit points as damage");
spell_type_set_mana(spell, 100, 500);
@@ -1882,7 +1874,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MELKOR_MIND_STEAL, "MELKOR_MIND_STEAL", "Mind Steal");
+ spell_type *spell = spell_new(&MELKOR_MIND_STEAL, "Mind Steal");
spell_type_describe(spell, "It allows your spirit to temporarily leave your own body, which will");
spell_type_describe(spell, "be vulnerable, to control one of your enemies body.");
spell_type_set_mana(spell, 1000, 3000);
@@ -1894,7 +1886,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&YAVANNA_CHARM_ANIMAL, "YAVANNA_CHARM_ANIMAL", "Charm Animal");
+ spell_type *spell = spell_new(&YAVANNA_CHARM_ANIMAL, "Charm Animal");
spell_type_describe(spell, "It tries to tame an animal");
spell_type_set_mana(spell, 10, 100);
spell_type_set_difficulty(spell, 1, 30);
@@ -1905,7 +1897,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&YAVANNA_GROW_GRASS, "YAVANNA_GROW_GRASS", "Grow Grass");
+ spell_type *spell = spell_new(&YAVANNA_GROW_GRASS, "Grow Grass");
spell_type_describe(spell, "Create a floor of grass around you. While on grass and praying");
spell_type_describe(spell, "a worshipper of Yavanna will know a greater regeneration rate");
spell_type_set_mana(spell, 70, 150);
@@ -1917,7 +1909,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&YAVANNA_TREE_ROOTS, "YAVANNA_TREE_ROOTS", "Tree Roots");
+ spell_type *spell = spell_new(&YAVANNA_TREE_ROOTS, "Tree Roots");
spell_type_describe(spell, "Creates roots deep in the floor from your feet, making you more stable and able");
spell_type_describe(spell, "to make stronger attacks, but prevents any movement (even teleportation).");
spell_type_describe(spell, "It also makes you recover from stunning almost immediately.");
@@ -1930,7 +1922,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&YAVANNA_WATER_BITE, "YAVANNA_WATER_BITE", "Water Bite");
+ spell_type *spell = spell_new(&YAVANNA_WATER_BITE, "Water Bite");
spell_type_describe(spell, "Imbues your melee weapon with a natural stream of water");
spell_type_describe(spell, "At level 25, it spreads over a 1 radius zone around your target");
spell_type_set_mana(spell, 150, 300);
@@ -1942,7 +1934,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&YAVANNA_UPROOT, "YAVANNA_UPROOT", "Uproot");
+ spell_type *spell = spell_new(&YAVANNA_UPROOT, "Uproot");
spell_type_describe(spell, "Awakes a tree to help you battle the forces of Morgoth");
spell_type_set_mana(spell, 250, 350);
spell_type_set_difficulty(spell, 35, 95);
@@ -1953,7 +1945,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEMON_BLADE, "DEMON_BLADE", "Demon Blade");
+ spell_type *spell = spell_new(&DEMON_BLADE, "Demon Blade");
spell_type_describe(spell, "Imbues your blade with fire to deal more damage");
spell_type_describe(spell, "At level 30 it deals hellfire damage");
spell_type_describe(spell, "At level 45 it spreads over a 1 radius zone around your target");
@@ -1975,7 +1967,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEMON_MADNESS, "DEMON_MADNESS", "Demon Madness");
+ spell_type *spell = spell_new(&DEMON_MADNESS, "Demon Madness");
spell_type_describe(spell, "Fire 2 balls in opposite directions of randomly chaos, confusion or charm");
spell_type_set_mana(spell, 5, 20);
spell_type_set_difficulty(spell, 10, 25);
@@ -1985,7 +1977,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEMON_FIELD, "DEMON_FIELD", "Demon Field");
+ spell_type *spell = spell_new(&DEMON_FIELD, "Demon Field");
spell_type_describe(spell, "Fires a cloud of deadly nexus over a radius of 7");
spell_type_set_mana(spell, 20, 60);
spell_type_set_difficulty(spell, 20, 60);
@@ -1995,7 +1987,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DOOM_SHIELD, "DOOM_SHIELD", "Doom Shield");
+ spell_type *spell = spell_new(&DOOM_SHIELD, "Doom Shield");
spell_type_describe(spell, "Raises a mirror of pain around you, doing very high damage to your foes");
spell_type_describe(spell, "that dare hit you, but greatly reduces your armour class");
spell_type_set_mana(spell, 2, 30);
@@ -2006,7 +1998,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&UNHOLY_WORD, "UNHOLY_WORD", "Unholy Word");
+ spell_type *spell = spell_new(&UNHOLY_WORD, "Unholy Word");
spell_type_describe(spell, "Kills a pet to heal you");
spell_type_describe(spell, "There is a chance that the pet won't die but will turn against you");
spell_type_describe(spell, "it will decrease with higher level");
@@ -2018,7 +2010,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEMON_CLOAK, "DEMON_CLOAK", "Demon Cloak");
+ spell_type *spell = spell_new(&DEMON_CLOAK, "Demon Cloak");
spell_type_describe(spell, "Raises a mirror that can reflect bolts and arrows for a time");
spell_type_set_mana(spell, 10, 40);
spell_type_set_difficulty(spell, 20, 70);
@@ -2028,7 +2020,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEMON_SUMMON, "DEMON_SUMMON", "Summon Demon");
+ spell_type *spell = spell_new(&DEMON_SUMMON, "Summon Demon");
spell_type_describe(spell, "Summons a leveled demon to your side");
spell_type_describe(spell, "At level 35 it summons a high demon");
spell_type_set_mana(spell, 10, 50);
@@ -2039,7 +2031,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DISCHARGE_MINION, "DISCHARGE_MINION", "Discharge Minion");
+ spell_type *spell = spell_new(&DISCHARGE_MINION, "Discharge Minion");
spell_type_describe(spell, "The targeted pet will explode in a burst of gravity");
spell_type_set_mana(spell, 20, 50);
spell_type_set_difficulty(spell, 10, 30);
@@ -2049,7 +2041,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&CONTROL_DEMON, "CONTROL_DEMON", "Control Demon");
+ spell_type *spell = spell_new(&CONTROL_DEMON, "Control Demon");
spell_type_describe(spell, "Attempts to control a demon");
spell_type_set_mana(spell, 30, 70);
spell_type_set_difficulty(spell, 25, 55);
@@ -2059,7 +2051,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_HEAL_MONSTER, "DEVICE_HEAL_MONSTER", "Heal Monster");
+ spell_type *spell = spell_new(&DEVICE_HEAL_MONSTER, "Heal Monster");
spell_type_describe(spell, "Heals a monster");
spell_type_set_mana(spell, 5, 20);
spell_type_set_difficulty(spell, 3, 15);
@@ -2079,7 +2071,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_SPEED_MONSTER, "DEVICE_SPEED_MONSTER", "Haste Monster");
+ spell_type *spell = spell_new(&DEVICE_SPEED_MONSTER, "Haste Monster");
spell_type_describe(spell, "Haste a monster");
spell_type_set_mana(spell, 10, 10);
spell_type_set_difficulty(spell, 10, 30);
@@ -2099,12 +2091,12 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_WISH, "DEVICE_WISH", "Wish");
+ spell_type *spell = spell_new(&DEVICE_WISH, "Wish");
spell_type_describe(spell, "This grants you a wish, beware of what you ask for!");
spell_type_set_mana(spell, 400, 400);
spell_type_set_difficulty(spell, 50, 99);
spell_type_init_device(spell,
- device_wish_info,
+ no_info,
device_wish);
spell_type_set_device_charges(spell, "1+d2");
@@ -2119,12 +2111,12 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_SUMMON, "DEVICE_SUMMON", "Summon");
+ spell_type *spell = spell_new(&DEVICE_SUMMON, "Summon");
spell_type_describe(spell, "Summons hostile monsters near you");
spell_type_set_mana(spell, 5, 25);
spell_type_set_difficulty(spell, 5, 20);
spell_type_init_device(spell,
- device_summon_monster_info,
+ no_info,
device_summon_monster);
spell_type_set_device_charges(spell, "1+d20");
@@ -2139,7 +2131,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_MANA, "DEVICE_MANA", "Mana");
+ spell_type *spell = spell_new(&DEVICE_MANA, "Mana");
spell_type_describe(spell, "Restores a part(or all) of your mana");
spell_type_set_mana(spell, 1, 1);
spell_type_set_difficulty(spell, 30, 80);
@@ -2159,12 +2151,12 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_NOTHING, "DEVICE_NOTHING", "Nothing");
+ spell_type *spell = spell_new(&DEVICE_NOTHING, "Nothing");
spell_type_describe(spell, "It does nothing.");
spell_type_set_mana(spell, 0, 0);
spell_type_set_difficulty(spell, 1, 0);
spell_type_init_device(spell,
- device_nothing_info,
+ no_info,
device_nothing);
spell_type_set_device_charges(spell, "0+d0");
@@ -2187,18 +2179,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_MAGGOT, "DEVICE_MAGGOT", "Artifact Maggot");
- spell_type_set_activation_timeout(spell, "10+d50");
- spell_type_describe(spell, "terrify");
- spell_type_set_mana(spell, 7, 7);
- spell_type_set_difficulty(spell, 1, 20);
- spell_type_init_device(spell,
- device_maggot_info,
- device_maggot);
- }
-
- {
- spell_type *spell = spell_new(&DEVICE_HOLY_FIRE, "DEVICE_HOLY_FIRE", "Holy Fire of Mithrandir");
+ spell_type *spell = spell_new(&DEVICE_HOLY_FIRE, "Holy Fire of Mithrandir");
spell_type_describe(spell, "The Holy Fire created by this staff will deeply(double damage) burn");
spell_type_describe(spell, "all that is evil.");
spell_type_set_mana(spell, 50, 150);
@@ -2219,30 +2200,19 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&DEVICE_ETERNAL_FLAME, "DEVICE_ETERNAL_FLAME", "Artifact Eternal Flame");
- spell_type_set_activation_timeout(spell, "0");
- spell_type_describe(spell, "Imbuing an object with the eternal fire");
- spell_type_set_mana(spell, 0, 0);
- spell_type_set_difficulty(spell, 1, 0);
- spell_type_init_device(spell,
- device_eternal_flame_info,
- device_eternal_flame);
- }
-
- {
- spell_type *spell = spell_new(&MUSIC_STOP, "MUSIC_STOP", "Stop singing(I)");
+ spell_type *spell = spell_new(&MUSIC_STOP, "Stop singing(I)");
spell_type_describe(spell, "Stops the current song, if any.");
spell_type_set_mana(spell, 0, 0);
spell_type_set_difficulty(spell, 1, -400);
spell_type_set_castable_while_blind(spell, TRUE);
spell_type_init_music(spell,
1,
- music_stop_singing_info,
+ no_info,
music_stop_singing_spell);
}
{
- spell_type *spell = spell_new(&MUSIC_HOLD, "MUSIC_HOLD", "Holding Pattern(I)");
+ spell_type *spell = spell_new(&MUSIC_HOLD, "Holding Pattern(I)");
spell_type_describe(spell, "Slows down all monsters listening the song.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 1, 10);
@@ -2257,7 +2227,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_CONF, "MUSIC_CONF", "Illusion Pattern(II)");
+ spell_type *spell = spell_new(&MUSIC_CONF, "Illusion Pattern(II)");
spell_type_describe(spell, "Tries to confuse all monsters listening the song.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 2, 15);
@@ -2272,7 +2242,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_STUN, "MUSIC_STUN", "Stun Pattern(IV)");
+ spell_type *spell = spell_new(&MUSIC_STUN, "Stun Pattern(IV)");
spell_type_describe(spell, "Stuns all monsters listening the song.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 3, 25);
@@ -2287,7 +2257,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_LITE, "MUSIC_LITE", "Song of the Sun(I)");
+ spell_type *spell = spell_new(&MUSIC_LITE, "Song of the Sun(I)");
spell_type_describe(spell, "Provides light as long as you sing.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 1, 1);
@@ -2296,13 +2266,13 @@ void school_spells_init()
spell_type_init_music_lasting(
spell,
1,
- music_song_of_the_sun_info,
+ no_info,
music_song_of_the_sun_spell,
music_song_of_the_sun_lasting);
}
{
- spell_type *spell = spell_new(&MUSIC_HEAL, "MUSIC_HEAL", "Flow of Life(II)");
+ spell_type *spell = spell_new(&MUSIC_HEAL, "Flow of Life(II)");
spell_type_describe(spell, "Heals you as long as you sing.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
spell_type_set_mana(spell, 5, 30);
@@ -2316,7 +2286,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_HERO, "MUSIC_HERO", "Heroic Ballad(II)");
+ spell_type *spell = spell_new(&MUSIC_HERO, "Heroic Ballad(II)");
spell_type_describe(spell, "Increases melee accuracy");
spell_type_describe(spell, "At level 10 it increases it even more and reduces armour a bit");
spell_type_describe(spell, "At level 20 it increases it again");
@@ -2327,13 +2297,13 @@ void school_spells_init()
spell_type_init_music_lasting(
spell,
2,
- music_heroic_ballad_info,
+ no_info,
music_heroic_ballad_spell,
music_heroic_ballad_lasting);
}
{
- spell_type *spell = spell_new(&MUSIC_TIME, "MUSIC_TIME", "Hobbit Melodies(III)");
+ spell_type *spell = spell_new(&MUSIC_TIME, "Hobbit Melodies(III)");
spell_type_describe(spell, "Greatly increases your reflexes allowing you to block more melee blows.");
spell_type_describe(spell, "At level 15 it also makes you faster.");
spell_type_describe(spell, "Consumes the amount of mana each turn.");
@@ -2348,7 +2318,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_MIND, "MUSIC_MIND", "Clairaudience(IV)");
+ spell_type *spell = spell_new(&MUSIC_MIND, "Clairaudience(IV)");
spell_type_describe(spell, "Allows you to sense monster minds as long as you sing.");
spell_type_describe(spell, "At level 10 it identifies all objects in a radius on the floor,");
spell_type_describe(spell, "as well as probing monsters in that radius.");
@@ -2364,7 +2334,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_BLOW, "MUSIC_BLOW", "Blow(I)");
+ spell_type *spell = spell_new(&MUSIC_BLOW, "Blow(I)");
spell_type_describe(spell, "Produces a powerful, blowing, sound all around you.");
spell_type_set_mana(spell, 3, 30);
spell_type_set_difficulty(spell, 4, 20);
@@ -2375,7 +2345,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_WIND, "MUSIC_WIND", "Gush of Wind(II)");
+ spell_type *spell = spell_new(&MUSIC_WIND, "Gush of Wind(II)");
spell_type_describe(spell, "Produces a outgoing gush of wind that sends monsters away.");
spell_type_set_mana(spell, 15, 45);
spell_type_set_difficulty(spell, 14, 30);
@@ -2386,7 +2356,7 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_YLMIR, "MUSIC_YLMIR", "Horns of Ylmir(III)");
+ spell_type *spell = spell_new(&MUSIC_YLMIR, "Horns of Ylmir(III)");
spell_type_describe(spell, "Produces an earth shaking sound.");
spell_type_set_mana(spell, 25, 30);
spell_type_set_difficulty(spell, 20, 20);
@@ -2397,14 +2367,14 @@ void school_spells_init()
}
{
- spell_type *spell = spell_new(&MUSIC_AMBARKANTA, "MUSIC_AMBARKANTA", "Ambarkanta(IV)");
+ spell_type *spell = spell_new(&MUSIC_AMBARKANTA, "Ambarkanta(IV)");
spell_type_describe(spell, "Produces a reality shaking sound that transports you to a nearly");
spell_type_describe(spell, "identical reality.");
spell_type_set_mana(spell, 70, 70);
spell_type_set_difficulty(spell, 25, 60);
spell_type_init_music(spell,
4,
- music_ambarkanta_info,
+ no_info,
music_ambarkanta_spell);
}
diff --git a/src/spells5.hpp b/src/spells5.hpp
new file mode 100644
index 00000000..7359fa16
--- /dev/null
+++ b/src/spells5.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "h-basic.h"
+
+void school_spells_init();
+struct spell_type *spell_at(s32b index);
+s16b get_random_spell(s16b random_type, int lev);
+s16b get_random_stick(byte tval, int level);
+int find_spell(cptr name);
diff --git a/src/spells6.c b/src/spells6.cc
index 5db4e18e..a4564ae3 100644
--- a/src/spells6.c
+++ b/src/spells6.cc
@@ -1,34 +1,46 @@
-#include <angband.h>
+#include "spells6.hpp"
+
+#include "gods.hpp"
+#include "lua_bind.hpp"
+#include "object2.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "skills.hpp"
+#include "skill_type.hpp"
+#include "spell_type.hpp"
+#include "spells4.hpp"
+#include "variable.hpp"
+
+#include <cassert>
+#include <vector>
+#include <type_traits>
+
+struct school_provider
+{
+ byte deity_idx; /* Deity which provides school levels */
-#include <assert.h>
+ s16b skill_idx; /* Skill used for determining the boost */
-#include "spell_type.h"
+ long mul; /* Multiplier */
-static int compare_school_provider(school_provider *a, school_provider *b)
-{
- return SGLIB_NUMERIC_COMPARATOR(a->deity_idx, b->deity_idx);
-}
-
-static void school_provider_init(school_provider *p, byte deity_idx, long mul, long div)
-{
- assert(p != NULL);
+ long div; /* Divisor */
+};
- p->deity_idx = deity_idx;
- p->skill_idx = SKILL_PRAY;
- p->mul = mul;
- p->div = div;
- p->next = NULL;
-}
+struct school_provider_list {
+public:
+ std::vector<school_provider> v;
+};
-static school_provider *school_provider_new(byte deity_idx, long mul, long div)
+static school_provider school_provider_new(byte deity_idx, long mul, long div)
{
- school_provider *p = malloc(sizeof(school_provider));
- school_provider_init(p, deity_idx, mul, div);
+ school_provider p;
+ p.deity_idx = deity_idx;
+ p.skill_idx = SKILL_PRAY;
+ p.mul = mul;
+ p.div = div;
return p;
}
-SGLIB_DEFINE_LIST_FUNCTIONS(school_provider, compare_school_provider, next);
-
school_type *school_at(int index)
{
assert(index >= 0);
@@ -41,8 +53,10 @@ static void school_init(school_type *school, cptr name, s16b skill)
{
assert(school != NULL);
+ static_assert(std::is_pod<school_type>::value, "Cannot initialize non-POD using memset!");
memset(school, 0, sizeof(school_type));
+ school->providers = new school_provider_list();
school->name = name;
school->skill = skill;
@@ -96,14 +110,15 @@ static school_type *god_school_new(s32b *school_idx, byte god)
static void school_god(school_type *school, byte god, int mul, int div)
{
+ assert(school->providers != nullptr);
+
deity_type *deity = god_at(god);
assert(deity != NULL);
/* Ignore gods which aren't enabled for this module. */
if (god_enabled(deity))
{
- school_provider *school_provider = school_provider_new(god, mul, div);
- sglib_school_provider_add(&school->providers, school_provider);
+ school->providers->v.push_back(school_provider_new(god, mul, div));
}
}
@@ -136,23 +151,17 @@ static bool_ geomancy_depends_satisfied()
long get_provided_levels(school_type *school)
{
- school_provider *school_provider = NULL;
- struct sglib_school_provider_iterator school_provider_it;
-
- for (school_provider = sglib_school_provider_it_init(&school_provider_it, school->providers);
- school_provider != NULL;
- school_provider = sglib_school_provider_it_next(&school_provider_it))
+ for (auto school_provider: school->providers->v)
{
- if (school_provider->deity_idx == p_ptr->pgod)
+ if (school_provider.deity_idx == p_ptr->pgod)
{
- return (s_info[school_provider->skill_idx].value * school_provider->mul) / school_provider->div;
+ return (s_info[school_provider.skill_idx].value * school_provider.mul) / school_provider.div;
}
}
return 0;
}
-typedef struct get_level_school_callback_data get_level_school_callback_data;
struct get_level_school_callback_data {
bool_ allow_spell_power;
long bonus;
@@ -160,9 +169,8 @@ struct get_level_school_callback_data {
long num;
};
-static bool_ get_level_school_callback(void *data_, int school_idx)
+static bool get_level_school_callback(struct get_level_school_callback_data *data, int school_idx)
{
- get_level_school_callback_data *data = data_;
school_type *school = school_at(school_idx);
long r = 0, s = 0, p = 0, ok = 0;
@@ -170,7 +178,7 @@ static bool_ get_level_school_callback(void *data_, int school_idx)
if ((school->deity_idx > 0) &&
(school->deity_idx != p_ptr->pgod))
{
- return FALSE;
+ return false;
}
/* Take the basic skill value */
@@ -180,7 +188,7 @@ static bool_ get_level_school_callback(void *data_, int school_idx)
if ((school->depends_satisfied != NULL) &&
(!school->depends_satisfied()))
{
- return FALSE;
+ return false;
}
/* Include effects of Sorcery (if applicable) */
@@ -219,7 +227,7 @@ static bool_ get_level_school_callback(void *data_, int school_idx)
/* All schools must be non-zero to be able to use it. */
if (ok <= 0)
{
- return FALSE;
+ return false;
}
/* Apply it */
@@ -227,13 +235,11 @@ static bool_ get_level_school_callback(void *data_, int school_idx)
data->num += 1;
/* Keep going */
- return TRUE;
+ return true;
}
-void get_level_school(s32b spell_idx, s32b max, s32b min, s32b *level, bool_ *na)
+void get_level_school(spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na)
{
- spell_type *spell = spell_at(spell_idx);
-
assert(level != NULL);
assert(na != NULL);
@@ -252,12 +258,16 @@ void get_level_school(s32b spell_idx, s32b max, s32b min, s32b *level, bool_ *na
data.lvl = 0;
data.num = 0;
- /* Go through all the spell's schools. */
- if (!spell_type_school_foreach(spell, get_level_school_callback, &data))
+ // Go through all the spell's schools and count up all the
+ // levels and make sure we can actually cast the spell.
+ for (auto school_idx : spell_type_get_schools(spell))
{
- *level = min;
- *na = TRUE;
- return;
+ if (!get_level_school_callback(&data, school_idx))
+ {
+ *level = min;
+ *na = TRUE;
+ return;
+ }
}
/* Add the Spellpower skill as a bonus on top */
@@ -378,7 +388,7 @@ void schools_init()
/* Placeholder schools */
{
school_new(&SCHOOL_DEVICE, "Device", SKILL_DEVICE);
- school_new(&SCHOOL_DEVICE, "Music", SKILL_MUSIC);
+ school_new(&SCHOOL_MUSIC, "Music", SKILL_MUSIC);
}
}
diff --git a/src/spells6.hpp b/src/spells6.hpp
new file mode 100644
index 00000000..bbd32d9b
--- /dev/null
+++ b/src/spells6.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "school_type_fwd.hpp"
+
+void schools_init();
+school_type *school_at(int index);
+void mana_school_calc_mana(int *msp);
diff --git a/src/squelch/CMakeLists.txt b/src/squelch/CMakeLists.txt
new file mode 100644
index 00000000..7b1495ba
--- /dev/null
+++ b/src/squelch/CMakeLists.txt
@@ -0,0 +1,9 @@
+ADD_LIBRARY(squelch
+ automatizer.cc
+ condition.cc
+ condition_metadata.cc
+ cursor.cc
+ object_status.cc
+ rule.cc
+ tree_printer.cc
+)
diff --git a/src/squelch/automatizer.cc b/src/squelch/automatizer.cc
new file mode 100644
index 00000000..c3c52b1b
--- /dev/null
+++ b/src/squelch/automatizer.cc
@@ -0,0 +1,278 @@
+#include "tome/squelch/automatizer_fwd.hpp"
+#include "tome/squelch/automatizer.hpp"
+
+#include "tome/squelch/rule.hpp"
+#include "tome/squelch/cursor.hpp"
+#include "tome/squelch/tree_printer.hpp"
+#include "util.hpp"
+#include "z-term.h"
+
+namespace squelch {
+
+/**
+ * Parse rules from JSON array
+ */
+static std::vector< std::shared_ptr < Rule > > parse_rules(json_t *rules_j)
+{
+ std::vector< std::shared_ptr < Rule > > rules;
+
+ if (!json_is_array(rules_j))
+ {
+ msg_format("Error 'rules' is not an array");
+ return rules;
+ }
+
+ for (size_t i = 0; i < json_array_size(rules_j); i++)
+ {
+ json_t *rule_j = json_array_get(rules_j, i);
+ auto rule = Rule::parse_rule(rule_j);
+ if (rule)
+ {
+ rules.push_back(rule);
+ }
+ }
+
+ return rules;
+}
+
+//----------------------------------------------------------
+// Automatizer
+//----------------------------------------------------------
+
+int Automatizer::append_rule(std::shared_ptr< Rule > rule)
+{
+ m_rules.push_back(rule);
+ return m_rules.size() - 1;
+}
+
+void Automatizer::swap_rules(int i, int j)
+{
+ swap(m_rules.at(i), m_rules.at(j));
+}
+
+bool Automatizer::apply_rules(object_type *o_ptr, int item_idx) const
+{
+ for (auto rule : m_rules)
+ {
+ if (rule->apply_rule(o_ptr, item_idx))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::shared_ptr<json_t> Automatizer::to_json() const
+{
+ auto rules_json = std::shared_ptr<json_t>(json_array(), &json_decref);
+
+ for (auto rule : m_rules)
+ {
+ json_array_append_new(rules_json.get(), rule->to_json());
+ }
+
+ return rules_json;
+}
+
+void Automatizer::load_json(json_t *json)
+{
+ // Go through all the found rules
+ auto rules = parse_rules(json);
+
+ // Load rule
+ for (auto rule : rules)
+ {
+ append_rule(rule);
+ }
+}
+
+int Automatizer::remove_current_selection()
+{
+ assert(!m_rules.empty());
+
+ // Previously selected rule
+ int prev_selected_rule = m_selected_rule;
+ int new_selected_rule;
+
+ // If the cursor is at the top level then we want to delete
+ // the rule itself
+ if (m_cursor->size() < 1)
+ {
+ // Remove rule
+ m_rules.erase(m_rules.begin() + m_selected_rule);
+ // Select previous
+ new_selected_rule = prev_selected_rule - 1;
+ }
+ else
+ {
+ // Delete the currently selected condition in rule.
+ m_rules.at(m_selected_rule)->delete_selected_condition(m_cursor.get());
+ // Keep selection
+ new_selected_rule = m_selected_rule;
+ }
+
+ // Do we need to adjust to select a different rule?
+ if ((prev_selected_rule != new_selected_rule) && (new_selected_rule >= 0))
+ {
+ select_rule(new_selected_rule);
+ }
+
+ // Return the selected rule.
+ return m_selected_rule;
+}
+
+void Automatizer::reset_view()
+{
+ // Clear cursor
+ m_cursor->clear();
+
+ // Empty rules?
+ if (m_rules.empty())
+ {
+ return;
+ }
+
+ // Reset scroll position
+ m_tree_printer->reset_scroll();
+
+ // Put the top-level condition into cursor
+ auto condition = m_rules.at(m_selected_rule)->get_condition();
+ if (condition)
+ {
+ m_cursor->push(condition.get());
+ }
+}
+
+void Automatizer::show_current() const
+{
+ if (m_rules.empty())
+ {
+ return;
+ }
+
+ m_tree_printer->reset();
+ m_rules.at(m_selected_rule)->write_tree(
+ m_tree_printer.get(),
+ m_cursor.get());
+}
+
+void Automatizer::scroll_up()
+{
+ m_tree_printer->scroll_up();
+}
+
+void Automatizer::scroll_down()
+{
+ m_tree_printer->scroll_down();
+}
+
+void Automatizer::scroll_left()
+{
+ m_tree_printer->scroll_left();
+}
+
+void Automatizer::scroll_right()
+{
+ m_tree_printer->scroll_right();
+}
+
+void Automatizer::move_up()
+{
+ m_cursor->move_up();
+}
+
+void Automatizer::move_down()
+{
+ m_cursor->move_down();
+}
+
+void Automatizer::move_left()
+{
+ m_cursor->move_left();
+}
+
+void Automatizer::move_right()
+{
+ m_cursor->move_right();
+}
+
+void Automatizer::add_new_condition(std::function<std::shared_ptr<Condition> ()> factory)
+{
+ m_rules.at(m_selected_rule)->add_new_condition(
+ m_cursor.get(),
+ factory);
+}
+
+void Automatizer::get_rule_names(std::vector<const char *> *names) const
+{
+ names->resize(m_rules.size());
+ for (size_t i = 0; i < m_rules.size(); i++)
+ {
+ (*names)[i] = m_rules.at(i)->get_name();
+ }
+}
+
+int Automatizer::rules_count() const
+{
+ return m_rules.size();
+}
+
+int Automatizer::rules_begin() const
+{
+ return m_begin;
+}
+
+void Automatizer::select_rule(int selected_rule)
+{
+ m_selected_rule = selected_rule;
+
+ int wid, hgt;
+ Term_get_size(&wid, &hgt);
+
+ // Adjust selection to conform to bounds.
+ {
+ int rules_size = m_rules.size(); // Convert to int to avoid warnings
+
+ if (m_selected_rule < 0)
+ {
+ m_selected_rule = rules_size - 1;
+ m_begin = m_selected_rule - hgt + 3;
+ if (m_begin < 0)
+ {
+ m_begin = 0;
+ }
+ }
+
+ if (m_selected_rule < m_begin)
+ {
+ m_begin = m_selected_rule;
+ }
+
+ if (m_selected_rule >= rules_size)
+ {
+ m_selected_rule = 0;
+ m_begin = 0;
+ }
+
+ if (m_selected_rule >= m_begin + hgt - 2)
+ {
+ m_begin++;
+ }
+ }
+
+ // Adjust tree printer and cursor.
+ reset_view();
+}
+
+int Automatizer::selected_rule() const
+{
+ return m_selected_rule;
+}
+
+std::shared_ptr<Rule> Automatizer::current_rule()
+{
+ return m_rules.at(m_selected_rule);
+}
+
+} // namespace
diff --git a/src/squelch/condition.cc b/src/squelch/condition.cc
new file mode 100644
index 00000000..c3b8c3f5
--- /dev/null
+++ b/src/squelch/condition.cc
@@ -0,0 +1,1078 @@
+#include "tome/squelch/condition_fwd.hpp"
+#include "tome/squelch/condition.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+#include "tome/squelch/cursor.hpp"
+#include "tome/squelch/tree_printer.hpp"
+#include "../ability_type.hpp"
+#include "../object1.hpp"
+#include "../object2.hpp"
+#include "../object_kind.hpp"
+#include "../object_type.hpp"
+#include "../player_race.hpp"
+#include "../player_race_mod.hpp"
+#include "../player_spec.hpp"
+#include "../player_type.hpp"
+#include "../skills.hpp"
+#include "../skill_type.hpp"
+#include "../quark.hpp"
+#include "../util.hpp"
+#include "../variable.hpp"
+
+namespace squelch {
+
+EnumStringMap<match_type> &match_mapping()
+{
+ // TODO: This is quite ugly and leads to valgrind complaints
+ static auto m = new EnumStringMap<match_type> {
+ { match_type::AND, "and" },
+ { match_type::OR, "or" },
+ { match_type::NOT, "not" },
+ { match_type::NAME, "name" },
+ { match_type::CONTAIN, "contain" },
+ { match_type::INSCRIBED, "inscribed" },
+ { match_type::DISCOUNT, "discount" },
+ { match_type::SYMBOL, "symbol" },
+ { match_type::STATE, "state" },
+ { match_type::STATUS, "status" },
+ { match_type::TVAL, "tval" },
+ { match_type::SVAL, "sval" },
+ { match_type::RACE, "race" },
+ { match_type::SUBRACE, "subrace" },
+ { match_type::CLASS, "class" },
+ { match_type::LEVEL, "level" },
+ { match_type::SKILL, "skill" },
+ { match_type::ABILITY, "ability" },
+ { match_type::INVENTORY, "inventory" },
+ { match_type::EQUIPMENT, "equipment" } };
+ return *m;
+};
+
+EnumStringMap<identification_state> &identification_state_mapping()
+{
+ // TODO: This is quite ugly and leads to valgrind complaints
+ static auto m = new EnumStringMap<identification_state> {
+ { identification_state::IDENTIFIED, "identified" },
+ { identification_state::NOT_IDENTIFIED, "not identified" } };
+ return *m;
+}
+
+json_t *Condition::to_json() const
+{
+ json_t *j = json_object();
+ json_object_set_new(j, "type",
+ json_string(match_mapping().stringify(match)));
+ to_json(j);
+ return j;
+}
+
+void Condition::display(TreePrinter *tree_printer, Cursor *cursor) const
+{
+ assert(tree_printer);
+
+ // Use normal or "selected" colours?
+ uint8_t bcol = TERM_L_GREEN;
+ uint8_t ecol = TERM_GREEN;
+ if (cursor->is_selected(this))
+ {
+ bcol = TERM_VIOLET;
+ ecol = TERM_VIOLET;
+ }
+
+ // Indent a level and display tree.
+ tree_printer->indent();
+ write_tree(tree_printer, cursor, ecol, bcol);
+ tree_printer->dedent();
+}
+
+std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json)
+{
+ // Parsers for concrete types of conditions.
+ static std::map< match_type,
+ std::function< std::shared_ptr< Condition > ( json_t * ) > > parsers {
+ { match_type::AND, &AndCondition::from_json },
+ { match_type::OR, &OrCondition::from_json },
+ { match_type::NOT, &NotCondition::from_json },
+ { match_type::INVENTORY, &InventoryCondition::from_json },
+ { match_type::EQUIPMENT, &EquipmentCondition::from_json },
+ { match_type::NAME, &NameCondition::from_json },
+ { match_type::CONTAIN, &ContainCondition::from_json },
+ { match_type::SYMBOL, &SymbolCondition::from_json },
+ { match_type::INSCRIBED, &InscriptionCondition::from_json },
+ { match_type::DISCOUNT, &DiscountCondition::from_json },
+ { match_type::TVAL, &TvalCondition::from_json },
+ { match_type::SVAL, &SvalCondition::from_json },
+ { match_type::STATUS, &StatusCondition::from_json },
+ { match_type::STATE, &StateCondition::from_json },
+ { match_type::RACE, &RaceCondition::from_json },
+ { match_type::SUBRACE, &SubraceCondition::from_json },
+ { match_type::CLASS, &ClassCondition::from_json },
+ { match_type::LEVEL, &LevelCondition::from_json },
+ { match_type::SKILL, &SkillCondition::from_json },
+ { match_type::ABILITY, &AbilityCondition::from_json } };
+
+ if ((condition_json == nullptr) || json_is_null(condition_json))
+ {
+ return nullptr;
+ }
+
+ cptr type_s = nullptr;
+ if (json_unpack(condition_json,
+ "{s:s}",
+ "type", &type_s) < 0)
+ {
+ msg_print("Missing/invalid 'type' in condition");
+ return nullptr;
+ }
+
+ match_type match;
+ if (!match_mapping().parse(type_s, &match))
+ {
+ msg_format("Invalid 'type' in condition: %s", type_s);
+ return nullptr;
+ }
+
+ // Look up parser and... parse
+ auto parser_i = parsers.find(match);
+ if (parser_i != parsers.end())
+ {
+ return parser_i->second(condition_json);
+ }
+
+ assert(false && "Missing parser");
+ return nullptr;
+}
+
+json_t *Condition::optional_to_json(std::shared_ptr<Condition> condition)
+{
+ return condition
+ ? condition->to_json()
+ : json_null();
+}
+
+bool TvalCondition::is_match(object_type *o_ptr) const
+{
+ return (o_ptr->tval == m_tval);
+}
+
+std::shared_ptr<Condition> TvalCondition::from_json(json_t *j)
+{
+ int tval;
+
+ if (json_unpack(j, "{s:i}", "tval", &tval) < 0)
+ {
+ msg_print("Missing/invalid 'tval' property");
+ return nullptr;
+ }
+
+ return std::make_shared<TvalCondition>(tval);
+}
+
+void TvalCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "tval", json_integer(m_tval));
+}
+
+void TvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "tval");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, format("%d", (int) m_tval));
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+bool NameCondition::is_match(object_type *o_ptr) const
+{
+ char buf1[128];
+ object_desc(buf1, o_ptr, -1, 0);
+
+ return boost::algorithm::iequals(m_name, buf1);
+}
+
+std::shared_ptr<Condition> NameCondition::from_json(json_t *j)
+{
+ cptr s = nullptr;
+ if (json_unpack(j, "{s:s}", "name", &s) < 0)
+ {
+ msg_print("Missing/invalid 'name' property");
+ return nullptr;
+ }
+ return std::make_shared<NameCondition>(s);
+}
+
+void NameCondition::write_tree(TreePrinter *p, Cursor *cursor, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "name");
+ p->write(ecol, " is \"");
+ p->write(TERM_WHITE, m_name.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void NameCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "name", json_string(m_name.c_str()));
+}
+
+bool ContainCondition::is_match(object_type *o_ptr) const
+{
+ char buf1[128];
+ object_desc(buf1, o_ptr, -1, 0);
+ return boost::algorithm::icontains(buf1, m_contain);
+}
+
+std::shared_ptr<Condition> ContainCondition::from_json(json_t *j)
+{
+ cptr s = nullptr;
+ if (json_unpack(j, "{s:s}", "contain", &s) < 0)
+ {
+ msg_print("Missing/invalid 'contain' property");
+ return nullptr;
+ }
+ return std::make_shared<ContainCondition>(s);
+}
+
+void ContainCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "name");
+ p->write(ecol, " contains \"");
+ p->write(TERM_WHITE, m_contain.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void ContainCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "contain", json_string(m_contain.c_str()));
+}
+
+bool SvalCondition::is_match(object_type *o_ptr) const
+{
+ return (object_aware_p(o_ptr) &&
+ (o_ptr->sval >= m_min) &&
+ (o_ptr->sval <= m_max));
+}
+
+std::shared_ptr<Condition> SvalCondition::from_json(json_t *j)
+{
+ int min, max;
+
+ if (json_unpack(j, "{s:i,s:i}",
+ "min", &min,
+ "max", &max) < 0)
+ {
+ msg_print("Missing/invalid 'min'/'max' properties");
+ return nullptr;
+ }
+
+ return std::make_shared<SvalCondition>(min, max);
+}
+
+void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "sval");
+ p->write(ecol, " is from ");
+ p->write(TERM_WHITE, format("%d", m_min));
+ p->write(ecol, " to ");
+ p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, "\n");
+}
+
+void SvalCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "min", json_integer(m_min));
+ json_object_set_new(j, "max", json_integer(m_max));
+}
+
+void GroupingCondition::add_child(ConditionFactory const &factory)
+{
+ auto c_ptr = factory();
+ if (c_ptr)
+ {
+ m_conditions.push_back(c_ptr);
+ }
+}
+
+void GroupingCondition::remove_child(Condition *condition)
+{
+ m_conditions.erase(
+ std::remove_if(
+ std::begin(m_conditions),
+ std::end(m_conditions),
+ [&] (std::shared_ptr<Condition> p) {
+ return p.get() == condition;
+ }),
+ std::end(m_conditions));
+}
+
+std::shared_ptr<Condition> GroupingCondition::first_child()
+{
+ if (!m_conditions.empty())
+ {
+ return m_conditions.front();
+ }
+ return nullptr;
+}
+
+std::shared_ptr<Condition> GroupingCondition::previous_child(Condition *current)
+{
+ std::shared_ptr<Condition> prev_condition;
+
+ for (auto condition_p : m_conditions)
+ {
+ if (condition_p.get() == current)
+ {
+ // Do we have a previous child?
+ if (prev_condition)
+ {
+ return prev_condition;
+ }
+ else
+ {
+ // No predecessor
+ return nullptr;
+ }
+ }
+ // Keep track of predecessor
+ prev_condition = condition_p;
+ }
+
+ return nullptr;
+}
+
+std::shared_ptr<Condition> GroupingCondition::next_child(Condition *current)
+{
+ for (auto it = m_conditions.begin();
+ it != m_conditions.end();
+ it++)
+ {
+ if (it->get() == current)
+ {
+ it++;
+ // Move to next child (if any)
+ if (it == m_conditions.end())
+ {
+ // No successor
+ return nullptr;
+ }
+
+ return *it;
+ }
+ }
+
+ return nullptr;
+}
+
+std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(json_t *j)
+{
+ json_t *conditions_j = json_object_get(j, "conditions");
+
+ if ((conditions_j == nullptr) ||
+ (json_is_null(conditions_j)))
+ {
+ return std::vector< std::shared_ptr<Condition> >();
+ }
+ else if (!json_is_array(conditions_j))
+ {
+ msg_print("'conditions' property has invalid type");
+ return std::vector< std::shared_ptr<Condition> >();
+ }
+ else
+ {
+ std::vector< std::shared_ptr<Condition> > subconditions;
+ for (size_t i = 0; i < json_array_size(conditions_j); i++)
+ {
+ json_t *subcondition_j =
+ json_array_get(conditions_j, i);
+
+ std::shared_ptr<Condition> subcondition =
+ parse_condition(subcondition_j);
+
+ if (subcondition != nullptr)
+ {
+ subconditions.push_back(subcondition);
+ }
+ }
+ return subconditions;
+ }
+}
+
+void GroupingCondition::to_json(json_t *j) const
+{
+ json_t *ja = json_array();
+ for (auto condition_p : m_conditions)
+ {
+ json_array_append_new(ja, optional_to_json(condition_p));
+ }
+ json_object_set_new(j, "conditions", ja);
+}
+
+bool AndCondition::is_match(object_type *o_ptr) const
+{
+ for (auto condition_p : m_conditions)
+ {
+ if (!condition_p->is_match(o_ptr))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+std::shared_ptr<Condition> AndCondition::from_json(json_t *j)
+{
+ auto condition = std::make_shared<AndCondition>();
+ for (auto subcondition : parse_conditions(j))
+ {
+ condition->add_condition(subcondition);
+ }
+ return condition;
+}
+
+void AndCondition::write_tree(TreePrinter *p, Cursor *c, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "All of the following are true:");
+ p->write(TERM_WHITE, "\n");
+
+ for (auto condition_p : m_conditions)
+ {
+ condition_p->display(p, c);
+ }
+}
+
+bool OrCondition::is_match(object_type *o_ptr) const
+{
+ for (auto condition_p : m_conditions)
+ {
+ if (condition_p->is_match(o_ptr))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::shared_ptr<Condition> OrCondition::from_json(json_t *j)
+{
+ std::shared_ptr<OrCondition> condition =
+ std::make_shared<OrCondition>();
+
+ for (auto subcondition : parse_conditions(j))
+ {
+ condition->add_condition(subcondition);
+ }
+
+ return condition;
+}
+
+void OrCondition::write_tree(TreePrinter *p, Cursor *c, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "At least one of the following are true:");
+ p->write(TERM_WHITE, "\n");
+
+ for (auto condition_p : m_conditions)
+ {
+ condition_p->display(p, c);
+ }
+}
+
+bool StatusCondition::is_match(object_type *o_ptr) const
+{
+ return m_status == object_status(o_ptr);
+}
+
+std::shared_ptr<Condition> StatusCondition::from_json(json_t *j)
+{
+ cptr s;
+ if (json_unpack(j, "{s:s}", "status", &s) < 0)
+ {
+ msg_print("Missing/invalid 'status' property");
+ return nullptr;
+ }
+
+ status_type status;
+ if (!status_mapping().parse(s, &status))
+ {
+ msg_format("Invalid 'status' property: %s", s);
+ return nullptr;
+ }
+
+ return std::make_shared<StatusCondition>(status);
+}
+
+void StatusCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "status");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, status_mapping().stringify(m_status));
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void StatusCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "status", json_string(status_mapping().stringify(m_status)));
+}
+
+bool RaceCondition::is_match(object_type *o_ptr) const
+{
+ return boost::algorithm::iequals(m_race, rp_ptr->title);
+}
+
+std::shared_ptr<Condition> RaceCondition::from_json(json_t *j)
+{
+ cptr s;
+
+ if (json_unpack(j, "{s:s}", "race", &s) < 0)
+ {
+ msg_print("Missing/invalid 'race' property");
+ return nullptr;
+ }
+
+ return std::make_shared<RaceCondition>(s);
+}
+
+void RaceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Player ");
+ p->write(bcol, "race");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, m_race.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void RaceCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "race", json_string(m_race.c_str()));
+}
+
+bool SubraceCondition::is_match(object_type *o_ptr) const
+{
+ return boost::algorithm::iequals(m_subrace, rmp_ptr->title);
+}
+
+std::shared_ptr<Condition> SubraceCondition::from_json(json_t *j)
+{
+ cptr s;
+
+ if (json_unpack(j, "{s:s}", "subrace", &s) < 0)
+ {
+ msg_print("Missing/invalid 'subrace' property");
+ return nullptr;
+ }
+
+ return std::make_shared<SubraceCondition>(s);
+}
+
+void SubraceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Player ");
+ p->write(bcol, "subrace");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, m_subrace.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void SubraceCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "subrace", json_string(m_subrace.c_str()));
+}
+
+bool ClassCondition::is_match(object_type *o_ptr) const
+{
+ return boost::algorithm::iequals(m_class, spp_ptr->title);
+}
+
+std::shared_ptr<Condition> ClassCondition::from_json(json_t *j)
+{
+ cptr s;
+
+ if (json_unpack(j, "{s:s}", "class", &s) < 0)
+ {
+ msg_print("Missing/invalid 'class' property");
+ return nullptr;
+ }
+
+ return std::make_shared<ClassCondition>(s);
+}
+
+void ClassCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Player ");
+ p->write(bcol, "class");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, m_class.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void ClassCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "class", json_string(m_class.c_str()));
+}
+
+bool InscriptionCondition::is_match(object_type *o_ptr) const
+{
+ if (o_ptr->note == 0)
+ {
+ return false;
+ }
+ return boost::algorithm::icontains(
+ quark_str(o_ptr->note),
+ m_inscription);
+}
+
+std::shared_ptr<Condition> InscriptionCondition::from_json(json_t *j)
+{
+ cptr s = nullptr;
+ if (json_unpack(j, "{s:s}", "inscription", &s) < 0)
+ {
+ msg_print("Missing/invalid 'inscription' property");
+ return nullptr;
+ }
+ return std::make_shared<InscriptionCondition>(s);
+}
+
+void InscriptionCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "It is ");
+ p->write(bcol, "inscribed");
+ p->write(ecol, " with ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, m_inscription.c_str());
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void InscriptionCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "inscription", json_string(m_inscription.c_str()));
+}
+
+bool DiscountCondition::is_match(object_type *o_ptr) const
+{
+ return (object_aware_p(o_ptr) &&
+ (o_ptr->discount >= m_min) &&
+ (o_ptr->discount <= m_max));
+}
+
+std::shared_ptr<Condition> DiscountCondition::from_json(json_t *j)
+{
+ int min, max;
+
+ if (json_unpack(j, "{s:i,s:i}",
+ "min", &min,
+ "max", &max) < 0)
+ {
+ msg_print("Missing/invalid 'min'/'max' properties");
+ return nullptr;
+ }
+
+ return std::make_shared<DiscountCondition>(min, max);
+}
+
+void DiscountCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "discount");
+ p->write(ecol, " is from ");
+ p->write(TERM_WHITE, format("%d", m_min));
+ p->write(ecol, " to ");
+ p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, "\n");
+}
+
+void DiscountCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "min", json_integer(m_min));
+ json_object_set_new(j, "max", json_integer(m_max));
+}
+
+bool LevelCondition::is_match(object_type *) const
+{
+ return ((p_ptr->lev >= m_min) &&
+ (p_ptr->lev <= m_max));
+}
+
+std::shared_ptr<Condition> LevelCondition::from_json(json_t *j)
+{
+ int min, max;
+ if (json_unpack(j, "{s:i,s:i}",
+ "min", &min,
+ "max", &max) < 0)
+ {
+ msg_print("Missing/invalid 'min'/'max' properties");
+ return nullptr;
+ }
+
+ return std::make_shared<LevelCondition>(min, max);
+}
+
+void LevelCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Your ");
+ p->write(bcol, "level");
+ p->write(ecol, " is from ");
+
+ p->write(TERM_WHITE, format("%d", m_min));
+ p->write(ecol, " to ");
+ p->write(TERM_WHITE, format("%d", m_max));
+ p->write(TERM_WHITE, "\n");
+}
+
+void LevelCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "min", json_integer(m_min));
+ json_object_set_new(j, "max", json_integer(m_max));
+}
+
+bool SkillCondition::is_match(object_type *) const
+{
+ uint16_t sk = get_skill(m_skill_idx);
+ return ((sk >= m_min) &&
+ (sk <= m_max));
+}
+
+std::shared_ptr<Condition> SkillCondition::from_json(json_t *j)
+{
+ cptr s;
+ int min, max;
+ if (json_unpack(j, "{s:i,s:i,s:s}",
+ "min", &min,
+ "max", &max,
+ "name", &s) < 0)
+ {
+ msg_print("Missing/invalid 'min'/'max'/'name' properties");
+ return nullptr;
+ }
+
+ auto si = find_skill_i(s);
+ if (si < 0)
+ {
+ msg_print("Invalid 'name' property");
+ return nullptr;
+ }
+
+ return std::make_shared<SkillCondition>(si, min, max);
+}
+
+void SkillCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Your skill in ");
+ p->write(bcol, s_info[m_skill_idx].name);
+ p->write(ecol, " is from ");
+ p->write(TERM_WHITE, format("%d", (int) m_min));
+ p->write(ecol, " to ");
+ p->write(TERM_WHITE, format("%d", (int) m_max));
+ p->write(TERM_WHITE, "\n");
+}
+
+void SkillCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "name",
+ json_string(s_info[m_skill_idx].name));
+ json_object_set_new(j, "min",
+ json_integer(m_min));
+ json_object_set_new(j, "max",
+ json_integer(m_max));
+}
+
+bool StateCondition::is_match(object_type *o_ptr) const
+{
+ switch (m_state)
+ {
+ case identification_state::IDENTIFIED:
+ return object_known_p(o_ptr);
+ case identification_state::NOT_IDENTIFIED:
+ return !object_known_p(o_ptr);
+ }
+
+ assert(false);
+ return false;
+}
+
+std::shared_ptr<Condition> StateCondition::from_json(json_t *j)
+{
+ cptr s;
+ if (json_unpack(j, "{s:s}", "state", &s) < 0)
+ {
+ msg_print("Missing/invalid 'state' property");
+ return nullptr;
+ }
+
+ identification_state state;
+ if (!identification_state_mapping().parse(s, &state))
+ {
+ msg_format("Invalid 'state' property: %s", s);
+ return nullptr;
+ }
+
+ return std::make_shared<StateCondition>(state);
+}
+
+void StateCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "state");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, identification_state_mapping().stringify(m_state));
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void StateCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "state",
+ json_string(identification_state_mapping().
+ stringify(m_state)));
+}
+
+bool SymbolCondition::is_match(object_type *o_ptr) const
+{
+ object_kind *k_ptr = &k_info[o_ptr->k_idx];
+ return k_ptr->d_char == m_symbol;
+}
+
+std::shared_ptr<Condition> SymbolCondition::from_json(json_t *j)
+{
+ cptr s_ = nullptr;
+ if (json_unpack(j, "{s:s}", "symbol", &s_) < 0)
+ {
+ msg_print("Missing/invalid 'symbol' property");
+ return nullptr;
+ }
+
+ std::string s(s_);
+ if (s.empty())
+ {
+ msg_print("Invalid 'symbol' property: Too short");
+ return nullptr;
+ }
+ if (s.size() > 1)
+ {
+ msg_print("Invalid 'symbol' property: Too long");
+ return nullptr;
+ }
+
+ return std::make_shared<SymbolCondition>(s[0]);
+}
+
+void SymbolCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ p->write(ecol, "Its ");
+ p->write(bcol, "symbol");
+ p->write(ecol, " is ");
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, format("%c", m_symbol));
+ p->write(ecol, "\"");
+ p->write(TERM_WHITE, "\n");
+}
+
+void SymbolCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "symbol",
+ json_string(format("%c", m_symbol)));
+}
+
+bool AbilityCondition::is_match(object_type *) const
+{
+ return has_ability(m_ability_idx);
+}
+
+std::shared_ptr<Condition> AbilityCondition::from_json(json_t *j)
+{
+ cptr a;
+ if (json_unpack(j, "{s:s}", "ability", &a) < 0)
+ {
+ msg_print("Missing/invalid 'ability' property");
+ return nullptr;
+ }
+
+ auto ai = find_ability(a);
+ if (ai < 0)
+ {
+ msg_print("Invalid 'ability' property");
+ return nullptr;
+ }
+
+ return std::make_shared<AbilityCondition>(ai);
+}
+
+void AbilityCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
+{
+ cptr ability_s = ab_info[m_ability_idx].name;
+
+ p->write(ecol, "You have the ");
+ p->write(bcol, ability_s);
+ p->write(ecol, " ability");
+ p->write(TERM_WHITE, "\n");
+}
+
+void AbilityCondition::to_json(json_t *j) const
+{
+ cptr ability_s = ab_info[m_ability_idx].name;
+ json_object_set_new(j, "ability", json_string(ability_s));
+}
+
+void SingleSubconditionCondition::add_child(std::function< std::shared_ptr<Condition> () > const &factory)
+{
+ // If we already have a subcondition then we cannot
+ // add one.
+ if (!m_subcondition)
+ {
+ m_subcondition = factory();
+ }
+}
+
+void SingleSubconditionCondition::remove_child(Condition *c)
+{
+ if (m_subcondition.get() == c) {
+ m_subcondition.reset();
+ }
+}
+
+std::shared_ptr<Condition> SingleSubconditionCondition::first_child()
+{
+ return m_subcondition;
+}
+
+void SingleSubconditionCondition::to_json(json_t *j) const
+{
+ json_object_set_new(j, "condition",
+ optional_to_json(m_subcondition));
+}
+
+std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(json_t *in_json)
+{
+ json_t *condition_j =
+ json_object_get(in_json, "condition");
+
+ if ((condition_j == nullptr) ||
+ (json_is_null(condition_j)))
+ {
+ return nullptr;
+ }
+ else if (!json_is_object(condition_j))
+ {
+ msg_format("Invalid 'condition' property");
+ return nullptr;
+ }
+ else
+ {
+ return parse_condition(condition_j);
+ }
+}
+
+bool NotCondition::is_match(object_type *o_ptr) const
+{
+ if (!m_subcondition)
+ {
+ return true;
+ }
+
+ return !m_subcondition->is_match(o_ptr);
+}
+
+std::shared_ptr<Condition> NotCondition::from_json(json_t *j)
+{
+ return std::make_shared<NotCondition>(parse_single_subcondition(j));
+}
+
+void NotCondition::write_tree(TreePrinter *p, Cursor *c, byte ecol, byte bcol) const
+{
+ p->write(ecol, "Negate the following:");
+ p->write(TERM_WHITE, "\n");
+ if (m_subcondition)
+ {
+ m_subcondition->display(p, c);
+ }
+}
+
+bool InventoryCondition::is_match(object_type *) const
+{
+ if (!m_subcondition)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < INVEN_WIELD; i++)
+ {
+ if (m_subcondition->is_match(&p_ptr->inventory[i]))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::shared_ptr<Condition> InventoryCondition::from_json(json_t *j)
+{
+ return std::make_shared<InventoryCondition>(
+ parse_single_subcondition(j));
+}
+
+void InventoryCondition::write_tree(TreePrinter *p, Cursor *c, byte ecol, byte bcol) const
+{
+ p->write(ecol, "Something in your ");
+ p->write(bcol, "inventory");
+ p->write(ecol, " matches the following:");
+ p->write(TERM_WHITE, "\n");
+ if (m_subcondition)
+ {
+ m_subcondition->display(p, c);
+ }
+}
+
+bool EquipmentCondition::is_match(object_type *) const
+{
+ if (!m_subcondition)
+ {
+ return false;
+ }
+
+ for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++)
+ {
+ if (m_subcondition->is_match(&p_ptr->inventory[i]))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::shared_ptr<Condition> EquipmentCondition::from_json(json_t *j)
+{
+ return std::make_shared<EquipmentCondition>(
+ parse_single_subcondition(j));
+}
+
+void EquipmentCondition::write_tree(TreePrinter *p, Cursor *c, byte ecol, byte bcol) const
+{
+ p->write(ecol, "Something in your ");
+ p->write(bcol, "equipment");
+ p->write(ecol, " matches the following:");
+ p->write(TERM_WHITE, "\n");
+ if (m_subcondition)
+ {
+ m_subcondition->display(p, c);
+ }
+}
+
+} // namespace
diff --git a/src/squelch/condition_metadata.cc b/src/squelch/condition_metadata.cc
new file mode 100644
index 00000000..62a90e58
--- /dev/null
+++ b/src/squelch/condition_metadata.cc
@@ -0,0 +1,496 @@
+#include "tome/squelch/condition_metadata.hpp"
+#include "tome/squelch/condition.hpp"
+
+#include <vector>
+
+#include "tome/squelch/object_status.hpp"
+#include "lua_bind.hpp"
+#include "skills.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "z-term.h"
+
+namespace squelch {
+
+static std::shared_ptr<Condition> create_condition_name()
+{
+ cptr s = lua_input_box("Object name to match?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<NameCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_contain()
+{
+ cptr s = lua_input_box("Word to find in object name?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<ContainCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_inscribed()
+{
+ cptr s = lua_input_box("Word to find in object inscription?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<InscriptionCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_discount()
+{
+ int min, max;
+
+ {
+ cptr s = lua_input_box("Min discount?", 79);
+ if (sscanf(s, "%d", &min) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ {
+ cptr s = lua_input_box("Max discount?", 79);
+ if (sscanf(s, "%d", &max) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ return std::make_shared<DiscountCondition>(min, max);
+}
+
+static std::shared_ptr<Condition> create_condition_symbol()
+{
+ char c;
+ cptr s = lua_input_box("Symbol to match?", 1);
+ if (sscanf(s, "%c", &c) < 1)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<SymbolCondition>(c);
+}
+
+static std::shared_ptr<Condition> create_condition_status()
+{
+ status_type status;
+ char c;
+
+ c = lua_msg_box("[t]errible, [v]ery bad, [b]ad, "
+ "[a]verage, [G]ood, [V]ery good, [S]pecial?");
+
+ switch (c)
+ {
+ case 't': status = status_type::TERRIBLE; break;
+ case 'v': status = status_type::VERY_BAD; break;
+ case 'b': status = status_type::BAD; break;
+ case 'a': status = status_type::AVERAGE; break;
+ case 'G': status = status_type::GOOD; break;
+ case 'V': status = status_type::VERY_GOOD; break;
+ case 'S': status = status_type::SPECIAL; break;
+ default: return nullptr;
+ }
+
+ return std::make_shared<StatusCondition>(status);
+}
+
+static std::shared_ptr<Condition> create_condition_state()
+{
+ char c = lua_msg_box("[i]dentified, [n]on identified?");
+
+ identification_state s;
+ switch (c)
+ {
+ case 'i': s = identification_state::IDENTIFIED; break;
+ case 'n': s = identification_state::NOT_IDENTIFIED; break;
+ default: return nullptr;
+ }
+
+ return std::make_shared<StateCondition>(s);
+}
+
+static bool in_byte_range(int x)
+{
+ return (x >= 0) && (x < 256);
+}
+
+static std::shared_ptr<Condition> create_condition_tval()
+{
+ cptr s = lua_input_box("Tval to match?", 79);
+ int tval;
+ if (sscanf(s, "%d", &tval) < 1)
+ {
+ return nullptr;
+ }
+
+ if (!in_byte_range(tval))
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<TvalCondition>(tval);
+}
+
+static std::shared_ptr<Condition> create_condition_sval()
+{
+ int sval_min, sval_max;
+
+ {
+ cptr s = lua_input_box("Min sval?", 79);
+ if ((sscanf(s, "%d", &sval_min) < 1) ||
+ (!in_byte_range(sval_min)))
+ {
+ return nullptr;
+ }
+ }
+
+ {
+ cptr s = lua_input_box("Max sval?", 79);
+ if ((sscanf(s, "%d", &sval_max) < 1) ||
+ (!in_byte_range(sval_max)))
+ {
+ return nullptr;
+ }
+ }
+
+ return std::make_shared<SvalCondition>(sval_min, sval_max);
+}
+
+static std::shared_ptr<Condition> create_condition_race()
+{
+ cptr s = lua_input_box("Player race to match?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<RaceCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_subrace()
+{
+ cptr s = lua_input_box("Player subrace to match?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<SubraceCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_class()
+{
+ cptr s = lua_input_box("Player class to match?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<ClassCondition>(s);
+}
+
+static std::shared_ptr<Condition> create_condition_level()
+{
+ int min, max;
+
+ {
+ cptr s = lua_input_box("Min player level?", 79);
+ if (sscanf(s, "%d", &min) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ {
+ cptr s = lua_input_box("Max player level?", 79);
+ if (sscanf(s, "%d", &max) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ return std::make_shared<LevelCondition>(min, max);
+}
+
+static std::shared_ptr<Condition> create_condition_skill()
+{
+ int min, max;
+
+ {
+ cptr s = lua_input_box("Min skill level?", 79);
+ if (sscanf(s, "%d", &min) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ {
+ cptr s = lua_input_box("Max skill level?", 79);
+ if (sscanf(s, "%d", &max) < 1)
+ {
+ return nullptr;
+ }
+ }
+
+ s16b skill_idx;
+ {
+ cptr s = lua_input_box("Skill name?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ skill_idx = find_skill_i(s);
+ if (skill_idx < 0)
+ {
+ return nullptr;
+ }
+ }
+
+ return std::make_shared<SkillCondition>(skill_idx, min, max);
+}
+
+static std::shared_ptr<Condition> create_condition_ability()
+{
+ cptr s = lua_input_box("Ability name?", 79);
+ if (strlen(s) == 0)
+ {
+ return nullptr;
+ }
+
+ s16b ai = find_ability(s);
+ if (ai < 0)
+ {
+ return nullptr;
+ }
+
+ return std::make_shared<AbilityCondition>(ai);
+}
+
+static void display_desc(match_type match_type_)
+{
+ int i = 0;
+ auto line = [&i] (const char *s) {
+ c_prt(TERM_WHITE, s, i + 1, 17);
+ i++;
+ };
+
+ switch (match_type_)
+ {
+ case match_type::AND:
+ line("Check is true if all rules within it are true");
+ break;
+
+ case match_type::OR:
+ line("Check is true if at least one rule within it is true");
+ break;
+
+ case match_type::NOT:
+ line("Invert the result of its child rule");
+ break;
+
+ case match_type::NAME:
+ line("Check is true if object name matches name");
+ break;
+
+ case match_type::CONTAIN:
+ line("Check is true if object name contains word");
+ break;
+
+ case match_type::INSCRIBED:
+ line("Check is true if object inscription contains word");
+ break;
+
+ case match_type::DISCOUNT:
+ line("Check is true if object discount is between two values");
+ break;
+
+ case match_type::SYMBOL:
+ line("Check is true if object symbol is ok");
+ break;
+
+ case match_type::STATE:
+ line("Check is true if object is identified/unidentified");
+ break;
+
+ case match_type::STATUS:
+ line("Check is true if object status is ok");
+ break;
+
+ case match_type::TVAL:
+ line("Check is true if object tval(from k_info.txt) is ok");
+
+ case match_type::SVAL:
+ line("Check is true if object sval(from k_info.txt) is between");
+ line("two values");
+ break;
+
+ case match_type::RACE:
+ line("Check is true if player race is ok");
+ break;
+
+ case match_type::SUBRACE:
+ line("Check is true if player subrace is ok");
+ break;
+
+ case match_type::CLASS:
+ line("Check is true if player class is ok");
+ break;
+
+ case match_type::LEVEL:
+ line("Check is true if player level is between 2 values");
+ break;
+
+ case match_type::SKILL:
+ line("Check is true if player skill level is between 2 values");
+ break;
+
+ case match_type::ABILITY:
+ line("Check is true if player has the ability");
+ break;
+
+ case match_type::INVENTORY:
+ line("Check is true if something in player's inventory matches");
+ line("the contained rule");
+ break;
+
+ case match_type::EQUIPMENT:
+ line("Check is true if something in player's equipment matches");
+ line("the contained rule");
+ break;
+ }
+}
+
+std::shared_ptr<Condition> new_condition_interactive()
+{
+ static std::vector<match_type> condition_types = {
+ match_type::AND,
+ match_type::OR,
+ match_type::NOT,
+ match_type::NAME,
+ match_type::CONTAIN,
+ match_type::INSCRIBED,
+ match_type::DISCOUNT,
+ match_type::SYMBOL,
+ match_type::STATE,
+ match_type::STATUS,
+ match_type::TVAL,
+ match_type::SVAL,
+ match_type::RACE,
+ match_type::SUBRACE,
+ match_type::CLASS,
+ match_type::LEVEL,
+ match_type::SKILL,
+ match_type::ABILITY,
+ match_type::INVENTORY,
+ match_type::EQUIPMENT
+ };
+ static std::vector<const char *> condition_type_names;
+
+ // Fill in types names?
+ if (condition_type_names.empty())
+ {
+ for (auto condition_type : condition_types)
+ {
+ condition_type_names.push_back(
+ match_mapping().stringify(condition_type));
+ }
+ }
+
+ // Choose
+ int begin = 0, sel = 0;
+ while (1)
+ {
+ int wid, hgt;
+ Term_clear();
+ Term_get_size(&wid, &hgt);
+
+ display_list(0, 0, hgt - 1, 15, "Rule types", condition_type_names.data(), condition_types.size(), begin, sel, TERM_L_GREEN);
+
+ display_desc(condition_types[sel]);
+
+ char c = inkey();
+
+ if (c == ESCAPE) break;
+ else if (c == '8')
+ {
+ sel--;
+ if (sel < 0)
+ {
+ sel = condition_types.size() - 1;
+ begin = condition_types.size() - hgt;
+ if (begin < 0) begin = 0;
+ }
+ if (sel < begin) begin = sel;
+ }
+ else if (c == '2')
+ {
+ sel++;
+ if (sel >= static_cast<int>(condition_types.size()))
+ {
+ sel = 0;
+ begin = 0;
+ }
+ if (sel >= begin + hgt - 1) begin++;
+ }
+ else if (c == '\r')
+ {
+ switch (condition_types[sel])
+ {
+ case match_type::AND:
+ return std::make_shared<AndCondition>();
+ case match_type::OR:
+ return std::make_shared<OrCondition>();
+ case match_type::NOT:
+ return std::make_shared<NotCondition>();
+ case match_type::NAME:
+ return create_condition_name();
+ case match_type::CONTAIN:
+ return create_condition_contain();
+ case match_type::INSCRIBED:
+ return create_condition_inscribed();
+ case match_type::DISCOUNT:
+ return create_condition_discount();
+ case match_type::SYMBOL:
+ return create_condition_symbol();
+ case match_type::STATE:
+ return create_condition_state();
+ case match_type::STATUS:
+ return create_condition_status();
+ case match_type::TVAL:
+ return create_condition_tval();
+ case match_type::SVAL:
+ return create_condition_sval();
+ case match_type::RACE:
+ return create_condition_race();
+ case match_type::SUBRACE:
+ return create_condition_subrace();
+ case match_type::CLASS:
+ return create_condition_class();
+ case match_type::LEVEL:
+ return create_condition_level();
+ case match_type::SKILL:
+ return create_condition_skill();
+ case match_type::ABILITY:
+ return create_condition_ability();
+ case match_type::INVENTORY:
+ return std::make_shared<InventoryCondition>();
+ case match_type::EQUIPMENT:
+ return std::make_shared<EquipmentCondition>();
+
+ }
+ }
+ }
+ return nullptr;
+}
+
+} // namespace
diff --git a/src/squelch/cursor.cc b/src/squelch/cursor.cc
new file mode 100644
index 00000000..3a3bec46
--- /dev/null
+++ b/src/squelch/cursor.cc
@@ -0,0 +1,96 @@
+#include "tome/squelch/cursor_fwd.hpp"
+#include "tome/squelch/cursor.hpp"
+
+#include <algorithm>
+#include <cassert>
+
+#include "tome/squelch/condition.hpp"
+
+namespace squelch {
+
+bool Cursor::is_selected(Condition const *condition) const
+{
+ return std::end(m_conditions) !=
+ std::find(std::begin(m_conditions),
+ std::end(m_conditions),
+ condition);
+}
+
+Condition *Cursor::pop()
+{
+ assert(!m_conditions.empty());
+ Condition *c = m_conditions.back();
+ m_conditions.pop_back();
+ return c;
+}
+
+Condition *Cursor::current()
+{
+ assert(!m_conditions.empty());
+ return m_conditions.back();
+}
+
+void Cursor::move_right()
+{
+ if (m_conditions.empty()) {
+ return;
+ }
+ // Go right if the currently selected condition has children.
+ std::shared_ptr<Condition> c = current()->first_child();
+ if (c)
+ {
+ push(c.get());
+ }
+}
+
+void Cursor::move_left()
+{
+ if (size() > 1)
+ {
+ pop();
+ }
+}
+
+void Cursor::move_up()
+{
+ if (size() > 1)
+ {
+ Condition *prev_top = pop();
+
+ // Find previous child
+ std::shared_ptr<Condition> prev_condition =
+ current()->previous_child(prev_top);
+
+ // Do we have a previous child?
+ if (prev_condition)
+ {
+ push(prev_condition.get());
+ }
+ else
+ {
+ push(prev_top);
+ }
+ }
+}
+
+void Cursor::move_down()
+{
+ if (size() > 1)
+ {
+ Condition *prev_top = pop();
+
+ std::shared_ptr<Condition> next_condition =
+ current()->next_child(prev_top);
+
+ if (next_condition)
+ {
+ push(next_condition.get());
+ }
+ else
+ {
+ push(prev_top);
+ }
+ }
+}
+
+} // namespace
diff --git a/src/squelch/object_status.cc b/src/squelch/object_status.cc
new file mode 100644
index 00000000..075c0529
--- /dev/null
+++ b/src/squelch/object_status.cc
@@ -0,0 +1,153 @@
+#include "tome/squelch/object_status_fwd.hpp"
+#include "tome/squelch/object_status.hpp"
+
+#include "../inventory.hpp"
+#include "../object1.hpp"
+#include "../object2.hpp"
+#include "../object_type.hpp"
+#include "../variable.hpp"
+
+namespace squelch {
+
+EnumStringMap<status_type> &status_mapping()
+{
+ // TODO: This is quite ugly and leads to valgrind complaints
+ static auto m = new EnumStringMap<status_type> {
+ { status_type::BAD, "bad" },
+ { status_type::VERY_BAD, "very bad" },
+ { status_type::AVERAGE, "average" },
+ { status_type::GOOD, "good" },
+ { status_type::VERY_GOOD, "very good" },
+ { status_type::SPECIAL, "special" },
+ { status_type::TERRIBLE, "terrible" },
+ { status_type::NONE, "none" },
+ { status_type::CHEST_EMPTY, "(empty chest)" },
+ { status_type::CHEST_DISARMED, "(disarmed chest)" } };
+ return *m;
+}
+
+status_type object_status(object_type *o_ptr)
+{
+ if (!object_known_p(o_ptr))
+ {
+ switch (o_ptr->sense)
+ {
+ case SENSE_CURSED: return status_type::BAD;
+ case SENSE_WORTHLESS: return status_type::VERY_BAD;
+ case SENSE_AVERAGE: return status_type::AVERAGE;
+ case SENSE_GOOD_LIGHT: return status_type::GOOD;
+ case SENSE_GOOD_HEAVY: return status_type::GOOD;
+ case SENSE_EXCELLENT: return status_type::VERY_GOOD;
+ case SENSE_SPECIAL: return status_type::SPECIAL;
+ case SENSE_TERRIBLE: return status_type::TERRIBLE;
+ default: return status_type::NONE;
+ }
+ }
+ else
+ {
+ s16b slot = wield_slot_ideal(o_ptr, TRUE);
+
+ if (artifact_p(o_ptr))
+ {
+ if (!(o_ptr->ident & IDENT_CURSED))
+ {
+ return status_type::SPECIAL;
+ }
+ else
+ {
+ return status_type::TERRIBLE;
+ }
+ }
+ else if ((o_ptr->name2 > 0) ||
+ (o_ptr->name2b > 0))
+ {
+ if (!(o_ptr->ident & IDENT_CURSED))
+ {
+ return status_type::VERY_GOOD;
+ }
+ else
+ {
+ return status_type::VERY_BAD;
+ }
+ }
+ else if ((slot == INVEN_WIELD) ||
+ (slot == INVEN_BOW) ||
+ (slot == INVEN_AMMO) ||
+ (slot == INVEN_TOOL))
+ {
+ if (o_ptr->to_h + o_ptr->to_d < 0)
+ {
+ return status_type::BAD;
+ }
+ else if (o_ptr->to_h + o_ptr->to_d > 0)
+ {
+ return status_type::GOOD;
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+ else if ((slot >= INVEN_BODY) &&
+ (slot <= INVEN_FEET))
+ {
+ if (o_ptr->to_a < 0)
+ {
+ return status_type::BAD;
+ }
+ else if (o_ptr->to_a > 0)
+ {
+ return status_type::GOOD;
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+ else if (slot == INVEN_RING)
+ {
+ if ((o_ptr->to_d + o_ptr->to_h < 0) ||
+ (o_ptr->to_a < 0) ||
+ (o_ptr->pval < 0))
+ {
+ return status_type::BAD;
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+ else if (slot == INVEN_NECK)
+ {
+ if (o_ptr->pval < 0)
+ {
+ return status_type::BAD;
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+ else if (o_ptr->tval == TV_CHEST)
+ {
+ if (o_ptr->pval == 0)
+ {
+ return status_type::CHEST_EMPTY;
+ }
+ else if (o_ptr->pval < 0)
+ {
+ return status_type::CHEST_DISARMED;
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+ else
+ {
+ return status_type::AVERAGE;
+ }
+ }
+}
+
+} // namespace
diff --git a/src/squelch/rule.cc b/src/squelch/rule.cc
new file mode 100644
index 00000000..1c17d2fd
--- /dev/null
+++ b/src/squelch/rule.cc
@@ -0,0 +1,332 @@
+#include "tome/squelch/rule_fwd.hpp"
+#include "tome/squelch/rule.hpp"
+
+#include "tome/squelch/cursor.hpp"
+#include "tome/squelch/condition.hpp"
+#include "tome/squelch/tree_printer.hpp"
+#include "../angband.h"
+#include "../modules.hpp"
+#include "../object1.hpp"
+#include "../object2.hpp"
+#include "../object_type.hpp"
+#include "../quark.hpp"
+#include "../tables.hpp"
+#include "../util.hpp"
+#include "../variable.hpp"
+
+namespace squelch {
+
+EnumStringMap<action_type> &action_mapping()
+{
+ static auto m = new EnumStringMap<action_type> {
+ { action_type::AUTO_DESTROY, "destroy" },
+ { action_type::AUTO_PICKUP, "pickup" },
+ { action_type::AUTO_INSCRIBE, "inscribe" } };
+ return *m;
+}
+
+void Rule::set_name(const char *new_name)
+{
+ assert(new_name != nullptr);
+ m_name = new_name;
+}
+
+const char *Rule::get_name() const
+{
+ return m_name.c_str();
+}
+
+std::shared_ptr<Condition> Rule::get_condition() const
+{
+ return m_condition;
+}
+
+json_t *Rule::to_json() const
+{
+ json_t *rule_json = json_object();
+ json_object_set_new(rule_json,
+ "name",
+ json_string(m_name.c_str()));
+ json_object_set_new(rule_json,
+ "action",
+ json_string(action_mapping().stringify(m_action)));
+ json_object_set_new(rule_json,
+ "module",
+ json_string(modules[m_module_idx].meta.name));
+ json_object_set_new(rule_json,
+ "condition",
+ Condition::optional_to_json(m_condition));
+ return rule_json;
+}
+
+void Rule::add_new_condition(Cursor *cursor,
+ ConditionFactory const &factory)
+{
+ // Top-level condition?
+ if (!m_condition)
+ {
+ // Sanity check for navigation stack
+ assert(cursor->empty());
+
+ // Create new top-level condition
+ m_condition = factory();
+
+ // Select the condition
+ if (m_condition)
+ {
+ cursor->push(m_condition.get());
+ }
+ }
+ else
+ {
+ cursor->current()->add_child(factory);
+ }
+}
+
+void Rule::delete_selected_condition(Cursor *cursor)
+{
+ assert(cursor->size() >= 1);
+
+ if (cursor->size() == 1)
+ {
+ cursor->pop();
+ m_condition.reset();
+ }
+ else
+ {
+ Condition *prev_top = cursor->pop();
+ Condition *top = cursor->current();
+
+ // Jump up a level; this is a simple way to ensure a
+ // valid cursor. We could be a little cleverer here by
+ // trying to move inside the current level, but it
+ // gets a little complicated.
+ cursor->move_left();
+
+ // Now we can remove the condition from its parent
+ top->remove_child(prev_top);
+ }
+}
+
+void Rule::write_tree(TreePrinter *tree_printer, Cursor *cursor) const
+{
+ // Write out the main rule
+ do_write_tree(tree_printer);
+
+ // Write out the condition
+ if (m_condition)
+ {
+ m_condition->display(tree_printer, cursor);
+ }
+}
+
+bool Rule::apply_rule(object_type *o_ptr, int item_idx) const
+{
+ // Check module
+ if (m_module_idx != game_module_idx)
+ {
+ return false;
+ }
+
+ // Check condition
+ if (m_condition && m_condition->is_match(o_ptr))
+ {
+ return do_apply_rule(o_ptr, item_idx);
+ }
+
+ // Doesn't apply
+ return false;
+}
+
+std::shared_ptr<Rule> Rule::parse_rule(json_t *rule_json)
+{
+ if (!json_is_object(rule_json))
+ {
+ msg_print("Rule is not an object");
+ return nullptr;
+ }
+
+ // Retrieve the attributes
+ char *rule_name_s = nullptr;
+ char *rule_action_s = nullptr;
+ char *rule_module_s = nullptr;
+ if (json_unpack(rule_json,
+ "{s:s,s:s,s:s}",
+ "name", &rule_name_s,
+ "action", &rule_action_s,
+ "module", &rule_module_s) < 0)
+ {
+ msg_print("Rule missing required field(s)");
+ return nullptr;
+ }
+
+ // Convert attributes
+ action_type action;
+ if (!action_mapping().parse((cptr) rule_action_s, &action))
+ {
+ msg_format("Invalid rule action '%s'", rule_action_s);
+ return nullptr;
+ }
+
+ int module_idx = find_module((cptr) rule_module_s);
+ if (module_idx < 0)
+ {
+ msg_format("Skipping rule for unrecognized module '%s'",
+ (cptr) rule_module_s);
+ return nullptr;
+ }
+
+ // Parse condition
+ std::shared_ptr<Condition> condition =
+ Condition::parse_condition(json_object_get(rule_json, "condition"));
+
+ // Parse rule
+ switch (action)
+ {
+ case action_type::AUTO_INSCRIBE:
+ {
+ json_t *rule_inscription_j = json_object_get(rule_json, "inscription");
+
+ if (rule_inscription_j == nullptr)
+ {
+ msg_print("Inscription rule missing 'inscription' attribute");
+ return nullptr;
+ }
+ if (!json_is_string(rule_inscription_j))
+ {
+ msg_print("Inscription rule 'inscription' attribute wrong type");
+ return nullptr;
+ }
+
+ std::string inscription =
+ json_string_value(rule_inscription_j);
+ return std::make_shared<InscribeRule>(
+ rule_name_s, module_idx, condition, inscription);
+ }
+
+ case action_type::AUTO_PICKUP:
+ return std::make_shared<PickUpRule>(
+ rule_name_s, module_idx, condition);
+
+ case action_type::AUTO_DESTROY:
+ return std::make_shared<DestroyRule>(
+ rule_name_s, module_idx, condition);
+ }
+
+ assert(false);
+ return nullptr;
+}
+
+
+void DestroyRule::do_write_tree(TreePrinter *p) const
+{
+ p->write(TERM_GREEN, "A rule named \"");
+ p->write(TERM_WHITE, m_name.c_str());
+ p->write(TERM_GREEN, "\" to ");
+ p->write(TERM_L_GREEN, "destroy");
+ p->write(TERM_GREEN, " when");
+ p->write(TERM_WHITE, "\n");
+}
+
+bool DestroyRule::do_apply_rule(object_type *o_ptr, int item_idx) const
+{
+ // Must be identified
+ if (object_aware_p(o_ptr) == FALSE)
+ {
+ return false;
+ }
+
+ // Never destroy inscribed items
+ if (o_ptr->note)
+ {
+ return false;
+ }
+
+ // Ignore artifacts; cannot be destroyed anyway
+ if (artifact_p(o_ptr))
+ {
+ return false;
+ }
+
+ // Cannot destroy CURSE_NO_DROP objects.
+ {
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+
+ if ((f4 & TR4_CURSE_NO_DROP) != 0)
+ {
+ return false;
+ }
+ }
+
+ // Destroy
+ msg_print("<Auto-destroy>");
+ inc_stack_size(item_idx, -o_ptr->number);
+ return true;
+}
+
+void PickUpRule::do_write_tree(TreePrinter *p) const
+{
+ p->write(TERM_GREEN, "A rule named \"");
+ p->write(TERM_WHITE, m_name.c_str());
+ p->write(TERM_GREEN, "\" to ");
+ p->write(TERM_L_GREEN, "pick up");
+ p->write(TERM_GREEN, " when");
+ p->write(TERM_WHITE, "\n");
+}
+
+bool PickUpRule::do_apply_rule(object_type *o_ptr, int item_idx) const
+{
+ if (item_idx >= 0)
+ {
+ return false;
+ }
+
+ if (!inven_carry_okay(o_ptr))
+ {
+ return false;
+ }
+
+ msg_print("<Auto-pickup>");
+ object_pickup(-item_idx);
+ return true;
+}
+
+json_t *InscribeRule::to_json() const
+{
+ json_t *j = Rule::to_json();
+
+ json_object_set_new(j,
+ "inscription",
+ json_string(m_inscription.c_str()));
+
+ return j;
+}
+
+void InscribeRule::do_write_tree(TreePrinter *p) const
+{
+ p->write(TERM_GREEN, "A rule named \"");
+ p->write(TERM_WHITE, m_name.c_str());
+ p->write(TERM_GREEN, "\" to ");
+ p->write(TERM_L_GREEN, "inscribe");
+ p->write(TERM_GREEN, " an item with \"");
+ p->write(TERM_WHITE, m_inscription.c_str());
+ p->write(TERM_GREEN, "\" when");
+ p->write(TERM_WHITE, "\n");
+}
+
+bool InscribeRule::do_apply_rule(object_type *o_ptr, int) const
+{
+ // Already inscribed?
+ if (o_ptr->note != 0)
+ {
+ return false;
+ }
+
+ // Inscribe
+ msg_format("<Auto-Inscribe {%s}>", m_inscription.c_str());
+ o_ptr->note = quark_add(m_inscription.c_str());
+ return true;
+}
+
+} // namespace
diff --git a/src/squelch/tree_printer.cc b/src/squelch/tree_printer.cc
new file mode 100644
index 00000000..2be098dc
--- /dev/null
+++ b/src/squelch/tree_printer.cc
@@ -0,0 +1,89 @@
+#include "tome/squelch/tree_printer_fwd.hpp"
+#include "tome/squelch/tree_printer.hpp"
+
+#include "../z-term.h"
+
+namespace squelch {
+
+TreePrinter::TreePrinter() : m_indent(0)
+{
+ int wid, hgt;
+ // Output window
+ Term_get_size(&wid, &hgt);
+ m_write_out_y = 1;
+ m_write_out_x = 16;
+ m_write_out_h = hgt - 4 - 1;
+ m_write_out_w = wid - 1 - 15 - 1;
+ // Set position
+ reset();
+ reset_scroll();
+}
+
+void TreePrinter::indent() {
+ m_indent++;
+}
+
+void TreePrinter::dedent() {
+ m_indent--;
+}
+
+void TreePrinter::reset() {
+ m_write_x = 0;
+ m_write_y = 0;
+}
+
+void TreePrinter::reset_scroll() {
+ m_write_off_y = 0;
+ m_write_off_x = 0;
+}
+
+void TreePrinter::scroll_up() {
+ m_write_off_y--;
+}
+
+void TreePrinter::scroll_down() {
+ m_write_off_y++;
+}
+
+void TreePrinter::scroll_left() {
+ m_write_off_x++;
+}
+
+void TreePrinter::scroll_right() {
+ m_write_off_x--;
+}
+
+void TreePrinter::write(uint8_t color, cptr line)
+{
+ cptr p = line;
+
+ for (p = line; *p != '\0'; p++)
+ {
+ char c = *p;
+ int x = m_write_x - m_write_off_x + 3*m_indent;
+ int y = m_write_y - m_write_off_y;
+
+ if (c != '\n')
+ {
+ if ((y >= 0) &&
+ (y < m_write_out_h) &&
+ (x >= 0) &&
+ (x < m_write_out_w))
+ {
+ Term_putch(x + m_write_out_x,
+ y + m_write_out_y,
+ color,
+ c);
+ }
+
+ m_write_x += 1;
+ }
+ else
+ {
+ m_write_x = 0;
+ m_write_y += 1;
+ }
+ }
+}
+
+} // namespace
diff --git a/src/squeltch.c b/src/squeltch.c
deleted file mode 100644
index 5bf67cd5..00000000
--- a/src/squeltch.c
+++ /dev/null
@@ -1,3582 +0,0 @@
-/* File: squeltch.c */
-
-/* Purpose: Automatizer */
-
-/*
- * Copyright (c) 2002 DarkGod
- *
- * 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.
- */
-
-#include "angband.h"
-
-#include <jansson.h>
-
-#include "quark.h"
-
-#define RULES_MAX 4096
-#define STACK_MAX 1024
-
-typedef enum { BAD, VERY_BAD, AVERAGE,
- GOOD, VERY_GOOD, SPECIAL,
- TERRIBLE, NONE, CHEST_EMPTY,
- CHEST_DISARMED } status_type;
-
-struct status_map_type {
- status_type status;
- cptr status_s;
-};
-
-status_type object_status(object_type *o_ptr)
-{
- if (!object_known_p(o_ptr))
- {
- switch (o_ptr->sense)
- {
- case SENSE_CURSED: return BAD;
- case SENSE_WORTHLESS: return VERY_BAD;
- case SENSE_AVERAGE: return AVERAGE;
- case SENSE_GOOD_LIGHT: return GOOD;
- case SENSE_GOOD_HEAVY: return GOOD;
- case SENSE_EXCELLENT: return VERY_GOOD;
- case SENSE_SPECIAL: return SPECIAL;
- case SENSE_TERRIBLE: return TERRIBLE;
- default: return NONE;
- }
- }
- else
- {
- s16b slot = wield_slot_ideal(o_ptr, TRUE);
-
- if (artifact_p(o_ptr))
- {
- if (!(o_ptr->ident & IDENT_CURSED))
- {
- return SPECIAL;
- }
- else
- {
- return TERRIBLE;
- }
- }
- else if ((o_ptr->name2 > 0) ||
- (o_ptr->name2b > 0))
- {
- if (!(o_ptr->ident & IDENT_CURSED))
- {
- return VERY_GOOD;
- }
- else
- {
- return VERY_BAD;
- }
- }
- else if ((slot == INVEN_WIELD) ||
- (slot == INVEN_BOW) ||
- (slot == INVEN_AMMO) ||
- (slot == INVEN_TOOL))
- {
- if (o_ptr->to_h + o_ptr->to_d < 0)
- {
- return BAD;
- }
- else if (o_ptr->to_h + o_ptr->to_d > 0)
- {
- return GOOD;
- }
- else
- {
- return AVERAGE;
- }
- }
- else if ((slot >= INVEN_BODY) &&
- (slot <= INVEN_FEET))
- {
- if (o_ptr->to_a < 0)
- {
- return BAD;
- }
- else if (o_ptr->to_a > 0)
- {
- return GOOD;
- }
- else
- {
- return AVERAGE;
- }
- }
- else if (slot == INVEN_RING)
- {
- if ((o_ptr->to_d + o_ptr->to_h < 0) ||
- (o_ptr->to_a < 0) ||
- (o_ptr->pval < 0))
- {
- return BAD;
- }
- else
- {
- return AVERAGE;
- }
- }
- else if (slot == INVEN_NECK)
- {
- if (o_ptr->pval < 0)
- {
- return BAD;
- }
- else
- {
- return AVERAGE;
- }
- }
- else if (o_ptr->tval == TV_CHEST)
- {
- if (o_ptr->pval == 0)
- {
- return CHEST_EMPTY;
- }
- else if (o_ptr->pval < 0)
- {
- return CHEST_DISARMED;
- }
- else
- {
- return AVERAGE;
- }
- }
- else
- {
- return AVERAGE;
- }
- }
-}
-
-#define STATUS_MAP_SIZE 10
-struct status_map_type status_map[STATUS_MAP_SIZE] = {
- { BAD, "bad" },
- { VERY_BAD, "very bad" },
- { AVERAGE, "average" },
- { GOOD, "good" },
- { VERY_GOOD, "very good" },
- { SPECIAL, "special" },
- { TERRIBLE, "terrible" },
- { NONE, "none" },
- { CHEST_EMPTY, "(empty chest)" },
- { CHEST_DISARMED, "(disarmed chest)" },
-};
-
-static cptr status_to_string(status_type status)
-{
- int i;
-
- for (i = 0; i < STATUS_MAP_SIZE; i++)
- {
- if (status_map[i].status == status)
- {
- return status_map[i].status_s;
- }
- }
-
- assert(FALSE);
- return NULL;
-}
-
-static bool_ status_from_string(cptr s, status_type *status)
-{
- int i;
-
- for (i = 0; i < STATUS_MAP_SIZE; i++)
- {
- if (streq(status_map[i].status_s, s))
- {
- *status = status_map[i].status;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Type of automatizer actions */
-typedef enum { AUTO_DESTROY,
- AUTO_PICKUP,
- AUTO_INSCRIBE } action_type;
-
-/* Convert action to/from string */
-struct action_map_type {
- action_type action;
- cptr action_s;
-};
-
-#define ACTION_MAP_SIZE 3
-struct action_map_type action_map[ACTION_MAP_SIZE] = {
- { AUTO_DESTROY, "destroy" },
- { AUTO_PICKUP, "pickup" },
- { AUTO_INSCRIBE, "inscribe" }
-};
-
-static cptr action_to_string(action_type action)
-{
- int i = 0;
-
- for (i = 0; i < ACTION_MAP_SIZE; i++)
- {
- if (action == action_map[i].action)
- {
- return action_map[i].action_s;
- }
- }
-
- assert(FALSE);
- return NULL;
-}
-
-static bool_ action_from_string(cptr s, action_type *action)
-{
- int i = 0;
-
- for (i = 0; i < ACTION_MAP_SIZE; i++)
- {
- if (streq(action_map[i].action_s, s))
- {
- *action = action_map[i].action;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Identification state */
-typedef enum { IDENTIFIED, NOT_IDENTIFIED } identification_state;
-
-#define S_IDENTIFIED "identified"
-#define S_NOT_IDENTIFIED "not identified"
-
-cptr identification_state_to_string(identification_state i)
-{
- switch (i)
- {
- case IDENTIFIED: return S_IDENTIFIED;
- case NOT_IDENTIFIED: return S_NOT_IDENTIFIED;
- }
-
- assert(FALSE);
- return NULL;
-}
-
-bool_ identification_state_from_string(cptr s, identification_state *state)
-{
- if (streq(s, S_IDENTIFIED))
- {
- *state = IDENTIFIED;
- return TRUE;
- }
- else if (streq(s, S_NOT_IDENTIFIED))
- {
- *state = NOT_IDENTIFIED;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/* Match type */
-typedef enum { M_AND , M_OR , M_NOT , M_NAME , M_CONTAIN ,
- M_INSCRIBED, M_DISCOUNT, M_SYMBOL , M_STATE , M_STATUS ,
- M_TVAL , M_SVAL , M_RACE , M_SUBRACE , M_CLASS ,
- M_LEVEL , M_SKILL , M_ABILITY, M_INVENTORY, M_EQUIPMENT }
- match_type;
-
-struct match_type_map {
- match_type i;
- cptr s;
-};
-
-#define MATCH_TYPE_MAP_SIZE 20
-struct match_type_map match_type_map[MATCH_TYPE_MAP_SIZE] = {
- { M_AND, "and" },
- { M_OR, "or" },
- { M_NOT, "not" },
- { M_NAME, "name" },
- { M_CONTAIN, "contain" },
- { M_INSCRIBED, "inscribed" },
- { M_DISCOUNT, "discount" },
- { M_SYMBOL, "symbol" },
- { M_STATE, "state" },
- { M_STATUS, "status" },
- { M_TVAL, "tval" },
- { M_SVAL, "sval" },
- { M_RACE, "race" },
- { M_SUBRACE, "subrace" },
- { M_CLASS, "class" },
- { M_LEVEL, "level" },
- { M_SKILL, "skill" },
- { M_ABILITY, "ability" },
- { M_INVENTORY, "inventory" },
- { M_EQUIPMENT, "equipment" },
-};
-
-cptr match_type_to_string(match_type m)
-{
- int i;
-
- for (i = 0; i < MATCH_TYPE_MAP_SIZE; i++)
- {
- if (match_type_map[i].i == m)
- {
- return match_type_map[i].s;
- }
- }
-
- assert(FALSE);
- return NULL;
-}
-
-bool_ match_type_from_string(cptr s, match_type *match)
-{
- int i;
-
- for (i = 0; i < MATCH_TYPE_MAP_SIZE; i++)
- {
- if (streq(match_type_map[i].s, s))
- {
- *match = match_type_map[i].i;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/* Forward declarations */
-typedef struct condition_type condition_type;
-struct condition_type;
-
-/* List of conditions */
-typedef struct condition_list condition_list;
-struct condition_list {
- condition_type *condition;
- condition_list *next;
-};
-
-int compare_condition_list(condition_list *a, condition_list *b)
-{
- assert(FALSE);
-}
-
-SGLIB_DEFINE_LIST_PROTOTYPES(condition_list, compare_condition_list, next);
-SGLIB_DEFINE_LIST_FUNCTIONS(condition_list, compare_condition_list, next);
-
-/* Condition instance */
-struct condition_type
-{
- /* What do we want to match? */
- match_type match;
- /* Sub-conditions for logical connectives; if applicable */
- struct {
- condition_list *c;
- } conditions;
- /* Sub-condition for cases where there is only a single subcondition */
- condition_type *subcondition;
- /* Tval to match if applicable. */
- byte tval;
- /* Sval range if applicable. */
- struct {
- byte min;
- byte max;
- } sval_range;
- /* Discount range. */
- struct {
- int min;
- int max;
- } discount;
- /* Level range */
- struct {
- int min;
- int max;
- } level_range;
- /* Skill range */
- struct {
- s16b min;
- s16b max;
- s16b skill_idx;
- } skill_range;
- /* Identification state to match if applicable */
- identification_state identification_state;
- /* Status to match if applicable */
- status_type status;
- /* Name to match */
- char *name;
- /* Symbol to match if applicable */
- char symbol;
- /* Inscription to find */
- char *inscription;
- /* Subrace to match if applicable */
- char *subrace;
- /* Race to match if applicable */
- char *race;
- /* Class to match if applicable */
- char *klass;
- /* Ability to match if applicable */
- s16b ability;
- /* Comment */
- char *comment;
-};
-
-static condition_type *condition_new(match_type match)
-{
- condition_type *cp = malloc(sizeof(condition_type));
- memset(cp, 0, sizeof(condition_type));
- cp->match = match;
- return cp;
-}
-
-static condition_type *condition_new_tval(byte tval)
-{
- condition_type *cp = condition_new(M_TVAL);
- cp->tval = tval;
- return cp;
-}
-
-static condition_type *condition_new_sval(byte min, byte max)
-{
- condition_type *cp = condition_new(M_SVAL);
- cp->sval_range.min = min;
- cp->sval_range.max = max;
- return cp;
-}
-
-static condition_type *condition_new_and()
-{
- condition_type *cp = condition_new(M_AND);
- return cp;
-}
-
-static condition_type *condition_new_or()
-{
- condition_type *cp = condition_new(M_OR);
- return cp;
-}
-
-static condition_type *condition_new_not()
-{
- condition_type *cp = condition_new(M_NOT);
- return cp;
-}
-
-static condition_type *condition_new_name(cptr name)
-{
- condition_type *cp = condition_new(M_NAME);
- cp->name = strdup(name);
- return cp;
-}
-
-static condition_type *condition_new_contain(cptr name)
-{
- condition_type *cp = condition_new(M_CONTAIN);
- cp->name = strdup(name);
- return cp;
-}
-
-static condition_type *condition_new_inscribed(cptr name)
-{
- condition_type *cp = condition_new(M_INSCRIBED);
- cp->inscription = strdup(name);
- return cp;
-}
-
-static condition_type *condition_new_status(status_type status)
-{
- condition_type *cp = condition_new(M_STATUS);
- cp->status = status;
- return cp;
-}
-
-static condition_type *condition_new_state(identification_state state)
-{
- condition_type *cp = condition_new(M_STATE);
- cp->identification_state = state;
- return cp;
-}
-
-static condition_type *condition_new_discount(int min, int max)
-{
- condition_type *cp = condition_new(M_DISCOUNT);
- cp->discount.min = min;
- cp->discount.max = max;
- return cp;
-}
-
-static condition_type *condition_new_symbol(char c)
-{
- condition_type *cp = condition_new(M_SYMBOL);
- cp->symbol = c;
- return cp;
-}
-
-static condition_type *condition_new_race(cptr race)
-{
- condition_type *cp = condition_new(M_RACE);
- cp->race = strdup(race);
- return cp;
-}
-
-static condition_type *condition_new_subrace(cptr subrace)
-{
- condition_type *cp = condition_new(M_SUBRACE);
- cp->subrace = strdup(subrace);
- return cp;
-}
-
-static condition_type *condition_new_class(cptr klass)
-{
- condition_type *cp = condition_new(M_CLASS);
- cp->klass = strdup(klass);
- return cp;
-}
-
-static condition_type *condition_new_level(int min, int max)
-{
- condition_type *cp = condition_new(M_LEVEL);
- cp->level_range.min = min;
- cp->level_range.max = max;
- return cp;
-}
-
-static condition_type *condition_new_skill(s16b min, s16b max, s16b skill_idx)
-{
- condition_type *cp = condition_new(M_SKILL);
- cp->skill_range.min = min;
- cp->skill_range.max = max;
- cp->skill_range.skill_idx = skill_idx;
- return cp;
-}
-
-static condition_type *condition_new_ability(s16b ability_idx)
-{
- condition_type *cp = condition_new(M_ABILITY);
- cp->ability = ability_idx;
- return cp;
-}
-
-static condition_type *condition_new_inventory()
-{
- condition_type *cp = condition_new(M_INVENTORY);
- return cp;
-}
-
-static condition_type *condition_new_equipment()
-{
- condition_type *cp = condition_new(M_EQUIPMENT);
- return cp;
-}
-
-static void condition_and_add(condition_type *and_c, condition_type *c)
-{
- if (and_c == NULL || c == NULL)
- {
- return;
- }
-
- assert(and_c != NULL);
- assert(c != NULL);
- assert((and_c->match == M_AND) || (and_c->match == M_OR));
-
- condition_list *cl = malloc(sizeof(condition_list));
- cl->condition = c;
- cl->next = NULL;
-
- sglib_condition_list_add(&and_c->conditions.c, cl);
-}
-
-static void condition_or_add(condition_type *or_c, condition_type *c)
-{
- condition_and_add(or_c, c);
-}
-
-static void condition_destroy(condition_type **cp)
-{
- condition_type *c = NULL;
- assert(cp != NULL);
- assert(*cp != NULL);
-
- c = *cp;
-
- /* Free sub-conditions if any */
- {
- condition_list *current = NULL;
- condition_list *next = NULL;
-
- for (current = c->conditions.c;
- current != NULL;
- current = next)
- {
- condition_destroy(&current->condition);
- next = current->next;
- free(current);
- }
- }
-
- /* Free sub-condition if any */
- if (c->subcondition)
- {
- condition_destroy(&c->subcondition);
- }
-
- /* Free name if any */
- if (c->name)
- {
- free(c->name);
- c->name = NULL;
- }
-
- /* Free inscription if any */
- if (c->inscription)
- {
- free(c->inscription);
- c->inscription = NULL;
- }
-
- /* Free subrace if any */
- if (c->subrace)
- {
- free(c->subrace);
- c->subrace = NULL;
- }
-
- /* Free race if any */
- if (c->race)
- {
- free(c->race);
- c->race = NULL;
- }
-
- /* Free class if any */
- if (c->klass)
- {
- free(c->klass);
- c->klass = NULL;
- }
-
- /* Free comment if any */
- if (c->comment)
- {
- free(c->comment);
- c->comment = NULL;
- }
-
- /* Free the condition itself */
- free(*cp);
- *cp = NULL;
-}
-
-static bool_ condition_eval(condition_type *c, object_type *o_ptr)
-{
- bool_ is_and = (c->match == M_AND);
- bool_ is_or = (c->match == M_OR);
-
- switch (c->match)
- {
- case M_AND:
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- struct condition_list *child = NULL;
-
- for (child = sglib_condition_list_it_init(&it, c->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- if (is_and && (!condition_eval(child->condition, o_ptr)))
- {
- return FALSE;
- }
-
- if (is_or && condition_eval(child->condition, o_ptr))
- {
- return TRUE;
- }
- }
-
- if (is_and)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
-
- case M_NOT:
- {
- if (c->subcondition == NULL)
- {
- return TRUE;
- }
-
- return !condition_eval(c->subcondition, o_ptr);
- }
-
- case M_INVENTORY:
- {
- int i;
-
- if (c->subcondition == NULL)
- {
- return FALSE;
- }
-
- for (i = 0; i < INVEN_WIELD; i++)
- {
- if (condition_eval(c->subcondition, &p_ptr->inventory[i]))
- {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- case M_EQUIPMENT:
- {
- int i;
-
- if (c->subcondition == NULL)
- {
- return FALSE;
- }
-
- for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
- {
- if (condition_eval(c->subcondition, &p_ptr->inventory[i]))
- {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- case M_NAME:
- {
- char buf1[128];
- char buf2[128];
-
- object_desc(buf1, o_ptr, -1, 0);
- strlower(buf1);
-
- sprintf(buf2, "%s", c->name);
- strlower(buf2);
-
- return streq(buf1, buf2);
- }
-
- case M_CONTAIN:
- {
- char buf1[128];
- char buf2[128];
-
- object_desc(buf1, o_ptr, -1, 0);
- strlower(buf1);
-
- sprintf(buf2, "%s", c->name);
- strlower(buf2);
-
- return (strstr(buf1, buf2) != NULL);
- }
-
- case M_SYMBOL:
- {
- object_kind *k_ptr = &k_info[o_ptr->k_idx];
-
- return k_ptr->d_char == c->symbol;
- }
-
- case M_INSCRIBED:
- {
- char buf1[128];
- char buf2[128];
-
- if (o_ptr->note == 0)
- {
- return FALSE;
- }
-
- sprintf(buf1, "%s", quark_str(o_ptr->note));
- strlower(buf1);
-
- sprintf(buf2, "%s", c->inscription);
- strlower(buf2);
-
- return (strstr(buf1, buf2) != NULL);
- }
-
- case M_DISCOUNT:
- {
- return (object_aware_p(o_ptr) &&
- (o_ptr->discount >= c->discount.min) &&
- (o_ptr->discount <= c->discount.max));
- }
-
- case M_TVAL:
- {
- return (o_ptr->tval == c->tval);
- }
-
- case M_SVAL:
- {
- return (object_aware_p(o_ptr) &&
- (o_ptr->sval >= c->sval_range.min) &&
- (o_ptr->sval <= c->sval_range.max));
- }
-
- case M_STATUS:
- {
- return c->status == object_status(o_ptr);
- }
-
- case M_STATE:
- {
- switch (c->identification_state)
- {
- case IDENTIFIED:
- return object_known_p(o_ptr);
- case NOT_IDENTIFIED:
- return !object_known_p(o_ptr);
- default:
- assert(FALSE);
- }
- }
-
- case M_RACE:
- {
- char buf1[128];
- char buf2[128];
-
- sprintf(buf1, "%s", rp_ptr->title + rp_name);
- strlower(buf1);
-
- sprintf(buf2, "%s", c->race);
- strlower(buf2);
-
- return streq(buf1, buf2);
- }
-
- case M_SUBRACE:
- {
- char buf1[128];
- char buf2[128];
-
- sprintf(buf1, "%s", rmp_ptr->title + rmp_name);
- strlower(buf1);
-
- sprintf(buf2, "%s", c->subrace);
- strlower(buf2);
-
- return streq(buf1, buf2);
- }
-
- case M_CLASS:
- {
- char buf1[128];
- char buf2[128];
-
- sprintf(buf1, "%s", spp_ptr->title + c_name);
- strlower(buf1);
-
- sprintf(buf2, "%s", c->klass);
- strlower(buf2);
-
- return streq(buf1, buf2);
- }
-
- case M_LEVEL:
- {
- return ((p_ptr->lev >= c->level_range.min) &&
- (p_ptr->lev <= c->level_range.max));
- }
-
- case M_SKILL:
- {
- s16b sk = get_skill(c->skill_range.skill_idx);
- return ((sk >= c->skill_range.min) &&
- (sk <= c->skill_range.max));
- }
-
- case M_ABILITY:
- {
- return has_ability(c->ability);
- }
-
- }
-
- /* Don't match by default */
- return FALSE;
-}
-
-static json_t *condition_to_json(condition_type *c)
-{
- json_t *json = NULL;
-
- if (c == NULL)
- {
- return json_null();
- }
-
- json = json_object();
- json_object_set_new(json, "type",
- json_string(match_type_to_string(c->match)));
-
- switch (c->match)
- {
- case M_AND:
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- struct condition_list *child = NULL;
-
- json_t *conditions_json = json_array();
-
- for (child = sglib_condition_list_it_init(&it, c->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- json_array_append_new(conditions_json,
- condition_to_json(child->condition));
- }
-
- json_object_set_new(json, "conditions", conditions_json);
- break;
- }
-
- case M_NOT:
- case M_INVENTORY:
- case M_EQUIPMENT:
- {
- json_object_set_new(json, "condition",
- condition_to_json(c->subcondition));
- break;
- }
-
- case M_NAME:
- {
- json_object_set_new(json, "name",
- json_string(c->name));
- break;
- }
-
- case M_CONTAIN:
- {
- json_object_set_new(json, "contain",
- json_string(c->name));
- break;
- }
-
- case M_SYMBOL:
- {
- json_object_set_new(json, "symbol",
- json_string(format("%c", c->symbol)));
- break;
- }
-
- case M_INSCRIBED:
- {
- json_object_set_new(json, "inscription",
- json_string(c->inscription));
- break;
- }
-
- case M_DISCOUNT:
- {
- json_object_set_new(json, "min",
- json_integer(c->discount.min));
- json_object_set_new(json, "max",
- json_integer(c->discount.max));
- break;
- }
-
- case M_TVAL:
- {
- json_object_set_new(json, "tval",
- json_integer(c->tval));
- break;
- }
-
- case M_SVAL:
- {
- json_object_set_new(json, "min",
- json_integer(c->sval_range.min));
- json_object_set_new(json, "max",
- json_integer(c->sval_range.max));
- break;
- }
-
- case M_STATUS:
- {
- json_object_set_new(json, "status",
- json_string(status_to_string(c->status)));
- break;
- }
-
- case M_STATE:
- {
- json_object_set_new(json, "state",
- json_string(identification_state_to_string(c->identification_state)));
- break;
- }
-
- case M_RACE:
- {
- json_object_set_new(json, "race",
- json_string(c->race));
- break;
- }
-
- case M_SUBRACE:
- {
- json_object_set_new(json, "subrace",
- json_string(c->subrace));
- break;
- }
-
- case M_CLASS:
- {
- json_object_set_new(json, "class",
- json_string(c->klass));
- break;
- }
-
- case M_LEVEL:
- {
- json_object_set_new(json, "min",
- json_integer(c->level_range.min));
- json_object_set_new(json, "max",
- json_integer(c->level_range.max));
- break;
- }
-
- case M_SKILL:
- {
- json_object_set_new(json, "name",
- json_string(s_info[c->skill_range.skill_idx].name + s_name));
- json_object_set_new(json, "min",
- json_integer(c->skill_range.min));
- json_object_set_new(json, "max",
- json_integer(c->skill_range.max));
- break;
- }
-
- case M_ABILITY:
- {
- json_object_set_new(json, "ability",
- json_string(ab_info[c->ability].name + ab_name));
- break;
- }
-
- }
-
- return json;
-}
-
-/*
- * Cursor to maintain position in condition tree
- */
-static condition_type *cursor_stack[STACK_MAX];
-static int cursor_count = 0;
-
-static void cursor_push(condition_type *condition)
-{
- assert(cursor_count < STACK_MAX);
-
- cursor_stack[cursor_count] = condition;
- cursor_count++;
-}
-
-static condition_type *cursor_pop()
-{
- condition_type *c = NULL;
-
- assert(cursor_count > 0);
-
- c = cursor_stack[cursor_count-1];
- cursor_stack[cursor_count] = NULL;
- cursor_count--;
- return c;
-}
-
-static condition_type *cursor_top()
-{
- assert(cursor_count > 0);
-
- return cursor_stack[cursor_count - 1];
-}
-
-static void cursor_clear()
-{
- while (cursor_count > 0)
- {
- cursor_pop();
- }
-}
-
-/* Rule */
-typedef struct arule_type arule_type;
-struct arule_type {
- /* Rule name */
- char *name;
- /* Which action do we take? */
- action_type action; /* Which action to take */
- /* Which module does this rule apply to? */
- int module_idx;
- /* Inscription to use for inscription rules. */
- char *inscription;
- /* Condition. */
- condition_type *condition; /* Condition for rule match */
-};
-
-/* Initialize a rule */
-static arule_type *rule_new(cptr name, action_type action, int module_idx, condition_type *condition, cptr inscription)
-{
- arule_type *rp = malloc(sizeof(arule_type));
- rp->name = strdup(name);
- rp->action = action;
- rp->module_idx = module_idx;
- rp->condition = condition;
- rp->inscription = (inscription == NULL) ? NULL : strdup(inscription);
- return rp;
-}
-
-static void rule_set_name(arule_type *rule, cptr new_name)
-{
- if (rule->name)
- {
- free(rule->name);
- }
-
- rule->name = strdup(new_name);
-}
-
-static void rule_destroy(arule_type **rp)
-{
- if ((*rp)->name)
- {
- free((*rp)->name);
- }
-
- if ((*rp)->inscription)
- {
- free((*rp)->inscription);
- }
-
- if ((*rp)->condition)
- {
- condition_destroy(&(*rp)->condition);
- }
-
- free(*rp);
- *rp = NULL;
-}
-
-/* Current list of rules. */
-static arule_type *rules[RULES_MAX];
-static int rules_count = 0; /* Number of rules currently in list */
-
-static int rules_append(arule_type *rule)
-{
- assert(rules_count < RULES_MAX);
-
- rules[rules_count] = rule;
- rules_count++;
- return rules_count-1;
-}
-
-static void rules_remove(arule_type *rule)
-{
- int i, j;
-
- for (i = 0; i < rules_count; i++)
- {
- if (rules[i] == rule)
- {
- /* Free the rule */
- rule_destroy(&rule);
- /* Move rest of rest "up" */
- for (j = i+1; j < rules_count; j++)
- {
- rules[j-1] = rules[j];
- }
- /* We're done */
- rules_count--;
- return;
- }
- }
-}
-
-static void rules_swap(int i, int j)
-{
- arule_type *tmp_rptr = NULL;
-
- assert(i >= 0);
- assert(i < rules_count);
-
- assert(j >= 0);
- assert(j < rules_count);
-
- tmp_rptr = rules[i];
- rules[i] = rules[j];
- rules[j] = tmp_rptr;
-}
-
-static bool_* automatizer_auto_destroy(object_type *o_ptr, int item_idx)
-{
- static bool_ TRUE_VAL = TRUE;
-
- /* Must be identified */
- if (object_aware_p(o_ptr) == FALSE)
- {
- return NULL;
- }
-
- /* Inscribed things won't be destroyed! */
- if (o_ptr->note)
- {
- return NULL;
- }
-
- /* Ignore artifacts; cannot be destroyed anyway. */
- if (artifact_p(o_ptr))
- {
- return NULL;
- }
-
- /* Cannot destroy CURSE_NO_DROP objects. */
- {
- u32b f1, f2, f3, f4, f5, esp;
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- if ((f4 & TR4_CURSE_NO_DROP) != 0)
- {
- return NULL;
- }
- }
-
- /* Destroy! */
- msg_print("<Auto-destroy>");
-
- inc_stack_size(item_idx, -o_ptr->number);
- return &TRUE_VAL;
-}
-
-static bool_* automatizer_auto_pickup(object_type *o_ptr, int item_idx)
-{
- static bool_ TRUE_VAL = TRUE;
-
- if (item_idx >= 0)
- {
- return NULL;
- }
-
- if (!inven_carry_okay(o_ptr))
- {
- return NULL;
- }
-
- msg_print("<Auto-pickup>");
-
- object_pickup(-item_idx);
- return &TRUE_VAL;
-}
-
-/* Apply rules */
-static bool_ apply_rule(arule_type *rule, object_type *o_ptr, int item_idx)
-{
- /* Check module */
- if (rule->module_idx != game_module_idx)
- {
- return FALSE;
- }
-
- /* Check condition */
- assert (rule->condition != NULL);
- if (condition_eval(rule->condition, o_ptr))
- {
- switch (rule->action)
- {
-
- case AUTO_DESTROY:
- {
- if (automatizer_auto_destroy(o_ptr, item_idx) == NULL)
- return FALSE;
- break;
- }
-
- case AUTO_PICKUP:
- {
- if (automatizer_auto_pickup(o_ptr, item_idx) == NULL)
- return FALSE;
- break;
- }
-
- case AUTO_INSCRIBE:
- {
- /* Already inscribed? */
- if (o_ptr->note != 0)
- {
- return FALSE;
- }
-
- /* Inscribe */
- msg_format("<Auto-Inscribe {%s}>", rule->inscription);
- o_ptr->note = quark_add(rule->inscription);
- break;
- }
-
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static bool_ apply_rules(object_type *o_ptr, int item_idx)
-{
- int i;
-
- for (i = 0; i < rules_count; i++)
- {
- if (apply_rule(rules[i], o_ptr, item_idx))
- {
- return TRUE;
- }
- }
-
- /* Don't keep trying */
- return FALSE;
-}
-
-static json_t *rule_to_json(arule_type *rule)
-{
- json_t *rule_json = json_object();
-
- json_object_set_new(rule_json,
- "name",
- json_string(rule->name));
- json_object_set_new(rule_json,
- "action",
- json_string(action_to_string(rule->action)));
- json_object_set_new(rule_json,
- "module",
- json_string(modules[rule->module_idx].meta.name));
-
- if (rule->inscription)
- {
- json_object_set_new(rule_json,
- "inscription",
- json_string(rule->inscription));
- }
-
- json_object_set_new(rule_json,
- "condition",
- condition_to_json(rule->condition));
-
- return rule_json;
-}
-
-static json_t *rules_to_json()
-{
- int i;
- json_t *rules_json = json_array();
-
- for (i = 0; i < rules_count; i++)
- {
- json_array_append_new(rules_json, rule_to_json(rules[i]));
- }
-
- return rules_json;
-}
-
-/* Check the floor for "crap" */
-void squeltch_grid(void)
-{
- s16b this_o_idx, next_o_idx = 0;
-
- if (!automatizer_enabled) return;
-
- /* Scan the pile of objects */
- for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx)
- {
- /* Acquire object */
- object_type * o_ptr = &o_list[this_o_idx];
-
- /* We've now seen one of these */
- if (!k_info[o_ptr->k_idx].flavor)
- {
- object_aware(o_ptr);
- }
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Apply rules */
- apply_rules(o_ptr, -this_o_idx);
- }
-}
-
-
-/* Check the inventory for "crap" */
-void squeltch_inventory(void)
-{
- int i;
- int num_iter = 0;
- bool_ found = TRUE;
-
- if (!automatizer_enabled) return;
-
- while (found && num_iter ++ < 100)
- {
- /* Sometimes an index in the inventory is skipped */
- found = FALSE;
-
- for (i = 0; i < INVEN_PACK; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- if (apply_rules(o_ptr, i))
- {
- found = TRUE;
- break;
- }
- }
- }
- if (num_iter >= 100)
- {
- cmsg_format(TERM_VIOLET, "'apply_rules' ran too often.");
- }
-}
-
-/********************** The interface **********************/
-static void get_rule_names(cptr *list)
-{
- int i;
-
- for (i = 0; i < rules_count; i++)
- {
- list[i] = rules[i]->name;
- }
-}
-
-typedef struct condition_metadata condition_metadata;
-struct condition_metadata {
- match_type match;
- cptr description[3];
- condition_type *(*create_condition)();
-};
-
-#define TYPES_LIST_SIZE 21
-
-static condition_type *create_condition_name()
-{
- cptr s = lua_input_box("Object name to match?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_name(s);
-}
-
-static condition_type *create_condition_contain()
-{
- cptr s = lua_input_box("Word to find in object name?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_contain(s);
-}
-
-static condition_type *create_condition_inscribed()
-{
- cptr s = lua_input_box("Word to find in object inscription?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_inscribed(s);
-}
-
-static condition_type *create_condition_discount()
-{
- int min, max;
-
- {
- cptr s = lua_input_box("Min discount?", 79);
- if (sscanf(s, "%d", &min) < 1)
- {
- return NULL;
- }
- }
-
- {
- cptr s = lua_input_box("Max discount?", 79);
- if (sscanf(s, "%d", &max) < 1)
- {
- return NULL;
- }
- }
-
- return condition_new_discount(min, max);
-}
-
-static condition_type *create_condition_symbol()
-{
- char c;
- cptr s = lua_input_box("Symbol to match?", 1);
- if (sscanf(s, "%c", &c) < 1)
- {
- return NULL;
- }
-
- return condition_new_symbol(c);
-}
-
-static condition_type *create_condition_status()
-{
- status_type status;
- char c;
-
- c = lua_msg_box("[t]errible, [v]ery bad, [b]ad, "
- "[a]verage, [G]ood, [V]ery good, [S]pecial?");
-
- switch (c)
- {
- case 't': status = TERRIBLE; break;
- case 'v': status = VERY_BAD; break;
- case 'b': status = BAD; break;
- case 'a': status = AVERAGE; break;
- case 'G': status = GOOD; break;
- case 'V': status = VERY_GOOD; break;
- case 'S': status = SPECIAL; break;
- default: return NULL;
- }
-
- return condition_new_status(status);
-}
-
-static condition_type *create_condition_state()
-{
- identification_state s;
- char c;
-
- c = lua_msg_box("[i]dentified, [n]on identified?");
-
- switch (c)
- {
- case 'i': s = IDENTIFIED; break;
- case 'n': s = NOT_IDENTIFIED; break;
- default: return NULL;
- }
-
- return condition_new_state(s);
-}
-
-static condition_type *create_condition_tval()
-{
- int tval;
- cptr s = lua_input_box("Tval to match?", 79);
- if (sscanf(s, "%d", &tval) < 1)
- {
- return NULL;
- }
-
- return condition_new_tval(tval);
-}
-
-static condition_type *create_condition_sval()
-{
- int sval_min, sval_max;
-
- {
- cptr s = lua_input_box("Min sval?", 79);
- if (sscanf(s, "%d", &sval_min) < 1)
- {
- return NULL;
- }
- }
-
- {
- cptr s = lua_input_box("Max sval?", 79);
- if (sscanf(s, "%d", &sval_max) < 1)
- {
- return NULL;
- }
- }
-
- return condition_new_sval(sval_min, sval_max);
-}
-
-static condition_type *create_condition_race()
-{
- cptr s = lua_input_box("Player race to match?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_race(s);
-}
-
-static condition_type *create_condition_subrace()
-{
- cptr s = lua_input_box("Player subrace to match?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_subrace(s);
-}
-
-static condition_type *create_condition_class()
-{
- cptr s = lua_input_box("Player class to match?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- return condition_new_class(s);
-}
-
-static condition_type *create_condition_level()
-{
- int min, max;
-
- {
- cptr s = lua_input_box("Min player level?", 79);
- if (sscanf(s, "%d", &min) < 1)
- {
- return NULL;
- }
- }
-
- {
- cptr s = lua_input_box("Max player level?", 79);
- if (sscanf(s, "%d", &max) < 1)
- {
- return NULL;
- }
- }
-
- return condition_new_level(min, max);
-}
-
-static condition_type *create_condition_skill()
-{
- int min, max;
- s16b skill_idx;
-
- {
- cptr s = lua_input_box("Min skill level?", 79);
- if (sscanf(s, "%d", &min) < 1)
- {
- return NULL;
- }
- }
-
- {
- cptr s = lua_input_box("Max skill level?", 79);
- if (sscanf(s, "%d", &max) < 1)
- {
- return NULL;
- }
- }
-
- {
- cptr s = lua_input_box("Skill name?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- skill_idx = find_skill_i(s);
- if (skill_idx < 0)
- {
- return NULL;
- }
- }
-
- return condition_new_skill(min, max, skill_idx);
-}
-
-static condition_type *create_condition_ability()
-{
- s16b ai;
- cptr s = lua_input_box("Ability name?", 79);
- if (strlen(s) == 0)
- {
- return NULL;
- }
-
- ai = find_ability(s);
- if (ai < 0)
- {
- return NULL;
- }
-
- return condition_new_ability(ai);
-}
-
-static condition_metadata types_list[TYPES_LIST_SIZE] =
-{
- { M_AND,
- { "Check is true if all rules within it are true",
- NULL },
- condition_new_and,
- },
- { M_OR,
- { "Check is true if at least one rule within it is true",
- NULL },
- condition_new_or,
- },
- { M_NOT,
- { "Invert the result of its child rule",
- NULL },
- condition_new_not,
- },
- { M_NAME,
- { "Check is true if object name matches name",
- NULL },
- create_condition_name,
- },
- { M_CONTAIN,
- { "Check is true if object name contains word",
- NULL },
- create_condition_contain,
- },
- { M_INSCRIBED,
- { "Check is true if object inscription contains word",
- NULL },
- create_condition_inscribed,
- },
- { M_DISCOUNT,
- { "Check is true if object discount is between two values",
- NULL },
- create_condition_discount,
- },
- { M_SYMBOL,
- { "Check is true if object symbol is ok",
- NULL },
- create_condition_symbol,
- },
- { M_STATE,
- { "Check is true if object is identified/unidentified",
- NULL },
- create_condition_state,
- },
- { M_STATUS,
- { "Check is true if object status is ok",
- NULL },
- create_condition_status,
- },
- { M_TVAL,
- { "Check is true if object tval(from k_info.txt) is ok",
- NULL },
- create_condition_tval,
- },
- { M_SVAL,
- { "Check is true if object sval(from k_info.txt) is between",
- "two values",
- NULL },
- create_condition_sval,
- },
- { M_RACE,
- { "Check is true if player race is ok",
- NULL },
- create_condition_race,
- },
- { M_SUBRACE,
- { "Check is true if player subrace is ok",
- NULL },
- create_condition_subrace,
- },
- { M_CLASS,
- { "Check is true if player class is ok",
- NULL },
- create_condition_class,
- },
- { M_LEVEL,
- { "Check is true if player level is between 2 values",
- NULL },
- create_condition_level,
- },
- { M_SKILL,
- { "Check is true if player skill level is between 2 values",
- NULL },
- create_condition_skill,
- },
- { M_ABILITY,
- { "Check is true if player has the ability",
- NULL },
- create_condition_ability,
- },
- { M_INVENTORY,
- { "Check is true if something in player's inventory matches",
- "the contained rule",
- NULL },
- condition_new_inventory,
- },
- { M_EQUIPMENT,
- { "Check is true if something in player's equipment matches",
- "the contained rule",
- NULL },
- condition_new_equipment,
- },
-};
-
-static void display_desc(condition_metadata *condition_metadata)
-{
- int i;
-
- assert(condition_metadata != NULL);
-
- for (i = 0; condition_metadata->description[i] != NULL; i++)
- {
- c_prt(TERM_WHITE, condition_metadata->description[i], i + 1, 17);
- }
-}
-
-/* Create a new rule */
-static condition_metadata *automatizer_select_condition_type()
-{
- int wid, hgt, max = TYPES_LIST_SIZE, begin = 0, sel = 0, i;
- char c;
- cptr types_names[TYPES_LIST_SIZE];
-
- /* Create list of names for display */
- for (i = 0; i < TYPES_LIST_SIZE; i++)
- {
- types_names[i] = match_type_to_string(types_list[i].match);
- }
-
- while (1)
- {
- Term_clear();
- Term_get_size(&wid, &hgt);
-
- display_list(0, 0, hgt - 1, 15, "Rule types", types_names, max, begin, sel, TERM_L_GREEN);
-
- display_desc(&types_list[sel]);
-
- c = inkey();
-
- if (c == ESCAPE) break;
- else if (c == '8')
- {
- sel--;
- if (sel < 0)
- {
- sel = max - 1;
- begin = max - hgt;
- if (begin < 0) begin = 0;
- }
- if (sel < begin) begin = sel;
- }
- else if (c == '2')
- {
- sel++;
- if (sel >= max)
- {
- sel = 0;
- begin = 0;
- }
- if (sel >= begin + hgt - 1) begin++;
- }
- else if (c == '\r')
- {
- return &types_list[sel];
- }
- }
- return NULL;
-}
-
-static void adjust_begin(int *begin, int *sel, int max, int hgt)
-{
- if (*sel < 0)
- {
- *sel = max - 1;
- *begin = *sel - hgt + 3;
- if (*begin < 0) *begin = 0;
- }
- if (*sel < *begin) *begin = *sel;
-
- if (*sel >= max)
- {
- *sel = 0;
- *begin = 0;
- }
- if (*sel >= *begin + hgt - 2) (*begin)++;
-}
-
-static int create_new_rule()
-{
- action_type action;
- char name[20] = { '\0' };
- char *inscription = NULL;
- int wid = 0, hgt = 0;
- char typ;
- arule_type *rule = NULL;
-
- Term_get_size(&wid, &hgt);
-
- sprintf(name, "%s", "No name");
- if (!input_box("Name?", hgt / 2, wid / 2, name, sizeof(name)))
- {
- return -1;
- }
-
- typ = lua_msg_box("[D]estroy, [P]ickup, [I]nscribe?");
-
- switch (typ)
- {
- case 'd':
- case 'D':
- action = AUTO_DESTROY;
- break;
-
- case 'p':
- case 'P':
- action = AUTO_PICKUP;
- break;
-
- case 'i':
- case 'I':
- {
- char *i = NULL;
-
- action = AUTO_INSCRIBE;
-
- i = lua_input_box("Inscription?", 79);
- if ((i == NULL) || (strlen(i) == 0))
- {
- return -1;
- }
-
- inscription = i;
-
- break;
- }
-
- default:
- return -1;
- }
-
- /* Make rule */
- rule = rule_new(name, action, game_module_idx, NULL, inscription);
-
- /* Append to list of rules */
- return rules_append(rule);
-}
-
-static void add_child(condition_type *current)
-{
- condition_metadata *metadata = NULL;
-
- switch (current->match)
- {
- case M_NOT:
- case M_EQUIPMENT:
- case M_INVENTORY:
- {
- if (current->subcondition != NULL)
- {
- return;
- }
-
- metadata = automatizer_select_condition_type();
- if (metadata == NULL)
- {
- return;
- }
-
- current->subcondition = metadata->create_condition();
- break;
- }
-
- case M_AND:
- metadata = automatizer_select_condition_type();
- if (metadata == NULL)
- {
- return;
- }
- condition_and_add(current, metadata->create_condition());
- break;
-
- case M_OR:
- metadata = automatizer_select_condition_type();
- if (metadata == NULL)
- {
- return;
- }
- condition_or_add(current, metadata->create_condition());
- break;
-
- default:
- /* No other types of conditions have children */
- break;
- }
-}
-
-static int tree_indent = 0;
-static int tree_write_out_y = 0;
-static int tree_write_out_x = 0;
-static int tree_write_out_h = 0;
-static int tree_write_out_w = 0;
-static int tree_write_y = 0;
-static int tree_write_x = 0;
-static int tree_write_off_x = 0;
-static int tree_write_off_y = 0;
-
-static void tree_write(byte color, cptr line)
-{
- cptr p = line;
-
- for (p = line; *p != '\0'; p++)
- {
- char c = *p;
- int x = tree_write_x - tree_write_off_x + 3*tree_indent;
- int y = tree_write_y - tree_write_off_y;
-
- if (c != '\n')
- {
- if ((y >= 0) &&
- (y < tree_write_out_h) &&
- (x >= 0) &&
- (x < tree_write_out_w))
- {
- Term_putch(x + tree_write_out_x,
- y + tree_write_out_y,
- color,
- c);
- }
-
- tree_write_x += 1;
- }
- else
- {
- tree_write_x = 0;
- tree_write_y += 1;
- }
- }
-}
-
-static void display_condition(condition_type *condition)
-{
- byte bcol = TERM_L_GREEN;
- byte ecol = TERM_GREEN;
- int i;
-
- assert(condition != NULL);
-
- /* If this condition is present in the cursor stack,
- then we use the "active" colors. */
- for (i = 0; i < cursor_count; i++)
- {
- if (cursor_stack[i] == condition)
- {
- bcol = TERM_VIOLET;
- ecol = TERM_VIOLET;
- break;
- }
- }
-
- tree_indent++;
-
- switch (condition->match)
- {
- case M_INVENTORY:
- case M_EQUIPMENT:
- {
- cptr where_s = (condition->match == M_INVENTORY)
- ? "inventory"
- : "equipment";
-
- tree_write(ecol, "Something in your ");
- tree_write(bcol, where_s);
- tree_write(ecol, " matches the following:");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_SKILL:
- {
- cptr skill_name =
- s_info[condition->skill_range.skill_idx].name + s_name;
-
- tree_write(ecol, "Your skill in ");
- tree_write(bcol, skill_name);
- tree_write(ecol, " is from ");
- tree_write(TERM_WHITE, format("%d", (int) condition->skill_range.min));
- tree_write(ecol, " to ");
- tree_write(TERM_WHITE, format("%d", (int) condition->skill_range.max));
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_ABILITY:
- {
- cptr ability_name =
- ab_info[condition->ability].name + ab_name;
-
- tree_write(ecol, "You have the ");
- tree_write(bcol, ability_name);
- tree_write(ecol, " ability");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_LEVEL:
- {
- tree_write(ecol, "Your ");
- tree_write(bcol, "level");
- tree_write(ecol, " is from ");
-
- tree_write(TERM_WHITE, format("%d", condition->level_range.min));
- tree_write(ecol, " to ");
- tree_write(TERM_WHITE, format("%d", condition->level_range.max));
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_SVAL:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "sval");
- tree_write(ecol, " is from ");
- tree_write(TERM_WHITE, format("%d", condition->sval_range.min));
- tree_write(ecol, " to ");
- tree_write(TERM_WHITE, format("%d", condition->sval_range.max));
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_DISCOUNT:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "discount");
- tree_write(ecol, " is from ");
- tree_write(TERM_WHITE, format("%d", condition->discount.min));
- tree_write(ecol, " to ");
- tree_write(TERM_WHITE, format("%d", condition->discount.max));
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_AND:
- {
- struct sglib_condition_list_iterator it;
- struct condition_list *child = NULL;
-
- tree_write(ecol, "All of the following are true:");
- tree_write(TERM_WHITE, "\n");
-
- for (child = sglib_condition_list_it_init(&it, condition->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- display_condition(child->condition);
- }
-
- break;
- }
-
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- struct condition_list *child = NULL;
-
- tree_write(ecol, "At least one of the following are true:");
- tree_write(TERM_WHITE, "\n");
-
- for (child = sglib_condition_list_it_init(&it, condition->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- display_condition(child->condition);
- }
-
- break;
- }
-
- case M_NOT:
- {
- tree_write(ecol, "Negate the following:");
- tree_write(TERM_WHITE, "\n");
- if (condition->subcondition != NULL)
- {
- display_condition(condition->subcondition);
- }
- break;
- }
-
- case M_NAME:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "name");
- tree_write(ecol, " is \"");
- tree_write(TERM_WHITE, condition->name);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_CONTAIN:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "name");
- tree_write(ecol, " contains \"");
- tree_write(TERM_WHITE, condition->name);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_INSCRIBED:
- {
- tree_write(ecol, "It is ");
- tree_write(bcol, "inscribed");
- tree_write(ecol, " with ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, condition->inscription);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_SYMBOL:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "symbol");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, format("%c", condition->symbol));
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_STATE:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "state");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, identification_state_to_string(condition->identification_state));
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_STATUS:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "status");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, status_to_string(condition->status));
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_TVAL:
- {
- tree_write(ecol, "Its ");
- tree_write(bcol, "tval");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, format("%d", condition->tval));
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_RACE:
- {
- tree_write(ecol, "Player ");
- tree_write(bcol, "race");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, condition->race);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_SUBRACE:
- {
- tree_write(ecol, "Player ");
- tree_write(bcol, "subrace");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, condition->subrace);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case M_CLASS:
- {
- tree_write(ecol, "Player ");
- tree_write(bcol, "class");
- tree_write(ecol, " is ");
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, condition->klass);
- tree_write(ecol, "\"");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- }
-
- tree_indent--;
-}
-
-static void display_rule(arule_type *rule)
-{
- cptr action_s;
- int hgt, wid;
-
- action_s = action_to_string(rule->action);
-
- Term_get_size(&wid, &hgt);
-
- tree_write_out_y = 1;
- tree_write_out_x = 16;
- tree_write_out_h = hgt - 4 - 1;
- tree_write_out_w = wid - 1 - 15 - 1;
- tree_write_y = 0;
- tree_write_x = 0;
-
- switch (rule->action)
- {
- case AUTO_DESTROY:
- case AUTO_PICKUP:
- {
- tree_write(TERM_GREEN, "A rule named \"");
- tree_write(TERM_WHITE, rule->name);
- tree_write(TERM_GREEN, "\" to ");
- tree_write(TERM_L_GREEN, action_s);
- tree_write(TERM_GREEN, " when");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- case AUTO_INSCRIBE:
- {
- tree_write(TERM_GREEN, "A rule named \"");
- tree_write(TERM_WHITE, rule->name);
- tree_write(TERM_GREEN, "\" to ");
- tree_write(TERM_L_GREEN, "inscribe");
- tree_write(TERM_GREEN, " an item with \"");
- tree_write(TERM_WHITE, rule->inscription);
- tree_write(TERM_GREEN, "\" when");
- tree_write(TERM_WHITE, "\n");
- break;
- }
-
- }
-
- /* Write out the condition */
- if (rule->condition != NULL)
- {
- display_condition(rule->condition);
- }
-}
-
-static void adjust_current(int sel)
-{
- if (rules_count == 0)
- {
- cursor_clear();
- return;
- }
-
- tree_write_off_y = 0;
- tree_write_off_x = 0;
-
- /* Put the top-level condition into cursor */
- cursor_clear();
- if (rules[sel]->condition != NULL)
- {
- cursor_push(rules[sel]->condition);
- }
-}
-
-static void tree_scroll_up()
-{
- tree_write_off_y = tree_write_off_y - 1;
-}
-
-static void tree_scroll_down()
-{
- tree_write_off_y = tree_write_off_y + 1;
-}
-
-static void tree_scroll_left()
-{
- tree_write_off_x = tree_write_off_x + 1;
-}
-
-static void tree_scroll_right()
-{
- tree_write_off_x = tree_write_off_x - 1;
-}
-
-static void automatizer_save_rules()
-{
- char name[30] = { '\0' };
- char buf[1025];
- char ch;
- int hgt, wid;
-
- Term_get_size(&wid, &hgt);
-
- sprintf(name, "automat.atm");
- if (!input_box("Save name?", hgt / 2, wid / 2, name, sizeof(name)))
- {
- return;
- }
-
- /* Build the filename */
- path_build(buf, 1024, ANGBAND_DIR_USER, name);
-
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
-
- if (file_exist(buf))
- {
- c_put_str(TERM_WHITE, "File exists, continue?[y/n]",
- hgt / 2,
- wid / 2 - 14);
- ch = inkey();
- if ((ch != 'Y') && (ch != 'y'))
- {
- return;
- }
- }
-
- /* Write to file */
- {
- json_t *rules_json = rules_to_json();
- int status = json_dump_file(rules_json, buf, JSON_INDENT(2) | JSON_SORT_KEYS);
- if (status == 0)
- {
- c_put_str(TERM_WHITE, "Saved rules in file ",
- hgt / 2,
- wid / 2 - 14);
- }
- else
- {
- c_put_str(TERM_WHITE, "Saving rules failed! ",
- hgt / 2,
- wid / 2 - 14);
- }
-
- /* Deallocate JSON */
- json_decref(rules_json);
-
- /* Wait for keypress */
- inkey();
- }
-}
-
-static void rename_rule(arule_type *rule)
-{
- char name[16];
- int wid, hgt;
-
- assert(rule != NULL);
-
- Term_get_size(&wid, &hgt);
-
- sprintf(name, "%s", rule->name);
- if (input_box("New name?", hgt / 2, wid / 2, name, sizeof(name)))
- {
- rule_set_name(rule, name);
- }
-}
-
-static void add_new_condition(arule_type *current_rule)
-{
- /* Top-level condition? */
- if (current_rule->condition == NULL)
- {
- condition_metadata *metadata = NULL;
-
- /* Sanity check for navigation stack */
- assert(cursor_count == 0);
-
- /* Select type of clause */
- metadata = automatizer_select_condition_type();
- if (metadata == NULL)
- {
- return;
- }
-
- /* Create the condition directly; we can
- always add a top-level condition so there's
- no need for the sanity checking in
- add_child(). */
- current_rule->condition = metadata->create_condition();
- if (current_rule->condition != NULL)
- {
- cursor_push(current_rule->condition);
- }
- }
- else
- {
- condition_type *current_condition = cursor_top();
- add_child(current_condition);
- }
-}
-
-static void tree_go_right()
-{
- condition_type *top = cursor_top();
-
- /* Can only go right if the currently selected condition
- has children. */
- switch (top->match)
- {
- case M_AND:
- case M_OR:
- {
- /* Pick first child */
- struct sglib_condition_list_iterator it;
- condition_list *i = sglib_condition_list_it_init(&it, top->conditions.c);
- /* Move right if possible */
- if (i != NULL)
- {
- cursor_push(i->condition);
- }
- break;
- }
-
- case M_NOT:
- case M_INVENTORY:
- case M_EQUIPMENT:
- {
- if (top->subcondition != NULL)
- {
- cursor_push(top->subcondition);
- }
- break;
- }
-
- default:
- /* Not possible to move */
- break;
- }
-}
-
-static void tree_go_left()
-{
- if (cursor_count > 1)
- {
- cursor_pop();
- }
-}
-
-static void tree_go_up()
-{
- if (cursor_count > 1)
- {
- condition_type *prev_top = cursor_pop();
- condition_type *top = cursor_top();
-
- switch (top->match)
- {
- case M_AND:
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- condition_list *child = NULL;
- condition_list *prev_child = NULL;
-
- /* We have a list of children */
- for (child = sglib_condition_list_it_init(&it, top->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- if (child->condition == prev_top)
- {
- /* Do we have a previous child? */
- if (prev_child == NULL)
- {
- /* No predecessor; don't move */
- cursor_push(prev_top);
- break;
- }
- else
- {
- cursor_push(prev_child->condition);
- break; /* Done */
- }
- }
- /* Keep track of previous child */
- prev_child = child;
- }
-
- break;
- }
-
- default:
- {
- /* No other match types have children; restore
- original top. */
- cursor_push(prev_top);
- break;
- }
-
- }
- }
-}
-
-static void tree_go_down()
-{
- if (cursor_count > 1)
- {
- condition_type *prev_top = cursor_pop();
- condition_type *top = cursor_top();
-
- switch (top->match)
- {
- case M_AND:
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- condition_list *child = NULL;
-
- /* We have a list of children */
- for (child = sglib_condition_list_it_init(&it, top->conditions.c);
- child != NULL;
- child = sglib_condition_list_it_next(&it))
- {
- if (child->condition == prev_top)
- {
- /* Move to next child (if any) */
- child = sglib_condition_list_it_next(&it);
- if (child == NULL)
- {
- /* No successor; don't move */
- cursor_push(prev_top);
- break;
- }
- else
- {
- cursor_push(child->condition);
- break; /* Done */
- }
- }
- }
-
- break;
- }
-
- default:
- {
- /* No other match types have multiple children; restore
- original top. */
- cursor_push(prev_top);
- break;
- }
-
- }
- }
-}
-
-static int automatizer_del_self(int sel)
-{
- /* If the cursor is at the top level then
- we want to delete the rule itself */
- if (cursor_count < 1)
- {
- rules_remove(rules[sel]);
- return sel - 1; /* Move selection up */
- }
- else if (cursor_count == 1)
- {
- cursor_pop();
- condition_destroy(&rules[sel]->condition);
- return sel;
- }
- else
- {
- condition_type *prev_top = cursor_pop();
- condition_type *top = cursor_top();
-
- /* Jump up a level; this is a simple way to ensure a
- valid cursor. We could be a little cleverer here by
- trying to move inside the current level, but it's a
- little complicated. */
- tree_go_left();
-
- /* Now we can remove the condition from its parent */
- switch (top->match)
- {
-
- case M_AND:
- case M_OR:
- {
- struct sglib_condition_list_iterator it;
- condition_list *item = NULL;
-
- /* We have a list of children */
- for (item = sglib_condition_list_it_init(&it, top->conditions.c);
- item != NULL;
- item = sglib_condition_list_it_next(&it))
- {
- if (item->condition == prev_top)
- {
- /* Found */
- break;
- }
- }
-
- /* Must have found item; otherwise internal structure
- is damaged. */
- assert (item != NULL);
- sglib_condition_list_delete(&top->conditions.c, item);
-
- /* Destroy the condition */
- condition_destroy(&prev_top);
- break;
- }
-
- case M_NOT:
- case M_EQUIPMENT:
- case M_INVENTORY:
- {
- assert(top->subcondition != NULL);
- condition_destroy(&top->subcondition);
- break;
- }
-
- default:
- /* If we get here, something's wrong with the
- navigation structures. */
- assert(FALSE);
- break;
- }
-
- /* Keep selection */
- return sel;
- }
-}
-
-#define ACTIVE_LIST 0
-#define ACTIVE_RULE 1
-void do_cmd_automatizer()
-{
- int wid = 0, hgt = 0;
- char c;
- int max, begin = 0, sel = 0;
- int active = ACTIVE_LIST;
- cptr keys;
- cptr keys2;
- cptr keys3;
- cptr rule_names[RULES_MAX];
-
- Term_get_size(&wid, &hgt);
-
- if (!automatizer_enabled)
- {
- if (msg_box("Automatizer is currently disabled, enable it? (y/n)", hgt / 2, wid / 2) == 'y')
- {
- automatizer_enabled = TRUE;
- }
- else
- return;
- }
-
- screen_save();
-
- adjust_current(sel);
-
- while (1)
- {
- Term_clear();
- Term_get_size(&wid, &hgt);
-
- max = rules_count;
- get_rule_names(rule_names);
- display_list(0, 0, hgt - 1, 15, "Rules", rule_names, max, begin, sel, (active == ACTIVE_LIST) ? TERM_L_GREEN : TERM_GREEN);
-
- draw_box(0, 15, hgt - 4, wid - 1 - 15);
- if (active == ACTIVE_RULE)
- {
- keys = "#Bup#W/#Bdown#W/#Bleft#W/#Bright#W to navitage rule, #B9#W/#B3#W/#B7#W/#B1#W to scroll";
- keys2 = "#Btab#W for switch, #Ba#Wdd clause, #Bd#Welete clause/rule";
- keys3 = "#G?#W for Automatizer help";
- }
- else
- {
- keys = "#Bup#W/#Bdown#W to scroll, #Btab#W to switch to the rule window";
- keys2 = "#Bu#W/#Bd#W to move rules, #Bn#Wew rule, #Br#Wename rule, #Bs#Wave rules";
- keys3 = "#Rk#W to #rdisable#W the automatizer, #G?#W for Automatizer help";
- }
- display_message(17, hgt - 3, strlen(keys), TERM_WHITE, keys);
- display_message(17, hgt - 2, strlen(keys2), TERM_WHITE, keys2);
- display_message(17, hgt - 1, strlen(keys3), TERM_WHITE, keys3);
-
- if (max)
- {
- display_rule(rules[sel]);
- }
-
- c = inkey();
-
- if (c == ESCAPE) break;
- if (active == ACTIVE_LIST)
- {
- if (c == '?')
- {
- screen_save();
- show_file("automat.txt", "Automatizer help", 0, 0);
- screen_load();
- }
- else if (c == '8')
- {
- if (!max) continue;
- sel--;
- adjust_begin(&begin, &sel, max, hgt);
- adjust_current(sel);
- }
- else if (c == '2')
- {
- if (!max) continue;
- sel++;
- adjust_begin(&begin, &sel, max, hgt);
- adjust_current(sel);
- }
- else if (c == 'u')
- {
- if (sel > 0)
- {
- rules_swap(sel-1, sel);
- sel -= 1;
-
- adjust_begin(&begin, &sel, max, hgt);
- adjust_current(sel);
- }
- }
- else if (c == 'd')
- {
- if (!max) continue;
-
- if (sel < rules_count - 1)
- {
- rules_swap(sel, sel+1);
- sel += 1;
-
- adjust_begin(&begin, &sel, max, hgt);
- adjust_current(sel);
- }
- }
- else if (c == 'n')
- {
- int i = create_new_rule();
- if (i >= 0)
- {
- sel = i;
- adjust_current(sel);
- active = ACTIVE_RULE;
- }
- }
- else if (c == 's')
- {
- automatizer_save_rules();
- }
- else if (c == 'r')
- {
- if (!max) continue;
-
- rename_rule(rules[sel]);
- continue;
- }
- else if (c == 'k')
- {
- automatizer_enabled = FALSE;
- break;
- }
- else if (c == '\t')
- {
- if (!max) continue;
- active = ACTIVE_RULE;
- }
- }
- else if (active == ACTIVE_RULE)
- {
- if (c == '?')
- {
- screen_save();
- show_file("automat.txt", "Automatizer help", 0, 0);
- screen_load();
- }
- else if (c == '8')
- {
- tree_go_up();
- }
- else if (c == '2')
- {
- tree_go_down();
- }
- else if (c == '6')
- {
- tree_go_right();
- }
- else if (c == '4')
- {
- tree_go_left();
- }
- else if (c == '9')
- {
- tree_scroll_up();
- }
- else if (c == '3')
- {
- tree_scroll_down();
- }
- else if (c == '7')
- {
- tree_scroll_left();
- }
- else if (c == '1')
- {
- tree_scroll_right();
- }
- else if (c == 'a')
- {
- add_new_condition(rules[sel]);
- }
- else if (c == 'd')
- {
- if (max)
- {
- int new_sel;
-
- new_sel = automatizer_del_self(sel);
- if ((sel != new_sel) && (new_sel >= 0))
- {
- sel = new_sel;
- adjust_begin(&begin, &sel, max, hgt);
- adjust_current(sel);
- }
- else if (new_sel == -1)
- {
- active = ACTIVE_LIST;
- }
- }
- }
- else if (c == '\t')
- {
- active = ACTIVE_LIST;
- }
- }
- }
-
- screen_load();
-}
-
-static void easy_add_rule(action_type action, cptr mode, bool_ do_status, object_type *o_ptr)
-{
- condition_type *condition = NULL;
-
- if (streq(mode, "tval"))
- {
- condition = condition_new_tval(o_ptr->tval);
- }
- else if (streq(mode, "tsval"))
- {
- condition_type *sval_condition =
- condition_new_sval(o_ptr->sval, o_ptr->sval);
- condition_type *tval_condition =
- condition_new_tval(o_ptr->tval);
-
- condition = condition_new_and();
- condition_and_add(condition, tval_condition);
- condition_and_add(condition, sval_condition);
- }
- else if (streq(mode, "name"))
- {
- char buf[128];
- object_desc(buf, o_ptr, -1, 0);
- strlower(buf);
-
- condition = condition_new_name(buf);
- }
-
- /* Use object status? */
- if (do_status == TRUE)
- {
- status_type status = object_status(o_ptr);
- condition_type *status_condition =
- condition_new_status(status);
- condition_type *and_condition =
- condition_new_and();
-
- condition_and_add(and_condition, condition);
- condition_and_add(and_condition, status_condition);
- /* Replace condition */
- condition = and_condition;
- }
-
- /* Build rule */
- {
- static arule_type *rule = NULL;
- /* Make rule */
- rule = rule_new(action_to_string(action),
- action,
- game_module_idx,
- condition,
- NULL);
-
- /* Append to list of rules */
- rules_append(rule);
- }
-
- msg_print("Rule added. Please go to the Automatizer screen (press = then T)");
- msg_print("to save the modified ruleset.");
-}
-
-/* Add a new rule in an easy way */
-bool_ automatizer_create = FALSE;
-void automatizer_add_rule(object_type *o_ptr, bool_ destroy)
-{
- char ch;
- bool_ do_status = FALSE;
- action_type action = AUTO_DESTROY;
-
- if (!destroy)
- {
- action = AUTO_PICKUP;
- }
-
- while (TRUE)
- {
- if (!get_com(format("%s all of the same [T]ype, [F]amily or [N]ame, also use [S]tatus (%s)? ", (destroy) ? "Destroy" : "Pickup", (do_status) ? "Yes" : "No"), &ch))
- {
- break;
- }
-
- if (ch == 'S' || ch == 's')
- {
- do_status = !do_status;
- continue;
- }
-
- if (ch == 'T' || ch == 't')
- {
- easy_add_rule(action, "tsval", do_status, o_ptr);
- break;
- }
-
- if (ch == 'F' || ch == 'f')
- {
- easy_add_rule(action, "tval", do_status, o_ptr);
- break;
- }
-
- if (ch == 'N' || ch == 'n')
- {
- easy_add_rule(action, "name", do_status, o_ptr);
- break;
- }
- }
-}
-
-static condition_type *parse_condition(json_t *condition_json)
-{
- cptr type_s = NULL;
- match_type match;
-
- if ((condition_json == NULL) || json_is_null(condition_json))
- {
- return NULL;
- }
-
- if (json_unpack(condition_json,
- "{s:s}",
- "type", &type_s) < 0)
- {
- msg_print("Missing/invalid 'type' in condition");
- return NULL;
- }
-
- if (!match_type_from_string(type_s, &match))
- {
- msg_format("Invalid 'type' in condition: %s", type_s);
- return NULL;
- }
-
- switch (match)
- {
- case M_AND:
- case M_OR:
- {
- json_t *conditions_j = json_object_get(condition_json,
- "conditions");
-
- if ((conditions_j == NULL) ||
- (json_is_null(conditions_j)))
- {
- return NULL;
- }
- else if (json_is_array(conditions_j))
- {
- int i;
- json_t *subcondition_j = NULL;
- condition_type *condition = condition_new(match);
- condition_type *subcondition = NULL;
-
- for (i = 0; i < json_array_size(conditions_j); i++)
- {
- subcondition_j =
- json_array_get(conditions_j, i);
- subcondition =
- parse_condition(subcondition_j);
-
- if (subcondition != NULL)
- {
- condition_and_add(condition, subcondition);
- }
- }
-
- return condition;
- }
- else
- {
- msg_print("'conditions' property has invalid type");
- return NULL;
- }
-
- break;
- }
-
- case M_NOT:
- case M_INVENTORY:
- case M_EQUIPMENT:
- {
- json_t *condition_j = json_object_get(condition_json,
- "condition");
-
- if ((condition_j == NULL) ||
- (json_is_null(condition_j)))
- {
- return NULL;
- }
- else if (json_is_object(condition_j))
- {
- condition_type *condition =
- condition_new(match);
- condition->subcondition =
- parse_condition(condition_j);
- return condition;
- }
- else
- {
- msg_print("Invlalid 'condition' property");
- return NULL;
- }
- }
-
- case M_NAME:
- {
- cptr s = NULL;
- if (json_unpack(condition_json,
- "{s:s}",
- "name", &s) < 0)
- {
- msg_print("Missing/invalid 'name' property");
- return NULL;
- }
-
- return condition_new_name(s);
- }
-
- case M_CONTAIN:
- {
- cptr s = NULL;
- if (json_unpack(condition_json,
- "{s:s}",
- "contain", &s) < 0)
- {
- msg_print("Missing/invalid 'contain' property");
- return NULL;
- }
-
- return condition_new_contain(s);
- }
-
- case M_SYMBOL:
- {
- cptr s = NULL;
- int sl;
- if (json_unpack(condition_json, "{s:s}", "symbol", &s) < 0)
- {
- msg_print("Missing/invalid 'symbol' property");
- return NULL;
- }
-
- sl = strlen(s);
- if (sl == 0)
- {
- msg_print("Invalid 'symbol' property: Too short");
- return NULL;
- }
- if (sl > 1)
- {
- msg_print("Invalid 'symbol' property: Too long");
- return NULL;
- }
-
- return condition_new_symbol(s[0]);
- }
-
- case M_INSCRIBED:
- {
- cptr s = NULL;
- if (json_unpack(condition_json, "{s:s}", "inscription", &s) < 0)
- {
- msg_print("Missing/invalid 'inscription' property");
- return NULL;
- }
-
- return condition_new_inscribed(s);
- }
-
- case M_DISCOUNT:
- {
- int min, max;
-
- if (json_unpack(condition_json, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
- {
- msg_print("Missing/invalid 'min'/'max' properties");
- return NULL;
- }
-
- return condition_new_discount(min, max);
- }
-
- case M_TVAL:
- {
- int tval;
-
- if (json_unpack(condition_json, "{s:i}", "tval", &tval) < 0)
- {
- msg_print("Missing/invalid 'tval' property");
- return NULL;
- }
-
- return condition_new_tval(tval);
- }
-
- case M_SVAL:
- {
- int min, max;
-
- if (json_unpack(condition_json, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
- {
- msg_print("Missing/invalid 'min'/'max' properties");
- return NULL;
- }
-
- return condition_new_sval(min, max);
- }
-
- case M_STATUS:
- {
- cptr s;
- status_type status;
-
- if (json_unpack(condition_json, "{s:s}", "status", &s) < 0)
- {
- msg_print("Missing/invalid 'status' property");
- return NULL;
- }
-
- if (!status_from_string(s, &status))
- {
- msg_format("Invalid 'status' property: %s", s);
- return NULL;
- }
-
- return condition_new_status(status);
- }
-
- case M_STATE:
- {
- cptr s;
- identification_state state;
-
- if (json_unpack(condition_json, "{s:s}", "state", &s) < 0)
- {
- msg_print("Missing/invalid 'state' property");
- return NULL;
- }
-
- if (!identification_state_from_string(s, &state))
- {
- msg_format("Invalid 'state' property: %s", s);
- return NULL;
- }
-
- return condition_new_state(state);
- }
-
- case M_RACE:
- {
- cptr s;
-
- if (json_unpack(condition_json, "{s:s}", "race", &s) < 0)
- {
- msg_print("Missing/invalid 'race' property");
- return NULL;
- }
-
- return condition_new_race(s);
- }
-
- case M_SUBRACE:
- {
- cptr s;
-
- if (json_unpack(condition_json, "{s:s}", "subrace", &s) < 0)
- {
- msg_print("Missing/invalid 'subrace' property");
- return NULL;
- }
-
- return condition_new_subrace(s);
- }
-
- case M_CLASS:
- {
- cptr s;
-
- if (json_unpack(condition_json, "{s:s}", "class", &s) < 0)
- {
- msg_print("Missing/invalid 'class' property");
- return NULL;
- }
-
- return condition_new_class(s);
- }
-
- case M_LEVEL:
- {
- int min, max;
-
- if (json_unpack(condition_json, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
- {
- msg_print("Missing/invalid 'min'/'max' properties");
- return NULL;
- }
-
- return condition_new_level(min, max);
- }
-
- case M_SKILL:
- {
- cptr s;
- s16b si;
- int min, max;
-
- if (json_unpack(condition_json, "{s:i,s:i,s:s}",
- "min", &min,
- "max", &max,
- "name", &s) < 0)
- {
- msg_print("Missing/invalid 'min'/'max'/'name' properties");
- return NULL;
- }
-
- si = find_skill_i(s);
- if (si < 0)
- {
- msg_print("Invalid 'name' property");
- return NULL;
- }
-
- return condition_new_skill(min, max, si);
- }
-
- case M_ABILITY:
- {
- cptr a;
- s16b ai;
-
- if (json_unpack(condition_json, "{s:s}",
- "ability", &a) < 0)
- {
- msg_print("Missing/invalid 'ability' property");
- return NULL;
- }
-
- ai = find_ability(a);
- if (ai < 0)
- {
- msg_print("Invalid 'ability' property");
- return NULL;
- }
-
- return condition_new_ability(ai);
- }
-
- }
-
- /* Could not parse */
- return NULL;
-}
-
-static void parse_rule(json_t *rule_json)
-{
- char *rule_name_s = NULL;
- char *rule_action_s = NULL;
- char *rule_module_s = NULL;
- json_t *rule_inscription_j = NULL;
- arule_type *rule = NULL;
- action_type action;
- int module_idx;
-
- if (!json_is_object(rule_json))
- {
- msg_print("Rule is not an object");
- return;
- }
-
- /* Retrieve the attributes */
- if (json_unpack(rule_json,
- "{s:s,s:s,s:s}",
- "name", &rule_name_s,
- "action", &rule_action_s,
- "module", &rule_module_s) < 0)
- {
- msg_print("Rule missing required field(s)");
- return;
- }
-
- /* Get the optional inscription */
- rule_inscription_j = json_object_get(rule_json, "inscription");
-
- /* Convert attributes */
- if (!action_from_string((cptr) rule_action_s, &action))
- {
- msg_format("Invalid rule action '%s'", rule_action_s);
- return;
- }
-
- module_idx = find_module((cptr) rule_module_s);
- if (module_idx < 0)
- {
- msg_format("Skipping rule for unrecognized module '%s'",
- (cptr) rule_module_s);
- return;
- }
-
- /* Sanity check: Inscription */
- if (action == AUTO_INSCRIBE)
- {
- if (rule_inscription_j == NULL)
- {
- msg_print("Inscription rule missing 'inscription' attribute");
- return;
- }
- if (!json_is_string(rule_inscription_j))
- {
- msg_print("Inscription rule 'inscription' attribute wrong type");
- return;
- }
- }
-
- /* Create rule */
- rule = rule_new(rule_name_s,
- action,
- module_idx,
- NULL,
- json_string_value(rule_inscription_j));
- rules_append(rule);
-
- /* Parse the conditions */
- rule->condition = parse_condition(json_object_get(rule_json, "condition"));
-}
-
-static void parse_rules(json_t *rules)
-{
- int i;
-
- if (!json_is_array(rules))
- {
- msg_format("Error 'rules' is not an array");
- return;
- }
-
- for (i = 0; i < json_array_size(rules); i++)
- {
- json_t *rule = json_array_get(rules, i);
- parse_rule(rule);
- }
-}
-
-/**
- * Initialize the automatizer. This function may be called multiple
- * times with different file names -- it should NOT clear any
- * automatizer state (including loaded rules).
- */
-void automatizer_init(cptr file_path)
-{
- json_t *rules_json = NULL;
- json_error_t error;
-
- /* Does the file exist? */
- if (!file_exist(file_path))
- {
- /* No big deal, we'll just skip */
- goto out;
- }
-
- /* Parse file */
- rules_json = json_load_file(file_path, 0, &error);
- if (rules_json == NULL)
- {
- msg_format("Error parsing automatizer rules from '%s'.", file_path);
- msg_format("Line %d, Column %d", error.line, error.column);
- msg_print(NULL);
- goto out;
- }
-
- /* Go through all the found rules */
- parse_rules(rules_json);
-
-out:
- if (rules_json == NULL)
- {
- json_decref(rules_json);
- }
-}
diff --git a/src/squeltch.cc b/src/squeltch.cc
new file mode 100644
index 00000000..8e8c5b8f
--- /dev/null
+++ b/src/squeltch.cc
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2002 DarkGod
+ * Copyright (c) 2012 Bardur Arantsson
+ *
+ * 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.
+ */
+
+#include "squeltch.hpp"
+
+#include "cave_type.hpp"
+#include "files.hpp"
+#include "loadsave.hpp"
+#include "lua_bind.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "player_type.hpp"
+#include "tome/squelch/tree_printer.hpp"
+#include "tome/squelch/condition.hpp"
+#include "tome/squelch/condition_metadata.hpp"
+#include "tome/squelch/rule.hpp"
+#include "tome/squelch/cursor.hpp"
+#include "tome/squelch/object_status.hpp"
+#include "tome/squelch/automatizer.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <jansson.h>
+#include <algorithm>
+#include <memory>
+#include <deque>
+#include <list>
+#include <string>
+#include <vector>
+
+using squelch::action_type;
+using squelch::action_mapping;
+
+using squelch::status_type;
+
+using squelch::Rule;
+using squelch::DestroyRule;
+using squelch::PickUpRule;
+using squelch::InscribeRule;
+
+using squelch::Condition;
+using squelch::AndCondition;
+using squelch::TvalCondition;
+using squelch::SvalCondition;
+using squelch::NameCondition;
+using squelch::StatusCondition;
+
+static squelch::Automatizer *automatizer = nullptr;
+
+void squeltch_grid(void)
+{
+ if (!automatizer_enabled)
+ {
+ return;
+ }
+
+ // Copy list of objects since we may modify it
+ auto const object_idxs(cave[p_ptr->py][p_ptr->px].o_idxs);
+
+ // Scan the pile of objects
+ for (auto const this_o_idx: object_idxs)
+ {
+ // Acquire object
+ object_type * o_ptr = &o_list[this_o_idx];
+
+ // We've now seen one of these
+ if (!k_info[o_ptr->k_idx].flavor)
+ {
+ object_aware(o_ptr);
+ }
+
+ // Apply rules
+ automatizer->apply_rules(o_ptr, -this_o_idx);
+ }
+}
+
+void squeltch_inventory(void)
+{
+ if (!automatizer_enabled)
+ {
+ return;
+ }
+
+ bool changed = true;
+ for (int num_iter = 0; changed && (num_iter < 100); num_iter++)
+ {
+ // No changes on this iteration.
+ changed = false;
+ // Traverse inventory
+ for (int i = 0; i < INVEN_PACK; i++)
+ {
+ object_type *o_ptr = &p_ptr->inventory[i];
+ if ((o_ptr->k_idx > 0) && automatizer->apply_rules(o_ptr, i))
+ {
+ // We have changes
+ changed = true;
+ // Re-traverse inventory
+ break;
+ }
+ }
+ }
+ // If we reached the iteration limit, "changed" will be true
+ if (changed)
+ {
+ cmsg_format(TERM_VIOLET, "'apply_rules' ran too often.");
+ }
+}
+
+static int create_new_rule()
+{
+ char name[20] = { '\0' };
+ int wid = 0, hgt = 0;
+
+ Term_get_size(&wid, &hgt);
+
+ sprintf(name, "%s", "No name");
+ if (!input_box("Name?", hgt / 2, wid / 2, name, sizeof(name)))
+ {
+ return -1;
+ }
+
+ char typ = lua_msg_box("[D]estroy, [P]ickup, [I]nscribe?");
+
+ std::shared_ptr<Rule> rule;
+ switch (typ)
+ {
+ case 'd':
+ case 'D':
+ rule = std::make_shared<DestroyRule>(name, game_module_idx, nullptr);
+ break;
+
+ case 'p':
+ case 'P':
+ rule = std::make_shared<PickUpRule>(name, game_module_idx, nullptr);
+ break;
+
+ case 'i':
+ case 'I':
+ {
+ cptr i = lua_input_box("Inscription?", 79);
+ if ((i == nullptr) || (strlen(i) == 0))
+ {
+ return -1;
+ }
+
+ rule = std::make_shared<InscribeRule>(
+ name, game_module_idx, nullptr, std::string(i));
+
+ break;
+ }
+
+ default:
+ return -1;
+ }
+
+ return automatizer->append_rule(rule);
+}
+
+static void automatizer_save_rules()
+{
+ char name[30] = { '\0' };
+ char buf[1025];
+ char ch;
+ int hgt, wid;
+
+ Term_get_size(&wid, &hgt);
+
+ sprintf(name, "%s.atm", player_name);
+
+ if (!input_box("Save name?", hgt / 2, wid / 2, name, sizeof(name)))
+ {
+ return;
+ }
+
+ // Build the filename
+ path_build(buf, 1024, ANGBAND_DIR_USER, name);
+
+ // File type is "TEXT"
+ FILE_TYPE(FILE_TYPE_TEXT);
+
+ if (file_exist(buf))
+ {
+ c_put_str(TERM_WHITE, "File exists, continue?[y/n]",
+ hgt / 2,
+ wid / 2 - 14);
+ ch = inkey();
+ if ((ch != 'Y') && (ch != 'y'))
+ {
+ return;
+ }
+ }
+
+ // Write to file
+ {
+ auto rules_json = automatizer->to_json();
+
+ int status = json_dump_file(rules_json.get(), buf,
+ JSON_INDENT(2) |
+ JSON_SORT_KEYS);
+ if (status == 0)
+ {
+ c_put_str(TERM_WHITE, "Saved rules in file ",
+ hgt / 2,
+ wid / 2 - 14);
+ }
+ else
+ {
+ c_put_str(TERM_WHITE, "Saving rules failed! ",
+ hgt / 2,
+ wid / 2 - 14);
+ }
+
+ // Wait for keypress
+ inkey();
+ }
+}
+
+static void rename_rule(Rule *rule)
+{
+ char name[16];
+ int wid, hgt;
+
+ assert(rule != nullptr);
+
+ Term_get_size(&wid, &hgt);
+
+ sprintf(name, "%s", rule->get_name());
+ if (input_box("New name?", hgt / 2, wid / 2, name, sizeof(name)))
+ {
+ rule->set_name(name);
+ }
+}
+
+#define ACTIVE_LIST 0
+#define ACTIVE_RULE 1
+void do_cmd_automatizer()
+{
+ int wid = 0, hgt = 0;
+ int active = ACTIVE_LIST;
+ cptr keys;
+ cptr keys2;
+ cptr keys3;
+ std::vector<cptr> rule_names;
+
+ Term_get_size(&wid, &hgt);
+
+ if (!automatizer_enabled)
+ {
+ if (msg_box("Automatizer is currently disabled, enable it? (y/n)", hgt / 2, wid / 2) == 'y')
+ {
+ automatizer_enabled = TRUE;
+ }
+ else
+ return;
+ }
+
+ screen_save();
+
+ automatizer->reset_view();
+
+ while (1)
+ {
+ Term_clear();
+ Term_get_size(&wid, &hgt);
+
+ automatizer->get_rule_names(&rule_names);
+
+ display_list(0, 0, hgt - 1, 15, "Rules", rule_names.data(), automatizer->rules_count(), automatizer->rules_begin(), automatizer->selected_rule(), (active == ACTIVE_LIST) ? TERM_L_GREEN : TERM_GREEN);
+
+ draw_box(0, 15, hgt - 4, wid - 1 - 15);
+ if (active == ACTIVE_RULE)
+ {
+ keys = "#Bup#W/#Bdown#W/#Bleft#W/#Bright#W to navitage rule, #B9#W/#B3#W/#B7#W/#B1#W to scroll";
+ keys2 = "#Btab#W for switch, #Ba#Wdd clause, #Bd#Welete clause/rule";
+ keys3 = "#G?#W for Automatizer help";
+ }
+ else
+ {
+ keys = "#Bup#W/#Bdown#W to scroll, #Btab#W to switch to the rule window";
+ keys2 = "#Bu#W/#Bd#W to move rules, #Bn#Wew rule, #Br#Wename rule, #Bs#Wave rules";
+ keys3 = "#Rk#W to #rdisable#W the automatizer, #G?#W for Automatizer help";
+ }
+ display_message(17, hgt - 3, strlen(keys), TERM_WHITE, keys);
+ display_message(17, hgt - 2, strlen(keys2), TERM_WHITE, keys2);
+ display_message(17, hgt - 1, strlen(keys3), TERM_WHITE, keys3);
+
+ automatizer->show_current();
+
+ char c = inkey();
+
+ if (c == ESCAPE) break;
+ if (active == ACTIVE_LIST)
+ {
+ if (c == '?')
+ {
+ screen_save();
+ show_file("automat.txt", "Automatizer help", 0, 0);
+ screen_load();
+ }
+ else if (c == '8')
+ {
+ if (!automatizer->rules_count()) continue;
+
+ automatizer->select_rule(
+ automatizer->selected_rule() - 1);
+ }
+ else if (c == '2')
+ {
+ if (!automatizer->rules_count()) continue;
+
+ automatizer->select_rule(
+ automatizer->selected_rule() + 1);
+ }
+ else if (c == 'u')
+ {
+ int sel = automatizer->selected_rule();
+ if (sel > 0)
+ {
+ automatizer->swap_rules(sel-1, sel);
+ automatizer->select_rule(sel-1);
+ }
+ }
+ else if (c == 'd')
+ {
+ if (!automatizer->rules_count()) continue;
+
+ int sel = automatizer->selected_rule();
+ if (sel < automatizer->rules_count() - 1)
+ {
+ automatizer->swap_rules(sel, sel+1);
+ automatizer->select_rule(sel+1);
+ }
+ }
+ else if (c == 'n')
+ {
+ int i = create_new_rule();
+ if (i >= 0)
+ {
+ automatizer->select_rule(i);
+ active = ACTIVE_RULE;
+ }
+ }
+ else if (c == 's')
+ {
+ automatizer_save_rules();
+ }
+ else if (c == 'r')
+ {
+ if (!automatizer->rules_count()) continue;
+
+ rename_rule(automatizer->current_rule().get());
+ continue;
+ }
+ else if (c == 'k')
+ {
+ automatizer_enabled = FALSE;
+ break;
+ }
+ else if (c == '\t')
+ {
+ if (!automatizer->rules_count()) continue;
+
+ active = ACTIVE_RULE;
+ }
+ }
+ else if (active == ACTIVE_RULE)
+ {
+ if (c == '?')
+ {
+ screen_save();
+ show_file("automat.txt", "Automatizer help", 0, 0);
+ screen_load();
+ }
+ else if (c == '8')
+ {
+ automatizer->move_up();
+ }
+ else if (c == '2')
+ {
+ automatizer->move_down();
+ }
+ else if (c == '6')
+ {
+ automatizer->move_right();
+ }
+ else if (c == '4')
+ {
+ automatizer->move_left();
+ }
+ else if (c == '9')
+ {
+ automatizer->scroll_up();
+ }
+ else if (c == '3')
+ {
+ automatizer->scroll_down();
+ }
+ else if (c == '7')
+ {
+ automatizer->scroll_left();
+ }
+ else if (c == '1')
+ {
+ automatizer->scroll_right();
+ }
+ else if (c == 'a')
+ {
+ automatizer->add_new_condition(
+ squelch::new_condition_interactive);
+ }
+ else if (c == 'd')
+ {
+ if (!automatizer->rules_count())
+ {
+ continue;
+ }
+
+ int new_sel =
+ automatizer->remove_current_selection();
+
+ if (new_sel == -1)
+ {
+ active = ACTIVE_LIST;
+ }
+ }
+ else if (c == '\t')
+ {
+ active = ACTIVE_LIST;
+ }
+ }
+ }
+
+ screen_load();
+}
+
+enum class add_rule_mode { TVAL, TSVAL, NAME };
+
+static void easy_add_rule(add_rule_mode mode, bool do_status, object_type *o_ptr)
+{
+ std::shared_ptr<Condition> condition;
+
+ switch (mode)
+ {
+
+ case add_rule_mode::TVAL:
+ condition = std::make_shared<TvalCondition>(o_ptr->tval);
+ break;
+
+ case add_rule_mode::TSVAL:
+ {
+ auto andCondition = std::make_shared<AndCondition>();
+
+ andCondition->add_condition(
+ std::make_shared<TvalCondition>(o_ptr->tval));
+ andCondition->add_condition(
+ std::make_shared<SvalCondition>(o_ptr->sval, o_ptr->sval));
+
+ condition = andCondition;
+ break;
+ }
+
+ case add_rule_mode::NAME:
+ {
+ char buf[128];
+ object_desc(buf, o_ptr, -1, 0);
+
+ condition = std::make_shared<NameCondition>(buf);
+ break;
+ }
+
+ }
+
+ // Use object status?
+ if (do_status)
+ {
+ status_type status = squelch::object_status(o_ptr);
+
+ auto andCondition = std::make_shared<AndCondition>();
+
+ andCondition->add_condition(
+ std::shared_ptr<Condition>(condition)); // cycle
+ andCondition->add_condition(
+ std::make_shared<StatusCondition>(status));
+
+ // Replace condition; breaks cycle
+ condition = andCondition;
+ }
+
+ // Rule name
+ auto rule_name = action_mapping().stringify(action_type::AUTO_DESTROY);
+
+ // Append to list of rules
+ automatizer->append_rule(
+ std::make_shared<DestroyRule>(
+ rule_name, game_module_idx, condition));
+
+ msg_print("Rule added. Please go to the Automatizer screen (press = then T)");
+ msg_print("to save the modified ruleset.");
+}
+
+void automatizer_add_rule(object_type *o_ptr)
+{
+ bool do_status = false;
+
+ while (true)
+ {
+ char ch;
+
+ if (!get_com(format("Destroy all of the same [T]ype, [F]amily or [N]ame, also use [S]tatus (%s)? ", (do_status) ? "Yes" : "No"), &ch))
+ {
+ break;
+ }
+
+ if (ch == 'S' || ch == 's')
+ {
+ do_status = !do_status;
+ continue;
+ }
+
+ if (ch == 'T' || ch == 't')
+ {
+ easy_add_rule(add_rule_mode::TSVAL, do_status, o_ptr);
+ break;
+ }
+
+ if (ch == 'F' || ch == 'f')
+ {
+ easy_add_rule(add_rule_mode::TVAL, do_status, o_ptr);
+ break;
+ }
+
+ if (ch == 'N' || ch == 'n')
+ {
+ easy_add_rule(add_rule_mode::NAME, do_status, o_ptr);
+ break;
+ }
+ }
+}
+
+/**
+ * Initialize the automatizer.
+ */
+void automatizer_init()
+{
+ // Only permit single initialization.
+ assert(automatizer == nullptr);
+
+ // Set up dependencies
+ auto tree_printer(std::make_shared<squelch::TreePrinter>());
+ auto cursor(std::make_shared<squelch::Cursor>());
+
+ // Initialize
+ automatizer = new squelch::Automatizer(tree_printer, cursor);
+}
+
+/**
+ * Load automatizer file. Returns true iff automatizer
+ * rules were loaded successfully.
+ */
+bool automatizer_load(boost::filesystem::path const &path)
+{
+ assert(automatizer != NULL);
+
+ // Does the path exist?
+ if (!boost::filesystem::exists(path))
+ {
+ return false; // Not fatal; just skip
+ }
+
+ // Parse file
+ json_error_t error;
+ std::shared_ptr<json_t> rules_json(
+ json_load_file(path.c_str(), 0, &error),
+ &json_decref);
+ if (rules_json == nullptr)
+ {
+ msg_format("Error parsing automatizer rules from '%s'.", path.c_str());
+ msg_format("Line %d, Column %d", error.line, error.column);
+ msg_print(nullptr);
+ return false;
+ }
+
+ // Load rules
+ automatizer->load_json(rules_json.get());
+ return true;
+}
diff --git a/src/squeltch.hpp b/src/squeltch.hpp
new file mode 100644
index 00000000..65ddfb51
--- /dev/null
+++ b/src/squeltch.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+#include <boost/filesystem.hpp>
+
+extern void squeltch_inventory(void);
+extern void squeltch_grid(void);
+extern void do_cmd_automatizer(void);
+extern void automatizer_add_rule(object_type *o_ptr);
+extern bool_ automatizer_create;
+extern void automatizer_init();
+extern bool automatizer_load(boost::filesystem::path const &path);
diff --git a/src/stairs_direction.hpp b/src/stairs_direction.hpp
new file mode 100644
index 00000000..b0b5f25d
--- /dev/null
+++ b/src/stairs_direction.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+typedef enum { STAIRS_UP, STAIRS_DOWN } stairs_direction;
diff --git a/src/stats.hpp b/src/stats.hpp
new file mode 100644
index 00000000..e682446c
--- /dev/null
+++ b/src/stats.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+/*
+ * Indexes of the various "stats" (hard-coded by savefiles, etc).
+ */
+#define A_STR 0
+#define A_INT 1
+#define A_WIS 2
+#define A_DEX 3
+#define A_CON 4
+#define A_CHR 5
diff --git a/src/status.c b/src/status.cc
index 967a8323..0a3977c7 100644
--- a/src/status.c
+++ b/src/status.cc
@@ -15,14 +15,24 @@
* there.
*/
-#include "angband.h"
-
-static void row_trival(char*, s16b, u32b, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
-static void row_bival(char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
-static void row_npval(char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
-static void statline(char*, int, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+#include "files.hpp"
+#include "monster2.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "player_type.hpp"
+#include "stats.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+
+static void row_trival(const char*, s16b, u32b, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+static void row_bival(const char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+static void row_npval(const char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+static void statline(const char*, int, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
static void row_hd_bon(int, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
-static void row_count(char*, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+static void row_count(const char*, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
static int row_x_start = 0;
static void status_count(s32b val1, int v1, s32b val2, int v2, s32b val3, int v3, s32b val4, int v4, byte ypos, byte xpos);
@@ -31,19 +41,19 @@ static void status_bival(s32b, byte, byte);
static void status_numeric(s32b, byte, byte);
static void status_curses(void);
static void status_companion(void);
-void status_sight(void);
-void status_attr(void);
-void status_combat(void);
-void status_main(void);
-void status_move(void);
-void status_item(void);
-void az_line(int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+static void status_sight(void);
+static void status_attr(void);
+static void status_combat(void);
+static void status_move(void);
+static void status_item(void);
+static void az_line(int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]);
+
#define STATNM_LENGTH 11
#define SL_LENGTH 11
#define INVEN_PLAYER (INVEN_TOTAL - INVEN_WIELD + 1)
-void status_attr(void)
+static void status_attr(void)
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
int yo = 0;
@@ -112,7 +122,7 @@ void status_move(void)
}
}
-void status_sight(void)
+static void status_sight(void)
/* Tell player about ESP, infravision, auto-id, see invis, and similar */
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
@@ -163,7 +173,7 @@ void status_sight(void)
}
}
-void status_item(void)
+static void status_item(void)
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
int yo = 3;
@@ -213,7 +223,7 @@ void status_item(void)
}
}
-void status_combat(void)
+static void status_combat(void)
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
int yo = 3;
@@ -272,7 +282,7 @@ void status_combat(void)
}
}
-void status_curses(void)
+static void status_curses(void)
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
int yo = 3;
@@ -298,7 +308,7 @@ void status_curses(void)
row_bival("Clone", 4, TR4_CLONE, yo++, flag_arr);
row_bival("Temp", 5, TR5_TEMPORARY, yo++, flag_arr);
yo++;
- row_count("Antimagic", 4, TR4_ANTIMAGIC_50, 5, 4, TR4_ANTIMAGIC_30, 3, 4, TR4_ANTIMAGIC_20, 2, 4, TR4_ANTIMAGIC_10, 1, yo++, flag_arr);
+ row_bival("Antimagic", 4, TR4_ANTIMAGIC_50, yo++, flag_arr);
c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0);
Term_fresh();
@@ -322,7 +332,7 @@ void status_curses(void)
}
}
-void status_res(void)
+static void status_res(void)
{
u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7];
int yo = 3;
@@ -373,7 +383,7 @@ void status_res(void)
}
}
-void status_main(void)
+void status_main()
{
int do_quit = 0;
char c;
@@ -430,11 +440,11 @@ void status_main(void)
}
Term_load();
character_icky = FALSE;
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
handle_stuff();
}
-void az_line(int xo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void az_line(int xo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
{
int index = xo; /* Leave room for description */
int i;
@@ -526,7 +536,7 @@ static void status_count(s32b val1, int v1, s32b val2, int v2, s32b val3, int v3
status_numeric(v, ypos, xpos);
}
-static void row_count(char* statname, s16b row1, u32b flag1, int v1, s16b row2, u32b flag2, int v2, s16b row3, u32b flag3, int v3, s16b row4, u32b flag4, int v4, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void row_count(const char* statname, s16b row1, u32b flag1, int v1, s16b row2, u32b flag2, int v2, s16b row3, u32b flag3, int v3, s16b row4, u32b flag4, int v4, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
{
int i;
int x = row_x_start;
@@ -543,7 +553,7 @@ static void row_count(char* statname, s16b row1, u32b flag1, int v1, s16b row2,
}
}
-static void row_trival(char* statname, s16b row, u32b flag, s16b row2, u32b flag2, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void row_trival(const char* statname, s16b row, u32b flag, s16b row2, u32b flag2, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
{
int i;
int x = row_x_start;
@@ -561,7 +571,7 @@ static void row_trival(char* statname, s16b row, u32b flag, s16b row2, u32b flag
}
}
-static void row_bival(char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void row_bival(const char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
{
int i;
int x = row_x_start;
@@ -576,7 +586,7 @@ static void row_bival(char* statname, s16b row, u32b flag, int yo, u32b flag_arr
}
}
-static void row_npval(char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void row_npval(const char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
/* Displays nicely a pval-based status row */
{
int i;
@@ -605,7 +615,7 @@ static void row_npval(char* statname, s16b row, u32b flag, int yo, u32b flag_arr
}
}
-static void statline(char* statname, int statidx, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
+static void statline(const char* statname, int statidx, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7])
/* Displays a status row for a primary stat */
{
int i;
@@ -742,7 +752,7 @@ static void status_companion(void)
fprintf(fff, "#####BCompanion: %s\n", m_name);
fprintf(fff, " Lev/Exp : [[[[[G%d / %ld]\n", m_ptr->level, (long int) m_ptr->exp);
- if (m_ptr->level < MONSTER_LEVEL_MAX) fprintf(fff, " Next lvl: [[[[[G%ld]\n", (long int) MONSTER_EXP((s32b)m_ptr->level + 1));
+ if (m_ptr->level < MONSTER_LEVEL_MAX) fprintf(fff, " Next lvl: [[[[[G%ld]\n", (long int) monster_exp(m_ptr->level + 1));
else fprintf(fff, " Next lvl: [[[[[G****]\n");
fprintf(fff, " HP : [[[[[G%ld / %ld]\n", (long int) m_ptr->hp, (long int) m_ptr->maxhp);
diff --git a/src/status.hpp b/src/status.hpp
new file mode 100644
index 00000000..74624446
--- /dev/null
+++ b/src/status.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+void status_main();
diff --git a/src/store.c b/src/store.cc
index ff5e89dc..8e9512cd 100644
--- a/src/store.c
+++ b/src/store.cc
@@ -1,7 +1,3 @@
-/* File: store.c */
-
-/* Purpose: Store commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,10 +6,40 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "spell_type.h"
-#include "quark.h"
+#include "store.hpp"
+
+#include "bldg.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd3.hpp"
+#include "cmd4.hpp"
+#include "cmd5.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "obj_theme.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "owner_type.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "spell_type.hpp"
+#include "skills.hpp"
+#include "spells5.hpp"
+#include "stats.hpp"
+#include "store_action_type.hpp"
+#include "store_type.hpp"
+#include "store_info_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+
+#include <cassert>
#define STORE_GENERAL_STORE "General Store"
#define STORE_ARMOURY "Armoury"
@@ -73,7 +99,7 @@ static void say_comment_1(void)
msg_print(comment_1[rand_int(MAX_COMMENT_1)]);
- if (randint(RUMOR_CHANCE) == 1 && speak_unique)
+ if (randint(RUMOR_CHANCE) == 1)
{
msg_print("The shopkeeper whispers something into your ear:");
get_rnd_line("rumors.txt", rumour);
@@ -281,6 +307,9 @@ static s32b price_item(object_type *o_ptr, int greed, bool_ flip)
/* Mega-Hack -- Black market sucks */
if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) price = price / 2;
+
+ /* No selling means you get no money */
+ if (no_selling) price = 0;
}
/* Shop is selling */
@@ -294,14 +323,14 @@ static s32b price_item(object_type *o_ptr, int greed, bool_ flip)
/* Mega-Hack -- Black market sucks */
if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) price = price * 2;
+
+ /* Never give items away for free */
+ if (price <= 0L) price = 1L;
}
/* Compute the final price (with rounding) */
price = (price * adjust + 50L) / 100L;
- /* Note -- Never become "free" */
- if (price <= 0L) return (1L);
-
/* Return the price */
return (price);
}
@@ -593,7 +622,7 @@ static bool_ store_check_num(object_type *o_ptr)
}
-bool_ is_blessed(object_type *o_ptr)
+static bool_ is_blessed(object_type const *o_ptr)
{
u32b f1, f2, f3, f4, f5, esp;
object_flags_known(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -608,17 +637,26 @@ bool_ is_blessed(object_type *o_ptr)
*
* Note that a shop-keeper must refuse to buy "worthless" items
*/
-static bool_ store_will_buy(object_type *o_ptr)
+static bool store_will_buy(object_type const *o_ptr)
{
- cptr store_name = st_info[st_ptr->st_idx].name + st_name;
+ cptr store_name = st_info[st_ptr->st_idx].name;
/* Hack -- The Home is simple */
- if (cur_store_num == 7) return (TRUE);
+ if (cur_store_num == 7)
+ {
+ return true;
+ }
- if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) return TRUE;
+ if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM)
+ {
+ return true;
+ }
/* XXX XXX XXX Ignore "worthless" items */
- if (object_value(o_ptr) <= 0) return (FALSE);
+ if (object_value(o_ptr) <= 0)
+ {
+ return false;
+ }
/* What do stores buy? */
if (streq(store_name, STORE_GENERAL_STORE))
@@ -636,7 +674,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_DIGGING:
case TV_CLOAK:
case TV_BOTTLE:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_ARMOURY))
@@ -652,7 +690,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_SOFT_ARMOR:
case TV_HARD_ARMOR:
case TV_DRAG_ARMOR:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_WEAPONSMITH))
@@ -670,7 +708,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_SWORD:
case TV_AXE:
case TV_MSTAFF:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_TEMPLE))
@@ -682,34 +720,34 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION2:
case TV_POTION:
case TV_HAFTED:
- return TRUE;
+ return true;
}
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
(spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_SPIRITUALITY))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_POLEARM) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_SWORD) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_AXE) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_BOOMERANG) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_ALCHEMY))
@@ -721,7 +759,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION:
case TV_BATERIE:
case TV_BOTTLE:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_MAGIC))
@@ -740,24 +778,24 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION:
case TV_MSTAFF:
case TV_RANDART:
- return TRUE;
+ return true;
}
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
(spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_MAGIC))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval != BOOK_RANDOM))
{
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_BLACK_MARKET))
{
- return TRUE;
+ return true;
}
else if (streq(store_name, STORE_BOOKS))
{
@@ -768,7 +806,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_MUSIC_BOOK:
case TV_DAEMON_BOOK:
case TV_DRUID_BOOK:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_PETS))
@@ -786,7 +824,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_ARROW:
case TV_BOW:
case TV_POTION2:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_RUNIC_MAGIC))
@@ -795,7 +833,7 @@ static bool_ store_will_buy(object_type *o_ptr)
{
case TV_RUNE1:
case TV_RUNE2:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_CONSTRUCTION_SUPPLIES))
@@ -804,7 +842,7 @@ static bool_ store_will_buy(object_type *o_ptr)
{
case TV_LITE:
case TV_DIGGING:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_MUSIC))
@@ -813,7 +851,7 @@ static bool_ store_will_buy(object_type *o_ptr)
}
/* Assume not okay */
- return (FALSE);
+ return false;
}
@@ -1213,16 +1251,9 @@ static void store_create(void)
{
obj_all_done = FALSE;
- /* Lua can define things to buy */
- if (process_hooks_ret(HOOK_STORE_STOCK, "O", "(d,s,d)", st_ptr->st_idx, st_info[st_ptr->st_idx].name + st_name, return_level()))
- {
- obj_all_done = TRUE;
- q_ptr = process_hooks_return[0].o_ptr;
- }
-
/* Magic Shop */
- else if (streq(st_info[st_ptr->st_idx].name + st_name, STORE_MAGIC) &&
- magik(20))
+ if (streq(st_info[st_ptr->st_idx].name, STORE_MAGIC) &&
+ magik(20))
{
s16b spell;
@@ -1237,7 +1268,7 @@ static void store_create(void)
}
/* Temple */
- else if (streq(st_info[st_ptr->st_idx].name + st_name, STORE_TEMPLE) &&
+ else if (streq(st_info[st_ptr->st_idx].name, STORE_TEMPLE) &&
magik(20))
{
s16b spell;
@@ -1450,12 +1481,6 @@ static void display_entry(int pos)
if (!o_ptr->k_idx) c = ' ';
Term_draw(cur_col, i + 6, a, c);
- if (use_bigtile)
- {
- cur_col++;
- if (a & 0x80)
- Term_draw(cur_col, i + 6, 255, 255);
- }
cur_col += 2;
}
@@ -1513,7 +1538,7 @@ static void display_entry(int pos)
if (x > p_ptr->au) color = TERM_L_DARK;
/* Actually draw the price */
- strnfmt(out_val, 160, "%9ld ", (long)x);
+ strnfmt(out_val, 160, "%9ld ", static_cast<long>(x));
c_put_str(color, out_val, i + 6, 68);
}
}
@@ -1564,7 +1589,7 @@ void store_prt_gold(void)
prt("Gold Remaining: ", 19, 53);
- strnfmt(out_val, 64, "%9ld", (long)p_ptr->au);
+ strnfmt(out_val, 64, "%9ld", static_cast<long>(p_ptr->au));
prt(out_val, 19, 68);
}
@@ -1594,10 +1619,8 @@ void display_store(void)
else if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM)
{
- cptr store_name = (st_name + st_info[cur_store_num].name);
-
/* Show the name of the store */
- strnfmt(buf, 80, "%s", store_name);
+ strnfmt(buf, 80, "%s", st_info[cur_store_num].name);
prt(buf, 3, 30);
/* Label the item descriptions */
@@ -1610,15 +1633,14 @@ void display_store(void)
/* Normal stores */
else
{
- cptr store_name = (st_name + st_info[cur_store_num].name);
- cptr owner_name = (ow_name + ot_ptr->name);
-
/* Put the owner name and race */
- strnfmt(buf, 80, "%s", owner_name);
+ strnfmt(buf, 80, "%s", ot_ptr->name);
put_str(buf, 3, 10);
/* Show the max price in the store (above prices) */
- strnfmt(buf, 80, "%s (%ld)", store_name, (long)(ot_ptr->max_cost));
+ strnfmt(buf, 80, "%s (" FMTs16b ")",
+ st_info[cur_store_num].name,
+ ot_ptr->max_cost);
prt(buf, 3, 50);
/* Label the item descriptions */
@@ -1831,8 +1853,8 @@ static bool_ sell_haggle(object_type *o_ptr, s32b *price)
/* Sell the whole pile */
cur_ask *= o_ptr->number;
- /* Describe the object (fully) */
- object_desc_store(o_name, o_ptr, TRUE, 3);
+ /* Describe the object */
+ object_desc(o_name, o_ptr, TRUE, 3);
/* Prompt */
strnfmt(out_val, sizeof(out_val), "%s: " FMTs32b, "Price", cur_ask);
@@ -2190,7 +2212,7 @@ void store_purchase(void)
}
else
{
- q = p_ptr->au / (best + (best / 10));
+ q = p_ptr->au / best;
}
if (o_ptr->number < q)
q = o_ptr->number;
@@ -2272,7 +2294,7 @@ void store_purchase(void)
object_desc(o_name, j_ptr, TRUE, 3);
/* Message */
- msg_format("You bought %s for %ld gold.", o_name, (long)price);
+ msg_format("You bought %s for " FMTs32b " gold.", o_name, price);
/* Erase the inscription */
j_ptr->note = 0;
@@ -2432,36 +2454,35 @@ void store_sell(void)
object_type *o_ptr;
- cptr q, s;
-
char o_name[80];
u32b f1, f2, f3, f4, f5, esp;
bool_ museum = (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) ? TRUE : FALSE;
- /* Prepare a prompt */
- if (cur_store_num == 7) q = "Drop which item? ";
- else if (museum) q = "Donate which item?";
- else q = "Sell which item? ";
-
- /* Only allow items the store will buy */
- item_tester_hook = store_will_buy;
-
- /* Get an item */
+ /* Prepare prompt */
+ cptr q, s;
if (cur_store_num == STORE_HOME)
{
+ q = "Drop which item? ";
s = "You have nothing to drop.";
}
else if (museum)
{
+ q = "Donate which item?";
s = "You have nothing to donate.";
}
else
{
+ q = "Sell which item? ";
s = "You have nothing that I want.";
}
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+
+ /* Get an item */
+ if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN), store_will_buy))
+ {
+ return;
+ }
/* Get the item */
o_ptr = get_object(item);
@@ -2604,7 +2625,7 @@ void store_sell(void)
object_desc(o_name, q_ptr, TRUE, 3);
/* Describe the result (in message buffer) */
- msg_format("You sold %s for %ld gold.", o_name, (long)price);
+ msg_format("You sold %s for " FMTs32b " gold.", o_name, price);
/* Analyze the prices (and comment verbally) */
purchase_analyze(price, value, dummy);
@@ -3026,13 +3047,6 @@ static bool_ store_process_command(void)
/*** System Commands ***/
- /* Hack -- User interface */
- case '!':
- {
- (void)Term_user(0);
- break;
- }
-
/* Single line from a pref file */
case '"':
{
@@ -3409,7 +3423,7 @@ void do_cmd_store(void)
p_ptr->update |= (PU_MONSTERS);
/* Redraw entire screen */
- p_ptr->redraw |= (PR_BASIC | PR_EXTRA);
+ p_ptr->redraw |= (PR_FRAME);
/* Redraw map */
p_ptr->redraw |= (PR_MAP);
@@ -3601,14 +3615,6 @@ void store_init(int town_num, int store_num)
}
-void move_to_black_market(object_type * o_ptr)
-{
- st_ptr = &town_info[p_ptr->town_num].store[6];
- o_ptr->ident |= IDENT_STOREB;
- (void)store_carry(o_ptr);
- object_wipe(o_ptr); /* Don't leave a bogus object behind... */
-}
-
/*
* Enter the home, and interact with it from the dungeon (trump magic).
*
@@ -3862,7 +3868,7 @@ void do_cmd_home_trump(void)
p_ptr->update |= (PU_MONSTERS);
/* Redraw entire screen */
- p_ptr->redraw |= (PR_BASIC | PR_EXTRA);
+ p_ptr->redraw |= (PR_FRAME);
/* Redraw map */
p_ptr->redraw |= (PR_MAP);
@@ -3870,65 +3876,3 @@ void do_cmd_home_trump(void)
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
}
-
-static void pay_for_requested_item(int value, object_type *q_ptr)
-{
- msg_format("It'll cost %i gold pieces. ", value);
-
- if (get_check("Do you wish to pay?"))
- {
- if (p_ptr->au < value)
- msg_print("You don't have enough money for it.");
- else
- {
- if (store_carry(q_ptr) != -1)
- {
- msg_print("The item has arrived in the Black Market.");
- p_ptr->au -= value;
-
- p_ptr->redraw |= PR_GOLD;
- }
- else
- msg_print("There isn't enough room for it.");
- }
- }
-}
-
-/*
- * Request item for merchants
- */
-void store_request_item(void)
-{
- char buf[80], name[80];
- object_type forge, *q_ptr = &forge;
- store_type *ost_ptr = st_ptr;
-
- /* Get the Black Market */
- st_ptr = &town_info[p_ptr->town_num].store[6];
-
- /* Make an empty string */
- buf[0] = 0;
-
- /* Ask for the wish */
- if (!get_string("Request what? ", buf, 80))
- {
- st_ptr = ost_ptr;
- return;
- }
-
- clean_wish_name(buf, name);
-
- if (test_object_wish(name, q_ptr, &forge, "request"))
- {
- int value = object_value_real(q_ptr) * 5;
-
- /* Pay for the delivery */
- pay_for_requested_item(value, q_ptr);
-
- /* Don't search any more */
- st_ptr = ost_ptr;
- return;
- }
-
- st_ptr = ost_ptr;
-}
diff --git a/src/store.hpp b/src/store.hpp
new file mode 100644
index 00000000..f67d94eb
--- /dev/null
+++ b/src/store.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+extern void do_cmd_store();
+extern void store_shuffle(int which);
+extern void store_maint(int town_num, int store_num);
+extern void store_init(int town_num, int store_num);
+extern void do_cmd_home_trump();
+extern void store_sell();
+extern void store_purchase();
+extern void store_examine();
+extern void store_stole();
+extern void store_prt_gold();
diff --git a/src/store_action_type.hpp b/src/store_action_type.hpp
new file mode 100644
index 00000000..048e13a0
--- /dev/null
+++ b/src/store_action_type.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Store/building actions.
+ */
+struct store_action_type
+{
+ const char *name; /* Name */
+
+ s16b costs[3]; /* Costs for liked people */
+ char letter; /* Action letter */
+ char letter_aux; /* Action letter */
+ s16b action; /* Action code */
+ s16b action_restr; /* Action restriction */
+};
diff --git a/src/store_action_type_fwd.hpp b/src/store_action_type_fwd.hpp
new file mode 100644
index 00000000..e1746dad
--- /dev/null
+++ b/src/store_action_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct store_action_type;
diff --git a/src/store_info_type.hpp b/src/store_info_type.hpp
new file mode 100644
index 00000000..030afe91
--- /dev/null
+++ b/src/store_info_type.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Number of items to choose stock from
+ */
+constexpr int STORE_CHOICES = 56;
+
+/**
+ * Store descriptor.
+ */
+struct store_info_type
+{
+ const char *name; /* Name */
+
+ s16b table[STORE_CHOICES][2]; /* Table -- Legal item kinds */
+ byte table_num; /* Number of items */
+ s16b max_obj; /* Number of items this store can hold */
+
+ u16b owners[4]; /* List of owners(refers to ow_info) */
+
+ u16b actions[6]; /* Actions(refers to ba_info) */
+
+ byte d_attr; /* Default building attribute */
+ char d_char; /* Default building character */
+
+ byte x_attr; /* Desired building attribute */
+ char x_char; /* Desired building character */
+
+ u32b flags1; /* Flags */
+};
diff --git a/src/store_info_type_fwd.hpp b/src/store_info_type_fwd.hpp
new file mode 100644
index 00000000..a0dace90
--- /dev/null
+++ b/src/store_info_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct store_info_type;
diff --git a/src/store_type.hpp b/src/store_type.hpp
new file mode 100644
index 00000000..e3f917ac
--- /dev/null
+++ b/src/store_type.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type.hpp"
+
+/**
+ * A store, with an owner, various state flags, a current stock
+ * of items, and a table of items that are often purchased.
+ */
+struct store_type
+{
+ u16b st_idx;
+
+ /**
+ * Owner index
+ */
+ u16b owner;
+
+ /**
+ * Closed until this turn.
+ */
+ s32b store_open;
+
+ /**
+ * Last visited on this turn.
+ */
+ s32b last_visit;
+
+ /**
+ * Stock: Number of entries.
+ */
+ byte stock_num;
+
+ /**
+ * Stock: Total size of array
+ */
+ s16b stock_size;
+
+ /**
+ * Stock: Actual stock items
+ */
+ object_type *stock;
+};
diff --git a/src/store_type_fwd.hpp b/src/store_type_fwd.hpp
new file mode 100644
index 00000000..15410563
--- /dev/null
+++ b/src/store_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct store_type;
diff --git a/src/string_list.c b/src/string_list.c
deleted file mode 100644
index 8a63cc3c..00000000
--- a/src/string_list.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "angband.h"
-
-int compare_string_list(string_list *a, string_list *b)
-{
- if (a == b)
- {
- return 0;
- }
-
- return strcmp(a->s, b->s);
-}
-
-SGLIB_DEFINE_LIST_FUNCTIONS(string_list, compare_string_list, next);
-
-/*
- * Initialize a string_list value. Copies the input string.
- */
-void string_list_init(string_list *sl, cptr s)
-{
- assert(sl != NULL);
-
- sl->s = string_make(s);
- sl->next = NULL;
-}
-
-/*
- * Destroy string_value.
- */
-void string_list_destroy(string_list *sl)
-{
- assert(sl != NULL);
-
- /* Free contained string */
- if (sl->s) {
- string_free(sl->s);
- sl->s = NULL;
- }
-
- /* We do NOT free the rest of the list. */
- sl->next = NULL;
-}
-
-/**
- * Append a string to a string_list.
- */
-void string_list_append(string_list **slist, cptr s)
-{
- string_list *e = malloc(sizeof(string_list));
- string_list_init(e, s);
-
- sglib_string_list_add(slist, e);
-}
diff --git a/src/tables.c b/src/tables.cc
index 1d5f1c49..42244d6c 100644
--- a/src/tables.c
+++ b/src/tables.cc
@@ -1,7 +1,3 @@
-/* File: tables.c */
-
-/* Purpose: Angband Tables */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,8 +6,40 @@
* included in all such copies.
*/
-#include "angband.h"
-
+#include "tables.hpp"
+#include "tables.h"
+
+#include "modules.hpp"
+#include "options.hpp"
+#include "q_library.hpp"
+#include "q_fireprof.hpp"
+#include "q_bounty.hpp"
+#include "q_thrain.hpp"
+#include "q_narsil.hpp"
+#include "q_evil.hpp"
+#include "q_betwen.hpp"
+#include "q_haunted.hpp"
+#include "q_invas.hpp"
+#include "q_nirna.hpp"
+#include "q_eol.hpp"
+#include "q_god.hpp"
+#include "q_dragons.hpp"
+#include "q_poison.hpp"
+#include "q_spider.hpp"
+#include "q_wolves.hpp"
+#include "q_shroom.hpp"
+#include "q_nazgul.hpp"
+#include "q_wight.hpp"
+#include "q_troll.hpp"
+#include "q_hobbit.hpp"
+#include "q_thief.hpp"
+#include "q_ultrae.hpp"
+#include "q_ultrag.hpp"
+#include "q_one.hpp"
+#include "q_main.hpp"
+#include "q_rand.hpp"
+#include "stats.hpp"
+#include "variable.hpp"
@@ -53,52 +81,6 @@ char hexsym[16] =
/*
- * Stat Table (INT/WIS) -- Number of half-spells per level
- */
-byte adj_mag_study[] =
-{
- 0 /* 3 */,
- 0 /* 4 */,
- 0 /* 5 */,
- 0 /* 6 */,
- 0 /* 7 */,
- 1 /* 8 */,
- 1 /* 9 */,
- 1 /* 10 */,
- 1 /* 11 */,
- 2 /* 12 */,
- 2 /* 13 */,
- 2 /* 14 */,
- 2 /* 15 */,
- 2 /* 16 */,
- 2 /* 17 */,
- 2 /* 18/00-18/09 */,
- 2 /* 18/10-18/19 */,
- 2 /* 18/20-18/29 */,
- 2 /* 18/30-18/39 */,
- 2 /* 18/40-18/49 */,
- 3 /* 18/50-18/59 */,
- 3 /* 18/60-18/69 */,
- 3 /* 18/70-18/79 */,
- 3 /* 18/80-18/89 */,
- 4 /* 18/90-18/99 */,
- 4 /* 18/100-18/109 */,
- 4 /* 18/110-18/119 */,
- 5 /* 18/120-18/129 */,
- 5 /* 18/130-18/139 */,
- 5 /* 18/140-18/149 */,
- 5 /* 18/150-18/159 */,
- 5 /* 18/160-18/169 */,
- 5 /* 18/170-18/179 */,
- 5 /* 18/180-18/189 */,
- 5 /* 18/190-18/199 */,
- 5 /* 18/200-18/209 */,
- 6 /* 18/210-18/219 */,
- 6 /* 18/220+ */
-};
-
-
-/*
* Stat Table (INT/WIS) -- extra half-mana-points per level
*/
byte adj_mag_mana[] =
@@ -283,52 +265,6 @@ byte adj_chr_gold[] =
/*
- * Stat Table (INT) -- Magic devices
- */
-byte adj_int_dev[] =
-{
- 0 /* 3 */,
- 0 /* 4 */,
- 0 /* 5 */,
- 0 /* 6 */,
- 0 /* 7 */,
- 1 /* 8 */,
- 1 /* 9 */,
- 1 /* 10 */,
- 1 /* 11 */,
- 1 /* 12 */,
- 1 /* 13 */,
- 1 /* 14 */,
- 2 /* 15 */,
- 2 /* 16 */,
- 2 /* 17 */,
- 3 /* 18/00-18/09 */,
- 3 /* 18/10-18/19 */,
- 4 /* 18/20-18/29 */,
- 4 /* 18/30-18/39 */,
- 5 /* 18/40-18/49 */,
- 5 /* 18/50-18/59 */,
- 6 /* 18/60-18/69 */,
- 6 /* 18/70-18/79 */,
- 7 /* 18/80-18/89 */,
- 7 /* 18/90-18/99 */,
- 8 /* 18/100-18/109 */,
- 9 /* 18/110-18/119 */,
- 10 /* 18/120-18/129 */,
- 11 /* 18/130-18/139 */,
- 12 /* 18/140-18/149 */,
- 13 /* 18/150-18/159 */,
- 14 /* 18/160-18/169 */,
- 15 /* 18/170-18/179 */,
- 16 /* 18/180-18/189 */,
- 17 /* 18/190-18/199 */,
- 18 /* 18/200-18/209 */,
- 19 /* 18/210-18/219 */,
- 20 /* 18/220+ */
-};
-
-
-/*
* Stat Table (WIS) -- Saving throw
*/
byte adj_wis_sav[] =
@@ -1088,15 +1024,6 @@ byte blows_table[12][12] =
};
-s16b arena_monsters[MAX_ARENA_MONS] =
-{
- 30, 43, 102, 118, 126, 149, 173,
- 183, 188, 191, 216, 230, 238, 244,
- 255, 262, 293, 297, 321, 349, 372,
- 401, 415, 454, 464, 485, 538, 631,
- 641
-};
-
/*
* This table allows quick conversion from "speed" to "energy"
@@ -1364,21 +1291,9 @@ option_type option_info[] =
{ &always_pickup, FALSE, 1, 5,
"always_pickup", "Pick things up by default" },
- { &prompt_pickup_heavy, TRUE, 1, 6,
- "prompt_pickup_heavy", "Prompt before picking up heavy objects" },
-
{ &always_repeat, TRUE, 1, 7,
"always_repeat", "Repeat obvious commands" },
- { &depth_in_feet, FALSE, 1, 8,
- "depth_in_feet", "Show dungeon level in feet" },
-
- { &stack_force_notes, TRUE, 1, 9,
- "stack_force_notes", "Merge inscriptions when stacking" },
-
- { &stack_force_costs, FALSE, 1, 10,
- "stack_force_costs", "Merge discounts when stacking" },
-
{ &ring_bell, FALSE, 1, 18,
"ring_bell", "Audible bell (on errors, etc)" },
/* Changed to default to FALSE -- it's so extremely annoying!!! -TY */
@@ -1427,12 +1342,6 @@ option_type option_info[] =
{ &last_words, TRUE, 2, 12,
"last_words", "Get last words when the character dies" },
- { &speak_unique, TRUE, 2, 13,
- "speak_unique", "Allow shopkeepers and uniques to speak" },
-
- { &auto_destroy, TRUE, 2, 14,
- "auto_destroy", "No query to destroy known worthless items" },
-
{ &wear_confirm, TRUE, 2, 15,
"confirm_wear", "Confirm to wear/wield known cursed items" },
@@ -1442,41 +1351,17 @@ option_type option_info[] =
{ &disturb_pets, FALSE, 2, 17,
"disturb_pets", "Disturb when visible pets move" },
- { &easy_open, TRUE, 2, 18,
- "easy_open", "Automatically open doors" },
-
- { &easy_disarm, TRUE, 2, 19,
- "easy_disarm", "Automatically disarm traps" },
-
- { &easy_tunnel, FALSE, 2, 20,
- "easy_tunnel", "Automatically tunnel walls" },
-
/*** Game-Play ***/
{ &auto_scum, TRUE, 3, 1,
"auto_scum", "Auto-scum for good levels" },
- { &stack_allow_items, TRUE, 3, 2,
- "stack_allow_items", "Allow weapons and armour to stack" },
-
- { &stack_allow_wands, TRUE, 3, 3,
- "stack_allow_wands", "Allow wands/staffs/rods to stack" },
-
- { &expand_look, FALSE, 3, 4,
- "expand_look", "Expand the power of the look command" },
-
- { &expand_list, FALSE, 3, 5,
- "expand_list", "Expand the power of the list commands" },
-
{ &view_perma_grids, TRUE, 3, 6,
"view_perma_grids", "Map remembers all perma-lit grids" },
{ &view_torch_grids, FALSE, 3, 7,
"view_torch_grids", "Map remembers all torch-lit grids" },
- { &monster_lite, TRUE, 3, 19,
- "monster_lite", "Allow some monsters to carry light" },
-
{ &dungeon_align, TRUE, 3, 8,
"dungeon_align", "Generate dungeons with aligned rooms" },
@@ -1486,18 +1371,9 @@ option_type option_info[] =
{ &flow_by_sound, FALSE, 3, 10,
"flow_by_sound", "Monsters chase current location (v.slow)" },
- { &player_symbols, FALSE, 3, 12,
- "player_symbols", "Use special symbols for the player char"},
-
- { &plain_descriptions, TRUE, 3, 13,
- "plain_descriptions", "Plain object descriptions" },
-
{ &smart_learn, FALSE, 3, 14,
"smart_learn", "Monsters learn from their mistakes" },
- { &smart_cheat, FALSE, 3, 15,
- "smart_cheat", "Monsters exploit players weaknesses" },
-
{ &small_levels, TRUE, 3, 17,
"small_levels", "Allow unusually small dungeon levels" },
@@ -1509,9 +1385,6 @@ option_type option_info[] =
{ &view_reduce_lite, FALSE, 4, 0,
"view_reduce_lite", "Reduce lite-radius when running" },
- { &view_reduce_view, FALSE, 4, 1,
- "view_reduce_view", "Reduce view-radius in town" },
-
{ &avoid_abort, FALSE, 4, 2,
"avoid_abort", "Avoid checking for user abort" },
@@ -1562,9 +1435,6 @@ option_type option_info[] =
{ &option_ingame_help, TRUE, 5, 1,
"ingame_help", "Ingame contextual help" },
- { &exp_need, FALSE, 5, 2,
- "exp_need", "Show the experience needed for next level" },
-
{ &auto_more, FALSE, 5, 4,
"auto_more", "Automatically clear '-more-' prompts" },
@@ -1580,9 +1450,6 @@ option_type option_info[] =
/*** Birth Options ***/
- { &maximize, TRUE, 6, 1,
- "maximize", "Maximise stats" },
-
{ &preserve, TRUE, 6, 2,
"preserve", "Preserve artifacts" },
@@ -1598,24 +1465,14 @@ option_type option_info[] =
{ &joke_monsters, FALSE, 6, 14,
"joke_monsters", "Allow use of some 'joke' monsters" },
- /* XXX */
-
{ &always_small_level, FALSE, 6, 16,
"always_small_level", "Always make small levels" },
{ &fate_option, TRUE, 6, 18,
"fate_option", "You can receive fates, good or bad" },
-
- /* XXX 17 is used BEFORE */
-
- /*** Stacking ***/
-
- { &testing_stack, TRUE, 7, 0,
- "testing_stack", "Allow objects to stack on floor" },
-
- { &testing_carry, TRUE, 7, 1,
- "testing_carry", "Allow monsters to carry objects" },
-
+
+ { &no_selling, FALSE, 6, 20,
+ "no_selling", "Items always sell for 0 gold" },
/*** End of Table ***/
@@ -2346,9 +2203,9 @@ magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS] =
"Telekinetic Wave",
"Powerful wave of pure telekinetic forces."
},
- };
+};
- magic_power necro_powers[MAX_NECRO_POWERS] =
+magic_power necro_powers[MAX_NECRO_POWERS] =
{
/* Level gained, cost, %fail, name, desc */
{
@@ -2476,43 +2333,6 @@ magic_power symbiotic_powers[MAX_SYMBIOTIC_POWERS] =
/*
- * Textual translation of your god's "niceness".
- */
-
-cptr deity_niceness[10] =
-{
- "a lovable deity",
- "a friendly deity",
- "an easygoing deity",
- "a forgiving deity",
- "an uncaring deity",
- "a wary deity",
- "an unforgiving deity",
- "an impatient deity",
- "a wrathful deity",
- "an easily angered deity"
-};
-
-/*
- * Textual translation of your standing with your god.
- */
-
-cptr deity_standing[11] =
-{
- "cursed",
- "persecuted",
- "punished",
- "despised",
- "disliked",
- "watched",
- "unnoticed",
- "noticed",
- "rewarded",
- "favored",
- "championed"
-};
-
-/*
* Name and description (max. 10 lines) of the gods.
* Only the first four lines are printed at birth.
*/
@@ -2603,8 +2423,7 @@ deity_type deity_info[MAX_GODS] =
{ MODULE_TOME, MODULE_THEME, -1, },
"Yavanna Kementari",
{
- "She is the Vala of nature, protectress of the great forests of "
- "Middle-earth.",
+ "She is the Vala of nature, protectress of the great forests of Middle-earth.",
"",
"",
"",
@@ -2652,8 +2471,7 @@ deity_type deity_info[MAX_GODS] =
{ MODULE_THEME, -1, },
"Ulmo",
{
- "Ulmo is called Lord of Waters, he rules all that is water"
- "on Arda.",
+ "Ulmo is called Lord of Waters, he rules all that is water on Arda.",
"",
"",
"",
@@ -2977,7 +2795,7 @@ flags_group flags_groups[MAX_FLAG_GROUP] =
TR1_VAMPIRIC | TR1_CHAOTIC | TR1_BLOWS | TR1_SPEED,
TR2_LIFE | TR2_REFLECT | TR2_FREE_ACT | TR2_HOLD_LIFE,
TR3_NO_MAGIC | TR3_NO_TELE | TR3_SEE_INVIS,
- TR4_ANTIMAGIC_10 | TR4_ANTIMAGIC_20,
+ TR4_ANTIMAGIC_50,
0,
},
};
@@ -3385,10 +3203,12 @@ power_type powers_type[POWER_MAX] =
1, 1, A_DEX, 1,
},
{
- "Merchant abilities",
- "You can request items and get loans.",
- "From now on you can use the merchant abilities.",
- "You can no longer use the merchant abilities.",
+ "notused", /* Merchant abilities; no longer used, but want to
+ * avoid having to move all potential places where
+ * we're indexing into this table. */
+ "notused",
+ "notused",
+ "notused",
0, 0, 0, 0,
},
{
@@ -3466,7 +3286,7 @@ quest_type quest[MAX_Q_IDX] =
0,
NULL,
- quest_null_hook,
+ NULL,
{0, 0},
NULL,
},
diff --git a/src/tables.h b/src/tables.h
new file mode 100644
index 00000000..9a5cfb58
--- /dev/null
+++ b/src/tables.h
@@ -0,0 +1,12 @@
+#pragma once
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char hexsym[16];
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/tables.hpp b/src/tables.hpp
new file mode 100644
index 00000000..4a3e33d6
--- /dev/null
+++ b/src/tables.hpp
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "angband.h"
+#include "activation.hpp"
+#include "between_exit.hpp"
+#include "body.hpp"
+#include "cli_comm_fwd.hpp"
+#include "flags_group.hpp"
+#include "gf_name_type.hpp"
+#include "inscription_info_type.hpp"
+#include "magic_power.hpp"
+#include "martial_arts.hpp"
+#include "module_type.hpp"
+#include "monster_power.hpp"
+#include "move_info_type.hpp"
+#include "option_type.hpp"
+#include "player_defs.hpp"
+#include "player_sex.hpp"
+#include "power_type.hpp"
+#include "powers.hpp"
+#include "quest_type.hpp"
+#include "tactic_info_type.hpp"
+#include "tval_desc.hpp"
+
+extern s16b ddd[9];
+extern s16b ddx[10];
+extern s16b ddy[10];
+extern s16b ddx_ddd[9];
+extern s16b ddy_ddd[9];
+extern byte adj_mag_mana[];
+extern byte adj_mag_fail[];
+extern byte adj_mag_stat[];
+extern byte adj_chr_gold[];
+extern byte adj_wis_sav[];
+extern byte adj_dex_dis[];
+extern byte adj_int_dis[];
+extern byte adj_dex_ta[];
+extern byte adj_str_td[];
+extern byte adj_dex_th[];
+extern byte adj_str_th[];
+extern byte adj_str_wgt[];
+extern byte adj_str_hold[];
+extern byte adj_str_dig[];
+extern byte adj_str_blow[];
+extern byte adj_dex_blow[];
+extern byte adj_dex_safe[];
+extern byte adj_con_fix[];
+extern byte adj_con_mhp[];
+extern byte blows_table[12][12];
+extern byte extract_energy[300];
+extern s32b player_exp[PY_MAX_LEVEL];
+extern player_sex sex_info[MAX_SEXES];
+extern cptr color_names[16];
+extern cptr stat_names[6];
+extern cptr stat_names_reduced[6];
+extern cptr window_flag_desc[32];
+extern option_type option_info[];
+extern martial_arts bear_blows[MAX_BEAR];
+extern martial_arts ma_blows[MAX_MA];
+extern magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS];
+extern magic_power necro_powers[MAX_NECRO_POWERS];
+extern magic_power mimic_powers[MAX_MIMIC_POWERS];
+extern magic_power symbiotic_powers[MAX_SYMBIOTIC_POWERS];
+extern move_info_type move_info[9];
+extern tactic_info_type tactic_info[9];
+extern activation activation_info[MAX_T_ACT];
+extern inscription_info_type inscription_info[MAX_INSCRIPTIONS];
+extern cptr sense_desc[];
+extern flags_group flags_groups[MAX_FLAG_GROUP];
+extern power_type powers_type[POWER_MAX];
+extern cptr artifact_names_list;
+extern monster_power monster_powers[96];
+extern tval_desc tval_descs[];
+extern between_exit between_exits[MAX_BETWEEN_EXITS];
+extern int month_day[9];
+extern cptr month_name[9];
+extern cli_comm *cli_info;
+extern int cli_total;
+extern quest_type quest[MAX_Q_IDX];
+extern int max_body_part[BODY_MAX];
+extern gf_name_type gf_names[];
+extern module_type modules[MAX_MODULES];
diff --git a/src/tactic_info_type.hpp b/src/tactic_info_type.hpp
new file mode 100644
index 00000000..da94767d
--- /dev/null
+++ b/src/tactic_info_type.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Tactics descriptor.
+ */
+struct tactic_info_type
+{
+ s16b to_hit;
+ s16b to_dam;
+ s16b to_ac;
+ s16b to_stealth;
+ s16b to_disarm;
+ s16b to_saving;
+ cptr name;
+};
diff --git a/src/terrain.hpp b/src/terrain.hpp
new file mode 100644
index 00000000..118a877a
--- /dev/null
+++ b/src/terrain.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+/*
+ * Wilderness terrains
+ */
+#define TERRAIN_EDGE 0 /* Edge of the World */
+#define TERRAIN_TOWN 1 /* Town */
+#define TERRAIN_DEEP_WATER 2 /* Deep water */
+#define TERRAIN_SHALLOW_WATER 3 /* Shallow water */
+#define TERRAIN_SWAMP 4 /* Swamp */
+#define TERRAIN_DIRT 5 /* Dirt */
+#define TERRAIN_GRASS 6 /* Grass */
+#define TERRAIN_TREES 7 /* Trees */
+#define TERRAIN_DESERT 8 /* Desert */
+#define TERRAIN_SHALLOW_LAVA 9 /* Shallow lava */
+#define TERRAIN_DEEP_LAVA 10 /* Deep lava */
+#define TERRAIN_MOUNTAIN 11 /* Mountain */
+
+#define MAX_WILD_TERRAIN 18
diff --git a/src/timer_type.hpp b/src/timer_type.hpp
new file mode 100644
index 00000000..0ce6b095
--- /dev/null
+++ b/src/timer_type.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "h-basic.h"
+
+/*
+ * Timer descriptor and runtime data.
+ */
+struct timer_type
+{
+ timer_type *next; /* The next timer in the list */
+
+ bool_ enabled; /* Is it currently counting? */
+
+ s32b delay; /* Delay between activations */
+ s32b countdown; /* The current number of turns passed, when it reaches delay it fires */
+
+ void (*callback)(); /* The C function to call upon firing */
+};
diff --git a/src/timer_type_fwd.hpp b/src/timer_type_fwd.hpp
new file mode 100644
index 00000000..bda03716
--- /dev/null
+++ b/src/timer_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct timer_type;
diff --git a/src/town_type.hpp b/src/town_type.hpp
new file mode 100644
index 00000000..f8458c60
--- /dev/null
+++ b/src/town_type.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "h-basic.h"
+#include "store_type_fwd.hpp"
+
+/**
+ * Town descriptor.
+ */
+struct town_type
+{
+ cptr name;
+ u32b seed; /* Seed for RNG */
+ store_type *store; /* The stores [max_st_idx] */
+ byte numstores;
+
+ byte flags; /* Town flags */
+ /* Left this for the sake of compatibility */
+ bool_ stocked; /* Is the town actualy stocked ? */
+
+ bool_ destroyed; /* Is the town destroyed? */
+};
diff --git a/src/town_type_fwd.hpp b/src/town_type_fwd.hpp
new file mode 100644
index 00000000..9de8c448
--- /dev/null
+++ b/src/town_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct town_type;
diff --git a/src/trap_type.hpp b/src/trap_type.hpp
new file mode 100644
index 00000000..d82c925b
--- /dev/null
+++ b/src/trap_type.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Trap descriptor.
+ */
+struct trap_type
+{
+ s16b probability; /* probability of existence */
+ s16b another; /* does this trap easily combine */
+ s16b p1valinc; /* how much does this trap attribute to p1val */
+ byte difficulty; /* how difficult to disarm */
+ byte minlevel; /* what is the minimum level on which the traps should be */
+ byte color; /* what is the color on screen */
+ u32b flags; /* where can these traps go - and perhaps other flags */
+ bool_ ident; /* do we know the name */
+ s16b known; /* how well is this trap known */
+ const char *name; /* normal name like weakness */
+ s16b dd, ds; /* base damage */
+ char *text; /* longer description once you've met this trap */
+ byte g_attr; /* Overlay graphic attribute */
+ char g_char; /* Overlay graphic character */
+};
diff --git a/src/trap_type_fwd.hpp b/src/trap_type_fwd.hpp
new file mode 100644
index 00000000..480edfef
--- /dev/null
+++ b/src/trap_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct trap_type;
diff --git a/src/traps.c b/src/traps.cc
index 999f9acc..bc4ef99f 100644
--- a/src/traps.c
+++ b/src/traps.cc
@@ -1,7 +1,3 @@
-/* File: traps.c */
-
-/* Purpose: handle traps */
-
/* the below copyright probably still applies, but it is heavily changed
* copied, adapted & re-engineered by JK.
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
@@ -11,7 +7,36 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "traps.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd1.hpp"
+#include "cmd2.hpp"
+#include "dungeon_info_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_spec.hpp"
+#include "player_type.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
bool_ do_player_trap_call_out(void)
{
@@ -346,7 +371,7 @@ static bool_ player_handle_trap_of_walls(void)
p_ptr->update |= (PU_DISTANCE);
/* Update the health bar */
- p_ptr->redraw |= (PR_HEALTH);
+ p_ptr->redraw |= (PR_FRAME);
/* Redraw map */
p_ptr->redraw |= (PR_MAP);
@@ -439,12 +464,9 @@ static bool_ player_handle_breath_trap(s16b rad, s16b type, u16b trap)
*/
static void trap_hit(s16b trap)
{
- s16b dam;
trap_type *t_ptr = &t_info[trap];
-
- dam = damroll(t_ptr->dd, t_ptr->ds);
-
- take_hit(dam, t_name + t_ptr->name);
+ s16b dam = damroll(t_ptr->dd, t_ptr->ds);
+ take_hit(dam, t_ptr->name);
}
/*
@@ -465,11 +487,6 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
trap = i_ptr->pval;
}
- if ((i_ptr == NULL) && (cave[y][x].o_idx != 0))
- {
- i_ptr = &o_list[cave[y][x].o_idx];
- }
-
switch (trap)
{
/* stat traps */
@@ -639,17 +656,14 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
/* Teleport Away Trap */
case TRAP_OF_TELEPORT_AWAY:
{
- int item, amt;
- object_type *o_ptr;
-
/* teleport away all items */
- while (cave[y][x].o_idx != 0)
+ while (!cave[y][x].o_idxs.empty())
{
- item = cave[y][x].o_idx;
+ auto item = cave[y][x].o_idxs.front();
- o_ptr = &o_list[item];
+ object_type *o_ptr = &o_list[item];
- amt = o_ptr->number;
+ int amt = o_ptr->number;
ident = do_trap_teleport_away(o_ptr, y, x);
@@ -868,7 +882,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
{
p_ptr->csp = 0;
p_ptr->csp_frac = 0;
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
msg_print("You sense a great loss.");
ident = TRUE;
}
@@ -876,7 +890,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
{
/* no sense saying this unless you never have mana */
msg_format("Suddenly you feel glad you're a mere %s",
- spp_ptr->title + c_name);
+ spp_ptr->title);
}
else
{
@@ -910,7 +924,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
msg_print("All of your coins were stolen!");
ident = TRUE;
}
- p_ptr->redraw |= (PR_GOLD);
+ p_ptr->redraw |= (PR_FRAME);
break;
}
@@ -1165,7 +1179,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
cv_ptr2 = &cave[cy][cx];
- if (!cave_valid_bold(cy, cx) || cv_ptr2->o_idx != 0) continue;
+ if (!cave_valid_bold(cy, cx) || (!cv_ptr2->o_idxs.empty())) continue;
/* don't put anything in vaults */
if (cv_ptr2->info & CAVE_ICKY) continue;
@@ -1368,8 +1382,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
/* Create a Wand of Nothing */
object_prep(j_ptr, lookup_kind(TV_WAND, SV_WAND_NOTHING));
- hack_apply_magic_power = -99;
- apply_magic(j_ptr, 0, FALSE, FALSE, FALSE);
+ apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
j_ptr->ident &= ~IDENT_KNOWN;
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
}
@@ -1379,8 +1392,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
/* Create a Staff of Nothing */
object_prep(j_ptr, lookup_kind(TV_STAFF, SV_STAFF_NOTHING));
- hack_apply_magic_power = -99;
- apply_magic(j_ptr, 0, FALSE, FALSE, FALSE);
+ apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
j_ptr->ident &= ~IDENT_KNOWN;
p_ptr->notice |= (PN_COMBINE | PN_REORDER);
}
@@ -1885,7 +1897,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
{
if (p_ptr->pgod == 0)
{
- msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title + c_name);
+ msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title);
}
else
{
@@ -1903,7 +1915,7 @@ bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item)
{
if (p_ptr->pgod == 0)
{
- msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title + c_name);
+ msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title);
}
else
{
@@ -1974,7 +1986,7 @@ void player_activate_door_trap(s16b y, s16b x)
!(f_info[c_ptr->feat].flags1 & FF1_DOOR)) return;
/* Disturb */
- disturb(0, 0);
+ disturb(0);
/* Message */
msg_print("You found a trap!");
@@ -1988,7 +2000,7 @@ void player_activate_door_trap(s16b y, s16b x)
{
t_info[c_ptr->t_idx].ident = TRUE;
msg_format("You identified that trap as %s.",
- t_name + t_info[c_ptr->t_idx].name);
+ t_info[c_ptr->t_idx].name);
}
}
@@ -2133,26 +2145,11 @@ void wiz_place_trap(int y, int x, int idx)
/*
* Hook to determine if an object is a device
*/
-static bool_ item_tester_hook_device(object_type *o_ptr)
+static bool item_tester_hook_device(object_type const *o_ptr)
{
- if (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) ||
+ return (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) ||
(o_ptr->tval == TV_STAFF) ||
- (o_ptr->tval == TV_WAND)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
-}
-
-/*
- * Hook to determine if an object is a potion
- */
-static bool_ item_tester_hook_potion(object_type *o_ptr)
-{
- if ((o_ptr->tval == TV_POTION) ||
- (o_ptr->tval == TV_POTION2)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ (o_ptr->tval == TV_WAND));
}
/*
@@ -2197,46 +2194,46 @@ void do_cmd_set_trap(void)
return;
}
- /* Restrict choices to trapkits */
- item_tester_tval = TV_TRAPKIT;
-
/* Get an item */
q = "Use which trapping kit? ";
s = "You have no trapping kits.";
- if (!get_item(&item_kit, q, s, USE_INVEN)) return;
+ if (!get_item(&item_kit,
+ q, s,
+ USE_INVEN,
+ object_filter::TVal(TV_TRAPKIT)))
+ {
+ return;
+ }
o_ptr = &p_ptr->inventory[item_kit];
/* Trap kits need a second object */
- switch (o_ptr->sval)
- {
- case SV_TRAPKIT_BOW:
- item_tester_tval = TV_ARROW;
- break;
- case SV_TRAPKIT_XBOW:
- item_tester_tval = TV_BOLT;
- break;
- case SV_TRAPKIT_SLING:
- item_tester_tval = TV_SHOT;
- break;
- case SV_TRAPKIT_POTION:
- item_tester_hook = item_tester_hook_potion;
- break;
- case SV_TRAPKIT_SCROLL:
- item_tester_tval = TV_SCROLL;
- break;
- case SV_TRAPKIT_DEVICE:
- item_tester_hook = item_tester_hook_device;
- break;
- default:
- msg_print("Unknown trapping kit type!");
- break;
- }
+ object_filter_t object_filter = object_filter::Or(
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_BOW),
+ object_filter::TVal(TV_ARROW)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_XBOW),
+ object_filter::TVal(TV_BOLT)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_SLING),
+ object_filter::TVal(TV_SHOT)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_POTION),
+ object_filter::Or(
+ object_filter::TVal(TV_POTION),
+ object_filter::TVal(TV_POTION2))),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_SCROLL),
+ object_filter::TVal(TV_SCROLL)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_DEVICE),
+ &item_tester_hook_device));
/* Get the second item */
q = "Load with what? ";
s = "You have nothing to load that trap with.";
- if (!get_item(&item_load, q, s, USE_INVEN)) return;
+ if (!get_item(&item_load, q, s, USE_INVEN, object_filter)) return;
/* Get the second object */
j_ptr = &p_ptr->inventory[item_load];
@@ -2519,7 +2516,7 @@ bool_ mon_hit_trap_aux_scroll(int m_idx, int sval)
dam = damroll(5, 10);
break;
case SV_SCROLL_STAR_DESTRUCTION:
- destroy_area(y, x, 15, TRUE, FALSE);
+ destroy_area(y, x, 15);
return (FALSE);
case SV_SCROLL_DISPEL_UNDEAD:
typ = GF_DISP_UNDEAD;
@@ -2622,7 +2619,7 @@ bool_ mon_hit_trap_aux_potion(int m_idx, object_type *o_ptr)
case SV_POTION_EXPERIENCE:
if (m_ptr->level < MONSTER_LEVEL_MAX)
{
- m_ptr->exp = MONSTER_EXP(m_ptr->level + 1);
+ m_ptr->exp = monster_exp(m_ptr->level + 1);
monster_check_experience(m_idx, FALSE);
}
return (FALSE);
@@ -2728,8 +2725,6 @@ bool_ mon_hit_trap(int m_idx)
monster_type *m_ptr = &m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- object_type *kit_o_ptr, *load_o_ptr, *j_ptr;
-
u32b f1, f2, f3, f4, f5, esp;
object_type object_type_body;
@@ -2756,9 +2751,10 @@ bool_ mon_hit_trap(int m_idx)
int cost = 0;
/* Get the trap objects */
- kit_o_ptr = &o_list[cave[my][mx].special2];
- load_o_ptr = &o_list[cave[my][mx].special];
- j_ptr = &object_type_body;
+ auto kit_o_idx = cave[my][mx].special2;
+ auto kit_o_ptr = &o_list[kit_o_idx];
+ auto load_o_ptr = &o_list[cave[my][mx].special];
+ auto j_ptr = &object_type_body;
/* Get trap properties */
object_flags(kit_o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -2998,8 +2994,7 @@ bool_ mon_hit_trap(int m_idx)
if (load_o_ptr->number <= 0)
{
remove = TRUE;
- delete_object_idx(kit_o_ptr->next_o_idx);
- kit_o_ptr->next_o_idx = 0;
+ delete_object_idx(kit_o_idx);
}
/* Drop (or break) near that location */
@@ -3044,8 +3039,7 @@ bool_ mon_hit_trap(int m_idx)
if (load_o_ptr->number <= 0)
{
remove = TRUE;
- delete_object_idx(kit_o_ptr->next_o_idx);
- kit_o_ptr->next_o_idx = 0;
+ delete_object_idx(kit_o_idx);
}
}
@@ -3086,8 +3080,7 @@ bool_ mon_hit_trap(int m_idx)
if (load_o_ptr->number <= 0)
{
remove = TRUE;
- delete_object_idx(kit_o_ptr->next_o_idx);
- kit_o_ptr->next_o_idx = 0;
+ delete_object_idx(kit_o_idx);
}
}
diff --git a/src/traps.hpp b/src/traps.hpp
new file mode 100644
index 00000000..3df1e430
--- /dev/null
+++ b/src/traps.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "h-basic.h"
+#include "object_type_fwd.hpp"
+
+extern bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item);
+extern void player_activate_door_trap(s16b y, s16b x);
+extern void place_trap(int y, int x);
+extern void place_trap_leveled(int y, int x, int lev);
+extern void place_trap_object(object_type *o_ptr);
+extern void wiz_place_trap(int y, int x, int idx);
+extern void do_cmd_set_trap(void);
+extern bool_ mon_hit_trap(int);
diff --git a/src/tval_desc.hpp b/src/tval_desc.hpp
new file mode 100644
index 00000000..abf0b5e2
--- /dev/null
+++ b/src/tval_desc.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+/**
+ * TVal description entry.
+ */
+struct tval_desc
+{
+ /**
+ * TVal
+ */
+ int tval;
+
+ /**
+ * Description
+ */
+ char const *desc;
+};
diff --git a/src/types.h b/src/types.h
deleted file mode 100644
index d9cae3cf..00000000
--- a/src/types.h
+++ /dev/null
@@ -1,2771 +0,0 @@
-/* File: types.h */
-
-/* Purpose: global type declarations */
-
-/*
- * Copyright (c) 1989 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.
- */
-
-
-/*
- * This file should ONLY be included by "angband.h"
- */
-
-
-/*
- * Note that "char" may or may not be signed, and that "signed char"
- * may or may not work on all machines. So always use "s16b" or "s32b"
- * for signed values. Also, note that unsigned values cause math problems
- * in many cases, so try to only use "u16b" and "u32b" for "bit flags",
- * unless you really need the extra bit of information, or you really
- * need to restrict yourself to a single byte for storage reasons.
- *
- * Also, if possible, attempt to restrict yourself to sub-fields of
- * known size (use "s16b" or "s32b" instead of "int", and "byte" instead
- * of "bool"), and attempt to align all fields along four-byte words, to
- * optimize storage issues on 32-bit machines. Also, avoid "bit flags"
- * since these increase the code size and slow down execution. When
- * you need to store bit flags, use one byte per flag, or, where space
- * is an issue, use a "byte" or "u16b" or "u32b", and add special code
- * to access the various bit flags.
- *
- * Many of these structures were developed to reduce the number of global
- * variables, facilitate structured program design, allow the use of ascii
- * template files, simplify access to indexed data, or facilitate efficient
- * clearing of many variables at once.
- *
- * Certain data is saved in multiple places for efficient access, currently,
- * this includes the tval/sval/weight fields in "object_type", various fields
- * in "header_type", and the "m_idx" and "o_idx" fields in "cave_type". All
- * of these could be removed, but this would, in general, slow down the game
- * and increase the complexity of the code.
- */
-
-
-/*
- * String list.
- */
-typedef struct string_list string_list;
-struct string_list {
- /* The string list owns the string */
- cptr s;
- /* Next */
- string_list *next;
-};
-
-int compare_string_list(string_list *a, string_list *b);
-SGLIB_DEFINE_LIST_PROTOTYPES(string_list, compare_string, next);
-
-void string_list_init(string_list *sl, cptr s); /* Initialize element; copies string */
-void string_list_destroy(string_list *sl); /* Destroy element */
-void string_list_append(string_list **slist, cptr s); /* Append string */
-
-
-
-/*
- * Template file header information (see "init.c"). 16 bytes.
- *
- * Note that the sizes of many of the "arrays" are between 32768 and
- * 65535, and so we must use "unsigned" values to hold the "sizes" of
- * these arrays below. Normally, I try to avoid using unsigned values,
- * since they can cause all sorts of bizarre problems, but I have no
- * choice here, at least, until the "race" array is split into "normal"
- * and "unique" monsters, which may or may not actually help.
- *
- * Note that, on some machines, for example, the Macintosh, the standard
- * "read()" and "write()" functions cannot handle more than 32767 bytes
- * at one time, so we need replacement functions, see "util.c" for details.
- *
- * Note that, on some machines, for example, the Macintosh, the standard
- * "malloc()" function cannot handle more than 32767 bytes at one time,
- * but we may assume that the "ralloc()" function can handle up to 65535
- * butes at one time. We should not, however, assume that the "ralloc()"
- * function can handle more than 65536 bytes at a time, since this might
- * result in segmentation problems on certain older machines, and in fact,
- * we should not assume that it can handle exactly 65536 bytes at a time,
- * since the internal functions may use an unsigned short to specify size.
- *
- * In general, these problems occur only on machines (such as most personal
- * computers) which use 2 byte "int" values, and which use "int" for the
- * arguments to the relevent functions.
- */
-
-typedef struct header header;
-
-struct header
-{
- u16b info_num; /* Number of "info" records */
-
- u32b name_size; /* Size of the "name" array in bytes */
-
- u32b text_size; /* Size of the "text" array in bytes */
-};
-
-
-/*
- * "Themed" objects.
- * Probability in percent for each class of objects to be dropped.
- * This could perhaps be an array - but that wouldn't be as clear.
- */
-typedef struct obj_theme obj_theme;
-struct obj_theme
-{
- byte treasure;
- byte combat;
- byte magic;
- byte tools;
-};
-
-
-/*
- * Information about terrain "features"
- */
-
-typedef struct feature_type feature_type;
-
-struct feature_type
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
- u32b tunnel; /* Text for tunneling */
- u32b block; /* Text for blocking */
-
- byte mimic; /* Feature to mimic */
-
- u32b flags1; /* First set of flags */
-
- byte extra; /* Extra byte (unused) */
-
- 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 */
-
- byte shimmer[7]; /* Shimmer colors */
-
- int d_dice[4]; /* Number of dices */
- int d_side[4]; /* Number of sides */
- int d_frequency[4]; /* Frequency of damage (1 is the minimum) */
- int d_type[4]; /* Type of damage */
-};
-
-
-/*
- * Information about object "kinds", including player knowledge.
- *
- * Only "aware" and "tried" are saved in the savefile
- */
-
-typedef struct object_kind object_kind;
-
-struct object_kind
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
-
- byte tval; /* Object type */
- byte sval; /* Object sub type */
-
- s32b pval; /* Object extra info */
- s32b pval2; /* Object extra info */
-
- s16b to_h; /* Bonus to hit */
- s16b to_d; /* Bonus to damage */
- s16b to_a; /* Bonus to armor */
-
- s16b activate; /* Activation number */
-
- s16b ac; /* Base armor */
-
- byte dd, ds; /* Damage dice/sides */
-
- s32b weight; /* Weight */
-
- s32b cost; /* Object "base cost" */
-
- u32b flags1; /* Flags, set 1 */
- u32b flags2; /* Flags, set 2 */
- u32b flags3; /* Flags, set 3 */
- u32b flags4; /* Flags, set 4 */
- u32b flags5; /* Flags, set 5 */
-
- u32b oflags1; /* Obvious Flags, set 1 */
- u32b oflags2; /* Obvious Flags, set 2 */
- u32b oflags3; /* Obvious Flags, set 3 */
- u32b oflags4; /* Obvious Flags, set 4 */
- u32b oflags5; /* Obvious Flags, set 5 */
-
- byte locale[4]; /* Allocation level(s) */
- byte chance[4]; /* Allocation chance(s) */
-
- byte level; /* Level */
- byte extra; /* Something */
-
-
- byte d_attr; /* Default object attribute */
- char d_char; /* Default object character */
-
-
- byte x_attr; /* Desired object attribute */
- char x_char; /* Desired object character */
-
-
- byte flavor; /* Special object flavor (or zero) */
-
- bool_ easy_know; /* This object is always known (if aware) */
-
-
- bool_ aware; /* The player is "aware" of the item's effects */
-
- bool_ tried; /* The player has "tried" one of the items */
-
- bool_ know; /* extractable flag for the alchemist */
-
- u32b esp; /* ESP flags */
- u32b oesp; /* Obvious ESP flags */
-
- byte btval; /* Become Object type */
- byte bsval; /* Become Object sub type */
- bool_ artifact; /* Is it a normal artifact(already generated) */
-
- s16b power; /* Power granted(if any) */
-};
-
-
-
-/*
- * Information about "artifacts".
- *
- * Note that the save-file only writes "cur_num" to the savefile.
- *
- * Note that "max_num" is always "1" (if that artifact "exists")
- */
-
-typedef struct artifact_type artifact_type;
-
-struct artifact_type
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
-
- byte tval; /* Artifact type */
- byte sval; /* Artifact sub type */
-
- s16b pval; /* Artifact extra info */
-
- s16b to_h; /* Bonus to hit */
- s16b to_d; /* Bonus to damage */
- s16b to_a; /* Bonus to armor */
-
- s16b activate; /* Activation Number */
-
- s16b ac; /* Base armor */
-
- byte dd, ds; /* Damage when hits */
-
- s16b weight; /* Weight */
-
- s32b cost; /* Artifact "cost" */
-
- u32b flags1; /* Artifact Flags, set 1 */
- u32b flags2; /* Artifact Flags, set 2 */
- u32b flags3; /* Artifact Flags, set 3 */
- u32b flags4; /* Artifact Flags, set 4 */
- u32b flags5; /* Artifact Flags, set 5 */
-
- u32b oflags1; /* Obvious Flags, set 1 */
- u32b oflags2; /* Obvious Flags, set 2 */
- u32b oflags3; /* Obvious Flags, set 3 */
- u32b oflags4; /* Obvious Flags, set 4 */
- u32b oflags5; /* Obvious Flags, set 5 */
-
- byte level; /* Artifact level */
- byte rarity; /* Artifact rarity */
-
- byte cur_num; /* Number created (0 or 1) */
- byte max_num; /* Unused (should be "1") */
-
- u32b esp; /* ESP flags */
- u32b oesp; /* ESP flags */
-
- s16b power; /* Power granted(if any) */
-
- s16b set; /* Does it belongs to a set ?*/
-};
-
-
-/*
- * Information about "ego-items".
- */
-
-typedef struct ego_item_type ego_item_type;
-
-struct ego_item_type
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
-
- bool_ before; /* Before or after the object name ? */
-
- byte tval[10];
- byte min_sval[10];
- byte max_sval[10];
-
- byte rating; /* Rating boost */
-
- byte level; /* Minimum level */
- byte rarity; /* Object rarity */
- byte mrarity; /* Object rarity */
-
- s16b max_to_h; /* Maximum to-hit bonus */
- s16b max_to_d; /* Maximum to-dam bonus */
- s16b max_to_a; /* Maximum to-ac bonus */
-
- s16b activate; /* Activation Number */
-
- s32b max_pval; /* Maximum pval */
-
- s32b cost; /* Ego-item "cost" */
-
- byte rar[5];
- u32b flags1[5]; /* Ego-Item Flags, set 1 */
- u32b flags2[5]; /* Ego-Item Flags, set 2 */
- u32b flags3[5]; /* Ego-Item Flags, set 3 */
- u32b flags4[5]; /* Ego-Item Flags, set 4 */
- u32b flags5[5]; /* Ego-Item Flags, set 5 */
- u32b esp[5]; /* ESP flags */
- u32b oflags1[5]; /* Ego-Item Obvious Flags, set 1 */
- u32b oflags2[5]; /* Ego-Item Obvious Flags, set 2 */
- u32b oflags3[5]; /* Ego-Item Obvious Flags, set 3 */
- u32b oflags4[5]; /* Ego-Item Obvious Flags, set 4 */
- u32b oflags5[5]; /* Ego-Item Obvious Flags, set 5 */
- u32b oesp[5]; /* Obvious ESP flags */
- u32b fego[5]; /* ego flags */
-
- u32b need_flags1; /* Ego-Item Flags, set 1 */
- u32b need_flags2; /* Ego-Item Flags, set 2 */
- u32b need_flags3; /* Ego-Item Flags, set 3 */
- u32b need_flags4; /* Ego-Item Flags, set 4 */
- u32b need_flags5; /* Ego-Item Flags, set 5 */
- u32b need_esp; /* ESP flags */
- u32b forbid_flags1; /* Ego-Item Flags, set 1 */
- u32b forbid_flags2; /* Ego-Item Flags, set 2 */
- u32b forbid_flags3; /* Ego-Item Flags, set 3 */
- u32b forbid_flags4; /* Ego-Item Flags, set 4 */
- u32b forbid_flags5; /* Ego-Item Flags, set 5 */
- u32b forbid_esp; /* ESP flags */
-
- s16b power; /* Power granted(if any) */
-};
-
-
-/*
- * Information about "random artifacts parts".
- */
-typedef struct randart_part_type randart_part_type;
-struct randart_part_type
-{
- byte tval[20];
- byte min_sval[20];
- byte max_sval[20];
-
- byte level; /* Minimum level */
- byte rarity; /* Object rarity */
- byte mrarity; /* Object rarity */
-
- s16b max_to_h; /* Maximum to-hit bonus */
- s16b max_to_d; /* Maximum to-dam bonus */
- s16b max_to_a; /* Maximum to-ac bonus */
-
- s32b max_pval; /* Maximum pval */
-
- s32b value; /* power value */
- s16b max; /* Number of time it can appear on a single item */
-
- u32b flags1; /* Ego-Item Flags, set 1 */
- u32b flags2; /* Ego-Item Flags, set 2 */
- u32b flags3; /* Ego-Item Flags, set 3 */
- u32b flags4; /* Ego-Item Flags, set 4 */
- u32b flags5; /* Ego-Item Flags, set 5 */
- u32b esp; /* ESP flags */
- u32b fego; /* ego flags */
-
- u32b aflags1; /* Ego-Item Flags, set 1 */
- u32b aflags2; /* Ego-Item Flags, set 2 */
- u32b aflags3; /* Ego-Item Flags, set 3 */
- u32b aflags4; /* Ego-Item Flags, set 4 */
- u32b aflags5; /* Ego-Item Flags, set 5 */
- u32b aesp; /* ESP flags */
-
- s16b power; /* Power granted(if any) */
-};
-
-typedef struct randart_gen_type randart_gen_type;
-struct randart_gen_type
-{
- int chance; /* Chance to have that number of powers */
- int dd;
- int ds;
- int plus; /* xdy+plus power */
-};
-
-
-/*
- * Monster blow structure
- *
- * - Method (RBM_*)
- * - Effect (RBE_*)
- * - Damage Dice
- * - Damage Sides
- */
-
-typedef struct monster_blow monster_blow;
-
-struct monster_blow
-{
- byte method;
- byte effect;
- byte d_dice;
- byte d_side;
-};
-
-
-
-/*
- * Monster "race" information, including racial memories
- *
- * Note that "d_attr" and "d_char" are used for MORE than "visual" stuff.
- *
- * Note that "x_attr" and "x_char" are used ONLY for "visual" stuff.
- *
- * Note that "cur_num" (and "max_num") represent the number of monsters
- * of the given race currently on (and allowed on) the current level.
- * This information yields the "dead" flag for Unique monsters.
- *
- * Note that "max_num" is reset when a new player is created.
- * Note that "cur_num" is reset when a new level is created.
- *
- * Note that several of these fields, related to "recall", can be
- * scrapped if space becomes an issue, resulting in less "complete"
- * monster recall (no knowledge of spells, etc). All of the "recall"
- * fields have a special prefix to aid in searching for them.
- */
-
-
-typedef struct monster_race monster_race;
-
-struct monster_race
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
-
- u16b hdice; /* Creatures hit dice count */
- u16b hside; /* Creatures hit dice sides */
-
- s16b ac; /* Armour Class */
-
- s16b sleep; /* Inactive counter (base) */
- byte aaf; /* Area affect radius (1-100) */
- byte speed; /* Speed (normally 110) */
-
- s32b mexp; /* Exp value for kill */
-
- s32b weight; /* Weight of the monster */
-
- byte freq_inate; /* Inate spell frequency */
- byte freq_spell; /* Other spell frequency */
-
- u32b flags1; /* Flags 1 (general) */
- u32b flags2; /* Flags 2 (abilities) */
- u32b flags3; /* Flags 3 (race/resist) */
- u32b flags4; /* Flags 4 (inate/breath) */
- u32b flags5; /* Flags 5 (normal spells) */
- u32b flags6; /* Flags 6 (special spells) */
- u32b flags7; /* Flags 7 (movement related abilities) */
- u32b flags8; /* Flags 8 (wilderness info) */
- u32b flags9; /* Flags 9 (drops info) */
-
- monster_blow blow[4]; /* Up to four blows per round */
-
- byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
-
- byte level; /* Level of creature */
- byte rarity; /* Rarity of creature */
-
-
- byte d_attr; /* Default monster attribute */
- char d_char; /* Default monster character */
-
-
- byte x_attr; /* Desired monster attribute */
- char x_char; /* Desired monster character */
-
-
- s16b max_num; /* Maximum population allowed per level */
-
- byte cur_num; /* Monster population on current level */
-
-
- s16b r_sights; /* Count sightings of this monster */
- s16b r_deaths; /* Count deaths from this monster */
-
- s16b r_pkills; /* Count monsters killed in this life */
- s16b r_tkills; /* Count monsters killed in all lives */
-
- byte r_wake; /* Number of times woken up (?) */
- byte r_ignore; /* Number of times ignored (?) */
-
- byte r_xtra1; /* Something (unused) */
- byte r_xtra2; /* Something (unused) */
-
- byte r_drop_gold; /* Max number of gold dropped at once */
- byte r_drop_item; /* Max number of item dropped at once */
-
- byte r_cast_inate; /* Max number of inate spells seen */
- byte r_cast_spell; /* Max number of other spells seen */
-
- byte r_blows[4]; /* Number of times each blow type was seen */
-
- u32b r_flags1; /* Observed racial flags */
- u32b r_flags2; /* Observed racial flags */
- u32b r_flags3; /* Observed racial flags */
- u32b r_flags4; /* Observed racial flags */
- u32b r_flags5; /* Observed racial flags */
- u32b r_flags6; /* Observed racial flags */
- u32b r_flags7; /* Observed racial flags */
- u32b r_flags8; /* Observed racial flags */
- u32b r_flags9; /* Observed racial flags */
-
- bool_ on_saved; /* Is the (unique) on a saved level ? */
-
- byte total_visible; /* Amount of this race that are visible */
-
- obj_theme drops; /* The drops type */
-};
-
-
-typedef struct monster_ego monster_ego;
-
-struct monster_ego
-{
- u32b name; /* Name (offset) */
- bool_ before; /* Display ego before or after */
-
- monster_blow blow[4]; /* Up to four blows per round */
- byte blowm[4][2];
-
- s16b hdice; /* Creatures hit dice count */
- s16b hside; /* Creatures hit dice sides */
-
- s16b ac; /* Armour Class */
-
- s16b sleep; /* Inactive counter (base) */
- s16b aaf; /* Area affect radius (1-100) */
- s16b speed; /* Speed (normally 110) */
-
- s32b mexp; /* Exp value for kill */
-
- s32b weight; /* Weight of the monster */
-
- byte freq_inate; /* Inate spell frequency */
- byte freq_spell; /* Other spell frequency */
-
- /* Ego flags */
- u32b flags1; /* Flags 1 */
- u32b flags2; /* Flags 1 */
- u32b flags3; /* Flags 1 */
- u32b flags7; /* Flags 1 */
- u32b flags8; /* Flags 1 */
- u32b flags9; /* Flags 1 */
- u32b hflags1; /* Flags 1 */
- u32b hflags2; /* Flags 1 */
- u32b hflags3; /* Flags 1 */
- u32b hflags7; /* Flags 1 */
- u32b hflags8; /* Flags 1 */
- u32b hflags9; /* Flags 1 */
-
- /* Monster flags */
- u32b mflags1; /* Flags 1 (general) */
- u32b mflags2; /* Flags 2 (abilities) */
- u32b mflags3; /* Flags 3 (race/resist) */
- u32b mflags4; /* Flags 4 (inate/breath) */
- u32b mflags5; /* Flags 5 (normal spells) */
- u32b mflags6; /* Flags 6 (special spells) */
- u32b mflags7; /* Flags 7 (movement related abilities) */
- u32b mflags8; /* Flags 8 (wilderness info) */
- u32b mflags9; /* Flags 9 (drops info) */
-
- /* Negative Flags, to be removed from the monster flags */
- u32b nflags1; /* Flags 1 (general) */
- u32b nflags2; /* Flags 2 (abilities) */
- u32b nflags3; /* Flags 3 (race/resist) */
- u32b nflags4; /* Flags 4 (inate/breath) */
- u32b nflags5; /* Flags 5 (normal spells) */
- u32b nflags6; /* Flags 6 (special spells) */
- u32b nflags7; /* Flags 7 (movement related abilities) */
- u32b nflags8; /* Flags 8 (wilderness info) */
- u32b nflags9; /* Flags 9 (drops info) */
-
- s16b level; /* Level of creature */
- s16b rarity; /* Rarity of creature */
-
-
- byte d_attr; /* Default monster attribute */
- char d_char; /* Default monster character */
-
- byte g_attr; /* Overlay graphic attribute */
- char g_char; /* Overlay graphic character */
-
- char r_char[5]; /* Monster race allowed */
- char nr_char[5]; /* Monster race not allowed */
-};
-
-
-
-/*
- * Information about "vault generation"
- */
-
-typedef struct vault_type vault_type;
-
-struct vault_type
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
-
- byte typ; /* Vault type */
-
- byte rat; /* Vault rating */
-
- byte hgt; /* Vault height */
- byte wid; /* Vault width */
-
- s16b lvl; /* level of special (if any) */
- byte dun_type; /* Dungeon type where the level will show up */
-
- s16b mon[10]; /* special monster */
- int item[3]; /* number of item (usually artifact) */
-};
-
-
-/* jk */
-/* name and description are in some other arrays */
-typedef struct trap_type trap_type;
-
-struct trap_type
-{
- s16b probability; /* probability of existence */
- s16b another; /* does this trap easily combine */
- s16b p1valinc; /* how much does this trap attribute to p1val */
- byte difficulty; /* how difficult to disarm */
- byte minlevel; /* what is the minimum level on which the traps should be */
- byte color; /* what is the color on screen */
- u32b flags; /* where can these traps go - and perhaps other flags */
- bool_ ident; /* do we know the name */
- s16b known; /* how well is this trap known */
- s16b name; /* normal name like weakness */
- s16b dd, ds; /* base damage */
- s16b text; /* longer description once you've met this trap */
- byte g_attr; /* Overlay graphic attribute */
- char g_char; /* Overlay graphic character */
-};
-
-
-
-/*
- * A single "grid" in a Cave
- *
- * Note that several aspects of the code restrict the actual cave
- * to a max size of 256 by 256. In partcular, locations are often
- * saved as bytes, limiting each coordinate to the 0-255 range.
- *
- * The "o_idx" and "m_idx" fields are very interesting. There are
- * many places in the code where we need quick access to the actual
- * monster or object(s) in a given cave grid. The easiest way to
- * do this is to simply keep the index of the monster and object
- * (if any) with the grid, but this takes 198*66*4 bytes of memory.
- * Several other methods come to mind, which require only half this
- * amound of memory, but they all seem rather complicated, and would
- * probably add enough code that the savings would be lost. So for
- * these reasons, we simply store an index into the "o_list" and
- * "m_list" arrays, using "zero" when no monster/object is present.
- *
- * Note that "o_idx" is the index of the top object in a stack of
- * objects, using the "next_o_idx" field of objects (see below) to
- * create the singly linked list of objects. If "o_idx" is zero
- * then there are no objects in the grid.
- */
-
-typedef struct cave_type cave_type;
-
-struct cave_type
-{
- u16b info; /* Hack -- cave flags */
-
- byte feat; /* Hack -- feature type */
-
- s16b o_idx; /* Object in this grid */
-
- s16b m_idx; /* Monster in this grid */
-
- s16b t_idx; /* trap index (in t_list) or zero */
-
- s16b special, special2; /* Special cave info */
-
- s16b inscription; /* Inscription of the grid */
-
- byte mana; /* Magical energy of the grid */
-
- byte mimic; /* Feature to mimic */
-
- byte cost; /* Hack -- cost of flowing */
- byte when; /* Hack -- when cost was computed */
-
- s16b effect; /* The lasting effects */
-};
-
-/* Lasting spell effects(clouds, ..) */
-typedef struct effect_type effect_type;
-struct effect_type
-{
- s16b time; /* For how long */
- s16b dam; /* How much damage */
- s16b type; /* Of which type */
- s16b cy; /* Center of the cast*/
- s16b cx; /* Center of the cast*/
- s16b rad; /* Radius -- if needed */
- u32b flags; /* Flags */
-};
-
-/*
- * Object information, for a specific object.
- *
- * Note that a "discount" on an item is permanent and never goes away.
- *
- * Note that inscriptions are now handled via the "quark_str()" function
- * applied to the "note" field, which will return NULL if "note" is zero.
- *
- * Note that "object" records are "copied" on a fairly regular basis,
- * and care must be taken when handling such objects.
- *
- * Note that "object flags" must now be derived from the object kind,
- * the artifact and ego-item indexes, and the two "xtra" fields.
- *
- * Each cave grid points to one (or zero) objects via the "o_idx"
- * field (above). Each object then points to one (or zero) objects
- * via the "next_o_idx" field, forming a singly linked list, which
- * in game terms, represents a "stack" of objects in the same grid.
- *
- * Each monster points to one (or zero) objects via the "hold_o_idx"
- * field (below). Each object then points to one (or zero) objects
- * via the "next_o_idx" field, forming a singly linked list, which
- * in game terms, represents a pile of objects held by the monster.
- *
- * The "held_m_idx" field is used to indicate which monster, if any,
- * is holding the object. Objects being held have "ix=0" and "iy=0".
- */
-
-typedef struct object_type object_type;
-
-struct object_type
-{
- s16b k_idx; /* Kind index (zero if "dead") */
-
- byte iy; /* Y-position on map, or zero */
- byte ix; /* X-position on map, or zero */
-
- byte tval; /* Item type (from kind) */
- byte sval; /* Item sub-type (from kind) */
-
- s32b pval; /* Item extra-parameter */
- s16b pval2; /* Item extra-parameter for some special
- items*/
- s32b pval3; /* Item extra-parameter for some special
- items*/
-
- byte discount; /* Discount (if any) */
-
- byte number; /* Number of items */
-
- s32b weight; /* Item weight */
-
- byte elevel; /* Item exp level */
- s32b exp; /* Item exp */
-
- byte name1; /* Artifact type, if any */
- s16b name2; /* Ego-Item type, if any */
- s16b name2b; /* Second Ego-Item type, if any */
-
- byte xtra1; /* Extra info type */
- s16b xtra2; /* Extra info index */
-
- s16b to_h; /* Plusses to hit */
- s16b to_d; /* Plusses to damage */
- s16b to_a; /* Plusses to AC */
-
- s16b ac; /* Normal AC */
-
- byte dd, ds; /* Damage dice/sides */
-
- s16b timeout; /* Timeout Counter */
-
- byte ident; /* Special flags */
-
- byte marked; /* Object is marked */
-
- u16b note; /* Inscription index */
- u16b art_name; /* Artifact name (random artifacts) */
-
- u32b art_flags1; /* Flags, set 1 Alas, these were necessary */
- u32b art_flags2; /* Flags, set 2 for the random artifacts of*/
- u32b art_flags3; /* Flags, set 3 Zangband */
- u32b art_flags4; /* Flags, set 4 PernAngband */
- u32b art_flags5; /* Flags, set 5 PernAngband */
- u32b art_esp; /* Flags, set esp PernAngband */
-
- u32b art_oflags1; /* Obvious Flags, set 1 */
- u32b art_oflags2; /* Obvious Flags, set 2 */
- u32b art_oflags3; /* Obvious Flags, set 3 */
- u32b art_oflags4; /* Obvious Flags, set 4 */
- u32b art_oflags5; /* Obvious Flags, set 5 */
- u32b art_oesp; /* Obvious Flags, set esp */
-
- s16b next_o_idx; /* Next object in stack (if any) */
-
- s16b held_m_idx; /* Monster holding us (if any) */
-
- byte sense; /* Pseudo-id status */
-
- byte found; /* How did we find it */
- s16b found_aux1; /* Stores info for found */
- s16b found_aux2; /* Stores info for found */
- s16b found_aux3; /* Stores info for found */
- s16b found_aux4; /* Stores info for found */
-};
-
-
-/*
- * Monster mind, use for skills and such
- */
-typedef struct monster_mind monster_mind;
-struct monster_mind
-{
- /*
- * Without this, bcc can't compile because it does not
- * allow empty structure. Remove this when you add some
- * variables to this structure. -- Kusunose
- */
- byte dummy;
-};
-
-
-
-/*
- * Monster information, for a specific monster.
- *
- * Note: fy, fx constrain dungeon size to 256x256
- *
- * The "hold_o_idx" field points to the first object of a stack
- * of objects (if any) being carried by the monster (see above).
- */
-
-typedef struct monster_type monster_type;
-
-struct monster_type
-{
- s16b r_idx; /* Monster race index */
-
- u16b ego; /* Ego monster type */
-
- byte fy; /* Y location on map */
- byte fx; /* X location on map */
-
- s32b hp; /* Current Hit points */
- s32b maxhp; /* Max Hit points */
-
- monster_blow blow[4]; /* Up to four blows per round */
-
- byte speed; /* Speed (normally 110) */
- byte level; /* Level of creature */
- s16b ac; /* Armour Class */
- u32b exp; /* Experience */
-
- s16b csleep; /* Inactive counter */
-
- byte mspeed; /* Monster "speed" */
- byte energy; /* Monster "energy" */
-
- byte stunned; /* Monster is stunned */
- byte confused; /* Monster is confused */
- byte monfear; /* Monster is afraid */
-
- s16b bleeding; /* Monster is bleeding */
- s16b poisoned; /* Monster is poisoned */
-
- byte cdis; /* Current dis from player */
-
- s32b mflag; /* Extra monster flags */
-
- bool_ ml; /* Monster is "visible" */
-
- s16b hold_o_idx; /* Object being held (if any) */
-
- u32b smart; /* Field for "smart_learn" */
-
- s16b status; /* Status(friendly, pet, companion, ..) */
-
- s16b target; /* Monster target */
-
- s16b possessor; /* Is it under the control of a possessor ? */
-
- monster_race *sr_ptr; /* Does it have a specific race(not in r_info) */
-
- monster_mind *mind; /* Does it have a mind? */
-};
-
-
-
-
-/*
- * An entry for the object/monster allocation functions
- *
- * Pass 1 is determined from allocation information
- * Pass 2 is determined from allocation restriction
- * Pass 3 is determined from allocation calculation
- */
-
-typedef struct alloc_entry alloc_entry;
-
-struct alloc_entry
-{
- s16b index; /* The actual index */
-
- byte level; /* Base dungeon level */
- byte prob1; /* Probability, pass 1 */
- byte prob2; /* Probability, pass 2 */
- byte prob3; /* Probability, pass 3 */
-
- u16b total; /* Unused for now */
-};
-
-
-
-/*
- * Available "options"
- *
- * - Address of actual option variable (or NULL)
- *
- * - Normal Value (TRUE or FALSE)
- *
- * - Option Page Number (or zero)
- *
- * - Savefile Set (or zero)
- * - Savefile Bit in that set
- *
- * - Textual name (or NULL)
- * - Textual description
- */
-
-typedef struct option_type option_type;
-
-struct option_type
-{
- bool_ *o_var;
-
- byte o_norm;
-
- byte o_page;
-
- byte o_bit;
-
- cptr o_text;
- cptr o_desc;
-};
-
-/*
- * A store owner
- */
-typedef struct owner_type owner_type;
-
-struct owner_type
-{
- u32b name; /* Name (offset) */
-
- s16b max_cost; /* Purse limit */
-
- s16b inflation; /* Inflation */
-
- u32b races[2][2]; /* Liked/hated races */
- u32b classes[2][2]; /* Liked/hated classes */
-
- s16b costs[3]; /* Costs for liked people */
-};
-
-
-
-
-/*
- * A store, with an owner, various state flags, a current stock
- * of items, and a table of items that are often purchased.
- */
-typedef struct store_type store_type;
-
-struct store_type
-{
- u16b st_idx;
-
- u16b owner; /* Owner index */
-
- s32b store_open; /* Closed until this turn */
-
- s32b last_visit; /* Last visited on this turn */
-
- byte stock_num; /* Stock -- Number of entries */
- s16b stock_size; /* Stock -- Total Size of Array */
- object_type *stock; /* Stock -- Actual stock items */
-};
-
-/*
- * A store/building type
- */
-typedef struct store_info_type store_info_type;
-
-struct store_info_type
-{
- u32b name; /* Name (offset) */
-
- s16b table[STORE_CHOICES][2]; /* Table -- Legal item kinds */
- byte table_num; /* Number of items */
- s16b max_obj; /* Number of items this store can hold */
-
- u16b owners[4]; /* List of owners(refers to ow_info) */
-
- u16b actions[6]; /* Actions(refers to ba_info) */
-
- byte d_attr; /* Default building attribute */
- char d_char; /* Default building character */
-
- byte x_attr; /* Desired building attribute */
- char x_char; /* Desired building character */
-
- u32b flags1; /* Flags */
-};
-
-/*
- * Stores/buildings actions
- */
-typedef struct store_action_type store_action_type;
-
-struct store_action_type
-{
- u32b name; /* Name (offset) */
-
- s16b costs[3]; /* Costs for liked people */
- char letter; /* Action letter */
- char letter_aux; /* Action letter */
- s16b action; /* Action code */
- s16b action_restr; /* Action restriction */
-};
-
-/*
- * the spell function must provide the desc
- */
-typedef struct magic_type magic_type;
-
-struct magic_type
-{
- byte slevel; /* Required level (to learn) */
- byte smana; /* Required mana (to cast) */
- byte sfail; /* Minimum chance of failure */
- byte sexp; /* Encoded experience bonus */
-};
-
-/*
- * Player sex info
- */
-
-typedef struct player_sex player_sex;
-
-struct player_sex
-{
- cptr title; /* Type of sex */
-
- cptr winner; /* Name of winner */
-};
-
-
-/*
- * Player racial info
- */
-
-typedef struct player_race player_race;
-
-struct player_race
-{
- s32b title; /* Type of race */
- s32b desc;
-
- s16b r_adj[6]; /* Racial stat bonuses */
-
- char luck; /* Luck */
-
- s16b r_dis; /* disarming */
- s16b r_dev; /* magic devices */
- s16b r_sav; /* saving throw */
- s16b r_stl; /* stealth */
- s16b r_srh; /* search ability */
- s16b r_fos; /* search frequency */
- s16b r_thn; /* combat (normal) */
- s16b r_thb; /* combat (shooting) */
-
- byte r_mhp; /* Race hit-dice modifier */
- u16b r_exp; /* Race experience factor */
-
- byte b_age; /* base age */
- byte m_age; /* mod age */
-
- byte m_b_ht; /* base height (males) */
- byte m_m_ht; /* mod height (males) */
- byte m_b_wt; /* base weight (males) */
- byte m_m_wt; /* mod weight (males) */
-
- byte f_b_ht; /* base height (females) */
- byte f_m_ht; /* mod height (females) */
- byte f_b_wt; /* base weight (females) */
- byte f_m_wt; /* mod weight (females) */
-
- byte infra; /* Infra-vision range */
-
- u32b choice[2]; /* Legal class choices */
-
- s16b powers[4]; /* Powers of the race */
-
- byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
-
- s16b chart; /* Chart history */
-
- u32b flags1;
- u32b flags2; /* flags */
-
- u32b oflags1[PY_MAX_LEVEL + 1];
- u32b oflags2[PY_MAX_LEVEL + 1];
- u32b oflags3[PY_MAX_LEVEL + 1];
- u32b oflags4[PY_MAX_LEVEL + 1];
- u32b oflags5[PY_MAX_LEVEL + 1];
- u32b oesp[PY_MAX_LEVEL + 1];
- s16b opval[PY_MAX_LEVEL + 1];
-
- char skill_basem[MAX_SKILLS];
- u32b skill_base[MAX_SKILLS];
- char skill_modm[MAX_SKILLS];
- s16b skill_mod[MAX_SKILLS];
-
- s16b obj_tval[5];
- s16b obj_sval[5];
- s16b obj_pval[5];
- s16b obj_dd[5];
- s16b obj_ds[5];
- s16b obj_num;
-
- struct
- {
- s16b ability;
- s16b level;
- } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
-};
-
-typedef struct player_race_mod player_race_mod;
-
-struct player_race_mod
-{
- s32b title; /* Type of race mod */
- s32b desc; /* Desc */
- bool_ place; /* TRUE = race race modifier, FALSE = Race modifier race */
-
- s16b r_adj[6]; /* (+) Racial stat bonuses */
-
- char luck; /* Luck */
- s16b mana; /* Mana % */
-
- s16b r_dis; /* (+) disarming */
- s16b r_dev; /* (+) magic devices */
- s16b r_sav; /* (+) saving throw */
- s16b r_stl; /* (+) stealth */
- s16b r_srh; /* (+) search ability */
- s16b r_fos; /* (+) search frequency */
- s16b r_thn; /* (+) combat (normal) */
- s16b r_thb; /* (+) combat (shooting) */
-
- char r_mhp; /* (+) Race mod hit-dice modifier */
- s16b r_exp; /* (+) Race mod experience factor */
-
- char b_age; /* (+) base age */
- char m_age; /* (+) mod age */
-
- char m_b_ht; /* (+) base height (males) */
- char m_m_ht; /* (+) mod height (males) */
- char m_b_wt; /* (+) base weight (males) */
- char m_m_wt; /* (+) mod weight (males) */
-
- char f_b_ht; /* (+) base height (females) */
- char f_m_ht; /* (+) mod height (females) */
- char f_b_wt; /* (+) base weight (females) */
- char f_m_wt; /* (+) mod weight (females) */
-
- char infra; /* (+) Infra-vision range */
-
- u32b choice[2]; /* Legal race choices */
-
- u32b pclass[2]; /* Classes allowed */
- u32b mclass[2]; /* Classes restricted */
-
- s16b powers[4]; /* Powers of the subrace */
-
- char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
-
- u32b flags1;
- u32b flags2; /* flags */
-
- u32b oflags1[PY_MAX_LEVEL + 1];
- u32b oflags2[PY_MAX_LEVEL + 1];
- u32b oflags3[PY_MAX_LEVEL + 1];
- u32b oflags4[PY_MAX_LEVEL + 1];
- u32b oflags5[PY_MAX_LEVEL + 1];
- u32b oesp[PY_MAX_LEVEL + 1];
- s16b opval[PY_MAX_LEVEL + 1];
-
- byte g_attr; /* Overlay graphic attribute */
- char g_char; /* Overlay graphic character */
-
- char skill_basem[MAX_SKILLS];
- u32b skill_base[MAX_SKILLS];
- char skill_modm[MAX_SKILLS];
- s16b skill_mod[MAX_SKILLS];
-
- s16b obj_tval[5];
- s16b obj_sval[5];
- s16b obj_pval[5];
- s16b obj_dd[5];
- s16b obj_ds[5];
- s16b obj_num;
-
- struct
- {
- s16b ability;
- s16b level;
- } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
-};
-
-
-/*
- * Player class info
- */
-
-typedef struct player_spec player_spec;
-
-struct player_spec
-{
- s32b title; /* Type of class spec */
- s32b desc; /* Small desc of the class spec */
-
- char skill_basem[MAX_SKILLS]; /* Mod for value */
- u32b skill_base[MAX_SKILLS]; /* value */
- char skill_modm[MAX_SKILLS]; /* mod for mod */
- s16b skill_mod[MAX_SKILLS]; /* mod */
-
- u32b skill_ideal[MAX_SKILLS]; /* Ideal skill levels at level 50 */
-
- s16b obj_tval[5];
- s16b obj_sval[5];
- s16b obj_pval[5];
- s16b obj_dd[5];
- s16b obj_ds[5];
- s16b obj_num;
-
- u32b gods;
-
- u32b flags1;
- u32b flags2; /* flags */
-
- struct
- {
- s16b ability;
- s16b level;
- } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
-};
-
-typedef struct player_class player_class;
-
-struct player_class
-{
- s32b title; /* Type of class */
- s32b desc; /* Small desc of the class */
- s32b titles[PY_MAX_LEVEL / 5];
-
- s16b c_adj[6]; /* Class stat modifier */
-
- s16b c_dis; /* class disarming */
- s16b c_dev; /* class magic devices */
- s16b c_sav; /* class saving throws */
- s16b c_stl; /* class stealth */
- s16b c_srh; /* class searching ability */
- s16b c_fos; /* class searching frequency */
- s16b c_thn; /* class to hit (normal) */
- s16b c_thb; /* class to hit (bows) */
-
- s16b x_dis; /* extra disarming */
- s16b x_dev; /* extra magic devices */
- s16b x_sav; /* extra saving throws */
- s16b x_stl; /* extra stealth */
- s16b x_srh; /* extra searching ability */
- s16b x_fos; /* extra searching frequency */
- s16b x_thn; /* extra to hit (normal) */
- s16b x_thb; /* extra to hit (bows) */
-
- s16b c_mhp; /* Class hit-dice adjustment */
- s16b c_exp; /* Class experience factor */
-
- s16b powers[4]; /* Powers of the class */
-
- s16b spell_book; /* Tval of spell books (if any) */
- s16b spell_stat; /* Stat for spells (if any) */
- s16b spell_lev; /* The higher it is the higher the spells level are */
- s16b spell_fail; /* The higher it is the higher the spells failure are */
- s16b spell_mana; /* The higher it is the higher the spells mana are */
- s16b spell_first; /* Level of first spell */
- s16b spell_weight; /* Weight that hurts spells */
- byte max_spell_level; /* Maximun spell level */
- byte magic_max_spell; /* Maximun numbner of spells one can learn by natural means */
-
- u32b flags1; /* flags */
- u32b flags2; /* flags */
-
- s16b mana;
- s16b blow_num;
- s16b blow_wgt;
- s16b blow_mul;
- s16b extra_blows;
-
- s32b sense_base;
- s32b sense_pl;
- s32b sense_plus;
- byte sense_heavy;
- byte sense_heavy_magic;
-
- s16b obj_tval[5];
- s16b obj_sval[5];
- s16b obj_pval[5];
- s16b obj_dd[5];
- s16b obj_ds[5];
- s16b obj_num;
-
- char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */
-
- u32b oflags1[PY_MAX_LEVEL + 1];
- u32b oflags2[PY_MAX_LEVEL + 1];
- u32b oflags3[PY_MAX_LEVEL + 1];
- u32b oflags4[PY_MAX_LEVEL + 1];
- u32b oflags5[PY_MAX_LEVEL + 1];
- u32b oesp[PY_MAX_LEVEL + 1];
- s16b opval[PY_MAX_LEVEL + 1];
-
- char skill_basem[MAX_SKILLS];
- u32b skill_base[MAX_SKILLS];
- char skill_modm[MAX_SKILLS];
- s16b skill_mod[MAX_SKILLS];
-
- u32b gods;
-
- player_spec spec[MAX_SPEC];
-
- struct
- {
- s16b ability;
- s16b level;
- } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */
-};
-
-typedef struct meta_class_type meta_class_type;
-struct meta_class_type
-{
- char name[80]; /* Name */
- byte color;
- s16b *classes; /* list of classes */
-};
-
-/* Help type */
-typedef struct help_info help_info;
-struct help_info
-{
- bool_ enabled; /* ingame help enabled */
- bool_ activated[HELP_MAX]; /* help item #i activated? */
-};
-
-
-/*
- * Most of the "player" information goes here.
- *
- * This stucture gives us a large collection of player variables.
- *
- * This structure contains several "blocks" of information.
- * (1) the "permanent" info
- * (2) the "variable" info
- * (3) the "transient" info
- *
- * All of the "permanent" info, and most of the "variable" info,
- * is saved in the savefile. The "transient" info is recomputed
- * whenever anything important changes.
- */
-
-typedef struct player_type player_type;
-
-struct player_type
-{
- s32b lives; /* How many times we resurected */
-
- s16b oldpy; /* Previous player location -KMW- */
- s16b oldpx; /* Previous player location -KMW- */
-
- s16b py; /* Player location */
- s16b px; /* Player location */
-
- byte psex; /* Sex index */
- byte prace; /* Race index */
- byte pracem; /* Race Mod index */
- byte pclass; /* Class index */
- byte pspec; /* Class spec index */
- byte mimic_form; /* Actualy transformation */
- s16b mimic_level; /* Level of the mimic effect */
- byte oops; /* Unused */
-
- object_type inventory[INVEN_TOTAL]; /* Player inventory */
-
- byte hitdie; /* Hit dice (sides) */
- u16b expfact; /* Experience factor */
-
- byte maximize; /* Maximize stats */
- byte preserve; /* Preserve artifacts */
- byte special; /* Special levels */
- byte allow_one_death; /* Blood of life */
-
- s16b age; /* Characters age */
- s16b ht; /* Height */
- s16b wt; /* Weight */
- s16b sc; /* Social Class */
-
-
- s32b au; /* Current Gold */
-
- s32b max_exp; /* Max experience */
- s32b exp; /* Cur experience */
- u16b exp_frac; /* Cur exp frac (times 2^16) */
-
- s16b lev; /* Level */
-
- s16b town_num; /* Current town number */
- s16b arena_number; /* monster number in arena -KMW- */
- s16b inside_arena; /* Is character inside arena? */
- s16b inside_quest; /* Inside quest level */
- bool_ exit_bldg; /* Goal obtained in arena? -KMW- */
-
- s32b wilderness_x; /* Coordinates in the wilderness */
- s32b wilderness_y;
- bool_ wild_mode; /* TRUE = Small map, FLASE = Big map */
- bool_ old_wild_mode; /* TRUE = Small map, FLASE = Big map */
-
- s16b mhp; /* Max hit pts */
- s16b chp; /* Cur hit pts */
- u16b chp_frac; /* Cur hit frac (times 2^16) */
- s16b hp_mod; /* A modificator(permanent) */
-
- s16b msp; /* Max mana pts */
- s16b csp; /* Cur mana pts */
- u16b csp_frac; /* Cur mana frac (times 2^16) */
-
- s16b msane; /* Max sanity */
- s16b csane; /* Cur sanity */
- u16b csane_frac; /* Cur sanity frac */
-
- s32b grace; /* Your God's appreciation factor. */
- s32b grace_delay; /* Delay factor for granting piety. */
- byte pgod; /* Your God. */
- bool_ praying; /* Praying to your god. */
- s16b melkor_sacrifice; /* How much hp has been sacrified for damage */
-
- s16b max_plv; /* Max Player Level */
-
- s16b stat_max[6]; /* Current "maximal" stat values */
- s16b stat_cur[6]; /* Current "natural" stat values */
-
- s16b luck_cur; /* Current "natural" luck value (range -30 <> 30) */
- s16b luck_max; /* Current "maximal base" luck value (range -30 <> 30) */
- s16b luck_base; /* Current "base" luck value (range -30 <> 30) */
-
- s16b speed_factor; /* Timed -- Fast */
- s16b fast; /* Timed -- Fast */
- s16b lightspeed; /* Timed -- Light Speed */
- s16b slow; /* Timed -- Slow */
- s16b blind; /* Timed -- Blindness */
- s16b paralyzed; /* Timed -- Paralysis */
- s16b confused; /* Timed -- Confusion */
- s16b afraid; /* Timed -- Fear */
- s16b image; /* Timed -- Hallucination */
- s16b poisoned; /* Timed -- Poisoned */
- s16b cut; /* Timed -- Cut */
- s16b stun; /* Timed -- Stun */
-
- s16b protevil; /* Timed -- Protection from Evil*/
- s16b protgood; /* Timed -- Protection from Good*/
- s16b protundead; /* Timed -- Protection from Undead*/
- s16b invuln; /* Timed -- Invulnerable */
- s16b hero; /* Timed -- Heroism */
- s16b shero; /* Timed -- Super Heroism */
- s16b shield; /* Timed -- Shield Spell */
- s16b shield_power; /* Timed -- Shield Spell Power */
- s16b shield_opt; /* Timed -- Shield Spell options */
- s16b shield_power_opt; /* Timed -- Shield Spell Power */
- s16b shield_power_opt2; /* Timed -- Shield Spell Power */
- s16b blessed; /* Timed -- Blessed */
- s16b tim_invis; /* Timed -- See Invisible */
- s16b tim_infra; /* Timed -- Infra Vision */
-
- s16b oppose_acid; /* Timed -- oppose acid */
- s16b oppose_elec; /* Timed -- oppose lightning */
- s16b oppose_fire; /* Timed -- oppose heat */
- s16b oppose_cold; /* Timed -- oppose cold */
- s16b oppose_pois; /* Timed -- oppose poison */
- s16b oppose_ld; /* Timed -- oppose light & dark */
- s16b oppose_cc; /* Timed -- oppose chaos & confusion */
- s16b oppose_ss; /* Timed -- oppose sound & shards */
- s16b oppose_nex; /* Timed -- oppose nexus */
-
- s16b rush; /* Rush and Bush */
-
- s16b tim_esp; /* Timed ESP */
- s16b tim_wraith; /* Timed wraithform */
- s16b tim_ffall; /* Timed Levitation */
- s16b tim_fly; /* Timed Levitation */
- s16b tim_fire_aura; /* Timed Fire Aura */
- s16b tim_poison; /* Timed poison hands */
- s16b tim_thunder; /* Timed thunderstorm */
- s16b tim_thunder_p1; /* Timed thunderstorm */
- s16b tim_thunder_p2; /* Timed thunderstorm */
-
- s16b tim_project; /* Timed project upon melee blow */
- s16b tim_project_dam;
- s16b tim_project_gf;
- s16b tim_project_rad;
- s16b tim_project_flag;
-
- s16b tim_roots; /* Timed roots */
- s16b tim_roots_ac;
- s16b tim_roots_dam;
-
- s16b resist_magic; /* Timed Resist Magic (later) */
- s16b tim_invisible; /* Timed Invisibility */
- s16b tim_inv_pow; /* Power of timed invisibility */
- s16b tim_mimic; /* Timed Mimic */
- s16b tim_lite; /* Timed Lite */
- s16b tim_regen; /* Timed extra regen */
- s16b tim_regen_pow; /* Timed extra regen power */
- s16b holy; /* Holy Aura */
- s16b walk_water; /* Walk over water as a god */
- s16b tim_mental_barrier; /* Sustain Int&Wis */
- s16b strike; /* True Strike(+25 hit) */
- s16b meditation; /* Meditation(+50 mana -25 to hit/to dam) */
- s16b tim_reflect; /* Timed Reflection */
- s16b tim_res_time; /* Timed Resistance to Time */
- s16b tim_deadly; /* Timed deadly blow */
- s16b prob_travel; /* Timed probability travel */
- s16b disrupt_shield;/* Timed disruption shield */
- s16b parasite; /* Timed parasite */
- s16b parasite_r_idx;/* Timed parasite monster */
- s32b loan; /* Amount of loan */
- s32b loan_time; /* Timer -- time to payback loan */
- s16b absorb_soul; /* Timed soul absordtion */
- s16b tim_magic_breath; /* Magical breathing -- can breath anywhere */
- s16b tim_water_breath; /* Water breathing -- can breath underwater */
- s16b tim_precognition; /* Timed precognition */
-
- s16b immov_cntr; /* Timed -- Last ``immovable'' command. */
-
- s16b recall_dungeon; /* Recall in which dungeon */
- s16b word_recall; /* Word of recall counter */
-
- s32b energy; /* Current energy */
-
- s16b food; /* Current nutrition */
-
- byte confusing; /* Glowing hands */
- byte searching; /* Currently searching */
-
- s16b new_spells; /* Number of spells available */
-
- s16b old_spells;
-
- s16b xtra_spells; /* Number of xtra spell learned(via potion) */
-
- bool_ old_cumber_armor;
- bool_ old_cumber_glove;
- bool_ old_heavy_wield;
- bool_ old_heavy_shoot;
- bool_ old_icky_wield;
-
- s16b old_lite; /* Old radius of lite (if any) */
- s16b old_view; /* Old radius of view (if any) */
-
- s16b old_food_aux; /* Old value of food */
-
-
- bool_ cumber_armor; /* Mana draining armor */
- bool_ cumber_glove; /* Mana draining gloves */
- bool_ heavy_wield; /* Heavy weapon */
- bool_ heavy_shoot; /* Heavy shooter */
- bool_ icky_wield; /* Icky weapon */
- bool_ immovable; /* Immovable character */
-
- s16b cur_lite; /* Radius of lite (if any) */
-
-
- u32b notice; /* Special Updates (bit flags) */
- u32b update; /* Pending Updates (bit flags) */
- u32b redraw; /* Normal Redraws (bit flags) */
- u32b window; /* Window Redraws (bit flags) */
-
- s16b stat_use[6]; /* Current modified stats */
- s16b stat_top[6]; /* Maximal modified stats */
-
- s16b stat_add[6]; /* Modifiers to stat values */
- s16b stat_ind[6]; /* Indexes into stat tables */
- s16b stat_cnt[6]; /* Counter for temporary drains */
- s16b stat_los[6]; /* Amount of temporary drains */
-
- bool_ immune_acid; /* Immunity to acid */
- bool_ immune_elec; /* Immunity to lightning */
- bool_ immune_fire; /* Immunity to fire */
- bool_ immune_cold; /* Immunity to cold */
- bool_ immune_neth; /* Immunity to nether */
-
- bool_ resist_acid; /* Resist acid */
- bool_ resist_elec; /* Resist lightning */
- bool_ resist_fire; /* Resist fire */
- bool_ resist_cold; /* Resist cold */
- bool_ resist_pois; /* Resist poison */
-
- bool_ resist_conf; /* Resist confusion */
- bool_ resist_sound; /* Resist sound */
- bool_ resist_lite; /* Resist light */
- bool_ resist_dark; /* Resist darkness */
- bool_ resist_chaos; /* Resist chaos */
- bool_ resist_disen; /* Resist disenchant */
- bool_ resist_shard; /* Resist shards */
- bool_ resist_nexus; /* Resist nexus */
- bool_ resist_blind; /* Resist blindness */
- bool_ resist_neth; /* Resist nether */
- bool_ resist_fear; /* Resist fear */
- bool_ resist_continuum; /* Resist space-time continuum disruption */
-
- bool_ sensible_fire; /* Fire does more damage on the player */
- bool_ sensible_lite; /* Lite does more damage on the player and blinds her/him */
-
- bool_ reflect; /* Reflect 'bolt' attacks */
- bool_ sh_fire; /* Fiery 'immolation' effect */
- bool_ sh_elec; /* Electric 'immolation' effect */
- bool_ wraith_form; /* wraithform */
-
- bool_ anti_magic; /* Anti-magic */
- bool_ anti_tele; /* Prevent teleportation */
-
- bool_ sustain_str; /* Keep strength */
- bool_ sustain_int; /* Keep intelligence */
- bool_ sustain_wis; /* Keep wisdom */
- bool_ sustain_dex; /* Keep dexterity */
- bool_ sustain_con; /* Keep constitution */
- bool_ sustain_chr; /* Keep charisma */
-
- bool_ aggravate; /* Aggravate monsters */
- bool_ teleport; /* Random teleporting */
-
- bool_ exp_drain; /* Experience draining */
- byte drain_mana; /* mana draining */
- byte drain_life; /* hp draining */
-
- bool_ magical_breath; /* Magical breathing -- can breath anywhere */
- bool_ water_breath; /* Water breathing -- can breath underwater */
- bool_ climb; /* Can climb mountains */
- bool_ fly; /* Can fly over some features */
- bool_ ffall; /* No damage falling */
- bool_ lite; /* Permanent light */
- bool_ free_act; /* Never paralyzed */
- bool_ see_inv; /* Can see invisible */
- bool_ regenerate; /* Regenerate hit pts */
- bool_ hold_life; /* Resist life draining */
- u32b telepathy; /* Telepathy */
- bool_ slow_digest; /* Slower digestion */
- bool_ bless_blade; /* Blessed blade */
- byte xtra_might; /* Extra might bow */
- bool_ impact; /* Earthquake blows */
- bool_ auto_id; /* Auto id items */
-
- s16b invis; /* Invisibility */
-
- s16b dis_to_h; /* Known bonus to hit */
- s16b dis_to_d; /* Known bonus to dam */
- s16b dis_to_a; /* Known bonus to ac */
-
- s16b dis_ac; /* Known base ac */
-
- s16b to_l; /* Bonus to life */
- s16b to_m; /* Bonus to mana */
- s16b to_s; /* Bonus to spell */
- s16b to_h; /* Bonus to hit */
- s16b to_d; /* Bonus to dam */
- s16b to_h_melee; /* Bonus to hit for melee */
- s16b to_d_melee; /* Bonus to dam for melee */
- s16b to_h_ranged; /* Bonus to hit for ranged */
- s16b to_d_ranged; /* Bonus to dam for ranged */
- s16b to_a; /* Bonus to ac */
-
- s16b ac; /* Base ac */
-
- byte antimagic; /* Power of the anti magic field */
- byte antimagic_dis; /* Radius of the anti magic field */
-
- s16b see_infra; /* Infravision range */
-
- s16b skill_dis; /* Skill: Disarming */
- s16b skill_dev; /* Skill: Magic Devices */
- s16b skill_sav; /* Skill: Saving throw */
- s16b skill_stl; /* Skill: Stealth factor */
- s16b skill_srh; /* Skill: Searching ability */
- s16b skill_fos; /* Skill: Searching frequency */
- s16b skill_thn; /* Skill: To hit (normal) */
- s16b skill_thb; /* Skill: To hit (shooting) */
- s16b skill_tht; /* Skill: To hit (throwing) */
- s16b skill_dig; /* Skill: Digging */
-
- s16b num_blow; /* Number of blows */
- s16b num_fire; /* Number of shots */
- s16b xtra_crit; /* % of increased crits */
-
- byte throw_mult; /* Multiplier for throw damage */
-
- byte tval_xtra; /* Correct xtra tval */
-
- byte tval_ammo; /* Correct ammo tval */
-
- s16b pspeed; /* Current speed */
-
- u32b mimic_extra; /* Mimicry powers use that */
- u32b antimagic_extra; /* Antimagic powers */
- u32b druid_extra; /* Druid powers */
- u32b druid_extra2; /* Druid powers */
- u32b druid_extra3; /* Druid powers */
- u32b music_extra; /* Music songs */
- u32b music_extra2; /* Music songs */
- u32b necro_extra; /* Necro powers */
- u32b necro_extra2; /* Necro powers */
-
- u32b race_extra1; /* Variable for race */
- u32b race_extra2; /* Variable for race */
- u32b race_extra3; /* Variable for race */
- u32b race_extra4; /* Variable for race */
- u32b race_extra5; /* Variable for race */
- u32b race_extra6; /* Variable for race */
- u32b race_extra7; /* Variable for race */
-
- s16b dodge_chance; /* Dodging chance */
-
- u32b maintain_sum; /* Do we have partial summons */
-
- byte spellbinder_num; /* Number of spells bound */
- u32b spellbinder[4]; /* Spell bounds */
- byte spellbinder_trigger; /* Spellbinder trigger condition */
-
- cptr mimic_name;
-
- char tactic; /* from 128-4 extremely coward to */
- /* 128+4 berserker */
- char movement; /* base movement way */
-
- s16b companion_killed; /* Number of companion death */
-
- bool_ no_mortal; /* Fated to never die by the hand of a mortal being */
-
- bool_ black_breath; /* The Tolkien's Black Breath */
-
- bool_ precognition; /* Like the cheat mode */
-
- /*** Extra flags -- used for lua and easying stuff ***/
- u32b xtra_f1;
- u32b xtra_f2;
- u32b xtra_f3;
- u32b xtra_f4;
- u32b xtra_f5;
- u32b xtra_esp;
-
- /* Corruptions */
- bool_ corruptions[CORRUPTIONS_MAX];
- bool_ corrupt_anti_teleport_stopped;
-
- /*** Pet commands ***/
- byte pet_follow_distance; /* Length of the imaginary "leash" for pets */
- byte pet_open_doors; /* flag - allow pets to open doors */
- byte pet_pickup_items; /* flag - allow pets to pickup items */
-
- s16b control; /* Controlled monster */
- byte control_dir; /* Controlled monster */
-
- /*** Body changing variables ***/
- u16b body_monster; /* In which body is the player */
- bool_ disembodied; /* Is the player in a body ? */
- byte body_parts[INVEN_TOTAL - INVEN_WIELD]; /* Which body parts does he have ? */
-
- /* Astral */
- bool_ astral; /* We started at the bottom ? */
-
- /* Powers */
- bool_ powers[POWER_MAX]; /* Actual powers */
- bool_ powers_mod[POWER_MAX]; /* Intrinsinc powers */
-
- /* Skills */
- s16b skill_points;
- s16b skill_last_level; /* Prevents gaining skills by losing level and regaining them */
- s16b melee_style; /* How are */
- s16b use_piercing_shots; /* for archery */
-
- /* Dripping Tread spell timer */
- s16b dripping_tread;
-
- /* Help */
- help_info help;
-
- /* Inertia control */
- s32b inertia_controlled_spell;
-
- /* For automatic stat-gain */
- s16b last_rewarded_level;
-
- /*** Temporary fields ***/
-
- bool_ did_nothing; /* True if the last action wasnt a real action */
- bool_ leaving; /* True if player is leaving */
-};
-
-
-/* For Monk martial arts */
-
-typedef struct martial_arts martial_arts;
-
-struct martial_arts
-{
- cptr desc; /* A verbose attack description */
- int min_level; /* Minimum level to use */
- int chance; /* Chance of 'success' */
- int dd; /* Damage dice */
- int ds; /* Damage sides */
- s16b effect; /* Special effects */
- s16b power; /* Special effects power */
-};
-
-
-
-/* Powers - used by Mindcrafters and Necromancers */
-typedef struct magic_power magic_power;
-
-struct magic_power
-{
- int min_lev;
- int mana_cost;
- int fail;
- cptr name;
- cptr desc;
-};
-
-/* Border */
-typedef struct border_type border_type;
-
-struct border_type
-{
- byte north[MAX_WID];
- byte south[MAX_WID];
- byte east[MAX_HGT];
- byte west[MAX_HGT];
- byte north_west;
- byte north_east;
- byte south_west;
- byte south_east;
-};
-
-
-/*
- * A structure describing a wilderness area
- * with a terrain, a town or a dungeon entrance
- */
-typedef struct wilderness_type_info wilderness_type_info;
-
-struct wilderness_type_info
-{
- u32b name; /* Name (offset) */
- u32b text; /* Text (offset) */
- u16b entrance; /* Which town is there(<1000 i's a town, >=1000 it a dungeon) */
- s32b wild_x; /* Map coordinates (backed out while parsing map) */
- s32b wild_y;
- byte road; /* Flags of road */
- int level; /* Difficulty level */
- u32b flags1; /* Some flags */
- byte feat; /* The feature of f_info.txt that is used to allow passing, ... and to get a char/color/graph */
- byte terrain_idx; /* Terrain index(defined in defines.h) */
-
- byte terrain[MAX_WILD_TERRAIN];/* Feature types for the plasma generator */
-};
-
-/*
- * A structure describing a wilderness map
- */
-typedef struct wilderness_map wilderness_map;
-
-struct wilderness_map
-{
- int feat; /* Wilderness feature */
- u32b seed; /* Seed for the RNG */
- u16b entrance; /* Entrance for dungeons */
-
- bool_ known; /* Is it seen by the player ? */
-};
-
-/*
- * A structure describing a town with
- * stores and buildings
- */
-typedef struct town_type town_type;
-struct town_type
-{
- cptr name;
- u32b seed; /* Seed for RNG */
- store_type *store; /* The stores [max_st_idx] */
- byte numstores;
-
- byte flags; /* Town flags */
- /* Left this for the sake of compatibility */
- bool_ stocked; /* Is the town actualy stocked ? */
-
- bool_ destroyed; /* Is the town destroyed? */
-};
-
-
-/* Alchemists */
-
-typedef struct tval_desc2
-{
- int tval;
- cptr desc;
-} tval_desc2;
-
-typedef struct alchemist_recipe alchemist_recipe;
-struct alchemist_recipe
-{
- int sval_essence;
- byte tval;
- byte sval;
- byte qty;
-};
-
-typedef struct artifact_select_flag artifact_select_flag;
-struct artifact_select_flag {
- byte group; /* Flag group to display it in */
- int flag; /* item flag to set */
- byte level; /* Player skill level to start at */
- int desc; /* Display this description to select flag */
- u32b xp; /* xp cost for this flag */
- bool_ pval; /* indicates this flag benifits from pval */
- int item_desc; /* Description of required item */
- int item_descp; /* Description of required item */
- byte rtval; /* Required items' tval */
- byte rsval; /* Required items' sval */
- int rpval; /* Required items' pval (zero for no req) */
- int rflag[6]; /* Monster Race flags for required Corpses */
-};
-
-/*
- A structure for deity information.
- */
-typedef struct deity_type deity_type;
-struct deity_type
-{
- int modules[3]; /* terminated with -1 */
- cptr name;
- char desc[10][80];
-};
-
-/* A structure for tactics */
-typedef struct tactic_info_type tactic_info_type;
-
-struct tactic_info_type
-{
- s16b to_hit;
- s16b to_dam;
- s16b to_ac;
- s16b to_stealth;
- s16b to_disarm;
- s16b to_saving;
- cptr name;
-};
-
-/* A structure to describe a random artifact. */
-typedef struct random_artifact random_artifact;
-
-struct random_artifact
-{
- char name_full[80]; /* Full name for the artifact */
- char name_short[80]; /* Un-Id'd name */
- byte level; /* Level of the artifact */
- byte attr; /* Color that is used on the screen */
- u32b cost; /* Object's value */
- byte activation; /* Activation. */
- s16b timeout; /* Timeout. */
- byte generated; /* Does it exist already? */
-};
-
-/* A structure to describe an activation. */
-typedef struct activation activation;
-
-struct activation
-{
- char desc[80]; /* Desc of the activation */
- u32b cost; /* costs value */
- s16b spell; /* Spell. */
-};
-
-/* A structure to describe a music. */
-typedef struct music music;
-
-struct music
-{
- char desc[80]; /* Desc of the music */
- s16b music; /* Music. */
- s16b dur; /* Duration(if any) */
- s16b init_recharge; /* Minimal recharge time */
- s16b turn_recharge; /* Recharge time for each more turn */
- byte min_inst; /* Minimum instrument for the music */
- byte rarity; /* Rarity of the music(use 100 to unallow to be randomly generated) */
-};
-
-/* A structure to describe the random spells of the Power Mages */
-typedef struct random_spell random_spell;
-
-struct random_spell
-{
- char desc[30]; /* Desc of the spell */
- char name[30]; /* Name of the spell */
- s16b mana; /* Mana cost */
- s16b fail; /* Failure rate */
- u32b proj_flags; /* Project function flags */
- byte GF; /* Type of the projection */
- byte radius;
- byte dam_sides;
- byte dam_dice;
- byte level; /* Level needed */
- bool_ untried; /* Is the spell was tried? */
-};
-
-/* A structure to describe the fate of the player */
-typedef struct fate fate;
-
-struct fate
-{
- byte fate; /* Which fate */
- byte level; /* On which level */
- byte serious; /* Is it sure? */
- s16b o_idx; /* Object to find */
- s16b e_idx; /* Ego-Item to find */
- s16b a_idx; /* Artifact to find */
- s16b v_idx; /* Vault to find */
- s16b r_idx; /* Monster to find */
- s16b count; /* Number of things */
- s16b time; /* Turn before */
- bool_ know; /* Has it been predicted? */
- bool_ icky; /* Hackish runtime-only flag */
-};
-
-/* A structure for movements */
-typedef struct move_info_type move_info_type;
-
-struct move_info_type
-{
- s16b to_speed;
- s16b to_search;
- s16b to_stealth;
- s16b to_percep;
- cptr name;
-};
-
-/* Define monster generation rules */
-typedef struct rule_type rule_type;
-struct rule_type
-{
- byte mode; /* Mode of combination of the monster flags */
- byte percent; /* Percent of monsters affected by the rule */
-
- u32b mflags1; /* The monster flags that are allowed */
- u32b mflags2;
- u32b mflags3;
- u32b mflags4;
- u32b mflags5;
- u32b mflags6;
- u32b mflags7;
- u32b mflags8;
- u32b mflags9;
-
- char r_char[5]; /* Monster race allowed */
-};
-
-/* A structure for the != dungeon types */
-typedef struct dungeon_info_type dungeon_info_type;
-struct dungeon_info_type
-{
- u32b name; /* Name */
- u32b text; /* Description */
- char short_name[3]; /* Short name */
-
- char generator[30]; /* Name of the level generator */
-
- s16b floor1; /* Floor tile 1 */
- byte floor_percent1[2]; /* Chance of type 1 */
- s16b floor2; /* Floor tile 2 */
- byte floor_percent2[2]; /* Chance of type 2 */
- s16b floor3; /* Floor tile 3 */
- byte floor_percent3[2]; /* Chance of type 3 */
- s16b outer_wall; /* Outer wall tile */
- s16b inner_wall; /* Inner wall tile */
- s16b fill_type1; /* Cave tile 1 */
- byte fill_percent1[2]; /* Chance of type 1 */
- s16b fill_type2; /* Cave tile 2 */
- byte fill_percent2[2]; /* Chance of type 2 */
- s16b fill_type3; /* Cave tile 3 */
- byte fill_percent3[2]; /* Chance of type 3 */
- byte fill_method; /* Smoothing parameter for the above */
-
- s16b mindepth; /* Minimal depth */
- s16b maxdepth; /* Maximal depth */
-
- bool_ principal; /* If it's a part of the main dungeon */
- byte next; /* The next part of the main dungeon */
- byte min_plev; /* Minimal plev needed to enter -- it's an anti-cheating mesure */
-
- int min_m_alloc_level; /* Minimal number of monsters per level */
- int max_m_alloc_chance; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */
-
- u32b flags1; /* Flags 1 */
- u32b flags2; /* Flags 1 */
-
- int size_x, size_y; /* Desired numers of panels */
-
- byte rule_percents[100]; /* Flat rule percents */
- rule_type rules[5]; /* Monster generation rules */
-
- int final_object; /* The object you'll find at the bottom */
- int final_artifact; /* The artifact you'll find at the bottom */
- int final_guardian; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */
-
- int ix, iy, ox, oy; /* Wilderness coordinates of the entrance/output of the dungeon */
-
- obj_theme objs; /* The drops type */
-
- int d_dice[4]; /* Number of dices */
- int d_side[4]; /* Number of sides */
- int d_frequency[4]; /* Frequency of damage (1 is the minimum) */
- int d_type[4]; /* Type of damage */
-
- s16b t_idx[TOWN_DUNGEON]; /* The towns */
- s16b t_level[TOWN_DUNGEON]; /* The towns levels */
- s16b t_num; /* Number of towns */
-};
-
-/* A structure for inscriptions */
-typedef struct inscription_info_type inscription_info_type;
-struct inscription_info_type
-{
- char text[40]; /* The inscription itself */
- byte when; /* When it is executed */
- bool_ know; /* Is the inscription know ? */
- byte mana; /* Grid mana needed */
-};
-
-/* To hold Runecrafters prefered spells */
-typedef struct rune_spell rune_spell;
-struct rune_spell
-{
- char name[30]; /* name */
-
- s16b type; /* Type of the spell(GF) */
- s16b rune2; /* Modifiers */
- s16b mana; /* Mana involved */
-};
-
-/* For level gaining artifacts, artifact creation, ... */
-typedef struct flags_group flags_group;
-struct flags_group
-{
- char name[30]; /* Name */
- byte color; /* Color */
-
- byte price; /* Price to "buy" it */
-
- u32b flags1; /* Flags set 1 */
- u32b flags2; /* Flags set 2 */
- u32b flags3; /* Flags set 3 */
- u32b flags4; /* Flags set 4 */
- u32b esp; /* ESP flags set */
-};
-
-/* For powers(racial, class, mutation, artifacts, ... */
-typedef struct power_type power_type;
-struct power_type
-{
- char *name; /* Name */
- char *desc_text; /* Text describing power */
- char *gain_text; /* Text displayed on gaining the power */
- char *lose_text; /* Text displayed on losing the power */
-
- byte level; /* Min level */
- byte cost; /* Mana/Life cost */
- byte stat; /* Stat used */
- byte diff; /* Difficulty */
-};
-
-/* Hooks */
-typedef bool_ (*hook_type)(char *fmt);
-
-typedef struct hook_move_in hook_move_in;
-struct hook_move_in {
- int y;
- int x;
-};
-
-typedef struct hook_get_in hook_get_in;
-struct hook_get_in {
- object_type *o_ptr;
- int o_idx;
-};
-
-typedef struct hook_end_turn_in hook_end_turn_in;
-struct hook_end_turn_in {
- bool_ is_quest;
-};
-
-typedef struct hook_player_level_in hook_player_level_in;
-struct hook_player_level_in {
- int gained_levels;
-};
-
-typedef enum { IDENT_NORMAL, IDENT_FULL } identify_mode;
-
-typedef struct hook_identify_in hook_identify_in;
-struct hook_identify_in {
- object_type *o_ptr;
- identify_mode mode;
-};
-
-typedef struct hook_give_in hook_give_in;
-struct hook_give_in {
- int m_idx;
- int item;
-};
-
-typedef struct hook_eat_in hook_eat_in;
-struct hook_eat_in {
- object_type *o_ptr;
-};
-
-typedef struct hook_eat_out hook_eat_out;
-struct hook_eat_out {
- bool_ ident;
-};
-
-typedef enum { STAIRS_UP, STAIRS_DOWN } stairs_direction;
-
-typedef struct hook_stair_in hook_stair_in;
-struct hook_stair_in {
- stairs_direction direction;
-};
-
-typedef struct hook_stair_out hook_stair_out;
-struct hook_stair_out {
- bool_ allow;
-};
-
-typedef struct hook_new_monster_end_in hook_new_monster_end_in;
-struct hook_new_monster_end_in {
- monster_type *m_ptr;
-};
-
-/*
- * Structure for the "quests"
- */
-typedef struct quest_type quest_type;
-
-struct quest_type
-{
- bool_ silent;
-
- char name[40]; /* Quest name */
-
- char desc[10][80]; /* Quest desc */
-
- s16b status; /* Is the quest taken, completed, finished? */
-
- s16b level; /* Dungeon level */
-
- s16b *plot; /* Which plot does it belongs to? */
-
- bool_ (*init)(int q); /* Function that takes care of generating hardcoded quests */
-
- s32b data[9]; /* Various datas used by the quests */
-
- bool_ (*gen_desc)(FILE *fff); /* Function for generating description. */
-};
-typedef struct random_quest random_quest;
-struct random_quest
-{
- byte type; /* Type/number of monsters to kill(0 = no quest) */
- s16b r_idx; /* Monsters to crush */
- bool_ done; /* Done ? */
-};
-
-/* Monster powers for player uses */
-typedef struct monster_power monster_power;
-struct monster_power
-{
- u32b power; /* Power RF?_xxx */
- cptr name; /* Name of it */
- int mana; /* Mana needed */
- bool_ great; /* Need the use of great spells */
-};
-
-/* Tval descs */
-typedef struct tval_desc tval_desc;
-struct tval_desc
-{
- int tval; /* tval */
- cptr desc; /* desc */
-};
-
-/*
- * Between exit
- */
-typedef struct between_exit between_exit;
-struct between_exit
-{
- s16b corresp; /* Corresponding between gate */
- bool_ dungeon; /* Do we exit in a dungeon or in the wild ? */
-
- s16b wild_x, wild_y; /* Wilderness spot to land onto */
- s16b px, py; /* Location of the map */
-
- s16b d_idx; /* Dungeon to land onto */
- s16b level;
-};
-
-/*
- * A structure to hold "rolled" information
- */
-typedef struct birther birther;
-struct birther
-{
- s16b sex;
- s16b race;
- s16b rmod;
- s16b pclass;
- s16b spec;
-
- byte quests;
-
- byte god;
- s32b grace;
- s32b god_favor;
-
- s16b age;
- s16b wt;
- s16b ht;
- s16b sc;
-
- s32b au;
-
- s16b stat[6];
- s16b luck;
-
- s16b chaos_patron;
-
- u32b weapon;
-
- char history[4][60];
-
- bool_ quick_ok;
-};
-
-typedef struct hooks_chain hooks_chain;
-struct hooks_chain
-{
- hook_type hook;
- bool_ (*hook_f)(void *, void *, void *);
- void *hook_data;
- char name[40];
- char script[40];
- byte type;
- hooks_chain *next;
-};
-
-typedef union hook_return hook_return;
-union hook_return
-{
- s32b num;
- cptr str;
- object_type *o_ptr;
- monster_type *m_ptr;
-};
-
-/*
- * Forward declare
- */
-typedef struct hist_type hist_type;
-
-/*
- * Player background information
- */
-struct hist_type
-{
- s32b info; /* Textual History -- uses rp_text */
-
- byte roll; /* Frequency of this entry */
- s16b chart; /* Chart index */
- s16b next; /* Next chart index */
- byte bonus; /* Social Class Bonus + 50 */
-};
-
-/*
- * Item sets
- */
-typedef struct set_type set_type;
-struct set_type
-{
- u32b name; /* Name */
- u32b desc; /* Desc */
-
- byte num; /* Number of artifacts used */
- byte num_use; /* Number actually wore */
- struct /* the various items */
- {
- bool_ present; /* Is it actually wore ? */
- s16b a_idx; /* What artifact ? */
- s16b pval[6]; /* Pval for each combination */
- u32b flags1[6]; /* Flags */
- u32b flags2[6]; /* Flags */
- u32b flags3[6]; /* Flags */
- u32b flags4[6]; /* Flags */
- u32b flags5[6]; /* Flags */
- u32b esp[6]; /* Flags */
- } arts[6];
-};
-
-/* A structure for CLI commands. */
-typedef struct cli_comm cli_comm;
-struct cli_comm
-{
- cptr comm; /* Extended name of the command. */
- cptr descrip; /* Description of the command. */
- s16b key; /* Key to convert command to. */
-};
-
-/*
- * Range
- */
-typedef struct range_type range_type;
-struct range_type
-{
- s32b min;
- s32b max;
-};
-
-/*
- * Dice
- */
-typedef struct dice_type dice_type;
-struct dice_type
-{
- long base; /* Base value to which roll is added. */
- long num; /* Number of dice */
- long sides; /* Sides per dice */
-};
-
-/*
- * Device allocation for skill
- */
-typedef struct device_allocation device_allocation;
-struct device_allocation
-{
- byte tval;
- s32b rarity;
- range_type base_level;
- range_type max_level;
- /* Next device allocation in the list */
- device_allocation *next;
-};
-
-int compare_device_allocation(device_allocation *a, device_allocation *b);
-SGLIB_DEFINE_LIST_PROTOTYPES(device_allocation, compare_device_allocation, next);
-
-
-/*
- * Skills !
- */
-typedef struct skill_type skill_type;
-struct skill_type
-{
- u32b name; /* Name */
- u32b desc; /* Description */
- u32b action_desc; /* Action Description */
-
- s16b action_mkey; /* Action do to */
-
- s32b i_value; /* Actual value */
- s32b i_mod; /* Modifier(1 skill point = modifier skill) */
-
- s32b value; /* Actual value */
- s32b mod; /* Modifier(1 skill point = modifier skill) */
- s16b rate; /* Modifier decreasing rate */
-
- u32b uses; /* Number of times used */
-
- s16b action[MAX_SKILLS]; /* List of actions against other skills */
-
- s16b father; /* Father in the skill tree */
- bool_ dev; /* Is the branch developped ? */
- s16b order; /* Order in the tree */
- bool_ hidden; /* Innactive */
-
- byte random_gain_chance; /* random gain chance, still needs the flag */
-
- u32b flags1; /* Skill flags */
-};
-
-typedef struct school_provider school_provider;
-struct school_provider
-{
- byte deity_idx; /* Deity which provides school levels */
-
- s16b skill_idx; /* Skill used for determining the boost */
-
- long mul; /* Multiplier */
-
- long div; /* Divisor */
-
- school_provider *next; /* Next provider in list */
-};
-
-typedef struct school_type school_type;
-struct school_type
-{
- cptr name; /* Name */
- s16b skill; /* Skill used for that school */
- bool_ spell_power; /* Does spell power affect spells in this school? */
- bool_ sorcery; /* Does Sorcery affect this school? */
-
- int deity_idx; /* Deity; if <=0, no deity required */
- deity_type *deity; /* Direct pointer to deity */
-
- int (*bonus_levels)(); /* Calculate number of bonus levels */
-
- bool_ (*depends_satisfied)(); /* Are dependendies satisfied? */
-
- school_provider *providers; /* List of secondary providers of this school */
-};
-
-/*
- * Spell index list.
- */
-typedef struct spell_idx_list spell_idx_list;
-struct spell_idx_list {
- s32b i; /* Spell index */
- spell_idx_list *next; /* for list */
-};
-
-/*
- * School book.
- */
-typedef struct school_book_type school_book_type;
-struct school_book_type {
- spell_idx_list *spell_idx_list;
-};
-
-/*
- * Desc for GF_FOO
- */
-typedef struct gf_name_type gf_name_type;
-struct gf_name_type
-{
- int gf;
- cptr name;
-};
-
-/*
- * Timers
- */
-typedef struct timer_type timer_type;
-struct timer_type
-{
- timer_type *next; /* The next timer in the list */
-
- bool_ enabled; /* Is it currently counting? */
-
- s32b delay; /* Delay between activations */
- s32b countdown; /* The current number of turns passed, when it reaches delay it fires */
-
- void (*callback)(); /* The C function to call upon firing */
-};
-
-/*
- * Abilities
- */
-typedef struct ability_type ability_type;
-struct ability_type
-{
- u32b name; /* Name */
- u32b desc; /* Description */
- u32b action_desc; /* Action Description */
-
- s16b action_mkey; /* Action do to */
-
- s16b cost; /* Skill points cost */
-
- bool_ acquired; /* Do the player actualylg ot it ? */
-
- /* Prereqs */
- s16b skills[10]; /* List of prereq skills(10 max) */
- s16b skill_levels[10]; /* List of prereq skills(10 max) */
- s16b stat[6]; /* List of prereq stats */
- s16b need_abilities[10]; /* List of prereq abilities(10 max) */
- s16b forbid_abilities[10]; /* List of forbidden abilities(10 max) */
-};
-
-/**
- * Module metadata
- */
-typedef struct module_meta_type module_meta_type;
-struct module_meta_type
-{
- /* Module name */
- cptr name;
-
- /* Module version number */
- struct {
- s32b major;
- s32b minor;
- s32b patch;
- } version;
-
- /* Module author */
- struct {
- cptr name;
- cptr email;
- } author;
-
- /* Module description */
- cptr desc;
-
- /* Save file tag */
- cptr save_file_tag;
-
- /* Module directory */
- cptr module_dir;
-};
-
-/**
- * Modules
- */
-typedef struct module_type module_type;
-struct module_type
-{
- /* Metadata about the module: author, description, etc. */
- module_meta_type meta;
-
- /* Random artifact generation chances */
- struct {
- s32b weapon_chance;
- s32b armor_chance;
- s32b jewelry_chance;
- } randarts;
-
- /* Max player level. */
- int max_plev;
-
- /* Skills */
- struct {
- /* Skill points per level */
- s32b skill_per_level;
- /* Maximum "overage" for skill points, i.e. how many skill
- points you can go above your current level. */
- s32b max_skill_overage;
- } skills;
-
- /* Function to show introduction to module */
- void (*intro)();
-
- /* Function to compute race status, i.e. whether monsters
- are friendly/neutral towards the player. Returns NULL
- to indicate that no override happens. */
- s16b *(*race_status)(int r_idx);
-};
-
-/**
- * Corruptions
- */
-typedef struct corruption_type corruption_type;
-struct corruption_type
-{
- int modules[3]; /* Modules where this corruption is available; terminated with -1 entry */
- byte color;
- cptr group;
- cptr name;
- cptr get_text;
- cptr lose_text; /* If NULL, the corruption is NOT removable by any means */
- cptr desc;
- s16b depends[5]; /* terminated by a -1 entry */
- s16b opposes[5]; /* terminated by a -1 entry */
- void (*gain_callback)(); /* callback to invoke when gained */
- s16b power; /* index of granted power if >= 0, ignored otherwise */
-};
-
-/**
- * Mimicry forms
- */
-typedef struct mimic_duration_type mimic_duration_type;
-struct mimic_duration_type
-{
- s16b min;
- s16b max;
-};
-
-typedef struct mimic_form_type mimic_form_type;
-struct mimic_form_type
-{
- int modules[3]; /* Modules where this mimicry form is available; terminated with a -1 entry */
- cptr name; /* Name of mimicry form */
- cptr obj_name; /* Object mimicry form name */
- cptr desc; /* Description */
- cptr realm; /* Realm of mimicry */
- bool_ limit; /* If true, the form is not available except through special means */
- byte level;
- byte rarity;
- mimic_duration_type duration;
- s32b (*calc)(); /* Callback to calculate bonuses; return number of blows to add */
- void (*power)(); /* Callback to calculate powers */
-};
diff --git a/src/util.c b/src/util.cc
index ba52c89b..675a02d1 100644
--- a/src/util.c
+++ b/src/util.cc
@@ -2,113 +2,36 @@
/* Purpose: Angband utilities -BEN- */
-
-#include "angband.h"
-
-#include "messages.h"
-#include "quark.h"
-
-
-
-#ifndef HAS_MEMSET
-
-/*
-* For those systems that don't have "memset()"
-*
-* Set the value of each of 'n' bytes starting at 's' to 'c', return 's'
-* If 'n' is negative, you will erase a whole lot of memory.
-*/
-char *memset(char *s, int c, huge n)
-{
- char *t;
- for (t = s; len--; ) *t++ = c;
- return (s);
-}
-
-#endif
-
-
-
-#ifndef HAS_STRICMP
-
-/*
-* For those systems that don't have "stricmp()"
-*
-* Compare the two strings "a" and "b" ala "strcmp()" ignoring case.
-*/
-int stricmp(cptr a, cptr b)
-{
- cptr s1, s2;
- char z1, z2;
-
- /* Scan the strings */
- for (s1 = a, s2 = b; TRUE; s1++, s2++)
- {
- z1 = FORCEUPPER(*s1);
- z2 = FORCEUPPER(*s2);
- if (z1 < z2) return ( -1);
- if (z1 > z2) return (1);
- if (!z1) return (0);
- }
-}
-
-#endif
-
-
-#ifdef SET_UID
-
-# ifndef HAS_USLEEP
-
-/*
-* For those systems that don't have "usleep()" but need it.
-*
-* Fake "usleep()" function grabbed from the inl netrek server -cba
-*/
-int usleep(huge usecs)
-{
- struct timeval Timer;
-
- int nfds = 0;
-
-#ifdef FD_SET
- fd_set *no_fds = NULL;
-#else
-int *no_fds = NULL;
-#endif
-
-
- /* Was: int readfds, writefds, exceptfds; */
- /* Was: readfds = writefds = exceptfds = 0; */
-
-
- /* Paranoia -- No excessive sleeping */
- if (usecs > 4000000L) core("Illegal usleep() call");
-
-
- /* Wait for it */
- Timer.tv_sec = (usecs / 1000000L);
- Timer.tv_usec = (usecs % 1000000L);
-
- /* Wait for it */
- if (select(nfds, no_fds, no_fds, no_fds, &Timer) < 0)
- {
- /* Hack -- ignore interrupts */
- if (errno != EINTR) return -1;
- }
-
- /* Success */
- return 0;
-}
-
-# endif
-
-
-/*
-* Hack -- External functions
-*/
-extern struct passwd *getpwuid();
-extern struct passwd *getpwnam();
-
+#include "util.hpp"
+#include "util.h"
+
+#include "cli_comm.hpp"
+#include "cmd3.hpp"
+#include "cmd4.hpp"
+#include "init1.hpp"
+#include "messages.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "tables.h"
+#include "tables.hpp"
+#include "timer_type.hpp"
+#include "variable.h"
+#include "variable.hpp"
+#include "xtra1.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <chrono>
+#include <thread>
+
+using boost::algorithm::iequals;
+using std::this_thread::sleep_for;
+using std::chrono::milliseconds;
/*
* Find a default user name from the system.
@@ -132,9 +55,6 @@ void user_name(char *buf, int id)
strcpy(buf, "PLAYER");
}
-#endif /* SET_UID */
-
-
/*
@@ -337,7 +257,6 @@ errr path_build(char *buf, int max, cptr path, cptr file)
*/
FILE *my_fopen(cptr file, cptr mode)
{
-#ifndef MACH_O_CARBON
char buf[1024];
@@ -347,24 +266,6 @@ FILE *my_fopen(cptr file, cptr mode)
/* Attempt to fopen the file anyway */
return (fopen(buf, mode));
-#else /* MACH_O_CARBON */
-
-char buf[1024];
-FILE *s;
-
-/* Hack -- Try to parse the path */
-if (path_parse(buf, 1024, file)) return (NULL);
-
-/* Attempt to fopen the file anyway */
-s = fopen(buf, mode);
-
-/* Set creator and type if the file is successfully opened */
-if (s) fsetfileinfo(buf, _fcreator, _ftype);
-
-/* Done */
-return (s);
-
-#endif /* MACH_O_CARBON */
}
@@ -541,28 +442,6 @@ errr fd_move(cptr file, cptr what)
/*
-* Hack -- attempt to copy a file
-*/
-errr fd_copy(cptr file, cptr what)
-{
- char buf[1024];
- char aux[1024];
-
- /* Hack -- Try to parse the path */
- if (path_parse(buf, 1024, file)) return ( -1);
-
- /* Hack -- Try to parse the path */
- if (path_parse(aux, 1024, what)) return ( -1);
-
- /* Copy XXX XXX XXX */
- /* (void)rename(buf, aux); */
-
- /* XXX XXX XXX */
- return (1);
-}
-
-
-/*
* Hack -- attempt to open a file descriptor (create file)
*
* This function should fail if the file already exists
@@ -577,27 +456,10 @@ int fd_make(cptr file, int mode)
/* Hack -- Try to parse the path */
if (path_parse(buf, 1024, file)) return ( -1);
-#ifdef MACH_O_CARBON
-
-{
-int fdes;
-
-/* Create the file, fail if exists, write-only, binary */
-fdes = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
-
-/* Set creator and type if the file is successfully opened */
-if (fdes >= 0) fsetfileinfo(buf, _fcreator, _ftype);
-
-/* Return the descriptor */
-return (fdes);
-}
-
-#else /* MACH_O_CARBON */
/* Create the file, fail if exists, write-only, binary */
return (open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode));
-#endif /* MACH_O_CARBON */
}
@@ -614,91 +476,10 @@ int fd_open(cptr file, int flags)
/* Hack -- Try to parse the path */
if (path_parse(buf, 1024, file)) return ( -1);
-#ifdef MACH_O_CARBON
-
- {
- int fdes;
-
- /* Attempt to open the file */
- fdes = open(buf, flags | O_BINARY, 0);
-
- /* Set creator and type if the file is successfully opened */
- if (fdes >= 0) fsetfileinfo(buf, _fcreator, _ftype);
-
- /* Return the descriptor */
- return (fdes);
- }
-
-#else /* MACH_O_CARBON */
/* Attempt to open the file */
return (open(buf, flags | O_BINARY, 0));
-#endif /* MACH_O_CARBON */
-}
-
-
-/*
-* Hack -- attempt to lock a file descriptor
-*
-* Legal lock types -- F_UNLCK, F_RDLCK, F_WRLCK
-*/
-errr fd_lock(int fd, int what)
-{
- /* XXX XXX */
- what = what ? what : 0;
-
- /* Verify the fd */
- if (fd < 0) return ( -1);
-
-#ifdef SET_UID
-
-# ifdef USG
-
-# if defined(F_ULOCK) && defined(F_LOCK)
-
- /* Un-Lock */
- if (what == F_UNLCK)
- {
- /* Unlock it, Ignore errors */
- lockf(fd, F_ULOCK, 0);
- }
-
- /* Lock */
- else
- {
- /* Lock the score file */
- if (lockf(fd, F_LOCK, 0) != 0) return (1);
- }
-
-# endif
-
-# else
-
-# if defined(LOCK_UN) && defined(LOCK_EX)
-
- /* Un-Lock */
- if (what == F_UNLCK)
- {
- /* Unlock it, Ignore errors */
- (void)flock(fd, LOCK_UN);
- }
-
- /* Lock */
- else
- {
- /* Lock the score file */
- if (flock(fd, LOCK_EX) != 0) return (1);
- }
-
-# endif
-
-# endif
-
-#endif
-
- /* Success */
- return (0);
}
@@ -902,40 +683,6 @@ static int dehex(char c)
}
-static int my_stricmp(cptr a, cptr b)
-{
- cptr s1, s2;
- char z1, z2;
-
- /* Scan the strings */
- for (s1 = a, s2 = b; TRUE; s1++, s2++)
- {
- z1 = FORCEUPPER(*s1);
- z2 = FORCEUPPER(*s2);
- if (z1 < z2) return ( -1);
- if (z1 > z2) return (1);
- if (!z1) return (0);
- }
-}
-
-static int my_strnicmp(cptr a, cptr b, int n)
-{
- cptr s1, s2;
- char z1, z2;
-
- /* Scan the strings */
- for (s1 = a, s2 = b; n > 0; s1++, s2++, n--)
- {
- z1 = FORCEUPPER(*s1);
- z2 = FORCEUPPER(*s2);
- if (z1 < z2) return ( -1);
- if (z1 > z2) return (1);
- if (!z1) return (0);
- }
- return 0;
-}
-
-
static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
{
char *s = *bufptr;
@@ -959,8 +706,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
for (i = 0; macro_modifier_chr[i]; i++)
{
len = strlen(macro_modifier_name[i]);
-
- if (!my_strnicmp(str, macro_modifier_name[i], len))
+ if (iequals(str, macro_modifier_name[i]))
break;
}
if (!macro_modifier_chr[i]) break;
@@ -972,7 +718,7 @@ static void trigger_text_to_ascii(char **bufptr, cptr *strptr)
for (i = 0; i < max_macrotrigger; i++)
{
len = strlen(macro_trigger_name[i]);
- if (!my_strnicmp(str, macro_trigger_name[i], len) && ']' == str[len])
+ if (iequals(str, macro_trigger_name[i]) && ']' == str[len])
{
/* a trigger name found */
break;
@@ -1204,8 +950,8 @@ bool_ trigger_ascii_to_text(char **bufptr, cptr *strptr)
for (i = 0; i < max_macrotrigger; i++)
{
- if (!my_stricmp(key_code, macro_trigger_keycode[0][i])
- || !my_stricmp(key_code, macro_trigger_keycode[1][i]))
+ if (iequals(key_code, macro_trigger_keycode[0][i])
+ || iequals(key_code, macro_trigger_keycode[1][i]))
break;
}
if (i == max_macrotrigger)
@@ -1482,7 +1228,7 @@ errr macro_add(cptr pat, cptr act)
if (n >= 0)
{
/* Free the old macro action */
- string_free(macro__act[n]);
+ free(macro__act[n]);
}
/* Create a new macro */
@@ -1492,11 +1238,11 @@ errr macro_add(cptr pat, cptr act)
n = macro__num++;
/* Save the pattern */
- macro__pat[n] = string_make(pat);
+ macro__pat[n] = strdup(pat);
}
/* Save the action */
- macro__act[n] = string_make(act);
+ macro__act[n] = strdup(act);
/* Efficiency */
macro__use[(byte)(pat[0])] = TRUE;
@@ -1508,22 +1254,6 @@ errr macro_add(cptr pat, cptr act)
/*
-* 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);
-}
-
-
-/*
* Local "need flush" variable
*/
static bool_ flush_later = FALSE;
@@ -1567,7 +1297,10 @@ void bell(void)
Term_fresh();
/* Make a bell noise (if allowed) */
- if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0);
+ if (ring_bell)
+ {
+ Term_bell();
+ }
/* Flush the input (later!) */
flush();
@@ -1579,11 +1312,8 @@ void bell(void)
*/
void sound(int val)
{
- /* No sound */
- if (!use_sound) return;
-
- /* Make a sound (if allowed) */
- Term_xtra(TERM_XTRA_SOUND, val);
+ /* Ignore; sound not currently supported. */
+ return;
}
@@ -1675,7 +1405,7 @@ static char inkey_aux(void)
if (w >= 100) break;
/* Delay */
- Term_xtra(TERM_XTRA_DELAY, w);
+ sleep_for(milliseconds(w));
}
}
@@ -1751,6 +1481,8 @@ static char inkey_aux(void)
*/
static cptr inkey_next = NULL;
+bool_ inkey_flag = FALSE;
+
/*
* Get a keypress from the user.
@@ -1761,11 +1493,6 @@ static cptr inkey_next = NULL;
* 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.
*
@@ -1810,11 +1537,8 @@ static cptr inkey_next = NULL;
* "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)
+static char inkey_real(bool_ inkey_scan)
{
int v;
@@ -1827,13 +1551,13 @@ char inkey(void)
term *old = Term;
/* Hack -- Use the "inkey_next" pointer */
- if (inkey_next && *inkey_next && !inkey_xtra)
+ if (inkey_next && *inkey_next)
{
/* Get next character, and advance */
ch = *inkey_next++;
/* Cancel the various "global parameters" */
- inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+ inkey_base = inkey_flag = inkey_scan = FALSE;
/* Accept result */
macro_recorder_add(ch);
@@ -1844,20 +1568,6 @@ char inkey(void)
inkey_next = NULL;
- /* Hack -- handle delayed "flush()" */
- if (inkey_xtra)
- {
- /* End "macro action" */
- parse_macro = FALSE;
-
- /* End "macro trigger" */
- parse_under = FALSE;
-
- /* Forget old keypresses */
- Term_flush();
- }
-
-
/* Access cursor state */
(void)Term_get_cursor(&v);
@@ -1896,9 +1606,6 @@ char inkey(void)
/* Hack -- activate main screen */
Term_activate(angband_term[0]);
- /* Mega-Hack -- reset saved flag */
- character_saved = FALSE;
-
/* Only once */
done = TRUE;
}
@@ -1943,7 +1650,7 @@ char inkey(void)
if (w >= 100) break;
/* Delay */
- Term_xtra(TERM_XTRA_DELAY, w);
+ sleep_for(milliseconds(w));
}
}
@@ -1962,13 +1669,8 @@ char inkey(void)
/* Strip this key */
ch = 0;
- if (!do_movies)
- /* Do an html dump */
- do_cmd_html_dump();
- else
- /* Do a text box in the cmovie */
- do_cmovie_insert();
-
+ /* Do an html dump */
+ do_cmd_html_dump();
/* Continue */
continue;
@@ -2025,7 +1727,7 @@ char inkey(void)
/* Cancel the various "global parameters" */
- inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+ inkey_base = inkey_flag = FALSE;
/* Return the keypress */
@@ -2033,6 +1735,14 @@ char inkey(void)
return (ch);
}
+char inkey(void) {
+ return inkey_real(FALSE);
+}
+
+char inkey_scan() {
+ return inkey_real(TRUE);
+}
+
/*
* Hack -- flush
*/
@@ -2117,13 +1827,14 @@ void cmsg_print(byte color, cptr msg)
static int p = 0;
int n;
+ int wid;
char *t;
char buf[1024];
- int lim = Term->wid - 8;
-
+ Term_get_size(&wid, nullptr);
+ int lim = wid - 8;
/* Hack -- Reset */
if (!msg_flag) p = 0;
@@ -2639,9 +2350,11 @@ void text_out_c(byte a, cptr str)
void clear_from(int row)
{
int y;
+ int hgt;
+ Term_get_size(nullptr, &hgt);
/* Erase requested rows */
- for (y = row; y < Term->hgt; y++)
+ for (y = row; y < hgt; y++)
{
/* Erase part of the screen */
Term_erase(0, y, 255);
@@ -3644,7 +3357,6 @@ void strlower(char *buf)
* must exactly match (look out for commas and the like!), or else 0 is
* returned. Case doesn't matter. -GSN-
*/
-
int test_monster_name(cptr name)
{
int i;
@@ -3653,13 +3365,11 @@ int test_monster_name(cptr name)
for (i = 1; i < max_r_idx; i++)
{
monster_race *r_ptr = &r_info[i];
- cptr mon_name = r_name + r_ptr->name;
-
- /* If name matches, give us the number */
- if (stricmp(name, mon_name) == 0) return (i);
+ if (r_ptr->name && iequals(name, r_ptr->name)) return (i);
}
return (0);
}
+
int test_mego_name(cptr name)
{
int i;
@@ -3668,10 +3378,7 @@ int test_mego_name(cptr name)
for (i = 1; i < max_re_idx; i++)
{
monster_ego *re_ptr = &re_info[i];
- cptr mon_name = re_name + re_ptr->name;
-
- /* If name matches, give us the number */
- if (stricmp(name, mon_name) == 0) return (i);
+ if (re_ptr->name && iequals(name, re_ptr->name)) return (i);
}
return (0);
}
@@ -3690,10 +3397,8 @@ int test_item_name(cptr name)
for (i = 1; i < max_k_idx; i++)
{
object_kind *k_ptr = &k_info[i];
- cptr obj_name = k_name + k_ptr->name;
-
/* If name matches, give us the number */
- if (stricmp(name, obj_name) == 0) return (i);
+ if (k_ptr->name && iequals(name, k_ptr->name)) return (i);
}
return (0);
}
@@ -3783,12 +3488,18 @@ cptr get_player_race_name(int pr, int ps)
if (ps)
{
- if (race_mod_info[ps].place) sprintf(buf, "%s %s", race_info[pr].title + rp_name, race_mod_info[ps].title + rmp_name);
- else sprintf(buf, "%s %s", race_mod_info[ps].title + rmp_name, race_info[pr].title + rp_name);
+ if (race_mod_info[ps].place)
+ {
+ sprintf(buf, "%s %s", race_info[pr].title, race_mod_info[ps].title);
+ }
+ else
+ {
+ sprintf(buf, "%s %s", race_mod_info[ps].title, race_info[pr].title);
+ }
}
else
{
- sprintf(buf, "%s", race_info[pr].title + rp_name);
+ sprintf(buf, "%s", race_info[pr].title);
}
return (buf);
@@ -3797,10 +3508,11 @@ cptr get_player_race_name(int pr, int ps)
/*
* Ask to select an item in a list
*/
-int ask_menu(cptr ask, char **items, int max)
+int ask_menu(cptr ask, const std::vector<std::string> &items)
{
int ret = -1, i, start = 0;
char c;
+ int size = items.size(); // Convert to int to avoid warnings
/* Enter "icky" mode */
character_icky = TRUE;
@@ -3814,9 +3526,9 @@ int ask_menu(cptr ask, char **items, int max)
Term_load();
Term_save();
prt(ask, 0, 0);
- for (i = start; (i < max) && (i < start + 20); i++)
+ for (i = start; (i < size) && (i < start + 20); i++)
{
- prt(format("%c) %s", I2A(i - start), items[i]), i - start + 1, 0);
+ prt(format("%c) %s", I2A(i - start), items[i].c_str()), i - start + 1, 0);
}
/* Wait for user input */
@@ -3828,7 +3540,7 @@ int ask_menu(cptr ask, char **items, int max)
/* Scroll */
else if (c == '+')
{
- if (start + 20 < max)
+ if (start + 20 < size)
start += 20;
continue;
}
@@ -3845,7 +3557,7 @@ int ask_menu(cptr ask, char **items, int max)
else
{
c = tolower(c);
- if (A2I(c) + start >= max)
+ if (A2I(c) + start >= size)
{
bell();
continue;
@@ -3980,27 +3692,16 @@ char msg_box(cptr text, int y, int x)
return inkey();
}
-/* Rescale a value */
-s32b rescale(s32b x, s32b max, s32b new_max)
-{
- return (x * new_max) / max;
-}
-
-/* Nicer wrapper around TERM_XTRA_SCANSUBDIR */
-void scansubdir(cptr dir)
-{
- strnfmt(scansubdir_dir, 1024, "%s", dir);
- Term_xtra(TERM_XTRA_SCANSUBDIR, 0);
-}
-
/*
* Timers
*/
timer_type *new_timer(void (*callback)(), s32b delay)
{
- timer_type *t_ptr = NULL;
+ timer_type *t_ptr = new timer_type();
+
+ static_assert(std::is_pod<timer_type>::value, "Cannot memset a non-POD type");
+ memset(t_ptr, 0, sizeof(timer_type));
- MAKE(t_ptr, timer_type);
t_ptr->next = gl_timers;
gl_timers = t_ptr;
@@ -4012,26 +3713,6 @@ timer_type *new_timer(void (*callback)(), s32b delay)
return t_ptr;
}
-void del_timer(timer_type *t_ptr)
-{
- timer_type *i, *old;
-
- old = NULL;
- for (i = gl_timers; (i != NULL) && (i != t_ptr); old = i, i = i->next)
- ;
- if (i)
- {
- if (old == NULL)
- gl_timers = t_ptr->next;
- else
- old->next = t_ptr->next;
-
- FREE(t_ptr, timer_type);
- }
- else
- cmsg_print(TERM_VIOLET, "Unknown timer!");
-}
-
int get_keymap_mode()
{
if (rogue_like_commands)
@@ -4043,3 +3724,28 @@ int get_keymap_mode()
return KEYMAP_MODE_ORIG;
}
}
+
+/**
+ * Determines if a map location is fully inside the outer walls
+ */
+bool in_bounds(int y, int x)
+{
+ return (y > 0) && (x > 0) && (y < cur_hgt-1) && (x < cur_wid-1);
+}
+
+/**
+ * Determines if a map location is on or inside the outer walls
+ */
+bool in_bounds2(int y, int x)
+{
+ return (y >= 0) && (x >= 0) && (y < cur_hgt) && (x < cur_wid);
+}
+
+/**
+ * Determines if a map location is currently "on screen" -RAK-
+ * Note that "panel_contains(Y,X)" always implies "in_bounds2(Y,X)".
+ */
+bool panel_contains(int y, int x)
+{
+ return (y >= panel_row_min) && (y <= panel_row_max) && (x >= panel_col_min) && (x <= panel_col_max);
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 00000000..4ae797b9
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "h-basic.h"
+
+// C linkage required for these functions since main-* code uses them.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern errr path_parse(char *buf, int max, cptr file);
+extern errr path_build(char *buf, int max, cptr path, cptr file);
+extern void bell(void);
+extern errr macro_add(cptr pat, cptr act);
+extern sint macro_find_exact(cptr pat);
+extern char inkey(void);
+extern void prt(cptr str, int row, int col);
+extern void pause_line(int row);
+extern void user_name(char *buf, int id);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/util.hpp b/src/util.hpp
new file mode 100644
index 00000000..5cb2f058
--- /dev/null
+++ b/src/util.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "h-basic.h"
+#include "timer_type_fwd.hpp"
+
+#include <vector>
+#include <string>
+
+extern bool_ input_box(cptr text, int y, int x, char *buf, int max);
+extern void draw_box(int y, int x, int h, int w);
+extern void display_list(int y, int x, int h, int w, cptr title, cptr *list, int max, int begin, int sel, byte sel_color);
+extern cptr get_player_race_name(int pr, int ps);
+extern cptr get_month_name(int month, bool_ full, bool_ compact);
+extern cptr get_day(int day);
+extern s32b bst(s32b what, s32b t);
+extern errr path_temp(char *buf, int max);
+extern FILE *my_fopen(cptr file, cptr mode);
+extern errr my_fgets(FILE *fff, char *buf, huge n);
+extern errr my_fputs(FILE *fff, cptr buf, huge n);
+extern errr my_fclose(FILE *fff);
+extern errr fd_kill(cptr file);
+extern errr fd_move(cptr file, cptr what);
+extern int fd_make(cptr file, int mode);
+extern int fd_open(cptr file, int flags);
+extern errr fd_seek(int fd, huge n);
+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 flush(void);
+extern void sound(int num);
+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 char inkey_scan(void);
+extern void display_message(int x, int y, int split, byte color, cptr t);
+extern void cmsg_print(byte color, cptr msg);
+extern void msg_print(cptr msg);
+extern void cmsg_format(byte color, cptr fmt, ...);
+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);
+extern void text_out_to_screen(byte a, cptr str);
+extern void text_out_to_file(byte a, cptr str);
+extern void text_out(cptr str);
+extern void text_out_c(byte a, cptr str);
+extern void clear_from(int row);
+extern int ask_menu(cptr ask, const std::vector<std::string> &items);
+extern bool_ askfor_aux_complete;
+extern bool_ askfor_aux(char *buf, int len);
+extern bool_ get_string(cptr prompt, char *buf, int len);
+extern bool_ get_check(cptr prompt);
+extern bool_ get_com(cptr prompt, char *command);
+extern s32b get_quantity(cptr prompt, s32b max);
+extern char request_command_ignore_keymaps[];
+extern bool_ request_command_inven_mode;
+extern void request_command(int shopping);
+extern bool_ is_a_vowel(int ch);
+extern int get_keymap_dir(char ch);
+extern byte count_bits(u32b array);
+extern void strlower(char *buf);
+extern int test_monster_name(cptr name);
+extern int test_mego_name(cptr name);
+extern int test_item_name(cptr name);
+extern char msg_box(cptr text, int y, int x);
+extern timer_type *new_timer(void (*callback)(), s32b delay);
+extern int get_keymap_mode();
+extern void repeat_push(int what);
+extern bool_ repeat_pull(int *what);
+extern void repeat_check(void);
+extern void get_count(int number, int max);
+extern bool in_bounds(int y, int x);
+extern bool in_bounds2(int y, int x);
+extern bool panel_contains(int y, int x);
diff --git a/src/variable.c b/src/variable.cc
index ac67e308..ca4aca01 100644
--- a/src/variable.c
+++ b/src/variable.cc
@@ -1,7 +1,3 @@
-/* File: variable.c */
-
-/* Purpose: Angband variables */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,7 +6,13 @@
* included in all such copies.
*/
-#include "angband.h"
+#include "variable.hpp"
+#include "variable.h"
+
+#include "cli_comm_fwd.hpp"
+#include "player_type.hpp"
+#include "randart_gen_type.hpp"
+#include "util.hpp"
int max_macrotrigger = 0;
@@ -26,7 +28,6 @@ char *macro_trigger_keycode[2][MAX_MACRO_TRIG];
byte version_major;
byte version_minor;
byte version_patch;
-byte version_extra = VERSION_EXTRA;
/*
* Savefile version
@@ -34,13 +35,10 @@ byte version_extra = VERSION_EXTRA;
byte sf_major; /* Savefile's "version_major" */
byte sf_minor; /* Savefile's "version_minor" */
byte sf_patch; /* Savefile's "version_patch" */
-byte sf_extra; /* Savefile's "version_extra" */
-u32b vernum;
/*
* Savefile information
*/
-u32b sf_xtra; /* Operating system info */
u32b sf_when; /* Time when savefile created */
u16b sf_lives; /* Number of past "lives" with this file */
u16b sf_saves; /* Number of "saves" during this life */
@@ -49,11 +47,8 @@ u16b sf_saves; /* Number of "saves" during this life */
* Run-time aruments
*/
bool_ arg_wizard; /* Command arg -- Request wizard mode */
-bool_ arg_sound; /* Command arg -- Request special sounds */
-bool_ arg_graphics; /* Command arg -- Request graphics mode */
bool_ arg_force_original; /* Command arg -- Request original keyset */
bool_ arg_force_roguelike; /* Command arg -- Request roguelike keyset */
-bool_ arg_bigtile = FALSE; /* Command arg -- Request big tile mode */
/*
* Various things
@@ -62,7 +57,6 @@ bool_ arg_bigtile = FALSE; /* Command arg -- Request big tile mode */
bool_ character_generated; /* The character exists */
bool_ character_dungeon; /* The character has a dungeon */
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 */
@@ -109,20 +103,12 @@ s32b old_turn; /* Turn when level began (feelings) */
bool_ wizard; /* Is the player currently in Wizard mode? */
-bool_ use_sound; /* The "sound" mode is enabled */
-bool_ use_graphics; /* The "graphics" mode is enabled */
-bool_ use_bigtile = FALSE;
-byte graphics_mode; /* Current graphics mode */
-
u16b total_winner; /* Semi-Hack -- Game has been won */
u16b has_won; /* Semi-Hack -- Game has been won */
u16b noscore; /* Track various "cheating" conditions */
bool_ inkey_base; /* See the "inkey()" function */
-bool_ inkey_xtra; /* See the "inkey()" function */
-bool_ inkey_scan; /* See the "inkey()" function */
-bool_ inkey_flag; /* See the "inkey()" function */
s16b coin_type; /* Hack -- force coin type */
@@ -132,7 +118,6 @@ bool_ shimmer_monsters; /* Hack -- optimize multi-hued monsters */
bool_ shimmer_objects; /* Hack -- optimize multi-hued objects */
bool_ repair_monsters; /* Hack -- optimize detect monsters */
-bool_ repair_objects; /* Hack -- optimize detect objects */
bool_ hack_mind;
int artifact_bias;
@@ -148,7 +133,6 @@ s16b m_max = 1; /* Number of allocated monsters */
s16b m_cnt = 0; /* Number of live monsters */
s16b hack_m_idx = 0; /* Hack -- see "process_monsters()" */
-s16b hack_m_idx_ii = 0;
char summon_kin_type; /* Hack, by Julian Lighton: summon 'relatives' */
int total_friends = 0;
@@ -182,110 +166,6 @@ int text_out_indent = 0;
*/
-/* Option Set 1 -- User Interface */
-
-bool_ rogue_like_commands; /* Rogue-like commands */
-bool_ quick_messages; /* Activate quick messages */
-bool_ carry_query_flag; /* Prompt before picking things up */
-bool_ use_old_target; /* Use old target by default */
-bool_ always_pickup; /* Pick things up by default */
-bool_ prompt_pickup_heavy; /* Don't pick up the corpses */
-bool_ always_repeat; /* Repeat obvious commands */
-bool_ depth_in_feet; /* Show dungeon level in feet */
-
-bool_ stack_force_notes; /* Merge inscriptions when stacking */
-bool_ stack_force_costs; /* Merge discounts when stacking */
-
-bool_ ring_bell; /* Ring the bell (on errors, etc) */
-
-
-/* Option Set 2 -- Disturbance */
-
-bool_ find_ignore_stairs; /* Run past stairs */
-bool_ find_ignore_doors; /* Run through open doors */
-bool_ find_cut; /* Run past known corners */
-bool_ find_examine; /* Run into potential corners */
-
-bool_ disturb_move; /* Disturb whenever any monster moves */
-bool_ disturb_near; /* Disturb whenever viewable monster moves */
-bool_ disturb_panel; /* Disturb whenever map panel changes */
-bool_ disturb_detect; /* Disturb whenever leaving trap-detected area */
-bool_ disturb_state; /* Disturn whenever player state changes */
-bool_ disturb_minor; /* Disturb whenever boring things happen */
-bool_ disturb_other; /* Disturb whenever various things happen */
-
-bool_ alert_hitpoint; /* Alert user to critical hitpoints */
-bool_ alert_failure; /* Alert user to various failures */
-bool_ last_words; /* Get last words upon dying */
-bool_ speak_unique; /* Speaking uniques + shopkeepers */
-bool_ small_levels; /* Allow unusually small dungeon levels */
-bool_ empty_levels; /* Allow empty 'arena' levels */
-bool_ always_small_level; /* Small levels */
-bool_ player_symbols; /* Use varying symbols for the player char */
-bool_ plain_descriptions; /* Plain object descriptions */
-bool_ auto_destroy; /* Known worthless items are destroyed without confirmation */
-bool_ confirm_stairs; /* Prompt before staircases... */
-bool_ wear_confirm; /* Confirm before putting on known cursed items */
-bool_ disturb_pets; /* Pets moving nearby disturb us */
-
-
-/* Option Set 3 -- Game-Play */
-
-bool_ auto_scum; /* Auto-scum for good levels */
-
-bool_ stack_allow_items; /* Allow weapons and armor to stack */
-bool_ stack_allow_wands; /* Allow wands/staffs/rods to stack */
-
-bool_ expand_look; /* Expand the power of the look command */
-bool_ expand_list; /* Expand the power of the list commands */
-
-bool_ view_perma_grids; /* Map remembers all perma-lit grids */
-bool_ view_torch_grids; /* Map remembers all torch-lit grids */
-
-bool_ monster_lite; /* Allow some monsters to carry light */
-
-bool_ dungeon_align; /* Generate dungeons with aligned rooms */
-bool_ dungeon_stair; /* Generate dungeons with connected stairs */
-
-bool_ flow_by_sound; /* Monsters track new player location */
-
-bool_ track_follow; /* Monsters follow the player */
-bool_ track_target; /* Monsters target the player */
-
-bool_ smart_learn; /* Monsters learn from their mistakes */
-bool_ smart_cheat; /* Monsters exploit player weaknesses */
-
-
-/* Option Set 4 -- Efficiency */
-
-bool_ view_reduce_lite; /* Reduce lite-radius when running */
-bool_ view_reduce_view; /* Reduce view-radius in town */
-
-bool_ avoid_abort; /* Avoid checking for user abort */
-bool_ avoid_shimmer; /* Avoid processing extra shimmering */
-bool_ avoid_other; /* Avoid processing special colors */
-
-bool_ flush_failure; /* Flush input on any failure */
-bool_ flush_disturb; /* Flush input on disturbance */
-bool_ flush_command; /* Flush input before every command */
-
-bool_ fresh_before; /* Flush output before normal commands */
-bool_ fresh_after; /* Flush output after normal commands */
-bool_ fresh_message; /* Flush output after all messages */
-
-bool_ hilite_player; /* Hilite the player with the cursor */
-
-bool_ view_yellow_lite; /* Use special colors for torch-lit grids */
-bool_ view_bright_lite; /* Use special colors for 'viewable' grids */
-
-bool_ view_granite_lite; /* Use special colors for wall grids (slow) */
-bool_ view_special_lite; /* Use special colors for floor grids (slow) */
-
-/* Option set 5 -- Testing */
-
-bool_ testing_stack; /* Test the stacking code */
-
-bool_ testing_carry; /* Test the carrying code */
/* Cheating options */
@@ -318,8 +198,6 @@ s16b rating; /* Level's current rating */
bool_ good_item_flag; /* True if "Artifact" on this level */
-bool_ closing_flag; /* Dungeon is closing */
-
/*
* Dungeon size info
*/
@@ -419,12 +297,12 @@ s16b macro__num;
/*
* Array of macro patterns [MACRO_MAX]
*/
-cptr *macro__pat;
+char **macro__pat;
/*
* Array of macro actions [MACRO_MAX]
*/
-cptr *macro__act;
+char **macro__act;
/*
* Array of macro types [MACRO_MAX]
@@ -498,84 +376,9 @@ byte angband_color_table[256][4] =
/*
- * Standard sound names
- */
-char angband_sound_name[SOUND_MAX][16] =
-{
- "",
- "hit",
- "miss",
- "flee",
- "drop",
- "kill",
- "level",
- "death",
- "study",
- "teleport",
- "shoot",
- "quaff",
- "zap",
- "walk",
- "tpother",
- "hitwall",
- "eat",
- "store1",
- "store2",
- "store3",
- "store4",
- "dig",
- "opendoor",
- "shutdoor",
- "tplevel",
- "scroll",
- "buy",
- "sell",
- "warn",
- "rocket",
- "n_kill",
- "u_kill",
- "quest",
- "heal",
- "x_heal",
- "bite",
- "claw",
- "m_spell",
- "summon",
- "breath",
- "ball",
- "m_heal",
- "atkspell",
- "evil",
- "touch",
- "sting",
- "crush",
- "slime",
- "wail",
- "winner",
- "fire",
- "acid",
- "elec",
- "cold",
- "illegal",
- "fail",
- "wakeup",
- "invuln",
- "fall",
- "pain",
- "destitem",
- "moan",
- "show",
- "unused",
- "explode",
-};
-
-
-/*
* The array of "cave grids" [MAX_WID][MAX_HGT].
- * Not completely allocated, that would be inefficient
- * Not completely hardcoded, that would overflow memory
*/
-cave_type *cave[MAX_HGT];
+cave_type **cave = nullptr;
/*
* The array of dungeon items [max_o_idx]
@@ -605,7 +408,7 @@ u16b max_real_towns;
town_type *town_info;
/*
- * The size of "alloc_kind_table" (at most max_k_idx * 4)
+ * The size of "alloc_kind_table" (at most max_k_idx * ALLOCATIONS_MAX)
*/
s16b alloc_kind_size;
@@ -651,7 +454,7 @@ char tval_to_char[128];
/*
* Keymaps for each "mode" associated with each keypress.
*/
-cptr keymap_act[KEYMAP_MODES][256];
+char *keymap_act[KEYMAP_MODES][256];
@@ -697,177 +500,117 @@ s16b player_hp[PY_MAX_LEVEL];
/*
* The alchemy recipe arrays
*/
-header *al_head;
alchemist_recipe *alchemist_recipes;
-char *al_name;
artifact_select_flag *a_select_flags;
/*
* The vault generation arrays
*/
-header *v_head;
vault_type *v_info;
-char *v_name;
-char *v_text;
/*
* The terrain feature arrays
*/
-header *f_head;
feature_type *f_info;
-char *f_name;
-char *f_text;
/*
* The object kind arrays
*/
-header *k_head;
object_kind *k_info;
-char *k_name;
-char *k_text;
/*
* The artifact arrays
*/
-header *a_head;
artifact_type *a_info;
-char *a_name;
-char *a_text;
/*
* The item set arrays
*/
-header *set_head;
set_type *set_info;
-char *set_name;
-char *set_text;
/*
* The ego-item arrays
*/
-header *e_head;
ego_item_type *e_info;
-char *e_name;
-char *e_text;
/*
* The randart arrays
*/
-header *ra_head;
randart_part_type *ra_info;
randart_gen_type ra_gen[30];
/* jk */
/* the trap-arrays */
-header *t_head;
trap_type *t_info;
-char *t_name;
-char *t_text;
/*
* The monster race arrays
*/
-header *r_head;
monster_race *r_info;
-char *r_name;
-char *r_text;
/*
* The monster ego race arrays
*/
-header *re_head;
monster_ego *re_info;
-char *re_name;
/*
* The dungeon types arrays
*/
-header *d_head;
dungeon_info_type *d_info;
-char *d_name;
-char *d_text;
/*
* Player abilities arrays
*/
-header *ab_head;
ability_type *ab_info;
-char *ab_name;
-char *ab_text;
/*
* Player skills arrays
*/
-header *s_head;
skill_type *s_info;
-char *s_name;
-char *s_text;
/*
* Player race arrays
*/
-header *rp_head;
player_race *race_info;
-char *rp_name;
-char *rp_text;
/*
* Player mod race arrays
*/
-header *rmp_head;
player_race_mod *race_mod_info;
-char *rmp_name;
-char *rmp_text;
/*
* Player class arrays
*/
-header *c_head;
player_class *class_info;
-char *c_name;
-char *c_text;
meta_class_type *meta_class_info;
/*
* The wilderness features arrays
*/
-header *wf_head;
wilderness_type_info *wf_info;
-char *wf_name;
-char *wf_text;
int wildc2i[256];
/*
* The store/building types arrays
*/
-header *st_head;
store_info_type *st_info;
-char *st_name;
-/* char *st_text; */
/*
* The building actions types arrays
*/
-header *ba_head;
store_action_type *ba_info;
-char *ba_name;
-/* char *ba_text; */
/*
* The owner types arrays
*/
-header *ow_head;
owner_type *ow_info;
-char *ow_name;
-/* char *ow_text; */
/*
- * The dungeon types arrays
+ * Default texts for feature information.
*/
-header *d_head;
-dungeon_info_type *d_info;
-char *d_name;
-char *d_text;
+cptr DEFAULT_FEAT_TEXT = "a wall blocking your way";
+cptr DEFAULT_FEAT_TUNNEL = "You cannot tunnel through that.";
+cptr DEFAULT_FEAT_BLOCK = DEFAULT_FEAT_TEXT;
/*
* Hack -- The special Angband "System Suffix"
@@ -895,144 +638,84 @@ cptr ANGBAND_GRAF = "old";
* Path name: The main "lib" directory
* This variable is not actually used anywhere in the code
*/
-cptr ANGBAND_DIR;
+char *ANGBAND_DIR;
/*
* Core lua system
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_CORE;
+char *ANGBAND_DIR_CORE;
/*
* Textual dungeon level definition files
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_DNGN;
+char *ANGBAND_DIR_DNGN;
/*
* Binary image files for the "*_info" arrays (binary)
* These files are not portable between platforms
*/
-cptr ANGBAND_DIR_DATA;
+char *ANGBAND_DIR_DATA;
/*
* Textual template files for the "*_info" arrays (ascii)
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_EDIT;
+char *ANGBAND_DIR_EDIT;
/*
* Various extra files (ascii)
* These files may be portable between platforms
*/
-cptr ANGBAND_DIR_FILE;
+char *ANGBAND_DIR_FILE;
/*
* Help files (normal) for the online help (ascii)
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_HELP;
+char *ANGBAND_DIR_HELP;
/*
* Help files (spoilers) for the online help (ascii)
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_INFO;
+char *ANGBAND_DIR_INFO;
/*
* Modules, those subdirectories are half-mirrors of lib/
*/
-cptr ANGBAND_DIR_MODULES;
-
-/*
- * Patches, contains one subdir per patch with a patch.lua file
- * in it and a patch_init() function in it
- */
-cptr ANGBAND_DIR_PATCH;
+char *ANGBAND_DIR_MODULES;
/*
* Textual template files for the plot files (ascii)
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_NOTE;
+char *ANGBAND_DIR_NOTE;
/*
* Savefiles for current characters (binary)
* These files are portable between platforms
*/
-cptr ANGBAND_DIR_SAVE;
-
-/*
- * Scripts.
- * These files are portable between platforms
- */
-cptr ANGBAND_DIR_SCPT;
+char *ANGBAND_DIR_SAVE;
/*
* Default "preference" files (ascii)
* These files are rarely portable between platforms
*/
-cptr ANGBAND_DIR_PREF;
+char *ANGBAND_DIR_PREF;
/*
* User "preference" files (ascii)
* These files are rarely portable between platforms
*/
-cptr ANGBAND_DIR_USER;
+char *ANGBAND_DIR_USER;
/*
* Various extra files (binary)
* These files are rarely portable between platforms
*/
-cptr ANGBAND_DIR_XTRA;
-
-/*
- * Cmovie files of entire games (ascii)
- * Apart from possible newline things, likely portable btw platforms
- */
-
-cptr ANGBAND_DIR_CMOV;
-
-/*
- * Some variables values are created on the fly XXX XXX
- */
-
-char pref_tmp_value[8];
-
-
-
-/*
- * Total Hack -- allow all items to be listed (even empty ones)
- * This is only used by "do_cmd_inven_e()" and is cleared there.
- */
-bool_ item_tester_full;
-
-
-/*
- * Here is a "pseudo-hook" used during calls to "get_item()" and
- * "show_inven()" and "show_equip()", and the choice window routines.
- */
-byte item_tester_tval;
-
-
-/*
- * Here is a "hook" used during calls to "get_item()" and
- * "show_inven()" and "show_equip()", and the choice window routines.
- */
-bool_ (*item_tester_hook)(object_type*);
-
-
-
-/*
- * Current "comp" function for ang_sort()
- */
-bool_ (*ang_sort_comp)(vptr u, vptr v, int a, int b);
-
-
-/*
- * Current "swap" function for ang_sort()
- */
-void (*ang_sort_swap)(vptr u, vptr v, int a, int b);
+char *ANGBAND_DIR_XTRA;
@@ -1048,11 +731,9 @@ bool_ (*get_mon_num2_hook)(int r_idx);
*/
bool_ (*get_obj_num_hook)(int k_idx);
-
-bool_ easy_open = TRUE;
-bool_ easy_disarm = TRUE;
-bool_ easy_tunnel = FALSE;
-
+/*
+ * Devices
+ */
s32b get_level_max_stick = -1;
s32b get_level_use_stick = -1;
@@ -1137,7 +818,7 @@ u16b max_st_idx;
/*
* Item sets
*/
-s16b max_set_idx = 1;
+u16b max_set_idx = 1;
/*
* Maximum number of players info in p_info.txt
@@ -1204,18 +885,6 @@ s32b RANDART_ARMOR;
s32b RANDART_JEWEL;
/*
- * Current bounties. An array of tuples of two, with the first being the
- * r_idx of the monster, and the second the monster's worth.
- */
-s16b bounties[MAX_BOUNTIES][2];
-
-/*
- * Spell description
- */
-bool_ info_spell = FALSE;
-char spell_txt[50];
-
-/*
* Random spells.
*/
random_spell random_spells[MAX_SPELLS];
@@ -1246,30 +915,14 @@ fate fates[MAX_FATES];
byte dungeon_type;
s16b *max_dlv;
-/*
- * Number of total bounties the player had had.
- */
-u32b total_bounties;
-
/* The Doppleganger index in m_list */
s16b doppleganger;
/* To allow wilderness encounters */
bool_ generate_encounter;
-/* Autoroler */
-bool_ autoroll;
-
-/* Point based */
-bool_ point_based;
-
-/* Maximize, preserve, special levels, ironman_rooms */
-bool_ maximize, preserve, special_lvls, ironman_rooms;
-
-/* In inventory option window, just erase the letters,
- * rather that displaying the list without the invalid
- * selections */
-bool_ inventory_no_move;
+/* Special levels */
+bool_ special_lvls;
/*
* Such an ugly hack ...
@@ -1279,21 +932,6 @@ bool_ *k_allow_special;
bool_ *a_allow_special;
/*
- * Gives a random object to newly created characters
- */
-bool_ rand_birth;
-
-/*
- * Which monsters are allowed ?
- */
-bool_ joke_monsters;
-
-/*
- * Center view
- */
-bool_ center_player = FALSE;
-
-/*
* Plots
*/
s16b plots[MAX_PLOTS];
@@ -1304,27 +942,12 @@ s16b plots[MAX_PLOTS];
random_quest random_quests[MAX_RANDOM_QUEST];
/*
- * Show exp left
- */
-bool_ exp_need;
-
-/*
- * Fated ?
- */
-bool_ fate_option;
-
-/*
* Special levels
*/
bool_ *special_lvl[MAX_DUNGEON_DEPTH];
bool_ generate_special_feeling = FALSE;
/*
- * Auto more
- */
-bool_ auto_more;
-
-/*
* Dungeon flags
*/
u32b dungeon_flags1;
@@ -1342,26 +965,8 @@ hist_type *bg;
int max_bg_idx;
/*
- * Variable savefile stuff
- */
-s32b extra_savefile_parts = 0;
-
-/*
- * Quests
- */
-quest_type quest[MAX_Q_IDX];
-
-/*
- * Display the player as a special symbol when in bad health ?
- */
-bool_ player_char_health;
-
-
-/*
* The spell list of schools
*/
-s16b school_spells_count = 0;
-spell_type *school_spells[SCHOOL_SPELLS_MAX];
s16b schools_count = 0;
school_type schools[SCHOOLS_MAX];
@@ -1381,11 +986,6 @@ char gen_skill_modm[MAX_SKILLS];
s16b gen_skill_mod[MAX_SKILLS];
/*
- * Display stats as linear
- */
-bool_ linear_stats;
-
-/*
* Table of "cli" macros.
*/
cli_comm *cli_info;
@@ -1397,14 +997,10 @@ int cli_total = 0;
int max_bact = 127;
/*
- * Ingame contextual help
- */
-bool_ option_ingame_help = TRUE;
-
-/*
* Automatizer enabled status
*/
bool_ automatizer_enabled = FALSE;
+bool_ automatizer_create = FALSE;
/*
* Location of the last teleportation thath affected the level
@@ -1454,3 +1050,57 @@ const char *get_version_string()
}
return version_str;
}
+
+/*
+ * A list of tvals and their textual names
+ */
+tval_desc tvals[] =
+{
+ { TV_SWORD, "Sword" },
+ { TV_POLEARM, "Polearm" },
+ { TV_HAFTED, "Hafted Weapon" },
+ { TV_AXE, "Axe" },
+ { TV_BOW, "Bow" },
+ { TV_BOOMERANG, "Boomerang" },
+ { TV_ARROW, "Arrows" },
+ { TV_BOLT, "Bolts" },
+ { TV_SHOT, "Shots" },
+ { TV_SHIELD, "Shield" },
+ { TV_CROWN, "Crown" },
+ { TV_HELM, "Helm" },
+ { TV_GLOVES, "Gloves" },
+ { TV_BOOTS, "Boots" },
+ { TV_CLOAK, "Cloak" },
+ { TV_DRAG_ARMOR, "Dragon Scale Mail" },
+ { TV_HARD_ARMOR, "Hard Armor" },
+ { TV_SOFT_ARMOR, "Soft Armor" },
+ { TV_RING, "Ring" },
+ { TV_AMULET, "Amulet" },
+ { TV_LITE, "Lite" },
+ { TV_POTION, "Potion" },
+ { TV_POTION2, "Potion" },
+ { TV_SCROLL, "Scroll" },
+ { TV_WAND, "Wand" },
+ { TV_STAFF, "Staff" },
+ { TV_ROD_MAIN, "Rod" },
+ { TV_ROD, "Rod Tip" },
+ { TV_BOOK, "Schools Spellbook", },
+ { TV_SYMBIOTIC_BOOK, "Symbiotic Spellbook", },
+ { TV_DRUID_BOOK, "Elemental Stone" },
+ { TV_MUSIC_BOOK, "Music Book" },
+ { TV_DAEMON_BOOK, "Daemon Book" },
+ { TV_SPIKE, "Spikes" },
+ { TV_DIGGING, "Digger" },
+ { TV_CHEST, "Chest" },
+ { TV_FOOD, "Food" },
+ { TV_FLASK, "Flask" },
+ { TV_MSTAFF, "Mage Staff" },
+ { TV_BATERIE, "Essence" },
+ { TV_PARCHMENT, "Parchment" },
+ { TV_INSTRUMENT, "Musical Instrument" },
+ { TV_RUNE1, "Rune 1" },
+ { TV_RUNE2, "Rune 2" },
+ { TV_JUNK, "Junk" },
+ { TV_TRAPKIT, "Trapping Kit" },
+ { 0, NULL }
+};
diff --git a/src/variable.h b/src/variable.h
new file mode 100644
index 00000000..90a462b5
--- /dev/null
+++ b/src/variable.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "angband.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern cptr ANGBAND_SYS;
+extern cptr ANGBAND_KEYBOARD;
+extern char *ANGBAND_DIR_MODULES;
+extern char *ANGBAND_DIR_SAVE;
+extern char *ANGBAND_DIR_CORE;
+extern char *ANGBAND_DIR_DNGN;
+extern char *ANGBAND_DIR_DATA;
+extern char *ANGBAND_DIR_EDIT;
+extern char *ANGBAND_DIR_FILE;
+extern char *ANGBAND_DIR_HELP;
+extern char *ANGBAND_DIR_INFO;
+extern char *ANGBAND_DIR_NOTE;
+extern char *ANGBAND_DIR_PREF;
+extern char *ANGBAND_DIR_USER;
+extern char *ANGBAND_DIR_XTRA;
+extern term *angband_term[ANGBAND_TERM_MAX];
+extern char angband_term_name[ANGBAND_TERM_MAX][80];
+extern byte angband_color_table[256][4];
+extern bool_ arg_wizard;
+extern bool_ arg_force_original;
+extern bool_ arg_force_roguelike;
+extern bool_ character_generated;
+extern bool_ character_icky;
+extern bool_ inkey_flag;
+extern bool_ msg_flag;
+extern char player_name[32];
+extern char player_base[32];
+extern char savefile[1024];
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/variable.hpp b/src/variable.hpp
new file mode 100644
index 00000000..74c74f77
--- /dev/null
+++ b/src/variable.hpp
@@ -0,0 +1,317 @@
+#pragma once
+
+#include "angband.h"
+#include "ability_type_fwd.hpp"
+#include "alchemist_recipe_fwd.hpp"
+#include "alloc_entry_fwd.hpp"
+#include "artifact_select_flag_fwd.hpp"
+#include "artifact_type_fwd.hpp"
+#include "birther.hpp"
+#include "cave_type_fwd.hpp"
+#include "deity_type.hpp"
+#include "dungeon_info_type_fwd.hpp"
+#include "effect_type.hpp"
+#include "ego_item_type_fwd.hpp"
+#include "fate.hpp"
+#include "feature_type_fwd.hpp"
+#include "hist_type_fwd.hpp"
+#include "meta_class_type_fwd.hpp"
+#include "monster_ego_fwd.hpp"
+#include "monster_race_fwd.hpp"
+#include "monster_type_fwd.hpp"
+#include "object_kind_fwd.hpp"
+#include "object_type_fwd.hpp"
+#include "owner_type_fwd.hpp"
+#include "player_class_fwd.hpp"
+#include "player_defs.hpp"
+#include "player_race_fwd.hpp"
+#include "player_race_mod_fwd.hpp"
+#include "player_sex_fwd.hpp"
+#include "player_spec_fwd.hpp"
+#include "player_type_fwd.hpp"
+#include "randart_gen_type_fwd.hpp"
+#include "randart_part_type_fwd.hpp"
+#include "random_artifact.hpp"
+#include "random_quest.hpp"
+#include "random_spell.hpp"
+#include "rune_spell.hpp"
+#include "school_type.hpp"
+#include "set_type_fwd.hpp"
+#include "skill_type_fwd.hpp"
+#include "skills_defs.hpp"
+#include "store_action_type_fwd.hpp"
+#include "store_info_type_fwd.hpp"
+#include "timer_type_fwd.hpp"
+#include "town_type_fwd.hpp"
+#include "trap_type_fwd.hpp"
+#include "tval_desc.hpp"
+#include "vault_type_fwd.hpp"
+#include "wilderness_map_fwd.hpp"
+#include "wilderness_type_info_fwd.hpp"
+
+extern int max_macrotrigger;
+extern char *macro_template;
+extern char *macro_modifier_chr;
+extern char *macro_modifier_name[MAX_MACRO_MOD];
+extern char *macro_trigger_name[MAX_MACRO_TRIG];
+extern char *macro_trigger_keycode[2][MAX_MACRO_TRIG];
+extern byte version_major;
+extern byte version_minor;
+extern byte version_patch;
+extern byte sf_major;
+extern byte sf_minor;
+extern byte sf_patch;
+extern u32b sf_when;
+extern u16b sf_lives;
+extern u16b sf_saves;
+extern bool_ character_dungeon;
+extern bool_ character_loaded;
+extern bool_ character_xtra;
+extern u32b seed_flavor;
+extern s16b command_cmd;
+extern s16b command_arg;
+extern s16b command_rep;
+extern s16b command_dir;
+extern s16b command_wrk;
+extern s16b command_new;
+extern s32b energy_use;
+extern bool_ create_up_stair;
+extern bool_ create_down_stair;
+extern bool_ create_up_shaft;
+extern bool_ create_down_shaft;
+extern bool_ alive;
+extern bool_ death;
+extern s16b running;
+extern s16b resting;
+extern s16b cur_hgt;
+extern s16b cur_wid;
+extern s16b dun_level;
+extern s16b old_dun_level;
+extern s16b num_repro;
+extern s16b object_level;
+extern s16b monster_level;
+extern s32b turn;
+extern s32b old_turn;
+extern bool_ wizard;
+extern u16b total_winner;
+extern u16b has_won;
+extern u16b noscore;
+extern bool_ inkey_base;
+extern s16b coin_type;
+extern bool_ opening_chest;
+extern bool_ shimmer_monsters;
+extern bool_ shimmer_objects;
+extern bool_ repair_monsters;
+extern s16b inven_cnt;
+extern s16b equip_cnt;
+extern s16b o_max;
+extern s16b o_cnt;
+extern s16b m_max;
+extern s16b m_cnt;
+extern s16b hack_m_idx;
+extern int total_friends;
+extern s32b total_friend_levels;
+extern int leaving_quest;
+extern char summon_kin_type;
+extern bool_ hack_mind;
+extern bool_ is_autosave;
+extern int artifact_bias;
+extern FILE *text_out_file;
+extern void (*text_out_hook)(byte a, cptr str);
+extern int text_out_indent;
+extern bool_ cheat_peek;
+extern bool_ cheat_hear;
+extern bool_ cheat_room;
+extern bool_ cheat_xtra;
+extern bool_ cheat_know;
+extern bool_ cheat_live;
+extern byte hitpoint_warn;
+extern byte delay_factor;
+extern s16b autosave_freq;
+extern bool_ autosave_t;
+extern bool_ autosave_l;
+extern s16b feeling;
+extern s16b rating;
+extern bool_ good_item_flag;
+extern s16b max_panel_rows, max_panel_cols;
+extern s16b panel_row_min, panel_row_max;
+extern s16b panel_col_min, panel_col_max;
+extern s16b panel_col_prt, panel_row_prt;
+extern byte feat_wall_outer;
+extern byte feat_wall_inner;
+extern s16b floor_type[100];
+extern s16b fill_type[100];
+extern s16b target_who;
+extern s16b target_col;
+extern s16b target_row;
+extern s16b health_who;
+extern s16b monster_race_idx;
+extern s16b monster_ego_idx;
+extern object_type *tracked_object;
+extern char died_from[80];
+extern char history[4][60];
+extern s16b lite_n;
+extern s16b lite_y[LITE_MAX];
+extern s16b 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 char **macro__pat;
+extern char **macro__act;
+extern bool_ *macro__cmd;
+extern char *macro__buf;
+extern u32b option_flag[8];
+extern u32b option_mask[8];
+extern u32b window_flag[ANGBAND_TERM_MAX];
+extern u32b window_mask[ANGBAND_TERM_MAX];
+extern cave_type **cave;
+extern object_type *o_list;
+extern monster_type *m_list;
+extern monster_type *km_list;
+extern u16b max_real_towns;
+extern u16b max_towns;
+extern town_type *town_info;
+extern s16b alloc_kind_size;
+extern alloc_entry *alloc_kind_table;
+extern bool_ alloc_kind_table_valid;
+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 tval_to_char[128];
+extern char *keymap_act[KEYMAP_MODES][256];
+extern player_type *p_ptr;
+extern player_sex *sp_ptr;
+extern player_race *rp_ptr;
+extern player_race_mod *rmp_ptr;
+extern player_class *cp_ptr;
+extern player_spec *spp_ptr;
+extern u32b alchemist_known_egos[32];
+extern alchemist_recipe *alchemist_recipes;
+extern u32b alchemist_known_artifacts[6];
+extern u32b alchemist_gained;
+extern s16b player_hp[PY_MAX_LEVEL];
+extern artifact_select_flag *a_select_flags;
+extern ability_type *ab_info;
+extern skill_type *s_info;
+extern vault_type *v_info;
+extern feature_type *f_info;
+extern object_kind *k_info;
+extern artifact_type *a_info;
+extern ego_item_type *e_info;
+extern randart_part_type *ra_info;
+extern randart_gen_type ra_gen[30];
+extern monster_race *r_info;
+extern monster_ego *re_info;
+extern dungeon_info_type *d_info;
+extern player_class *class_info;
+extern meta_class_type *meta_class_info;
+extern player_race *race_info;
+extern player_race_mod *race_mod_info;
+extern trap_type *t_info;
+extern wilderness_type_info *wf_info;
+extern int wildc2i[256];
+extern store_info_type *st_info;
+extern store_action_type *ba_info;
+extern owner_type *ow_info;
+extern set_type *set_info;
+extern cptr DEFAULT_FEAT_TEXT;
+extern cptr DEFAULT_FEAT_TUNNEL;
+extern cptr DEFAULT_FEAT_BLOCK;
+extern cptr ANGBAND_GRAF;
+extern char *ANGBAND_DIR;
+extern bool_ (*get_mon_num_hook)(int r_idx);
+extern bool_ (*get_mon_num2_hook)(int r_idx);
+extern bool_ (*get_obj_num_hook)(int k_idx);
+extern u16b max_wild_x;
+extern u16b max_wild_y;
+extern wilderness_map **wild_map;
+extern u16b old_max_s_idx;
+extern u16b max_ab_idx;
+extern u16b max_s_idx;
+extern u16b max_al_idx;
+extern u16b max_r_idx;
+extern u16b max_re_idx;
+extern u16b max_k_idx;
+extern u16b max_v_idx;
+extern u16b max_f_idx;
+extern u16b max_a_idx;
+extern u16b max_e_idx;
+extern u16b max_ra_idx;
+extern u16b max_d_idx;
+extern u16b max_o_idx;
+extern u16b max_m_idx;
+extern u16b max_t_idx;
+extern u16b max_rp_idx;
+extern u16b max_c_idx;
+extern u16b max_mc_idx;
+extern u16b max_rmp_idx;
+extern u16b max_st_idx;
+extern u16b max_ba_idx;
+extern u16b max_ow_idx;
+extern u16b max_wf_idx;
+extern u16b max_set_idx;
+extern int init_flags;
+extern bool_ ambush_flag;
+extern bool_ fate_flag;
+extern s16b no_breeds;
+extern bool_ carried_monster_hit;
+extern random_artifact random_artifacts[MAX_RANDARTS];
+extern s32b RANDART_WEAPON;
+extern s32b RANDART_ARMOR;
+extern s32b RANDART_JEWEL;
+extern random_spell random_spells[MAX_SPELLS];
+extern s16b spell_num;
+extern rune_spell rune_spells[MAX_RUNES];
+extern s16b rune_num;
+extern fate fates[MAX_FATES];
+extern byte dungeon_type;
+extern s16b *max_dlv;
+extern s16b doppleganger;
+extern bool_ generate_encounter;
+extern bool_ special_lvls;
+extern bool_ *m_allow_special;
+extern bool_ *k_allow_special;
+extern bool_ *a_allow_special;
+extern s16b plots[MAX_PLOTS];
+extern random_quest random_quests[MAX_RANDOM_QUEST];
+extern bool_ *special_lvl[MAX_DUNGEON_DEPTH];
+extern bool_ generate_special_feeling;
+extern u32b dungeon_flags1;
+extern u32b dungeon_flags2;
+extern birther previous_char;
+extern int max_bg_idx;
+extern s16b schools_count;
+extern school_type schools[SCHOOLS_MAX];
+extern int project_time;
+extern s32b project_time_effect;
+extern effect_type effects[MAX_EFFECTS];
+extern char gen_skill_basem[MAX_SKILLS];
+extern u32b gen_skill_base[MAX_SKILLS];
+extern char gen_skill_modm[MAX_SKILLS];
+extern s16b gen_skill_mod[MAX_SKILLS];
+extern int max_bact;
+extern bool_ automatizer_enabled;
+extern s16b last_teleportation_y;
+extern s16b last_teleportation_x;
+extern cptr game_module;
+extern s32b game_module_idx;
+extern s32b VERSION_MAJOR;
+extern s32b VERSION_MINOR;
+extern s32b VERSION_PATCH;
+extern s32b max_plev;
+extern s32b DUNGEON_BASE;
+extern s32b DUNGEON_DEATH;
+extern s32b DUNGEON_ASTRAL;
+extern s32b DUNGEON_ASTRAL_WILD_X;
+extern s32b DUNGEON_ASTRAL_WILD_Y;
+extern deity_type deity_info[MAX_GODS];
+extern timer_type *gl_timers;
+extern const char *get_version_string();
+extern tval_desc tvals[];
+extern hist_type *bg;
diff --git a/src/vault_type.hpp b/src/vault_type.hpp
new file mode 100644
index 00000000..650599cb
--- /dev/null
+++ b/src/vault_type.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * Vault descriptors.
+ */
+struct vault_type
+{
+ char *data; /* Vault data */
+
+ byte typ; /* Vault type */
+
+ byte rat; /* Vault rating */
+
+ byte hgt; /* Vault height */
+ byte wid; /* Vault width */
+
+ s16b lvl; /* level of special (if any) */
+ byte dun_type; /* Dungeon type where the level will show up */
+
+ s16b mon[10]; /* special monster */
+ int item[3]; /* number of item (usually artifact) */
+};
diff --git a/src/vault_type_fwd.hpp b/src/vault_type_fwd.hpp
new file mode 100644
index 00000000..25ffd8cc
--- /dev/null
+++ b/src/vault_type_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct vault_type;
diff --git a/src/wild.c b/src/wild.cc
index 279b79d9..e9def091 100644
--- a/src/wild.c
+++ b/src/wild.cc
@@ -1,7 +1,3 @@
-/* File: generate.c */
-
-/* Purpose: Wilderness & Town related things */
-
/*
* Copyright (c) 2001 James E. Wilson, Robert A. Koeneke, DarkGod
*
@@ -10,8 +6,28 @@
* included in all such copies.
*/
-#include "angband.h"
-
+#include "wild.hpp"
+
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "feature_type.hpp"
+#include "hook_wild_gen_in.hpp"
+#include "hooks.hpp"
+#include "init1.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "options.hpp"
+#include "player_type.hpp"
+#include "store_info_type.hpp"
+#include "tables.hpp"
+#include "town_type.hpp"
+#include "util.hpp"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+
+#include <memory>
/*
@@ -49,7 +65,7 @@ static void perturb_point_mid(int x1, int x2, int x3, int x4,
if (avg > depth_max) avg = depth_max;
/* Set the new value. */
- cave[ymid][xmid].feat = (byte)avg;
+ cave[ymid][xmid].feat = static_cast<byte>(avg);
}
@@ -73,7 +89,7 @@ static void perturb_point_end(int x1, int x2, int x3,
if (avg > depth_max) avg = depth_max;
/* Set the new value. */
- cave[ymid][xmid].feat = (byte)avg;
+ cave[ymid][xmid].feat = static_cast<byte>(avg);
}
@@ -133,7 +149,7 @@ static void plasma_recursive(int x1, int y1, int x2, int y2,
*
* Return the number of floor grids
*/
-int generate_area(int y, int x, bool_ border, bool_ corner, bool_ refresh)
+static int generate_area(int y, int x, bool_ border, bool_ corner)
{
int road, entrance;
int x1, y1;
@@ -173,15 +189,12 @@ int generate_area(int y, int x, bool_ border, bool_ corner, bool_ refresh)
/* Hack -- Induce consistant town layout */
Rand_value = wild_map[y][x].seed;
- if (!corner)
+ /* Create level background */
+ for (y1 = 0; y1 < MAX_HGT; y1++)
{
- /* Create level background */
- for (y1 = 0; y1 < MAX_HGT; y1++)
+ for (x1 = 0; x1 < MAX_WID; x1++)
{
- for (x1 = 0; x1 < MAX_WID; x1++)
- {
- cave_set_feat(y1, x1, MAX_WILD_TERRAIN / 2);
- }
+ cave_set_feat(y1, x1, MAX_WILD_TERRAIN / 2);
}
}
@@ -190,10 +203,10 @@ int generate_area(int y, int x, bool_ border, bool_ corner, bool_ refresh)
* ToDo: calculate the medium height of the adjacent
* terrains for every corner.
*/
- cave_set_feat(1, 1, (byte)rand_int(MAX_WILD_TERRAIN));
- cave_set_feat(MAX_HGT - 2, 1, (byte)rand_int(MAX_WILD_TERRAIN));
- cave_set_feat(1, MAX_WID - 2, (byte)rand_int(MAX_WILD_TERRAIN));
- cave_set_feat(MAX_HGT - 2, MAX_WID - 2, (byte)rand_int(MAX_WILD_TERRAIN));
+ cave_set_feat(1, 1, rand_int(MAX_WILD_TERRAIN));
+ cave_set_feat(MAX_HGT - 2, 1, rand_int(MAX_WILD_TERRAIN));
+ cave_set_feat(1, MAX_WID - 2, rand_int(MAX_WILD_TERRAIN));
+ cave_set_feat(MAX_HGT - 2, MAX_WID - 2, rand_int(MAX_WILD_TERRAIN));
if (!corner)
{
@@ -335,13 +348,29 @@ int generate_area(int y, int x, bool_ border, bool_ corner, bool_ refresh)
/*
* Border of the wilderness area
*/
-static border_type border;
+namespace {
+
+ struct border_type
+ {
+ byte north[MAX_WID];
+ byte south[MAX_WID];
+ byte east[MAX_HGT];
+ byte west[MAX_HGT];
+ byte north_west;
+ byte north_east;
+ byte south_west;
+ byte south_east;
+ };
+
+ border_type border;
+
+}
/*
* Build the wilderness area outside of the town.
* -KMW-
*/
-void wilderness_gen(int refresh)
+void wilderness_gen()
{
int i, y, x, hack_floor;
bool_ daytime;
@@ -362,7 +391,7 @@ void wilderness_gen(int refresh)
get_mon_num_prep();
/* North border */
- generate_area(y - 1, x, TRUE, FALSE, refresh);
+ generate_area(y - 1, x, TRUE, FALSE);
for (i = 1; i < MAX_WID - 1; i++)
{
@@ -370,7 +399,7 @@ void wilderness_gen(int refresh)
}
/* South border */
- generate_area(y + 1, x, TRUE, FALSE, refresh);
+ generate_area(y + 1, x, TRUE, FALSE);
for (i = 1; i < MAX_WID - 1; i++)
{
@@ -378,7 +407,7 @@ void wilderness_gen(int refresh)
}
/* West border */
- generate_area(y, x - 1, TRUE, FALSE, refresh);
+ generate_area(y, x - 1, TRUE, FALSE);
for (i = 1; i < MAX_HGT - 1; i++)
{
@@ -386,7 +415,7 @@ void wilderness_gen(int refresh)
}
/* East border */
- generate_area(y, x + 1, TRUE, FALSE, refresh);
+ generate_area(y, x + 1, TRUE, FALSE);
for (i = 1; i < MAX_HGT - 1; i++)
{
@@ -394,24 +423,24 @@ void wilderness_gen(int refresh)
}
/* North west corner */
- generate_area(y - 1, x - 1, FALSE, TRUE, refresh);
+ generate_area(y - 1, x - 1, FALSE, TRUE);
border.north_west = cave[MAX_HGT - 2][MAX_WID - 2].feat;
/* North east corner */
- generate_area(y - 1, x + 1, FALSE, TRUE, refresh);
+ generate_area(y - 1, x + 1, FALSE, TRUE);
border.north_east = cave[MAX_HGT - 2][1].feat;
/* South west corner */
- generate_area(y + 1, x - 1, FALSE, TRUE, refresh);
+ generate_area(y + 1, x - 1, FALSE, TRUE);
border.south_west = cave[1][MAX_WID - 2].feat;
/* South east corner */
- generate_area(y + 1, x + 1, FALSE, TRUE, refresh);
+ generate_area(y + 1, x + 1, FALSE, TRUE);
border.south_east = cave[1][1].feat;
/* Create terrain of the current area */
- hack_floor = generate_area(y, x, FALSE, FALSE, refresh);
+ hack_floor = generate_area(y, x, FALSE, FALSE);
/* Special boundary walls -- North */
@@ -503,7 +532,6 @@ void wilderness_gen(int refresh)
player_place(p_ptr->oldpy, p_ptr->oldpx);
- if (!refresh)
{
int lim = (generate_encounter == TRUE) ? 60 : MIN_M_ALLOC_TN;
@@ -533,7 +561,8 @@ void wilderness_gen(int refresh)
}
}
- process_hooks(HOOK_WILD_GEN, "(d)", FALSE);
+ struct hook_wild_gen_in in = { FALSE };
+ process_hooks_new(HOOK_WILD_GEN, &in, NULL);
}
/*
@@ -601,7 +630,8 @@ void wilderness_gen_small()
}
}
- process_hooks(HOOK_WILD_GEN, "(d)", TRUE);
+ struct hook_wild_gen_in in = { TRUE };
+ process_hooks_new(HOOK_WILD_GEN, &in, NULL);
}
/* Show a small radius of wilderness around the player */
@@ -956,8 +986,6 @@ static void town_gen_hack(int t_idx, int qy, int qx)
int y, x, floor, num = 0;
bool_ (*old_get_mon_num_hook)(int r_idx);
- int *rooms;
-
/* Do we use dungeon floor or normal one */
if (magik(TOWN_NORMAL_FLOOR)) floor = FEAT_FLOOR;
else floor = 0;
@@ -974,8 +1002,8 @@ static void town_gen_hack(int t_idx, int qy, int qx)
}
/* Prepare an Array of "remaining stores", and count them */
- C_MAKE(rooms, max_st_idx, int);
- num = get_shops(rooms);
+ std::unique_ptr<int[]> rooms(new int[max_st_idx]);
+ num = get_shops(rooms.get());
/* Place two rows of stores */
for (y = 0; y < 2; y++)
@@ -990,7 +1018,6 @@ static void town_gen_hack(int t_idx, int qy, int qx)
}
}
}
- C_FREE(rooms, max_st_idx, int);
/* Generates the town's borders */
if (magik(TOWN_NORMAL_FLOOR)) town_borders(t_idx, qy, qx);
@@ -1029,7 +1056,7 @@ static void town_gen_hack(int t_idx, int qy, int qx)
monster_type *m_ptr = &m_list[m_idx];
if (m_ptr->level < (dun_level / 2))
{
- m_ptr->exp = MONSTER_EXP(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
+ m_ptr->exp = monster_exp(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
monster_check_experience(m_idx, TRUE);
}
}
@@ -1047,8 +1074,6 @@ static void town_gen_circle(int t_idx, int qy, int qx)
int y, x, cy, cx, rad, floor, num = 0;
bool_ (*old_get_mon_num_hook)(int r_idx);
- int *rooms;
-
/* Do we use dungeon floor or normal one */
if (magik(TOWN_NORMAL_FLOOR)) floor = FEAT_FLOOR;
else floor = 0;
@@ -1110,8 +1135,8 @@ static void town_gen_circle(int t_idx, int qy, int qx)
}
/* Prepare an Array of "remaining stores", and count them */
- C_MAKE(rooms, max_st_idx, int);
- num = get_shops(rooms);
+ std::unique_ptr<int[]> rooms(new int[max_st_idx]);
+ num = get_shops(rooms.get());
/* Place two rows of stores */
for (y = 0; y < 2; y++)
@@ -1126,7 +1151,6 @@ static void town_gen_circle(int t_idx, int qy, int qx)
}
}
}
- C_FREE(rooms, max_st_idx, int);
/* Some inhabitants(leveled .. hehe :) */
@@ -1160,7 +1184,7 @@ static void town_gen_circle(int t_idx, int qy, int qx)
monster_type *m_ptr = &m_list[m_idx];
if (m_ptr->level < (dun_level / 2))
{
- m_ptr->exp = MONSTER_EXP(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
+ m_ptr->exp = monster_exp(m_ptr->level + (dun_level / 2) + randint(dun_level / 2));
monster_check_experience(m_idx, TRUE);
}
}
@@ -1178,11 +1202,9 @@ static void town_gen_hidden(int t_idx, int qy, int qx)
{
int y, x, n, num = 0, i;
- int *rooms;
-
/* Prepare an Array of "remaining stores", and count them */
- C_MAKE(rooms, max_st_idx, int);
- num = get_shops(rooms);
+ std::unique_ptr<int[]> rooms(new int[max_st_idx]);
+ num = get_shops(rooms.get());
/* Get a number of stores to place */
n = rand_int(num / 2) + (num / 2);
@@ -1205,7 +1227,6 @@ static void town_gen_hidden(int t_idx, int qy, int qx)
build_store_hidden(rooms[num], y, x);
}
}
- C_FREE(rooms, max_st_idx, int);
}
diff --git a/src/wild.hpp b/src/wild.hpp
new file mode 100644
index 00000000..4cd9f0e7
--- /dev/null
+++ b/src/wild.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+extern void wilderness_gen();
+extern void wilderness_gen_small(void);
+extern void reveal_wilderness_around_player(int y, int x, int h, int w);
+extern void town_gen(int t_idx);
diff --git a/src/wilderness_map.hpp b/src/wilderness_map.hpp
new file mode 100644
index 00000000..41e873bd
--- /dev/null
+++ b/src/wilderness_map.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "h-basic.h"
+
+/**
+ * A structure describing a wilderness map
+ */
+struct wilderness_map
+{
+ int feat; /* Wilderness feature */
+ u32b seed; /* Seed for the RNG */
+ u16b entrance; /* Entrance for dungeons */
+
+ bool_ known; /* Is it seen by the player ? */
+};
diff --git a/src/wilderness_map_fwd.hpp b/src/wilderness_map_fwd.hpp
new file mode 100644
index 00000000..806efb1b
--- /dev/null
+++ b/src/wilderness_map_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct wilderness_map;
diff --git a/src/wilderness_type_info.hpp b/src/wilderness_type_info.hpp
new file mode 100644
index 00000000..bc23c03e
--- /dev/null
+++ b/src/wilderness_type_info.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "h-basic.h"
+#include "terrain.hpp"
+
+/**
+ * A structure describing a wilderness area
+ * with a terrain, a town or a dungeon entrance
+ */
+struct wilderness_type_info
+{
+ const char *name; /* Name */
+ const char *text; /* Text */
+
+ u16b entrance; /* Which town is there(<1000 i's a town, >=1000 it a dungeon) */
+ s32b wild_x; /* Map coordinates (backed out while parsing map) */
+ s32b wild_y;
+ byte road; /* Flags of road */
+ int level; /* Difficulty level */
+ u32b flags1; /* Some flags */
+ byte feat; /* The feature of f_info.txt that is used to allow passing, ... and to get a char/color/graph */
+ byte terrain_idx; /* Terrain index(defined in defines.h) */
+
+ byte terrain[MAX_WILD_TERRAIN];/* Feature types for the plasma generator */
+};
diff --git a/src/wilderness_type_info_fwd.hpp b/src/wilderness_type_info_fwd.hpp
new file mode 100644
index 00000000..a206c9e3
--- /dev/null
+++ b/src/wilderness_type_info_fwd.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+struct wilderness_type_info;
diff --git a/src/wizard1.c b/src/wizard1.cc
index 7daef324..476def67 100644
--- a/src/wizard1.c
+++ b/src/wizard1.cc
@@ -1,9 +1,23 @@
-/* File: wizard1.c */
-
-/* Purpose: Spoiler generation -BEN- */
-
-#include "angband.h"
-
+#include "wizard1.hpp"
+
+#include "alchemist_recipe.hpp"
+#include "artifact_select_flag.hpp"
+#include "artifact_type.hpp"
+#include "cmd7.hpp"
+#include "ego_item_type.hpp"
+#include "monster_race.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "object_type.hpp"
+#include "skill_type.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+
+#include <vector>
/*
* The spoiler file being created
@@ -281,8 +295,7 @@ static void kind_info(char *buf, char *dam, char *wgt, int *lev, s32b *val, int
if ((k_ptr->tval == TV_WAND) || (k_ptr->tval == TV_STAFF))
{
- hack_apply_magic_power = -99;
- apply_magic(q_ptr, 0, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0));
}
/* Level */
@@ -1311,10 +1324,6 @@ static void spoil_artifact(cptr fname)
*/
static void spoil_mon_desc(cptr fname)
{
- int i, n = 0;
-
- s16b *who;
-
char buf[1024];
char nam[80];
@@ -1342,7 +1351,7 @@ static void spoil_mon_desc(cptr fname)
}
/* Allocate the "who" array */
- C_MAKE(who, max_r_idx, s16b);
+ std::vector<s16b> who;
/* Dump the header */
sprintf(buf, "Monster Spoilers for %s", get_version_string());
@@ -1357,30 +1366,30 @@ static void spoil_mon_desc(cptr fname)
/* Scan the monsters */
- for (i = 1; i < max_r_idx; i++)
+ for (size_t i = 1; i < max_r_idx; i++)
{
monster_race *r_ptr = &r_info[i];
/* Use that monster */
- if (r_ptr->name) who[n++] = i;
+ if (r_ptr->name) {
+ who.push_back(i);
+ }
}
/* Scan again */
- for (i = 0; i < n; i++)
+ for (auto const who_i : who)
{
- monster_race *r_ptr = &r_info[who[i]];
-
- cptr name = (r_name + r_ptr->name);
+ monster_race *r_ptr = &r_info[who_i];
/* Get the "name" */
if (r_ptr->flags1 & (RF1_UNIQUE))
{
- sprintf(nam, "[U] %s", name);
+ sprintf(nam, "[U] %s", r_ptr->name);
}
else
{
- sprintf(nam, "The %s", name);
+ sprintf(nam, "The %s", r_ptr->name);
}
@@ -1428,9 +1437,6 @@ static void spoil_mon_desc(cptr fname)
/* End it */
fprintf(fff, "\n");
- /* Free the "who" array */
- C_KILL(who, max_r_idx, s16b);
-
/* Check for errors */
if (ferror(fff) || my_fclose(fff))
{
@@ -1529,7 +1535,7 @@ static void spoil_mon_info(cptr fname)
}
/* Name */
- sprintf(buf, "%s (", (r_name + r_ptr->name)); /* ---)--- */
+ sprintf(buf, "%s (", r_ptr->name); /* ---)--- */
spoil_out(buf);
/* Color */
@@ -1588,7 +1594,7 @@ static void spoil_mon_info(cptr fname)
/* Describe */
- spoil_out(r_text + r_ptr->text);
+ spoil_out(r_ptr->text);
spoil_out(" ");
@@ -2325,7 +2331,7 @@ static void spoil_mon_info(cptr fname)
}
-char *long_intro =
+static const char *long_intro =
"Essences are the tools of the trade for Alchemists, "
"and unfortunately are useless for any other class. "
"Alchemists use essences to create magical items for them to use.\n\n"
@@ -2480,8 +2486,8 @@ static void spoil_bateries(cptr fname)
spoil_out(format("%-2d %8d %-24s %s\n",
a_select_flags[i].level,
a_select_flags[i].xp,
- al_name + a_select_flags[i].desc,
- al_name + a_select_flags[i].item_desc));
+ a_select_flags[i].desc,
+ a_select_flags[i].item_desc));
/* cycle through all alchemist_recipies*/
for ( j = 0 ; j < max_al_idx ; j++ )
{
@@ -2492,7 +2498,7 @@ static void spoil_bateries(cptr fname)
)
{
spoil_out(format(" %d essences of %s\n", alchemist_recipes[j].qty,
- k_name + k_info[lookup_kind(TV_BATERIE, alchemist_recipes[j].sval_essence)].name));
+ k_info[lookup_kind(TV_BATERIE, alchemist_recipes[j].sval_essence)].name));
}
}
}
@@ -2517,7 +2523,7 @@ static void spoil_bateries(cptr fname)
/* print item desc (ego (tval=1)or item)*/
if (ar_ptr->tval == 1)
{
- strcpy(o_name, e_name + e_info[ar_ptr->sval].name);
+ strcpy(o_name, e_info[ar_ptr->sval].name);
}
else
{
@@ -2537,7 +2543,7 @@ static void spoil_bateries(cptr fname)
}
/* print essence required*/
spoil_out(format(" %d %s", ar_ptr->qty,
- k_name + k_info[lookup_kind(TV_BATERIE, ar_ptr->sval_essence)].name));
+ k_info[lookup_kind(TV_BATERIE, ar_ptr->sval_essence)].name));
}
spoil_out(NULL);
@@ -2572,7 +2578,7 @@ void print_magic_powers( magic_power *powers, int max_powers, void(*power_info)(
/* Dump the header line */
spoiler_blanklines(2);
- sprintf(buf, "%s", s_info[skill_num].name + s_name);
+ sprintf(buf, "%s", s_info[skill_num].name);
spoiler_underline(buf);
spoiler_blanklines(1);
@@ -2652,16 +2658,10 @@ static void spoil_spells(cptr fname)
}
-
-/*
- * Forward declare
- */
-extern void do_cmd_spoilers(void);
-
/*
* Create Spoiler files -BEN-
*/
-void do_cmd_spoilers(void)
+void do_cmd_spoilers()
{
int i;
diff --git a/src/wizard1.hpp b/src/wizard1.hpp
new file mode 100644
index 00000000..0429aa70
--- /dev/null
+++ b/src/wizard1.hpp
@@ -0,0 +1,3 @@
+#pragma once
+
+void do_cmd_spoilers();
diff --git a/src/wizard2.c b/src/wizard2.cc
index 66ddaa38..7bce50c7 100644
--- a/src/wizard2.c
+++ b/src/wizard2.cc
@@ -1,7 +1,3 @@
-/* File: wizard2.c */
-
-/* Purpose: Wizard commands */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,15 +6,44 @@
* included in all such copies.
*/
-#include "angband.h"
-
-void do_cmd_wizard_body(s16b);
-extern void status_main(void);
+#include "wizard2.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "cmd4.hpp"
+#include "corrupt.hpp"
+#include "dungeon_info_type.hpp"
+#include "files.hpp"
+#include "hooks.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "player_type.hpp"
+#include "randart.hpp"
+#include "status.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "traps.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "wizard1.hpp"
+#include "xtra1.hpp"
+#include "xtra2.hpp"
/*
* Adds a lvl to a monster
*/
-void wiz_inc_monster_level(int level)
+static void wiz_inc_monster_level(int level)
{
monster_type *m_ptr;
int ii, jj;
@@ -29,12 +54,12 @@ void wiz_inc_monster_level(int level)
{
m_ptr = &m_list[cave[jj][ii].m_idx];
- m_ptr->exp = MONSTER_EXP(m_ptr->level + level);
+ m_ptr->exp = monster_exp(m_ptr->level + level);
monster_check_experience(cave[jj][ii].m_idx, FALSE);
}
}
-void wiz_align_monster(int status)
+static void wiz_align_monster(int status)
{
monster_type *m_ptr;
int ii, jj;
@@ -52,7 +77,7 @@ void wiz_align_monster(int status)
/*
* Teleport directly to a town
*/
-void teleport_player_town(int town)
+static void teleport_player_town(int town)
{
int x = 0, y = 0;
@@ -69,7 +94,6 @@ finteletown:
p_ptr->wilderness_y = y;
p_ptr->wilderness_x = x;
- p_ptr->inside_arena = 0;
leaving_quest = p_ptr->inside_quest;
p_ptr->inside_quest = 0;
@@ -113,7 +137,7 @@ void do_cmd_rerate(void)
/* Update and redraw hitpoints */
p_ptr->update |= (PU_HP);
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -479,60 +503,6 @@ static void wiz_display_item(object_type *o_ptr)
}
-/*
- * A list of tvals and their textual names
- */
-tval_desc2 tvals[] =
-{
- { TV_SWORD, "Sword" },
- { TV_POLEARM, "Polearm" },
- { TV_HAFTED, "Hafted Weapon" },
- { TV_AXE, "Axe" },
- { TV_BOW, "Bow" },
- { TV_BOOMERANG, "Boomerang" },
- { TV_ARROW, "Arrows" },
- { TV_BOLT, "Bolts" },
- { TV_SHOT, "Shots" },
- { TV_SHIELD, "Shield" },
- { TV_CROWN, "Crown" },
- { TV_HELM, "Helm" },
- { TV_GLOVES, "Gloves" },
- { TV_BOOTS, "Boots" },
- { TV_CLOAK, "Cloak" },
- { TV_DRAG_ARMOR, "Dragon Scale Mail" },
- { TV_HARD_ARMOR, "Hard Armor" },
- { TV_SOFT_ARMOR, "Soft Armor" },
- { TV_RING, "Ring" },
- { TV_AMULET, "Amulet" },
- { TV_LITE, "Lite" },
- { TV_POTION, "Potion" },
- { TV_POTION2, "Potion" },
- { TV_SCROLL, "Scroll" },
- { TV_WAND, "Wand" },
- { TV_STAFF, "Staff" },
- { TV_ROD_MAIN, "Rod" },
- { TV_ROD, "Rod Tip" },
- { TV_BOOK, "Schools Spellbook", },
- { TV_SYMBIOTIC_BOOK, "Symbiotic Spellbook", },
- { TV_DRUID_BOOK, "Elemental Stone" },
- { TV_MUSIC_BOOK, "Music Book" },
- { TV_DAEMON_BOOK, "Daemon Book" },
- { TV_SPIKE, "Spikes" },
- { TV_DIGGING, "Digger" },
- { TV_CHEST, "Chest" },
- { TV_FOOD, "Food" },
- { TV_FLASK, "Flask" },
- { TV_MSTAFF, "Mage Staff" },
- { TV_BATERIE, "Essence" },
- { TV_PARCHMENT, "Parchment" },
- { TV_INSTRUMENT, "Musical Instrument" },
- { TV_RUNE1, "Rune 1" },
- { TV_RUNE2, "Rune 2" },
- { TV_JUNK, "Junk" },
- { TV_TRAPKIT, "Trapping Kit" },
- { 0, NULL }
-};
-
/*
* Strip an "object name" into a buffer
@@ -543,7 +513,7 @@ static void strip_name(char *buf, int k_idx)
object_kind *k_ptr = &k_info[k_idx];
- cptr str = (k_name + k_ptr->name);
+ cptr str = k_ptr->name;
/* Skip past leading characters */
@@ -816,8 +786,7 @@ static void wiz_reroll_item(object_type *o_ptr)
else if (ch == 'b' || ch == 'B')
{
object_prep(q_ptr, o_ptr->k_idx);
- hack_apply_magic_power = -2;
- apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);
+ apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE, boost::make_optional(-2));
}
/* Apply normal magic, but first clear object */
@@ -889,7 +858,7 @@ static void wiz_statistics(object_type *o_ptr)
long i, matches, better, worse, other;
char ch;
- char *quality;
+ const char *quality;
bool_ good, great;
@@ -970,11 +939,8 @@ static void wiz_statistics(object_type *o_ptr)
/* Output every few rolls */
if ((i < 100) || (i % 100 == 0))
{
- /* Do not wait */
- inkey_scan = TRUE;
-
/* Allow interupt */
- if (inkey())
+ if (inkey_scan())
{
/* Flush */
flush();
@@ -1109,30 +1075,22 @@ static void wiz_quantity_item(object_type *o_ptr)
*/
static void do_cmd_wiz_play(void)
{
- int item;
-
- object_type forge;
- object_type *q_ptr;
-
- object_type *o_ptr;
-
- char ch;
-
- bool_ changed;
-
- cptr q, s;
-
/* Get an item */
- q = "Play with which object? ";
- s = "You have nothing to play with.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Play with which object? ",
+ "You have nothing to play with.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* The item was not changed */
- changed = FALSE;
+ bool_ changed = FALSE;
/* Icky */
@@ -1143,7 +1101,8 @@ static void do_cmd_wiz_play(void)
/* Get local object */
- q_ptr = &forge;
+ object_type forge;
+ object_type *q_ptr = &forge;
/* Copy object */
object_copy(q_ptr, o_ptr);
@@ -1152,6 +1111,8 @@ static void do_cmd_wiz_play(void)
/* The main loop */
while (TRUE)
{
+ char ch;
+
/* Display the item */
wiz_display_item(q_ptr);
@@ -1421,7 +1382,6 @@ static void do_cmd_wiz_jump(void)
/* Change level */
dun_level = command_arg;
- p_ptr->inside_arena = 0;
leaving_quest = p_ptr->inside_quest;
p_ptr->inside_quest = 0;
@@ -1504,8 +1464,14 @@ static void do_cmd_wiz_named(int r_idx, bool_ slp)
/* Place it (allow groups) */
m_allow_special[r_idx] = TRUE;
- if (place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_ENEMY)) break;
+ int m_idx = place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_ENEMY);
m_allow_special[r_idx] = FALSE;
+
+ // If summoning succeeded, we stop.
+ if (m_idx)
+ {
+ break;
+ }
}
}
@@ -1526,7 +1492,6 @@ void do_cmd_wiz_named_friendly(int r_idx, bool_ slp)
if (r_idx >= max_r_idx) return;
/* Try 10 times */
- m_allow_special[r_idx] = TRUE;
for (i = 0; i < 10; i++)
{
int d = 1;
@@ -1538,9 +1503,16 @@ void do_cmd_wiz_named_friendly(int r_idx, bool_ slp)
if (!cave_empty_bold(y, x)) continue;
/* Place it (allow groups) */
- if (place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_PET)) break;
+ m_allow_special[r_idx] = TRUE;
+ int m_idx = place_monster_aux(y, x, r_idx, slp, TRUE, MSTATUS_PET);
+ m_allow_special[r_idx] = FALSE;
+
+ // Stop if we succeeded
+ if (m_idx)
+ {
+ break;
+ }
}
- m_allow_special[r_idx] = FALSE;
}
@@ -1566,7 +1538,7 @@ static void do_cmd_wiz_zap(void)
}
-extern void do_cmd_wiz_body(s16b bidx)
+static void do_cmd_wiz_body(s16b bidx)
/* Might create problems with equipment slots. For safety,
be nude when calling this function */
{
@@ -1578,24 +1550,10 @@ extern void do_cmd_wiz_body(s16b bidx)
/*
- * External function
- */
-extern void do_cmd_spoilers(void);
-
-
-
-/*
- * Hack -- declare external function
- */
-extern void do_cmd_debug(void);
-
-
-
-/*
* Ask for and parse a "debug command"
* The "command_arg" may have been set.
*/
-void do_cmd_debug(void)
+void do_cmd_debug()
{
int x, y;
char cmd;
@@ -1670,7 +1628,7 @@ void do_cmd_debug(void)
{
dungeon_type = command_arg;
dun_level = d_info[dungeon_type].mindepth;
- msg_format("You go into %s", d_text + d_info[dungeon_type].text);
+ msg_format("You go into %s", d_info[dungeon_type].text);
/* Leaving */
p_ptr->leaving = TRUE;
@@ -1797,7 +1755,7 @@ void do_cmd_debug(void)
/* Display the hitpoints */
p_ptr->update |= (PU_HP);
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1866,7 +1824,7 @@ void do_cmd_debug(void)
p_ptr->tim_mimic = 100;
p_ptr->mimic_form = command_arg;
/* Redraw title */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
break;
@@ -1903,8 +1861,7 @@ void do_cmd_debug(void)
/* Not a Wizard Command */
default:
- if (!process_hooks(HOOK_DEBUG_COMMAND, "(d)", cmd))
- msg_print("That is not a valid debug command.");
+ msg_print("That is not a valid debug command.");
break;
}
}
diff --git a/src/wizard2.hpp b/src/wizard2.hpp
new file mode 100644
index 00000000..cec515c8
--- /dev/null
+++ b/src/wizard2.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void do_cmd_rerate(void);
+extern void do_cmd_wiz_cure_all(void);
+extern void do_cmd_wiz_named_friendly(int r_idx, bool_ slp);
+extern void do_cmd_debug();
diff --git a/src/xtra1.c b/src/xtra1.cc
index 638a2102..87ecd62f 100644
--- a/src/xtra1.c
+++ b/src/xtra1.cc
@@ -1,7 +1,3 @@
-/* File: misc.c */
-
-/* Purpose: misc code */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -10,9 +6,49 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include "messages.h"
+#include "xtra1.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "cmd7.hpp"
+#include "dungeon_info_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hook_calculate_hp_in.hpp"
+#include "hook_calculate_hp_out.hpp"
+#include "hooks.hpp"
+#include "levels.hpp"
+#include "messages.hpp"
+#include "mimic.hpp"
+#include "monster1.hpp"
+#include "monster2.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "skill_type.hpp"
+#include "skills.hpp"
+#include "spells3.hpp"
+#include "spells6.hpp"
+#include "stats.hpp"
+#include "tables.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "xtra2.hpp"
+
+#include <cassert>
/*
* Converts stat num into a six-char (right justified) string
@@ -117,6 +153,12 @@ s16b modify_stat_value(int value, int amount)
}
}
+ /* Clip to permissible range */
+ if (value < 3)
+ {
+ value = 3;
+ }
+
/* Return new value */
return (value);
}
@@ -274,7 +316,7 @@ static void prt_title(void)
/* Normal */
else
{
- p = cp_ptr->titles[(p_ptr->lev - 1) / 5] + c_text;
+ p = cp_ptr->titles[(p_ptr->lev - 1) / 5];
}
@@ -311,20 +353,13 @@ static void prt_exp(void)
{
char out_val[32];
- if (!exp_need)
+ if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev))
{
- (void)sprintf(out_val, "%8ld", (long)p_ptr->exp);
+ (void)sprintf(out_val, "********");
}
else
{
- if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev))
- {
- (void)sprintf(out_val, "********");
- }
- else
- {
- (void)sprintf(out_val, "%8ld", (long)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp);
- }
+ (void)sprintf(out_val, "%8ld", (long)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp);
}
if (p_ptr->exp >= p_ptr->max_exp)
@@ -490,7 +525,7 @@ static void prt_sp(void)
/*
* Prints depth in stat area
*/
-static void prt_depth(void)
+static void prt_depth(int row, int col)
{
char depths[32];
dungeon_info_type *d_ptr = &d_info[dungeon_type];
@@ -499,10 +534,6 @@ static void prt_depth(void)
{
strcpy(depths, " ");
}
- else if (p_ptr->inside_arena)
- {
- strcpy(depths, "Arena");
- }
else if (get_dungeon_name(depths))
{
/* Empty */
@@ -517,28 +548,13 @@ static void prt_depth(void)
}
else if (!dun_level)
{
- if (wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name + wf_name)
- strcpy(depths, wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name + wf_name);
- else
- strcpy(depths, "Town/Wild");
- }
- else if (depth_in_feet)
- {
- if (dungeon_flags1 & DF1_TOWER)
+ if (wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name)
{
- (void)strnfmt(depths, 32, "%c%c%c -%d ft",
- d_ptr->short_name[0],
- d_ptr->short_name[1],
- d_ptr->short_name[2],
- dun_level * 50);
+ strcpy(depths, wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name);
}
else
{
- (void)strnfmt(depths, 32, "%c%c%c %d ft",
- d_ptr->short_name[0],
- d_ptr->short_name[1],
- d_ptr->short_name[2],
- dun_level * 50);
+ strcpy(depths, "Town/Wild");
}
}
else
@@ -563,132 +579,9 @@ static void prt_depth(void)
/* Right-Adjust the "depth", and clear old values */
if (p_ptr->word_recall)
- c_prt(TERM_ORANGE, format("%13s", depths), ROW_DEPTH, COL_DEPTH);
- else
- prt(format("%13s", depths), ROW_DEPTH, COL_DEPTH);
-}
-
-
-/*
- * Prints status of hunger
- */
-static void prt_hunger(void)
-{
- /* Fainting / Starving */
- if (p_ptr->food < PY_FOOD_FAINT)
- {
- c_put_str(TERM_RED, "Weak ", ROW_HUNGRY, COL_HUNGRY);
- }
-
- /* Weak */
- else if (p_ptr->food < PY_FOOD_WEAK)
- {
- c_put_str(TERM_ORANGE, "Weak ", ROW_HUNGRY, COL_HUNGRY);
- }
-
- /* Hungry */
- else if (p_ptr->food < PY_FOOD_ALERT)
- {
- c_put_str(TERM_YELLOW, "Hungry", ROW_HUNGRY, COL_HUNGRY);
- }
-
- /* Normal */
- else if (p_ptr->food < PY_FOOD_FULL)
- {
- c_put_str(TERM_L_GREEN, " ", ROW_HUNGRY, COL_HUNGRY);
- }
-
- /* Full */
- else if (p_ptr->food < PY_FOOD_MAX)
- {
- c_put_str(TERM_L_GREEN, "Full ", ROW_HUNGRY, COL_HUNGRY);
- }
-
- /* Gorged */
- else
- {
- c_put_str(TERM_GREEN, "Gorged", ROW_HUNGRY, COL_HUNGRY);
- }
-}
-
-
-/*
- * Prints Blind status
- */
-static void prt_blind(void)
-{
- if (p_ptr->blind)
- {
- c_put_str(TERM_ORANGE, "Blind", ROW_BLIND, COL_BLIND);
- }
- else
- {
- put_str(" ", ROW_BLIND, COL_BLIND);
- }
-}
-
-
-/*
- * Prints Confusion status
- */
-static void prt_confused(void)
-{
- if (p_ptr->confused)
- {
- c_put_str(TERM_ORANGE, "Conf", ROW_CONFUSED, COL_CONFUSED);
- }
- else
- {
- put_str(" ", ROW_CONFUSED, COL_CONFUSED);
- }
-}
-
-
-/*
- * Prints Fear status
- */
-static void prt_afraid(void)
-{
- if (p_ptr->afraid)
- {
- c_put_str(TERM_ORANGE, "Afraid", ROW_AFRAID, COL_AFRAID);
- }
- else
- {
- put_str(" ", ROW_AFRAID, COL_AFRAID);
- }
-}
-
-
-/*
- * Prints Poisoned status
- */
-static void prt_poisoned(void)
-{
- if (p_ptr->poisoned)
- {
- c_put_str(TERM_ORANGE, "Poison", ROW_POISONED, COL_POISONED);
- }
+ c_prt(TERM_ORANGE, format("%13s", depths), row, col);
else
- {
- put_str(" ", ROW_POISONED, COL_POISONED);
- }
-}
-
-
-/*
- * Prints trap detection status
- */
-static void prt_dtrap(void)
-{
- if (cave[p_ptr->py][p_ptr->px].info & CAVE_DETECT)
- {
- c_put_str(TERM_L_GREEN, "DTrap", ROW_DTRAP, COL_DTRAP);
- }
- else
- {
- put_str(" ", ROW_DTRAP, COL_DTRAP);
- }
+ prt(format("%13s", depths), row, col);
}
@@ -699,7 +592,7 @@ static void prt_dtrap(void)
* This function was a major bottleneck when resting, so a lot of
* the text formatting code was optimized in place below.
*/
-static void prt_state(void)
+static void prt_state(int row, int col)
{
byte attr = TERM_WHITE;
@@ -804,14 +697,14 @@ static void prt_state(void)
}
/* Display the info (or blanks) */
- c_put_str(attr, text, ROW_STATE, COL_STATE);
+ c_put_str(attr, text, row, col);
}
/*
* Prints the speed of a character. -CJS-
*/
-static void prt_speed(void)
+static void prt_speed(int row, int col)
{
int i = p_ptr->pspeed;
@@ -836,58 +729,167 @@ static void prt_speed(void)
}
/* Display the speed */
- c_put_str(attr, format("%-10s", buf), ROW_SPEED, COL_SPEED);
+ c_put_str(attr, format("%-10s", buf), row, col);
}
-static void prt_study(void)
+
+/*
+ * Prints status line
+ */
+static void prt_status_line(void)
{
+ int wid, hgt;
+ Term_get_size(&wid, &hgt);
+ int row = hgt - 1;
+
+ /* Fainting / Starving */
+ int col = 0;
+ if (p_ptr->food < PY_FOOD_FAINT)
+ {
+ c_put_str(TERM_RED, "Weak ", row, col);
+ }
+ else if (p_ptr->food < PY_FOOD_WEAK)
+ {
+ c_put_str(TERM_ORANGE, "Weak ", row, col);
+ }
+ else if (p_ptr->food < PY_FOOD_ALERT)
+ {
+ c_put_str(TERM_YELLOW, "Hungry", row, col);
+ }
+ else if (p_ptr->food < PY_FOOD_FULL)
+ {
+ c_put_str(TERM_L_GREEN, " ", row, col);
+ }
+ else if (p_ptr->food < PY_FOOD_MAX)
+ {
+ c_put_str(TERM_L_GREEN, "Full ", row, col);
+ }
+ else
+ {
+ c_put_str(TERM_GREEN, "Gorged", row, col);
+ }
+
+ /* Blind */
+ col = 7;
+ if (p_ptr->blind)
+ {
+ c_put_str(TERM_ORANGE, "Blind", row, col);
+ }
+ else
+ {
+ put_str(" ", row, col);
+ }
+
+ /* Confusion */
+ col = 13;
+ if (p_ptr->confused)
+ {
+ c_put_str(TERM_ORANGE, "Conf", row, col);
+ }
+ else
+ {
+ put_str(" ", row, col);
+ }
+
+ /* Fear */
+ col = 18;
+ if (p_ptr->afraid)
+ {
+ c_put_str(TERM_ORANGE, "Afraid", row, col);
+ }
+ else
+ {
+ put_str(" ", row, col);
+ }
+
+ /* Poison */
+ col = 25;
+ if (p_ptr->poisoned)
+ {
+ c_put_str(TERM_ORANGE, "Poison", row, col);
+ }
+ else
+ {
+ put_str(" ", row, col);
+ }
+
+ /* Dtrap */
+ col = 32;
+ if (cave[p_ptr->py][p_ptr->px].info & CAVE_DETECT)
+ {
+ c_put_str(TERM_L_GREEN, "DTrap", row, col);
+ }
+ else
+ {
+ put_str(" ", row, col);
+ }
+
+ /* State */
+ col = 38;
+ prt_state(row, col);
+
+ /* Speed */
+ col = 49;
+ prt_speed(row, col);
+
+ /* "Study" */
+ col = 60;
if (p_ptr->skill_points)
{
- put_str("Skill", ROW_STUDY, COL_STUDY);
+ put_str("Skill", row, col);
}
else
{
- put_str(" ", ROW_STUDY, COL_STUDY);
+ put_str(" ", row, col);
}
+
+ /* Depth */
+ col = wid - 14;
+ prt_depth(row, col);
}
+
static void prt_cut(void)
{
int c = p_ptr->cut;
+ int hgt;
+ Term_get_size(nullptr, &hgt);
+ int row = hgt - 3;
+ int col = 0;
if (c > 1000)
{
- c_put_str(TERM_L_RED, "Mortal wound", ROW_CUT, COL_CUT);
+ c_put_str(TERM_L_RED, "Mortal wound", row, col);
}
else if (c > 200)
{
- c_put_str(TERM_RED, "Deep gash ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_RED, "Deep gash ", row, col);
}
else if (c > 100)
{
- c_put_str(TERM_RED, "Severe cut ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_RED, "Severe cut ", row, col);
}
else if (c > 50)
{
- c_put_str(TERM_ORANGE, "Nasty cut ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_ORANGE, "Nasty cut ", row, col);
}
else if (c > 25)
{
- c_put_str(TERM_ORANGE, "Bad cut ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_ORANGE, "Bad cut ", row, col);
}
else if (c > 10)
{
- c_put_str(TERM_YELLOW, "Light cut ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_YELLOW, "Light cut ", row, col);
}
else if (c)
{
- c_put_str(TERM_YELLOW, "Graze ", ROW_CUT, COL_CUT);
+ c_put_str(TERM_YELLOW, "Graze ", row, col);
}
else
{
- put_str(" ", ROW_CUT, COL_CUT);
+ put_str(" ", row, col);
}
}
@@ -896,22 +898,26 @@ static void prt_cut(void)
static void prt_stun(void)
{
int s = p_ptr->stun;
+ int hgt;
+ Term_get_size(nullptr, &hgt);
+ int row = hgt - 2;
+ int col = 0;
if (s > 100)
{
- c_put_str(TERM_RED, "Knocked out ", ROW_STUN, COL_STUN);
+ c_put_str(TERM_RED, "Knocked out ", row, col);
}
else if (s > 50)
{
- c_put_str(TERM_ORANGE, "Heavy stun ", ROW_STUN, COL_STUN);
+ c_put_str(TERM_ORANGE, "Heavy stun ", row, col);
}
else if (s)
{
- c_put_str(TERM_ORANGE, "Stun ", ROW_STUN, COL_STUN);
+ c_put_str(TERM_ORANGE, "Stun ", row, col);
}
else
{
- put_str(" ", ROW_STUN, COL_STUN);
+ put_str(" ", row, col);
}
}
@@ -933,32 +939,37 @@ static void prt_stun(void)
*/
static void health_redraw(void)
{
+ int hgt;
+ Term_get_size(nullptr, &hgt);
+ int col = 0;
+ int row = hgt - 4;
+
/* Not tracking */
if (!health_who)
{
/* Erase the health bar */
- Term_erase(COL_INFO, ROW_INFO, 12);
+ Term_erase(col, row, 12);
}
/* Tracking an unseen monster */
else if (!m_list[health_who].ml)
{
/* Indicate that the monster health is "unknown" */
- Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
+ Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
}
/* Tracking a hallucinatory monster */
else if (p_ptr->image)
{
/* Indicate that the monster health is "unknown" */
- Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
+ Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
}
/* Tracking a dead monster (???) */
- else if (!m_list[health_who].hp < 0)
+ else if ((m_list[health_who].hp < 0))
{
/* Indicate that the monster health is "unknown" */
- Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
+ Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
}
/* Tracking a visible monster */
@@ -1002,15 +1013,15 @@ static void health_redraw(void)
len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;
/* Default to "unknown" */
- Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
+ Term_putstr(col, row, 12, TERM_WHITE, "[----------]");
/* Dump the current "health" (use '*' symbols) */
if (m_ptr->stunned) {
- Term_putstr(COL_INFO + 1, ROW_INFO, len, attr, "ssssssssss");
+ Term_putstr(col + 1, row, len, attr, "ssssssssss");
} else if (m_ptr->confused) {
- Term_putstr(COL_INFO + 1, ROW_INFO, len, attr, "cccccccccc");
+ Term_putstr(col + 1, row, len, attr, "cccccccccc");
} else {
- Term_putstr(COL_INFO + 1, ROW_INFO, len, attr, "**********");
+ Term_putstr(col + 1, row, len, attr, "**********");
}
}
}
@@ -1020,13 +1031,13 @@ static void health_redraw(void)
/*
* Display basic info (mostly left of map)
*/
-static void prt_frame_basic(void)
+static void prt_frame(void)
{
int i;
/* Race and Class */
- prt_field(rp_ptr->title + rp_name, ROW_RACE, COL_RACE);
- prt_field(spp_ptr->title + c_name, ROW_CLASS, COL_CLASS);
+ prt_field(rp_ptr->title, ROW_RACE, COL_RACE);
+ prt_field(spp_ptr->title, ROW_CLASS, COL_CLASS);
/* Title */
prt_title();
@@ -1059,41 +1070,15 @@ static void prt_frame_basic(void)
/* Gold */
prt_gold();
- /* Current depth */
- prt_depth();
-
- /* Special */
- health_redraw();
-}
-
-
-/*
- * Display extra info (mostly below map)
- */
-static void prt_frame_extra(void)
-{
/* Cut/Stun */
prt_cut();
prt_stun();
- /* Food */
- prt_hunger();
-
- /* Various */
- prt_blind();
- prt_confused();
- prt_afraid();
- prt_poisoned();
- prt_dtrap();
-
- /* State */
- prt_state();
-
- /* Speed */
- prt_speed();
+ /* Current depth */
+ prt_status_line();
- /* Study spells */
- prt_study();
+ /* Special */
+ health_redraw();
}
@@ -1412,10 +1397,8 @@ static void fix_m_list(void)
/* Skip unseen monsters */
if (r_ptr->flags9 & RF9_MIMIC)
{
- object_type *o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[m_ptr->hold_o_idx];
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
/* Memorized objects */
if (!o_ptr->marked) continue;
@@ -1479,11 +1462,11 @@ static void fix_m_list(void)
/* Dump the monster name */
if (r_ptr->total_visible == 1)
{
- c_prt(attr, (r_name + r_ptr->name), (num % (h - 1)) + 1, (num / (h - 1) * 26));
+ c_prt(attr, r_ptr->name, (num % (h - 1)) + 1, (num / (h - 1) * 26));
}
else
{
- c_prt(attr, format("%s (x%d)", r_name + r_ptr->name, r_ptr->total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26);
+ c_prt(attr, format("%s (x%d)", r_ptr->name, r_ptr->total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26);
}
num++;
@@ -1506,19 +1489,6 @@ static void fix_m_list(void)
/*
- * Calculate number of spells player should have, and forget,
- * or remember, spells until that number is properly reflected.
- *
- * Note that this function induces various "status" messages,
- * which must be bypasses until the character is created.
- */
-static void calc_spells(void)
-{
- p_ptr->new_spells = 0;
-}
-
-
-/*
* Calculate powers of player given the current set of corruptions.
*/
static void calc_powers_corruption()
@@ -1566,9 +1536,6 @@ static void calc_powers(void)
/* Calculate powers granted by corruptions */
calc_powers_corruption();
- /* Hooked powers */
- process_hooks(HOOK_CALC_POWERS, "()");
-
/* Add objects powers */
for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
{
@@ -1633,8 +1600,7 @@ static void calc_powers(void)
/*
* Calculate the player's sanity
*/
-
-void calc_sanity(void)
+static void calc_sanity()
{
int bonus, msane;
@@ -1659,7 +1625,7 @@ void calc_sanity(void)
p_ptr->csane_frac = 0;
}
- p_ptr->redraw |= (PR_SANITY);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->window |= (PW_PLAYER);
}
}
@@ -1711,7 +1677,7 @@ static void calc_mana(void)
msp += msp * cp_ptr->mana / 100;
/* Apply Eru mana */
- GOD(GOD_ERU)
+ if (p_ptr->pgod == GOD_ERU)
{
s32b tmp = p_ptr->grace;
@@ -1777,19 +1743,7 @@ static void calc_mana(void)
msp -= ((cur_wgt - max_wgt) / 10);
}
- /* When meditating your mana is increased ! */
- if (p_ptr->meditation)
- {
- msp += 50;
- p_ptr->csp += 50;
- }
-
/* Sp mods? */
- if (process_hooks_ret(HOOK_CALC_MANA, "d", "(d)", msp))
- {
- msp = process_hooks_return[0].num;
- }
-
mana_school_calc_mana(&msp);
meta_inertia_control_calc_mana(&msp);
@@ -1811,7 +1765,7 @@ static void calc_mana(void)
}
/* Display mana later */
- p_ptr->redraw |= (PR_MANA);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -1871,6 +1825,8 @@ void calc_hitpoints(void)
bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128);
/* Calculate hitpoints */
+ assert(p_ptr->lev - 1 >= 0);
+ assert(p_ptr->lev - 1 < PY_MAX_LEVEL);
mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2);
/* Always have at least one hitpoint per level */
@@ -1888,7 +1844,7 @@ void calc_hitpoints(void)
}
/* Factor in the melkor hp modifications */
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
mhp -= (p_ptr->melkor_sacrifice * 10);
if (mhp < 1) mhp = 1;
@@ -1931,9 +1887,13 @@ void calc_hitpoints(void)
}
/* Hp mods? */
- if (process_hooks_ret(HOOK_CALC_HP, "d", "(d)", mhp))
{
- mhp = process_hooks_return[0].num;
+ struct hook_calculate_hp_in in = { mhp };
+ struct hook_calculate_hp_out out = { 0 };
+ if (process_hooks_new(HOOK_CALC_HP, &in, &out))
+ {
+ mhp = out.mhp;
+ }
}
/* Never less than 1 */
@@ -1955,7 +1915,7 @@ void calc_hitpoints(void)
p_ptr->mhp = mhp;
/* Display hitpoints (later) */
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2073,9 +2033,6 @@ int weight_limit(void)
/* Weight limit based only on strength */
i = adj_str_wgt[p_ptr->stat_ind[A_STR]] * 100;
- if (process_hooks_ret(HOOK_CALC_WEIGHT, "d", "(d)", i))
- i = process_hooks_return[0].num;
-
/* Return the result */
return (i);
}
@@ -2378,7 +2335,7 @@ int get_archery_skill()
static void calc_gods()
{
/* Boost WIS if the player follows Eru */
- GOD(GOD_ERU)
+ if (p_ptr->pgod == GOD_ERU)
{
if (p_ptr->grace > 10000) p_ptr->stat_add[A_WIS] += 1;
if (p_ptr->grace > 20000) p_ptr->stat_add[A_WIS] += 1;
@@ -2386,7 +2343,7 @@ static void calc_gods()
}
/* Boost str, con, chr and reduce int, wis if the player follows Melkor */
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
if (p_ptr->grace > 10000) p_ptr->stat_add[A_STR] += 1;
if (p_ptr->grace > 20000) p_ptr->stat_add[A_STR] += 1;
@@ -2408,7 +2365,7 @@ static void calc_gods()
if (p_ptr->grace > 20000) p_ptr->stat_add[A_WIS] -= 1;
if (p_ptr->grace > 30000) p_ptr->stat_add[A_WIS] -= 1;
- PRAY_GOD(GOD_MELKOR)
+ if (praying_to(GOD_MELKOR))
{
if (p_ptr->grace > 5000) p_ptr->invis += 30;
if (p_ptr->grace > 15000) p_ptr->immune_fire = TRUE;
@@ -2417,7 +2374,7 @@ static void calc_gods()
}
/* Gifts of Manwe if the player is praying to Manwe */
- PRAY_GOD(GOD_MANWE)
+ if (praying_to(GOD_MANWE))
{
s32b add = p_ptr->grace;
@@ -2432,13 +2389,13 @@ static void calc_gods()
}
/* Manwe bonus not requiring the praying status */
- GOD(GOD_MANWE)
+ if (p_ptr->pgod == GOD_MANWE)
{
if (p_ptr->grace >= 2000) p_ptr->ffall = TRUE;
}
/* Boost Str and Con if the player is following Tulkas */
- GOD(GOD_TULKAS)
+ if (p_ptr->pgod == GOD_TULKAS)
{
if (p_ptr->grace > 5000) p_ptr->stat_add[A_CON] += 1;
if (p_ptr->grace > 10000) p_ptr->stat_add[A_CON] += 1;
@@ -2450,7 +2407,7 @@ static void calc_gods()
}
/* Aule provides to-hit/damage bonuses and fire resistance */
- GOD(GOD_AULE)
+ if (p_ptr->pgod == GOD_AULE)
{
if (p_ptr->grace > 0)
{
@@ -2476,7 +2433,7 @@ static void calc_gods()
/* Mandos provides nether resistance and, while praying,
nether immunity and prevents teleportation. */
- GOD(GOD_MANDOS)
+ if (p_ptr->pgod == GOD_MANDOS)
{
p_ptr->resist_neth = TRUE;
@@ -2495,7 +2452,7 @@ static void calc_gods()
/* Ulmo provides water breath and, while praying can
provide poison resistance and magic breath. */
- GOD(GOD_ULMO)
+ if (p_ptr->pgod == GOD_ULMO)
{
p_ptr->water_breath = TRUE;
@@ -2734,37 +2691,6 @@ void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pva
if (tmp > 0) p_ptr->antimagic_dis += tmp;
}
- if (f4 & (TR4_ANTIMAGIC_30))
- {
- s32b tmp;
-
- tmp = 7 + get_skill_scale(SKILL_ANTIMAGIC, 33) - antimagic_mod;
- if (tmp > 0) p_ptr->antimagic += tmp;
-
- tmp = 1 + get_skill_scale(SKILL_ANTIMAGIC, 2) - antimagic_mod / 15;
- if (tmp > 0) p_ptr->antimagic_dis += tmp;
- }
-
- if (f4 & (TR4_ANTIMAGIC_20))
- {
- s32b tmp;
-
- tmp = 5 + get_skill_scale(SKILL_ANTIMAGIC, 15) - antimagic_mod;
- if (tmp > 0) p_ptr->antimagic += tmp;
-
- p_ptr->antimagic_dis += 2;
- }
-
- if (f4 & (TR4_ANTIMAGIC_10))
- {
- s32b tmp;
-
- tmp = 1 + get_skill_scale(SKILL_ANTIMAGIC, 9) - antimagic_mod;
- if (tmp > 0) p_ptr->antimagic += tmp;
-
- p_ptr->antimagic_dis += 1;
- }
-
if (f4 & (TR4_AUTO_ID))
{
p_ptr->auto_id = TRUE;
@@ -2788,6 +2714,33 @@ void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pva
}
}
+
+
+/**
+ * Are barehand fighter's hands empty?
+ */
+static bool_ monk_empty_hands(void)
+{
+ int i;
+ object_type *o_ptr;
+
+ if (p_ptr->melee_style != SKILL_HAND) return FALSE;
+
+ i = 0;
+ while (p_ptr->body_parts[i] == INVEN_WIELD)
+ {
+ o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
+
+ if (o_ptr->k_idx) return FALSE;
+
+ i++;
+ }
+
+ return TRUE;
+}
+
+
+
/*
* Calculate the players current "state", taking into account
* not only race/class intrinsics, but also objects being worn
@@ -2872,9 +2825,6 @@ void calc_bonuses(bool_ silent)
/* Starts with single throwing damage */
p_ptr->throw_mult = 1;
- /* Reset the "xtra" tval */
- p_ptr->tval_xtra = 0;
-
/* Reset the "ammo" tval */
p_ptr->tval_ammo = 0;
@@ -3070,22 +3020,18 @@ void calc_bonuses(bool_ silent)
apply_flags(rmp_ptr->oflags1[i], rmp_ptr->oflags2[i], rmp_ptr->oflags3[i], rmp_ptr->oflags4[i], rmp_ptr->oflags5[i], rmp_ptr->oesp[i], rmp_ptr->opval[i], 0, 0, 0, 0);
}
- if (PRACE_FLAG(PR1_HURT_LITE))
+ if (race_flags1_p(PR1_HURT_LITE))
p_ptr->sensible_lite = TRUE;
}
/* The extra flags */
apply_flags(p_ptr->xtra_f1, p_ptr->xtra_f2, p_ptr->xtra_f3, p_ptr->xtra_f4, p_ptr->xtra_f5, p_ptr->xtra_esp, 0, 0, 0, 0, 0);
- /* Hack -- apply racial/class stat maxes */
- if (p_ptr->maximize)
+ /* Apply the racial modifiers */
+ for (i = 0; i < 6; i++)
{
- /* Apply the racial modifiers */
- for (i = 0; i < 6; i++)
- {
- /* Modify the stats for "race" */
- p_ptr->stat_add[i] += (rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]);
- }
+ /* Modify the stats for "race" */
+ p_ptr->stat_add[i] += (rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]);
}
@@ -3192,7 +3138,7 @@ void calc_bonuses(bool_ silent)
/* Hack -- aura of fire also provides light */
if (p_ptr->sh_fire) p_ptr->lite = TRUE;
- if (PRACE_FLAG(PR1_AC_LEVEL))
+ if (race_flags1_p(PR1_AC_LEVEL))
{
p_ptr->to_a += 20 + (p_ptr->lev / 5);
p_ptr->dis_to_a += 20 + (p_ptr->lev / 5);
@@ -3217,7 +3163,7 @@ void calc_bonuses(bool_ silent)
p_ptr->stat_top[i] = top;
/* Redisplay the stats later */
- p_ptr->redraw |= (PR_STATS);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -3233,7 +3179,7 @@ void calc_bonuses(bool_ silent)
p_ptr->stat_use[i] = use;
/* Redisplay the stats later */
- p_ptr->redraw |= (PR_STATS);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -3279,7 +3225,7 @@ void calc_bonuses(bool_ silent)
}
/* Provide the damage we get from sacrifice */
- GOD(GOD_MELKOR)
+ if (p_ptr->pgod == GOD_MELKOR)
{
int x = wisdom_scale(4);
if (x < 1) x = 1;
@@ -3425,27 +3371,12 @@ void calc_bonuses(bool_ silent)
p_ptr->dis_to_h += 15;
}
- /* Temporary "Meditation" */
- if (p_ptr->meditation)
- {
- p_ptr->to_d -= 25;
- p_ptr->dis_to_d -= 25;
- p_ptr->to_h -= 25;
- p_ptr->dis_to_h -= 25;
- }
-
/* Temporary "Reflection" */
if (p_ptr->tim_reflect)
{
p_ptr->reflect = TRUE;
}
- /* Temporary "Time Resistance" */
- if (p_ptr->tim_res_time)
- {
- p_ptr->resist_continuum = TRUE;
- }
-
/* Temporary "Levitation" and "Flying" */
if (p_ptr->tim_ffall)
{
@@ -3456,12 +3387,6 @@ void calc_bonuses(bool_ silent)
p_ptr->fly = TRUE;
}
- /* Temporary "Fire Aura" */
- if (p_ptr->tim_fire_aura)
- {
- p_ptr->sh_fire = TRUE;
- }
-
/* Oppose Light & Dark */
if (p_ptr->oppose_ld)
{
@@ -3489,13 +3414,6 @@ void calc_bonuses(bool_ silent)
p_ptr->resist_nexus = TRUE;
}
- /* Mental barrier */
- if (p_ptr->tim_mental_barrier)
- {
- p_ptr->sustain_int = TRUE;
- p_ptr->sustain_wis = TRUE;
- }
-
/* Temporary "fast" */
if (p_ptr->fast)
{
@@ -3584,12 +3502,8 @@ void calc_bonuses(bool_ silent)
/* Searching slows the player down */
if (p_ptr->searching) p_ptr->pspeed -= 10;
- /* In order to get a "nice" mana path druids need to ahve a 0 speed */
- if ((p_ptr->druid_extra2 == CLASS_MANA_PATH) && (p_ptr->pspeed > 110))
- p_ptr->pspeed = 110;
-
/* Display the speed (if needed) */
- if (p_ptr->pspeed != old_speed) p_ptr->redraw |= (PR_SPEED);
+ if (p_ptr->pspeed != old_speed) p_ptr->redraw |= (PR_FRAME);
/* Actual Modifier Bonuses (Un-inflate stat bonuses) */
@@ -3608,7 +3522,7 @@ void calc_bonuses(bool_ silent)
if ((p_ptr->dis_ac != old_dis_ac) || (p_ptr->dis_to_a != old_dis_to_a))
{
/* Redraw */
- p_ptr->redraw |= (PR_ARMOR);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -3692,13 +3606,13 @@ void calc_bonuses(bool_ silent)
if (p_ptr->num_fire < 1) p_ptr->num_fire = 1;
}
- if (PRACE_FLAG(PR1_XTRA_MIGHT_BOW) && p_ptr->tval_ammo == TV_ARROW)
+ if (race_flags1_p(PR1_XTRA_MIGHT_BOW) && p_ptr->tval_ammo == TV_ARROW)
p_ptr->xtra_might += 1;
- if (PRACE_FLAG(PR1_XTRA_MIGHT_SLING) && p_ptr->tval_ammo == TV_SHOT)
+ if (race_flags1_p(PR1_XTRA_MIGHT_SLING) && p_ptr->tval_ammo == TV_SHOT)
p_ptr->xtra_might += 1;
- if (PRACE_FLAG(PR1_XTRA_MIGHT_XBOW) && p_ptr->tval_ammo == TV_BOLT)
+ if (race_flags1_p(PR1_XTRA_MIGHT_XBOW) && p_ptr->tval_ammo == TV_BOLT)
p_ptr->xtra_might += 1;
/* Examine the "current tool" */
@@ -4221,7 +4135,6 @@ void update_stuff(void)
if (p_ptr->update & (PU_SPELLS))
{
p_ptr->update &= ~(PU_SPELLS);
- calc_spells();
}
if (p_ptr->update & (PU_POWERS))
@@ -4272,7 +4185,7 @@ void update_stuff(void)
if (p_ptr->update & (PU_MON_LITE))
{
p_ptr->update &= ~(PU_MON_LITE);
- if (monster_lite) update_mon_lite();
+ update_mon_lite();
}
}
@@ -4294,10 +4207,6 @@ void redraw_stuff(void)
if (character_icky) return;
- /* Should we tell lua to redisplay too ? */
- process_hooks(HOOK_REDRAW, "()");
-
-
/* Hack -- clear the screen */
if (p_ptr->redraw & (PR_WIPE))
{
@@ -4314,182 +4223,10 @@ void redraw_stuff(void)
}
- if (p_ptr->redraw & (PR_BASIC))
- {
- p_ptr->redraw &= ~(PR_BASIC);
- p_ptr->redraw &= ~(PR_MISC | PR_TITLE | PR_STATS);
- p_ptr->redraw &= ~(PR_LEV | PR_EXP | PR_GOLD);
- p_ptr->redraw &= ~(PR_ARMOR | PR_HP | PR_MANA | PR_PIETY | PR_MH);
- p_ptr->redraw &= ~(PR_DEPTH | PR_HEALTH);
- prt_frame_basic();
- }
-
- if (p_ptr->redraw & (PR_MISC))
- {
- p_ptr->redraw &= ~(PR_MISC);
- prt_field(rp_ptr->title + rp_name, ROW_RACE, COL_RACE);
- prt_field(spp_ptr->title + c_name, ROW_CLASS, COL_CLASS);
- }
-
- if (p_ptr->redraw & (PR_TITLE))
- {
- p_ptr->redraw &= ~(PR_TITLE);
- prt_title();
- }
-
- if (p_ptr->redraw & (PR_LEV))
+ if (p_ptr->redraw & (PR_FRAME))
{
- p_ptr->redraw &= ~(PR_LEV);
- prt_level();
- }
-
- if (p_ptr->redraw & (PR_EXP))
- {
- p_ptr->redraw &= ~(PR_EXP);
- prt_exp();
- }
-
- if (p_ptr->redraw & (PR_STATS))
- {
- p_ptr->redraw &= ~(PR_STATS);
- prt_stat(A_STR);
- prt_stat(A_INT);
- prt_stat(A_WIS);
- prt_stat(A_DEX);
- prt_stat(A_CON);
- prt_stat(A_CHR);
- }
-
- if (p_ptr->redraw & (PR_ARMOR))
- {
- p_ptr->redraw &= ~(PR_ARMOR);
- prt_ac();
- }
-
- if (p_ptr->redraw & (PR_HP))
- {
- p_ptr->redraw &= ~(PR_HP);
- prt_hp();
- }
-
- if (p_ptr->redraw & (PR_MANA))
- {
- p_ptr->redraw &= ~(PR_MANA);
- prt_sp();
- }
-
- if (p_ptr->redraw & (PR_PIETY))
- {
- p_ptr->redraw &= ~(PR_PIETY);
- prt_piety();
- }
-
- if (p_ptr->redraw & (PR_MH))
- {
- p_ptr->redraw &= ~(PR_MH);
- prt_mh();
- }
-
- if (p_ptr->redraw & (PR_GOLD))
- {
- p_ptr->redraw &= ~(PR_GOLD);
- prt_gold();
- }
-
- if (p_ptr->redraw & (PR_DEPTH))
- {
- p_ptr->redraw &= ~(PR_DEPTH);
- prt_depth();
- }
-
- if (p_ptr->redraw & (PR_HEALTH))
- {
- p_ptr->redraw &= ~(PR_HEALTH);
- health_redraw();
- }
-
-
- if (p_ptr->redraw & (PR_EXTRA))
- {
- p_ptr->redraw &= ~(PR_EXTRA);
- p_ptr->redraw &= ~(PR_CUT | PR_STUN);
- p_ptr->redraw &= ~(PR_HUNGER);
- p_ptr->redraw &= ~(PR_BLIND | PR_CONFUSED);
- p_ptr->redraw &= ~(PR_AFRAID | PR_POISONED);
- p_ptr->redraw &= ~(PR_STATE | PR_SPEED | PR_STUDY | PR_SANITY);
- prt_frame_extra();
- }
-
- if (p_ptr->redraw & (PR_CUT))
- {
- p_ptr->redraw &= ~(PR_CUT);
- prt_cut();
- }
-
- if (p_ptr->redraw & (PR_STUN))
- {
- p_ptr->redraw &= ~(PR_STUN);
- prt_stun();
- }
-
- if (p_ptr->redraw & (PR_HUNGER))
- {
- p_ptr->redraw &= ~(PR_HUNGER);
- prt_hunger();
- }
-
- if (p_ptr->redraw & (PR_BLIND))
- {
- p_ptr->redraw &= ~(PR_BLIND);
- prt_blind();
- }
-
- if (p_ptr->redraw & (PR_CONFUSED))
- {
- p_ptr->redraw &= ~(PR_CONFUSED);
- prt_confused();
- }
-
- if (p_ptr->redraw & (PR_AFRAID))
- {
- p_ptr->redraw &= ~(PR_AFRAID);
- prt_afraid();
- }
-
- if (p_ptr->redraw & (PR_POISONED))
- {
- p_ptr->redraw &= ~(PR_POISONED);
- prt_poisoned();
- }
-
- if (p_ptr->redraw & (PR_DTRAP))
- {
- p_ptr->redraw &= ~(PR_DTRAP);
- prt_dtrap();
- }
-
- if (p_ptr->redraw & (PR_STATE))
- {
- p_ptr->redraw &= ~(PR_STATE);
- prt_state();
- }
-
- if (p_ptr->redraw & (PR_SPEED))
- {
- p_ptr->redraw &= ~(PR_SPEED);
- prt_speed();
- }
-
- if (p_ptr->redraw & (PR_STUDY))
- {
- p_ptr->redraw &= ~(PR_STUDY);
- prt_study();
- }
-
- if (p_ptr->redraw & (PR_SANITY))
- {
- p_ptr->redraw &= ~(PR_SANITY);
- prt_sane();
+ p_ptr->redraw &= ~(PR_FRAME);
+ prt_frame();
}
}
@@ -4595,26 +4332,6 @@ void handle_stuff(void)
}
-bool_ monk_empty_hands(void)
-{
- int i;
- object_type *o_ptr;
-
- if (p_ptr->melee_style != SKILL_HAND) return FALSE;
-
- i = 0;
- while (p_ptr->body_parts[i] == INVEN_WIELD)
- {
- o_ptr = &p_ptr->inventory[INVEN_WIELD + i];
-
- if (o_ptr->k_idx) return FALSE;
-
- i++;
- }
-
- return TRUE;
-}
-
bool_ monk_heavy_armor(void)
{
u16b monk_arm_wgt = 0;
@@ -4951,3 +4668,13 @@ int luck(int min, int max)
return (luck + min);
}
+
+bool race_flags1_p(u32b flags1_mask)
+{
+ return (rp_ptr->flags1 | rmp_ptr->flags1 | cp_ptr->flags1 | spp_ptr->flags1) & flags1_mask;
+}
+
+bool race_flags2_p(u32b flags2_mask)
+{
+ return (rp_ptr->flags2 | rmp_ptr->flags2 | cp_ptr->flags2 | spp_ptr->flags2) & flags2_mask;
+}
diff --git a/src/xtra1.hpp b/src/xtra1.hpp
new file mode 100644
index 00000000..df2592ac
--- /dev/null
+++ b/src/xtra1.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "h-basic.h"
+
+extern void fix_message(void);
+extern void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a);
+extern int luck(int min, int max);
+extern int weight_limit(void);
+extern bool_ calc_powers_silent;
+extern void cnv_stat(int i, char *out_val);
+extern s16b modify_stat_value(int value, int amount);
+extern void calc_hitpoints(void);
+extern void notice_stuff(void);
+extern void update_stuff(void);
+extern void redraw_stuff(void);
+extern void window_stuff(void);
+extern void handle_stuff(void);
+extern bool_ monk_heavy_armor(void);
+extern void calc_bonuses(bool_ silent);
+extern void gain_fate(byte fate);
+extern void fate_desc(char *desc, int fate);
+extern void dump_fates(FILE *OutFile);
+extern bool race_flags1_p(u32b flags1_mask);
+extern bool race_flags2_p(u32b flags2_mask);
diff --git a/src/xtra2.c b/src/xtra2.cc
index f437c6d1..6ddf4ac9 100644
--- a/src/xtra2.c
+++ b/src/xtra2.cc
@@ -1,8 +1,3 @@
-/* File: xtra2.c */
-/* File: xtra2.c */
-
-/* Purpose: effects of various "objects", targetting and panel handling */
-
/*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
@@ -11,49 +6,64 @@
* included in all such copies.
*/
-#include "angband.h"
-
-#include <assert.h>
-
-#include "quark.h"
-
-/*
- * Invoke The Rush
- */
-bool_ set_rush(int v)
-{
- int j;
-
- /* Invoke The Bust */
- if (!v)
- {
- p_ptr->rush = 0;
-
- j = 50 - randint(p_ptr->lev);
- set_paralyzed(j);
- set_slow(j + 50 - randint(p_ptr->lev));
- return TRUE;
- }
-
- /* When is The Bust going to happen? */
- p_ptr->rush = v;
-
- /* The bonuses of The Rush */
- set_hero(p_ptr->hero + v);
- set_tim_deadly(p_ptr->tim_deadly + v);
- set_strike(p_ptr->strike + v);
- if (magik(p_ptr->lev / 2))
- {
- set_light_speed(p_ptr->lightspeed + v);
- }
- else
- {
- set_fast(p_ptr->fast + v, 10);
- }
- if (magik(p_ptr->lev / 2)) set_tim_esp(p_ptr->tim_esp + v);
- return TRUE;
-}
-
+#include "xtra2.hpp"
+
+#include "artifact_type.hpp"
+#include "cave.hpp"
+#include "cave_type.hpp"
+#include "corrupt.hpp"
+#include "dungeon_info_type.hpp"
+#include "ego_item_type.hpp"
+#include "feature_type.hpp"
+#include "files.hpp"
+#include "gods.hpp"
+#include "hook_player_level_in.hpp"
+#include "hook_monster_death_in.hpp"
+#include "hooks.hpp"
+#include "melee2.hpp"
+#include "mimic.hpp"
+#include "monster1.hpp"
+#include "monster2.hpp"
+#include "monster3.hpp"
+#include "monster_ego.hpp"
+#include "monster_race.hpp"
+#include "monster_type.hpp"
+#include "notes.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+#include "object_kind.hpp"
+#include "options.hpp"
+#include "player_class.hpp"
+#include "player_race.hpp"
+#include "player_race_mod.hpp"
+#include "player_type.hpp"
+#include "quark.hpp"
+#include "randart.hpp"
+#include "skill_type.hpp"
+#include "skills.hpp"
+#include "spells1.hpp"
+#include "spells2.hpp"
+#include "stats.hpp"
+#include "store_info_type.hpp"
+#include "tables.hpp"
+#include "trap_type.hpp"
+#include "util.hpp"
+#include "util.h"
+#include "variable.h"
+#include "variable.hpp"
+#include "wilderness_map.hpp"
+#include "wilderness_type_info.hpp"
+#include "wizard2.hpp"
+#include "xtra1.hpp"
+
+#include <type_traits>
+#include <cassert>
+
+#include <boost/algorithm/string/predicate.hpp>
+
+using boost::algorithm::iequals;
+
+static void corrupt_corrupted(void);
/*
* Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
@@ -118,7 +128,7 @@ bool_ set_parasite(int v, int r)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -172,7 +182,7 @@ static bool_ set_simple_field(
/* Disturb */
if (disturb_state)
- disturb(0, 0);
+ disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -365,26 +375,6 @@ bool_ set_tim_fly(int v)
}
/*
- * Set "p_ptr->meditation"
- */
-bool_ set_meditation(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->meditation, v,
- TERM_WHITE, "You start meditating on yourself...",
- TERM_WHITE, "You stop your self meditation.");
-
- /* Recalculate bonuses */
- if (notice)
- {
- p_ptr->update |= (PU_MANA);
- }
-
- /* Result */
- return notice;
-}
-
-/*
* Set "p_ptr->tim_reflect"
*/
bool_ set_tim_reflect(int v)
@@ -396,28 +386,6 @@ bool_ set_tim_reflect(int v)
}
/*
- * Set "p_ptr->tim_res_time"
- */
-bool_ set_tim_res_time(int v)
-{
- return set_simple_field(
- &p_ptr->tim_res_time, v,
- TERM_WHITE, "You are now protected against space-time distortions.",
- TERM_WHITE, "You are no longer protected against space-time distortions.");
-}
-
-/*
- * Set "p_ptr->tim_fire_aura"
- */
-bool_ set_tim_fire_aura(int v)
-{
- return set_simple_field(
- &p_ptr->tim_fire_aura, v,
- TERM_WHITE, "You are enveloped in flames.",
- TERM_WHITE, "You are no longer enveloped in flames.");
-}
-
-/*
* Set "p_ptr->strike"
*/
bool_ set_strike(int v)
@@ -519,10 +487,10 @@ bool_ set_mimic(int v, int p, int level)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Redraw title */
- p_ptr->redraw |= (PR_TITLE);
+ p_ptr->redraw |= (PR_FRAME);
/* Recalculate bonuses */
p_ptr->update |= (PU_BODY | PU_BONUS | PU_SANITY);
@@ -555,7 +523,7 @@ bool_ set_blind(int v)
p_ptr->redraw |= (PR_MAP);
/* Redraw the "blind" */
- p_ptr->redraw |= (PR_BLIND);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_OVERHEAD);
@@ -616,7 +584,7 @@ bool_ set_confused(int v)
if (notice)
{
/* Redraw the "confused" */
- p_ptr->redraw |= (PR_CONFUSED);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -640,7 +608,7 @@ bool_ set_poisoned(int v)
if (notice)
{
/* Redraw the "poisoned" */
- p_ptr->redraw |= (PR_POISONED);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -664,7 +632,7 @@ bool_ set_afraid(int v)
if (notice)
{
/* Redraw the "afraid" */
- p_ptr->redraw |= (PR_AFRAID);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -691,7 +659,7 @@ static bool_ set_paralyzed_aux(int v)
if (notice)
{
/* Redraw the state */
- p_ptr->redraw |= (PR_STATE);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -816,7 +784,7 @@ bool_ set_fast(int v, int p)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -944,26 +912,6 @@ bool_ set_holy(int v)
}
/*
- * Set "p_ptr->walk_water", notice observable changes
- */
-bool_ set_walk_water(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->walk_water, v,
- TERM_WHITE, "You feel strangely buoyant!",
- TERM_WHITE, "You feel much less buoyant.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
* Set "p_ptr->shero", notice observable changes
*/
bool_ set_shero(int v)
@@ -1178,7 +1126,7 @@ bool_ set_tim_thunder(int v, int p1, int p2)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
@@ -1242,26 +1190,6 @@ bool_ set_tim_infra(int v)
/*
- * Set "p_ptr->tim_mental_barrier", notice observable changes
- */
-bool_ set_mental_barrier(int v)
-{
- bool_ notice = set_simple_field(
- &p_ptr->tim_mental_barrier, v,
- TERM_WHITE, "Your mind grows stronger!",
- TERM_WHITE, "Your mind is no longer especially strong.");
-
- if (notice)
- {
- /* Handle stuff */
- handle_stuff();
- }
-
- /* Result */
- return notice;
-}
-
-/*
* Set "p_ptr->oppose_acid", notice observable changes
*/
bool_ set_oppose_acid(int v)
@@ -1405,7 +1333,7 @@ bool_ set_tim_regen(int v, int p)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Handle stuff */
handle_stuff();
@@ -1429,7 +1357,7 @@ bool_ set_stun(int v)
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
- if (PRACE_FLAG(PR1_NO_STUN)) v = 0;
+ if (race_flags1_p(PR1_NO_STUN)) v = 0;
/* Knocked out */
if (p_ptr->stun > 100)
@@ -1545,7 +1473,7 @@ bool_ set_stun(int v)
/* None */
case 0:
msg_print("You are no longer stunned.");
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
break;
}
@@ -1560,13 +1488,13 @@ bool_ set_stun(int v)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
/* Redraw the "stun" */
- p_ptr->redraw |= (PR_STUN);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -1590,7 +1518,7 @@ bool_ set_cut(int v)
/* Hack -- Force good values */
v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
- if (PRACE_FLAG(PR1_NO_CUT)) v = 0;
+ if (race_flags1_p(PR1_NO_CUT)) v = 0;
/* Mortal wound */
if (p_ptr->cut > 1000)
@@ -1753,7 +1681,7 @@ bool_ set_cut(int v)
/* None */
case 0:
msg_print("You are no longer bleeding.");
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
break;
}
@@ -1768,13 +1696,13 @@ bool_ set_cut(int v)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
/* Redraw the "cut" */
- p_ptr->redraw |= (PR_CUT);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -1982,13 +1910,13 @@ bool_ set_food(int v)
if (!notice) return (FALSE);
/* Disturb */
- if (disturb_state) disturb(0, 0);
+ if (disturb_state) disturb(0);
/* Recalculate bonuses */
p_ptr->update |= (PU_BONUS);
/* Redraw hunger */
- p_ptr->redraw |= (PR_HUNGER);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -2023,7 +1951,7 @@ void check_experience(void)
if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
/* Redraw experience */
- p_ptr->redraw |= (PR_EXP);
+ p_ptr->redraw |= (PR_FRAME);
/* Handle stuff */
handle_stuff();
@@ -2042,7 +1970,7 @@ void check_experience(void)
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);
/* Redraw some stuff */
- p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2065,7 +1993,7 @@ void check_experience(void)
if (p_ptr->lev > p_ptr->max_plv)
{
p_ptr->max_plv = p_ptr->lev;
- if ((PRACE_FLAG(PR1_CORRUPT)) &&
+ if ((race_flags1_p(PR1_CORRUPT)) &&
(randint(3) == 1))
{
level_corruption = TRUE;
@@ -2083,7 +2011,7 @@ void check_experience(void)
p_ptr->skill_last_level = p_ptr->lev;
p_ptr->skill_points += modules[game_module_idx].skills.skill_per_level;
cmsg_format(TERM_L_GREEN, "You can increase %d more skills.", p_ptr->skill_points);
- p_ptr->redraw |= PR_STUDY;
+ p_ptr->redraw |= PR_FRAME;
}
/* Gain this level's abilities */
@@ -2102,7 +2030,7 @@ void check_experience(void)
p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);
/* Redraw some stuff */
- p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2119,8 +2047,6 @@ void check_experience(void)
}
/* Hook it! */
- process_hooks(HOOK_PLAYER_LEVEL, "(d)", gained);
-
{
hook_player_level_in in = { gained };
process_hooks_new(HOOK_PLAYER_LEVEL, &in, NULL);
@@ -2196,7 +2122,7 @@ void gain_exp(s32b amount)
}
}
- if ((p_ptr->max_exp > 0) && (PRACE_FLAG(PR1_CORRUPT)))
+ if ((p_ptr->max_exp > 0) && (race_flags1_p(PR1_CORRUPT)))
{
if ((randint(p_ptr->max_exp) < amount) || (randint(12000000) < amount))
{
@@ -2209,9 +2135,6 @@ void gain_exp(s32b amount)
/* Gain some experience */
p_ptr->exp += amount / num;
- /* Hook it! */
- process_hooks(HOOK_PLAYER_EXP, "(d)", amount / num);
-
/* Slowly recover from experience drainage */
if (p_ptr->exp < p_ptr->max_exp)
{
@@ -2235,9 +2158,6 @@ void lose_exp(s32b amount)
/* Lose some experience */
p_ptr->exp -= amount;
- /* Hook it! */
- process_hooks(HOOK_PLAYER_EXP, "(d)", amount);
-
/* Check Experience */
check_experience();
}
@@ -2253,7 +2173,7 @@ void lose_exp(s32b amount)
*/
int get_coin_type(monster_race *r_ptr)
{
- cptr name = (r_name + r_ptr->name);
+ cptr name = r_ptr->name;
/* Analyze "coin" monsters */
if (r_ptr->d_char == '$')
@@ -2588,8 +2508,6 @@ void monster_death(int m_idx)
int dump_item = 0;
int dump_gold = 0;
- s16b this_o_idx, next_o_idx = 0;
-
monster_type *m_ptr = &m_list[m_idx];
monster_race *r_ptr = race_inf(m_ptr);
@@ -2608,7 +2526,10 @@ void monster_death(int m_idx)
x = m_ptr->fx;
/* Process the appropriate hooks */
- process_hooks(HOOK_MONSTER_DEATH, "(d)", m_idx);
+ {
+ struct hook_monster_death_in in = { m_idx };
+ process_hooks_new(HOOK_MONSTER_DEATH, &in, NULL);
+ }
/* Per-god processing */
monster_death_gods(m_idx, m_ptr);
@@ -2628,7 +2549,7 @@ void monster_death(int m_idx)
/* Display the hitpoints */
p_ptr->update |= (PU_HP);
- p_ptr->redraw |= (PR_HP);
+ p_ptr->redraw |= (PR_FRAME);
/* Window stuff */
p_ptr->window |= (PW_PLAYER);
@@ -2639,27 +2560,17 @@ void monster_death(int m_idx)
}
}
- /* Handle the possibility of player vanquishing arena combatant -KMW- */
- if (p_ptr->inside_arena)
- {
- p_ptr->exit_bldg = TRUE;
- msg_print("Victorious! You're on your way to becoming Champion.");
- p_ptr->arena_number++;
- }
-
/* If the doppleganger die, the variable must be set accordingly */
if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = 0;
+ /* Need copy of object list since we're going to mutate it */
+ auto const object_idxs(m_ptr->hold_o_idxs);
+
/* Drop objects being carried */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: object_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type * o_ptr = &o_list[this_o_idx];
/* Paranoia */
o_ptr->held_m_idx = 0;
@@ -2681,13 +2592,13 @@ void monster_death(int m_idx)
}
/* Forget objects */
- m_ptr->hold_o_idx = 0;
+ m_ptr->hold_o_idxs.clear();
/* Average dungeon and monster levels */
object_level = (dun_level + m_ptr->level) / 2;
/* Mega^2-hack -- destroying the Stormbringer gives it us! */
- if (strstr((r_name + r_ptr->name), "Stormbringer"))
+ if (strstr(r_ptr->name, "Stormbringer"))
{
/* Get local object */
q_ptr = &forge;
@@ -2737,7 +2648,7 @@ void monster_death(int m_idx)
* Mega^3-hack: killing a 'Warrior of the Dawn' is likely to
* spawn another in the fallen one's place!
*/
- else if (strstr((r_name + r_ptr->name), "the Dawn"))
+ else if (strstr(r_ptr->name, "the Dawn"))
{
if (!(randint(20) == 13))
{
@@ -2773,13 +2684,13 @@ void monster_death(int m_idx)
}
/* One more ultra-hack: An Unmaker goes out with a big bang! */
- else if (strstr((r_name + r_ptr->name), "Unmaker"))
+ else if (strstr(r_ptr->name, "Unmaker"))
{
int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
(void)project(m_idx, 6, y, x, 100, GF_CHAOS, flg);
}
/* Pink horrors are replaced with 2 Blue horrors */
- else if (strstr((r_name + r_ptr->name), "ink horror"))
+ else if (strstr(r_ptr->name, "ink horror"))
{
for (i = 0; i < 2; i++)
{
@@ -2806,7 +2717,7 @@ void monster_death(int m_idx)
/* Mega-Hack -- drop "winner" treasures */
else if (r_ptr->flags1 & (RF1_DROP_CHOSEN))
{
- if (strstr((r_name + r_ptr->name), "Morgoth, Lord of Darkness"))
+ if (strstr(r_ptr->name, "Morgoth, Lord of Darkness"))
{
/* Get local object */
q_ptr = &forge;
@@ -2844,7 +2755,7 @@ void monster_death(int m_idx)
/* Drop it in the dungeon */
drop_near(q_ptr, -1, y, x);
}
- else if (strstr((r_name + r_ptr->name), "Smeagol"))
+ else if (strstr(r_ptr->name, "Smeagol"))
{
/* Get local object */
q_ptr = &forge;
@@ -2883,7 +2794,7 @@ void monster_death(int m_idx)
create_artifact(q_ptr, TRUE, FALSE);
/* Save the inscription */
- q_ptr->art_name = quark_add(format("of %s", r_name + r_ptr->name));
+ q_ptr->art_name = quark_add(format("of %s", r_ptr->name));
q_ptr->found = OBJ_FOUND_MONSTER;
q_ptr->found_aux1 = m_ptr->r_idx;
@@ -2900,32 +2811,32 @@ void monster_death(int m_idx)
int chance = 0;
int I_kind = 0;
- if (strstr((r_name + r_ptr->name), "Marda, rider of the Gold Laronth"))
+ if (strstr(r_ptr->name, "Marda, rider of the Gold Laronth"))
{
a_idx = ART_MARDA;
chance = 50;
}
- else if (strstr((r_name + r_ptr->name), "Saruman of Many Colours"))
+ else if (strstr(r_ptr->name, "Saruman of Many Colours"))
{
a_idx = ART_PALANTIR;
chance = 30;
}
- else if (strstr((r_name + r_ptr->name), "Hagen, son of Alberich"))
+ else if (strstr(r_ptr->name, "Hagen, son of Alberich"))
{
a_idx = ART_NIMLOTH;
chance = 66;
}
- else if (strstr((r_name + r_ptr->name), "Durin's Bane"))
+ else if (strstr(r_ptr->name, "Durin's Bane"))
{
a_idx = ART_CALRIS;
chance = 60;
}
- else if (strstr((r_name + r_ptr->name), "Gothmog, the High Captain of Balrogs"))
+ else if (strstr(r_ptr->name, "Gothmog, the High Captain of Balrogs"))
{
a_idx = ART_GOTHMOG;
chance = 50;
}
- else if (strstr((r_name + r_ptr->name), "Eol, the Dark Elf"))
+ else if (strstr(r_ptr->name, "Eol, the Dark Elf"))
{
a_idx = ART_ANGUIREL;
chance = 50;
@@ -3205,7 +3116,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
/* Redraw (later) if needed */
- if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
+ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME);
/* Some mosnters are immune to death */
if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE;
@@ -3246,7 +3157,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
while (--curses);
}
- if (speak_unique && (r_ptr->flags2 & (RF2_CAN_SPEAK)))
+ if (r_ptr->flags2 & (RF2_CAN_SPEAK))
{
char line_got[80];
/* Dump a message */
@@ -3359,35 +3270,38 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
/* Manwe appreciate evil monster death */
if (r_ptr->flags3 & RF3_EVIL)
{
- int inc = m_ptr->level / 2;
+ int inc = std::max(1, m_ptr->level / 2);
- if (!inc) inc = 1;
- PRAY_GOD(GOD_MANWE) inc_piety(GOD_MANWE, inc);
+ if (praying_to(GOD_MANWE))
+ {
+ inc_piety(GOD_MANWE, inc);
+ }
+
+ inc = std::max(2, inc);
- if (inc < 2) inc = 2;
inc_piety(GOD_TULKAS, inc / 2);
- PRAY_GOD(GOD_TULKAS)
+
+ if (praying_to(GOD_TULKAS))
{
inc_piety(GOD_TULKAS, inc / 2);
- if (r_ptr->flags3 & RF3_DEMON) inc_piety(GOD_TULKAS, inc);
+ if (r_ptr->flags3 & RF3_DEMON)
+ {
+ inc_piety(GOD_TULKAS, inc);
+ }
}
}
/* Yavanna likes when corruption is destroyed */
if ((r_ptr->flags3 & RF3_NONLIVING) || (r_ptr->flags3 & RF3_DEMON) || (r_ptr->flags3 & RF3_UNDEAD))
{
- int inc = m_ptr->level / 2;
-
- if (!inc) inc = 1;
+ int inc = std::max(1, m_ptr->level / 2);
inc_piety(GOD_YAVANNA, inc);
}
/* Yavanna doesnt like any killing in her name */
- PRAY_GOD(GOD_YAVANNA)
+ if (praying_to(GOD_YAVANNA))
{
- int inc = m_ptr->level / 2;
-
- if (!inc) inc = 1;
+ int inc = std::max(1, m_ptr->level / 2);
inc_piety(GOD_YAVANNA, -inc);
/* Killing animals in her name is a VERY bad idea */
@@ -3438,11 +3352,8 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note)
{
char note[80];
- /* Get true name even if blinded/hallucinating */
- cptr monst = (r_name + r_ptr->name);
-
/* Write note */
- sprintf(note, "Killed %s", monst);
+ sprintf(note, "Killed %s", r_ptr->name);
add_note(note, 'U');
}
@@ -3486,7 +3397,6 @@ void get_screen_size(int *wid_p, int *hgt_p)
Term_get_size(wid_p, hgt_p);
*hgt_p -= ROW_MAP + 1;
*wid_p -= COL_MAP + 1;
- if (use_bigtile) *wid_p /= 2;
}
/*
@@ -3689,7 +3599,7 @@ void verify_panel(void)
panel_col_min = pcol_min;
/* Hack -- optional disturb on "panel change" */
- if (disturb_panel && !center_player) disturb(0, 0);
+ if (disturb_panel && !center_player) disturb(0);
/* Recalculate the boundaries */
panel_bounds();
@@ -3741,7 +3651,7 @@ void resize_map(void)
p_ptr->update |= (PU_UN_VIEW | PU_VIEW | PU_MONSTERS | PU_MON_LITE);
/* Redraw everything */
- p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);
+ p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP);
/* Hack -- update */
handle_stuff();
@@ -3789,7 +3699,7 @@ void resize_window(void)
/*
* Monster health description
*/
-cptr look_mon_desc(int m_idx)
+static cptr look_mon_desc(int m_idx)
{
monster_type *m_ptr = &m_list[m_idx];
monster_race *r_ptr = race_inf(m_ptr);
@@ -3837,6 +3747,18 @@ cptr look_mon_desc(int m_idx)
/*
+ * Current "comp" function for ang_sort()
+ */
+static bool_ (*ang_sort_comp)(vptr u, vptr v, int a, int b) = nullptr;
+
+/*
+ * Current "swap" function for ang_sort()
+ */
+static void (*ang_sort_swap)(vptr u, vptr v, int a, int b) = nullptr;
+
+
+
+/*
* Angband sorting algorithm -- quick sort in place
*
* Note that the details of the data we are sorting is hidden,
@@ -3844,7 +3766,7 @@ cptr look_mon_desc(int m_idx)
* function hooks to interact with the data, which is given as
* two pointers, and which may have any user-defined form.
*/
-void ang_sort_aux(vptr u, vptr v, int p, int q)
+static void ang_sort_aux(vptr u, vptr v, int p, int q)
{
int z, a, b;
@@ -3893,7 +3815,7 @@ void ang_sort_aux(vptr u, vptr v, int p, int q)
* function hooks to interact with the data, which is given as
* two pointers, and which may have any user-defined form.
*/
-void ang_sort(vptr u, vptr v, int n)
+static void ang_sort(vptr u, vptr v, int n)
{
/* Sort the array */
ang_sort_aux(u, v, 0, n - 1);
@@ -3918,7 +3840,7 @@ void ang_sort(vptr u, vptr v, int n)
* Future versions may restrict the ability to target "trappers"
* and "mimics", but the semantics is a little bit weird.
*/
-bool_ target_able(int m_idx)
+static bool target_able(int m_idx)
{
monster_type *m_ptr = &m_list[m_idx];
@@ -4107,11 +4029,6 @@ static s16b target_pick(int y1, int x1, int dy, int dx)
*/
static bool_ target_set_accept(int y, int x)
{
- cave_type *c_ptr;
-
- s16b this_o_idx, next_o_idx = 0;
-
-
/* Player grid is always interesting */
if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE);
@@ -4121,7 +4038,7 @@ static bool_ target_set_accept(int y, int x)
/* Examine the grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* Visible monsters */
if (c_ptr->m_idx && c_ptr->m_idx < max_r_idx)
@@ -4133,18 +4050,16 @@ static bool_ target_set_accept(int y, int x)
}
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const this_o_idx: c_ptr->o_idxs)
{
- object_type * o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ object_type *o_ptr = &o_list[this_o_idx];
/* Memorized object */
- if (o_ptr->marked) return (TRUE);
+ if (o_ptr->marked)
+ {
+ return (TRUE);
+ }
}
/* Interesting memorized features */
@@ -4187,9 +4102,6 @@ static void target_set_prepare(int mode)
{
cave_type *c_ptr = &cave[y][x];
- /* Require line of sight, unless "look" is "expanded" */
- if (!expand_look && !player_has_los_bold(y, x)) continue;
-
/* Require "interesting" contents */
if (!target_set_accept(y, x)) continue;
@@ -4272,8 +4184,6 @@ static int target_set_aux(int y, int x, int mode, cptr info)
{
cave_type *c_ptr = &cave[y][x];
- s16b this_o_idx, next_o_idx = 0;
-
cptr s1, s2, s3;
bool_ boring;
@@ -4338,14 +4248,15 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Mimics special treatment -- looks like an object */
if ((r_ptr->flags9 & RF9_MIMIC) && (m_ptr->csleep))
{
- object_type *o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[m_ptr->hold_o_idx];
+ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()];
if (o_ptr->marked)
{
- if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
+ if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
+ {
+ break;
+ }
}
}
else
@@ -4424,9 +4335,10 @@ static int target_set_aux(int y, int x, int mode, cptr info)
if (m_ptr->mflag & MFLAG_PARTIAL) mstat = " (partial) ";
/* Describe, and prompt for recall */
- sprintf(out_val, "%s%s%s%s (level %d, %s%s)%s%s[r,%s]",
+ sprintf(out_val, "%s%s%s%s (level %d, %s%s%s)%s%s[r,%s]",
s1, s2, s3, m_name,
m_ptr->level, look_mon_desc(c_ptr->m_idx),
+ (m_ptr->csleep) ? ", asleep" : "",
(m_ptr->mflag & MFLAG_QUEST) ? ", quest" : "",
(m_ptr->smart & SM_CLONED ? " (clone)" : ""),
(mstat), info);
@@ -4464,19 +4376,15 @@ static int target_set_aux(int y, int x, int mode, cptr info)
s2 = "carrying ";
/* Scan all objects being carried */
- for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
+ std::size_t i = 0;
+ for (; i < m_ptr->hold_o_idxs.size(); i++)
{
- char o_name[80];
-
- object_type *o_ptr;
-
/* Acquire object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ auto this_o_idx = m_ptr->hold_o_idxs.at(i);
+ object_type *o_ptr = &o_list[this_o_idx];
/* Obtain an object description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe the object */
@@ -4486,17 +4394,26 @@ static int target_set_aux(int y, int x, int mode, cptr info)
query = inkey();
/* Always stop at "normal" keys */
- if ((query != '\r') && (query != '\n') && (query != ' ')) break;
+ if ((query != '\r') && (query != '\n') && (query != ' '))
+ {
+ break;
+ }
/* Sometimes stop at "space" key */
- if ((query == ' ') && !(mode & (TARGET_LOOK))) break;
+ if ((query == ' ') && !(mode & (TARGET_LOOK)))
+ {
+ break;
+ }
/* Change the intro */
s2 = "also carrying ";
}
- /* Double break */
- if (this_o_idx) break;
+ /* Double break? */
+ if (i != m_ptr->hold_o_idxs.size())
+ {
+ break;
+ }
/* Use a preposition */
s2 = "on ";
@@ -4504,29 +4421,29 @@ static int target_set_aux(int y, int x, int mode, cptr info)
}
}
-
-
/* Scan all objects in the grid */
- for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
{
- object_type * o_ptr;
-
- /* Acquire object */
- o_ptr = &o_list[this_o_idx];
+ std::size_t i = 0;
+ for (; i < c_ptr->o_idxs.size(); i++)
+ {
+ /* Acquire object */
+ auto this_o_idx = c_ptr->o_idxs.at(i);
+ object_type *o_ptr = &o_list[this_o_idx];
- /* Acquire next object */
- next_o_idx = o_ptr->next_o_idx;
+ /* Describe it */
+ if (o_ptr->marked && target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query))
+ {
+ break;
+ }
+ }
- /* Describe it */
- if (o_ptr->marked)
+ /* Double break? */
+ if (i != c_ptr->o_idxs.size())
{
- if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
+ break;
}
}
- /* Double break */
- if (this_o_idx) break;
-
/* Actual traps */
if ((c_ptr->info & (CAVE_TRDT)) && c_ptr->t_idx)
{
@@ -4535,7 +4452,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Name trap */
if (t_info[c_ptr->t_idx].ident)
{
- s4 = format("(%s)", t_name + t_info[c_ptr->t_idx].name);
+ s4 = format("(%s)", t_info[c_ptr->t_idx].name);
}
else
{
@@ -4580,11 +4497,11 @@ static int target_set_aux(int y, int x, int mode, cptr info)
/* Hack -- special handling for building doors */
if (feat == FEAT_SHOP)
{
- name = st_name + st_info[c_ptr->special].name;
+ name = st_info[c_ptr->special].name;
}
else
{
- name = f_name + f_info[feat].name;
+ name = f_info[feat].name;
}
/* Hack -- handle unknown grids */
@@ -4612,20 +4529,19 @@ static int target_set_aux(int y, int x, int mode, cptr info)
if ((feat == FEAT_MORE) && c_ptr->special)
{
s3 = "";
- name = d_text + d_info[c_ptr->special].text;
+ name = d_info[c_ptr->special].text;
}
if (p_ptr->wild_mode && (feat == FEAT_TOWN))
{
s3 = "";
name = format("%s(%s)",
- wf_name + wf_info[wild_map[y][x].feat].name,
- wf_text + wf_info[wild_map[y][x].feat].text);
+ wf_info[wild_map[y][x].feat].name,
+ wf_info[wild_map[y][x].feat].text);
}
if ((feat == FEAT_FOUNTAIN) && (c_ptr->info & CAVE_IDNT))
{
- object_kind *k_ptr;
int tv, sv;
if (c_ptr->special <= SV_POTION_LAST)
@@ -4639,8 +4555,7 @@ static int target_set_aux(int y, int x, int mode, cptr info)
sv = c_ptr->special - SV_POTION_LAST;
}
- k_ptr = &k_info[lookup_kind(tv, sv)];
- info = k_name + k_ptr->name;
+ info = k_info[lookup_kind(tv, sv)].name;
}
/* Display a message */
@@ -4824,7 +4739,6 @@ bool_ target_set(int mode)
if (++m == temp_n)
{
m = 0;
- if (!expand_list) done = TRUE;
}
break;
}
@@ -4834,7 +4748,6 @@ bool_ target_set(int mode)
if (m-- == 0)
{
m = temp_n - 1;
- if (!expand_list) done = TRUE;
}
break;
}
@@ -5362,102 +5275,6 @@ bool_ tgt_pt(int *x, int *y)
return success;
}
-bool_ get_hack_dir(int *dp)
-{
- int dir;
- cptr p;
- char command;
-
-
- /* Initialize */
- (*dp) = 0;
-
- /* Global direction */
- dir = 0;
-
- /* (No auto-targetting */
-
- /* Ask until satisfied */
- while (!dir)
- {
- /* Choose a prompt */
- if (!target_okay())
- {
- p = "Direction ('*' to choose a target, Escape to cancel)? ";
- }
- else
- {
- p = "Direction ('5' for target, '*' to re-target, Escape to cancel)? ";
- }
-
- /* 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:
- {
- /* Look up the direction */
- dir = get_keymap_dir(command);
-
- break;
- }
- }
-
- /* Verify requested targets */
- if ((dir == 5) && !target_okay()) dir = 0;
-
- /* Error */
- if (!dir) bell();
- }
-
- /* No direction */
- if (!dir) return (FALSE);
-
- /* Save the direction */
- command_dir = dir;
-
- /* Check for confusion */
- if (p_ptr->confused)
- {
- /* XXX XXX XXX */
- /* Random direction */
- dir = ddd[rand_int(8)];
- }
-
- /* Notice confusion */
- if (command_dir != dir)
- {
- /* Warn the user */
- msg_print("You are confused.");
- }
-
- /* Save direction */
- (*dp) = dir;
-
- /* A "valid" direction was entered */
- return (TRUE);
-}
-
/*
* Set "p_ptr->grace", notice observable changes
*/
@@ -5467,11 +5284,11 @@ void set_grace(s32b v)
if (v > 300000) v = 300000;
p_ptr->grace = v;
p_ptr->update |= PU_BONUS;
- p_ptr->redraw |= (PR_PIETY);
+ p_ptr->redraw |= (PR_FRAME);
handle_stuff();
}
-bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, char *what)
+static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, const char *what)
{
int i, j, jb, save_aware;
char buf[200];
@@ -5572,7 +5389,7 @@ bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, char
object_desc(buf, o_ptr, FALSE, 0);
strlower(buf);
- if (!stricmp(buf, name))
+ if (iequals(buf, name))
{
/* Don't search any more */
return TRUE;
@@ -5589,7 +5406,7 @@ bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, char
return FALSE;
}
-void clean_wish_name(char *buf, char *name)
+static void clean_wish_name(char *buf, char *name)
{
char *p;
int i, j;
@@ -5695,7 +5512,7 @@ void make_wish(void)
if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
if (r_ptr->flags1 & RF1_UNIQUE) continue;
- sprintf(buf, "%s", r_ptr->name + r_name);
+ sprintf(buf, "%s", r_ptr->name);
strlower(buf);
if (strstr(mname, buf))
@@ -5707,20 +5524,26 @@ void make_wish(void)
if (j && !re_ptr->name) continue;
- if (!mego_ok(i, j)) continue;
+ if (!mego_ok(r_ptr, j)) continue;
if (j)
{
- if (re_ptr->before) sprintf(buf, "%s %s", re_name + re_ptr->name, r_ptr->name + r_name);
- else sprintf(buf, "%s %s", r_ptr->name + r_name, re_name + re_ptr->name);
+ if (re_ptr->before)
+ {
+ sprintf(buf, "%s %s", re_ptr->name, r_ptr->name);
+ }
+ else
+ {
+ sprintf(buf, "%s %s", r_ptr->name, re_ptr->name);
+ }
}
else
{
- sprintf(buf, "%s", r_ptr->name + r_name);
+ sprintf(buf, "%s", r_ptr->name);
}
strlower(buf);
- if (!stricmp(mname, buf))
+ if (iequals(mname, buf))
{
int wy = p_ptr->py, wx = p_ptr->px;
int attempts = 100;
@@ -5748,7 +5571,7 @@ void make_wish(void)
* Corrupted have a 1/3 chance of losing a mutation each time this is called,
* assuming they have any in the first place
*/
-void corrupt_corrupted(void)
+static void corrupt_corrupted(void)
{
if (magik(45))
{
@@ -5773,28 +5596,47 @@ void switch_subrace(int racem, bool_ copy_old)
/* If we switch to the saved subrace, we copy over the old subrace data */
if (copy_old && (racem == SUBRACE_SAVE))
{
- s32b old_title = race_mod_info[SUBRACE_SAVE].title;
- s32b old_desc = race_mod_info[SUBRACE_SAVE].desc;
-
- COPY(&race_mod_info[SUBRACE_SAVE], &race_mod_info[p_ptr->pracem], player_race_mod);
-
+ // This code is very reliant on the race_mod_info
+ // elements being simple PODs, in particular the
+ // text pointers being *unmanaged* owned pointers.
+ static_assert(std::is_pod<player_race_mod>::value,
+ "This code needs reworking");
+ // Keep references to owned pointers.
+ auto old_title = race_mod_info[SUBRACE_SAVE].title;
+ auto old_desc = race_mod_info[SUBRACE_SAVE].desc;
+ // Copy everything
+ race_mod_info[SUBRACE_SAVE] = race_mod_info[p_ptr->pracem];
+ // "Undo" copy of title and description (since they're *owned* pointers)
race_mod_info[SUBRACE_SAVE].title = old_title;
race_mod_info[SUBRACE_SAVE].desc = old_desc;
- strcpy(race_mod_info[SUBRACE_SAVE].title + rmp_name, race_mod_info[p_ptr->pracem].title + rmp_name);
+ // Replace subrace title with the title currently held by player.
+ set_subrace_title(&race_mod_info[SUBRACE_SAVE], race_mod_info[p_ptr->pracem].title);
}
p_ptr->pracem = racem;
rmp_ptr = &race_mod_info[p_ptr->pracem];
}
-cptr get_subrace_title(int racem)
+void set_subrace_title(player_race_mod *rmp_ptr, cptr name)
{
- return race_mod_info[racem].title + rmp_name;
+ // Free old title.
+ free(rmp_ptr->title);
+ // Allocate copy of new title.
+ rmp_ptr->title = strdup(name);
+ if (!rmp_ptr->title) {
+ abort();
+ }
}
-void set_subrace_title(int racem, cptr name)
+void set_subrace_description(player_race_mod *rmp_ptr, cptr desc)
{
- strcpy(race_mod_info[racem].title + rmp_name, name);
+ // Free old description
+ free(rmp_ptr->desc);
+ // Allocate copy of new description.
+ rmp_ptr->desc = strdup(desc);
+ if (!rmp_ptr->desc) {
+ abort();
+ }
}
/*
@@ -5816,7 +5658,7 @@ void do_rebirth()
p_ptr->max_plv = p_ptr->lev;
/* Redraw/calc stuff */
- p_ptr->redraw |= (PR_BASIC);
+ p_ptr->redraw |= (PR_FRAME);
p_ptr->update |= (PU_BONUS);
handle_stuff();
diff --git a/src/xtra2.hpp b/src/xtra2.hpp
new file mode 100644
index 00000000..cb16f6d9
--- /dev/null
+++ b/src/xtra2.hpp
@@ -0,0 +1,94 @@
+#pragma once
+
+#include "h-basic.h"
+#include "monster_race_fwd.hpp"
+#include "object_type_fwd.hpp"
+#include "player_race_mod_fwd.hpp"
+
+extern void do_rebirth(void);
+extern void set_subrace_title(player_race_mod *rmp_ptr, cptr name);
+extern void set_subrace_description(player_race_mod *rmp_ptr, cptr desc);
+extern void switch_subrace(int racem, bool_ copy_old);
+extern void drop_from_wild(void);
+extern bool_ set_roots(int v, s16b ac, s16b dam);
+extern bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag);
+extern bool_ set_parasite(int v, int r);
+extern bool_ set_disrupt_shield(int v);
+extern bool_ set_prob_travel(int v);
+extern bool_ set_absorb_soul(int v);
+extern bool_ set_tim_breath(int v, bool_ magical);
+extern bool_ set_tim_precognition(int v);
+extern bool_ set_tim_deadly(int v);
+extern bool_ set_tim_reflect(int v);
+extern bool_ set_tim_thunder(int v, int p1, int p2);
+extern bool_ set_strike(int v);
+extern bool_ set_tim_regen(int v, int p);
+extern bool_ set_tim_ffall(int v);
+extern bool_ set_tim_fly(int v);
+extern bool_ set_poison(int v);
+extern bool_ set_holy(int v);
+extern void set_grace(s32b v);
+extern bool_ set_mimic(int v, int p, int level);
+extern bool_ set_no_breeders(int v);
+extern bool_ set_invis(int v,int p);
+extern bool_ set_lite(int v);
+extern bool_ set_blind(int v);
+extern bool_ set_confused(int v);
+extern bool_ set_poisoned(int v);
+extern bool_ set_afraid(int v);
+extern bool_ set_paralyzed(int v);
+extern void dec_paralyzed();
+extern bool_ set_image(int v);
+extern bool_ set_fast(int v, int p);
+extern bool_ set_light_speed(int v);
+extern bool_ set_slow(int v);
+extern bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2);
+extern bool_ set_blessed(int v);
+extern bool_ set_hero(int v);
+extern bool_ set_shero(int v);
+extern bool_ set_protevil(int v);
+extern bool_ set_protgood(int v);
+extern bool_ set_protundead(int v);
+extern bool_ set_invuln(int v);
+extern bool_ set_tim_invis(int v);
+extern bool_ set_tim_infra(int v);
+extern bool_ set_mental_barrier(int v);
+extern bool_ set_oppose_acid(int v);
+extern bool_ set_oppose_elec(int v);
+extern bool_ set_oppose_fire(int v);
+extern bool_ set_oppose_cold(int v);
+extern bool_ set_oppose_pois(int v);
+extern bool_ set_oppose_ld(int v);
+extern bool_ set_oppose_cc(int v);
+extern bool_ set_oppose_ss(int v);
+extern bool_ set_oppose_nex(int v);
+extern bool_ set_stun(int v);
+extern bool_ set_cut(int v);
+extern bool_ set_food(int v);
+extern void check_experience(void);
+extern void check_experience_obj(object_type *o_ptr);
+extern void gain_exp(s32b amount);
+extern void lose_exp(s32b amount);
+extern int get_coin_type(monster_race *r_ptr);
+extern void monster_death(int m_idx);
+extern bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note);
+extern bool_ change_panel(int dy, int dx);
+extern void verify_panel(void);
+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_ set_shadow(int v);
+extern bool_ set_tim_esp(int v);
+extern bool_ tgp_pt(int *x, int * y);
+extern bool_ tgt_pt (int *x, int *y);
+extern void do_poly_self(void);
+extern bool_ curse_weapon(void);
+extern bool_ curse_armor(void);
+extern void make_wish(void);
+extern void create_between_gate(int dist, int y, int x);
+
+extern "C" {
+ extern void resize_map(void);
+ extern void resize_window(void);
+}
diff --git a/src/z-form.c b/src/z-form.c
index b3d5d005..b9a78fca 100644
--- a/src/z-form.c
+++ b/src/z-form.c
@@ -5,8 +5,8 @@
#include "z-form.h"
#include "z-util.h"
-#include "z-virt.h"
+#include <stdlib.h>
/*
* Here is some information about the routines in this file.
@@ -17,10 +17,10 @@
* (using only the first "max length" bytes), and return the "length"
* of the resulting string, not including the (mandatory) terminator.
*
- * The format strings allow the basic "sprintf()" format sequences, though
- * some of them are processed slightly more carefully or portably, as well
- * as a few "special" sequences, including the "%r" and "%v" sequences, and
- * the "capilitization" sequences of "%C", "%S", and "%V".
+ * The format strings allow the basic "sprintf()" format sequences,
+ * though some of them are processed slightly more carefully or
+ * portably, as well as a few "special" sequences, including the
+ * "capilitization" sequences of "%C", "%S", and "%V".
*
* Note that some "limitations" are enforced by the current implementation,
* for example, no "format sequence" can exceed 100 characters, including any
@@ -99,13 +99,6 @@
*
* Format("%V", vptr v)
* Note -- possibly significant mode flag
- * Format("%v", vptr v)
- * Append the object "v", using the current "user defined print routine".
- * User specified modifiers, often ignored.
- *
- * Format("%r", vstrnfmt_aux_func *fp)
- * Set the "user defined print routine" (vstrnfmt_aux) to "fp".
- * No legal modifiers.
*
*
* For examples below, assume "int n = 0; int m = 100; char buf[100];",
@@ -126,12 +119,6 @@
* For example: "s = buf; n = vstrnfmt(s+n, 100-n, ...); ..." will allow
* multiple bounded "appends" to "buf", with constant access to "strlen(buf)".
*
- * For example: "format("The %r%v was destroyed!", obj_desc, obj);"
- * (where "obj_desc(buf, max, fmt, obj)" will "append" a "description"
- * of the given object to the given buffer, and return the total length)
- * will return a "useful message" about the object "obj", for example,
- * "The Large Shield was destroyed!".
- *
* For example: "format("%^-.*s", i, txt)" will produce a string containing
* the first "i" characters of "txt", left justified, with the first non-space
* character capitilized, if reasonable.
@@ -140,40 +127,6 @@
-
-/*
- * The "type" of the "user defined print routine" pointer
- */
-typedef uint (*vstrnfmt_aux_func)(char *buf, uint max, cptr fmt, vptr arg);
-
-/*
- * The "default" user defined print routine. Ignore the "fmt" string.
- */
-static uint vstrnfmt_aux_dflt(char *buf, uint max, cptr fmt, vptr arg)
-{
- uint len;
- char tmp[32];
-
- /* XXX XXX */
- fmt = fmt ? fmt : 0;
-
- /* Pointer display */
- sprintf(tmp, "<<%p>>", arg);
- len = strlen(tmp);
- if (len >= max) len = max - 1;
- tmp[len] = '\0';
- strcpy(buf, tmp);
- return (len);
-}
-
-/*
- * The "current" user defined print routine. It can be changed
- * dynamically by sending the proper "%r" sequence to "vstrnfmt()"
- */
-static vstrnfmt_aux_func vstrnfmt_aux = vstrnfmt_aux_dflt;
-
-
-
/*
* Basic "vararg" format function.
*
@@ -316,19 +269,6 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
continue;
}
- /* Hack -- Pre-process "%r" */
- if (*s == 'r')
- {
- /* Extract the next argument, and save it (globally) */
- vstrnfmt_aux = va_arg(vp, vstrnfmt_aux_func);
-
- /* Skip the "r" */
- s++;
-
- /* Continue */
- continue;
- }
-
/* Begin the "aux" string */
q = 0;
@@ -576,23 +516,6 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
break;
}
- /* User defined data */
- case 'V':
- case 'v':
- {
- vptr arg;
-
- /* Access next argument */
- arg = va_arg(vp, vptr);
-
- /* Format the "user data" */
- (void)vstrnfmt_aux(tmp, 1000, aux, arg);
-
- /* Done */
- break;
- }
-
-
/* Oops */
default:
{
@@ -608,19 +531,7 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
/* Mega-Hack -- handle "capitilization" */
if (do_xtra)
{
- /* Now append "tmp" to "buf" */
- for (q = 0; tmp[q]; q++)
- {
- /* Notice first non-space */
- if (!isspace(tmp[q]))
- {
- /* Capitalize if possible */
- if (islower(tmp[q])) tmp[q] = toupper(tmp[q]);
-
- /* Done */
- break;
- }
- }
+ capitalize(tmp);
}
/* Now append "tmp" to "buf" */
@@ -647,16 +558,20 @@ uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp)
* Do a vstrnfmt (see above) into a (growable) static buffer.
* This buffer is usable for very short term formatting of results.
*/
-char *vformat(cptr fmt, va_list vp)
+static char *vformat(cptr fmt, va_list vp)
{
static char *format_buf = NULL;
- static huge format_len = 0;
+ static size_t format_len = 0;
/* Initial allocation */
if (!format_buf)
{
format_len = 1024;
- C_MAKE(format_buf, format_len, char);
+ format_buf = calloc(format_len, sizeof(char));
+ if (format_buf == NULL)
+ {
+ abort(); // Nothing sensible we can do
+ }
}
/* Null format yields last result */
@@ -674,9 +589,13 @@ char *vformat(cptr fmt, va_list vp)
if (len < format_len - 1) break;
/* Grow the buffer */
- C_KILL(format_buf, format_len, char);
+ free(format_buf);
format_len = format_len * 2;
- C_MAKE(format_buf, format_len, char);
+ format_buf = calloc(format_len, sizeof(char));
+ if (format_buf == NULL)
+ {
+ abort(); // Nothing sensible we can do
+ }
}
/* Return the new buffer */
@@ -762,29 +681,6 @@ char *format(cptr fmt, ...)
/*
- * Vararg interface to plog()
- */
-void plog_fmt(cptr fmt, ...)
-{
- char *res;
- va_list vp;
-
- /* Begin the Varargs Stuff */
- va_start(vp, fmt);
-
- /* Format the args */
- res = vformat(fmt, vp);
-
- /* End the Varargs Stuff */
- va_end(vp);
-
- /* Call plog */
- plog(res);
-}
-
-
-
-/*
* Vararg interface to quit()
*/
void quit_fmt(cptr fmt, ...)
@@ -804,28 +700,3 @@ void quit_fmt(cptr fmt, ...)
/* Call quit() */
quit(res);
}
-
-
-
-/*
- * Vararg interface to core()
- */
-void core_fmt(cptr fmt, ...)
-{
- char *res;
- va_list vp;
-
- /* Begin the Varargs Stuff */
- va_start(vp, fmt);
-
- /* If requested, Do a virtual fprintf to stderr */
- res = vformat(fmt, vp);
-
- /* End the Varargs Stuff */
- va_end(vp);
-
- /* Call core() */
- core(res);
-}
-
-
diff --git a/src/z-form.h b/src/z-form.h
index 2dcfa96c..61702432 100644
--- a/src/z-form.h
+++ b/src/z-form.h
@@ -1,7 +1,4 @@
-/* File z-form.h */
-
-#ifndef INCLUDED_Z_FORM_H
-#define INCLUDED_Z_FORM_H
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -17,7 +14,7 @@ extern "C" {
* See "z-form.c" for more detailed information about the routines,
* including a list of the legal "format sequences".
*
- * This file makes use of both "z-util.c" and "z-virt.c"
+ * This file makes use "z-util.c"
*/
@@ -32,23 +29,12 @@ extern uint strnfmt(char *buf, uint max, cptr fmt, ...);
/* Simple interface to "vstrnfmt()", assuming infinite length */
extern uint strfmt(char *buf, cptr fmt, ...);
-/* Format arguments into a static resizing buffer */
-extern char *vformat(cptr fmt, va_list vp);
-
/* Simple interface to "vformat()" */
extern char *format(cptr fmt, ...);
-/* Vararg interface to "plog()", using "format()" */
-extern void plog_fmt(cptr fmt, ...);
-
/* Vararg interface to "quit()", using "format()" */
extern void quit_fmt(cptr fmt, ...);
-/* Vararg interface to "core()", using "format()" */
-extern void core_fmt(cptr fmt, ...);
-
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif
diff --git a/src/z-rand.h b/src/z-rand.h
index 39cc958c..ba17dabe 100644
--- a/src/z-rand.h
+++ b/src/z-rand.h
@@ -1,7 +1,4 @@
-/* File: z-rand.h */
-
-#ifndef INCLUDED_Z_RAND_H
-#define INCLUDED_Z_RAND_H
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -91,6 +88,3 @@ extern s32b maxroll(s16b num, s16b sides);
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-
-#endif
diff --git a/src/z-term.c b/src/z-term.c
index 4e89ffb7..891c10f3 100644
--- a/src/z-term.c
+++ b/src/z-term.c
@@ -1,5 +1,3 @@
-/* File: z-term.c */
-
/*
* Copyright (c) 1997 Ben Harrison
*
@@ -10,11 +8,8 @@
/* Purpose: a generic, efficient, terminal window package -BEN- */
-#include "angband.h"
-
#include "z-term.h"
-#include "z-virt.h"
/*
@@ -86,13 +81,9 @@
*
* This package allows each "grid" in each window to hold an attr/char
* pair, with each ranging from 0 to 255, and makes very few assumptions
- * about the meaning of any attr/char values. Normally, we assume that
- * "attr 0" is "black", with the semantics that "black" text should be
- * sent to "Term_wipe()" instead of "Term_text()", but this sematics is
- * modified if either the "always_pict" or the "always_text" flags are
- * set. We assume that "char 0" is "dangerous", since placing such a
- * "char" in the middle of a string "terminates" the string, and usually
- * we prevent its use.
+ * about the meaning of any attr/char values. We assume that "attr 0" is
+ * "black", with the semantics that "black" text should be
+ * sent to "Term_wipe()" instead of "Term_text()".
*
* Finally, we use a special attr/char pair, defaulting to "attr 0" and
* "char 32", also known as "black space", when we "erase" or "clear"
@@ -160,8 +151,7 @@
* The new formalism includes a "displayed" screen image (old) which
* is actually seen by the user, a "requested" screen image (scr)
* which is being prepared for display, a "memorized" screen image
- * (mem) which is used to save and restore screen images, and a
- * "temporary" screen image (tmp) which is currently unused.
+ * (mem) which is used to save and restore screen images.
*
*
* Several "flags" are available in each "term" to allow the underlying
@@ -184,16 +174,10 @@
*
* Term->init_hook = Init the term
* Term->nuke_hook = Nuke the term
- * Term->user_hook = Perform user actions
* Term->xtra_hook = Perform extra actions
* Term->curs_hook = Draw (or Move) the cursor
* Term->wipe_hook = Draw some blank spaces
* Term->text_hook = Draw some text in the window
- * Term->pict_hook = Draw some attr/chars in the window
- *
- * The "Term->user_hook" hook provides a simple hook to an implementation
- * defined function, with application defined semantics. It is available
- * to the program via the "Term_user()" function.
*
* The "Term->xtra_hook" hook provides a variety of different functions,
* based on the first parameter (which should be taken from the various
@@ -211,26 +195,13 @@
* The "Term->wipe_hook" hook provides this package with a simple way
* to "erase", starting at "x,y", the next "n" grids. This hook assumes
* that the input is valid. This hook is required, unless the setting
- * of the "always_pict" or "always_text" flags makes it optional.
+ * of the "always_text" flag makes it optional.
*
* The "Term->text_hook" hook provides this package with a simple way
* to "draw", starting at "x,y", the "n" chars contained in "cp", using
* the attr "a". This hook assumes that the input is valid, and that
* "n" is between 1 and 256 inclusive, but it should NOT assume that
- * the contents of "cp" are null-terminated. This hook is required,
- * unless the setting of the "always_pict" flag makes it optional.
- *
- * The "Term->pict_hook" hook provides this package with a simple way
- * to "draw", starting at "x,y", the "n" attr/char pairs contained in
- * the arrays "ap" and "cp". This hook assumes that the input is valid,
- * and that "n" is between 1 and 256 inclusive, but it should NOT assume
- * that the contents of "cp" are null-terminated. This hook is optional,
- * unless the setting of the "always_pict" or "higher_pict" flags make
- * it required. Note that recently, this hook was changed from taking
- * a byte "a" and a char "c" to taking a length "n", an array of bytes
- * "ap" and an array of chars "cp". Old implementations of this hook
- * should now iterate over all "n" attr/char pairs.
- *
+ * the contents of "cp" are null-terminated.
*
* The game "Angband" uses a set of files called "main-xxx.c", for
* various "xxx" suffixes. Most of these contain a function called
@@ -254,12 +225,6 @@
* files use "white space" ("attr 1" / "char 32") to "erase" or "clear"
* any window, for efficiency.
*
- * The game "Angband" uses the "Term_user" hook to allow any of the
- * "main-xxx.c" files to interact with the user, by calling this hook
- * whenever the user presses the "!" key when the game is waiting for
- * a new command. This could be used, for example, to provide "unix
- * shell commands" to the Unix versions of the game.
- *
* See "main-xxx.c" for a simple skeleton file which can be used to
* create a "visual system" for a new platform when porting Angband.
*/
@@ -271,50 +236,40 @@
*/
term *Term = NULL;
-/* File handler for saving movies */
-FILE *movfile = NULL;
-int do_movies = 0; /* Later set this as a global */
-/* set to 1 if you want movies made */
-time_t lastc;
-int last_paused = 0;
-int cmovie_get_msecond(void);
-
-/* Record cmovies with millisecond frame rate */
-long cmov_last_time_msec;
-long cmov_delta_time_msec;
-
-
/*** Local routines ***/
/*
+ * Calloc wrapper which aborts if NULL is returned by calloc
+ */
+static void *safe_calloc(size_t nmemb, size_t size)
+{
+ void *p = calloc(nmemb, size);
+ if ((nmemb > 0) && (p == NULL))
+ {
+ abort();
+ }
+ return p;
+}
+
+/*
* Nuke a term_win (see below)
*/
static errr term_win_nuke(term_win *s, int w, int h)
{
/* Free the window access arrays */
- C_KILL(s->a, h, byte*);
- C_KILL(s->c, h, char*);
-
- /* Free the window content arrays */
- C_KILL(s->va, h * w, byte);
- C_KILL(s->vc, h * w, char);
-
- /* Free the terrain access arrays */
- C_KILL(s->ta, h, byte*);
- C_KILL(s->tc, h, char*);
+ free(s->a);
+ s->a = NULL;
- /* Free the terrain content arrays */
- C_KILL(s->vta, h * w, byte);
- C_KILL(s->vtc, h * w, char);
+ free(s->c);
+ s->c = NULL;
- /* Free the ego graphics access arrays */
- C_KILL(s->ea, h, byte*);
- C_KILL(s->ec, h, char*);
+ /* Free the window content arrays */
+ free(s->va);
+ s->va = NULL;
- /* Free the ego graphics content arrays */
- C_KILL(s->vea, h * w, byte);
- C_KILL(s->vec, h * w, char);
+ free(s->vc);
+ s->vc = NULL;
/* Success */
return (0);
@@ -329,42 +284,18 @@ static errr term_win_init(term_win *s, int w, int h)
int y;
/* Make the window access arrays */
- C_MAKE(s->a, h, byte*);
- C_MAKE(s->c, h, char*);
+ s->a = safe_calloc(h, sizeof(byte*));
+ s->c = safe_calloc(h, sizeof(char*));
/* Make the window content arrays */
- C_MAKE(s->va, h * w, byte);
- C_MAKE(s->vc, h * w, char);
-
- /* Make the terrain access arrays */
- C_MAKE(s->ta, h, byte*);
- C_MAKE(s->tc, h, char*);
-
- /* Make the terrain content arrays */
- C_MAKE(s->vta, h * w, byte);
- C_MAKE(s->vtc, h * w, char);
-
- /* Make the ego graphics access arrays */
- C_MAKE(s->ea, h, byte*);
- C_MAKE(s->ec, h, char*);
-
- /* Make the ego graphics content arrays */
- C_MAKE(s->vea, h * w, byte);
- C_MAKE(s->vec, h * w, char);
-
+ s->va = safe_calloc(h * w, sizeof(byte));
+ s->vc = safe_calloc(h * w, sizeof(char));
/* Prepare the window access arrays */
for (y = 0; y < h; y++)
{
s->a[y] = s->va + w * y;
s->c[y] = s->vc + w * y;
-
- s->ta[y] = s->vta + w * y;
- s->tc[y] = s->vtc + w * y;
-
- s->ea[y] = s->vea + w * y;
- s->ec[y] = s->vec + w * y;
-
}
/* Success */
@@ -388,28 +319,10 @@ static errr term_win_copy(term_win *s, term_win *f, int w, int h)
byte *s_aa = s->a[y];
char *s_cc = s->c[y];
- byte *f_taa = f->ta[y];
- char *f_tcc = f->tc[y];
-
- byte *s_taa = s->ta[y];
- char *s_tcc = s->tc[y];
-
- byte *f_eaa = f->ea[y];
- char *f_ecc = f->ec[y];
-
- byte *s_eaa = s->ea[y];
- char *s_ecc = s->ec[y];
-
for (x = 0; x < w; x++)
{
*s_aa++ = *f_aa++;
*s_cc++ = *f_cc++;
-
- *s_taa++ = *f_taa++;
- *s_tcc++ = *f_tcc++;
-
- *s_eaa++ = *f_eaa++;
- *s_ecc++ = *f_ecc++;
}
}
@@ -429,25 +342,9 @@ static errr term_win_copy(term_win *s, term_win *f, int w, int h)
/*
- * Execute the "Term->user_hook" hook, if available (see above).
- */
-errr Term_user(int n)
-{
- /* Verify the hook */
- if (!Term->user_hook) return ( -1);
-
- /* Call the hook */
- return ((*Term->user_hook)(n));
-}
-
-/*
* Execute the "Term->xtra_hook" hook, if available (see above).
* And *hacky* get a return code
*/
-long Term_xtra_long;
-char scansubdir_dir[1024];
-int scansubdir_max = 0;
-cptr scansubdir_result[255];
errr Term_xtra(int n, int v)
{
/* Verify the hook */
@@ -498,18 +395,6 @@ static errr Term_text_hack(int x, int y, int n, byte a, const char *cp)
return ( -1);
}
-/*
- * Hack -- fake hook for "Term_pict()" (see above)
- */
-static errr Term_pict_hack(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp)
-{
- /* Compiler silliness */
- if (x || y || n || ap || cp || tap || tcp || eap || ecp) return ( -2);
-
- /* Oops */
- return ( -1);
-}
-
/*** Efficient routines ***/
@@ -520,34 +405,20 @@ static errr Term_pict_hack(int x, int y, int n, const byte *ap, const char *cp,
*
* Assumes given location and values are valid.
*/
-void Term_queue_char(int x, int y, byte a, char c, byte ta, char tc, byte ea, char ec)
+void Term_queue_char(int x, int y, byte a, char c)
{
term_win *scrn = Term->scr;
byte *scr_aa = &scrn->a[y][x];
char *scr_cc = &scrn->c[y][x];
- byte *scr_taa = &scrn->ta[y][x];
- char *scr_tcc = &scrn->tc[y][x];
-
- byte *scr_eaa = &scrn->ea[y][x];
- char *scr_ecc = &scrn->ec[y][x];
-
/* Hack -- Ignore non-changes */
- if ((*scr_aa == a) && (*scr_cc == c) &&
- (*scr_taa == ta) && (*scr_tcc == tc) &&
- (*scr_eaa == ea) && (*scr_ecc == ec)) return;
+ if ((*scr_aa == a) && (*scr_cc == c)) return;
/* Save the "literal" information */
*scr_aa = a;
*scr_cc = c;
- *scr_taa = ta;
- *scr_tcc = tc;
-
- *scr_eaa = ea;
- *scr_ecc = ec;
-
/* Check for new min/max row info */
if (y < Term->y1) Term->y1 = y;
if (y > Term->y2) Term->y2 = y;
@@ -558,89 +429,6 @@ void Term_queue_char(int x, int y, byte a, char c, byte ta, char tc, byte ea, ch
}
-/*
- * Mentally draw a string of attr/chars at a given location
- *
- * Assumes given location and values are valid.
- *
- * This function is designed to be fast, with no consistancy checking.
- * It is used to update the map in the game.
- */
-void Term_queue_line(int x, int y, int n, byte *a, char *c, byte *ta, char *tc, byte *ea, char *ec)
-{
- term_win *scrn = Term->scr;
-
- int x1 = -1;
- int x2 = -1;
-
- byte *scr_aa = &scrn->a[y][x];
- char *scr_cc = &scrn->c[y][x];
-
- byte *scr_taa = &scrn->ta[y][x];
- char *scr_tcc = &scrn->tc[y][x];
-
- byte *scr_eaa = &scrn->ea[y][x];
- char *scr_ecc = &scrn->ec[y][x];
-
- while (n--)
- {
-
- /* Hack -- Ignore non-changes */
- if ((*scr_aa == *a) && (*scr_cc == *c) &&
- (*scr_taa == *ta) && (*scr_tcc == *tc) &&
- (*scr_eaa == *ea) && (*scr_ecc == *ec))
- {
- x++;
- a++;
- c++;
- ta++;
- tc++;
- ea++;
- ec++;
- scr_aa++;
- scr_cc++;
- scr_taa++;
- scr_tcc++;
- scr_eaa++;
- scr_ecc++;
- continue;
- }
-
- /* Save the "literal" information */
- *scr_taa++ = *ta++;
- *scr_tcc++ = *tc++;
-
- /* Save the "literal" information */
- *scr_eaa++ = *ea++;
- *scr_ecc++ = *ec++;
-
- /* Save the "literal" information */
- *scr_aa++ = *a++;
- *scr_cc++ = *c++;
-
- /* Track minimum changed column */
- if (x1 < 0) x1 = x;
-
- /* Track maximum changed column */
- x2 = x;
-
- x++;
- }
-
- /* Expand the "change area" as needed */
- if (x1 >= 0)
- {
- /* Check for new min/max row info */
- if (y < Term->y1) Term->y1 = y;
- if (y > Term->y2) Term->y2 = y;
-
- /* Check for new min/max col info in this row */
- if (x1 < Term->x1[y]) Term->x1[y] = x1;
- if (x2 > Term->x2[y]) Term->x2[y] = x2;
- }
-}
-
-
/*
* Mentally draw some attr/chars at a given location
@@ -657,40 +445,19 @@ void Term_queue_chars(int x, int y, int n, byte a, cptr s)
byte *scr_aa = Term->scr->a[y];
char *scr_cc = Term->scr->c[y];
- byte *scr_taa = Term->scr->ta[y];
- char *scr_tcc = Term->scr->tc[y];
-
- byte *scr_eaa = Term->scr->ea[y];
- char *scr_ecc = Term->scr->ec[y];
-
/* Queue the attr/chars */
for ( ; n; x++, s++, n--)
{
int oa = scr_aa[x];
int oc = scr_cc[x];
- int ota = scr_taa[x];
- int otc = scr_tcc[x];
-
- int oea = scr_eaa[x];
- int oec = scr_ecc[x];
-
/* Hack -- Ignore non-changes */
- if ((oa == a) && (oc == *s) &&
- (ota == 0) && (otc == 0) &&
- (oea == 0) && (oec == 0)) continue;
-
+ if ((oa == a) && (oc == *s)) continue;
/* Save the "literal" information */
scr_aa[x] = a;
scr_cc[x] = *s;
- scr_taa[x] = 0;
- scr_tcc[x] = 0;
-
- scr_taa[x] = 0;
- scr_tcc[x] = 0;
-
/* Note the "range" of window updates */
if (x1 < 0) x1 = x;
x2 = x;
@@ -711,321 +478,6 @@ void Term_queue_chars(int x, int y, int n, byte a, cptr s)
-/*** Refresh routines ***/
-
-
-/*
- * Flush a row of the current window (see "Term_fresh")
- *
- * Display text using "Term_pict()"
- */
-static void Term_fresh_row_pict(int y, int x1, int x2)
-{
- int x;
-
- byte *old_aa = Term->old->a[y];
- char *old_cc = Term->old->c[y];
-
- byte *scr_aa = Term->scr->a[y];
- char *scr_cc = Term->scr->c[y];
-
- byte *old_taa = Term->old->ta[y];
- char *old_tcc = Term->old->tc[y];
-
- byte *scr_taa = Term->scr->ta[y];
- char *scr_tcc = Term->scr->tc[y];
-
- byte ota;
- char otc;
-
- byte nta;
- char ntc;
-
- byte *old_eaa = Term->old->ea[y];
- char *old_ecc = Term->old->ec[y];
-
- byte *scr_eaa = Term->scr->ea[y];
- char *scr_ecc = Term->scr->ec[y];
-
- byte oea;
- char oec;
-
- byte nea;
- char nec;
-
-
-
- /* Pending length */
- int fn = 0;
-
- /* Pending start */
- int fx = 0;
-
- byte oa;
- char oc;
-
- byte na;
- char nc;
-
- /* Scan "modified" columns */
- for (x = x1; x <= x2; x++)
- {
- /* See what is currently here */
- oa = old_aa[x];
- oc = old_cc[x];
-
- /* See what is desired there */
- na = scr_aa[x];
- nc = scr_cc[x];
-
- ota = old_taa[x];
- otc = old_tcc[x];
-
- nta = scr_taa[x];
- ntc = scr_tcc[x];
-
- oea = old_eaa[x];
- oec = old_ecc[x];
-
- nea = scr_eaa[x];
- nec = scr_ecc[x];
-
- /* Handle unchanged grids */
- if ((na == oa) && (nc == oc) &&
- (nta == ota) && (ntc == otc) &&
- (nea == oea) && (nec == oec))
- {
- /* Flush */
- if (fn)
- {
- /* Draw pending attr/char pairs */
- (void)((*Term->pict_hook)(fx, y, fn,
- &scr_aa[fx], &scr_cc[fx],
- &scr_taa[fx], &scr_tcc[fx],
- &scr_eaa[fx], &scr_ecc[fx]));
-
- /* Forget */
- fn = 0;
- }
-
- /* Skip */
- continue;
- }
- /* Save new contents */
- old_aa[x] = na;
- old_cc[x] = nc;
-
- old_taa[x] = nta;
- old_tcc[x] = ntc;
-
- old_eaa[x] = nea;
- old_ecc[x] = nec;
-
- /* Restart and Advance */
- if (fn++ == 0) fx = x;
- }
-
- /* Flush */
- if (fn)
- {
- /* Draw pending attr/char pairs */
- (void)((*Term->pict_hook)(fx, y, fn,
- &scr_aa[fx], &scr_cc[fx],
- &scr_taa[fx], &scr_tcc[fx],
- &scr_eaa[fx], &scr_ecc[fx]));
- }
-}
-
-
-
-/*
- * Flush a row of the current window (see "Term_fresh")
- *
- * 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;
-
- byte *old_aa = Term->old->a[y];
- char *old_cc = Term->old->c[y];
-
- byte *scr_aa = Term->scr->a[y];
- char *scr_cc = Term->scr->c[y];
-
- byte *old_taa = Term->old->ta[y];
- char *old_tcc = Term->old->tc[y];
- byte *scr_taa = Term->scr->ta[y];
- char *scr_tcc = Term->scr->tc[y];
-
- byte ota;
- char otc;
- byte nta;
- char ntc;
-
- byte *old_eaa = Term->old->ea[y];
- char *old_ecc = Term->old->ec[y];
- byte *scr_eaa = Term->scr->ea[y];
- char *scr_ecc = Term->scr->ec[y];
-
- byte oea;
- char oec;
- byte nea;
- char nec;
-
- /* The "always_text" flag */
- int always_text = Term->always_text;
-
- /* Pending length */
- int fn = 0;
-
- /* Pending start */
- int fx = 0;
-
- /* Pending attr */
- byte fa = Term->attr_blank;
-
- byte oa;
- char oc;
-
- byte na;
- char nc;
-
- /* Scan "modified" columns */
- for (x = x1; x <= x2; x++)
- {
- /* See what is currently here */
- oa = old_aa[x];
- oc = old_cc[x];
-
- /* See what is desired there */
- na = scr_aa[x];
- nc = scr_cc[x];
-
- ota = old_taa[x];
- otc = old_tcc[x];
-
- nta = scr_taa[x];
- ntc = scr_tcc[x];
-
- oea = old_eaa[x];
- oec = old_ecc[x];
-
- nea = scr_eaa[x];
- nec = scr_ecc[x];
-
- /* Handle unchanged grids */
- if ((na == oa) && (nc == oc) &&
- (nta == ota) && (ntc == otc) &&
- (nea == oea) && (nec == oec))
- {
- /* Flush */
- if (fn)
- {
- /* Draw pending chars (normal) */
- if (fa || always_text)
- {
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
- }
- /* Draw pending chars (black) */
- else
- {
- (void)((*Term->wipe_hook)(fx, y, fn));
- }
- /* Forget */
- fn = 0;
- }
-
- /* Skip */
- continue;
- }
-
- /* Save new contents */
- old_aa[x] = na;
- old_cc[x] = nc;
-
- old_taa[x] = nta;
- old_tcc[x] = ntc;
-
- old_eaa[x] = nea;
- old_ecc[x] = nec;
-
- /* 2nd byte of bigtile */
- if (na == 255) continue;
-
- /* Handle high-bit attr/chars */
- if (na & 0x80)
- {
- /* Flush */
- if (fn)
- {
- /* Draw pending chars (normal) */
- if (fa || always_text)
- {
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
- }
- /* Draw pending chars (black) */
- else
- {
- (void)((*Term->wipe_hook)(fx, y, fn));
- }
- /* Forget */
- fn = 0;
- }
-
- /* Hack -- Draw the special attr/char pair */
- (void)((*Term->pict_hook)(x, y, 1, &na, &nc, &nta, &ntc, &nea, &nec));
-
- /* Skip */
- continue;
- }
-
- /* Notice new color */
- if (fa != na)
- {
- /* Flush */
- if (fn)
- {
- /* Draw the pending chars */
- if (fa || always_text)
- {
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
- }
- /* Hack -- Erase "leading" spaces */
- else
- {
- (void)((*Term->wipe_hook)(fx, y, fn));
- }
- /* Forget */
- fn = 0;
- }
-
- /* Save the new color */
- fa = na;
- }
-
- /* Restart and Advance */
- if (fn++ == 0) fx = x;
- }
-
- /* Flush */
- if (fn)
- {
- /* Draw pending chars (normal) */
- if (fa || always_text)
- {
- (void)((*Term->text_hook)(fx, y, fn, fa, &scr_cc[fx]));
- }
- /* Draw pending chars (black) */
- else
- {
- (void)((*Term->wipe_hook)(fx, y, fn));
- }
- }
-}
-
-
/*
* Flush a row of the current window (see "Term_fresh")
*
@@ -1172,21 +624,9 @@ static void Term_fresh_row_text(int y, int x1, int x2)
* Note that "Term_xtra(TERM_XTRA_CLEAR,0)" must erase the entire screen,
* including the cursor, if needed, and may place the cursor anywhere.
*
- * Note that "Term_xtra(TERM_XTRA_FROSH,y)" will be always be called
- * after any row "y" has been "flushed", unless the "Term->never_frosh"
- * flag is set, and "Term_xtra(TERM_XTRA_FRESH,0)" will be called after
+ * Note that "Term_xtra(TERM_XTRA_FRESH,0)" will be called after
* all of the rows have been "flushed".
*
- * Note the use of three different functions to handle the actual flush,
- * based on the settings of the "Term->always_pict" and "Term->higher_pict"
- * flags (see below).
- *
- * The three helper functions (above) work by collecting similar adjacent
- * grids into stripes, and then sending each stripe to "Term->pict_hook",
- * "Term->text_hook", or "Term->wipe_hook", based on the settings of the
- * "Term->always_pict" and "Term->higher_pict" flags, which select which
- * of the helper functions to call to flush each row.
- *
* The helper functions currently "skip" any grids which already contain
* the desired contents. This may or may not be the best method, especially
* when the desired content fits nicely into the current stripe. For example,
@@ -1209,18 +649,6 @@ static void Term_fresh_row_text(int y, int x1, int x2)
* and situations in which two grids in the same row are changed, but
* the grids between them are unchanged.
*
- * If the "Term->always_pict" flag is set, then "Term_fresh_row_pict()"
- * will be used instead of "Term_fresh_row_text()". This allows all the
- * modified grids to be collected into stripes of attr/char pairs, which
- * are then sent to the "Term->pict_hook" hook, which can draw these pairs
- * in whatever way it would like.
- *
- * If the "Term->higher_pict" flag is set, then "Term_fresh_row_both()"
- * will be used instead of "Term_fresh_row_text()". This allows all the
- * "special" attr/char pairs (in which both the attr and char have the
- * high-bit set) to be sent (one pair at a time) to the "Term->pict_hook"
- * hook, which can draw these pairs in whatever way it would like.
- *
* Normally, the "Term_wipe()" function is used only to display "blanks"
* that were induced by "Term_clear()" or "Term_erase()", and then only
* if the "attr_blank" and "char_blank" fields have not been redefined
@@ -1233,10 +661,6 @@ static void Term_fresh_row_text(int y, int x1, int x2)
* drawn in the color "black", to be explicitly drawn. This is useful
* for machines which implement "Term_wipe()" by just drawing spaces.
*
- * Note that the "Term->always_pict" flag will disable the use of the
- * "Term_wipe()" function entirely, and force everything, even text
- * drawn in the attr "black", to be explicitly drawn.
- *
* Note that if no "black" text is ever drawn, and if "attr_blank" is
* not "zero", then the "Term_wipe" hook will never be used, even if
* the "Term->always_text" flag is not set.
@@ -1298,7 +722,6 @@ errr Term_fresh(void)
if (!Term->curs_hook) Term->curs_hook = Term_curs_hack;
if (!Term->wipe_hook) Term->wipe_hook = Term_wipe_hack;
if (!Term->text_hook) Term->text_hook = Term_text_hack;
- if (!Term->pict_hook) Term->pict_hook = Term_pict_hack;
/* Handle "total erase" */
@@ -1307,16 +730,6 @@ errr Term_fresh(void)
byte na = Term->attr_blank;
char nc = Term->char_blank;
- if ((do_movies == 1) && IN_MAINWINDOW)
- {
- if (!cmovie_get_msecond())
- {
- fprintf(movfile, "S:%ld:\n", cmov_delta_time_msec);
- }
- fprintf(movfile, "C:\n");
- last_paused = 0;
- }
-
/* Physically erase the entire window */
Term_xtra(TERM_XTRA_CLEAR, 0);
@@ -1329,25 +742,12 @@ errr Term_fresh(void)
byte *aa = old->a[y];
char *cc = old->c[y];
- byte *taa = old->ta[y];
- char *tcc = old->tc[y];
-
- byte *eaa = old->ea[y];
- char *ecc = old->ec[y];
-
-
/* Wipe each column */
for (x = 0; x < w; x++)
{
/* Wipe each grid */
*aa++ = na;
*cc++ = nc;
-
- *taa++ = na;
- *tcc++ = nc;
-
- *eaa++ = na;
- *ecc++ = nc;
}
}
@@ -1382,32 +782,8 @@ errr Term_fresh(void)
byte oa = old_aa[tx];
char oc = old_cc[tx];
- byte *old_taa = old->ta[ty];
- char *old_tcc = old->tc[ty];
-
- byte ota = old_taa[tx];
- char otc = old_tcc[tx];
-
- byte *old_eaa = old->ea[ty];
- char *old_ecc = old->ec[ty];
-
- byte oea = old_eaa[tx];
- char oec = old_ecc[tx];
-
- /* Hack -- use "Term_pict()" always */
- if (Term->always_pict)
- {
- (void)((*Term->pict_hook)(tx, ty, 1, &oa, &oc, &ota, &otc, &oea, &oec));
- }
-
- /* Hack -- use "Term_pict()" sometimes */
- else if (Term->higher_pict && (oa & 0x80))
- {
- (void)((*Term->pict_hook)(tx, ty, 1, &oa, &oc, &ota, &otc, &oea, &oec));
- }
-
/* Hack -- restore the actual character */
- else if (oa || Term->always_text)
+ if (oa || Term->always_text)
{
(void)((*Term->text_hook)(tx, ty, 1, oa, &oc));
}
@@ -1460,40 +836,12 @@ errr Term_fresh(void)
/* Flush each "modified" row */
if (x1 <= x2)
{
- if ((do_movies == 1) && IN_MAINWINDOW)
- {
- /* Most magic happens here */
- cmovie_record_line(y);
- last_paused = 0;
- }
-
- /* 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);
- }
+ /* Flush the row */
+ Term_fresh_row_text(y, x1, x2);
/* This row is all done */
Term->x1[y] = w;
Term->x2[y] = 0;
-
- /* Hack -- Flush that row (if allowed) */
- if (!Term->never_frosh) Term_xtra(TERM_XTRA_FROSH, y);
}
}
@@ -1629,7 +977,7 @@ errr Term_draw(int x, int y, byte a, char c)
if (!c) return ( -2);
/* Queue it for later */
- Term_queue_char(x, y, a, c, 0, 0, 0, 0);
+ Term_queue_char(x, y, a, c);
/* Success */
return (0);
@@ -1663,7 +1011,7 @@ errr Term_addch(byte a, char c)
if (!c) return ( -2);
/* Queue the given character for display */
- Term_queue_char(Term->scr->cx, Term->scr->cy, a, c, 0, 0, 0, 0);
+ Term_queue_char(Term->scr->cx, Term->scr->cy, a, c);
/* Advance the cursor */
Term->scr->cx++;
@@ -1788,12 +1136,6 @@ errr Term_erase(int x, int y, int n)
byte *scr_aa;
char *scr_cc;
- byte *scr_taa;
- char *scr_tcc;
-
- byte *scr_eaa;
- char *scr_ecc;
-
/* Place cursor */
if (Term_gotoxy(x, y)) return ( -1);
@@ -1804,12 +1146,6 @@ errr Term_erase(int x, int y, int n)
scr_aa = Term->scr->a[y];
scr_cc = Term->scr->c[y];
- scr_taa = Term->scr->ta[y];
- scr_tcc = Term->scr->tc[y];
-
- scr_eaa = Term->scr->ea[y];
- scr_ecc = Term->scr->ec[y];
-
if (n > 0 && (byte)scr_cc[x] == 255 && scr_aa[x] == 255)
{
x--;
@@ -1829,12 +1165,6 @@ errr Term_erase(int x, int y, int n)
scr_aa[x] = na;
scr_cc[x] = nc;
- scr_taa[x] = 0;
- scr_tcc[x] = 0;
-
- scr_eaa[x] = 0;
- scr_ecc[x] = 0;
-
/* Track minimum changed column */
if (x1 < 0) x1 = x;
@@ -1886,23 +1216,11 @@ errr Term_clear(void)
byte *scr_aa = Term->scr->a[y];
char *scr_cc = Term->scr->c[y];
- byte *scr_taa = Term->scr->ta[y];
- char *scr_tcc = Term->scr->tc[y];
-
- byte *scr_eaa = Term->scr->ea[y];
- char *scr_ecc = Term->scr->ec[y];
-
/* Wipe each column */
for (x = 0; x < w; x++)
{
scr_aa[x] = na;
scr_cc[x] = nc;
-
- scr_taa[x] = 0;
- scr_tcc[x] = 0;
-
- scr_eaa[x] = 0;
- scr_ecc[x] = 0;
}
/* This row has changed */
@@ -1930,17 +1248,6 @@ errr Term_clear(void)
*/
errr Term_redraw(void)
{
- /* Pat */
- if ((do_movies == 1) && IN_MAINWINDOW)
- {
- if (!cmovie_get_msecond())
- {
- fprintf(movfile, "S:%ld:\n", cmov_delta_time_msec);
- }
- last_paused = 1;
- }
- /* Endpat */
-
/* Force "total erase" */
Term->total_erase = TRUE;
@@ -1995,6 +1302,10 @@ errr Term_redraw_section(int x1, int y1, int x2, int y2)
}
+void Term_bell()
+{
+ Term_xtra(TERM_XTRA_NOISE, 0);
+}
/*** Access routines ***/
@@ -2018,8 +1329,15 @@ errr Term_get_cursor(int *v)
errr Term_get_size(int *w, int *h)
{
/* Access the cursor */
- (*w) = Term->wid;
- (*h) = Term->hgt;
+ if (w)
+ {
+ (*w) = Term->wid;
+ }
+
+ if (h)
+ {
+ (*h) = Term->hgt;
+ }
/* Success */
return (0);
@@ -2156,14 +1474,6 @@ errr Term_inkey(char *ch, bool_ wait, bool_ take)
Term_xtra(TERM_XTRA_BORED, 0);
}
- /* PatN */
- if ((do_movies == 1) && (last_paused == 0) && (!cmovie_get_msecond()))
- {
- fprintf(movfile, "S:%ld:\n", cmov_delta_time_msec);
- last_paused = 1;
- }
- /* PatNEnd */
-
/* Wait */
if (wait)
{
@@ -2218,7 +1528,7 @@ errr Term_save(void)
if (!Term->mem)
{
/* Allocate window */
- MAKE(Term->mem, term_win);
+ Term->mem = safe_calloc(1, sizeof(struct term_win));
/* Initialize window */
term_win_init(Term->mem, w, h);
@@ -2241,7 +1551,7 @@ term_win* Term_save_to(void)
term_win *save;
/* Allocate window */
- MAKE(save, term_win);
+ save = safe_calloc(1, sizeof(struct term_win));
/* Initialize window */
term_win_init(save, w, h);
@@ -2269,7 +1579,7 @@ errr Term_load(void)
if (!Term->mem)
{
/* Allocate window */
- MAKE(Term->mem, term_win);
+ Term->mem = safe_calloc(1, sizeof(struct term_win));
/* Initialize window */
term_win_init(Term->mem, w, h);
@@ -2327,52 +1637,10 @@ errr Term_load_from(term_win *save, bool_ final)
/* Free is requested */
if (final)
- FREE(save, term_win);
-
- /* Success */
- return (0);
-}
-
-/*
- * Exchange the "requested" screen with the "tmp" screen
- */
-errr Term_exchange(void)
-{
- int y;
-
- int w = Term->wid;
- int h = Term->hgt;
-
- term_win *exchanger;
-
-
- /* Create */
- if (!Term->tmp)
{
- /* Allocate window */
- MAKE(Term->tmp, term_win);
-
- /* Initialize window */
- term_win_init(Term->tmp, w, h);
- }
-
- /* Swap */
- exchanger = Term->scr;
- Term->scr = Term->tmp;
- Term->tmp = exchanger;
-
- /* Assume change */
- for (y = 0; y < h; y++)
- {
- /* Assume change */
- Term->x1[y] = 0;
- Term->x2[y] = w - 1;
+ free(save);
}
- /* Assume change */
- Term->y1 = 0;
- Term->y2 = h - 1;
-
/* Success */
return (0);
}
@@ -2392,7 +1660,6 @@ errr Term_resize(int w, int h)
term_win *hold_old;
term_win *hold_scr;
term_win *hold_mem;
- term_win *hold_tmp;
/* Resizing is forbidden */
if (Term->fixed_shape) return ( -1);
@@ -2402,8 +1669,7 @@ errr Term_resize(int w, int h)
/* Ignore non-changes */
- if ((Term->wid == w) && (Term->hgt == h) && (arg_bigtile == use_bigtile)) return (1);
- use_bigtile = arg_bigtile;
+ if ((Term->wid == w) && (Term->hgt == h)) return (1);
/* Minimum dimensions */
wid = MIN(Term->wid, w);
@@ -2422,15 +1688,12 @@ errr Term_resize(int w, int h)
/* Save old window */
hold_mem = Term->mem;
- /* Save old window */
- hold_tmp = Term->tmp;
-
/* Create new scanners */
- C_MAKE(Term->x1, h, byte);
- C_MAKE(Term->x2, h, byte);
+ Term->x1 = safe_calloc(h, sizeof(byte));
+ Term->x2 = safe_calloc(h, sizeof(byte));
/* Create new window */
- MAKE(Term->old, term_win);
+ Term->old = safe_calloc(1, sizeof(struct term_win));
/* Initialize new window */
term_win_init(Term->old, w, h);
@@ -2439,7 +1702,7 @@ errr Term_resize(int w, int h)
term_win_copy(Term->old, hold_old, wid, hgt);
/* Create new window */
- MAKE(Term->scr, term_win);
+ Term->scr = safe_calloc(1, sizeof(struct term_win));
/* Initialize new window */
term_win_init(Term->scr, w, h);
@@ -2451,7 +1714,7 @@ errr Term_resize(int w, int h)
if (hold_mem)
{
/* Create new window */
- MAKE(Term->mem, term_win);
+ Term->mem = safe_calloc(1, sizeof(struct term_win));
/* Initialize new window */
term_win_init(Term->mem, w, h);
@@ -2460,28 +1723,18 @@ errr Term_resize(int w, int h)
term_win_copy(Term->mem, hold_mem, wid, hgt);
}
- /* If needed */
- if (hold_tmp)
- {
- /* Create new window */
- MAKE(Term->tmp, term_win);
-
- /* Initialize new window */
- term_win_init(Term->tmp, w, h);
-
- /* Save the contents */
- term_win_copy(Term->tmp, hold_tmp, wid, hgt);
- }
-
/* Free some arrays */
- C_KILL(hold_x1, Term->hgt, byte);
- C_KILL(hold_x2, Term->hgt, byte);
+ free(hold_x1);
+ hold_x1 = NULL;
+ free(hold_x2);
+ hold_x2 = NULL;
/* Nuke */
term_win_nuke(hold_old, Term->wid, Term->hgt);
/* Kill */
- KILL(hold_old, term_win);
+ free(hold_old);
+ hold_old = NULL;
/* Illegal cursor */
if (Term->old->cx >= w) Term->old->cu = 1;
@@ -2491,7 +1744,8 @@ errr Term_resize(int w, int h)
term_win_nuke(hold_scr, Term->wid, Term->hgt);
/* Kill */
- KILL(hold_scr, term_win);
+ free(hold_scr);
+ hold_scr = NULL;
/* Illegal cursor */
if (Term->scr->cx >= w) Term->scr->cu = 1;
@@ -2504,27 +1758,14 @@ errr Term_resize(int w, int h)
term_win_nuke(hold_mem, Term->wid, Term->hgt);
/* Kill */
- KILL(hold_mem, term_win);
+ free(hold_mem);
+ hold_mem = NULL;
/* Illegal cursor */
if (Term->mem->cx >= w) Term->mem->cu = 1;
if (Term->mem->cy >= h) Term->mem->cu = 1;
}
- /* If needed */
- if (hold_tmp)
- {
- /* Nuke */
- term_win_nuke(hold_tmp, Term->wid, Term->hgt);
-
- /* Kill */
- KILL(hold_tmp, term_win);
-
- /* Illegal cursor */
- if (Term->tmp->cx >= w) Term->tmp->cu = 1;
- if (Term->tmp->cy >= h) Term->tmp->cu = 1;
- }
-
/* Save new size */
Term->wid = w;
Term->hgt = h;
@@ -2624,13 +1865,15 @@ errr term_nuke(term *t)
term_win_nuke(t->old, w, h);
/* Kill "displayed" */
- KILL(t->old, term_win);
+ free(t->old);
+ t->old = NULL;
/* Nuke "requested" */
term_win_nuke(t->scr, w, h);
/* Kill "requested" */
- KILL(t->scr, term_win);
+ free(t->scr);
+ t->scr = NULL;
/* If needed */
if (t->mem)
@@ -2639,25 +1882,19 @@ errr term_nuke(term *t)
term_win_nuke(t->mem, w, h);
/* Kill "memorized" */
- KILL(t->mem, term_win);
- }
-
- /* If needed */
- if (t->tmp)
- {
- /* Nuke "temporary" */
- term_win_nuke(t->tmp, w, h);
-
- /* Kill "temporary" */
- KILL(t->tmp, term_win);
+ free(t->mem);
+ t->mem = NULL;
}
/* Free some arrays */
- C_KILL(t->x1, h, byte);
- C_KILL(t->x2, h, byte);
+ free(t->x1);
+ t->x1 = NULL;
+ free(t->x2);
+ t->x2 = NULL;
/* Free the input queue */
- C_KILL(t->key_queue, t->key_size, char);
+ free(t->key_queue);
+ t->key_queue = NULL;
/* Success */
return (0);
@@ -2675,7 +1912,7 @@ errr term_init(term *t, int w, int h, int k)
int y;
/* Wipe it */
- (void)WIPE(t, term);
+ memset(t, 0, sizeof(term));
/* Prepare the input queue */
@@ -2685,7 +1922,7 @@ errr term_init(term *t, int w, int h, int k)
t->key_size = k;
/* Allocate the input queue */
- C_MAKE(t->key_queue, t->key_size, char);
+ t->key_queue = safe_calloc(t->key_size, sizeof(char));
/* Save the size */
@@ -2693,19 +1930,19 @@ errr term_init(term *t, int w, int h, int k)
t->hgt = h;
/* Allocate change arrays */
- C_MAKE(t->x1, h, byte);
- C_MAKE(t->x2, h, byte);
+ t->x1 = safe_calloc(h, sizeof(byte));
+ t->x2 = safe_calloc(h, sizeof(byte));
/* Allocate "displayed" */
- MAKE(t->old, term_win);
+ t->old = safe_calloc(1, sizeof(struct term_win));
/* Initialize "displayed" */
term_win_init(t->old, w, h);
/* Allocate "requested" */
- MAKE(t->scr, term_win);
+ t->scr = safe_calloc(1, sizeof(struct term_win));
/* Initialize "requested" */
term_win_init(t->scr, w, h);
@@ -2735,42 +1972,3 @@ errr term_init(term *t, int w, int h, int k)
/* Success */
return (0);
}
-
-/*
- * Determine if we are called in the same second as the last time?
- * This *ASSUMES* that time_t is seconds past something. Is this portable?
- */
-int cmovie_get_msecond(void)
-{
-#ifndef USE_PRECISE_CMOVIE
- /* Not very precise, but portable */
- time_t thisc;
-
- thisc = time(NULL);
-
- cmov_delta_time_msec = 300;
-
- if (thisc == lastc)
- {
- return 1;
- }
- return 0;
-#else /* Very precise but needs main-foo.c to define TERM_XTRA_GET_DELAY */
-Term_xtra(TERM_XTRA_GET_DELAY, 0);
-
- cmov_delta_time_msec = Term_xtra_long - cmov_last_time_msec;
- cmov_last_time_msec = Term_xtra_long;
- return 0;
-#endif
-}
-
-void cmovie_init_second()
-{
-#ifndef USE_PRECISE_CMOVIE
- /* Not very precise, but portable */
- cmov_last_time_msec = 0;
-#else /* Precise but need main-foo.c to have TERM_XTRA_GET_DELAY */
- Term_xtra(TERM_XTRA_GET_DELAY, 0);
- cmov_last_time_msec = Term_xtra_long;
-#endif
-}
diff --git a/src/z-term.h b/src/z-term.h
index 31e5b308..a52a5c27 100644
--- a/src/z-term.h
+++ b/src/z-term.h
@@ -17,8 +17,6 @@ extern "C" {
#include "h-basic.h"
-#define IN_MAINWINDOW (Term == term_screen)
-
/*
* A term_win is a "window" for a Term
*
@@ -48,18 +46,6 @@ struct term_win
byte *va;
char *vc;
- byte **ta;
- char **tc;
-
- byte *vta;
- char *vtc;
-
- byte **ea;
- char **ec;
-
- byte *vea;
- char *vec;
-
};
@@ -67,19 +53,9 @@ struct term_win
/*
* 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"
* This "term" is "active"
*
@@ -98,23 +74,12 @@ struct term_win
* - Flag "soft_cursor"
* This "term" uses a "software" cursor
*
- * - Flag "always_pict"
- * Use the "Term_pict()" routine for all text
- *
- * - Flag "higher_pict"
- * Use the "Term_pict()" routine for special text
- *
* - 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
*
- * - Flag "never_frosh"
- * Never call the "TERM_XTRA_FROSH" action
*
*
* - Value "attr_blank"
@@ -151,8 +116,6 @@ struct term_win
* - Hook for init-ing the term
* - Hook for nuke-ing the term
*
- * - Hook for user actions
- *
* - Hook for extra actions
*
* - Hook for placing the cursor
@@ -168,35 +131,23 @@ typedef struct term term;
struct term
{
- vptr user;
-
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;
byte attr_blank;
char char_blank;
char *key_queue;
-
u16b key_head;
u16b key_tail;
- u16b key_xtra;
u16b key_size;
byte wid;
@@ -211,14 +162,11 @@ struct term
term_win *old;
term_win *scr;
- term_win *tmp;
term_win *mem;
void (*init_hook)(term *t);
void (*nuke_hook)(term *t);
- errr (*user_hook)(int n);
-
errr (*xtra_hook)(int n, int v);
errr (*curs_hook)(int x, int y);
@@ -229,14 +177,36 @@ struct term
void (*resize_hook)(void);
- errr (*pict_hook)(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp);
-
};
+/*** Color constants ***/
+/*
+ * Angband "attributes" (with symbols, and base (R,G,B) codes)
+ *
+ * The "(R,G,B)" codes are given in "fourths" of the "maximal" value,
+ * and should "gamma corrected" on most (non-Macintosh) machines.
+ */
+#define TERM_DARK 0 /* 'd' */ /* 0,0,0 */
+#define TERM_WHITE 1 /* 'w' */ /* 4,4,4 */
+#define TERM_SLATE 2 /* 's' */ /* 2,2,2 */
+#define TERM_ORANGE 3 /* 'o' */ /* 4,2,0 */
+#define TERM_RED 4 /* 'r' */ /* 3,0,0 */
+#define TERM_GREEN 5 /* 'g' */ /* 0,2,1 */
+#define TERM_BLUE 6 /* 'b' */ /* 0,0,4 */
+#define TERM_UMBER 7 /* 'u' */ /* 2,1,0 */
+#define TERM_L_DARK 8 /* 'D' */ /* 1,1,1 */
+#define TERM_L_WHITE 9 /* 'W' */ /* 3,3,3 */
+#define TERM_VIOLET 10 /* 'v' */ /* 4,0,4 */
+#define TERM_YELLOW 11 /* 'y' */ /* 4,4,0 */
+#define TERM_L_RED 12 /* 'R' */ /* 4,0,0 */
+#define TERM_L_GREEN 13 /* 'G' */ /* 0,4,0 */
+#define TERM_L_BLUE 14 /* 'B' */ /* 0,4,4 */
+#define TERM_L_UMBER 15 /* 'U' */ /* 3,2,1 */
+
/**** Available Constants ****/
@@ -251,11 +221,8 @@ struct term
*
* The "TERM_XTRA_EVENT" action uses "v" to "wait" for an event
* The "TERM_XTRA_SHAPE" action uses "v" to "show" the cursor
- * The "TERM_XTRA_FROSH" action uses "v" for the index of the row
- * The "TERM_XTRA_SOUND" action uses "v" for the index of a sound
* The "TERM_XTRA_ALIVE" action uses "v" to "activate" (or "close")
* The "TERM_XTRA_LEVEL" action uses "v" to "resume" (or "suspend")
- * The "TERM_XTRA_DELAY" action uses "v" as a "millisecond" value
*
* The other actions do not need a "v" code, so "zero" is used.
*/
@@ -263,39 +230,24 @@ struct term
#define TERM_XTRA_FLUSH 2 /* Flush all pending events */
#define TERM_XTRA_CLEAR 3 /* Clear the entire window */
#define TERM_XTRA_SHAPE 4 /* Set cursor shape (optional) */
-#define TERM_XTRA_FROSH 5 /* Flush one row (optional) */
#define TERM_XTRA_FRESH 6 /* Flush all rows (optional) */
#define TERM_XTRA_NOISE 7 /* Make a noise (optional) */
-#define TERM_XTRA_SOUND 8 /* Make a sound (optional) */
#define TERM_XTRA_BORED 9 /* Handle stuff when bored (optional) */
#define TERM_XTRA_REACT 10 /* React to global changes (optional) */
#define TERM_XTRA_ALIVE 11 /* Change the "hard" level (optional) */
#define TERM_XTRA_LEVEL 12 /* Change the "soft" level (optional) */
-#define TERM_XTRA_DELAY 13 /* Delay some milliseconds (optional) */
-#define TERM_XTRA_GET_DELAY 14 /* Get the cuyrrent time in milliseconds (optional) */
-#define TERM_XTRA_SCANSUBDIR 15 /* Scan for subdir in a dir */
#define TERM_XTRA_RENAME_MAIN_WIN 16 /* Rename the main game window */
/**** Available Variables ****/
extern term *Term;
-extern FILE *movfile;
-extern int do_movies;
-extern int last_paused;
-
/**** Available Functions ****/
-extern errr Term_user(int n);
extern errr Term_xtra(int n, int v);
-extern long Term_xtra_long;
-extern char scansubdir_dir[1024];
-extern int scansubdir_max;
-extern cptr scansubdir_result[255];
-extern void Term_queue_char(int x, int y, byte a, char c, byte ta, char tc, byte ea, char ec);
-extern void Term_queue_line(int x, int y, int n, byte *a, char *c, byte *ta, char *tc, byte *ea, char *ec);
+extern void Term_queue_char(int x, int y, byte a, char c);
extern void Term_queue_chars(int x, int y, int n, byte a, cptr s);
extern errr Term_fresh(void);
@@ -310,6 +262,7 @@ extern errr Term_erase(int x, int y, int n);
extern errr Term_clear(void);
extern errr Term_redraw(void);
extern errr Term_redraw_section(int x1, int y1, int x2, int y2);
+extern void Term_bell();
extern errr Term_get_cursor(int *v);
extern errr Term_get_size(int *w, int *h);
@@ -326,8 +279,6 @@ extern term_win* Term_save_to(void);
extern errr Term_load(void);
extern errr Term_load_from(term_win *save, bool_ final);
-extern errr Term_exchange(void);
-
extern errr Term_resize(int w, int h);
extern errr Term_activate(term *t);
diff --git a/src/z-util.c b/src/z-util.c
index 7c5374f3..0304a1da 100644
--- a/src/z-util.c
+++ b/src/z-util.c
@@ -4,122 +4,7 @@
#include "z-util.h"
-
-
-/*
- * Global variables for temporary use
- */
-char char_tmp = 0;
-byte byte_tmp = 0;
-sint sint_tmp = 0;
-uint uint_tmp = 0;
-long long_tmp = 0;
-huge huge_tmp = 0;
-errr errr_tmp = 0;
-
-
-/*
- * Global pointers for temporary use
- */
-cptr cptr_tmp = NULL;
-vptr vptr_tmp = NULL;
-
-
-
-
-/*
- * Constant bool meaning true
- */
-bool_ bool_true = 1;
-
-/*
- * Constant bool meaning false
- */
-bool_ bool_false = 0;
-
-
-/*
- * Global NULL cptr
- */
-cptr cptr_null = NULL;
-
-
-/*
- * Global NULL vptr
- */
-vptr vptr_null = NULL;
-
-
-
-/*
- * Global SELF vptr
- */
-vptr vptr_self = (vptr)(&vptr_self);
-
-
-
-/*
- * Convenient storage of the program name
- */
-cptr argv0 = NULL;
-
-
-
-/*
- * A routine that does nothing
- */
-void func_nothing(void)
-{
- /* Do nothing */
-}
-
-
-/*
- * A routine that always returns "success"
- */
-errr func_success(void)
-{
- return (0);
-}
-
-
-/*
- * A routine that always returns a simple "problem code"
- */
-errr func_problem(void)
-{
- return (1);
-}
-
-
-/*
- * A routine that always returns a simple "failure code"
- */
-errr func_failure(void)
-{
- return ( -1);
-}
-
-
-
-/*
- * A routine that always returns "true"
- */
-bool_ func_true(void)
-{
- return (1);
-}
-
-
-/*
- * A routine that always returns "false"
- */
-bool_ func_false(void)
-{
- return (0);
-}
-
-
+#include <assert.h>
/*
@@ -150,6 +35,27 @@ bool_ suffix(cptr s, cptr t)
}
+/**
+ * Captialize letter
+ */
+void capitalize(char *s)
+{
+ char *p = s;
+ assert(s != NULL);
+
+ for (; *p; p++)
+ {
+ if (!isspace(*p))
+ {
+ if (islower(*p))
+ {
+ *p = toupper(*p);
+ }
+ /* Done */
+ break;
+ }
+ }
+}
/*
@@ -167,7 +73,7 @@ void plog(cptr str)
if (plog_aux) (*plog_aux)(str);
/* Just do a labeled fprintf to stderr */
- else (void)(fprintf(stderr, "%s: %s\n", argv0 ? argv0 : "???", str));
+ else (void)(fprintf(stderr, "%s\n", str));
}
@@ -200,35 +106,3 @@ void quit(cptr str)
/* Failure */
(void)(exit( -1));
}
-
-
-
-/*
- * Redefinable "core" action
- */
-void (*core_aux)(cptr) = NULL;
-
-/*
- * Dump a core file, after printing a warning message
- * As with "quit()", try to use the "core_aux()" hook first.
- */
-void core(cptr str)
-{
- char *crash = NULL;
-
- /* Use the aux function */
- if (core_aux) (*core_aux)(str);
-
- /* Dump the warning string */
- if (str) plog(str);
-
- /* Attempt to Crash */
- (*crash) = (*crash);
-
- /* Be sure we exited */
- quit("core() failed");
-}
-
-
-
-
diff --git a/src/z-util.h b/src/z-util.h
index 11dbdb4e..914a64e7 100644
--- a/src/z-util.h
+++ b/src/z-util.h
@@ -1,7 +1,4 @@
-/* File z-util.h */
-
-#ifndef INCLUDED_Z_UTIL_H
-#define INCLUDED_Z_UTIL_H
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -11,61 +8,17 @@ extern "C" {
/*
- * Extremely basic stuff, like global temp and constant variables.
- * Also, some very useful low level functions, such as "streq()".
- * All variables and functions in this file are "addressable".
+ * Extremely basic stuff, like "streq()".
*/
-/**** Available variables ****/
-
-/* Temporary Vars */
-extern char char_tmp;
-extern byte byte_tmp;
-extern sint sint_tmp;
-extern uint uint_tmp;
-extern long long_tmp;
-extern huge huge_tmp;
-extern errr errr_tmp;
-
-/* Temporary Pointers */
-extern cptr cptr_tmp;
-extern vptr vptr_tmp;
-
-
-/* Constant pointers (NULL) */
-extern cptr cptr_null;
-extern vptr vptr_null;
-
-
-/* A bizarre vptr that always points at itself */
-extern vptr vptr_self;
-
-
-/* A cptr to the name of the program */
-extern cptr argv0;
-
-
/* Aux functions */
extern void (*plog_aux)(cptr);
extern void (*quit_aux)(cptr);
-extern void (*core_aux)(cptr);
/**** Available Functions ****/
-/* Function that does nothing */
-extern void func_nothing(void);
-
-/* Functions that return basic "errr" codes */
-extern errr func_success(void);
-extern errr func_problem(void);
-extern errr func_failure(void);
-
-/* Functions that return bools */
-extern bool_ func_true(void);
-extern bool_ func_false(void);
-
/* Test equality, prefix, suffix */
extern bool_ streq(cptr s, cptr t);
@@ -73,19 +26,16 @@ extern bool_ prefix(cptr s, cptr t);
extern bool_ suffix(cptr s, cptr t);
+/* Capitalize the first letter of string. Ignores whitespace at the start of string. */
+extern void capitalize(char *s);
+
/* Print an error message */
extern void plog(cptr str);
/* Exit, with optional message */
extern void quit(cptr str);
-/* Dump core, with optional message */
-extern void core(cptr str);
-
-
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif
diff --git a/src/z-virt.c b/src/z-virt.c
deleted file mode 100644
index 92632080..00000000
--- a/src/z-virt.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* File: z-virt.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.
- */
-
-/* Purpose: Memory management routines -BEN- */
-
-#include "z-virt.h"
-
-#include "z-util.h"
-
-
-/*
- * Optional auxiliary "rnfree" function
- */
-vptr (*rnfree_aux)(vptr, huge) = NULL;
-
-/*
- * Free some memory (allocated by ralloc), return NULL
- */
-vptr rnfree(vptr p, huge len)
-{
- /* Easy to free zero bytes */
- if (len == 0) return (NULL);
-
- /* Use the "aux" function */
- if (rnfree_aux) return ((*rnfree_aux)(p, len));
-
- /* Use "free" */
- free ((char*)(p));
-
- /* Done */
- return (NULL);
-}
-
-
-/*
- * Optional auxiliary "rpanic" function
- */
-vptr (*rpanic_aux)(huge) = NULL;
-
-/*
- * The system is out of memory, so panic. If "rpanic_aux" is set,
- * it can be used to free up some memory and do a new "ralloc()",
- * or if not, it can be used to save things, clean up, and exit.
- * By default, this function simply crashes the computer.
- */
-vptr rpanic(huge len)
-{
- /* Hopefully, we have a real "panic" function */
- if (rpanic_aux) return ((*rpanic_aux)(len));
-
- /* Attempt to crash before icky things happen */
- core("Out of Memory!");
-
- /* Paranoia */
- return ((vptr)(NULL));
-}
-
-
-/*
- * Optional auxiliary "ralloc" function
- */
-vptr (*ralloc_aux)(huge) = NULL;
-
-
-/*
- * Allocate some memory
- */
-vptr ralloc(huge len)
-{
- vptr mem;
-
- /* Allow allocation of "zero bytes" */
- if (len == 0) return ((vptr)(NULL));
-
- /* Use the aux function if set */
- if (ralloc_aux) mem = (*ralloc_aux)(len);
-
- /* Use malloc() to allocate some memory */
- else mem = ((vptr)(malloc((size_t)(len))));
-
- /* We were able to acquire memory */
- if (!mem) mem = rpanic(len);
-
- /* Return the memory, if any */
- return (mem);
-}
-
-
-
-
-/*
- * Allocate a constant string, containing the same thing as 'str'
- */
-cptr string_make(cptr str)
-{
- huge len = 0;
- cptr t = str;
- char *s, *res;
-
- /* Simple sillyness */
- if (!str) return (str);
-
- /* Get the number of chars in the string, including terminator */
- while (str[len++]) /* loop */;
-
- /* Allocate space for the string */
- s = res = (char*)(ralloc(len));
-
- /* Copy the string (with terminator) */
- while ((*s++ = *t++) != 0) /* loop */;
-
- /* Return the allocated, initialized, string */
- return (res);
-}
-
-
-/*
- * Un-allocate a string allocated above.
- * Depends on no changes being made to the string.
- */
-errr string_free(cptr str)
-{
- huge len = 0;
-
- /* Succeed on non-strings */
- if (!str) return (0);
-
- /* Count the number of chars in 'str' plus the terminator */
- while (str[len++]) /* loop */;
-
- /* Kill the buffer of chars we must have allocated above */
- rnfree((vptr)(str), len);
-
- /* Success */
- return (0);
-}
-
-
diff --git a/src/z-virt.h b/src/z-virt.h
deleted file mode 100644
index 58aed382..00000000
--- a/src/z-virt.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* File: z-virt.h */
-
-/*
- * 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.
- */
-
-#ifndef INCLUDED_Z_VIRT_H
-#define INCLUDED_Z_VIRT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "h-basic.h"
-
-/*
- * Memory management routines.
- *
- * Set ralloc_aux to modify the memory allocation routine.
- * Set rnfree_aux to modify the memory de-allocation routine.
- * Set rpanic_aux to let the program react to memory failures.
- *
- * These routines work best as a *replacement* for malloc/free.
- *
- * The string_make() and string_free() routines handle dynamic strings.
- * A dynamic string is a string allocated at run-time, which should not
- * be modified once it has been created.
- *
- * Note the macros below which simplify the details of allocation,
- * deallocation, setting, clearing, casting, size extraction, etc.
- *
- * The macros MAKE/C_MAKE and KILL/C_KILL have a "procedural" metaphor,
- * and they actually modify their arguments.
- *
- * Note that, for some reason, some allocation macros may disallow
- * "stars" in type names, but you can use typedefs to circumvent
- * this. For example, instead of "type **p; MAKE(p,type*);" you
- * can use "typedef type *type_ptr; type_ptr *p; MAKE(p,type_ptr)".
- *
- * Note that it is assumed that "memset()" will function correctly,
- * in particular, that it returns its first argument.
- */
-
-
-
-/**** Available macros ****/
-
-
-/* Size of 'N' things of type 'T' */
-#define C_SIZE(N,T) \
- ((huge)((N)*(sizeof(T))))
-
-/* Size of one thing of type 'T' */
-#define SIZE(T) \
- ((huge)(sizeof(T)))
-
-
-/* Wipe an array of type T[N], at location P, and return P */
-#define C_WIPE(P,N,T) \
- (memset((char*)(P),0,C_SIZE(N,T)))
-
-/* Wipe a thing of type T, at location P, and return P */
-#define WIPE(P,T) \
- (memset((char*)(P),0,SIZE(T)))
-
-
-/* Load an array of type T[N], at location P1, from another, at location P2 */
-#define C_COPY(P1,P2,N,T) \
- (memcpy((char*)(P1),(char*)(P2),C_SIZE(N,T)))
-
-/* Load a thing of type T, at location P1, from another, at location P2 */
-#define COPY(P1,P2,T) \
- (memcpy((char*)(P1),(char*)(P2),SIZE(T)))
-
-
-/* Free an array of N things of type T at P, return NULL */
-#define C_FREE(P,N,T) \
- (rnfree(P,C_SIZE(N,T)))
-
-/* Free one thing of type T at P, return NULL */
-#define FREE(P,T) \
- (rnfree(P,SIZE(T)))
-
-
-/* Allocate, and return, an array of type T[N] */
-#define C_RNEW(N,T) \
- (ralloc(C_SIZE(N,T)))
-
-/* Allocate, and return, a thing of type T */
-#define RNEW(T) \
- (ralloc(SIZE(T)))
-
-
-/* Allocate, wipe, and return an array of type T[N] */
-#define C_ZNEW(N,T) \
- (C_WIPE(C_RNEW(N,T),N,T))
-
-/* Allocate, wipe, and return a thing of type T */
-#define ZNEW(T) \
- (WIPE(RNEW(T),T))
-
-
-/* Allocate a wiped array of type T[N], assign to pointer P */
-#define C_MAKE(P,N,T) \
- ((P)=C_ZNEW(N,T))
-
-/* Allocate a wiped thing of type T, assign to pointer P */
-#define MAKE(P,T) \
- ((P)=ZNEW(T))
-
-
-/* Free an array of type T[N], at location P, and set P to NULL */
-#define C_KILL(P,N,T) \
- ((P)=C_FREE(P,N,T))
-
-/* Free a thing of type T, at location P, and set P to NULL */
-#define KILL(P,T) \
- ((P)=FREE(P,T))
-
-
-
-/**** Available variables ****/
-
-/* Replacement hook for "rnfree()" */
-extern vptr (*rnfree_aux)(vptr, huge);
-
-/* Replacement hook for "rpanic()" */
-extern vptr (*rpanic_aux)(huge);
-
-/* Replacement hook for "ralloc()" */
-extern vptr (*ralloc_aux)(huge);
-
-
-/**** Available functions ****/
-
-/* De-allocate a given amount of memory */
-extern vptr rnfree(vptr p, huge len);
-
-/* Panic, attempt to Allocate 'len' bytes */
-extern vptr rpanic(huge len);
-
-/* Allocate (and return) 'len', or dump core */
-extern vptr ralloc(huge len);
-
-/* Create a "dynamic string" */
-extern cptr string_make(cptr str);
-
-/* Free a string allocated with "string_make()" */
-extern errr string_free(cptr str);
-
-
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-
-
-#endif
diff --git a/tests/get_level_device.cc b/tests/get_level_device.cc
new file mode 100644
index 00000000..43dce624
--- /dev/null
+++ b/tests/get_level_device.cc
@@ -0,0 +1,184 @@
+#include "lua_bind.hpp"
+#include "spell_type.hpp"
+#include <bandit/bandit.h>
+using namespace bandit;
+
+//
+// Declarations for testing purposes:
+//
+
+s32b get_level_device(spell_type *spell, s32b max, s32b min, s32b device_skill, std::function<s32b(spell_type *, s32b, s32b, s32b, s32b)> lua_get_level_ = lua_get_level);
+
+//
+// Tests
+//
+
+go_bandit([]() {
+
+ describe("get_level_device", []() {
+
+ s32b passed_in_max;
+ s32b passed_in_min;
+
+ // Fake get_level function we can use to detect what's being passed to the real one.
+ auto fake_get_level = [&](struct spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus) -> s32b {
+ // Store the passed input values for verification purposes
+ passed_in_max = max;
+ passed_in_min = min;
+ // Return the input "lvl" unmodified.
+ return lvl;
+ };
+
+ before_each([&]() {
+ // Reset saved state
+ passed_in_max = -1;
+ passed_in_min = -1;
+ });
+
+ // Magic-Device skill levels that we've tested at.
+ const std::vector<s32b> device_skill_values {
+ 15300, // @15.3
+ 35300, // @35.3
+ 45300, // @45.3
+ 50000 // @50.0
+ };
+
+ // "Remove Curses" spell and expected result levels.
+ auto remove_curses_spell = spell_type_new("TEST: Remove Curses");
+ spell_type_set_difficulty(remove_curses_spell, 10, 42 /* notused */);
+
+ const std::map<s32b, s32b> remove_curses_expected_levels {
+ { 15300, 7 },
+ { 35300, 15 },
+ { 45300, 15 },
+ { 50000, 15 }
+ };
+
+ // "Wish" spell and expected result levels.
+ auto wish_spell = spell_type_new("TEST: Wish");
+ spell_type_set_difficulty(wish_spell, 50, 42 /* notused */);
+
+ const std::map<s32b, s32b> wish_expected_levels {
+ { 15300, 1 },
+ { 35300, 1 },
+ { 45300, 1 },
+ { 50000, 2 }
+ };
+
+ // "Heal Monster" spell and expected result levels.
+ auto heal_monster_spell = spell_type_new("TEST: Heal Monster");
+ spell_type_set_difficulty(heal_monster_spell, 3, 42 /* notused */);
+
+ const std::map<s32b, s32b> heal_monster_expected_levels {
+ { 15300, 108 },
+ { 35300, 152 },
+ { 45300, 152 },
+ { 50000, 152 }
+ };
+
+ // "Teleport Away" spell and expected result levels.
+ auto teleport_away_spell = spell_type_new("TEST: Teleport Away");
+ spell_type_set_difficulty(teleport_away_spell, 23, 42 /* notused */);
+
+ const std::map<s32b, s32b> teleport_away_expected_levels {
+ { 15300, 1 },
+ { 35300, 16 },
+ { 45300, 20 },
+ { 50000, 20 }
+ };
+
+ //
+ // Basic tests for "min <= 0" and "max <= 0".
+ //
+
+ it("should clamp 'min' parameter to 1", [&]() {
+ // Setup
+ s32b device_skill = 100; /* doesn't matter for this test */
+ get_level_max_stick = 1; /* doesn't matter for this test */
+ get_level_use_stick = 1; /* doesn't matter for this test */
+ auto spell = remove_curses_spell; /* doesn't matter for this test */
+ s32b max = 100; /* doesn't matter for this test */
+ s32b min = 0;
+ // Exercise
+ get_level_device(spell, max, min, device_skill, fake_get_level);
+ // Verify
+ AssertThat(passed_in_min, Equals(1));
+ });
+
+ it("should use 50 as default for 'max' parameter if zero or less", [&]() {
+ // Setup
+ s32b device_skill = 100; /* doesn't matter for this test */
+ get_level_max_stick = 1; /* doesn't matter for this test */
+ get_level_use_stick = 1; /* doesn't matter for this test */
+ auto spell = remove_curses_spell; /* doesn't matter for this test */
+ s32b max = 0;
+ s32b min = 25; /* doesn't matter for this test */
+ // Exercise
+ get_level_device(spell, max, min, device_skill, fake_get_level);
+ // Verify
+ AssertThat(passed_in_max, Equals(50));
+ });
+
+ //
+ // Table-driven tests derived from empirical testing
+ // using printf.
+ //
+
+ for (auto device_skill: device_skill_values)
+ {
+ it("calculates 'Remove Curses' staff level correctly for different magic device levels" , [&] {
+ // Setup: Device values for Remove Curses staff
+ get_level_use_stick = 1;
+ get_level_max_stick = 15;
+ // Setup: Max and min
+ s32b max = 50;
+ s32b min = 1;
+ // Exercise
+ s32b actualLevel = get_level_device(remove_curses_spell, max, min, device_skill);
+ // Verify: Check expected levels.
+ AssertThat(actualLevel, Equals(remove_curses_expected_levels.at(device_skill)));
+ });
+
+ it("calculates 'Wish' staff level correctly for different magic device levels", [&] {
+ // Setup: Device values for Wish staff
+ get_level_use_stick = 1;
+ get_level_max_stick = 1;
+ // Setup: Max and min
+ s32b max = 50;
+ s32b min = 1;
+ // Exercise
+ s32b actualLevel = get_level_device(wish_spell, max, min, device_skill);
+ // Verify: Check expected levels.
+ AssertThat(actualLevel, Equals(wish_expected_levels.at(device_skill)));
+ });
+
+ it("calculates 'Heal Monster' wand level correctly for different magic device levels", [&] {
+ // Setup: Device values for Heal Monster wand
+ get_level_use_stick = 1;
+ get_level_max_stick = 20;
+ // Setup: Max and min
+ s32b max = 380;
+ s32b min = 1;
+ // Exercise
+ s32b actualLevel = get_level_device(heal_monster_spell, max, min, device_skill);
+ // Verify: Check expected levels.
+ AssertThat(actualLevel, Equals(heal_monster_expected_levels.at(device_skill)));
+ });
+
+ it("calculates 'Teleport Away' wand level correctly for different magic device levels", [&] {
+ // Setup: Device values for Teleport Away wand
+ get_level_use_stick = 3;
+ get_level_max_stick = 20;
+ // Setup: Max and min
+ s32b max = 50;
+ s32b min = 1;
+ // Exercise
+ s32b actualLevel = get_level_device(teleport_away_spell, max, min, device_skill);
+ // Verify: Check expected levels.
+ AssertThat(actualLevel, Equals(teleport_away_expected_levels.at(device_skill)));
+ });
+ }
+
+ });
+
+});
diff --git a/tests/harness.cc b/tests/harness.cc
new file mode 100644
index 00000000..3a66ad55
--- /dev/null
+++ b/tests/harness.cc
@@ -0,0 +1,7 @@
+#include <bandit/bandit.h>
+using namespace bandit;
+
+int main(int argc, char** argv)
+{
+ return bandit::run(argc, argv);
+}
diff --git a/tests/lua_get_level.cc b/tests/lua_get_level.cc
new file mode 100644
index 00000000..a434903e
--- /dev/null
+++ b/tests/lua_get_level.cc
@@ -0,0 +1,135 @@
+#include "lua_bind.hpp"
+#include "spell_type.hpp"
+#include <bandit/bandit.h>
+using namespace bandit;
+
+go_bandit([]() {
+ describe("lua_get_level", []() {
+
+ auto createEntsPotion = ([]() {
+ auto my_spell = spell_type_new("TEST: Ent's Potion");
+ spell_type_set_difficulty(my_spell, 6, 35); // Copied from standard Ent's Potion spell.
+ return my_spell;
+ });
+
+ auto createSenseHidden = ([]() {
+ auto my_spell = spell_type_new("TEST: Sense Hidden");
+ spell_type_set_difficulty(my_spell, 5, 25); // Copied from standard Sense Hidden spell.
+ return my_spell;
+ });
+
+ //
+ // Test cases derived from empirical testing of the code before refactoring.
+ //
+
+ it("calculates \"Ent's Potion\" level appropriately for Sorcery@1.0", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 100, 50, -50, 0);
+ // Verify
+ AssertThat(actualResult, Equals(-4));
+ });
+
+ it("calculates \"Ent's Potion\" cost appropriately for Sorcery@1.0", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 100, 15, 7, 0);
+ // Verify
+ AssertThat(actualResult, Equals(7));
+ });
+
+ it("calculates \"Ent's Potion\" level appropriately for Sorcery@25.0", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 50, 1, 0);
+ // Verify
+ AssertThat(actualResult, Equals(20));
+ });
+
+ it("calculates \"Ent's Potion\" cost appropriately for Sorcery@25.0", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 15, 7, 0);
+ // Verify
+ AssertThat(actualResult, Equals(7));
+ });
+
+ it("calculates \"Ent's Potion\" level appropriately for Sorcery@25.0 with +3 equipment SP bonus", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 50, 1, 300);
+ // Verify
+ AssertThat(actualResult, Equals(23));
+ });
+
+ it("calculates \"Ent's Potion\" cost appropriately for Sorcery@25.0 with +3 equipment SP bonus", [&](){
+ // Setup
+ auto my_spell = createEntsPotion();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 15, 7, 300);
+ // Verify
+ AssertThat(actualResult, Equals(7));
+
+ });
+
+ it("calculates \"Sense Hidden\" level appropriately for Sorcery@1.0", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 100, 50, -50, 0);
+ // Verify
+ AssertThat(actualResult, Equals(-3));
+ });
+
+ it("calculates \"Sense Hidden\" cost appropriately for Sorcery@1.0", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 100, 10, 2, 0);
+ // Verify
+ AssertThat(actualResult, Equals(2));
+ });
+
+ it("calculates \"Sense Hidden\" level appropriately for Sorcery@25.0", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 50, 1, 0);
+ // Verify
+ AssertThat(actualResult, Equals(21));
+ });
+
+ it("calculates \"Sense Hidden\" cost appropriately for Sorcery@25.0", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 10, 2, 0);
+ // Verify
+ AssertThat(actualResult, Equals(4));
+ });
+
+ it("calculates \"Sense Hidden\" level appropriately for Sorcery@25.0 with +3 equipment SP bonus", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 50, 1, 300);
+ // Verify
+ AssertThat(actualResult, Equals(24));
+ });
+
+ it("calculates \"Sense Hidden\" cost appropriately for Sorcery@25.0 with +3 equipment SP bonus", [&](){
+ // Setup
+ auto my_spell = createSenseHidden();
+ // Exercise
+ auto actualResult = lua_get_level(my_spell, 2500, 10, 2, 300);
+ // Verify
+ AssertThat(actualResult, Equals(4));
+ });
+
+ });
+});
diff --git a/vendor/bandit/.travis.yml b/vendor/bandit/.travis.yml
new file mode 100644
index 00000000..f6f5b222
--- /dev/null
+++ b/vendor/bandit/.travis.yml
@@ -0,0 +1,17 @@
+language: cpp
+sudo: true
+compiler:
+ - gcc
+ - clang
+before_install:
+ - sudo add-apt-repository ppa:kubuntu-ppa/backports -y
+ - sudo apt-get update -qq
+ - sudo apt-get install -qq cmake=2.8.12.2-0ubuntu1~ubuntu12.04.1~ppa2
+before_script:
+ - BUILD_DIR=`pwd`/builds
+ - mkdir -p ${BUILD_DIR}
+ - cd ${BUILD_DIR}
+ - cmake ..
+script:
+ - cd ${BUILD_DIR}
+ - make
diff --git a/vendor/bandit/.vimrc b/vendor/bandit/.vimrc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/vendor/bandit/.vimrc
diff --git a/vendor/bandit/CMakeLists.txt b/vendor/bandit/CMakeLists.txt
new file mode 100644
index 00000000..a777e73b
--- /dev/null
+++ b/vendor/bandit/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required(VERSION 2.8)
+project(bandit)
+
+option(BANDIT_BUILD_SPECS "Build the Bandit specs" ON)
+option(BANDIT_RUN_SPECS "Run the Bandit specs" ON)
+option(SNOWHOUSE_IS_CPP11 "Build Snowhouse with C++11 settings" ON)
+
+set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+include(cotire/CMake/cotire)
+
+include_directories("${PROJECT_SOURCE_DIR}")
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ./bin)
+
+if (MSVC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /MP ")
+else()
+ # Assume GCC-style arguments
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdeprecated -Wdeprecated-declarations -Wshadow -Wall -W -Werror -Wfloat-equal -Wundef -Wendif-labels")
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+endif()
+
+#
+# If we're on Mac OS we assume we have libc++, otherwise we assume
+# we don't need it. (TODO: make this check more sofisticated)
+#
+if (CMAKE_HOST_APPLE AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+endif()
+
+if (BANDIT_BUILD_SPECS)
+ FILE(GLOB BanditSpecSourceFiles specs/*.cpp specs/**/*.cpp)
+ add_executable(bandit-specs ${BanditSpecSourceFiles} )
+ set_target_properties(bandit-specs PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "specs/specs.h")
+ set_target_properties(bandit-specs PROPERTIES COTIRE_ADD_UNIT_BUILD FALSE)
+ cotire(bandit-specs)
+endif()
+
+add_subdirectory(bandit/assertion_frameworks/snowhouse)
+
+if (BANDIT_BUILD_SPECS AND BANDIT_RUN_SPECS)
+ add_custom_command(TARGET bandit-specs
+ POST_BUILD
+ COMMAND bandit-specs --no-color --reporter=dots
+ WORKING_DIRECTORY ./bin)
+elseif (BANDIT_RUN_SPECS)
+ message(WARNING "Unable to run Bandit specs - set:\n option(BANDIT_BUILD_SPECS, \"Build the Bandit specs\" ON)\nand clear your CMake cache")
+endif()
+
diff --git a/vendor/bandit/LICENSE.md b/vendor/bandit/LICENSE.md
new file mode 100644
index 00000000..9d61348c
--- /dev/null
+++ b/vendor/bandit/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Joakim Karlsson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/bandit/README.md b/vendor/bandit/README.md
new file mode 100644
index 00000000..0c95d420
--- /dev/null
+++ b/vendor/bandit/README.md
@@ -0,0 +1,63 @@
+bandit
+======
+[![Build Status](https://travis-ci.org/joakimkarlsson/bandit.png)](https://travis-ci.org/joakimkarlsson/bandit)
+
+Human friendly unit testing for C++11
+
+Bandit is a framework for C++11 that wants to make working with unit tests a pleasant
+experience.
+
+For more information, go to [the bandit website](http://banditcpp.org).
+
+Bandit is released under the [MIT license](LICENSE.md)
+
+#An example
+
+This is a complete test application written in bandit:
+
+```cpp
+#include <bandit/bandit.h>
+using namespace bandit;
+
+// Tell bandit there are tests here.
+go_bandit([](){
+
+ // We're describing how a fuzzbox works.
+ describe("fuzzbox:", [](){
+ guitar_ptr guitar;
+ fuzzbox_ptr fuzzbox;
+
+ // Make sure each test has a fresh setup with
+ // a guitar with a fuzzbox connected to it.
+ before_each([&](){
+ guitar = guitar_ptr(new struct guitar());
+ fuzzbox = fuzzbox_ptr(new struct fuzzbox());
+ guitar->add_effect(*fuzzbox);
+ });
+
+ it("starts in clean mode", [&](){
+ AssertThat(guitar->sound(), Equals(sounds::clean));
+ });
+
+ // Describe what happens when we turn on the fuzzbox.
+ describe("in distorted mode", [&](){
+
+ // Turn on the fuzzbox.
+ before_each([&](){
+ fuzzbox->flip();
+ });
+
+ it("sounds distorted", [&](){
+ AssertThat(guitar->sound(), Equals(sounds::distorted));
+ });
+ });
+ });
+
+});
+
+int main(int argc, char* argv[])
+{
+ // Run the tests.
+ return bandit::run(argc, argv);
+}
+```
diff --git a/vendor/bandit/bandit/adapters/adapter.h b/vendor/bandit/bandit/adapters/adapter.h
new file mode 100644
index 00000000..809212a1
--- /dev/null
+++ b/vendor/bandit/bandit/adapters/adapter.h
@@ -0,0 +1,12 @@
+#ifndef BANDIT_ADAPTER_H
+#define BANDIT_ADAPTER_H
+
+namespace bandit { namespace adapters {
+
+ struct assertion_adapter
+ {
+ virtual void adapt_exceptions(detail::voidfunc_t) = 0;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/adapters/adapters.h b/vendor/bandit/bandit/adapters/adapters.h
new file mode 100644
index 00000000..fbfddaea
--- /dev/null
+++ b/vendor/bandit/bandit/adapters/adapters.h
@@ -0,0 +1,16 @@
+#ifndef BANDIT_ADAPTERS_H
+#define BANDIT_ADAPTERS_H
+
+#include <bandit/adapters/adapter.h>
+#include <bandit/adapters/snowhouse.h>
+
+namespace bandit { namespace detail {
+
+ inline bandit::adapters::assertion_adapter& registered_adapter()
+ {
+ static bandit::adapters::snowhouse_adapter adapter;
+ return adapter;
+ }
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/adapters/snowhouse.h b/vendor/bandit/bandit/adapters/snowhouse.h
new file mode 100644
index 00000000..f0776662
--- /dev/null
+++ b/vendor/bandit/bandit/adapters/snowhouse.h
@@ -0,0 +1,22 @@
+#ifndef BANDIT_ADAPTERS_SNOWHOUSE_H
+#define BANDIT_ADAPTERS_SNOWHOUSE_H
+
+namespace bandit { namespace adapters {
+
+ struct snowhouse_adapter : public assertion_adapter
+ {
+ void adapt_exceptions(detail::voidfunc_t func)
+ {
+ try
+ {
+ func();
+ }
+ catch(const snowhouse::AssertionException& ex)
+ {
+ throw bandit::detail::assertion_exception(ex.GetMessage(), ex.GetFilename(), ex.GetLineNumber());
+ }
+ }
+ };
+
+}}
+#endif
diff --git a/vendor/bandit/bandit/assertion_exception.h b/vendor/bandit/bandit/assertion_exception.h
new file mode 100644
index 00000000..9abc9867
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_exception.h
@@ -0,0 +1,41 @@
+#ifndef BANDIT_ASSERTION_EXCEPTION_H
+#define BANDIT_ASSERTION_EXCEPTION_H
+
+namespace bandit { namespace detail {
+
+ struct assertion_exception : public std::runtime_error
+ {
+ assertion_exception(const std::string& message,
+ const std::string& filename, const unsigned int linenumber)
+ : std::runtime_error(message), file_name_(filename), line_number_(linenumber)
+ {}
+
+ assertion_exception(const std::string& message)
+ : std::runtime_error(message), line_number_(0)
+ {}
+
+ //
+ // To make gcc < 4.7 happy.
+ //
+ assertion_exception(const assertion_exception&) = default;
+ assertion_exception(assertion_exception&&) = default;
+ virtual ~assertion_exception() noexcept
+ {}
+
+ const std::string& file_name() const
+ {
+ return file_name_;
+ }
+
+ unsigned int line_number() const
+ {
+ return line_number_;
+ }
+
+ private:
+ std::string file_name_;
+ unsigned int line_number_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeCloseTo.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeCloseTo.h
new file mode 100644
index 00000000..e4507c4c
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeCloseTo.h
@@ -0,0 +1,55 @@
+#ifndef BANDIT_BECLOSETO_H
+#define BANDIT_BECLOSETO_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class BeCloseTo : public Matcher
+ {
+ public:
+ explicit BeCloseTo(const T& expectedValue): Matcher(), _expectedValue(expectedValue), _threshold(0.01) {}
+
+ BeCloseTo<T>& within(float threshold)
+ {
+ _threshold = threshold;
+ return *this;
+ }
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return this->subtractable_types_match(actualValue, _expectedValue);
+ }
+
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "be close to <" << _expectedValue << ">" << " (within " << _threshold << ")";
+ return ss.str();
+ }
+
+ private:
+ template<typename U, typename V>
+ bool subtractable_types_match(const U& actualValue, const V& expectedValue) const
+ {
+ return (actualValue > (expectedValue - _threshold)) && (actualValue < (expectedValue + _threshold));
+ }
+
+
+ private:
+ const T& _expectedValue;
+ float _threshold;
+ };
+
+ template<typename T>
+ BeCloseTo<T> be_close_to(const T& expectedValue)
+ {
+ return BeCloseTo<T>(expectedValue);
+ }
+}}
+
+#endif // BANDIT_BECLOSETO_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeEmpty.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeEmpty.h
new file mode 100644
index 00000000..a83ef994
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeEmpty.h
@@ -0,0 +1,32 @@
+#ifndef BANDIT_BEEMPTY_H
+#define BANDIT_BEEMPTY_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ class BeEmpty : public Matcher
+ {
+ private:
+ // BeEmpty & operator=(const BeEmpty &);
+
+ public:
+ explicit BeEmpty() : Matcher() {}
+
+ template<typename U>
+ bool matches(const U& container) const
+ {
+ return container.empty();
+ }
+
+ protected:
+ std::string failure_message_end() const
+ {
+ return std::string("be empty");
+ }
+ };
+
+ static const BeEmpty be_empty = BeEmpty();
+}}
+
+#endif // BANDIT_BEEMPTY_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeFalsy.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeFalsy.h
new file mode 100644
index 00000000..718c6366
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeFalsy.h
@@ -0,0 +1,39 @@
+#ifndef BANDIT_BEFALSY_H
+#define BANDIT_BEFALSY_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ class BeFalsy : public Matcher
+ {
+ private:
+ // BeFalsy& operator=(const BeFalsy&);
+
+ public:
+ explicit BeFalsy() : Matcher() {}
+ // ~BeFalsy() {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return !actualValue;
+ }
+
+ bool matches(const std::nullptr_t&) const
+ {
+ return true;
+ }
+
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ return std::string("evaluate to false");
+ }
+ };
+
+ static const BeFalsy be_falsy = BeFalsy();
+}}
+
+#endif // BANDIT_BEFALSY_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeGTE.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeGTE.h
new file mode 100644
index 00000000..072b2caf
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeGTE.h
@@ -0,0 +1,45 @@
+#ifndef BANDIT_BEGREATERTHANOREQUAL_H
+#define BANDIT_BEGREATERTHANOREQUAL_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class BeGTE : public Matcher
+ {
+ public:
+ explicit BeGTE(const T& expectedValue) : Matcher(), _expectedValue(expectedValue) {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return actualValue >= _expectedValue;
+ }
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "be greater than or equal to <" << _expectedValue << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _expectedValue;
+ };
+
+ template<typename T>
+ BeGTE<T> be_gte(const T& expectedValue)
+ {
+ return BeGTE<T>(expectedValue);
+ }
+
+ template<typename T>
+ BeGTE<T> be_greater_than_or_equal_to(const T& expectedValue)
+ {
+ return be_gte(expectedValue);
+ }
+}}
+
+#endif // BANDIT_BEGREATERTHANOREQUAL_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeGreaterThan.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeGreaterThan.h
new file mode 100644
index 00000000..95d93d1e
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeGreaterThan.h
@@ -0,0 +1,39 @@
+#ifndef BANDIT_BEGREATERTHAN_H
+#define BANDIT_BEGREATERTHAN_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class BeGreaterThan : public Matcher
+ {
+ public:
+ explicit BeGreaterThan(const T& expectedValue) : Matcher(), _expectedValue(expectedValue) {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return actualValue > _expectedValue;
+ }
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "be greater than <" << _expectedValue << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _expectedValue;
+ };
+
+ template<typename T>
+ BeGreaterThan<T> be_greater_than(const T& expectedValue)
+ {
+ return BeGreaterThan<T>(expectedValue);
+ }
+}}
+
+#endif // BANDIT_BEGREATERTHAN_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeLTE.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeLTE.h
new file mode 100644
index 00000000..83463f75
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeLTE.h
@@ -0,0 +1,45 @@
+#ifndef BANDIT_BELESSTHANOREQUAL_H
+#define BANDIT_BELESSTHANOREQUAL_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class BeLTE : public Matcher
+ {
+ public:
+ explicit BeLTE(const T& expectedValue) : Matcher(), _expectedValue(expectedValue) {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return actualValue <= _expectedValue;
+ }
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "be less than or equal to <" << _expectedValue << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _expectedValue;
+ };
+
+ template<typename T>
+ BeLTE<T> be_lte(const T& expectedValue)
+ {
+ return BeLTE<T>(expectedValue);
+ }
+
+ template<typename T>
+ BeLTE<T> be_less_than_or_equal_to(const T& expectedValue)
+ {
+ return be_lte(expectedValue);
+ }
+}}
+
+#endif // BANDIT_BELESSTHANOREQUAL_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeLessThan.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeLessThan.h
new file mode 100644
index 00000000..87a2dc5e
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeLessThan.h
@@ -0,0 +1,39 @@
+#ifndef BANDIT_BELESSTHAN_H
+#define BANDIT_BELESSTHAN_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class BeLessThan : public Matcher
+ {
+ public:
+ explicit BeLessThan(const T& expectedValue) : Matcher(), _expectedValue(expectedValue) {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return actualValue < _expectedValue;
+ }
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "be less than <" << _expectedValue << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _expectedValue;
+ };
+
+ template<typename T>
+ BeLessThan<T> be_less_than(const T& expectedValue)
+ {
+ return BeLessThan<T>(expectedValue);
+ }
+}}
+
+#endif // BANDIT_BELESSTHAN_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeNull.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeNull.h
new file mode 100644
index 00000000..6e034d10
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeNull.h
@@ -0,0 +1,29 @@
+#ifndef BANDIT_BENULL_H
+#define BANDIT_BENULL_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ class BeNull : public Matcher
+ {
+ public:
+ BeNull() : Matcher() {}
+
+ template<typename U>
+ bool matches(U *const & actualValue) const
+ {
+ return !actualValue;
+ }
+
+ protected:
+ std::string failure_message_end() const
+ {
+ return std::string("be nil");
+ }
+ };
+
+ static const BeNull be_null = BeNull();
+}}
+
+#endif // BANDIT_BENULL_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/BeTruthy.h b/vendor/bandit/bandit/assertion_frameworks/matchers/BeTruthy.h
new file mode 100644
index 00000000..c8652538
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/BeTruthy.h
@@ -0,0 +1,35 @@
+#ifndef BANDIT_BETRUTHY_H
+#define BANDIT_BETRUTHY_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ class BeTruthy : public Matcher
+ {
+ public:
+ BeTruthy() : Matcher() {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return !!actualValue;
+ }
+
+ bool matches(const std::nullptr_t&) const
+ {
+ return false;
+ }
+
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ return std::string("evaluate to true");
+ }
+ };
+
+ static const BeTruthy be_truthy = BeTruthy();
+}}
+
+#endif // BANDIT_BETRUTHY_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/Contain.h b/vendor/bandit/bandit/assertion_frameworks/matchers/Contain.h
new file mode 100644
index 00000000..f048e3a3
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/Contain.h
@@ -0,0 +1,58 @@
+#ifndef BANDIT_CONTAIN_H
+#define BANDIT_CONTAIN_H
+
+#include <cstring>
+#include <vector>
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class Contain : public Matcher
+ {
+ public:
+ explicit Contain(const T& element) : Matcher(), _element(element) {}
+
+ template<typename U>
+ bool matches(const U& container) const
+ {
+ return container.find(_element) != container.end();
+ }
+
+ template<typename U>
+ bool matches(const std::vector<U>& container) const
+ {
+ return std::find(container.begin(), container.end(), _element) != container.end();
+ }
+
+ bool matches(const char *const container) const
+ {
+ return (_element != NULL) && (container != NULL) && (strstr(container, _element) != NULL);
+ }
+
+ bool matches(char *const container) const
+ {
+ return (_element != NULL) && (container != NULL) && (strstr(container, _element) != NULL);
+ }
+
+ protected:
+ std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "contain <" << _element << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _element;
+ };
+
+ template<typename T>
+ Contain<T> contain(const T& element)
+ {
+ return Contain<T>(element);
+ }
+}}
+
+#endif // BANDIT_CONTAIN_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/Equal.h b/vendor/bandit/bandit/assertion_frameworks/matchers/Equal.h
new file mode 100644
index 00000000..521c6008
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/Equal.h
@@ -0,0 +1,90 @@
+#ifndef BANDIT_EQUAL_H
+#define BANDIT_EQUAL_H
+
+#include <cstring>
+#include <memory>
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& obj)
+ {
+ return os << *obj;
+ }
+
+ template<typename T>
+ class Equal : public Matcher
+ {
+ public:
+ explicit Equal(const T& expectedValue) : Matcher(), _expectedValue(expectedValue) {}
+
+ template<typename U>
+ bool matches(const U& actualValue) const
+ {
+ return actualValue == _expectedValue;
+ }
+
+ bool matches(char* actualValue) const
+ {
+ return strcmp(actualValue, &*_expectedValue) == 0;
+ }
+
+ bool matches(const char* actualValue) const
+ {
+ return strcmp(actualValue, &*_expectedValue) == 0;
+ }
+
+ template<typename U>
+ bool matches(const std::unique_ptr<U>& pointer) const
+ {
+ return matches(pointer.get());
+ }
+
+ protected:
+ virtual std::string failure_message_end() const
+ {
+ std::ostringstream ss;
+ ss << "equal <" << _expectedValue << ">";
+ return ss.str();
+ }
+
+ private:
+ const T& _expectedValue;
+ };
+
+ template<typename T>
+ Equal<T> equal(const T& expectedValue)
+ {
+ return Equal<T>(expectedValue);
+ }
+
+ template<typename T, typename U>
+ bool operator==(const ValueProxy<T>& actualValue, const U& expectedValue)
+ {
+ return actualValue.to == expectedValue;
+ }
+
+ template<typename T, typename U>
+ bool operator==(const MatchProxy<T>& matchProxy, const U& expectedValue)
+ {
+ matchProxy(equal(expectedValue));
+ return true;
+ }
+
+ template<typename T, typename U>
+ bool operator!=(const ValueProxy<T>& actualValue, const U& expectedValue)
+ {
+ return actualValue.to != expectedValue;
+ }
+
+ template<typename T, typename U>
+ bool operator!=(const MatchProxy<T>& matchProxy, const U& expectedValue)
+ {
+ matchProxy.negate()(equal(expectedValue));
+ return true;
+ }
+}}
+
+#endif // BANDIT_EQUAL_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/MatchProxy.h b/vendor/bandit/bandit/assertion_frameworks/matchers/MatchProxy.h
new file mode 100644
index 00000000..b637ef0d
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/MatchProxy.h
@@ -0,0 +1,43 @@
+#ifndef BANDIT_MATCHPROXY_H
+#define BANDIT_MATCHPROXY_H
+
+#include "MatcherException.h"
+
+namespace bandit { namespace Matchers
+{
+ template<typename T> class ValueProxy;
+
+ template<typename T>
+ class MatchProxy
+ {
+ private:
+ template<typename U>
+ MatchProxy(const MatchProxy<U>&);
+
+ template<typename U>
+ MatchProxy& operator=(const MatchProxy<U>&);
+
+ public:
+ explicit MatchProxy(const ValueProxy<T>& value, bool negate_ = false) : _value(value), _negate(negate_) {}
+
+ template<typename MatcherType>
+ void operator()(const MatcherType& matcher) const
+ {
+ if( matcher.matches(_value._value) == _negate )
+ {
+ throw MatcherException(_value._filename, _value._lineNumber, matcher.failure_message(_value._value, _negate));
+ }
+ }
+
+ MatchProxy<T> negate() const
+ {
+ return MatchProxy<T>(_value, !_negate);
+ }
+
+ private:
+ const ValueProxy<T>& _value;
+ bool _negate;
+ };
+}}
+
+#endif // BANDIT_MATCHPROXY_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/Matcher.h b/vendor/bandit/bandit/assertion_frameworks/matchers/Matcher.h
new file mode 100644
index 00000000..ad48c0a5
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/Matcher.h
@@ -0,0 +1,74 @@
+#ifndef BANDIT_MATCHER_H
+#define BANDIT_MATCHER_H
+
+#include <sstream>
+
+//#import "CedarStringifiers.h"
+
+namespace bandit { namespace Matchers {
+ class Matcher
+ {
+ public:
+ Matcher() {}
+
+ template<typename U>
+ std::string failure_message(const U& value, bool negate) const
+ {
+ std::ostringstream ss;
+ ss << "Expected <" << value << "> " << (negate ? "to not " : "to ") << failure_message_end();
+ return ss.str();
+ }
+
+ std::string failure_message(char *const value, bool negate) const
+ {
+ return failure_message((value ? value : "NULL"), negate);
+ }
+
+ template<typename U>
+ std::string failure_message(const std::unique_ptr<U>& value, bool negate) const
+ {
+ return failure_message(value.get(), negate);
+ }
+
+ std::string failure_message(const std::nullptr_t pointer, bool negate) const
+ {
+ (void)pointer;
+ return failure_message("nullptr", negate);
+ }
+
+ template<typename U>
+ std::string failure_message(std::function<U>& value, bool negate) const
+ {
+ return failure_message(typeid(value).name(), negate);
+ }
+
+ template<typename U>
+ std::string failure_message(const std::function<U>& value, bool negate) const
+ {
+ return failure_message(typeid(value).name(), negate);
+ }
+
+ template<typename U, template <class T, class = std::allocator<T> > class container >
+ std::string failure_message(const container<U>& value, bool negate) const
+ {
+ return failure_message(typeid(value).name(), negate);
+ }
+
+ template<typename U, template <class T, class = std::less<T>, class = std::allocator<T> > class container >
+ std::string failure_message(const container<U>& value, bool negate) const
+ {
+ return failure_message(typeid(value).name(), negate);
+ }
+
+ template<typename U, typename V, template <class K, class T, class = std::less<K>, class = std::allocator<std::pair<const K,T>> > class container >
+ std::string failure_message(const container<U,V>& value, bool negate) const
+ {
+ return failure_message(typeid(value).name(), negate);
+ }
+
+ protected:
+ virtual std::string failure_message_end() const = 0;
+ };
+}}
+
+#endif // BANDIT_MATCHER_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/MatcherException.h b/vendor/bandit/bandit/assertion_frameworks/matchers/MatcherException.h
new file mode 100644
index 00000000..5d657ed7
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/MatcherException.h
@@ -0,0 +1,16 @@
+#ifndef BANDIT_MATCHER_EXCEPTION_H
+#define BANDIT_MATCHER_EXCEPTION_H
+
+#include <bandit/assertion_exception.h>
+
+namespace bandit { namespace Matchers {
+ class MatcherException : public detail::assertion_exception
+ {
+ public:
+ MatcherException(const std::string& filename, const unsigned linenumber, const std::string& message) : detail::assertion_exception(message, filename, linenumber) {}
+ MatcherException(const MatcherException&) = default;
+ virtual ~MatcherException() noexcept {}
+ };
+}}
+
+#endif // BANDIT_MATCHER_EXCEPTION_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/ThrowException.h b/vendor/bandit/bandit/assertion_frameworks/matchers/ThrowException.h
new file mode 100644
index 00000000..cd8bfc34
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/ThrowException.h
@@ -0,0 +1,60 @@
+#ifndef BANDIT_THROWEXCEPTION_H
+#define BANDIT_THROWEXCEPTION_H
+
+#include "Matcher.h"
+
+namespace bandit { namespace Matchers {
+
+ template <typename T>
+ class ThrowException : public Matcher
+ {
+ public:
+ ThrowException() : Matcher(), _allow_subclasses(false) {}
+ explicit ThrowException(bool allow_subclasses) : Matcher(), _allow_subclasses(allow_subclasses) {}
+
+ template <typename U = std::exception>
+ ThrowException<U> operator()() const
+ {
+ return ThrowException<U>();
+ }
+
+ ThrowException& or_subclass()
+ {
+ _allow_subclasses = true;
+ return *this;
+ }
+
+ template <typename U>
+ bool matches(const U& block) const
+ {
+ try
+ {
+ block();
+ }
+ catch(const T& e)
+ {
+ return true;
+ }
+ catch(...) // Wrong exception
+ {
+ _exception = std::current_exception();
+ }
+
+ return false;
+ }
+
+ protected:
+ std::string failure_message_end() const
+ {
+ return std::string("throw an exception");
+ }
+
+ private:
+ bool _allow_subclasses;
+ mutable std::exception_ptr _exception;
+ };
+
+ static const ThrowException<std::exception> throw_exception;
+}}
+
+#endif // BANDIT_THROWEXCEPTION_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/ValueProxy.h b/vendor/bandit/bandit/assertion_frameworks/matchers/ValueProxy.h
new file mode 100644
index 00000000..0cd5d35c
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/ValueProxy.h
@@ -0,0 +1,26 @@
+#ifndef BANDIT_VALUEPROXY_H
+#define BANDIT_VALUEPROXY_H
+
+#include "MatchProxy.h"
+
+namespace bandit { namespace Matchers {
+
+ template<typename T>
+ class ValueProxy
+ {
+ public:
+ MatchProxy<T> to;
+ MatchProxy<T> to_not;
+
+ explicit ValueProxy(const char* filename, int lineNumber, const T& value) : to(*this), to_not(*this, true), _value(value), _filename(filename), _lineNumber(lineNumber) {}
+
+ private:
+ friend class MatchProxy<T>;
+
+ const T& _value;
+ std::string _filename;
+ int _lineNumber;
+ };
+}}
+
+#endif // BANDIT_VALUEPROXY_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/matchers.h b/vendor/bandit/bandit/assertion_frameworks/matchers/matchers.h
new file mode 100644
index 00000000..033cefcd
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/matchers.h
@@ -0,0 +1,19 @@
+#ifndef BANDIT_MATCHERS_H
+#define BANDIT_MATCHERS_H
+
+#include "must.h"
+
+#include "BeCloseTo.h"
+#include "BeEmpty.h"
+#include "BeFalsy.h"
+#include "BeGreaterThan.h"
+#include "BeGTE.h"
+#include "BeLessThan.h"
+#include "BeLTE.h"
+#include "BeNull.h"
+#include "BeTruthy.h"
+#include "Contain.h"
+#include "Equal.h"
+#include "ThrowException.h"
+
+#endif // BANDIT_MATCHERS_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/matchers/must.h b/vendor/bandit/bandit/assertion_frameworks/matchers/must.h
new file mode 100644
index 00000000..54eedb7f
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/matchers/must.h
@@ -0,0 +1,36 @@
+#ifndef BANDIT_MUST_H
+#define BANDIT_MUST_H
+
+#include "ValueProxy.h"
+
+namespace bandit { namespace Matchers
+{
+ struct ValueMarker
+ {
+ const char* filename;
+ int lineNumber;
+ };
+
+ template<typename T>
+ const ValueProxy<T> operator,(const T& value, const ValueMarker& marker)
+ {
+ return ValueProxy<T>(marker.filename, marker.lineNumber, value);
+ }
+
+ template<typename T>
+ const MatchProxy<T> operator,(const ValueProxy<T>& value, bool negate)
+ {
+ return negate ? value.to_not : value.to;
+ }
+
+ template<typename T, typename MatcherType>
+ void operator,(const MatchProxy<T>& matchProxy, const MatcherType& matcher)
+ {
+ matchProxy(matcher);
+ }
+}}
+
+#define must ,(bandit::Matchers::ValueMarker){__FILE__, __LINE__},false,
+#define must_not ,(bandit::Matchers::ValueMarker){__FILE__, __LINE__},true,
+
+#endif //BANDIT_MUST_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/CMakeLists.txt b/vendor/bandit/bandit/assertion_frameworks/snowhouse/CMakeLists.txt
new file mode 100644
index 00000000..ea43226b
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(snowhouse)
+
+option(SNOWHOUSE_BUILD_TESTS "Build the Snowhouse tests" ON)
+option(SNOWHOUSE_RUN_TESTS "Run the Snowhouse tests" ON)
+option(SNOWHOUSE_IS_CPP11 "Whether to build this as a C++11 project" OFF)
+
+include_directories("${PROJECT_SOURCE_DIR}")
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ./bin)
+
+set(CMAKE_CXX_FLAGS "-Wfatal-errors -Wall -W -Werror -Wfloat-equal -Wundef -Wendif-labels -Wshadow -pedantic-errors")
+
+if(SNOWHOUSE_IS_CPP11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdeprecated")
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+
+ if (CMAKE_HOST_APPLE AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+ endif()
+endif()
+
+message(${CMAKE_CXX_FLAGS})
+
+if (SNOWHOUSE_BUILD_TESTS)
+ FILE(GLOB SnowhouseSpecSourceFiles example/*.cpp)
+ add_executable(snowhouse-tests ${SnowhouseSpecSourceFiles})
+endif()
+
+if (SNOWHOUSE_BUILD_TESTS AND SNOWHOUSE_RUN_TESTS)
+ add_custom_command(TARGET snowhouse-tests
+ POST_BUILD
+ COMMAND snowhouse-tests
+ WORKING_DIRECTORY ./bin)
+elseif (SNOWHOUSE_RUN_TESTS)
+ message(WARNING "Unable to run snowhouse tests - set:\n option(SNOWHOUSE_BUILD_TESTS, \"Build the Snowhouse tests\" ON)\nand clear your CMakeCache.txt")
+endif()
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/LICENSE_1_0.txt b/vendor/bandit/bandit/assertion_frameworks/snowhouse/LICENSE_1_0.txt
new file mode 100644
index 00000000..36b7cd93
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/README.md b/vendor/bandit/bandit/assertion_frameworks/snowhouse/README.md
new file mode 100644
index 00000000..ecd6e039
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/README.md
@@ -0,0 +1,419 @@
+snowhouse
+=========
+
+An assertion library for C++
+
+Snowhouse is a stand alone assertion framework for C++. It was originally
+developed as part of [Igloo](http://github.com/joakimkarlsson/igloo) and has
+been extracted to be usable in other contexts.
+
+## Usage
+
+```C++
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+
+int main()
+{
+ std::cout << "Testing that 23 is 23" << std::endl;
+ AssertThat(23, Is().EqualTo(23));
+
+ try
+ {
+ AssertThat(12, Is().LessThan(11).And().GreaterThan(99));
+ }
+ catch(const AssertionException& ex)
+ {
+ std::cout << "Apparently this failed:" << std::endl;
+ std::cout << ex.GetMessage() << std::endl;
+ }
+
+ return 0;
+}
+```
+
+### Assertions
+
+Snowhouse uses a constraint based assertion model that is heavily inspired by the
+model used in [NUnit](http://nunit.org/). An assertion in Snowhouse is written
+using the following format:
+
+```cpp
+AssertThat(actual_value, <constraint expression>);
+```
+
+where &lt;constraint expression&gt; is an expression that actual_value is evaluated against when the test is executed.
+
+Constraint expressions come in two basic forms: composite and fluent expressions
+
+#### Composite Expressions
+
+With composite expressions, you can create compact, powerful expressions that combine a set of predefined constraints with ones that you provide yourself.
+
+Example:
+
+```cpp
+AssertThat(length, IsGreaterThan(4) && !Equals(10));
+```
+
+Composite expressions can be any combination of constraints and the standard logical C++ operators.
+
+You can also add your own constraints to be used within composite expressions.
+
+####Fluent Expressions
+
+With fluent expressions, you can create assertions that better convey the intent of a test without exposing implementation-specific details. Fluent expressions aim to help you create tests that are not just by developers for developers, but rather can be read and understood by domain experts.
+
+Fluent expressions also has the ability to make assertions on the elements in a conteiner in a way you cannot achieve with composite expressions.
+
+Example:
+
+```cpp
+AssertThat(length, Is().GreaterThan(4).And().Not().EqualTo(10));
+```
+
+### Basic Constraints
+
+####Equality Constraint
+
+Used to verify equality between actual and expected.
+
+```cpp
+AssertThat(x, Equals(12));
+AssertThat(x, Is().EqualTo(12));
+```
+
+####EqualityWithDelta Constraint
+
+Used to verify equality between actual and expected, allowing the two to differ by a delta.
+
+```cpp
+AssertThat(2.49, EqualsWithDelta(2.5, 0.1));
+AssertThat(2.49, Is().EqualToWithDelta(2.5, 0.1));
+```
+
+####GreaterThan Constraint
+
+Used to verify that actual is greater than a value.
+
+```cpp
+AssertThat(x, IsGreaterThan(4));
+AssertThat(x, Is().GreaterThan(4));
+```
+
+
+####LessThan Constraint
+
+Used to verify that actual is less than a value.
+
+```cpp
+AssertThat(x, IsLessThan(3));
+AssertThat(x, Is().LessThan(3));
+```
+
+####GreaterThanOrEqualTo Constraint
+
+Used to verify that actual is greater than or equal to a value.
+
+```cpp
+AssertThat(x, IsGreaterThanOrEqualTo(5));
+AssertThat(x, Is().GreaterThanOrEqualTo(5));
+```
+
+####LessThanOrEqualTo Constraint
+
+Used to verify that actual is less than or equal to a value.
+
+```cpp
+AssertThat(x, IsLessThanOrEqualTo(6));
+AssertThat(x, Is().LessThanOrEqualTo(6));
+```
+
+### Pointer Constraints
+
+Used to check for `nullptr` equality.
+
+```cpp
+AssertThat(x, IsNull());
+AssertThat(x, Is().Null());
+```
+
+### String Constraints
+
+String assertions in Snowhouse are used to verify the values of STL strings (std::string).
+
+####Equality Constraints
+
+Used to verify that actual is equal to an expected value.
+
+```cpp
+AssertThat(actual_str, Equals("foo"));
+AssertThat(actual_str, Is().EqualTo("foo"));
+```
+
+####Contains Constraint
+
+Used to verify that a string contains a substring.
+
+```cpp
+AssertThat(actual_str, Contains("foo"));
+AssertThat(actual_str, Is().Containing("foo"));
+```
+
+####EndsWith Constraint
+
+Used to verify that a string ends with an expected substring.
+
+```cpp
+AssertThat(actual_str, EndsWith("foo"));
+AssertThat(actual_str, Is().EndingWith("foo"));
+```
+
+####StartsWith Constraint
+
+Used to verify that a string starts with an expected substring.
+
+```cpp
+AssertThat(actual_str, StartsWith("foo"));
+AssertThat(actual_str, Is().StartingWith("foo"));
+```
+
+####HasLength Constraint
+
+Used to verify that a string is of the expected length.
+
+```cpp
+AssertThat(actual_str, HasLength(5));
+AssertThat(actual_str, Is().OfLength(5));
+```
+
+###Constraints on Multi Line Strings
+
+If you have a string that contains multiple lines, you can use the collection constraints to make assertions on the content of that string. This may be handy if you have a string that, for instance, represents the resulting content of a file or a network transmission.
+
+Snowhouse can handle both windows (CR+LF) and unix (LF) line endings
+
+```cpp
+std::string lines = "First line\r\nSecond line\r\nThird line";
+AssertThat(lines, Has().Exactly(1).StartingWith("Second"));
+```
+
+###Container Constraints
+
+The following constraints can be applied to containers in the standard template library:
+
+####Contains Constraint
+
+Used to verify that a container contains an expected value.
+
+```cpp
+AssertThat(container, Contains(12));
+AssertThat(container, Is().Containing(12));
+```
+
+####HasLength Constraint
+
+Used to verify that a container has the expected length.
+
+```cpp
+AssertThat(container, HasLength(3));
+AssertThat(container, Is().OfLength(3));
+```
+
+####IsEmpty Constraint
+
+Used to verify that a container is empty.
+
+```cpp
+AssertThat(contatiner, IsEmpty());
+AssertThat(container, Is().Empty());
+```
+
+####All
+
+Used to verify that all elements of a STL sequence container matches an expectation.
+
+```cpp
+AssertThat(container, Has().All().LessThan(5).Or().EqualTo(66));
+```
+
+####AtLeast
+
+Used to verify that at least a specified amount of elements in a STL sequence container matches an expectation.
+
+```cpp
+AssertThat(container, Has().AtLeast(3).StartingWith("foo"));
+```
+
+####AtMost
+
+Used to verify that at most a specified amount of elements in a STL sequence container matches an expectation.
+
+```cpp
+Assert:That(container, Has().AtMost(2).Not().Containing("failed"));
+```
+
+####Exactly
+
+Used to verify that a STL sequence container has exactly a specified amount of elements that matches an expectation.
+
+```cpp
+AssertThat(container, Has().Exactly(3).GreaterThan(10).And().LessThan(20));
+```
+
+####EqualsContainer
+
+Used to verify that two STL sequence containers are equal.
+
+```cpp
+AssertThat(container1, EqualsContainer(container2));
+AssertThat(container1, Is().EqualToContainer(container2));
+```
+
+#####Predicate functions
+
+You can supply a predicate function or a functor to EqualsContainer to customize how to compare the elements in the two containers.
+
+With a predicate function:
+
+```cpp
+static bool are_my_types_equal(const my_type& lhs, const my_type& rhs)
+{
+ return lhs.my_val_ == rhs.my_val_;
+}
+
+AssertThat(container1, EqualsContainer(container2, are_my_types_equal));
+```
+
+With a functor as predicate:
+
+```cpp
+struct within_delta
+{
+ within_delta(int delta) : delta_(delta) {}
+
+ bool operator()(const my_type& lhs, const my_type& rhs) const
+ {
+ return abs(lhs.my_val_ - rhs.my_val_) <= delta_;
+ }
+
+private:
+ int delta_;
+};
+
+AssertThat(container1, Is().EqualToContainer(container1, within_delta(1));
+```
+
+###Exceptions
+
+Exception constraints can be used to verify that your code throws the correct exceptions.
+
+####AssertThrows
+
+AssertThrows succeeds if the exception thrown by the call is of the supplied type (or one of its subtypes).
+
+```cpp
+AssertThrows(std::logic_error, myObject.a_method(42));
+```
+
+####Making Assertions on the Thrown Exceptions
+
+If AssertThrows succeeds, it will store the thrown exception so that you can make more detailed assertions on it.
+
+```cpp
+AssertThrows(std::logic_error, myObject.a_method(42));
+AssertThat(LastException<std::logic_error>().what(), Is().Containing("logic failure"));
+```
+
+The LastException<> is available in the scope of the call to AssertThrows. An exception is not available between specs in order to avoid the result of one spec contaminating another.
+
+###Custom Constraints
+
+You can add your own constraints to Snowhouse to create more expressive specifications.
+
+####Fulfills Constraints
+
+By defining the following matcher
+
+```cpp
+struct IsEvenNumber
+{
+ bool Matches(const int actual) const
+ {
+ return (actual % 2) == 0;
+ }
+
+ friend std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& );
+};
+
+std::ostream& operator<<(std::ostream& stm, const IsEvenNumber& )
+{
+ stm << "An even number";
+ return stm;
+}
+```
+
+You can create the following constraints in Snowhouse:
+
+```cpp
+AssertThat(42, Fulfills(IsEvenNumber()));
+AssertThat(42, Is().Fulfilling(IsEvenNumber()));
+```
+
+Your custom matcher should implement a method called Matches() that takes a parameter of the type you expect and returns true if the passed parameter fulfills the constraint.
+
+To get more expressive failure messages, you should also implement the streaming operator as in the example above.
+
+##Getting better output for your types
+
+Whenever Snowhouse prints an error message for a type, it will use the stream operator for that type, otherwise it will print "[unsupported type]"
+as a placeholder.
+
+```cpp
+struct MyType { /*...*/ };
+
+AssertThat(myType, Fulfills(MyConstraint());
+```
+
+Will output the following if the constraint fails:
+
+```bash
+Expected: To fulfill my constraint
+Actual: [unsupported type]
+```
+
+If we add a stream operator:
+
+```cpp
+std::ostream& operator<<(std::ostream& stream, const MyType& a)
+{
+ stream << "MyType( x = " << a.x << " )";
+ return stream;
+}
+```
+
+the output will be a bit more readable:
+
+```bash
+Expected: To fullfill my constraint
+Actual: MyType( x = 23 )
+```
+
+##Configurable Failure Handlers
+
+You can provide Snowhouse with custom failure handlers, for example to call `std::terminate` instead of throwing an exception. See `DefaultFailureHandler` for an example of a failure handler. You can derive your own macros with custom failure handlers using `SNOWHOUSE_ASSERT_THAT` and `SNOWHOUSE_ASSERT_THROWS`. See the definitions of `AssertThat` and `AssertThrows` for examples of these. Define `SNOWHOUSE_NO_MACROS` to disable the unprefixed macros `AssertThat` and `AssertThrows`.
+
+### Example Use Cases
+
+#### Assert Program State
+
+Log an error immediately as we may crash if we try to continue. Don't attempt to unwind the stack as we may be inside a destructor or `nothrow` function. We may want to call `std::terminate`, or attempt to muddle along with the rest of the program.
+
+#### Assert Program State in Safe Builds
+
+As above, but only in debug builds.
+
+#### Test Assert
+
+Assert that a test behaved as expected. Throw an exception and let our testing framework deal with the test failure.
+
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/cross_compile.sh b/vendor/bandit/bandit/assertion_frameworks/snowhouse/cross_compile.sh
new file mode 100755
index 00000000..d3a73279
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/cross_compile.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+STATUS=""
+
+function build_for {
+ local CC=$1
+ local CXX=$2
+ local CXX_VERSION=$3
+
+ echo "Compiling for $CC, $CXX, $CXX_VERSION..."
+
+ if [[ "$CXX_VERSION" == "CXX" ]]; then
+ local SNOWHOUSE_IS_CPP11=OFF
+ else
+ local SNOWHOUSE_IS_CPP11=ON
+ fi
+
+ echo "SNOWHOUSE_IS_CPP11=$SNOWHOUSE_IS_CPP11"
+
+ BUILD_DIR=build-$CC-$CXX_VERSION
+ mkdir $BUILD_DIR
+ pushd $BUILD_DIR
+ CC=$CC CXX=$CXX cmake -DSNOWHOUSE_IS_CPP11=$SNOWHOUSE_IS_CPP11 ../..
+ make
+ STATUS="$STATUS\n$BUILD_DIR - Status: $?"
+ popd
+}
+
+if [[ -d builds ]]; then
+ rm -rf builds
+fi
+
+mkdir builds
+pushd builds
+
+build_for gcc-4.5 g++-4.5 CXX
+build_for gcc-4.6 g++-4.6 CXX
+build_for gcc-4.6 g++-4.6 CXX11
+build_for gcc-4.7 g++-4.7 CXX
+build_for gcc-4.7 g++-4.7 CXX11
+build_for gcc-4.8 g++-4.8 CXX
+build_for gcc-4.8 g++-4.8 CXX11
+build_for gcc-4.9 g++-4.9 CXX
+build_for gcc-4.9 g++-4.9 CXX11
+build_for clang clang++ CXX
+build_for clang clang++ CXX11
+popd
+
+echo "============================================"
+echo -e $STATUS
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/basic_assertions.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/basic_assertions.cpp
new file mode 100644
index 00000000..2766ec0a
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/basic_assertions.cpp
@@ -0,0 +1,228 @@
+#include <stdexcept>
+#include <sstream>
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void throwRuntimeError() {
+ throw std::runtime_error("This is expected");
+}
+
+struct IgnoreErrors {
+ template <class ExpectedType, class ActualType>
+ static void Handle(const ExpectedType&, const ActualType&, const char*, int)
+ {
+ }
+
+ static void Handle(const std::string&)
+ {
+ }
+};
+
+void BasicAssertions()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " ASSERTIONS " << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleIntegerEquality" << std::endl;
+ {
+ Assert::That(5, Is().EqualTo(5));
+ }
+
+ std::cout << "ShouldDetectIntegerInequality" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, Is().EqualTo(4)), "equal to 4");
+ }
+
+ std::cout << "ShouldDetectIfNotFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, Is().Not().EqualTo(5)), "Expected: not equal to 5\nActual: 5\n");
+ }
+
+ std::cout << "ShouldHandleStrings" << std::endl;
+ {
+ Assert::That(std::string("joakim"), Is().EqualTo(std::string("joakim")));
+ }
+
+ std::cout << "ShouldHandleStringsWithoutExplicitTemplateSpecialization" << std::endl;
+ {
+ Assert::That("kim", Is().EqualTo("kim"));
+ }
+
+ std::cout << "ShouldHandleGreaterThan" << std::endl;
+ {
+ Assert::That(5, Is().GreaterThan(4));
+ }
+
+ std::cout << "ShouldDetectWhenGreaterThanFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, Is().GreaterThan(5)),
+ "Expected: greater than 5\nActual: 5\n");
+ }
+
+ std::cout << "ShouldHandleLessThan" << std::endl;
+ {
+ Assert::That(5, Is().LessThan(6));
+ }
+
+ std::cout << "ShouldDetectWhenLessThanFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(6, Is().LessThan(5)),
+ "Expected: less than 5\nActual: 6\n");
+ }
+
+ std::cout << "ShouldThrowExplicitFailureMessage" << std::endl;
+ {
+ AssertTestFails(Assert::Failure("foo"), "foo");
+ }
+
+ std::cout << "Should contain location information" << std::endl;
+ {
+ int line;
+ std::string file;
+
+ try
+ {
+ Assert::That(5, Equals(2), "filename", 32);
+ }
+ catch(const AssertionException& e)
+ {
+ line = e.GetLineNumber();
+ file = e.GetFilename();
+ }
+
+ Assert::That(line, Equals(32));
+ Assert::That(file, Equals("filename"));
+ }
+
+ std::cout << "ShouldEnsureExceptionIsThrown" << std::endl;
+ {
+
+ AssertThrows(std::runtime_error, throwRuntimeError());
+ }
+
+ std::cout << "ShouldIgnoreTheError" << std::endl;
+ {
+ ConfigurableAssert<IgnoreErrors>::That(1, Equals(2));
+ }
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " ASSERTIONS EXPRESSION TEMPLATES" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleIntegerEquality" << std::endl;
+ {
+ Assert::That(5, Equals(5));
+ }
+
+ std::cout << "ShouldDetectIntegerInequality" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, Equals(4)), "equal to 4");
+ }
+
+ std::cout << "ShouldDetectIfNotFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, !Equals(5)),
+ "Expected: not equal to 5\nActual: 5\n");
+ }
+
+ std::cout << "ShouldHandleStrings" << std::endl;
+ {
+ Assert::That(std::string("joakim"), Equals(std::string("joakim")));
+ }
+
+ std::cout << "ShouldHandleStringsWithoutExplicitTemplateSpecialization"
+ << std::endl;
+ {
+ Assert::That("kim", Equals("kim"));
+ }
+
+ std::cout << "ShouldHandleGreaterThan" << std::endl;
+ {
+ Assert::That(5, IsGreaterThan(4));
+ }
+
+ std::cout << "ShouldHandleGreaterThanOrEqualTo" << std::endl;
+ {
+ Assert::That(4, IsGreaterThanOrEqualTo(4));
+ Assert::That(5, IsGreaterThanOrEqualTo(4));
+ }
+
+ std::cout << "ShouldDetectWhenGreaterThanFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, IsGreaterThan(5)),
+ "Expected: greater than 5\nActual: 5\n");
+ }
+
+ std::cout << "ShouldDetectWhenGreaterThanOrEqualToFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(4, IsGreaterThanOrEqualTo(5)),
+ "Expected: greater than or equal to 5\nActual: 4\n");
+ }
+
+ std::cout << "ShouldHandleLessThan" << std::endl;
+ {
+ Assert::That(5, IsLessThan(6));
+ }
+
+ std::cout << "ShouldHandleLessThanOrEqualTo" << std::endl;
+ {
+ Assert::That(5, IsLessThanOrEqualTo(6));
+ Assert::That(6, IsLessThanOrEqualTo(6));
+ }
+
+ std::cout << "ShouldDetectWhenLessThanFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(6, IsLessThan(5)),
+ "Expected: less than 5\nActual: 6\n");
+ }
+
+ std::cout << "ShouldDetectWhenLessThanOrEqualToFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(6, IsLessThanOrEqualTo(5)),
+ "Expected: less than or equal to 5\nActual: 6\n");
+ }
+
+#if __cplusplus > 199711L
+ std::cout << "ShouldHandleNull" << std::endl;
+ {
+ Assert::That(nullptr, IsNull());
+ }
+
+ std::cout << "ShouldHandleNull" << std::endl;
+ {
+ Assert::That(nullptr, Is().Null());
+ }
+
+ std::cout << "ShouldHandleNotNull" << std::endl;
+ {
+ int anInt = 0;
+ Assert::That(&anInt, ! IsNull());
+ }
+
+ std::cout << "ShouldDetectWhenIsNullFails" << std::endl;
+ {
+ int anInt = 0;
+ std::ostringstream message;
+ message << "Expected: equal to nullptr\nActual: " << &anInt << "\n";
+ AssertTestFails(Assert::That(&anInt, IsNull()), message.str());
+ }
+
+ std::cout << "ShouldDetectWhenIsNullFails" << std::endl;
+ {
+ int anInt = 0;
+ std::ostringstream message;
+ message << "Expected: equal to nullptr\nActual: " << &anInt << "\n";
+ AssertTestFails(Assert::That(&anInt, Is().Null()), message.str());
+ }
+
+ std::cout << "ShouldDetectWhenIsNotNullFails" << std::endl;
+ {
+ std::ostringstream message;
+ message << "Expected: not equal to nullptr\nActual: nullptr\n";
+
+ AssertTestFails(Assert::That(nullptr, ! IsNull()), message.str());
+ }
+#endif
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/boolean_operators.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/boolean_operators.cpp
new file mode 100644
index 00000000..3e4577a5
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/boolean_operators.cpp
@@ -0,0 +1,48 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void BooleanOperators()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " Boolean operators" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleIsFalseOperator" << std::endl;
+ {
+ Assert::That(false, IsFalse());
+ }
+
+ std::cout << "ShouldHandleWhenIsFalseFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(true, IsFalse()), "Expected: false");
+ }
+
+ std::cout << "ShouldHandleIsTrueOperator" << std::endl;
+ {
+ Assert::That(true, IsTrue());
+ }
+
+ std::cout << "ShouldHandleWhenIsTrueFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(false, IsTrue()), "Expected: true");
+ }
+
+ std::cout << "ShouldHandleFluentIsTrue" << std::endl;
+ {
+ Assert::That(true, Is().True());
+ AssertTestFails(Assert::That(false, Is().True()), "Expected: true");
+ }
+
+ std::cout << "ShouldHandleFluentIsFalse" << std::endl;
+ {
+ Assert::That(false, Is().False());
+ AssertTestFails(Assert::That(true, Is().False()), "Expected: false");
+ }
+
+ std::cout << "ShouldTreatAssertWithoutConstraintAsBooleanConstrains" << std::endl;
+ {
+ Assert::That(true);
+ }
+}
+
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/container_spec.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/container_spec.cpp
new file mode 100644
index 00000000..c668dffa
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/container_spec.cpp
@@ -0,0 +1,85 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+struct my_type
+{
+ my_type(int my_val)
+ : my_val_(my_val)
+ {}
+
+ friend bool operator==(const my_type&, const my_type&);
+ friend bool operator!=(const my_type&, const my_type&);
+ friend std::ostream& operator<<(std::ostream&, const my_type&);
+
+ int my_val_;
+};
+
+bool operator==(const my_type& lhs, const my_type& rhs)
+{
+ return lhs.my_val_ == rhs.my_val_;
+}
+
+bool operator!=(const my_type& lhs, const my_type& rhs)
+{
+ return !(lhs == rhs);
+}
+
+std::ostream& operator<<(std::ostream& stream, const my_type& item)
+{
+ stream << "(my_type: my_val_=" << item.my_val_ << " )";
+ return stream;
+}
+
+static bool are_my_types_equal(const my_type& lhs, const my_type& rhs)
+{
+ return lhs.my_val_ == rhs.my_val_;
+}
+
+void ContainerConstraints()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " ContainerContstraints" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "it_should_be_able_to_compare_containers_of_custom_types" << std::endl;
+ {
+ const my_type e[] = {my_type(1), my_type(3)};
+ const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
+ std::list<my_type> my_container_;
+ my_container_.push_back(my_type(1));
+ my_container_.push_back(my_type(3));
+
+ AssertThat(my_container_, EqualsContainer(expected));
+ }
+
+ std::cout << "it_should_handle_failing_comparisons" << std::endl;
+ {
+ const my_type e[] = {my_type(1), my_type(2)};
+ const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
+ std::list<my_type> my_container_;
+ my_container_.push_back(my_type(1));
+ my_container_.push_back(my_type(3));
+
+ AssertTestFails(Assert::That(my_container_, EqualsContainer(expected)),
+ "Expected: [ (my_type: my_val_=1 ), (my_type: my_val_=2 ) ]");
+ }
+
+ std::cout << "it_should_handle_comparison_with_a_predicate_function" << std::endl;
+ {
+ const my_type e[] = {my_type(1), my_type(3)};
+ const std::list<my_type> expected(e, e + sizeof(e) / sizeof(e[0]));
+ std::list<my_type> my_container_;
+ my_container_.push_back(my_type(1));
+ my_container_.push_back(my_type(3));
+
+ Assert::That(my_container_, EqualsContainer(expected, are_my_types_equal));
+ Assert::That(my_container_, Is().EqualToContainer(expected, are_my_types_equal));
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/custom_matchers_test.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/custom_matchers_test.cpp
new file mode 100644
index 00000000..c5437f9f
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/custom_matchers_test.cpp
@@ -0,0 +1,69 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+struct IsEvenNumberNoStreamOperator
+{
+ bool Matches(const int actual) const
+ {
+ return (actual % 2) == 0;
+ }
+};
+
+struct IsEvenNumberWithStreamOperator
+{
+ bool Matches(const int actual) const
+ {
+ return (actual % 2) == 0;
+ }
+
+ friend std::ostream& operator<<(std::ostream& stm,
+ const IsEvenNumberWithStreamOperator& );
+};
+
+std::ostream& operator<<(std::ostream& stm,
+ const IsEvenNumberWithStreamOperator& )
+{
+ stm << "An even number";
+ return stm;
+}
+
+void CustomMatchers()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " CustomMatchersNoStreamOperator" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "CanHandleCustomMatcher" << std::endl;
+ {
+ Assert::That(2, Fulfills(IsEvenNumberNoStreamOperator()));
+ }
+
+ std::cout << "CustomMatcherWithFluent" << std::endl;
+ {
+ Assert::That(2, Is().Fulfilling(IsEvenNumberNoStreamOperator()));
+ }
+
+ std::cout << "OutputsCorrectMessageWhenFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(3, Fulfills(IsEvenNumberNoStreamOperator())),
+ "Expected: [unsupported type]\nActual: 3");
+ }
+
+
+ std::cout << "================================================" << std::endl;
+ std::cout << "CustomMatcherWithStreamOperator" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ErrorMessageUsesCustomStreamOperatorIfAvailable" << std::endl;
+ {
+ AssertTestFails(Assert::That(3, Fulfills(IsEvenNumberWithStreamOperator())),
+ "Expected: An even number\nActual: 3");
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/exceptions_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/exceptions_tests.cpp
new file mode 100644
index 00000000..0f1ac2ab
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/exceptions_tests.cpp
@@ -0,0 +1,97 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2013.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <snowhouse/snowhouse.h>
+#include <stdexcept>
+using namespace snowhouse;
+
+#include "tests.h"
+
+class ClassWithExceptions
+{
+public:
+ int LogicError()
+ {
+ throw std::logic_error("not logical!");
+ }
+
+ double RangeError()
+ {
+ throw std::range_error("range error!");
+ }
+
+ void NoError()
+ {
+ }
+};
+
+void ExceptionTests()
+{
+ ClassWithExceptions objectUnderTest;
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " ExceptionTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+
+ std::cout << "CanDetectExceptions" << std::endl;
+ {
+ AssertThrows(std::exception, objectUnderTest.LogicError());
+ }
+
+ std::cout << "CanAssertOnLastException" << std::endl;
+ {
+ AssertThrows(std::logic_error, objectUnderTest.LogicError());
+ Assert::That(LastException<std::logic_error>().what(), Contains("not logical!"));
+ }
+
+ std::cout << "CanDetectWhenWrongExceptionIsThrown" << std::endl;
+ {
+ AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.RangeError()), "Wrong exception");
+ }
+
+ std::cout << "CanPrintExpectedExceptionTypeWhenWrongExceptionIsThrown" << std::endl;
+ {
+ AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.RangeError()), "Expected std::logic_error");
+ }
+
+ std::cout << "CanHaveSeveralExceptionAssertionsInSameSpec" << std::endl;
+ {
+ AssertThrows(std::logic_error, objectUnderTest.LogicError());
+ Assert::That(LastException<std::logic_error>().what(), Contains("not logical!"));
+
+ AssertThrows(std::range_error, objectUnderTest.RangeError());
+ Assert::That(LastException<std::range_error>().what(), Contains("range error!"));
+ }
+
+ std::cout << "CanHaveSeveralExceptionAssertionForTheSameExceptionInSameSpec" << std::endl;
+ {
+ AssertThrows(std::logic_error, objectUnderTest.LogicError());
+ Assert::That(LastException<std::logic_error>().what(), Contains("not logical!"));
+
+ AssertThrows(std::logic_error, objectUnderTest.LogicError());
+ Assert::That(LastException<std::logic_error>().what(), Contains("not logical!"));
+ }
+
+ std::cout << "CanDetectWhenNoExceptionIsThrown" << std::endl;
+ {
+ AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.NoError()), "No exception");
+ }
+
+ std::cout << "CanPrintExpectedExceptionWhenNoExceptionIsThrown" << std::endl;
+ {
+ AssertTestFails(AssertThrows(std::logic_error, objectUnderTest.NoError()), "Expected std::logic_error");
+ }
+
+ std::cout << "ExceptionsAreDestoryedWhenWeExitScope" << std::endl;
+ {
+ {
+ AssertThrows(std::logic_error, objectUnderTest.LogicError());
+ }
+ AssertThrows(AssertionException, LastException<std::logic_error>());
+ Assert::That(LastException<AssertionException>().GetMessage(), Contains("No exception was stored"));
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/expression_error_handling.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/expression_error_handling.cpp
new file mode 100644
index 00000000..de96f038
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/expression_error_handling.cpp
@@ -0,0 +1,28 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void ExpressionErrorHandling()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " ExpressionErrorHandling" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::vector<int> collection;
+ collection.push_back(1);
+ collection.push_back(2);
+ collection.push_back(3);
+
+ std::cout << "AnInvalidAllOperationShouldBeReportedProperly" << std::endl;
+ {
+ AssertTestFails(Assert::That(collection, Has().All()),
+ "The expression after \"all\" operator does not yield any result");
+ }
+
+ std::cout << "AnInvalidAtLeastOperationShouldBeReportedProperly" << std::endl;
+ {
+ AssertTestFails(Assert::That(collection, Has().AtLeast(2)),
+ "The expression after \"at least 2\" operator does not yield any result");
+ }
+
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/main.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/main.cpp
new file mode 100644
index 00000000..616b97ff
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/main.cpp
@@ -0,0 +1,43 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void BooleanOperators();
+void BasicAssertions();
+void ContainerConstraints();
+void CustomMatchers();
+void ExceptionTests();
+void ExpressionErrorHandling();
+void MapTests();
+void OperatorTests();
+void SequenceContainerTests();
+void StringLineTests();
+void StringTests();
+void StringizeTests();
+
+int main()
+{
+ try
+ {
+ BasicAssertions();
+ BooleanOperators();
+ ContainerConstraints();
+ CustomMatchers();
+ ExceptionTests();
+ ExpressionErrorHandling();
+ MapTests();
+ OperatorTests();
+ SequenceContainerTests();
+ StringLineTests();
+ StringTests();
+ StringizeTests();
+ }
+ catch(const AssertionException& e)
+ {
+ std::cout << "Tests failed!" << std::endl;
+ std::cout << e.GetMessage() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/map_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/map_tests.cpp
new file mode 100644
index 00000000..813b5011
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/map_tests.cpp
@@ -0,0 +1,38 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void MapTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " MapTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::map<std::string, int> ages;
+ ages["joakim"] = 38;
+ ages["maria"] = 36;
+ ages["hanna"] = 6;
+ ages["moa"] = 4;
+
+ std::cout << "ContainingShouldDetermineIfKeyExists" << std::endl;
+ {
+ Assert::That(ages, Is().Containing("joakim"));
+ }
+
+ std::cout << "ShouldGiveAProperMessageWhenContainingFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(ages, Is().Not().Containing("hanna")),
+ "Expected: not contains hanna");
+ }
+
+ std::cout << "ContainingShouldDetermineIfKeyExists" << std::endl;
+ {
+ Assert::That(ages, Contains("joakim"));
+ }
+
+ std::cout << "ShouldGiveAProperMessageWhenContainingFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(ages, !Contains("hanna")),
+ "Expected: not contains hanna");
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/operator_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/operator_tests.cpp
new file mode 100644
index 00000000..3d11ae07
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/operator_tests.cpp
@@ -0,0 +1,137 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void OperatorTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " OperatorTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleAndOperatorExpressionTemplates" << std::endl;
+ {
+ Assert::That(5, IsLessThan(6) && IsGreaterThan(4));
+ }
+
+ std::cout << "ShouldHandleAndOperator" << std::endl;
+ {
+ Assert::That(5, Is().LessThan(6).And().GreaterThan(4));
+ }
+
+ std::cout << "ShouldHandleAndOperatorFailExpressionTemplates" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, IsLessThan(7) && IsGreaterThan(5)),
+ "less than 7 and greater than 5");
+ }
+
+ std::cout << "ShouldHandleAndOperatorFail" << std::endl;
+ {
+ AssertTestFails(Assert::That(5, Is().LessThan(7).And().GreaterThan(5)),
+ "less than 7 and greater than 5");
+ }
+
+ std::cout << "ShouldHandleOrOperator" << std::endl;
+ {
+ Assert::That(12, Is().LessThan(7).Or().GreaterThan(5));
+ }
+
+ std::cout << "ShouldHandleOrOperatorExpressionTemplates" << std::endl;
+ {
+ Assert::That(12, IsLessThan(7) || IsGreaterThan(5));
+ }
+
+ std::cout << "ShouldHandleOrOperatorFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(67, Is().LessThan(12).Or().GreaterThan(99)),
+ "less than 12 or greater than 99");
+ }
+
+ std::cout << "ShouldHandleOrOperatorFailsExpressionTemplates" << std::endl;
+ {
+ AssertTestFails(Assert::That(67, IsLessThan(12) || IsGreaterThan(99)),
+ "less than 12 or greater than 99");
+ }
+
+ std::cout << "ShouldHandleNotOperators" << std::endl;
+ {
+ Assert::That(5, Is().Not().EqualTo(4));
+ }
+
+ std::cout << "ShouldHandleNotOperatorsExpressionTemplates" << std::endl;
+ {
+ Assert::That(5, !Equals(4));
+ }
+
+ std::cout << "ShouldHandleNotOperatorsFails" << std::endl;
+ {
+ AssertTestFails(Assert::That(12, Is().Not().EqualTo(12)), "not equal to 12");
+ }
+
+ std::cout << "ShouldHandleNotOperatorsFailsExpressionTemplates" << std::endl;
+ {
+ AssertTestFails(Assert::That(12, !Equals(12)), "not equal to 12");
+ }
+
+ std::cout << "ShouldHandleNotOperatorsForStrings" << std::endl;
+ {
+ Assert::That("joakim", Is().Not().EqualTo("harry"));
+ }
+
+ std::cout << "ShouldHandleNotOperatorsForStringsExpressionTemplates" << std::endl;
+ {
+ Assert::That("joakim", !Equals("harry"));
+ }
+
+ std::cout << "ShouldHandleBothLeftAndRightAssociativeOperators" << std::endl;
+ {
+ Assert::That(5, Is().GreaterThan(4).And().Not().LessThan(3));
+ }
+
+ std::cout << "ShouldHandleBothLeftAndRightAssociativeOperatorsExpressionTemplates" << std::endl;
+ {
+ Assert::That(5, IsGreaterThan(4)&& !IsLessThan(3));
+ }
+
+ std::cout << "MalformedExpressionYieldsError" << std::endl;
+ {
+ AssertTestFails(Assert::That(4, Is().Not()),
+ "The expression contains a not operator without any operand");
+ }
+
+ std::cout <<
+ "EqualsWithDeltaOperator_should_fail_for_actual_larger_than_delta"
+ << std::endl;
+ {
+ AssertTestFails(Assert::That(3.9, EqualsWithDelta(3, 0.5)),
+ "Expected: equal to 3 (+/- 0.5)");
+ }
+
+ std::cout << "EqualsWithDeltaOperator_should_fail_for_actual_less_than_delta" << std::endl;
+ {
+ AssertTestFails(Assert::That(2.49, EqualsWithDelta(3, 0.5)),
+ "Expected: equal to 3 (+/- 0.5)");
+ }
+
+ std::cout << "EqualsWithDeltaOperator_should_succeed" << std::endl;
+ {
+ Assert::That(2, EqualsWithDelta(1.9, 0.1));
+ }
+
+ std::cout << "Fluent_equals_with_delta_should_fail_for_actual_larger_than_delta" << std::endl;
+ {
+ AssertTestFails(Assert::That(3.9, Is().EqualToWithDelta(3, 0.5)),
+ "Expected: equal to 3 (+/- 0.5)");
+ }
+
+ std::cout << "Fluent_EqualsWithDeltaOperator_should_fail_for_actual_less_than_delta" << std::endl;
+ {
+ AssertTestFails(Assert::That(2.49, Is().EqualToWithDelta(3, 0.5)),
+ "Expected: equal to 3 (+/- 0.5)");
+ }
+
+ std::cout << "Fluent_EqualsWithDeltaOperator_should_succeed" << std::endl;
+ {
+ Assert::That(2, Is().EqualToWithDelta(1.9, 0.1));
+ }
+
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/sequence_container_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/sequence_container_tests.cpp
new file mode 100644
index 00000000..c090cc58
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/sequence_container_tests.cpp
@@ -0,0 +1,192 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+
+template <typename T>
+void SequenceContainerActual()
+{
+ const char* ExpectedActual = "\nActual: [ 1, 2, 3, 5, 8 ]";
+
+ T container;
+ container.clear();
+ container.push_back(1);
+ container.push_back(2);
+ container.push_back(3);
+ container.push_back(5);
+ container.push_back(8);
+
+ std::cout << "ShouldHandleAllOperator" << std::endl;
+ {
+ Assert::That(container, Has().All().GreaterThan(1).Or().LessThan(4));
+ }
+
+ std::cout << "ShouldHandleFailingAllOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().All().GreaterThan(4)), std::string("Expected: all greater than 4") + ExpectedActual);
+ }
+
+ std::cout << "SHouldHandleInvalidExpressionAfterAllOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().All().Not()), "The expression contains a not operator without any operand");
+ }
+
+ std::cout << "ShouldHandleNoExpressionAfterAllOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().All()), "The expression after \"all\" operator does not yield any result");
+ }
+
+ std::cout << "ShouldHandleAtLeastOperator" << std::endl;
+ {
+ Assert::That(container, Has().AtLeast(1).LessThan(5));
+ }
+
+ std::cout << "ShouldHandleFailingAtLeastOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().AtLeast(2).LessThan(2)), std::string("Expected: at least 2 less than 2") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleExactlyOperator" << std::endl;
+ {
+ Assert::That(container, Has().Exactly(1).EqualTo(3));
+ }
+
+ std::cout << "ShouldHandleFailingExactlyOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().Exactly(2).EqualTo(3)), std::string("Expected: exactly 2 equal to 3") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleAtMostOperator" << std::endl;
+ {
+ Assert::That(container, Has().AtMost(1).EqualTo(5));
+ }
+
+ std::cout << "ShouldHandleFailingAtMostOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().AtMost(1).EqualTo(3).Or().EqualTo(5)), std::string("Expected: at most 1 equal to 3 or equal to 5") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleNoneOperator" << std::endl;
+ {
+ Assert::That(container, Has().None().EqualTo(666));
+ }
+
+ std::cout << "ShouldHandleFailingNoneOperator" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Has().None().EqualTo(5)), std::string("Expected: none equal to 5") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleContaining" << std::endl;
+ {
+ Assert::That(container, Contains(3));
+ }
+
+ std::cout << "ShouldDetectFailingContains" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Contains(99)), std::string("contains 99") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleOfLength" << std::endl;
+ {
+ Assert::That(container, HasLength(5));
+ }
+
+ std::cout << "ShouldHandleFailingOfLength" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, HasLength(7)), std::string("of length 7") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleContaining_ExpressionTemplates" << std::endl;
+ {
+ Assert::That(container, Contains(3));
+ }
+
+ std::cout << "ShouldDetectFailingContains_ExpressionTemplates" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Contains(99)), std::string("contains 99") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleOfLength_ExpressionTemplates" << std::endl;
+ {
+ Assert::That(container, HasLength(5));
+ }
+
+ std::cout << "ShouldHandleFailingOfLengthForVectors" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, HasLength(7)), std::string("of length 7") + ExpectedActual);
+ }
+
+ std::cout << "ShouldHandleIsEmpty" << std::endl;
+ {
+ T is_empty;
+
+ Assert::That(is_empty, IsEmpty());
+ }
+
+ std::cout << "ShouldHandleFailingIsEmpty" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, IsEmpty()), "of length 0");
+ }
+
+ std::cout << "ShouldHandleFluentIsEmpty" << std::endl;
+ {
+ T is_empty;
+
+ Assert::That(is_empty, Is().Empty());
+ }
+
+ std::cout << "ShouldHandleFailingFluentIsEmpty" << std::endl;
+ {
+ AssertTestFails(Assert::That(container, Is().Empty()), "of length 0");
+ }
+
+ std::cout << "ShouldHandlerEqualsContainer" << std::endl;
+ {
+ std::list<int> expected;
+ expected.assign(container.begin(), container.end());
+
+ AssertThat(container, EqualsContainer(expected));
+ }
+
+ std::cout << "ShouldHandleEqualsContainer_Fluent" << std::endl;
+ {
+ std::list<int> expected;
+ expected.assign(container.begin(), container.end());
+
+ AssertThat(container, Is().EqualToContainer(expected));
+ }
+
+ std::cout << "ShouldHandleFailingEqualsContainer" << std::endl;
+ {
+ const int e[] = {4, 2, 4};
+ std::list<int> expected(e, e + sizeof(e) / sizeof(e[0]));
+
+ AssertTestFails(Assert::That(container, EqualsContainer(expected)), "Expected: [ 4, 2, 4 ]");
+ }
+
+ std::cout << "ShouldHandleFailingEqualsContainer_Fluent" << std::endl;
+ {
+ const int e[] = {4, 2, 4};
+ std::list<int> expected(e, e + sizeof(e) / sizeof(e[0]));
+
+ AssertTestFails(Assert::That(container, Is().EqualToContainer(expected)), "Expected: [ 4, 2, 4 ]");
+ }
+}
+
+void SequenceContainerTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " SequenceContainerTests(vector)" << std::endl;
+ std::cout << "================================================" << std::endl;
+ SequenceContainerActual<std::vector<int> >();
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " SequenceContainerTests(list)" << std::endl;
+ std::cout << "================================================" << std::endl;
+ SequenceContainerActual<std::list<int> >();
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " SequenceContainerTests(deque)" << std::endl;
+ std::cout << "================================================" << std::endl;
+ SequenceContainerActual<std::deque<int> >();
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_line_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_line_tests.cpp
new file mode 100644
index 00000000..8cf90cfb
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_line_tests.cpp
@@ -0,0 +1,179 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void StringLineTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " StringLineTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "CanAssertThatAtLeastOneLineInAStreamMatches" << std::endl;
+ {
+ Assert::That("First line\n", Has().AtLeast(1).EqualTo("First line"));
+ }
+
+ std::cout << "CanDetectWhenAssertionFails" << std::endl;
+ {
+ AssertTestFails(Assert::That("First line\n", Has().AtLeast(1).EqualTo("Second line")), "Expected: at least 1 equal to Second line");
+ }
+
+ std::cout << "CanHandleLineMissingNewline" << std::endl;
+ {
+ Assert::That("First line", Has().AtLeast(1).EqualTo("First line"));
+ }
+
+ std::cout << "CanHandleSeveralLines" << std::endl;
+ {
+ std::string lines = "First line\nSecond line";
+ Assert::That(lines, Has().Exactly(2).EndingWith("line"));
+ }
+
+ std::cout << "CanHandleWindowsLineEndings" << std::endl;
+ {
+ std::string lines = "First line\r\nSecond line\r\nThird line";
+ Assert::That(lines, Has().Exactly(3).EndingWith("line"));
+ }
+
+ std::cout << "CanMatchBeginningOfLinesWithWindowsLineEndings" << std::endl;
+ {
+ std::string lines = "First line\nSecond line\r\nThird line";
+ Assert::That(lines, Has().Exactly(1).StartingWith("Second"));
+ }
+
+ std::cout << "CanHandleEmptyLinesWhenUsingWindowsLineEndings" << std::endl;
+ {
+ std::string lines = "\r\nSecond line\r\n\r\n";
+ Assert::That(lines, Has().Exactly(2).OfLength(0));
+ }
+
+ std::cout << "CanHandleLastLineMissingNewlineForWindowsLineEndings" << std::endl;
+ {
+ std::string lines = "First line\r\nSecond line";
+ Assert::That(lines, Has().Exactly(2).EndingWith("line"));
+ }
+
+ std::cout << "CanHandleAllEmptyLines" << std::endl;
+ {
+ Assert::That("\n\n\n\n\n\n", Has().Exactly(6).OfLength(0));
+ }
+
+ std::cout << "CanHandleAllEmptyLinesWithWindowsLineEndings" << std::endl;
+ {
+ Assert::That("\r\n\r\n\r\n", Has().Exactly(3).OfLength(0));
+ }
+
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " StringLineParserTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+
+ std::cout << "CanParseEmptyString" << std::endl;
+ {
+ std::vector<std::string> res;
+
+ StringLineParser::Parse("", res);
+
+ Assert::That(res, HasLength(0));
+ }
+
+ std::cout << "CanParseSingleLine" << std::endl;
+ {
+ std::vector<std::string> res;
+
+ StringLineParser::Parse("Simple line", res);
+
+ Assert::That(res, HasLength(1));
+ Assert::That(res, Has().Exactly(1).EqualTo("Simple line"));
+ }
+
+ std::cout << "CanParseTwoLines" << std::endl;
+ {
+ std::vector<std::string> res;
+
+ StringLineParser::Parse("One line\nTwo lines", res);
+
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Two lines"));
+ }
+
+ std::cout << "CanParseThreeLines" << std::endl;
+ {
+ std::vector<std::string> res;
+
+ StringLineParser::Parse("One line\nTwo lines\nThree lines", res);
+
+ Assert::That(res, HasLength(3));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Two lines"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Three lines"));
+ }
+
+ std::cout << "CanHandleStringEndingWithNewline" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("One line\n", res);
+ Assert::That(res, HasLength(1));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ }
+
+ std::cout << "CanHandleSingleLineWithWindowsLineEnding" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("One line\r\n", res);
+ Assert::That(res, HasLength(1));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ }
+
+ std::cout << "CanHandleTwoLinesWithWindowsLineEndings" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("One line\r\nTwo lines", res);
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Two lines"));
+ }
+
+ std::cout << "CanHandleEmptyLineWithNewline" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("\n", res);
+ Assert::That(res, Is().OfLength(1).And().Exactly(1).OfLength(0));
+ }
+
+ std::cout << "CanHandleTwoEmptyLines" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("\n\n", res);
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(2).OfLength(0));
+ }
+
+ std::cout << "CanHandleTwoEmptyLinesWithWindowsLineEndings" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("\r\n\r\n", res);
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(2).OfLength(0));
+ }
+
+ std::cout << "CanHandleCarriageReturnOnly" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("One line\rTwo lines", res);
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Two lines"));
+ }
+
+ std::cout << "CanHandleCarriageReturnOnlyAtEndOfString" << std::endl;
+ {
+ std::vector<std::string> res;
+ StringLineParser::Parse("One line\r\nTwo lines\r", res);
+ Assert::That(res, HasLength(2));
+ Assert::That(res, Has().Exactly(1).EqualTo("One line"));
+ Assert::That(res, Has().Exactly(1).EqualTo("Two lines"));
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_tests.cpp
new file mode 100644
index 00000000..989ad42b
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/string_tests.cpp
@@ -0,0 +1,65 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+void StringTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " StringTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleStringContainsConstraint" << std::endl;
+ {
+ Assert::That("abcdef", Contains("bcde"));
+ }
+
+ std::cout << "StringConstraintShouldHandleMatchAtBeginningOfString" << std::endl;
+ {
+ Assert::That("abcdef", Contains("a"));
+ }
+
+ std::cout << "ShouldDetectFailingContains" << std::endl;
+ {
+ AssertTestFails(Assert::That("abcdef", Contains("hello")), "contains hello");
+ }
+
+ std::cout << "ShouldHandleStringStartingWithConstraint" << std::endl;
+ {
+ Assert::That("abcdef", StartsWith("abc"));
+ }
+
+ std::cout << "ShouldHandleStringEndingWithConstraint" << std::endl;
+ {
+ Assert::That("abcdef", EndsWith("def"));
+ }
+
+ std::cout << "ShouldHandleOperatorsForStrings" << std::endl;
+ {
+ Assert::That("abcdef", StartsWith("ab") && EndsWith("ef"));
+ }
+
+ std::cout << "ShouldHandleStringsWithMultipleOperators" << std::endl;
+ {
+ Assert::That("abcdef", StartsWith("ab") && !EndsWith("qwqw"));
+ }
+
+ std::cout << "ShouldHandleOfLength" << std::endl;
+ {
+ Assert::That("12345", HasLength(5));
+ }
+
+ std::cout << "ShouldHandleWeirdLongExpressions" << std::endl;
+ {
+ Assert::That("12345", HasLength(5) && StartsWith("123") && !EndsWith("zyxxy"));
+ }
+
+ std::cout << "ShouldHandleStdStrings" << std::endl;
+ {
+ Assert::That("12345", Contains(std::string("23")));
+ }
+
+ std::cout << "ShouldHandleSimpleChar" << std::endl;
+ {
+ Assert::That("12345", StartsWith('1'));
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/stringize_tests.cpp b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/stringize_tests.cpp
new file mode 100644
index 00000000..a0971274
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/stringize_tests.cpp
@@ -0,0 +1,111 @@
+#include <snowhouse/snowhouse.h>
+using namespace snowhouse;
+#include "tests.h"
+
+namespace
+{
+ // No overload for operator<<(std::ostream&) or specialization of igloo::Stringizer
+ struct WithoutStreamOperator
+ {
+ WithoutStreamOperator(int id)
+ : m_id(id)
+ {
+ }
+
+ bool operator==(const WithoutStreamOperator& rhs) const
+ {
+ return m_id == rhs.m_id;
+ }
+
+ int m_id;
+ };
+
+ // Has operator<<(std::ostream&)
+ struct WithStreamOperator : public WithoutStreamOperator
+ {
+ WithStreamOperator(int id)
+ : WithoutStreamOperator(id)
+ {
+ }
+ };
+
+ std::ostream& operator<<(std::ostream& stream, const WithStreamOperator& a)
+ {
+ stream << a.m_id;
+ return stream;
+ }
+
+ // Has no operator<<(std::ostream&), but a specialization of igloo::Stringizer
+ struct WithoutStreamOperatorButWithStringizer : public WithoutStreamOperator
+ {
+ WithoutStreamOperatorButWithStringizer(int id)
+ : WithoutStreamOperator(id)
+ {
+ }
+ };
+}
+
+namespace snowhouse {
+
+ template<>
+ struct Stringizer< WithoutStreamOperatorButWithStringizer >
+ {
+ static std::string ToString(const WithoutStreamOperatorButWithStringizer& value)
+ {
+ return snowhouse::Stringize(value.m_id);
+ }
+ };
+}
+
+void StringizeTests()
+{
+ std::cout << "================================================" << std::endl;
+ std::cout << " StringizeTests" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleTypesWithStreamOperators" << std::endl;
+ {
+ WithStreamOperator a(12);
+ WithStreamOperator b(13);
+ AssertTestFails(Assert::That(a, Is().EqualTo(b)), "Expected: equal to 13\nActual: 12");
+ }
+
+ std::cout << "ShouldHandleTypesWithoutStreamOperators" << std::endl;
+ {
+ WithoutStreamOperator a(12);
+ WithoutStreamOperator b(13);
+ AssertTestFails(Assert::That(a, Is().EqualTo(b)), "Expected: equal to [unsupported type]\nActual: [unsupported type]");
+ }
+
+ std::cout << "ShouldHandleTypesWithTraits" << std::endl;
+ {
+ WithoutStreamOperatorButWithStringizer a(12);
+ WithoutStreamOperatorButWithStringizer b(13);
+ AssertTestFails(Assert::That(a, Is().EqualTo(b)), "Expected: equal to 13\nActual: 12");
+ }
+
+ std::cout << "================================================" << std::endl;
+ std::cout << " StringizeTestsExpressionTemplates" << std::endl;
+ std::cout << "================================================" << std::endl;
+
+ std::cout << "ShouldHandleTypesWithStreamOperators" << std::endl;
+ {
+ WithStreamOperator a(12);
+ WithStreamOperator b(13);
+ AssertTestFails(Assert::That(a, Equals(b)), "Expected: equal to 13\nActual: 12");
+ }
+
+ std::cout << "ShouldHandleTypesWithoutStreamOperators" << std::endl;
+ {
+ WithoutStreamOperator a(12);
+ WithoutStreamOperator b(13);
+ AssertTestFails(Assert::That(a, Equals(b)), "Expected: equal to [unsupported type]\nActual: [unsupported type]");
+ }
+
+ std::cout << "ShouldHandleTypesWithTraits" << std::endl;
+ {
+ WithoutStreamOperatorButWithStringizer a(12);
+ WithoutStreamOperatorButWithStringizer b(13);
+ AssertTestFails(Assert::That(a, Is().EqualTo(b)), "Expected: equal to 13\nActual: 12");
+ }
+}
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/tests.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/tests.h
new file mode 100644
index 00000000..9dd1d28c
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/example/tests.h
@@ -0,0 +1,16 @@
+#ifndef SNOWHOUSE_EXAMPLES_TEST_H
+#define SNOWHOUSE_EXAMPLES_TEST_H
+
+#define AssertTestFails(assertion, expected_error_text) \
+ std::string IGLOO_INTERNAL_expected_error = "Test did not fail"; \
+ try \
+ { \
+ assertion; \
+ } \
+ catch(const AssertionException& exception_from_igloo_assertion) \
+ { \
+ IGLOO_INTERNAL_expected_error = exception_from_igloo_assertion.GetMessage(); \
+ } \
+ Assert::That(IGLOO_INTERNAL_expected_error, Is().Containing(expected_error_text));
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assert.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assert.h
new file mode 100644
index 00000000..64981094
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assert.h
@@ -0,0 +1,126 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ASSERT_H
+#define IGLOO_ASSERT_H
+
+#include "stringize.h"
+#include "stringizers.h"
+
+namespace snowhouse {
+
+ struct DefaultFailureHandler
+ {
+ template <class ExpectedType, class ActualType>
+ static void Handle(const ExpectedType& expected, const ActualType& actual, const char* file_name, int line_number)
+ {
+ std::ostringstream str;
+
+ str << "Expected: " << snowhouse::Stringize(expected) << std::endl;
+ str << "Actual: " << snowhouse::Stringize(actual) << std::endl;
+
+ throw AssertionException(str.str(), file_name, line_number);
+ }
+
+ static void Handle(const std::string& message)
+ {
+ throw AssertionException(message);
+ }
+ };
+
+ template<typename FailureHandler>
+ class ConfigurableAssert
+ {
+ public:
+
+ template <typename ActualType, typename ConstraintListType>
+ static void That(const ActualType& actual, ExpressionBuilder<ConstraintListType> expression)
+ {
+ const char* no_file = "";
+ int line_number = 0;
+
+ ConfigurableAssert<FailureHandler>::That(actual, expression, no_file, line_number);
+ }
+
+ template <typename ActualType, typename ConstraintListType>
+ static void That(const ActualType& actual, ExpressionBuilder<ConstraintListType> expression, const char* file_name, int line_number)
+ {
+ try
+ {
+ ResultStack result;
+ OperatorStack operators;
+ expression.Evaluate(result, operators, actual);
+
+ while (!operators.empty())
+ {
+ ConstraintOperator* op = operators.top();
+ op->PerformOperation(result);
+ operators.pop();
+ }
+
+ if (result.empty())
+ {
+ throw InvalidExpressionException("The expression did not yield any result");
+ }
+
+ if (!result.top())
+ {
+ FailureHandler::Handle(expression, actual, file_name, line_number);
+ }
+ }
+ catch (const InvalidExpressionException& e)
+ {
+ FailureHandler::Handle("Malformed expression: \"" + snowhouse::Stringize(expression) + "\"\n" + e.Message());
+ }
+ }
+
+ template <typename ConstraintListType>
+ static void That(const char* actual, ExpressionBuilder<ConstraintListType> expression)
+ {
+ return That(std::string(actual), expression);
+ }
+
+ template <typename ActualType, typename ExpressionType>
+ static void That(const ActualType& actual, const ExpressionType& expression)
+ {
+ const char* no_file = "";
+ int no_line = 0;
+ That(actual, expression, no_file, no_line);
+ }
+
+ template <typename ActualType, typename ExpressionType>
+ static void That(const ActualType& actual, const ExpressionType& expression, const char* file_name, int line_number)
+ {
+ if (!expression(actual))
+ {
+ FailureHandler::Handle(expression, actual, file_name, line_number);
+ }
+ }
+
+ template <typename ExpressionType>
+ static void That(const char* actual, const ExpressionType& expression)
+ {
+ return That(std::string(actual), expression);
+ }
+
+ static void That(bool actual)
+ {
+ if (!actual)
+ {
+ FailureHandler::Handle("Expected: true\nActual: false");
+ }
+ }
+
+ static void Failure(const std::string& message)
+ {
+ FailureHandler::Handle(message);
+ }
+ };
+
+ typedef ConfigurableAssert<DefaultFailureHandler> Assert;
+}
+
+#endif // IGLOO_ASSERT_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertionexception.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertionexception.h
new file mode 100644
index 00000000..d0747742
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertionexception.h
@@ -0,0 +1,58 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ASSERTIONEXCEPTION_H
+#define IGLOO_ASSERTIONEXCEPTION_H
+
+namespace snowhouse {
+ class AssertionException : public std::exception
+ {
+ public:
+ AssertionException(const std::string& message)
+ : m_message(message), m_fileName(""), m_line(0)
+ {}
+
+ AssertionException(const std::string& message, const std::string& fileName, unsigned int line)
+ : m_message(message), m_fileName(fileName), m_line(line)
+ {}
+
+#if __cplusplus > 199711L
+ AssertionException(const AssertionException&) = default;
+#endif
+
+#if __cplusplus > 199711L
+ virtual ~AssertionException() noexcept
+ {
+ }
+#else
+ virtual ~AssertionException() throw()
+ {
+ }
+#endif
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+
+ std::string GetFilename() const
+ {
+ return m_fileName;
+ }
+
+ unsigned int GetLineNumber() const
+ {
+ return m_line;
+ }
+
+ private:
+ std::string m_message;
+ std::string m_fileName;
+ unsigned int m_line;
+ };
+}
+
+#endif // IGLOO_ASSERTIONEXCEPTION_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertmacro.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertmacro.h
new file mode 100644
index 00000000..df5b4b34
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/assertmacro.h
@@ -0,0 +1,22 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ASSERTMACRO_H
+#define IGLOO_ASSERTMACRO_H
+
+#include "assert.h"
+
+#define SNOWHOUSE_ASSERT_THAT(p1,p2,FAILURE_HANDLER)\
+ ::snowhouse::ConfigurableAssert<FAILURE_HANDLER>::That((p1), (p2), __FILE__, __LINE__);\
+
+#ifndef SNOWHOUSE_NO_MACROS
+
+#define AssertThat(p1,p2)\
+ SNOWHOUSE_ASSERT_THAT((p1), (p2), ::snowhouse::DefaultFailureHandler);\
+
+#endif // SNOWHOUSE_NO_MACROS
+
+#endif // IGLOO_ASSERTMACRO_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/constraints.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/constraints.h
new file mode 100644
index 00000000..a12433d1
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/constraints.h
@@ -0,0 +1,23 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_CONSTRAINTS_H
+#define IGLOO_CONSTRAINTS_H
+
+#include "containsconstraint.h"
+#include "endswithconstraint.h"
+#include "equalsconstraint.h"
+#include "haslengthconstraint.h"
+#include "isgreaterthanconstraint.h"
+#include "isgreaterthanorequaltoconstraint.h"
+#include "islessthanconstraint.h"
+#include "islessthanorequaltoconstraint.h"
+#include "startswithconstraint.h"
+#include "fulfillsconstraint.h"
+#include "equalswithdeltaconstraint.h"
+#include "equalscontainerconstraint.h"
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/containsconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/containsconstraint.h
new file mode 100644
index 00000000..f20d6800
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/containsconstraint.h
@@ -0,0 +1,80 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_CONTAINSCONSTRAINT_H
+#define IGLOO_CONTAINSCONSTRAINT_H
+
+#include <algorithm>
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template <typename ContainerType>
+ struct find_in_container_traits
+ {
+ template <typename ExpectedType>
+ static bool find(const ContainerType& container, const ExpectedType& expected)
+ {
+ return std::find(container.begin(), container.end(), expected) != container.end();
+ }
+ };
+
+ template <typename KeyType, typename ValueType>
+ struct find_in_container_traits<std::map<KeyType, ValueType> >
+ {
+ template <typename ExpectedType>
+ static bool find(const std::map<KeyType, ValueType>& container, const ExpectedType& expected)
+ {
+ return container.find(expected) != container.end();
+ }
+ };
+
+ template <typename ExpectedType>
+ struct ContainsConstraint : Expression< ContainsConstraint<ExpectedType> >
+ {
+ ContainsConstraint(const ExpectedType& expected)
+ : m_expected(expected) {}
+
+ template <typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return find_in_container_traits<ActualType>::find(actual, m_expected);
+ }
+
+ bool operator()(const std::string& actual) const
+ {
+ return actual.find(m_expected) != actual.npos;
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline ContainsConstraint<ExpectedType> Contains(const ExpectedType& expected)
+ {
+ return ContainsConstraint<ExpectedType>(expected);
+ }
+
+ inline ContainsConstraint<std::string> Contains(const char* expected)
+ {
+ return ContainsConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< ContainsConstraint< ExpectedType > >
+ {
+ static std::string ToString(const ContainsConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "contains " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/endswithconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/endswithconstraint.h
new file mode 100644
index 00000000..c867e203
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/endswithconstraint.h
@@ -0,0 +1,53 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ENDSWITHCONSTRAINT_H
+#define IGLOO_ENDSWITHCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template <typename ExpectedType>
+ struct EndsWithConstraint : Expression< EndsWithConstraint<ExpectedType> >
+ {
+ EndsWithConstraint(const ExpectedType& expected)
+ : m_expected(expected) {}
+
+ bool operator()(const std::string& actual) const
+ {
+ size_t expectedPos = actual.length() - m_expected.length();
+ return actual.find(m_expected) == expectedPos;
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline EndsWithConstraint<ExpectedType> EndsWith(const ExpectedType& expected)
+ {
+ return EndsWithConstraint<ExpectedType>(expected);
+ }
+
+ inline EndsWithConstraint<std::string> EndsWith(const char* expected)
+ {
+ return EndsWithConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< EndsWithConstraint< ExpectedType > >
+ {
+ static std::string ToString(const EndsWithConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "ends with " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalsconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalsconstraint.h
new file mode 100644
index 00000000..a47f6bf4
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalsconstraint.h
@@ -0,0 +1,83 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EQUALSCONSTRAINT_H
+#define IGLOO_EQUALSCONSTRAINT_H
+
+#include <cstddef>
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType >
+ struct EqualsConstraint : Expression< EqualsConstraint<ExpectedType> >
+ {
+ EqualsConstraint(const ExpectedType& expected)
+ : m_expected(expected)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return (m_expected == actual);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline EqualsConstraint<ExpectedType> Equals(const ExpectedType& expected)
+ {
+ return EqualsConstraint<ExpectedType>(expected);
+ }
+
+ inline EqualsConstraint<std::string> Equals(const char* expected)
+ {
+ return EqualsConstraint<std::string>(expected);
+ }
+
+ inline EqualsConstraint<bool> IsFalse()
+ {
+ return EqualsConstraint<bool>(false);
+ }
+
+ inline EqualsConstraint<bool> IsTrue()
+ {
+ return EqualsConstraint<bool>(true);
+ }
+
+#if __cplusplus > 199711L
+ inline EqualsConstraint<std::nullptr_t> IsNull()
+ {
+ return EqualsConstraint<std::nullptr_t>(nullptr);
+ }
+#endif
+
+ template <>
+ struct Stringizer< EqualsConstraint< bool > >
+ {
+ static std::string ToString(const EqualsConstraint<bool>& constraint)
+ {
+ return constraint.m_expected ? "true" : "false";
+ }
+ };
+
+ template< typename ExpectedType >
+ struct Stringizer< EqualsConstraint< ExpectedType > >
+ {
+ static std::string ToString(const EqualsConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "equal to " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalscontainerconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalscontainerconstraint.h
new file mode 100644
index 00000000..f8650952
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalscontainerconstraint.h
@@ -0,0 +1,80 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EQUALSCONTAINERCONSTRAINT_H
+#define IGLOO_EQUALSCONTAINERCONSTRAINT_H
+
+namespace snowhouse {
+
+ namespace constraint_internal {
+ template<typename T>
+ inline bool default_comparer(const T& lhs, const T& rhs)
+ {
+ return lhs == rhs;
+ }
+ }
+
+ template< typename ExpectedType, typename BinaryPredicate>
+ struct EqualsContainerConstraint : Expression< EqualsContainerConstraint<ExpectedType, BinaryPredicate> >
+ {
+ EqualsContainerConstraint(const ExpectedType& expected, const BinaryPredicate predicate)
+ : expected_(expected), predicate_(predicate)
+ {}
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ typename ActualType::const_iterator actual_it;
+ typename ExpectedType::const_iterator expected_it;
+
+ for(actual_it = actual.begin(), expected_it = expected_.begin(); actual_it != actual.end() && expected_it != expected_.end(); actual_it++, expected_it++)
+ {
+ if(!predicate_(*actual_it, *expected_it))
+ {
+ return false;
+ }
+ }
+
+ return actual.size() == expected_.size();
+ }
+
+ const ExpectedType expected_;
+ const BinaryPredicate predicate_;
+
+ private:
+
+#if __cplusplus > 199711L
+#else
+ EqualsContainerConstraint& operator=(const EqualsContainerConstraint&) { return *this; }
+#endif
+
+ };
+
+ template< typename ExpectedType>
+ inline EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)> EqualsContainer(const ExpectedType& expected)
+ {
+ return EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)>(expected, constraint_internal::default_comparer);
+ }
+
+ template< typename ExpectedType, typename BinaryPredicate >
+ inline EqualsContainerConstraint<ExpectedType, BinaryPredicate> EqualsContainer(const ExpectedType& expected, const BinaryPredicate predicate)
+ {
+ return EqualsContainerConstraint<ExpectedType, BinaryPredicate>(expected, predicate);
+ }
+
+ template< typename ExpectedType, typename BinaryPredicate >
+ struct Stringizer< EqualsContainerConstraint<ExpectedType, BinaryPredicate> >
+ {
+ static std::string ToString(const EqualsContainerConstraint<ExpectedType, BinaryPredicate>& constraint)
+ {
+ std::ostringstream builder;
+ builder << snowhouse::Stringize(constraint.expected_);
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalswithdeltaconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalswithdeltaconstraint.h
new file mode 100644
index 00000000..b54fb74e
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/equalswithdeltaconstraint.h
@@ -0,0 +1,51 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EQUALSWITHDELTACONSTRAINT_H
+#define IGLOO_EQUALSWITHDELTACONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType, typename DeltaType >
+ struct EqualsWithDeltaConstraint : Expression< EqualsWithDeltaConstraint<ExpectedType, DeltaType> >
+ {
+ EqualsWithDeltaConstraint(const ExpectedType& expected, const DeltaType& delta)
+ : m_expected(expected), m_delta(delta)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return ((m_expected <= (actual + m_delta)) && (m_expected >= (actual - m_delta)));
+ }
+
+ ExpectedType m_expected;
+ DeltaType m_delta;
+ };
+
+ template< typename ExpectedType, typename DeltaType >
+ inline EqualsWithDeltaConstraint<ExpectedType, DeltaType> EqualsWithDelta(const ExpectedType& expected, const DeltaType& delta)
+ {
+ return EqualsWithDeltaConstraint<ExpectedType, DeltaType>(expected, delta);
+ }
+
+ template< typename ExpectedType, typename DeltaType >
+ struct Stringizer< EqualsWithDeltaConstraint< ExpectedType, DeltaType > >
+ {
+ static std::string ToString(const EqualsWithDeltaConstraint<ExpectedType, DeltaType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "equal to " << snowhouse::Stringize(constraint.m_expected) << " (+/- " << snowhouse::Stringize(constraint.m_delta) << ")";
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/andexpression.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/andexpression.h
new file mode 100644
index 00000000..8b6b7d12
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/andexpression.h
@@ -0,0 +1,46 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ANDEXPRESSION_H
+#define IGLOO_ANDEXPRESSION_H
+
+#include "./expression_fwd.h"
+
+namespace snowhouse {
+
+ template< typename LeftExpression, typename RightExpression >
+ struct AndExpression : Expression< AndExpression<LeftExpression, RightExpression> >
+ {
+ AndExpression(const LeftExpression& left, const RightExpression& right)
+ : m_left(left)
+ , m_right(right)
+ {
+ }
+
+ template< typename ActualType >
+ bool operator()(const ActualType& actual) const
+ {
+ return (m_left(actual) && m_right(actual));
+ }
+
+ LeftExpression m_left;
+ RightExpression m_right;
+ };
+
+ template< typename LeftExpression, typename RightExpression >
+ struct Stringizer< AndExpression<LeftExpression, RightExpression> >
+ {
+ static std::string ToString(const AndExpression<LeftExpression, RightExpression>& expression)
+ {
+ std::ostringstream builder;
+ builder << Stringize(expression.m_left) << " and " << Stringize(expression.m_right);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression.h
new file mode 100644
index 00000000..fa894818
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression.h
@@ -0,0 +1,38 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EXPRESSION_H
+#define IGLOO_EXPRESSION_H
+
+#include "./notexpression.h"
+#include "./andexpression.h"
+#include "./orexpression.h"
+
+namespace snowhouse {
+
+ template<typename T>
+ struct Expression
+ {
+ NotExpression<T> operator!() const
+ {
+ return NotExpression<T>(static_cast<const T&>(*this));
+ }
+
+ template< typename Right >
+ AndExpression<T, Right> operator&&(const Right& right) const
+ {
+ return AndExpression<T, Right>(static_cast<const T&>(*this), right);
+ }
+
+ template< typename Right >
+ OrExpression<T, Right> operator||(const Right& right) const
+ {
+ return OrExpression<T, Right>(static_cast<const T&>(*this), right);
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression_fwd.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression_fwd.h
new file mode 100644
index 00000000..c0e3706e
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/expression_fwd.h
@@ -0,0 +1,15 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EXPRESSION_FWD_H
+#define IGLOO_EXPRESSION_FWD_H
+
+namespace snowhouse {
+ template<typename T>
+ struct Expression;
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/notexpression.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/notexpression.h
new file mode 100644
index 00000000..4785f07b
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/notexpression.h
@@ -0,0 +1,44 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_NOTEXPRESSION_H
+#define IGLOO_NOTEXPRESSION_H
+
+#include "./expression_fwd.h"
+
+namespace snowhouse {
+
+ template< typename ExpressionType >
+ struct NotExpression : Expression< NotExpression<ExpressionType> >
+ {
+ NotExpression(const ExpressionType& expression)
+ : m_expression(expression)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return !m_expression(actual);
+ }
+
+ ExpressionType m_expression;
+ };
+
+ template< typename ExpressionType >
+ struct Stringizer< NotExpression<ExpressionType> >
+ {
+ static std::string ToString(const NotExpression<ExpressionType>& expression)
+ {
+ std::ostringstream builder;
+ builder << "not " << snowhouse::Stringize(expression.m_expression);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/orexpression.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/orexpression.h
new file mode 100644
index 00000000..c1b6c12b
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/expressions/orexpression.h
@@ -0,0 +1,46 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_OREXPRESSION_H
+#define IGLOO_OREXPRESSION_H
+
+#include "./expression_fwd.h"
+
+namespace snowhouse {
+
+ template< typename LeftExpression, typename RightExpression >
+ struct OrExpression : Expression< OrExpression<LeftExpression, RightExpression> >
+ {
+ OrExpression(const LeftExpression& left, const RightExpression& right)
+ : m_left(left)
+ , m_right(right)
+ {
+ }
+
+ template< typename ActualType >
+ bool operator()(const ActualType& actual) const
+ {
+ return (m_left(actual) || m_right(actual));
+ }
+
+ LeftExpression m_left;
+ RightExpression m_right;
+ };
+
+ template< typename LeftExpression, typename RightExpression >
+ struct Stringizer< OrExpression<LeftExpression, RightExpression> >
+ {
+ static std::string ToString(const OrExpression<LeftExpression, RightExpression>& expression)
+ {
+ std::ostringstream builder;
+ builder << snowhouse::Stringize(expression.m_left) << " or " << snowhouse::Stringize(expression.m_right);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/fulfillsconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/fulfillsconstraint.h
new file mode 100644
index 00000000..577056c1
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/fulfillsconstraint.h
@@ -0,0 +1,51 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef FULFILLSCONSTRAINT_H
+#define FULFILLSCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename MatcherType >
+ struct FulfillsConstraint : Expression< FulfillsConstraint<MatcherType> >
+ {
+ FulfillsConstraint(const MatcherType& matcher)
+ : m_matcher(matcher)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return m_matcher.Matches(actual);
+ }
+
+ MatcherType m_matcher;
+ };
+
+ template< typename MatcherType >
+ inline FulfillsConstraint<MatcherType> Fulfills(const MatcherType& matcher)
+ {
+ return FulfillsConstraint<MatcherType>(matcher);
+ }
+
+ template< typename MatcherType >
+ struct Stringizer< FulfillsConstraint< MatcherType > >
+ {
+ static std::string ToString(const FulfillsConstraint<MatcherType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << snowhouse::Stringize(constraint.m_matcher);
+
+ return builder.str();
+ }
+ };
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/haslengthconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/haslengthconstraint.h
new file mode 100644
index 00000000..fb6e7cc9
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/haslengthconstraint.h
@@ -0,0 +1,60 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_HASLENGTHCONSTRAINT_H
+#define IGLOO_HASLENGTHCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template <typename ExpectedType>
+ struct HasLengthConstraint : Expression< HasLengthConstraint<ExpectedType> >
+ {
+ HasLengthConstraint(const ExpectedType& expected)
+ : m_expected(expected) {}
+
+ template <typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ typedef typename ActualType::size_type SizeType;
+ SizeType expectedSize = static_cast<SizeType>(m_expected);
+ return (actual.size() == expectedSize);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline HasLengthConstraint<ExpectedType> HasLength(const ExpectedType& expected)
+ {
+ return HasLengthConstraint<ExpectedType>(expected);
+ }
+
+ inline HasLengthConstraint<int> IsEmpty()
+ {
+ return HasLength<int>(0);
+ }
+
+ inline HasLengthConstraint<std::string> HasLength(const char* expected)
+ {
+ return HasLengthConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< HasLengthConstraint< ExpectedType > >
+ {
+ static std::string ToString(const HasLengthConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "of length " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanconstraint.h
new file mode 100644
index 00000000..e7ef01f8
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanconstraint.h
@@ -0,0 +1,55 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ISGREATERTHANCONSTRAINT_H
+#define IGLOO_ISGREATERTHANCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType >
+ struct IsGreaterThanConstraint : Expression< IsGreaterThanConstraint<ExpectedType> >
+ {
+ IsGreaterThanConstraint(const ExpectedType& expected)
+ : m_expected(expected)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return (actual > m_expected);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline IsGreaterThanConstraint<ExpectedType> IsGreaterThan(const ExpectedType& expected)
+ {
+ return IsGreaterThanConstraint<ExpectedType>(expected);
+ }
+
+ inline IsGreaterThanConstraint<std::string> IsGreaterThan(const char* expected)
+ {
+ return IsGreaterThanConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< IsGreaterThanConstraint< ExpectedType > >
+ {
+ static std::string ToString(const IsGreaterThanConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "greater than " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanorequaltoconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanorequaltoconstraint.h
new file mode 100644
index 00000000..3752887b
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/isgreaterthanorequaltoconstraint.h
@@ -0,0 +1,55 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ISGREATERTHANOREQUALTOCONSTRAINT_H
+#define IGLOO_ISGREATERTHANOREQUALTOCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType >
+ struct IsGreaterThanOrEqualToConstraint : Expression < IsGreaterThanOrEqualToConstraint<ExpectedType> >
+ {
+ IsGreaterThanOrEqualToConstraint(const ExpectedType& expected)
+ : m_expected(expected)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return (actual >= m_expected);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline IsGreaterThanOrEqualToConstraint<ExpectedType> IsGreaterThanOrEqualTo(const ExpectedType& expected)
+ {
+ return IsGreaterThanOrEqualToConstraint<ExpectedType>(expected);
+ }
+
+ inline IsGreaterThanOrEqualToConstraint<std::string> IsGreaterThanOrEqualTo(const char* expected)
+ {
+ return IsGreaterThanOrEqualToConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer < IsGreaterThanOrEqualToConstraint< ExpectedType > >
+ {
+ static std::string ToString(const IsGreaterThanOrEqualToConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "greater than or equal to " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanconstraint.h
new file mode 100644
index 00000000..7379dcf7
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanconstraint.h
@@ -0,0 +1,54 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ISLESSTHANCONSTRAINT_H
+#define IGLOO_ISLESSTHANCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType >
+ struct IsLessThanConstraint : Expression< IsLessThanConstraint<ExpectedType> >
+ {
+ IsLessThanConstraint(const ExpectedType& expected)
+ : m_expected(expected)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return (actual < m_expected);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline IsLessThanConstraint<ExpectedType> IsLessThan(const ExpectedType& expected)
+ {
+ return IsLessThanConstraint<ExpectedType>(expected);
+ }
+
+ inline IsLessThanConstraint<std::string> IsLessThan(const char* expected)
+ {
+ return IsLessThanConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< IsLessThanConstraint< ExpectedType > >
+ {
+ static std::string ToString(const IsLessThanConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "less than " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanorequaltoconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanorequaltoconstraint.h
new file mode 100644
index 00000000..36e02ab4
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/islessthanorequaltoconstraint.h
@@ -0,0 +1,55 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ISLESSTHANOREQUALTOCONSTRAINT_H
+#define IGLOO_ISLESSTHANOREQUALTOCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template< typename ExpectedType >
+ struct IsLessThanOrEqualToConstraint : Expression < IsLessThanOrEqualToConstraint<ExpectedType> >
+ {
+ IsLessThanOrEqualToConstraint(const ExpectedType& expected)
+ : m_expected(expected)
+ {
+ }
+
+ template<typename ActualType>
+ bool operator()(const ActualType& actual) const
+ {
+ return (actual <= m_expected);
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline IsLessThanOrEqualToConstraint<ExpectedType> IsLessThanOrEqualTo(const ExpectedType& expected)
+ {
+ return IsLessThanOrEqualToConstraint<ExpectedType>(expected);
+ }
+
+ inline IsLessThanOrEqualToConstraint<std::string> IsLessThanOrEqualTo(const char* expected)
+ {
+ return IsLessThanOrEqualToConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer < IsLessThanOrEqualToConstraint< ExpectedType > >
+ {
+ static std::string ToString(const IsLessThanOrEqualToConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "less than or equal to " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/startswithconstraint.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/startswithconstraint.h
new file mode 100644
index 00000000..ffdd1696
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/constraints/startswithconstraint.h
@@ -0,0 +1,52 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_STARTSWITHCONSTRAINT_H
+#define IGLOO_STARTSWITHCONSTRAINT_H
+
+#include "./expressions/expression.h"
+
+namespace snowhouse {
+
+ template <typename ExpectedType>
+ struct StartsWithConstraint : Expression< StartsWithConstraint<ExpectedType> >
+ {
+ StartsWithConstraint(const ExpectedType& expected)
+ : m_expected(expected) {}
+
+ bool operator()(const std::string& actual) const
+ {
+ return actual.find(m_expected) == 0;
+ }
+
+ ExpectedType m_expected;
+ };
+
+ template< typename ExpectedType >
+ inline StartsWithConstraint<ExpectedType> StartsWith(const ExpectedType& expected)
+ {
+ return StartsWithConstraint<ExpectedType>(expected);
+ }
+
+ inline StartsWithConstraint<std::string> StartsWith(const char* expected)
+ {
+ return StartsWithConstraint<std::string>(expected);
+ }
+
+ template< typename ExpectedType >
+ struct Stringizer< StartsWithConstraint< ExpectedType > >
+ {
+ static std::string ToString(const StartsWithConstraint<ExpectedType>& constraint)
+ {
+ std::ostringstream builder;
+ builder << "starts with " << snowhouse::Stringize(constraint.m_expected);
+
+ return builder.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/exceptions.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/exceptions.h
new file mode 100644
index 00000000..22ad11ef
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/exceptions.h
@@ -0,0 +1,120 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EXCEPTIONS_H
+#define IGLOO_EXCEPTIONS_H
+
+#include "assert.h"
+
+namespace snowhouse {
+
+ template <typename ExceptionType>
+ class ExceptionStorage
+ {
+ public:
+ static void last_exception(ExceptionType*** e, bool clear=false)
+ {
+ static ExceptionType* last = NULL;
+ if(clear && last)
+ {
+ delete last;
+ return;
+ }
+
+ *e = &last;
+ silly_warning_about_unused_arg(e);
+ }
+
+ static ExceptionType*** silly_warning_about_unused_arg(ExceptionType*** e)
+ {
+ return e;
+ }
+
+ static void store(const ExceptionType& e)
+ {
+ ExceptionType** last = NULL;
+ last_exception(&last);
+ if(*last)
+ {
+ delete *last;
+ *last = NULL;
+ }
+
+ *last = new ExceptionType(e);
+ }
+
+ void compiler_thinks_i_am_unused() {}
+
+ ~ExceptionStorage()
+ {
+ ExceptionType** e = NULL;
+ last_exception(&e);
+ if(*e)
+ {
+ delete *e;
+ *e = NULL;
+ }
+ }
+ };
+
+ template <typename ExceptionType>
+ inline ExceptionType& LastException()
+ {
+ ExceptionType** e = NULL;
+ ExceptionStorage<ExceptionType>::last_exception(&e);
+ if(*e == NULL)
+ {
+ Assert::Failure("No exception was stored");
+ }
+
+ return **e;
+ }
+}
+
+#define IGLOO_CONCAT2(a, b) a##b
+#define IGLOO_CONCAT(a, b) IGLOO_CONCAT2(a, b)
+
+#define SNOWHOUSE_ASSERT_THROWS(EXCEPTION_TYPE, METHOD, FAILURE_HANDLER_TYPE) \
+::snowhouse::ExceptionStorage<EXCEPTION_TYPE> IGLOO_CONCAT(IGLOO_storage_, __LINE__); IGLOO_CONCAT(IGLOO_storage_, __LINE__).compiler_thinks_i_am_unused(); \
+{ \
+ bool wrong_exception = false; \
+ bool no_exception = false; \
+ try \
+ { \
+ METHOD; \
+ no_exception = true; \
+ } \
+ catch (const EXCEPTION_TYPE& e) \
+ { \
+ ::snowhouse::ExceptionStorage<EXCEPTION_TYPE>::store(e); \
+ } \
+ catch(...) \
+ { \
+ wrong_exception = true; \
+ } \
+ if(no_exception) \
+ { \
+ std::ostringstream stm; \
+ stm << "Expected " << #EXCEPTION_TYPE << ". No exception was thrown."; \
+ ::snowhouse::ConfigurableAssert<FAILURE_HANDLER_TYPE>::Failure(stm.str()); \
+ } \
+ if(wrong_exception) \
+ { \
+ std::ostringstream stm; \
+ stm << "Expected " << #EXCEPTION_TYPE << ". Wrong exception was thrown."; \
+ ::snowhouse::ConfigurableAssert<FAILURE_HANDLER_TYPE>::Failure(stm.str()); \
+ } \
+}
+
+#ifndef SNOWHOUSE_NO_MACROS
+
+#define AssertThrows(EXCEPTION_TYPE, METHOD) SNOWHOUSE_ASSERT_THROWS(EXCEPTION_TYPE, (METHOD), ::snowhouse::DefaultFailureHandler)
+
+#endif // SNOWHOUSE_NO_MACROS
+
+#endif
+
+
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintadapter.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintadapter.h
new file mode 100644
index 00000000..b1719288
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintadapter.h
@@ -0,0 +1,39 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_CONSTRAINTADAPTER_H
+#define IGLOO_CONSTRAINTADAPTER_H
+
+namespace snowhouse {
+
+ template <typename ConstraintType>
+ struct ConstraintAdapter
+ {
+ ConstraintAdapter(const ConstraintType& constraint) : m_constraint(constraint)
+ {
+ }
+
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ result.push(m_constraint(actual));
+ EvaluateConstraintList(list.m_tail, result, operators, actual);
+ }
+
+ ConstraintType m_constraint;
+ };
+
+ template<typename ConstraintType>
+ struct Stringizer< ConstraintAdapter<ConstraintType> >
+ {
+ static std::string ToString(const ConstraintAdapter<ConstraintType>& constraintAdapter)
+ {
+ return snowhouse::Stringize(constraintAdapter.m_constraint);
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintlist.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintlist.h
new file mode 100644
index 00000000..1a62a60e
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/constraintlist.h
@@ -0,0 +1,91 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_CONSTRAINT_H
+#define IGLOO_CONSTRAINT_H
+
+namespace snowhouse {
+
+ struct ConstraintOperator;
+ typedef std::stack<bool> ResultStack;
+ typedef std::stack<ConstraintOperator*> OperatorStack;
+
+ template <typename HT, typename TT>
+ struct ConstraintList
+ {
+ typedef HT HeadType;
+ typedef TT TailType;
+
+ ConstraintList(const HeadType& head, const TailType& tail)
+ : m_head(head), m_tail(tail)
+ {
+ }
+
+ HeadType m_head;
+ TailType m_tail;
+ };
+
+ struct Nil
+ {
+ Nil() {}
+ Nil(const Nil&) {}
+ };
+
+
+ // ---- These structs defines the resulting types of list concatenation operations
+ template <typename L1, typename L2>
+ struct type_concat
+ {
+ typedef ConstraintList<typename L1::HeadType, typename type_concat<typename L1::TailType, L2>::t> t;
+ };
+
+ template <typename L2> struct type_concat<Nil, L2> { typedef L2 t; };
+
+ template <typename L3> inline L3 tr_concat(const Nil&, const Nil&) { return Nil(); }
+
+
+ // ---- These structs define the concatenation operations.
+
+ template <typename LeftList, typename RightList, typename ResultList>
+ struct ListConcat
+ {
+ static ResultList Concatenate(const LeftList& left, const RightList& right)
+ {
+ return ResultList(left.m_head, ListConcat<typename LeftList::TailType, RightList, typename type_concat< typename LeftList::TailType, RightList>::t>::Concatenate(left.m_tail, right));
+ }
+ };
+
+ // Concatenating an empty list with a second list yields the second list
+ template <typename RightList, typename ResultList>
+ struct ListConcat<Nil, RightList, ResultList>
+ {
+ static ResultList Concatenate(const Nil&, const RightList& right)
+ {
+ return right;
+ }
+
+ };
+
+ // Concatenating two empty lists yields an empty list
+ template <typename ResultList>
+ struct ListConcat<Nil, Nil, ResultList>
+ {
+ static ResultList Concatenate(const Nil&, const Nil&)
+ {
+ return Nil();
+ }
+ };
+
+ // ---- The concatenation operation
+
+ template <typename L1, typename L2>
+ inline typename type_concat<L1, L2>::t Concatenate(const L1& list1, const L2& list2)
+ {
+ return ListConcat<L1, L2, typename type_concat<L1, L2>::t>::Concatenate(list1, list2);
+ }
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/expressionbuilder.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/expressionbuilder.h
new file mode 100644
index 00000000..f0889f1d
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/expressionbuilder.h
@@ -0,0 +1,357 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EXPRESSIONBUILDER_H
+#define IGLOO_EXPRESSIONBUILDER_H
+
+#include <cstddef>
+
+namespace snowhouse {
+
+ // ---- Evaluation of list of constraints
+
+ template <typename ConstraintListType, typename ActualType>
+ inline void EvaluateConstraintList(ConstraintListType& constraint_list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ constraint_list.m_head.Evaluate(constraint_list, result, operators, actual);
+ }
+
+ template <typename ActualType>
+ inline void EvaluateConstraintList(Nil&, ResultStack&, OperatorStack&, const ActualType&) {}
+
+
+ template <typename ConstraintListType>
+ struct ExpressionBuilder
+ {
+ ExpressionBuilder(const ConstraintListType& list) : m_constraint_list(list)
+ {
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<ExpectedType> >, Nil> >::t>
+ EqualTo(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<EqualsConstraint<ExpectedType> > ConstraintAdapterType;
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType, typename DeltaType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsWithDeltaConstraint<ExpectedType, DeltaType> >, Nil> >::t>
+ EqualToWithDelta(const ExpectedType& expected, const DeltaType& delta)
+ {
+ typedef ConstraintAdapter<EqualsWithDeltaConstraint<ExpectedType, DeltaType> > ConstraintAdapterType;
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+
+ ConstraintAdapterType constraint(EqualsWithDeltaConstraint<ExpectedType, DeltaType>(expected, delta));
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename MatcherType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<FulfillsConstraint<MatcherType> >, Nil> >::t>
+ Fulfilling(const MatcherType& matcher)
+ {
+ typedef ConstraintAdapter<FulfillsConstraint<MatcherType> > ConstraintAdapterType;
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+
+ ConstraintAdapterType constraint(matcher);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<bool> >, Nil> >::t>
+ False()
+ {
+ return EqualTo<bool>(false);
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<bool> >, Nil> >::t>
+ True()
+ {
+ return EqualTo<bool>(true);
+ }
+
+#if __cplusplus > 199711L
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<std::nullptr_t> >, Nil> >::t>
+ Null()
+ {
+ return EqualTo<std::nullptr_t>(nullptr);
+ }
+#endif
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsConstraint<std::string> >, Nil> >::t>
+ EqualTo(const char* expected)
+ {
+ return EqualTo<std::string>(std::string(expected));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsGreaterThanConstraint<ExpectedType> >, Nil> >::t>
+ GreaterThan(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<IsGreaterThanConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsGreaterThanOrEqualToConstraint<ExpectedType> >, Nil> >::t>
+ GreaterThanOrEqualTo(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<IsGreaterThanOrEqualToConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsLessThanConstraint<ExpectedType> >, Nil> >::t>
+ LessThan(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<IsLessThanConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<IsLessThanOrEqualToConstraint<ExpectedType> >, Nil> >::t>
+ LessThanOrEqualTo(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<IsLessThanOrEqualToConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<ContainsConstraint<ExpectedType> >, Nil> >::t>
+ Containing(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<ContainsConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<ContainsConstraint<std::string> >, Nil> >::t>
+ Containing(const char* expected)
+ {
+ return Containing<std::string>(std::string(expected));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EndsWithConstraint<ExpectedType> >, Nil> >::t>
+ EndingWith(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<EndsWithConstraint<ExpectedType> > ConstraintAdapterType;
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EndsWithConstraint<std::string> >, Nil> >::t>
+ EndingWith(const char* expected)
+ {
+ return EndingWith(std::string(expected));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<StartsWithConstraint<ExpectedType> >, Nil> >::t>
+ StartingWith(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<StartsWithConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<StartsWithConstraint<std::string> >, Nil> >::t>
+ StartingWith(const char* expected)
+ {
+ return StartingWith(std::string(expected));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<HasLengthConstraint<ExpectedType> >, Nil> >::t>
+ OfLength(const ExpectedType& expected)
+ {
+ typedef ConstraintAdapter<HasLengthConstraint<ExpectedType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(expected);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<HasLengthConstraint<int> >, Nil> >::t>
+ Empty()
+ {
+ typedef ConstraintAdapter<HasLengthConstraint<int> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(0);
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsContainerConstraint<ExpectedType, bool (*)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&)> >, Nil> >::t>
+ EqualToContainer(const ExpectedType& expected)
+ {
+ typedef bool (*DefaultBinaryPredivateType)(const typename ExpectedType::value_type&, const typename ExpectedType::value_type&);
+ typedef ConstraintAdapter<EqualsContainerConstraint<ExpectedType, DefaultBinaryPredivateType> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(EqualsContainerConstraint<ExpectedType, DefaultBinaryPredivateType>(expected, constraint_internal::default_comparer<typename ExpectedType::value_type>));
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ExpectedType, typename BinaryPredicate>
+ ExpressionBuilder<typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapter<EqualsContainerConstraint<ExpectedType, BinaryPredicate> >, Nil> >::t>
+ EqualToContainer(const ExpectedType& expected, const BinaryPredicate predicate)
+ {
+ typedef ConstraintAdapter<EqualsContainerConstraint<ExpectedType, BinaryPredicate> > ConstraintAdapterType;
+
+ typedef ExpressionBuilder< typename type_concat<ConstraintListType, ConstraintList<ConstraintAdapterType, Nil> >::t > BuilderType;
+ ConstraintAdapterType constraint(EqualsContainerConstraint<ExpectedType, BinaryPredicate>(expected, predicate));
+ ConstraintList<ConstraintAdapterType, Nil> node(constraint, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ typedef ConstraintList<AndOperator, Nil> AndOperatorNode;
+ typedef ConstraintList<OrOperator, Nil> OrOperatorNode;
+ typedef ConstraintList<NotOperator, Nil> NotOperatorNode;
+ typedef ConstraintList<AllOperator, Nil> AllOperatorNode;
+ typedef ConstraintList<AtLeastOperator, Nil> AtLeastOperatorNode;
+ typedef ConstraintList<ExactlyOperator, Nil> ExactlyOperatorNode;
+ typedef ConstraintList<AtMostOperator, Nil> AtMostOperatorNode;
+ typedef ConstraintList<NoneOperator, Nil> NoneOperatorNode;
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, AllOperatorNode>::t> All()
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, AllOperatorNode>::t> BuilderType;
+ AllOperator op;
+ AllOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, AtLeastOperatorNode>::t> AtLeast(unsigned int expected)
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, AtLeastOperatorNode>::t> BuilderType;
+ AtLeastOperator op(expected);
+ AtLeastOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, ExactlyOperatorNode>::t> Exactly(unsigned int expected)
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, ExactlyOperatorNode>::t> BuilderType;
+ ExactlyOperator op(expected);
+ ExactlyOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, AtMostOperatorNode>::t> AtMost(unsigned int expected)
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, AtMostOperatorNode>::t> BuilderType;
+ AtMostOperator op(expected);
+ AtMostOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, NoneOperatorNode>::t> None()
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, NoneOperatorNode>::t> BuilderType;
+ NoneOperator op;
+ NoneOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, AndOperatorNode>::t> And()
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, AndOperatorNode>::t> BuilderType;
+ AndOperator op;
+ AndOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, OrOperatorNode>::t> Or()
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, OrOperatorNode>::t> BuilderType;
+ OrOperator op;
+ OrOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ ExpressionBuilder<typename type_concat<ConstraintListType, NotOperatorNode>::t> Not()
+ {
+ typedef ExpressionBuilder<typename type_concat<ConstraintListType, NotOperatorNode>::t> BuilderType;
+ NotOperator op;
+ NotOperatorNode node(op, Nil());
+ return BuilderType(Concatenate(m_constraint_list, node));
+ }
+
+ template <typename ActualType>
+ void Evaluate(ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ EvaluateConstraintList(m_constraint_list, result, operators, actual);
+ }
+
+ ConstraintListType m_constraint_list;
+ };
+
+ template <typename T>
+ inline void StringizeConstraintList(const T& list, std::ostringstream& stm)
+ {
+ if (stm.tellp() > 0)
+ stm << " ";
+
+ stm << snowhouse::Stringize(list.m_head);
+ StringizeConstraintList(list.m_tail, stm);
+ }
+
+ inline void StringizeConstraintList(const Nil&, std::ostringstream&)
+ {
+ }
+
+ template<typename ConstraintListType>
+ struct Stringizer< ExpressionBuilder<ConstraintListType> >
+ {
+ static std::string ToString(const ExpressionBuilder<ConstraintListType>& builder)
+ {
+ std::ostringstream stm;
+ StringizeConstraintList(builder.m_constraint_list, stm);
+
+ return stm.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/fluent.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/fluent.h
new file mode 100644
index 00000000..6bbd4b81
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/fluent.h
@@ -0,0 +1,38 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_FLUENT_H
+#define IGLOO_FLUENT_H
+
+#include "constraintlist.h"
+#include "constraintadapter.h"
+#include "operators/constraintoperator.h"
+#include "operators/andoperator.h"
+#include "operators/oroperator.h"
+#include "operators/collections/collectionconstraintevaluator.h"
+#include "operators/collections/alloperator.h"
+#include "operators/collections/noneoperator.h"
+#include "operators/collections/atleastoperator.h"
+#include "operators/collections/exactlyoperator.h"
+#include "operators/collections/atmostoperator.h"
+#include "operators/notoperator.h"
+#include "expressionbuilder.h"
+
+namespace snowhouse {
+
+ inline ExpressionBuilder<Nil> Is()
+ {
+ return ExpressionBuilder<Nil>(Nil());
+ }
+
+ inline ExpressionBuilder<Nil> Has()
+ {
+ return ExpressionBuilder<Nil>(Nil());
+ }
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/andoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/andoperator.h
new file mode 100644
index 00000000..39670632
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/andoperator.h
@@ -0,0 +1,54 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ANDOPERATOR_H
+#define IGLOO_ANDOPERATOR_H
+
+namespace snowhouse {
+
+ struct AndOperator : public ConstraintOperator
+ {
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result);
+
+ operators.push(this);
+
+ EvaluateConstraintList(list.m_tail, result, operators, actual);
+ }
+
+ void PerformOperation(ResultStack& result)
+ {
+ if(result.size() < 2)
+ {
+ throw InvalidExpressionException("The expression contains an and operator with too few operands");
+ }
+
+ bool right = result.top();
+ result.pop();
+ bool left = result.top();
+ result.pop();
+
+ result.push(left && right);
+ }
+
+ int Precedence() const
+ {
+ return 3;
+ }
+ };
+
+ template<>
+ struct Stringizer<AndOperator>
+ {
+ static std::string ToString(const AndOperator&)
+ {
+ return "and";
+ }
+ };
+}
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/alloperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/alloperator.h
new file mode 100644
index 00000000..4157faf9
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/alloperator.h
@@ -0,0 +1,35 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ALLOPERATOR_H
+#define IGLOO_ALLOPERATOR_H
+
+#include "collectionoperator.h"
+
+namespace snowhouse {
+
+ struct AllOperator : public CollectionOperator
+ {
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
+
+ result.push(passed_elements == actual.size());
+ }
+ };
+
+ template<>
+ struct Stringizer<AllOperator>
+ {
+ static std::string ToString(const AllOperator&)
+ {
+ return "all";
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atleastoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atleastoperator.h
new file mode 100644
index 00000000..d46e697f
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atleastoperator.h
@@ -0,0 +1,41 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ATLEASTOPERATOR_H
+#define IGLOO_ATLEASTOPERATOR_H
+
+#include "collectionoperator.h"
+
+namespace snowhouse {
+
+ struct AtLeastOperator : public CollectionOperator
+ {
+ AtLeastOperator(unsigned int expected) : m_expected(expected) {}
+
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
+
+ result.push(passed_elements >= m_expected);
+ }
+
+ unsigned int m_expected;
+ };
+
+ template<>
+ struct Stringizer<AtLeastOperator>
+ {
+ static std::string ToString(const AtLeastOperator& op)
+ {
+ std::ostringstream stm;
+ stm << "at least " << op.m_expected;
+ return stm.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atmostoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atmostoperator.h
new file mode 100644
index 00000000..53debbc8
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/atmostoperator.h
@@ -0,0 +1,39 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_ATMOSTOPERATOR_H
+#define IGLOO_ATMOSTOPERATOR_H
+
+namespace snowhouse {
+
+ struct AtMostOperator : public CollectionOperator
+ {
+ AtMostOperator(unsigned int expected) : m_expected(expected) {}
+
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
+
+ result.push(passed_elements <= m_expected);
+ }
+
+ unsigned int m_expected;
+ };
+
+ template<>
+ struct Stringizer<AtMostOperator>
+ {
+ static std::string ToString(const AtMostOperator& op)
+ {
+ std::ostringstream stm;
+ stm << "at most " << op.m_expected;
+ return stm.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h
new file mode 100644
index 00000000..3fa30f2c
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h
@@ -0,0 +1,113 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_COLLECTIONCONSTRAINTEVALUATOR_H
+#define IGLOO_COLLECTIONCONSTRAINTEVALUATOR_H
+
+#include <string>
+#include "../invalidexpressionexception.h"
+
+namespace snowhouse
+{
+
+template<typename ConstraintListType, typename ActualType>
+struct CollectionConstraintEvaluator
+{
+ static unsigned int Evaluate(const ConstraintOperator& op,
+ ConstraintListType& expression, ResultStack& result,
+ OperatorStack& operators, const ActualType& actual)
+ {
+ ConstraintOperator::EvaluateOperatorsWithLessOrEqualPrecedence(op,
+ operators, result);
+
+ unsigned int passed_elements = 0;
+ typename ActualType::const_iterator it;
+ for(it = actual.begin(); it != actual.end(); it++)
+ {
+ if(ConstraintOperator::EvaluateElementAgainstRestOfExpression(expression,
+ *it))
+ {
+ passed_elements++;
+ }
+ }
+
+ return passed_elements;
+ }
+};
+
+struct StringLineParser
+{
+ static void Parse(const std::string& str, std::vector<std::string>& res)
+ {
+ size_t start = 0;
+ size_t newline = FindNewline(str, start);
+
+ while(newline != std::string::npos)
+ {
+ StoreLine(str, start, newline, res);
+ start = MoveToNextLine(str, newline);
+ newline = FindNewline(str, start);
+ }
+
+ if(start < str.size())
+ {
+ StoreLine(str, start, std::string::npos, res);
+ }
+ }
+
+private:
+ static size_t FindNewline(const std::string& str, size_t start)
+ {
+ return str.find_first_of("\r\n", start);
+ }
+
+ static void StoreLine(const std::string& str, size_t start, size_t end,
+ std::vector<std::string>& res)
+ {
+ std::string line = str.substr(start, end - start);
+ res.push_back(line);
+ }
+
+ static size_t MoveToNextLine(const std::string& str, size_t newline)
+ {
+ if(str.find("\r\n", newline) == newline)
+ {
+ return newline + 2;
+ }
+
+ if(str.find("\n", newline) == newline)
+ {
+ return newline + 1;
+ }
+
+ if(str.find("\r", newline) == newline)
+ {
+ return newline + 1;
+ }
+
+ std::ostringstream stm;
+ stm << "This string seems to contain an invalid line ending at position "
+ << newline << ":\n" << str << std::endl;
+ throw InvalidExpressionException(stm.str());
+ }
+};
+
+template<typename ConstraintListType>
+struct CollectionConstraintEvaluator<ConstraintListType, std::string>
+{
+ static unsigned int Evaluate(const ConstraintOperator& op,
+ ConstraintListType& expression, ResultStack& result,
+ OperatorStack& operators, const std::string& actual)
+ {
+ std::vector<std::string> lines;
+ StringLineParser::Parse(actual, lines);
+ return CollectionConstraintEvaluator<ConstraintListType, std::vector<std::string> >::Evaluate(op, expression, result, operators, lines);
+ }
+};
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionoperator.h
new file mode 100644
index 00000000..c1bb8bec
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/collectionoperator.h
@@ -0,0 +1,24 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_COLLECTIONOPERATOR_H
+#define IGLOO_COLLECTIONOPERATOR_H
+
+namespace snowhouse {
+ struct CollectionOperator : public ConstraintOperator
+ {
+ void PerformOperation(ResultStack&)
+ {
+ }
+
+ int Precedence() const
+ {
+ return 1;
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/exactlyoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/exactlyoperator.h
new file mode 100644
index 00000000..81c2dcaa
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/exactlyoperator.h
@@ -0,0 +1,39 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_EXACTLYOPERATOR_H
+#define IGLOO_EXACTLYOPERATOR_H
+
+namespace snowhouse {
+
+ struct ExactlyOperator : public CollectionOperator
+ {
+ ExactlyOperator(unsigned int expected) : m_expected(expected) {}
+
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
+
+ result.push(passed_elements == m_expected);
+ }
+
+ unsigned int m_expected;
+ };
+
+ template<>
+ struct Stringizer< ExactlyOperator >
+ {
+ static std::string ToString(const ExactlyOperator& op)
+ {
+ std::ostringstream stm;
+ stm << "exactly " << op.m_expected;
+ return stm.str();
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/noneoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/noneoperator.h
new file mode 100644
index 00000000..c4570915
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/collections/noneoperator.h
@@ -0,0 +1,33 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_NONEOPERATOR_H
+#define IGLOO_NONEOPERATOR_H
+
+namespace snowhouse {
+
+ struct NoneOperator : public CollectionOperator
+ {
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ unsigned int passed_elements = CollectionConstraintEvaluator<ConstraintListType, ActualType>::Evaluate(*this, list, result, operators, actual);
+ result.push(passed_elements == 0);
+ }
+ };
+
+ template<>
+ struct Stringizer<NoneOperator>
+ {
+ static std::string ToString(const NoneOperator&)
+ {
+ return "none";
+ }
+ };
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/constraintoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/constraintoperator.h
new file mode 100644
index 00000000..eafe6c51
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/constraintoperator.h
@@ -0,0 +1,70 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_CONTRAINTOPERATOR_H
+#define IGLOO_CONTRAINTOPERATOR_H
+
+#include "invalidexpressionexception.h"
+
+namespace snowhouse {
+
+ struct ConstraintOperator
+ {
+#if __cplusplus > 199711L
+#else
+ virtual ~ConstraintOperator() {}
+#endif
+
+ virtual void PerformOperation(ResultStack& result) = 0;
+ virtual int Precedence() const = 0;
+
+ template <typename ConstraintListType, typename ActualType>
+ static bool EvaluateElementAgainstRestOfExpression(ConstraintListType& list, const ActualType& actual)
+ {
+ ResultStack innerResult;
+ OperatorStack innerOperators;
+
+ EvaluateConstraintList(list.m_tail, innerResult, innerOperators, actual);
+ EvaluateAllOperatorsOnStack(innerOperators, innerResult);
+
+ if(innerResult.empty())
+ {
+ throw InvalidExpressionException("The expression after \"" + snowhouse::Stringize(list.m_head) + "\" operator does not yield any result");
+ }
+
+ return innerResult.top();
+ }
+
+ static void EvaluateOperatorsWithLessOrEqualPrecedence(const ConstraintOperator& op, OperatorStack& operators, ResultStack& result)
+ {
+ while(!operators.empty())
+ {
+ ConstraintOperator* op_from_stack = operators.top();
+
+ if(op_from_stack->Precedence() > op.Precedence())
+ {
+ break;
+ }
+
+ op_from_stack->PerformOperation(result);
+ operators.pop();
+ }
+ }
+
+ static void EvaluateAllOperatorsOnStack(OperatorStack& operators, ResultStack& result)
+ {
+ while(!operators.empty())
+ {
+ ConstraintOperator* op = operators.top();
+ op->PerformOperation(result);
+ operators.pop();
+ }
+ }
+ };
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/invalidexpressionexception.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/invalidexpressionexception.h
new file mode 100644
index 00000000..404341f1
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/invalidexpressionexception.h
@@ -0,0 +1,28 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_INVALUDEXPRESSIONEXCEPTION_H
+#define IGLOO_INVALUDEXPRESSIONEXCEPTION_H
+
+namespace snowhouse {
+
+ struct InvalidExpressionException
+ {
+ InvalidExpressionException(const std::string& message) : m_message(message)
+ {
+ }
+
+ const std::string& Message() const
+ {
+ return m_message;
+ }
+
+ std::string m_message;
+ };
+
+}
+
+#endif // IGLOO_INVALUDEXPRESSIONEXCEPTION_H
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/notoperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/notoperator.h
new file mode 100644
index 00000000..709c8413
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/notoperator.h
@@ -0,0 +1,53 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_NOTOPERATOR_H
+#define IGLOO_NOTOPERATOR_H
+
+namespace snowhouse {
+
+ struct NotOperator : public ConstraintOperator
+ {
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result);
+
+ operators.push(this);
+
+ EvaluateConstraintList(list.m_tail, result, operators, actual);
+ }
+
+ void PerformOperation(ResultStack& result)
+ {
+ if(result.size() < 1)
+ {
+ throw InvalidExpressionException("The expression contains a not operator without any operand");
+ }
+
+ bool right = result.top();
+ result.pop();
+
+ result.push(!right);
+ }
+
+ int Precedence() const
+ {
+ return 2;
+ }
+ };
+
+ template<>
+ struct Stringizer<NotOperator>
+ {
+ static std::string ToString(const NotOperator&)
+ {
+ return "not";
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/oroperator.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/oroperator.h
new file mode 100644
index 00000000..5a307ff6
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/fluent/operators/oroperator.h
@@ -0,0 +1,55 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_OROPERATOR_H
+#define IGLOO_OROPERATOR_H
+
+namespace snowhouse {
+
+ struct OrOperator : public ConstraintOperator
+ {
+ template <typename ConstraintListType, typename ActualType>
+ void Evaluate(ConstraintListType& list, ResultStack& result, OperatorStack& operators, const ActualType& actual)
+ {
+ EvaluateOperatorsWithLessOrEqualPrecedence(*this, operators, result);
+
+ operators.push(this);
+
+ EvaluateConstraintList(list.m_tail, result, operators, actual);
+ }
+
+ void PerformOperation(ResultStack& result)
+ {
+ if(result.size() < 2)
+ {
+ throw InvalidExpressionException("The expression contains an or operator with too few operands");
+ }
+
+ bool right = result.top();
+ result.pop();
+ bool left = result.top();
+ result.pop();
+
+ result.push(left || right);
+ }
+
+ int Precedence() const
+ {
+ return 4;
+ }
+ };
+
+ template<>
+ struct Stringizer<OrOperator>
+ {
+ static std::string ToString(const OrOperator&)
+ {
+ return "or";
+ }
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h
new file mode 100644
index 00000000..38214aa7
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h
@@ -0,0 +1,33 @@
+#ifndef _SNOWHOUSE_H_JK_2013_06_28
+#define _SNOWHOUSE_H_JK_2013_06_28
+
+#define SNOWHOUSE_VERSION "2.1.0"
+
+#if __cplusplus > 199711L
+#ifdef _MSC_VER
+// Visual Studio (including 2013) does not support the noexcept keyword
+#define _ALLOW_KEYWORD_MACROS
+#define noexcept
+#endif
+#endif
+
+
+#include <iostream>
+#include <map>
+#include <vector>
+#include <sstream>
+#include <stack>
+#include <list>
+#include <memory>
+#include <algorithm>
+
+#include "stringize.h"
+#include "constraints/constraints.h"
+#include "fluent/fluent.h"
+#include "assertionexception.h"
+#include "assert.h"
+#include "assertmacro.h"
+#include "exceptions.h"
+
+#endif
+
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringize.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringize.h
new file mode 100644
index 00000000..42249f57
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringize.h
@@ -0,0 +1,104 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_STRINGIZE_H
+#define IGLOO_STRINGIZE_H
+
+#include <cstddef>
+
+namespace snowhouse {
+ namespace detail {
+
+ // This type soaks up any implicit conversions and makes the following operator<<
+ // less preferred than any other such operator found via ADL.
+ struct any
+ {
+ // Conversion constructor for any type.
+ template <class T>
+ any(T const&);
+ };
+
+ // A tag type returned by operator<< for the any struct in this namespace
+ // when T does not support <<.
+ struct tag {};
+
+ // Fallback operator<< for types T that don't support <<.
+ tag operator<<(std::ostream&, any const&);
+
+ // Two overloads to distinguish whether T supports a certain operator expression.
+ // The first overload returns a reference to a two-element character array and is chosen if
+ // T does not support the expression, such as <<, whereas the second overload returns a char
+ // directly and is chosen if T supports the expression. So using sizeof(check(<expression>))
+ // returns 2 for the first overload and 1 for the second overload.
+ typedef char yes;
+ typedef char (&no)[2];
+
+ no check(tag);
+
+ template <class T>
+ yes check(T const&);
+
+ template <class T>
+ struct is_output_streamable
+ {
+ static const T& x;
+ static const bool value = sizeof(check(std::cout << x)) == sizeof(yes);
+ };
+
+ template<typename T, bool type_is_streamable>
+ struct DefaultStringizer
+ {
+ static std::string ToString(const T& value)
+ {
+ std::ostringstream buf;
+ buf << value;
+ return buf.str();
+ }
+ };
+
+ template<typename T>
+ struct DefaultStringizer<T, false>
+ {
+ static std::string ToString(const T&)
+ {
+ return "[unsupported type]";
+ }
+ };
+ }
+
+ template<typename T>
+ struct Stringizer;
+
+ template<typename T>
+ std::string Stringize(const T& value)
+ {
+ return Stringizer<T>::ToString(value);
+ }
+
+ // NOTE: Specialize snowhouse::Stringizer to customize assertion messages
+ template<typename T>
+ struct Stringizer
+ {
+ static std::string ToString(const T& value)
+ {
+ return detail::DefaultStringizer< T, detail::is_output_streamable<T>::value >::ToString(value);
+ }
+ };
+
+#if __cplusplus > 199711L
+ // We need this because nullptr_t has ambiguous overloads of operator<< in the standard library.
+ template<>
+ struct Stringizer<std::nullptr_t>
+ {
+ static std::string ToString(std::nullptr_t)
+ {
+ return "nullptr";
+ }
+ };
+#endif
+}
+
+#endif
diff --git a/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringizers.h b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringizers.h
new file mode 100644
index 00000000..79a416de
--- /dev/null
+++ b/vendor/bandit/bandit/assertion_frameworks/snowhouse/snowhouse/stringizers.h
@@ -0,0 +1,60 @@
+
+// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef IGLOO_STRINGIZERS_H
+#define IGLOO_STRINGIZERS_H
+
+namespace snowhouse
+{
+
+ namespace detail
+ {
+
+ template<typename Container>
+ struct SequentialContainerStringizer
+ {
+ static std::string
+ ToString(const Container& cont)
+ {
+ std::ostringstream stm;
+ typedef typename Container::const_iterator Iterator;
+
+ stm << "[ ";
+ for (Iterator it = cont.begin(); it != cont.end();)
+ {
+ stm << snowhouse::Stringize(*it);
+
+ if (++it != cont.end())
+ {
+ stm << ", ";
+ }
+ }
+ stm << " ]";
+ return stm.str();
+ }
+ };
+ }
+
+ template<typename T>
+ struct Stringizer<std::vector<T> > : detail::SequentialContainerStringizer<
+ std::vector<T> >
+ {
+ };
+
+ template<typename T>
+ struct Stringizer<std::deque<T> > : detail::SequentialContainerStringizer<
+ std::deque<T> >
+ {
+ };
+
+ template<typename T>
+ struct Stringizer<std::list<T> > : detail::SequentialContainerStringizer<
+ std::list<T> >
+ {
+ };
+}
+
+#endif
diff --git a/vendor/bandit/bandit/bandit.h b/vendor/bandit/bandit/bandit.h
new file mode 100644
index 00000000..c9caeda9
--- /dev/null
+++ b/vendor/bandit/bandit/bandit.h
@@ -0,0 +1,42 @@
+#ifndef BANDIT_BANDIT_H
+#define BANDIT_BANDIT_H
+
+#ifdef _MSC_VER
+// Visual Studio (including 2013) does not support the noexcept keyword
+#define _ALLOW_KEYWORD_MACROS
+#define noexcept
+#endif
+
+#include <cassert>
+#include <functional>
+#include <iostream>
+#include <list>
+#include <deque>
+#include <stdexcept>
+
+#define BANDIT_VERSION "2.0.0"
+
+namespace bandit { namespace detail {
+ typedef std::function<void ()> voidfunc_t;
+}}
+
+#include <bandit/assertion_frameworks/snowhouse/snowhouse/snowhouse.h>
+using namespace snowhouse;
+
+#include <bandit/assertion_frameworks/matchers/matchers.h>
+
+#include <bandit/external/optionparser.h>
+#include <bandit/options.h>
+#include <bandit/test_run_error.h>
+#include <bandit/registration/registration.h>
+#include <bandit/assertion_exception.h>
+#include <bandit/failure_formatters/failure_formatters.h>
+#include <bandit/adapters/adapters.h>
+#include <bandit/listener.h>
+#include <bandit/reporters/reporters.h>
+#include <bandit/context.h>
+#include <bandit/run_policies/run_policies.h>
+#include <bandit/grammar.h>
+#include <bandit/runner.h>
+
+#endif
diff --git a/vendor/bandit/bandit/context.h b/vendor/bandit/bandit/context.h
new file mode 100644
index 00000000..71194253
--- /dev/null
+++ b/vendor/bandit/bandit/context.h
@@ -0,0 +1,97 @@
+#ifndef BANDIT_CONTEXT_H
+#define BANDIT_CONTEXT_H
+
+namespace bandit {
+ namespace detail {
+
+ class context
+ {
+ public:
+ virtual ~context() {}
+ virtual const std::string& name() = 0;
+ virtual void execution_is_starting() = 0;
+ virtual void register_before_each(voidfunc_t func) = 0;
+ virtual void register_after_each(voidfunc_t func) = 0;
+ virtual void run_before_eaches() = 0;
+ virtual void run_after_eaches() = 0;
+ virtual bool hard_skip() = 0;
+ };
+
+ class bandit_context : public context
+ {
+ public:
+ bandit_context(const char* desc, bool hard_skip_a)
+ : desc_(desc), hard_skip_(hard_skip_a), is_executing_(false)
+ {}
+
+ const std::string& name()
+ {
+ return desc_;
+ }
+
+ void execution_is_starting()
+ {
+ is_executing_ = true;
+ }
+
+ void register_before_each(voidfunc_t func)
+ {
+ if(is_executing_)
+ {
+ throw test_run_error("before_each was called after 'describe' or 'it'");
+ }
+
+ before_eaches_.push_back(func);
+ }
+
+ void register_after_each(voidfunc_t func)
+ {
+ if(is_executing_)
+ {
+ throw test_run_error("after_each was called after 'describe' or 'it'");
+ }
+
+ after_eaches_.push_back(func);
+ }
+
+ void run_before_eaches()
+ {
+ run_all(before_eaches_);
+ }
+
+ void run_after_eaches()
+ {
+ run_all(after_eaches_);
+ }
+
+ bool hard_skip()
+ {
+ return hard_skip_;
+ }
+
+ private:
+ void run_all(const std::list<voidfunc_t>& funcs)
+ {
+ auto call_func = [](voidfunc_t f){ f(); };
+
+ for_each(funcs.begin(), funcs.end(), call_func);
+ }
+
+ private:
+ std::string desc_;
+ bool hard_skip_;
+ bool is_executing_;
+ std::list<voidfunc_t> before_eaches_;
+ std::list<voidfunc_t> after_eaches_;
+ };
+ typedef std::deque<context*> contextstack_t;
+
+ inline contextstack_t& context_stack()
+ {
+ static contextstack_t contexts;
+ return contexts;
+ }
+ }
+}
+
+#endif
diff --git a/vendor/bandit/bandit/external/optionparser.h b/vendor/bandit/bandit/external/optionparser.h
new file mode 100644
index 00000000..ffeaac66
--- /dev/null
+++ b/vendor/bandit/bandit/external/optionparser.h
@@ -0,0 +1,2825 @@
+/*
+ * The Lean Mean C++ Option Parser
+ *
+ * Copyright (C) 2012 Matthias S. Benkmann
+ *
+ * The "Software" in the following 2 paragraphs refers to this file containing
+ * the code to The Lean Mean C++ Option Parser.
+ * The "Software" does NOT refer to any other files which you
+ * may have received alongside this file (e.g. as part of a larger project that
+ * incorporates The Lean Mean C++ Option Parser).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software, to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * NOTE: It is recommended that you read the processed HTML doxygen documentation
+ * rather than this source. If you don't know doxygen, it's like javadoc for C++.
+ * If you don't want to install doxygen you can find a copy of the processed
+ * documentation at
+ *
+ * http://optionparser.sourceforge.net/
+ *
+ */
+
+/**
+ * @file
+ *
+ * @brief This is the only file required to use The Lean Mean C++ Option Parser.
+ * Just \#include it and you're set.
+ *
+ * The Lean Mean C++ Option Parser handles the program's command line arguments
+ * (argc, argv).
+ * It supports the short and long option formats of getopt(), getopt_long()
+ * and getopt_long_only() but has a more convenient interface.
+ * The following features set it apart from other option parsers:
+ *
+ * @par Highlights:
+ * <ul style="padding-left:1em;margin-left:0">
+ * <li> It is a header-only library. Just <code>\#include "optionparser.h"</code> and you're set.
+ * <li> It is freestanding. There are no dependencies whatsoever, not even the
+ * C or C++ standard library.
+ * <li> It has a usage message formatter that supports column alignment and
+ * line wrapping. This aids localization because it adapts to
+ * translated strings that are shorter or longer (even if they contain
+ * Asian wide characters).
+ * <li> Unlike getopt() and derivatives it doesn't force you to loop through
+ * options sequentially. Instead you can access options directly like this:
+ * <ul style="margin-top:.5em">
+ * <li> Test for presence of a switch in the argument vector:
+ * @code if ( options[QUIET] ) ... @endcode
+ * <li> Evaluate --enable-foo/--disable-foo pair where the last one used wins:
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
+ * <li> Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
+ * @code int verbosity = options[VERBOSE].count(); @endcode
+ * <li> Iterate over all --file=&lt;fname> arguments:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ * <li> If you really want to, you can still process all arguments in order:
+ * @code
+ * for (int i = 0; i < p.optionsCount(); ++i) {
+ * Option& opt = buffer[i];
+ * switch(opt.index()) {
+ * case HELP: ...
+ * case VERBOSE: ...
+ * case FILE: fname = opt.arg; ...
+ * case UNKNOWN: ...
+ * @endcode
+ * </ul>
+ * </ul> @n
+ * Despite these features the code size remains tiny.
+ * It is smaller than <a href="http://uclibc.org">uClibc</a>'s GNU getopt() and just a
+ * couple 100 bytes larger than uClibc's SUSv3 getopt(). @n
+ * (This does not include the usage formatter, of course. But you don't have to use that.)
+ *
+ * @par Download:
+ * Tarball with examples and test programs:
+ * <a style="font-size:larger;font-weight:bold" href="http://sourceforge.net/projects/optionparser/files/optionparser-1.3.tar.gz/download">optionparser-1.3.tar.gz</a> @n
+ * Just the header (this is all you really need):
+ * <a style="font-size:larger;font-weight:bold" href="http://optionparser.sourceforge.net/optionparser.h">optionparser.h</a>
+ *
+ * @par Changelog:
+ * <b>Version 1.3:</b> Compatible with Microsoft Visual C++. @n
+ * <b>Version 1.2:</b> Added @ref option::Option::namelen "Option::namelen" and removed the extraction
+ * of short option characters into a special buffer. @n
+ * Changed @ref option::Arg::Optional "Arg::Optional" to accept arguments if they are attached
+ * rather than separate. This is what GNU getopt() does and how POSIX recommends
+ * utilities should interpret their arguments.@n
+ * <b>Version 1.1:</b> Optional mode with argument reordering as done by GNU getopt(), so that
+ * options and non-options can be mixed. See
+ * @ref option::Parser::parse() "Parser::parse()".
+ *
+ * @par Feedback:
+ * Send questions, bug reports, feature requests etc. to: <tt><b>optionparser-feedback<span id="antispam">&nbsp;(a)&nbsp;</span>lists.sourceforge.net</b></tt>
+ * @htmlonly <script type="text/javascript">document.getElementById("antispam").innerHTML="@"</script> @endhtmlonly
+ *
+ *
+ * @par Example program:
+ * (Note: @c option::* identifiers are links that take you to their documentation.)
+ * @code
+ * #include <iostream>
+ * #include "optionparser.h"
+ *
+ * enum optionIndex { UNKNOWN, HELP, PLUS };
+ * const option::Descriptor usage[] =
+ * {
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "USAGE: example [options]\n\n"
+ * "Options:" },
+ * {HELP, 0,"" , "help",option::Arg::None, " --help \tPrint usage and exit." },
+ * {PLUS, 0,"p", "plus",option::Arg::None, " --plus, -p \tIncrement count." },
+ * {UNKNOWN, 0,"" , "" ,option::Arg::None, "\nExamples:\n"
+ * " example --unknown -- --this_is_no_option\n"
+ * " example -unk --plus -ppp file1 file2\n" },
+ * {0,0,0,0,0,0}
+ * };
+ *
+ * int main(int argc, char* argv[])
+ * {
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
+ * option::Stats stats(usage, argc, argv);
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
+ * option::Parser parse(usage, argc, argv, options, buffer);
+ *
+ * if (parse.error())
+ * return 1;
+ *
+ * if (options[HELP] || argc == 0) {
+ * option::printUsage(std::cout, usage);
+ * return 0;
+ * }
+ *
+ * std::cout << "--plus count: " <<
+ * options[PLUS].count() << "\n";
+ *
+ * for (option::Option* opt = options[UNKNOWN]; opt; opt = opt->next())
+ * std::cout << "Unknown option: " << opt->name << "\n";
+ *
+ * for (int i = 0; i < parse.nonOptionsCount(); ++i)
+ * std::cout << "Non-option #" << i << ": " << parse.nonOption(i) << "\n";
+ * }
+ * @endcode
+ *
+ * @par Option syntax:
+ * @li The Lean Mean C++ Option Parser follows POSIX <code>getopt()</code> conventions and supports
+ * GNU-style <code>getopt_long()</code> long options as well as Perl-style single-minus
+ * long options (<code>getopt_long_only()</code>).
+ * @li short options have the format @c -X where @c X is any character that fits in a char.
+ * @li short options can be grouped, i.e. <code>-X -Y</code> is equivalent to @c -XY.
+ * @li a short option may take an argument either separate (<code>-X foo</code>) or
+ * attached (@c -Xfoo). You can make the parser accept the additional format @c -X=foo by
+ * registering @c X as a long option (in addition to being a short option) and
+ * enabling single-minus long options.
+ * @li an argument-taking short option may be grouped if it is the last in the group, e.g.
+ * @c -ABCXfoo or <code> -ABCX foo </code> (@c foo is the argument to the @c -X option).
+ * @li a lone minus character @c '-' is not treated as an option. It is customarily used where
+ * a file name is expected to refer to stdin or stdout.
+ * @li long options have the format @c --option-name.
+ * @li the option-name of a long option can be anything and include any characters.
+ * Even @c = characters will work, but don't do that.
+ * @li [optional] long options may be abbreviated as long as the abbreviation is unambiguous.
+ * You can set a minimum length for abbreviations.
+ * @li [optional] long options may begin with a single minus. The double minus form is always
+ * accepted, too.
+ * @li a long option may take an argument either separate (<code> --option arg </code>) or
+ * attached (<code> --option=arg </code>). In the attached form the equals sign is mandatory.
+ * @li an empty string can be passed as an attached long option argument: <code> --option-name= </code>.
+ * Note the distinction between an empty string as argument and no argument at all.
+ * @li an empty string is permitted as separate argument to both long and short options.
+ * @li Arguments to both short and long options may start with a @c '-' character. E.g.
+ * <code> -X-X </code>, <code>-X -X</code> or <code> --long-X=-X </code>. If @c -X
+ * and @c --long-X take an argument, that argument will be @c "-X" in all 3 cases.
+ * @li If using the built-in @ref option::Arg::Optional "Arg::Optional", optional arguments must
+ * be attached.
+ * @li the special option @c -- (i.e. without a name) terminates the list of
+ * options. Everything that follows is a non-option argument, even if it starts with
+ * a @c '-' character. The @c -- itself will not appear in the parse results.
+ * @li the first argument that doesn't start with @c '-' or @c '--' and does not belong to
+ * a preceding argument-taking option, will terminate the option list and is the
+ * first non-option argument. All following command line arguments are treated as
+ * non-option arguments, even if they start with @c '-' . @n
+ * NOTE: This behaviour is mandated by POSIX, but GNU getopt() only honours this if it is
+ * explicitly requested (e.g. by setting POSIXLY_CORRECT). @n
+ * You can enable the GNU behaviour by passing @c true as first argument to
+ * e.g. @ref option::Parser::parse() "Parser::parse()".
+ * @li Arguments that look like options (i.e. @c '-' followed by at least 1 character) but
+ * aren't, are NOT treated as non-option arguments. They are treated as unknown options and
+ * are collected into a list of unknown options for error reporting. @n
+ * This means that in order to pass a first non-option
+ * argument beginning with the minus character it is required to use the
+ * @c -- special option, e.g.
+ * @code
+ * program -x -- --strange-filename
+ * @endcode
+ * In this example, @c --strange-filename is a non-option argument. If the @c --
+ * were omitted, it would be treated as an unknown option. @n
+ * See @ref option::Descriptor::longopt for information on how to collect unknown options.
+ *
+ */
+
+#ifndef OPTIONPARSER_H_
+#define OPTIONPARSER_H_
+
+/** @brief The namespace of The Lean Mean C++ Option Parser. */
+namespace option
+{
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#pragma intrinsic(_BitScanReverse)
+struct MSC_Builtin_CLZ
+{
+ static int builtin_clz(unsigned x)
+ {
+ unsigned long index;
+ _BitScanReverse(&index, x);
+ return 32-index; // int is always 32bit on Windows, even for target x64
+ }
+};
+#define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
+
+#pragma warning( push )
+#pragma warning( disable: 4510 )
+#pragma warning( disable: 4512 )
+#pragma warning( disable: 4610 )
+#pragma warning( disable: 4127 )
+#endif
+
+class Option;
+
+/**
+ * @brief Possible results when checking if an argument is valid for a certain option.
+ *
+ * In the case that no argument is provided for an option that takes an
+ * optional argument, return codes @c ARG_OK and @c ARG_IGNORE are equivalent.
+ */
+enum ArgStatus
+{
+ //! The option does not take an argument.
+ ARG_NONE,
+ //! The argument is acceptable for the option.
+ ARG_OK,
+ //! The argument is not acceptable but that's non-fatal because the option's argument is optional.
+ ARG_IGNORE,
+ //! The argument is not acceptable and that's fatal.
+ ARG_ILLEGAL
+};
+
+/**
+ * @brief Signature of functions that check if an argument is valid for a certain type of option.
+ *
+ * Every Option has such a function assigned in its Descriptor.
+ * @code
+ * Descriptor usage[] = { {UNKNOWN, 0, "", "", Arg::None, ""}, ... };
+ * @endcode
+ *
+ * A CheckArg function has the following signature:
+ * @code ArgStatus CheckArg(const Option& option, bool msg); @endcode
+ *
+ * It is used to check if a potential argument would be acceptable for the option.
+ * It will even be called if there is no argument. In that case @c option.arg will be @c NULL.
+ *
+ * If @c msg is @c true and the function determines that an argument is not acceptable and
+ * that this is a fatal error, it should output a message to the user before
+ * returning @ref ARG_ILLEGAL. If @c msg is @c false the function should remain silent (or you
+ * will get duplicate messages).
+ *
+ * See @ref ArgStatus for the meaning of the return values.
+ *
+ * While you can provide your own functions,
+ * often the following pre-defined checks (which never return @ref ARG_ILLEGAL) will suffice:
+ *
+ * @li @c Arg::None @copybrief Arg::None
+ * @li @c Arg::Optional @copybrief Arg::Optional
+ *
+ */
+typedef ArgStatus (*CheckArg)(const Option& option, bool msg);
+
+/**
+ * @brief Describes an option, its help text (usage) and how it should be parsed.
+ *
+ * The main input when constructing an option::Parser is an array of Descriptors.
+
+ * @par Example:
+ * @code
+ * enum OptionIndex {CREATE, ...};
+ * enum OptionType {DISABLE, ENABLE, OTHER};
+ *
+ * const option::Descriptor usage[] = {
+ * { CREATE, // index
+ * OTHER, // type
+ * "c", // shortopt
+ * "create", // longopt
+ * Arg::None, // check_arg
+ * "--create Tells the program to create something." // help
+ * }
+ * , ...
+ * };
+ * @endcode
+ */
+struct Descriptor
+{
+ /**
+ * @brief Index of this option's linked list in the array filled in by the parser.
+ *
+ * Command line options whose Descriptors have the same index will end up in the same
+ * linked list in the order in which they appear on the command line. If you have
+ * multiple long option aliases that refer to the same option, give their descriptors
+ * the same @c index.
+ *
+ * If you have options that mean exactly opposite things
+ * (e.g. @c --enable-foo and @c --disable-foo ), you should also give them the same
+ * @c index, but distinguish them through different values for @ref type.
+ * That way they end up in the same list and you can just take the last element of the
+ * list and use its type. This way you get the usual behaviour where switches later
+ * on the command line override earlier ones without having to code it manually.
+ *
+ * @par Tip:
+ * Use an enum rather than plain ints for better readability, as shown in the example
+ * at Descriptor.
+ */
+ const unsigned index;
+
+ /**
+ * @brief Used to distinguish between options with the same @ref index.
+ * See @ref index for details.
+ *
+ * It is recommended that you use an enum rather than a plain int to make your
+ * code more readable.
+ */
+ const int type;
+
+ /**
+ * @brief Each char in this string will be accepted as a short option character.
+ *
+ * The string must not include the minus character @c '-' or you'll get undefined
+ * behaviour.
+ *
+ * If this Descriptor should not have short option characters, use the empty
+ * string "". NULL is not permitted here!
+ *
+ * See @ref longopt for more information.
+ */
+ const char* const shortopt;
+
+ /**
+ * @brief The long option name (without the leading @c -- ).
+ *
+ * If this Descriptor should not have a long option name, use the empty
+ * string "". NULL is not permitted here!
+ *
+ * While @ref shortopt allows multiple short option characters, each
+ * Descriptor can have only a single long option name. If you have multiple
+ * long option names referring to the same option use separate Descriptors
+ * that have the same @ref index and @ref type. You may repeat
+ * short option characters in such an alias Descriptor but there's no need to.
+ *
+ * @par Dummy Descriptors:
+ * You can use dummy Descriptors with an
+ * empty string for both @ref shortopt and @ref longopt to add text to
+ * the usage that is not related to a specific option. See @ref help.
+ * The first dummy Descriptor will be used for unknown options (see below).
+ *
+ * @par Unknown Option Descriptor:
+ * The first dummy Descriptor in the list of Descriptors,
+ * whose @ref shortopt and @ref longopt are both the empty string, will be used
+ * as the Descriptor for unknown options. An unknown option is a string in
+ * the argument vector that is not a lone minus @c '-' but starts with a minus
+ * character and does not match any Descriptor's @ref shortopt or @ref longopt. @n
+ * Note that the dummy descriptor's @ref check_arg function @e will be called and
+ * its return value will be evaluated as usual. I.e. if it returns @ref ARG_ILLEGAL
+ * the parsing will be aborted with <code>Parser::error()==true</code>. @n
+ * if @c check_arg does not return @ref ARG_ILLEGAL the descriptor's
+ * @ref index @e will be used to pick the linked list into which
+ * to put the unknown option. @n
+ * If there is no dummy descriptor, unknown options will be dropped silently.
+ *
+ */
+ const char* const longopt;
+
+ /**
+ * @brief For each option that matches @ref shortopt or @ref longopt this function
+ * will be called to check a potential argument to the option.
+ *
+ * This function will be called even if there is no potential argument. In that case
+ * it will be passed @c NULL as @c arg parameter. Do not confuse this with the empty
+ * string.
+ *
+ * See @ref CheckArg for more information.
+ */
+ const CheckArg check_arg;
+
+ /**
+ * @brief The usage text associated with the options in this Descriptor.
+ *
+ * You can use option::printUsage() to format your usage message based on
+ * the @c help texts. You can use dummy Descriptors where
+ * @ref shortopt and @ref longopt are both the empty string to add text to
+ * the usage that is not related to a specific option.
+ *
+ * See option::printUsage() for special formatting characters you can use in
+ * @c help to get a column layout.
+ *
+ * @attention
+ * Must be UTF-8-encoded. If your compiler supports C++11 you can use the "u8"
+ * prefix to make sure string literals are properly encoded.
+ */
+ const char* help;
+};
+
+/**
+ * @brief A parsed option from the command line together with its argument if it has one.
+ *
+ * The Parser chains all parsed options with the same Descriptor::index together
+ * to form a linked list. This allows you to easily implement all of the common ways
+ * of handling repeated options and enable/disable pairs.
+ *
+ * @li Test for presence of a switch in the argument vector:
+ * @code if ( options[QUIET] ) ... @endcode
+ * @li Evaluate --enable-foo/--disable-foo pair where the last one used wins:
+ * @code if ( options[FOO].last()->type() == DISABLE ) ... @endcode
+ * @li Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose):
+ * @code int verbosity = options[VERBOSE].count(); @endcode
+ * @li Iterate over all --file=&lt;fname> arguments:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+class Option
+{
+ Option* next_;
+ Option* prev_;
+public:
+ /**
+ * @brief Pointer to this Option's Descriptor.
+ *
+ * Remember that the first dummy descriptor (see @ref Descriptor::longopt) is used
+ * for unknown options.
+ *
+ * @attention
+ * @c desc==NULL signals that this Option is unused. This is the default state of
+ * elements in the result array. You don't need to test @c desc explicitly. You
+ * can simply write something like this:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * This works because of <code> operator const Option*() </code>.
+ */
+ const Descriptor* desc;
+
+ /**
+ * @brief The name of the option as used on the command line.
+ *
+ * The main purpose of this string is to be presented to the user in messages.
+ *
+ * In the case of a long option, this is the actual @c argv pointer, i.e. the first
+ * character is a '-'. In the case of a short option this points to the option
+ * character within the @c argv string.
+ *
+ * Note that in the case of a short option group or an attached option argument, this
+ * string will contain additional characters following the actual name. Use @ref namelen
+ * to filter out the actual option name only.
+ *
+ */
+ const char* name;
+
+ /**
+ * @brief Pointer to this Option's argument (if any).
+ *
+ * NULL if this option has no argument. Do not confuse this with the empty string which
+ * is a valid argument.
+ */
+ const char* arg;
+
+ /**
+ * @brief The length of the option @ref name.
+ *
+ * Because @ref name points into the actual @c argv string, the option name may be
+ * followed by more characters (e.g. other short options in the same short option group).
+ * This value is the number of bytes (not characters!) that are part of the actual name.
+ *
+ * For a short option, this length is always 1. For a long option this length is always
+ * at least 2 if single minus long options are permitted and at least 3 if they are disabled.
+ *
+ * @note
+ * In the pathological case of a minus within a short option group (e.g. @c -xf-z), this
+ * length is incorrect, because this case will be misinterpreted as a long option and the
+ * name will therefore extend to the string's 0-terminator or a following '=" character
+ * if there is one. This is irrelevant for most uses of @ref name and @c namelen. If you
+ * really need to distinguish the case of a long and a short option, compare @ref name to
+ * the @c argv pointers. A long option's @c name is always identical to one of them,
+ * whereas a short option's is never.
+ */
+ int namelen;
+
+ /**
+ * @brief Returns Descriptor::type of this Option's Descriptor, or 0 if this Option
+ * is invalid (unused).
+ *
+ * Because this method (and last(), too) can be used even on unused Options with desc==0, you can (provided
+ * you arrange your types properly) switch on type() without testing validity first.
+ * @code
+ * enum OptionType { UNUSED=0, DISABLED=0, ENABLED=1 };
+ * enum OptionIndex { FOO };
+ * const Descriptor usage[] = {
+ * { FOO, ENABLED, "", "enable-foo", Arg::None, 0 },
+ * { FOO, DISABLED, "", "disable-foo", Arg::None, 0 },
+ * { 0, 0, 0, 0, 0, 0 } };
+ * ...
+ * switch(options[FOO].last()->type()) // no validity check required!
+ * {
+ * case ENABLED: ...
+ * case DISABLED: ... // UNUSED==DISABLED !
+ * }
+ * @endcode
+ */
+ int type() const
+ {
+ return desc == 0 ? 0 : desc->type;
+ }
+
+ /**
+ * @brief Returns Descriptor::index of this Option's Descriptor, or -1 if this Option
+ * is invalid (unused).
+ */
+ int index() const
+ {
+ return desc == 0 ? -1 : desc->index;
+ }
+
+ /**
+ * @brief Returns the number of times this Option (or others with the same Descriptor::index)
+ * occurs in the argument vector.
+ *
+ * This corresponds to the number of elements in the linked list this Option is part of.
+ * It doesn't matter on which element you call count(). The return value is always the same.
+ *
+ * Use this to implement cumulative options, such as -v, -vv, -vvv for
+ * different verbosity levels.
+ *
+ * Returns 0 when called for an unused/invalid option.
+ */
+ int count()
+ {
+ int c = (desc == 0 ? 0 : 1);
+ Option* p = first();
+ while (!p->isLast())
+ {
+ ++c;
+ p = p->next_;
+ };
+ return c;
+ }
+
+ /**
+ * @brief Returns true iff this is the first element of the linked list.
+ *
+ * The first element in the linked list is the first option on the command line
+ * that has the respective Descriptor::index value.
+ *
+ * Returns true for an unused/invalid option.
+ */
+ bool isFirst() const
+ {
+ return isTagged(prev_);
+ }
+
+ /**
+ * @brief Returns true iff this is the last element of the linked list.
+ *
+ * The last element in the linked list is the last option on the command line
+ * that has the respective Descriptor::index value.
+ *
+ * Returns true for an unused/invalid option.
+ */
+ bool isLast() const
+ {
+ return isTagged(next_);
+ }
+
+ /**
+ * @brief Returns a pointer to the first element of the linked list.
+ *
+ * Use this when you want the first occurrence of an option on the command line to
+ * take precedence. Note that this is not the way most programs handle options.
+ * You should probably be using last() instead.
+ *
+ * @note
+ * This method may be called on an unused/invalid option and will return a pointer to the
+ * option itself.
+ */
+ Option* first()
+ {
+ Option* p = this;
+ while (!p->isFirst())
+ p = p->prev_;
+ return p;
+ }
+
+ /**
+ * @brief Returns a pointer to the last element of the linked list.
+ *
+ * Use this when you want the last occurrence of an option on the command line to
+ * take precedence. This is the most common way of handling conflicting options.
+ *
+ * @note
+ * This method may be called on an unused/invalid option and will return a pointer to the
+ * option itself.
+ *
+ * @par Tip:
+ * If you have options with opposite meanings (e.g. @c --enable-foo and @c --disable-foo), you
+ * can assign them the same Descriptor::index to get them into the same list. Distinguish them by
+ * Descriptor::type and all you have to do is check <code> last()->type() </code> to get
+ * the state listed last on the command line.
+ */
+ Option* last()
+ {
+ return first()->prevwrap();
+ }
+
+ /**
+ * @brief Returns a pointer to the previous element of the linked list or NULL if
+ * called on first().
+ *
+ * If called on first() this method returns NULL. Otherwise it will return the
+ * option with the same Descriptor::index that precedes this option on the command
+ * line.
+ */
+ Option* prev()
+ {
+ return isFirst() ? 0 : prev_;
+ }
+
+ /**
+ * @brief Returns a pointer to the previous element of the linked list with wrap-around from
+ * first() to last().
+ *
+ * If called on first() this method returns last(). Otherwise it will return the
+ * option with the same Descriptor::index that precedes this option on the command
+ * line.
+ */
+ Option* prevwrap()
+ {
+ return untag(prev_);
+ }
+
+ /**
+ * @brief Returns a pointer to the next element of the linked list or NULL if called
+ * on last().
+ *
+ * If called on last() this method returns NULL. Otherwise it will return the
+ * option with the same Descriptor::index that follows this option on the command
+ * line.
+ */
+ Option* next()
+ {
+ return isLast() ? 0 : next_;
+ }
+
+ /**
+ * @brief Returns a pointer to the next element of the linked list with wrap-around from
+ * last() to first().
+ *
+ * If called on last() this method returns first(). Otherwise it will return the
+ * option with the same Descriptor::index that follows this option on the command
+ * line.
+ */
+ Option* nextwrap()
+ {
+ return untag(next_);
+ }
+
+ /**
+ * @brief Makes @c new_last the new last() by chaining it into the list after last().
+ *
+ * It doesn't matter which element you call append() on. The new element will always
+ * be appended to last().
+ *
+ * @attention
+ * @c new_last must not yet be part of a list, or that list will become corrupted, because
+ * this method does not unchain @c new_last from an existing list.
+ */
+ void append(Option* new_last)
+ {
+ Option* p = last();
+ Option* f = first();
+ p->next_ = new_last;
+ new_last->prev_ = p;
+ new_last->next_ = tag(f);
+ f->prev_ = tag(new_last);
+ }
+
+ /**
+ * @brief Casts from Option to const Option* but only if this Option is valid.
+ *
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
+ * Otherwise returns NULL. This allows testing an Option directly
+ * in an if-clause to see if it is used:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * It also allows you to write loops like this:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+ operator const Option*() const
+ {
+ return desc ? this : 0;
+ }
+
+ /**
+ * @brief Casts from Option to Option* but only if this Option is valid.
+ *
+ * If this Option is valid (i.e. @c desc!=NULL), returns this.
+ * Otherwise returns NULL. This allows testing an Option directly
+ * in an if-clause to see if it is used:
+ * @code
+ * if (options[CREATE])
+ * {
+ * ...
+ * }
+ * @endcode
+ * It also allows you to write loops like this:
+ * @code for (Option* opt = options[FILE]; opt; opt = opt->next())
+ * fname = opt->arg; ... @endcode
+ */
+ operator Option*()
+ {
+ return desc ? this : 0;
+ }
+
+ /**
+ * @brief Creates a new Option that is a one-element linked list and has NULL
+ * @ref desc, @ref name, @ref arg and @ref namelen.
+ */
+ Option() :
+ desc(0), name(0), arg(0), namelen(0)
+ {
+ prev_ = tag(this);
+ next_ = tag(this);
+ }
+
+ /**
+ * @brief Creates a new Option that is a one-element linked list and has the given
+ * values for @ref desc, @ref name and @ref arg.
+ *
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
+ * the first '=' character or the string's 0-terminator.
+ */
+ Option(const Descriptor* desc_, const char* name_, const char* arg_)
+ {
+ init(desc_, name_, arg_);
+ }
+
+ /**
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
+ *
+ * After this operation @c *this will be a one-element linked list.
+ */
+ void operator=(const Option& orig)
+ {
+ init(orig.desc, orig.name, orig.arg);
+ }
+
+ /**
+ * @brief Makes @c *this a copy of @c orig except for the linked list pointers.
+ *
+ * After this operation @c *this will be a one-element linked list.
+ */
+ Option(const Option& orig)
+ {
+ init(orig.desc, orig.name, orig.arg);
+ }
+
+private:
+ /**
+ * @internal
+ * @brief Sets the fields of this Option to the given values (extracting @c name if necessary).
+ *
+ * If @c name_ points at a character other than '-' it will be assumed to refer to a
+ * short option and @ref namelen will be set to 1. Otherwise the length will extend to
+ * the first '=' character or the string's 0-terminator.
+ */
+ void init(const Descriptor* desc_, const char* name_, const char* arg_)
+ {
+ desc = desc_;
+ name = name_;
+ arg = arg_;
+ prev_ = tag(this);
+ next_ = tag(this);
+ namelen = 0;
+ if (name == 0)
+ return;
+ namelen = 1;
+ if (name[0] != '-')
+ return;
+ while (name[namelen] != 0 && name[namelen] != '=')
+ ++namelen;
+ }
+
+ static Option* tag(Option* ptr)
+ {
+ return (Option*) ((unsigned long long) ptr | 1);
+ }
+
+ static Option* untag(Option* ptr)
+ {
+ return (Option*) ((unsigned long long) ptr & ~1ull);
+ }
+
+ static bool isTagged(Option* ptr)
+ {
+ return ((unsigned long long) ptr & 1);
+ }
+};
+
+/**
+ * @brief Functions for checking the validity of option arguments.
+ *
+ * @copydetails CheckArg
+ *
+ * The following example code
+ * can serve as starting place for writing your own more complex CheckArg functions:
+ * @code
+ * struct Arg: public option::Arg
+ * {
+ * static void printError(const char* msg1, const option::Option& opt, const char* msg2)
+ * {
+ * fprintf(stderr, "ERROR: %s", msg1);
+ * fwrite(opt.name, opt.namelen, 1, stderr);
+ * fprintf(stderr, "%s", msg2);
+ * }
+ *
+ * static option::ArgStatus Unknown(const option::Option& option, bool msg)
+ * {
+ * if (msg) printError("Unknown option '", option, "'\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus Required(const option::Option& option, bool msg)
+ * {
+ * if (option.arg != 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires an argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
+ * {
+ * if (option.arg != 0 && option.arg[0] != 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires a non-empty argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ *
+ * static option::ArgStatus Numeric(const option::Option& option, bool msg)
+ * {
+ * char* endptr = 0;
+ * if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
+ * if (endptr != option.arg && *endptr == 0)
+ * return option::ARG_OK;
+ *
+ * if (msg) printError("Option '", option, "' requires a numeric argument\n");
+ * return option::ARG_ILLEGAL;
+ * }
+ * };
+ * @endcode
+ */
+struct Arg
+{
+ //! @brief For options that don't take an argument: Returns ARG_NONE.
+ static ArgStatus None(const Option&, bool)
+ {
+ return ARG_NONE;
+ }
+
+ //! @brief Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.
+ static ArgStatus Optional(const Option& option, bool)
+ {
+ if (option.arg && option.name[option.namelen] != 0)
+ return ARG_OK;
+ else
+ return ARG_IGNORE;
+ }
+};
+
+/**
+ * @brief Determines the minimum lengths of the buffer and options arrays used for Parser.
+ *
+ * Because Parser doesn't use dynamic memory its output arrays have to be pre-allocated.
+ * If you don't want to use fixed size arrays (which may turn out too small, causing
+ * command line arguments to be dropped), you can use Stats to determine the correct sizes.
+ * Stats work cumulative. You can first pass in your default options and then the real
+ * options and afterwards the counts will reflect the union.
+ */
+struct Stats
+{
+ /**
+ * @brief Number of elements needed for a @c buffer[] array to be used for
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
+ * into this Stats object.
+ *
+ * @note
+ * This number is always 1 greater than the actual number needed, to give
+ * you a sentinel element.
+ */
+ unsigned buffer_max;
+
+ /**
+ * @brief Number of elements needed for an @c options[] array to be used for
+ * @ref Parser::parse() "parsing" the same argument vectors that were fed
+ * into this Stats object.
+ *
+ * @note
+ * @li This number is always 1 greater than the actual number needed, to give
+ * you a sentinel element.
+ * @li This number depends only on the @c usage, not the argument vectors, because
+ * the @c options array needs exactly one slot for each possible Descriptor::index.
+ */
+ unsigned options_max;
+
+ /**
+ * @brief Creates a Stats object with counts set to 1 (for the sentinel element).
+ */
+ Stats() :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ }
+
+ /**
+ * @brief Creates a new Stats object and immediately updates it for the
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
+ * if you just want to update @ref options_max.
+ *
+ * @note
+ * The calls to Stats methods must match the later calls to Parser methods.
+ * See Parser::parse() for the meaning of the arguments.
+ */
+ Stats(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief Stats(...) with non-const argv.
+ Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX Stats(...) (gnu==false).
+ Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX Stats(...) (gnu==false) with non-const argv.
+ Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false) :
+ buffer_max(1), options_max(1) // 1 more than necessary as sentinel
+ {
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ /**
+ * @brief Updates this Stats object for the
+ * given @c usage and argument vector. You may pass 0 for @c argc and/or @c argv,
+ * if you just want to update @ref options_max.
+ *
+ * @note
+ * The calls to Stats methods must match the later calls to Parser methods.
+ * See Parser::parse() for the meaning of the arguments.
+ */
+ void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false);
+
+ //! @brief add() with non-const argv.
+ void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX add() (gnu==false).
+ void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
+ }
+
+ //! @brief POSIX add() (gnu==false) with non-const argv.
+ void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
+ bool single_minus_longopt = false)
+ {
+ add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
+ }
+private:
+ class CountOptionsAction;
+};
+
+/**
+ * @brief Checks argument vectors for validity and parses them into data
+ * structures that are easier to work with.
+ *
+ * @par Example:
+ * @code
+ * int main(int argc, char* argv[])
+ * {
+ * argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
+ * option::Stats stats(usage, argc, argv);
+ * option::Option options[stats.options_max], buffer[stats.buffer_max];
+ * option::Parser parse(usage, argc, argv, options, buffer);
+ *
+ * if (parse.error())
+ * return 1;
+ *
+ * if (options[HELP])
+ * ...
+ * @endcode
+ */
+class Parser
+{
+ int op_count; //!< @internal @brief see optionsCount()
+ int nonop_count; //!< @internal @brief see nonOptionsCount()
+ const char** nonop_args; //!< @internal @brief see nonOptions()
+ bool err; //!< @internal @brief see error()
+public:
+
+ /**
+ * @brief Creates a new Parser.
+ */
+ Parser() :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ }
+
+ /**
+ * @brief Creates a new Parser and immediately parses the given argument vector.
+ * @copydetails parse()
+ */
+ Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief Parser(...) with non-const argv.
+ Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX Parser(...) (gnu==false).
+ Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX Parser(...) (gnu==false) with non-const argv.
+ Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1) :
+ op_count(0), nonop_count(0), nonop_args(0), err(false)
+ {
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ /**
+ * @brief Parses the given argument vector.
+ *
+ * @param gnu if true, parse() will not stop at the first non-option argument. Instead it will
+ * reorder arguments so that all non-options are at the end. This is the default behaviour
+ * of GNU getopt() but is not conforming to POSIX. @n
+ * Note, that once the argument vector has been reordered, the @c gnu flag will have
+ * no further effect on this argument vector. So it is enough to pass @c gnu==true when
+ * creating Stats.
+ * @param usage Array of Descriptor objects that describe the options to support. The last entry
+ * of this array must have 0 in all fields.
+ * @param argc The number of elements from @c argv that are to be parsed. If you pass -1, the number
+ * will be determined automatically. In that case the @c argv list must end with a NULL
+ * pointer.
+ * @param argv The arguments to be parsed. If you pass -1 as @c argc the last pointer in the @c argv
+ * list must be NULL to mark the end.
+ * @param options Each entry is the first element of a linked list of Options. Each new option
+ * that is parsed will be appended to the list specified by that Option's
+ * Descriptor::index. If an entry is not yet used (i.e. the Option is invalid),
+ * it will be replaced rather than appended to. @n
+ * The minimum length of this array is the greatest Descriptor::index value that
+ * occurs in @c usage @e PLUS ONE.
+ * @param buffer Each argument that is successfully parsed (including unknown arguments, if they
+ * have a Descriptor whose CheckArg does not return @ref ARG_ILLEGAL) will be stored in this
+ * array. parse() scans the array for the first invalid entry and begins writing at that
+ * index. You can pass @c bufmax to limit the number of options stored.
+ * @param min_abbr_len Passing a value <code> min_abbr_len > 0 </code> enables abbreviated long
+ * options. The parser will match a prefix of a long option as if it was
+ * the full long option (e.g. @c --foob=10 will be interpreted as if it was
+ * @c --foobar=10 ), as long as the prefix has at least @c min_abbr_len characters
+ * (not counting the @c -- ) and is unambiguous.
+ * @n Be careful if combining @c min_abbr_len=1 with @c single_minus_longopt=true
+ * because the ambiguity check does not consider short options and abbreviated
+ * single minus long options will take precedence over short options.
+ * @param single_minus_longopt Passing @c true for this option allows long options to begin with
+ * a single minus. The double minus form will still be recognized. Note that
+ * single minus long options take precedence over short options and short option
+ * groups. E.g. @c -file would be interpreted as @c --file and not as
+ * <code> -f -i -l -e </code> (assuming a long option named @c "file" exists).
+ * @param bufmax The greatest index in the @c buffer[] array that parse() will write to is
+ * @c bufmax-1. If there are more options, they will be processed (in particular
+ * their CheckArg will be called) but not stored. @n
+ * If you used Stats::buffer_max to dimension this array, you can pass
+ * -1 (or not pass @c bufmax at all) which tells parse() that the buffer is
+ * "large enough".
+ * @attention
+ * Remember that @c options and @c buffer store Option @e objects, not pointers. Therefore it
+ * is not possible for the same object to be in both arrays. For those options that are found in
+ * both @c buffer[] and @c options[] the respective objects are independent copies. And only the
+ * objects in @c options[] are properly linked via Option::next() and Option::prev().
+ * You can iterate over @c buffer[] to
+ * process all options in the order they appear in the argument vector, but if you want access to
+ * the other Options with the same Descriptor::index, then you @e must access the linked list via
+ * @c options[]. You can get the linked list in options from a buffer object via something like
+ * @c options[buffer[i].index()].
+ */
+ void parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1);
+
+ //! @brief parse() with non-const argv.
+ void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX parse() (gnu==false).
+ void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
+ int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ //! @brief POSIX parse() (gnu==false) with non-const argv.
+ void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
+ bool single_minus_longopt = false, int bufmax = -1)
+ {
+ parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
+ }
+
+ /**
+ * @brief Returns the number of valid Option objects in @c buffer[].
+ *
+ * @note
+ * @li The returned value always reflects the number of Options in the buffer[] array used for
+ * the most recent call to parse().
+ * @li The count (and the buffer[]) includes unknown options if they are collected
+ * (see Descriptor::longopt).
+ */
+ int optionsCount()
+ {
+ return op_count;
+ }
+
+ /**
+ * @brief Returns the number of non-option arguments that remained at the end of the
+ * most recent parse() that actually encountered non-option arguments.
+ *
+ * @note
+ * A parse() that does not encounter non-option arguments will leave this value
+ * as well as nonOptions() undisturbed. This means you can feed the Parser a
+ * default argument vector that contains non-option arguments (e.g. a default filename).
+ * Then you feed it the actual arguments from the user. If the user has supplied at
+ * least one non-option argument, all of the non-option arguments from the default
+ * disappear and are replaced by the user's non-option arguments. However, if the
+ * user does not supply any non-option arguments the defaults will still be in
+ * effect.
+ */
+ int nonOptionsCount()
+ {
+ return nonop_count;
+ }
+
+ /**
+ * @brief Returns a pointer to an array of non-option arguments (only valid
+ * if <code>nonOptionsCount() >0 </code>).
+ *
+ * @note
+ * @li parse() does not copy arguments, so this pointer points into the actual argument
+ * vector as passed to parse().
+ * @li As explained at nonOptionsCount() this pointer is only changed by parse() calls
+ * that actually encounter non-option arguments. A parse() call that encounters only
+ * options, will not change nonOptions().
+ */
+ const char** nonOptions()
+ {
+ return nonop_args;
+ }
+
+ /**
+ * @brief Returns <b><code>nonOptions()[i]</code></b> (@e without checking if i is in range!).
+ */
+ const char* nonOption(int i)
+ {
+ return nonOptions()[i];
+ }
+
+ /**
+ * @brief Returns @c true if an unrecoverable error occurred while parsing options.
+ *
+ * An illegal argument to an option (i.e. CheckArg returns @ref ARG_ILLEGAL) is an
+ * unrecoverable error that aborts the parse. Unknown options are only an error if
+ * their CheckArg function returns @ref ARG_ILLEGAL. Otherwise they are collected.
+ * In that case if you want to exit the program if either an illegal argument
+ * or an unknown option has been passed, use code like this
+ *
+ * @code
+ * if (parser.error() || options[UNKNOWN])
+ * exit(1);
+ * @endcode
+ *
+ */
+ bool error()
+ {
+ return err;
+ }
+
+private:
+ friend struct Stats;
+ class StoreOptionAction;
+ struct Action;
+
+ /**
+ * @internal
+ * @brief This is the core function that does all the parsing.
+ * @retval false iff an unrecoverable error occurred.
+ */
+ static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
+ bool single_minus_longopt, bool print_errors, int min_abbr_len);
+
+ /**
+ * @internal
+ * @brief Returns true iff @c st1 is a prefix of @c st2 and
+ * in case @c st2 is longer than @c st1, then
+ * the first additional character is '='.
+ *
+ * @par Examples:
+ * @code
+ * streq("foo", "foo=bar") == true
+ * streq("foo", "foobar") == false
+ * streq("foo", "foo") == true
+ * streq("foo=bar", "foo") == false
+ * @endcode
+ */
+ static bool streq(const char* st1, const char* st2)
+ {
+ while (*st1 != 0)
+ if (*st1++ != *st2++)
+ return false;
+ return (*st2 == 0 || *st2 == '=');
+ }
+
+ /**
+ * @internal
+ * @brief Like streq() but handles abbreviations.
+ *
+ * Returns true iff @c st1 and @c st2 have a common
+ * prefix with the following properties:
+ * @li (if min > 0) its length is at least @c min characters or the same length as @c st1 (whichever is smaller).
+ * @li (if min <= 0) its length is the same as that of @c st1
+ * @li within @c st2 the character following the common prefix is either '=' or end-of-string.
+ *
+ * Examples:
+ * @code
+ * streqabbr("foo", "foo=bar",<anything>) == true
+ * streqabbr("foo", "fo=bar" , 2) == true
+ * streqabbr("foo", "fo" , 2) == true
+ * streqabbr("foo", "fo" , 0) == false
+ * streqabbr("foo", "f=bar" , 2) == false
+ * streqabbr("foo", "f" , 2) == false
+ * streqabbr("fo" , "foo=bar",<anything>) == false
+ * streqabbr("foo", "foobar" ,<anything>) == false
+ * streqabbr("foo", "fobar" ,<anything>) == false
+ * streqabbr("foo", "foo" ,<anything>) == true
+ * @endcode
+ */
+ static bool streqabbr(const char* st1, const char* st2, long long min)
+ {
+ const char* st1start = st1;
+ while (*st1 != 0 && (*st1 == *st2))
+ {
+ ++st1;
+ ++st2;
+ }
+
+ return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');
+ }
+
+ /**
+ * @internal
+ * @brief Returns true iff character @c ch is contained in the string @c st.
+ *
+ * Returns @c true for @c ch==0 .
+ */
+ static bool instr(char ch, const char* st)
+ {
+ while (*st != 0 && *st != ch)
+ ++st;
+ return *st == ch;
+ }
+
+ /**
+ * @internal
+ * @brief Rotates <code>args[-count],...,args[-1],args[0]</code> to become
+ * <code>args[0],args[-count],...,args[-1]</code>.
+ */
+ static void shift(const char** args, int count)
+ {
+ for (int i = 0; i > -count; --i)
+ {
+ const char* temp = args[i];
+ args[i] = args[i - 1];
+ args[i - 1] = temp;
+ }
+ }
+};
+
+/**
+ * @internal
+ * @brief Interface for actions Parser::workhorse() should perform for each Option it
+ * parses.
+ */
+struct Parser::Action
+{
+ /**
+ * @brief Called by Parser::workhorse() for each Option that has been successfully
+ * parsed (including unknown
+ * options if they have a Descriptor whose Descriptor::check_arg does not return
+ * @ref ARG_ILLEGAL.
+ *
+ * Returns @c false iff a fatal error has occured and the parse should be aborted.
+ */
+ virtual bool perform(Option&)
+ {
+ return true;
+ }
+
+ /**
+ * @brief Called by Parser::workhorse() after finishing the parse.
+ * @param numargs the number of non-option arguments remaining
+ * @param args pointer to the first remaining non-option argument (if numargs > 0).
+ *
+ * @return
+ * @c false iff a fatal error has occurred.
+ */
+ virtual bool finished(int numargs, const char** args)
+ {
+ (void) numargs;
+ (void) args;
+ return true;
+ }
+};
+
+/**
+ * @internal
+ * @brief An Action to pass to Parser::workhorse() that will increment a counter for
+ * each parsed Option.
+ */
+class Stats::CountOptionsAction: public Parser::Action
+{
+ unsigned* buffer_max;
+public:
+ /**
+ * Creates a new CountOptionsAction that will increase @c *buffer_max_ for each
+ * parsed Option.
+ */
+ CountOptionsAction(unsigned* buffer_max_) :
+ buffer_max(buffer_max_)
+ {
+ }
+
+ bool perform(Option&)
+ {
+ if (*buffer_max == 0x7fffffff)
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
+ ++*buffer_max;
+ return true;
+ }
+};
+
+/**
+ * @internal
+ * @brief An Action to pass to Parser::workhorse() that will store each parsed Option in
+ * appropriate arrays (see Parser::parse()).
+ */
+class Parser::StoreOptionAction: public Parser::Action
+{
+ Parser& parser;
+ Option* options;
+ Option* buffer;
+ int bufmax; //! Number of slots in @c buffer. @c -1 means "large enough".
+public:
+ /**
+ * @brief Creates a new StoreOption action.
+ * @param parser_ the parser whose op_count should be updated.
+ * @param options_ each Option @c o is chained into the linked list @c options_[o.desc->index]
+ * @param buffer_ each Option is appended to this array as long as there's a free slot.
+ * @param bufmax_ number of slots in @c buffer_. @c -1 means "large enough".
+ */
+ StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :
+ parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
+ {
+ // find first empty slot in buffer (if any)
+ int bufidx = 0;
+ while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
+ ++bufidx;
+
+ // set parser's optionCount
+ parser.op_count = bufidx;
+ }
+
+ bool perform(Option& option)
+ {
+ if (bufmax < 0 || parser.op_count < bufmax)
+ {
+ if (parser.op_count == 0x7fffffff)
+ return false; // overflow protection: don't accept number of options that doesn't fit signed int
+
+ buffer[parser.op_count] = option;
+ int idx = buffer[parser.op_count].desc->index;
+ if (options[idx])
+ options[idx].append(buffer[parser.op_count]);
+ else
+ options[idx] = buffer[parser.op_count];
+ ++parser.op_count;
+ }
+ return true; // NOTE: an option that is discarded because of a full buffer is not fatal
+ }
+
+ bool finished(int numargs, const char** args)
+ {
+ // only overwrite non-option argument list if there's at least 1
+ // new non-option argument. Otherwise we keep the old list. This
+ // makes it easy to use default non-option arguments.
+ if (numargs > 0)
+ {
+ parser.nonop_count = numargs;
+ parser.nonop_args = args;
+ }
+
+ return true;
+ }
+};
+
+inline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],
+ Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)
+{
+ StoreOptionAction action(*this, options, buffer, bufmax);
+ err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);
+}
+
+inline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,
+ bool single_minus_longopt)
+{
+ // determine size of options array. This is the greatest index used in the usage + 1
+ int i = 0;
+ while (usage[i].shortopt != 0)
+ {
+ if (usage[i].index + 1 >= options_max)
+ options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel
+
+ ++i;
+ }
+
+ CountOptionsAction action(&buffer_max);
+ Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);
+}
+
+inline bool Parser::workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
+ bool single_minus_longopt, bool print_errors, int min_abbr_len)
+{
+ // protect against NULL pointer
+ if (args == 0)
+ numargs = 0;
+
+ int nonops = 0;
+
+ while (numargs != 0 && *args != 0)
+ {
+ const char* param = *args; // param can be --long-option, -srto or non-option argument
+
+ // in POSIX mode the first non-option argument terminates the option list
+ // a lone minus character is a non-option argument
+ if (param[0] != '-' || param[1] == 0)
+ {
+ if (gnu)
+ {
+ ++nonops;
+ ++args;
+ if (numargs > 0)
+ --numargs;
+ continue;
+ }
+ else
+ break;
+ }
+
+ // -- terminates the option list. The -- itself is skipped.
+ if (param[1] == '-' && param[2] == 0)
+ {
+ shift(args, nonops);
+ ++args;
+ if (numargs > 0)
+ --numargs;
+ break;
+ }
+
+ bool handle_short_options;
+ const char* longopt_name;
+ if (param[1] == '-') // if --long-option
+ {
+ handle_short_options = false;
+ longopt_name = param + 2;
+ }
+ else
+ {
+ handle_short_options = true;
+ longopt_name = param + 1; //for testing a potential -long-option
+ }
+
+ bool try_single_minus_longopt = single_minus_longopt;
+ bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?
+
+ do // loop over short options in group, for long options the body is executed only once
+ {
+ int idx = 0;
+
+ const char* optarg = 0;
+
+ /******************** long option **********************/
+ if (handle_short_options == false || try_single_minus_longopt)
+ {
+ idx = 0;
+ while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
+ ++idx;
+
+ if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options
+ {
+ int i1 = 0;
+ while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
+ ++i1;
+ if (usage[i1].longopt != 0)
+ { // now test if the match is unambiguous by checking for another match
+ int i2 = i1 + 1;
+ while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
+ ++i2;
+
+ if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx
+ idx = i1;
+ }
+ }
+
+ // if we found something, disable handle_short_options (only relevant if single_minus_longopt)
+ if (usage[idx].longopt != 0)
+ handle_short_options = false;
+
+ try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group
+
+ optarg = longopt_name;
+ while (*optarg != 0 && *optarg != '=')
+ ++optarg;
+ if (*optarg == '=') // attached argument
+ ++optarg;
+ else
+ // possibly detached argument
+ optarg = (have_more_args ? args[1] : 0);
+ }
+
+ /************************ short option ***********************************/
+ if (handle_short_options)
+ {
+ if (*++param == 0) // point at the 1st/next option character
+ break; // end of short option group
+
+ idx = 0;
+ while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
+ ++idx;
+
+ if (param[1] == 0) // if the potential argument is separate
+ optarg = (have_more_args ? args[1] : 0);
+ else
+ // if the potential argument is attached
+ optarg = param + 1;
+ }
+
+ const Descriptor* descriptor = &usage[idx];
+
+ if (descriptor->shortopt == 0) /************** unknown option ********************/
+ {
+ // look for dummy entry (shortopt == "" and longopt == "") to use as Descriptor for unknown options
+ idx = 0;
+ while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
+ ++idx;
+ descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
+ }
+
+ if (descriptor != 0)
+ {
+ Option option(descriptor, param, optarg);
+ switch (descriptor->check_arg(option, print_errors))
+ {
+ case ARG_ILLEGAL:
+ return false; // fatal
+ case ARG_OK:
+ // skip one element of the argument vector, if it's a separated argument
+ if (optarg != 0 && have_more_args && optarg == args[1])
+ {
+ shift(args, nonops);
+ if (numargs > 0)
+ --numargs;
+ ++args;
+ }
+
+ // No further short options are possible after an argument
+ handle_short_options = false;
+
+ break;
+ case ARG_IGNORE:
+ case ARG_NONE:
+ option.arg = 0;
+ break;
+ }
+
+ if (!action.perform(option))
+ return false;
+ }
+
+ } while (handle_short_options);
+
+ shift(args, nonops);
+ ++args;
+ if (numargs > 0)
+ --numargs;
+
+ } // while
+
+ if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number
+ numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.
+
+ if (numargs < 0) // if we don't know the number of remaining non-option arguments
+ { // we need to count them
+ numargs = 0;
+ while (args[numargs] != 0)
+ ++numargs;
+ }
+
+ return action.finished(numargs + nonops, args - nonops);
+}
+
+/**
+ * @internal
+ * @brief The implementation of option::printUsage().
+ */
+struct PrintUsageImplementation
+{
+ /**
+ * @internal
+ * @brief Interface for Functors that write (part of) a string somewhere.
+ */
+ struct IStringWriter
+ {
+ /**
+ * @brief Writes the given number of chars beginning at the given pointer somewhere.
+ */
+ virtual void operator()(const char*, int)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with signature <code>func(string, size)</code> where
+ * string can be initialized with a const char* and size with an int.
+ */
+ template<typename Function>
+ struct FunctionWriter: public IStringWriter
+ {
+ Function* write;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*write)(str, size);
+ }
+
+ FunctionWriter(Function* w) :
+ write(w)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a reference to an object with a <code>write(string, size)</code>
+ * method like that of @c std::ostream.
+ */
+ template<typename OStream>
+ struct OStreamWriter: public IStringWriter
+ {
+ OStream& ostream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ ostream.write(str, size);
+ }
+
+ OStreamWriter(OStream& o) :
+ ostream(o)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Like OStreamWriter but encapsulates a @c const reference, which is
+ * typically a temporary object of a user class.
+ */
+ template<typename Temporary>
+ struct TemporaryWriter: public IStringWriter
+ {
+ const Temporary& userstream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ userstream.write(str, size);
+ }
+
+ TemporaryWriter(const Temporary& u) :
+ userstream(u)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with the signature <code>func(fd, string, size)</code> (the
+ * signature of the @c write() system call)
+ * where fd can be initialized from an int, string from a const char* and size from an int.
+ */
+ template<typename Syscall>
+ struct SyscallWriter: public IStringWriter
+ {
+ Syscall* write;
+ int fd;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*write)(fd, str, size);
+ }
+
+ SyscallWriter(Syscall* w, int f) :
+ write(w), fd(f)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Encapsulates a function with the same signature as @c std::fwrite().
+ */
+ template<typename Function, typename Stream>
+ struct StreamWriter: public IStringWriter
+ {
+ Function* fwrite;
+ Stream* stream;
+
+ virtual void operator()(const char* str, int size)
+ {
+ (*fwrite)(str, size, 1, stream);
+ }
+
+ StreamWriter(Function* w, Stream* s) :
+ fwrite(w), stream(s)
+ {
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Sets <code> i1 = max(i1, i2) </code>
+ */
+ static void upmax(int& i1, int i2)
+ {
+ i1 = (i1 >= i2 ? i1 : i2);
+ }
+
+ /**
+ * @internal
+ * @brief Moves the "cursor" to column @c want_x assuming it is currently at column @c x
+ * and sets @c x=want_x .
+ * If <code> x > want_x </code>, a line break is output before indenting.
+ *
+ * @param write Spaces and possibly a line break are written via this functor to get
+ * the desired indentation @c want_x .
+ * @param[in,out] x the current indentation. Set to @c want_x by this method.
+ * @param want_x the desired indentation.
+ */
+ static void indent(IStringWriter& write, int& x, int want_x)
+ {
+ int indent = want_x - x;
+ if (indent < 0)
+ {
+ write("\n", 1);
+ indent = want_x;
+ }
+
+ if (indent > 0)
+ {
+ char space = ' ';
+ for (int i = 0; i < indent; ++i)
+ write(&space, 1);
+ x = want_x;
+ }
+ }
+
+ /**
+ * @brief Returns true if ch is the unicode code point of a wide character.
+ *
+ * @note
+ * The following character ranges are treated as wide
+ * @code
+ * 1100..115F
+ * 2329..232A (just 2 characters!)
+ * 2E80..A4C6 except for 303F
+ * A960..A97C
+ * AC00..D7FB
+ * F900..FAFF
+ * FE10..FE6B
+ * FF01..FF60
+ * FFE0..FFE6
+ * 1B000......
+ * @endcode
+ */
+ static bool isWideChar(unsigned ch)
+ {
+ if (ch == 0x303F)
+ return false;
+
+ return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
+ || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
+ || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
+ || (0x1B000 <= ch));
+ }
+
+ /**
+ * @internal
+ * @brief Splits a @c Descriptor[] array into tables, rows, lines and columns and
+ * iterates over these components.
+ *
+ * The top-level organizational unit is the @e table.
+ * A table begins at a Descriptor with @c help!=NULL and extends up to
+ * a Descriptor with @c help==NULL.
+ *
+ * A table consists of @e rows. Due to line-wrapping and explicit breaks
+ * a row may take multiple lines on screen. Rows within the table are separated
+ * by \\n. They never cross Descriptor boundaries. This means a row ends either
+ * at \\n or the 0 at the end of the help string.
+ *
+ * A row consists of columns/cells. Columns/cells within a row are separated by \\t.
+ * Line breaks within a cell are marked by \\v.
+ *
+ * Rows in the same table need not have the same number of columns/cells. The
+ * extreme case are interjections, which are rows that contain neither \\t nor \\v.
+ * These are NOT treated specially by LinePartIterator, but they are treated
+ * specially by printUsage().
+ *
+ * LinePartIterator iterates through the usage at 3 levels: table, row and part.
+ * Tables and rows are as described above. A @e part is a line within a cell.
+ * LinePartIterator iterates through 1st parts of all cells, then through the 2nd
+ * parts of all cells (if any),... @n
+ * Example: The row <code> "1 \v 3 \t 2 \v 4" </code> has 2 cells/columns and 4 parts.
+ * The parts will be returned in the order 1, 2, 3, 4.
+ *
+ * It is possible that some cells have fewer parts than others. In this case
+ * LinePartIterator will "fill up" these cells with 0-length parts. IOW, LinePartIterator
+ * always returns the same number of parts for each column. Note that this is different
+ * from the way rows and columns are handled. LinePartIterator does @e not guarantee that
+ * the same number of columns will be returned for each row.
+ *
+ */
+ class LinePartIterator
+ {
+ const Descriptor* tablestart; //!< The 1st descriptor of the current table.
+ const Descriptor* rowdesc; //!< The Descriptor that contains the current row.
+ const char* rowstart; //!< Ptr to 1st character of current row within rowdesc->help.
+ const char* ptr; //!< Ptr to current part within the current row.
+ int col; //!< Index of current column.
+ int len; //!< Length of the current part (that ptr points at) in BYTES
+ int screenlen; //!< Length of the current part in screen columns (taking narrow/wide chars into account).
+ int max_line_in_block; //!< Greatest index of a line within the block. This is the number of \\v within the cell with the most \\vs.
+ int line_in_block; //!< Line index within the current cell of the current part.
+ int target_line_in_block; //!< Line index of the parts we should return to the user on this iteration.
+ bool hit_target_line; //!< Flag whether we encountered a part with line index target_line_in_block in the current cell.
+
+ /**
+ * @brief Determines the byte and character lengths of the part at @ref ptr and
+ * stores them in @ref len and @ref screenlen respectively.
+ */
+ void update_length()
+ {
+ screenlen = 0;
+ for (len = 0; ptr[len] != 0 && ptr[len] != '\v' && ptr[len] != '\t' && ptr[len] != '\n'; ++len)
+ {
+ ++screenlen;
+ unsigned ch = (unsigned char) ptr[len];
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
+ {
+ // int __builtin_clz (unsigned int x)
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
+ while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte
+ {
+ ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code
+ ++len;
+ }
+ // ch is the decoded unicode code point
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
+ ++screenlen;
+ }
+ }
+ }
+
+ public:
+ //! @brief Creates an iterator for @c usage.
+ LinePartIterator(const Descriptor usage[]) :
+ tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
+ target_line_in_block(0), hit_target_line(true)
+ {
+ }
+
+ /**
+ * @brief Moves iteration to the next table (if any). Has to be called once on a new
+ * LinePartIterator to move to the 1st table.
+ * @retval false if moving to next table failed because no further table exists.
+ */
+ bool nextTable()
+ {
+ // If this is NOT the first time nextTable() is called after the constructor,
+ // then skip to the next table break (i.e. a Descriptor with help == 0)
+ if (rowdesc != 0)
+ {
+ while (tablestart->help != 0 && tablestart->shortopt != 0)
+ ++tablestart;
+ }
+
+ // Find the next table after the break (if any)
+ while (tablestart->help == 0 && tablestart->shortopt != 0)
+ ++tablestart;
+
+ restartTable();
+ return rowstart != 0;
+ }
+
+ /**
+ * @brief Reset iteration to the beginning of the current table.
+ */
+ void restartTable()
+ {
+ rowdesc = tablestart;
+ rowstart = tablestart->help;
+ ptr = 0;
+ }
+
+ /**
+ * @brief Moves iteration to the next row (if any). Has to be called once after each call to
+ * @ref nextTable() to move to the 1st row of the table.
+ * @retval false if moving to next row failed because no further row exists.
+ */
+ bool nextRow()
+ {
+ if (ptr == 0)
+ {
+ restartRow();
+ return rowstart != 0;
+ }
+
+ while (*ptr != 0 && *ptr != '\n')
+ ++ptr;
+
+ if (*ptr == 0)
+ {
+ if ((rowdesc + 1)->help == 0) // table break
+ return false;
+
+ ++rowdesc;
+ rowstart = rowdesc->help;
+ }
+ else // if (*ptr == '\n')
+ {
+ rowstart = ptr + 1;
+ }
+
+ restartRow();
+ return true;
+ }
+
+ /**
+ * @brief Reset iteration to the beginning of the current row.
+ */
+ void restartRow()
+ {
+ ptr = rowstart;
+ col = -1;
+ len = 0;
+ screenlen = 0;
+ max_line_in_block = 0;
+ line_in_block = 0;
+ target_line_in_block = 0;
+ hit_target_line = true;
+ }
+
+ /**
+ * @brief Moves iteration to the next part (if any). Has to be called once after each call to
+ * @ref nextRow() to move to the 1st part of the row.
+ * @retval false if moving to next part failed because no further part exists.
+ *
+ * See @ref LinePartIterator for details about the iteration.
+ */
+ bool next()
+ {
+ if (ptr == 0)
+ return false;
+
+ if (col == -1)
+ {
+ col = 0;
+ update_length();
+ return true;
+ }
+
+ ptr += len;
+ while (true)
+ {
+ switch (*ptr)
+ {
+ case '\v':
+ upmax(max_line_in_block, ++line_in_block);
+ ++ptr;
+ break;
+ case '\t':
+ if (!hit_target_line) // if previous column did not have the targetline
+ { // then "insert" a 0-length part
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+
+ hit_target_line = false;
+ line_in_block = 0;
+ ++col;
+ ++ptr;
+ break;
+ case 0:
+ case '\n':
+ if (!hit_target_line) // if previous column did not have the targetline
+ { // then "insert" a 0-length part
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+
+ if (++target_line_in_block > max_line_in_block)
+ {
+ update_length();
+ return false;
+ }
+
+ hit_target_line = false;
+ line_in_block = 0;
+ col = 0;
+ ptr = rowstart;
+ continue;
+ default:
+ ++ptr;
+ continue;
+ } // switch
+
+ if (line_in_block == target_line_in_block)
+ {
+ update_length();
+ hit_target_line = true;
+ return true;
+ }
+ } // while
+ }
+
+ /**
+ * @brief Returns the index (counting from 0) of the column in which
+ * the part pointed to by @ref data() is located.
+ */
+ int column()
+ {
+ return col;
+ }
+
+ /**
+ * @brief Returns the index (counting from 0) of the line within the current column
+ * this part belongs to.
+ */
+ int line()
+ {
+ return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line
+ }
+
+ /**
+ * @brief Returns the length of the part pointed to by @ref data() in raw chars (not UTF-8 characters).
+ */
+ int length()
+ {
+ return len;
+ }
+
+ /**
+ * @brief Returns the width in screen columns of the part pointed to by @ref data().
+ * Takes multi-byte UTF-8 sequences and wide characters into account.
+ */
+ int screenLength()
+ {
+ return screenlen;
+ }
+
+ /**
+ * @brief Returns the current part of the iteration.
+ */
+ const char* data()
+ {
+ return ptr;
+ }
+ };
+
+ /**
+ * @internal
+ * @brief Takes input and line wraps it, writing out one line at a time so that
+ * it can be interleaved with output from other columns.
+ *
+ * The LineWrapper is used to handle the last column of each table as well as interjections.
+ * The LineWrapper is called once for each line of output. If the data given to it fits
+ * into the designated width of the last column it is simply written out. If there
+ * is too much data, an appropriate split point is located and only the data up to this
+ * split point is written out. The rest of the data is queued for the next line.
+ * That way the last column can be line wrapped and interleaved with data from
+ * other columns. The following example makes this clearer:
+ * @code
+ * Column 1,1 Column 2,1 This is a long text
+ * Column 1,2 Column 2,2 that does not fit into
+ * a single line.
+ * @endcode
+ *
+ * The difficulty in producing this output is that the whole string
+ * "This is a long text that does not fit into a single line" is the
+ * 1st and only part of column 3. In order to produce the above
+ * output the string must be output piecemeal, interleaved with
+ * the data from the other columns.
+ */
+ class LineWrapper
+ {
+ static const int bufmask = 15; //!< Must be a power of 2 minus 1.
+ /**
+ * @brief Ring buffer for length component of pair (data, length).
+ */
+ int lenbuf[bufmask + 1];
+ /**
+ * @brief Ring buffer for data component of pair (data, length).
+ */
+ const char* datbuf[bufmask + 1];
+ /**
+ * @brief The indentation of the column to which the LineBuffer outputs. LineBuffer
+ * assumes that the indentation has already been written when @ref process()
+ * is called, so this value is only used when a buffer flush requires writing
+ * additional lines of output.
+ */
+ int x;
+ /**
+ * @brief The width of the column to line wrap.
+ */
+ int width;
+ int head; //!< @brief index for next write
+ int tail; //!< @brief index for next read - 1 (i.e. increment tail BEFORE read)
+
+ /**
+ * @brief Multiple methods of LineWrapper may decide to flush part of the buffer to
+ * free up space. The contract of process() says that only 1 line is output. So
+ * this variable is used to track whether something has output a line. It is
+ * reset at the beginning of process() and checked at the end to decide if
+ * output has already occurred or is still needed.
+ */
+ bool wrote_something;
+
+ bool buf_empty()
+ {
+ return ((tail + 1) & bufmask) == head;
+ }
+
+ bool buf_full()
+ {
+ return tail == head;
+ }
+
+ void buf_store(const char* data, int len)
+ {
+ lenbuf[head] = len;
+ datbuf[head] = data;
+ head = (head + 1) & bufmask;
+ }
+
+ //! @brief Call BEFORE reading ...buf[tail].
+ void buf_next()
+ {
+ tail = (tail + 1) & bufmask;
+ }
+
+ /**
+ * @brief Writes (data,len) into the ring buffer. If the buffer is full, a single line
+ * is flushed out of the buffer into @c write.
+ */
+ void output(IStringWriter& write, const char* data, int len)
+ {
+ if (buf_full())
+ write_one_line(write);
+
+ buf_store(data, len);
+ }
+
+ /**
+ * @brief Writes a single line of output from the buffer to @c write.
+ */
+ void write_one_line(IStringWriter& write)
+ {
+ if (wrote_something) // if we already wrote something, we need to start a new line
+ {
+ write("\n", 1);
+ int _ = 0;
+ indent(write, _, x);
+ }
+
+ if (!buf_empty())
+ {
+ buf_next();
+ write(datbuf[tail], lenbuf[tail]);
+ }
+
+ wrote_something = true;
+ }
+ public:
+
+ /**
+ * @brief Writes out all remaining data from the LineWrapper using @c write.
+ * Unlike @ref process() this method indents all lines including the first and
+ * will output a \\n at the end (but only if something has been written).
+ */
+ void flush(IStringWriter& write)
+ {
+ if (buf_empty())
+ return;
+ int _ = 0;
+ indent(write, _, x);
+ wrote_something = false;
+ while (!buf_empty())
+ write_one_line(write);
+ write("\n", 1);
+ }
+
+ /**
+ * @brief Process, wrap and output the next piece of data.
+ *
+ * process() will output at least one line of output. This is not necessarily
+ * the @c data passed in. It may be data queued from a prior call to process().
+ * If the internal buffer is full, more than 1 line will be output.
+ *
+ * process() assumes that the a proper amount of indentation has already been
+ * output. It won't write any further indentation before the 1st line. If
+ * more than 1 line is written due to buffer constraints, the lines following
+ * the first will be indented by this method, though.
+ *
+ * No \\n is written by this method after the last line that is written.
+ *
+ * @param write where to write the data.
+ * @param data the new chunk of data to write.
+ * @param len the length of the chunk of data to write.
+ */
+ void process(IStringWriter& write, const char* data, int len)
+ {
+ wrote_something = false;
+
+ while (len > 0)
+ {
+ if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)
+ {
+ output(write, data, len);
+ len = 0;
+ }
+ else // if (len > width) it's possible (but not guaranteed) that utf8len > width
+ {
+ int utf8width = 0;
+ int maxi = 0;
+ while (maxi < len && utf8width < width)
+ {
+ int charbytes = 1;
+ unsigned ch = (unsigned char) data[maxi];
+ if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
+ {
+ // int __builtin_clz (unsigned int x)
+ // Returns the number of leading 0-bits in x, starting at the most significant bit
+ unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
+ ch = ch & mask; // mask out length bits, we don't verify their correctness
+ while ((maxi + charbytes < len) && //
+ (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte
+ {
+ ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code
+ ++charbytes;
+ }
+ // ch is the decoded unicode code point
+ if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
+ {
+ if (utf8width + 2 > width)
+ break;
+ ++utf8width;
+ }
+ }
+ ++utf8width;
+ maxi += charbytes;
+ }
+
+ // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits
+ // onto the 1st line. If maxi == len, all characters fit on the line.
+
+ if (maxi == len)
+ {
+ output(write, data, len);
+ len = 0;
+ }
+ else // if (maxi < len) at least 1 character (data[maxi] that is) doesn't fit on the line
+ {
+ int i;
+ for (i = maxi; i >= 0; --i)
+ if (data[i] == ' ')
+ break;
+
+ if (i >= 0)
+ {
+ output(write, data, i);
+ data += i + 1;
+ len -= i + 1;
+ }
+ else // did not find a space to split at => split before data[maxi]
+ { // data[maxi] is always the beginning of a character, never a continuation byte
+ output(write, data, maxi);
+ data += maxi;
+ len -= maxi;
+ }
+ }
+ }
+ }
+ if (!wrote_something) // if we didn't already write something to make space in the buffer
+ write_one_line(write); // write at most one line of actual output
+ }
+
+ /**
+ * @brief Constructs a LineWrapper that wraps its output to fit into
+ * screen columns @c x1 (incl.) to @c x2 (excl.).
+ *
+ * @c x1 gives the indentation LineWrapper uses if it needs to indent.
+ */
+ LineWrapper(int x1, int x2) :
+ x(x1), width(x2 - x1), head(0), tail(bufmask)
+ {
+ if (width < 2) // because of wide characters we need at least width 2 or the code breaks
+ width = 2;
+ }
+ };
+
+ /**
+ * @internal
+ * @brief This is the implementation that is shared between all printUsage() templates.
+ * Because all printUsage() templates share this implementation, there is no template bloat.
+ */
+ static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
+ int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
+ {
+ if (width < 1) // protect against nonsense values
+ width = 80;
+
+ if (width > 10000) // protect against overflow in the following computation
+ width = 10000;
+
+ int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
+ int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
+ if (last_column_own_line_max_width == 0)
+ last_column_own_line_max_width = 1;
+
+ LinePartIterator part(usage);
+ while (part.nextTable())
+ {
+
+ /***************** Determine column widths *******************************/
+
+ const int maxcolumns = 8; // 8 columns are enough for everyone
+ int col_width[maxcolumns];
+ int lastcolumn;
+ int leftwidth;
+ int overlong_column_threshold = 10000;
+ do
+ {
+ lastcolumn = 0;
+ for (int i = 0; i < maxcolumns; ++i)
+ col_width[i] = 0;
+
+ part.restartTable();
+ while (part.nextRow())
+ {
+ while (part.next())
+ {
+ if (part.column() < maxcolumns)
+ {
+ upmax(lastcolumn, part.column());
+ if (part.screenLength() < overlong_column_threshold)
+ // We don't let rows that don't use table separators (\t or \v) influence
+ // the width of column 0. This allows the user to interject section headers
+ // or explanatory paragraphs that do not participate in the table layout.
+ if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
+ || part.data()[part.length()] == '\v')
+ upmax(col_width[part.column()], part.screenLength());
+ }
+ }
+ }
+
+ /*
+ * If the last column doesn't fit on the same
+ * line as the other columns, we can fix that by starting it on its own line.
+ * However we can't do this for any of the columns 0..lastcolumn-1.
+ * If their sum exceeds the maximum width we try to fix this by iteratively
+ * ignoring the widest line parts in the width determination until
+ * we arrive at a series of column widths that fit into one line.
+ * The result is a layout where everything is nicely formatted
+ * except for a few overlong fragments.
+ * */
+
+ leftwidth = 0;
+ overlong_column_threshold = 0;
+ for (int i = 0; i < lastcolumn; ++i)
+ {
+ leftwidth += col_width[i];
+ upmax(overlong_column_threshold, col_width[i]);
+ }
+
+ } while (leftwidth > width);
+
+ /**************** Determine tab stops and last column handling **********************/
+
+ int tabstop[maxcolumns];
+ tabstop[0] = 0;
+ for (int i = 1; i < maxcolumns; ++i)
+ tabstop[i] = tabstop[i - 1] + col_width[i - 1];
+
+ int rightwidth = width - tabstop[lastcolumn];
+ bool print_last_column_on_own_line = false;
+ if (rightwidth < last_column_min_width && rightwidth < col_width[lastcolumn])
+ {
+ print_last_column_on_own_line = true;
+ rightwidth = last_column_own_line_max_width;
+ }
+
+ // If lastcolumn == 0 we must disable print_last_column_on_own_line because
+ // otherwise 2 copies of the last (and only) column would be output.
+ // Actually this is just defensive programming. It is currently not
+ // possible that lastcolumn==0 and print_last_column_on_own_line==true
+ // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
+ // rightwidth==width => rightwidth>=last_column_min_width (unless someone passes
+ // a bullshit value >100 for last_column_min_percent) => the above if condition
+ // is false => print_last_column_on_own_line==false
+ if (lastcolumn == 0)
+ print_last_column_on_own_line = false;
+
+ LineWrapper lastColumnLineWrapper(width - rightwidth, width);
+ LineWrapper interjectionLineWrapper(0, width);
+
+ part.restartTable();
+
+ /***************** Print out all rows of the table *************************************/
+
+ while (part.nextRow())
+ {
+ int x = -1;
+ while (part.next())
+ {
+ if (part.column() > lastcolumn)
+ continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)
+
+ if (part.column() == 0)
+ {
+ if (x >= 0)
+ write("\n", 1);
+ x = 0;
+ }
+
+ indent(write, x, tabstop[part.column()]);
+
+ if ((part.column() < lastcolumn)
+ && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
+ || part.data()[part.length()] == '\v'))
+ {
+ write(part.data(), part.length());
+ x += part.screenLength();
+ }
+ else // either part.column() == lastcolumn or we are in the special case of
+ // an interjection that doesn't contain \v or \t
+ {
+ // NOTE: This code block is not necessarily executed for
+ // each line, because some rows may have fewer columns.
+
+ LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
+
+ if (!print_last_column_on_own_line)
+ lineWrapper.process(write, part.data(), part.length());
+ }
+ } // while
+
+ if (print_last_column_on_own_line)
+ {
+ part.restartRow();
+ while (part.next())
+ {
+ if (part.column() == lastcolumn)
+ {
+ write("\n", 1);
+ int _ = 0;
+ indent(write, _, width - rightwidth);
+ lastColumnLineWrapper.process(write, part.data(), part.length());
+ }
+ }
+ }
+
+ write("\n", 1);
+ lastColumnLineWrapper.flush(write);
+ interjectionLineWrapper.flush(write);
+ }
+ }
+ }
+
+}
+;
+
+/**
+ * @brief Outputs a nicely formatted usage string with support for multi-column formatting
+ * and line-wrapping.
+ *
+ * printUsage() takes the @c help texts of a Descriptor[] array and formats them into
+ * a usage message, wrapping lines to achieve the desired output width.
+ *
+ * <b>Table formatting:</b>
+ *
+ * Aside from plain strings which are simply line-wrapped, the usage may contain tables. Tables
+ * are used to align elements in the output.
+ *
+ * @code
+ * // Without a table. The explanatory texts are not aligned.
+ * -c, --create |Creates something.
+ * -k, --kill |Destroys something.
+ *
+ * // With table formatting. The explanatory texts are aligned.
+ * -c, --create |Creates something.
+ * -k, --kill |Destroys something.
+ * @endcode
+ *
+ * Table formatting removes the need to pad help texts manually with spaces to achieve
+ * alignment. To create a table, simply insert \\t (tab) characters to separate the cells
+ * within a row.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c, --create \tCreates something." },
+ * {..., "-k, --kill \tDestroys something." }, ...
+ * @endcode
+ *
+ * Note that you must include the minimum amount of space desired between cells yourself.
+ * Table formatting will insert further spaces as needed to achieve alignment.
+ *
+ * You can insert line breaks within cells by using \\v (vertical tab).
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c,\v--create \tCreates\vsomething." },
+ * {..., "-k,\v--kill \tDestroys\vsomething." }, ...
+ *
+ * // results in
+ *
+ * -c, Creates
+ * --create something.
+ * -k, Destroys
+ * --kill something.
+ * @endcode
+ *
+ * You can mix lines that do not use \\t or \\v with those that do. The plain
+ * lines will not mess up the table layout. Alignment of the table columns will
+ * be maintained even across these interjections.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "-c, --create \tCreates something." },
+ * {..., "----------------------------------" },
+ * {..., "-k, --kill \tDestroys something." }, ...
+ *
+ * // results in
+ *
+ * -c, --create Creates something.
+ * ----------------------------------
+ * -k, --kill Destroys something.
+ * @endcode
+ *
+ * You can have multiple tables within the same usage whose columns are
+ * aligned independently. Simply insert a dummy Descriptor with @c help==0.
+ *
+ * @code
+ * const option::Descriptor usage[] = {
+ * {..., "Long options:" },
+ * {..., "--very-long-option \tDoes something long." },
+ * {..., "--ultra-super-mega-long-option \tTakes forever to complete." },
+ * {..., 0 }, // ---------- table break -----------
+ * {..., "Short options:" },
+ * {..., "-s \tShort." },
+ * {..., "-q \tQuick." }, ...
+ *
+ * // results in
+ *
+ * Long options:
+ * --very-long-option Does something long.
+ * --ultra-super-mega-long-option Takes forever to complete.
+ * Short options:
+ * -s Short.
+ * -q Quick.
+ *
+ * // Without the table break it would be
+ *
+ * Long options:
+ * --very-long-option Does something long.
+ * --ultra-super-mega-long-option Takes forever to complete.
+ * Short options:
+ * -s Short.
+ * -q Quick.
+ * @endcode
+ *
+ * <b>Output methods:</b>
+ *
+ * Because TheLeanMeanC++Option parser is freestanding, you have to provide the means for
+ * output in the first argument(s) to printUsage(). Because printUsage() is implemented as
+ * a set of template functions, you have great flexibility in your choice of output
+ * method. The following example demonstrates typical uses. Anything that's similar enough
+ * will work.
+ *
+ * @code
+ * #include <unistd.h> // write()
+ * #include <iostream> // cout
+ * #include <sstream> // ostringstream
+ * #include <cstdio> // fwrite()
+ * using namespace std;
+ *
+ * void my_write(const char* str, int size) {
+ * fwrite(str, size, 1, stdout);
+ * }
+ *
+ * struct MyWriter {
+ * void write(const char* buf, size_t size) const {
+ * fwrite(str, size, 1, stdout);
+ * }
+ * };
+ *
+ * struct MyWriteFunctor {
+ * void operator()(const char* buf, size_t size) {
+ * fwrite(str, size, 1, stdout);
+ * }
+ * };
+ * ...
+ * printUsage(my_write, usage); // custom write function
+ * printUsage(MyWriter(), usage); // temporary of a custom class
+ * MyWriter writer;
+ * printUsage(writer, usage); // custom class object
+ * MyWriteFunctor wfunctor;
+ * printUsage(&wfunctor, usage); // custom functor
+ * printUsage(write, 1, usage); // write() to file descriptor 1
+ * printUsage(cout, usage); // an ostream&
+ * printUsage(fwrite, stdout, usage); // fwrite() to stdout
+ * ostringstream sstr;
+ * printUsage(sstr, usage); // an ostringstream&
+ *
+ * @endcode
+ *
+ * @par Notes:
+ * @li the @c write() method of a class that is to be passed as a temporary
+ * as @c MyWriter() is in the example, must be a @c const method, because
+ * temporary objects are passed as const reference. This only applies to
+ * temporary objects that are created and destroyed in the same statement.
+ * If you create an object like @c writer in the example, this restriction
+ * does not apply.
+ * @li a functor like @c MyWriteFunctor in the example must be passed as a pointer.
+ * This differs from the way functors are passed to e.g. the STL algorithms.
+ * @li All printUsage() templates are tiny wrappers around a shared non-template implementation.
+ * So there's no penalty for using different versions in the same program.
+ * @li printUsage() always interprets Descriptor::help as UTF-8 and always produces UTF-8-encoded
+ * output. If your system uses a different charset, you must do your own conversion. You
+ * may also need to change the font of the console to see non-ASCII characters properly.
+ * This is particularly true for Windows.
+ * @li @b Security @b warning: Do not insert untrusted strings (such as user-supplied arguments)
+ * into the usage. printUsage() has no protection against malicious UTF-8 sequences.
+ *
+ * @param prn The output method to use. See the examples above.
+ * @param usage the Descriptor[] array whose @c help texts will be formatted.
+ * @param width the maximum number of characters per output line. Note that this number is
+ * in actual characters, not bytes. printUsage() supports UTF-8 in @c help and will
+ * count multi-byte UTF-8 sequences properly. Asian wide characters are counted
+ * as 2 characters.
+ * @param last_column_min_percent (0-100) The minimum percentage of @c width that should be available
+ * for the last column (which typically contains the textual explanation of an option).
+ * If less space is available, the last column will be printed on its own line, indented
+ * according to @c last_column_own_line_max_percent.
+ * @param last_column_own_line_max_percent (0-100) If the last column is printed on its own line due to
+ * less than @c last_column_min_percent of the width being available, then only
+ * @c last_column_own_line_max_percent of the extra line(s) will be used for the
+ * last column's text. This ensures an indentation. See example below.
+ *
+ * @code
+ * // width=20, last_column_min_percent=50 (i.e. last col. min. width=10)
+ * --3456789 1234567890
+ * 1234567890
+ *
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
+ * // last_column_own_line_max_percent=75
+ * --3456789
+ * 123456789012345
+ * 67890
+ *
+ * // width=20, last_column_min_percent=75 (i.e. last col. min. width=15)
+ * // last_column_own_line_max_percent=33 (i.e. max. 5)
+ * --3456789
+ * 12345
+ * 67890
+ * 12345
+ * 67890
+ * @endcode
+ */
+template<typename OStream>
+void printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::OStreamWriter<OStream> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Function>
+void printUsage(Function* prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::FunctionWriter<Function> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Temporary>
+void printUsage(const Temporary& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Syscall>
+void printUsage(Syscall* prn, int fd, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+template<typename Function, typename Stream>
+void printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =
+ 50,
+ int last_column_own_line_max_percent = 75)
+{
+ PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);
+ PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
+}
+
+}
+// namespace option
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif /* OPTIONPARSER_H_ */
diff --git a/vendor/bandit/bandit/failure_formatters/default_failure_formatter.h b/vendor/bandit/bandit/failure_formatters/default_failure_formatter.h
new file mode 100644
index 00000000..48cc9021
--- /dev/null
+++ b/vendor/bandit/bandit/failure_formatters/default_failure_formatter.h
@@ -0,0 +1,30 @@
+#ifndef BANDIT_DEFAULT_FAILURE_FORMATTER_H
+#define BANDIT_DEFAULT_FAILURE_FORMATTER_H
+
+namespace bandit { namespace detail {
+
+ struct default_failure_formatter : public failure_formatter
+ {
+ std::string format(const assertion_exception& err) const
+ {
+ std::stringstream ss;
+ if(err.file_name().size())
+ {
+ ss << err.file_name();
+
+ if(err.line_number())
+ {
+ ss << ":" << err.line_number();
+ }
+
+ ss << ": ";
+ }
+
+ ss << err.what();
+
+ return ss.str();
+ }
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/failure_formatters/failure_formatter.h b/vendor/bandit/bandit/failure_formatters/failure_formatter.h
new file mode 100644
index 00000000..486624f0
--- /dev/null
+++ b/vendor/bandit/bandit/failure_formatters/failure_formatter.h
@@ -0,0 +1,13 @@
+#ifndef BANDIT_FAILURE_FORMATTER_H
+#define BANDIT_FAILURE_FORMATTER_H
+
+namespace bandit { namespace detail {
+
+ struct failure_formatter
+ {
+ virtual std::string format(const assertion_exception&) const = 0;
+ };
+ typedef std::unique_ptr<failure_formatter> failure_formatter_ptr;
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/failure_formatters/failure_formatters.h b/vendor/bandit/bandit/failure_formatters/failure_formatters.h
new file mode 100644
index 00000000..d0914651
--- /dev/null
+++ b/vendor/bandit/bandit/failure_formatters/failure_formatters.h
@@ -0,0 +1,16 @@
+#ifndef BANDIT_FAILURE_FORMATTERS
+#define BANDIT_FAILURE_FORMATTERS
+
+#include "failure_formatter.h"
+#include "default_failure_formatter.h"
+#include "visual_studio_failure_formatter.h"
+
+namespace bandit { namespace detail {
+ inline failure_formatter& registered_failure_formatter()
+ {
+ static default_failure_formatter formatter;
+ return formatter;
+ }
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/failure_formatters/visual_studio_failure_formatter.h b/vendor/bandit/bandit/failure_formatters/visual_studio_failure_formatter.h
new file mode 100644
index 00000000..6ff3fdeb
--- /dev/null
+++ b/vendor/bandit/bandit/failure_formatters/visual_studio_failure_formatter.h
@@ -0,0 +1,36 @@
+#ifndef BANDIT_VISUAL_STUDIO_FAILURE_FORMATTER_H
+#define BANDIT_VISUAL_STUDIO_FAILURE_FORMATTER_H
+
+namespace bandit { namespace detail {
+
+ struct visual_studio_failure_formatter : public failure_formatter
+ {
+ std::string format(const assertion_exception& err) const
+ {
+ std::stringstream ss;
+ if(err.file_name().size())
+ {
+ ss << err.file_name();
+
+ if(err.line_number())
+ {
+ ss << "(" << err.line_number() << ")";
+ }
+
+ ss << ": ";
+ }
+ else
+ {
+ ss << "bandit: ";
+ }
+
+ ss << err.what();
+
+ return ss.str();
+
+ }
+ };
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/grammar.h b/vendor/bandit/bandit/grammar.h
new file mode 100644
index 00000000..1f973344
--- /dev/null
+++ b/vendor/bandit/bandit/grammar.h
@@ -0,0 +1,185 @@
+#ifndef BANDIT_GRAMMAR_H
+#define BANDIT_GRAMMAR_H
+
+namespace bandit {
+
+ inline void describe(const char* desc, detail::voidfunc_t func,
+ detail::listener& listener, detail::contextstack_t& context_stack,
+ bool hard_skip = false)
+ {
+ listener.context_starting(desc);
+
+ context_stack.back()->execution_is_starting();
+
+ detail::bandit_context ctxt(desc, hard_skip);
+
+ context_stack.push_back(&ctxt);
+ try
+ {
+ func();
+ }
+ catch(const bandit::detail::test_run_error& error)
+ {
+ listener.test_run_error(desc, error);
+ }
+
+ context_stack.pop_back();
+
+ listener.context_ended(desc);
+ }
+
+ inline void describe(const char* desc, detail::voidfunc_t func)
+ {
+ describe(desc, func, detail::registered_listener(), detail::context_stack());
+ }
+
+ inline void describe_skip(const char* desc, detail::voidfunc_t func,
+ detail::listener& listener, detail::contextstack_t& context_stack)
+ {
+ bool skip = true;
+ describe(desc, func, listener, context_stack, skip);
+ }
+
+ inline void describe_skip(const char* desc, detail::voidfunc_t func)
+ {
+ describe_skip(desc, func, detail::registered_listener(),
+ detail::context_stack());
+ }
+
+ inline void xdescribe(const char* desc, detail::voidfunc_t func,
+ detail::listener& listener=detail::registered_listener(),
+ detail::contextstack_t& context_stack=detail::context_stack())
+ {
+ describe_skip(desc, func, listener, context_stack);
+ }
+
+ inline void before_each(detail::voidfunc_t func,
+ detail::contextstack_t& context_stack)
+ {
+ context_stack.back()->register_before_each(func);
+ }
+
+ inline void before_each(detail::voidfunc_t func)
+ {
+ before_each(func, detail::context_stack());
+ }
+
+ inline void after_each(detail::voidfunc_t func,
+ detail::contextstack_t& context_stack)
+ {
+ context_stack.back()->register_after_each(func);
+ }
+
+ inline void after_each(detail::voidfunc_t func)
+ {
+ after_each(func, detail::context_stack());
+ }
+
+ inline void it_skip(const char* desc, detail::voidfunc_t, detail::listener& listener)
+ {
+ listener.it_skip(desc);
+ }
+
+ inline void it_skip(const char* desc, detail::voidfunc_t func)
+ {
+ it_skip(desc, func, detail::registered_listener());
+ }
+
+ inline void xit(const char* desc, detail::voidfunc_t func, detail::listener& listener=detail::registered_listener())
+ {
+ it_skip(desc, func, listener);
+ }
+
+ inline void it(const char* desc, detail::voidfunc_t func, detail::listener& listener,
+ detail::contextstack_t& context_stack,
+ bandit::adapters::assertion_adapter& assertion_adapter,
+ detail::run_policy& run_policy)
+ {
+ if(!run_policy.should_run(desc, context_stack))
+ {
+ it_skip(desc, func, listener);
+ return;
+ }
+
+ listener.it_starting(desc);
+
+ context_stack.back()->execution_is_starting();
+
+ auto run_before_eaches = [&](){
+ for_each(context_stack.begin(), context_stack.end(), [](detail::context* ctxt){
+ ctxt->run_before_eaches();
+ });
+ };
+
+ auto run_after_eaches = [&](){
+ for_each(context_stack.begin(), context_stack.end(), [](detail::context* ctxt){
+ ctxt->run_after_eaches();
+ });
+ };
+
+ bool we_have_been_successful_so_far = false;
+ try
+ {
+ assertion_adapter.adapt_exceptions([&](){
+ run_before_eaches();
+
+ func();
+ we_have_been_successful_so_far = true;
+ });
+ }
+ catch(const bandit::detail::assertion_exception& ex)
+ {
+ listener.it_failed(desc, ex);
+ run_policy.encountered_failure();
+ }
+ catch(const std::exception& ex)
+ {
+ std::string err = std::string("exception: ") + ex.what();
+ listener.it_failed(desc, bandit::detail::assertion_exception(err));
+ run_policy.encountered_failure();
+ }
+ catch(...)
+ {
+ listener.it_unknown_error(desc);
+ run_policy.encountered_failure();
+ }
+
+ try
+ {
+ assertion_adapter.adapt_exceptions([&](){
+ run_after_eaches();
+
+ if(we_have_been_successful_so_far)
+ {
+ listener.it_succeeded(desc);
+ }
+ });
+ }
+ catch(const bandit::detail::assertion_exception& ex)
+ {
+ listener.it_failed(desc, ex);
+ run_policy.encountered_failure();
+ }
+ catch(const std::exception& ex)
+ {
+ std::string err = std::string("exception: ") + ex.what();
+ listener.it_failed(desc, bandit::detail::assertion_exception(err));
+ run_policy.encountered_failure();
+ }
+ catch(...)
+ {
+ listener.it_unknown_error(desc);
+ run_policy.encountered_failure();
+ }
+ }
+
+ inline void it(const char* desc, detail::voidfunc_t func)
+ {
+ it(desc, func, detail::registered_listener(), detail::context_stack(),
+ detail::registered_adapter(), detail::registered_run_policy());
+ }
+
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/listener.h b/vendor/bandit/bandit/listener.h
new file mode 100644
index 00000000..07501fcf
--- /dev/null
+++ b/vendor/bandit/bandit/listener.h
@@ -0,0 +1,27 @@
+#ifndef BANDIT_LISTENER_H
+#define BANDIT_LISTENER_H
+
+namespace bandit { namespace detail {
+ struct listener
+ {
+ virtual ~listener() {}
+
+ virtual void test_run_starting() = 0;
+ virtual void test_run_complete() = 0;
+
+ virtual void context_starting(const char* desc) = 0;
+ virtual void context_ended(const char* desc) = 0;
+ virtual void test_run_error(const char* desc, const test_run_error& error) = 0;
+
+ virtual void it_starting(const char* desc) = 0;
+ virtual void it_succeeded(const char* desc) = 0;
+ virtual void it_failed(const char* desc, const detail::assertion_exception& ex) = 0;
+ virtual void it_unknown_error(const char* desc) = 0;
+ virtual void it_skip(const char* desc) = 0;
+
+ virtual bool did_we_pass() const = 0;
+ };
+ typedef std::unique_ptr<listener> listener_ptr;
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/options.h b/vendor/bandit/bandit/options.h
new file mode 100644
index 00000000..493512cf
--- /dev/null
+++ b/vendor/bandit/bandit/options.h
@@ -0,0 +1,111 @@
+#ifndef BANDIT_OPTIONS_H
+#define BANDIT_OPTIONS_H
+
+namespace bandit { namespace detail {
+
+ // TODO: print any unknown options
+ // TODO: check for parser errors
+ struct options
+ {
+
+ options(int argc, char* argv[])
+ {
+ argc -= (argc>0); argv += (argc>0); // Skip program name (argv[0]) if present
+ option::Stats stats(usage(), argc, argv);
+ options_.resize(stats.options_max);
+ std::vector<option::Option> buffer(stats.buffer_max);
+ option::Parser parse(usage(), argc, argv, options_.data(), buffer.data());
+ parsed_ok_ = !parse.error();
+ }
+
+ bool help() const
+ {
+ return options_[HELP] != NULL;
+ }
+
+ void print_usage() const
+ {
+ option::printUsage(std::cout, usage());
+ }
+
+ bool version() const
+ {
+ return options_[VERSION] != NULL;
+ }
+
+ const char* reporter() const
+ {
+ return options_[REPORTER].arg;
+ }
+
+ bool no_color() const
+ {
+ return options_[NO_COLOR] != NULL;
+ }
+
+ typedef enum
+ {
+ FORMATTER_DEFAULT,
+ FORMATTER_VS,
+ FORMATTER_UNKNOWN
+ } formatters;
+
+ formatters formatter() const
+ {
+ std::string arg = options_[FORMATTER].arg ? options_[FORMATTER].arg : "";
+ if(arg == "vs")
+ {
+ return formatters::FORMATTER_VS;
+ }
+
+ return formatters::FORMATTER_DEFAULT;
+ }
+
+ const char* skip() const
+ {
+ return options_[SKIP].arg ? options_[SKIP].arg : "";
+ }
+
+ const char* only() const
+ {
+ return options_[ONLY].arg ? options_[ONLY].arg : "";
+ }
+
+ bool break_on_failure() const
+ {
+ return options_[BREAK_ON_FAILURE] != NULL;
+ }
+
+ private:
+ enum option_index { UNKNOWN, VERSION, HELP, REPORTER, NO_COLOR,
+ FORMATTER, SKIP, ONLY, BREAK_ON_FAILURE };
+
+ static const option::Descriptor* usage()
+ {
+ static const option::Descriptor usage[] =
+ {
+ {UNKNOWN, 0, "", "", option::Arg::None, "USAGE: <executable> [options]\n\n"
+ "Options:" },
+ {VERSION, 0, "", "version", option::Arg::None, " --version, \tPrint version of bandit"},
+ {HELP, 0, "", "help", option::Arg::None, " --help, \tPrint usage and exit."},
+ {REPORTER, 0, "", "reporter", option::Arg::Optional, " --reporter=<reporter>, \tSelect reporter (dots, singleline, xunit, info, spec)"},
+ {NO_COLOR, 0, "", "no-color", option::Arg::None, " --no-color, \tSuppress colors in output"},
+ {FORMATTER, 0, "", "formatter", option::Arg::Optional, " --formatter=<formatter>, \tSelect formatting of errors (default, vs)"},
+ {SKIP, 0, "", "skip", option::Arg::Optional, " --skip=<substring>, \tskip all 'describe' and 'it' containing substring"},
+ {ONLY, 0, "", "only", option::Arg::Optional, " --only=<substring>, \tonly run 'describe' and 'it' containing substring"},
+ {BREAK_ON_FAILURE, 0, "", "break-on-failure", option::Arg::Optional, " --break-on-failure, \tstop test run on first failing test"},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+ return usage;
+ }
+
+ private:
+ std::vector<option::Option> options_;
+ bool parsed_ok_;
+
+ };
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/registration/registrar.h b/vendor/bandit/bandit/registration/registrar.h
new file mode 100644
index 00000000..d57a1f46
--- /dev/null
+++ b/vendor/bandit/bandit/registration/registrar.h
@@ -0,0 +1,25 @@
+#ifndef BANDIT_REGISTRAR_H
+#define BANDIT_REGISTRAR_H
+
+namespace bandit { namespace detail {
+
+ struct spec_registrar
+ {
+ spec_registrar( bandit::detail::voidfunc_t func)
+ {
+ bandit::detail::specs().push_back(func);
+ }
+ };
+
+}}
+
+#define go_bandit \
+ static bandit::detail::spec_registrar bandit_registrar
+
+#define SPEC_BEGIN(name) \
+go_bandit([]{
+
+#define SPEC_END \
+});
+
+#endif
diff --git a/vendor/bandit/bandit/registration/registration.h b/vendor/bandit/bandit/registration/registration.h
new file mode 100644
index 00000000..ad3f8b06
--- /dev/null
+++ b/vendor/bandit/bandit/registration/registration.h
@@ -0,0 +1,7 @@
+#ifndef BANDIT_REGISTRATION_H
+#define BANDIT_REGISTRATION_H
+
+#include <bandit/registration/spec_registry.h>
+#include <bandit/registration/registrar.h>
+
+#endif
diff --git a/vendor/bandit/bandit/registration/spec_registry.h b/vendor/bandit/bandit/registration/spec_registry.h
new file mode 100644
index 00000000..50c35402
--- /dev/null
+++ b/vendor/bandit/bandit/registration/spec_registry.h
@@ -0,0 +1,17 @@
+#ifndef BANDIT_SPEC_REGISTRY_H
+#define BANDIT_SPEC_REGISTRY_H
+
+namespace bandit {
+ namespace detail {
+ typedef std::list<voidfunc_t> spec_registry;
+
+ inline detail::spec_registry& specs()
+ {
+ static detail::spec_registry registry;
+ return registry;
+ }
+ }
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/colorizer.h b/vendor/bandit/bandit/reporters/colorizer.h
new file mode 100644
index 00000000..e8979eec
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/colorizer.h
@@ -0,0 +1,141 @@
+#ifndef BANDIT_REPORTERS_COLORIZER_H
+#define BANDIT_REPORTERS_COLORIZER_H
+
+#ifdef _WIN32
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+#endif
+
+namespace bandit { namespace detail {
+
+#ifdef _WIN32
+ struct colorizer
+ {
+ colorizer(bool colors_enabled = true)
+ : colors_enabled_(colors_enabled),
+ stdout_handle_(GetStdHandle(STD_OUTPUT_HANDLE))
+ {
+ original_color_ = get_console_color();
+ }
+
+ const char* green() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(FOREGROUND_GREEN);
+ }
+ return "";
+ }
+
+ const char* yellow() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
+ }
+ return "";
+ }
+
+ const char* blue() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(FOREGROUND_BLUE);
+ }
+ return "";
+ }
+
+ const char* red() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(FOREGROUND_RED);
+ }
+ return "";
+ }
+
+ const char* white() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+ }
+ return "";
+ }
+
+ const char* reset() const
+ {
+ if(colors_enabled_)
+ {
+ set_console_color(original_color_);
+ }
+ return "";
+ }
+
+ private:
+ WORD get_console_color() const
+ {
+ CONSOLE_SCREEN_BUFFER_INFO info{};
+ GetConsoleScreenBufferInfo(stdout_handle_, &info);
+ return info.wAttributes;
+ }
+
+ void set_console_color(WORD color) const
+ {
+ SetConsoleTextAttribute(stdout_handle_, color);
+ }
+
+ private:
+ bool colors_enabled_;
+ HANDLE stdout_handle_;
+ WORD original_color_;
+ };
+
+#else
+ struct colorizer
+ {
+ colorizer(bool colors_enabled = true)
+ : colors_enabled_(colors_enabled)
+ {}
+
+ const char* green() const
+ {
+ return colors_enabled_ ? "\033[1;32m" : "";
+ }
+
+ const char* yellow() const
+ {
+ return colors_enabled_ ? "\033[1;33m" : "";
+ }
+
+ const char* blue() const
+ {
+ return colors_enabled_ ? "\033[1;34m" : "";
+ }
+
+ const char* red() const
+ {
+ return colors_enabled_ ? "\033[1;31m" : "";
+ }
+
+ const char* white() const
+ {
+ return colors_enabled_ ? "\033[1;37m" : "";
+ }
+
+ const char* reset() const
+ {
+ return colors_enabled_ ? "\033[0m" : "";
+ }
+
+ private:
+ bool colors_enabled_;
+ };
+#endif
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/dots_reporter.h b/vendor/bandit/bandit/reporters/dots_reporter.h
new file mode 100644
index 00000000..3c5083fe
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/dots_reporter.h
@@ -0,0 +1,69 @@
+#ifndef BANDIT_DOTS_REPORTER_H
+#define BANDIT_DOTS_REPORTER_H
+
+namespace bandit { namespace detail {
+
+ struct dots_reporter : public progress_reporter
+ {
+ dots_reporter(std::ostream& stm, const failure_formatter& failure_formatter,
+ const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer)
+ {}
+
+ dots_reporter(const failure_formatter& failure_formatter, const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer)
+ {}
+
+ dots_reporter& operator=(const dots_reporter&) { return *this; }
+
+ void test_run_complete()
+ {
+ progress_reporter::test_run_complete();
+
+ stm_ << std::endl;
+
+ test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_,
+ test_run_errors_, colorizer_);
+ summary.write(stm_);
+ stm_.flush();
+ }
+
+ void test_run_error(const char* desc, const struct test_run_error& err)
+ {
+ progress_reporter::test_run_error(desc, err);
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl;
+
+ test_run_errors_.push_back(ss.str());
+ }
+
+ void it_succeeded(const char* desc)
+ {
+ progress_reporter::it_succeeded(desc);
+ stm_ << colorizer_.green() << "." << colorizer_.reset();
+ stm_.flush();
+ }
+
+ void it_failed(const char* desc, const assertion_exception& ex)
+ {
+ progress_reporter::it_failed(desc, ex);
+ stm_ << colorizer_.red() << "F" << colorizer_.reset();
+ stm_.flush();
+ }
+
+ void it_unknown_error(const char* desc)
+ {
+ progress_reporter::it_unknown_error(desc);
+ stm_ << colorizer_.red() << "E" << colorizer_.reset();
+ stm_.flush();
+ }
+
+ private:
+ std::ostream& stm_;
+ const detail::colorizer& colorizer_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/info_reporter.h b/vendor/bandit/bandit/reporters/info_reporter.h
new file mode 100644
index 00000000..f9b987d0
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/info_reporter.h
@@ -0,0 +1,194 @@
+#ifndef BANDIT_INFO_REPORTER_H
+#define BANDIT_INFO_REPORTER_H
+
+namespace bandit {
+namespace detail {
+
+struct info_reporter : public progress_reporter
+{
+ info_reporter(std::ostream &stm, const failure_formatter &failure_formatter,
+ const detail::colorizer &colorizer)
+ : progress_reporter(failure_formatter)
+ , stm_(stm)
+ , colorizer_(colorizer)
+ , indentation_(0)
+ {}
+
+ info_reporter(const failure_formatter &failure_formatter, const detail::colorizer &colorizer)
+ : progress_reporter(failure_formatter)
+ , stm_(std::cout)
+ , colorizer_(colorizer)
+ , indentation_(0)
+ {}
+
+ info_reporter &operator=(const info_reporter &)
+ {
+ return *this;
+ }
+
+ void summary()
+ {
+ stm_
+ << colorizer_.white()
+ << "Tests run: " << specs_run_
+ << std::endl;
+ if (specs_skipped_ > 0) {
+ stm_
+ << colorizer_.yellow()
+ << "Skipped: " << specs_skipped_
+ << std::endl;
+ }
+ if (specs_succeeded_ > 0) {
+ stm_
+ << colorizer_.green()
+ << "Passed: " << specs_succeeded_
+ << std::endl;
+ }
+ if (specs_failed_ > 0) {
+ stm_
+ << colorizer_.red()
+ << "Failed: " << specs_failed_
+ << std::endl;
+ std::for_each(failures_.begin(), failures_.end(), [&](const std::string &failure) {
+ stm_
+ << colorizer_.white()
+ << " (*) "
+ << colorizer_.red()
+ << failure << std::endl;
+ });
+ }
+ if (test_run_errors_.size() > 0) {
+ stm_
+ << colorizer_.red()
+ << "Errors: " << test_run_errors_.size()
+ << std::endl;
+ std::for_each(test_run_errors_.begin(), test_run_errors_.end(), [&](const std::string &error) {
+ stm_
+ << colorizer_.white()
+ << " (*) "
+ << colorizer_.red()
+ << error << std::endl;
+ });
+ }
+ stm_
+ << colorizer_.reset()
+ << std::endl;
+ }
+
+ void test_run_complete()
+ {
+ progress_reporter::test_run_complete();
+ stm_ << std::endl;
+ summary();
+ stm_.flush();
+ }
+
+ void test_run_error(const char *desc, const struct test_run_error &err)
+ {
+ progress_reporter::test_run_error(desc, err);
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl;
+
+ test_run_errors_.push_back(ss.str());
+ }
+
+ virtual void context_starting(const char *desc)
+ {
+ progress_reporter::context_starting(desc);
+
+ stm_
+ << indent()
+ << colorizer_.blue()
+ << "begin "
+ << colorizer_.white()
+ << desc
+ << colorizer_.reset()
+ << std::endl;
+ ++indentation_;
+ stm_.flush();
+
+ }
+
+ virtual void context_ended(const char *desc)
+ {
+ progress_reporter::context_ended(desc);
+ --indentation_;
+ stm_
+ << indent()
+ << colorizer_.blue()
+ << "end "
+ << colorizer_.reset()
+ << desc << std::endl;
+ }
+
+ virtual void it_starting(const char *desc)
+ {
+ progress_reporter::it_starting(desc);
+ stm_
+ << indent()
+ << colorizer_.yellow()
+ << "[ TEST ]"
+ << colorizer_.reset()
+ << " it " << desc;
+ ++indentation_;
+ stm_.flush();
+ }
+
+ virtual void it_succeeded(const char *desc)
+ {
+ progress_reporter::it_succeeded(desc);
+ --indentation_;
+ stm_
+ << "\r" << indent()
+ << colorizer_.green()
+ << "[ PASS ]"
+ << colorizer_.reset()
+ << " it " << desc
+ << std::endl;
+ stm_.flush();
+ }
+
+ virtual void it_failed(const char *desc, const assertion_exception &ex)
+ {
+ progress_reporter::it_failed(desc, ex);
+ --indentation_;
+ stm_
+ << "\r" << indent()
+ << colorizer_.red()
+ << "[ FAIL ]"
+ << colorizer_.reset()
+ << " it " << desc
+ << std::endl;
+ stm_.flush();
+ }
+
+ virtual void it_unknown_error(const char *desc)
+ {
+ progress_reporter::it_unknown_error(desc);
+ --indentation_;
+ stm_
+ << "\r" << indent()
+ << colorizer_.red()
+ << "-ERROR->"
+ << colorizer_.reset()
+ << " it " << desc
+ << std::endl;
+ stm_.flush();
+ }
+
+private:
+ std::string indent()
+ {
+ return std::string(2*indentation_, ' ');
+ }
+
+ std::ostream &stm_;
+ const detail::colorizer &colorizer_;
+ int indentation_;
+};
+}
+}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/progress_reporter.h b/vendor/bandit/bandit/reporters/progress_reporter.h
new file mode 100644
index 00000000..d9dc47bd
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/progress_reporter.h
@@ -0,0 +1,116 @@
+#ifndef BANDIT_PROGRESS_REPORTER_H
+#define BANDIT_PROGRESS_REPORTER_H
+
+namespace bandit { namespace detail {
+
+ struct progress_reporter : public listener
+ {
+ progress_reporter(const detail::failure_formatter& failure_formatter)
+ : specs_run_(0), specs_succeeded_(0), specs_failed_(0), specs_skipped_(0),
+ failure_formatter_(failure_formatter)
+ {}
+
+ progress_reporter& operator=(const progress_reporter&) { return *this; }
+
+ virtual void test_run_starting()
+ {
+ specs_run_ = 0;
+ specs_succeeded_ = 0;
+ specs_failed_ = 0;
+ specs_skipped_ = 0;
+ failures_.clear();
+ contexts_.clear();
+ }
+
+ virtual void test_run_complete()
+ {
+ }
+
+ virtual void context_starting(const char* desc)
+ {
+ contexts_.push_back(std::string(desc));
+ }
+
+ virtual void context_ended(const char*)
+ {
+ contexts_.pop_back();
+ }
+
+ virtual void test_run_error(const char*, const struct test_run_error&)
+ {}
+
+ void it_starting(const char*)
+ {
+ specs_run_++;
+ }
+
+ void it_succeeded(const char*)
+ {
+ specs_succeeded_++;
+ }
+
+ void it_failed(const char* desc, const assertion_exception& ex)
+ {
+ specs_failed_++;
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << current_context_name() << " " << desc << ":" << std::endl;
+ ss << failure_formatter_.format(ex);
+
+ failures_.push_back(ss.str());
+ }
+
+ void it_unknown_error(const char* desc)
+ {
+ specs_failed_++;
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << current_context_name() << " " << desc << ":" << std::endl;
+ ss << "Unknown exception";
+ ss << std::endl;
+
+ failures_.push_back(ss.str());
+ }
+
+ void it_skip(const char* /* desc */)
+ {
+ specs_skipped_++;
+ }
+
+ bool did_we_pass() const
+ {
+ return specs_run_ > 0 && specs_failed_ == 0 && test_run_errors_.size() == 0;
+ }
+
+ protected:
+ std::string current_context_name()
+ {
+ std::string name;
+
+ std::for_each(contexts_.begin(), contexts_.end(), [&](const std::string context){
+ if(name.size() > 0)
+ {
+ name += " ";
+ }
+
+ name += context;
+ });
+
+ return name;
+ }
+
+ protected:
+ int specs_run_;
+ int specs_succeeded_;
+ int specs_failed_;
+ int specs_skipped_;
+ const detail::failure_formatter& failure_formatter_;
+ std::list<std::string> contexts_;
+ std::list<std::string> failures_;
+ std::list<std::string> test_run_errors_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/reporters.h b/vendor/bandit/bandit/reporters/reporters.h
new file mode 100644
index 00000000..12179270
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/reporters.h
@@ -0,0 +1,29 @@
+#ifndef BANDIT_REPORTERS_H
+#define BANDIT_REPORTERS_H
+
+#include <bandit/reporters/colorizer.h>
+#include <bandit/reporters/progress_reporter.h>
+#include <bandit/reporters/test_run_summary.h>
+#include <bandit/reporters/dots_reporter.h>
+#include <bandit/reporters/single_line_reporter.h>
+#include <bandit/reporters/xunit_reporter.h>
+#include <bandit/reporters/info_reporter.h>
+#include <bandit/reporters/spec_reporter.h>
+
+namespace bandit { namespace detail {
+
+ inline listener& registered_listener(listener* reporter = NULL)
+ {
+ static struct listener* reporter_;
+
+ if(reporter)
+ {
+ reporter_ = reporter;
+ }
+
+ return *reporter_;
+ }
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/single_line_reporter.h b/vendor/bandit/bandit/reporters/single_line_reporter.h
new file mode 100644
index 00000000..08d1c08d
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/single_line_reporter.h
@@ -0,0 +1,86 @@
+#ifndef BANDIT_REPORTERS_SINGLE_LINE_REPORTER_H
+#define BANDIT_REPORTERS_SINGLE_LINE_REPORTER_H
+
+namespace bandit { namespace detail {
+
+ struct single_line_reporter : public progress_reporter
+ {
+ single_line_reporter(std::ostream& stm, const failure_formatter& failure_formatter,
+ const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer)
+ {}
+
+ single_line_reporter(const failure_formatter& failure_formatter,
+ const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer)
+ {}
+
+ single_line_reporter& operator=(const single_line_reporter&) { return *this; }
+
+ void test_run_complete()
+ {
+ progress_reporter::test_run_complete();
+
+ stm_ << std::endl;
+
+ test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_,
+ test_run_errors_, colorizer_);
+ summary.write(stm_);
+ }
+
+ void test_run_error(const char* desc, const struct test_run_error& err)
+ {
+ progress_reporter::test_run_error(desc, err);
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl;
+
+ test_run_errors_.push_back(ss.str());
+ }
+
+ void it_starting(const char* desc)
+ {
+ print_status_line();
+ progress_reporter::it_starting(desc);
+ }
+
+ void it_succeeded(const char* desc)
+ {
+ progress_reporter::it_succeeded(desc);
+ print_status_line();
+ }
+
+ void it_failed(const char* desc, const assertion_exception& ex)
+ {
+ progress_reporter::it_failed(desc, ex);
+ print_status_line();
+ }
+
+ void it_unknown_error(const char* desc)
+ {
+ progress_reporter::it_unknown_error(desc);
+ print_status_line();
+ }
+
+ private:
+ void print_status_line()
+ {
+ stm_ << '\r';
+ stm_ << "Executed " << specs_run_ << " tests.";
+
+ if(specs_failed_)
+ {
+ stm_ << " " << specs_succeeded_ << " succeeded. " << colorizer_.red() << specs_failed_ <<
+ " failed." << colorizer_.reset();
+ }
+ stm_.flush();
+ }
+
+ private:
+ std::ostream& stm_;
+ const detail::colorizer& colorizer_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/spec_reporter.h b/vendor/bandit/bandit/reporters/spec_reporter.h
new file mode 100644
index 00000000..6d63bfb0
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/spec_reporter.h
@@ -0,0 +1,126 @@
+#ifndef BANDIT_SPEC_REPORTER_H
+#define BANDIT_SPEC_REPORTER_H
+
+namespace bandit { namespace detail {
+
+ struct spec_reporter : public progress_reporter
+ {
+ spec_reporter(std::ostream& stm, const failure_formatter& failure_formatter,
+ const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(stm), colorizer_(colorizer), indentation_(0)
+ {}
+
+ spec_reporter(const failure_formatter& failure_formatter, const detail::colorizer& colorizer)
+ : progress_reporter(failure_formatter), stm_(std::cout), colorizer_(colorizer), indentation_(0)
+ {}
+
+ spec_reporter& operator=(const spec_reporter&) { return *this; }
+
+ void test_run_complete()
+ {
+ progress_reporter::test_run_complete();
+
+ stm_ << std::endl;
+
+ test_run_summary summary(specs_run_, specs_failed_, specs_succeeded_, specs_skipped_, failures_,
+ test_run_errors_, colorizer_);
+ summary.write(stm_);
+ stm_.flush();
+ }
+
+ void test_run_error(const char* desc, const struct test_run_error& err)
+ {
+ progress_reporter::test_run_error(desc, err);
+
+ std::stringstream ss;
+ ss << std::endl;
+ ss << "Failed to run \"" << current_context_name() << "\": error \"" << err.what() << "\"" << std::endl;
+
+ test_run_errors_.push_back(ss.str());
+ }
+
+ virtual void context_starting(const char* desc)
+ {
+ progress_reporter::context_starting(desc);
+
+ stm_ << indent();
+ stm_ << "describe " << desc << std::endl;
+ increase_indent();
+ stm_.flush();
+
+ }
+
+ virtual void context_ended(const char* desc)
+ {
+ progress_reporter::context_ended(desc);
+ decrease_indent();
+ }
+
+ virtual void it_starting(const char* desc)
+ {
+ progress_reporter::it_starting(desc);
+ stm_ << indent() << "- it " << desc << " ... ";
+ stm_.flush();
+ }
+
+ virtual void it_succeeded(const char* desc)
+ {
+ progress_reporter::it_succeeded(desc);
+ stm_ << colorizer_.green();
+ stm_ << "OK";
+ stm_ << colorizer_.reset();
+ stm_ << std::endl;
+ stm_.flush();
+ }
+
+ virtual void it_failed(const char* desc, const assertion_exception& ex)
+ {
+ progress_reporter::it_failed(desc, ex);
+ stm_ << colorizer_.red();
+ stm_ << "FAILED";
+ stm_ << colorizer_.reset();
+ stm_ << std::endl;
+ stm_.flush();
+ }
+
+ virtual void it_unknown_error(const char* desc)
+ {
+ progress_reporter::it_unknown_error(desc);
+ stm_ << colorizer_.red();
+ stm_ << "ERROR";
+ stm_ << colorizer_.reset();
+ stm_ << std::endl;
+ stm_.flush();
+ }
+
+ virtual void it_skip(const char* desc)
+ {
+ progress_reporter::it_skip(desc);
+ stm_ << indent() << "- it " << desc << " ... SKIPPED" << std::endl;
+ stm_.flush();
+ }
+
+ private:
+ void increase_indent()
+ {
+ indentation_++;
+ }
+
+ void decrease_indent()
+ {
+ indentation_--;
+ }
+
+ std::string indent()
+ {
+ return std::string(indentation_, '\t');
+ }
+
+ private:
+ std::ostream& stm_;
+ const detail::colorizer& colorizer_;
+ int indentation_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/test_run_summary.h b/vendor/bandit/bandit/reporters/test_run_summary.h
new file mode 100644
index 00000000..aa1d4a59
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/test_run_summary.h
@@ -0,0 +1,90 @@
+#ifndef BANDIT_TEST_RUN_SUMMARY_H
+#define BANDIT_TEST_RUN_SUMMARY_H
+
+namespace bandit { namespace detail {
+
+ struct test_run_summary
+ {
+ test_run_summary(int specs_run, int specs_failed, int specs_succeeded, int specs_skipped,
+ const std::list<std::string>& failures, const std::list<std::string>& test_run_errors,
+ const detail::colorizer& colorizer)
+ : specs_run_(specs_run), specs_succeeded_(specs_succeeded), specs_failed_(specs_failed),
+ specs_skipped_(specs_skipped), failures_(failures), test_run_errors_(test_run_errors),
+ colorizer_(colorizer)
+ {}
+
+ test_run_summary& operator=(const test_run_summary&) { return *this; }
+
+ void write(std::ostream& stm)
+ {
+ if(specs_run_ == 0 && test_run_errors_.size() == 0)
+ {
+ stm << colorizer_.red();
+ stm << "Could not find any tests.";
+ stm << colorizer_.reset();
+ stm << std::endl;
+ return;
+ }
+
+ if(specs_failed_ == 0 && test_run_errors_.size() == 0)
+ {
+ stm << colorizer_.green();
+ stm << "Success!";
+ stm << colorizer_.reset();
+ stm << std::endl;
+ }
+
+ if(test_run_errors_.size() > 0)
+ {
+ std::for_each(test_run_errors_.begin(), test_run_errors_.end(),
+ [&](const std::string& error){
+ stm << error << std::endl;
+ });
+ }
+
+
+ if(specs_failed_ > 0)
+ {
+ stm << colorizer_.red();
+ stm << "There were failures!";
+ stm << colorizer_.reset() << std::endl;
+ std::for_each(failures_.begin(), failures_.end(),
+ [&](const std::string& failure) {
+ stm << failure << std::endl;
+ });
+ stm << std::endl;
+ }
+
+ stm << "Test run complete. " << specs_run_ << " tests run. " << specs_succeeded_ <<
+ " succeeded.";
+
+ if(specs_skipped_ > 0)
+ {
+ stm << " " << specs_skipped_ << " skipped.";
+ }
+
+ if(specs_failed_ > 0)
+ {
+ stm << " " << specs_failed_ << " failed.";
+ }
+
+ if(test_run_errors_.size() > 0)
+ {
+ stm << " " << test_run_errors_.size() << " test run errors.";
+ }
+
+ stm << std::endl;
+ }
+
+ private:
+ int specs_run_;
+ int specs_succeeded_;
+ int specs_failed_;
+ int specs_skipped_;
+ std::list<std::string> failures_;
+ std::list<std::string> test_run_errors_;
+ const detail::colorizer& colorizer_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/reporters/xunit_reporter.h b/vendor/bandit/bandit/reporters/xunit_reporter.h
new file mode 100644
index 00000000..15f6ea29
--- /dev/null
+++ b/vendor/bandit/bandit/reporters/xunit_reporter.h
@@ -0,0 +1,109 @@
+#ifndef BANDIT_REPORTERS_XUNIT_REPORTER_H
+#define BANDIT_REPORTERS_XUNIT_REPORTER_H
+
+namespace bandit { namespace detail {
+
+ struct xunit_reporter : public progress_reporter
+ {
+ xunit_reporter(std::ostream& stm, const failure_formatter& formatter)
+ : progress_reporter(formatter), stm_(stm)
+ {
+ }
+
+ xunit_reporter(const failure_formatter& formatter)
+ : progress_reporter(formatter), stm_(std::cout)
+ {
+ }
+
+ void it_starting(const char* desc)
+ {
+ progress_reporter::it_starting(desc);
+ work_stm_ << "\t<testcase classname=\"" << escape(current_context_name()) << "\" ";
+ work_stm_ << "name=\"" << escape(desc) << "\" time=\"0\">\n";
+ }
+
+ void it_succeeded(const char* desc)
+ {
+ progress_reporter::it_succeeded(desc);
+ work_stm_ << "\t</testcase>\n";
+ }
+
+ void it_failed(const char* desc, const assertion_exception& ex)
+ {
+ progress_reporter::it_failed(desc, ex);
+ work_stm_ << "\t\t<failure message=\"" << escape(failure_formatter_.format(ex)) << "\" />\n";
+ work_stm_ << "\t</testcase>\n";
+ }
+
+ void it_unknown_error(const char* desc)
+ {
+ progress_reporter::it_unknown_error(desc);
+ work_stm_ << "\t\t<failure message=\"Unknown exception\" />\n";
+ work_stm_ << "\t</testcase>\n";
+ }
+
+ void it_skip(const char* desc)
+ {
+ progress_reporter::it_skip(desc);
+ work_stm_ << "\t<testcase classname=\"" << escape(current_context_name()) << "\" ";
+ work_stm_ << "name=\"" << escape(desc) << "\" time=\"0\">\n";
+ work_stm_ << "\t\t<skipped />\n";
+ work_stm_ << "\t</testcase>\n";
+ }
+
+ void test_run_complete()
+ {
+ stm_ << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+ stm_ << "<testsuite name=\"bandit\" tests=\"" << specs_run_ << "\" errors=\"0\" failures=\""
+ << specs_failed_ << "\"";
+
+ if(specs_skipped_ > 0)
+ {
+ stm_ << " skipped=\"" << specs_skipped_ << "\"";
+ }
+
+ stm_ << ">\n";
+
+ stm_ << work_stm_.str();
+
+ stm_ << "</testsuite>\n";
+ }
+
+ private:
+ std::string escape(const std::string& str)
+ {
+ std::stringstream stm;
+
+ std::for_each(str.begin(), str.end(), [&](char c){
+ switch(c)
+ {
+ case '&':
+ stm << "&amp;";
+ break;
+ case '<':
+ stm << "&lt;";
+ break;
+ case '>':
+ stm << "&gt;";
+ break;
+ case '\\':
+ stm << "&apos;";
+ break;
+ case '\"':
+ stm << "&quot;";
+ break;
+ default:
+ stm << c;
+ }
+ });
+
+ return stm.str();
+ }
+
+ private:
+ std::ostream& stm_;
+ std::stringstream work_stm_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/run_policies/always_run_policy.h b/vendor/bandit/bandit/run_policies/always_run_policy.h
new file mode 100644
index 00000000..29bdc627
--- /dev/null
+++ b/vendor/bandit/bandit/run_policies/always_run_policy.h
@@ -0,0 +1,16 @@
+#ifndef BANDIT_ALWAYS_RUN_POLICY_H
+#define BANDIT_ALWAYS_RUN_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct always_run_policy : public run_policy
+ {
+ bool should_run(const char* /* it_name */, const contextstack_t& /* contexts */) const
+ {
+ return true;
+ }
+ };
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/run_policies/bandit_run_policy.h b/vendor/bandit/bandit/run_policies/bandit_run_policy.h
new file mode 100644
index 00000000..4a5c0808
--- /dev/null
+++ b/vendor/bandit/bandit/run_policies/bandit_run_policy.h
@@ -0,0 +1,161 @@
+#ifndef BANDIT_BANDIT_RUN_POLICY_H
+#define BANDIT_BANDIT_RUN_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct bandit_run_policy : public run_policy
+ {
+ bandit_run_policy(const char* skip_pattern, const char* only_pattern, bool break_on_failure)
+ : run_policy(), skip_pattern_(skip_pattern), only_pattern_(only_pattern), break_on_failure_(break_on_failure)
+ {}
+
+ bool should_run(const char* it_name, const contextstack_t& contexts) const
+ {
+ if(break_on_failure_ && has_encountered_failure())
+ {
+ return false;
+ }
+
+ //
+ // Never run if a context has been marked as skip
+ // using 'describe_skip'
+ //
+ if(has_context_with_hard_skip(contexts))
+ {
+ return false;
+ }
+
+ //
+ // Always run if no patterns have been specifed
+ //
+ if(!has_skip_pattern() && !has_only_pattern())
+ {
+ return true;
+ }
+
+ if(has_only_pattern() && !has_skip_pattern())
+ {
+ return context_matches_only_pattern(contexts)
+ || matches_only_pattern(it_name);
+ }
+
+ if(has_skip_pattern() && !has_only_pattern())
+ {
+ bool skip = context_matches_skip_pattern(contexts) ||
+ matches_skip_pattern(it_name);
+ return !skip;
+ }
+
+ //
+ // If we've come this far, both 'skip' and 'only'
+ // have been specified.
+ //
+ // If our contexts match 'only' we're still good
+ // regardless of whether there's a 'skip' somewhere
+ // in the context stack as well.
+ if(context_matches_only_pattern(contexts))
+ {
+ //
+ // We can still mark the current 'it' as 'skip'
+ // and ignore it. We check that here.
+ //
+ return !matches_skip_pattern(it_name);
+ }
+
+ //
+ // If we've gotten this far, the context matches 'skip'
+ // We can still run this spec if it is specifically marked
+ // as 'only'.
+ //
+ return matches_only_pattern(it_name);
+ }
+
+ private:
+ bool has_context_with_hard_skip(const contextstack_t& contexts) const
+ {
+ contextstack_t::const_iterator it;
+ for(it = contexts.begin(); it != contexts.end(); it++)
+ {
+ if((*it)->hard_skip())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool has_only_pattern() const
+ {
+ return only_pattern_.size() > 0;
+ }
+
+ bool has_skip_pattern() const
+ {
+ return skip_pattern_.size() > 0;
+ }
+
+ bool context_matches_only_pattern(const contextstack_t& contexts) const
+ {
+ contextstack_t::const_iterator it;
+ for(it = contexts.begin(); it != contexts.end(); it++)
+ {
+ if(matches_only_pattern((*it)->name()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool context_matches_skip_pattern(const contextstack_t& contexts) const
+ {
+ contextstack_t::const_iterator it;
+ for(it = contexts.begin(); it != contexts.end(); it++)
+ {
+ if(matches_skip_pattern((*it)->name()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool matches_only_pattern(const char* name) const
+ {
+ std::string n(name);
+ return matches_only_pattern(n);
+ }
+
+ bool matches_only_pattern(const std::string& name) const
+ {
+ return matches_pattern(name, only_pattern_);
+ }
+
+ bool matches_skip_pattern(const char* name) const
+ {
+ std::string n(name);
+ return matches_skip_pattern(n);
+ }
+
+ bool matches_skip_pattern(const std::string& name) const
+ {
+ return matches_pattern(name, skip_pattern_);
+ }
+
+ bool matches_pattern(const std::string& name, const std::string& pattern) const
+ {
+ return name.find(pattern) != std::string::npos;
+ }
+
+ private:
+ std::string skip_pattern_;
+ std::string only_pattern_;
+ bool break_on_failure_;
+ };
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/run_policies/never_run_policy.h b/vendor/bandit/bandit/run_policies/never_run_policy.h
new file mode 100644
index 00000000..003fd889
--- /dev/null
+++ b/vendor/bandit/bandit/run_policies/never_run_policy.h
@@ -0,0 +1,14 @@
+#ifndef BANDIT_NEVER_RUN_POLICY_H
+#define BANDIT_NEVER_RUN_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct never_run_policy : public run_policy
+ {
+ bool should_run(const char* /* it_name */, const contextstack_t& /* contexts */) const
+ {
+ return false;
+ }
+ };
+}}
+#endif
diff --git a/vendor/bandit/bandit/run_policies/run_policies.h b/vendor/bandit/bandit/run_policies/run_policies.h
new file mode 100644
index 00000000..88d8dbb5
--- /dev/null
+++ b/vendor/bandit/bandit/run_policies/run_policies.h
@@ -0,0 +1,9 @@
+#ifndef BANDIT_RUN_POLICIES_H
+#define BANDIT_RUN_POLICIES_H
+
+#include "run_policy.h"
+#include "always_run_policy.h"
+#include "never_run_policy.h"
+#include "bandit_run_policy.h"
+
+#endif
diff --git a/vendor/bandit/bandit/run_policies/run_policy.h b/vendor/bandit/bandit/run_policies/run_policy.h
new file mode 100644
index 00000000..4a6e8e1d
--- /dev/null
+++ b/vendor/bandit/bandit/run_policies/run_policy.h
@@ -0,0 +1,44 @@
+#ifndef BANDIT_RUN_POLICY_H
+#define BANDIT_RUN_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct run_policy
+ {
+ run_policy() : encountered_failure_(false) {}
+ run_policy(const run_policy& other) = default;
+ run_policy(run_policy&&) = default;
+ virtual ~run_policy() {}
+
+ virtual bool should_run(const char* it_name, const contextstack_t& contexts) const = 0;
+
+ virtual void encountered_failure()
+ {
+ encountered_failure_ = true;
+ }
+
+ virtual bool has_encountered_failure() const
+ {
+ return encountered_failure_;
+ }
+
+ private:
+ bool encountered_failure_;
+ };
+ typedef std::unique_ptr<run_policy> run_policy_ptr;
+
+ inline run_policy& registered_run_policy(run_policy* policy = NULL)
+ {
+ static struct run_policy* policy_;
+
+ if(policy)
+ {
+ policy_ = policy;
+ }
+
+ return *policy_;
+ }
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/runner.h b/vendor/bandit/bandit/runner.h
new file mode 100644
index 00000000..1f8dcd11
--- /dev/null
+++ b/vendor/bandit/bandit/runner.h
@@ -0,0 +1,103 @@
+#ifndef BANDIT_RUNNER_H
+#define BANDIT_RUNNER_H
+
+namespace bandit {
+
+ namespace detail {
+
+ inline run_policy_ptr create_run_policy(const options& opt)
+ {
+ return run_policy_ptr(new bandit_run_policy(opt.skip(), opt.only(), opt.break_on_failure()));
+ }
+
+ inline listener_ptr create_reporter(const options& opt,
+ const failure_formatter* formatter, const colorizer& colorizer)
+ {
+ std::string name(opt.reporter() ? opt.reporter() : "");
+
+ if(name == "singleline")
+ {
+ return std::unique_ptr<detail::listener>(new single_line_reporter(*formatter, colorizer));
+ }
+
+ if(name == "xunit")
+ {
+ return std::unique_ptr<detail::listener>(new xunit_reporter(*formatter));
+ }
+
+ if(name == "info")
+ {
+ return std::unique_ptr<detail::listener>(new info_reporter(*formatter, colorizer));
+ }
+
+ if(name == "spec")
+ {
+ return std::unique_ptr<detail::listener>(new spec_reporter(*formatter, colorizer));
+ }
+
+ return std::unique_ptr<detail::listener>(new dots_reporter(*formatter, colorizer));
+ }
+
+ typedef std::function<listener_ptr (const std::string&, const failure_formatter*)> reporter_factory_fn;
+ typedef std::function<detail::listener* (detail::listener*)> register_reporter_fn;
+
+ inline failure_formatter_ptr create_formatter(const options& opt)
+ {
+ if(opt.formatter() == options::formatters::FORMATTER_VS)
+ {
+ return failure_formatter_ptr(new visual_studio_failure_formatter());
+ }
+
+ return failure_formatter_ptr(new default_failure_formatter());
+ }
+ }
+
+ inline int run(const detail::options& opt, const detail::spec_registry& specs,
+ detail::contextstack_t& context_stack, detail::listener& listener)
+ {
+ if(opt.help())
+ {
+ opt.print_usage();
+ return 0;
+ }
+
+ if(opt.version())
+ {
+ std::cout << "bandit version " << BANDIT_VERSION << std::endl;
+ return 0;
+ }
+
+ auto call_func = [](const detail::voidfunc_t& func) {
+ func();
+ };
+
+ listener.test_run_starting();
+
+ bool hard_skip = false;
+ detail::bandit_context global_context("", hard_skip);
+ context_stack.push_back(&global_context);
+
+ for_each(specs.begin(), specs.end(), call_func);
+
+ listener.test_run_complete();
+
+ return listener.did_we_pass() ? 0 : 1;
+ }
+
+ inline int run(int argc, char* argv[])
+ {
+ detail::options opt(argc, argv);
+ detail::failure_formatter_ptr formatter(create_formatter(opt));
+ bandit::detail::colorizer colorizer(!opt.no_color());
+ detail::listener_ptr reporter(create_reporter(opt, formatter.get(), colorizer));
+
+ detail::registered_listener(reporter.get());
+
+ detail::run_policy_ptr run_policy = create_run_policy(opt);
+ registered_run_policy(run_policy.get());
+
+ return run(opt, detail::specs(), detail::context_stack(), *reporter);
+ }
+}
+
+#endif
diff --git a/vendor/bandit/bandit/skip_policies/always_include_policy.h b/vendor/bandit/bandit/skip_policies/always_include_policy.h
new file mode 100644
index 00000000..2e978308
--- /dev/null
+++ b/vendor/bandit/bandit/skip_policies/always_include_policy.h
@@ -0,0 +1,16 @@
+#ifndef BANDIT_ALWAYS_INCLUDE_POLICY_H
+#define BANDIT_ALWAYS_INCLUDE_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct always_include_policy : public skip_policy
+ {
+ bool should_skip(const char*) const
+ {
+ return false;
+ }
+ };
+
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/skip_policies/always_skip_policy.h b/vendor/bandit/bandit/skip_policies/always_skip_policy.h
new file mode 100644
index 00000000..9d6a4bfc
--- /dev/null
+++ b/vendor/bandit/bandit/skip_policies/always_skip_policy.h
@@ -0,0 +1,15 @@
+#ifndef BANDIT_ALWAYS_SKIP_POLICY_H
+#define BANDIT_ALWAYS_SKIP_POLICY_H
+
+namespace bandit { namespace detail {
+
+ struct always_skip_policy : public skip_policy
+ {
+ bool should_skip(const char*) const
+ {
+ return true;
+ }
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/skip_policies/name_contains_skip_policy.h b/vendor/bandit/bandit/skip_policies/name_contains_skip_policy.h
new file mode 100644
index 00000000..da727c3d
--- /dev/null
+++ b/vendor/bandit/bandit/skip_policies/name_contains_skip_policy.h
@@ -0,0 +1,28 @@
+#ifndef BANDIT_NAME_CONTAINS_SKIP_POLICY_H
+#define BANDIT_NAME_CONTAINS_SKIP_POLICY_H
+
+namespace bandit { namespace detail {
+ struct name_contains_skip_policy : public skip_policy
+ {
+ name_contains_skip_policy(const char* pattern)
+ : pattern_(pattern)
+ {}
+
+ bool should_skip(const char* name) const
+ {
+ if(pattern_.size() == 0)
+ {
+ return false;
+ }
+
+ std::string n(name);
+ bool skip = n.find(pattern_) != std::string::npos;
+ return skip;
+ }
+
+ private:
+ const std::string pattern_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/bandit/skip_policies/skip_policies.h b/vendor/bandit/bandit/skip_policies/skip_policies.h
new file mode 100644
index 00000000..f3fbfbfd
--- /dev/null
+++ b/vendor/bandit/bandit/skip_policies/skip_policies.h
@@ -0,0 +1,9 @@
+#ifndef BANDIT_SKIP_POLICIES
+#define BANDIT_SKIP_POLICIES
+
+#include <bandit/skip_policies/skip_policy.h>
+#include <bandit/skip_policies/always_include_policy.h>
+#include <bandit/skip_policies/always_skip_policy.h>
+#include <bandit/skip_policies/name_contains_skip_policy.h>
+
+#endif
diff --git a/vendor/bandit/bandit/skip_policies/skip_policy.h b/vendor/bandit/bandit/skip_policies/skip_policy.h
new file mode 100644
index 00000000..ca606dfb
--- /dev/null
+++ b/vendor/bandit/bandit/skip_policies/skip_policy.h
@@ -0,0 +1,29 @@
+#ifndef BANDIT_SKIP_POLICY_H
+#define BANDIT_SKIP_POLICY_H
+
+namespace bandit {
+
+ struct skip_policy
+ {
+ virtual bool should_skip(const char* name) const = 0;
+ };
+ typedef std::unique_ptr<skip_policy> skip_policy_ptr;
+
+ namespace detail {
+
+ inline skip_policy& registered_skip_policy(skip_policy* policy = NULL)
+ {
+ static struct skip_policy* policy_;
+
+ if(policy)
+ {
+ policy_ = policy;
+ }
+
+ return *policy_;
+ }
+ }
+
+}
+
+#endif
diff --git a/vendor/bandit/bandit/test_run_error.h b/vendor/bandit/bandit/test_run_error.h
new file mode 100644
index 00000000..307ef3fe
--- /dev/null
+++ b/vendor/bandit/bandit/test_run_error.h
@@ -0,0 +1,12 @@
+#ifndef BANDIT_TEST_RUN_ERROR
+#define BANDIT_TEST_RUN_ERROR
+
+namespace bandit { namespace detail {
+
+ struct test_run_error : public std::runtime_error
+ {
+ test_run_error(const char* message) : std::runtime_error(message) {}
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/cmake/cotire.cmake b/vendor/bandit/cmake/cotire.cmake
new file mode 100644
index 00000000..a6e3141c
--- /dev/null
+++ b/vendor/bandit/cmake/cotire.cmake
@@ -0,0 +1,3185 @@
+# - cotire (compile time reducer)
+#
+# See the cotire manual for usage hints.
+#
+#=============================================================================
+# Copyright 2012-2013 Sascha Kratky
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#=============================================================================
+
+if(__COTIRE_INCLUDED)
+ return()
+endif()
+set(__COTIRE_INCLUDED TRUE)
+
+# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode
+# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid
+if (NOT CMAKE_SCRIPT_MODE_FILE)
+ cmake_policy(PUSH)
+endif()
+# we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5
+# we need APPEND_STRING option for set_property available since 2.8.6
+cmake_minimum_required(VERSION 2.8.6)
+if (NOT CMAKE_SCRIPT_MODE_FILE)
+ cmake_policy(POP)
+endif()
+
+set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
+set (COTIRE_CMAKE_MODULE_VERSION "1.4.1")
+
+include(CMakeParseArguments)
+include(ProcessorCount)
+
+function (cotire_determine_compiler_version _language _versionPrefix)
+ if (NOT ${_versionPrefix}_VERSION)
+ # use CMake's predefined compiler version variable (available since CMake 2.8.8)
+ if (DEFINED CMAKE_${_language}_COMPILER_VERSION)
+ set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}")
+ elseif (WIN32)
+ # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
+ unset (ENV{VS_UNICODE_OUTPUT})
+ string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
+ execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1}
+ ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10)
+ string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}")
+ else()
+ # assume GCC like command line interface
+ string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1)
+ execute_process (COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion"
+ OUTPUT_VARIABLE ${_versionPrefix}_VERSION
+ RESULT_VARIABLE _result
+ OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10)
+ if (_result)
+ set (${_versionPrefix}_VERSION "")
+ endif()
+ endif()
+ if (${_versionPrefix}_VERSION)
+ set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version")
+ endif()
+ set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE)
+ if (COTIRE_DEBUG)
+ message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}")
+ endif()
+ endif()
+endfunction()
+
+function (cotire_get_source_file_extension _sourceFile _extVar)
+ # get_filename_component returns extension from first occurrence of . in file name
+ # this function computes the extension from last occurrence of . in file name
+ string (FIND "${_sourceFile}" "." _index REVERSE)
+ if (_index GREATER -1)
+ math (EXPR _index "${_index} + 1")
+ string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt)
+ else()
+ set (_sourceExt "")
+ endif()
+ set (${_extVar} "${_sourceExt}" PARENT_SCOPE)
+endfunction()
+
+macro (cotire_check_is_path_relative_to _path _isRelativeVar)
+ set (${_isRelativeVar} FALSE)
+ if (IS_ABSOLUTE "${_path}")
+ foreach (_dir ${ARGN})
+ file (RELATIVE_PATH _relPath "${_dir}" "${_path}")
+ if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\."))
+ set (${_isRelativeVar} TRUE)
+ break()
+ endif()
+ endforeach()
+ endif()
+endmacro()
+
+function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar)
+ set (_sourceFiles "")
+ set (_excludedSourceFiles "")
+ set (_cotiredSourceFiles "")
+ if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
+ set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}")
+ else()
+ set (_languageExtensions "")
+ endif()
+ if (CMAKE_${_language}_IGNORE_EXTENSIONS)
+ set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}")
+ else()
+ set (_ignoreExtensions "")
+ endif()
+ if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS)
+ set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}")
+ else()
+ set (_excludeExtensions "")
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_language} source file extensions: ${_languageExtensions}")
+ message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}")
+ message (STATUS "${_language} exclude extensions: ${_excludeExtensions}")
+ endif()
+ foreach (_sourceFile ${ARGN})
+ get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY)
+ get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT)
+ get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC)
+ get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE)
+ set (_sourceIsFiltered FALSE)
+ if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic)
+ cotire_get_source_file_extension("${_sourceFile}" _sourceExt)
+ if (_sourceExt)
+ list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex)
+ if (_ignoreIndex LESS 0)
+ list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex)
+ if (_excludeIndex GREATER -1)
+ list (APPEND _excludedSourceFiles "${_sourceFile}")
+ else()
+ list (FIND _languageExtensions "${_sourceExt}" _sourceIndex)
+ if (_sourceIndex GREATER -1)
+ set (_sourceIsFiltered TRUE)
+ elseif ("${_sourceLanguage}" STREQUAL "${_language}")
+ # add to excluded sources, if file is not ignored and has correct language without having the correct extension
+ list (APPEND _excludedSourceFiles "${_sourceFile}")
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}")
+ endif()
+ if (_sourceIsFiltered)
+ get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED)
+ get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET)
+ get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS)
+ if (COTIRE_DEBUG)
+ message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired}")
+ endif()
+ if (_sourceIsCotired)
+ list (APPEND _cotiredSourceFiles "${_sourceFile}")
+ elseif (_sourceIsExcluded OR _sourceCompileFlags)
+ list (APPEND _excludedSourceFiles "${_sourceFile}")
+ else()
+ list (APPEND _sourceFiles "${_sourceFile}")
+ endif()
+ endif()
+ endforeach()
+ if (COTIRE_DEBUG)
+ message (STATUS "All: ${ARGN}")
+ message (STATUS "${_language}: ${_sourceFiles}")
+ message (STATUS "Excluded: ${_excludedSourceFiles}")
+ message (STATUS "Cotired: ${_cotiredSourceFiles}")
+ endif()
+ set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE)
+ set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE)
+ set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type)
+ set (_filteredObjects "")
+ foreach (_object ${ARGN})
+ get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
+ if (_isSet)
+ get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
+ if (_propertyValue)
+ list (APPEND _filteredObjects "${_object}")
+ endif()
+ endif()
+ endforeach()
+ set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type)
+ set (_filteredObjects "")
+ foreach (_object ${ARGN})
+ get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET)
+ if (_isSet)
+ get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
+ if (NOT _propertyValue)
+ list (APPEND _filteredObjects "${_object}")
+ endif()
+ endif()
+ endforeach()
+ set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_source_file_property_values _valuesVar _property)
+ set (_values "")
+ foreach (_sourceFile ${ARGN})
+ get_source_file_property(_propertyValue "${_sourceFile}" ${_property})
+ if (_propertyValue)
+ list (APPEND _values "${_propertyValue}")
+ endif()
+ endforeach()
+ set (${_valuesVar} ${_values} PARENT_SCOPE)
+endfunction()
+
+function (cotrie_resolve_config_properites _configurations _propertiesVar)
+ set (_properties "")
+ foreach (_property ${ARGN})
+ if ("${_property}" MATCHES "<CONFIG>")
+ foreach (_config ${_configurations})
+ string (TOUPPER "${_config}" _upperConfig)
+ string (REPLACE "<CONFIG>" "${_upperConfig}" _configProperty "${_property}")
+ list (APPEND _properties ${_configProperty})
+ endforeach()
+ else()
+ list (APPEND _properties ${_property})
+ endif()
+ endforeach()
+ set (${_propertiesVar} ${_properties} PARENT_SCOPE)
+endfunction()
+
+function (cotrie_copy_set_properites _configurations _type _source _target)
+ cotrie_resolve_config_properites("${_configurations}" _properties ${ARGN})
+ foreach (_property ${_properties})
+ get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET)
+ if (_isSet)
+ get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property})
+ set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}")
+ endif()
+ endforeach()
+endfunction()
+
+function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar)
+ if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ set (_flagPrefix "[/-]")
+ else()
+ set (_flagPrefix "--?")
+ endif()
+ set (_optionFlag "")
+ set (_matchedOptions "")
+ set (_unmatchedOptions "")
+ foreach (_compileFlag ${ARGN})
+ if (_compileFlag)
+ if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}")
+ # option with separate argument
+ list (APPEND _matchedOptions "${_compileFlag}")
+ set (_optionFlag "")
+ elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$")
+ # remember option
+ set (_optionFlag "${CMAKE_MATCH_2}")
+ elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$")
+ # option with joined argument
+ list (APPEND _matchedOptions "${CMAKE_MATCH_3}")
+ set (_optionFlag "")
+ else()
+ # flush remembered option
+ if (_optionFlag)
+ list (APPEND _matchedOptions "${_optionFlag}")
+ set (_optionFlag "")
+ endif()
+ # add to unfiltered options
+ list (APPEND _unmatchedOptions "${_compileFlag}")
+ endif()
+ endif()
+ endforeach()
+ if (_optionFlag)
+ list (APPEND _matchedOptions "${_optionFlag}")
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "Filter ${_flagFilter}")
+ if (_matchedOptions)
+ message (STATUS "Matched ${_matchedOptions}")
+ endif()
+ if (_unmatchedOptions)
+ message (STATUS "Unmatched ${_unmatchedOptions}")
+ endif()
+ endif()
+ set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE)
+ set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar)
+ string (TOUPPER "${_config}" _upperConfig)
+ # collect options from CMake language variables
+ set (_compileFlags "")
+ if (CMAKE_${_language}_FLAGS)
+ set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}")
+ endif()
+ if (CMAKE_${_language}_FLAGS_${_upperConfig})
+ set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}")
+ endif()
+ if (_target)
+ # add option from CMake target type variable
+ get_target_property(_targetType ${_target} TYPE)
+ if (POLICY CMP0018)
+ # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on
+ cmake_policy(GET CMP0018 _PIC_Policy)
+ else()
+ # default to old behavior
+ set (_PIC_Policy "OLD")
+ endif()
+ if (COTIRE_DEBUG)
+ message(STATUS "CMP0018=${_PIC_Policy}")
+ endif()
+ if (_PIC_Policy STREQUAL "NEW")
+ # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property
+ get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE)
+ if (_targetPIC)
+ if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE)
+ set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}")
+ elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC)
+ set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}")
+ endif()
+ endif()
+ else()
+ # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY_<Lang>_FLAGS
+ if (_targetType STREQUAL "MODULE_LIBRARY")
+ # flags variable for module library uses different name SHARED_MODULE
+ # (e.g., CMAKE_SHARED_MODULE_C_FLAGS)
+ set (_targetType SHARED_MODULE)
+ endif()
+ if (CMAKE_${_targetType}_${_language}_FLAGS)
+ set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}")
+ endif()
+ endif()
+ endif()
+ if (_directory)
+ # add_definitions may have been used to add flags to the compiler command
+ get_directory_property(_dirDefinitions DIRECTORY "${_directory}" DEFINITIONS)
+ if (_dirDefinitions)
+ set (_compileFlags "${_compileFlags} ${_dirDefinitions}")
+ endif()
+ endif()
+ if (_target)
+ # add target compile options
+ get_target_property(_targetflags ${_target} COMPILE_FLAGS)
+ if (_targetflags)
+ set (_compileFlags "${_compileFlags} ${_targetflags}")
+ endif()
+ endif()
+ if (UNIX)
+ separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}")
+ elseif(WIN32)
+ separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}")
+ else()
+ separate_arguments(_compileFlags)
+ endif()
+ # platform specific flags
+ if (APPLE)
+ get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig})
+ if (NOT _architectures)
+ get_target_property(_architectures ${_target} OSX_ARCHITECTURES)
+ endif()
+ foreach (_arch ${_architectures})
+ list (APPEND _compileFlags "-arch" "${_arch}")
+ endforeach()
+ if (CMAKE_OSX_SYSROOT AND CMAKE_OSX_SYSROOT_DEFAULT AND CMAKE_${_language}_HAS_ISYSROOT)
+ if (NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "${CMAKE_OSX_SYSROOT_DEFAULT}")
+ list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}")
+ endif()
+ endif()
+ if (CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG)
+ list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
+ endif()
+ endif()
+ if (COTIRE_DEBUG AND _compileFlags)
+ message (STATUS "Target ${_target} compile flags ${_compileFlags}")
+ endif()
+ set (${_flagsVar} ${_compileFlags} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar)
+ set (_includeDirs "")
+ # default include dirs
+ if (CMAKE_INCLUDE_CURRENT_DIR)
+ list (APPEND _includeDirs "${_targetBinaryDir}")
+ list (APPEND _includeDirs "${_targetSourceDir}")
+ endif()
+ # parse additional include directories from target compile flags
+ set (_targetFlags "")
+ cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
+ cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags})
+ if (_dirs)
+ list (APPEND _includeDirs ${_dirs})
+ endif()
+ # target include directories
+ get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES)
+ if (_target)
+ get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES)
+ if (_targetDirs)
+ list (APPEND _dirs ${_targetDirs})
+ list (REMOVE_DUPLICATES _dirs)
+ endif()
+ endif()
+ list (LENGTH _includeDirs _projectInsertIndex)
+ foreach (_dir ${_dirs})
+ if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE)
+ cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
+ if (_isRelative)
+ list (LENGTH _includeDirs _len)
+ if (_len EQUAL _projectInsertIndex)
+ list (APPEND _includeDirs "${_dir}")
+ else()
+ list (INSERT _includeDirs _projectInsertIndex "${_dir}")
+ endif()
+ math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1")
+ else()
+ list (APPEND _includeDirs "${_dir}")
+ endif()
+ else()
+ list (APPEND _includeDirs "${_dir}")
+ endif()
+ endforeach()
+ list (REMOVE_DUPLICATES _includeDirs)
+ if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES)
+ list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES})
+ endif()
+ if (COTIRE_DEBUG AND _includeDirs)
+ message (STATUS "Target ${_target} include dirs ${_includeDirs}")
+ endif()
+ set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE)
+endfunction()
+
+macro (cotire_make_C_identifier _identifierVar _str)
+ # mimic CMake SystemTools::MakeCindentifier behavior
+ if ("${_str}" MATCHES "^[0-9].+$")
+ set (_str "_${str}")
+ endif()
+ string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}")
+endmacro()
+
+function (cotire_get_target_export_symbol _target _exportSymbolVar)
+ set (_exportSymbol "")
+ get_target_property(_targetType ${_target} TYPE)
+ get_target_property(_enableExports ${_target} ENABLE_EXPORTS)
+ if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR
+ (_targetType STREQUAL "EXECUTABLE" AND _enableExports))
+ get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL)
+ if (NOT _exportSymbol)
+ set (_exportSymbol "${_target}_EXPORTS")
+ endif()
+ cotire_make_C_identifier(_exportSymbol "${_exportSymbol}")
+ endif()
+ set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar)
+ string (TOUPPER "${_config}" _upperConfig)
+ set (_configDefinitions "")
+ # CMAKE_INTDIR for multi-configuration build systems
+ if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
+ list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"")
+ endif()
+ # target export define symbol
+ cotire_get_target_export_symbol("${_target}" _defineSymbol)
+ if (_defineSymbol)
+ list (APPEND _configDefinitions "${_defineSymbol}")
+ endif()
+ # directory compile definitions
+ get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS)
+ if (_definitions)
+ list (APPEND _configDefinitions ${_definitions})
+ endif()
+ get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig})
+ if (_definitions)
+ list (APPEND _configDefinitions ${_definitions})
+ endif()
+ # target compile definitions
+ get_target_property(_definitions ${_target} COMPILE_DEFINITIONS)
+ if (_definitions)
+ list (APPEND _configDefinitions ${_definitions})
+ endif()
+ get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig})
+ if (_definitions)
+ list (APPEND _configDefinitions ${_definitions})
+ endif()
+ # parse additional compile definitions from target compile flags
+ # and don't look at directory compile definitions, which we already handled
+ set (_targetFlags "")
+ cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags)
+ cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags})
+ if (_definitions)
+ list (APPEND _configDefinitions ${_definitions})
+ endif()
+ list (REMOVE_DUPLICATES _configDefinitions)
+ if (COTIRE_DEBUG AND _configDefinitions)
+ message (STATUS "Target ${_target} compile definitions ${_configDefinitions}")
+ endif()
+ set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar)
+ # parse target compile flags omitting compile definitions and include directives
+ set (_targetFlags "")
+ cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags)
+ set (_compilerFlags "")
+ cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags})
+ if (COTIRE_DEBUG AND _compilerFlags)
+ message (STATUS "Target ${_target} compiler flags ${_compilerFlags}")
+ endif()
+ set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE)
+endfunction()
+
+function (cotire_add_sys_root_paths _pathsVar)
+ if (APPLE)
+ if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT)
+ foreach (_path IN LISTS ${_pathsVar})
+ if (IS_ABSOLUTE "${_path}")
+ get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE)
+ if (EXISTS "${_path}")
+ list (APPEND ${_pathsVar} "${_path}")
+ endif()
+ endif()
+ endforeach()
+ endif()
+ endif()
+ set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE)
+ if (COTIRE_DEBUG)
+ message (STATUS "${_pathsVar}=${${_pathsVar}}")
+ endif()
+endfunction()
+
+function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar)
+ set (_extraProperties ${ARGN})
+ set (_result "")
+ if (_extraProperties)
+ list (FIND _extraProperties "${_sourceFile}" _index)
+ if (_index GREATER -1)
+ math (EXPR _index "${_index} + 1")
+ list (LENGTH _extraProperties _len)
+ math (EXPR _len "${_len} - 1")
+ foreach (_index RANGE ${_index} ${_len})
+ list (GET _extraProperties ${_index} _value)
+ if ("${_value}" MATCHES "${_pattern}")
+ list (APPEND _result "${_value}")
+ else()
+ break()
+ endif()
+ endforeach()
+ endif()
+ endif()
+ set (${_resultVar} ${_result} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar)
+ set (_compileDefinitions "")
+ if (NOT CMAKE_SCRIPT_MODE_FILE)
+ string (TOUPPER "${_config}" _upperConfig)
+ get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS)
+ if (_definitions)
+ list (APPEND _compileDefinitions ${_definitions})
+ endif()
+ get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig})
+ if (_definitions)
+ list (APPEND _compileDefinitions ${_definitions})
+ endif()
+ endif()
+ cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN})
+ if (_definitions)
+ list (APPEND _compileDefinitions ${_definitions})
+ endif()
+ if (COTIRE_DEBUG AND _compileDefinitions)
+ message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}")
+ endif()
+ set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_source_files_compile_definitions _config _language _definitionsVar)
+ set (_configDefinitions "")
+ foreach (_sourceFile ${ARGN})
+ cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions)
+ if (_sourceDefinitions)
+ list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-")
+ endif()
+ endforeach()
+ set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar)
+ set (_sourceUndefs "")
+ if (NOT CMAKE_SCRIPT_MODE_FILE)
+ get_source_file_property(_undefs "${_sourceFile}" ${_property})
+ if (_undefs)
+ list (APPEND _sourceUndefs ${_undefs})
+ endif()
+ endif()
+ cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN})
+ if (_undefs)
+ list (APPEND _sourceUndefs ${_undefs})
+ endif()
+ if (COTIRE_DEBUG AND _sourceUndefs)
+ message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}")
+ endif()
+ set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_source_files_undefs _property _sourceUndefsVar)
+ set (_sourceUndefs "")
+ foreach (_sourceFile ${ARGN})
+ cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs)
+ if (_undefs)
+ list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-")
+ endif()
+ endforeach()
+ set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE)
+endfunction()
+
+macro (cotire_set_cmd_to_prologue _cmdVar)
+ set (${_cmdVar} "${CMAKE_COMMAND}")
+ if (COTIRE_DEBUG)
+ list (APPEND ${_cmdVar} "--warn-uninitialized")
+ endif()
+ list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$<CONFIGURATION>")
+ if (COTIRE_VERBOSE)
+ list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON")
+ elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles")
+ list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)")
+ endif()
+endmacro()
+
+function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1)
+ if (NOT _compilerExe)
+ set (_compilerExe "${CMAKE_${_language}_COMPILER}")
+ endif()
+ if (NOT _compilerArg1)
+ set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1})
+ endif()
+ string (STRIP "${_compilerArg1}" _compilerArg1)
+ set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE)
+endfunction()
+
+macro (cotire_add_definitions_to_cmd _cmdVar _language)
+ foreach (_definition ${ARGN})
+ if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ list (APPEND ${_cmdVar} "/D${_definition}")
+ else()
+ list (APPEND ${_cmdVar} "-D${_definition}")
+ endif()
+ endforeach()
+endmacro()
+
+macro (cotire_add_includes_to_cmd _cmdVar _language)
+ foreach (_include ${ARGN})
+ if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ file (TO_NATIVE_PATH "${_include}" _include)
+ list (APPEND ${_cmdVar} "/I${_include}")
+ else()
+ list (APPEND ${_cmdVar} "-I${_include}")
+ endif()
+ endforeach()
+endmacro()
+
+macro (cotire_add_compile_flags_to_cmd _cmdVar)
+ foreach (_flag ${ARGN})
+ list (APPEND ${_cmdVar} "${_flag}")
+ endforeach()
+endmacro()
+
+function (cotire_check_file_up_to_date _fileIsUpToDateVar _file)
+ set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE)
+ set (_triggerFile "")
+ foreach (_dependencyFile ${ARGN})
+ if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}")
+ set (_triggerFile "${_dependencyFile}")
+ break()
+ endif()
+ endforeach()
+ get_filename_component(_fileName "${_file}" NAME)
+ if (EXISTS "${_file}")
+ if (_triggerFile)
+ if (COTIRE_VERBOSE)
+ message (STATUS "${_fileName} update triggered by ${_triggerFile} change.")
+ endif()
+ else()
+ if (COTIRE_VERBOSE)
+ message (STATUS "${_fileName} is up-to-date.")
+ endif()
+ set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE)
+ endif()
+ else()
+ if (COTIRE_VERBOSE)
+ message (STATUS "${_fileName} does not exist yet.")
+ endif()
+ endif()
+endfunction()
+
+macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar)
+ set (${_relPathVar} "")
+ foreach (_includeDir ${_includeDirs})
+ if (IS_DIRECTORY "${_includeDir}")
+ file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}")
+ if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")
+ string (LENGTH "${${_relPathVar}}" _closestLen)
+ string (LENGTH "${_relPath}" _relLen)
+ if (_closestLen EQUAL 0 OR _relLen LESS _closestLen)
+ set (${_relPathVar} "${_relPath}")
+ endif()
+ endif()
+ elseif ("${_includeDir}" STREQUAL "${_headerFile}")
+ # if path matches exactly, return short non-empty string
+ set (${_relPathVar} "1")
+ break()
+ endif()
+ endforeach()
+endmacro()
+
+macro (cotire_check_header_file_location _headerFile _insideIncudeDirs _outsideIncudeDirs _headerIsInside)
+ # check header path against ignored and honored include directories
+ cotire_find_closest_relative_path("${_headerFile}" "${_insideIncudeDirs}" _insideRelPath)
+ if (_insideRelPath)
+ # header is inside, but could be become outside if there is a shorter outside match
+ cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncudeDirs}" _outsideRelPath)
+ if (_outsideRelPath)
+ string (LENGTH "${_insideRelPath}" _insideRelPathLen)
+ string (LENGTH "${_outsideRelPath}" _outsideRelPathLen)
+ if (_outsideRelPathLen LESS _insideRelPathLen)
+ set (${_headerIsInside} FALSE)
+ else()
+ set (${_headerIsInside} TRUE)
+ endif()
+ else()
+ set (${_headerIsInside} TRUE)
+ endif()
+ else()
+ # header is outside
+ set (${_headerIsInside} FALSE)
+ endif()
+endmacro()
+
+macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar)
+ if (NOT EXISTS "${_headerFile}")
+ set (${_headerIsIgnoredVar} TRUE)
+ elseif (IS_DIRECTORY "${_headerFile}")
+ set (${_headerIsIgnoredVar} TRUE)
+ elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$")
+ # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path
+ # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation
+ # with the error message "error: no include path in which to search for header.h"
+ set (${_headerIsIgnoredVar} TRUE)
+ else()
+ set (${_headerIsIgnoredVar} FALSE)
+ endif()
+endmacro()
+
+macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar)
+ # check header file extension
+ cotire_get_source_file_extension("${_headerFile}" _headerFileExt)
+ set (${_headerIsIgnoredVar} FALSE)
+ if (_headerFileExt)
+ list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index)
+ if (_index GREATER -1)
+ set (${_headerIsIgnoredVar} TRUE)
+ endif()
+ endif()
+endmacro()
+
+macro (cotire_parse_line _line _headerFileVar _headerDepthVar)
+ if (MSVC)
+ # cl.exe /showIncludes output looks different depending on the language pack used, e.g.:
+ # English: "Note: including file: C:\directory\file"
+ # German: "Hinweis: Einlesen der Datei: C:\directory\file"
+ # We use a very general regular expression, relying on the presence of the : characters
+ if ("${_line}" MATCHES ":( +)([^:]+:[^:]+)$")
+ # Visual Studio compiler output
+ string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
+ get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE)
+ else()
+ set (${_headerFileVar} "")
+ set (${_headerDepthVar} 0)
+ endif()
+ else()
+ if ("${_line}" MATCHES "^(\\.+) (.*)$")
+ # GCC like output
+ string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar})
+ if (IS_ABSOLUTE "${CMAKE_MATCH_2}")
+ set (${_headerFileVar} "${CMAKE_MATCH_2}")
+ else()
+ get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH)
+ endif()
+ else()
+ set (${_headerFileVar} "")
+ set (${_headerDepthVar} 0)
+ endif()
+ endif()
+endmacro()
+
+function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honoredIncudeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar)
+ if (WIN32)
+ # prevent CMake macro invocation errors due to backslash characters in Windows paths
+ string (REPLACE "\\" "/" _scanOutput "${_scanOutput}")
+ endif()
+ # canonize slashes
+ string (REPLACE "//" "/" _scanOutput "${_scanOutput}")
+ # prevent semicolon from being interpreted as a line separator
+ string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}")
+ # then separate lines
+ string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}")
+ list (LENGTH _scanOutput _len)
+ # remove duplicate lines to speed up parsing
+ list (REMOVE_DUPLICATES _scanOutput)
+ list (LENGTH _scanOutput _uniqueLen)
+ if (COTIRE_VERBOSE)
+ message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes")
+ if (_ignoredExtensions)
+ message (STATUS "Ignored extensions: ${_ignoredExtensions}")
+ endif()
+ if (_ignoredIncudeDirs)
+ message (STATUS "Ignored paths: ${_ignoredIncudeDirs}")
+ endif()
+ if (_honoredIncudeDirs)
+ message (STATUS "Included paths: ${_honoredIncudeDirs}")
+ endif()
+ endif()
+ set (_sourceFiles ${ARGN})
+ set (_selectedIncludes "")
+ set (_unparsedLines "")
+ # stack keeps track of inside/outside project status of processed header files
+ set (_headerIsInsideStack "")
+ foreach (_line IN LISTS _scanOutput)
+ if (_line)
+ cotire_parse_line("${_line}" _headerFile _headerDepth)
+ if (_headerFile)
+ cotire_check_header_file_location("${_headerFile}" "${_ignoredIncudeDirs}" "${_honoredIncudeDirs}" _headerIsInside)
+ if (COTIRE_DEBUG)
+ message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}")
+ endif()
+ # update stack
+ list (LENGTH _headerIsInsideStack _stackLen)
+ if (_headerDepth GREATER _stackLen)
+ math (EXPR _stackLen "${_stackLen} + 1")
+ foreach (_index RANGE ${_stackLen} ${_headerDepth})
+ list (APPEND _headerIsInsideStack ${_headerIsInside})
+ endforeach()
+ else()
+ foreach (_index RANGE ${_headerDepth} ${_stackLen})
+ list (REMOVE_AT _headerIsInsideStack -1)
+ endforeach()
+ list (APPEND _headerIsInsideStack ${_headerIsInside})
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_headerIsInsideStack}")
+ endif()
+ # header is a candidate if it is outside project
+ if (NOT _headerIsInside)
+ # get parent header file's inside/outside status
+ if (_headerDepth GREATER 1)
+ math (EXPR _index "${_headerDepth} - 2")
+ list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside)
+ else()
+ set (_parentHeaderIsInside TRUE)
+ endif()
+ # select header file if parent header file is inside project
+ # (e.g., a project header file that includes a standard header file)
+ if (_parentHeaderIsInside)
+ cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored)
+ if (NOT _headerIsIgnored)
+ cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored)
+ if (NOT _headerIsIgnored)
+ list (APPEND _selectedIncludes "${_headerFile}")
+ else()
+ # fix header's inside status on stack, it is ignored by extension now
+ list (REMOVE_AT _headerIsInsideStack -1)
+ list (APPEND _headerIsInsideStack TRUE)
+ endif()
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}")
+ endif()
+ endif()
+ endif()
+ else()
+ if (MSVC)
+ # for cl.exe do not keep unparsed lines which solely consist of a source file name
+ string (FIND "${_sourceFiles}" "${_line}" _index)
+ if (_index LESS 0)
+ list (APPEND _unparsedLines "${_line}")
+ endif()
+ else()
+ list (APPEND _unparsedLines "${_line}")
+ endif()
+ endif()
+ endif()
+ endforeach()
+ list (REMOVE_DUPLICATES _selectedIncludes)
+ set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE)
+ set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE)
+endfunction()
+
+function (cotire_scan_includes _includesVar)
+ set(_options "")
+ set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION LANGUAGE UNPARSED_LINES)
+ set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
+ if (NOT _option_LANGUAGE)
+ set (_option_LANGUAGE "CXX")
+ endif()
+ if (NOT _option_COMPILER_ID)
+ set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
+ endif()
+ set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1})
+ cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
+ cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
+ cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
+ cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
+ cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd)
+ # only consider existing source files for scanning
+ set (_existingSourceFiles "")
+ foreach (_sourceFile ${_sourceFiles})
+ if (EXISTS "${_sourceFile}")
+ list (APPEND _existingSourceFiles "${_sourceFile}")
+ endif()
+ endforeach()
+ if (NOT _existingSourceFiles)
+ set (${_includesVar} "" PARENT_SCOPE)
+ return()
+ endif()
+ list (APPEND _cmd ${_existingSourceFiles})
+ if (COTIRE_VERBOSE)
+ message (STATUS "execute_process: ${_cmd}")
+ endif()
+ if (_option_COMPILER_ID MATCHES "MSVC")
+ if (COTIRE_DEBUG)
+ message (STATUS "clearing VS_UNICODE_OUTPUT")
+ endif()
+ # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
+ unset (ENV{VS_UNICODE_OUTPUT})
+ endif()
+ execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output)
+ if (_result)
+ message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.")
+ endif()
+ cotire_parse_includes(
+ "${_option_LANGUAGE}" "${_output}"
+ "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}"
+ "${_option_IGNORE_EXTENSIONS}"
+ _includes _unparsedLines
+ ${_sourceFiles})
+ set (${_includesVar} ${_includes} PARENT_SCOPE)
+ if (_option_UNPARSED_LINES)
+ set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE)
+ endif()
+endfunction()
+
+macro (cotire_append_undefs _contentsVar)
+ set (_undefs ${ARGN})
+ if (_undefs)
+ list (REMOVE_DUPLICATES _undefs)
+ foreach (_definition ${_undefs})
+ list (APPEND ${_contentsVar} "#undef ${_definition}")
+ endforeach()
+ endif()
+endmacro()
+
+macro (cotire_comment_str _language _commentText _commentVar)
+ if ("${_language}" STREQUAL "CMAKE")
+ set (${_commentVar} "# ${_commentText}")
+ else()
+ set (${_commentVar} "/* ${_commentText} */")
+ endif()
+endmacro()
+
+function (cotire_write_file _language _file _contents _force)
+ get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
+ cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1)
+ cotire_comment_str("${_language}" "${_file}" _header2)
+ set (_contents "${_header1}\n${_header2}\n${_contents}")
+ if (COTIRE_DEBUG)
+ message (STATUS "${_contents}")
+ endif()
+ if (_force OR NOT EXISTS "${_file}")
+ file (WRITE "${_file}" "${_contents}")
+ else()
+ file (READ "${_file}" _oldContents)
+ if (NOT "${_oldContents}" STREQUAL "${_contents}")
+ file (WRITE "${_file}" "${_contents}")
+ else()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_file} unchanged")
+ endif()
+ endif()
+ endif()
+endfunction()
+
+function (cotire_generate_unity_source _unityFile)
+ set(_options "")
+ set(_oneValueArgs LANGUAGE)
+ set(_multiValueArgs
+ DEPENDS SOURCES_COMPILE_DEFINITIONS
+ PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ if (_option_DEPENDS)
+ cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS})
+ if (_unityFileIsUpToDate)
+ return()
+ endif()
+ endif()
+ set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
+ if (NOT _option_PRE_UNDEFS)
+ set (_option_PRE_UNDEFS "")
+ endif()
+ if (NOT _option_SOURCES_PRE_UNDEFS)
+ set (_option_SOURCES_PRE_UNDEFS "")
+ endif()
+ if (NOT _option_POST_UNDEFS)
+ set (_option_POST_UNDEFS "")
+ endif()
+ if (NOT _option_SOURCES_POST_UNDEFS)
+ set (_option_SOURCES_POST_UNDEFS "")
+ endif()
+ set (_contents "")
+ if (_option_PROLOGUE)
+ list (APPEND _contents ${_option_PROLOGUE})
+ endif()
+ if (_option_LANGUAGE AND _sourceFiles)
+ if ("${_option_LANGUAGE}" STREQUAL "CXX")
+ list (APPEND _contents "#ifdef __cplusplus")
+ elseif ("${_option_LANGUAGE}" STREQUAL "C")
+ list (APPEND _contents "#ifndef __cplusplus")
+ endif()
+ endif()
+ set (_compileUndefinitions "")
+ foreach (_sourceFile ${_sourceFiles})
+ cotire_get_source_compile_definitions(
+ "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions
+ ${_option_SOURCES_COMPILE_DEFINITIONS})
+ cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS})
+ cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS})
+ if (_option_PRE_UNDEFS)
+ list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS})
+ endif()
+ if (_sourcePreUndefs)
+ list (APPEND _compileUndefinitions ${_sourcePreUndefs})
+ endif()
+ if (_compileUndefinitions)
+ cotire_append_undefs(_contents ${_compileUndefinitions})
+ set (_compileUndefinitions "")
+ endif()
+ if (_sourcePostUndefs)
+ list (APPEND _compileUndefinitions ${_sourcePostUndefs})
+ endif()
+ if (_option_POST_UNDEFS)
+ list (APPEND _compileUndefinitions ${_option_POST_UNDEFS})
+ endif()
+ foreach (_definition ${_compileDefinitions})
+ if ("${_definition}" MATCHES "^([a-zA-Z0-9_]+)=(.+)$")
+ list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}")
+ list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}")
+ else()
+ list (APPEND _contents "#define ${_definition}")
+ list (INSERT _compileUndefinitions 0 "${_definition}")
+ endif()
+ endforeach()
+ get_filename_component(_sourceFile "${_sourceFile}" ABSOLUTE)
+ if (WIN32)
+ file (TO_NATIVE_PATH "${_sourceFile}" _sourceFile)
+ endif()
+ list (APPEND _contents "#include \"${_sourceFile}\"")
+ endforeach()
+ if (_compileUndefinitions)
+ cotire_append_undefs(_contents ${_compileUndefinitions})
+ set (_compileUndefinitions "")
+ endif()
+ if (_option_LANGUAGE AND _sourceFiles)
+ list (APPEND _contents "#endif")
+ endif()
+ if (_option_EPILOGUE)
+ list (APPEND _contents ${_option_EPILOGUE})
+ endif()
+ list (APPEND _contents "")
+ string (REPLACE ";" "\n" _contents "${_contents}")
+ if (COTIRE_VERBOSE)
+ message ("${_contents}")
+ endif()
+ cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE)
+endfunction()
+
+function (cotire_generate_prefix_header _prefixFile)
+ set(_options "")
+ set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION)
+ set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS
+ INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ if (_option_DEPENDS)
+ cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS})
+ if (_prefixFileIsUpToDate)
+ return()
+ endif()
+ endif()
+ set (_epilogue "")
+ if (_option_COMPILER_ID MATCHES "Intel")
+ # Intel compiler requires hdrstop pragma to stop generating PCH file
+ set (_epilogue "#pragma hdrstop")
+ endif()
+ set (_sourceFiles ${_option_UNPARSED_ARGUMENTS})
+ cotire_scan_includes(_selectedHeaders ${_sourceFiles}
+ LANGUAGE "${_option_LANGUAGE}"
+ COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}"
+ COMPILER_ID "${_option_COMPILER_ID}"
+ COMPILER_VERSION "${_option_COMPILER_VERSION}"
+ COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS}
+ COMPILE_FLAGS ${_option_COMPILE_FLAGS}
+ INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES}
+ IGNORE_PATH ${_option_IGNORE_PATH}
+ INCLUDE_PATH ${_option_INCLUDE_PATH}
+ IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS}
+ UNPARSED_LINES _unparsedLines)
+ cotire_generate_unity_source("${_prefixFile}" EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders})
+ set (_unparsedLinesFile "${_prefixFile}.log")
+ if (_unparsedLines)
+ if (COTIRE_VERBOSE OR NOT _selectedHeaders)
+ list (LENGTH _unparsedLines _skippedLineCount)
+ file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}")
+ message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}")
+ endif()
+ string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}")
+ endif()
+ file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n")
+endfunction()
+
+function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar)
+ set (_flags ${${_flagsVar}})
+ if (_compilerID MATCHES "MSVC")
+ # cl.exe options used
+ # /nologo suppresses display of sign-on banner
+ # /TC treat all files named on the command line as C source files
+ # /TP treat all files named on the command line as C++ source files
+ # /EP preprocess to stdout without #line directives
+ # /showIncludes list include files
+ set (_sourceFileTypeC "/TC")
+ set (_sourceFileTypeCXX "/TP")
+ if (_flags)
+ # append to list
+ list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes)
+ else()
+ # return as a flag string
+ set (_flags "${_sourceFileType${_language}} /EP /showIncludes")
+ endif()
+ elseif (_compilerID MATCHES "GNU")
+ # GCC options used
+ # -H print the name of each header file used
+ # -E invoke preprocessor
+ # -fdirectives-only do not expand macros, requires GCC >= 4.3
+ if (_flags)
+ # append to list
+ list (APPEND _flags -H -E)
+ if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
+ list (APPEND _flags "-fdirectives-only")
+ endif()
+ else()
+ # return as a flag string
+ set (_flags "-H -E")
+ if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0")
+ set (_flags "${_flags} -fdirectives-only")
+ endif()
+ endif()
+ elseif (_compilerID MATCHES "Clang")
+ # Clang options used
+ # -H print the name of each header file used
+ # -E invoke preprocessor
+ if (_flags)
+ # append to list
+ list (APPEND _flags -H -E)
+ else()
+ # return as a flag string
+ set (_flags "-H -E")
+ endif()
+ elseif (_compilerID MATCHES "Intel")
+ if (WIN32)
+ # Windows Intel options used
+ # /nologo do not display compiler version information
+ # /QH display the include file order
+ # /EP preprocess to stdout, omitting #line directives
+ # /TC process all source or unrecognized file types as C source files
+ # /TP process all source or unrecognized file types as C++ source files
+ set (_sourceFileTypeC "/TC")
+ set (_sourceFileTypeCXX "/TP")
+ if (_flags)
+ # append to list
+ list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH)
+ else()
+ # return as a flag string
+ set (_flags "${_sourceFileType${_language}} /EP /QH")
+ endif()
+ else()
+ # Linux / Mac OS X Intel options used
+ # -H print the name of each header file used
+ # -EP preprocess to stdout, omitting #line directives
+ # -Kc++ process all source or unrecognized file types as C++ source files
+ if (_flags)
+ # append to list
+ if ("${_language}" STREQUAL "CXX")
+ list (APPEND _flags -Kc++)
+ endif()
+ list (APPEND _flags -H -EP)
+ else()
+ # return as a flag string
+ if ("${_language}" STREQUAL "CXX")
+ set (_flags "-Kc++ ")
+ endif()
+ set (_flags "${_flags}-H -EP")
+ endif()
+ endif()
+ else()
+ message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
+ endif()
+ set (${_flagsVar} ${_flags} PARENT_SCOPE)
+endfunction()
+
+function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar)
+ set (_flags ${${_flagsVar}})
+ if (_compilerID MATCHES "MSVC")
+ file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
+ file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
+ file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
+ # cl.exe options used
+ # /Yc creates a precompiled header file
+ # /Fp specifies precompiled header binary file name
+ # /FI forces inclusion of file
+ # /TC treat all files named on the command line as C source files
+ # /TP treat all files named on the command line as C++ source files
+ # /Zs syntax check only
+ set (_sourceFileTypeC "/TC")
+ set (_sourceFileTypeCXX "/TP")
+ if (_flags)
+ # append to list
+ list (APPEND _flags /nologo "${_sourceFileType${_language}}"
+ "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
+ else()
+ # return as a flag string
+ set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
+ endif()
+ elseif (_compilerID MATCHES "GNU|Clang")
+ # GCC / Clang options used
+ # -x specify the source language
+ # -c compile but do not link
+ # -o place output in file
+ set (_xLanguage_C "c-header")
+ set (_xLanguage_CXX "c++-header")
+ if (_flags)
+ # append to list
+ list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}")
+ else()
+ # return as a flag string
+ set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"")
+ endif()
+ elseif (_compilerID MATCHES "Intel")
+ if (WIN32)
+ file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
+ file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
+ file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative)
+ # Windows Intel options used
+ # /nologo do not display compiler version information
+ # /Yc create a precompiled header (PCH) file
+ # /Fp specify a path or file name for precompiled header files
+ # /FI tells the preprocessor to include a specified file name as the header file
+ # /TC process all source or unrecognized file types as C source files
+ # /TP process all source or unrecognized file types as C++ source files
+ # /Zs syntax check only
+ # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
+ set (_sourceFileTypeC "/TC")
+ set (_sourceFileTypeCXX "/TP")
+ if (_flags)
+ # append to list
+ list (APPEND _flags /nologo "${_sourceFileType${_language}}"
+ "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ list (APPEND _flags "/Wpch-messages")
+ endif()
+ else()
+ # return as a flag string
+ set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ set (_flags "${_flags} /Wpch-messages")
+ endif()
+ endif()
+ else()
+ # Linux / Mac OS X Intel options used
+ # -pch-dir location for precompiled header files
+ # -pch-create name of the precompiled header (PCH) to create
+ # -Kc++ process all source or unrecognized file types as C++ source files
+ # -fsyntax-only check only for correct syntax
+ # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
+ get_filename_component(_pchDir "${_pchFile}" PATH)
+ get_filename_component(_pchName "${_pchFile}" NAME)
+ set (_xLanguage_C "c-header")
+ set (_xLanguage_CXX "c++-header")
+ if (_flags)
+ # append to list
+ if ("${_language}" STREQUAL "CXX")
+ list (APPEND _flags -Kc++)
+ endif()
+ list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ list (APPEND _flags "-Wpch-messages")
+ endif()
+ else()
+ # return as a flag string
+ set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ set (_flags "${_flags} -Wpch-messages")
+ endif()
+ endif()
+ endif()
+ else()
+ message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
+ endif()
+ set (${_flagsVar} ${_flags} PARENT_SCOPE)
+endfunction()
+
+function (cotire_add_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar)
+ set (_flags ${${_flagsVar}})
+ if (_compilerID MATCHES "MSVC")
+ file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
+ file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
+ # cl.exe options used
+ # /Yu uses a precompiled header file during build
+ # /Fp specifies precompiled header binary file name
+ # /FI forces inclusion of file
+ if (_flags)
+ # append to list
+ list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
+ else()
+ # return as a flag string
+ set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
+ endif()
+ elseif (_compilerID MATCHES "GNU")
+ # GCC options used
+ # -include process include file as the first line of the primary source file
+ # -Winvalid-pch warns if precompiled header is found but cannot be used
+ if (_flags)
+ # append to list
+ list (APPEND _flags "-include" "${_prefixFile}" "-Winvalid-pch")
+ else()
+ # return as a flag string
+ set (_flags "-include \"${_prefixFile}\" -Winvalid-pch")
+ endif()
+ elseif (_compilerID MATCHES "Clang")
+ # Clang options used
+ # -include process include file as the first line of the primary source file
+ # -Qunused-arguments don't emit warning for unused driver arguments
+ if (_flags)
+ # append to list
+ list (APPEND _flags "-include" "${_prefixFile}" "-Qunused-arguments")
+ else()
+ # return as a flag string
+ set (_flags "-include \"${_prefixFile}\" -Qunused-arguments")
+ endif()
+ elseif (_compilerID MATCHES "Intel")
+ if (WIN32)
+ file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
+ file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
+ # Windows Intel options used
+ # /Yu use a precompiled header (PCH) file
+ # /Fp specify a path or file name for precompiled header files
+ # /FI tells the preprocessor to include a specified file name as the header file
+ # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
+ if (_flags)
+ # append to list
+ list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ list (APPEND _flags "/Wpch-messages")
+ endif()
+ else()
+ # return as a flag string
+ set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ set (_flags "${_flags} /Wpch-messages")
+ endif()
+ endif()
+ else()
+ # Linux / Mac OS X Intel options used
+ # -pch-dir location for precompiled header files
+ # -pch-use name of the precompiled header (PCH) to use
+ # -include process include file as the first line of the primary source file
+ # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2)
+ get_filename_component(_pchDir "${_pchFile}" PATH)
+ get_filename_component(_pchName "${_pchFile}" NAME)
+ if (_flags)
+ # append to list
+ list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ list (APPEND _flags "-Wpch-messages")
+ endif()
+ else()
+ # return as a flag string
+ set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"")
+ if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0")
+ set (_flags "${_flags} -Wpch-messages")
+ endif()
+ endif()
+ endif()
+ else()
+ message (FATAL_ERROR "Unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.")
+ endif()
+ set (${_flagsVar} ${_flags} PARENT_SCOPE)
+endfunction()
+
+function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile)
+ set(_options "")
+ set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION LANGUAGE)
+ set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ if (NOT _option_LANGUAGE)
+ set (_option_LANGUAGE "CXX")
+ endif()
+ if (NOT _option_COMPILER_ID)
+ set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}")
+ endif()
+ cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}")
+ cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS})
+ cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS})
+ cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES})
+ cotire_add_pch_compilation_flags(
+ "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}"
+ "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd)
+ if (COTIRE_VERBOSE)
+ message (STATUS "execute_process: ${_cmd}")
+ endif()
+ if (_option_COMPILER_ID MATCHES "MSVC")
+ if (COTIRE_DEBUG)
+ message (STATUS "clearing VS_UNICODE_OUTPUT")
+ endif()
+ # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared
+ unset (ENV{VS_UNICODE_OUTPUT})
+ endif()
+ execute_process(COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE _result)
+ if (_result)
+ message (FATAL_ERROR "Error ${_result} precompiling ${_prefixFile}.")
+ endif()
+endfunction()
+
+function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar)
+ set (_unsupportedCompiler
+ "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}")
+ if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
+ # supported since Visual Studio C++ 6.0
+ # and CMake does not support an earlier version
+ set (${_msgVar} "" PARENT_SCOPE)
+ elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU")
+ # GCC PCH support requires version >= 3.4
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
+ "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0")
+ set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
+ else()
+ set (${_msgVar} "" PARENT_SCOPE)
+ endif()
+ elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang")
+ # all Clang versions have PCH support
+ set (${_msgVar} "" PARENT_SCOPE)
+ elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
+ # Intel PCH support requires version >= 8.0.0
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND
+ "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0")
+ set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE)
+ else()
+ set (${_msgVar} "" PARENT_SCOPE)
+ endif()
+ else()
+ set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE)
+ endif()
+ if (APPLE)
+ # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64)
+ if (CMAKE_CONFIGURATION_TYPES)
+ set (_configs ${CMAKE_CONFIGURATION_TYPES})
+ elseif (CMAKE_BUILD_TYPE)
+ set (_configs ${CMAKE_BUILD_TYPE})
+ else()
+ set (_configs "None")
+ endif()
+ foreach (_config ${_configs})
+ set (_targetFlags "")
+ cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags)
+ cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags})
+ list (LENGTH _architectures _numberOfArchitectures)
+ if (_numberOfArchitectures GREATER 1)
+ string (REPLACE ";" ", " _architectureStr "${_architectures}")
+ set (${_msgVar}
+ "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})."
+ PARENT_SCOPE)
+ break()
+ endif()
+ endforeach()
+ endif()
+endfunction()
+
+macro (cotire_get_intermediate_dir _cotireDir)
+ get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE)
+endmacro()
+
+macro (cotire_setup_file_extension_variables)
+ set (_unityFileExt_C ".c")
+ set (_unityFileExt_CXX ".cxx")
+ set (_prefixFileExt_C ".h")
+ set (_prefixFileExt_CXX ".hxx")
+endmacro()
+
+function (cotire_make_single_unity_source_file_path _language _target _unityFileVar)
+ cotire_setup_file_extension_variables()
+ if (NOT DEFINED _unityFileExt_${_language})
+ set (${_unityFileVar} "" PARENT_SCOPE)
+ return()
+ endif()
+ set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
+ set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}")
+ cotire_get_intermediate_dir(_baseDir)
+ set (_unityFile "${_baseDir}/${_unityFileName}")
+ set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE)
+ if (COTIRE_DEBUG)
+ message(STATUS "${_unityFile}")
+ endif()
+endfunction()
+
+function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar)
+ cotire_setup_file_extension_variables()
+ if (NOT DEFINED _unityFileExt_${_language})
+ set (${_unityFileVar} "" PARENT_SCOPE)
+ return()
+ endif()
+ set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
+ cotire_get_intermediate_dir(_baseDir)
+ set (_startIndex 0)
+ set (_index 0)
+ set (_unityFiles "")
+ set (_sourceFiles ${ARGN})
+ foreach (_sourceFile ${_sourceFiles})
+ get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE)
+ math (EXPR _unityFileCount "${_index} - ${_startIndex}")
+ if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes))
+ if (_index GREATER 0)
+ # start new unity file segment
+ math (EXPR _endIndex "${_index} - 1")
+ set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
+ list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
+ endif()
+ set (_startIndex ${_index})
+ endif()
+ math (EXPR _index "${_index} + 1")
+ endforeach()
+ list (LENGTH _sourceFiles _numberOfSources)
+ if (_startIndex EQUAL 0)
+ # there is only a single unity file
+ cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles)
+ elseif (_startIndex LESS _numberOfSources)
+ # end with final unity file segment
+ math (EXPR _endIndex "${_index} - 1")
+ set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}")
+ list (APPEND _unityFiles "${_baseDir}/${_unityFileName}")
+ endif()
+ set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE)
+ if (COTIRE_DEBUG)
+ message(STATUS "${_unityFiles}")
+ endif()
+endfunction()
+
+function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar)
+ cotire_setup_file_extension_variables()
+ if (NOT DEFINED _unityFileExt_${_language})
+ set (${_prefixFileVar} "" PARENT_SCOPE)
+ return()
+ endif()
+ set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}")
+ set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
+ string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}")
+ string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}")
+ set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE)
+endfunction()
+
+function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar)
+ cotire_setup_file_extension_variables()
+ if (NOT _language)
+ set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
+ set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}")
+ elseif (DEFINED _prefixFileExt_${_language})
+ set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}")
+ set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}")
+ else()
+ set (_prefixFileBaseName "")
+ set (_prefixFileName "")
+ endif()
+ set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE)
+ set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE)
+endfunction()
+
+function (cotire_make_prefix_file_path _language _target _prefixFileVar)
+ cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
+ set (${_prefixFileVar} "" PARENT_SCOPE)
+ if (_prefixFileName)
+ if (NOT _language)
+ set (_language "C")
+ endif()
+ if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel")
+ cotire_get_intermediate_dir(_baseDir)
+ set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar)
+ cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName)
+ set (${_pchFileVar} "" PARENT_SCOPE)
+ if (_prefixFileBaseName AND _prefixFileName)
+ cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg)
+ if (NOT _msg)
+ if (XCODE)
+ # For Xcode, we completely hand off the compilation of the prefix header to the IDE
+ return()
+ endif()
+ cotire_get_intermediate_dir(_baseDir)
+ if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC")
+ # MSVC uses the extension .pch added to the prefix header base name
+ set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE)
+ elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang")
+ # GCC / Clang look for a precompiled header corresponding to the prefix header with the extension .gch appended
+ set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE)
+ elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel")
+ # Intel uses the extension .pchi added to the prefix header base name
+ set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+function (cotire_select_unity_source_files _unityFile _sourcesVar)
+ set (_sourceFiles ${ARGN})
+ if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)")
+ set (_startIndex ${CMAKE_MATCH_1})
+ set (_endIndex ${CMAKE_MATCH_2})
+ list (LENGTH _sourceFiles _numberOfSources)
+ if (NOT _startIndex LESS _numberOfSources)
+ math (EXPR _startIndex "${_numberOfSources} - 1")
+ endif()
+ if (NOT _endIndex LESS _numberOfSources)
+ math (EXPR _endIndex "${_numberOfSources} - 1")
+ endif()
+ set (_files "")
+ foreach (_index RANGE ${_startIndex} ${_endIndex})
+ list (GET _sourceFiles ${_index} _file)
+ list (APPEND _files "${_file}")
+ endforeach()
+ else()
+ set (_files ${_sourceFiles})
+ endif()
+ set (${_sourcesVar} ${_files} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar)
+ set (_dependencySources "")
+ # depend on target's generated source files
+ cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN})
+ if (_generatedSources)
+ # but omit all generated source files that have the COTIRE_EXCLUDED property set to true
+ cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources})
+ if (_excludedGeneratedSources)
+ list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources})
+ endif()
+ # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly
+ cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources})
+ if (_excludedNonDependencySources)
+ list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources})
+ endif()
+ if (_generatedSources)
+ list (APPEND _dependencySources ${_generatedSources})
+ endif()
+ endif()
+ if (COTIRE_DEBUG AND _dependencySources)
+ message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}")
+ endif()
+ set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
+endfunction()
+
+function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar)
+ # depend on target source files marked with custom COTIRE_DEPENDENCY property
+ set (_dependencySources "")
+ cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN})
+ if (COTIRE_DEBUG AND _dependencySources)
+ message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}")
+ endif()
+ set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE)
+endfunction()
+
+function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar)
+ set (COTIRE_TARGET_SOURCES ${ARGN})
+ get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME)
+ set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}")
+ cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES})
+ cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES})
+ # set up variables to be configured
+ set (COTIRE_TARGET_LANGUAGE "${_language}")
+ cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER)
+ get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH)
+ cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH)
+ get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH)
+ cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH)
+ get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS)
+ get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS)
+ get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
+ cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES})
+ cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES})
+ set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}")
+ foreach (_config ${_configurations})
+ string (TOUPPER "${_config}" _upperConfig)
+ cotire_get_target_include_directories(
+ "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig})
+ cotire_get_target_compile_definitions(
+ "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig})
+ cotire_get_target_compiler_flags(
+ "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig})
+ cotire_get_source_files_compile_definitions(
+ "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES})
+ endforeach()
+ get_cmake_property(_vars VARIABLES)
+ string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}")
+ # remove COTIRE_VERBOSE which is passed as a CMake define on command line
+ list (REMOVE_ITEM _matchVars COTIRE_VERBOSE)
+ set (_contents "")
+ foreach (_var IN LISTS _matchVars ITEMS
+ MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES
+ CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1
+ CMAKE_${_language}_SOURCE_FILE_EXTENSIONS)
+ if (DEFINED ${_var})
+ string (REPLACE "\"" "\\\"" _value "${${_var}}")
+ set (_contents "${_contents}set (${_var} \"${_value}\")\n")
+ endif()
+ endforeach()
+ cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE)
+ set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_pch_file_compilation _language _targetBinaryDir _targetScript _prefixFile _pchFile)
+ set (_sourceFiles ${ARGN})
+ if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file
+ # the remaining files include the precompiled header, see cotire_setup_prefix_file_inclusion
+ if (_sourceFiles)
+ file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative)
+ file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative)
+ list (GET _sourceFiles 0 _hostFile)
+ set (_flags "")
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ cotire_add_pch_compilation_flags(
+ "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
+ "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags)
+ set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
+ set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}")
+ # make first source file depend on prefix header
+ set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}")
+ endif()
+ elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
+ # for makefile based generator, we add a custom command to precompile the prefix header
+ if (_targetScript)
+ cotire_set_cmd_to_prologue(_cmds)
+ list (GET _sourceFiles 0 _hostFile)
+ list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}")
+ file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}")
+ if (COTIRE_DEBUG)
+ message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}")
+ endif()
+ set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE)
+ add_custom_command(OUTPUT "${_pchFile}"
+ COMMAND ${_cmds}
+ DEPENDS "${_prefixFile}"
+ IMPLICIT_DEPENDS ${_language} "${_prefixFile}"
+ WORKING_DIRECTORY "${_targetSourceDir}"
+ COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM)
+ endif()
+ endif()
+endfunction()
+
+function (cotire_setup_prefix_file_inclusion _language _target _wholeTarget _prefixFile _pchFile)
+ set (_sourceFiles ${ARGN})
+ if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ # for Visual Studio and Intel, we include the precompiled header in all but the first source file
+ # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation
+ list (LENGTH _sourceFiles _numberOfSourceFiles)
+ if (_numberOfSourceFiles GREATER 1)
+ # mark sources as cotired to prevent them from being used in another cotired target
+ set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
+ list (REMOVE_AT _sourceFiles 0)
+ set (_flags "")
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ cotire_add_pch_inclusion_flags(
+ "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
+ "${_prefixFile}" "${_pchFile}" _flags)
+ set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
+ # make source files depend on precompiled header
+ set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
+ endif()
+ elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
+ if (NOT _wholeTarget)
+ # for makefile based generator, we force the inclusion of the prefix header for a subset
+ # of the source files, if this is a multi-language target or has excluded files
+ set (_flags "")
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ cotire_add_pch_inclusion_flags(
+ "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
+ "${_prefixFile}" "${_pchFile}" _flags)
+ set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
+ # mark sources as cotired to prevent them from being used in another cotired target
+ set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}")
+ endif()
+ # make source files depend on precompiled header
+ set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}")
+ endif()
+endfunction()
+
+function (cotire_get_first_set_property_value _propertyValueVar _type _object)
+ set (_properties ${ARGN})
+ foreach (_property ${_properties})
+ get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property})
+ if (_propertyValue)
+ set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE)
+ return()
+ endif()
+ endforeach()
+ set (${_propertyValueVar} "" PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar)
+ set (_files ${ARGN})
+ set (_filesPaths "")
+ foreach (_file ${_files})
+ if (IS_ABSOLUTE "${_file}")
+ set (_filePath "${_file}")
+ else()
+ get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE)
+ endif()
+ file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}")
+ if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.")
+ list (APPEND _filesPaths "${_fileRelPath}")
+ else()
+ list (APPEND _filesPaths "${_filePath}")
+ endif()
+ endforeach()
+ cotire_set_cmd_to_prologue(_prefixCmd)
+ list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine")
+ if (_targetScript)
+ list (APPEND _prefixCmd "${_targetScript}")
+ endif()
+ list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths})
+ if (COTIRE_DEBUG)
+ message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}")
+ endif()
+ set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE)
+ file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}")
+ get_filename_component(_joinedFileName "${_joinedFileRelPath}" NAME_WE)
+ if (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
+ set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}")
+ elseif (_language AND _joinedFileName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$")
+ set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}")
+ else()
+ set (_comment "Generating ${_joinedFileRelPath}")
+ endif()
+ add_custom_command(
+ OUTPUT "${_joinedFile}"
+ COMMAND ${_prefixCmd}
+ DEPENDS ${_files}
+ COMMENT "${_comment}"
+ WORKING_DIRECTORY "${_sourceDir}" VERBATIM)
+ list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
+ set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget)
+ if (XCODE)
+ # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers
+ # if necessary, we also generate a single prefix header which includes all language specific prefix headers
+ set (_prefixFiles "")
+ foreach (_language ${_languages})
+ get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
+ if (_prefixFile)
+ list (APPEND _prefixFiles "${_prefixFile}")
+ endif()
+ endforeach()
+ set (_cmds ${ARGN})
+ list (LENGTH _prefixFiles _numberOfPrefixFiles)
+ if (_numberOfPrefixFiles GREATER 1)
+ cotire_make_prefix_file_path("" ${_target} _prefixHeader)
+ cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles})
+ else()
+ set (_prefixHeader "${_prefixFiles}")
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}")
+ endif()
+ add_custom_command(TARGET "${_target}"
+ PRE_BUILD ${_cmds}
+ WORKING_DIRECTORY "${_targetSourceDir}"
+ COMMENT "Updating target ${_target} prefix headers" VERBATIM)
+ # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++
+ set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
+ set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}")
+ elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
+ # for makefile based generator, we force inclusion of the prefix header for all target source files
+ # if this is a single-language target without any excluded files
+ if (_wholeTarget)
+ set (_language "${_languages}")
+ # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level
+ # see cotire_setup_prefix_file_inclusion
+ if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER)
+ get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER)
+ set (_flags "")
+ cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER)
+ cotire_add_pch_inclusion_flags(
+ "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}"
+ "${_prefixFile}" "${_pchFile}" _flags)
+ set_property (TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ")
+ endif()
+ endif()
+ endif()
+endfunction()
+
+function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _unityFiles _cmdsVar)
+ set (_dependencySources "")
+ cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN})
+ foreach (_unityFile ${_unityFiles})
+ file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}")
+ set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE)
+ # set up compiled unity source dependencies
+ # this ensures that missing source files are generated before the unity file is compiled
+ if (COTIRE_DEBUG AND _dependencySources)
+ message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}")
+ endif()
+ if (_dependencySources)
+ set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_dependencySources})
+ endif()
+ if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel
+ set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj")
+ endif()
+ cotire_set_cmd_to_prologue(_unityCmd)
+ list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetScript}" "${_unityFile}")
+ if (COTIRE_DEBUG)
+ message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_targetScript}")
+ endif()
+ add_custom_command(
+ OUTPUT "${_unityFile}"
+ COMMAND ${_unityCmd}
+ DEPENDS "${_targetScript}"
+ COMMENT "Generating ${_language} unity source ${_unityFileRelPath}"
+ WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM)
+ list (APPEND ${_cmdsVar} COMMAND ${_unityCmd})
+ endforeach()
+ list (LENGTH _unityFiles _numberOfUnityFiles)
+ if (_numberOfUnityFiles GREATER 1)
+ # create a joint unity file from all unity file segments
+ cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
+ cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles})
+ endif()
+ set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_single_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar)
+ set (_sourceFiles ${ARGN})
+ set (_dependencySources "")
+ cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles})
+ cotire_set_cmd_to_prologue(_prefixCmd)
+ list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}")
+ set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE)
+ if (COTIRE_DEBUG)
+ message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_targetScript} ${_unityFile} ${_dependencySources}")
+ endif()
+ file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}")
+ add_custom_command(
+ OUTPUT "${_prefixFile}" "${_prefixFile}.log"
+ COMMAND ${_prefixCmd}
+ DEPENDS "${_targetScript}" "${_unityFile}" ${_dependencySources}
+ COMMENT "Generating ${_language} prefix header ${_prefixFileRelPath}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
+ list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd})
+ set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_multi_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar)
+ set (_sourceFiles ${ARGN})
+ list (LENGTH _unityFiles _numberOfUnityFiles)
+ if (_numberOfUnityFiles GREATER 1)
+ cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile)
+ cotire_setup_single_prefix_generation_command(
+ ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
+ "${_prefixFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles})
+ else()
+ cotire_setup_single_prefix_generation_command(
+ ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}"
+ "${_prefixFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles})
+ endif()
+ set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE)
+endfunction()
+
+function (cotire_init_cotire_target_properties _target)
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE)
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE)
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE)
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}")
+ cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}")
+ if (NOT _isRelative)
+ set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}")
+ endif()
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "")
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "")
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET)
+ if (NOT _isSet)
+ set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "")
+ endif()
+ get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET)
+ if (NOT _isSet)
+ if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
+ set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}")
+ else()
+ set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "")
+ endif()
+ endif()
+endfunction()
+
+function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar)
+ get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
+ get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
+ string (REPLACE ";" " " _languagesStr "${_languages}")
+ string (REPLACE ";" ", " _excludedStr "${ARGN}")
+ set (_targetMsg "")
+ if (NOT _languages)
+ set (_targetMsg "Target ${_target} cannot be cotired.")
+ if (_disableMsg)
+ set (_targetMsg "${_targetMsg} ${_disableMsg}")
+ endif()
+ elseif (NOT _targetUsePCH AND NOT _targetAddSCU)
+ set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.")
+ if (_disableMsg)
+ set (_targetMsg "${_targetMsg} ${_disableMsg}")
+ endif()
+ elseif (NOT _targetUsePCH)
+ if (_allExcludedSourceFiles)
+ set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr} without precompiled header.")
+ else()
+ set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.")
+ endif()
+ if (_disableMsg)
+ set (_targetMsg "${_targetMsg} ${_disableMsg}")
+ endif()
+ elseif (NOT _targetAddSCU)
+ if (_allExcludedSourceFiles)
+ set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr} without unity build.")
+ else()
+ set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.")
+ endif()
+ else()
+ if (_allExcludedSourceFiles)
+ set (_targetMsg "${_languagesStr} target ${_target} cotired excluding files ${_excludedStr}.")
+ else()
+ set (_targetMsg "${_languagesStr} target ${_target} cotired.")
+ endif()
+ endif()
+ set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE)
+endfunction()
+
+function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar)
+ set (_languages ${ARGN})
+ set (_allSourceFiles "")
+ set (_allExcludedSourceFiles "")
+ set (_allCotiredSourceFiles "")
+ set (_targetLanguages "")
+ get_target_property(_targetType ${_target} TYPE)
+ get_target_property(_targetSourceFiles ${_target} SOURCES)
+ get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
+ get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
+ set (_disableMsg "")
+ foreach (_language ${_languages})
+ get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER)
+ get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE)
+ if (_prefixHeader OR _unityBuildFile)
+ message (WARNING "Target ${_target} has already been cotired.")
+ set (${_targetLanguagesVar} "" PARENT_SCOPE)
+ return()
+ endif()
+ if (_targetUsePCH AND "${_language}" STREQUAL "C" OR "${_language}" STREQUAL "CXX")
+ cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg)
+ if (_disableMsg)
+ set (_targetUsePCH FALSE)
+ endif()
+ endif()
+ set (_sourceFiles "")
+ set (_excludedSources "")
+ set (_cotiredSources "")
+ cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
+ if (_sourceFiles OR _excludedSources OR _cotiredSources)
+ list (APPEND _targetLanguages ${_language})
+ endif()
+ if (_sourceFiles)
+ list (APPEND _allSourceFiles ${_sourceFiles})
+ endif()
+ if (_excludedSources)
+ list (APPEND _allExcludedSourceFiles ${_excludedSources})
+ endif()
+ if (_cotiredSources)
+ list (APPEND _allCotiredSourceFiles ${_cotiredSources})
+ endif()
+ endforeach()
+ set (_targetMsgLevel STATUS)
+ if (NOT _targetLanguages)
+ string (REPLACE ";" " or " _languagesStr "${_languages}")
+ set (_disableMsg "No ${_languagesStr} source files.")
+ set (_targetUsePCH FALSE)
+ set (_targetAddSCU FALSE)
+ endif()
+ if (_targetUsePCH)
+ list (LENGTH _allSourceFiles _numberOfSources)
+ if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
+ set (_disableMsg "Too few applicable sources.")
+ set (_targetUsePCH FALSE)
+ elseif (_allCotiredSourceFiles)
+ cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles})
+ list (REMOVE_DUPLICATES _cotireTargets)
+ string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}")
+ set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.")
+ set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},")
+ set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.")
+ set (_targetMsgLevel SEND_ERROR)
+ set (_targetUsePCH FALSE)
+ elseif (XCODE AND _allExcludedSourceFiles)
+ # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target
+ set (_disableMsg "Exclusion of source files not supported for generator Xcode.")
+ set (_targetUsePCH FALSE)
+ elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY")
+ # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target
+ set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.")
+ set (_targetUsePCH FALSE)
+ endif()
+ endif()
+ set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH})
+ set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU})
+ cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles})
+ if (_targetMsg)
+ if (NOT DEFINED COTIREMSG_${_target})
+ set (COTIREMSG_${_target} "")
+ endif()
+ if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR
+ NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}")
+ # cache message to avoid redundant messages on re-configure
+ set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.")
+ message (${_targetMsgLevel} "${_targetMsg}")
+ endif()
+ endif()
+ set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE)
+endfunction()
+
+function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar)
+ set (_sourceFiles ${ARGN})
+ get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES)
+ if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)")
+ set (_numberOfThreads "${CMAKE_MATCH_2}")
+ if (NOT _numberOfThreads)
+ # use all available cores
+ ProcessorCount(_numberOfThreads)
+ endif()
+ list (LENGTH _sourceFiles _numberOfSources)
+ math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}")
+ # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files
+ if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
+ set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES})
+ endif()
+ elseif (NOT _maxIncludes MATCHES "[0-9]+")
+ set (_maxIncludes 0)
+ endif()
+ if (COTIRE_DEBUG)
+ message (STATUS "${_target} unity source max includes = ${_maxIncludes}")
+ endif()
+ set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE)
+endfunction()
+
+function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTargetVar _cmdsVar)
+ set (${_cmdsVar} "" PARENT_SCOPE)
+ get_target_property(_targetSourceFiles ${_target} SOURCES)
+ set (_sourceFiles "")
+ set (_excludedSources "")
+ set (_cotiredSources "")
+ cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
+ if (NOT _sourceFiles AND NOT _cotiredSources)
+ return()
+ endif()
+ set (_wholeTarget ${${_wholeTargetVar}})
+ set (_cmds "")
+ # check for user provided unity source file list
+ get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT)
+ if (NOT _unitySourceFiles)
+ set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources})
+ endif()
+ cotire_generate_target_script(
+ ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript ${_unitySourceFiles})
+ cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles})
+ cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles})
+ if (NOT _unityFiles)
+ return()
+ endif()
+ cotire_setup_unity_generation_commands(
+ ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_unityFiles}" _cmds ${_unitySourceFiles})
+ cotire_make_prefix_file_path(${_language} ${_target} _prefixFile)
+ if (_prefixFile)
+ # check for user provided prefix header files
+ get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT)
+ if (_prefixHeaderFiles)
+ cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles})
+ else()
+ cotire_setup_multi_prefix_generation_command(
+ ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles})
+ endif()
+ get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
+ if (_targetUsePCH)
+ cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile)
+ if (_pchFile)
+ cotire_setup_pch_file_compilation(
+ ${_language} "${_targetBinaryDir}" "${_targetScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
+ if (_excludedSources)
+ set (_wholeTarget FALSE)
+ endif()
+ cotire_setup_prefix_file_inclusion(
+ ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles})
+ endif()
+ endif()
+ endif()
+ # mark target as cotired for language
+ set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}")
+ if (_prefixFile)
+ set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}")
+ if (_targetUsePCH AND _pchFile)
+ set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}")
+ endif()
+ endif()
+ set (${_wholeTargetVar} ${_wholeTarget} PARENT_SCOPE)
+ set (${_cmdsVar} ${_cmds} PARENT_SCOPE)
+endfunction()
+
+function (cotire_setup_clean_target _target)
+ set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}")
+ if (NOT TARGET "${_cleanTargetName}")
+ cotire_set_cmd_to_prologue(_cmds)
+ get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE)
+ list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}")
+ add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM)
+ cotire_init_target("${_cleanTargetName}")
+ endif()
+endfunction()
+
+function (cotire_setup_pch_target _languages _configurations _target)
+ if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja")
+ # for makefile based generators, we add a custom target to trigger the generation of the cotire related files
+ set (_dependsFiles "")
+ foreach (_language ${_languages})
+ set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE)
+ if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel")
+ # Visual Studio and Intel only create precompiled header as a side effect
+ list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER)
+ endif()
+ cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props})
+ if (_dependsFile)
+ list (APPEND _dependsFiles "${_dependsFile}")
+ endif()
+ endforeach()
+ if (_dependsFiles)
+ set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}")
+ add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles})
+ cotire_init_target("${_pchTargetName}")
+ cotire_add_to_pch_all_target(${_pchTargetName})
+ endif()
+ else()
+ # for other generators, we add the "clean all" target to clean up the precompiled header
+ cotire_setup_clean_all_target()
+ endif()
+endfunction()
+
+function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target)
+ get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME)
+ if (NOT _unityTargetName)
+ set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}")
+ endif()
+ # determine unity target sub type
+ get_target_property(_targetType ${_target} TYPE)
+ if ("${_targetType}" STREQUAL "EXECUTABLE")
+ get_target_property(_isWin32 ${_target} WIN32_EXECUTABLE)
+ get_target_property(_isMacOSX_Bundle ${_target} MACOSX_BUNDLE)
+ if (_isWin32)
+ set (_unityTargetSubType WIN32)
+ elseif (_isMacOSX_Bundle)
+ set (_unityTargetSubType MACOSX_BUNDLE)
+ else()
+ set (_unityTargetSubType "")
+ endif()
+ elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY")
+ set (_unityTargetSubType "${CMAKE_MATCH_1}")
+ else()
+ message (WARNING "Unknown target type ${_targetType}.")
+ return()
+ endif()
+ # determine unity target sources
+ get_target_property(_targetSourceFiles ${_target} SOURCES)
+ set (_unityTargetSources ${_targetSourceFiles})
+ foreach (_language ${_languages})
+ get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE)
+ if (_unityFiles)
+ # remove source files that are included in the unity source
+ set (_sourceFiles "")
+ set (_excludedSources "")
+ set (_cotiredSources "")
+ cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles})
+ if (_sourceFiles OR _cotiredSources)
+ list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources})
+ endif()
+ # if cotire is applied to a target which has not been added in the current source dir,
+ # non-existing files cannot be referenced from the unity build target (this is a CMake restriction)
+ if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+ set (_nonExistingFiles "")
+ foreach (_file ${_unityTargetSources})
+ if (NOT EXISTS "${_file}")
+ list (APPEND _nonExistingFiles "${_file}")
+ endif()
+ endforeach()
+ if (_nonExistingFiles)
+ if (COTIRE_VERBOSE)
+ message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}")
+ endif()
+ list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles})
+ endif()
+ endif()
+ # add unity source files instead
+ list (APPEND _unityTargetSources ${_unityFiles})
+ endif()
+ endforeach()
+ if (COTIRE_DEBUG)
+ message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}")
+ endif()
+ # generate unity target
+ if ("${_targetType}" STREQUAL "EXECUTABLE")
+ add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
+ else()
+ add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources})
+ endif()
+ set (_outputDirProperties
+ ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
+ LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
+ RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_<CONFIG>)
+ # copy output location properties
+ if (COTIRE_UNITY_OUTPUT_DIRECTORY)
+ set (_setDefaultOutputDir TRUE)
+ if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
+ set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}")
+ else()
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
+ cotrie_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties})
+ foreach (_property ${_properties})
+ get_property(_outputDir TARGET ${_target} PROPERTY ${_property})
+ if (_outputDir)
+ get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
+ set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}")
+ set (_setDefaultOutputDir FALSE)
+ endif()
+ endforeach()
+ if (_setDefaultOutputDir)
+ get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE)
+ endif()
+ endif()
+ if (_setDefaultOutputDir)
+ set_target_properties(${_unityTargetName} PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}"
+ LIBRARY_OUTPUT_DIRECTORY "${_outputDir}"
+ RUNTIME_OUTPUT_DIRECTORY "${_outputDir}")
+ endif()
+ else()
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties})
+ endif()
+ # copy output name
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_<CONFIG>
+ LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_<CONFIG>
+ OUTPUT_NAME OUTPUT_NAME_<CONFIG>
+ RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_<CONFIG>
+ PREFIX <CONFIG>_POSTFIX SUFFIX)
+ # copy compile stuff
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ COMPILE_DEFINITIONS COMPILE_DEFINITIONS_<CONFIG>
+ COMPILE_FLAGS Fortran_FORMAT
+ INCLUDE_DIRECTORIES
+ INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
+ POSITION_INDEPENDENT_CODE)
+ # copy link stuff
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH
+ LINKER_LANGUAGE LINK_DEPENDS
+ LINK_FLAGS LINK_FLAGS_<CONFIG>
+ LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_<CONFIG>
+ LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_<CONFIG>
+ LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC
+ STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_<CONFIG>
+ NO_SONAME SOVERSION VERSION)
+ # copy Qt stuff
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ AUTOMOC AUTOMOC_MOC_OPTIONS)
+ # copy cmake stuff
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK)
+ # copy platform stuff
+ if (APPLE)
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST
+ OSX_ARCHITECTURES OSX_ARCHITECTURES_<CONFIG> PRIVATE_HEADER PUBLIC_HEADER RESOURCE)
+ elseif (WIN32)
+ cotrie_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName}
+ GNUtoMS
+ PDB_NAME PDB_NAME_<CONFIG> PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_<CONFIG>
+ VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_KEYWORD
+ VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER
+ VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES)
+ endif()
+ # use output name from original target
+ get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME)
+ if (NOT _targetOutputName)
+ set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}")
+ endif()
+ # use export symbol from original target
+ cotire_get_target_export_symbol("${_target}" _defineSymbol)
+ if (_defineSymbol)
+ set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}")
+ if ("${_targetType}" STREQUAL "EXECUTABLE")
+ set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE)
+ endif()
+ endif()
+ cotire_init_target(${_unityTargetName})
+ cotire_add_to_unity_all_target(${_unityTargetName})
+ set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}")
+endfunction(cotire_setup_unity_build_target)
+
+function (cotire_target _target)
+ set(_options "")
+ set(_oneValueArgs SOURCE_DIR BINARY_DIR)
+ set(_multiValueArgs LANGUAGES CONFIGURATIONS)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ if (NOT _option_SOURCE_DIR)
+ set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+ if (NOT _option_BINARY_DIR)
+ set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ if (NOT _option_LANGUAGES)
+ get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
+ endif()
+ if (NOT _option_CONFIGURATIONS)
+ if (CMAKE_CONFIGURATION_TYPES)
+ set (_option_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
+ elseif (CMAKE_BUILD_TYPE)
+ set (_option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}")
+ else()
+ set (_option_CONFIGURATIONS "None")
+ endif()
+ endif()
+ # trivial checks
+ get_target_property(_imported ${_target} IMPORTED)
+ if (_imported)
+ message (WARNING "Imported target ${_target} cannot be cotired.")
+ return()
+ endif()
+ # check if target needs to be cotired for build type
+ # when using configuration types, the test is performed at build time
+ cotire_init_cotire_target_properties(${_target})
+ if (NOT CMAKE_CONFIGURATION_TYPES)
+ if (CMAKE_BUILD_TYPE)
+ list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index)
+ else()
+ list (FIND _option_CONFIGURATIONS "None" _index)
+ endif()
+ if (_index EQUAL -1)
+ if (COTIRE_DEBUG)
+ message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})")
+ endif()
+ return()
+ endif()
+ endif()
+ # choose languages that apply to the target
+ cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages ${_option_LANGUAGES})
+ if (NOT _targetLanguages)
+ return()
+ endif()
+ list (LENGTH _targetLanguages _numberOfLanguages)
+ if (_numberOfLanguages GREATER 1)
+ set (_wholeTarget FALSE)
+ else()
+ set (_wholeTarget TRUE)
+ endif()
+ set (_cmds "")
+ foreach (_language ${_targetLanguages})
+ cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}"
+ "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} _wholeTarget _cmd)
+ if (_cmd)
+ list (APPEND _cmds ${_cmd})
+ endif()
+ endforeach()
+ get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD)
+ if (_targetAddSCU)
+ cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target})
+ endif()
+ get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER)
+ if (_targetUsePCH)
+ cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds})
+ cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target})
+ endif()
+ get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN)
+ if (_targetAddCleanTarget)
+ cotire_setup_clean_target(${_target})
+ endif()
+endfunction()
+
+function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName)
+ if (_targetName)
+ file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*")
+ else()
+ file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*")
+ endif()
+ # filter files in intermediate directory
+ set (_filesToRemove "")
+ foreach (_file ${_cotireFiles})
+ get_filename_component(_dir "${_file}" PATH)
+ get_filename_component(_dirName "${_dir}" NAME)
+ if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}")
+ list (APPEND _filesToRemove "${_file}")
+ endif()
+ endforeach()
+ if (_filesToRemove)
+ if (COTIRE_VERBOSE)
+ message (STATUS "removing ${_filesToRemove}")
+ endif()
+ file (REMOVE ${_filesToRemove})
+ endif()
+endfunction()
+
+function (cotire_init_target _targetName)
+ if (COTIRE_TARGETS_FOLDER)
+ set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}")
+ endif()
+ if (MSVC_IDE)
+ set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
+ endif()
+endfunction()
+
+function (cotire_add_to_pch_all_target _pchTargetName)
+ set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}")
+ if (NOT TARGET "${_targetName}")
+ add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
+ cotire_init_target("${_targetName}")
+ endif()
+ cotire_setup_clean_all_target()
+ add_dependencies(${_targetName} ${_pchTargetName})
+endfunction()
+
+function (cotire_add_to_unity_all_target _unityTargetName)
+ set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}")
+ if (NOT TARGET "${_targetName}")
+ add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM)
+ cotire_init_target("${_targetName}")
+ endif()
+ cotire_setup_clean_all_target()
+ add_dependencies(${_targetName} ${_unityTargetName})
+endfunction()
+
+function (cotire_setup_clean_all_target)
+ set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}")
+ if (NOT TARGET "${_targetName}")
+ cotire_set_cmd_to_prologue(_cmds)
+ list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}")
+ add_custom_target(${_targetName} COMMAND ${_cmds}
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM)
+ cotire_init_target("${_targetName}")
+ endif()
+endfunction()
+
+function (cotire)
+ set(_options "")
+ set(_oneValueArgs SOURCE_DIR BINARY_DIR)
+ set(_multiValueArgs LANGUAGES CONFIGURATIONS)
+ cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+ set (_targets ${_option_UNPARSED_ARGUMENTS})
+ if (NOT _option_SOURCE_DIR)
+ set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+ if (NOT _option_BINARY_DIR)
+ set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ foreach (_target ${_targets})
+ if (TARGET ${_target})
+ cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}
+ SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}")
+ else()
+ message (WARNING "${_target} is not a target")
+ endif()
+ endforeach()
+endfunction()
+
+if (CMAKE_SCRIPT_MODE_FILE)
+
+ # cotire is being run in script mode
+ # locate -P on command args
+ set (COTIRE_ARGC -1)
+ foreach (_index RANGE ${CMAKE_ARGC})
+ if (COTIRE_ARGC GREATER -1)
+ set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}")
+ math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1")
+ elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P")
+ set (COTIRE_ARGC 0)
+ endif()
+ endforeach()
+
+ # include target script if available
+ if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$")
+ # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES)
+ include("${COTIRE_ARGV2}")
+ endif()
+
+ if (COTIRE_DEBUG)
+ message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}")
+ endif()
+
+ if (WIN32)
+ # for MSVC, compiler IDs may not always be set correctly
+ if (MSVC)
+ set (CMAKE_C_COMPILER_ID "MSVC")
+ set (CMAKE_CXX_COMPILER_ID "MSVC")
+ endif()
+ endif()
+
+ if (NOT COTIRE_BUILD_TYPE)
+ set (COTIRE_BUILD_TYPE "None")
+ endif()
+ string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig)
+ set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}})
+ set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}})
+ set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}})
+ # check if target has been cotired for actual build type COTIRE_BUILD_TYPE
+ list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index)
+ if (_index GREATER -1)
+ set (_sources ${COTIRE_TARGET_SOURCES})
+ set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}})
+ else()
+ if (COTIRE_DEBUG)
+ message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})")
+ endif()
+ set (_sources "")
+ set (_sourcesDefinitions "")
+ endif()
+ set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS})
+ set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS})
+ set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS})
+ set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS})
+
+ if ("${COTIRE_ARGV1}" STREQUAL "unity")
+
+ cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources})
+ cotire_generate_unity_source(
+ "${COTIRE_ARGV3}" ${_sources}
+ LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
+ DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV2}"
+ SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions}
+ PRE_UNDEFS ${_targetPreUndefs}
+ POST_UNDEFS ${_targetPostUndefs}
+ SOURCES_PRE_UNDEFS ${_sourcesPreUndefs}
+ SOURCES_POST_UNDEFS ${_sourcesPostUndefs})
+
+ elseif ("${COTIRE_ARGV1}" STREQUAL "prefix")
+
+ set (_files "")
+ foreach (_index RANGE 4 ${COTIRE_ARGC})
+ if (COTIRE_ARGV${_index})
+ list (APPEND _files "${COTIRE_ARGV${_index}}")
+ endif()
+ endforeach()
+
+ cotire_generate_prefix_header(
+ "${COTIRE_ARGV3}" ${_files}
+ COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
+ COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
+ COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
+ COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
+ LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
+ DEPENDS "${COTIRE_ARGV0}" "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}
+ IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}"
+ INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH}
+ IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}"
+ INCLUDE_DIRECTORIES ${_includeDirs}
+ COMPILE_DEFINITIONS ${_compileDefinitions}
+ COMPILE_FLAGS ${_compileFlags})
+
+ elseif ("${COTIRE_ARGV1}" STREQUAL "precompile")
+
+ set (_files "")
+ foreach (_index RANGE 5 ${COTIRE_ARGC})
+ if (COTIRE_ARGV${_index})
+ list (APPEND _files "${COTIRE_ARGV${_index}}")
+ endif()
+ endforeach()
+
+ cotire_precompile_prefix_header(
+ "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}"
+ COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}"
+ COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1}
+ COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}"
+ COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}"
+ LANGUAGE "${COTIRE_TARGET_LANGUAGE}"
+ INCLUDE_DIRECTORIES ${_includeDirs}
+ COMPILE_DEFINITIONS ${_compileDefinitions}
+ COMPILE_FLAGS ${_compileFlags})
+
+ elseif ("${COTIRE_ARGV1}" STREQUAL "combine")
+
+ if (COTIRE_TARGET_LANGUAGE)
+ set (_startIndex 3)
+ else()
+ set (_startIndex 2)
+ endif()
+ set (_files "")
+ foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC})
+ if (COTIRE_ARGV${_index})
+ list (APPEND _files "${COTIRE_ARGV${_index}}")
+ endif()
+ endforeach()
+ if (COTIRE_TARGET_LANGUAGE)
+ cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}")
+ else()
+ cotire_generate_unity_source(${_files})
+ endif()
+
+ elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup")
+
+ cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}")
+
+ else()
+ message (FATAL_ERROR "Unknown cotire command \"${COTIRE_ARGV1}\".")
+ endif()
+
+else()
+
+ # cotire is being run in include mode
+ # set up all variable and property definitions
+
+ unset (COTIRE_C_COMPILER_VERSION CACHE)
+ unset (COTIRE_CXX_COMPILER_VERSION CACHE)
+
+ if (NOT DEFINED COTIRE_DEBUG_INIT)
+ if (DEFINED COTIRE_DEBUG)
+ set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG})
+ else()
+ set (COTIRE_DEBUG_INIT FALSE)
+ endif()
+ endif()
+ option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT})
+
+ if (NOT DEFINED COTIRE_VERBOSE_INIT)
+ if (DEFINED COTIRE_VERBOSE)
+ set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE})
+ else()
+ set (COTIRE_VERBOSE_INIT FALSE)
+ endif()
+ endif()
+ option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT})
+
+ set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING
+ "Ignore headers with the listed file extensions from the generated prefix header.")
+
+ set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING
+ "Ignore headers from these directories when generating the prefix header.")
+
+ set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING
+ "Ignore sources with the listed file extensions from the generated unity source.")
+
+ set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING
+ "Minimum number of sources in target required to enable use of precompiled header.")
+
+ if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT)
+ if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES)
+ set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES})
+ elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio")
+ # enable parallelization for generators that run multiple jobs by default
+ set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j")
+ else()
+ set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0")
+ endif()
+ endif()
+ set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING
+ "Maximum number of source files to include in a single unity source file.")
+
+ if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX)
+ set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix")
+ endif()
+ if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX)
+ set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity")
+ endif()
+ if (NOT COTIRE_INTDIR)
+ set (COTIRE_INTDIR "cotire")
+ endif()
+ if (NOT COTIRE_PCH_ALL_TARGET_NAME)
+ set (COTIRE_PCH_ALL_TARGET_NAME "all_pch")
+ endif()
+ if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME)
+ set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity")
+ endif()
+ if (NOT COTIRE_CLEAN_ALL_TARGET_NAME)
+ set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire")
+ endif()
+ if (NOT COTIRE_CLEAN_TARGET_SUFFIX)
+ set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire")
+ endif()
+ if (NOT COTIRE_PCH_TARGET_SUFFIX)
+ set (COTIRE_PCH_TARGET_SUFFIX "_pch")
+ endif()
+ if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX)
+ set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity")
+ endif()
+ if (NOT DEFINED COTIRE_TARGETS_FOLDER)
+ set (COTIRE_TARGETS_FOLDER "cotire")
+ endif()
+ if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY)
+ if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
+ # generated Ninja build files do not work if the unity target produces the same output file as the cotired target
+ set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity")
+ else()
+ set (COTIRE_UNITY_OUTPUT_DIRECTORY "")
+ endif()
+ endif()
+
+ # define cotire cache variables
+
+ define_property(
+ CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH"
+ BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
+ FULL_DOCS
+ "The variable can be set to a semicolon separated list of include directories."
+ "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
+ "If not defined, defaults to empty list."
+ )
+
+ define_property(
+ CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS"
+ BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header."
+ FULL_DOCS
+ "The variable can be set to a semicolon separated list of file extensions."
+ "If a header file extension matches one in the list, it will be excluded from the generated prefix header."
+ "Includes with an extension in CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS are always ignored."
+ "If not defined, defaults to inc;inl;ipp."
+ )
+
+ define_property(
+ CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS"
+ BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source."
+ FULL_DOCS
+ "The variable can be set to a semicolon separated list of file extensions."
+ "If a source file extension matches one in the list, it will be excluded from the generated unity source file."
+ "Source files with an extension in CMAKE_<LANG>_IGNORE_EXTENSIONS are always excluded."
+ "If not defined, defaults to m;mm."
+ )
+
+ define_property(
+ CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES"
+ BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header."
+ FULL_DOCS
+ "The variable can be set to an integer > 0."
+ "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target."
+ "If not defined, defaults to 3."
+ )
+
+ define_property(
+ CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES"
+ BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
+ FULL_DOCS
+ "This may be set to an integer >= 0."
+ "If 0, cotire will only create a single unity source file."
+ "If a target contains more than that number of source files, cotire will create multiple unity source files for it."
+ "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores."
+ "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs."
+ "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
+ "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise."
+ )
+
+ # define cotire directory properties
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER"
+ BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header."
+ FULL_DOCS
+ "See target property COTIRE_ENABLE_PRECOMPILED_HEADER."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD"
+ BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory."
+ FULL_DOCS
+ "See target property COTIRE_ADD_UNITY_BUILD."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_ADD_CLEAN"
+ BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory."
+ FULL_DOCS
+ "See target property COTIRE_ADD_CLEAN."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH"
+ BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
+ FULL_DOCS
+ "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH"
+ BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
+ FULL_DOCS
+ "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file."
+ FULL_DOCS
+ "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file."
+ FULL_DOCS
+ "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS."
+ )
+
+ define_property(
+ DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES"
+ BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
+ FULL_DOCS
+ "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES."
+ )
+
+ # define cotire target properties
+
+ define_property(
+ TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED
+ BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header."
+ FULL_DOCS
+ "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header."
+ "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target."
+ "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header."
+ "The target name will be set to this target's name with the suffix _pch appended."
+ "Inherited from directory."
+ "Defaults to TRUE."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED
+ BRIEF_DOCS "Add a new target that performs a unity build for this target."
+ FULL_DOCS
+ "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources."
+ "Most of the relevant target properties will be copied from this target to the new unity build target."
+ "Target dependencies and linked libraries have to be manually set up for the new unity build target."
+ "The unity target name will be set to this target's name with the suffix _unity appended."
+ "Inherited from directory."
+ "Defaults to TRUE."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED
+ BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target."
+ FULL_DOCS
+ "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)."
+ "The clean target name will be set to this target's name with the suffix _clean_cotire appended."
+ "Inherited from directory."
+ "Defaults to FALSE."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED
+ BRIEF_DOCS "Ignore headers from these directories when generating the prefix header."
+ FULL_DOCS
+ "The property can be set to a list of directories."
+ "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header."
+ "Inherited from directory."
+ "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED
+ BRIEF_DOCS "Honor headers from these directories when generating the prefix header."
+ FULL_DOCS
+ "The property can be set to a list of directories."
+ "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header."
+ "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH,"
+ "the option which yields the closer relative path match wins."
+ "Inherited from directory."
+ "If not set, this property is initialized to the empty list."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file."
+ FULL_DOCS
+ "This may be set to a semicolon-separated list of preprocessor symbols."
+ "cotire will add corresponding #undef directives to the generated unit source file before each target source file."
+ "Inherited from directory."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file."
+ FULL_DOCS
+ "This may be set to a semicolon-separated list of preprocessor symbols."
+ "cotire will add corresponding #undef directives to the generated unit source file after each target source file."
+ "Inherited from directory."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED
+ BRIEF_DOCS "Maximum number of source files to include in a single unity source file."
+ FULL_DOCS
+ "This may be set to an integer > 0."
+ "If a target contains more than that number of source files, cotire will create multiple unity build files for it."
+ "If not set, cotire will only create a single unity source file."
+ "Inherited from directory."
+ "Defaults to empty."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE_INIT"
+ BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one."
+ FULL_DOCS
+ "If set, cotire will only add the given file(s) to the generated unity source file."
+ "If not set, cotire will add all the target source files to the generated unity source file."
+ "The property can be set to a user provided unity source file."
+ "Defaults to empty."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER_INIT"
+ BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one."
+ FULL_DOCS
+ "If set, cotire will add the given header file(s) to the generated prefix header file."
+ "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file."
+ "The property can be set to a user provided prefix header file (e.g., stdafx.h)."
+ "Defaults to empty."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_<LANG>_UNITY_SOURCE"
+ BRIEF_DOCS "Read-only property. The generated <LANG> unity source file(s)."
+ FULL_DOCS
+ "cotire sets this property to the path of the generated <LANG> single computation unit source file for the target."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_<LANG>_PREFIX_HEADER"
+ BRIEF_DOCS "Read-only property. The generated <LANG> prefix header file."
+ FULL_DOCS
+ "cotire sets this property to the full path of the generated <LANG> language prefix header for the target."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_<LANG>_PRECOMPILED_HEADER"
+ BRIEF_DOCS "Read-only property. The generated <LANG> precompiled header file."
+ FULL_DOCS
+ "cotire sets this property to the full path of the generated <LANG> language precompiled header binary for the target."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME"
+ BRIEF_DOCS "The name of the generated unity build target corresponding to this target."
+ FULL_DOCS
+ "This property can be set to the desired name of the unity target that will be created by cotire."
+ "If not set, the unity target name will be set to this target's name with the suffix _unity appended."
+ "After this target has been processed by cotire, the property is set to the actual name of the generated unity target."
+ "Defaults to empty string."
+ )
+
+ # define cotire source properties
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_EXCLUDED"
+ BRIEF_DOCS "Do not modify source file's build command."
+ FULL_DOCS
+ "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header."
+ "The source file will also be excluded from the generated unity source file."
+ "Source files that have their COMPILE_FLAGS property set will be excluded by default."
+ "Defaults to FALSE."
+ )
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_DEPENDENCY"
+ BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file."
+ FULL_DOCS
+ "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file."
+ "If the file is modified, cotire will re-generate the prefix header source upon build."
+ "Defaults to FALSE."
+ )
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS"
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file."
+ FULL_DOCS
+ "This may be set to a semicolon-separated list of preprocessor symbols."
+ "cotire will add corresponding #undef directives to the generated unit source file before this file is included."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS"
+ BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file."
+ FULL_DOCS
+ "This may be set to a semicolon-separated list of preprocessor symbols."
+ "cotire will add corresponding #undef directives to the generated unit source file after this file is included."
+ "Defaults to empty string."
+ )
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE"
+ BRIEF_DOCS "Start a new unity source file which includes this source file as the first one."
+ FULL_DOCS
+ "If this property is set to TRUE, cotire will complete the current unity file and start a new one."
+ "The new unity source file will include this source file as the first one."
+ "This property essentially works as a separator for unity source files."
+ "Defaults to FALSE."
+ )
+
+ define_property(
+ SOURCE PROPERTY "COTIRE_TARGET"
+ BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target."
+ FULL_DOCS
+ "cotire sets this property to the name of target, that the source file's build command has been altered for."
+ "Defaults to empty string."
+ )
+
+ message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.")
+
+endif()
diff --git a/vendor/bandit/cross_compile.sh b/vendor/bandit/cross_compile.sh
new file mode 100755
index 00000000..7be77aaa
--- /dev/null
+++ b/vendor/bandit/cross_compile.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+build_results=()
+
+function build_for {
+ CC=$1
+ CXX=$2
+ BUILD_DIR=$CC
+
+ mkdir $BUILD_DIR
+ pushd $BUILD_DIR
+ CC=$CC CXX=$CXX cmake ../..
+ make
+ build_results+=("$CC: $?")
+ popd
+}
+
+if [[ -d builds ]]; then
+ rm -rf builds
+fi
+
+mkdir builds
+pushd builds
+
+build_for clang-3.6 clang++-3.6
+build_for gcc-5 g++-5
+build_for clang clang++
+build_for gcc-4.9 g++-4.9
+build_for gcc-4.8 g++-4.8
+build_for gcc-4.7 g++-4.7
+build_for gcc-4.6 g++-4.6
+build_for gcc-4.5 g++-4.5
+
+popd
+
+echo
+echo "Result:"
+for res in "${build_results[@]}"
+do
+ echo $res
+done
+
+echo "Done"
diff --git a/vendor/bandit/specs/before_each_after_each.spec.cpp b/vendor/bandit/specs/before_each_after_each.spec.cpp
new file mode 100644
index 00000000..29d40574
--- /dev/null
+++ b/vendor/bandit/specs/before_each_after_each.spec.cpp
@@ -0,0 +1,78 @@
+#include <specs/specs.h>
+
+namespace bf = bandit::fakes;
+
+go_bandit([](){
+
+ describe("before_each/after_each", [&](){
+ std::unique_ptr<bandit::detail::contextstack_t> context_stack;
+ std::unique_ptr<bf::fake_context> context;
+
+ before_each([&](){
+ context = std::unique_ptr<bf::fake_context>(new bf::fake_context());
+ context_stack = std::unique_ptr<bandit::detail::contextstack_t>(new bandit::detail::contextstack_t());
+ context_stack->push_back(context.get());
+ });
+
+ describe("before_each", [&](){
+ bandit::detail::voidfunc_t before_each_fn;
+
+ before_each([&](){
+ before_each_fn = [](){};
+ });
+
+ it("registers itself for the current context in the stack", [&](){
+ before_each(before_each_fn, *context_stack);
+ Assert::That(context->call_log(), Has().Exactly(1).EqualTo("register_before_each"));
+ });
+
+ });
+
+ describe("after_each", [&](){
+ bandit::detail::voidfunc_t after_each_fn;
+
+ before_each([&](){
+ after_each_fn = [](){};
+ });
+
+ it("registers itself for the current context in the stack", [&](){
+ after_each(after_each_fn, *context_stack);
+ Assert::That(context->call_log(), Has().Exactly(1).EqualTo("register_after_each"));
+ });
+
+ });
+ });
+
+ describe("before_each/after_each integration", [&](){
+ bandit::specs::logging_fake logger;
+
+ before_each([&](){
+ logger.log() << "first before_each called" << std::endl;
+ });
+
+ before_each([&](){
+ logger.log() << "second before_each called" << std::endl;
+ });
+
+ after_each([&](){
+ logger.log() << "first after_each called" << std::endl;
+ });
+
+ after_each([&](){
+ logger.log() << "second after_each called" << std::endl;
+ });
+
+ it("should only have called the before_each functions for the first test", [&](){
+ Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("first before_each called"));
+ Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("second before_each called"));
+ Assert::That(logger.call_log(), Has().None().Containing("after_each"));
+ });
+
+ it("should have called 'before_each' function twice, and 'after_each' functions once for the second test", [&](){
+ Assert::That(logger.call_log(), Has().Exactly(2).EqualTo("first before_each called"));
+ Assert::That(logger.call_log(), Has().Exactly(2).EqualTo("second before_each called"));
+ Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("first after_each called"));
+ Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("second after_each called"));
+ });
+ });
+});
diff --git a/vendor/bandit/specs/context.spec.cpp b/vendor/bandit/specs/context.spec.cpp
new file mode 100644
index 00000000..d517ef80
--- /dev/null
+++ b/vendor/bandit/specs/context.spec.cpp
@@ -0,0 +1,44 @@
+#include <specs/specs.h>
+
+go_bandit([](){
+
+ describe("bandit_context:", [&](){
+
+ std::unique_ptr<bandit::detail::bandit_context> context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ context = std::unique_ptr<bandit::detail::bandit_context>(
+ new bandit::detail::bandit_context("context name", hard_skip));
+ });
+
+ it("is ok to register before_each as it is not executing", [&](){
+ context->register_before_each([](){});
+ });
+
+ it("is ok to register after_each as it is not executing", [&](){
+ context->register_after_each([](){});
+ });
+
+ describe("is executing", [&](){
+
+ before_each([&](){
+ context->execution_is_starting();
+ });
+
+ it("is not ok to register before_each", [&](){
+ AssertThrows(bandit::detail::test_run_error, context->register_before_each([](){}));
+ Assert::That(LastException<bandit::detail::test_run_error>().what(),
+ Equals("before_each was called after 'describe' or 'it'"));
+ });
+
+ it("is not ok to register after_each", [&](){
+ AssertThrows(bandit::detail::test_run_error, context->register_after_each([](){}));
+ Assert::That(LastException<bandit::detail::test_run_error>().what(),
+ Equals("after_each was called after 'describe' or 'it'"));
+ });
+ });
+
+ });
+
+});
diff --git a/vendor/bandit/specs/describe.spec.cpp b/vendor/bandit/specs/describe.spec.cpp
new file mode 100644
index 00000000..d4600a28
--- /dev/null
+++ b/vendor/bandit/specs/describe.spec.cpp
@@ -0,0 +1,117 @@
+#include <specs/specs.h>
+
+using namespace bandit::fakes;
+namespace bd = bandit::detail;
+
+SPEC_BEGIN(describe)
+
+ describe("describe:", [](){
+ bandit::detail::voidfunc_t describe_fn;
+ fake_reporter_ptr reporter;
+ std::unique_ptr<bd::contextstack_t> context_stack;
+ std::unique_ptr<fake_context> global_context;
+
+ before_each([&](){
+ reporter = fake_reporter_ptr(new fake_reporter());
+
+ context_stack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t());
+
+ global_context = std::unique_ptr<fake_context>(new fake_context());
+ context_stack->push_back(global_context.get());
+ });
+
+
+ auto call_describe = [&](){
+ describe("context name", describe_fn, *reporter, *context_stack);
+ };
+
+ describe("with a succeeding 'it'", [&](){
+ int context_stack_size_while_running;
+
+ before_each([&](){
+ context_stack_size_while_running = 0;
+ describe_fn = [&](){context_stack_size_while_running = context_stack->size();};
+ });
+
+ it("tells its parent context that execution has started", [&](){
+ // This is important as once execution has started,
+ // before_each and after_each calls cannot be guaranteed to
+ // be run before any 'it' method.
+
+ call_describe();
+ AssertThat(global_context->call_log(), Has().AtLeast(1).EqualTo("execution_is_starting"));
+ });
+
+ it("tells reporter it's starting a run", [&](){
+ call_describe();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_starting: context name"));
+ });
+
+ it("tells reporter it's finished a run", [&](){
+ call_describe();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_ended: context name"));
+ });
+
+ it("pushes a new context during execution", [&](){
+ call_describe();
+ AssertThat(context_stack_size_while_running, Equals(2));
+ });
+
+ it("pops the context from the stack after execution so that only the global context is left", [&](){
+ call_describe();
+ AssertThat(*context_stack, Is().OfLength(1));
+ });
+
+ });
+
+ describe("with test run error", [&](){
+ //
+ // This can occur if after_each or before_each are called
+ // after execution has started for a context.
+ //
+
+ before_each([&](){
+ describe_fn = [&](){ throw bandit::detail::test_run_error("we dun goofed!"); };
+ });
+
+ it("doesn't propagate the error", [&](){
+ call_describe();
+ });
+
+ it("tells reporter to report the error", [&](){
+ call_describe();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_error: context name (we dun goofed!)"));
+ });
+
+ });
+
+ describe("skip", [&](){
+ bool context_is_hard_skip;
+ describe_fn =
+ [&](){ context_is_hard_skip = context_stack->back()->hard_skip(); };
+
+ before_each([&](){
+ context_is_hard_skip = false;
+ });
+
+ describe("describe_skip", [&](){
+
+ it("pushes a context marked as skipped on the stack", [&](){
+ describe_skip("context name", describe_fn, *reporter, *context_stack);
+ AssertThat(context_is_hard_skip, IsTrue());
+ });
+
+ });
+
+ describe("xdescribe", [&](){
+
+ it("pushes a context marked as skipped on the stack", [&](){
+ xdescribe("context name", describe_fn, *reporter, *context_stack);
+ AssertThat(context_is_hard_skip, IsTrue());
+ });
+
+ });
+ });
+ });
+
+SPEC_END
diff --git a/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp b/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp
new file mode 100644
index 00000000..6d29b694
--- /dev/null
+++ b/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp
@@ -0,0 +1,21 @@
+#include <specs/specs.h>
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("default failure formatter", [&](){
+ bd::default_failure_formatter formatter;
+
+ it("formats assertions with file and line number", [&](){
+ bd::assertion_exception exception("message", "file", 321);
+ AssertThat(formatter.format(exception), Equals("file:321: message"));
+ });
+
+ it("formats assertions without file and line number", [&](){
+ bd::assertion_exception exception("message");
+ AssertThat(formatter.format(exception), Equals("message"));
+ });
+
+ });
+
+});
diff --git a/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp b/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp
new file mode 100644
index 00000000..0d283c8e
--- /dev/null
+++ b/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp
@@ -0,0 +1,22 @@
+#include <specs/specs.h>
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("Visual Studio failure formatter:", [&](){
+
+ bd::visual_studio_failure_formatter formatter;
+
+ it("formats assertions with file and line number", [&](){
+ bd::assertion_exception exception("message", "file", 321);
+ AssertThat(formatter.format(exception), Equals("file(321): message"));
+ });
+
+ it("formats assertions without file and line number", [&](){
+ bd::assertion_exception exception("message");
+ AssertThat(formatter.format(exception), Equals("bandit: message"));
+ });
+
+ });
+
+});
diff --git a/vendor/bandit/specs/fakes/fake_context.h b/vendor/bandit/specs/fakes/fake_context.h
new file mode 100644
index 00000000..e5d1d870
--- /dev/null
+++ b/vendor/bandit/specs/fakes/fake_context.h
@@ -0,0 +1,69 @@
+#ifndef BANDIT_FAKE_CONTEXT_H
+#define BANDIT_FAKE_CONTEXT_H
+
+namespace bandit { namespace fakes {
+
+ struct fake_context : public bandit::detail::context, public bandit::specs::logging_fake
+ {
+ fake_context() : hard_skip_(false), name_("fake_context"),
+ custom_after_each_([](){}), custom_before_each_([](){})
+ {}
+
+ const std::string& name()
+ {
+ log() << "name" << std::endl;
+ return name_;
+ }
+
+ void execution_is_starting()
+ {
+ log() << "execution_is_starting" << std::endl;
+ }
+
+ void register_before_each(detail::voidfunc_t)
+ {
+ log() << "register_before_each" << std::endl;
+ }
+
+ void register_after_each(detail::voidfunc_t)
+ {
+ log() << "register_after_each" << std::endl;
+ }
+
+ void run_before_eaches()
+ {
+ log() << "run_before_eaches" << std::endl;
+ custom_before_each_();
+ }
+
+ void run_after_eaches()
+ {
+ log() << "run_after_eaches" << std::endl;
+ custom_after_each_();
+ }
+
+ bool hard_skip()
+ {
+ log() << "hard_skip: returning " << hard_skip_ << std::endl;
+ return hard_skip_;
+ }
+
+ void with_after_each(detail::voidfunc_t call)
+ {
+ custom_after_each_ = call;
+ }
+
+ void with_before_each(detail::voidfunc_t call)
+ {
+ custom_before_each_ = call;
+ }
+
+ private:
+ bool hard_skip_;
+ std::string name_;
+ detail::voidfunc_t custom_after_each_;
+ detail::voidfunc_t custom_before_each_;
+ };
+}}
+
+#endif
diff --git a/vendor/bandit/specs/fakes/fake_reporter.h b/vendor/bandit/specs/fakes/fake_reporter.h
new file mode 100644
index 00000000..032ed44d
--- /dev/null
+++ b/vendor/bandit/specs/fakes/fake_reporter.h
@@ -0,0 +1,78 @@
+#ifndef BANDIT_SPECS_FAKE_REPORTER_H
+#define BANDIT_SPECS_FAKE_REPORTER_H
+
+namespace bandit { namespace fakes {
+ struct fake_reporter :
+ public bandit::detail::listener,
+ public bandit::specs::logging_fake
+ {
+ fake_reporter() : test_run_status_(true)
+ {}
+
+ void test_run_starting()
+ {
+ log() << "test_run_starting" << std::endl;
+ }
+
+ void test_run_complete()
+ {
+ log() << "test_run_complete" << std::endl;
+ }
+
+ void context_starting(const char* desc)
+ {
+ log() << "context_starting: " << desc << std::endl;
+ }
+
+ void context_ended(const char* desc)
+ {
+ log() << "context_ended: " << desc << std::endl;
+ }
+
+ void test_run_error(const char* desc, const struct bandit::detail::test_run_error& err)
+ {
+ log() << "test_run_error: " << desc << " (" << strip_newline(err.what()) << ")" << std::endl;
+ }
+
+ void it_starting(const char* desc)
+ {
+ log() << "it_starting: " << desc << std::endl;
+ }
+
+ void it_succeeded(const char* desc)
+ {
+ log() << "it_succeeded: " << desc << std::endl;
+ }
+
+ void it_failed(const char* desc, const bandit::detail::assertion_exception& ex)
+ {
+ log() << "it_failed: " << desc << " (" << strip_newline(ex.what()) << ")" << std::endl;
+ }
+
+ void it_unknown_error(const char* desc)
+ {
+ log() << "it_unknown_error: " << desc << std::endl;
+ }
+
+ void it_skip(const char* desc)
+ {
+ log() << "it_skip: " << desc << std::endl;
+ }
+
+ bool did_we_pass() const
+ {
+ return test_run_status_;
+ }
+
+ void set_test_run_status(bool status)
+ {
+ test_run_status_ = status;
+ }
+
+ private:
+ bool test_run_status_;
+ };
+ typedef std::unique_ptr<fake_reporter> fake_reporter_ptr;
+}}
+
+#endif
diff --git a/vendor/bandit/specs/fakes/fakes.h b/vendor/bandit/specs/fakes/fakes.h
new file mode 100644
index 00000000..a48517f6
--- /dev/null
+++ b/vendor/bandit/specs/fakes/fakes.h
@@ -0,0 +1,8 @@
+#ifndef BANDIT_SPECS_FAKES_H
+#define BANDIT_SPECS_FAKES_H
+
+#include <specs/fakes/logging_fake.h>
+#include <specs/fakes/fake_reporter.h>
+#include <specs/fakes/fake_context.h>
+
+#endif
diff --git a/vendor/bandit/specs/fakes/logging_fake.h b/vendor/bandit/specs/fakes/logging_fake.h
new file mode 100644
index 00000000..ac1d3dd0
--- /dev/null
+++ b/vendor/bandit/specs/fakes/logging_fake.h
@@ -0,0 +1,32 @@
+#ifndef BANDIT_SPECS_LOGGING_FAKE_H
+#define BANDIT_SPECS_LOGGING_FAKE_H
+#include <sstream>
+
+namespace bandit { namespace specs {
+
+ struct logging_fake
+ {
+ std::ostream& log()
+ {
+ return logstm_;
+ }
+
+ std::string strip_newline(const char* val)
+ {
+ std::string no_newline = val;
+ std::transform(no_newline.begin(), no_newline.end(), no_newline.begin(), [](const char& c) {
+ return (c == '\n' || c == '\r') ? ' ' : c;
+ });
+ return no_newline;
+ }
+
+ std::string call_log()
+ {
+ return logstm_.str();
+ }
+
+ private:
+ std::stringstream logstm_;
+ };
+}}
+#endif
diff --git a/vendor/bandit/specs/fuzzbox.spec.cpp b/vendor/bandit/specs/fuzzbox.spec.cpp
new file mode 100644
index 00000000..6515a554
--- /dev/null
+++ b/vendor/bandit/specs/fuzzbox.spec.cpp
@@ -0,0 +1,77 @@
+#include <specs/specs.h>
+
+namespace fuzzbox {
+
+ typedef enum {
+ clean,
+ distorted
+ } sounds;
+
+ struct fuzzbox
+ {
+ fuzzbox() : sound_(sounds::clean)
+ {}
+
+ void flip()
+ {
+ sound_ = sounds::distorted;
+ }
+
+ sounds sound()
+ {
+ return sound_;
+ }
+
+ private:
+ sounds sound_;
+ };
+ typedef std::unique_ptr<fuzzbox> fuzzbox_ptr;
+
+ struct guitar
+ {
+ void add_effect(fuzzbox* effect)
+ {
+ effect_ = effect;
+ }
+
+ sounds sound()
+ {
+ return effect_->sound();
+ }
+
+ private:
+ fuzzbox* effect_;
+ };
+ typedef std::unique_ptr<guitar> guitar_ptr;
+
+go_bandit([](){
+
+ describe("fuzzbox:", [](){
+ guitar_ptr guitar;
+ fuzzbox_ptr fuzzbox;
+
+ before_each([&](){
+ guitar = guitar_ptr(new struct guitar());
+ fuzzbox = fuzzbox_ptr(new struct fuzzbox());
+ guitar->add_effect(fuzzbox.get());
+ });
+
+ it("starts in clean mode", [&](){
+ AssertThat(guitar->sound(), Equals(sounds::clean));
+ });
+
+ describe("in distorted mode", [&](){
+
+ before_each([&](){
+ fuzzbox->flip();
+ });
+
+ it("sounds distorted", [&](){
+ AssertThat(guitar->sound(), Equals(sounds::distorted));
+ });
+ });
+ });
+
+});
+
+}
diff --git a/vendor/bandit/specs/it.spec.cpp b/vendor/bandit/specs/it.spec.cpp
new file mode 100644
index 00000000..287a1ede
--- /dev/null
+++ b/vendor/bandit/specs/it.spec.cpp
@@ -0,0 +1,355 @@
+#include <specs/specs.h>
+using namespace bandit::fakes;
+namespace bd = bandit::detail;
+
+go_bandit([](){
+ describe("it:", [&](){
+ bd::voidfunc_t it_func;
+ fake_reporter_ptr reporter;
+ std::unique_ptr<bd::contextstack_t> contexts;
+ std::unique_ptr<fake_context> context;
+ bandit::adapters::snowhouse_adapter assertion_adapter;
+ bd::run_policy_ptr run_policy;
+
+ before_each([&](){
+ reporter = fake_reporter_ptr(new fake_reporter());
+ contexts = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t());
+ context = std::unique_ptr<fake_context>(new fake_context());
+ contexts->push_back(context.get());
+
+ run_policy = bd::run_policy_ptr(new bd::always_run_policy());
+ });
+
+ auto call_it = [&]() {
+ it("my it", it_func, *reporter, *contexts, assertion_adapter, *run_policy);
+ };
+
+ it("tells the current context that execution has started", [&](){
+ // This is important as once execution has started,
+ // before_each and after_each calls cannot be guaranteed to
+ // be run before any 'it' method.
+
+ call_it();
+ AssertThat(context->call_log(), Has().AtLeast(1).EqualTo("execution_is_starting"));
+ });
+
+ describe("with succeeding test", [&](){
+ before_each([&](){
+ it_func = [](){};
+ });
+
+ it("tells reporter it's starting", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_starting: my it"));
+ });
+
+ it("tells reporter it's succeeded", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_succeeded: my it"));
+ });
+
+ it("calls before_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches"));
+ });
+
+ it("calls after_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches"));
+ });
+
+ describe("but with a failing after_each", [&](){
+
+ before_each([&](){
+ context->with_after_each([](){ AssertThat(2, Equals(3)); });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 3 Actual: 2 )"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ describe("but with a std::exception in after_each", [&](){
+
+ before_each([&](){
+ context->with_after_each([](){ throw std::logic_error("logic is wrong!"); });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic is wrong!)"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+
+ });
+
+ describe("but with an unknown error in after_each", [&](){
+
+ before_each([&](){
+ context->with_after_each([](){ throw 25; });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ describe("but with a failing before_each", [&](){
+
+ before_each([&](){
+ context->with_before_each([](){ AssertThat(2, Equals(3)); });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 3 Actual: 2 )"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ describe("but with a std::exception in before_each", [&](){
+
+ before_each([&](){
+ context->with_before_each([](){ throw std::logic_error("logic is wrong!"); });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic is wrong!)"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ describe("but with an unknown error in before_each", [&](){
+
+ before_each([&](){
+ context->with_before_each([](){ throw 25; });
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it"));
+ });
+
+ it("doesn't report a succeeding test", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ });
+
+ describe("with failing test", [&](){
+ before_each([&](){
+ it_func = [](){ AssertThat(3, Equals(2)); };
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 2 Actual: 3 )"));
+ });
+
+ it("calls before_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches"));
+ });
+
+ it("calls after_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+
+ describe("with crashing test", [&](){
+ before_each([&](){
+ it_func = [](){ throw 44; };
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it"));
+ });
+
+ it("calls before_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches"));
+ });
+
+ it("calls after_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+ });
+
+ describe("with test throwing exception based on 'std::exception'", [&](){
+
+ before_each([&](){
+ it_func = [](){ throw std::logic_error("logic error"); };
+ });
+
+ it("tells reporter it's failed", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic error)"));
+ });
+
+ it("calls before_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches"));
+ });
+
+ it("calls after_each in context", [&](){
+ call_it();
+ AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches"));
+ });
+
+ it("tells run_policy that we have a failing test", [&](){
+ call_it();
+ AssertThat(run_policy->has_encountered_failure(), IsTrue());
+ });
+
+ });
+
+ describe("it_skip", [&](){
+
+ it("tells reporter it's skipped", [&](){
+ it_skip("my it", [](){}, *reporter);
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it"));
+ });
+
+ it("doesn't call function", [&](){
+ bool called = false;
+ it_skip("my it", [&](){ called = true; }, *reporter);
+ AssertThat(called, IsFalse());
+ });
+
+ });
+
+ describe("xit", [&](){
+
+ it("tells reporter it's skipped", [&](){
+ xit("my it", [](){}, *reporter);
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it"));
+ });
+
+ it("doesn't call function", [&](){
+ bool called = false;
+ xit("my it", [&](){ called = true; }, *reporter);
+ AssertThat(called, IsFalse());
+ });
+
+ });
+
+ describe("with a run policy that says to skip this 'it'", [&](){
+ bool it_was_called;
+
+ before_each([&](){
+ run_policy = bd::run_policy_ptr(new bd::never_run_policy());
+ it_func = [&](){ it_was_called = true; };
+ it_was_called = false;
+ });
+
+ it("tells reporter it's skipped", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it"));
+ });
+
+ it("doesn't call function", [&](){
+ call_it();
+ AssertThat(it_was_called, IsFalse());
+ });
+
+ });
+
+ describe("skipping", [&](){
+ bool it_was_called;
+
+ before_each([&](){
+ it_func = [&](){ it_was_called = true; };
+ it_was_called = false;
+ });
+
+ describe("with a policy that says to skip this it", [&](){
+
+ before_each([&](){
+ run_policy = bd::run_policy_ptr(new bd::never_run_policy());
+ });
+
+ it("tells reporter it's skipped", [&](){
+ call_it();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it"));
+ });
+
+ it("doesn't call function", [&](){
+ call_it();
+ AssertThat(it_was_called, IsFalse());
+ });
+
+ });
+ });
+ });
+});
diff --git a/vendor/bandit/specs/main.cpp b/vendor/bandit/specs/main.cpp
new file mode 100644
index 00000000..dde5de2d
--- /dev/null
+++ b/vendor/bandit/specs/main.cpp
@@ -0,0 +1,6 @@
+#include <specs/specs.h>
+
+int main(int argc, char* argv[])
+{
+ return bandit::run(argc, argv);
+}
diff --git a/vendor/bandit/specs/matchers/be_close_to.cpp b/vendor/bandit/specs/matchers/be_close_to.cpp
new file mode 100644
index 00000000..64309673
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_close_to.cpp
@@ -0,0 +1,112 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeCloseTo)
+
+describe("be_close_to matcher", []{
+ describe("when the actual value is declared as a float", [&]{
+ float actualValue = 2.0 / 3.0;
+
+ describe("and the expected value is also a float", [&]{
+ float expectedValue;
+
+ describe("with an explicit threshold", [&]{
+ float threshold = 0.1;
+
+ describe("and the values are within the given threshold", [&]{
+ before_each([&]{
+ expectedValue = 2.0 / 3.0 + 0.01;
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must be_close_to(expectedValue).within(threshold);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue).within(threshold); }());
+ });
+ });
+
+ describe("and the values are not within the given threshold", [&]{
+ before_each([&]{
+ expectedValue = 2.0 / 3.0 + 0.2;
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not be_close_to(expectedValue).within(threshold);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue).within(threshold); }());
+ });
+ });
+ });
+
+ describe("without an explicit threshold", [&]{
+ describe("and the values are within the default threshold", [&]{
+ before_each([&]{
+ expectedValue = 2.0 / 3.0 + 0.000001;
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must be_close_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue); }());
+ });
+ });
+
+ describe("and the values are not within the default threshold", [&]{
+ before_each([&]{
+ expectedValue = 2.0 / 3.0 + 0.1;
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not be_close_to(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue); }());
+ });
+ });
+ });
+ });
+
+ describe("and the expected value is a compatible non-float type", [&]{
+ int expectedValue;
+ float threshold = 1;
+
+ describe("and the values are within the given threshold", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must be_close_to(expectedValue).within(threshold);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue).within(threshold); }());
+ });
+ });
+
+ describe("and the values are not within the given threshold", [&]{
+ before_each([&]{
+ expectedValue = 5;
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not be_close_to(expectedValue).within(threshold);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue).within(threshold); }());
+ });
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_empty.cpp b/vendor/bandit/specs/matchers/be_empty.cpp
new file mode 100644
index 00000000..3ed4a6f9
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_empty.cpp
@@ -0,0 +1,89 @@
+#include <set>
+
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeEmpty)
+
+describe("be_empty matcher", [&]{
+ describe("when the value is an STL vector", [&]{
+ describe("which is empty", [&]{
+ std::vector<int> container;
+
+ it("must pass a positive match", [&]{
+ container must be_empty;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not be_empty; }());
+ });
+ });
+
+ describe("which is not empty", [&]{
+ std::vector<int> container {2, 7};
+
+ it("must pass a negative match", [&]{
+ container must_not be_empty;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must be_empty; }());
+ });
+ });
+ });
+
+ describe("when the value is an STL map", [&]{
+ describe("which is empty", [&]{
+ std::map<int, int> container;
+
+ it("must pass a positive match", [&]{
+ container must be_empty;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not be_empty; }());
+ });
+ });
+
+ describe("which is not empty", [&]{
+ std::map<int, int> container {{5, 6}, {7,10}};
+
+ it("must pass a negative match", [&]{
+ container must_not be_empty;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must be_empty; }());
+ });
+ });
+ });
+
+ describe("when the value is an STL set", [&]{
+ describe("which is empty", [&]{
+ std::set<int> container;
+
+ it("must pass a positive match", [&]{
+ container must be_empty;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not be_empty; }());
+ });
+ });
+
+ describe("which is not empty", [&]{
+ std::set<int> container {5, 7};
+
+ it("must pass a negative match", [&]{
+ container must_not be_empty;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must be_empty; }());
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_falsy.cpp b/vendor/bandit/specs/matchers/be_falsy.cpp
new file mode 100644
index 00000000..d8c71c1b
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_falsy.cpp
@@ -0,0 +1,85 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeFalsy)
+
+describe("be_falsy matcher", [&]{
+ describe("when the value is a built-in type", [&]{
+ bool value;
+
+ describe("which evaluates to false", [&]{
+ before_each([&]{
+ value = false;
+ });
+
+ it("must accept a positive match", [&]{
+ value must be_falsy;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_falsy; }());
+ });
+ });
+
+ describe("which evaluates to true", [&]{
+ before_each([&]{
+ value = true;
+ });
+
+ it("must accept a negative match", [&]{
+ value must_not be_falsy;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_falsy; }());
+ });
+ });
+ });
+
+ describe("when the value is nullptr", [&]{
+ auto value = nullptr;
+
+ it("must accept a positive match", [&]{
+ value must be_falsy;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_falsy; }());
+ });
+ });
+
+ describe("when the value is a pointer", [&]{
+ char* value;
+
+ describe("which evaluates to false", [&]{
+ before_each([&]{
+ value = NULL;
+ });
+
+ it("must accept a positive match", [&]{
+ value must be_falsy;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_falsy; }());
+ });
+ });
+
+ describe("which evaluates to true", [&]{
+ before_each([&]{
+ value = (char*)"cat";
+ });
+
+ it("must accept a negative match", [&]{
+ value must_not be_falsy;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_falsy; }());
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_greater_than.cpp b/vendor/bandit/specs/matchers/be_greater_than.cpp
new file mode 100644
index 00000000..17a97fe3
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_greater_than.cpp
@@ -0,0 +1,105 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeGreaterThan)
+
+describe("be_greater_than matcher", []{
+ describe("when the actual value is a built-in type", [&]{
+ int actualValue = 10;
+
+ describe("and the expected value is the same built-in type", [&]{
+ int expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_greater_than(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_greater_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_greater_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }());
+ });
+ });
+ });
+
+ describe("and the expected value is a different, but comparable, built-in type", [&]{
+ float expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1.1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_greater_than(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100.1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_greater_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_greater_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }());
+ });
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_gte.cpp b/vendor/bandit/specs/matchers/be_gte.cpp
new file mode 100644
index 00000000..f0e18313
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_gte.cpp
@@ -0,0 +1,120 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+
+SPEC_BEGIN(Matchers::BeGTE)
+
+describe("be_gte matcher", [&]{
+ int someInteger = 10;
+
+ describe("when the actual value is a built-in type", [&]{
+ int actualValue = someInteger;
+
+ describe("and the expected value is the same built-in type", [&]{
+ int expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_gte(expectedValue);
+ actualValue must be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_gte(expectedValue);
+ actualValue must_not be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_gte(expectedValue);
+ actualValue must be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+ });
+
+ describe("and the expected value is a different, but comparable, built-in type", [&]{
+ float expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1.1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_gte(expectedValue);
+ actualValue must be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100.1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_gte(expectedValue);
+ actualValue must_not be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = someInteger / 1.0;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_gte(expectedValue);
+ actualValue must be_greater_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }());
+ });
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_less_than.cpp b/vendor/bandit/specs/matchers/be_less_than.cpp
new file mode 100644
index 00000000..30f60c47
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_less_than.cpp
@@ -0,0 +1,105 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeLessThan)
+
+describe("be_less_than matcher", []{
+ describe("when the actual value is a built-in type", [&]{
+ int actualValue = 10;
+
+ describe("and the expected value is the same built-in type", [&]{
+ int expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_less_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_less_than(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_less_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }());
+ });
+ });
+ });
+
+ describe("and the expected value is a different, but comparable, built-in type", [&]{
+ float expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1.1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_less_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100.1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_less_than(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_less_than(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }());
+ });
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_lte.cpp b/vendor/bandit/specs/matchers/be_lte.cpp
new file mode 100644
index 00000000..443ac1c5
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_lte.cpp
@@ -0,0 +1,119 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeLTE)
+
+describe("be_lte matcher", [&]{
+ int someInteger = 10;
+
+ describe("when the actual value is a built-in type", [&]{
+ int actualValue = someInteger;
+
+ describe("and the expected value is the same built-in type", [&]{
+ int expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_lte(expectedValue);
+ actualValue must_not be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_lte(expectedValue);
+ actualValue must be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = actualValue;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_lte(expectedValue);
+ actualValue must be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+ });
+
+ describe("and the expected value is a different, but comparable, built-in type", [&]{
+ float expectedValue;
+
+ describe("and the actual value is greater than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 1.1;
+ });
+
+ it("must pass a negative match", [&]{
+ actualValue must_not be_lte(expectedValue);
+ actualValue must_not be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value is less than the expected value", [&]{
+ before_each([&]{
+ expectedValue = 100.1;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_lte(expectedValue);
+ actualValue must be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+
+ describe("and the actual value equals the expected value", [&]{
+ before_each([&]{
+ expectedValue = someInteger / 1.0;
+ });
+
+ it("must pass a positive match", [&]{
+ actualValue must be_lte(expectedValue);
+ actualValue must be_less_than_or_equal_to(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }());
+ AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }());
+ });
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_null.cpp b/vendor/bandit/specs/matchers/be_null.cpp
new file mode 100644
index 00000000..ae3cd40d
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_null.cpp
@@ -0,0 +1,43 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeNull)
+
+describe("be_null matcher", [&]{
+ describe("when the value is a pointer to a built-in type", [&]{
+ int* value;
+
+ describe("which is NULL", [&]{
+ before_each([&]{
+ value = NULL;
+ });
+
+ it("must pass a positive match", [&]{
+ value must be_null;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_null; }());
+ });
+ });
+
+ describe("which is not NULL", [&]{
+ int i = 7;
+
+ before_each([&]{
+ value = &i;
+ });
+
+ it("must pass a negative match", [&]{
+ value must_not be_null;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_null; }());
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/be_truthy.cpp b/vendor/bandit/specs/matchers/be_truthy.cpp
new file mode 100644
index 00000000..5e583fbf
--- /dev/null
+++ b/vendor/bandit/specs/matchers/be_truthy.cpp
@@ -0,0 +1,85 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::BeTruthy)
+
+describe("be_truthy matcher", [&]{
+ describe("when the value is a built-in type", [&]{
+ bool value;
+
+ describe("which evaluates to false", [&]{
+ before_each([&]{
+ value = false;
+ });
+
+ it("must accept a negative match", [&]{
+ value must_not be_truthy;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_truthy; }());
+ });
+ });
+
+ describe("which evaluates to true", [&]{
+ before_each([&]{
+ value = true;
+ });
+
+ it("must accept a positive match", [&]{
+ value must be_truthy;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_truthy; }());
+ });
+ });
+ });
+
+ describe("when the value is nullptr", [&]{
+ auto value = nullptr;
+
+ it("must accept a negative match", [&]{
+ value must_not be_truthy;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_truthy; }());
+ });
+ });
+
+ describe("when the value is a pointer", [&]{
+ char* value;
+
+ describe("which evaluates to false", [&]{
+ before_each([&]{
+ value = NULL;
+ });
+
+ it("must accept a negative match", [&]{
+ value must_not be_truthy;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ value must be_truthy; }());
+ });
+ });
+
+ describe("which evaluates to true", [&]{
+ before_each([&]{
+ value = (char*)"cat";
+ });
+
+ it("must accept a positive match", [&]{
+ value must be_truthy;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ value must_not be_truthy; }());
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/contain.cpp b/vendor/bandit/specs/matchers/contain.cpp
new file mode 100644
index 00000000..2c0b4b3b
--- /dev/null
+++ b/vendor/bandit/specs/matchers/contain.cpp
@@ -0,0 +1,156 @@
+#include <set>
+
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::Contain)
+
+describe("contain matcher", [&]{
+ std::string element0("element0");
+ std::string element1("element1");
+
+ describe("when the container is an STL vector", [&]{
+ describe("which contains the element", [&]{
+ std::vector<std::string> container {element0, element1};
+
+ it("must pass a positive match", [&]{
+ container must contain(element1);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not contain(element1); }());
+ });
+ });
+
+ describe("which does not contain the element", [&]{
+ std::vector<int> container;
+
+ it("must pass a negative match", [&]{
+ container must_not contain(4);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain(4); }());
+ });
+ });
+ });
+
+ describe("when the container is an STL map", [&]{
+ describe("which contains the expected key", [&]{
+ std::map<int, int> container {{5, 6}, {7,10}};
+
+ it("must pass a positive match", [&]{
+ container must contain(5);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not contain(5); }());
+ });
+ });
+
+ describe("which does not contain the expected value", [&]{
+ std::map<int, int> container;
+
+ it("must pass a negative match", [&]{
+ container must_not contain(6);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain(6); }());
+ });
+ });
+ });
+
+ describe("when the container is an STL set", [&]{
+ describe("which contains the element", [&]{
+ std::set<int> container {5, 7};
+
+ it("must pass a positive match", [&]{
+ container must contain(7);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not contain(7); }());
+ });
+ });
+
+ describe("which does not contain the element", [&]{
+ std::set<int> container;
+
+ it("must pass a negative match", [&]{
+ container must_not contain(7);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain(7); }());
+ });
+ });
+ });
+
+ describe("when the container is a C string", [&]{
+ describe("which is null", [&]{
+ char* container = NULL;
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain("foo"); }());
+ });
+ });
+
+ describe("which contains the substring", [&]{
+ char* container = (char*)"jack and jill";
+ char* element = (char*)"jack";
+
+ it("must pass a positive match", [&]{
+ container must contain(element);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not contain(element); }());
+ });
+ });
+
+ describe("which does not contain the substring", [&]{
+ char* container = (char*)"batman and robin";
+ char* element = (char*)"catwoman";
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain(element); }());
+ });
+
+ it("must pass a negative match", [&]{
+ container must_not contain(element);
+ });
+ });
+ });
+
+ describe("when the container is a const C string", [&]{
+ describe("which contains the substring", [&]{
+ const char* container = (char*)"jack and jill";
+ const char* element = (char*)"jack";
+
+ it("must pass a positive match", [&]{
+ container must contain(element);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ container must_not contain(element); }());
+ });
+ });
+
+ describe("which does not contain the substring", [&]{
+ const char* container = (char*)"batman and robin";
+ const char* element = (char*)"catwoman";
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ container must contain(element); }());
+ });
+
+ it("must pass a negative match", [&]{
+ container must_not contain(element);
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/matchers/equal.cpp b/vendor/bandit/specs/matchers/equal.cpp
new file mode 100644
index 00000000..f7f31b0b
--- /dev/null
+++ b/vendor/bandit/specs/matchers/equal.cpp
@@ -0,0 +1,214 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::Equal)
+
+describe("when the actual value is a built-in type", []{
+ int actualValue = 1;
+
+ describe("and the expected value is the same built-in type", [&]{
+ int expectedValue;
+
+ describe("and the values are equal", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }());
+ });
+ });
+
+ describe("and the values are not equal", [&]{
+ before_each([&]{
+ expectedValue = 147;
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not equal(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }());
+ });
+ });
+ });
+
+ describe("and the expected value is a different, but comparable, built-in type", [&]{
+ long int expectedValue;
+
+ describe("and the values are equal", [&]{
+ before_each([&]{
+ expectedValue = 1;
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }());
+ });
+ });
+
+ describe("and the values are not equal", [&]{
+ before_each([&]{
+ expectedValue = 42;
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not equal(expectedValue);
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }());
+ });
+ });
+ });
+});
+
+describe("when the actual value is declared as a C string", []{
+ char* actualValue = (char*)"actualValue";
+
+ describe("and the expected value is declared as a C string", [&]{
+ std::unique_ptr<char> expectedValue;
+
+ before_each([&]{
+ expectedValue.reset((char*)calloc(strlen(actualValue) + 1, sizeof(char)));
+ });
+
+ describe("and the values are equal", [&]{
+ before_each([&]{
+ stpcpy(expectedValue.get(), actualValue);
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue.get());
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue.get()); }());
+ });
+ });
+
+ describe("and the values are not equal", [&]{
+ before_each([&]{
+ stpcpy(expectedValue.get(), "expectedVal");
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not equal(expectedValue.get());
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue.get()); }());
+ });
+ });
+ });
+
+ describe("and the expected value is declared as a const C string", [&]{
+ const char *expectedValue;
+
+ describe("and the values are equal", [&]{
+ before_each([&]{
+ expectedValue = "actualValue";
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }());
+ });
+ });
+ });
+
+ describe("when the expected value is a unique_ptr to a C string", [&]{
+ std::unique_ptr<char> expectedValue;
+
+ before_each([&]{
+ expectedValue.reset((char*)calloc(strlen(actualValue) + 1, sizeof(char)));
+ });
+
+ describe("and the values are equal", [&]{
+ before_each([&]{
+ stpcpy(expectedValue.get(), actualValue);
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }());
+ });
+ });
+ });
+});
+
+describe("when the actual value is a unique_ptr", []{
+ std::unique_ptr<char> actualValue;
+ auto expectedValue = (char*)"expectedValue";
+
+ before_each([&]{
+ actualValue.reset((char*)calloc(strlen(expectedValue) + 1, sizeof(char)));
+ });
+
+ describe("when the strings are equal", [&]{
+ before_each([&]{
+ stpcpy(actualValue.get(), expectedValue);
+ });
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+ });
+
+ describe("when the strings are not equal", [&]{
+ before_each([&]{
+ stpcpy(actualValue.get(), "hello");
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not equal(expectedValue);
+ });
+ });
+});
+
+describe("when the actual value is declared as char array", []{
+ describe("and the expected value is declared as a C string", []{
+ char actualValue[] = "actualValue";
+
+ describe("and the values are equal", [&]{
+ char* expectedValue = (char*)"actualValue";
+
+ it("must accept a positive match", [&]{
+ actualValue must equal(expectedValue);
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }());
+ });
+ });
+
+ describe("and the values are not equal", [&]{
+ char* expectedValue = (char*)"expectedValue";
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }());
+ });
+
+ it("must accept a negative match", [&]{
+ actualValue must_not equal(expectedValue);
+ });
+ });
+ });
+});
+
+SPEC_END \ No newline at end of file
diff --git a/vendor/bandit/specs/matchers/throw_exception.cpp b/vendor/bandit/specs/matchers/throw_exception.cpp
new file mode 100644
index 00000000..c7531d5f
--- /dev/null
+++ b/vendor/bandit/specs/matchers/throw_exception.cpp
@@ -0,0 +1,104 @@
+#include <specs/specs.h>
+
+using namespace bandit::Matchers;
+
+SPEC_BEGIN(Matchers::ThrowException)
+
+describe("throw_exception", []{
+ describe("when no exception is specified", [&]{
+ std::exception exception;
+
+ std::function<void()> exception_block = [&]{ throw exception; };
+
+ describe("when the block throws an exception", [&]{
+ it("must pass a positive match", [&]{
+ exception_block must throw_exception;
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(MatcherException, [&]{ exception_block must_not throw_exception; }());
+ });
+ });
+
+ describe("when the block does not throw an exception", [&]{
+ std::function<void()> quiet_block = [&]{};
+
+ it("must pass a negative match", [&]{
+ quiet_block must_not throw_exception;
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ quiet_block must throw_exception; }());
+ });
+ });
+ });
+
+ describe("with an exception class specified", [&]{
+ std::logic_error expected_exception("logic_error");
+
+ describe("when the block throws the expected exception", [&]{
+ std::function<void()> exception_block = [&]{ throw expected_exception; };
+
+ it("must pass a positive match", [&]{
+ exception_block must throw_exception.operator()<decltype(expected_exception)>();
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ exception_block must_not throw_exception.operator()<decltype(expected_exception)>(); }());
+ });
+ });
+
+ // TODO: Because C++ lacks reflection, there's no way to implement
+ // subclass-checking. I'm leaving these tests here for when the
+ // language has evolved sufficiently.
+ xdescribe("when the block throws a sublass of the specified exception", [&]{
+ std::function<void()> subclass_block = [&]{ throw std::invalid_argument("invalid argument"); };
+
+ describe("when subclasses are expected", [&]{
+ it("must pass a positive match", [&]{
+ subclass_block must throw_exception.operator()<std::logic_error>().or_subclass();
+ });
+
+ it("must reject a negative match", [&]{
+ AssertThrows(std::exception, [&]{ subclass_block must_not throw_exception.operator()<std::logic_error>().or_subclass(); }());
+ });
+ });
+
+ describe("when subclasses are not expected", [&]{
+ it("must pass a negative match", [&]{
+ subclass_block must_not throw_exception.operator()<std::logic_error>();
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ subclass_block must throw_exception.operator()<std::logic_error>(); }());
+ });
+ });
+ });
+
+ describe("when the block throws an unrelated exception", [&]{
+ std::function<void()> unrelated_block = [&]{ throw std::range_error("range error"); };
+
+ it("must pass a negative match", [&]{
+ unrelated_block must_not throw_exception.operator()<decltype(expected_exception)>();
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ unrelated_block must throw_exception.operator()<decltype(expected_exception)>(); }());
+ });
+ });
+
+ describe("when the block does not throw an exception", [&]{
+ std::function<void()> quiet_block = [&]{};
+
+ it("must pass a negative match", [&]{
+ quiet_block must_not throw_exception.operator()<decltype(expected_exception)>();
+ });
+
+ it("must reject a positive match", [&]{
+ AssertThrows(std::exception, [&]{ quiet_block must throw_exception.operator()<decltype(expected_exception)>(); }());
+ });
+ });
+ });
+});
+
+SPEC_END
diff --git a/vendor/bandit/specs/options.spec.cpp b/vendor/bandit/specs/options.spec.cpp
new file mode 100644
index 00000000..74d057ec
--- /dev/null
+++ b/vendor/bandit/specs/options.spec.cpp
@@ -0,0 +1,121 @@
+#include <specs/specs.h>
+
+using namespace bandit::specs::util;
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("options:", [&](){
+
+ it("parses the '--help' option", [&](){
+ const char* args[] = {"executable", "--help"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+
+ AssertThat(opt.help(), IsTrue());
+ });
+
+ it("parses the '--version' option", [&](){
+ const char* args[] = {"executable", "--version"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+
+ AssertThat(opt.version(), IsTrue());
+ });
+
+ it("parses the '--no-color' option", [&](){
+ const char* args[] = {"executable", "--no-color"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+
+ AssertThat(opt.no_color(), IsTrue());
+ });
+
+ it("parser the '--formatter=vs' option", [&](){
+ const char* args[] = {"executable", "--formatter=vs"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_VS));
+ });
+
+ it("parser the '--formatter=default' option", [&](){
+ const char* args[] = {"executable", "--formatter=default"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_DEFAULT));
+ });
+
+ it("parses the '--skip=\"substring\"' option", [&](){
+ const char* args[] = {"executable", "--skip=substring"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.skip(), Equals("substring"));
+ });
+
+ it("parses skip as empty string if not present", [&](){
+ const char* args[] = {"executable"};
+ argv_helper argv(1, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.skip(), Equals(""));
+ });
+
+ it("parses the '--only=\"substring\"' option", [&](){
+ const char* args[] = {"executable", "--only=substring"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.only(), Equals("substring"));
+ });
+
+ it("parses only as empty string if not present", [&](){
+ const char* args[] = {"executable"};
+ argv_helper argv(1, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+ AssertThat(opt.only(), Equals(""));
+ });
+
+ it("parses the '--break-on-failure' oprtion", [&](){
+ const char* args[] = {"executable", "--break-on-failure"};
+ argv_helper argv(2, args);
+
+ bd::options opt(argv.argc(), argv.argv());
+
+ AssertThat(opt.break_on_failure(), IsTrue());
+ });
+
+ describe("with no arguments", [&](){
+ const char* args[] = {"executable"};
+ argv_helper argv(1, args);
+ bd::options opt(argv.argc(), argv.argv());
+
+ it("cannot find '--help'", [&](){
+ AssertThat(opt.help(), IsFalse());
+ });
+
+ it("cannot find '--version'", [&](){
+ AssertThat(opt.version(), IsFalse());
+ });
+
+ it("cannot find '--no-color'", [&](){
+ AssertThat(opt.no_color(), IsFalse());
+ });
+
+ it("cannot fine '--break-on-failure'", [&](){
+ AssertThat(opt.break_on_failure(), IsFalse())
+ });
+
+ it("uses default formatter for '--formatter'", [&](){
+ AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_DEFAULT));
+ });
+ });
+ });
+
+});
diff --git a/vendor/bandit/specs/reporters/colorizer.spec.cpp b/vendor/bandit/specs/reporters/colorizer.spec.cpp
new file mode 100644
index 00000000..7708ec81
--- /dev/null
+++ b/vendor/bandit/specs/reporters/colorizer.spec.cpp
@@ -0,0 +1,45 @@
+#ifndef _WIN32
+#include <specs/specs.h>
+
+go_bandit([](){
+
+ describe("colorizer: ", [&](){
+
+ describe("colors enabled", [&](){
+ bandit::detail::colorizer colorizer;
+
+ it("can set color to green", [&](){
+ AssertThat(colorizer.green(), Equals("\033[1;32m"));
+ });
+
+ it("set color to red", [&](){
+ AssertThat(colorizer.red(), Equals("\033[1;31m"));
+ });
+ it("resets color", [&](){
+ AssertThat(colorizer.reset(), Equals("\033[0m"));
+ });
+
+ });
+
+ describe("colors disabled", [&](){
+
+ bandit::detail::colorizer colorizer(false);
+
+ it("ignores setting color to green", [&](){
+ AssertThat(colorizer.green(), Equals(""));
+ });
+
+ it("ignores setting color to red", [&](){
+ AssertThat(colorizer.red(), Equals(""));
+ });
+
+ it("ignores resetting colors", [&](){
+ AssertThat(colorizer.reset(), Equals(""));
+ });
+
+ });
+
+ });
+
+});
+#endif \ No newline at end of file
diff --git a/vendor/bandit/specs/reporters/dots_reporter.spec.cpp b/vendor/bandit/specs/reporters/dots_reporter.spec.cpp
new file mode 100644
index 00000000..f06c8d77
--- /dev/null
+++ b/vendor/bandit/specs/reporters/dots_reporter.spec.cpp
@@ -0,0 +1,202 @@
+#include <specs/specs.h>
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("dots_reporter:", [&](){
+ std::unique_ptr<std::stringstream> stm;
+ std::unique_ptr<bd::dots_reporter> reporter;
+ bd::default_failure_formatter formatter;
+ bd::colorizer colorizer(false);
+
+ before_each([&](){
+ stm = std::unique_ptr<std::stringstream>(new std::stringstream());
+ reporter = std::unique_ptr<bd::dots_reporter>(
+ new bd::dots_reporter(*stm, formatter, colorizer));
+ });
+
+ auto output = [&](){ return stm->str(); };
+
+ describe("an empty test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->test_run_complete();
+ });
+
+ it("reports no tests where run", [&](){
+ AssertThat(output(), Equals("\nCould not find any tests.\n"));
+ });
+
+ it("is not considered successful", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+
+ });
+
+ describe("a successful test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a successful test run", [&](){
+ AssertThat(output(), Contains("Success!"));
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded.\n"));
+ });
+
+ it("displays a dot for the successful test", [&](){
+ AssertThat(output(), StartsWith("."));
+ });
+
+ it("reports a successful test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(true));
+ });
+ });
+
+ describe("a failing test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ bd::assertion_exception exception("assertion failed!", "some_file", 123);
+ reporter->it_failed("my test", exception);
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a failing test run in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n"));
+ });
+
+ it("reports the failed assertion", [&](){
+ AssertThat(output(), Contains("my context my test:\nsome_file:123: assertion failed!"));
+ });
+
+ it("only reports assertion failure once", [&](){
+ AssertThat(output(), Has().Exactly(1).EndingWith("assertion failed!"));
+ });
+
+ it("reports an 'F' for the failed assertion", [&](){
+ AssertThat(output(), StartsWith("F"));
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+ });
+
+ describe("a test run with a non assertion_exception thrown", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ reporter->it_unknown_error("my test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports an 'E' for the failed test", [&](){
+ AssertThat(output(), StartsWith("E"));
+ });
+
+ it("reports the failed test", [&](){
+ AssertThat(output(), Contains("my context my test:\nUnknown exception"))
+ });
+
+ });
+
+ describe("a failing test run with nested contexts", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->context_starting("a nested context");
+ reporter->it_starting("my test");
+
+ bd::assertion_exception exception("assertion failed!", "some_file", 123);
+ reporter->it_failed("my test", exception);
+
+ reporter->context_ended("a nested context");
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a failing test run in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n"));
+ });
+
+ it("reports the failed assertion", [&](){
+ AssertThat(output(), Contains("my context a nested context my test:\nsome_file:123: assertion failed!"));
+ });
+
+ it("reports an 'F' for the failed assertion", [&](){
+ AssertThat(output(), StartsWith("F"));
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+
+ });
+
+ describe("a context with test run errors", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+
+ bd::test_run_error error("we dun goofed!");
+ reporter->test_run_error("my context", error);
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports that the context has failed", [&](){
+ AssertThat(output(), Contains("Failed to run \"my context\": error \"we dun goofed!\""));
+ });
+
+ it("reports test run errors in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 0 tests run. 0 succeeded. 1 test run errors.\n"))
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+ });
+
+ describe("a context with a skipped test", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->it_skip("my skipped test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports that there is one skipped test in the summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded. 1 skipped.\n"));
+ });
+
+ });
+ });
+
+
+});
diff --git a/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp b/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp
new file mode 100644
index 00000000..ef7b5206
--- /dev/null
+++ b/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp
@@ -0,0 +1,201 @@
+#include <specs/specs.h>
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("single line reporter", [&](){
+ std::unique_ptr<std::stringstream> stm;
+ std::unique_ptr<bd::single_line_reporter> reporter;
+ bd::default_failure_formatter formatter;
+ bd::colorizer colorizer(false);
+
+ before_each([&](){
+ stm = std::unique_ptr<std::stringstream>(new std::stringstream());
+ reporter = std::unique_ptr<bd::single_line_reporter>(
+ new bd::single_line_reporter(*stm, formatter, colorizer));
+ });
+
+ auto output = [&](){ return stm->str(); };
+
+ describe("an empty test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->test_run_complete();
+ });
+
+ it("reports that no tests were run", [&](){
+ AssertThat(output(), Equals("\nCould not find any tests.\n"));
+ });
+
+ it("is not considered successful", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+ });
+
+ describe("a successful test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a successful test run", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded.\n"));
+ });
+
+ it("displays progress for the test", [&](){
+ AssertThat(output(), StartsWith("\rExecuted 0 tests."
+ "\rExecuted 1 tests."));
+ });
+
+ it("reports a successful test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(true));
+ });
+ });
+
+ describe("a failing test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ bd::assertion_exception exception("assertion failed!", "some_file", 123);
+ reporter->it_failed("my test", exception);
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a failing test run in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n"));
+ });
+
+ it("reports the failed assertion", [&](){
+ AssertThat(output(), Contains("my context my test:\nsome_file:123: assertion failed!"));
+ });
+
+ it("reports failing test in progress", [&](){
+ AssertThat(output(), StartsWith("\rExecuted 0 tests."
+ "\rExecuted 1 tests. 0 succeeded. 1 failed."));
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+ });
+
+ describe("a test run with a non assertion_exception thrown", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ reporter->it_unknown_error("my test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports failing test in progress", [&](){
+ AssertThat(output(), StartsWith("\rExecuted 0 tests."
+ "\rExecuted 1 tests. 0 succeeded. 1 failed."));
+ });
+
+ it("reports the failed test", [&](){
+ AssertThat(output(), Contains("my context my test:\nUnknown exception"))
+ });
+
+ });
+
+ describe("a failing test run with nested contexts", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->context_starting("a nested context");
+ reporter->it_starting("my test");
+
+ bd::assertion_exception exception("assertion failed!", "some_file", 123);
+ reporter->it_failed("my test", exception);
+
+ reporter->context_ended("a nested context");
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports a failing test run in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n"));
+ });
+
+ it("reports the failed assertion", [&](){
+ AssertThat(output(), Contains("my context a nested context my test:\nsome_file:123: assertion failed!"));
+ });
+
+ it("displays a failed test in progress report", [&](){
+ AssertThat(output(), StartsWith("\rExecuted 0 tests."
+ "\rExecuted 1 tests. 0 succeeded. 1 failed."));
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+
+ });
+
+ describe("a context with test run errors", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+
+ bd::test_run_error error("we dun goofed!");
+ reporter->test_run_error("my context", error);
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports that the context has failed", [&](){
+ AssertThat(output(), Contains("Failed to run \"my context\": error \"we dun goofed!\""));
+ });
+
+ it("reports test run errors in summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 0 tests run. 0 succeeded. 1 test run errors.\n"))
+ });
+
+ it("reports a failed test run", [&](){
+ AssertThat(reporter->did_we_pass(), Equals(false));
+ });
+ });
+
+ describe("a context with a skipped test", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->it_skip("my skipped test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("reports that there is one skipped test in the summary", [&](){
+ AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded. 1 skipped.\n"));
+ });
+
+ });
+
+
+ });
+
+});
diff --git a/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp b/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp
new file mode 100644
index 00000000..07f0c3b7
--- /dev/null
+++ b/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp
@@ -0,0 +1,161 @@
+#include <specs/specs.h>
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("xunit_reporter:", [&](){
+ std::unique_ptr<std::stringstream> stm;
+ bd::default_failure_formatter formatter;
+ std::unique_ptr<bd::xunit_reporter> reporter;
+
+ auto output = [&](){ return stm->str(); };
+
+ before_each([&](){
+ stm = std::unique_ptr<std::stringstream>(new std::stringstream());
+ reporter = std::unique_ptr<bd::xunit_reporter>(new bd::xunit_reporter(*stm, formatter));
+ });
+
+ describe("an empty test run", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->test_run_complete();
+ });
+
+ it("adds a header to the output", [&](){
+ AssertThat(output(), StartsWith("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
+ });
+
+ it("outputs an empty test report", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"0\" errors=\"0\" failures=\"0\">\n"
+ "</testsuite>\n"));
+ });
+
+ });
+
+ describe("a test run with one, successful, test", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("outputs info about the successful test", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"0\">\n"
+ "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n"
+ "\t</testcase>\n"
+ "</testsuite>\n"));
+ });
+ });
+
+ describe("a test run with one, failing test", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ bd::assertion_exception exception("assertion failed!", "some_file", 123);
+ reporter->it_failed("my test", exception);
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+
+ });
+
+ it("outputs the failing test", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n"
+ "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n"
+ "\t\t<failure message=\"some_file:123: assertion failed!\" />\n"
+ "\t</testcase>\n"
+ "</testsuite>\n"));
+ });
+
+ });
+
+ describe("a test run with one test with an unknown error", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+ reporter->it_starting("my test");
+
+ reporter->it_unknown_error("my test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("outputs the erroneous test", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n"
+ "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n"
+ "\t\t<failure message=\"Unknown exception\" />\n"
+ "\t</testcase>\n"
+ "</testsuite>\n"));
+ });
+
+ });
+
+ describe("a test run with one test failing with characters that need escaping", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context & < > \\ \"");
+ reporter->it_starting("my test & < > \\ \"");
+
+ bd::assertion_exception exception("assertion failed & < > \\ \"", "some_file", 123);
+ reporter->it_failed("my test & < > \\ \"", exception);
+
+ reporter->context_ended("my context & < > \\ \"");
+ reporter->test_run_complete();
+ });
+
+ it("outputs the escaped characters", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n"
+ "\t<testcase classname=\"my context &amp; &lt; &gt; &apos; &quot;\" name=\"my test &amp; &lt; &gt; &apos; &quot;\" time=\"0\">\n"
+ "\t\t<failure message=\"some_file:123: assertion failed &amp; &lt; &gt; &apos; &quot;\" />\n"
+ "\t</testcase>\n"
+ "</testsuite>\n"));
+ });
+
+ });
+
+ describe("a context with a skipped test", [&](){
+
+ before_each([&](){
+ reporter->test_run_starting();
+ reporter->context_starting("my context");
+
+ reporter->it_starting("my test");
+ reporter->it_succeeded("my test");
+ reporter->it_skip("my skipped test");
+
+ reporter->context_ended("my context");
+ reporter->test_run_complete();
+ });
+
+ it("outputs info about the skipped test", [&](){
+ AssertThat(output(), Contains(
+ "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"0\" skipped=\"1\">\n"
+ "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n"
+ "\t</testcase>\n"
+ "\t<testcase classname=\"my context\" name=\"my skipped test\" time=\"0\">\n"
+ "\t\t<skipped />\n"
+ "\t</testcase>\n"
+ "</testsuite>\n"));
+ });
+
+ });
+
+ });
+
+});
diff --git a/vendor/bandit/specs/run.spec.cpp b/vendor/bandit/specs/run.spec.cpp
new file mode 100644
index 00000000..6e59bac7
--- /dev/null
+++ b/vendor/bandit/specs/run.spec.cpp
@@ -0,0 +1,77 @@
+#include <specs/specs.h>
+using namespace bandit::fakes;
+using namespace bandit::specs::util;
+namespace bd = bandit::detail;
+
+go_bandit([](){
+
+ describe("run:", [&](){
+ std::unique_ptr<bd::spec_registry> specs;
+ std::unique_ptr<argv_helper> argv;
+ fake_reporter_ptr reporter;
+ std::unique_ptr<bd::contextstack_t> context_stack;
+
+ auto call_run = [&]() -> int {
+ bd::options opt(argv->argc(), argv->argv());
+ return bandit::run(opt, *specs, *context_stack, *reporter);
+ };
+
+ before_each([&](){
+ specs = std::unique_ptr<bd::spec_registry>(new bd::spec_registry());
+
+ reporter = fake_reporter_ptr(new fake_reporter());
+
+ context_stack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t());
+
+ const char* args[] = {"executable"};
+ argv = std::unique_ptr<argv_helper>(new argv_helper(1, args));
+ });
+
+ it("pushes the global context on the context stack", [&](){
+ call_run();
+ AssertThat(*context_stack, Is().OfLength(1));
+ });
+
+ describe("a successful test run", [&](){
+ int number_of_specs_called;
+
+ before_each([&](){
+ number_of_specs_called = 0;
+ specs->push_back([&](){ number_of_specs_called++; });
+ });
+
+ it("calls the context", [&](){
+ call_run();
+ AssertThat(number_of_specs_called, Equals(1));
+ });
+
+ it("tells reporter a test run is about to start", [&](){
+ call_run();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_starting"));
+ });
+
+ it("tells reporter a test run has completed", [&](){
+ call_run();
+ AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_complete"));
+ });
+
+ it("returns 0 as no specs failed", [&](){
+ AssertThat(call_run(), Equals(0));
+ });
+ });
+
+
+ describe("a failing test run", [&](){
+
+ before_each([&](){
+ reporter->set_test_run_status(false);
+ });
+
+ it("returns a non-zero error code", [&](){
+ AssertThat(call_run(), IsGreaterThan(0));
+ });
+
+ });
+ });
+
+});
diff --git a/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp b/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp
new file mode 100644
index 00000000..75f56bc6
--- /dev/null
+++ b/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp
@@ -0,0 +1,250 @@
+#include <specs/specs.h>
+
+go_bandit([](){
+ namespace bd = bandit::detail;
+
+ describe("bandit run policy", [&](){
+ std::unique_ptr<bd::contextstack_t> contextstack;
+ std::unique_ptr<bd::context> global_context;
+ std::string only_pattern;
+ std::string skip_pattern;
+ bool break_on_failure;
+
+ auto create_policy = [&]() -> bd::bandit_run_policy {
+ return bd::bandit_run_policy(skip_pattern.c_str(), only_pattern.c_str(), break_on_failure);
+ };
+
+ before_each([&](){
+ contextstack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t());
+ bool hard_skip = false;
+ global_context = std::unique_ptr<bd::context>(new bd::bandit_context("", hard_skip));
+ contextstack->push_back(global_context.get());
+ break_on_failure = false;
+ });
+
+ describe("neither skip nor only specified", [&](){
+ before_each([&](){
+ only_pattern = "";
+ skip_pattern = "";
+ });
+
+ it("always says run", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ describe("with 'break-on-failure' set", [&](){
+
+ before_each([&](){
+ break_on_failure = true;
+ });
+
+ it("says run if no failure has been encountered", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ it("says don't run if a failure has been encountered", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ policy.encountered_failure();
+ AssertThat(policy.should_run("it name", *contextstack), IsFalse());
+ });
+
+ });
+
+ describe("has context marked with 'hard_skip' in stack", [&](){
+ std::unique_ptr<bd::context> hard_skip_context;
+
+ before_each([&](){
+ bool hard_skip = true;
+ hard_skip_context = std::unique_ptr<bd::context>(new bd::bandit_context("always ignore", hard_skip));
+ contextstack->push_back(hard_skip_context.get());
+ });
+
+ it("never runs", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsFalse());
+ AssertThat(policy.should_run("it name matches 'skip'", *contextstack), IsFalse());
+ AssertThat(policy.should_run("it name matches 'only'", *contextstack), IsFalse());
+ });
+
+ });
+
+ });
+
+ describe("'skip' specified, 'only' unspecified", [&](){
+
+ before_each([&](){
+ only_pattern = "";
+ skip_pattern = "skip";
+ });
+
+ describe("current context matches 'skip'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("never runs", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsFalse());
+ });
+
+ });
+
+ describe("current context doesn't match 'skip'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context doesn't match", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("runs if spec's name doesn't match", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ it("doesn't run if spec's name matches", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse());
+ });
+
+ });
+
+ });
+
+ describe("'only' specified, 'skip' unspecified", [&](){
+
+ before_each([&](){
+ only_pattern = "only";
+ skip_pattern = "";
+ });
+
+ describe("current context matches 'only'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("always runs", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ });
+
+ describe("current context doesn't match 'only'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context doesn't match", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("doesn't run if spec's name doesn't match", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsFalse());
+ });
+
+ it("runs if spec's name matches", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name matching 'only'", *contextstack), IsTrue());
+ });
+
+ });
+
+ });
+
+ describe("'skip' specified, 'only' specified", [&](){
+
+ before_each([&](){
+ only_pattern = "only";
+ skip_pattern = "skip";
+ });
+
+ describe("current context matches 'skip'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("doesn't run if 'it' doesn't match 'only'", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsFalse());
+ });
+
+ it("runs if 'it' matches 'only'", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it matches 'only'", *contextstack), IsTrue());
+ });
+
+ });
+
+ describe("current context 'only'", [&](){
+ std::unique_ptr<bd::context> current_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip));
+ contextstack->push_back(current_context.get());
+ });
+
+ it("runs if spec's name doesn't match anything", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ it("doesn't run if spec's name matches 'skip'", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse());
+ });
+
+ });
+
+ describe("has both 'only' and 'skip' in context stack", [&](){
+ std::unique_ptr<bd::context> current_context;
+ std::unique_ptr<bd::context> parent_context;
+
+ before_each([&](){
+ bool hard_skip = false;
+ current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip));
+ parent_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip));
+ contextstack->push_back(parent_context.get());
+ contextstack->push_back(current_context.get());
+ });
+
+ it("runs if spec's name doesn't match anything", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name", *contextstack), IsTrue());
+ });
+
+ it("doesn't run if spec's name matches 'skip'", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse());
+ });
+ it("runs if spec's name matches 'only'", [&](){
+ bd::bandit_run_policy policy = create_policy();
+ AssertThat(policy.should_run("it name matching 'only'", *contextstack), IsTrue());
+ });
+
+ });
+
+ });
+
+
+ });
+
+});
+
diff --git a/vendor/bandit/specs/specs.h b/vendor/bandit/specs/specs.h
new file mode 100644
index 00000000..219e89ee
--- /dev/null
+++ b/vendor/bandit/specs/specs.h
@@ -0,0 +1,10 @@
+#ifndef BANDIT_SPECS
+#define BANDIT_SPECS
+
+#include <bandit/bandit.h>
+using namespace bandit;
+
+#include <specs/fakes/fakes.h>
+#include <specs/util/util.h>
+
+#endif
diff --git a/vendor/bandit/specs/synopsis.spec.cpp b/vendor/bandit/specs/synopsis.spec.cpp
new file mode 100644
index 00000000..3b717f75
--- /dev/null
+++ b/vendor/bandit/specs/synopsis.spec.cpp
@@ -0,0 +1,54 @@
+#include <specs/specs.h>
+
+go_bandit([](){
+ describe("my first spec", [&]() {
+ int a;
+
+ before_each([&](){
+ a = 99;
+ });
+
+ it("should be initialized", [&](){
+ AssertThat(a, Equals(99));
+ a = 102;
+ });
+
+ describe("nested spec", [&](){
+
+ before_each([&](){
+ a += 3;
+ });
+
+ it("should build on outer spec", [&](){
+ AssertThat(a, Equals(102));
+ a = 666;
+ });
+
+ it("should build on outer spec yet again", [&](){
+ AssertThat(a, Equals(102));
+ a = 667;
+ });
+
+ });
+
+ it("should be initialized before each it", [&](){
+ AssertThat(a, Equals(99));
+ });
+ });
+
+ describe("my second spec", [&](){
+ int b;
+
+ before_each([&](){
+ b = 22;
+ });
+
+ before_each([&](){
+ b += 3;
+ });
+
+ it("should be 25", [&](){
+ AssertThat(b, Equals(25));
+ });
+ });
+});
diff --git a/vendor/bandit/specs/util/argv_helper.h b/vendor/bandit/specs/util/argv_helper.h
new file mode 100644
index 00000000..dac26765
--- /dev/null
+++ b/vendor/bandit/specs/util/argv_helper.h
@@ -0,0 +1,62 @@
+#ifndef BANDIT_SPECS_ARGV_HELPER_H
+#define BANDIT_SPECS_ARGV_HELPER_H
+
+#include <string.h>
+
+namespace bandit { namespace specs { namespace util {
+
+ //
+ // main() is supposed to receive its arguments as a non const 'char* argv[]'.
+ // This is a pain to create for each test. It's a whole lot easier to create
+ // a 'const char* argv[]' construct.
+ //
+ // This class helps copy from 'const char**' to 'char**' and handle cleanup
+ // automatically.
+ //
+ struct argv_helper
+ {
+ argv_helper(int argc_a, const char* argv_a[])
+ : argc_(argc_a)
+ {
+ non_const_argv_ = new char*[argc_];
+ for(int i=0; i < argc_; i++)
+ {
+ std::string s(argv_a[i]);
+ non_const_argv_[i] = new char[s.size() + 1];
+ for(size_t c=0;c<s.size();c++)
+ {
+ non_const_argv_[i][c] = s[c];
+ }
+ non_const_argv_[i][s.size()] = 0;
+ }
+ }
+
+
+
+ ~argv_helper()
+ {
+ for(int i=0; i < argc_; i++)
+ {
+ delete[] non_const_argv_[i];
+ }
+
+ delete[] non_const_argv_;
+ }
+
+ char** argv()
+ {
+ return non_const_argv_;
+ }
+
+ int argc()
+ {
+ return argc_;
+ }
+
+ private:
+ int argc_;
+ char** non_const_argv_;
+ };
+
+}}}
+#endif
diff --git a/vendor/bandit/specs/util/util.h b/vendor/bandit/specs/util/util.h
new file mode 100644
index 00000000..7ed17dd8
--- /dev/null
+++ b/vendor/bandit/specs/util/util.h
@@ -0,0 +1,6 @@
+#ifndef BANDIT_SPECS_UTIL_H
+#define BANDIT_SPECS_UTIL_H
+
+#include "argv_helper.h"
+
+#endif