diff options
Diffstat (limited to 'src')
567 files changed, 75993 insertions, 146641 deletions
diff --git a/src/.cvsignore b/src/.cvsignore deleted file mode 100644 index d99b4ed2..00000000 --- a/src/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.sconsign -.gdb_history -makefile -tome -tolua -w_*.c -TOME.EXE -TOLUA.EXE diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..485f14c6 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,7 @@ +/harness +/tome-gcu +/tome-gtk2 +/tome-sdl +/tome-x11 +/tome-win +*.plist diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 932fef4b..30ceb76c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,31 +1,140 @@ -# Lua support code. -ADD_SUBDIRECTORY(lua) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/bandit) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/fmt) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/pcg-cpp/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../vendor/jsoncons) + +# Add subdirectories +ADD_SUBDIRECTORY (squelch) -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 modules.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 - status.c files.c notes.c loadsave.c - cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c - help.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 - # Lua bits: - lua_bind.c script.c w_mnster.c w_player.c w_play_c.c w_z_pack.c - w_obj.c w_util.c w_spells.c w_quest.c w_dun.c +# 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 + game.cc + gen_evol.cc + gen_maze.cc + generate.cc + gods.cc + help.cc + hiscore.cc + hooks.cc + init1.cc + init2.cc + joke.cc + level_marker.cc + levels.cc + loadsave.cc + lua_bind.cc + melee1.cc + melee2.cc + message.cc + messages.cc + mimic.cc + modules.cc + monster_spell.cc + monster_type.cc + monster1.cc + monster2.cc + monster3.cc + notes.cc + object1.cc + object2.cc + object_filter.cc + object_flag_meta.cc + options.cc + player_type.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 + quest.cc + randart.cc + range.cc + skills.cc + spell_type.cc + spells1.cc + spells2.cc + spells3.cc + spells4.cc + spells5.cc + spells6.cc + squeltch.cc + store.cc + tables.cc + util.cc + variable.cc + wild.cc + wizard2.cc + seed.cc + xtra1.cc + xtra2.cc + z-form.c + z-rand.cc + z-term.c + z-util.c ) +# Sources (TEST) +SET(SRCS_TESTS + ../tests/get_level_device.cc + ../tests/harness.cc + ../tests/lua_get_level.cc + ../tests/flag_set.cc + ../tests/grid.cc +) + +ADD_LIBRARY(game + ${SRCS_COMMON} ${SRCS_VENDOR} +) + +ADD_LIBRARY(game_main + main.cc) + # Need a few additional source files for Windows. -if(WIN32) - SET(SRCS ${SRCS} main-win.c readdib.c) +IF(WIN32) + SET(SRCS ${SRCS} main-win.c) # Resource files require a little workaround. - if(MINGW) + IF(MINGW) # Workaround for resource compilation for mingw on CMake. # See http://www.cmake.org/Bug/view.php?id=4068 ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/angband_rc.o @@ -33,40 +142,44 @@ if(WIN32) -i${CMAKE_CURRENT_SOURCE_DIR}/angband.rc -o ${CMAKE_CURRENT_BINARY_DIR}/angband_rc.o) SET(SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/angband_rc.o) - else(MINGW) + ELSE(MINGW) SET(SRCS ${SRCS} angband.rc) - endif(MINGW) -endif(WIN32) + ENDIF(MINGW) + # Executable for Win32 + ADD_EXECUTABLE(tome-win WIN32 main-win.c) + TARGET_LINK_LIBRARIES(tome-win game squelch ${LIBS} winmm wsock32) + INSTALL(TARGETS tome-win RUNTIME DESTINATION bin) +ENDIF(WIN32) +# tome executables +IF(X11_FOUND) + INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR}) + ADD_EXECUTABLE(tome-x11 main-x11.c) + TARGET_LINK_LIBRARIES(tome-x11 game_main game squelch ${LIBS} ${X11_LIBRARIES}) + INSTALL(TARGETS tome-x11 RUNTIME DESTINATION bin) +ENDIF() -# Macro for defining tolua targets. -MACRO(TOLUA_FILE MODULE_NAME OUTPUT_FILE_NAME) - ADD_CUSTOM_COMMAND( - OUTPUT ${OUTPUT_FILE_NAME} - COMMAND tolua -n ${MODULE_NAME} -o ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILE_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_NAME}.pkg - DEPENDS tolua ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_NAME}.pkg - ) - SET_SOURCE_FILES_PROPERTIES("${OUTPUT_FILE_NAME}" PROPERTIES GENERATED TRUE) -ENDMACRO(TOLUA_FILE) +IF(SDL_FOUND AND SDLIMAGE_FOUND AND SDLTTF_FOUND) + INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR} ${SDLTTF_INCLUDE_DIR}) + ADD_EXECUTABLE(tome-sdl main-sdl.c) + TARGET_LINK_LIBRARIES(tome-sdl game_main game squelch ${LIBS} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ${SDL_LIBRARY} m) + INSTALL(TARGETS tome-sdl RUNTIME DESTINATION bin) +ENDIF() -# Process all the needed modules. -TOLUA_FILE(monster w_mnster.c) -TOLUA_FILE(player w_player.c) -TOLUA_FILE(player_c w_play_c.c) -TOLUA_FILE(z_pack w_z_pack.c) -TOLUA_FILE(object w_obj.c) -TOLUA_FILE(util w_util.c) -TOLUA_FILE(spells w_spells.c) -TOLUA_FILE(quest w_quest.c) -TOLUA_FILE(dungeon w_dun.c) +IF(CURSES_FOUND) + INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIR}) + ADD_EXECUTABLE(tome-gcu main-gcu.c) + TARGET_LINK_LIBRARIES(tome-gcu game_main game squelch ${LIBS} ${CURSES_LIBRARIES}) + INSTALL(TARGETS tome-gcu RUNTIME DESTINATION bin) +ENDIF() -# tome executable -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lua) -ADD_EXECUTABLE(tome ${EXECUTABLE_OPTIONS} ${SRCS}) -TARGET_LINK_LIBRARIES(tome lua ${LIBS}) +IF(GTK2_FOUND) + INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS}) + ADD_EXECUTABLE(tome-gtk2 main-gtk2.c) + TARGET_LINK_LIBRARIES(tome-gtk2 game_main game squelch ${LIBS} ${GTK2_LIBRARIES}) + INSTALL(TARGETS tome-gtk2 RUNTIME DESTINATION bin) +ENDIF() -# Installation -INSTALL(TARGETS tome - RUNTIME DESTINATION games -) +# test harness executable +ADD_EXECUTABLE(harness ${SRCS_TESTS}) +TARGET_LINK_LIBRARIES(harness game squelch ${LIBS}) diff --git a/src/ability_type.hpp b/src/ability_type.hpp new file mode 100644 index 00000000..0ec596ba --- /dev/null +++ b/src/ability_type.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include <string> +#include <vector> + +#include "h-basic.h" + +/** + * Abilities. + */ +struct ability_type +{ +public: + struct skill_requirement { + s16b skill_idx = 0; + s16b level = 0; + }; + +public: + std::string name; /* Name */ + std::string desc; /* Description */ + + std::string action_desc; /* Action Description */ + + s16b action_mkey = 0; /* Action do to */ + + s16b cost = 0; /* Skill points cost */ + + std::vector<skill_requirement> need_skills; /* List of prereq skills */ + + s16b stat[6] { }; /* List of prereq stats */ + + std::vector<s16b> need_abilities; /* List of prereq abilities */ + + /** + * Default constructor + */ + ability_type() + { + for (auto &stat_ref: stat) + { + // Requirement is always met unless otherwise specified. + stat_ref = -1; + } + } + +}; 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/alloc.hpp b/src/alloc.hpp new file mode 100644 index 00000000..1d4ce815 --- /dev/null +++ b/src/alloc.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "h-basic.h" +#include "alloc_entry.hpp" + +#include <vector> + +/** + * Allocations of object kinds and monster races. + */ +struct Alloc { + + /* + * The entries in the "kind allocator table" + */ + std::vector<alloc_entry> kind_table; + + /* + * The flag to tell if kind_table contains valid entries + * for normal (i.e. kind_is_legal) object allocation + */ + bool kind_table_valid = false; + + /* + * The entries in the "race allocator table" + */ + std::vector<alloc_entry> race_table; + +}; diff --git a/src/alloc_entry.hpp b/src/alloc_entry.hpp new file mode 100644 index 00000000..5e0e547f --- /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 = -1; /* The actual index */ + + byte level = 0; /* Base dungeon level */ + byte prob1 = 0; /* Probability, pass 1 */ + byte prob2 = 0; /* Probability, pass 2 */ + byte prob3 = 0; /* 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 cac38122..5fbc94e5 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,9 +26,7 @@ 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,12 +37,9 @@ extern "C" { /* - * 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 "externs.h" -#include "plots.h" /***** Some copyright messages follow below *****/ @@ -103,8 +92,3 @@ extern "C" { #ifdef __cplusplus } /* extern "C" */ #endif - -#endif - - - diff --git a/src/angband.rc b/src/angband.rc index 00e16516..37856f4a 100644 --- a/src/angband.rc +++ b/src/angband.rc @@ -1,10 +1,5 @@ /* File: angband.rc */ -/* - * If the windows command to compile this file understands #ifdef's, please - * say #ifdef ALLOW_QUITTING to select from "A&bort" and "Sh&ow scores" - */ - ANGBAND MENU { POPUP "&File" @@ -12,7 +7,6 @@ ANGBAND MENU MENUITEM "&Save", 110 MENUITEM SEPARATOR MENUITEM "S&how score", 120 - /*MENUITEM "A&bort", 120*/ MENUITEM "E&xit", 121 } @@ -107,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_type.hpp b/src/artifact_type.hpp new file mode 100644 index 00000000..9f866aa7 --- /dev/null +++ b/src/artifact_type.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "h-basic.h" +#include "object_flag_set.hpp" + +/** + * 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 = nullptr; /* Artifact name */ + char *text = nullptr; /* Artifact description */ + + byte tval = 0; /* Artifact type */ + byte sval = 0; /* Artifact sub type */ + + s16b pval = 0; /* Artifact extra info */ + + s16b to_h = 0; /* Bonus to hit */ + s16b to_d = 0; /* Bonus to damage */ + s16b to_a = 0; /* Bonus to armor */ + + s16b activate = 0; /* Activation Number */ + + s16b ac = 0; /* Base armor */ + + byte dd = 0; /* Damage dice */ + byte ds = 0; /* Damage sides */ + + s16b weight = 0; /* Weight */ + + s32b cost = 0; /* Artifact "cost" */ + + object_flag_set flags; /* Artifact Flags */ + object_flag_set oflags; /* Obvious Flags */ + + byte level = 0; /* Artifact level */ + byte rarity = 0; /* Artifact rarity */ + + byte cur_num = 0; /* Number created (0 or 1) */ + + s16b power = 0; /* Power granted, if any */ + + s16b set = 0; /* Which set does it belong it, if any? */ + +}; 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 f073b2f6..f677e6e1 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,8 +5,62 @@ * not for profit purposes provided that this copyright and statement are * included in all such copies. */ - -#include "angband.h" +#include "birth.hpp" + +#include "ability_type.hpp" +#include "artifact_type.hpp" +#include "corrupt.hpp" +#include "cmd4.hpp" +#include "cmd5.hpp" +#include "dungeon_flag.hpp" +#include "dungeon_info_type.hpp" +#include "files.h" +#include "files.hpp" +#include "game.hpp" +#include "gods.hpp" +#include "help.hpp" +#include "hooks.hpp" +#include "init2.hpp" +#include "mimic.hpp" +#include "messages.hpp" +#include "modules.hpp" +#include "monster2.hpp" +#include "monster_race.hpp" +#include "monster_race_flag.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_flag.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 "util.hpp" +#include "util.h" +#include "variable.h" +#include "variable.hpp" +#include "wilderness_map.hpp" +#include "xtra1.hpp" +#include "xtra2.hpp" +#include "z-rand.hpp" + +#include <algorithm> +#include <boost/filesystem.hpp> +#include <fmt/format.h> +#include <numeric> +#include <string> /* * How often the autoroller will update the display and pause @@ -54,73 +104,48 @@ static s32b auto_round; */ static s32b last_round; -/* Human */ -static 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", - "Er", "El", "Eow", "F", "Fr", "G", "Gr", "Gw", "Gal", "Gl", "H", "Ha", - "Ib", "Jer", "K", "Ka", "Ked", "L", "Loth", "Lar", "Leg", "M", "Mir", - "N", "Nyd", "Ol", "Oc", "On", "P", "Pr", "R", "Rh", "S", "Sev", "T", - "Tr", "Th", "V", "Y", "Z", "W", "Wic", -}; - -static char *human_syllable2[] = -{ - "a", "ae", "au", "ao", "are", "ale", "ali", "ay", "ardo", "e", "ei", - "ea", "eri", "era", "ela", "eli", "enda", "erra", "i", "ia", "ie", - "ire", "ira", "ila", "ili", "ira", "igo", "o", "oa", "oi", "oe", - "ore", "u", "y", -}; - -static char *human_syllable3[] = -{ - "a", "and", "b", "bwyn", "baen", "bard", "c", "ctred", "cred", "ch", - "can", "d", "dan", "don", "der", "dric", "dfrid", "dus", "f", "g", - "gord", "gan", "l", "li", "lgrin", "lin", "lith", "lath", "loth", - "ld", "ldric", "ldan", "m", "mas", "mos", "mar", "mond", "n", - "nydd", "nidd", "nnon", "nwan", "nyth", "nad", "nn", "nnor", "nd", - "p", "r", "ron", "rd", "s", "sh", "seth", "sean", "t", "th", "tha", - "tlan", "trem", "tram", "v", "vudd", "w", "wan", "win", "wyn", "wyr", - "wyr", "wyth", -}; - /* * Random Name Generator * based on a Javascript by Michael Hensley * "http://geocities.com/timessquare/castle/6274/" */ -static void create_random_name(int race, char *name) +static std::string create_random_name() { - char *syl1, *syl2, *syl3; - - int idx; - - - /* Paranoia */ - if (!name) return; - - /* Select the monster type */ - switch (race) - { - /* Create the monster name */ - - /* Use human ones */ - default: - { - idx = rand_int(sizeof(human_syllable1) / sizeof(char *)); - syl1 = human_syllable1[idx]; - idx = rand_int(sizeof(human_syllable2) / sizeof(char *)); - syl2 = human_syllable2[idx]; - idx = rand_int(sizeof(human_syllable3) / sizeof(char *)); - syl3 = human_syllable3[idx]; - - break; - } - } - - /* Concatenate selected syllables */ - strnfmt(name, 32, "%s%s%s", syl1, syl2, syl3); + static const std::vector<std::string> 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", + "Er", "El", "Eow", "F", "Fr", "G", "Gr", "Gw", "Gal", "Gl", "H", "Ha", + "Ib", "Jer", "K", "Ka", "Ked", "L", "Loth", "Lar", "Leg", "M", "Mir", + "N", "Nyd", "Ol", "Oc", "On", "P", "Pr", "R", "Rh", "S", "Sev", "T", + "Tr", "Th", "V", "Y", "Z", "W", "Wic", + }; + + static const std::vector<std::string> human_syllable2 + { + "a", "ae", "au", "ao", "are", "ale", "ali", "ay", "ardo", "e", "ei", + "ea", "eri", "era", "ela", "eli", "enda", "erra", "i", "ia", "ie", + "ire", "ira", "ila", "ili", "ira", "igo", "o", "oa", "oi", "oe", + "ore", "u", "y", + }; + + static const std::vector<std::string> human_syllable3 + { + "a", "and", "b", "bwyn", "baen", "bard", "c", "ctred", "cred", "ch", + "can", "d", "dan", "don", "der", "dric", "dfrid", "dus", "f", "g", + "gord", "gan", "l", "li", "lgrin", "lin", "lith", "lath", "loth", + "ld", "ldric", "ldan", "m", "mas", "mos", "mar", "mond", "n", + "nydd", "nidd", "nnon", "nwan", "nyth", "nad", "nn", "nnor", "nd", + "p", "r", "ron", "rd", "s", "sh", "seth", "sean", "t", "th", "tha", + "tlan", "trem", "tram", "v", "vudd", "w", "wan", "win", "wyn", "wyr", + "wyr", "wyth", + }; + + auto const &syl1 = *uniform_element(human_syllable1); + auto const &syl2 = *uniform_element(human_syllable2); + auto const &syl3 = *uniform_element(human_syllable3); + + return syl1 + syl2 + syl3; } @@ -151,15 +176,13 @@ void print_desc(cptr txt) /* * Save the current data for later */ -static void save_prev_data(void) +static void save_prev_data() { - int i; - + auto &previous_char = game->previous_char; /*** Save the current data ***/ /* Save the data */ - previous_char.sex = p_ptr->psex; previous_char.race = p_ptr->prace; previous_char.rmod = p_ptr->pracem; previous_char.pclass = p_ptr->pclass; @@ -170,30 +193,14 @@ static void save_prev_data(void) previous_char.god = p_ptr->pgod; previous_char.grace = p_ptr->grace; - previous_char.age = p_ptr->age; - previous_char.wt = p_ptr->wt; - previous_char.ht = p_ptr->ht; - previous_char.sc = p_ptr->sc; previous_char.au = p_ptr->au; /* Save the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { previous_char.stat[i] = p_ptr->stat_max[i]; } previous_char.luck = p_ptr->luck_base; - - /* Save the chaos patron */ - previous_char.chaos_patron = p_ptr->chaos_patron; - - /* Save the weapon specialty */ - previous_char.weapon = 0; - - /* Save the history */ - for (i = 0; i < 4; i++) - { - strcpy(previous_char.history[i], history[i]); - } } @@ -202,51 +209,29 @@ static void save_prev_data(void) */ static void load_prev_data(bool_ save) { - int i; - + auto &previous_char = game->previous_char; birther temp; /*** Save the current data ***/ /* Save the data */ - temp.age = p_ptr->age; - temp.wt = p_ptr->wt; - temp.ht = p_ptr->ht; - temp.sc = p_ptr->sc; temp.au = p_ptr->au; /* Save the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { temp.stat[i] = p_ptr->stat_max[i]; } temp.luck = p_ptr->luck_base; - /* Save the chaos patron */ - temp.chaos_patron = p_ptr->chaos_patron; - - /* Save the weapon specialty */ - temp.weapon = 0; - - /* Save the history */ - for (i = 0; i < 4; i++) - { - strcpy(temp.history[i], history[i]); - } - - /*** Load the previous data ***/ /* Load the data */ - p_ptr->age = previous_char.age; - p_ptr->wt = previous_char.wt; - p_ptr->ht = previous_char.ht; - p_ptr->sc = previous_char.sc; p_ptr->au = previous_char.au; /* Load the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { p_ptr->stat_max[i] = previous_char.stat[i]; p_ptr->stat_cur[i] = previous_char.stat[i]; @@ -254,44 +239,19 @@ static void load_prev_data(bool_ save) p_ptr->luck_base = previous_char.luck; p_ptr->luck_max = previous_char.luck; - /* Load the chaos patron */ - p_ptr->chaos_patron = previous_char.chaos_patron; - - /* Load the history */ - for (i = 0; i < 4; i++) - { - strcpy(history[i], previous_char.history[i]); - } - /*** Save the current data ***/ if (!save) return; /* Save the data */ - previous_char.age = temp.age; - previous_char.wt = temp.wt; - previous_char.ht = temp.ht; - previous_char.sc = temp.sc; previous_char.au = temp.au; /* Save the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { previous_char.stat[i] = temp.stat[i]; } 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++) - { - strcpy(previous_char.history[i], temp.history[i]); - } } @@ -341,22 +301,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++; - } } } @@ -372,7 +320,7 @@ static int adjust_stat(int value, int amount, int auto_roll) * * For efficiency, we include a chunk of "calc_bonuses()". */ -static void get_stats(void) +static void get_stats() { int i, j; @@ -423,27 +371,13 @@ static void get_stats(void) p_ptr->stat_max[i] = j; /* Obtain a "bonus" for "race" and "class" */ - bonus = rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]; + bonus = rp_ptr->ps.adj[i] + rmp_ptr->ps.adj[i] + cp_ptr->ps.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; @@ -457,308 +391,121 @@ static void get_stats(void) /* - * Roll for some info that the auto-roller ignores + * Roll for player HP */ -static void get_extra(void) +void roll_player_hp() { - int i, j, min_value, max_value; - -#ifdef SHOW_LIFE_RATE - - int percent; - -#endif - - - /* Level one */ - p_ptr->max_plv = p_ptr->lev = 1; - - /* 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; - 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; - - /* Initial hitpoints */ - p_ptr->mhp = p_ptr->hitdie; + auto &player_hp = game->player_hp; - /* Minimum hitpoints at highest level */ - min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8; - min_value += PY_MAX_LEVEL; + // Minimum hitpoints at highest level + int const min_value = + (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8 + PY_MAX_LEVEL; - /* Maximum hitpoints at highest level */ - max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8; - max_value += PY_MAX_LEVEL; + // Maximum hitpoints at highest level + int const max_value = + (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8 + PY_MAX_LEVEL; - /* Pre-calculate level 1 hitdice */ + // Pre-calculate level 1 hitdice; first roll is always maximal player_hp[0] = p_ptr->hitdie; - /* Roll out the hitpoints */ - while (TRUE) + // Roll out the hitpoints + while (true) { - /* Roll the hitpoint values */ - for (i = 1; i < PY_MAX_LEVEL; i++) - { - j = randint(p_ptr->hitdie); - player_hp[i] = player_hp[i - 1] + j; - } + // Roll the hitpoint values + std::generate( + player_hp.begin() + 1, + player_hp.end(), + []() { return randint(p_ptr->hitdie); }); - /* XXX Could also require acceptable "mid-level" hitpoints */ + // Sum along + std::partial_sum( + player_hp.begin(), + player_hp.end(), + player_hp.begin()); - /* Require "valid" hitpoints at highest level */ - if (player_hp[PY_MAX_LEVEL - 1] < min_value) continue; - if (player_hp[PY_MAX_LEVEL - 1] > max_value) continue; + // Require "valid" hitpoints at highest level + if (player_hp.back() < min_value) continue; + if (player_hp.back() > max_value) continue; - /* Acceptable */ + // Acceptable break; } - - p_ptr->tactic = 4; - p_ptr->movement = 4; - -#ifdef SHOW_LIFE_RATE - - percent = (int)(((long)player_hp[PY_MAX_LEVEL - 1] * 200L) / - (p_ptr->hitdie + ((PY_MAX_LEVEL - 1) * p_ptr->hitdie))); - - msg_format("Current Life Rating is %d/100.", percent); - msg_print(NULL); - -#endif /* SHOW_LIFE_RATE */ } /* - * Get the racial history, and social class, using the "history charts". + * Roll for some info that the auto-roller ignores */ -static void get_history(void) +static void get_extra() { - int i, n, chart, roll, social_class; - - char *s, *t; - - char buf[240]; - - - /* Clear the previous history strings */ - for (i = 0; i < 4; i++) history[i][0] = '\0'; - - /* Clear the history text */ - buf[0] = '\0'; - - /* Initial social class */ - social_class = randint(4); - - /* Starting place */ - chart = rp_ptr->chart; - - /* Process the history */ - while (chart) - { - /* Start over */ - i = 0; - - /* Roll for nobility */ - roll = randint(100); - - - /* Access the proper entry in the table */ - while ((chart != bg[i].chart) || (roll > bg[i].roll)) i++; - - /* Acquire the textual history */ - (void)strcat(buf, bg[i].info + rp_text); - - /* Add in the social class */ - social_class += (int)(bg[i].bonus) - 50; - - /* Enter the next chart */ - chart = bg[i].next; - } - - - - /* Verify social class */ - if (social_class > 100) social_class = 100; - else if (social_class < 1) social_class = 1; - - /* Save the social class */ - p_ptr->sc = social_class; - - - /* Skip leading spaces */ - for (s = buf; *s == ' '; s++) /* loop */; - - /* Get apparent length */ - n = strlen(s); - - /* Kill trailing spaces */ - while ((n > 0) && (s[n - 1] == ' ')) s[--n] = '\0'; - - - /* Start at first line */ - i = 0; - - /* Collect the history */ - while (TRUE) - { - /* Extract remaining length */ - n = strlen(s); - - /* All done */ - if (n < 60) - { - /* Save one line of history */ - strcpy(history[i++], s); + /* Level one */ + p_ptr->max_plv = p_ptr->lev = 1; - /* All done */ - break; - } + /* Experience factor */ + p_ptr->expfact = rp_ptr->ps.exp + rmp_ptr->ps.exp + cp_ptr->ps.exp; - /* Find a reasonable break-point */ - for (n = 60; ((n > 0) && (s[n - 1] != ' ')); n--) /* loop */; + /* Initialize quest */ + p_ptr->inside_quest = 0; - /* Save next location */ - t = s + n; + /* Hitdice */ + p_ptr->hitdie = rp_ptr->ps.mhp + rmp_ptr->ps.mhp + cp_ptr->ps.mhp; - /* Wipe trailing spaces */ - while ((n > 0) && (s[n - 1] == ' ')) s[--n] = '\0'; + /* Initial hitpoints */ + p_ptr->mhp = p_ptr->hitdie; - /* Save one line of history */ - strcpy(history[i++], s); + /* Roll for HP */ + roll_player_hp(); - /* Start next line */ - for (s = t; *s == ' '; s++) /* loop */; - } + /* Set tactics and movement */ + p_ptr->tactic = 4; + p_ptr->movement = 4; } /* * Fill the random_artifacts array with relevant info. */ -errr init_randart(void) +static errr init_randart() { - int i; - - long cost; - - random_artifact* ra_ptr; - char buf[80]; - - for (i = 0; i < MAX_RANDARTS; i++) + for (int i = 0; i < MAX_RANDARTS; i++) { - ra_ptr = &random_artifacts[i]; - - strcpy(ra_ptr->name_short, - get_line("rart_s.txt", ANGBAND_DIR_FILE, buf, i)); - strcpy(ra_ptr->name_full, - get_line("rart_f.txt", ANGBAND_DIR_FILE, buf, i)); - - ra_ptr->attr = randint(15); - ra_ptr->activation = rand_int(MAX_T_ACT); - ra_ptr->generated = FALSE; - - cost = randnor(0, 250); + // Generate a 'cost' + auto cost = randnor(0, 250); + if (cost < 0) + { + cost = 0; + } - if (cost < 0) cost = 0; + // Generate the random artifact + random_artifact ra; + ra.name_short = get_line("rart_s.txt", ANGBAND_DIR_FILE, buf, i); + ra.name_full = get_line("rart_f.txt", ANGBAND_DIR_FILE, buf, i); + ra.attr = randint(15); + ra.activation = rand_int(MAX_T_ACT); + ra.generated = FALSE; + ra.cost = cost; - ra_ptr->cost = cost; + // Push + game->random_artifacts.push_back(ra); } return 0; } -/* - * A helper function for get_ahw(), also called by polymorph code - */ -void get_height_weight(void) -{ - int h_mean, h_stddev; - - int w_mean, w_stddev; - - - /* Extract mean and standard deviation -- Male */ - if (p_ptr->psex == SEX_MALE) - { - h_mean = rp_ptr->m_b_ht + rmp_ptr->m_b_ht; - h_stddev = rp_ptr->m_m_ht + rmp_ptr->m_m_ht; - - w_mean = rp_ptr->m_b_wt + rmp_ptr->m_b_wt; - w_stddev = rp_ptr->m_m_wt + rmp_ptr->m_m_wt; - } - - /* Female */ - else if (p_ptr->psex == SEX_FEMALE) - { - h_mean = rp_ptr->f_b_ht + rmp_ptr->f_b_ht; - h_stddev = rp_ptr->f_m_ht + rmp_ptr->f_m_ht; - - w_mean = rp_ptr->f_b_wt + rmp_ptr->f_b_wt; - w_stddev = rp_ptr->f_m_wt + rmp_ptr->f_m_wt; - } - - /* Neuter XXX */ - else - { - h_mean = (rp_ptr->m_b_ht + rmp_ptr->m_b_ht + - rp_ptr->f_b_ht + rmp_ptr->f_b_ht) / 2, - h_stddev = (rp_ptr->m_m_ht + rmp_ptr->m_m_ht + - rp_ptr->f_m_ht + rmp_ptr->f_m_ht) / 2; - - w_mean = (rp_ptr->m_b_wt + rmp_ptr->m_b_wt + - rp_ptr->f_b_wt + rmp_ptr->f_b_wt) / 2, - w_stddev = (rp_ptr->m_m_wt + rmp_ptr->m_m_wt + - rp_ptr->f_m_wt + rmp_ptr->f_m_wt) / 2; - } - - /* Calculate height/weight */ - p_ptr->ht = randnor(h_mean, h_stddev); - p_ptr->wt = randnor(w_mean, w_stddev); - - /* Weight/height shouldn't be negative */ - if (p_ptr->ht < 1) p_ptr->ht = 1; - if (p_ptr->wt < 1) p_ptr->wt = 1; -} - - -/* - * Computes character's age, height, and weight - */ -static void get_ahw(void) -{ - /* Calculate the age */ - p_ptr->age = rp_ptr->b_age + rmp_ptr->b_age + - randint(rp_ptr->m_age + rmp_ptr->m_age); - - /* Calculate the height/weight */ - get_height_weight(); -} - - - /* * Get the player's starting money */ -static void get_money(void) +static void get_money() { - int i, gold; - - - /* Social Class determines starting gold */ - gold = (p_ptr->sc * 6) + randint(100) + 300; + /* Starting gold */ + int gold = randint(100) + 300; /* Process the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { /* Mega-Hack -- reduce gold for high stats */ if (stat_use[i] >= 18 + 50) gold -= 300; @@ -781,7 +528,7 @@ static void get_money(void) * * See 'display_player()' for basic method. */ -static void birth_put_stats(void) +static void birth_put_stats() { int i, p; @@ -818,85 +565,57 @@ static void birth_put_stats(void) /* * Clear all the global "character" data */ -static void player_wipe(void) +static void player_wipe() { - int i, j; - - bool_ *powers; - bool_ *corruptions; - + auto const &d_info = game->edit_data.d_info; + auto &r_info = game->edit_data.r_info; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &level_markers = game->level_markers; /* Wipe special levels */ wipe_saved(); - /* Save the powers & corruptions */ - powers = p_ptr->powers; - corruptions = p_ptr->corruptions; - /* Hack -- zero the struct */ - p_ptr = WIPE(p_ptr, player_type); + *p_ptr = player_type(); - /* Restore the powers & corruptions */ - p_ptr->powers = powers; - p_ptr->corruptions = corruptions; + /* Level 1 is the first level */ + p_ptr->lev = 1; /* Not dead yet */ p_ptr->lives = 0; - /* Wipe the corruptions */ - (void)C_WIPE(p_ptr->corruptions, max_corruptions, bool_); - - /* Wipe the history */ - for (i = 0; i < 4; i++) - { - for (j = 0; j < 60; j++) - { - if (j < 59) history[i][j] = ' '; - else history[i][j] = '\0'; - } - } - /* Wipe the towns */ - for (i = 0; i < max_d_idx; i++) + for (auto &&i: level_markers) { - for (j = 0; j < MAX_DUNGEON_DEPTH; j++) + for (auto &&j: i) { - special_lvl[j][i] = 0; + j = level_marker::NORMAL; } } /* Wipe the towns */ - for (i = max_real_towns + 1; i < max_towns; i++) + for (std::size_t i = max_real_towns + 1; i < max_towns; i++) { town_info[i].flags = 0; } /* Wipe the quests */ - for (i = 0; i < MAX_Q_IDX_INIT; i++) + for (std::size_t i = 0; i < MAX_Q_IDX; i++) { quest[i].status = QUEST_STATUS_UNTAKEN; - for (j = 0; j < 4; j++) + for (auto &quest_data : quest[i].data) { - quest[i].data[j] = 0; + quest_data = 0; } } - /* Wipe the rune spells */ - rune_num = 0; - for (i = 0; i < MAX_RUNES; i++) - { - strcpy(rune_spells[i].name, ""); - rune_spells[i].type = 0; - rune_spells[i].rune2 = 0; - rune_spells[i].mana = 0; - } - /* No items */ inven_cnt = 0; equip_cnt = 0; /* Clear the inventory */ - for (i = 0; i < INVEN_TOTAL; i++) + for (std::size_t i = 0; i < INVEN_TOTAL; i++) { object_wipe(&p_ptr->inventory[i]); } @@ -905,35 +624,29 @@ static void player_wipe(void) init_randart(); /* Start with no artifacts made yet */ - for (i = 0; i < max_a_idx; i++) + for (auto &a_ref: a_info) { - artifact_type *a_ptr = &a_info[i]; - a_ptr->cur_num = 0; + a_ref.cur_num = 0; } /* Reset the "objects" */ - for (i = 1; i < max_k_idx; i++) + for (auto &k_ref: k_info) { - object_kind *k_ptr = &k_info[i]; - /* Reset "tried" */ - k_ptr->tried = FALSE; + k_ref.tried = FALSE; /* Reset "aware" */ - k_ptr->aware = FALSE; - - /* Reset "know" */ - k_ptr->know = FALSE; + k_ref.aware = FALSE; /* Reset "artifact" */ - k_ptr->artifact = 0; + k_ref.artifact = 0; } /* Reset the "monsters" */ - for (i = 1; i < max_r_idx; i++) + for (auto &r_ref: r_info) { - monster_race *r_ptr = &r_info[i]; + auto r_ptr = &r_ref; /* Hack -- Reset the counter */ r_ptr->cur_num = 0; @@ -942,8 +655,7 @@ static void player_wipe(void) r_ptr->max_num = 100; /* Hack -- Reset the max counter */ - if (r_ptr->flags1 & RF1_UNIQUE) r_ptr->max_num = 1; - if (r_ptr->flags3 & RF3_UNIQUE_4) r_ptr->max_num = 4; + if (r_ptr->flags & RF_UNIQUE) r_ptr->max_num = 1; /* Clear player kills */ r_ptr->r_pkills = 0; @@ -956,20 +668,8 @@ static void player_wipe(void) /* Hack -- Well fed player */ p_ptr->food = PY_FOOD_FULL - 1; - /* Wipe the alchemists' recipes */ - for ( i = 0 ; i < 32 ; i++) - alchemist_known_egos[i] = 0; - for ( i = 0 ; i < 6 ; i++) - alchemist_known_artifacts[i] = 0; - alchemist_gained = 0; - /* Clear "cheat" options */ - cheat_peek = FALSE; - cheat_hear = FALSE; - cheat_room = FALSE; - cheat_xtra = FALSE; - cheat_know = FALSE; - cheat_live = FALSE; + options->reset_cheat_options(); /* Assume no winning game */ total_winner = 0; @@ -979,11 +679,8 @@ static void player_wipe(void) noscore = 0; wizard = 0; - /* Assume no innate spells */ - spell_num = 0; - /* Clear the fate */ - for (i = 0; i < MAX_FATES; i++) + for (std::size_t i = 0; i < MAX_FATES; i++) { fates[i].fate = 0; } @@ -1001,12 +698,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; @@ -1017,22 +708,15 @@ static void player_wipe(void) doppleganger = 0; /* Wipe the recall depths */ - for (i = 0; i < max_d_idx; i++) + for (std::size_t i = 0; i < d_info.size(); i++) { max_dlv[i] = 0; } /* Wipe the known inscription list */ - for (i = 0; i < MAX_INSCRIPTIONS; i++) - { - inscription_info[i].know = FALSE; - } - - /* Wipe the known traps list */ - for (i = 0; i < max_t_idx; i++) + for (auto &inscription_known: p_ptr->inscriptions) { - t_info[i].known = 0; - t_info[i].ident = FALSE; + inscription_known = false; } /* Reset wild_mode to FALSE */ @@ -1042,43 +726,86 @@ 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_INIT; i++) + for (std::size_t i = 0; i < POWER_MAX; i++) { p_ptr->powers_mod[i] = 0; } /* No companions killed */ p_ptr->companion_killed = 0; + + /* Inertia control */ + p_ptr->inertia_controlled_spell = -1; + + /* Automatic stat-gain */ + p_ptr->last_rewarded_level = 1; } /* Create an object */ -void outfit_obj(int tv, int sv, int pval, int dd, int ds) +static void outfit_obj(object_proto const *proto) { object_type forge; - object_type *q_ptr; /* Get local object */ - q_ptr = &forge; + auto q_ptr = &forge; q_ptr->pval = 0; q_ptr->pval2 = 0; /* Hack -- Give the player an object */ - object_prep(q_ptr, lookup_kind(tv, sv)); + object_prep(q_ptr, lookup_kind(proto->tval, proto->sval)); - if (pval) - q_ptr->pval = pval; + if (proto->pval) + { + q_ptr->pval = proto->pval; + } /* These objects are "storebought" */ q_ptr->ident |= IDENT_MENTAL; - q_ptr->number = damroll(dd, ds); + q_ptr->number = damroll(proto->dd, proto->ds); object_aware(q_ptr); object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); +} + + +static void outfit_objs(std::vector<object_proto> const &protos) +{ + for (auto const &proto: protos) + { + outfit_obj(&proto); + } +} + + +/* + * Give the player an object. + */ +static void player_outfit_object(int qty, int tval, int sval) +{ + object_type forge; + object_type *q_ptr = &forge; + object_prep(q_ptr, lookup_kind(tval, sval)); + q_ptr->number = qty; + object_aware(q_ptr); + object_known(q_ptr); + inven_carry(q_ptr, FALSE); +} + + +/* + * Give player a spell book. + */ +static void player_outfit_spellbook(cptr spell_name) +{ + object_type forge; + object_type *q_ptr = &forge; + object_prep(q_ptr, lookup_kind(TV_BOOK, 255)); + q_ptr->pval = find_spell(spell_name); + q_ptr->ident |= IDENT_MENTAL | IDENT_KNOWN; + inven_carry(q_ptr, FALSE); } @@ -1087,239 +814,192 @@ void outfit_obj(int tv, int sv, int pval, int dd, int ds) * * Having an item makes the player "aware" of its purpose. */ -static void player_outfit(void) +static void player_outfit() { - int i; + // Shorthand names for convenience + cptr class_name = spp_ptr->title; + auto const &subrace_name = rmp_ptr->title; /* * Get an adventurer guide describing a bit of the * wilderness. */ { - object_type forge; - object_type *q_ptr = &forge; /* Hack -- Give the player an adventurer guide */ - object_prep(q_ptr, lookup_kind(TV_PARCHMENT, 20)); - q_ptr->number = 1; - object_aware(q_ptr); - object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); + player_outfit_object(1, TV_PARCHMENT, 20); } - process_hooks(HOOK_BIRTH_OBJECTS, "()"); - + /* + * Provide spell books + */ + if (game_module_idx == MODULE_TOME) { - object_type forge; - object_type *q_ptr = &forge; - /* Hack -- Give the player some food */ - object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_RATION)); - q_ptr->number = (byte)rand_range(3, 7); - object_aware(q_ptr); - object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); + if (streq(class_name, "Ranger")) + { + player_outfit_spellbook("Phase Door"); + } } - + if (streq(class_name, "Geomancer")) { - object_type forge; - object_type *q_ptr = &forge; - /* Hack -- Give the player some torches */ - object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_TORCH)); - q_ptr->number = (byte)rand_range(3, 7); - q_ptr->timeout = rand_range(3, 7) * 500; - object_aware(q_ptr); - object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); + player_outfit_spellbook("Geyser"); } - - /* Rogues have a better knowledge of traps */ - if (has_ability(AB_TRAPPING)) + if (streq(class_name, "Priest(Eru)")) { - t_info[TRAP_OF_DAGGER_I].known = randint(50) + 50; - t_info[TRAP_OF_POISON_NEEDLE].known = randint(50) + 50; - t_info[TRAP_OF_FIRE_BOLT].known = randint(50) + 50; - t_info[TRAP_OF_DAGGER_I].ident = TRUE; - t_info[TRAP_OF_POISON_NEEDLE].ident = TRUE; - t_info[TRAP_OF_FIRE_BOLT].ident = TRUE; - - /* Hack -- Give the player a some ammo for the traps */ - object_type forge; - object_type *q_ptr = &forge; - object_prep(q_ptr, lookup_kind(TV_SHOT, SV_AMMO_NORMAL)); - q_ptr->number = (byte)rand_range(5, 15); - object_aware(q_ptr); - object_known(q_ptr); - - /* These objects are "storebought" */ - q_ptr->ident |= IDENT_MENTAL; - - (void)inven_carry(q_ptr, FALSE); + player_outfit_spellbook("See the Music"); } - - /* Hack -- Give the player some useful objects */ - for (i = 0; i < rp_ptr->obj_num; i++) - outfit_obj(rp_ptr->obj_tval[i], rp_ptr->obj_sval[i], rp_ptr->obj_pval[i], rp_ptr->obj_dd[i], rp_ptr->obj_ds[i]); - for (i = 0; i < rmp_ptr->obj_num; i++) - outfit_obj(rmp_ptr->obj_tval[i], rmp_ptr->obj_sval[i], rmp_ptr->obj_pval[i], rmp_ptr->obj_dd[i], rmp_ptr->obj_ds[i]); - for (i = 0; i < cp_ptr->obj_num; i++) - outfit_obj(cp_ptr->obj_tval[i], cp_ptr->obj_sval[i], cp_ptr->obj_pval[i], cp_ptr->obj_dd[i], cp_ptr->obj_ds[i]); - for (i = 0; i < cp_ptr->spec[p_ptr->pspec].obj_num; i++) - outfit_obj(cp_ptr->spec[p_ptr->pspec].obj_tval[i], cp_ptr->spec[p_ptr->pspec].obj_sval[i], cp_ptr->spec[p_ptr->pspec].obj_pval[i], cp_ptr->spec[p_ptr->pspec].obj_dd[i], cp_ptr->spec[p_ptr->pspec].obj_ds[i]); -} - - -/* 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++) + if (streq(class_name, "Priest(Manwe)")) { - 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++) + player_outfit_spellbook("Manwe's Blessing"); + } + if (streq(class_name, "Druid")) + { + player_outfit_spellbook("Charm Animal"); + } + if (streq(class_name, "Dark-Priest")) + { + player_outfit_spellbook("Curse"); + } + if (streq(class_name, "Paladin")) + { + player_outfit_spellbook("Divine Aim"); + } + if (game_module_idx == MODULE_THEME) + { + /* Priests */ + if (streq(class_name, "Stonewright")) { - 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; - } + player_outfit_spellbook("Firebrand"); } - - q_ptr->type = random_quests_types[rand_int(MAX_RANDOM_QUESTS_TYPES)]; - - /* XXX XXX XXX Try until valid choice is found */ - while (tries) + if (streq(class_name, "Priest(Varda)")) { - 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; + player_outfit_spellbook("Light of Valinor"); + } + if (streq(class_name, "Priest(Ulmo)")) + { + player_outfit_spellbook("Song of Belegaer"); + } + if (streq(class_name, "Priest(Mandos)")) + { + player_outfit_spellbook("Tears of Luthien"); + } - /* Accept only monsters that are not good */ - if (r_ptr->flags3 & RF3_GOOD) continue; + /* Dragons */ + if (subrace_name == "Red") + { + player_outfit_spellbook("Globe of Light"); + } + if (subrace_name == "Black") + { + player_outfit_spellbook("Geyser"); + } + if (subrace_name == "Green") + { + player_outfit_spellbook("Noxious Cloud"); + } + if (subrace_name == "Blue") + { + player_outfit_spellbook("Stone Skin"); + } + if (subrace_name == "White") + { + player_outfit_spellbook("Sense Monsters"); + } + if (subrace_name == "Ethereal") + { + player_outfit_spellbook("Recharge"); + } - /* Assume no explosion attacks */ - ok = TRUE; + /* Demons */ + if (subrace_name == "(Aewrog)") + { + player_outfit_spellbook("Charm"); + } + if (subrace_name == "(Narrog)") + { + player_outfit_spellbook("Phase Door"); + } - /* Reject monsters with exploding attacks */ - for (k = 0; k < 4; k++) - { - if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE; - } - if (!ok) continue; + /* Peace-mages */ + if (streq(class_name, "Peace-mage")) + { + player_outfit_spellbook("Phase Door"); + } - /* No mutliple uniques */ - if ((r_ptr->flags1 & RF1_UNIQUE) && - ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue; + /* Wainriders */ + if (streq(class_name, "Wainrider")) + { + player_outfit_spellbook("Curse"); + } + } - /* No single non uniques */ - if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue; + if (streq(class_name, "Mimic")) + { + object_type forge; + object_type *q_ptr = &forge; + + object_prep(q_ptr, lookup_kind(TV_CLOAK, SV_MIMIC_CLOAK)); + q_ptr->pval2 = resolve_mimic_name("Mouse"); + q_ptr->ident |= IDENT_MENTAL | IDENT_KNOWN; + inven_carry(q_ptr, FALSE); + } - /* Level restriction */ - min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl; + if (game_module_idx == MODULE_THEME) + { + /* Give everyone a scroll of WoR. */ + player_outfit_object(1, TV_SCROLL, SV_SCROLL_WORD_OF_RECALL); - /* Accept monsters matching the level restriction */ - if (r_ptr->level > min_level) break; - } + /* Identify everything in pack. */ + identify_pack_fully(); + } - /* Arg could not find anything ??? */ - if (!tries) - { - if (wizard) message_add(MESSAGE_MSG, 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; - } + if (rmp_ptr->title == "Vampire") + { + player_gain_corruption(CORRUPT_VAMPIRE_TEETH); + player_gain_corruption(CORRUPT_VAMPIRE_STRENGTH); + player_gain_corruption(CORRUPT_VAMPIRE_VAMPIRE); + } - q_ptr->done = FALSE; + process_hooks_new(HOOK_BIRTH_OBJECTS, NULL, NULL); + meta_inertia_control_hook_birth_objects(); - if (wizard) message_add(MESSAGE_MSG, - format("Quest for %d on lvl %d", - q_ptr->r_idx, rl), TERM_RED); - } + { + /* Hack -- Give the player some food */ + int qty = (byte)rand_range(3, 7); + player_outfit_object(qty, TV_FOOD, SV_FOOD_RATION); + } - lvl += step; + { + object_type forge; + object_type *q_ptr = &forge; + /* Hack -- Give the player some torches */ + object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_TORCH)); + q_ptr->number = (byte)rand_range(3, 7); + q_ptr->timeout = rand_range(3, 7) * 500; + object_aware(q_ptr); + object_known(q_ptr); + inven_carry(q_ptr, FALSE); } - dungeon_type = old_type; + /* Outfit the player with starting items */ + outfit_objs(rp_ptr->object_protos); + outfit_objs(rmp_ptr->object_protos); + outfit_objs(cp_ptr->object_protos); + outfit_objs(cp_ptr->spec[p_ptr->pspec].object_protos); } -int dump_classes(s16b *classes, int sel, u32b *restrictions) + +static void dump_classes(std::vector<u16b> const &classes, int sel, u32b *restrictions) { - int n = 0; + auto const &class_info = game->edit_data.class_info; char buf[80]; - char *desc; - - cptr str; - - C_MAKE(desc, c_head->text_size, char); /* Clean up */ clear_from(12); - while (classes[n] != -1) + int n_max = static_cast<int>(classes.size()); // Warning avoidance + + for (int n = 0; n < n_max; n++) { cptr mod = ""; char p2 = ')', p1 = ' '; @@ -1327,7 +1007,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) { @@ -1337,17 +1016,23 @@ 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.c_str(), 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->flags & PR_EXPERIMENTAL) + { + desc += "\nEXPERIMENTAL"; + } + + print_desc(desc.c_str()); if (!(restrictions[classes[n] / 32] & BIT(classes[n])) || - cp_ptr->flags1 & PR1_EXPERIMENTAL) + (cp_ptr->flags & PR_EXPERIMENTAL)) c_put_str(TERM_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); else c_put_str(TERM_L_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); @@ -1355,44 +1040,34 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions) else { if (!(restrictions[classes[n] / 32] & BIT(classes[n])) || - cp_ptr->flags1 & PR1_EXPERIMENTAL) + (cp_ptr->flags & PR_EXPERIMENTAL)) c_put_str(TERM_SLATE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); else put_str(buf, 18 + (n / 4), 1 + 20 * (n % 4)); } - n++; - } - - C_FREE(desc, c_head->text_size, char); - return (n); + } } -int dump_specs(int sel) +static void dump_specs(int sel_) { - int n = 0; + auto const &class_info = game->edit_data.class_info; - char buf[80]; - char *desc; + assert(sel_ >= 0); + std::size_t sel = sel_; - cptr str; - - C_MAKE(desc, c_head->text_size, char); - - /* Clean up */ clear_from(12); - for (n = 0; n < MAX_SPEC; n++) - { - char p2 = ')', p1 = ' '; + auto specs = &class_info[p_ptr->pclass].spec; - /* Found the last one ? */ - if (!class_info[p_ptr->pclass].spec[n].title) break; + for (std::size_t n = 0; n < specs->size(); n++) + { + char p2 = ')'; + char p1 = ' '; /* Analyze */ p_ptr->pspec = n; - spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec]; - str = spp_ptr->title + c_name; + spp_ptr = &(*specs)[p_ptr->pspec]; if (sel == n) { @@ -1401,56 +1076,63 @@ int dump_specs(int sel) } /* Display */ - strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str); + char buf[80]; + 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->flags & PR_EXPERIMENTAL) + { + desc += "\nEXPERIMENTAL"; + } + + print_desc(desc.c_str()); - if (spp_ptr->flags1 & PR1_EXPERIMENTAL) + if (spp_ptr->flags & PR_EXPERIMENTAL) + { c_put_str(TERM_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); + } else + { c_put_str(TERM_L_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); + } } else { - if (spp_ptr->flags1 & PR1_EXPERIMENTAL) + if (spp_ptr->flags & PR_EXPERIMENTAL) + { c_put_str(TERM_SLATE, buf, 18 + (n / 4), 1 + 20 * (n % 4)); + } else + { put_str(buf, 18 + (n / 4), 1 + 20 * (n % 4)); + } } } - - C_FREE(desc, c_head->text_size, char); - - return (n); } -int dump_races(int sel) +static int dump_races(int sel) { + auto const &race_info = game->edit_data.race_info; + int n = 0; char buf[80]; - char *desc; - - cptr str; - - C_MAKE(desc, rp_head->text_size, char); /* Clean up */ clear_from(12); - for (n = 0; n < max_rp_idx; n++) + for (n = 0; n < static_cast<int>(race_info.size()); n++) { char p2 = ')', p1 = ' '; /* Analyze */ p_ptr->prace = n; rp_ptr = &race_info[p_ptr->prace]; - str = rp_ptr->title + rp_name; if (sel == n) { @@ -1459,45 +1141,46 @@ 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.c_str()); /* 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->flags & PR_EXPERIMENTAL) + { + desc += "\nEXPERIMENTAL"; + } - if (rp_ptr->flags1 & PR1_EXPERIMENTAL) + print_desc(desc.c_str()); + + if (rp_ptr->flags & PR_EXPERIMENTAL) c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); else c_put_str(TERM_L_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); } else { - if (rp_ptr->flags1 & PR1_EXPERIMENTAL) + if (rp_ptr->flags & PR_EXPERIMENTAL) c_put_str(TERM_SLATE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); else put_str(buf, 18 + (n / 5), 1 + 15 * (n % 5)); } } - C_FREE(desc, rp_head->text_size, char); - return (n); } -int dump_rmods(int sel, int *racem, int max) +static int dump_rmods(int sel, int *racem, int max) { + auto const &race_mod_info = game->edit_data.race_mod_info; + int n = 0; char buf[80]; - char *desc; - - cptr str; - - C_MAKE(desc, rmp_head->text_size, char); /* Clean up */ clear_from(12); @@ -1510,7 +1193,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) { @@ -1520,37 +1202,41 @@ 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.c_str()); 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->description; + if (rmp_ptr->flags & PR_EXPERIMENTAL) + { + desc += "\nEXPERIMENTAL"; + } + + print_desc(desc.c_str()); - if (rmp_ptr->flags1 & PR1_EXPERIMENTAL) + if (rmp_ptr->flags & PR_EXPERIMENTAL) c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); else c_put_str(TERM_L_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); } else { - if (rmp_ptr->flags1 & PR1_EXPERIMENTAL) + if (rmp_ptr->flags & PR_EXPERIMENTAL) c_put_str(TERM_SLATE, buf, 18 + (n / 5), 1 + 15 * (n % 5)); else put_str(buf, 18 + (n / 5), 1 + 15 * (n % 5)); } } - C_FREE(desc, rmp_head->text_size, char); - return (n); } -int dump_gods(int sel, int *choice, int max) +static int dump_gods(int sel, int *choice, int max) { int i, j; char buf[80]; @@ -1613,26 +1299,25 @@ static bool_ do_quick_start = FALSE; static bool_ player_birth_aux_ask() { - int i, k, n, v, sel; + auto &class_info = game->edit_data.class_info; + auto const &race_info = game->edit_data.race_info; + auto const &race_mod_info = game->edit_data.race_mod_info; + auto const &d_info = game->edit_data.d_info; - s32b tmp; + int k, n, v, sel; int racem[100], max_racem = 0; u32b restrictions[2]; - cptr str; - char c; - char p2 = ')'; - char buf[200]; char inp[200]; - s16b *class_types; - - s32b allow_quest; + int const NAME_ROW = 2; + int const RACE_ROW = 3; + int const CLASS_ROW = 4; /*** Intro ***/ @@ -1640,14 +1325,12 @@ static bool_ player_birth_aux_ask() Term_clear(); /* Title everything */ - put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class :", 5, 1); + put_str("Name :", NAME_ROW, 1); + c_put_str(TERM_L_BLUE, game->player_name.c_str(), NAME_ROW, 9); - /* Dump the default name */ - c_put_str(TERM_L_BLUE, player_name, 2, 9); + put_str("Race :", RACE_ROW, 1); + put_str("Class :", CLASS_ROW, 1); /*** Instructions ***/ @@ -1664,16 +1347,12 @@ static bool_ player_birth_aux_ask() /*** Quick Start ***/ - if (previous_char.quick_ok) + if (game->previous_char.quick_ok) { - /* Extra info */ - Term_putstr(1, 15, -1, TERM_WHITE, - "Do you want to use the quick start function(same character as your last one)."); - /* Choose */ while (1) { - put_str("Use quick start (y/n)?", 20, 2); + put_str("Use same character as last time (y/n)? ", 20, 2); c = inkey(); if (c == 'Q') quit(NULL); else if (c == 'S') return (FALSE); @@ -1693,86 +1372,27 @@ static bool_ player_birth_aux_ask() /* Clean up */ clear_from(15); - /*** Player sex ***/ - - if (do_quick_start) - { - k = previous_char.sex; - } - else - { - /* Extra info */ - Term_putstr(5, 15, -1, TERM_WHITE, - "Your 'sex' does not have any significant gameplay effects."); - - /* Prompt for "Sex" */ - for (n = 0; n < MAX_SEXES; n++) - { - /* 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); - put_str(buf, 21 + (n / 5), 2 + 15 * (n % 5)); - } - - /* Choose */ - while (1) - { - strnfmt(buf, 200, "Choose a sex (%c-%c), * for random, = for options: ", I2A(0), I2A(n - 1)); - put_str(buf, 20, 2); - c = inkey(); - if (c == 'Q') quit(NULL); - if (c == 'S') return (FALSE); - if (c == '*') - { - k = rand_int(MAX_SEXES); - break; - } - k = (islower(c) ? A2I(c) : -1); - if ((k >= 0) && (k < n)) break; - if (c == '?') do_cmd_help(); - else if (c == '=') - { - screen_save(); - do_cmd_options_aux(6, "Startup Options", FALSE); - screen_load(); - } - else bell(); - } - } - - /* Set sex */ - p_ptr->psex = k; - sp_ptr = &sex_info[p_ptr->psex]; - str = sp_ptr->title; - - /* Display */ - c_put_str(TERM_L_BLUE, str, 3, 9); - /* Clean up */ clear_from(15); /*** Player race ***/ - if (do_quick_start) { - k = previous_char.race; + k = game->previous_char.race; } else { /* Only one choice = instant choice */ - if (max_rp_idx == 1) + if (race_info.size() == 1) + { k = 0; + } else { /* Extra info */ Term_putstr(5, 16, -1, TERM_WHITE, "Your 'race' determines various intrinsic factors and bonuses."); - hack_corruption = FALSE; /* Dump races */ sel = 0; @@ -1782,7 +1402,7 @@ static bool_ player_birth_aux_ask() while (1) { strnfmt(buf, 200, "Choose a race (%c-%c), * for a random choice, = for options, 8/2/4/6 for movement: ", - I2A(0), I2A(max_rp_idx - 1)); + I2A(0), I2A(race_info.size() - 1)); put_str(buf, 17, 2); c = inkey(); @@ -1790,12 +1410,15 @@ static bool_ player_birth_aux_ask() if (c == 'S') return (FALSE); if (c == '*') { - k = rand_int(max_rp_idx); + k = rand_int(race_info.size()); break; } k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; - if (c == '?') exec_lua(format("ingame_help('select_context', 'race', '%s')", race_info[sel].title + rp_name)); + if (c == '?') + { + help_race(race_info[sel].title); + } else if (c == '=') { screen_save(); @@ -1840,16 +1463,18 @@ 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.c_str(), RACE_ROW, 9); /* Get a random name */ - if (!do_quick_start) create_random_name(p_ptr->prace, player_name); + if (!do_quick_start) + { + game->player_name = create_random_name(); + } /* Display */ - c_put_str(TERM_L_BLUE, player_name, 2, 9); + c_put_str(TERM_L_BLUE, game->player_name.c_str(), NAME_ROW, 9); /* Clean up */ clear_from(12); @@ -1858,21 +1483,23 @@ static bool_ player_birth_aux_ask() /*** Player race mod ***/ if (do_quick_start) { - k = previous_char.rmod; + k = game->previous_char.rmod; p_ptr->pracem = k; rmp_ptr = &race_mod_info[p_ptr->pracem]; } else { /* Only one choice = instant choice */ - if (max_rmp_idx == 1) + if (race_mod_info.size() == 1) + { k = 0; + } else { for (n = 0; n < 100; n++) racem[n] = 0; max_racem = 0; - for (n = 0; n < max_rmp_idx; n++) + for (n = 0; n < static_cast<int>(race_mod_info.size()); n++) { /* Analyze */ p_ptr->pracem = n; @@ -1911,14 +1538,25 @@ static bool_ player_birth_aux_ask() if (c == 'S') return (FALSE); if (c == '*') { - do - { - k = rand_int(max_racem); + // Which choices are legal? + std::vector<int> valid_choices(max_racem); + for (int i = 0; i < max_racem; i++) { + if ((BIT(racem[i]) & rmp_ptr->choice[racem[i] / 32])) + { + valid_choices.push_back(i); + } } - while (!(BIT(racem[k]) & rmp_ptr->choice[racem[k] / 32])); + + // Choose + assert(!valid_choices.empty()); + k = *uniform_element(valid_choices); + break; } - else if (c == '?') exec_lua(format("ingame_help('select_context', 'subrace', '%s')", race_mod_info[racem[sel]].title + rmp_name)); + else if (c == '?') + { + help_subrace(race_mod_info[racem[sel]].title.c_str()); + } k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < max_racem) && @@ -1968,7 +1606,8 @@ static bool_ player_birth_aux_ask() rmp_ptr = &race_mod_info[p_ptr->pracem]; /* Display */ - c_put_str(TERM_L_BLUE, get_player_race_name(p_ptr->prace, p_ptr->pracem), 4, 9); + auto const race_name = get_player_race_name(p_ptr->prace, p_ptr->pracem); + c_put_str(TERM_L_BLUE, race_name.c_str(), RACE_ROW, 9); } } @@ -1979,72 +1618,49 @@ static bool_ player_birth_aux_ask() /*** Player class ***/ if (do_quick_start) { - k = previous_char.pclass; + k = game->previous_char.pclass; p_ptr->pclass = k; cp_ptr = &class_info[p_ptr->pclass]; - k = previous_char.spec; + k = game->previous_char.spec; p_ptr->pspec = k; spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec]; } else { - int z; - - for (z = 0; z < 2; z++) + for (int z = 0; z < 2; z++) + { restrictions[z] = (rp_ptr->choice[z] | rmp_ptr->pclass[z]) & (~rmp_ptr->mclass[z]); + } - if (max_mc_idx > 1) + // Get list of all the classes. + std::vector<u16b> class_types; + for (std::size_t i = 0; i < class_info.size(); i++) { - /* Extra info */ - Term_putstr(5, 13, -1, TERM_WHITE, - "Your 'class' determines various intrinsic abilities and bonuses."); + class_types.push_back(i); + } - /* Get a class type */ - for (i = 0; i < max_mc_idx; i++) - c_put_str(meta_class_info[i].color, format("%c) %s", I2A(i), meta_class_info[i].name), 16 + i, 2); - while (1) - { - strnfmt(buf, 200, "Choose a class type (a-%c), * for random, = for options: ", I2A(max_mc_idx - 1)); - put_str(buf, 15, 2); - c = inkey(); - if (c == 'Q') quit(NULL); - if (c == 'S') return (FALSE); - if (c == '*') - { - k = rand_int(max_mc_idx); - break; - } - k = (islower(c) ? A2I(c) : (D2I(c) + 26)); - if ((k >= 0) && (k < max_mc_idx)) break; - if (c == '?') do_cmd_help(); - else if (c == '=') - { - screen_save(); - do_cmd_options_aux(6, "Startup Options", FALSE); - screen_load(); - } - else bell(); + // Sort into display order + std::stable_sort( + class_types.begin(), + class_types.end(), + [&class_info](auto i, auto j) { + return class_info[i].display_order_idx < class_info[j].display_order_idx; } - } - else - { - k = 0; - } - class_types = meta_class_info[k].classes; - clear_from(15); + ); /* Count classes */ - n = 0; - while (class_types[n] != -1) n++; + n = class_types.size(); /* Only one choice = instant choice */ if (n == 1) + { k = 0; + } else { /* Dump classes */ sel = 0; - n = dump_classes(class_types, sel, restrictions); + dump_classes(class_types, sel, restrictions); /* Get a class */ while (1) @@ -2061,7 +1677,10 @@ static bool_ player_birth_aux_ask() } k = (islower(c) ? A2I(c) : (D2I(c) + 26)); if ((k >= 0) && (k < n)) break; - if (c == '?') exec_lua(format("ingame_help('select_context', 'class', '%s')", class_info[class_types[sel]].title + c_name)); + if (c == '?') + { + help_class(class_info[class_types[sel]].title); + } else if (c == '=') { screen_save(); @@ -2110,11 +1729,7 @@ static bool_ player_birth_aux_ask() clear_from(15); /* Count choices */ - for (n = 0; n < MAX_SPEC; n++) - { - /* Found the last one ? */ - if (!class_info[p_ptr->pclass].spec[n].title) break; - } + n = class_info[p_ptr->pclass].spec.size(); /* Only one choice = auto choice */ if (n == 1) @@ -2123,7 +1738,7 @@ static bool_ player_birth_aux_ask() { /* Dump classes spec */ sel = 0; - n = dump_specs(sel); + dump_specs(sel); /* Get a class */ while (1) @@ -2140,7 +1755,10 @@ static bool_ player_birth_aux_ask() } k = (islower(c) ? A2I(c) : (D2I(c) + 26)); if ((k >= 0) && (k < n)) break; - if (c == '?') exec_lua(format("ingame_help('select_context', 'class', '%s')", class_info[p_ptr->pclass].spec[sel].title + c_name)); + if (c == '?') + { + help_class(class_info[p_ptr->pclass].spec[sel].title); + } else if (c == '=') { screen_save(); @@ -2185,10 +1803,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, CLASS_ROW, 9); /* Clean up */ clear_from(15); @@ -2196,26 +1813,27 @@ static bool_ player_birth_aux_ask() /*** Player god ***/ if (do_quick_start) { - k = previous_char.god; + k = game->previous_char.god; p_ptr->pgod = k; - set_grace(previous_char.grace); + set_grace(game->previous_char.grace); } - else if (PRACE_FLAG(PR1_NO_GOD)) + else if (race_flags_p(PR_NO_GOD)) { p_ptr->pgod = GOD_NONE; } else { - int *choice; + int choice[MAX_GODS]; int max = 0; - C_MAKE(choice, max_gods, int); - /* Get the list of possible gods */ - for (n = 0; n < max_gods; n++) + for (n = 0; n < MAX_GODS; n++) { - if ((cp_ptr->gods | spp_ptr->gods) & BIT(n)) + if (god_enabled(&deity_info[n]) && + ((cp_ptr->gods | spp_ptr->gods) & BIT(n))) + { choice[max++] = n; + } } if (!max) @@ -2243,8 +1861,6 @@ static bool_ player_birth_aux_ask() if (c == 'Q') quit(NULL); if (c == 'S') { - C_FREE(choice, max_gods, int); - return (FALSE); } if (c == '*') @@ -2258,7 +1874,10 @@ static bool_ player_birth_aux_ask() k = choice[k]; break; } - if (c == '?') exec_lua(format("ingame_help('select_context', 'god', '%s')", deity_info[choice[sel]].name)); + if (c == '?') + { + help_god(deity_info[choice[sel]].name); + } else if (c == '=') { screen_save(); @@ -2299,15 +1918,13 @@ static bool_ player_birth_aux_ask() else bell(); } - C_FREE(choice, max_gods, int); - /* Set god */ p_ptr->pgod = k; p_ptr->grace = 0; } /* A god that like us ? more grace ! */ - if (PRACE_FLAGS(PR1_GOD_FRIEND)) + if (race_flags_p(PR_GOD_FRIEND)) { set_grace(200); } @@ -2334,11 +1951,8 @@ 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; + /* Is the player an "astral" being? */ + p_ptr->astral = (race_flags_p(PR_ASTRAL)) ? TRUE : FALSE; /* * A note by pelpel. (remove this please) @@ -2354,23 +1968,16 @@ static bool_ player_birth_aux_ask() /* Set the recall dungeon accordingly */ - call_lua("get_module_info", "(s)", "d", "base_dungeon", &tmp); - dungeon_type = tmp; + dungeon_type = DUNGEON_BASE; p_ptr->recall_dungeon = dungeon_type; max_dlv[dungeon_type] = d_info[dungeon_type].mindepth; if (p_ptr->astral) { - s32b x, y, astral_dun; - - call_lua("get_module_info", "(s)", "d", "astral_dungeon", &astral_dun); - dungeon_type = astral_dun; - /* Somewhere in the misty mountains */ - call_lua("get_module_info", "(s)", "d", "astral_wild_x", &x); - call_lua("get_module_info", "(s)", "d", "astral_wild_y", &y); - p_ptr->wilderness_x = x; - p_ptr->wilderness_y = y; + dungeon_type = DUNGEON_ASTRAL; + p_ptr->wilderness_x = DUNGEON_ASTRAL_WILD_X; + p_ptr->wilderness_y = DUNGEON_ASTRAL_WILD_Y; } /* Clean up */ @@ -2379,12 +1986,11 @@ static bool_ player_birth_aux_ask() /*** User enters number of quests ***/ /* Heino Vander Sanden and Jimmy De Laet */ - call_lua("get_module_info", "(s)", "d", "rand_quest", &allow_quest); - if (!ironman_rooms && allow_quest) + if (!options->ironman_rooms) { if (do_quick_start) { - v = previous_char.quests; + v = game->previous_char.quests; } else { @@ -2437,16 +2043,13 @@ 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; /* Init the plots */ - call_lua("get_module_info", "(s)", "d", "C_quest", &allow_quest); - if (allow_quest) { plots[PLOT_MAIN] = QUEST_NECRO; quest[plots[PLOT_MAIN]].status = QUEST_STATUS_TAKEN; @@ -2469,7 +2072,7 @@ static bool_ player_birth_aux_ask() plots[PLOT_OTHER] = QUEST_NULL; } - quest_random_init_hook(QUEST_RANDOM); + quest_random_init_hook(); /* Ok */ return (TRUE); @@ -2501,7 +2104,7 @@ static const int birth_stat_costs[(18-10) + 1] = * * Taken from V 2.9.0 */ -static bool_ player_birth_aux_point(void) +static bool_ player_birth_aux_point() { int i; @@ -2519,8 +2122,6 @@ static bool_ player_birth_aux_point(void) char buf[80]; - int mode = 0; - /* Initialize stats */ for (i = 0; i < 6; i++) @@ -2533,18 +2134,6 @@ static bool_ player_birth_aux_point(void) /* Roll for base hitpoints */ get_extra(); - /* Roll for age/height/weight */ - get_ahw(); - - /* Roll for social class */ - get_history(); - - /*** Generate ***/ - process_hooks(HOOK_BIRTH, "()"); - - /* Hack -- get a chaos patron even if you are not a chaos warrior */ - p_ptr->chaos_patron = (randint(MAX_PATRON)) - 1; - /* Get luck */ p_ptr->luck_base = rp_ptr->luck + rmp_ptr->luck + rand_range( -5, 5); p_ptr->luck_max = p_ptr->luck_base; @@ -2558,24 +2147,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]; @@ -2613,7 +2186,7 @@ static bool_ player_birth_aux_point(void) p_ptr->csp = p_ptr->msp; /* Display the player */ - display_player(mode); + display_player(0); /* Display the costs header */ put_str("Cost", row - 2, col + 32); @@ -2683,8 +2256,6 @@ static bool_ player_birth_aux_auto() { int i, j, m, v; - int mode = 0; - bool_ flag = FALSE; bool_ prev = FALSE; @@ -2700,10 +2271,8 @@ static bool_ player_birth_aux_auto() char inp[80]; -#ifdef ALLOW_AUTOROLLER - /* Initialize */ - if (autoroll) + if (options->autoroll) { int mval[6]; @@ -2727,7 +2296,7 @@ static bool_ player_birth_aux_auto() stat_match[i] = 0; /* Race/Class bonus */ - j = rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]; + j = rp_ptr->ps.adj[i] + rmp_ptr->ps.adj[i] + cp_ptr->ps.adj[i]; /* Obtain the "maximal" stat */ m = adjust_stat(17, j, TRUE); @@ -2766,7 +2335,7 @@ static bool_ player_birth_aux_auto() if (!askfor_aux(inp, 8)) inp[0] = '\0'; /* Weirdos stat display .. erm .. I mean, original stat display */ - if (!linear_stats) + if (!options->linear_stats) { /* Hack -- add a fake slash */ strcat(inp, "/"); @@ -2802,26 +2371,23 @@ static bool_ player_birth_aux_auto() } } -#endif /* ALLOW_AUTOROLLER */ - /* Roll */ while (TRUE) { /* Feedback */ - if (autoroll) + if (options->autoroll) { Term_clear(); put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class:", 5, 1); + c_put_str(TERM_L_BLUE, game->player_name.c_str(), 2, 9); + + put_str("Race :", 3, 1); + auto const player_race_name = get_player_race_name(p_ptr->prace, p_ptr->pracem); + c_put_str(TERM_L_BLUE, player_race_name.c_str(), 3, 9); - c_put_str(TERM_L_BLUE, player_name, 2, 9); - 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); + put_str("Class:", 4, 1); + c_put_str(TERM_L_BLUE, spp_ptr->title, 4, 9); /* Label stats */ put_str("STR:", 2 + A_STR, 61); @@ -2849,7 +2415,7 @@ static bool_ player_birth_aux_auto() } /* Auto-roll */ - while (autoroll) + while (options->autoroll) { bool_ accept = TRUE; @@ -2896,17 +2462,8 @@ static bool_ player_birth_aux_auto() /* Make sure they see everything */ Term_fresh(); -#ifndef USE_FAST_AUTOROLLER - - /* Delay 1/10 second */ - if (fast_autoroller && flag) Term_xtra(TERM_XTRA_DELAY, 100); - -#endif - /* Do not wait for a key */ - inkey_scan = TRUE; - /* Check for a keypress */ - if (inkey()) break; + if (inkey_scan()) break; } } @@ -2916,27 +2473,12 @@ static bool_ player_birth_aux_auto() /*** Display ***/ - /* Mode */ - mode = 0; - /* Roll for base hitpoints */ get_extra(); - /* Roll for age/height/weight */ - get_ahw(); - - /* Roll for social class */ - get_history(); - /* Roll for gold */ get_money(); - /*** Generate ***/ - process_hooks(HOOK_BIRTH, "()"); - - /* Hack -- get a chaos patron even if you are not a chaos warrior */ - p_ptr->chaos_patron = (randint(MAX_PATRON)) - 1; - /* Input loop */ while (TRUE) { @@ -2953,15 +2495,13 @@ static bool_ player_birth_aux_auto() p_ptr->csp = p_ptr->msp; /* Display the player */ - display_player(mode); + display_player(0); /* Prepare a prompt (must squeeze everything in) */ Term_gotoxy(2, 23); Term_addch(TERM_WHITE, b1); Term_addstr( -1, TERM_WHITE, "'r' to reroll"); if (prev) Term_addstr( -1, TERM_WHITE, ", 'p' for prev"); - if (mode) Term_addstr( -1, TERM_WHITE, ", 'h' for Misc."); - else Term_addstr( -1, TERM_WHITE, ", 'h' for History"); Term_addstr( -1, TERM_WHITE, ", or ESC to accept"); Term_addch(TERM_WHITE, b2); @@ -2987,13 +2527,6 @@ static bool_ player_birth_aux_auto() continue; } - /* Toggle the display */ - if ((c == 'H') || (c == 'h')) - { - mode = ((mode != 0) ? 0 : 1); - continue; - } - /* Help */ if (c == '?') { @@ -3031,20 +2564,20 @@ static bool_ player_birth_aux_auto() */ static bool_ player_birth_aux() { - char c; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; - int i, j; - - int y = 0, x = 0; - - char old_history[4][60]; + char c; /* Ask */ if (!player_birth_aux_ask()) return (FALSE); - for (i = 1; i < max_s_idx; i++) - s_info[i].dev = FALSE; - for (i = 1; i < max_s_idx; i++) + for (std::size_t i = 1; i < s_descriptors.size(); i++) + { + s_info[i].dev = false; + } + + for (std::size_t i = 1; i < s_descriptors.size(); i++) { s32b value = 0, mod = 0; @@ -3055,14 +2588,18 @@ static bool_ player_birth_aux() /* Develop only revelant branches */ if (s_info[i].value || s_info[i].mod) { - int z = s_info[i].father; + int z = s_descriptors[i].father; while (z != -1) { - s_info[z].dev = TRUE; - z = s_info[z].father; + // Mark as developed + s_info[z].dev = true; + // Next node up the tree + z = s_descriptors[z].father; if (z == 0) + { break; + } } } } @@ -3089,7 +2626,7 @@ static bool_ player_birth_aux() else { /* Point based */ - if (point_based) + if (options->point_based) { if (!player_birth_aux_point()) return FALSE; } @@ -3099,83 +2636,9 @@ static bool_ player_birth_aux() if (!player_birth_aux_auto()) return FALSE; } - /* Edit character background */ - for (i = 0; i < 4; i++) - { - strnfmt(old_history[i], 60, "%s", history[i]); - } - /* Turn 0 to space */ - for (i = 0; i < 4; i++) - { - for (j = 0; history[i][j]; j++) /* loop */; - - for (; j < 59; j++) history[i][j] = ' '; - } - display_player(1); - c_put_str(TERM_L_GREEN, "(Character Background - Edit Mode)", 15, 20); - while (TRUE) - { - for (i = 0; i < 4; i++) - { - put_str(history[i], i + 16, 10); - } - c_put_str(TERM_L_BLUE, format("%c", history[y][x]), y + 16, x + 10); - - /* Place cursor just after cost of current stat */ - Term_gotoxy(x + 10, y + 16); - - c = inkey(); - - if (c == '8') - { - y--; - if (y < 0) y = 3; - } - else if (c == '2') - { - y++; - if (y > 3) y = 0; - } - else if (c == '6') - { - x++; - if (x > 59) x = 0; - } - else if (c == '4') - { - x--; - if (x < 0) x = 59; - } - else if (c == '\r') - { - break; - } - else if (c == ESCAPE) - { - for (i = 0; i < 4; i++) - { - strnfmt(history[i], 60, "%s", old_history[i]); - put_str(history[i], i + 16, 10); - } - break; - } - else - { - history[y][x++] = c; - if (x > 58) - { - x = 0; - y++; - if (y > 3) y = 0; - } - } - } - - /*** Finish up ***/ /* Get a name, recolor it, prepare savefile */ - get_name(); @@ -3193,7 +2656,7 @@ static bool_ player_birth_aux() } /* Save this for the next character */ - previous_char.quick_ok = TRUE; + game->previous_char.quick_ok = TRUE; save_prev_data(); /* Accept */ @@ -3202,105 +2665,9 @@ static bool_ player_birth_aux() /* - * Helper function for validate_bg(). - */ -static void validate_bg_aux(int chart, bool_ chart_checked[], char *buf) -{ - char *s; - - int i; - - - /* Assume the chart does not exist */ - bool_ chart_exists = FALSE; - - /* Assume the chart is not complete */ - bool_ chart_complete = FALSE; - - int bg_max = max_bg_idx; - - /* No chart */ - if (!chart) return; - - /* Already saw this chart */ - if (chart_checked[chart]) return; - - /* Build a debug message */ - s = buf + strlen(buf); - - /* XXX XXX XXX */ - (void) strnfmt(s, -1, "%d --> ", chart); - - /* Check each chart */ - for (i = 0; i < bg_max; i++) - { - /* Require same chart */ - if (bg[i].chart != chart) continue; - - /* The chart exists */ - chart_exists = TRUE; - - /* Validate the "next" chart recursively */ - validate_bg_aux(bg[i].next, chart_checked, buf); - - /* Require a terminator */ - if (bg[i].roll != 100) continue; - - /* The chart is complete */ - chart_complete = TRUE; - } - - /* Failed: The chart does not exist */ - if (!chart_exists) - { - quit_fmt("birth.c: bg[] chart %d does not exist\n%s", chart, buf); - } - - /* Failed: The chart is not complete */ - if (!chart_complete) - { - quit_fmt("birth.c: bg[] chart %d is not complete", chart); - } - - /* Remember we saw this chart */ - chart_checked[chart] = TRUE; - - /* Build a debug message */ - *s = 0; -} - - -/* - * Verify that the bg[] table is valid. - */ -static void validate_bg(void) -{ - int i, race; - - bool_ chart_checked[512]; - - char buf[1024]; - - - for (i = 0; i < 512; i++) chart_checked[i] = FALSE; - - /* Check each race */ - for (race = 0; race < max_rp_idx; race++) - { - /* Get the first chart for this race */ - int chart = race_info[race].chart; - - (void) strcpy(buf, ""); - - /* Validate the chart recursively */ - validate_bg_aux(chart, chart_checked, buf); - } -} - -/* * Initialize a random town */ -void init_town(int t_idx, int level) +static void init_town(int t_idx) { town_type *t_ptr = &town_info[t_idx]; @@ -3311,10 +2678,7 @@ void init_town(int t_idx, int level) t_ptr->flags &= ~(TOWN_KNOWN); /* Generation seed for the town */ - t_ptr->seed = randint(0x10000000); - - /* Total hack and not even used */ - t_ptr->numstores = 8; + t_ptr->seed = seed_t::system(); } /* @@ -3323,12 +2687,14 @@ void init_town(int t_idx, int level) * Note that we may be called with "junk" leftover in the various * fields, so we must be sure to clear them first. */ -void player_birth(void) +void player_birth() { - int i, j, rtown = TOWN_RANDOM; + auto const &st_info = game->edit_data.st_info; + auto &d_info = game->edit_data.d_info; + auto &messages = game->messages; - /* Validate the bg[] table */ - validate_bg(); + /* Starting index for generated towns */ + std::size_t rtown = TOWN_RANDOM; /* Create a new character */ while (1) @@ -3347,38 +2713,36 @@ void player_birth(void) recalc_skills(FALSE); /* grab level 1 abilities */ - for (i = 0; i < max_ab_idx; i++) - ab_info[i].acquired = FALSE; + p_ptr->abilities.clear(); apply_level_abilities(1); /* Complete the god */ - i = p_ptr->pgod; - p_ptr->pgod = 0; - follow_god(i, TRUE); + { + byte i = p_ptr->pgod; + p_ptr->pgod = 0; + follow_god(i, TRUE); + } /* Select the default melee type */ select_default_melee(); /* Make a note file if that option is set */ - if (take_notes) - { - add_note_type(NOTE_BIRTH); - } + add_note_type(NOTE_BIRTH); /* Note player birth in the message recall */ - message_add(MESSAGE_MSG, " ", TERM_L_BLUE); - message_add(MESSAGE_MSG, " ", TERM_L_BLUE); - message_add(MESSAGE_MSG, "====================", TERM_L_BLUE); - message_add(MESSAGE_MSG, " ", TERM_L_BLUE); - message_add(MESSAGE_MSG, " ", TERM_L_BLUE); + messages.add(" ", TERM_L_BLUE); + messages.add(" ", TERM_L_BLUE); + messages.add("====================", TERM_L_BLUE); + messages.add(" ", TERM_L_BLUE); + messages.add(" ", TERM_L_BLUE); /* Hack -- outfit the player */ player_outfit(); /* Initialize random towns in the dungeons */ - for (i = 0; i < max_d_idx; i++) + for (std::size_t i = 0; i < d_info.size(); i++) { - dungeon_info_type *d_ptr = &d_info[i]; + auto d_ptr = &d_info[i]; int num = 0, z; d_ptr->t_num = 0; @@ -3387,7 +2751,7 @@ void player_birth(void) d_ptr->t_idx[z] = 0; d_ptr->t_level[z] = 0; } - if (!(d_ptr->flags1 & DF1_RANDOM_TOWNS)) continue; + if (!(d_ptr->flags & DF_RANDOM_TOWNS)) continue; /* Can we add a town ? */ while (magik(TOWN_CHANCE - (num * 10))) @@ -3399,15 +2763,17 @@ void player_birth(void) while (TRUE) { - int j; bool_ ok = TRUE; lev = rand_range(d_ptr->mindepth, d_ptr->maxdepth - 1); /* Be sure it wasnt already used */ - for (j = 0; j < num; j++) + for (int j = 0; j < num; j++) { - if (d_ptr->t_level[j] == lev) ok = FALSE; + if (d_ptr->t_level[j] == lev) + { + ok = FALSE; + } } /* Ok found one */ @@ -3415,10 +2781,13 @@ void player_birth(void) } d_ptr->t_level[num] = lev; - if (wizard) message_add(MESSAGE_MSG, format("Random dungeon town: d_idx:%d, lev:%d", i, lev), TERM_WHITE); + if (wizard) + { + messages.add(format("Random dungeon town: d_idx:%d, lev:%d", i, lev), TERM_WHITE); + } /* Create the town */ - init_town(d_ptr->t_idx[num], d_ptr->t_level[num]); + init_town(d_ptr->t_idx[num]); num++; @@ -3430,7 +2799,7 @@ void player_birth(void) } /* Init the towns */ - for (i = 1; i < max_towns; i++) + for (std::size_t i = 1; i < max_towns; i++) { /* Not destroyed ! yet .. ;) */ town_info[i].destroyed = FALSE; @@ -3441,7 +2810,7 @@ void player_birth(void) create_stores_stock(i); /* Init the stores */ - for (j = 0; j < max_st_idx; j++) + for (std::size_t j = 0; j < st_info.size(); j++) { /* Initialize */ store_init(i, j); @@ -3449,28 +2818,27 @@ void player_birth(void) } /* Init wilderness seeds */ - for (i = 0; i < max_wild_x; i++) + auto &wilderness = game->wilderness; + for (std::size_t y = 0; y < wilderness.height(); y++) { - for (j = 0; j < max_wild_y; j++) + for (std::size_t x = 0; x < wilderness.width(); x++) { - wild_map[j][i].seed = rand_int(0x10000000); - wild_map[j][i].entrance = 0; - wild_map[j][i].known = FALSE; + auto &w = wilderness(x, y); + w.seed = seed_t::system(); + w.entrance = 0; + w.known = FALSE; } } - - /* Select bounty monsters. */ - select_bounties(); } -char savefile_module[46][80]; -char savefile_names[46][30]; -char savefile_desc[46][80]; -bool_ savefile_alive[46]; -int savefile_idx[46]; +static char savefile_module[46][80]; +static char savefile_names[46][30]; +static char savefile_desc[46][80]; +static bool_ savefile_alive[46]; +static int savefile_idx[46]; /* * Grab all the names from an index @@ -3480,7 +2848,7 @@ int load_savefile_names() FILE *fff; char buf[1024]; char tmp[50]; - char player_base_save[32]; + std::string player_base_save; int max = 0, fd; @@ -3488,9 +2856,6 @@ int load_savefile_names() strcpy(tmp, "global.svg"); path_build(buf, 1024, ANGBAND_DIR_SAVE, tmp); - /* File type is "TEXT" */ - FILE_TYPE(FILE_TYPE_TEXT); - /* Read the file */ fff = my_fopen(buf, "r"); @@ -3499,7 +2864,7 @@ int load_savefile_names() /* Save the current 'player_base' */ - strncpy(player_base_save, player_base, 32); + player_base_save = game->player_base; /* @@ -3558,12 +2923,9 @@ int load_savefile_names() strcpy(savefile_desc[max], buf + i); /* Build platform-dependent savefile name */ - strncpy(player_base, savefile_names[max], 32); + game->player_base = savefile_names[max]; process_player_name(TRUE); - /* File type is 'SAVE' */ - FILE_TYPE(FILE_TYPE_SAVE); - /* Try to open the savefile */ fd = fd_open(savefile, O_RDONLY); @@ -3578,7 +2940,7 @@ int load_savefile_names() my_fclose(fff); /* Restore the values of 'player_base' and 'savefile' */ - strncpy(player_base, player_base_save, 32); + game->player_base = player_base_save; process_player_name(TRUE); return (max); @@ -3600,9 +2962,6 @@ void save_savefile_names() strcpy(tmp, "global.svg"); path_build(buf, 1024, ANGBAND_DIR_SAVE, tmp); - /* File type is "TEXT" */ - FILE_TYPE(FILE_TYPE_TEXT); - /* Read the file */ fff = my_fopen(buf, "w"); @@ -3613,15 +2972,16 @@ void save_savefile_names() * Save, use '@' intead of ':' as a separator because it cannot exists * in savefiles */ + auto const player_race_name = get_player_race_name(p_ptr->prace, p_ptr->pracem); 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, + (death) ? '0' : '1', game->player_base.c_str(), game->player_name.c_str(), + player_race_name.c_str(), + spp_ptr->title, (!death) ? "alive" : "dead"); for (i = 0; i < max; i++) { - if (!strcmp(savefile_names[i], player_base)) continue; + if (!strcmp(savefile_names[i], game->player_base.c_str())) continue; fprintf(fff, "%s@%c%s@%s\n", savefile_module[i], (savefile_alive[i]) ? '1' : '0', savefile_names[i], savefile_desc[i]); } @@ -3694,7 +3054,7 @@ savefile_try_again: { s32b can_use; - call_lua("module_savefile_loadable", "(s)", "d", savefile_module[k], &can_use); + can_use = module_savefile_loadable(savefile_module[k]); if (can_use) { savefile_idx[m++] = k; @@ -3752,22 +3112,20 @@ savefile_try_again: } else if (((k == 0x7F) || (k == '\010')) && (sel >= 2)) { - char player_base_save[32]; - if (!get_check(format("Really delete '%s'?", savefile_names[savefile_idx[sel - 2]]))) continue; /* Save current 'player_base' */ - strncpy(player_base_save, player_base, 32); + std::string player_base_save = game->player_base; /* Build platform-dependent save file name */ - strncpy(player_base, savefile_names[savefile_idx[sel - 2]], 32); + game->player_base = savefile_names[savefile_idx[sel - 2]]; process_player_name(TRUE); /* Remove the savefile */ fd_kill(savefile); /* Restore 'player_base' and 'savefile' */ - strncpy(player_base, player_base_save, 32); + game->player_base = player_base_save; process_player_name(TRUE); /* Reload, gods I hate using goto .. */ @@ -3776,18 +3134,49 @@ savefile_try_again: continue; } + // + // React + // + if (k == 'a') { /* Display prompt */ prt("Enter the name of the savefile that will hold this character: ", 23, 0); /* Ask the user for a string */ - if (!askfor_aux(player_base, 15)) continue; + if (!askfor_aux(&game->player_base, 15)) continue; /* Process the player name */ process_player_name(TRUE); - return (TRUE); + // If the savefile already exists, we do *NOT* want to + // create a new game, so we'll need to return FALSE for + // that. + if (boost::filesystem::exists(savefile)) + { + // Show a message so user doesn't get confused. + msg_print(NULL); + + // Prompt for it + prt(fmt::format( + "Character '{}' already exists! Press any key to load.", + game->player_base), + 0, 0); + + // Wait + inkey(); + + // Erase the prompt + prt("", 0, 0); + + // Load character + return FALSE; + } + else + { + // Start new game + return TRUE; + } } if (k == 'b') { @@ -3795,7 +3184,7 @@ savefile_try_again: prt("Enter the name of a savefile: ", 23, 0); /* Ask the user for a string */ - if (!askfor_aux(player_base, 15)) continue; + if (!askfor_aux(&game->player_base, 15)) continue; /* Process the player name */ process_player_name(TRUE); @@ -3811,7 +3200,7 @@ savefile_try_again: if ((x < 2) || (x >= max)) continue; - strnfmt(player_base, 32, "%s", savefile_names[savefile_idx[x - 2]]); + game->player_base = savefile_names[savefile_idx[x - 2]]; /* Process the player name */ process_player_name(TRUE); diff --git a/src/birth.hpp b/src/birth.hpp new file mode 100644 index 00000000..82bdfcf6 --- /dev/null +++ b/src/birth.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "h-basic.h" + +void print_desc_aux(cptr txt, int y, int x); +void save_savefile_names(); +bool_ begin_screen(); +void player_birth(); +void roll_player_hp(); + +extern bool_ no_begin_screen; diff --git a/src/birther.hpp b/src/birther.hpp new file mode 100644 index 00000000..0c28b513 --- /dev/null +++ b/src/birther.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "h-basic.h" + +#include <string> +#include <vector> + +/** + * Player information during the birth process. + */ +struct birther +{ + s16b race; + s16b rmod; + s16b pclass; + s16b spec; + + byte quests; + + byte god; + s32b grace; + + s32b au; + + s16b stat[6]; + s16b luck; + + bool_ quick_ok; +}; diff --git a/src/bldg.c b/src/bldg.cc index 48e94e9f..9b3750a6 100644 --- a/src/bldg.c +++ b/src/bldg.cc @@ -13,10 +13,37 @@ * 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 "game.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 "object_flag.hpp" +#include "owner_type.hpp" +#include "player_race_flag.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" +#include "z-rand.hpp" /* remember building location */ static int building_loc = 0; @@ -25,10 +52,11 @@ 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 const *s_ptr, int state) { - owner_type *ow_ptr = &ow_info[s_ptr->owner]; + auto const &ow_info = game->edit_data.ow_info; + auto ow_ptr = &ow_info[s_ptr->owner]; /* Check race */ if (ow_ptr->races[state][p_ptr->prace / 32] & (1 << p_ptr->prace)) @@ -50,7 +78,7 @@ bool_ is_state_aux(store_type *s_ptr, int state) /* * Test if the state accords with the player */ -bool_ is_state(store_type *s_ptr, int state) +bool_ is_state(store_type const *s_ptr, int state) { if (state == STORE_NORMAL) { @@ -84,218 +112,95 @@ static void clear_bldg(int min_row, int max_row) /* * Display a building. */ -void show_building(store_type *s_ptr) +void show_building(store_type const *s_ptr) { - char buff[20]; - - int i; - - byte action_color; - - char tmp_str[80]; - - store_info_type *st_ptr = &st_info[s_ptr->st_idx]; + auto const &ba_info = game->edit_data.ba_info; + auto const &st_info = game->edit_data.st_info; - store_action_type *ba_ptr; + auto st_ptr = &st_info[s_ptr->st_idx]; - - for (i = 0; i < 6; i++) + for (std::size_t i = 0; i < st_ptr->actions.size(); i++) { - ba_ptr = &ba_info[st_ptr->actions[i]]; + auto ba_ptr = &ba_info[st_ptr->actions[i]]; + + byte action_color; + char buff[20]; - if (ba_ptr->letter != '.') + if (ba_ptr->action_restr == 0) { - if (ba_ptr->action_restr == 0) + if ((is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) || + (is_state(s_ptr, STORE_HATED) && (ba_ptr->costs[STORE_HATED] == 0)) || + (is_state(s_ptr, STORE_NORMAL) && (ba_ptr->costs[STORE_NORMAL] == 0))) { - if ((is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) || - (is_state(s_ptr, STORE_HATED) && (ba_ptr->costs[STORE_HATED] == 0)) || - (is_state(s_ptr, STORE_NORMAL) && (ba_ptr->costs[STORE_NORMAL] == 0))) - { - action_color = TERM_WHITE; - buff[0] = '\0'; - } - else if (is_state(s_ptr, STORE_LIKED)) - { - action_color = TERM_L_GREEN; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); - } - else if (is_state(s_ptr, STORE_HATED)) - { - action_color = TERM_RED; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_HATED]); - } - else - { - action_color = TERM_YELLOW; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_NORMAL]); - } + action_color = TERM_WHITE; + buff[0] = '\0'; } - else if (ba_ptr->action_restr == 1) + else if (is_state(s_ptr, STORE_LIKED)) { - if ((is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) || - (is_state(s_ptr, STORE_NORMAL) && (ba_ptr->costs[STORE_NORMAL] == 0))) - { - action_color = TERM_WHITE; - buff[0] = '\0'; - } - else if (is_state(s_ptr, STORE_LIKED)) - { - action_color = TERM_L_GREEN; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); - } - else if (is_state(s_ptr, STORE_HATED)) - { - action_color = TERM_L_DARK; - strnfmt(buff, 20, "(closed)"); - } - else - { - action_color = TERM_YELLOW; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_NORMAL]); - } + action_color = TERM_L_GREEN; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); + } + else if (is_state(s_ptr, STORE_HATED)) + { + action_color = TERM_RED; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_HATED]); } else { - if (is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) - { - action_color = TERM_WHITE; - buff[0] = '\0'; - } - else if (is_state(s_ptr, STORE_LIKED)) - { - action_color = TERM_L_GREEN; - strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); - } - else - { - action_color = TERM_L_DARK; - strnfmt(buff, 20, "(closed)"); - } + action_color = TERM_YELLOW; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_NORMAL]); } - - 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); - 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: + else if (ba_ptr->action_restr == 1) { - if (p_ptr->arena_number == MAX_ARENA_MONS) + if ((is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) || + (is_state(s_ptr, STORE_NORMAL) && (ba_ptr->costs[STORE_NORMAL] == 0))) { - 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++; + action_color = TERM_WHITE; + buff[0] = '\0'; } - else if (p_ptr->arena_number > MAX_ARENA_MONS) + else if (is_state(s_ptr, STORE_LIKED)) { - msg_print("You enter the arena briefly and bask in your glory."); - msg_print(NULL); + action_color = TERM_L_GREEN; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); + } + else if (is_state(s_ptr, STORE_HATED)) + { + action_color = TERM_L_DARK; + strnfmt(buff, 20, "(closed)"); } 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; + action_color = TERM_YELLOW; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_NORMAL]); } - - break; } - - case BACT_POSTER: + else { - 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."); + if (is_state(s_ptr, STORE_LIKED) && (ba_ptr->costs[STORE_LIKED] == 0)) + { + action_color = TERM_WHITE; + buff[0] = '\0'; + } + else if (is_state(s_ptr, STORE_LIKED)) + { + action_color = TERM_L_GREEN; + strnfmt(buff, 20, "(%dgp)", ba_ptr->costs[STORE_LIKED]); + } 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); + action_color = TERM_L_DARK; + strnfmt(buff, 20, "(closed)"); } - - break; } - case BACT_ARENA_RULES: - { - /* Save screen */ - screen_save(); - - /* Peruse the arena help file */ - (void)show_file("arena.txt", NULL, 0, 0); + char tmp_str[80]; - /* Load screen */ - screen_load(); + strnfmt(tmp_str, 80, " %c", ba_ptr->letter); + c_put_str(TERM_YELLOW, tmp_str, 21 + (i / 2), 17 + (30 * (i % 2))); - break; - } + strnfmt(tmp_str, 80, ") %s %s", ba_ptr->name.c_str(), buff); + c_put_str(action_color, tmp_str, 21 + (i / 2), 2 + 17 + (30 * (i % 2))); } } @@ -427,7 +332,7 @@ static bool_ gamble_comm(int cmd) if (cmd == BACT_GAMBLE_RULES) { /* Peruse the gambling help file */ - (void)show_file("gambling.txt", NULL, 0, 0); + show_file("gambling.txt", NULL); } else { @@ -541,40 +446,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 +541,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_flags_p(PR_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))); switch (cmd) { @@ -680,7 +551,7 @@ static bool_ inn_comm(int cmd) { msg_print("The barkeep gives you some gruel and a beer."); msg_print(NULL); - (void) set_food(PY_FOOD_MAX - 1); + set_food(PY_FOOD_MAX - 1); } else msg_print("You're a vampire and I don't have any food for you!"); @@ -760,9 +631,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 +702,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 +723,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; @@ -869,7 +743,7 @@ static bool_ castle_quest(int y, int x) get_questinfo(plots[plot]); /* Add the hooks */ - if (quest[plots[plot]].type == HOOK_TYPE_C) quest[plots[plot]].init(plots[plot]); + quest[plots[plot]].init(); return (TRUE); } @@ -880,13 +754,13 @@ static bool_ castle_quest(int y, int x) /* * Displaying town history -KMW- */ -static void town_history(void) +static void town_history() { /* Save screen */ screen_save(); /* Peruse the building help file */ - (void)show_file("bldg.txt", NULL, 0, 0); + show_file("bldg.txt", NULL); /* Load screen */ screen_load(); @@ -896,7 +770,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, byte color) { char tmp_str[80]; @@ -914,80 +788,77 @@ static void compare_weapon_aux2(object_type *o_ptr, int numblows, int r, int c, */ static void compare_weapon_aux1(object_type *o_ptr, int col, int r) { - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - + auto const f = object_flags(o_ptr); - if (f1 & (TR1_SLAY_ANIMAL)) + if (f & TR_SLAY_ANIMAL) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 2, "Animals:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_EVIL)) + if (f & TR_SLAY_EVIL) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 2, "Evil:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_UNDEAD)) + if (f & TR_SLAY_UNDEAD) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Undead:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_DEMON)) + if (f & TR_SLAY_DEMON) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Demons:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_ORC)) + if (f & TR_SLAY_ORC) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Orcs:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_TROLL)) + if (f & TR_SLAY_TROLL) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Trolls:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_GIANT)) + if (f & TR_SLAY_GIANT) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Giants:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_SLAY_DRAGON)) + if (f & TR_SLAY_DRAGON) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Dragons:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_KILL_DRAGON)) + if (f & TR_KILL_DRAGON) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 5, "Dragons:", - f1, f2, f3, TERM_YELLOW); + TERM_YELLOW); } - if (f1 & (TR1_BRAND_ACID)) + if (f & TR_BRAND_ACID) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Acid:", - f1, f2, f3, TERM_RED); + TERM_RED); } - if (f1 & (TR1_BRAND_ELEC)) + if (f & TR_BRAND_ELEC) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Elec:", - f1, f2, f3, TERM_RED); + TERM_RED); } - if (f1 & (TR1_BRAND_FIRE)) + if (f & TR_BRAND_FIRE) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Fire:", - f1, f2, f3, TERM_RED); + TERM_RED); } - if (f1 & (TR1_BRAND_COLD)) + if (f & TR_BRAND_COLD) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Cold:", - f1, f2, f3, TERM_RED); + TERM_RED); } - if (f1 & (TR1_BRAND_POIS)) + if (f & TR_BRAND_POIS) { compare_weapon_aux2(o_ptr, p_ptr->num_blow, r++, col, 3, "Poison:", - f1, f2, f3, TERM_RED); + TERM_RED); } } @@ -1023,7 +894,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); } @@ -1031,36 +902,30 @@ static bool_ item_tester_hook_melee_weapon(object_type *o_ptr) /* * compare_weapons -KMW- */ -static bool_ compare_weapons(void) +static bool_ compare_weapons() { - 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 +936,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); @@ -1121,8 +986,7 @@ static bool_ compare_weapons(void) * sharpen arrows, repair armor, repair weapon * -KMW- */ -static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac, - int ireward, bool_ set_reward) +static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac) { int i; @@ -1216,403 +1080,25 @@ static bool_ fix_item(int istart, int iend, int ispecific, bool_ iac, /* * Research Item */ -static bool_ research_item(void) +static bool_ research_item() { clear_bldg(5, 18); return (identify_fully()); } -/* - * 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 */ -bool_ bldg_process_command(store_type *s_ptr, int i) +bool_ bldg_process_command(const store_type *s_ptr, store_action_type const *ba_ptr) { - store_action_type *ba_ptr = &ba_info[st_info[s_ptr->st_idx].actions[i]]; - int bact = ba_ptr->action; int bcost; bool_ paid = FALSE; - bool_ set_reward = FALSE; - bool_ recreate = FALSE; @@ -1638,22 +1124,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) { @@ -1662,8 +1132,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i) return FALSE; } - if (!bcost) set_reward = TRUE; - switch (bact) { case BACT_RESEARCH_ITEM: @@ -1685,9 +1153,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 +1186,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: { @@ -1754,12 +1208,6 @@ bool_ bldg_process_command(store_type *s_ptr, int i) break; } - case BACT_RESEARCH_MONSTER: - { - paid = !research_mon(); - break; - } - case BACT_COMPARE_WEAPONS: { paid = compare_weapons(); @@ -1768,15 +1216,13 @@ bool_ bldg_process_command(store_type *s_ptr, int i) case BACT_ENCHANT_WEAPON: { - paid = fix_item(INVEN_WIELD, INVEN_WIELD, 0, FALSE, - BACT_ENCHANT_WEAPON, set_reward); + paid = fix_item(INVEN_WIELD, INVEN_WIELD, 0, FALSE); break; } case BACT_ENCHANT_ARMOR: { - paid = fix_item(INVEN_BODY, INVEN_FEET, 0, TRUE, - BACT_ENCHANT_ARMOR, set_reward); + paid = fix_item(INVEN_BODY, INVEN_FEET, 0, TRUE); break; } @@ -1842,15 +1288,13 @@ bool_ bldg_process_command(store_type *s_ptr, int i) case BACT_ENCHANT_ARROWS: { - paid = fix_item(0, INVEN_WIELD, TV_ARROW, FALSE, - BACT_ENCHANT_ARROWS, set_reward); + paid = fix_item(0, INVEN_WIELD, TV_ARROW, FALSE); break; } case BACT_ENCHANT_BOW: { - paid = fix_item(INVEN_BOW, INVEN_BOW, TV_BOW, FALSE, - BACT_ENCHANT_BOW, set_reward); + paid = fix_item(INVEN_BOW, INVEN_BOW, TV_BOW, FALSE); break; } @@ -1880,30 +1324,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,92 +1373,41 @@ 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); + case BACT_DROP_ITEM: + { + quest_bounty_drop_item(); + break; + } - req = get_quantity(prompt, req); + case BACT_GET_ITEM: + { + quest_bounty_get_item(); + break; + } - p_ptr->loan -= req; - p_ptr->au -= req; + case BACT_LIBRARY_QUEST: + { + quest_library_building(&paid, &recreate); + break; + } - if (!p_ptr->loan) p_ptr->loan_time = 0; + case BACT_FIREPROOF_QUEST: + { + quest_fireproof_building(&paid, &recreate); + break; + } - msg_format("You pay back %i gold pieces", req); - paid = TRUE; - break; - } + case BACT_EREBOR_KEY: + { + msg_print("You will need Thorin's Key and Thrain's Map" + " to get anywhere in Erebor. One may be found" + " in the Barrow-Downs. The other, in Mirkwood."); + break; + } 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) @@ -2056,7 +1425,7 @@ bool_ bldg_process_command(store_type *s_ptr, int i) /* * Enter quest level */ -void enter_quest(void) +void enter_quest() { if (!(cave[p_ptr->py][p_ptr->px].feat == FEAT_QUEST_ENTER)) { @@ -2078,121 +1447,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..3b3412fa --- /dev/null +++ b/src/bldg.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "h-basic.h" +#include "store_action_type_fwd.hpp" +#include "store_type_fwd.hpp" + +bool_ bldg_process_command(store_type const *s_ptr, store_action_type const *action); +void show_building(store_type const *s_ptr); +bool_ is_state(store_type const *s_ptr, int state); +void enter_quest(); 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/carbon/Angband.icns b/src/carbon/Angband.icns Binary files differdeleted file mode 100644 index 3d775739..00000000 --- a/src/carbon/Angband.icns +++ /dev/null diff --git a/src/carbon/Carbon.r b/src/carbon/Carbon.r deleted file mode 100644 index e3194dd2..00000000 --- a/src/carbon/Carbon.r +++ /dev/null @@ -1,1568 +0,0 @@ -/* - * Minimal Resources for T.o.M.E. - * - * Turned into human-readable and programmer-friendly format by pelpel - * - * - * This might help mac/non-mac coders to play, modify, hack and do - * whatever they like with this file. - * - * - * Header files and reasons for their inclusion: - * - * MacTypes.r - 'STR ' and 'STR#' - * Finder.r - 'BNDL' and 'FREF' - * Dialogs.r - 'ALRT', 'DITL' and 'DLOG' - * Menus.r - 'MENU' and 'MBAR' - * Processes.r - 'SIZE' - */ - -#include <MacTypes.r> -#include <Finder.r> -#include <Dialogs.r> -#include <Menus.r> -#include <Processes.r> - - -#ifndef MACH_O - -/* - * Signature - Who am I? - * Vanilla uses 'A271' - * ID should always be 0. - */ -#define AngbandSignature 'PrnA' - -type AngbandSignature as 'STR '; - -resource AngbandSignature (0, "Owner resource", purgeable) -{ - "T.o.M.E. 2.3.4" -}; - - -/* OS X Finder requires this to recognise a Carbon-compatible PEF binary */ -data 'plst' (0) -{ - "$00"; -}; - - -/* - * Inform system of program's characteristics - * ID should always be -1. - */ -resource 'SIZE' (-1) -{ - /* - * Flags dumped = 0101 1000 1100 0000 - */ - reserved, - - /* accepts/ignores suspend&resume events? */ - acceptSuspendResumeEvents, - - reserved, - - /* can use background null events */ - canBackground, - - /* activates own windows in response to OS events */ - doesActivateOnFGSwitch, - - /* app has a user interface */ - backgroundAndForeground, - - /* don't return mouse events in front window on resume */ - dontGetFrontClicks, - - /* applications use this */ - ignoreAppDiedEvents, - - /* works with 24- or 32-bit addr */ - is32BitCompatible, - - /* can use high-level events */ - isHighLevelEventAware, - - /* only local high-level events */ - onlyLocalHLEvents, - - /* can't use stationery documents */ - notStationeryAware, - - /* can't use inline services */ - dontUseTextEditServices, - - /* all windows redrawn when monitor(s) change */ - notDisplayManagerAware, - - reserved, - reserved, - - /* preferred memory size */ - 16 * (1024 * 1024), - - /* minimum memory size */ - 4 * (1024 * 1024) -}; - - -/* - * File types used by Angband - */ -resource 'FREF' (128, purgeable) -{ - /* file type */ - 'APPL', - - /* maps to icon list resource w/ local ID 0 in bundle resource */ - 0, - - /* leave empty string for name */ - "" -}; - -resource 'FREF' (129, purgeable) -{ - /* file type */ - 'SAVE', - - /* maps to icon list resource w/ local ID 1 in bundle resource */ - 1, - - /* leave empty string for name */ - "" -}; - -resource 'FREF' (130, purgeable) -{ - /* file type */ - 'TEXT', - - /* maps to icon list resource w/ local ID 2 in bundle resource */ - 2, - - /* leave empty string for name */ - "" -}; - -resource 'FREF' (131, purgeable) -{ - /* file type */ - 'DATA', - - /* maps to icon list resource w/ local ID 3 in bundle resource */ - 3, - - /* leave empty string for name */ - "" -}; - - -/* - * Bundle information - */ -resource 'BNDL' (128, purgeable) -{ - /* Our signature */ - AngbandSignature, - - /* resource ID of signature resource: should always be 0 */ - 0, - - { - /* mapping local IDs in 'FREF's to 'ICN#' IDs */ - 'ICN#', - { - /* local ID 0 -> ICN# 128 */ - 0, 128, - - /* local ID 1 -> ICN# 129 */ - 1, 129, - - /* local ID 2 -> ICN# 130 */ - 2, 130, - - /* local ID 3 -> ICN# 131 */ - 3, 131 - }, - - /* local res IDs for 'FREF's: no duplicates */ - 'FREF', - { - /* local ID 0 -> FREF 128 */ - 0, 128, - - /* local ID 1 -> FREF 129 */ - 1, 129, - - /* local ID 2 -> FREF 130 */ - 2, 130, - - /* local ID 3 -> FREF 131 */ - 3, 131 - } - } -}; - -#endif /* !MACH_O */ - -/* - * Menu definitions - */ -resource 'MENU' (128, preload) -{ - /* menu ID */ - 128, - - /* use standard definition proc */ - textMenuProc, - - /* everything but the divider is enabled */ - 0b11111111111111111111111111111101, - /* or we can use 0... */ - - /* enable the title */ - enabled, - - /* menu title */ - apple, - - /* its contents */ - { - /* First item */ - "About T.o.M.E. ...", noicon, nokey, nomark, plain; - - /* Second item - divider */ - "-", noicon, nokey, nomark, plain; - } -}; - -resource 'MENU' (129, preload) -{ - /* menu ID */ - 129, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000011011, - - /* enable the title */ - enabled, - - /* menu title */ - "File", - - /* its contents */ - { -#if 0 - /* item #1 */ - "New", noicon, "N", nomark, plain; - - /* item #2 */ - "Open", noicon, "O", nomark, plain; - - /* item #3 */ - "Import", noicon, "I", nomark, plain; -#endif - /* item #1 (was #4) */ - "Close", noicon, "W", nomark, plain; - - /* item #2 (was #5) */ - "Save", noicon, "S", nomark, plain; - - /* item #3 (was #6) */ - "-", noicon, nokey, nomark, plain; - - /* item #4 (was #7) */ - "Score", noicon, "H", nomark, plain; - - /* item #4 (was #7) */ - "Quit", noicon, "Q", nomark, plain; - } -}; - - -resource 'MENU' (130, preload) -{ - /* menu ID */ - 130, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000111101, - - /* enable the title */ - enabled, - - /* menu title */ - "Edit", - - /* its contents */ - { - /* item #1 */ - "Undo", noicon, "Z", nomark, plain; - - /* item #2 */ - "-", noicon, nokey, nomark, plain; - - /* item #3 */ - "Cut", noicon, "X", nomark, plain; - - /* item #4 */ - "Copy", noicon, "C", nomark, plain; - - /* item #5 */ - "Paste", noicon, "V", nomark, plain; - - /* item #6 */ - "Clear", noicon, nokey, nomark, plain; - } -}; - -resource 'MENU' (131, preload) -{ - /* menu ID */ - 131, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000011, - - /* enable the title */ - enabled, - - /* menu title */ - "Font", - - /* its contents */ - { - /* item #1 */ - "Bold", noicon, nokey, nomark, plain; - - /* item #2 */ - "Wide", noicon, nokey, nomark, plain; - - /* item #3 */ - "-", noicon, nokey, nomark, plain; - - /* the rest are supplied by the program */ - } -}; - -resource 'MENU' (132, preload) -{ - /* menu ID */ - 132, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000000, - - /* enable the title */ - enabled, - - /* menu title */ - "Size", - - /* its contents */ - { - /* Let the program fill it in */ - } -}; - -resource 'MENU' (133, preload) -{ - /* menu ID */ - 133, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000000, - - /* enable the title */ - enabled, - - /* menu title */ - "Windows", - - /* its contents */ - { - /* Let the program create them for us */ - } -}; - -resource 'MENU' (134, preload) -{ - /* menu ID */ - 134, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000011011, - - /* enable the title */ - enabled, - - /* menu title */ - "Special", - - /* its contents */ - { - /* item #1 */ - "Sound", noicon, nokey, nomark, plain; - - /* item #2 - 0x90 = 144 */ - "Graphics", noicon, hierarchicalMenu, "\0x90", plain; - - /* item #3 - 0x91 = 145 */ - "TileWidth", noicon, hierarchicalMenu, "\0x91", plain; - - /* item #4 - 0x92 = 146 */ - "TileHeight", noicon, hierarchicalMenu, "\0x92", plain; - - /* item #5 */ - "-", noicon, nokey, nomark, plain; - - /* item #6 */ - "Fiddle", noicon, nokey, nomark, plain; - - /* item #7 */ - "Wizard", noicon, nokey, nomark, plain; - } -}; - -/* Graphics submenu */ -resource 'MENU' (144, preload) -{ - /* menu ID */ - 144, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000111, - - /* enable the title */ - enabled, - - /* menu title (ignored) */ - "Graphics", - - /* menu items */ - { - /* item #1 */ - "None", noicon, nokey, nomark, plain; - - /* item #2 */ - "8x8", noicon, nokey, nomark, plain; - - /* item #3 */ - "16x16", noicon, nokey, nomark, plain; - - /* item #4 */ - "32x32", noicon, nokey, nomark, plain; - - /* item #5 */ - "-", noicon, nokey, nomark, plain; - - /* item #6 */ - "Enlarge tiles", noicon, nokey, nomark, plain; - } -}; - -/* Tilewidth submenu */ -resource 'MENU' (145, preload) -{ - /* menu ID */ - 145, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000000, - - /* enable the title */ - enabled, - - /* menu title */ - "TileWidth", - - /* its contents */ - { - /* Let the program create them for us */ - } -}; - -/* TileHeight submenu */ -resource 'MENU' (146, preload) -{ - /* menu ID */ - 146, - - /* use standard definition proc */ - textMenuProc, - - /* let the program enable/disable them */ - 0b00000000000000000000000000000000, - - /* enable the title */ - enabled, - - /* menu title */ - "TileHeight", - - /* its contents */ - { - /* Let the program create them for us */ - } -}; - -/* Menu bar definition */ -resource 'MBAR' (128, preload) -{ - { 128, 129, 130, 131, 132, 133, 134 } -}; - - -/* - * Dialogue item lists - */ -resource 'DITL' (129, purgeable) -{ - { - /** item #1 **/ - - /* bounding rect */ - { 45, 353, 65, 411 }, - - /* type */ - Button - { - /* enable flag */ - enabled, - - /* title */ - "OK" - }, - - /** item #2 **/ - - /* bounding rect */ - { 19, 68, 90, 339 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "^0" - }, - - /** item #3 **/ - - /* bounding rect */ - { 38, 21, 70, 53 }, - - /* type */ - Icon - { - /* enable flag */ - disabled, - - /* 'ICON' ID */ - 128 - } - } -}; - - -resource 'DITL' (128, purgeable) -{ - { - /** item #1 **/ - - /* bounding rect */ - { -4, 0, 225, 308 }, - - /* type */ - UserItem - { - /* enable flag */ - enabled - }, - - /** item #2 **/ - - /* bounding rect */ - { 7, 108, 24, 235 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "T.o.M.E. 2.3.3" - }, - - /** item #3 **/ - - /* bounding rect */ - { 36, 80, 53, 275 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Copyright (c) 1998-2003" - }, - - /** item #4 **/ - { 53, 122, 70, 220 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "DarkGod" - }, - - /** item #5 **/ - - /* bounding rect */ - { 70, 81, 87, 255 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "(darkgod@ifrance.com)" - }, - - /** item #6 **/ - - /* bounding rect */ - { 99, 88, 116, 266 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Original Copyright by" - }, - - /** item #7 **/ - - /* bounding rect */ - { 135, 92, 151, 255 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Robert A. Koeneke" - }, - - /** item #8 **/ - - /* bounding rect */ - { 119, 103, 135, 255 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "James E. Wilson" - }, - - /** item #9 **/ - - /* bounding rect */ - { 150, 112, 166, 255 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - "Ben Harrison" - }, - - /** item #10 */ - - /* bounding rect */ - { 166, 62, 182, 145 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Topi Ylinen" - }, - - /** item #11 **/ - - /* bounding rect */ - { 166, 148, 182, 294 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Robert Ruehlmann" - }, - - /** item #12 **/ - - /* bounding rect */ - { 190, 96, 207, 255 }, - - /* type */ - StaticText - { - /* enable flag */ - disabled, - - /* title */ - "Macintosh Version" - } - } -}; - -resource 'ALRT' (130, purgeable) -{ - /* bounding rect */ - { 144, 154, 283, 384 }, - - /* 'DITL' ID */ - 130, - - /* bold outline, draw alert and beeps */ - { - /* stage 4 */ - OK, visible, sound1; - - /* stage 3 */ - OK, visible, sound1; - - /* stage 2 */ - OK, visible, sound1; - - /* stage 1 */ - OK, visible, sound1; - }, - -#if ALRT_RezTemplateVersion == 1 - - /* centered to parent window */ - centerParentWindow - -#endif /* ALRT_RezTemplateVersion == 1 */ -}; - -resource 'ALRT' (129, purgeable) -{ - /* bounding rect */ - { 40, 40, 150, 471 }, - - /* 'DITL' ID */ - 129, - - /* bold outline, draw alert and beeps */ - { - /* stage 4 */ - OK, visible, sound1; - - /* stage 3 */ - OK, visible, sound1; - - /* stage 2 */ - OK, visible, sound1; - - /* stage 1 */ - OK, visible, sound1; - }, - -#if ALRT_RezTemplateVersion == 1 - - /* centered to parent window */ - centerParentWindow - -#endif /* ALRT_RezTemplateVersion == 1 */ -}; - -resource 'ALRT' (128, purgeable) -{ - /* bounding rect */ - { 40, 40, 150, 471 }, - - /* 'DITL' ID */ - 129, - - /* bold outline, draw alert and beeps */ - { - /* stage 4 */ - OK, visible, sound1; - - /* stage 3 */ - OK, visible, sound1; - - /* stage 2 */ - OK, visible, sound1; - - /* stage 1 */ - OK, visible, sound1; - }, - -#if ALRT_RezTemplateVersion == 1 - - /* centered to parent window */ - centerParentWindow - -#endif /* ALRT_RezTemplateVersion == 1 */ -}; - -resource 'DLOG' (128, purgeable) -{ - /* bounding rect */ - { 112, 202, 341, 512 }, - - /* procID */ - dBoxProc, - - /* visibility */ - invisible, - - /* has closebox? */ - noGoAway, - - /* refCon */ - 0x0, - - /* 'DITL' ID */ - 128, - - /* title */ - "", - -#if DLOG_RezTemplateVersion == 1 - - /* position */ - centerMainScreen - -#endif /* DLOG_RezTemplateVersion == 1 */ -}; - - -/* - * Additional resources for Carbon - */ -resource 'STR#' (128, purgeable) -{ - { - /* item #1 */ - "Please select the \"lib\" folder" - } -}; - - -/* - * Warning Icon (The ! one) - */ -data 'ICON' (128, purgeable) { - $"0001 8000 0003 C000 0003 C000 0006 6000" - $"0006 6000 000C 3000 000C 3000 0018 1800" - $"0019 9800 0033 CC00 0033 CC00 0063 C600" - $"0063 C600 00C3 C300 00C3 C300 0183 C180" - $"0183 C180 0303 C0C0 0303 C0C0 0603 C060" - $"0601 8060 0C01 8030 0C00 0030 1800 0018" - $"1801 8018 3003 C00C 3003 C00C 6001 8006" - $"6000 0006 C000 0003 FFFF FFFF 7FFF FFFE" -}; - - -#ifndef MACH_O - -/* - * The JRRT icons we all know and love: you are not expected to change these, - * unless you are afraid of Tolkien Estate solicitors... - */ - -data 'icl4' (129, purgeable) { - $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" - $"000F 0000 0000 0000 0000 0CFF 0000 0000" - $"000F 000F FFFF FFFF 0000 0CF0 F000 0000" - $"000F 000F 0F0F 0F0F 0000 0CF0 0F00 0000" - $"000F 0FFF FFFF FFFF FFFF FCF0 00F0 0000" - $"000F 0F0F 0F0F 0F0F 0F0F 0CF0 000F 0000" - $"000F 0FFF FFFF FFFF FFFF FCFF FFFF F000" - $"000F 000F 0F0F 0F0F 0000 00CC CCCC FC00" - $"000F 000F FFFF FFFF 0000 0000 0FF0 FC00" - $"000F 0000 000F 0F00 0000 0000 0F00 FC00" - $"000F 0000 000F FF00 0FFF FFFF FFF0 FC00" - $"000F 0000 000F 0F00 0F0F 0F0F 0F00 FC00" - $"000F 0FFF FFFF FFFF FFFF FFFF FFF0 FC00" - $"000F 0F0F 0F0F 0F0F 0F00 0000 0F00 FC00" - $"000F 0FFF FFFF FFFF F000 FFC0 0000 FC00" - $"000F 0F0F 0000 0000 00FF FC0F C000 FC00" - $"000F 0FFF 0000 00FC 000F FC0C 0FC0 FC00" - $"000F 0F0F 0000 00FF FFFF FFFF FFC0 FC00" - $"000F 0FFF FFFF 0FFC CFFF FFFC CFFC FC00" - $"000F 0F0F 0F0F 0CC0 FC0F FC0F CCC0 FC00" - $"000F 0FFF FFFF 0000 FC0F FC0F C000 FC00" - $"000F 0F0F 0F0F 0F00 0FFF FFFC 0000 FC00" - $"000F 0FFF FFFF FFF0 00FF FFC0 0000 FC00" - $"000F 0F0F 0F0F 0F00 0FCF FCF0 0000 FC00" - $"000F 0FFF FFFF FF0F FC0F FC0F FC00 FC00" - $"000F 0F0F 0F0F 0F0C C00F FC0C C000 FC00" - $"000F 0FFF FFFF FF00 0FCF FC00 0000 FC00" - $"000F 0F0F 0F0F 0F0F 0C0F FC00 0000 FC00" - $"000F 0FFF FFFF FFFF 000F CFFC 0000 FC00" - $"000F 0F0F 0F0F 0F0F 0FFC 0CC0 0000 FC00" - $"000F 0000 0000 0000 0CC0 0000 0000 FC00" - $"000F FFFF FFFF FFFF FFFF FFFF FFFF FC00" -}; - -data 'icl4' (130, purgeable) { - $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" - $"000F 0000 0000 0000 0000 0CFF 0000 0000" - $"000F 0000 0000 0000 0000 0CF0 F000 0000" - $"000F 0000 FFFF FFFF FFFF CCF0 0F00 0000" - $"000F 0000 CCCC CCCC CCCC CCF0 00F0 0000" - $"000F 0000 0000 0000 0000 0CF0 000F 0000" - $"000F 00FF FFFF FFFF FFFF CCFF FFFF F000" - $"000F 00CC CCCC CCCC CCCC C0CC CCCC FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F 00FF FFFF FFFF FFFF FFFF FFFC FC00" - $"000F 00CC CCCC CCCC CCCC CCCC CCCC FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F 00FF FFFF FFFF FFFF FFFF FFFC FC00" - $"000F 00CC CCCC CCCC CCCC CCCC CCCC FC00" - $"000F 0000 0000 0000 0000 FFC0 0000 FC00" - $"000F 00FF FFFF C000 00FF FC0F C000 FC00" - $"000F 00CC CCCC C0FC 000F FC0C 0FC0 FC00" - $"000F 0000 0000 00FF FFFF FFFF FFC0 FC00" - $"000F 00FF FFFC 0FFC CFFF FFFC CFFC FC00" - $"000F 00CC CCCC 0CC0 FC0F FC0F CCC0 FC00" - $"000F 0000 0000 0000 FC0F FC0F C000 FC00" - $"000F 0000 FFFF FC00 0FFF FFFC 0000 FC00" - $"000F 0000 CCCC CC00 00FF FFC0 0000 FC00" - $"000F 0000 0000 0000 0FCF FCF0 0000 FC00" - $"000F 00FF FFFF FC0F FC0F FC0F FC00 FC00" - $"000F 00CC CCCC CC0C C00F FC0C C000 FC00" - $"000F 0000 0000 0000 0FCF FC00 0000 FC00" - $"000F 00FF FFFF FFC0 0C0F FC00 0000 FC00" - $"000F 00CC CCCC CCC0 000F CFFC 0000 FC00" - $"000F 0000 0000 0000 0FFC 0CC0 0000 FC00" - $"000F 0000 0000 0000 0CC0 0000 0000 FC00" - $"000F FFFF FFFF FFFF FFFF FFFF FFFF FC00" -}; - -data 'icl4' (128, purgeable) { - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"F333 3333 3FFF 000F ED00 FFF3 3333 333F" - $"F333 333F F000 00FE D0ED 00FF F333 333F" - $"F333 33FF 0000 00DD 0FED 0FDF FF33 333F" - $"F333 3F00 0000 00FF 0ED0 00FD 00F3 333F" - $"F333 F000 0000 00CF FED0 00D0 000F 333F" - $"F33F 000F 0000 000F FED0 0000 0E00 F33F" - $"F3FF 00FF FFFF FFFF FFFF FFFF FFE0 FF3F" - $"F3F0 0FFF FFFF FFFF FFFF FFFF FFFE 0F3F" - $"FF00 FEED DDDD DDDF FEDD DDDD DDFF EDFF" - $"FF00 FDD0 000F FFFF FEFF FF00 0000 EDFF" - $"FF00 D000 00FF DDDF FEDD DFF0 0000 D0FF" - $"F000 0000 0FFD 000F FED0 00FE D000 000F" - $"F000 0000 0FFD 000F FED0 00FE D000 000F" - $"F000 0000 0FFD 000F FED0 00FE D000 000F" - $"F000 0000 00FF D00F FED0 0FFD 0000 000F" - $"F000 0000 000F FFFF FEFF FFD0 0000 000F" - $"F000 0000 000D DDFF FEFD DD00 0000 000F" - $"F000 0000 0000 0FFF FEFF 0000 0000 000F" - $"F000 0000 0000 FFDF FEDF F000 0000 000F" - $"FF00 0000 000F FD0F FED0 FF00 0000 00FF" - $"FF00 000F FFFF D00F FED0 0FFF FFD0 00FF" - $"FF00 0000 FFFD 000F FED0 00FF FD00 00FF" - $"F3F0 0000 DDD0 000F FED0 00DD D000 0F3F" - $"F3FF 0000 0000 F00F FED0 0000 0000 FF3F" - $"F33F 0000 000F DFDF FED0 0000 0000 F33F" - $"F333 F000 0000 FD0F FFD0 0000 000F 333F" - $"F333 3F00 0000 D00F FFF0 FFD0 00F3 333F" - $"F333 33FF 00F0 00FF FDFF FD00 FF33 333F" - $"F333 333F F00F FFFF D00D D00F F333 333F" - $"F333 3333 3FFF FFDD 0000 FFF3 3333 333F" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" -}; - -data 'icl4' (131, purgeable) { - $"000F FFFF FFFF FFFF FFFF FFF0 0000 0000" - $"000F 0000 0000 0000 0000 00FF 0000 0000" - $"000F 0F00 0F00 FF00 0FF0 00FC F000 0000" - $"000F 0FF0 FF0F 00F0 F00F 00FC 0F00 0000" - $"000F 0F0F 0F0F 00F0 F000 00FC 00F0 0000" - $"000F 0F00 0F0F FFF0 F000 00FC 000F 0000" - $"000F 0F00 0F0F 00F0 F00F 00FF FFFF F000" - $"000F 0F00 0F0F 00F0 0FF0 000C CCCC FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F FFFF FFFF FFFF FFFF FFFF FFFF FC00" - $"000F CCCC CCCC CCCC CCCC CCCC CCCC FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F 0000 0000 0000 0000 0000 0000 FC00" - $"000F 0000 0000 0000 0000 FFC0 0000 FC00" - $"000F 0000 0000 0000 00FF FC0F C000 FC00" - $"000F 0000 0000 00FC 000F FC0C 0FC0 FC00" - $"000F 0000 0000 00FF FFFF FFFF FFC0 FC00" - $"000F 0000 0000 0FFC CFFF FFFC CFFC FC00" - $"000F 0000 0000 0CC0 FC0F FC0F CCC0 FC00" - $"000F 0000 0000 0000 FC0F FC0F C000 FC00" - $"000F 0000 0000 0000 0FFF FFFC 0000 FC00" - $"000F 0000 0000 0000 00FF FFC0 0000 FC00" - $"000F 0000 0000 0000 0FCF FCF0 0000 FC00" - $"000F 0000 0000 000F FC0F FC0F FC00 FC00" - $"000F 0000 0000 000C C00F FC0C C000 FC00" - $"000F 0000 0000 0000 0FCF FC00 0000 FC00" - $"000F 0000 0000 0000 0C0F FC00 0000 FC00" - $"000F 0000 0000 0000 000F CFFC 0000 FC00" - $"000F 0000 0000 0000 0FFC 0CC0 0000 FC00" - $"000F 0000 0000 0000 0CC0 0000 0000 FC00" - $"000F FFFF FFFF FFFF FFFF FFFF FFFF FC00" -}; - -data 'ICN#' (128, purgeable) { - $"FFFF DFFF FFF1 8FFF FF83 23FF FF00 657F" - $"FC03 423F F801 C01F F101 C04F F3FF FFEF" - $"E7FF FFF7 CE01 C03B C81F FC0B C031 C603" - $"8061 C301 8061 C301 8061 C301 8031 C601" - $"801F FC01 8003 E001 8007 F001 800D D801" - $"C019 CC03 C1F1 C7C3 C0E1 C383 E001 C007" - $"F009 C00F F015 C00F F809 C01F FC01 EC3F" - $"FF23 B8FF FF9F 01FF FFFC 0FFF FFF3 FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" -}; - -data 'ICN#' (129, purgeable) { - $"1FFF FE00 1000 0300 11FF 0280 1155 0240" - $"17FF FA20 1555 5210 17FF FBF8 1155 0008" - $"11FF 0068 1014 0048 101C 7FE8 1014 5548" - $"17FF FFE8 1555 4008 17FF 8C08 1500 3908" - $"1702 1848 1503 FFC8 17F6 7E68 1550 9908" - $"17F0 9908 1554 7E08 17FE 3C08 1554 5A08" - $"17FD 9988 1554 1808 17FC 5808 1555 1808" - $"17FF 1608 1555 6008 1000 0008 1FFF FFF8" - $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" - $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" -}; - -data 'ICN#' (130, purgeable) { - $"1FFF FE00 1000 0300 1000 0280 10FF F240" - $"1000 0220 1000 0210 13FF F3F8 1000 0008" - $"1000 0008 13FF FFE8 1000 0008 1000 0008" - $"13FF FFE8 1000 0008 1000 0C08 13F0 3908" - $"1002 1848 1003 FFC8 13E6 7E68 1000 9908" - $"1000 9908 10F8 7E08 1000 3C08 1000 5A48" - $"13F9 9988 1000 1808 1000 5808 13FC 1808" - $"1000 1608 1000 6008 1000 0008 1FFF FFF8" - $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" - $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" -}; - -data 'ICN#' (131, purgeable) { - $"1FFF FE00 1000 0300 144C 6280 16D2 9240" - $"1552 8220 145E 8210 1452 93F8 1452 6008" - $"1000 0008 1FFF FFF8 1000 0008 1000 0008" - $"1000 0008 1000 0008 1000 0C08 1000 3908" - $"1002 1848 1003 FFC8 1006 7E68 1000 9908" - $"1000 9908 1000 7E08 1000 3C08 1000 5A48" - $"1001 9988 1000 1808 1000 5808 1000 1808" - $"1000 1608 1000 6008 1000 0008 1FFF FFF8" - $"1FFF FE00 1FFF FF00 1FFF FF80 1FFF FFC0" - $"1FFF FFE0 1FFF FFF0 1FFF FFF8 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" - $"1FFF FFFC 1FFF FFFC 1FFF FFFC 1FFF FFFC" -}; - -data 'ics#' (128, purgeable) { - $"FFFF F99F F18F FFFF E7E3 8991 8991 87E1" - $"83C1 85A1 9999 C183 E587 F18F F97F FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" -}; - -data 'ics#' (129, purgeable) { - $"7FF0 4018 5FD4 555E 5FC2 4412 5FFA 5502" - $"5F12 557E 5F3A 5556 5F3A 551A 4022 7FFE" - $"7FF0 7FF8 7FFC 7FFE 7FFE 7FFE 7FFE 7FFE" - $"7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE 7FFE" -}; - -data 'ics#' (130, purgeable) { - $"7FF0 4018 5FD4 401E 5FC2 4002 5FFA 4002" - $"5F12 407E 5F3A 4056 5F3A 401A 4022 7FFE" - $"7FF0 7FF8 7FFC 7FFE 7FFF 7FFF 7FFF 7FFF" - $"7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF" -}; - -data 'ics#' (131, purgeable) { - $"7FF0 4018 5FD4 5F9E 57C2 4002 7FFE 4002" - $"4012 407E 403A 4056 403A 401A 4022 7FFE" - $"7FF0 7FF8 7FFC 7FFE 7FFF 7FFF 7FFF 7FFF" - $"7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF" -}; - -data 'icl8' (129, purgeable) { - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F7 FFFF 0000 0000 0000 0000" - $"0000 00FF F5F5 F5FF FFFF FFFF FFFF FFFF" - $"F5F5 F5F5 F5F7 FFF5 FF00 0000 0000 0000" - $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF" - $"F5F5 F5F5 F5F7 FFF5 F5FF 0000 0000 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFF7 FFF5 F5F5 FF00 0000 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5FF" - $"F5FF F5FF F5F7 FFF5 F5F5 F5FF 0000 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFF7 FFFF FFFF FFFF FF00 0000" - $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF" - $"F5F5 F5F5 F5F5 F7F7 F7F7 F7F7 FFF7 0000" - $"0000 00FF F5F5 F5FF FFFF FFFF FFFF FFFF" - $"F5F5 F5F5 F5F5 F5F5 F5FF FFF5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5FF F5FF F5F5" - $"F5F5 F5F5 F5F5 F5F5 F5FF F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5FF FFFF F5F5" - $"F5FF FFFF FFFF FFFF FFFF FFF5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5FF F5FF F5F5" - $"F5FF F5FF F5FF F5FF F5FF F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFF5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5FF" - $"F5FF F5F5 F5F5 F5F5 F5FF F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFFF" - $"FFF5 F5F5 FFFF F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5F5 F5F5 F5F5 F5F5" - $"F5F5 FFFF FFF8 F7FF F8F6 F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF F5F5 F5F5 F5F5 FFF8" - $"F6F5 F5FF FFF8 F6F8 F6FF F8F6 FFF7 0000" - $"0000 00FF F5FF F5FF F5F5 F5F5 F5F5 FFFF" - $"FFFF FFFF FFFF FFFF FFFF F8F6 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF F5FF FFF8" - $"F8FF FFFF FFFF FFF8 F6FF FFF8 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5F8 F8F6" - $"FFF8 F6FF FFF8 F6FF F8F6 F6F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF F5F6 F6F5" - $"FFF8 F6FF FFF8 F6FF F8F6 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5F5" - $"F5FF FFFF FFFF FFF8 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFF5" - $"F5F5 FFFF FFFF F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5F5" - $"F5FF F8FF FFF8 FFF5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF F5FF" - $"FFF8 F6FF FFF8 F6FF FFF8 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5F8" - $"F8F6 F5FF FFF8 F6F8 F8F5 F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF F5F6" - $"F6FF F8FF FFF8 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5FF" - $"F5F8 F6FF FFF8 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5FF FFFF FFFF FFFF FFFF FFFF" - $"F5F6 F5FF F8FF FFF8 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5FF F5FF" - $"F5FF FFF8 F7F8 F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F8 F8F7 F6F6 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFF7 0000" -}; - -data 'icl8' (128, purgeable) { - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF F9FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFD7 D7D7 D7D7 D7D7 D7FF FFFF 0000 00FF" - $"FCF9 F7F7 FFFF FFD7 D7D7 D7D7 D7D7 6BFF" - $"FFD7 4747 4747 4747 FF00 0000 F5F5 FFFC" - $"F9F7 FCF8 F7F5 FFFF FF47 4747 4747 6BFF" - $"FFD7 4747 4747 FFFF 00F5 F5F5 F5F5 F9F9" - $"F7FF FCF8 F7FF F7FF F9FF 4747 4747 6BFF" - $"FFD7 4747 47FF 0000 F5F5 F5F5 F5F5 FFFF" - $"F7FC F9F7 F5F5 FFF9 F7F5 FF47 4747 6BFF" - $"FFD7 4747 FF00 F5F5 F5F5 F5F5 F5F5 F7FF" - $"FFFC F9F7 F5F5 F9F7 F5F5 F5FF 4747 6BFF" - $"FFD7 47FF 00F5 F5FF F5F5 F5F5 F5F5 F5FF" - $"FFFC F9F7 F5F5 F5F5 F5FC F5F5 FF47 6BFF" - $"FFD7 47FF 00F5 FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FCF5 FF47 6BFF" - $"FFD7 FF00 F5FF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFC F5FF 6BFF" - $"FFFF 00F7 FFFC FCF9 F9F9 F9F9 F9F9 F9FF" - $"FFFC F9F9 F9F9 F9F9 F9F9 FFFF FCF9 FFFF" - $"FFFF 00F7 FCF9 F9F7 F7F7 F7FF FFFF FFFF" - $"FFFC FFFF FFFF F7F7 F7F7 F7F7 FCF9 FFFF" - $"FFFF 00F7 F9F7 F7F5 F5F5 FFFF F8F8 F8FF" - $"FFFC F9F9 F9FF FFF7 F7F5 F5F7 F9F7 FFFF" - $"FFF5 F5F5 F7F5 F5F5 F5FF FFF9 F7F7 F7FF" - $"FFFC F9F7 F7F7 FFFC F8F7 F5F5 F7F7 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5FF FFF9 F7F5 F5FF" - $"FFFC F9F7 F5F5 FFFC F8F7 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5FF FFF9 F7F5 F5FF" - $"FFFC F9F7 F5F5 FFFC F8F7 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5F5 FFFF F9F7 F5FF" - $"FFFC F9F7 F5FF FFF8 F7F5 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5F5 F5FF FFFF FFFF" - $"FFFC FFFF FFFF F8F7 F5F5 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5F5 F5F9 F9F9 FFFF" - $"FFFC FFF9 F9F9 F7F5 F5F5 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5F5 F5F5 F5FF FFFF" - $"FFFC FFFF F7F7 F5F5 F5F5 F5F5 F5F5 F8FF" - $"FF00 F5F5 F5F5 F5F5 F5F5 F5F5 FFFF F9FF" - $"FFFC F9FF FFF5 F5F5 F5F5 F5F5 F5F5 F8FF" - $"FFFF F5F5 F5F5 F5F5 F5F5 F5FF FFF9 F7FF" - $"FFFC F9F7 FFFF F5F5 F5F5 F5F5 F5F8 FFFF" - $"FFFF F5F5 F5F5 F7FF FFFF FFFF F9F7 F5FF" - $"FFFC F9F7 F7FF FFFF FFFF F9F5 F5F8 FFFF" - $"FFFF F5F5 F5F5 F5F7 FFFF FFF9 F7F5 F5FF" - $"FFFC F9F7 F5F7 FFFF FFF9 F7F5 F5F8 FFFF" - $"FFD7 FFF5 F5F5 F5F7 F9F9 F9F7 F5F5 F5FF" - $"FFFC F9F7 F5F5 F9F9 F9F7 F5F5 F8FF 6BFF" - $"FFD7 47FF F5F5 F5F5 F7F7 F7F5 FFF6 F5FF" - $"FFFC F9F7 F5F5 F5F7 F7F5 F5F8 FF47 6BFF" - $"FFD7 47FF F5F5 F5F5 F5F5 F5FF F7FF F8FF" - $"FFFC F9F7 F5F5 F5F5 F5F5 F5F8 FF47 6BFF" - $"FFD7 4747 FFF5 F5F5 F5F5 F5F5 FFF8 F7FF" - $"FFFF F9F7 F5F5 F5F5 F5F5 F8FF 4747 6BFF" - $"FFD7 4747 47FF F5F5 F5F5 F5F5 F8F7 F5FF" - $"FFFF FFF7 FFFF F9F7 F8F8 FF47 4747 6BFF" - $"FFD7 4747 4747 FFFF F5F5 FFF5 F7F5 FFFF" - $"FFF8 FFFF FFF9 F7F8 FFFF 4747 4747 6BFF" - $"FFD7 4747 4747 4747 FFF5 F5FF FFFF FFFF" - $"F8F6 F5F9 F9F7 F5FF 4747 4747 4747 6BFF" - $"FFD7 6B6B 6B6B 6B6B 6BFF FFFF FFFF F8F8" - $"F8F8 F8F5 FFFF FF6B 6B6B 6B6B 6B6B 6BFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF F8F8 FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" -}; - -data 'icl8' (130, purgeable) { - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F8 FFFF 0000 0000 0000 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F8 FFF6 FF00 0000 0000 0000" - $"0000 00FF F5F5 F5F5 FFFF FFFF FFFF FFFF" - $"FFFF FFFF F8F8 FFF6 F6FF 0000 0000 0000" - $"0000 00FF F5F5 F5F5 F8F8 F8F8 F8F8 F8F8" - $"F8F8 F8F8 F8F8 FFF6 F6F6 FF00 0000 0000" - $"0000 00FF F5F5 F5F5 F6F6 F6F6 F6F6 F6F6" - $"F6F6 F6F6 F6F8 FFF6 F6F6 F6FF 0000 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF F8F8 FFFF FFFF FFFF FF00 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F8 F8F8" - $"F8F8 F8F8 F8F5 F8F8 F8F8 F8F8 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F6 F6F6" - $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFF8 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F8 F8F8" - $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F6 F6F6" - $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFF8 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F8 F8F8" - $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F6 F6F6" - $"F6F6 F6F6 FFFF F8F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF F8F5 F5F5" - $"F5F5 FFFF FFF8 F6FF F8F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F5 FFF8" - $"F5F5 F5FF FFF8 F5F8 F5FF F8F6 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F5 FFFF" - $"FFFF FFFF FFFF FFFF FFFF F8F6 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFF8 F6FF FFF8" - $"F8FF FFFF FFFF FFF8 F8FF FFF8 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F6F8 F8F5" - $"FFF8 F6FF FFF8 F6FF F8F8 F8F6 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F5 F5F5" - $"FFF8 F6FF FFF8 F6FF F8F6 F6F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 FFFF FFFF FFF8 F6F5" - $"F5FF FFFF FFFF FFF8 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F8F8 F8F8 F8F8 F6F5" - $"F5F5 FFFF FFFF F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F6F6 F6F6 F6F6 F6F5" - $"F5FF F8FF FFF8 FFF6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF FFF8 F6FF" - $"FFF8 F6FF FFF8 F6FF FFF8 F6F5 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F8 F6F8" - $"F8F6 F5FF FFF8 F6F8 F8F6 F5F5 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F6 F6F5" - $"F6FF F8FF FFF8 F6F6 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 FFFF FFFF FFFF FFFF F8F6" - $"F5F8 F6FF FFF8 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F8F8 F8F8 F8F8 F8F8 F8F6" - $"F5F6 F5FF F8FF FFF8 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F6F6 F6F6 F6F6 F6F6 F6F6" - $"F5FF FFF8 F6F8 F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F8 F8F6 F5F5 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFF7 0000" -}; - -data 'icl8' (131, purgeable) { - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FF00 0000 0000 0000 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F5 FFFF 0000 0000 0000 0000" - $"0000 00FF F5FF F5F5 F5FF F5F5 FFFF F5F5" - $"F5FF FFF5 F5F5 FFF8 FF00 0000 0000 0000" - $"0000 00FF F5FF FFF5 FFFF F5FF 00F5 FFF5" - $"FF00 00FF F5F5 FFF8 F6FF 0000 0000 0000" - $"0000 00FF F5FF F5FF F5FF F5FF F5F5 FFF5" - $"FF00 0000 F5F5 FFF8 F6F6 FF00 0000 0000" - $"0000 00FF F5FF F5F5 F5FF F5FF FFFF FFF5" - $"FF00 F5F5 F5F5 FFF8 F6F6 F6FF 0000 0000" - $"0000 00FF F5FF F5F5 F5FF F5FF F5F5 FFF5" - $"FF00 F5FF 00F5 FFFF FFFF FFFF FF00 0000" - $"0000 00FF F5FF F5F5 F5FF F5FF F5F5 FFF5" - $"00FF FF00 0000 F5F8 F8F8 F8F8 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F500 00F5 F5F5 F5F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFF7 0000" - $"0000 00FF F8F8 F8F8 F8F8 F8F8 F8F8 F8F8" - $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 F500 FFFF F8F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 FFFF FFF8 F6FF F8F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FFF8" - $"F5F5 F5FF FFF8 F5F8 F5FF F8F6 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 FFFF" - $"FFFF FFFF FFFF FFFF FFFF F8F6 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5FF FFF8" - $"F8FF FFFF FFFF FFF8 F8FF FFF8 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F8 F8F5" - $"FFF8 F6FF FFF8 F6FF F8F8 F8F6 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"FFF8 F6FF FFF8 F6FF F8F6 F6F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5FF FFFF FFFF FFF8 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F5 FFFF FFFF F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5FF F8FF FFF8 FFF6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF" - $"FFF8 F6FF FFF8 F6FF FFF8 F6F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F8" - $"F8F6 F5FF FFF8 F6F8 F8F6 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F6FF F8FF FFF8 F6F6 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F8 F6FF FFF8 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F6 F5FF F8FF FFF8 F6F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5FF FFF8 F6F8 F8F6 F5F5 F5F5 FFF7 0000" - $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" - $"F5F8 F8F6 F5F5 F6F5 F5F5 F5F5 FFF7 0000" - $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFF7 0000" -}; - -data 'ics8' (128, purgeable) { - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" - $"FF47 4747 FFFF F6FF FFF8 FFFF 4747 47FF" - $"FF47 47FF F6F6 F6FF FFF8 F6F6 FF47 47FF" - $"FF47 FFFF FFFF FFFF FFFF FFFF FFFF 47FF" - $"FF47 FFF8 F8FF FFFF FFFF FFF8 F8F8 47FF" - $"FFFF F8F6 FFF8 F8FF FFF8 F8FF F8F6 FFFF" - $"FFF6 F6F6 FFF8 F6FF FFF8 F6FF F8F6 F6FF" - $"FFF6 F6F6 F6FF FFFF FFFF FFF8 F6F6 F6FF" - $"FFF6 F6F6 F6F6 FFFF FFFF F8F6 F6F6 F6FF" - $"FFF6 F6F6 F6FF F8FF FFF8 FFF6 F6F6 F6FF" - $"FFFF F6FF FFF8 F6FF FFF8 F6FF FFF8 FFFF" - $"FFFF F6F8 F8F6 F6FF FFF8 F6F8 F8F8 47FF" - $"FF47 FFF6 F6FF F8FF FFF8 F6F6 F6FF 47FF" - $"FF47 47FF F6F8 F6FF FFF8 F6F6 FF47 47FF" - $"FF47 4747 FFFF F6FF F8FF FFFF 4747 47FF" - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" -}; - -data 'ics8' (129, purgeable) { - $"00FF FFFF FFFF FFFF FFFF FFFF 0000 0000" - $"00FF F5F5 F5F5 F5F5 F5F5 F5FF FF00 0000" - $"00FF F5FF FFFF FFFF FFFF F5FF F5FF 0000" - $"00FF F5FF F5FF F5FF F5FF F5FF FFFF FF00" - $"00FF F5FF FFFF FFFF FFFF F5F5 F5F5 FF00" - $"00FF F5F5 F5FF F5F5 F5F5 F5FF F5F5 FF00" - $"00FF F5FF FFFF FFFF FFFF FFFF FFF5 FF00" - $"00FF F5FF F5FF F5FF F5F5 F5F5 F5F5 FF00" - $"00FF F5FF FFFF FFFF F5F5 F5FF F5F5 FF00" - $"00FF F5FF F5FF F5FF F5FF FFFF FFFF FF00" - $"00FF F5FF FFFF FFFF F5F5 FFFF FF00 FF00" - $"00FF F5FF F5FF F5FF F5FF 00FF 00FF FF00" - $"00FF F5FF FFFF FFFF F5F5 FFFF FFF5 FF00" - $"00FF F5FF F5FF F5FF F5F5 F5FF FFF5 FF00" - $"00FF F5F5 F5F5 F5F5 F5F5 FFF5 F5F5 FF00" - $"00FF FFFF FFFF FFFF FFFF FFFF FFFF FF00" -}; - -data 'ics8' (130, purgeable) { - $"00FF FFFF FFFF FFFF FFFF FFFF 0000 0000" - $"00FF F5F5 F5F5 F5F5 F5F5 F5FF FF00 0000" - $"00FF F5FF FFFF FFFF FFFF F7FF F5FF 0000" - $"00FF F5F7 F7F7 F7F7 F7F7 F7FF FFFF FF00" - $"00FF F5FF FFFF FFFF FFFF F7F5 F5F5 FFF7" - $"00FF F5F7 F7F7 F7F7 F7F7 F7F5 F5F5 FFF7" - $"00FF F5FF FFFF FFFF FFFF FFFF FFF7 FFF7" - $"00FF F5F7 F7F7 F7F7 F7F7 F7F7 F7F7 FFF7" - $"00FF F5FF FFFF FFFF F7F5 F5FF F5F5 FFF7" - $"00FF F5F7 F7F7 F7F7 F7FF FFFF FFFF FFF7" - $"00FF F5FF FFFF FFFF F7F5 FFFF FFF5 FFF7" - $"00FF F5F7 F7F7 F7F7 F7FF F5FF F5FF FFF7" - $"00FF F5FF FFFF FFFF F7F5 FFFF FFF5 FFF7" - $"00FF F5F7 F7F7 F7F7 F7F5 F5FF FFF5 FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 FFF5 F5F5 FFF7" - $"00FF FFFF FFFF FFFF FFFF FFFF FFFF FFF7" -}; - -data 'ics8' (131, purgeable) { - $"00FF FFFF FFFF FFFF FFFF FFFF 0000 0000" - $"00FF F5F5 F5F5 F5F5 F5F5 F5FF FF00 0000" - $"00FF F5FF FFFF FFFF FFFF F5FF F5FF 0000" - $"00FF F5FF FFFF FFFF FF00 F5FF FFFF FF00" - $"00FF F5FF 00FF FFFF FFFF F5F5 F7F7 FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 FFF7" - $"00FF FFFF FFFF FFFF FFFF FFFF FFFF FFF7" - $"00FF F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 F5FF F5F5 FFF7" - $"00FF F5F5 F5F5 F5F5 F5FF FFFF FFFF FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 FFFF FFF5 FFF7" - $"00FF F5F5 F5F5 F5F5 F5FF F5FF F5FF FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 FFFF FFF5 FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 F5FF FFF5 FFF7" - $"00FF F5F5 F5F5 F5F5 F5F5 FFF5 F5F5 FFF7" - $"00FF FFFF FFFF FFFF FFFF FFFF FFFF FFF7" -}; - -data 'ics4' (128, purgeable) { - $"FFFF FFFF FFFF FFFF F333 FFCF FCFF 333F" - $"F33F CCCF FCCC F33F F3FF FFFF FFFF FF3F" - $"FFFC CFFF FFFC CCFF FFCC FCCF FCCF CCFF" - $"FCCC FCCF FCCF CCCF FCCC CFFF FFFC CCCF" - $"FCCC CCFF FFCC CCCF FCCC CFCF FCFC CCCF" - $"FFCF FCCF FCCF FCFF FFCC CCCF FCCC CCFF" - $"F3FC CFCF FCCC CF3F F33F CCCF FCCC F33F" - $"F333 FFCF CFFF 333F FFFF FFFF FFFF FFFF" -}; - -data 'ics4' (129, purgeable) { - $"0FFF FFFF FFFF 0000 0F00 0000 000F F000" - $"0F0F FFFF FF0F 0F00 0F0F 0F0F 0F0F FFF0" - $"0F0F FFFF FF00 00F0 0F00 0F00 000F 00F0" - $"0F0F FFFF FFFF F0F0 0F0F 0F0F 0000 00F0" - $"0F0F FFFF 000F 00F0 0F0F 0F0F 0FFF FFF0" - $"0F0F FFFF 00FF F0F0 0F0F 0F0F 0F0F 0FF0" - $"0F0F FFFF 00FF F0F0 0F0F 0F0F 000F F0F0" - $"0F00 0000 00F0 00F0 0FFF FFFF FFFF FFF0" -}; - -data 'ics4' (130, purgeable) { - $"0FFF FFFF FFFF 0000 0FCC CCCC CCCF F000" - $"0FCF FFFF FFCF CF00 0FCC CCCC CCCF FFF0" - $"0FCF FFFF FFCC CCFD 0FCC CCCC CCCC CCFD" - $"0FCF FFFF FFFF FCFD 0FCC CCCC CCCC CCFD" - $"0FCF FFFF CCCF CCFD 0FCC CCCC CFFF FFFD" - $"0FCF FFFF CCFF FCFD 0FCC CCCC CFCF CFFD" - $"0FCF FFFF CCFF FCFD 0FCC CCCC CCCF FCFD" - $"0FCC CCCC CCFC CCFD 0FFF FFFF FFFF FFFD" -}; - -data 'ics4' (131, purgeable) { - $"0FFF FFFF FFFF 0000 0FCC CCCC CCCF F000" - $"0FCF FFFF FFCF CF00 0FCF FFFF FCCF FFF0" - $"0FCF CFFF FFCC DDFD 0FCC CCCC CCCC CCFD" - $"0FFF FFFF FFFF FFFD 0FCC CCCC CCCC CCFD" - $"0FCC CCCC CCCF CCFD 0FCC CCCC CFFF FFFD" - $"0FCC CCCC CCFF FCFD 0FCC CCCC CFCF CFFD" - $"0FCC CCCC CCFF FCFD 0FCC CCCC CCCF FCFD" - $"0FCC CCCC CCFC CCFD 0FFF FFFF FFFF FFFD" -}; - -#endif /* !MACH_O */ - diff --git a/src/carbon/Data.icns b/src/carbon/Data.icns Binary files differdeleted file mode 100644 index dbaec173..00000000 --- a/src/carbon/Data.icns +++ /dev/null diff --git a/src/carbon/Edit.icns b/src/carbon/Edit.icns Binary files differdeleted file mode 100644 index 5e55c272..00000000 --- a/src/carbon/Edit.icns +++ /dev/null diff --git a/src/carbon/Image-DS_Store b/src/carbon/Image-DS_Store Binary files differdeleted file mode 100644 index efd42e72..00000000 --- a/src/carbon/Image-DS_Store +++ /dev/null diff --git a/src/carbon/Info.plist b/src/carbon/Info.plist deleted file mode 100644 index fff3fb15..00000000 --- a/src/carbon/Info.plist +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plist version="1.0"> - <dict> - <key>CFBundleName</key><string>T.o.M.E.</string> - <key>CFBundleDisplayName</key><string>T.o.M.E. (OS X)</string> - <key>CFBundleExecutable</key><string>tome</string> - <key>CFBundlePackageType</key><string>APPL</string> - <key>CFBundleSignature</key><string>PrnA</string> - <key>CFBundleVersion</key><string>2.3.4</string> - <key>CFBundleShortVersionString</key><string>234</string> - <key>CFBundleIconFile</key><string>Angband</string> - <key>CFBundleIdentifier</key><string>net.t-o-m-e.tome</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 game data</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>*</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> diff --git a/src/carbon/Save.icns b/src/carbon/Save.icns Binary files differdeleted file mode 100644 index 362f80f6..00000000 --- a/src/carbon/Save.icns +++ /dev/null diff --git a/src/carbon/getversion b/src/carbon/getversion deleted file mode 100755 index 786fd14b..00000000 --- a/src/carbon/getversion +++ /dev/null @@ -1,2 +0,0 @@ -#! /bin/sh -grep CFBundleVersion carbon/Info.plist | perl -pe "s,.*<string>([^<]*)<.*,\\1," diff --git a/src/cave.c b/src/cave.cc index d23fc44c..cad1506e 100644 --- a/src/cave.c +++ b/src/cave.cc @@ -1,10 +1,35 @@ -/* File: cave.c */ - -/* Purpose: low level dungeon routines -BEN- */ - - -#include "angband.h" - +#include "cave.hpp" + +#include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" +#include "feature_type.hpp" +#include "game.hpp" +#include "hook_enter_dungeon_in.hpp" +#include "monster2.hpp" +#include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" +#include "monster_type.hpp" +#include "object1.hpp" +#include "object_flag.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 "util.hpp" +#include "util.h" +#include "variable.h" +#include "variable.hpp" +#include "z-rand.hpp" + +#include <cassert> +#include <vector> +#include <iterator> +#include <algorithm> /* * Support for Adam Bolt's tileset, lighting and transparency effects @@ -44,15 +69,15 @@ int distance(int y1, int x1, int y2, int x2) */ static bool_ is_wall(cave_type *c_ptr) { - byte feat; - + auto const &f_info = game->edit_data.f_info; /* Handle feature mimics */ - if (c_ptr->mimic) feat = c_ptr->mimic; - else feat = c_ptr->feat; + byte const feat = c_ptr->mimic + ? c_ptr->mimic + : c_ptr->feat; /* Paranoia */ - if (feat >= max_f_idx) return FALSE; + if (feat >= f_info.size()) return FALSE; /* Vanilla floors and doors aren't considered to be walls */ if (feat < FEAT_SECRET) return FALSE; @@ -67,7 +92,7 @@ static bool_ is_wall(cave_type *c_ptr) if (feat == FEAT_SMALL_TREES) return TRUE; /* Normal cases: use the WALL flag in f_info.txt */ - return (f_info[feat].flags1 & FF1_WALL) ? TRUE : FALSE; + return (f_info[feat].flags & FF_WALL) ? TRUE : FALSE; } @@ -333,7 +358,7 @@ bool_ los(int y1, int x1, int y2, int x2) /* * Returns true if the player's grid is dark */ -bool_ no_lite(void) +bool_ no_lite() { return (!player_can_see_bold(p_ptr->py, p_ptr->px)); } @@ -347,27 +372,22 @@ 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); + if (artifact_p(o_ptr)) + { + return (FALSE); + } } /* Accept */ @@ -376,106 +396,73 @@ 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; - - switch (graphics_mode) - { - /* Text mode */ - case GRAPHICS_NONE: - { - n = strlen(image_monster_hack); - - /* Random symbol from set above */ - *cp = (image_monster_hack[rand_int(n)]); + auto const &r_info = game->edit_data.r_info; - /* Random color */ - *ap = randint(15); + // Cached state which keeps a list of all the "live" monster race entries. + static std::vector<size_t> *instance = nullptr; - break; - } - - /* Normal graphics */ - default: + // First-time initialization + if (!instance) + { + // Create the list of "live" indexes + instance = new std::vector<size_t>(); + // Start at 1 to avoid 'player' + for (size_t i = 1; i < r_info.size(); 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); -/* - * Hack -- Legal object codes - */ -static cptr image_object_hack = "?/|\\\"!$()_-=[]{},~"; + // 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; +} -/* - * 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; + auto const &k_info = game->edit_data.k_info; - switch (graphics_mode) + // Cached state which keeps a list of the "live" object_kind entries. + static std::vector<size_t> *instance = nullptr; + + // 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 < k_info.size(); 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,26 +485,8 @@ static void image_random(byte *ap, char *cp) } -/* - * The 16x16 tile of the terrain supports lighting - */ -#if 1 - -#define feat_supports_lighting(F) \ -((f_info[F].flags1 & FF1_SUPPORT_LIGHT) != 0) - -#else - -static bool_ feat_supports_lighting(byte feat) -{ - if (f_info[feat].flags1 & FF1_SUPPORT_LIGHT) return TRUE; - else return FALSE; -} - -#endif - -char get_shimmer_color() +static char get_shimmer_color() { switch (randint(7)) { @@ -542,50 +511,60 @@ char get_shimmer_color() /* - * Table of breath colors. Must match listings in a single set of - * monster spell flags. - * - * The value "255" is special. Monsters with that kind of breath - * may be any color. + * Breath color */ -static byte breath_to_attr[32][2] = -{ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { TERM_SLATE, TERM_L_DARK }, /* RF4_BRTH_ACID */ - { TERM_BLUE, TERM_L_BLUE }, /* RF4_BRTH_ELEC */ - { TERM_RED, TERM_L_RED }, /* RF4_BRTH_FIRE */ - { TERM_WHITE, TERM_L_WHITE }, /* RF4_BRTH_COLD */ - { TERM_GREEN, TERM_L_GREEN }, /* RF4_BRTH_POIS */ - { TERM_L_GREEN, TERM_GREEN }, /* RF4_BRTH_NETHR */ - { TERM_YELLOW, TERM_ORANGE }, /* RF4_BRTH_LITE */ - { TERM_L_DARK, TERM_SLATE }, /* RF4_BRTH_DARK */ - { TERM_L_UMBER, TERM_UMBER }, /* RF4_BRTH_CONFU */ - { TERM_YELLOW, TERM_L_UMBER }, /* RF4_BRTH_SOUND */ - { 255, 255 }, /* (any color) */ /* RF4_BRTH_CHAOS */ - { TERM_VIOLET, TERM_VIOLET }, /* RF4_BRTH_DISEN */ - { TERM_L_RED, TERM_VIOLET }, /* RF4_BRTH_NEXUS */ - { TERM_L_BLUE, TERM_L_BLUE }, /* RF4_BRTH_TIME */ - { TERM_L_WHITE, TERM_SLATE }, /* RF4_BRTH_INER */ - { TERM_L_WHITE, TERM_SLATE }, /* RF4_BRTH_GRAV */ - { TERM_UMBER, TERM_L_UMBER }, /* RF4_BRTH_SHARD */ - { TERM_ORANGE, TERM_RED }, /* RF4_BRTH_PLAS */ - { TERM_UMBER, TERM_L_UMBER }, /* RF4_BRTH_FORCE */ - { TERM_L_BLUE, TERM_WHITE }, /* RF4_BRTH_MANA */ - { 0, 0 }, /* */ - { TERM_GREEN, TERM_L_GREEN }, /* RF4_BRTH_NUKE */ - { 0, 0 }, /* */ - { TERM_WHITE, TERM_L_RED }, /* RF4_BRTH_DISINT */ +struct breath_color { + std::size_t breath_idx; + byte first_color; + byte second_color; }; /* + * Breath colors. The value "255" is special. Monsters with + * that kind of breath may be any color. + */ +static breath_color const *lookup_breath_color(std::size_t i) +{ + static breath_color breath_to_attr[] = + { + { SF_BR_ACID_IDX, TERM_SLATE, TERM_L_DARK }, + { SF_BR_ELEC_IDX, TERM_BLUE, TERM_L_BLUE }, + { SF_BR_FIRE_IDX, TERM_RED, TERM_L_RED }, + { SF_BR_COLD_IDX, TERM_WHITE, TERM_L_WHITE }, + { SF_BR_POIS_IDX, TERM_GREEN, TERM_L_GREEN }, + { SF_BR_NETH_IDX, TERM_L_GREEN, TERM_GREEN }, + { SF_BR_LITE_IDX, TERM_YELLOW, TERM_ORANGE }, + { SF_BR_DARK_IDX, TERM_L_DARK, TERM_SLATE }, + { SF_BR_CONF_IDX, TERM_L_UMBER, TERM_UMBER }, + { SF_BR_SOUN_IDX, TERM_YELLOW, TERM_L_UMBER }, + { SF_BR_CHAO_IDX, 255, 255 }, + { SF_BR_DISE_IDX, TERM_VIOLET, TERM_VIOLET }, + { SF_BR_NEXU_IDX, TERM_L_RED, TERM_VIOLET }, + { SF_BR_TIME_IDX, TERM_L_BLUE, TERM_L_BLUE }, + { SF_BR_INER_IDX, TERM_L_WHITE, TERM_SLATE }, + { SF_BR_GRAV_IDX, TERM_L_WHITE, TERM_SLATE }, + { SF_BR_SHAR_IDX, TERM_UMBER, TERM_L_UMBER }, + { SF_BR_PLAS_IDX, TERM_ORANGE, TERM_RED }, + { SF_BR_WALL_IDX, TERM_UMBER, TERM_L_UMBER }, + { SF_BR_MANA_IDX, TERM_L_BLUE, TERM_WHITE }, + { SF_BR_NUKE_IDX, TERM_GREEN, TERM_L_GREEN }, + { SF_BR_DISI_IDX, TERM_WHITE, TERM_L_RED }, + }; + + for (auto const &breath_color: breath_to_attr) + { + if (breath_color.breath_idx == i) + { + return &breath_color; + } + } + + return nullptr; +} + + +/* * Multi-hued monsters shimmer acording to their breaths. * * If a monster has only one kind of breath, it uses both colors @@ -594,13 +573,11 @@ static byte breath_to_attr[32][2] = * * If a monster does not breath anything, it can be any color. */ -static byte multi_hued_attr(monster_race *r_ptr) +static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr) { byte allowed_attrs[15]; - int i, j; - - int stored_colors = 0; + std::size_t stored_colors = 0; int breaths = 0; @@ -613,18 +590,22 @@ static byte multi_hued_attr(monster_race *r_ptr) if (!r_ptr->freq_inate) return (get_shimmer_color()); /* Check breaths */ - for (i = 0; i < 32; i++) + for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++) { bool_ stored = FALSE; /* Don't have that breath */ - if (!(r_ptr->flags4 & (1L << i))) continue; + if (!(r_ptr->spells.bit(i))) continue; - /* Get the first color of this breath */ - first_color = breath_to_attr[i][0]; + /* Find the breath in our list */ + auto breath_color = lookup_breath_color(i); + if (!breath_color) + { + continue; + } - /* Breath has no color associated with it */ - if (first_color == 0) continue; + /* Get the first color of this breath */ + first_color = breath_color->first_color; /* Monster can be of any color */ if (first_color == 255) return (randint(15)); @@ -638,7 +619,7 @@ static byte multi_hued_attr(monster_race *r_ptr) /* Always store the first color */ - for (j = 0; j < stored_colors; j++) + for (std::size_t j = 0; j < stored_colors; j++) { /* Already stored */ if (allowed_attrs[j] == first_color) stored = TRUE; @@ -655,7 +636,7 @@ static byte multi_hued_attr(monster_race *r_ptr) */ if (breaths == 1) { - second_color = breath_to_attr[i][1]; + second_color = breath_color->second_color; } } @@ -866,78 +847,36 @@ 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; + auto const &st_info = game->edit_data.st_info; + auto const &r_info = game->edit_data.r_info; + auto const &f_info = game->edit_data.f_info; + auto const &k_info = game->edit_data.k_info; 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; - - /* Apply "mimic" field */ - if (c_ptr->mimic) - { - feat = c_ptr->mimic; - } - else - { - feat = f_info[feat].mimic; - } + auto const feat = c_ptr->mimic + ? c_ptr->mimic + : f_info[c_ptr->feat].mimic + ; /* Access floor */ - f_ptr = &f_info[feat]; - - - /* Reset attr/char */ - *eap = 0; - *ecp = 0; + auto f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -965,77 +904,13 @@ 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; } - /* Mega-Hack 3 -- Traps don't have f_info entries either */ - if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL)) - { - /* Trap index */ - t_idx = c_ptr->t_idx; - - if (use_graphics && - (t_info[t_idx].g_attr != 0) && - (t_info[t_idx].g_char != 0)) - { - - 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; - } - - } - 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; - - /* 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; - - a = tmp % 16; - } - } - } - } - - /**** Step 2 -- Apply special random effects ****/ - if (!avoid_other && !avoid_shimmer && attr_mutable) + if (!options->avoid_other && !options->avoid_shimmer) { /* Special terrain effect */ if (c_ptr->effect) @@ -1044,7 +919,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, } /* Multi-hued attr */ - else if (f_ptr->flags1 & FF1_ATTR_MULTI) + else if (f_ptr->flags & FF_ATTR_MULTI) { a = f_ptr->shimmer[rand_int(7)]; } @@ -1057,7 +932,6 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, * Special lighting effects, if specified and applicable * This will never happen for * - any grids in the overhead map - * - traps * - (graphics modes) terrain features without corresponding * "darker" tiles. * @@ -1066,84 +940,50 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, */ /* view_special_lite: lighting effects for boring features */ - if (view_special_lite && - ((f_ptr->flags1 & (FF1_FLOOR | FF1_REMEMBER)) == FF1_FLOOR)) + if (options->view_special_lite && + ((f_ptr->flags & (FF_FLOOR | FF_REMEMBER)) == FF_FLOOR)) { - if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)) && - (attr_mutable || (graf_new && feat_supports_lighting(feat)))) + if (!p_ptr->wild_mode) { /* Handle "seen" grids */ if (info & (CAVE_SEEN)) { /* Only lit by "torch" light */ - if (view_yellow_lite && !(info & (CAVE_GLOW))) + if (options->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) + else if (options->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]; } } } /* view_granite_lite: lighting effects for walls and doors */ - else if (view_granite_lite && - (f_ptr->flags1 & (FF1_NO_VISION | FF1_DOOR))) + else if (options->view_granite_lite && + (f_ptr->flags & (FF_NO_VISION | FF_DOOR))) { - if (!p_ptr->wild_mode && !(info & (CAVE_TRDT)) && - (attr_mutable || (graf_new && feat_supports_lighting(feat)))) + if (!p_ptr->wild_mode) { /* Handle "seen" grids */ if (info & (CAVE_SEEN)) @@ -1154,44 +994,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) + else if (options->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 */ } } } @@ -1221,10 +1037,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; @@ -1232,40 +1044,31 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, /**** Layer 2 -- Objects ****/ - if (feat != FEAT_MON_TRAP) + for (auto const o_idx: c_ptr->o_idxs) { - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) - { - object_type * o_ptr; + /* Acquire object */ + object_type *o_ptr = &o_list[o_idx]; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; + /* Memorized objects */ + if (o_ptr->marked) + { + /* Normal char */ + *cp = object_char(o_ptr); - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + /* Normal attr */ + *ap = object_attr(o_ptr); - /* Memorized objects */ - if (o_ptr->marked) + /* Multi-hued attr */ + if (!options->avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI)) { - /* Normal char */ - *cp = object_char(o_ptr); - - /* Normal attr */ - *ap = object_attr(o_ptr); - - /* Multi-hued attr */ - if (!avoid_other && attr_mutable && - (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI)) - { - *ap = get_shimmer_color(); - } + *ap = get_shimmer_color(); + } - /* Hack -- hallucination */ - if (p_ptr->image) image_object(ap, cp); + /* Hack -- hallucination */ + if (p_ptr->image) image_object(ap, cp); - /* Done */ - break; - } + /* Done */ + break; } } @@ -1275,14 +1078,12 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, if (c_ptr->m_idx) { monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_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) @@ -1294,8 +1095,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 (!options->avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI)) { *ap = get_shimmer_color(); } @@ -1309,46 +1109,12 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, /* Visible monster */ if (m_ptr->ml) { - 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; /* Ignore weird codes */ - if (avoid_other) - { - /* Use char */ - *cp = c; - - /* Use attr */ - *ap = a; - } - - /* Special attr/char codes */ - else if (!attr_mutable) + if (options->avoid_other) { /* Use char */ *cp = c; @@ -1358,10 +1124,10 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, } /* Multi-hued monster */ - else if (r_ptr->flags1 & (RF1_ATTR_MULTI)) + else if (r_ptr->flags & RF_ATTR_MULTI) { /* Is it a shapechanger? */ - if (r_ptr->flags2 & (RF2_SHAPECHANGER)) + if (r_ptr->flags & RF_SHAPECHANGER) { image_random(ap, cp); } @@ -1369,7 +1135,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, *cp = c; /* Multi-hued attr */ - if (r_ptr->flags2 & (RF2_ATTR_ANY)) + if (r_ptr->flags & RF_ATTR_ANY) { *ap = randint(15); } @@ -1380,7 +1146,7 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, } /* Normal monster (not "clear" in any way) */ - else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR | RF1_CHAR_CLEAR))) + else if (!(r_ptr->flags & (RF_ATTR_CLEAR | RF_CHAR_CLEAR))) { /* Use char */ *cp = c; @@ -1406,14 +1172,14 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, else { /* Normal (non-clear char) monster */ - if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR))) + if (!(r_ptr->flags & RF_CHAR_CLEAR)) { /* Normal char */ *cp = c; } /* Normal (non-clear attr) monster */ - else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR))) + else if (!(r_ptr->flags & RF_ATTR_CLEAR)) { /* Normal attr */ *ap = a; @@ -1434,14 +1200,10 @@ void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp, if ((y == p_ptr->py) && (x == p_ptr->px) && (!p_ptr->invis || p_ptr->see_inv)) { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - - /* Reset attr/char */ - *eap = 0; - *ecp = 0; + auto r_ptr = &r_info[p_ptr->body_monster]; /* Get the "player" attr */ - if (!avoid_other && attr_mutable && (r_ptr->flags1 & RF1_ATTR_MULTI)) + if (!options->avoid_other && (r_ptr->flags & RF_ATTR_MULTI)) { a = get_shimmer_color(); } @@ -1453,67 +1215,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 (options->player_char_health) { - case GRAPHICS_NONE: - case GRAPHICS_IBM: - { - if (player_char_health) - { - 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 (player_symbols) - { - a = BMP_FIRST_PC_CLASS + p_ptr->pclass; - c = BMP_FIRST_PC_RACE + p_ptr->prace; - } - - break; - } + int percent = p_ptr->chp * 10 / p_ptr->mhp; - case GRAPHICS_ISO: - case GRAPHICS_NEW: + if (percent < 7) { - 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; + c = I2D(percent); + if (percent < 3) a = TERM_L_RED; } - } /* Save the info */ @@ -1525,61 +1236,41 @@ 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; + auto const &st_info = game->edit_data.st_info; + auto const &r_info = game->edit_data.r_info; + auto const &f_info = game->edit_data.f_info; + auto const &k_info = game->edit_data.k_info; 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; + /* Shorthand */ + auto const avoid_other = options->avoid_other; /**** Preparation ****/ /* Access the grid */ - c_ptr = &cave[y][x]; + auto const 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; - - /* Apply "mimic" field */ - if (c_ptr->mimic) - { - feat = c_ptr->mimic; - } - else - { - feat = f_info[feat].mimic; - } + auto const feat = c_ptr->mimic + ? c_ptr->mimic + : f_info[c_ptr->feat].mimic; /* Access floor */ - f_ptr = &f_info[feat]; + feature_type const *f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -1613,41 +1304,6 @@ void map_info_default(int y, int x, byte *ap, char *cp) a = TERM_VIOLET; } - /* Mega-Hack 3 -- Traps don't have f_info entries either */ - if ((info & (CAVE_TRDT)) && (feat != FEAT_ILLUS_WALL)) - { - /* Trap index */ - t_idx = c_ptr->t_idx; - - /* - * 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) - { - c = f_info[FEAT_TRAP].d_char; - } - - /* Add attr */ - a = t_info[t_idx].color; - - /* Get a new color with a strange formula :) */ - if (t_info[t_idx].flags & FTRAP_CHANGE) - { - s32b tmp; - - tmp = dun_level + dungeon_type + feat; - - a = tmp % 16; - } - } - - /**** Step 2 -- Apply special random effects ****/ if (!avoid_other) { @@ -1658,7 +1314,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* Multi-hued attr */ - else if (f_ptr->flags1 & FF1_ATTR_MULTI) + else if (f_ptr->flags & FF_ATTR_MULTI) { a = f_ptr->shimmer[rand_int(7)]; } @@ -1671,7 +1327,6 @@ void map_info_default(int y, int x, byte *ap, char *cp) * Special lighting effects, if specified and applicable * This will never happen for * - any grids in the overhead map - * - traps * - (graphics modes) terrain features without corresponding * "darker" tiles. * @@ -1680,16 +1335,16 @@ void map_info_default(int y, int x, byte *ap, char *cp) */ /* view_special_lite: lighting effects for boring features */ - if (view_special_lite && - ((f_ptr->flags1 & (FF1_FLOOR | FF1_REMEMBER)) == FF1_FLOOR)) + if (options->view_special_lite && + ((f_ptr->flags & (FF_FLOOR | FF_REMEMBER)) == FF_FLOOR)) { - if (!p_ptr->wild_mode && !(info & (CAVE_TRDT))) + if (!p_ptr->wild_mode) { /* Handle "seen" grids */ if (info & (CAVE_SEEN)) { /* Only lit by "torch" light */ - if (view_yellow_lite && !(info & (CAVE_GLOW))) + if (options->view_yellow_lite && !(info & (CAVE_GLOW))) { /* Use "yellow" */ a = TERM_YELLOW; @@ -1711,7 +1366,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* "Out-of-sight" glowing grids -- handle "view_bright_lite" */ - else if (view_bright_lite) + else if (options->view_bright_lite) { /* Use darker colour */ a = dark_attrs[a & 0xF]; @@ -1720,10 +1375,10 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* view_granite_lite: lighting effects for walls and doors */ - else if (view_granite_lite && - (f_ptr->flags1 & (FF1_NO_VISION | FF1_DOOR))) + else if (options->view_granite_lite && + (f_ptr->flags & (FF_NO_VISION | FF_DOOR))) { - if (!p_ptr->wild_mode && !(info & (CAVE_TRDT))) + if (!p_ptr->wild_mode) { /* Handle "seen" grids */ if (info & (CAVE_SEEN)) @@ -1739,7 +1394,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* Handle "view_bright_lite" */ - else if (view_bright_lite) + else if (options->view_bright_lite) { /* Use darker colour */ a = dark_attrs[a & 0xF]; @@ -1779,40 +1434,31 @@ void map_info_default(int y, int x, byte *ap, char *cp) /**** Layer 2 -- Objects ****/ - if (feat != FEAT_MON_TRAP) + for (auto const this_o_idx: c_ptr->o_idxs) { - for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) - { - object_type * o_ptr; + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; - /* Acquire object */ - o_ptr = &o_list[this_o_idx]; + /* Memorized objects */ + if (o_ptr->marked) + { + /* Normal char */ + *cp = object_char_default(o_ptr); - /* Acquire next object */ - next_o_idx = o_ptr->next_o_idx; + /* Normal attr */ + *ap = object_attr_default(o_ptr); - /* Memorized objects */ - if (o_ptr->marked) + /* Multi-hued attr */ + if (!avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI)) { - /* Normal char */ - *cp = object_char_default(o_ptr); - - /* Normal attr */ - *ap = object_attr_default(o_ptr); - - /* Multi-hued attr */ - if (!avoid_other && - (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI)) - { - *ap = get_shimmer_color(); - } + *ap = get_shimmer_color(); + } - /* Hack -- hallucination */ - if (p_ptr->image) image_object(ap, cp); + /* Hack -- hallucination */ + if (p_ptr->image) image_object(ap, cp); - /* Done */ - break; - } + /* Done */ + break; } } @@ -1822,14 +1468,12 @@ void map_info_default(int y, int x, byte *ap, char *cp) if (c_ptr->m_idx) { monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_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) @@ -1841,8 +1485,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].flags & TR_ATTR_MULTI)) { *ap = get_shimmer_color(); } @@ -1856,8 +1499,6 @@ void map_info_default(int y, int x, byte *ap, char *cp) /* Visible monster */ if (m_ptr->ml) { - monster_race *r_ptr = race_inf(m_ptr); - /* Default attr/char */ c = r_ptr->d_char; a = r_ptr->d_attr; @@ -1873,10 +1514,10 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* Multi-hued monster */ - else if (r_ptr->flags1 & (RF1_ATTR_MULTI)) + else if (r_ptr->flags & RF_ATTR_MULTI) { /* Is it a shapechanger? */ - if (r_ptr->flags2 & (RF2_SHAPECHANGER)) + if (r_ptr->flags & RF_SHAPECHANGER) { image_random(ap, cp); } @@ -1884,7 +1525,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) *cp = c; /* Multi-hued attr */ - if (r_ptr->flags2 & (RF2_ATTR_ANY)) + if (r_ptr->flags & RF_ATTR_ANY) { *ap = randint(15); } @@ -1895,7 +1536,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) } /* Normal monster (not "clear" in any way) */ - else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR | RF1_CHAR_CLEAR))) + else if (!(r_ptr->flags & (RF_ATTR_CLEAR | RF_CHAR_CLEAR))) { /* Use char */ *cp = c; @@ -1918,14 +1559,14 @@ void map_info_default(int y, int x, byte *ap, char *cp) else { /* Normal (non-clear char) monster */ - if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR))) + if (!(r_ptr->flags & RF_CHAR_CLEAR)) { /* Normal char */ *cp = c; } /* Normal (non-clear attr) monster */ - else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR))) + else if (!(r_ptr->flags & RF_ATTR_CLEAR)) { /* Normal attr */ *ap = a; @@ -1948,10 +1589,10 @@ void map_info_default(int y, int x, byte *ap, char *cp) (!p_ptr->invis || (p_ptr->invis && p_ptr->see_inv))) { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; /* Get the "player" attr */ - if (!avoid_other && (r_ptr->flags1 & RF1_ATTR_MULTI)) + if (!avoid_other && (r_ptr->flags & RF_ATTR_MULTI)) { a = get_shimmer_color(); } @@ -1968,10 +1609,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; } @@ -1981,7 +1618,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; } @@ -2011,24 +1647,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); - } } @@ -2080,20 +1698,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; @@ -2102,30 +1715,28 @@ void note_spot(int y, int x) if (c_ptr->m_idx) { monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_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; } } /* Hack -- memorize grids */ - if (!(info & (CAVE_MARK))) + if (!(info & CAVE_MARK)) { /* Memorise some "boring" grids */ if (cave_plain_floor_grid(c_ptr)) { /* Option -- memorise certain floors */ - if ((info & (CAVE_TRDT)) || - ((info & (CAVE_GLOW)) && view_perma_grids ) || - view_torch_grids) + if (((info & CAVE_GLOW) && options->view_perma_grids) || + options->view_torch_grids) { /* Memorize */ - c_ptr->info |= (CAVE_MARK); + c_ptr->info |= CAVE_MARK; } } @@ -2133,7 +1744,7 @@ void note_spot(int y, int x) else { /* Memorize */ - c_ptr->info |= (CAVE_MARK); + c_ptr->info |= CAVE_MARK; } } } @@ -2146,39 +1757,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); } } @@ -2192,17 +1781,17 @@ void lite_spot(int y, int x) * of both "lite_spot()" and "print_rel()", and that we use the * "lite_spot()" function to display the player grid, if needed. */ -void prt_map(void) +void prt_map() { int x, y; int v; /* Access the cursor state */ - (void)Term_get_cursor(&v); + Term_get_cursor(&v); /* Hide the cursor */ - (void)Term_set_cursor(0); + Term_set_cursor(0); /* Dump the map */ for (y = panel_row_min; y <= panel_row_max; y++) @@ -2210,33 +1799,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); } } @@ -2244,7 +1814,7 @@ void prt_map(void) lite_spot(p_ptr->py, p_ptr->px); /* Restore the cursor */ - (void)Term_set_cursor(v); + Term_set_cursor(v); } @@ -2342,9 +1912,9 @@ static byte priority_table[][2] = */ static byte priority(byte a, char c) { - int i, p0, p1; + auto const &f_info = game->edit_data.f_info; - feature_type *f_ptr; + int i, p0, p1; /* Scan the table */ for (i = 0; TRUE; i++) @@ -2359,7 +1929,7 @@ static byte priority(byte a, char c) p0 = priority_table[i][0]; /* Access the feature */ - f_ptr = &f_info[p0]; + auto f_ptr = &f_info[p0]; /* Check character and attribute, accept matches */ if ((f_ptr->x_char == c) && (f_ptr->x_attr == a)) return (p1); @@ -2392,23 +1962,12 @@ 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; - int hgt, wid, yrat, xrat, yfactor, xfactor; /* 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 */ @@ -2427,40 +1986,30 @@ void display_map(int *cy, int *cx) /* Save lighting effects */ - old_view_special_lite = view_special_lite; - old_view_granite_lite = view_granite_lite; + auto const old_view_special_lite = options->view_special_lite; + auto const old_view_granite_lite = options->view_granite_lite; /* Disable lighting effects */ - view_special_lite = FALSE; - view_granite_lite = FALSE; - + options->view_special_lite = FALSE; + options->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); - } + // Nothing there. + ma.push_back(std::vector<byte>(wid + 2, TERM_WHITE)); + mc.push_back(std::vector<char>(wid + 2, ' ')); - /* 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] = ' '; - - /* 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; @@ -2479,7 +2028,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); @@ -2531,58 +2080,16 @@ 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; - view_granite_lite = old_view_granite_lite; + options->view_special_lite = old_view_special_lite; + options->view_granite_lite = old_view_granite_lite; } @@ -2591,7 +2098,7 @@ void display_map(int *cy, int *cx) * * Currently, the "player" is displayed on the map. XXX XXX XXX */ -void do_cmd_view_map(void) +void do_cmd_view_map() { int cy, cx; int wid, hgt; @@ -3203,38 +2710,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) @@ -3286,14 +2761,12 @@ static void vinfo_init_aux(vinfo_hack *hack, int y, int x, long m) * a number which is too high, running this function, and using the * error messages to obtain the correct values. */ -errr vinfo_init(void) +errr vinfo_init() { int i, y, x; long m; - vinfo_hack *hack; - int num_grids = 0; int queue_head = 0; @@ -3302,8 +2775,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) @@ -3314,8 +2787,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) @@ -3331,25 +2804,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); } } @@ -3362,21 +2835,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)); @@ -3419,14 +2886,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) { @@ -3507,10 +2974,6 @@ errr vinfo_init(void) } - /* Kill hack */ - KILL(hack, vinfo_hack); - - /* Success */ return (0); } @@ -3520,7 +2983,7 @@ errr vinfo_init(void) /* * Forget the "CAVE_VIEW" grids, redrawing as needed */ -void forget_view(void) +void forget_view() { int i; @@ -3628,7 +3091,7 @@ void forget_view(void) * special grids. Because the actual number of required grids is bizarre, * we simply allocate twice as many as we would normally need. XXX XXX XXX */ -void update_view(void) +void update_view() { int i, o; int y, x; @@ -3808,31 +3271,12 @@ void update_view(void) int yy = (y < p_ptr->py) ? (y + 1) : (y > p_ptr->py) ? (y - 1) : y; int xx = (x < p_ptr->px) ? (x + 1) : (x > p_ptr->px) ? (x - 1) : x; -#ifdef UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION - - /* Check for "complex" illumination */ - if ((!(cave[yy][xx].info & (CAVE_WALL)) && - (cave[yy][xx].info & (CAVE_GLOW))) || - (!(cave[y][xx].info & (CAVE_WALL)) && - (cave[y][xx].info & (CAVE_GLOW))) || - (!(cave[yy][x].info & (CAVE_WALL)) && - (cave[yy][x].info & (CAVE_GLOW)))) - { - /* Mark as seen */ - info |= (CAVE_SEEN); - } - -#else /* UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION */ - /* Check for "simple" illumination */ if (cave[yy][xx].info & (CAVE_GLOW)) { /* Mark as seen */ info |= (CAVE_SEEN); } - -#endif /* UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION */ - } /* Save cave info */ @@ -3966,7 +3410,7 @@ void update_view(void) /* * Clear monster light */ -void forget_mon_lite(void) +void forget_mon_lite() { int i, y, x; @@ -4014,7 +3458,7 @@ void forget_mon_lite(void) * This function works within the current player's field of view * calculated by update_view(), so it should normally be called * whenever FoV is updated (== PU_VIEW | PU_MON_LITE). The other - * case is when RF9_HAS_LITE monsters have moved or dead. Monster + * case is when RF_HAS_LITE monsters have moved or dead. Monster * creation occurs out of LoS, so I chose not to take this into * consideration. * @@ -4031,8 +3475,10 @@ void forget_mon_lite(void) * or brighter light, and it doesn't work well with PernAngband's already * colourful terrain features in aesthetically pleasing ways... -- pelpel */ -void update_mon_lite(void) +void update_mon_lite() { + auto const &f_info = game->edit_data.f_info; + int i, y, x, d; int fy, fx; @@ -4109,7 +3555,6 @@ void update_mon_lite(void) for (i = 1; i < m_max; i++) { monster_type *m_ptr = &m_list[i]; - monster_race *r_ptr; /* Skip dead monsters */ if (!m_ptr->r_idx) continue; @@ -4117,11 +3562,11 @@ void update_mon_lite(void) /* Skip out-of-sight monsters (MAX_SIGHT + max radius) */ if (m_ptr->cdis > MAX_SIGHT + 1) continue; - /* Access monster race info (with possible ego mods) */ - r_ptr = race_info_idx(m_ptr->r_idx, m_ptr->ego); + /* Access monster race */ + auto r_ptr = m_ptr->race(); /* Skip monsters not carrying light source */ - if (!(r_ptr->flags9 & RF9_HAS_LITE)) continue; + if (!(r_ptr->flags & RF_HAS_LITE)) continue; /* Access the location */ fy = m_ptr->fy; @@ -4172,7 +3617,7 @@ void update_mon_lite(void) * * We don't have four sides for a wall grid, so... */ - if (invis && (f_info[c_ptr->feat].flags1 & FF1_NO_VISION)) continue; + if (invis && (f_info[c_ptr->feat].flags & FF_NO_VISION)) continue; /* Give monster light to the location */ c_ptr->info |= (CAVE_MLIT | CAVE_SEEN); @@ -4287,32 +3732,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; @@ -4372,12 +3791,12 @@ static void update_flow_aux(int y, int x, int n) * We do not need a priority queue because the cost from grid * to grid is always "one" and we process them in order. */ -void update_flow(void) +void update_flow() { int x, y, d; /* Hack -- disabled */ - if (!flow_by_sound) return; + if (!options->flow_by_sound) return; /* Paranoia -- make sure the array is empty */ if (temp_n) return; @@ -4440,31 +3859,14 @@ void update_flow(void) /* * Hack -- map the current panel (plus some) ala "magic mapping" */ -void map_area(void) +void map_area() { - int i, x, y, y1, y2, x1, x2; - - cave_type *c_ptr; - - - /* Pick an area to map */ - y1 = panel_row_min - randint(10); - y2 = panel_row_max + randint(10); - x1 = panel_col_min - randint(20); - x2 = panel_col_max + randint(20); - - /* Speed -- shrink to fit legal bounds */ - if (y1 < 1) y1 = 1; - if (y2 > cur_hgt - 2) y2 = cur_hgt - 2; - if (x1 < 1) x1 = 1; - if (x2 > cur_wid - 2) x2 = cur_wid - 2; - - /* Scan that area */ - for (y = y1; y <= y2; y++) + /* Scan the whole map */ + for (int y = 1; y < cur_hgt - 1; y++) { - for (x = x1; x <= x2; x++) + for (int x = 1; x < cur_wid - 1; x++) { - c_ptr = &cave[y][x]; + auto c_ptr = &cave[y][x]; /* All non-walls are "checked" */ if (!is_wall(c_ptr)) @@ -4477,7 +3879,7 @@ void map_area(void) } /* Memorize known walls */ - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { c_ptr = &cave[y + ddy_ddd[i]][x + ddx_ddd[i]]; @@ -4517,7 +3919,7 @@ void map_area(void) * since this would prevent the use of "view_torch_grids" as a method to * keep track of what grids have been observed directly. */ -void wiz_lite(void) +void wiz_lite() { int i, y, x; @@ -4548,12 +3950,11 @@ void wiz_lite(void) if (c_ptr->m_idx) { monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_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; } } @@ -4581,7 +3982,7 @@ void wiz_lite(void) } /* Normally, memorize floors (see above) */ - if (view_perma_grids && !view_torch_grids) + if (options->view_perma_grids && !options->view_torch_grids) { /* Memorize the grid */ c_ptr->info |= (CAVE_MARK); @@ -4601,7 +4002,7 @@ void wiz_lite(void) p_ptr->window |= (PW_OVERHEAD); } -void wiz_lite_extra(void) +void wiz_lite_extra() { int y, x; for (y = 0; y < cur_hgt; y++) @@ -4617,7 +4018,7 @@ void wiz_lite_extra(void) /* * Forget the dungeon map (ala "Thinking of Maud..."). */ -void wiz_dark(void) +void wiz_dark() { int i, y, x; @@ -4888,7 +4289,7 @@ void health_track(int m_idx) health_who = m_idx; /* Redraw (later) */ - p_ptr->redraw |= (PR_HEALTH); + p_ptr->redraw |= (PR_FRAME); } @@ -4927,15 +4328,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() { - /* Unused */ - unused_flag = unused_flag; - /* Cancel auto-commands */ /* command_new = 0; */ @@ -4946,7 +4342,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 */ @@ -4956,7 +4352,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 */ @@ -4969,51 +4365,50 @@ void disturb(int stop_search, int unused_flag) p_ptr->update |= (PU_TORCH); } - /* Cancel searching if requested */ - if (stop_search && p_ptr->searching) + /* Flush the input if requested */ + if (options->flush_disturb) { - /* Cancel */ - p_ptr->searching = FALSE; - - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - /* Redraw the state */ - p_ptr->redraw |= (PR_STATE); + flush(); } - - /* Flush the input if requested */ - if (flush_disturb) flush(); } + /* - * Hack -- Check if a level is a "quest" level + * Disturb if option 'disturb_state' is set. */ -int is_quest(int level) +void disturb_on_state() { - int i = random_quest_number(); + if (options->disturb_state) + { + disturb(); + } +} - /* Check quests */ - if (p_ptr->inside_quest) - return (p_ptr->inside_quest); - if (i) return (QUEST_RANDOM); - /* Nope */ - return (0); +/* + * Disturb if option 'disturb_other' is set. + */ +void disturb_on_other() +{ + if (options->disturb_other) + { + disturb(); + } } + /* * 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_flags & DF_PRINCIPAL) && + (random_quests[dun_level].type) && (!random_quests[dun_level].done) && (!is_randhero(dun_level))) { @@ -5025,6 +4420,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 */ @@ -5053,3 +4467,178 @@ 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) +{ + auto const &f_info = game->edit_data.f_info; + + return bool(f_info[c->feat].flags & FF_FLOOR); +} + + + +/** + * 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) +{ + auto const &f_info = game->edit_data.f_info; + + return + (f_info[c->feat].flags & FF_FLOOR) && + !(f_info[c->feat].flags & FF_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) +{ + auto const &f_info = game->edit_data.f_info; + + return !(f_info[c->feat].flags & FF_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) +{ + auto const &f_info = game->edit_data.f_info; + + return + (f_info[cave[y][x].feat].flags & FF_FLOOR) && + (cave[y][x].o_idxs.empty()) && + !(f_info[cave[y][x].feat].flags & FF_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) +{ + auto const &f_info = game->edit_data.f_info; + + return + (f_info[cave[y][x].feat].flags & FF_FLOOR) && + !(f_info[cave[y][x].feat].flags & FF_PERMANENT) && + (cave[y][x].o_idxs.empty()) && + (cave[y][x].m_idx == 0); +} + +bool cave_naked_bold2(int y, int x) +{ + auto const &f_info = game->edit_data.f_info; + + return + (f_info[cave[y][x].feat].flags & FF_FLOOR) && + (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) +{ + auto const &f_info = game->edit_data.f_info; + + return bool(f_info[c->feat].flags & FF_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..ce1631a1 --- /dev/null +++ b/src/cave.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "h-basic.h" +#include "cave_type_fwd.hpp" +#include "object_type_fwd.hpp" + +int distance(int y1, int x1, int y2, int x2); +bool_ los(int y1, int x1, int y2, int x2); +bool_ cave_valid_bold(int y, int x); +bool_ no_lite(); +void map_info_default(int y, int x, byte *ap, char *cp); +void move_cursor_relative(int row, int col); +void print_rel(char c, byte a, int y, int x); +void note_spot(int y, int x); +void lite_spot(int y, int x); +void prt_map(); +void display_map(int *cy, int *cx); +void do_cmd_view_map(); +errr vinfo_init(); +void forget_view(); +void update_view(); +void forget_mon_lite(); +void update_mon_lite(); +void update_flow(); +void map_area(); +void wiz_lite(); +void wiz_lite_extra(); +void wiz_dark(); +void cave_set_feat(int y, int x, int feat); +void place_floor(int y, int x); +void place_floor_convert_glass(int y, int x); +void place_filler(int y, int x); +void mmove2(int *y, int *x, int y1, int x1, int y2, int x2); +bool_ projectable(int y1, int x1, int y2, int x2); +void scatter(int *yp, int *xp, int y, int x, int d); +void health_track(int m_idx); +void monster_race_track(int r_idx, int ego); +void object_track(object_type *o_ptr); +void disturb(); +void disturb_on_state(); +void disturb_on_other(); +int is_quest(int level); +int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags); +bool cave_floor_bold(int y, int x); +bool cave_floor_grid(cave_type const *c); +bool cave_plain_floor_bold(int y, int x); +bool cave_plain_floor_grid(cave_type const *c); +bool cave_sight_bold(int y, int x); +bool cave_sight_grid(cave_type const *c); +bool cave_clean_bold(int y, int x); +bool cave_empty_bold(int y, int x); +bool cave_naked_bold(int y, int x); +bool cave_naked_bold2(int y, int x); +bool cave_perma_bold(int y, int x); +bool cave_perma_grid(cave_type const *c); +bool player_has_los_bold(int y, int x); +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..08e6002f --- /dev/null +++ b/src/cave_type.hpp @@ -0,0 +1,63 @@ +#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 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 49c0d38f..13edf0ff 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,7 +6,50 @@ * included in all such copies. */ -#include "angband.h" +#include "cmd1.hpp" + +#include "cave.hpp" +#include "cave_type.hpp" +#include "cmd4.hpp" +#include "cmd5.hpp" +#include "dungeon_info_type.hpp" +#include "feature_flag.hpp" +#include "feature_type.hpp" +#include "files.hpp" +#include "game.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_race_flag.hpp" +#include "monster_spell_flag.hpp" +#include "monster_type.hpp" +#include "object_flag.hpp" +#include "object1.hpp" +#include "object2.hpp" +#include "options.hpp" +#include "player_race_flag.hpp" +#include "player_type.hpp" +#include "skills.hpp" +#include "spells1.hpp" +#include "spells2.hpp" +#include "spells3.hpp" +#include "tables.hpp" +#include "util.hpp" +#include "util.h" +#include "variable.h" +#include "variable.hpp" +#include "wild.hpp" +#include "xtra1.hpp" +#include "xtra2.hpp" +#include "z-rand.hpp" + #define MAX_VAMPIRIC_DRAIN 100 @@ -201,13 +240,10 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, { int mult = 1; - monster_race *r_ptr = race_inf(m_ptr); - - u32b f1, f2, f3, f4, f5, esp; - + auto const r_ptr = m_ptr->race(); /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); /* Some "weapons" and "ammo" do extra damage */ switch (o_ptr->tval) @@ -223,150 +259,84 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, case TV_DIGGING: { /* Slay Animal */ - if ((f1 & (TR1_SLAY_ANIMAL)) && (r_ptr->flags3 & (RF3_ANIMAL))) + if ((f & TR_SLAY_ANIMAL) && (r_ptr->flags & RF_ANIMAL)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_ANIMAL); - } - if (mult < 2) mult = 2; } /* Slay Evil */ - if ((f1 & (TR1_SLAY_EVIL)) && (r_ptr->flags3 & (RF3_EVIL))) + if ((f & TR_SLAY_EVIL) && (r_ptr->flags & RF_EVIL)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_EVIL); - } - if (mult < 2) mult = 2; } /* Slay Undead */ - if ((f1 & (TR1_SLAY_UNDEAD)) && (r_ptr->flags3 & (RF3_UNDEAD))) + if ((f & TR_SLAY_UNDEAD) && (r_ptr->flags & RF_UNDEAD)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_UNDEAD); - } - if (mult < 3) mult = 3; } /* Slay Demon */ - if ((f1 & (TR1_SLAY_DEMON)) && (r_ptr->flags3 & (RF3_DEMON))) + if ((f & TR_SLAY_DEMON) && (r_ptr->flags & RF_DEMON)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_DEMON); - } - if (mult < 3) mult = 3; } /* Slay Orc */ - if ((f1 & (TR1_SLAY_ORC)) && (r_ptr->flags3 & (RF3_ORC))) + if ((f & TR_SLAY_ORC) && (r_ptr->flags & RF_ORC)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_ORC); - } - if (mult < 3) mult = 3; } /* Slay Troll */ - if ((f1 & (TR1_SLAY_TROLL)) && (r_ptr->flags3 & (RF3_TROLL))) + if ((f & TR_SLAY_TROLL) && (r_ptr->flags & RF_TROLL)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_TROLL); - } - if (mult < 3) mult = 3; } /* Slay Giant */ - if ((f1 & (TR1_SLAY_GIANT)) && (r_ptr->flags3 & (RF3_GIANT))) + if ((f & TR_SLAY_GIANT) && (r_ptr->flags & RF_GIANT)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_GIANT); - } - if (mult < 3) mult = 3; } /* Slay Dragon */ - if ((f1 & (TR1_SLAY_DRAGON)) && (r_ptr->flags3 & (RF3_DRAGON))) + if ((f & TR_SLAY_DRAGON) && (r_ptr->flags & RF_DRAGON)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_DRAGON); - } - if (mult < 3) mult = 3; } /* Execute Dragon */ - if ((f1 & (TR1_KILL_DRAGON)) && (r_ptr->flags3 & (RF3_DRAGON))) + if ((f & TR_KILL_DRAGON) && (r_ptr->flags & RF_DRAGON)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_DRAGON); - } - if (mult < 5) mult = 5; } /* Execute Undead */ - if ((f5 & (TR5_KILL_UNDEAD)) && (r_ptr->flags3 & (RF3_UNDEAD))) + if ((f & TR_KILL_UNDEAD) && (r_ptr->flags & RF_UNDEAD)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_UNDEAD); - } if (mult < 5) mult = 5; } /* Execute Demon */ - if ((f5 & (TR5_KILL_DEMON)) && (r_ptr->flags3 & (RF3_DEMON))) + if ((f & TR_KILL_DEMON) && (r_ptr->flags & RF_DEMON)) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_DEMON); - } - if (mult < 5) mult = 5; } /* Brand (Acid) */ - if (f1 & (TR1_BRAND_ACID)) + if (f & TR_BRAND_ACID) { - /* Notice immunity */ - if (r_ptr->flags3 & (RF3_IM_ACID)) + if (r_ptr->flags & RF_IM_ACID) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_ACID); - } + // No additional multiplier } - - /* Notice susceptibility */ - else if (r_ptr->flags9 & (RF9_SUSCEP_ACID)) + else if (r_ptr->flags & RF_SUSCEP_ACID) { - if (m_ptr->ml) - { - r_ptr->r_flags9 |= (RF9_SUSCEP_ACID); - } if (mult < 6) mult = 6; } - - /* Otherwise, take the damage */ else { if (mult < 3) mult = 3; @@ -374,28 +344,16 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, } /* Brand (Elec) */ - if (f1 & (TR1_BRAND_ELEC)) + if (f & TR_BRAND_ELEC) { - /* Notice immunity */ - if (r_ptr->flags3 & (RF3_IM_ELEC)) + if (r_ptr->flags & RF_IM_ELEC) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_ELEC); - } + // No additional multiplier } - - /* Notice susceptibility */ - else if (r_ptr->flags9 & (RF9_SUSCEP_ELEC)) + else if (r_ptr->flags & RF_SUSCEP_ELEC) { - if (m_ptr->ml) - { - r_ptr->r_flags9 |= (RF9_SUSCEP_ELEC); - } if (mult < 6) mult = 6; } - - /* Otherwise, take the damage */ else { if (mult < 3) mult = 3; @@ -403,28 +361,16 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, } /* Brand (Fire) */ - if (f1 & (TR1_BRAND_FIRE)) + if (f & TR_BRAND_FIRE) { - /* Notice immunity */ - if (r_ptr->flags3 & (RF3_IM_FIRE)) + if (r_ptr->flags & RF_IM_FIRE) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_FIRE); - } + // No additional multiplier } - - /* Notice susceptibility */ - else if (r_ptr->flags3 & (RF3_SUSCEP_FIRE)) + else if (r_ptr->flags & RF_SUSCEP_FIRE) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_SUSCEP_FIRE); - } if (mult < 6) mult = 6; } - - /* Otherwise, take the damage */ else { if (mult < 3) mult = 3; @@ -432,28 +378,16 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, } /* Brand (Cold) */ - if (f1 & (TR1_BRAND_COLD)) + if (f & TR_BRAND_COLD) { - /* Notice immunity */ - if (r_ptr->flags3 & (RF3_IM_COLD)) + if (r_ptr->flags & RF_IM_COLD) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_COLD); - } + // No additional multiplier } - - /* Notice susceptibility */ - else if (r_ptr->flags3 & (RF3_SUSCEP_COLD)) + else if (r_ptr->flags & RF_SUSCEP_COLD) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_SUSCEP_COLD); - } if (mult < 6) mult = 6; } - - /* Otherwise, take the damage */ else { if (mult < 3) mult = 3; @@ -461,29 +395,17 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, } /* Brand (Poison) */ - if (f1 & (TR1_BRAND_POIS) || (p_ptr->tim_poison)) + if ((f & TR_BRAND_POIS) || (p_ptr->tim_poison)) { - /* Notice immunity */ - if (r_ptr->flags3 & (RF3_IM_POIS)) + if (r_ptr->flags & RF_IM_POIS) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_POIS); - } + // No additional damage } - - /* Notice susceptibility */ - else if (r_ptr->flags9 & (RF9_SUSCEP_POIS)) + else if (r_ptr->flags & RF_SUSCEP_POIS) { - if (m_ptr->ml) - { - r_ptr->r_flags9 |= (RF9_SUSCEP_POIS); - } if (mult < 6) mult = 6; if (magik(95)) *special |= SPEC_POIS; } - - /* Otherwise, take the damage */ else { if (mult < 3) mult = 3; @@ -492,18 +414,12 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, } /* Wounding */ - if (f5 & (TR5_WOUNDING)) + if (f & TR_WOUNDING) { - /* Notice immunity */ - if (r_ptr->flags8 & (RF8_NO_CUT)) + if (r_ptr->flags & RF_NO_CUT) { - if (m_ptr->ml) - { - r_info[m_ptr->r_idx].r_flags8 |= (RF8_NO_CUT); - } + // No additional damage } - - /* Otherwise, take the damage */ else { if (magik(50)) *special |= SPEC_CUT; @@ -520,103 +436,6 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, /* - * Search for hidden things - */ -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; - - /* 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 (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]; - - /* Invisible trap */ - if ((c_ptr->t_idx != 0) && !(c_ptr->info & CAVE_TRDT)) - { - /* Pick a trap */ - pick_trap(y, x); - - /* Message */ - msg_print("You have found a trap."); - - /* Disturb */ - disturb(0, 0); - } - - /* Secret door */ - if (c_ptr->feat == FEAT_SECRET) - { - /* Message */ - msg_print("You have found a secret door."); - - /* Pick a door XXX XXX XXX */ - cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); - cave[y][x].mimic = 0; - lite_spot(y, x); - - /* Disturb */ - disturb(0, 0); - } - - /* 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; - - /* Skip non-chests */ - if (o_ptr->tval != TV_CHEST) continue; - - /* Skip non-trapped chests */ - if (!o_ptr->pval) continue; - - /* Identify once */ - if (!object_known_p(o_ptr)) - { - /* Message */ - msg_print("You have discovered a trap on the chest!"); - - /* Know the trap */ - object_known(o_ptr); - - /* Notice it */ - disturb(0, 0); - } - } - } - } - } -} - - - - -/* * Player "wants" to pick up an object or gold. * Note that we ONLY handle things that can be picked up. * See "move_player()" for handling of other things. @@ -630,48 +449,17 @@ void carry(int pickup) } -/* - * Handle player hitting a real trap - */ -static void hit_trap(void) +static void touch_zap_player(monster_type *m_ptr) { - bool_ ident = FALSE; - - cave_type *c_ptr; - - - /* Disturb the player */ - disturb(0, 0); + auto r_ptr = m_ptr->race(); - /* Get the cave grid */ - c_ptr = &cave[p_ptr->py][p_ptr->px]; - if (c_ptr->t_idx != 0) - { - ident = player_activate_trap_type(p_ptr->py, p_ptr->px, NULL, -1); - if (ident) - { - 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); - } - } -} - - -void touch_zap_player(monster_type *m_ptr) -{ - int aura_damage = 0; - - monster_race *r_ptr = race_inf(m_ptr); - - - if (r_ptr->flags2 & (RF2_AURA_FIRE)) + if (r_ptr->flags & RF_AURA_FIRE) { if (!(p_ptr->immune_fire)) { char aura_dam[80]; - aura_damage = + int aura_damage = damroll(1 + (m_ptr->level / 26), 1 + (m_ptr->level / 17)); /* Hack -- Get the "died from" name */ @@ -684,19 +472,18 @@ void touch_zap_player(monster_type *m_ptr) if (p_ptr->sensible_fire) aura_damage = (aura_damage + 2) * 2; take_hit(aura_damage, aura_dam); - r_ptr->r_flags2 |= RF2_AURA_FIRE; handle_stuff(); } } - if (r_ptr->flags2 & (RF2_AURA_ELEC)) + if (r_ptr->flags & RF_AURA_ELEC) { if (!(p_ptr->immune_elec)) { char aura_dam[80]; - aura_damage = + int aura_damage = damroll(1 + (m_ptr->level / 26), 1 + (m_ptr->level / 17)); /* Hack -- Get the "died from" name */ @@ -707,7 +494,6 @@ void touch_zap_player(monster_type *m_ptr) msg_print("You get zapped!"); take_hit(aura_damage, aura_dam); - r_ptr->r_flags2 |= RF2_AURA_ELEC; handle_stuff(); } } @@ -721,11 +507,9 @@ void touch_zap_player(monster_type *m_ptr) static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, int x, int y) { - monster_type *t_ptr = &m_list[m_idx]; + auto const &r_info = game->edit_data.r_info; - monster_race *r_ptr; - - monster_race *tr_ptr = race_inf(t_ptr); + monster_type *t_ptr = &m_list[m_idx]; int ap_cnt; @@ -733,8 +517,6 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, char t_name[80]; - cptr sym_name = symbiote_name(TRUE); - char temp[80]; bool_ blinked = FALSE, touched = FALSE; @@ -743,17 +525,15 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, byte x_saver = t_ptr->fx; - object_type *o_ptr; - - /* Get the carried monster */ - o_ptr = &p_ptr->inventory[INVEN_CARRY]; + auto o_ptr = &p_ptr->inventory[INVEN_CARRY]; if (!o_ptr->k_idx) return; - r_ptr = &r_info[o_ptr->pval]; + /* Get monster race of the symbiote */ + auto r_ptr = &r_info[o_ptr->pval]; /* Not allowed to attack */ - if (r_ptr->flags1 & RF1_NEVER_BLOW) return; + if (r_ptr->flags & RF_NEVER_BLOW) return; /* Total armor */ ac = t_ptr->ac; @@ -775,9 +555,6 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, /* Scan through all four blows */ for (ap_cnt = 0; ap_cnt < 4; ap_cnt++) { - bool_ visible = FALSE; - bool_ obvious = FALSE; - int power = 0; int damage = 0; @@ -801,9 +578,6 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, /* break; */ } - /* Extract visibility (before blink) */ - visible = TRUE; - /* Extract the attack "power" */ power = get_attack_power(effect); @@ -811,7 +585,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(); /* Describe the attack method */ switch (method) @@ -984,15 +758,14 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, /* Message */ if (act) { - strfmt(temp, act, t_name); + strnfmt(temp, sizeof(temp), act, t_name); if (t_ptr->ml) - msg_format("%s %s", sym_name, temp); + { + msg_format("%s %s", symbiote_name(true).c_str(), temp); + } } - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side); @@ -1147,16 +920,15 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, if (touched) { + auto tr_ptr = t_ptr->race(); /* Aura fire */ - if ((tr_ptr->flags2 & RF2_AURA_FIRE) && - !(r_ptr->flags3 & RF3_IM_FIRE)) + if ((tr_ptr->flags & RF_AURA_FIRE) && + !(r_ptr->flags & RF_IM_FIRE)) { if (t_ptr->ml) { blinked = FALSE; msg_format("You are suddenly very hot!"); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_FIRE; } project(m_idx, 0, p_ptr->py, p_ptr->px, damroll(1 + ((t_ptr->level) / 26), @@ -1165,15 +937,13 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, } /* Aura elec */ - if ((tr_ptr->flags2 & (RF2_AURA_ELEC)) && - !(r_ptr->flags3 & (RF3_IM_ELEC))) + if ((tr_ptr->flags & RF_AURA_ELEC) && + !(r_ptr->flags & RF_IM_ELEC)) { if (t_ptr->ml) { blinked = FALSE; msg_format("You get zapped!"); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_ELEC; } project(m_idx, 0, p_ptr->py, p_ptr->px, damroll(1 + ((t_ptr->level) / 26), @@ -1204,35 +974,20 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, case RBM_CHARGE: { /* Disturb */ - disturb(1, 0); + disturb(); /* Message */ - msg_format("%s misses %s.", sym_name, t_name); + msg_format("%s misses %s.", symbiote_name(true).c_str(), t_name); break; } } } - - - /* Analyze "visible" monsters only */ - if (visible) - { - /* Count "obvious" attacks (and ones that cause damage) */ - if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) - { - /* Count attacks of this type */ - if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) - { - r_ptr->r_blows[ap_cnt]++; - } - } - } } /* Blink away */ if (blinked) { - msg_format("You and %s flee laughing!", symbiote_name(FALSE)); + msg_format("You and %s flee laughing!", symbiote_name(false).c_str()); teleport_player(MAX_SIGHT * 2 + 5); } @@ -1245,11 +1000,11 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, int x, int y) { - monster_type *t_ptr = &m_list[m_idx]; + auto const &r_info = game->edit_data.r_info; - monster_race *r_ptr; + monster_type *t_ptr = &m_list[m_idx]; - monster_race *tr_ptr = race_inf(t_ptr); + auto tr_ptr = t_ptr->race(); int ap_cnt; @@ -1268,10 +1023,10 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, if (!p_ptr->body_monster) return; - r_ptr = race_info_idx(p_ptr->body_monster, 0); + auto r_ptr = &r_info[p_ptr->body_monster]; /* Not allowed to attack */ - if (r_ptr->flags1 & RF1_NEVER_BLOW) return; + if (r_ptr->flags & RF_NEVER_BLOW) return; /* Total armor */ ac = t_ptr->ac; @@ -1294,9 +1049,6 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, for (ap_cnt = 0; ap_cnt < (p_ptr->num_blow > 4) ? 4 : p_ptr->num_blow; ap_cnt++) { - bool_ visible = FALSE; - bool_ obvious = FALSE; - int power = 0; int damage = 0; @@ -1320,17 +1072,14 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, /* break; */ } - /* Extract visibility (before blink) */ - visible = TRUE; - /* Extract the attack "power" */ - effect = get_attack_power(effect); + power = get_attack_power(effect); /* Monster hits */ if (!effect || check_hit2(power, rlev, ac)) { /* Always disturbing */ - disturb(1, 0); + disturb(); /* Describe the attack method */ switch (method) @@ -1503,15 +1252,12 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, /* Message */ if (act) { - strfmt(temp, act, t_name); + strnfmt(temp, sizeof(temp), act, t_name); if (t_ptr->ml) msg_format("You %s", temp); } - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side) + p_ptr->to_d; @@ -1666,15 +1412,13 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, if (touched) { /* Aura fire */ - if ((tr_ptr->flags2 & RF2_AURA_FIRE) && - !(r_ptr->flags3 & RF3_IM_FIRE)) + if ((tr_ptr->flags & RF_AURA_FIRE) && + !(r_ptr->flags & RF_IM_FIRE)) { if (t_ptr->ml) { blinked = FALSE; msg_format("You are suddenly very hot!"); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_FIRE; } project(m_idx, 0, p_ptr->py, p_ptr->px, damroll(1 + ((t_ptr->level) / 26), @@ -1683,15 +1427,13 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, } /* Aura elec */ - if ((tr_ptr->flags2 & (RF2_AURA_ELEC)) && - !(r_ptr->flags3 & (RF3_IM_ELEC))) + if ((tr_ptr->flags & RF_AURA_ELEC) && + !(r_ptr->flags & RF_IM_ELEC)) { if (t_ptr->ml) { blinked = FALSE; msg_format("You get zapped!"); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_ELEC; } project(m_idx, 0, p_ptr->py, p_ptr->px, damroll(1 + ((t_ptr->level) / 26), @@ -1723,7 +1465,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, case RBM_CHARGE: { /* Disturb */ - disturb(1, 0); + disturb(); /* Message */ msg_format("You miss %s.", t_name); @@ -1732,21 +1474,6 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, } } } - - - /* Analyze "visible" monsters only */ - if (visible) - { - /* Count "obvious" attacks (and ones that cause damage) */ - if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) - { - /* Count attacks of this type */ - if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) - { - r_ptr->r_blows[ap_cnt]++; - } - } - } } /* Blink away */ @@ -1813,33 +1540,29 @@ static void flavored_attack(int percent, char *output) */ void attack_special(monster_type *m_ptr, s32b special, int dam) { - char m_name[80]; - - monster_race *r_ptr = race_inf(m_ptr); - + auto const r_ptr = m_ptr->race(); /* Extract monster name (or "it") */ + char m_name[80]; monster_desc(m_name, m_ptr, 0); /* Special - Cut monster */ if (special & SPEC_CUT) { - /* Cut the monster */ - if (r_ptr->flags8 & (RF8_NO_CUT)) + if (r_ptr->flags & RF_NO_CUT) { - if (m_ptr->ml) - { - r_info[m_ptr->r_idx].r_flags8 |= (RF8_NO_CUT); - } + // No damage } else if (rand_int(100) >= r_ptr->level) { - /* Already partially poisoned */ - if (m_ptr->bleeding) msg_format("%^s is bleeding more strongly.", - m_name); - /* Was not poisoned */ + if (m_ptr->bleeding) + { + msg_format("%^s is bleeding more strongly.", m_name); + } else + { msg_format("%^s is bleeding.", m_name); + } m_ptr->bleeding += dam * 2; } @@ -1848,36 +1571,33 @@ void attack_special(monster_type *m_ptr, s32b special, int dam) /* Special - Poison monster */ if (special & SPEC_POIS) { - /* Poison the monster */ - if (r_ptr->flags3 & (RF3_IM_POIS)) + if (r_ptr->flags & RF_IM_POIS) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_IM_POIS); - } + // No damage } - /* Notice susceptibility */ - else if (r_ptr->flags9 & (RF9_SUSCEP_POIS)) + else if (r_ptr->flags & RF_SUSCEP_POIS) { - if (m_ptr->ml) + if (m_ptr->poisoned) { - r_ptr->r_flags9 |= (RF9_SUSCEP_POIS); + msg_format("%^s is more poisoned.", m_name); } - /* Already partially poisoned */ - if (m_ptr->poisoned) msg_format("%^s is more poisoned.", m_name); - /* Was not poisoned */ else + { msg_format("%^s is poisoned.", m_name); + } m_ptr->poisoned += dam * 2; } else if (rand_int(100) >= r_ptr->level) { - /* Already partially poisoned */ - if (m_ptr->poisoned) msg_format("%^s is more poisoned.", m_name); - /* Was not poisoned */ + if (m_ptr->poisoned) + { + msg_format("%^s is more poisoned.", m_name); + } else + { msg_format("%^s is poisoned.", m_name); + } m_ptr->poisoned += dam; } @@ -1891,12 +1611,10 @@ void attack_special(monster_type *m_ptr, s32b special, int dam) static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) { s16b special_effect = 0, stun_effect = 0, times = 0; - martial_arts *ma_ptr, *old_ptr, *blow_table = ma_blows; - int resist_stun = 0, max = MAX_MA; - monster_race *r_ptr = race_inf(m_ptr); - char m_name[80]; + martial_arts *blow_table = ma_blows; + int resist_stun = 0; + int max = MAX_MA; bool_ desc = FALSE; - bool_ done_crit; int plev = p_ptr->lev; if ((!p_ptr->body_monster) && (p_ptr->mimic_form == resolve_mimic_name("Bear")) && @@ -1912,17 +1630,16 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) max = MAX_MA; plev = get_skill(SKILL_HAND); } - ma_ptr = &blow_table[0]; - old_ptr = &blow_table[0]; + martial_arts *ma_ptr = &blow_table[0]; + martial_arts *old_ptr = &blow_table[0]; /* Extract monster name (or "it") */ - monster_desc(m_name, m_ptr, 0); - - if (r_ptr->flags1 & RF1_UNIQUE) resist_stun += 88; - if (r_ptr->flags3 & RF3_NO_CONF) resist_stun += 44; - if (r_ptr->flags3 & RF3_NO_SLEEP) resist_stun += 44; - if ((r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags3 & RF3_NONLIVING)) resist_stun += 88; + auto const r_ptr = m_ptr->race(); + if (r_ptr->flags & RF_UNIQUE) resist_stun += 88; + if (r_ptr->flags & RF_NO_CONF) resist_stun += 44; + if (r_ptr->flags & RF_NO_SLEEP) resist_stun += 44; + if ((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_NONLIVING)) resist_stun += 88; if (plev) { @@ -1940,7 +1657,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) { old_ptr = ma_ptr; - if (wizard && cheat_xtra) + if (wizard && options->cheat_xtra) { msg_print("Attack re-selected."); } @@ -1954,13 +1671,17 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) *k = damroll(ma_ptr->dd, ma_ptr->ds); + /* Extract name */ + char m_name[80]; + monster_desc(m_name, m_ptr, 0); + + /* Describe attack */ if (ma_ptr->effect & MA_KNEE) { - if (r_ptr->flags1 & RF1_MALE) + if (r_ptr->flags & RF_MALE) { if (!desc) msg_format("You hit %s in the groin with your knee!", m_name); - sound(SOUND_PAIN); special_effect = MA_KNEE; } else if (!desc) msg_format(ma_ptr->desc, m_name); @@ -1977,7 +1698,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) if (ma_ptr->effect & MA_SLOW) { if (! - ((r_ptr->flags1 & RF1_NEVER_MOVE) || + ((r_ptr->flags & RF_NEVER_MOVE) || strchr("UjmeEv$,DdsbBFIJQSXclnw!=?", r_ptr->d_char))) { if (!desc) msg_format("You kick %s in the ankle.", m_name); @@ -2007,6 +1728,7 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) desc = TRUE; } + bool_ done_crit; *k = critical_norm(plev * (randint(10)), ma_ptr->min_level, *k, -1, &done_crit); if ((special_effect & MA_KNEE) && ((*k + p_ptr->to_d) < m_ptr->hp)) @@ -2018,10 +1740,10 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) if (((special_effect & MA_FULL_SLOW) || (special_effect & MA_SLOW)) && ((*k + p_ptr->to_d) < m_ptr->hp)) { - if (!(r_ptr->flags1 & RF1_UNIQUE) && + if (!(r_ptr->flags & RF_UNIQUE) && (randint(plev) > m_ptr->level) && m_ptr->mspeed > 60) { - msg_format("%^s starts limping slower.", m_name); + msg_format("%^s starts limping.", m_name); m_ptr->mspeed -= 10; } } @@ -2044,27 +1766,28 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) /* * Apply nazgul effects */ -void do_nazgul(int *k, int *num, int num_blow, int weap, monster_race *r_ptr, +static void do_nazgul(int *k, int *num, int num_blow, int weap, std::shared_ptr<monster_race> r_ptr, object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - - bool_ mundane; bool_ allow_shatter = TRUE; /* Extract mundane-ness of the current weapon */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); /* It should be Slay Evil, Slay Undead, or *Slay Undead* */ - mundane = !(f1 & TR1_SLAY_EVIL) && !(f1 & TR1_SLAY_UNDEAD) && - !(f5 & TR5_KILL_UNDEAD); + bool_ const mundane = + !(f & TR_SLAY_EVIL) && + !(f & TR_SLAY_UNDEAD) && + !(f & TR_KILL_UNDEAD); /* Some blades can resist shattering */ - if (f5 & TR5_RES_MORGUL) + if (f & TR_RES_MORGUL) + { allow_shatter = FALSE; + } /* Mega Hack -- Hitting Nazgul is REALY dangerous (ideas from Akhronath) */ - if (r_ptr->flags7 & RF7_NAZGUL) + if (r_ptr->flags & RF_NAZGUL) { if ((!o_ptr->name2) && (!artifact_p(o_ptr)) && allow_shatter) { @@ -2141,6 +1864,8 @@ void do_nazgul(int *k, int *num, int num_blow, int weap, monster_race *r_ptr, */ void py_attack(int y, int x, int max_blow) { + auto const &r_info = game->edit_data.r_info; + int num = 0, k, bonus, chance; s32b special = 0; @@ -2149,12 +1874,6 @@ void py_attack(int y, int x, int max_blow) monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); - - object_type *o_ptr; - - char m_name[80]; - bool_ fear = FALSE; bool_ mdeath = FALSE; @@ -2177,15 +1896,12 @@ void py_attack(int y, int x, int max_blow) int drain_left = MAX_VAMPIRIC_DRAIN; - /* A massive hack -- life-draining weapons */ - u32b f1, f2, f3, f4, f5, esp; - int weap; /* Disturb the player */ - disturb(0, 0); + disturb(); - if (r_info[p_ptr->body_monster].flags1 & RF1_NEVER_BLOW) + if (r_info[p_ptr->body_monster].flags & RF_NEVER_BLOW) { msg_print("You cannot attack in this form!"); return; @@ -2209,15 +1925,9 @@ void py_attack(int y, int x, int max_blow) /* Extract monster name (or "it") */ + char m_name[80]; 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); @@ -2229,21 +1939,16 @@ void py_attack(int y, int x, int max_blow) !(p_ptr->stun || p_ptr->confused || p_ptr->image || !(m_ptr->ml))) { - if (!(p_ptr->inventory[INVEN_WIELD].art_name)) + // Only 'Stormbringer' can hit friendlies unless player forces attack. + if (p_ptr->inventory[INVEN_WIELD].artifact_name == "'Stormbringer'") { - msg_format("You stop to avoid hitting %s.", m_name); - return; + msg_format("Your black blade greedily attacks %s!", m_name); } - - if (! - (streq - (quark_str(p_ptr->inventory[INVEN_WIELD].art_name), "'Stormbringer'"))) + else { msg_format("You stop to avoid hitting %s.", m_name); return; } - - msg_format("Your black blade greedily attacks %s!", m_name); } /* Break goi/manashield */ @@ -2295,15 +2000,18 @@ void py_attack(int y, int x, int max_blow) num = 0; /* Access the weapon */ - o_ptr = &p_ptr->inventory[INVEN_WIELD + weap]; + object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD + weap]; + + /* Get race info */ + auto r_ptr = m_ptr->race(); /* Calculate the "attack quality" */ bonus = p_ptr->to_h + p_ptr->to_h_melee + o_ptr->to_h; chance = p_ptr->skill_thn + (bonus * BTH_PLUS_ADJ); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); - if (!(f4 & TR4_NEVER_BLOW)) + if (!(flags & TR_NEVER_BLOW)) { int num_blow = p_ptr->num_blow; @@ -2317,14 +2025,11 @@ void py_attack(int y, int x, int max_blow) /* Test for hit */ if (test_hit_norm(chance, m_ptr->ac, m_ptr->ml)) { - /* Sound */ - sound(SOUND_HIT); - /* Hack -- bare hands do one damage */ k = 1; /* Select a chaotic effect (50% chance) */ - if ((f1 & TR1_CHAOTIC) && (rand_int(2) == 0)) + if ((flags & TR_CHAOTIC) && (rand_int(2) == 0)) { if (randint(5) < 3) { @@ -2354,17 +2059,17 @@ void py_attack(int y, int x, int max_blow) } /* Vampiric drain */ - if ((f1 & TR1_VAMPIRIC) || (chaos_effect == 1)) + if ((flags & TR_VAMPIRIC) || (chaos_effect == 1)) { if (! - ((r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags3 & RF3_NONLIVING))) + ((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_NONLIVING))) drain_result = m_ptr->hp; else drain_result = 0; } - if (f1 & TR1_VORPAL && (randint(6) == 1)) + if ((flags & TR_VORPAL) && (randint(6) == 1)) vorpal_cut = TRUE; else vorpal_cut = FALSE; @@ -2403,7 +2108,7 @@ void py_attack(int y, int x, int max_blow) /* Stunning blow */ if (magik(get_skill(SKILL_STUN)) && (o_ptr->tval == TV_HAFTED) && (o_ptr->weight > 50) && done_crit) { - if (!(r_ptr->flags4 & (RF4_BR_SOUN)) && !(r_ptr->flags4 & (RF4_BR_WALL)) && k) + if (!(r_ptr->spells & SF_BR_SOUN) && !(r_ptr->spells & SF_BR_WALL) && k) { int tmp; @@ -2437,7 +2142,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)) { @@ -2464,9 +2169,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 = exec_lua("return get_level(MELKOR_CURSE, 100)"); + int lv = get_level_s(MELKOR_CURSE, 100); if (lv >= 10) { @@ -2475,13 +2180,13 @@ void py_attack(int y, int x, int max_blow) if (chance < 1) chance = 1; if ((p_ptr->grace > 5000) && magik(chance)) { - exec_lua(format("do_melkor_curse(%d)", c_ptr->m_idx)); + do_melkor_curse(c_ptr->m_idx); } } } /* May it clone the monster ? */ - if ((f4 & TR4_CLONE) && magik(30)) + if ((flags & TR_CLONE) && magik(30)) { msg_format("Oh no! Your weapon clones %^s!", m_name); @@ -2548,7 +2253,7 @@ void py_attack(int y, int x, int max_blow) /* Hack -- High-level warriors can spread their attacks out * among weaker foes. */ - if ((has_ability(AB_SPREAD_BLOWS)) && (num < num_blow) && + if ((p_ptr->has_ability(AB_SPREAD_BLOWS)) && (num < num_blow) && (energy_use)) { energy_use = energy_use * num / num_blow; @@ -2582,7 +2287,7 @@ void py_attack(int y, int x, int max_blow) { drain_heal = damroll(4, (drain_result / 6)); - if (cheat_xtra) + if (options->cheat_xtra) { msg_format("Draining left: %d", drain_left); } @@ -2624,13 +2329,8 @@ void py_attack(int y, int x, int max_blow) } /* Confuse the monster */ - if (r_ptr->flags3 & (RF3_NO_CONF)) + if (r_ptr->flags & RF_NO_CONF) { - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_NO_CONF); - } - msg_format("%^s is unaffected.", m_name); } else if (rand_int(100) < m_ptr->level) @@ -2655,8 +2355,8 @@ void py_attack(int y, int x, int max_blow) else if ((chaos_effect == 5) && cave_floor_bold(y, x) && (randint(90) > m_ptr->level)) { - if (!((r_ptr->flags1 & RF1_UNIQUE) || - (r_ptr->flags4 & RF4_BR_CHAO) || + if (!((r_ptr->flags & RF_UNIQUE) || + (r_ptr->spells & SF_BR_CHAO) || (m_ptr->mflag & MFLAG_QUEST))) { /* Handle polymorph */ @@ -2672,7 +2372,7 @@ void py_attack(int y, int x, int max_blow) monster_desc(m_name, m_ptr, 0); /* Hack -- Get new race */ - r_ptr = race_inf(m_ptr); + r_ptr = m_ptr->race(); fear = FALSE; } @@ -2691,9 +2391,6 @@ void py_attack(int y, int x, int max_blow) /* Player misses */ else { - /* Sound */ - sound(SOUND_MISS); - backstab = FALSE; /* Clumsy! */ /* Message */ @@ -2715,9 +2412,6 @@ void py_attack(int y, int x, int max_blow) /* Hack -- delay fear messages */ if (fear && m_ptr->ml) { - /* Sound */ - sound(SOUND_FLEE); - /* Message */ msg_format("%^s flees in terror!", m_name); } @@ -2733,136 +2427,18 @@ void py_attack(int y, int x, int max_blow) -static bool_ pattern_tile(int y, int x) -{ - return ((cave[y][x].feat <= FEAT_PATTERN_XTRA2) && - (cave[y][x].feat >= FEAT_PATTERN_START)); -} - - -static bool_ pattern_seq(int c_y, int c_x, int n_y, int n_x) -{ - if (!(pattern_tile(c_y, c_x)) && !(pattern_tile(n_y, n_x))) - return TRUE; - - if (cave[n_y][n_x].feat == FEAT_PATTERN_START) - { - if ((!(pattern_tile(c_y, c_x))) && - !(p_ptr->confused || p_ptr->stun || p_ptr->image)) - { - if (get_check - ("If you start walking the Straight Road, you must walk the whole way. Ok? ")) - return TRUE; - else - return FALSE; - } - else - return TRUE; - } - else if ((cave[n_y][n_x].feat == FEAT_PATTERN_OLD) || - (cave[n_y][n_x].feat == FEAT_PATTERN_END) || - (cave[n_y][n_x].feat == FEAT_PATTERN_XTRA2)) - { - if (pattern_tile(c_y, c_x)) - { - return TRUE; - } - else - { - msg_print - ("You must start walking the Straight Road from the startpoint."); - return FALSE; - } - } - else if ((cave[n_y][n_x].feat == FEAT_PATTERN_XTRA1) || - (cave[c_y][c_x].feat == FEAT_PATTERN_XTRA1)) - { - return TRUE; - } - else if (cave[c_y][c_x].feat == FEAT_PATTERN_START) - { - if (pattern_tile(n_y, n_x)) - return TRUE; - else - { - msg_print("You must walk the Straight Road in correct order."); - return FALSE; - } - } - else if ((cave[c_y][c_x].feat == FEAT_PATTERN_OLD) || - (cave[c_y][c_x].feat == FEAT_PATTERN_END) || - (cave[c_y][c_x].feat == FEAT_PATTERN_XTRA2)) - { - if (!pattern_tile(n_y, n_x)) - { - msg_print("You may not step off from the Straight Road."); - return FALSE; - } - else - { - return TRUE; - } - } - else - { - if (!pattern_tile(c_y, c_x)) - { - msg_print - ("You must start walking the Straight Road from the startpoint."); - return FALSE; - } - else - { - byte ok_move = FEAT_PATTERN_START; - switch (cave[c_y][c_x].feat) - { - case FEAT_PATTERN_1: - ok_move = FEAT_PATTERN_2; - break; - case FEAT_PATTERN_2: - ok_move = FEAT_PATTERN_3; - break; - case FEAT_PATTERN_3: - ok_move = FEAT_PATTERN_4; - break; - case FEAT_PATTERN_4: - ok_move = FEAT_PATTERN_1; - break; - default: - if (wizard) - msg_format("Funny Straight Road walking, %d.", - cave[c_y][c_x]); - return TRUE; /* Goof-up */ - } - - if ((cave[n_y][n_x].feat == ok_move) || - (cave[n_y][n_x].feat == cave[c_y][c_x].feat)) - return TRUE; - else - { - if (!pattern_tile(n_y, n_x)) - msg_print("You may not step off from the Straight Road."); - else - msg_print - ("You must walk the Straight Road in correct order."); - - return FALSE; - } - } - } -} - - - bool_ player_can_enter(byte feature) { + auto const &r_info = game->edit_data.r_info; + auto const &f_info = game->edit_data.f_info; + bool_ pass_wall; bool_ only_wall = FALSE; /* 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_flags_p(PR_SEMI_WRAITH))) pass_wall = TRUE; else pass_wall = FALSE; @@ -2898,32 +2474,135 @@ bool_ player_can_enter(byte feature) { if (p_ptr->fly || pass_wall || - (has_ability(AB_TREE_WALK)) || + p_ptr->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); } - if ((p_ptr->climb) && (f_info[feature].flags1 & FF1_CAN_CLIMB)) + if ((p_ptr->climb) && (f_info[feature].flags & FF_CAN_CLIMB)) return (TRUE); if ((p_ptr->fly) && - ((f_info[feature].flags1 & FF1_CAN_FLY) || - (f_info[feature].flags1 & FF1_CAN_LEVITATE))) + ((f_info[feature].flags & FF_CAN_FLY) || + (f_info[feature].flags & FF_CAN_LEVITATE))) return (TRUE); - else if (only_wall && (f_info[feature].flags1 & FF1_FLOOR)) + else if (only_wall && (f_info[feature].flags & FF_FLOOR)) return (FALSE); else if ((p_ptr->ffall) && - (f_info[feature].flags1 & FF1_CAN_LEVITATE)) + (f_info[feature].flags & FF_CAN_LEVITATE)) return (TRUE); else if ((pass_wall || only_wall) && - (f_info[feature].flags1 & FF1_CAN_PASS)) + (f_info[feature].flags & FF_CAN_PASS)) return (TRUE); - else if (f_info[feature].flags1 & FF1_NO_WALK) + else if (f_info[feature].flags & FF_NO_WALK) + return (FALSE); + else if ((f_info[feature].flags & FF_WEB) && + ((!(r_info[p_ptr->body_monster].flags & RF_SPIDER)) && (p_ptr->mimic_form != resolve_mimic_name("Spider")))) + return (FALSE); + + return (TRUE); +} + +/* + * 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) +{ + auto const &r_info = game->edit_data.r_info; + + int i, j; + + cave_type *c_ptr = &cave[y][x]; + + auto r_ptr = &r_info[p_ptr->body_monster]; + + + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR)) + { + msg_print("You cannot open doors."); + return (FALSE); - else if ((f_info[feature].flags1 & FF1_WEB) && - ((!(r_info[p_ptr->body_monster].flags7 & RF7_SPIDER)) && (p_ptr->mimic_form != resolve_mimic_name("Spider")))) + } + + /* 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 = 100; + + /* 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."); + + /* Open the door */ + cave_set_feat(y, x, FEAT_OPEN); + + /* Update some things */ + p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE); + + /* Experience */ + gain_exp(1); + } + + /* Failure */ + else + { + /* Failure */ + flush_on_failure(); + + /* Message */ + msg_print("You failed to pick the lock."); + } + } + /* Closed door */ + else + { + /* Open the door */ + cave_set_feat(y, x, FEAT_OPEN); + + /* Update some things */ + p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE); + } + + /* Result */ return (TRUE); } @@ -2936,43 +2615,43 @@ bool_ player_can_enter(byte feature) * any monster which might be in the destination grid. Previously, * moving into walls was "free" and did NOT hit invisible monsters. */ -void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) +void move_player_aux(int dir, int do_pickup, int run) { + auto const &d_info = game->edit_data.d_info; + auto const &r_info = game->edit_data.r_info; + auto const &f_info = game->edit_data.f_info; + int y, x, tmp; cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px]; monster_type *m_ptr; - monster_race *r_ptr = &r_info[p_ptr->body_monster], *mr_ptr; + auto r_ptr = &r_info[p_ptr->body_monster]; char m_name[80]; - bool_ stormbringer = FALSE; - - bool_ old_dtrap, new_dtrap; - bool_ oktomove = TRUE; /* Hack - random movement */ if (p_ptr->disembodied) tmp = dir; - else if ((r_ptr->flags1 & RF1_RAND_25) && (r_ptr->flags1 & RF1_RAND_50)) + else if ((r_ptr->flags & RF_RAND_25) && (r_ptr->flags & RF_RAND_50)) { if (randint(100) < 75) tmp = randint(9); else tmp = dir; } - else if (r_ptr->flags1 & RF1_RAND_50) + else if (r_ptr->flags & RF_RAND_50) { if (randint(100) < 50) tmp = randint(9); else tmp = dir; } - else if (r_ptr->flags1 & RF1_RAND_25) + else if (r_ptr->flags & RF_RAND_25) { if (randint(100) < 25) tmp = randint(9); @@ -3096,26 +2775,35 @@ 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; - - /* Get the monster */ - m_ptr = &m_list[c_ptr->m_idx]; - mr_ptr = race_inf(m_ptr); + { + hook_move_in in = { y, x }; + if (process_hooks_new(HOOK_MOVE, &in, NULL)) { + return; /* Prevent movement */ + } + } - if (p_ptr->inventory[INVEN_WIELD].art_name) + if (p_ptr->dripping_tread > 0) { - if (streq(quark_str(p_ptr->inventory[INVEN_WIELD].art_name), "'Stormbringer'")) - stormbringer = TRUE; + geomancy_random_floor(y, x, FALSE); + p_ptr->dripping_tread -= 1; + if (p_ptr->dripping_tread == 0) + { + msg_print("You stop dripping raw elemental energies."); + } } + + /* Get the monster */ + m_ptr = &m_list[c_ptr->m_idx]; + auto const mr_ptr = m_ptr->race(); + /* Hack -- attack monsters */ if (c_ptr->m_idx && (m_ptr->ml || player_can_enter(c_ptr->feat))) { /* Attack -- only if we can see it OR it is not in a wall */ if ((is_friend(m_ptr) > 0) && - !(p_ptr->confused || p_ptr->image || !(m_ptr->ml) || p_ptr->stun) && - (pattern_seq(p_ptr->py, p_ptr->px, y, x)) && + !(p_ptr->confused || p_ptr->image || !(m_ptr->ml) || p_ptr->stun) && ((player_can_enter(cave[y][x].feat)))) { m_ptr->csleep = 0; @@ -3129,13 +2817,16 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) /* Track a new monster */ if (m_ptr->ml) health_track(c_ptr->m_idx); + /* Is it Stormbringer? */ + bool stormbringer = p_ptr->inventory[INVEN_WIELD].artifact_name == "'Stormbringer'"; + /* displace? */ if (stormbringer && (randint(1000) > 666)) { py_attack(y, x, -1); } else if (cave_floor_bold(p_ptr->py, p_ptr->px) || - (mr_ptr->flags2 & RF2_PASS_WALL)) + (mr_ptr->flags & RF_PASS_WALL)) { msg_format("You push past %s.", m_name); m_ptr->fy = p_ptr->py; @@ -3167,28 +2858,13 @@ 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)) - { - msg_print("You stop to avoid triggering the trap."); - energy_use = 0; - oktomove = FALSE; - } - /* Player can't enter ? soo bad for him/her ... */ else if (!player_can_enter(c_ptr->feat)) { oktomove = FALSE; /* Disturb the player */ - disturb(0, 0); + disturb(); if (p_ptr->prob_travel) { @@ -3217,13 +2893,12 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) /* Wall (or secret door) */ else { - int feat; - - if (c_ptr->mimic) feat = c_ptr->mimic; - else - feat = f_info[c_ptr->feat].mimic; + int const feat = c_ptr->mimic + ? c_ptr->mimic + : 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); } @@ -3235,110 +2910,36 @@ 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; - - 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); + int feat; - if (!(p_ptr->confused || p_ptr->stun || p_ptr->image)) - energy_use = 0; - } + if (c_ptr->mimic) feat = c_ptr->mimic; else - { - do_cmd_tunnel_aux(y, x, dir); - return; - } - } - } - - /* Sound */ - sound(SOUND_HITWALL); - } - - /* Normal movement */ - if (!pattern_seq(p_ptr->py, p_ptr->px, y, x)) - { - if (!(p_ptr->confused || p_ptr->stun || p_ptr->image)) - { - energy_use = 0; - } - - disturb(0, 0); /* To avoid a loop with running */ - - oktomove = FALSE; - } - - - /* - * Check trap detection status -- retrieve them here - * because they are used by the movement code as well - */ - old_dtrap = ((cave[p_ptr->py][p_ptr->px].info & CAVE_DETECT) != 0); - new_dtrap = ((cave[y][x].info & CAVE_DETECT) != 0); - - /* Normal movement */ - if (oktomove && running && disturb_detect) - { - /* - * Disturb the player when about to leave the trap detected - * area - */ - if (old_dtrap && !new_dtrap) - { - /* Disturb player */ - disturb(0, 0); - - /* but don't take a turn */ - energy_use = 0; + feat = f_info[c_ptr->feat].mimic; - /* Tell player why */ - cmsg_print(TERM_VIOLET, "You are about to leave a trap detected zone."); - /* Flush */ - /* msg_print(NULL); */ + msg_format("There is %s.", f_info[feat].block); - oktomove = FALSE; + if (!(p_ptr->confused || p_ptr->stun || p_ptr->image)) + energy_use = 0; + } } } @@ -3363,9 +2964,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); @@ -3378,20 +2976,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) /* Check for new panel (redraw map) */ verify_panel(); - /* Check detection status */ - if (old_dtrap && !new_dtrap) - { - cmsg_print(TERM_VIOLET, "You leave a trap detected zone."); - if (running) msg_print(NULL); - p_ptr->redraw |= (PR_DTRAP); - } - 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); - } - /* Update stuff */ p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE); @@ -3402,34 +2986,22 @@ 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.c_str()); } else { - msg_print(f_text + f_info[feat].text); + msg_print(f_info[feat].text); } /* Flush message while running */ if (running) msg_print(NULL); } - /* Spontaneous Searching */ - if ((p_ptr->skill_fos >= 50) || (0 == rand_int(50 - p_ptr->skill_fos))) - { - search(); - } - - /* Continuous Searching */ - if (p_ptr->searching) - { - search(); - } - /* Handle "objects" */ carry(do_pickup); @@ -3437,7 +3009,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(); /* Hack -- Enter store */ command_new = '_'; @@ -3446,7 +3018,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); @@ -3455,31 +3027,11 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) if (running) msg_print(NULL); } - /* Discover invisible traps */ - else if ((c_ptr->t_idx != 0) && - !(f_info[cave[y][x].feat].flags1 & FF1_DOOR)) - { - /* Disturb */ - disturb(0, 0); - - if (!(c_ptr->info & (CAVE_TRDT))) - { - /* Message */ - msg_print("You found a trap!"); - - /* Pick a trap */ - pick_trap(p_ptr->py, p_ptr->px); - } - - /* Hit the trap */ - hit_trap(); - } - /* Execute the inscription */ else if (c_ptr->inscription) { /* Disturb */ - disturb(0, 0); + disturb(); msg_format("There is an inscription here: %s", inscription_info[c_ptr->inscription].text); @@ -3503,9 +3055,9 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) } } -void move_player(int dir, int do_pickup, bool_ disarm) +void move_player(int dir, int do_pickup) { - move_player_aux(dir, do_pickup, 0, disarm); + move_player_aux(dir, do_pickup, 0); } @@ -3514,13 +3066,7 @@ void move_player(int dir, int do_pickup, bool_ disarm) */ static int see_obstacle_grid(cave_type *c_ptr) { - /* - * Hack -- Avoid hitting detected traps, because we cannot rely on - * the CAVE_MARK check below, and traps can be set to nearly - * everything the player can move on to XXX XXX XXX - */ - if (c_ptr->info & (CAVE_TRDT)) return (TRUE); - + auto const &f_info = game->edit_data.f_info; /* Hack -- Handle special cases XXX XXX */ switch (c_ptr->feat) @@ -3543,7 +3089,7 @@ static int see_obstacle_grid(cave_type *c_ptr) /* "Safe" floor grids aren't obstacles */ - if (f_info[c_ptr->feat].flags1 & FF1_CAN_RUN) return (FALSE); + if (f_info[c_ptr->feat].flags & FF_CAN_RUN) return (FALSE); /* Must be known to the player */ if (!(c_ptr->info & (CAVE_MARK))) return (FALSE); @@ -3871,8 +3417,10 @@ static void run_init(int dir) * * Return TRUE if the running should be stopped */ -static bool_ run_test(void) +static bool_ run_test() { + auto const &f_info = game->edit_data.f_info; + int prev_dir, new_dir, check_dir = 0; int row, col; @@ -3881,9 +3429,6 @@ static bool_ run_test(void) int option = 0, option2 = 0; - cave_type *c_ptr; - - /* Where we came from */ prev_dir = find_prevdir; @@ -3895,9 +3440,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]; @@ -3906,7 +3448,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 */ @@ -3919,15 +3461,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); @@ -3973,7 +3510,7 @@ static bool_ run_test(void) case FEAT_BROKEN: { /* Option -- ignore */ - if (find_ignore_doors) notice = FALSE; + if (options->find_ignore_doors) notice = FALSE; /* Done */ break; @@ -3999,7 +3536,7 @@ static bool_ run_test(void) case FEAT_BETWEEN2: { /* Option -- ignore */ - if (find_ignore_stairs) notice = FALSE; + if (options->find_ignore_stairs) notice = FALSE; /* Done */ break; @@ -4007,14 +3544,11 @@ static bool_ run_test(void) } /* Check the "don't notice running" flag */ - if (f_info[c_ptr->feat].flags1 & FF1_DONT_NOTICE_RUNNING) + if (f_info[c_ptr->feat].flags & FF_DONT_NOTICE_RUNNING) { notice = FALSE; } - /* A detected trap is interesting */ - if (c_ptr->info & (CAVE_TRDT)) notice = TRUE; - /* Interesting feature */ if (notice) return (TRUE); @@ -4022,9 +3556,6 @@ static bool_ run_test(void) inv = FALSE; } - /* Mega-Hack -- Maze code removes CAVE_MARK XXX XXX XXX */ - if (c_ptr->info & (CAVE_TRDT)) return (TRUE); - /* Analyze unknown grids and floors */ if (inv || cave_floor_bold(row, col)) { @@ -4101,7 +3632,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)) @@ -4133,7 +3664,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)) @@ -4178,7 +3709,7 @@ static bool_ run_test(void) } /* Two options, examining corners */ - else if (find_examine && !find_cut) + else if (options->find_examine && !options->find_cut) { /* Primary option */ find_current = option; @@ -4200,7 +3731,7 @@ static bool_ run_test(void) { /* Can not see anything ahead and in the direction we */ /* are turning, assume that it is a potential corner. */ - if (find_examine && + if (options->find_examine && see_nothing(option, row, col) && see_nothing(option2, row, col)) { @@ -4216,7 +3747,7 @@ static bool_ run_test(void) } /* This corner is seen to be enclosed; we cut the corner. */ - else if (find_cut) + else if (options->find_cut) { find_current = option2; find_prevdir = option2; @@ -4262,7 +3793,7 @@ void run_step(int dir) msg_print("You cannot run in that direction."); /* Disturb */ - disturb(0, 0); + disturb(); /* Done */ return; @@ -4282,7 +3813,7 @@ void run_step(int dir) if (run_test()) { /* Disturb */ - disturb(0, 0); + disturb(); /* Done */ return; @@ -4297,54 +3828,17 @@ void run_step(int dir) /* Move the player, using the "pickup" flag */ - move_player_aux(find_current, always_pickup, 1, TRUE); + move_player_aux(find_current, options->always_pickup, 1); } /* - * 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) +void do_cmd_pet() { + auto const &r_info = game->edit_data.r_info; + int i = 0; int num = 0; @@ -4353,7 +3847,7 @@ void do_cmd_pet(void) char power_desc[36][80]; - bool_ flag, redraw; + bool_ flag; int ask; @@ -4432,80 +3926,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, ""); + /* Save the screen */ + character_icky = TRUE; + Term_save(); - /* Show list */ - redraw = TRUE; - - /* 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'; @@ -4553,11 +4022,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) @@ -4633,13 +4099,11 @@ void do_cmd_pet(void) /* Process the monsters (backwards) */ for (pet_ctr = m_max - 1; pet_ctr >= 1; pet_ctr--) { - monster_race *r_ptr; - /* Access the monster */ m_ptr = &m_list[pet_ctr]; - r_ptr = &r_info[m_ptr->r_idx]; + auto r_ptr = &r_info[m_ptr->r_idx]; - if ((!(r_ptr->flags7 & RF7_NO_DEATH)) && ((m_ptr->status == MSTATUS_PET) || (m_ptr->status == MSTATUS_FRIEND))) /* Get rid of it! */ + if ((!(r_ptr->flags & RF_NO_DEATH)) && ((m_ptr->status == MSTATUS_PET) || (m_ptr->status == MSTATUS_FRIEND))) /* Get rid of it! */ { bool_ checked = FALSE; char command; @@ -4702,13 +4166,11 @@ void do_cmd_pet(void) /* Process the monsters (backwards) */ for (pet_ctr = m_max - 1; pet_ctr >= 1; pet_ctr--) { - monster_race *r_ptr; - /* Access the monster */ m_ptr = &m_list[pet_ctr]; - r_ptr = &r_info[m_ptr->r_idx]; + auto r_ptr = &r_info[m_ptr->r_idx]; - if ((!(r_ptr->flags7 & RF7_NO_DEATH)) && ((m_ptr->status == MSTATUS_COMPANION))) /* Get rid of it! */ + if ((!(r_ptr->flags & RF_NO_DEATH)) && ((m_ptr->status == MSTATUS_COMPANION))) /* Get rid of it! */ { bool_ delete_this = FALSE; @@ -4788,35 +4250,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; @@ -4830,8 +4288,6 @@ bool_ do_cmd_integrate_body() p_ptr->wraith_form = FALSE; p_ptr->disembodied = FALSE; do_cmd_redraw(); - - return TRUE; } /* @@ -4839,9 +4295,11 @@ bool_ do_cmd_integrate_body() */ bool_ do_cmd_leave_body(bool_ drop_body) { + auto const &r_info = game->edit_data.r_info; + object_type *o_ptr, forge; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; int i; @@ -4878,7 +4336,7 @@ bool_ do_cmd_leave_body(bool_ drop_body) o_ptr->ident |= IDENT_STOREB; /* Unique corpses are unique */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { o_ptr->name1 = 201; } @@ -4962,56 +4420,49 @@ bool_ execute_inscription(byte i, byte y, byte x) case INSCRIP_CHASM: { - 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]; - r_ptr = race_inf(m_ptr); + monster_type *m_ptr = &m_list[c_ptr->m_idx]; + auto const r_ptr = m_ptr->race(); - if (r_ptr->flags7 & RF7_CAN_FLY) + if (r_ptr->flags & RF_CAN_FLY) { msg_print("The monster simply flies over the chasm."); } else { - if (!(r_ptr->flags1 & RF1_UNIQUE)) + if (!(r_ptr->flags & RF_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) { @@ -5079,13 +4530,14 @@ void do_cmd_engrave() { if (!strcmp(inscription_info[i].text, buf)) { - if (inscription_info[i].know) + if (p_ptr->inscriptions[i]) { - /* Save the inscription */ cave[p_ptr->py][p_ptr->px].inscription = i; } else + { msg_print("You can't use this inscription for now."); + } } } diff --git a/src/cmd1.hpp b/src/cmd1.hpp new file mode 100644 index 00000000..19b40ebf --- /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" + +void attack_special(monster_type *m_ptr, s32b special, int dam); +bool_ test_hit_fire(int chance, int ac, int vis); +bool_ test_hit_norm(int chance, int ac, int vis); +s16b critical_shot(int weight, int plus, int dam, int skill); +s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit); +s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, s32b *special); +void search(); +void carry(int pickup); +void py_attack(int y, int x, int max_blow); +bool_ player_can_enter(byte feature); +void move_player(int dir, int do_pickup); +void move_player_aux(int dir, int do_pickup, int run); +void run_step(int dir); +void do_cmd_pet(); +void do_cmd_integrate_body(); +bool_ do_cmd_leave_body(bool_ drop_body); +bool_ execute_inscription(byte i, byte y, byte x); +void do_cmd_engrave(); +void do_spin(); diff --git a/src/cmd2.c b/src/cmd2.cc index 2d05c125..a348c221 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,9 +6,61 @@ * included in all such copies. */ -#include "angband.h" - -void do_cmd_immovable_special(void); +#include "cmd2.hpp" + +#include "bldg.hpp" +#include "cave.hpp" +#include "cave_type.hpp" +#include "cmd1.hpp" +#include "dungeon_info_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" +#include "feature_type.hpp" +#include "files.hpp" +#include "game.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_race_flag.hpp" +#include "monster_type.hpp" +#include "object1.hpp" +#include "object2.hpp" +#include "object_flag.hpp" +#include "object_kind.hpp" +#include "options.hpp" +#include "player_race_flag.hpp" +#include "player_type.hpp" +#include "skills.hpp" +#include "spells1.hpp" +#include "spells2.hpp" +#include "spells3.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 "xtra1.hpp" +#include "xtra2.hpp" +#include "z-rand.hpp" + +#include <chrono> +#include <thread> + +using std::this_thread::sleep_for; +using std::chrono::milliseconds; + +void do_cmd_immovable_special(); /* * Try to bash an altar @@ -29,14 +77,16 @@ static bool_ do_cmd_bash_altar(int y, int x) */ static bool_ do_cmd_bash_fountain(int y, int x) { + auto const &r_info = game->edit_data.r_info; + int bash, temp; bool_ more = TRUE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_BASH_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_BASH_DOOR)) { msg_print("You cannot do that."); @@ -74,26 +124,65 @@ static bool_ do_cmd_bash_fountain(int y, int x) return (more); } +/* + * Stair hooks + */ +static bool_ stair_hooks(stairs_direction direction) +{ + hook_stair_in in = { direction }; + hook_stair_out out = { TRUE }; /* Allow by default */ + process_hooks_new(HOOK_STAIR, &in, &out); + return (!out.allow); +} + +/* + * Ask for confirmation before leaving level; based + * on whether the 'confirm_stairs' option is set. + */ +static bool ask_leave() +{ + if (options->confirm_stairs) + { + if (get_check("Really leave the level? ")) + { + return true; // Leave + } + else + { + return false; // Don't leave + } + } + else + { + return true; // Leave + } +} + /* * Go up one level */ -void do_cmd_go_up(void) +void do_cmd_go_up() { + auto const &d_info = game->edit_data.d_info; + bool_ go_up = FALSE, go_up_many = FALSE, prob_traveling = FALSE; cave_type *c_ptr; int oldl = dun_level; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; /* Player grid */ c_ptr = &cave[p_ptr->py][p_ptr->px]; /* Can we ? */ - if (process_hooks(HOOK_STAIR, "(s)", "up")) return; + if (stair_hooks(STAIRS_UP)) + { + return; + } /* Normal up stairs */ if ((c_ptr->feat == FEAT_LESS) || (c_ptr->feat == FEAT_WAY_LESS)) @@ -102,15 +191,11 @@ void do_cmd_go_up(void) { go_up = TRUE; } - else if ((dungeon_flags2 & DF2_ASK_LEAVE)) + else if (dungeon_flags & DF_ASK_LEAVE) { go_up = get_check("Leave this unique level forever? "); } - else if (confirm_stairs) - { - go_up = get_check("Really leave the level? "); - } - else + else if (ask_leave()) { go_up = TRUE; } @@ -123,15 +208,11 @@ void do_cmd_go_up(void) { go_up = TRUE; } - else if ((dungeon_flags2 & DF2_ASK_LEAVE)) + else if (dungeon_flags & DF_ASK_LEAVE) { go_up = get_check("Leave this unique level forever? "); } - else if (confirm_stairs) - { - go_up_many = get_check("Really leave the level? "); - } - else + else if (ask_leave()) { go_up_many = TRUE; } @@ -142,7 +223,7 @@ void do_cmd_go_up(void) { leaving_quest = p_ptr->inside_quest; - if ((dungeon_flags2 & DF2_ASK_LEAVE) && + if ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) return; @@ -156,12 +237,12 @@ void do_cmd_go_up(void) } /* Exits to previous area in flat terrains */ - else if (!(dungeon_flags1 & DF1_FLAT) && + else if (!(dungeon_flags & DF_FLAT) && p_ptr->prob_travel && !p_ptr->inside_quest) { if (d_ptr->mindepth == dun_level) return; - if (dungeon_flags2 & DF2_NO_EASY_MOVE) + if (dungeon_flags & DF_NO_EASY_MOVE) { msg_print("Some powerful force prevents your from teleporting."); return; @@ -169,12 +250,7 @@ void do_cmd_go_up(void) prob_traveling = TRUE; - if (confirm_stairs) - { - if (get_check("Really leave the level? ")) - go_up = TRUE; - } - else + if (ask_leave()) { go_up = TRUE; } @@ -238,7 +314,7 @@ void do_cmd_go_up(void) /* * Returns TRUE if we are in the Between... */ -static bool_ between_effect(void) +static bool_ between_effect() { byte bx, by; @@ -282,19 +358,19 @@ static bool_ between_effect(void) /* * Go down one level */ -void do_cmd_go_down(void) +void do_cmd_go_down() { + auto const &d_info = game->edit_data.d_info; + cave_type *c_ptr; bool_ go_down = FALSE, go_down_many = FALSE, prob_traveling = FALSE; - bool_ fall_trap = FALSE; - char i; int old_dun = dun_level; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; /* MUST be actived now */ @@ -305,10 +381,8 @@ void do_cmd_go_down(void) if (p_ptr->astral && (dun_level == 98)) return; - if (c_ptr->t_idx == TRAP_OF_SINKING) fall_trap = TRUE; - /* test if on special level */ - if ((dungeon_flags2 & DF2_ASK_LEAVE)) + if (dungeon_flags & DF_ASK_LEAVE) { prt("Leave this unique level forever (y/n) ? ", 0, 0); flush(); @@ -318,7 +392,10 @@ void do_cmd_go_down(void) } /* Can we ? */ - if (process_hooks(HOOK_STAIR, "(s)", "down")) return; + if (stair_hooks(STAIRS_DOWN)) + { + return; + } /* Normal up stairs */ if (c_ptr->feat == FEAT_SHAFT_DOWN) @@ -333,12 +410,7 @@ void do_cmd_go_down(void) } else { - if (confirm_stairs) - { - if (get_check("Really leave the level? ")) - go_down_many = TRUE; - } - else + if (ask_leave()) { go_down_many = TRUE; } @@ -362,12 +434,7 @@ void do_cmd_go_down(void) } else { - if (confirm_stairs) - { - if (get_check("Really leave the level? ")) - go_down = TRUE; - } - else + if (ask_leave()) { go_down = TRUE; } @@ -383,31 +450,26 @@ void do_cmd_go_down(void) return; } - else if (!(dungeon_flags1 & DF1_FLAT) && + else if (!(dungeon_flags & DF_FLAT) && p_ptr->prob_travel && !p_ptr->inside_quest) { if (d_ptr->maxdepth == dun_level) return; - if (dungeon_flags2 & DF2_NO_EASY_MOVE) + if (dungeon_flags & DF_NO_EASY_MOVE) { - msg_print("Some powerfull force prevents your from teleporting."); + msg_print("Some powerful force prevents your from teleporting."); return; } prob_traveling = TRUE; - if (confirm_stairs) - { - if (get_check("Really leave the level? ")) - go_down = TRUE; - } - else + if (ask_leave()) { go_down = TRUE; } } - else if (!(fall_trap)) + else { msg_print("I see no down staircase here."); return; @@ -417,15 +479,10 @@ void do_cmd_go_down(void) { energy_use = 0; - if (fall_trap) - msg_print("You deliberately jump through the trap door."); + if (c_ptr->feat == FEAT_WAY_MORE) + msg_print("You enter the next area."); else - { - if (c_ptr->feat == FEAT_WAY_MORE) - msg_print("You enter the next area."); - else - msg_print("You enter a maze of down staircases."); - } + msg_print("You enter a maze of down staircases."); autosave_checkpoint(); @@ -451,13 +508,16 @@ void do_cmd_go_down(void) { if (d_info[c_ptr->special].min_plev <= p_ptr->lev) { - dungeon_info_type *d_ptr = &d_info[c_ptr->special]; + auto 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 */ @@ -479,8 +539,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.c_str()); } else { @@ -493,80 +552,9 @@ void do_cmd_go_down(void) /* Leaving */ p_ptr->leaving = TRUE; - - if (!fall_trap) - { - /* Create a way back */ - if (go_down_many) - create_up_shaft = TRUE; - else - create_up_stair = TRUE; - } - } -} - - - -/* - * Simple command to "search" for one turn - */ -void do_cmd_search(void) -{ - /* 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; - } - - /* Take a turn */ - energy_use = 100; - - /* Search */ - search(); -} - - -/* - * Hack -- toggle search mode - */ -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); } } - - /* * Determine if a grid contains a chest */ @@ -574,20 +562,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; */ @@ -613,6 +595,8 @@ static s16b chest_check(int y, int x) */ static void chest_death(int y, int x, s16b o_idx) { + auto const &d_info = game->edit_data.d_info; + int number; bool_ small; @@ -682,41 +666,6 @@ static void chest_death(int y, int x, s16b o_idx) /* - * Chests have traps too. - * - * Exploding chest destroys contents (and traps). - * Note that the chest itself is never destroyed. - */ -static void chest_trap(int y, int x, s16b o_idx) -{ - int trap; - - object_type *o_ptr = &o_list[o_idx]; - - bool_ ident = FALSE; - - - /* Ignore disarmed chests */ - if (o_ptr->pval <= 0) return; - - /* Obtain the trap */ - trap = o_ptr->pval; - - /* Message */ - msg_print("You found a trap!"); - - /* Set off trap */ - ident = player_activate_trap_type(y, x, o_ptr, o_idx); - if (ident) - { - t_info[o_ptr->pval].ident = TRUE; - msg_format("You identified the trap as %s.", - t_name + t_info[trap].name); - } -} - - -/* * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination @@ -725,6 +674,8 @@ static void chest_trap(int y, int x, s16b o_idx) */ static bool_ do_cmd_open_chest(int y, int x, s16b o_idx) { + auto const &r_info = game->edit_data.r_info; + int i, j; bool_ flag = TRUE; @@ -733,10 +684,10 @@ static bool_ do_cmd_open_chest(int y, int x, s16b o_idx) object_type *o_ptr = &o_list[o_idx]; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR)) { msg_print("You cannot open chests."); @@ -753,7 +704,7 @@ static bool_ do_cmd_open_chest(int y, int x, s16b o_idx) flag = FALSE; /* Get the "disarm" factor */ - i = p_ptr->skill_dis; + i = 100; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; @@ -779,7 +730,7 @@ static bool_ do_cmd_open_chest(int y, int x, s16b o_idx) /* We may continue repeating */ more = TRUE; - if (flush_failure) flush(); + flush_on_failure(); msg_print("You failed to pick the lock."); } @@ -788,9 +739,6 @@ static bool_ do_cmd_open_chest(int y, int x, s16b o_idx) /* Allowed to open */ if (flag) { - /* Apply chest traps, if any */ - chest_trap(y, x, o_idx); - /* Let the Chest drop items */ chest_death(y, x, o_idx); } @@ -827,16 +775,6 @@ static bool_ is_closed(cave_type *c_ptr) return ((feat >= FEAT_DOOR_HEAD) && (feat <= FEAT_DOOR_TAIL)); } - -/* - * Return TRUE if the given grid has a trap - */ -static bool_ is_trap(cave_type *c_ptr) -{ - return ((c_ptr->info & (CAVE_TRDT)) != 0); -} - - /* * Return the number of doors/traps around (or under) * the character using the filter function 'test' @@ -918,9 +856,6 @@ static int count_chests(int *y, int *x, bool_ trapped) /* Already open */ if (o_ptr->pval == 0) continue; - /* No (known) traps here */ - if (trapped && (!object_known_p(o_ptr) || !o_ptr->pval)) continue; - /* OK */ ++count; @@ -969,16 +904,18 @@ static int coords_to_dir(int y, int x) */ static bool_ do_cmd_open_aux(int y, int x, int dir) { + auto const &r_info = game->edit_data.r_info; + int i, j; cave_type *c_ptr; bool_ more = FALSE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR)) { msg_print("You cannot open doors."); @@ -1002,7 +939,7 @@ static bool_ do_cmd_open_aux(int y, int x, int dir) else if (c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) { /* Disarm factor */ - i = p_ptr->skill_dis; + i = 100; /* Penalize some conditions */ if (p_ptr->blind || no_lite()) i = i / 10; @@ -1023,18 +960,12 @@ static bool_ do_cmd_open_aux(int y, int x, int dir) /* 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); } @@ -1043,7 +974,7 @@ static bool_ do_cmd_open_aux(int y, int x, int dir) else { /* Failure */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("You failed to pick the lock."); @@ -1056,17 +987,11 @@ static bool_ do_cmd_open_aux(int y, int x, int dir) /* 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 */ @@ -1080,8 +1005,10 @@ static bool_ do_cmd_open_aux(int y, int x, int dir) * * Unlocking a locked door/chest is worth one experience point. */ -void do_cmd_open(void) +void do_cmd_open() { + auto const &r_info = game->edit_data.r_info; + int y, x, dir; s16b o_idx; @@ -1090,18 +1017,17 @@ void do_cmd_open(void) bool_ more = FALSE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR)) { msg_print("You cannot open doors."); return; } - /* Option: Pick a direction */ - if (easy_open) + /* Pick a direction if there's an obvious target */ { int num_doors, num_chests; @@ -1135,7 +1061,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; @@ -1190,11 +1116,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(); } @@ -1210,14 +1133,16 @@ void do_cmd_open(void) */ static bool_ do_cmd_close_aux(int y, int x, int dir) { + auto const &r_info = game->edit_data.r_info; + cave_type *c_ptr; bool_ more = FALSE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_OPEN_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_OPEN_DOOR)) { msg_print("You cannot close doors."); @@ -1230,9 +1155,6 @@ static bool_ do_cmd_close_aux(int y, int x, int dir) /* Get grid and contents */ c_ptr = &cave[y][x]; - /* Set off trap */ - if (c_ptr->t_idx != 0) player_activate_door_trap(y, x); - /* Broken door */ if (c_ptr->feat == FEAT_BROKEN) { @@ -1248,9 +1170,6 @@ static bool_ do_cmd_close_aux(int y, int x, int dir) /* Update some things */ p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_MON_LITE); - - /* Sound */ - sound(SOUND_SHUTDOOR); } /* Result */ @@ -1261,7 +1180,7 @@ static bool_ do_cmd_close_aux(int y, int x, int dir) /* * Close an open door. */ -void do_cmd_close(void) +void do_cmd_close() { int y, x, dir; @@ -1270,8 +1189,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; @@ -1302,7 +1220,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; @@ -1347,7 +1265,7 @@ void do_cmd_close(void) } /* Cancel repeat unless we may continue */ - if (!more) disturb(0, 0); + if (!more) disturb(); } @@ -1356,6 +1274,8 @@ void do_cmd_close(void) */ static bool_ do_cmd_tunnel_test(int y, int x) { + auto const &f_info = game->edit_data.f_info; + /* Must have knowledge(execpt on "forget" levels) */ if (!(cave[y][x].info & (CAVE_MARK))) { @@ -1377,10 +1297,10 @@ static bool_ do_cmd_tunnel_test(int y, int x) } /* Must be tunnelable */ - if (!(f_info[cave[y][x].feat].flags1 & FF1_TUNNELABLE)) + if (!(f_info[cave[y][x].feat].flags & FF_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); @@ -1434,12 +1354,15 @@ 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) { + auto const &d_info = game->edit_data.d_info; + auto const &f_info = game->edit_data.f_info; + int skill_req = 0, skill_req_1pct = 0; cave_type *c_ptr = &cave[y][x]; - feature_type *f_ptr = &f_info[c_ptr->feat]; + auto f_ptr = &f_info[c_ptr->feat]; bool_ more = FALSE; @@ -1465,13 +1388,10 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir) /* Get grid */ c_ptr = &cave[y][x]; - /* Sound */ - sound(SOUND_DIG); - /* Titanium */ - if (f_ptr->flags1 & FF1_PERMANENT) + if (f_ptr->flags & FF_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)) @@ -1488,11 +1408,8 @@ 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 */ - if (rand_int(100) < 25) search(); } } @@ -1513,7 +1430,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; } } @@ -1593,7 +1510,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; } } @@ -1627,7 +1544,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; } } @@ -1643,9 +1560,6 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir) msg_print("You have finished the tunnel."); c_ptr->mimic = 0; lite_spot(y, x); - - /* Set off trap */ - if (c_ptr->t_idx != 0) player_activate_door_trap(y, x); } /* Keep trying */ @@ -1658,11 +1572,8 @@ 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 */ - if (rand_int(100) < 25) search(); } } @@ -1681,7 +1592,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; } } @@ -1720,7 +1631,7 @@ bool_ do_cmd_tunnel_aux(int y, int x, int dir) * Digging is very difficult without a "digger" weapon, but can be * accomplished by strong players using heavy weapons. */ -void do_cmd_tunnel(void) +void do_cmd_tunnel() { int y, x, dir; @@ -1738,7 +1649,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; @@ -1754,16 +1665,8 @@ void do_cmd_tunnel(void) /* Get grid */ c_ptr = &cave[y][x]; - /* No tunnelling through doors */ - if (((c_ptr->feat >= FEAT_DOOR_HEAD) && - (c_ptr->feat <= FEAT_DOOR_TAIL)) || (c_ptr->feat == FEAT_SHOP)) - { - /* Message */ - msg_print("You cannot tunnel through doors."); - } - /* No tunnelling through air */ - else if (cave_floor_grid(c_ptr)) + if (cave_floor_grid(c_ptr)) { /* Message */ msg_print("You cannot tunnel through air."); @@ -1791,423 +1694,9 @@ 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(); } - -/* - * Perform the basic "disarm" command - * - * Assume destination is a visible trap - * - * Assume there is no monster blocking the destination - * - * Returns TRUE if repeated commands may continue - */ -static bool_ do_cmd_disarm_chest(int y, int x, s16b o_idx) -{ - int i, j; - - bool_ more = FALSE; - - object_type *o_ptr = &o_list[o_idx]; - - trap_type *t_ptr = &t_info[o_ptr->pval]; - - - /* Take a turn */ - energy_use = 100; - - /* Get the "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 difficulty */ - j = i - t_ptr->difficulty * 3; - - /* Always have a small chance of success */ - if (j < 2) j = 2; - - /* Must find the trap first. */ - if (!object_known_p(o_ptr)) - { - msg_print("I don't see any traps."); - } - - /* Already disarmed/unlocked */ - else if (o_ptr->pval <= 0) - { - msg_print("The chest is not trapped."); - } - - /* Success (get a lot of experience) */ - else if (rand_int(100) < j) - { - msg_print("You have disarmed the chest."); - gain_exp(t_ptr->difficulty * 3); - o_ptr->pval = (0 - o_ptr->pval); - } - - /* Failure -- Keep trying */ - else if ((i > 5) && (randint(i) > 5)) - { - /* We may keep trying */ - more = TRUE; - if (flush_failure) flush(); - msg_print("You failed to disarm the chest."); - } - - /* Failure -- Set off the trap */ - else - { - msg_print("You set off a trap!"); - sound(SOUND_FAIL); - chest_trap(y, x, o_idx); - } - - /* Result */ - return (more); -} - - -/* - * Perform the basic "disarm" command - * - * Assume destination is a visible trap - * - * Assume there is no monster blocking the destination - * - * Returns TRUE if repeated commands may continue - */ -bool_ do_cmd_disarm_aux(int y, int x, int dir, int do_pickup) -{ - int i, j, power; - - cave_type *c_ptr; - - cptr name; - - bool_ more = FALSE; - - - /* Take a turn */ - energy_use = 100; - - /* Get grid and contents */ - c_ptr = &cave[y][x]; - - /* Access trap name */ - if (t_info[c_ptr->t_idx].ident) - name = (t_name + t_info[c_ptr->t_idx].name); - else - name = "unknown trap"; - - /* Get the "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; - - /* XXX XXX XXX Variable power? */ - - /* Extract trap "power" */ - power = t_info[c_ptr->t_idx].difficulty; - - /* Extract the difficulty */ - j = i - power; - - /* Always have a small chance of success */ - if (j < 2) j = 2; - - /* Success */ - if (rand_int(100) < j) - { - /* Message */ - msg_format("You have disarmed the %s.", name); - - /* Reward */ - gain_exp(power); - - /* Forget the trap */ - c_ptr->info &= ~(CAVE_MARK | CAVE_TRDT); - - /* Remove the trap */ - c_ptr->t_idx = 0; - - /* Move the player onto the trap */ - if (!(f_info[c_ptr->feat].flags1 & FF1_DOOR)) - move_player_aux(dir, do_pickup, 0, TRUE); - - /* Remove trap attr from grid */ - note_spot(y, x); - lite_spot(y, x); - } - - /* Failure -- Keep trying */ - else if ((i > 5) && (randint(i) > 5)) - { - /* Failure */ - if (flush_failure) flush(); - - /* Message */ - msg_format("You failed to disarm the %s.", name); - - /* We may keep trying */ - more = TRUE; - } - - /* Failure -- Set off the trap */ - else - { - /* Message */ - msg_format("You set off the %s!", name); - - /* Move the player onto the trap */ - if (!(f_info[c_ptr->feat].flags1 & FF1_DOOR)) - move_player_aux(dir, do_pickup, 0, FALSE); - } - - /* Result */ - return (more); -} - - -/* - * Disamrs the monster traps(no failure) - */ -void do_cmd_disarm_mon_trap(int y, int x) -{ - msg_print("You disarm the monster trap."); - - place_floor_convert_glass(y, x); - cave[p_ptr->py][p_ptr->px].special = cave[p_ptr->py][p_ptr->px].special2 = 0; -} - - -/* - * Disarms a trap, or chest - */ -void do_cmd_disarm(void) -{ - int y, x, dir; - - s16b o_idx; - - cave_type *c_ptr; - - bool_ more = FALSE; - - - /* Option: Pick a direction */ - if (easy_disarm) - { - int num_traps, num_chests; - - /* Count visible traps */ - num_traps = count_feats(&y, &x, is_trap, TRUE); - - /* Count chests (trapped) */ - num_chests = count_chests(&y, &x, TRUE); - - /* See if only one target */ - if (num_traps || num_chests) - { - if (num_traps + num_chests <= 1) - command_dir = coords_to_dir(y, x); - } - } - - /* 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; - } - - /* Get a direction (or abort) */ - if (get_rep_dir(&dir)) - { - /* Get location */ - y = p_ptr->py + ddy[dir]; - x = p_ptr->px + ddx[dir]; - - /* Get grid and contents */ - c_ptr = &cave[y][x]; - - /* Check for chests */ - o_idx = chest_check(y, x); - - /* Disarm a trap */ - if (((c_ptr->t_idx == 0) || (!(c_ptr->info & CAVE_TRDT))) && - !o_idx && (c_ptr->feat != FEAT_MON_TRAP)) - { - /* Message */ - msg_print("You see nothing there to disarm."); - } - - /* Monster in the way */ - else if (c_ptr->m_idx) - { - /* Message */ - msg_print("There is a monster in the way!"); - - /* Attack */ - py_attack(y, x, -1); - } - - /* Disarm chest */ - else if (o_idx) - { - /* Disarm the chest */ - more = do_cmd_disarm_chest(y, x, o_idx); - } - - /* Disarm trap */ - else - { - /* Disarm the trap */ - if (c_ptr->feat == FEAT_MON_TRAP) - { - do_cmd_disarm_mon_trap(y, x); - more = FALSE; - } - else - more = do_cmd_disarm_aux(y, x, dir, always_pickup); - } - } - - /* Cancel repeat unless told not to */ - if (!more) disturb(0, 0); -} - - /* * Perform the basic "bash" command * @@ -2219,16 +1708,18 @@ void do_cmd_disarm(void) */ static bool_ do_cmd_bash_aux(int y, int x, int dir) { + auto const &r_info = game->edit_data.r_info; + int bash, temp; cave_type *c_ptr; bool_ more = FALSE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_BASH_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_BASH_DOOR)) { msg_print("You cannot do that."); @@ -2266,26 +1757,17 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir) /* Break down the door */ if (rand_int(100) < 50) { - /* Set off trap */ - if (c_ptr->t_idx != 0) player_activate_door_trap(y, x); - cave_set_feat(y, x, FEAT_BROKEN); } /* Open the door */ else { - /* Set off trap */ - if (c_ptr->t_idx != 0) player_activate_door_trap(y, x); - cave_set_feat(y, x, FEAT_OPEN); } - /* Sound */ - sound(SOUND_OPENDOOR); - /* Hack -- Fall through the door. Can't disarm while falling. */ - move_player_aux(dir, always_pickup, 0, FALSE); + move_player_aux(dir, options->always_pickup, 0); /* Update some things */ p_ptr->update |= (PU_VIEW | PU_MON_LITE); @@ -2309,7 +1791,7 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir) msg_print("You are off-balance."); /* Hack -- Lose balance ala paralysis */ - (void)set_paralyzed(p_ptr->paralyzed + 2 + rand_int(2)); + set_paralyzed(2 + rand_int(2)); } /* Result */ @@ -2331,18 +1813,20 @@ static bool_ do_cmd_bash_aux(int y, int x, int dir) * * Creatures can also open or bash doors, see elsewhere. */ -void do_cmd_bash(void) +void do_cmd_bash() { + auto const &r_info = game->edit_data.r_info; + int y, x, dir; cave_type *c_ptr; bool_ more = FALSE; - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; - if ((p_ptr->body_monster != 0) && !(r_ptr->flags2 & RF2_BASH_DOOR)) + if ((p_ptr->body_monster != 0) && !(r_ptr->flags & RF_BASH_DOOR)) { msg_print("You cannot do that."); @@ -2356,7 +1840,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; @@ -2413,7 +1897,7 @@ void do_cmd_bash(void) } /* Unless valid action taken, cancel bash */ - if (!more) disturb(0, 0); + if (!more) disturb(); } @@ -2428,8 +1912,10 @@ void do_cmd_bash(void) * This command must always take a turn, to prevent free detection * of invisible monsters. */ -void do_cmd_alter(void) +void do_cmd_alter() { + auto const &f_info = game->edit_data.f_info; + int y, x, dir; cave_type *c_ptr; @@ -2444,7 +1930,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; @@ -2479,19 +1965,12 @@ void do_cmd_alter(void) } /* Tunnel through walls */ - else if (f_info[c_ptr->feat].flags1 & FF1_TUNNELABLE) + else if (f_info[c_ptr->feat].flags & FF_TUNNELABLE) { /* Tunnel */ more = do_cmd_tunnel_aux(y, x, dir); } - /* Disarm traps */ - else if (c_ptr->t_idx != 0) - { - /* Tunnel */ - more = do_cmd_disarm_aux(y, x, dir, always_pickup); - } - /* Oops */ else { @@ -2501,7 +1980,7 @@ void do_cmd_alter(void) } /* Cancel repetition unless we can continue */ - if (!more) disturb(0, 0); + if (!more) disturb(); } @@ -2545,7 +2024,7 @@ static bool_ get_spike(int *ip) * * This command may NOT be repeated */ -void do_cmd_spike(void) +void do_cmd_spike() { int y, x, dir, item; @@ -2612,8 +2091,10 @@ void do_cmd_spike(void) } -static void do_cmd_walk_jump(int pickup, bool_ disarm) +static void do_cmd_walk_jump(int pickup) { + auto const &wf_info = game->edit_data.wf_info; + int dir; bool_ more = FALSE; @@ -2626,7 +2107,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; @@ -2639,7 +2120,7 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm) energy_use = 100; /* Actually move the character */ - move_player(dir, pickup, disarm); + move_player(dir, pickup); /* Allow more walking */ more = TRUE; @@ -2649,8 +2130,9 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm) energy_use *= (p_ptr->wild_mode) ? ((MAX_HGT + MAX_WID) / 2) : 1; /* Hack again -- Is there a special encounter ??? */ + auto const &wilderness = game->wilderness; if (p_ptr->wild_mode && - magik(wf_info[wild_map[p_ptr->py][p_ptr->px].feat].level - (p_ptr->lev * 2))) + magik(wf_info[wilderness(p_ptr->px, p_ptr->py).feat].level - (p_ptr->lev * 2))) { /* Go into large wilderness view */ p_ptr->wilderness_x = p_ptr->px; @@ -2668,14 +2150,186 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm) } /* Cancel repeat unless we may continue */ - if (!more) disturb(0, 0); + if (!more) disturb(); +} + + +/* + * 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, options->always_pickup); + 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, options->always_pickup); + } + + /* Walking semantics */ + else + { + teleport_player_directed(10, dir); + } + + /* Cancel repetition unless we can continue */ + if (!more) disturb(); } /* * Support code for the "Walk" and "Jump" commands */ -void do_cmd_walk(int pickup, bool_ disarm) +void do_cmd_walk(int pickup) { /* Move (usually pickup) */ @@ -2685,7 +2339,7 @@ void do_cmd_walk(int pickup, bool_ disarm) } else { - do_cmd_walk_jump(pickup, disarm); + do_cmd_walk_jump(pickup); } } @@ -2718,7 +2372,7 @@ void do_cmd_run_run() /* * Start running. */ -void do_cmd_run(void) +void do_cmd_run() { if (p_ptr->immovable) { @@ -2748,7 +2402,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; @@ -2758,20 +2412,6 @@ void do_cmd_stay(int pickup) /* Take a turn */ energy_use = 100; - - /* Spontaneous Searching */ - if ((p_ptr->skill_fos >= 50) || (0 == rand_int(50 - p_ptr->skill_fos))) - { - search(); - } - - /* Continuous Searching */ - if (p_ptr->searching) - { - search(); - } - - /* Handle "objects" */ carry(pickup); @@ -2780,7 +2420,7 @@ void do_cmd_stay(int pickup) if (c_ptr->feat == FEAT_SHOP) { /* Disturb */ - disturb(0, 0); + disturb(); /* Hack -- enter store */ command_new = '_'; @@ -2790,17 +2430,19 @@ void do_cmd_stay(int pickup) /* * Resting allows a player to safely restore his hp -RAK- */ -void do_cmd_rest(void) +void do_cmd_rest() { + auto const &f_info = game->edit_data.f_info; + /* Can't rest on a Void Jumpgate -- too dangerous */ if (cave[p_ptr->py][p_ptr->px].feat == FEAT_BETWEEN) { /* 'R&\n' is one of our favourite macros, so we have to do this */ - if (flush_failure) flush(); + flush_on_failure(); /* 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; @@ -2810,7 +2452,7 @@ void do_cmd_rest(void) if (p_ptr->necro_extra & CLASS_UNDEAD) { /* 'R&\n' is one of our favourite macros, so we have to do this */ - if (flush_failure) flush(); + flush_on_failure(); /* Tell the player why */ msg_print("Resting is impossible while undead!"); @@ -2863,14 +2505,11 @@ void do_cmd_rest(void) /* Save the rest code */ resting = command_arg; - /* Cancel searching */ - p_ptr->searching = FALSE; - /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Redraw the state */ - p_ptr->redraw |= (PR_STATE); + p_ptr->redraw |= (PR_FRAME); /* Handle stuff */ handle_stuff(); @@ -3020,7 +2659,7 @@ int get_shooter_mult(object_type *o_ptr) * * Note that Bows of "Extra Shots" give an extra shot. */ -void do_cmd_fire(void) +void do_cmd_fire() { int dir, item; @@ -3052,9 +2691,7 @@ void do_cmd_fire(void) char o_name[80]; - cptr q, s; - - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); /* Get the "bow" (if any) */ @@ -3082,14 +2719,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); @@ -3123,10 +2761,6 @@ void do_cmd_fire(void) } - /* Sound */ - sound(SOUND_SHOOT); - - /* Describe the object */ object_desc(o_name, q_ptr, FALSE, 3); @@ -3231,7 +2865,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(); } @@ -3240,7 +2874,7 @@ void do_cmd_fire(void) else { /* Pause anyway, for consistancy */ - Term_xtra(TERM_XTRA_DELAY, msec); + sleep_for(milliseconds(msec)); } @@ -3250,7 +2884,7 @@ void do_cmd_fire(void) cave_type *c_ptr = &cave[y][x]; monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto const r_ptr = m_ptr->race(); /* Check the visibility */ visible = m_ptr->ml; @@ -3267,9 +2901,9 @@ void do_cmd_fire(void) cptr note_dies = " dies."; /* Some monsters get "destroyed" */ - if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || + if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || (strchr("Evg", r_ptr->d_char))) { /* Special note at death */ @@ -3357,9 +2991,6 @@ void do_cmd_fire(void) { char m_name[80]; - /* Sound */ - sound(SOUND_FLEE); - /* Get the monster name (or "it") */ monster_desc(m_name, m_ptr, 0); @@ -3459,9 +3090,11 @@ void do_cmd_fire(void) * to hit bonus of the weapon to have an effect? Should it ever cause * the item to be destroyed? Should it do any damage at all? */ -void do_cmd_throw(void) +void do_cmd_throw() { - int dir, item; + auto const &k_info = game->edit_data.k_info; + + int dir; s32b special = 0; @@ -3480,8 +3113,6 @@ void do_cmd_throw(void) object_type *q_ptr; - object_type *o_ptr; - bool_ hit_body = FALSE; bool_ hit_wall = FALSE; @@ -3492,26 +3123,25 @@ void do_cmd_throw(void) char o_name[80]; - int msec = delay_factor * delay_factor * delay_factor; - - cptr q, s; - - u32b f1, f2, f3, f4, f5, esp; - + auto const msec = options->delay_factor_ms(); /* 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); - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack - Cannot throw away 'no drop' cursed items */ - if (cursed_p(o_ptr) && (f4 & TR4_CURSE_NO_DROP)) + if (cursed_p(o_ptr) && (flags & TR_CURSE_NO_DROP)) { /* Oops */ msg_print("Hmmm, you seem to be unable to throw it."); @@ -3647,7 +3277,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(); } @@ -3656,7 +3286,7 @@ void do_cmd_throw(void) else { /* Pause anyway, for consistancy */ - Term_xtra(TERM_XTRA_DELAY, msec); + sleep_for(milliseconds(msec)); } @@ -3666,7 +3296,7 @@ void do_cmd_throw(void) cave_type *c_ptr = &cave[y][x]; monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto r_ptr = m_ptr->race(); /* Check the visibility */ visible = m_ptr->ml; @@ -3683,9 +3313,9 @@ void do_cmd_throw(void) cptr note_dies = " dies."; /* Some monsters get "destroyed" */ - if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || + if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || (strchr("Evg", r_ptr->d_char))) { /* Special note at death */ @@ -3769,9 +3399,6 @@ void do_cmd_throw(void) { char m_name[80]; - /* Sound */ - sound(SOUND_FLEE); - /* Get the monster name (or "it") */ monster_desc(m_name, m_ptr, 0); @@ -3839,8 +3466,10 @@ void do_cmd_throw(void) * to hit bonus of the weapon to have an effect? Should it ever cause * the item to be destroyed? Should it do any damage at all? */ -void do_cmd_boomerang(void) +void do_cmd_boomerang() { + auto const &k_info = game->edit_data.k_info; + int dir; int j, y, x, ny, nx, ty, tx; @@ -3867,7 +3496,7 @@ void do_cmd_boomerang(void) s32b special = 0; - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); /* Get the "bow" (if any) */ @@ -3974,7 +3603,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(); } @@ -3983,7 +3612,7 @@ void do_cmd_boomerang(void) else { /* Pause anyway, for consistancy */ - Term_xtra(TERM_XTRA_DELAY, msec); + sleep_for(milliseconds(msec)); } @@ -3993,7 +3622,7 @@ void do_cmd_boomerang(void) cave_type *c_ptr = &cave[y][x]; monster_type *m_ptr = &m_list[c_ptr->m_idx]; - monster_race *r_ptr = race_inf(m_ptr); + auto const r_ptr = m_ptr->race(); /* Check the visibility */ visible = m_ptr->ml; @@ -4010,9 +3639,9 @@ void do_cmd_boomerang(void) cptr note_dies = " dies."; /* Some monsters get "destroyed" */ - if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || + if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || (strchr("Evg", r_ptr->d_char))) { /* Special note at death */ @@ -4096,9 +3725,6 @@ void do_cmd_boomerang(void) { char m_name[80]; - /* Sound */ - sound(SOUND_FLEE); - /* Get the monster name (or "it") */ monster_desc(m_name, m_ptr, 0); @@ -4111,8 +3737,7 @@ void do_cmd_boomerang(void) j = (hit_body ? breakage_chance(o_ptr) : 0); /* Break the boomerang */ - if (!(o_ptr->art_name || artifact_p(o_ptr)) && - (rand_int(100) < j)) + if ((!artifact_p(o_ptr)) && (rand_int(100) < j)) { msg_print(format("Your %s is destroyed.", o_name)); inc_stack_size_ex(INVEN_BOW, -1, OPTIMIZE, NO_DESCRIBE); @@ -4150,7 +3775,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(); } @@ -4159,194 +3784,24 @@ void do_cmd_boomerang(void) else { /* Pause anyway, for consistancy */ - Term_xtra(TERM_XTRA_DELAY, 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; + sleep_for(milliseconds(msec)); } } - - /* 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)) + auto const &d_info = game->edit_data.d_info; + + /* quest? */ + if (p_ptr->inside_quest) { msg_print("There is no effect."); return (FALSE); } - if (dungeon_flags2 & DF2_NO_EASY_MOVE) + if (dungeon_flags & DF_NO_EASY_MOVE) { msg_print("Some powerful force prevents you from teleporting."); return FALSE; @@ -4386,7 +3841,7 @@ static bool_ tport_vertically(bool_ how) * Do a special ``movement'' action. Meant to be used for ``immovable'' * characters. */ -void do_cmd_immovable_special(void) +void do_cmd_immovable_special() { int i, ii, ij, dir; @@ -4447,8 +3902,8 @@ void do_cmd_immovable_special(void) /* Give some choices */ prt("(a) Teleport to a specific place.", 4, 5); prt("(b) Fetch an item.", 5, 5); - prt("(c) Go up 50'", 6, 5); - prt("(d) Go down 50'", 7, 5); + prt("(c) Go up one level", 6, 5); + prt("(d) Go down one level", 7, 5); /* Prompt */ prt("Command: ", 9, 0); @@ -4484,7 +3939,7 @@ void do_cmd_immovable_special(void) if (!get_aim_dir(&dir)) return; fetch(dir, p_ptr->lev * 15, FALSE); - py_pickup_floor(always_pickup); + py_pickup_floor(options->always_pickup); did_act = TRUE; break; @@ -4542,13 +3997,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; @@ -4556,17 +4011,19 @@ 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) return (TRUE); /* Books without any udun spells */ - if ((o_ptr->tval == TV_BOOK) && (exec_lua(format("return udun_in_book(%d, %d)", o_ptr->sval, o_ptr->pval)) == 0)) + if ((o_ptr->tval == TV_BOOK) && udun_in_book(o_ptr->sval, o_ptr->pval) <= 0) + { return TRUE; + } } /* Assume not */ @@ -4574,17 +4031,56 @@ 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 const *o_ptr) +{ + /* perhaps restrict this only to metal armour and weapons */ + return (o_ptr->found == OBJ_FOUND_SELFMADE); +} + +/* + * Handle sacrifices to Aule + */ +static void do_cmd_sacrifice_aule() +{ + int item; + + if (!get_item(&item, + "Sacrifice which item? ", + "You have nothing to sacrifice.", + USE_INVEN, + item_tester_hook_sacrifice_aule)) + { + return; + } + + /* Increase piety by the value of the item / 10. */ + { + object_type *o_ptr = get_object(item); + s32b delta = object_value(o_ptr) / 10; + + inc_piety(GOD_ALL, delta); + } + + /* Destroy the object */ + inc_stack_size(item, -1); +} + +/* * Handle sacrifices. * Grace is increased by value of sacrifice. */ -void do_cmd_sacrifice(void) +void do_cmd_sacrifice() { + auto const &r_info = game->edit_data.r_info; + byte on_what = cave[p_ptr->py][p_ptr->px].feat; /* Check valididty */ if ((on_what < FEAT_ALTAR_HEAD) || (on_what > FEAT_ALTAR_TAIL)) { - show_god_info(FALSE); + show_god_info(); return; } else @@ -4592,7 +4088,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; @@ -4610,7 +4106,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? ")) @@ -4638,15 +4134,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) @@ -4657,7 +4156,7 @@ void do_cmd_sacrifice(void) /* In books it depends of the spell levels*/ if (o_ptr->tval == TV_BOOK) { - int x = exec_lua(format("return levels_in_book(%d, %d)", o_ptr->sval, o_ptr->pval)); + int x = levels_in_book(o_ptr->sval, o_ptr->pval); inc_piety(GOD_MELKOR, 2 * x); } @@ -4666,10 +4165,12 @@ void do_cmd_sacrifice(void) inc_stack_size(item, -1); } } - else + + if (p_ptr->pgod == GOD_AULE) { - process_hooks(HOOK_SACRIFICE_GOD, "()", ""); + do_cmd_sacrifice_aule(); } + } } } @@ -4680,148 +4181,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 (if needed) */ - if (show_weights) lim -= 9; + /* 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; - /* Be sure to account for the weight */ - if (show_weights) l += 9; + /* 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 */ - if (show_weights) { 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; } @@ -4830,26 +4297,18 @@ 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; + auto const &r_info = game->edit_data.r_info; - 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)) { @@ -4857,17 +4316,17 @@ 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; } /* The monster is immune */ - if (r_info[m_ptr->r_idx].flags7 & (RF7_NO_THEFT)) + if (r_info[m_ptr->r_idx].flags & RF_NO_THEFT) { msg_print("The monster is guarding the treasures."); return; @@ -4875,7 +4334,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) @@ -4885,7 +4344,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); @@ -4912,7 +4371,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(); @@ -4920,7 +4379,7 @@ void do_cmd_steal() } /* Verify the item */ - if (ver && !verify("Try", 0 - monst_list[k])) + if (ver && !verify("Try", -objects[k])) { done = TRUE; @@ -4928,7 +4387,7 @@ void do_cmd_steal() } /* Accept that choice */ - item = monst_list[k]; + item = objects[k]; done = TRUE; break; @@ -4966,17 +4425,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_flags_p(PR_EASE_STEAL)) { s32b max_point; @@ -4990,8 +4443,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) @@ -5000,7 +4454,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); @@ -5012,7 +4466,7 @@ void do_cmd_steal() inven_carry(o_ptr, FALSE); } - /* Delete it */ + /* Delete source item */ o_list[item].k_idx = 0; } @@ -5028,24 +4482,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) @@ -5055,12 +4501,18 @@ 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)) { msg_print("The monster does not want your item."); } @@ -5098,7 +4550,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..9641dc72 --- /dev/null +++ b/src/cmd2.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "h-basic.h" +#include "object_type_fwd.hpp" +#include <vector> + +std::vector<s16b> show_monster_inven(int m_idx); +int breakage_chance(object_type *o_ptr); +void do_cmd_go_up(); +void do_cmd_go_down(); +void do_cmd_search(); +void do_cmd_toggle_search(); +void do_cmd_open(); +void do_cmd_close(); +void do_cmd_chat(); +void do_cmd_give(); +void do_cmd_tunnel(); +void do_cmd_bash(); +void do_cmd_alter(); +void do_cmd_spike(); +void do_cmd_walk(int pickup); +void do_cmd_stay(int pickup); +void do_cmd_run(); +void do_cmd_rest(); +int get_shooter_mult(object_type *o_ptr); +void do_cmd_fire(); +void do_cmd_throw(); +void do_cmd_boomerang(); +void do_cmd_immovable_special(); +void fetch(int dir, int wgt, bool_ require_los); +void do_cmd_sacrifice(); +void do_cmd_steal(); diff --git a/src/cmd3.c b/src/cmd3.cc index 02dbc1c4..cbf58820 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,14 +5,51 @@ * not for profit purposes provided that this copyright and statement are * included in all such copies. */ - -#include "angband.h" - +#include "cmd3.hpp" + +#include "artifact_type.hpp" +#include "cave.hpp" +#include "cave_type.hpp" +#include "cli_comm.hpp" +#include "files.hpp" +#include "game.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 "monster_race_flag.hpp" +#include "object1.hpp" +#include "object2.hpp" +#include "object_flag.hpp" +#include "object_kind.hpp" +#include "object_type.hpp" +#include "options.hpp" +#include "player_type.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 "z-rand.hpp" + +#include <cassert> +#include <algorithm> +#include <fmt/format.h> +#include <memory> +#include <utility> /* * Display p_ptr->inventory */ -void do_cmd_inven(void) +void do_cmd_inven() { char out_val[160]; @@ -28,16 +61,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(); @@ -77,7 +104,7 @@ void do_cmd_inven(void) /* * Display equipment */ -void do_cmd_equip(void) +void do_cmd_equip() { char out_val[160]; @@ -89,16 +116,10 @@ void do_cmd_equip(void) character_icky = TRUE; Term_save(); - /* Hack -- show empty slots */ - item_tester_full = TRUE; - /* Display the equipment */ - show_equip(); - - /* Hack -- undo the hack above */ - item_tester_full = FALSE; + show_equip_full(); - /* Build a prompt */ + /* Show prompt */ { s32b total_weight = calc_total_weight(); @@ -139,30 +160,20 @@ 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); - - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - /* Only one ultimate at a time */ - if (f4 & TR4_ULTIMATE) + if (object_flags(o_ptr) & TR_ULTIMATE) { - int i; - - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) + for (int i = INVEN_WIELD; i < INVEN_TOTAL; i++) { object_type *q_ptr = &p_ptr->inventory[i]; - /* Extract the flags */ - object_flags(q_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (!q_ptr->k_idx) continue; - if (f4 & TR4_ULTIMATE) return (FALSE); + if (object_flags(q_ptr) & TR_ULTIMATE) return (FALSE); } } @@ -193,35 +204,34 @@ bool_ is_slot_ok(int slot) /* * Wield or wear a single item from the pack or floor */ -void do_cmd_wield(void) +void do_cmd_wield() { + auto const &a_info = game->edit_data.a_info; + int item, slot, num = 1; object_type forge; 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); @@ -240,7 +250,7 @@ void do_cmd_wield(void) return; } - if ((cursed_p(o_ptr)) && (wear_confirm) + if ((cursed_p(o_ptr)) && (options->wear_confirm) && (object_known_p(o_ptr) || (o_ptr->ident & (IDENT_SENSE)))) { char dummy[512]; @@ -254,14 +264,20 @@ 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); + auto const flags = object_flags(o_ptr); /* Two handed weapons can't be wielded with a shield */ if ((is_slot_ok(slot - INVEN_WIELD + INVEN_ARM)) && - (f4 & TR4_MUST2H) && + (flags & TR_MUST2H) && (p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_idx != 0)) { object_desc(o_name, o_ptr, FALSE, 0); @@ -274,10 +290,10 @@ void do_cmd_wield(void) i_ptr = &p_ptr->inventory[slot - INVEN_ARM + INVEN_WIELD]; /* Extract the flags */ - object_flags(i_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const i_flags = object_flags(i_ptr); /* Prevent shield from being put on if wielding 2H */ - if ((f4 & TR4_MUST2H) && (i_ptr->k_idx) && + if ((i_flags & TR_MUST2H) && (i_ptr->k_idx) && (p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM)) { object_desc(o_name, o_ptr, FALSE, 0); @@ -286,7 +302,7 @@ void do_cmd_wield(void) } if ((p_ptr->body_parts[slot - INVEN_WIELD] == INVEN_ARM) && - (f4 & TR4_COULD2H)) + (i_flags & TR_COULD2H)) { if (!get_check("Are you sure you want to restrict your fighting? ")) { @@ -295,13 +311,9 @@ void do_cmd_wield(void) } } - - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if ((is_slot_ok(slot - INVEN_WIELD + INVEN_ARM)) && (p_ptr->inventory[slot - INVEN_WIELD + INVEN_ARM].k_idx != 0) && - (f4 & TR4_COULD2H)) + (flags & TR_COULD2H)) { if (!get_check("Are you sure you want to use this weapon with a shield?")) { @@ -309,19 +321,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; @@ -348,7 +347,7 @@ void do_cmd_wield(void) if (o_ptr->k_idx) { /* Take off existing item */ - (void)inven_takeoff(slot, 255, FALSE); + inven_takeoff(slot, 255, FALSE); } } else @@ -358,7 +357,7 @@ void do_cmd_wield(void) if (!object_similar(o_ptr, q_ptr)) { /* Take off existing item */ - (void)inven_takeoff(slot, 255, FALSE); + inven_takeoff(slot, 255, FALSE); } else { @@ -440,7 +439,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); } @@ -450,25 +449,20 @@ void do_cmd_wield(void) /* * Take off an item */ -void do_cmd_takeoff(void) +void do_cmd_takeoff() { - 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)) @@ -485,41 +479,37 @@ void do_cmd_takeoff(void) energy_use = 50; /* Take off the item */ - (void)inven_takeoff(item, 255, FALSE); + inven_takeoff(item, 255, FALSE); /* Recalculate hitpoint */ p_ptr->update |= (PU_HP); - p_ptr->redraw |= (PR_MH); + p_ptr->redraw |= (PR_FRAME); } /* * Drop an item */ -void do_cmd_drop(void) +void do_cmd_drop() { - 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_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + object_type *o_ptr = get_object(item); + auto const flags = object_flags(o_ptr); /* 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)) @@ -534,7 +524,7 @@ void do_cmd_drop(void) } else { - if (f4 & TR4_CURSE_NO_DROP) + if (flags & TR_CURSE_NO_DROP) { /* Oops */ msg_print("Hmmm, you seem to be unable to drop it."); @@ -545,8 +535,8 @@ void do_cmd_drop(void) } } - /* See how many items */ + int amt = 1; if (o_ptr->number > 1) { /* Get a quantity */ @@ -567,39 +557,37 @@ void do_cmd_drop(void) /* * Destroy an item */ -void do_cmd_destroy(void) +void do_cmd_destroy() { - int item, amt = 1; + auto const &k_info = game->edit_data.k_info; 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 */ @@ -619,20 +607,16 @@ 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; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if ((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr)) + auto const flags = object_flags(o_ptr); + if ((flags & TR_CURSE_NO_DROP) && cursed_p(o_ptr)) { /* Oops */ msg_print("Hmmm, you seem to be unable to destroy it."); @@ -643,7 +627,7 @@ void do_cmd_destroy(void) /* Artifacts cannot be destroyed */ - if (artifact_p(o_ptr) || o_ptr->art_name) + if (artifact_p(o_ptr)) { byte feel = SENSE_SPECIAL; @@ -673,12 +657,11 @@ void do_cmd_destroy(void) /* Message */ msg_format("You destroy %s.", o_name); - sound(SOUND_DESTITEM); /* Create an automatizer rule */ if (automatizer_create) { - automatizer_add_rule(o_ptr, TRUE); + automatizer_add_rule(o_ptr); } /* @@ -692,8 +675,10 @@ void do_cmd_destroy(void) } /* Eru wont be happy */ - if (f3 & TR3_BLESSED) + if (flags & TR_BLESSED) + { inc_piety(GOD_ERU, -10 * k_info[o_ptr->k_idx].level); + } /* Eliminate the item */ inc_stack_size(item, -amt); @@ -703,26 +688,23 @@ void do_cmd_destroy(void) /* * Observe an item which has been *identify*-ed */ -void do_cmd_observe(void) +void do_cmd_observe() { - 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 */ @@ -738,25 +720,23 @@ void do_cmd_observe(void) * Remove the inscription from an object * XXX Mention item (when done)? */ -void do_cmd_uninscribe(void) +void do_cmd_uninscribe() { - 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) + if (o_ptr->inscription.empty()) { msg_print("That item had no inscription to remove."); return; @@ -766,7 +746,7 @@ void do_cmd_uninscribe(void) msg_print("Inscription removed."); /* Remove the incription */ - o_ptr->note = 0; + o_ptr->inscription.clear(); /* Combine the pack */ p_ptr->notice |= (PN_COMBINE); @@ -779,49 +759,38 @@ void do_cmd_uninscribe(void) /* * Inscribe an object with a comment */ -void do_cmd_inscribe(void) +void do_cmd_inscribe() { - 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."; |