diff options
author | Manoj Srivastava <srivasta@debian.org> | 2020-05-22 20:05:37 -0700 |
---|---|---|
committer | Manoj Srivastava <srivasta@debian.org> | 2020-05-22 21:39:31 -0700 |
commit | 035291b7f18974925f9a85a41e057bdc462c75f1 (patch) | |
tree | d69056be1a045aec185393b52dadb6fc2d5f50c9 /src | |
parent | 9714b44a37dfc03aa00187726beea7ed8257415e (diff) | |
parent | 4e9b9c402ed95bf9a17fd6d795bc49bb4128a6fa (diff) |
Merge branch 'upstream'
Diffstat (limited to 'src')
341 files changed, 20627 insertions, 39547 deletions
diff --git a/src/.gitignore b/src/.gitignore index 098f3b10..485f14c6 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,7 @@ /harness -/tome +/tome-gcu +/tome-gtk2 +/tome-sdl +/tome-x11 +/tome-win *.plist diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4b2d2db..30ceb76c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,9 @@ 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) @@ -22,6 +25,7 @@ SET(SRCS_COMMON dice.cc dungeon.cc files.cc + game.cc gen_evol.cc gen_maze.cc generate.cc @@ -32,14 +36,17 @@ SET(SRCS_COMMON 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 @@ -48,7 +55,9 @@ SET(SRCS_COMMON object1.cc object2.cc object_filter.cc + object_flag_meta.cc options.cc + player_type.cc powers.cc q_betwen.cc q_bounty.cc @@ -78,11 +87,9 @@ SET(SRCS_COMMON q_ultrag.cc q_wight.cc q_wolves.cc - quark.cc quest.cc randart.cc range.cc - script.cc skills.cc spell_type.cc spells1.cc @@ -92,15 +99,13 @@ SET(SRCS_COMMON spells5.cc spells6.cc squeltch.cc - status.cc store.cc tables.cc - traps.cc util.cc variable.cc wild.cc - wizard1.cc wizard2.cc + seed.cc xtra1.cc xtra2.cc z-form.c @@ -109,31 +114,27 @@ SET(SRCS_COMMON z-util.c ) -# Sources (PROGRAM) -SET(SRCS_PROGRAM - main-gcu.c - main-gtk2.c - main-sdl.c - main-x11.c - main.c -) - # Sources (TEST) SET(SRCS_TESTS ../tests/get_level_device.cc ../tests/harness.cc ../tests/lua_get_level.cc + ../tests/flag_set.cc + ../tests/grid.cc ) ADD_LIBRARY(game - ${SRCS_COMMON} + ${SRCS_COMMON} ${SRCS_VENDOR} ) +ADD_LIBRARY(game_main + main.cc) + # Need a few additional source files for Windows. -if(WIN32) +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 @@ -141,20 +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() -# tome executable -ADD_EXECUTABLE(tome ${EXECUTABLE_OPTIONS} ${SRCS_PROGRAM}) -TARGET_LINK_LIBRARIES(tome game squelch ${LIBS}) +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() + +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() + +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() # test harness executable -ADD_EXECUTABLE(harness ${EXECUTABLE_OPTIONS} ${SRCS_TESTS}) +ADD_EXECUTABLE(harness ${SRCS_TESTS}) TARGET_LINK_LIBRARIES(harness game squelch ${LIBS}) - -# Installation -INSTALL(TARGETS tome - RUNTIME DESTINATION games -) diff --git a/src/ability_type.hpp b/src/ability_type.hpp index ea8a921d..0ec596ba 100644 --- a/src/ability_type.hpp +++ b/src/ability_type.hpp @@ -1,5 +1,8 @@ #pragma once +#include <string> +#include <vector> + #include "h-basic.h" /** @@ -7,21 +10,38 @@ */ struct ability_type { - const char *name; /* Name */ - char *desc; /* Description */ +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 */ - const char *action_desc; /* Action Description */ + std::vector<skill_requirement> need_skills; /* List of prereq skills */ - s16b action_mkey; /* Action do to */ + s16b stat[6] { }; /* List of prereq stats */ - s16b cost; /* Skill points cost */ + std::vector<s16b> need_abilities; /* List of prereq abilities */ - bool_ acquired; /* Do the player actualylg ot it ? */ + /** + * Default constructor + */ + ability_type() + { + for (auto &stat_ref: stat) + { + // Requirement is always met unless otherwise specified. + stat_ref = -1; + } + } - /* Prereqs */ - s16b skills[10]; /* List of prereq skills(10 max) */ - s16b skill_levels[10]; /* List of prereq skills(10 max) */ - s16b stat[6]; /* List of prereq stats */ - s16b need_abilities[10]; /* List of prereq abilities(10 max) */ - s16b forbid_abilities[10]; /* List of forbidden abilities(10 max) */ }; diff --git a/src/ability_type_fwd.hpp b/src/ability_type_fwd.hpp deleted file mode 100644 index bade8638..00000000 --- a/src/ability_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct ability_type; 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 index 41ec3b66..5e0e547f 100644 --- a/src/alloc_entry.hpp +++ b/src/alloc_entry.hpp @@ -11,10 +11,10 @@ */ struct alloc_entry { - s16b index; /* The actual index */ + s16b index = -1; /* The actual index */ - byte level; /* Base dungeon level */ - byte prob1; /* Probability, pass 1 */ - byte prob2; /* Probability, pass 2 */ - byte prob3; /* Probability, pass 3 */ + 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/artifact_type.hpp b/src/artifact_type.hpp index 7a4340aa..9f866aa7 100644 --- a/src/artifact_type.hpp +++ b/src/artifact_type.hpp @@ -1,6 +1,7 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" /** * Artifact descriptor. @@ -11,50 +12,39 @@ */ struct artifact_type { - char const *name; /* Artifact name */ - char *text; /* Artifact description */ + char const *name = nullptr; /* Artifact name */ + char *text = nullptr; /* Artifact description */ - byte tval; /* Artifact type */ - byte sval; /* Artifact sub type */ + byte tval = 0; /* Artifact type */ + byte sval = 0; /* Artifact sub type */ - s16b pval; /* Artifact extra info */ + s16b pval = 0; /* Artifact extra info */ - s16b to_h; /* Bonus to hit */ - s16b to_d; /* Bonus to damage */ - s16b to_a; /* Bonus to armor */ + s16b to_h = 0; /* Bonus to hit */ + s16b to_d = 0; /* Bonus to damage */ + s16b to_a = 0; /* Bonus to armor */ - s16b activate; /* Activation Number */ + s16b activate = 0; /* Activation Number */ - s16b ac; /* Base armor */ + s16b ac = 0; /* Base armor */ - byte dd, ds; /* Damage when hits */ + byte dd = 0; /* Damage dice */ + byte ds = 0; /* Damage sides */ - s16b weight; /* Weight */ + s16b weight = 0; /* Weight */ - s32b cost; /* Artifact "cost" */ + s32b cost = 0; /* Artifact "cost" */ - u32b flags1; /* Artifact Flags, set 1 */ - u32b flags2; /* Artifact Flags, set 2 */ - u32b flags3; /* Artifact Flags, set 3 */ - u32b flags4; /* Artifact Flags, set 4 */ - u32b flags5; /* Artifact Flags, set 5 */ + object_flag_set flags; /* Artifact Flags */ + object_flag_set oflags; /* Obvious Flags */ - u32b oflags1; /* Obvious Flags, set 1 */ - u32b oflags2; /* Obvious Flags, set 2 */ - u32b oflags3; /* Obvious Flags, set 3 */ - u32b oflags4; /* Obvious Flags, set 4 */ - u32b oflags5; /* Obvious Flags, set 5 */ + byte level = 0; /* Artifact level */ + byte rarity = 0; /* Artifact rarity */ - byte level; /* Artifact level */ - byte rarity; /* Artifact rarity */ + byte cur_num = 0; /* Number created (0 or 1) */ - byte cur_num; /* Number created (0 or 1) */ - byte max_num; /* Unused (should be "1") */ + s16b power = 0; /* Power granted, if any */ - u32b esp; /* ESP flags */ - u32b oesp; /* ESP flags */ + s16b set = 0; /* Which set does it belong it, if any? */ - s16b power; /* Power granted(if any) */ - - s16b set; /* Does it belongs to a set ?*/ }; diff --git a/src/artifact_type_fwd.hpp b/src/artifact_type_fwd.hpp deleted file mode 100644 index f3862d5a..00000000 --- a/src/artifact_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct artifact_type; diff --git a/src/birth.cc b/src/birth.cc index f3897496..f677e6e1 100644 --- a/src/birth.cc +++ b/src/birth.cc @@ -6,27 +6,27 @@ * included in all such copies. */ #include "birth.hpp" -#include "birth.h" #include "ability_type.hpp" #include "artifact_type.hpp" #include "corrupt.hpp" #include "cmd4.hpp" #include "cmd5.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "files.h" #include "files.hpp" +#include "game.hpp" #include "gods.hpp" #include "help.hpp" -#include "hist_type.hpp" #include "hooks.hpp" #include "init2.hpp" #include "mimic.hpp" #include "messages.hpp" -#include "meta_class_type.hpp" #include "modules.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "notes.hpp" #include "object1.hpp" #include "object2.hpp" @@ -34,6 +34,7 @@ #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" @@ -46,7 +47,6 @@ #include "store.hpp" #include "tables.hpp" #include "town_type.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -56,6 +56,10 @@ #include "xtra2.hpp" #include "z-rand.hpp" +#include <algorithm> +#include <boost/filesystem.hpp> +#include <fmt/format.h> +#include <numeric> #include <string> /* @@ -100,73 +104,48 @@ static s32b auto_round; */ static s32b last_round; -/* Human */ -static const char *human_syllable1[] = -{ - "Ab", "Ac", "Ad", "Af", "Agr", "Ast", "As", "Al", "Adw", "Adr", "Ar", - "B", "Br", "C", "Cr", "Ch", "Cad", "D", "Dr", "Dw", "Ed", "Eth", "Et", - "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 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 const 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() { - const 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; } @@ -197,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; @@ -216,24 +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 history */ - for (i = 0; i < 4; i++) - { - strcpy(previous_char.history[i], history[i]); - } } @@ -242,45 +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 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]; @@ -288,35 +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 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 history */ - for (i = 0; i < 4; i++) - { - strcpy(previous_char.history[i], temp.history[i]); - } } @@ -385,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; @@ -436,7 +371,7 @@ 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]; /* Start fully healed */ p_ptr->stat_cur[i] = p_ptr->stat_max[i]; @@ -456,289 +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; + auto &player_hp = game->player_hp; + // Minimum hitpoints at highest level + int const min_value = + (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8 + PY_MAX_LEVEL; - /* 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; + // Maximum hitpoints at highest level + int const max_value = + (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8 + PY_MAX_LEVEL; - /* Initialize quest */ - p_ptr->inside_quest = 0; - - /* Hitdice */ - p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp; - - /* Initial hitpoints */ - p_ptr->mhp = p_ptr->hitdie; - - /* Minimum hitpoints at highest level */ - min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8; - min_value += PY_MAX_LEVEL; - - /* Maximum hitpoints at highest level */ - max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8; - max_value += 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; } /* - * 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); - - /* 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. */ -static 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; @@ -761,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; @@ -798,17 +565,19 @@ static void birth_put_stats(void) /* * Clear all the global "character" data */ -static void player_wipe(void) +static void player_wipe() { - int i, j; - + 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(); /* Hack -- zero the struct */ - static_assert(std::is_pod<player_type>::value, "Cannot memset non-POD type"); - memset(p_ptr, 0, sizeof(player_type)); + *p_ptr = player_type(); /* Level 1 is the first level */ p_ptr->lev = 1; @@ -816,33 +585,23 @@ static void player_wipe(void) /* Not dead yet */ p_ptr->lives = 0; - /* 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; i++) + for (std::size_t i = 0; i < MAX_Q_IDX; i++) { quest[i].status = QUEST_STATUS_UNTAKEN; for (auto &quest_data : quest[i].data) @@ -851,22 +610,12 @@ static void player_wipe(void) } } - /* 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]); } @@ -875,32 +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; + 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; @@ -909,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; @@ -924,12 +669,7 @@ static void player_wipe(void) p_ptr->food = PY_FOOD_FULL - 1; /* 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; @@ -939,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; } @@ -971,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 */ @@ -997,7 +727,7 @@ static void player_wipe(void) p_ptr->allow_one_death = 0; /* Wipe the power list */ - for (i = 0; i < POWER_MAX; i++) + for (std::size_t i = 0; i < POWER_MAX; i++) { p_ptr->powers_mod[i] = 0; } @@ -1014,29 +744,39 @@ static void player_wipe(void) /* 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); + } } @@ -1051,7 +791,7 @@ static void player_outfit_object(int qty, int tval, int sval) q_ptr->number = qty; object_aware(q_ptr); object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); } @@ -1074,11 +814,11 @@ static void player_outfit_spellbook(cptr spell_name) * * 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; - cptr subrace_name = rmp_ptr->title; + auto const &subrace_name = rmp_ptr->title; /* * Get an adventurer guide describing a bit of the @@ -1144,37 +884,37 @@ static void player_outfit(void) } /* Dragons */ - if (streq(subrace_name, "Red")) + if (subrace_name == "Red") { player_outfit_spellbook("Globe of Light"); } - if (streq(subrace_name, "Black")) + if (subrace_name == "Black") { player_outfit_spellbook("Geyser"); } - if (streq(subrace_name, "Green")) + if (subrace_name == "Green") { player_outfit_spellbook("Noxious Cloud"); } - if (streq(subrace_name, "Blue")) + if (subrace_name == "Blue") { player_outfit_spellbook("Stone Skin"); } - if (streq(subrace_name, "White")) + if (subrace_name == "White") { player_outfit_spellbook("Sense Monsters"); } - if (streq(subrace_name, "Ethereal")) + if (subrace_name == "Ethereal") { player_outfit_spellbook("Recharge"); } /* Demons */ - if (streq(subrace_name, "(Aewrog)")) + if (subrace_name == "(Aewrog)") { player_outfit_spellbook("Charm"); } - if (streq(subrace_name, "(Narrog)")) + if (subrace_name == "(Narrog)") { player_outfit_spellbook("Phase Door"); } @@ -1212,7 +952,7 @@ static void player_outfit(void) identify_pack_fully(); } - if (streq(rmp_ptr->title, "Vampire")) + if (rmp_ptr->title == "Vampire") { player_gain_corruption(CORRUPT_VAMPIRE_TEETH); player_gain_corruption(CORRUPT_VAMPIRE_STRENGTH); @@ -1237,55 +977,29 @@ static void player_outfit(void) q_ptr->timeout = rand_range(3, 7) * 500; object_aware(q_ptr); object_known(q_ptr); - (void)inven_carry(q_ptr, FALSE); - } - - /* Rogues have a better knowledge of traps */ - if (has_ability(AB_TRAPPING)) - { - 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); + inven_carry(q_ptr, FALSE); } - /* 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]); + /* 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]; /* 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 = ' '; @@ -1302,7 +1016,7 @@ 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, cp_ptr->title, mod); + (n <= 25) ? I2A(n) : I2D(n - 26), p2, cp_ptr->title.c_str(), mod); /* Print some more info */ if (sel == n) @@ -1310,7 +1024,7 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions) std::string desc; desc += cp_ptr->desc; - if (cp_ptr->flags1 & PR1_EXPERIMENTAL) + if (cp_ptr->flags & PR_EXPERIMENTAL) { desc += "\nEXPERIMENTAL"; } @@ -1318,7 +1032,7 @@ int dump_classes(s16b *classes, int sel, u32b *restrictions) 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)); @@ -1326,36 +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++; - } - 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]; + assert(sel_ >= 0); + std::size_t sel = sel_; - /* 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]; + spp_ptr = &(*specs)[p_ptr->pspec]; if (sel == n) { @@ -1364,6 +1076,7 @@ int dump_specs(int sel) } /* Display */ + char buf[80]; strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, spp_ptr->title); /* Print some more info */ @@ -1372,32 +1085,40 @@ int dump_specs(int sel) std::string desc; desc += spp_ptr->desc; - if (spp_ptr->flags1 & PR1_EXPERIMENTAL) + 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)); + } } } - - 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]; @@ -1405,7 +1126,7 @@ int dump_races(int sel) /* 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 = ' '; @@ -1420,7 +1141,7 @@ int dump_races(int sel) } /* Display */ - strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, rp_ptr->title); + strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, rp_ptr->title.c_str()); /* Print some more info */ if (sel == n) @@ -1428,21 +1149,21 @@ int dump_races(int sel) std::string desc; desc += rp_ptr->desc; - if (rp_ptr->flags1 & PR1_EXPERIMENTAL) + if (rp_ptr->flags & PR_EXPERIMENTAL) { desc += "\nEXPERIMENTAL"; } print_desc(desc.c_str()); - if (rp_ptr->flags1 & PR1_EXPERIMENTAL) + 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)); @@ -1453,8 +1174,10 @@ int dump_races(int sel) } -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]; @@ -1479,7 +1202,7 @@ int dump_rmods(int sel, int *racem, int max) /* Display */ if (racem[n]) - strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, rmp_ptr->title); + 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); @@ -1488,22 +1211,22 @@ int dump_rmods(int sel, int *racem, int max) { std::string desc; - desc += rmp_ptr->desc; - if (rmp_ptr->flags1 & PR1_EXPERIMENTAL) + 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)); @@ -1513,7 +1236,7 @@ int dump_rmods(int sel, int *racem, int max) 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]; @@ -1576,7 +1299,12 @@ 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; + + int k, n, v, sel; int racem[100], max_racem = 0; @@ -1584,12 +1312,12 @@ static bool_ player_birth_aux_ask() char c; - char p2 = ')'; - char buf[200]; char inp[200]; - s16b *class_types; + int const NAME_ROW = 2; + int const RACE_ROW = 3; + int const CLASS_ROW = 4; /*** Intro ***/ @@ -1597,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 ***/ @@ -1621,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); @@ -1650,78 +1372,22 @@ 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]; - - /* Display */ - strnfmt(buf, 200, "%c%c %s", I2A(n), p2, sp_ptr->title); - 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]; - - /* Display */ - c_put_str(TERM_L_BLUE, sp_ptr->title, 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 */ @@ -1736,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(); @@ -1744,7 +1410,7 @@ 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); @@ -1799,13 +1465,16 @@ static bool_ player_birth_aux_ask() rp_ptr = &race_info[p_ptr->prace]; /* Display */ - c_put_str(TERM_L_BLUE, rp_ptr->title, 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); @@ -1814,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; @@ -1867,16 +1538,24 @@ 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 == '?') { - help_subrace(race_mod_info[racem[sel]].title); + help_subrace(race_mod_info[racem[sel]].title.c_str()); } k = (islower(c) ? A2I(c) : -1); @@ -1927,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); } } @@ -1938,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) @@ -2072,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) @@ -2085,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) @@ -2152,7 +1805,7 @@ static bool_ player_birth_aux_ask() spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec]; /* Display */ - c_put_str(TERM_L_BLUE, spp_ptr->title, 5, 9); + c_put_str(TERM_L_BLUE, spp_ptr->title, CLASS_ROW, 9); /* Clean up */ clear_from(15); @@ -2160,11 +1813,11 @@ 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 (race_flags1_p(PR1_NO_GOD)) + else if (race_flags_p(PR_NO_GOD)) { p_ptr->pgod = GOD_NONE; } @@ -2271,7 +1924,7 @@ static bool_ player_birth_aux_ask() } /* A god that like us ? more grace ! */ - if (race_flags1_p(PR1_GOD_FRIEND)) + if (race_flags_p(PR_GOD_FRIEND)) { set_grace(200); } @@ -2298,10 +1951,8 @@ static bool_ player_birth_aux_ask() } } - /* Set birth options: maximize, preserve, sepcial levels and astral */ - p_ptr->preserve = preserve; - p_ptr->special = special_lvls; - p_ptr->astral = (race_flags2_p(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) @@ -2335,11 +1986,11 @@ static bool_ player_birth_aux_ask() /*** User enters number of quests ***/ /* Heino Vander Sanden and Jimmy De Laet */ - if (!ironman_rooms) + if (!options->ironman_rooms) { if (do_quick_start) { - v = previous_char.quests; + v = game->previous_char.quests; } else { @@ -2421,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); @@ -2453,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; @@ -2471,8 +2122,6 @@ static bool_ player_birth_aux_point(void) char buf[80]; - int mode = 0; - /* Initialize stats */ for (i = 0; i < 6; i++) @@ -2485,12 +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(); - /* Get luck */ p_ptr->luck_base = rp_ptr->luck + rmp_ptr->luck + rand_range( -5, 5); p_ptr->luck_max = p_ptr->luck_base; @@ -2543,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); @@ -2613,8 +2256,6 @@ static bool_ player_birth_aux_auto() { int i, j, m, v; - int mode = 0; - bool_ flag = FALSE; bool_ prev = FALSE; @@ -2631,7 +2272,7 @@ static bool_ player_birth_aux_auto() /* Initialize */ - if (autoroll) + if (options->autoroll) { int mval[6]; @@ -2655,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); @@ -2694,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, "/"); @@ -2734,20 +2375,19 @@ static bool_ player_birth_aux_auto() 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, 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); @@ -2775,7 +2415,7 @@ static bool_ player_birth_aux_auto() } /* Auto-roll */ - while (autoroll) + while (options->autoroll) { bool_ accept = TRUE; @@ -2833,18 +2473,9 @@ 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(); @@ -2864,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); @@ -2898,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 == '?') { @@ -2942,20 +2564,20 @@ static bool_ player_birth_aux_auto() */ static bool_ player_birth_aux() { - char c; - - int i, j; - - int y = 0, x = 0; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; - 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; @@ -2966,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; + } } } } @@ -3000,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; } @@ -3010,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(); @@ -3104,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 */ @@ -3113,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]; @@ -3222,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(); } /* @@ -3234,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) @@ -3258,14 +2713,15 @@ 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(); @@ -3274,19 +2730,19 @@ void player_birth(void) add_note_type(NOTE_BIRTH); /* Note player birth in the message recall */ - message_add(" ", TERM_L_BLUE); - message_add(" ", TERM_L_BLUE); - message_add("====================", TERM_L_BLUE); - message_add(" ", TERM_L_BLUE); - message_add(" ", 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; @@ -3295,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))) @@ -3307,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 */ @@ -3325,11 +2783,11 @@ void player_birth(void) if (wizard) { - message_add(format("Random dungeon town: d_idx:%d, lev:%d", i, lev), TERM_WHITE); + 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++; @@ -3341,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; @@ -3352,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); @@ -3360,13 +2818,15 @@ 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; } } } @@ -3374,11 +2834,11 @@ void player_birth(void) -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 @@ -3388,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; @@ -3404,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; /* @@ -3463,7 +2923,7 @@ 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); /* Try to open the savefile */ @@ -3480,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); @@ -3512,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), + (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]); } @@ -3651,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 .. */ @@ -3675,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') { @@ -3694,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); @@ -3710,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.h b/src/birth.h deleted file mode 100644 index 41620bfa..00000000 --- a/src/birth.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "h-basic.h" - -// C linkage required for these functions since main-* code uses them. -#ifdef __cplusplus -extern "C" { -#endif - -extern bool_ no_begin_screen; - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/src/birth.hpp b/src/birth.hpp index fb036ecc..82bdfcf6 100644 --- a/src/birth.hpp +++ b/src/birth.hpp @@ -2,8 +2,10 @@ #include "h-basic.h" -extern void print_desc_aux(cptr txt, int y, int x); -extern void save_savefile_names(void); -extern bool_ begin_screen(void); -extern void get_height_weight(void); -extern void player_birth(void); +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 index f517fb9d..0c28b513 100644 --- a/src/birther.hpp +++ b/src/birther.hpp @@ -2,12 +2,14 @@ #include "h-basic.h" +#include <string> +#include <vector> + /** * Player information during the birth process. */ struct birther { - s16b sex; s16b race; s16b rmod; s16b pclass; @@ -17,19 +19,11 @@ struct birther byte god; s32b grace; - s32b god_favor; - - s16b age; - s16b wt; - s16b ht; - s16b sc; s32b au; s16b stat[6]; s16b luck; - char history[4][60]; - bool_ quick_ok; }; diff --git a/src/bldg.cc b/src/bldg.cc index 7095e8c3..9b3750a6 100644 --- a/src/bldg.cc +++ b/src/bldg.cc @@ -16,6 +16,7 @@ #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" @@ -23,7 +24,9 @@ #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" @@ -49,10 +52,11 @@ static int building_loc = 0; /* * A helper function for is_state */ -static 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)) @@ -74,7 +78,7 @@ static 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) { @@ -108,99 +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]; + auto const &ba_info = game->edit_data.ba_info; + auto const &st_info = game->edit_data.st_info; - int i; - - byte action_color; - - char tmp_str[80]; - - store_info_type *st_ptr = &st_info[s_ptr->st_idx]; + 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++) { - store_action_type *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]); } + } + else if (ba_ptr->action_restr == 1) + { + 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]); + } + } + 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)"); + } + } - strnfmt(tmp_str, 80, " %c", ba_ptr->letter); - c_put_str(TERM_YELLOW, tmp_str, 21 + (i / 2), 17 + (30 * (i % 2))); + char tmp_str[80]; - strnfmt(tmp_str, 80, ") %s %s", ba_ptr->name, buff); - c_put_str(action_color, tmp_str, 21 + (i / 2), 2 + 17 + (30 * (i % 2))); - } + 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.c_str(), buff); + c_put_str(action_color, tmp_str, 21 + (i / 2), 2 + 17 + (30 * (i % 2))); } } @@ -332,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,7 +541,7 @@ static bool_ inn_comm(int cmd) /* Extract race info */ - vampire = ((race_flags1_p(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) { @@ -551,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!"); @@ -743,7 +743,7 @@ static bool_ castle_quest(int y, int x) get_questinfo(plots[plot]); /* Add the hooks */ - quest[plots[plot]].init(plots[plot]); + quest[plots[plot]].init(); return (TRUE); } @@ -754,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(); @@ -770,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, const char *attr, 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]; @@ -788,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); } } @@ -905,7 +902,7 @@ static bool item_tester_hook_melee_weapon(object_type const *o_ptr) /* * compare_weapons -KMW- */ -static bool_ compare_weapons(void) +static bool_ compare_weapons() { int item, i; @@ -989,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; @@ -1084,7 +1080,7 @@ 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()); @@ -1095,18 +1091,14 @@ static bool_ research_item(void) /* * 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; @@ -1140,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: @@ -1218,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(); @@ -1232,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; } @@ -1306,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; } @@ -1445,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)) { diff --git a/src/bldg.hpp b/src/bldg.hpp index 0daebbee..3b3412fa 100644 --- a/src/bldg.hpp +++ b/src/bldg.hpp @@ -1,9 +1,10 @@ #pragma once #include "h-basic.h" +#include "store_action_type_fwd.hpp" #include "store_type_fwd.hpp" -extern bool_ bldg_process_command(store_type *s_ptr, int i); -extern void show_building(store_type *s_ptr); -extern bool_ is_state(store_type *s_ptr, int state); -extern void enter_quest(void); +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/cave.cc b/src/cave.cc index 5ff31019..cad1506e 100644 --- a/src/cave.cc +++ b/src/cave.cc @@ -1,12 +1,18 @@ #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" @@ -14,7 +20,6 @@ #include "spells1.hpp" #include "store_info_type.hpp" #include "tables.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -64,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; @@ -87,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; } @@ -353,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)); } @@ -379,7 +384,10 @@ bool_ cave_valid_bold(int y, int x) 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 */ @@ -393,6 +401,8 @@ bool_ cave_valid_bold(int y, int x) */ static void image_monster(byte *ap, char *cp) { + auto const &r_info = game->edit_data.r_info; + // Cached state which keeps a list of all the "live" monster race entries. static std::vector<size_t> *instance = nullptr; @@ -402,7 +412,7 @@ static void image_monster(byte *ap, char *cp) // Create the list of "live" indexes instance = new std::vector<size_t>(); // Start at 1 to avoid 'player' - for (size_t i = 1; i < max_r_idx; i++) + for (size_t i = 1; i < r_info.size(); i++) { if (r_info[i].name) { @@ -426,6 +436,8 @@ static void image_monster(byte *ap, char *cp) */ static void image_object(byte *ap, char *cp) { + auto const &k_info = game->edit_data.k_info; + // Cached state which keeps a list of the "live" object_kind entries. static std::vector<size_t> *instance = nullptr; @@ -435,7 +447,7 @@ static void image_object(byte *ap, char *cp) // Create the list of "live" indexes instance = new std::vector<size_t>(); // Filter all the "live" entries - for (size_t i = 0; i < max_k_idx; i++) + for (size_t i = 0; i < k_info.size(); i++) { if (k_info[i].name) { @@ -499,50 +511,60 @@ static 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 @@ -555,9 +577,7 @@ 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; @@ -570,18 +590,22 @@ static byte multi_hued_attr(std::shared_ptr<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)); @@ -595,7 +619,7 @@ static byte multi_hued_attr(std::shared_ptr<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; @@ -612,7 +636,7 @@ static byte multi_hued_attr(std::shared_ptr<monster_race> r_ptr) */ if (breaths == 1) { - second_color = breath_to_attr[i][1]; + second_color = breath_color->second_color; } } @@ -825,6 +849,11 @@ static byte darker_attrs[16] = static void map_info(int y, int x, byte *ap, char *cp) { + 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; @@ -841,20 +870,13 @@ static void map_info(int y, int x, byte *ap, char *cp) auto info = c_ptr->info; /* Feature code */ - auto 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 */ - feature_type *f_ptr = &f_info[feat]; + auto f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -887,43 +909,8 @@ static void map_info(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 */ - auto 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].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) + if (!options->avoid_other && !options->avoid_shimmer) { /* Special terrain effect */ if (c_ptr->effect) @@ -932,7 +919,7 @@ static void map_info(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)]; } @@ -945,7 +932,6 @@ static void map_info(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. * @@ -954,16 +940,16 @@ static void map_info(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; @@ -985,7 +971,7 @@ static void map_info(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]; @@ -994,10 +980,10 @@ static void map_info(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)) @@ -1013,7 +999,7 @@ static void map_info(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]; @@ -1058,34 +1044,31 @@ static void map_info(int y, int x, byte *ap, char *cp) /**** Layer 2 -- Objects ****/ - if (feat != FEAT_MON_TRAP) + for (auto const o_idx: c_ptr->o_idxs) { - for (auto const o_idx: c_ptr->o_idxs) - { - /* Acquire object */ - object_type *o_ptr = &o_list[o_idx]; + /* Acquire object */ + object_type *o_ptr = &o_list[o_idx]; - /* Memorized objects */ - if (o_ptr->marked) - { - /* Normal char */ - *cp = object_char(o_ptr); + /* Memorized objects */ + if (o_ptr->marked) + { + /* Normal char */ + *cp = object_char(o_ptr); - /* Normal attr */ - *ap = object_attr(o_ptr); + /* Normal attr */ + *ap = object_attr(o_ptr); - /* Multi-hued attr */ - if (!avoid_other && (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI)) - { - *ap = get_shimmer_color(); - } + /* Multi-hued attr */ + if (!options->avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI)) + { + *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; } } @@ -1097,7 +1080,7 @@ static void map_info(int y, int x, byte *ap, char *cp) monster_type *m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_MIMIC) { /* Acquire object being mimicked */ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; @@ -1112,7 +1095,7 @@ static void map_info(int y, int x, byte *ap, char *cp) *ap = object_attr(o_ptr); /* Multi-hued attr */ - if (!avoid_other && (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(); } @@ -1131,7 +1114,7 @@ static void map_info(int y, int x, byte *ap, char *cp) a = r_ptr->x_attr; /* Ignore weird codes */ - if (avoid_other) + if (options->avoid_other) { /* Use char */ *cp = c; @@ -1141,10 +1124,10 @@ static void map_info(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); } @@ -1152,7 +1135,7 @@ static void map_info(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); } @@ -1163,7 +1146,7 @@ static void map_info(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; @@ -1189,14 +1172,14 @@ static void map_info(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; @@ -1217,10 +1200,10 @@ static void map_info(int y, int x, byte *ap, char *cp) 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]; + auto r_ptr = &r_info[p_ptr->body_monster]; /* Get the "player" attr */ - if (!avoid_other && (r_ptr->flags1 & RF1_ATTR_MULTI)) + if (!options->avoid_other && (r_ptr->flags & RF_ATTR_MULTI)) { a = get_shimmer_color(); } @@ -1233,7 +1216,7 @@ static void map_info(int y, int x, byte *ap, char *cp) c = r_ptr->x_char; /* Show player health char instead? */ - if (player_char_health) + if (options->player_char_health) { int percent = p_ptr->chp * 10 / p_ptr->mhp; @@ -1258,14 +1241,22 @@ static void map_info(int y, int x, byte *ap, char *cp) */ void map_info_default(int y, int x, byte *ap, char *cp) { + 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; + /* Shorthand */ + auto const avoid_other = options->avoid_other; + /**** Preparation ****/ /* Access the grid */ - cave_type *c_ptr = &cave[y][x]; + auto const c_ptr = &cave[y][x]; /* Cache some frequently used values */ @@ -1274,20 +1265,12 @@ void map_info_default(int y, int x, byte *ap, char *cp) auto info = c_ptr->info; /* Feature code */ - auto 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 */ - feature_type *f_ptr = &f_info[feat]; + feature_type const *f_ptr = &f_info[feat]; /**** Layer 1 -- Terrain feature ****/ @@ -1321,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 */ - auto 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) { @@ -1366,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)]; } @@ -1379,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. * @@ -1388,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; @@ -1419,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]; @@ -1428,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)) @@ -1447,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]; @@ -1487,35 +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 (auto const this_o_idx: c_ptr->o_idxs) + /* Acquire object */ + object_type *o_ptr = &o_list[this_o_idx]; + + /* Memorized objects */ + if (o_ptr->marked) { - /* Acquire object */ - object_type *o_ptr = &o_list[this_o_idx]; + /* Normal char */ + *cp = object_char_default(o_ptr); - /* Memorized objects */ - if (o_ptr->marked) - { - /* Normal char */ - *cp = object_char_default(o_ptr); + /* Normal attr */ + *ap = object_attr_default(o_ptr); - /* Normal attr */ - *ap = object_attr_default(o_ptr); + /* Multi-hued attr */ + if (!avoid_other && (k_info[o_ptr->k_idx].flags & TR_ATTR_MULTI)) + { + *ap = get_shimmer_color(); + } - /* Multi-hued attr */ - if (!avoid_other && - (k_info[o_ptr->k_idx].flags5 & TR5_ATTR_MULTI)) - { - *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; } } @@ -1527,7 +1470,7 @@ void map_info_default(int y, int x, byte *ap, char *cp) monster_type *m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_MIMIC) { /* Acquire object being mimicked */ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; @@ -1542,7 +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 && (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(); } @@ -1571,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); } @@ -1582,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); } @@ -1593,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; @@ -1616,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; @@ -1646,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(); } @@ -1774,7 +1717,7 @@ void note_spot(int y, int x) monster_type *m_ptr = &m_list[c_ptr->m_idx]; 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->mimic_o_idx()]; o_ptr->marked = TRUE; @@ -1783,18 +1726,17 @@ void note_spot(int y, int x) /* 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; } } @@ -1802,7 +1744,7 @@ void note_spot(int y, int x) else { /* Memorize */ - c_ptr->info |= (CAVE_MARK); + c_ptr->info |= CAVE_MARK; } } } @@ -1839,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++) @@ -1872,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); } @@ -1970,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++) @@ -1987,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); @@ -2020,9 +1962,6 @@ void display_map(int *cy, int *cx) byte tp; - bool_ old_view_special_lite; - bool_ old_view_granite_lite; - int hgt, wid, yrat, xrat, yfactor, xfactor; @@ -2047,12 +1986,12 @@ 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; /* Set up initial maps */ @@ -2149,8 +2088,8 @@ void display_map(int *cy, int *cx) *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; } @@ -2159,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; @@ -2822,7 +2761,7 @@ 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; @@ -3044,7 +2983,7 @@ errr vinfo_init(void) /* * Forget the "CAVE_VIEW" grids, redrawing as needed */ -void forget_view(void) +void forget_view() { int i; @@ -3152,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; @@ -3471,7 +3410,7 @@ void update_view(void) /* * Clear monster light */ -void forget_mon_lite(void) +void forget_mon_lite() { int i, y, x; @@ -3519,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. * @@ -3536,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; @@ -3625,7 +3566,7 @@ void update_mon_lite(void) 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; @@ -3676,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); @@ -3850,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; @@ -3918,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)) @@ -3955,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]]; @@ -3995,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; @@ -4028,7 +3952,7 @@ void wiz_lite(void) monster_type *m_ptr = &m_list[c_ptr->m_idx]; 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->mimic_o_idx()]; o_ptr->marked = TRUE; @@ -4058,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); @@ -4078,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++) @@ -4094,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; @@ -4406,7 +4330,7 @@ void object_track(object_type *o_ptr) * * All disturbance cancels repeated commands, resting, and running. */ -void disturb(int stop_search) +void disturb() { /* Cancel auto-commands */ /* command_new = 0; */ @@ -4441,21 +4365,37 @@ void disturb(int stop_search) 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; + flush(); + } +} - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - /* Redraw the state */ - p_ptr->redraw |= (PR_FRAME); + +/* + * Disturb if option 'disturb_state' is set. + */ +void disturb_on_state() +{ + if (options->disturb_state) + { + disturb(); } +} - /* Flush the input if requested */ - if (flush_disturb) flush(); + + +/* + * Disturb if option 'disturb_other' is set. + */ +void disturb_on_other() +{ + if (options->disturb_other) + { + disturb(); + } } @@ -4467,7 +4407,7 @@ void disturb(int stop_search) static int random_quest_number() { if ((dun_level >= 1) && (dun_level < MAX_RANDOM_QUEST) && - (dungeon_flags1 & DF1_PRINCIPAL) && + (dungeon_flags & DF_PRINCIPAL) && (random_quests[dun_level].type) && (!random_quests[dun_level].done) && (!is_randhero(dun_level))) @@ -4550,7 +4490,9 @@ bool cave_floor_bold(int y, int x) */ bool cave_floor_grid(cave_type const *c) { - return (f_info[c->feat].flags1 & FF1_FLOOR) && (c->feat != FEAT_MON_TRAP); + auto const &f_info = game->edit_data.f_info; + + return bool(f_info[c->feat].flags & FF_FLOOR); } @@ -4569,9 +4511,11 @@ bool cave_plain_floor_bold(int y, int x) */ bool cave_plain_floor_grid(cave_type const *c) { + auto const &f_info = game->edit_data.f_info; + return - (f_info[c->feat].flags1 & FF1_FLOOR) && - !(f_info[c->feat].flags1 & FF1_REMEMBER); + (f_info[c->feat].flags & FF_FLOOR) && + !(f_info[c->feat].flags & FF_REMEMBER); } @@ -4595,7 +4539,9 @@ bool cave_sight_bold(int y, int x) bool cave_sight_grid(cave_type const *c) { - return !(f_info[c->feat].flags1 & FF1_NO_VISION); + auto const &f_info = game->edit_data.f_info; + + return !(f_info[c->feat].flags & FF_NO_VISION); } @@ -4609,11 +4555,12 @@ bool cave_sight_grid(cave_type const *c) */ bool cave_clean_bold(int y, int x) { + auto const &f_info = game->edit_data.f_info; + return - (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) && - (cave[y][x].feat != FEAT_MON_TRAP) && + (f_info[cave[y][x].feat].flags & FF_FLOOR) && (cave[y][x].o_idxs.empty()) && - !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT); + !(f_info[cave[y][x].feat].flags & FF_PERMANENT); } /* @@ -4641,19 +4588,21 @@ bool cave_empty_bold(int y, int x) */ bool cave_naked_bold(int y, int x) { + auto const &f_info = game->edit_data.f_info; + return - (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) && - (cave[y][x].feat != FEAT_MON_TRAP) && - !(f_info[cave[y][x].feat].flags1 & FF1_PERMANENT) && + (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].flags1 & FF1_FLOOR) && - (cave[y][x].feat != FEAT_MON_TRAP) && + (f_info[cave[y][x].feat].flags & FF_FLOOR) && (cave[y][x].o_idxs.empty()) && (cave[y][x].m_idx == 0); } @@ -4669,7 +4618,9 @@ bool cave_perma_bold(int y, int x) bool cave_perma_grid(cave_type const *c) { - return f_info[c->feat].flags1 & FF1_PERMANENT; + auto const &f_info = game->edit_data.f_info; + + return bool(f_info[c->feat].flags & FF_PERMANENT); } /* diff --git a/src/cave.hpp b/src/cave.hpp index 64f67dba..ce1631a1 100644 --- a/src/cave.hpp +++ b/src/cave.hpp @@ -4,52 +4,54 @@ #include "cave_type_fwd.hpp" #include "object_type_fwd.hpp" -extern int distance(int y1, int x1, int y2, int x2); -extern bool_ los(int y1, int x1, int y2, int x2); -extern bool_ cave_valid_bold(int y, int x); -extern bool_ no_lite(void); -extern void map_info_default(int y, int x, byte *ap, char *cp); -extern void move_cursor_relative(int row, int col); -extern void print_rel(char c, byte a, int y, int x); -extern void note_spot(int y, int x); -extern void lite_spot(int y, int x); -extern void prt_map(void); -extern void display_map(int *cy, int *cx); -extern void do_cmd_view_map(void); -extern errr vinfo_init(void); -extern void forget_view(void); -extern void update_view(void); -extern void forget_mon_lite(void); -extern void update_mon_lite(void); -extern void update_flow(void); -extern void map_area(void); -extern void wiz_lite(void); -extern void wiz_lite_extra(void); -extern void wiz_dark(void); -extern void cave_set_feat(int y, int x, int feat); -extern void place_floor(int y, int x); -extern void place_floor_convert_glass(int y, int x); -extern void place_filler(int y, int x); -extern void mmove2(int *y, int *x, int y1, int x1, int y2, int x2); -extern bool_ projectable(int y1, int x1, int y2, int x2); -extern void scatter(int *yp, int *xp, int y, int x, int d); -extern void health_track(int m_idx); -extern void monster_race_track(int r_idx, int ego); -extern void object_track(object_type *o_ptr); -extern void disturb(int stop_search); -extern int is_quest(int level); -extern int new_effect(int type, int dam, int time, int cy, int cx, int rad, s32b flags); -extern bool cave_floor_bold(int y, int x); -extern bool cave_floor_grid(cave_type const *c); -extern bool cave_plain_floor_bold(int y, int x); -extern bool cave_plain_floor_grid(cave_type const *c); -extern bool cave_sight_bold(int y, int x); -extern bool cave_sight_grid(cave_type const *c); -extern bool cave_clean_bold(int y, int x); -extern bool cave_empty_bold(int y, int x); -extern bool cave_naked_bold(int y, int x); -extern bool cave_naked_bold2(int y, int x); -extern bool cave_perma_bold(int y, int x); -extern bool cave_perma_grid(cave_type const *c); -extern bool player_has_los_bold(int y, int x); -extern bool player_can_see_bold(int y, int x); +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 index 958ace1d..08e6002f 100644 --- a/src/cave_type.hpp +++ b/src/cave_type.hpp @@ -38,8 +38,6 @@ struct cave_type s16b m_idx = 0; /* Monster in this grid */ - s16b t_idx = 0; /* trap index (in t_list) or zero */ - s16b special = 0; /* Special cave info */ s16b special2 = 0; /* Special cave info */ diff --git a/src/cmd1.cc b/src/cmd1.cc index f4066915..13edf0ff 100644 --- a/src/cmd1.cc +++ b/src/cmd1.cc @@ -13,8 +13,10 @@ #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" @@ -25,19 +27,20 @@ #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 "quark.hpp" #include "skills.hpp" #include "spells1.hpp" #include "spells2.hpp" #include "spells3.hpp" #include "tables.hpp" -#include "traps.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -239,11 +242,8 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, auto const r_ptr = m_ptr->race(); - u32b f1, f2, f3, f4, f5, esp; - - /* 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) @@ -259,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; @@ -410,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; @@ -439,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; @@ -468,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; @@ -497,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; @@ -528,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; @@ -556,89 +436,6 @@ s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, /* - * Search for hidden things - */ -void search(void) -{ - /* Start with base search ability */ - int chance = p_ptr->skill_srh; - - /* Penalize various conditions */ - if (p_ptr->blind || no_lite()) chance = chance / 10; - if (p_ptr->confused || p_ptr->image) chance = chance / 10; - - /* Search the nearby grids, which are always in bounds */ - for (int y = (p_ptr->py - 1); y <= (p_ptr->py + 1); y++) - { - for (int x = (p_ptr->px - 1); x <= (p_ptr->px + 1); x++) - { - /* Sometimes, notice things */ - if (rand_int(100) < chance) - { - /* Access the grid */ - cave_type *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); - } - - /* 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); - } - - /* Scan all objects in the grid */ - for (auto const o_idx: c_ptr->o_idxs) - { - object_type * o_ptr = &o_list[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); - } - } - } - } - } -} - - - - -/* * 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. @@ -652,39 +449,11 @@ void carry(int pickup) } -/* - * Handle player hitting a real trap - */ -static void hit_trap(void) -{ - bool_ ident = FALSE; - - cave_type *c_ptr; - - - /* Disturb the player */ - disturb(0); - - /* 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_info[c_ptr->t_idx].name); - } - } -} - - -void touch_zap_player(monster_type *m_ptr) +static void touch_zap_player(monster_type *m_ptr) { auto r_ptr = m_ptr->race(); - if (r_ptr->flags2 & (RF2_AURA_FIRE)) + if (r_ptr->flags & RF_AURA_FIRE) { if (!(p_ptr->immune_fire)) { @@ -703,13 +472,12 @@ 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)) { @@ -726,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(); } } @@ -740,9 +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_type *t_ptr = &m_list[m_idx]; int ap_cnt; @@ -750,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; @@ -760,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; @@ -792,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; @@ -818,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); @@ -828,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); + disturb(); /* Describe the attack method */ switch (method) @@ -1003,13 +760,12 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, { 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); @@ -1166,15 +922,13 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, { 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), @@ -1183,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), @@ -1222,35 +974,20 @@ static void carried_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, case RBM_CHARGE: { /* Disturb */ - disturb(1); + 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); } @@ -1263,6 +1000,8 @@ 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) { + auto const &r_info = game->edit_data.r_info; + monster_type *t_ptr = &m_list[m_idx]; auto tr_ptr = t_ptr->race(); @@ -1287,7 +1026,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, 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; @@ -1310,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; @@ -1336,9 +1072,6 @@ static void incarnate_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); @@ -1346,7 +1079,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, if (!effect || check_hit2(power, rlev, ac)) { /* Always disturbing */ - disturb(1); + disturb(); /* Describe the attack method */ switch (method) @@ -1525,9 +1258,6 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, } - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side) + p_ptr->to_d; @@ -1682,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), @@ -1699,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), @@ -1739,7 +1465,7 @@ static void incarnate_monster_attack(s16b m_idx, bool_ *fear, bool_ *mdeath, case RBM_CHARGE: { /* Disturb */ - disturb(1); + disturb(); /* Message */ msg_format("You miss %s.", t_name); @@ -1748,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 */ @@ -1838,22 +1549,20 @@ void attack_special(monster_type *m_ptr, s32b special, int dam) /* 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; } @@ -1862,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; } @@ -1929,11 +1635,11 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) /* Extract monster name (or "it") */ auto const r_ptr = m_ptr->race(); - 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; + 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) { @@ -1951,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."); } @@ -1972,11 +1678,10 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) /* 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); @@ -1993,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); @@ -2035,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; } } @@ -2064,24 +1769,25 @@ static void py_attack_hand(int *k, monster_type *m_ptr, s32b *special) 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) { @@ -2158,6 +1864,8 @@ static void do_nazgul(int *k, int *num, int num_blow, int weap, std::shared_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; @@ -2188,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); + 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; @@ -2234,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 */ @@ -2309,9 +2009,9 @@ void py_attack(int y, int x, int max_blow) 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; @@ -2325,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) { @@ -2362,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; @@ -2411,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; @@ -2474,7 +2171,7 @@ void py_attack(int y, int x, int max_blow) /* Melkor can cast curse for you*/ if (praying_to(GOD_MELKOR)) { - int lv = get_level(MELKOR_CURSE, 100, 1); + int lv = get_level_s(MELKOR_CURSE, 100); if (lv >= 10) { @@ -2489,7 +2186,7 @@ void py_attack(int y, int x, int max_blow) } /* 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); @@ -2556,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; @@ -2590,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); } @@ -2632,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) @@ -2663,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 */ @@ -2699,9 +2391,6 @@ void py_attack(int y, int x, int max_blow) /* Player misses */ else { - /* Sound */ - sound(SOUND_MISS); - backstab = FALSE; /* Clumsy! */ /* Message */ @@ -2723,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); } @@ -2743,13 +2429,16 @@ void py_attack(int y, int x, int max_blow) 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 || (race_flags1_p(PR1_SEMI_WRAITH))) + if (p_ptr->wraith_form || (race_flags_p(PR_SEMI_WRAITH))) pass_wall = TRUE; else pass_wall = FALSE; @@ -2785,30 +2474,30 @@ 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) && 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].flags1 & FF1_WEB) && - ((!(r_info[p_ptr->body_monster].flags7 & RF7_SPIDER)) && (p_ptr->mimic_form != resolve_mimic_name("Spider")))) + 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); @@ -2827,14 +2516,16 @@ bool_ player_can_enter(byte feature) 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]; - 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."); @@ -2859,7 +2550,7 @@ static bool_ easy_open_door(int y, int x) 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; @@ -2880,18 +2571,12 @@ static bool_ easy_open_door(int y, int x) /* 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); } @@ -2900,7 +2585,7 @@ static bool_ easy_open_door(int y, int x) else { /* Failure */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("You failed to pick the lock."); @@ -2910,17 +2595,11 @@ static bool_ easy_open_door(int y, int x) /* 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 */ @@ -2936,43 +2615,43 @@ static bool_ easy_open_door(int y, int x) * 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]; + 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); @@ -3118,12 +2797,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) m_ptr = &m_list[c_ptr->m_idx]; auto const mr_ptr = m_ptr->race(); - if (p_ptr->inventory[INVEN_WIELD].art_name) - { - if (streq(quark_str(p_ptr->inventory[INVEN_WIELD].art_name), "'Stormbringer'")) - stormbringer = TRUE; - } - /* Hack -- attack monsters */ if (c_ptr->m_idx && (m_ptr->ml || player_can_enter(c_ptr->feat))) { @@ -3144,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; @@ -3182,21 +2858,13 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) oktomove = FALSE; } - /* 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); + disturb(); if (p_ptr->prob_travel) { @@ -3225,11 +2893,10 @@ 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_info[feat].block); c_ptr->info |= (CAVE_MARK); @@ -3274,40 +2941,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) energy_use = 0; } } - - /* Sound */ - sound(SOUND_HITWALL); - } - - /* - * 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); - - /* but don't take a turn */ - energy_use = 0; - - /* Tell player why */ - cmsg_print(TERM_VIOLET, "You are about to leave a trap detected zone."); - /* Flush */ - /* msg_print(NULL); */ - - oktomove = FALSE; - } } /* Normal movement */ @@ -3343,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_FRAME); - } - else if (!old_dtrap && new_dtrap) - { - cmsg_print(TERM_L_BLUE, "You enter a trap detected zone."); - if (running) msg_print(NULL); - p_ptr->redraw |= (PR_FRAME); - } - /* Update stuff */ p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE); @@ -3372,7 +2991,7 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) /* Mega-hack for dungeon branches */ if ((feat == FEAT_MORE) && c_ptr->special) { - msg_format("There is %s", d_info[c_ptr->special].text); + msg_format("There is %s", d_info[c_ptr->special].text.c_str()); } else { @@ -3383,18 +3002,6 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) 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); @@ -3402,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); + disturb(); /* Hack -- Enter store */ command_new = '_'; @@ -3420,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); - - 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); + disturb(); msg_format("There is an inscription here: %s", inscription_info[c_ptr->inscription].text); @@ -3468,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); } @@ -3479,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) @@ -3508,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); @@ -3836,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; @@ -3927,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; @@ -3953,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; @@ -3961,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); @@ -3976,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)) { @@ -4132,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; @@ -4154,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)) { @@ -4170,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; @@ -4216,7 +3793,7 @@ void run_step(int dir) msg_print("You cannot run in that direction."); /* Disturb */ - disturb(0); + disturb(); /* Done */ return; @@ -4236,7 +3813,7 @@ void run_step(int dir) if (run_test()) { /* Disturb */ - disturb(0); + disturb(); /* Done */ return; @@ -4251,15 +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); } /* * 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; @@ -4520,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; @@ -4589,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; @@ -4720,9 +4295,11 @@ void 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; @@ -4759,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; } @@ -4855,13 +4432,13 @@ bool_ execute_inscription(byte i, byte y, byte x) 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(c_ptr->m_idx); @@ -4953,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 index 3ae44ed2..19b40ebf 100644 --- a/src/cmd1.hpp +++ b/src/cmd1.hpp @@ -4,22 +4,22 @@ #include "monster_type_fwd.hpp" #include "object_type_fwd.hpp" -extern void attack_special(monster_type *m_ptr, s32b special, int dam); -extern bool_ test_hit_fire(int chance, int ac, int vis); -extern bool_ test_hit_norm(int chance, int ac, int vis); -extern s16b critical_shot(int weight, int plus, int dam, int skill); -extern s16b critical_norm(int weight, int plus, int dam, int weapon_tval, bool_ *done_crit); -extern s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr, s32b *special); -extern void search(void); -extern void carry(int pickup); -extern void py_attack(int y, int x, int max_blow); -extern bool_ player_can_enter(byte feature); -extern void move_player(int dir, int do_pickup, bool_ disarm); -extern void move_player_aux(int dir, int do_pickup, int run, bool_ disarm); -extern void run_step(int dir); -extern void do_cmd_pet(void); -extern void do_cmd_integrate_body(); -extern bool_ do_cmd_leave_body(bool_ drop_body); -extern bool_ execute_inscription(byte i, byte y, byte x); -extern void do_cmd_engrave(void); -extern void do_spin(void); +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.cc b/src/cmd2.cc index cfdeab44..a348c221 100644 --- a/src/cmd2.cc +++ b/src/cmd2.cc @@ -13,8 +13,11 @@ #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" @@ -26,11 +29,14 @@ #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" @@ -38,8 +44,6 @@ #include "spells3.hpp" #include "stats.hpp" #include "tables.hpp" -#include "trap_type.hpp" -#include "traps.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -56,7 +60,7 @@ using std::this_thread::sleep_for; using std::chrono::milliseconds; -void do_cmd_immovable_special(void); +void do_cmd_immovable_special(); /* * Try to bash an altar @@ -73,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."); @@ -129,19 +135,44 @@ static bool_ stair_hooks(stairs_direction direction) 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 */ @@ -160,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; } @@ -181,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; } @@ -200,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; @@ -214,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; @@ -227,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; } @@ -296,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; @@ -340,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 */ @@ -363,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(); @@ -394,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; } @@ -423,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; } @@ -444,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; @@ -478,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(); @@ -512,7 +508,7 @@ 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 ? ;) */ { @@ -543,7 +539,7 @@ void do_cmd_go_down(void) dun_level = d_ptr->mindepth; } - msg_format("You go into %s", d_info[dungeon_type].text); + msg_format("You go into %s", d_info[dungeon_type].text.c_str()); } else { @@ -556,58 +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_FRAME); - - /* Cancel the arg */ - command_arg = 0; - } - - /* Take a turn */ - energy_use = 100; - - /* Search */ - search(); -} - - -/* - * Hack -- toggle search mode - */ -void do_cmd_toggle_search(void) -{ - p_ptr->update |= (PU_BONUS); - p_ptr->redraw |= (PR_FRAME); - p_ptr->searching = !p_ptr->searching; -} - - - /* * Determine if a grid contains a chest */ @@ -648,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; @@ -717,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_info[trap].name); - } -} - - -/* * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination @@ -760,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; @@ -768,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."); @@ -788,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; @@ -814,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."); } @@ -823,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); } @@ -862,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' @@ -953,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; @@ -1004,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."); @@ -1037,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; @@ -1058,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); } @@ -1078,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."); @@ -1091,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 */ @@ -1115,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; @@ -1125,10 +1017,10 @@ 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."); @@ -1225,7 +1117,7 @@ void do_cmd_open(void) } /* Cancel repeat unless we may continue */ - if (!more) disturb(0); + if (!more) disturb(); } @@ -1241,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."); @@ -1261,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) { @@ -1279,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 */ @@ -1292,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; @@ -1377,7 +1265,7 @@ void do_cmd_close(void) } /* Cancel repeat unless we may continue */ - if (!more) disturb(0); + if (!more) disturb(); } @@ -1386,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))) { @@ -1407,7 +1297,7 @@ 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_info[cave[y][x].feat].tunnel); @@ -1466,10 +1356,13 @@ static bool_ twall(int y, int x, byte feat) */ 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; @@ -1495,11 +1388,8 @@ static 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_ptr->tunnel); } @@ -1520,9 +1410,6 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir) /* We may continue chopping */ msg_print(f_ptr->tunnel); more = TRUE; - - /* Occasional Search XXX XXX */ - if (rand_int(100) < 25) search(); } } @@ -1673,9 +1560,6 @@ static 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 */ @@ -1690,9 +1574,6 @@ static bool_ do_cmd_tunnel_aux(int y, int x, int dir) /* We may continue tunelling */ msg_print(f_info[feat].tunnel); more = TRUE; - - /* Occasional Search XXX XXX */ - if (rand_int(100) < 25) search(); } } @@ -1750,7 +1631,7 @@ static 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; @@ -1784,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."); @@ -1821,309 +1694,9 @@ void do_cmd_tunnel(void) } /* Cancel repetition unless we can continue */ - if (!more) disturb(0); -} - - -/* - * 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); + 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_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_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; - - - /* Pick a direction if there's an obvious choice */ - { - 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_FRAME); - - /* 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); -} - - /* * Perform the basic "bash" command * @@ -2135,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."); @@ -2182,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); @@ -2225,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(2 + rand_int(2)); + set_paralyzed(2 + rand_int(2)); } /* Result */ @@ -2247,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."); @@ -2329,7 +1897,7 @@ void do_cmd_bash(void) } /* Unless valid action taken, cancel bash */ - if (!more) disturb(0); + if (!more) disturb(); } @@ -2344,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; @@ -2395,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 { @@ -2417,7 +1980,7 @@ void do_cmd_alter(void) } /* Cancel repetition unless we can continue */ - if (!more) disturb(0); + if (!more) disturb(); } @@ -2461,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; @@ -2528,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; @@ -2555,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; @@ -2565,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; @@ -2584,7 +2150,7 @@ static void do_cmd_walk_jump(int pickup, bool_ disarm) } /* Cancel repeat unless we may continue */ - if (!more) disturb(0); + if (!more) disturb(); } @@ -2729,7 +2295,7 @@ static void do_cmd_unwalk() else if (((feat >= FEAT_QUEST_ENTER) && (feat <= FEAT_QUEST_UP)) || ((feat >= FEAT_LESS) && (feat <= FEAT_MORE))) { - move_player(dir, always_pickup, TRUE); + move_player(dir, options->always_pickup); more = FALSE; } @@ -2746,7 +2312,7 @@ static void do_cmd_unwalk() while (dir == 5); } - move_player(dir, always_pickup, TRUE); + move_player(dir, options->always_pickup); } /* Walking semantics */ @@ -2756,14 +2322,14 @@ static void do_cmd_unwalk() } /* Cancel repetition unless we can continue */ - if (!more) disturb(0); + 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) */ @@ -2773,7 +2339,7 @@ void do_cmd_walk(int pickup, bool_ disarm) } else { - do_cmd_walk_jump(pickup, disarm); + do_cmd_walk_jump(pickup); } } @@ -2806,7 +2372,7 @@ void do_cmd_run_run() /* * Start running. */ -void do_cmd_run(void) +void do_cmd_run() { if (p_ptr->immovable) { @@ -2846,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); @@ -2868,7 +2420,7 @@ void do_cmd_stay(int pickup) if (c_ptr->feat == FEAT_SHOP) { /* Disturb */ - disturb(0); + disturb(); /* Hack -- enter store */ command_new = '_'; @@ -2878,13 +2430,15 @@ 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!", @@ -2898,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!"); @@ -2951,9 +2505,6 @@ 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); @@ -3108,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; @@ -3140,7 +2691,7 @@ void do_cmd_fire(void) char o_name[80]; - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); /* Get the "bow" (if any) */ @@ -3210,10 +2761,6 @@ void do_cmd_fire(void) } - /* Sound */ - sound(SOUND_SHOOT); - - /* Describe the object */ object_desc(o_name, q_ptr, FALSE, 3); @@ -3354,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 */ @@ -3444,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); @@ -3546,8 +3090,10 @@ 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() { + auto const &k_info = game->edit_data.k_info; + int dir; s32b special = 0; @@ -3577,7 +3123,7 @@ void do_cmd_throw(void) char o_name[80]; - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); /* Get an item */ int item; @@ -3592,11 +3138,10 @@ void do_cmd_throw(void) /* Access the item */ object_type *o_ptr = get_object(item); - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + 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."); @@ -3768,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 */ @@ -3854,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); @@ -3924,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; @@ -3952,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) */ @@ -4095,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 */ @@ -4181,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); @@ -4196,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); @@ -4252,6 +3792,8 @@ void do_cmd_boomerang(void) static bool_ tport_vertically(bool_ how) { + auto const &d_info = game->edit_data.d_info; + /* quest? */ if (p_ptr->inside_quest) { @@ -4259,7 +3801,7 @@ static bool_ tport_vertically(bool_ how) 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; @@ -4299,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; @@ -4360,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); @@ -4397,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; @@ -4529,8 +4071,10 @@ static void do_cmd_sacrifice_aule() * 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 */ @@ -4753,6 +4297,8 @@ std::vector<s16b> show_monster_inven(int m_idx) */ void do_cmd_steal() { + auto const &r_info = game->edit_data.r_info; + int dir = 0, item = -1, k = -1; bool_ done = FALSE; @@ -4780,7 +4326,7 @@ void do_cmd_steal() } /* 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; @@ -4883,7 +4429,7 @@ void do_cmd_steal() m_ptr->hold_o_idxs.erase(m_ptr->hold_o_idxs.begin() + k); /* Rogues gain some xp */ - if (race_flags1_p(PR1_EASE_STEAL)) + if (race_flags_p(PR_EASE_STEAL)) { s32b max_point; diff --git a/src/cmd2.hpp b/src/cmd2.hpp index 142238ab..9641dc72 100644 --- a/src/cmd2.hpp +++ b/src/cmd2.hpp @@ -4,30 +4,29 @@ #include "object_type_fwd.hpp" #include <vector> -extern std::vector<s16b> show_monster_inven(int m_idx); -extern int breakage_chance(object_type *o_ptr); -extern void do_cmd_go_up(void); -extern void do_cmd_go_down(void); -extern void do_cmd_search(void); -extern void do_cmd_toggle_search(void); -extern void do_cmd_open(void); -extern void do_cmd_close(void); -extern void do_cmd_chat(void); -extern void do_cmd_give(void); -extern void do_cmd_tunnel(void); -extern void do_cmd_disarm(void); -extern void do_cmd_bash(void); -extern void do_cmd_alter(void); -extern void do_cmd_spike(void); -extern void do_cmd_walk(int pickup, bool_ disarm); -extern void do_cmd_stay(int pickup); -extern void do_cmd_run(void); -extern void do_cmd_rest(void); -extern int get_shooter_mult(object_type *o_ptr); -extern void do_cmd_fire(void); -extern void do_cmd_throw(void); -extern void do_cmd_boomerang(void); -extern void do_cmd_immovable_special(void); -extern void fetch(int dir, int wgt, bool_ require_los); -extern void do_cmd_sacrifice(void); -extern void do_cmd_steal(void); +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.cc b/src/cmd3.cc index 59e61719..cbf58820 100644 --- a/src/cmd3.cc +++ b/src/cmd3.cc @@ -12,19 +12,21 @@ #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 "quark.hpp" #include "squeltch.hpp" #include "store.hpp" #include "store_type.hpp" @@ -40,13 +42,14 @@ #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]; @@ -101,7 +104,7 @@ void do_cmd_inven(void) /* * Display equipment */ -void do_cmd_equip(void) +void do_cmd_equip() { char out_val[160]; @@ -159,28 +162,18 @@ void do_cmd_equip(void) */ 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); } } @@ -211,8 +204,10 @@ 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; @@ -225,9 +220,6 @@ void do_cmd_wield(void) char o_name[80]; - u32b f1, f2, f3, f4, f5, esp; - - /* Get an item */ if (!get_item(&item, "Wear/Wield which item? ", @@ -258,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]; @@ -281,11 +273,11 @@ void do_cmd_wield(void) } /* 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); @@ -298,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); @@ -310,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? ")) { @@ -319,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?")) { @@ -359,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 @@ -369,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 { @@ -461,7 +449,7 @@ void do_cmd_wield(void) /* * Take off an item */ -void do_cmd_takeoff(void) +void do_cmd_takeoff() { /* Get an item */ int item; @@ -491,7 +479,7 @@ 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); @@ -503,7 +491,7 @@ void do_cmd_takeoff(void) /* * Drop an item */ -void do_cmd_drop(void) +void do_cmd_drop() { /* Get an item */ int item; @@ -517,8 +505,7 @@ void do_cmd_drop(void) /* Get the item */ object_type *o_ptr = get_object(item); - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Can we drop */ struct hook_drop_in in = { item }; @@ -537,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."); @@ -570,8 +557,10 @@ void do_cmd_drop(void) /* * Destroy an item */ -void do_cmd_destroy(void) +void do_cmd_destroy() { + auto const &k_info = game->edit_data.k_info; + int old_number; bool_ force = FALSE; @@ -626,10 +615,8 @@ void do_cmd_destroy(void) /* Take no time, just like the automatizer */ energy_use = 0; - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if ((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr)) + 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."); @@ -640,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; @@ -670,7 +657,6 @@ void do_cmd_destroy(void) /* Message */ msg_format("You destroy %s.", o_name); - sound(SOUND_DESTITEM); /* Create an automatizer rule */ if (automatizer_create) @@ -689,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); @@ -700,7 +688,7 @@ void do_cmd_destroy(void) /* * Observe an item which has been *identify*-ed */ -void do_cmd_observe(void) +void do_cmd_observe() { /* Get an item */ int item; @@ -732,7 +720,7 @@ 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() { /* Get an item */ int item; @@ -748,7 +736,7 @@ void do_cmd_uninscribe(void) 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; @@ -758,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); @@ -771,7 +759,7 @@ void do_cmd_uninscribe(void) /* * Inscribe an object with a comment */ -void do_cmd_inscribe(void) +void do_cmd_inscribe() { /* Get an item */ int item; @@ -794,22 +782,15 @@ void do_cmd_inscribe(void) msg_format("Inscribing %s.", o_name); msg_print(NULL); - /* Start with nothing */ + /* Start with old inscription */ char out_val[80]; - strcpy(out_val, ""); - - /* Use old inscription */ - if (o_ptr->note) - { - /* Start with the old inscription */ - strcpy(out_val, quark_str(o_ptr->note)); - } + strcpy(out_val, o_ptr->inscription.c_str()); /* Get a new inscription (possibly empty) */ if (get_string("Inscription: ", out_val, sizeof(out_val))) { /* Save the inscription */ - o_ptr->note = quark_add(out_val); + o_ptr->inscription = out_val; /* Combine the pack */ p_ptr->notice |= (PN_COMBINE); @@ -839,7 +820,7 @@ static object_filter_t const &item_tester_refill_lantern() /* * Refill the players lamp (from the pack or floor) */ -static void do_cmd_refill_lamp(void) +static void do_cmd_refill_lamp() { /* Get an item */ int item; @@ -902,7 +883,7 @@ static object_filter_t const &item_tester_refill_torch() /* * Refuel the players torch (from the pack or floor) */ -static void do_cmd_refill_torch(void) +static void do_cmd_refill_torch() { /* Get an item */ int item; @@ -954,15 +935,10 @@ static void do_cmd_refill_torch(void) /* * Refill the players lamp, or restock his torches */ -void do_cmd_refill(void) +void do_cmd_refill() { - object_type *o_ptr; - - u32b f1, f2, f3, f4, f5, esp; - - /* Get the light */ - o_ptr = &p_ptr->inventory[INVEN_LITE]; + auto o_ptr = &p_ptr->inventory[INVEN_LITE]; /* It is nothing */ if (o_ptr->tval != TV_LITE) @@ -971,9 +947,9 @@ void do_cmd_refill(void) return; } - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); - if (f4 & TR4_FUEL_LITE) + if (flags & TR_FUEL_LITE) { /* It's a torch */ if (o_ptr->sval == SV_LITE_TORCH || @@ -1002,7 +978,7 @@ void do_cmd_refill(void) /* * Target command */ -void do_cmd_target(void) +void do_cmd_target() { /* Target set */ if (target_set(TARGET_KILL)) @@ -1022,7 +998,7 @@ void do_cmd_target(void) /* * Look command */ -void do_cmd_look(void) +void do_cmd_look() { /* Look around */ if (target_set(TARGET_LOOK)) @@ -1036,7 +1012,7 @@ void do_cmd_look(void) /* * Allow the player to examine other sectors on the map */ -void do_cmd_locate(void) +void do_cmd_locate() { int dir, y1, x1, y2, x2; int panel_hgt, panel_wid; @@ -1249,6 +1225,8 @@ static cptr ident_info[] = */ static bool compare_monster_experience(int w1, int w2) { + auto const &r_info = game->edit_data.r_info; + /* Extract experience */ s32b z1 = r_info[w1].mexp; s32b z2 = r_info[w2].mexp; @@ -1266,6 +1244,8 @@ static bool compare_monster_experience(int w1, int w2) */ static bool compare_monster_level(int w1, int w2) { + auto const &r_info = game->edit_data.r_info; + /* Extract levels */ byte z1 = r_info[w1].level; byte z2 = r_info[w2].level; @@ -1278,28 +1258,13 @@ static bool compare_monster_level(int w1, int w2) return compare_monster_experience(w1, w2); } -/** - * Sort by total number of kills - */ -static bool compare_total_kills(int w1, int w2) -{ - /* Extract total kills */ - s16b z1 = r_info[w1].r_tkills; - s16b z2 = r_info[w2].r_tkills; - - /* Compare total kills */ - if (z1 < z2) return true; - if (z1 > z2) return false; - - /* Punt to monster level. */ - return compare_monster_level(w1, w2); -} - /* * Sort by player kills */ static bool compare_player_kills(int w1, int w2) { + auto const &r_info = game->edit_data.r_info; + /* Extract player kills */ s16b z1 = r_info[w1].r_pkills; s16b z2 = r_info[w2].r_pkills; @@ -1308,8 +1273,8 @@ static bool compare_player_kills(int w1, int w2) if (z1 < z2) return true; if (z1 > z2) return false; - /* Punt to total number of kills. */ - return compare_total_kills(w1, w2); + /* Punt to monster level. */ + return compare_monster_level(w1, w2); } @@ -1318,7 +1283,9 @@ static bool compare_player_kills(int w1, int w2) */ static void roff_top(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; byte a1, a2; @@ -1341,7 +1308,7 @@ static void roff_top(int r_idx) Term_gotoxy(0, 0); /* A title (use "The" for non-uniques) */ - if (!(r_ptr->flags1 & (RF1_UNIQUE))) + if (!(r_ptr->flags & RF_UNIQUE)) { Term_addstr( -1, TERM_WHITE, "The "); } @@ -1374,9 +1341,9 @@ static void roff_top(int r_idx) * * Note that the player ghosts are ignored. XXX XXX XXX */ -void do_cmd_query_symbol(void) +void do_cmd_query_symbol() { - int i, r_idx; + auto const &r_info = game->edit_data.r_info; char sym, query; @@ -1404,6 +1371,7 @@ void do_cmd_query_symbol(void) "or (Ctrl-A, Ctrl-U, Ctrl-N, Ctrl-M):", &sym)) return; /* Find that character info, and describe it */ + std::size_t i; for (i = 0; ident_info[i]; ++i) { if (sym == ident_info[i][0]) break; @@ -1445,19 +1413,16 @@ void do_cmd_query_symbol(void) prt(buf, 0, 0); /* Collect matching monsters */ - std::vector<u16b> who; - for (i = 1; i < max_r_idx; i++) + std::vector<std::size_t> who; + for (std::size_t i = 1; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; - - /* Nothing to recall */ - if (!cheat_know && !r_ptr->r_sights) continue; + auto r_ptr = &r_info[i]; /* Require non-unique monsters if needed */ - if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue; + if (norm && (r_ptr->flags & RF_UNIQUE)) continue; /* Require unique monsters if needed */ - if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue; + if (uniq && !(r_ptr->flags & RF_UNIQUE)) continue; /* Require monsters with the name requested if needed */ if (name) @@ -1529,7 +1494,7 @@ void do_cmd_query_symbol(void) while (1) { /* Extract a race */ - r_idx = who[i]; + auto r_idx = who[i]; /* Hack -- Auto-recall */ monster_race_track(r_idx, 0); @@ -1554,7 +1519,7 @@ void do_cmd_query_symbol(void) Term_save(); /* Recall on screen */ - screen_roff(who[i], 0, 0); + screen_roff(who[i], 0); /* Hack -- Complete the prompt (again) */ Term_addstr( -1, TERM_WHITE, " [(r)ecall, ESC]"); @@ -1608,206 +1573,6 @@ void do_cmd_query_symbol(void) /* - * research_mon - * -KMW- - */ -bool_ research_mon() -{ - int i, r_idx; - - char sym, query; - - char buf[128]; - - - s16b oldkills; - - byte oldwake; - - bool_ oldcheat; - - - bool_ all = FALSE; - - bool_ uniq = FALSE; - - bool_ norm = FALSE; - - bool_ notpicked; - - - bool_ recall = FALSE; - - monster_race *r2_ptr; - - /* Hack -- Remember "cheat_know" flag */ - oldcheat = cheat_know; - - - /* Get a character, or abort */ - if (!get_com("Enter character of monster: ", &sym)) return (TRUE); - - /* Find that character info, and describe it */ - for (i = 0; ident_info[i]; ++i) - { - if (sym == ident_info[i][0]) break; - } - - if (ident_info[i]) - { - strnfmt(buf, 128, "%c - %s.", sym, ident_info[i] + 2); - } - else - { - strnfmt(buf, 128, "%c - %s.", sym, "Unknown Symbol"); - } - - /* Display the result */ - prt(buf, 16, 10); - - - /* Collect matching monsters */ - std::vector<u16b> who; - for (i = 1; i < max_r_idx; i++) - { - monster_race *r_ptr = &r_info[i]; - - /* Hack -- Force "cheat_know" */ - cheat_know = TRUE; - - /* Nothing to recall */ - if (!cheat_know && !r_ptr->r_sights) continue; - - /* Require non-unique monsters if needed */ - if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue; - - /* Require unique monsters if needed */ - if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue; - - /* Collect "appropriate" monsters */ - if (all || (r_ptr->d_char == sym)) { - who.push_back(i); - } - } - - /* Nothing to recall */ - if (who.empty()) - { - /* Restore the "cheat_know" flag */ - cheat_know = oldcheat; - - return (TRUE); - } - - - query = 'y'; - - /* Sort by level */ - std::sort(std::begin(who), std::end(who), compare_monster_level); - - - /* Start at the end */ - i = who.size() - 1; - - notpicked = TRUE; - - /* Scan the monster memory */ - while (notpicked) - { - /* Extract a race */ - r_idx = who[i]; - - /* Hack -- Auto-recall */ - monster_race_track(r_idx, 0); - - /* Hack -- Handle stuff */ - handle_stuff(); - - /* Hack -- Begin the prompt */ - roff_top(r_idx); - - /* Hack -- Complete the prompt */ - Term_addstr( -1, TERM_WHITE, " [(r)ecall, ESC, space to continue]"); - - /* Interact */ - while (1) - { - /* Recall */ - if (recall) - { - /* Save the screen */ - character_icky = TRUE; - Term_save(); - - /* Recall on screen */ - r2_ptr = &r_info[r_idx]; - - oldkills = r2_ptr->r_tkills; - oldwake = r2_ptr->r_wake; - screen_roff(who[i], 0, 1); - r2_ptr->r_tkills = oldkills; - r2_ptr->r_wake = oldwake; - r2_ptr->r_sights = 1; - cheat_know = oldcheat; - notpicked = FALSE; - break; - - } - - /* Command */ - query = inkey(); - - /* Unrecall */ - if (recall) - { - /* Restore */ - Term_load(); - character_icky = FALSE; - } - - /* Normal commands */ - if (query != 'r') break; - - /* Toggle recall */ - recall = !recall; - } - - /* Stop scanning */ - if (query == ESCAPE) break; - - /* Move to "prev" monster */ - if (query == '-') - { - i++; - assert(i >= 0); - if (static_cast<size_t>(i) == who.size()) - { - i = 0; - } - } - - /* Move to "next" monster */ - else - { - if (i-- == 0) - { - i = who.size() - 1; - } - } - } - - - /* Re-display the identity */ - /* prt(buf, 5, 5);*/ - - /* Restore the "cheat_know" flag */ - cheat_know = oldcheat; - - return (notpicked); -} - - -/* * Try to "sense" the grid's mana */ bool_ do_cmd_sense_grid_mana() @@ -1836,9 +1601,8 @@ bool_ do_cmd_sense_grid_mana() /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("You failed to sense the grid's mana."); - sound(SOUND_FAIL); return FALSE; } @@ -1976,7 +1740,7 @@ static bool_ get_string_cli(cptr prompt, char *buf, int len) * * See defines.h for a list of the codes used. */ -void do_cmd_cli(void) +void do_cmd_cli() { char buff[80]; @@ -2009,33 +1773,23 @@ void do_cmd_cli(void) */ void do_cmd_cli_help() { - int i, j; - - FILE *fff; - - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; + fmt::MemoryWriter w; + for (int i = 0, j = -1; i < cli_total; i++) + { + if (j < i - 1) + { + w << "/"; + } - /* Open a new file */ - fff = my_fopen(file_name, "w"); + w.write("[[[[[G{}]", cli_info[i].comm); - for (i = 0, j = -1; i < cli_total; i++) - { - if (j < i - 1) fprintf(fff, "/"); - fprintf(fff, "[[[[[G%s]", cli_info[i].comm); if (cli_info[i].descrip != cli_info[i + 1].descrip) { - fprintf(fff, " %s\n", cli_info[i].descrip); + w.write(" {}\n", cli_info[i].descrip); j = i; } } - /* Close the file */ - my_fclose(fff); - /* Enter "icky" mode */ character_icky = TRUE; @@ -2043,16 +1797,13 @@ void do_cmd_cli_help() Term_save(); /* Display the file contents */ - show_file(file_name, "Command line help", 0, 0); + show_string(w.c_str(), "Command line help"); /* Restore the screen */ Term_load(); /* Leave "icky" mode */ character_icky = FALSE; - - /* Remove the file */ - fd_kill(file_name); } diff --git a/src/cmd3.hpp b/src/cmd3.hpp index 48677b77..97d3e22f 100644 --- a/src/cmd3.hpp +++ b/src/cmd3.hpp @@ -2,23 +2,22 @@ #include "h-basic.h" -extern void do_cmd_html_dump(void); -extern void cli_add(cptr active, cptr trigger, cptr descr); -extern void do_cmd_cli(void); -extern void do_cmd_cli_help(void); -extern void do_cmd_inven(void); -extern void do_cmd_equip(void); -extern void do_cmd_wield(void); -extern void do_cmd_takeoff(void); -extern void do_cmd_drop(void); -extern void do_cmd_destroy(void); -extern void do_cmd_observe(void); -extern void do_cmd_uninscribe(void); -extern void do_cmd_inscribe(void); -extern void do_cmd_refill(void); -extern void do_cmd_target(void); -extern void do_cmd_look(void); -extern void do_cmd_locate(void); -extern void do_cmd_query_symbol(void); -extern bool_ do_cmd_sense_grid_mana(void); -extern bool_ research_mon(void); +void do_cmd_html_dump(); +void cli_add(cptr active, cptr trigger, cptr descr); +void do_cmd_cli(); +void do_cmd_cli_help(); +void do_cmd_inven(); +void do_cmd_equip(); +void do_cmd_wield(); +void do_cmd_takeoff(); +void do_cmd_drop(); +void do_cmd_destroy(); +void do_cmd_observe(); +void do_cmd_uninscribe(); +void do_cmd_inscribe(); +void do_cmd_refill(); +void do_cmd_target(); +void do_cmd_look(); +void do_cmd_locate(); +void do_cmd_query_symbol(); +bool_ do_cmd_sense_grid_mana(); diff --git a/src/cmd4.cc b/src/cmd4.cc index 4b6c040c..a820da41 100644 --- a/src/cmd4.cc +++ b/src/cmd4.cc @@ -10,26 +10,30 @@ #include "artifact_type.hpp" #include "cave_type.hpp" #include "corrupt.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hooks.hpp" #include "init1.hpp" #include "levels.hpp" #include "messages.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "notes.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" +#include "options.hpp" #include "player_type.hpp" #include "skills.hpp" #include "squeltch.hpp" #include "tables.hpp" #include "town_type.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -37,11 +41,13 @@ #include "xtra1.hpp" #include "z-rand.hpp" +#include <algorithm> #include <cassert> +#include <fmt/format.h> #include <memory> +#include <numeric> #include <string> #include <vector> -#include <algorithm> /* * Hack -- redraw the screen @@ -54,7 +60,7 @@ * selecting various things, such as graphics mode, so it must call * the "TERM_XTRA_REACT" hook before redrawing the windows. */ -void do_cmd_redraw(void) +void do_cmd_redraw() { int j; @@ -125,7 +131,7 @@ void do_cmd_redraw(void) /* * Hack -- change name */ -void do_cmd_change_name(void) +void do_cmd_change_name() { char c; @@ -143,8 +149,8 @@ void do_cmd_change_name(void) /* Forever */ while (1) { - /* keep mode below 7 */ - mode = (mode + 6) % 6; + /* keep mode below 5 */ + mode = (mode + 5) % 5; /* Display the player */ display_player(mode); @@ -174,7 +180,7 @@ void do_cmd_change_name(void) /* File dump */ else if (c == 'f') { - strnfmt(tmp, 160, "%s.txt", player_name); + strnfmt(tmp, 160, "%s.txt", game->player_name.c_str()); if (get_string("Filename(you can post it to http://angband.oook.cz/): ", tmp, 80)) { if (tmp[0] && (tmp[0] != ' ')) @@ -199,11 +205,11 @@ void do_cmd_change_name(void) /* Change tactic */ if (c == 't') { - (void)do_cmd_change_tactic( -1); + do_cmd_change_tactic( -1); } else if (c == 'T') { - (void)do_cmd_change_tactic(1); + do_cmd_change_tactic(1); } /* Change movement */ @@ -247,12 +253,16 @@ void do_cmd_change_name(void) /* * Recall the most recent message */ -void do_cmd_message_one(void) +void do_cmd_message_one() { - cptr msg = format("> %s", message_str(0)); + auto const &messages = game->messages; + + auto message = messages.at(0); + + cptr msg = format("> %s", message.text_with_count().c_str()); /* Recall one message XXX XXX XXX */ - display_message(0, 0, strlen(msg), message_color(0), msg); + display_message(0, 0, strlen(msg), message.color, msg); } @@ -274,30 +284,21 @@ void do_cmd_message_one(void) * * Now taking advantages of big-screen. -pav- */ -void do_cmd_messages(void) +void do_cmd_messages() { - int i, j, k, n; - u32b q; - int wid, hgt; - - char shower[80]; - char finder[80]; - - /* Wipe finder */ - strcpy(finder, ""); - - /* Wipe shower */ - strcpy(shower, ""); + auto const &messages = game->messages; + /* String to highlight */ + std::string shower; /* Total messages */ - n = message_num(); + const int n = messages.size(); /* Start on first message */ - i = 0; + int i = 0; /* Start at leftmost edge */ - q = 0; + u32b q = 0; /* Enter "icky" mode */ character_icky = TRUE; @@ -312,35 +313,38 @@ void do_cmd_messages(void) Term_clear(); /* Retrieve current screen size */ + int wid; + int hgt; Term_get_size(&wid, &hgt); /* Dump up to 20 (or more in bigscreen) lines of messages */ + int j; for (j = 0; (j < (hgt - 4)) && (i + j < n); j++) { - cptr msg = message_str(i + j); - byte color = message_color(i + j); + auto message = messages.at(i + j); + auto text = message.text_with_count(); + auto color = message.color; /* Apply horizontal scroll */ - msg = (strlen(msg) >= q) ? (msg + q) : ""; + text = (text.size() >= q) ? text.substr(q) : ""; /* Dump the messages, bottom to top */ - display_message(0, (hgt - 3) - j, strlen(msg), color, msg); + display_message(0, (hgt - 3) - j, text.size(), color, text.c_str()); /* Hilite "shower" */ if (shower[0]) { - cptr str = msg; - + std::size_t pos = 0; /* Display matches */ - while ((str = strstr(str, shower)) != NULL) + while ((pos = text.find(shower, pos)) != std::string::npos) { - int len = strlen(shower); + std::size_t len = shower.size(); /* Display the match */ - Term_putstr(str - msg, (hgt - 3) - j, len, TERM_YELLOW, shower); + Term_putstr(pos, (hgt - 3) - j, len, TERM_YELLOW, shower.c_str()); /* Advance */ - str += len; + pos += len; } } } @@ -353,7 +357,7 @@ void do_cmd_messages(void) prt("[Press 'p' for older, 'n' for newer, ..., or ESCAPE]", hgt - 1, 0); /* Get a command */ - k = inkey(); + const auto k = inkey(); /* Exit on Escape */ if (k == ESCAPE) break; @@ -388,7 +392,10 @@ void do_cmd_messages(void) prt("Show: ", hgt - 1, 0); /* Get a "shower" string, or continue */ - if (!askfor_aux(shower, 80)) continue; + if (!askfor_aux(&shower, 80)) + { + continue; + } /* Okay */ continue; @@ -403,18 +410,22 @@ void do_cmd_messages(void) prt("Find: ", hgt - 1, 0); /* Get a "finder" string, or continue */ - if (!askfor_aux(finder, 80)) continue; + auto finder = shower; + if (!askfor_aux(&finder, 80)) + { + continue; + } /* Show it */ - strcpy(shower, finder); + shower = finder; /* Scan messages */ for (z = i + 1; z < n; z++) { - cptr msg = message_str(z); + auto message = messages.at(z); /* Search for it */ - if (strstr(msg, finder)) + if (message.text_with_count().find(finder) != std::string::npos) { /* New location */ i = z; @@ -494,7 +505,7 @@ namespace { /** * Interact with given vector of options. */ -static void interact_with_options(std::vector<option_type *> const &options, char const *info, interaction_mode_t interaction_mode) +static void interact_with_options(std::vector<option_type> const &options, char const *info, interaction_mode_t interaction_mode) { size_t n = options.size(); @@ -522,9 +533,9 @@ static void interact_with_options(std::vector<option_type *> const &options, cha /* Display the option text */ strnfmt(buf, 80, "%-48s: %s (%s)", - options[i]->o_desc, - (*options[i]->o_var ? "yes" : "no "), - options[i]->o_text); + options[i].o_desc, + (*options[i].o_var) ? "yes" : "no ", + options[i].o_text); c_prt(a, buf, i + 2, 0); } @@ -580,7 +591,7 @@ static void interact_with_options(std::vector<option_type *> const &options, cha { break; } - *(options[k]->o_var) = TRUE; + *(options[k].o_var) = TRUE; k = (k + 1) % n; break; } @@ -594,7 +605,7 @@ static void interact_with_options(std::vector<option_type *> const &options, cha break; } - *(options[k]->o_var) = FALSE; + *(options[k].o_var) = FALSE; k = (k + 1) % n; break; } @@ -614,56 +625,26 @@ static void interact_with_options(std::vector<option_type *> const &options, cha /* - * Cheating options - */ -static option_type cheat_info[6] = -{ - { &cheat_peek, FALSE, 0, 0, "cheat_peek", "Peek into object creation" }, - { &cheat_hear, FALSE, 0, 1, "cheat_hear", "Peek into monster creation" }, - { &cheat_room, FALSE, 0, 2, "cheat_room", "Peek into dungeon creation" }, - { &cheat_xtra, FALSE, 0, 3, "cheat_xtra", "Peek into something else" }, - { &cheat_know, FALSE, 0, 4, "cheat_know", "Know complete monster info" }, - { &cheat_live, FALSE, 0, 5, "cheat_live", "Allow player to avoid death" } -}; - -/* * Interact with some options for cheating */ static void do_cmd_options_cheat(cptr info) { - // Calculate number of cheat options - size_t n = std::distance(std::begin(cheat_info), std::end(cheat_info)); - - // Build the vector of options we're going to interact with - std::vector<option_type *> options; - options.reserve(n); - for (auto &option : cheat_info) - { - options.push_back(&option); - } - // Interact - interact_with_options(options, info, interaction_mode_t::READ_WRITE); + interact_with_options(options->cheat_options, info, interaction_mode_t::READ_WRITE); // If user toggled any of the options to TRUE, then we add those cheats // to the player's "noscore" flags. Note that it doesn't matter what the // previous value was -- we don't "unset" noscore flags anyway. - for (auto &option: options) + for (auto const &option: options->cheat_options) { - if (*option->o_var) + if (*option.o_var) { - noscore |= (option->o_page * 256 + option->o_bit); + noscore |= (option.o_page * 256 + option.o_bit); } } } -static option_type autosave_info[2] = -{ - { &autosave_l, FALSE, 0, 6, "autosave_l", "Autosave when entering new levels" }, - { &autosave_t, FALSE, 0, 7, "autosave_t", "Timed autosave" }, -}; - s16b toggle_frequency(s16b current) { if (current == 0) return (50); @@ -687,7 +668,9 @@ static void do_cmd_options_autosave(cptr info) { char ch; - int i, k = 0, n = 2; + int i, k = 0; + + int n = options->autosave_options.size(); int dir; @@ -714,15 +697,18 @@ static void do_cmd_options_autosave(cptr info) /* Color current option */ if (i == k) a = TERM_L_BLUE; + /* Get the option */ + auto const option = &options->autosave_options[i]; + /* Display the option text */ strnfmt(buf, 80, "%-48s: %s (%s)", - autosave_info[i].o_desc, - (*autosave_info[i].o_var ? "yes" : "no "), - autosave_info[i].o_text); + option->o_desc, + (*option->o_var) ? "yes" : "no ", + option->o_text); c_prt(a, buf, i + 2, 0); } - prt(format("Timed autosave frequency: every %d turns", autosave_freq), 5, 0); + prt(format("Timed autosave frequency: every %d turns", options->autosave_freq), 5, 0); /* Hilite current option */ @@ -768,8 +754,7 @@ static void do_cmd_options_autosave(cptr info) case 'Y': case '6': { - - (*autosave_info[k].o_var) = TRUE; + (*options->autosave_options[k].o_var) = TRUE; k = (k + 1) % n; break; @@ -779,7 +764,7 @@ static void do_cmd_options_autosave(cptr info) case 'N': case '4': { - (*autosave_info[k].o_var) = FALSE; + (*options->autosave_options[k].o_var) = FALSE; k = (k + 1) % n; break; @@ -788,9 +773,9 @@ static void do_cmd_options_autosave(cptr info) case 'f': case 'F': { - autosave_freq = toggle_frequency(autosave_freq); - prt(format("Timed autosave frequency: every %d turns", - autosave_freq), 5, 0); + options->autosave_freq = toggle_frequency(options->autosave_freq); + prt(fmt::format("Timed autosave frequency: every {} turns", + options->autosave_freq), 5, 0); break; } @@ -811,28 +796,29 @@ static void do_cmd_options_autosave(cptr info) void do_cmd_options_aux(int page, cptr info, bool_ read_only) { // Scrape together all the options from the relevant page. - std::vector<option_type *> options; - options.reserve(64); // Seems a reasonable number; anything more would be unusable anyway - for (size_t i = 0; option_info[i].o_desc; i++) - { - if (option_info[i].o_page == page) - { - options.push_back(&option_info[i]); - } - } + std::vector<option_type> page_options; + page_options.reserve(options->standard_options.size()); + std::copy_if( + std::begin(options->standard_options), + std::end(options->standard_options), + std::back_inserter(page_options), + [=](option_type const &option) -> bool { + return (option.o_page == page); + } + ); // Interact with the options interaction_mode_t interaction_mode = read_only ? interaction_mode_t::READ_ONLY : interaction_mode_t::READ_WRITE; - interact_with_options(options, info, interaction_mode); + interact_with_options(page_options, info, interaction_mode); } /* * Modify the "window" options */ -static void do_cmd_options_win(void) +static void do_cmd_options_win() { int i, j, d; @@ -848,7 +834,7 @@ static void do_cmd_options_win(void) /* Memorize old flags */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Acquire current flags */ old_flag[j] = window_flag[j]; @@ -865,7 +851,7 @@ static void do_cmd_options_win(void) prt("Window Flags (<dir>, t, y, n, ESC) ", 0, 0); /* Display the windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { byte a = TERM_WHITE; @@ -895,7 +881,7 @@ static void do_cmd_options_win(void) Term_putstr(0, i + 5, -1, a, str); /* Display the windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { byte a = TERM_WHITE; @@ -932,7 +918,7 @@ static void do_cmd_options_win(void) case 't': { /* Clear windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { window_flag[j] &= ~(1L << y); } @@ -982,7 +968,7 @@ static void do_cmd_options_win(void) } /* Notice changes */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { term *old = Term; @@ -1037,25 +1023,25 @@ static errr option_dump(cptr fname) fprintf(fff, "# Automatic option dump\n\n"); /* Dump options (skip cheat, adult, score) */ - for (i = 0; option_info[i].o_var != NULL; i++) + for (auto const &option: options->standard_options) { /* Require a real option */ - if (!option_info[i].o_text) continue; + if (!option.o_text) continue; /* No birth options */ - if (option_info[i].o_page == 6) continue; + if (option.o_page == 6) continue; /* Comment */ - fprintf(fff, "# Option '%s'\n", option_info[i].o_desc); + fprintf(fff, "# Option '%s'\n", option.o_desc); /* Dump the option */ - if ((*option_info[i].o_var)) + if (*option.o_var) { - fprintf(fff, "Y:%s\n", option_info[i].o_text); + fprintf(fff, "Y:%s\n", option.o_text); } else { - fprintf(fff, "X:%s\n", option_info[i].o_text); + fprintf(fff, "X:%s\n", option.o_text); } /* Skip a line */ @@ -1111,9 +1097,6 @@ static errr option_dump(cptr fname) */ static void do_cmd_pref_file_hack(int row) { - char ftmp[80]; - - /* Prompt */ prt("Command: Load a user pref file", row, 0); @@ -1121,21 +1104,24 @@ static void do_cmd_pref_file_hack(int row) prt("File: ", row + 2, 0); /* Default filename */ - strnfmt(ftmp, 80, "%s.prf", player_base); + std::string ftmp = fmt::format("{}.prf", game->player_base); /* Ask for a file (or cancel) */ - if (!askfor_aux(ftmp, 80)) return; + if (!askfor_aux(&ftmp, 80)) + { + return; + } /* Process the given filename */ - if (process_pref_file(ftmp)) + if (process_pref_file(ftmp.c_str())) { /* Mention failure */ - msg_format("Failed to load '%s'!", ftmp); + msg_format("Failed to load '%s'!", ftmp.c_str()); } else { /* Mention success */ - msg_format("Loaded '%s'.", ftmp); + msg_format("Loaded '%s'.", ftmp.c_str()); } } @@ -1146,7 +1132,7 @@ static void do_cmd_pref_file_hack(int row) * The user must use the "Ctrl-R" command to "adapt" to changes * in any options which control "visual" aspects of the game. */ -void do_cmd_options(void) +void do_cmd_options() { int k; @@ -1216,8 +1202,6 @@ void do_cmd_options(void) case 'u': case 'U': { - char ftmp[80]; - /* Prompt */ prt("Command: Append options to a file", 21, 0); @@ -1225,13 +1209,13 @@ void do_cmd_options(void) prt("File: ", 21, 0); /* Default filename */ - strnfmt(ftmp, 80, "%s.prf", player_base); + auto ftmp = fmt::format("{}.prf", game->player_base); /* Ask for a file */ - if (!askfor_aux(ftmp, 80)) continue; + if (!askfor_aux(&ftmp, 80)) continue; /* Dump the options */ - if (option_dump(ftmp)) + if (option_dump(ftmp.c_str())) { /* Failure */ msg_print("Failed!"); @@ -1340,14 +1324,26 @@ void do_cmd_options(void) /* Get a new value */ while (1) { - int msec = delay_factor * delay_factor * delay_factor; - prt(format("Current base delay factor: %d (%d msec)", - delay_factor, msec), 22, 0); + auto const msec = options->delay_factor_ms(); + + prt(fmt::format("Current base delay factor: {:d} ({:d} msec)", + options->delay_factor, msec), 22, 0); prt("Delay Factor (0-9 or ESC to accept): ", 23, 0); + k = inkey(); - if (k == ESCAPE) break; - if (isdigit(k)) delay_factor = D2I(k); - else bell(); + if (k == ESCAPE) + { + break; + } + + if (isdigit(k)) + { + options->delay_factor = D2I(k); + } + else + { + bell(); + } } break; @@ -1363,13 +1359,24 @@ void do_cmd_options(void) /* Get a new value */ while (1) { - prt(format("Current hitpoint warning: %d0%%", - hitpoint_warn), 22, 0); + prt(fmt::format("Current hitpoint warning: {:d}0%", + options->hitpoint_warn), 22, 0); prt("Hitpoint Warning (0-9 or ESC to accept): ", 20, 0); + k = inkey(); - if (k == ESCAPE) break; - if (isdigit(k)) hitpoint_warn = D2I(k); - else bell(); + if (k == ESCAPE) + { + break; + } + + if (isdigit(k)) + { + options->hitpoint_warn = D2I(k); + } + else + { + bell(); + } } break; @@ -1401,7 +1408,7 @@ void do_cmd_options(void) * * XXX XXX XXX Allow absolute file names? */ -void do_cmd_pref(void) +void do_cmd_pref() { char buf[80]; @@ -1413,7 +1420,7 @@ void do_cmd_pref(void) if (!get_string("Pref: ", buf, 80)) return; /* Process that pref command */ - (void)process_pref_file_aux(buf); + process_pref_file_aux(buf); } @@ -1642,19 +1649,10 @@ static errr keymap_dump(cptr fname) * * Could use some helpful instructions on this page. XXX XXX XXX */ -void do_cmd_macros(void) +void do_cmd_macros() { - int i; - - char tmp[1024]; - - char buf[1024]; - - int mode; - - /* Keymap mode */ - mode = get_keymap_mode(); + int mode = get_keymap_mode(); /* Enter "icky" mode */ @@ -1667,6 +1665,8 @@ void do_cmd_macros(void) /* Process requests until done */ while (1) { + char buf[1024]; + /* Clear screen */ Term_clear(); @@ -1700,7 +1700,7 @@ void do_cmd_macros(void) prt("Command: ", 16, 0); /* Get a command */ - i = inkey(); + int i = inkey(); /* Leave */ if (i == ESCAPE) break; @@ -1715,13 +1715,16 @@ void do_cmd_macros(void) prt("File: ", 18, 0); /* Default filename */ - strnfmt(tmp, 1024, "%s.prf", player_name); + auto tmp = fmt::format("{}.prf", game->player_name); /* Ask for a file */ - if (!askfor_aux(tmp, 80)) continue; + if (!askfor_aux(&tmp, 80)) + { + continue; + } /* Process the given filename */ - if (0 != process_pref_file(tmp)) + if (0 != process_pref_file(tmp.c_str())) { /* Prompt */ msg_print("Could not load file!"); @@ -1738,13 +1741,16 @@ void do_cmd_macros(void) prt("File: ", 18, 0); /* Default filename */ - strnfmt(tmp, 1024, "%s.prf", player_name); + auto tmp = fmt::format("{}.prf", game->player_name); /* Ask for a file */ - if (!askfor_aux(tmp, 80)) continue; + if (!askfor_aux(&tmp, 80)) + { + continue; + } /* Dump the macros */ - (void)macro_dump(tmp); + macro_dump(tmp.c_str()); /* Prompt */ msg_print("Appended macros."); @@ -1794,6 +1800,8 @@ void do_cmd_macros(void) /* Create a macro */ else if (i == '4') { + char tmp[1024]; + /* Prompt */ prt("Command: Create a macro", 16, 0); @@ -1855,13 +1863,16 @@ void do_cmd_macros(void) prt("File: ", 18, 0); /* Default filename */ - strnfmt(tmp, 1024, "%s.prf", player_name); + auto tmp = fmt::format("{}.prf", game->player_name); /* Ask for a file */ - if (!askfor_aux(tmp, 80)) continue; + if (!askfor_aux(&tmp, 80)) + { + continue; + } /* Dump the macros */ - (void)keymap_dump(tmp); + keymap_dump(tmp.c_str()); /* Prompt */ msg_print("Appended keymaps."); @@ -1911,6 +1922,8 @@ void do_cmd_macros(void) /* Create a keymap */ else if (i == '8') { + char tmp[1024]; + /* Prompt */ prt("Command: Create a keymap", 16, 0); @@ -1967,6 +1980,8 @@ void do_cmd_macros(void) /* Enter a new action */ else if (i == '0') { + char tmp[1024]; + /* Prompt */ prt("Command: Enter a new action", 16, 0); @@ -2005,8 +2020,12 @@ void do_cmd_macros(void) /* * Interact with "visuals" */ -void do_cmd_visuals(void) +void do_cmd_visuals() { + auto &r_info = game->edit_data.r_info; + auto &f_info = game->edit_data.f_info; + auto &k_info = game->edit_data.k_info; + int i; FILE *fff; @@ -2069,7 +2088,7 @@ void do_cmd_visuals(void) if (!askfor_aux(tmp, 70)) continue; /* Process the given filename */ - (void)process_pref_file(tmp); + process_pref_file(tmp); } /* Dump monster attr/chars */ @@ -2101,9 +2120,9 @@ void do_cmd_visuals(void) fprintf(fff, "# Monster attr/char definitions\n\n"); /* Dump monsters */ - for (i = 0; i < max_r_idx; i++) + for (std::size_t i = 0; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; + auto r_ptr = &r_info[i]; /* Skip non-entries */ if (!r_ptr->name) continue; @@ -2112,7 +2131,7 @@ void do_cmd_visuals(void) fprintf(fff, "# %s\n", r_ptr->name); /* Dump the monster attr/char info */ - fprintf(fff, "R:%d:0x%02X:0x%02X\n\n", i, + fprintf(fff, "R:%zu:0x%02X:0x%02X\n\n", i, static_cast<unsigned int>(r_ptr->x_attr), static_cast<unsigned int>(r_ptr->x_char)); } @@ -2156,9 +2175,9 @@ void do_cmd_visuals(void) fprintf(fff, "# Object attr/char definitions\n\n"); /* Dump objects */ - for (i = 0; i < max_k_idx; i++) + for (std::size_t k = 0; k < k_info.size(); k++) { - object_kind *k_ptr = &k_info[i]; + object_kind *k_ptr = &k_info[k]; /* Skip non-entries */ if (!k_ptr->name) continue; @@ -2167,7 +2186,7 @@ void do_cmd_visuals(void) fprintf(fff, "# %s\n", k_ptr->name); /* Dump the object attr/char info */ - fprintf(fff, "K:%d:0x%02X:0x%02X\n\n", i, + fprintf(fff, "K:%zu:0x%02X:0x%02X\n\n", k, (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char)); } @@ -2210,9 +2229,9 @@ void do_cmd_visuals(void) fprintf(fff, "# Feature attr/char definitions\n\n"); /* Dump features */ - for (i = 0; i < max_f_idx; i++) + for (std::size_t f_idx = 0; f_idx < f_info.size(); f_idx++) { - feature_type *f_ptr = &f_info[i]; + auto f_ptr = &f_info[f_idx]; /* Skip non-entries */ if (!f_ptr->name) continue; @@ -2221,7 +2240,7 @@ void do_cmd_visuals(void) fprintf(fff, "# %s\n", f_ptr->name); /* Dump the feature attr/char info */ - fprintf(fff, "F:%d:0x%02X:0x%02X\n\n", i, + fprintf(fff, "F:%zu:0x%02X:0x%02X\n\n", f_idx, (byte)(f_ptr->x_attr), (byte)(f_ptr->x_char)); } @@ -2246,7 +2265,7 @@ void do_cmd_visuals(void) /* Hack -- query until done */ while (1) { - monster_race *r_ptr = &r_info[r]; + auto r_ptr = &r_info[r]; byte da = (r_ptr->d_attr); char dc = (r_ptr->d_char); @@ -2281,8 +2300,8 @@ void do_cmd_visuals(void) if (i == ESCAPE) break; /* Analyze */ - if (i == 'n') r = (r + max_r_idx + 1) % max_r_idx; - if (i == 'N') r = (r + max_r_idx - 1) % max_r_idx; + if (i == 'n') r = (r + r_info.size() + 1) % r_info.size(); + if (i == 'N') r = (r + r_info.size() - 1) % r_info.size(); if (i == 'a') r_ptr->x_attr = (ca + 1); if (i == 'A') r_ptr->x_attr = (ca - 1); if (i == 'c') r_ptr->x_char = (cc + 1); @@ -2336,8 +2355,8 @@ void do_cmd_visuals(void) if (i == ESCAPE) break; /* Analyze */ - if (i == 'n') k = (k + max_k_idx + 1) % max_k_idx; - if (i == 'N') k = (k + max_k_idx - 1) % max_k_idx; + if (i == 'n') k = (k + k_info.size() + 1) % k_info.size(); + if (i == 'N') k = (k + k_info.size() - 1) % k_info.size(); if (i == 'a') k_info[k].x_attr = (ca + 1); if (i == 'A') k_info[k].x_attr = (ca - 1); if (i == 'c') k_info[k].x_char = (cc + 1); @@ -2356,7 +2375,7 @@ void do_cmd_visuals(void) /* Hack -- query until done */ while (1) { - feature_type *f_ptr = &f_info[f]; + auto f_ptr = &f_info[f]; byte da = f_ptr->d_attr; char dc = f_ptr->d_char; @@ -2391,8 +2410,8 @@ void do_cmd_visuals(void) if (i == ESCAPE) break; /* Analyze */ - if (i == 'n') f = (f + max_f_idx + 1) % max_f_idx; - if (i == 'N') f = (f + max_f_idx - 1) % max_f_idx; + if (i == 'n') f = (f + f_info.size() + 1) % f_info.size(); + if (i == 'N') f = (f + f_info.size() - 1) % f_info.size(); if (i == 'a') f_info[f].x_attr = (ca + 1); if (i == 'A') f_info[f].x_attr = (ca - 1); if (i == 'c') f_info[f].x_char = (cc + 1); @@ -2437,7 +2456,7 @@ void do_cmd_visuals(void) /* * Interact with "colors" */ -void do_cmd_colors(void) +void do_cmd_colors() { int i; @@ -2494,7 +2513,7 @@ void do_cmd_colors(void) if (!askfor_aux(tmp, 70)) continue; /* Process the given filename */ - (void)process_pref_file(tmp); + process_pref_file(tmp); /* Mega-Hack -- react to changes */ Term_xtra(TERM_XTRA_REACT, 0); @@ -2659,7 +2678,7 @@ void do_cmd_colors(void) * Take notes. There are two ways this can happen, either in the message * recall or a file. */ -void do_cmd_note(void) +void do_cmd_note() { char buf[80]; @@ -2680,7 +2699,7 @@ void do_cmd_note(void) /* * Mention the current version */ -void do_cmd_version(void) +void do_cmd_version() { /* Silly message */ msg_format("You are playing %s made by %s (%s).", @@ -2714,14 +2733,16 @@ static cptr do_cmd_feeling_text[11] = * Note that "feeling" is set to zero unless some time has passed. * Note that this is done when the level is GENERATED, not entered. */ -void do_cmd_feeling(void) +void do_cmd_feeling() { + auto const &d_info = game->edit_data.d_info; + /* Verify the feeling */ if (feeling < 0) feeling = 0; if (feeling > 10) feeling = 10; /* Feeling of the fate */ - if (fate_flag && !(dungeon_flags2 & DF2_SPECIAL) && !p_ptr->inside_quest) + if (fate_flag && !(dungeon_flags & DF_SPECIAL) && !p_ptr->inside_quest) { msg_print("You feel that you will meet your fate here."); } @@ -2733,11 +2754,11 @@ void do_cmd_feeling(void) } /* No useful feeling in special levels */ - if (dungeon_flags2 & DF2_DESC) + if (dungeon_flags & DF_DESC) { char buf[1024]; - if ((get_dungeon_save(buf)) || (generate_special_feeling) || (dungeon_flags2 & DF2_DESC_ALWAYS)) + if (get_dungeon_save(buf) || game->generate_special_feeling || (dungeon_flags & DF_DESC_ALWAYS)) { if (!get_level_desc(buf)) msg_print("Someone forgot to describe this level!"); else msg_print(buf); @@ -2757,7 +2778,7 @@ void do_cmd_feeling(void) { /* This could be simplified with a correct p_ptr->town_num */ int i, town_level = 0; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; /* Is it a town level ? */ for (i = 0; i < TOWN_DUNGEON; i++) @@ -2784,7 +2805,7 @@ static char hack[17] = "dwsorgbuDWvyRGBU"; /* * Hack -- load a screen dump from a file */ -void do_cmd_load_screen(void) +void do_cmd_load_screen() { int i, y, x; @@ -2872,7 +2893,7 @@ void do_cmd_load_screen(void) for (x = 0; x < len; x++) { /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < 16; i++) @@ -2908,7 +2929,7 @@ void do_cmd_load_screen(void) /* * Hack -- save a screen dump to a file */ -void do_cmd_save_screen(void) +void do_cmd_save_screen() { int y, x; int wid, hgt; @@ -2948,7 +2969,7 @@ void do_cmd_save_screen(void) for (x = 0; x < wid; x++) { /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; @@ -2972,7 +2993,7 @@ void do_cmd_save_screen(void) for (x = 0; x < wid; x++) { /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = hack[a & 0x0F]; @@ -3009,30 +3030,20 @@ void do_cmd_save_screen(void) /* * Check the status of "artifacts" */ -void do_cmd_knowledge_artifacts(void) +void do_cmd_knowledge_artifacts() { - int i, k, z, x, y; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; - FILE *fff; - - char file_name[1024]; + int i, z, x, y; char base_name[80]; - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - /* Scan the artifacts */ - std::unique_ptr<bool_[]> okay(new bool_[max_a_idx]); - for (k = 0; k < max_a_idx; k++) + std::vector<bool_> okay(a_info.size(), FALSE); + for (std::size_t k = 0; k < a_info.size(); k++) { - artifact_type *a_ptr = &a_info[k]; - - /* Default */ - okay[k] = FALSE; + auto a_ptr = &a_info[k]; /* Skip "empty" artifacts */ if (!a_ptr->name) continue; @@ -3044,16 +3055,13 @@ void do_cmd_knowledge_artifacts(void) okay[k] = TRUE; } - std::unique_ptr<bool_[]> okayk(new bool_[max_k_idx]); - for (k = 0; k < max_k_idx; k++) + std::vector<bool_> okayk(k_info.size(), FALSE); + for (std::size_t k = 0; k < k_info.size(); k++) { - object_kind *k_ptr = &k_info[k]; - - /* Default */ - okayk[k] = FALSE; + auto k_ptr = &k_info[k]; /* Skip "empty" artifacts */ - if (!(k_ptr->flags3 & TR3_NORM_ART)) continue; + if (!(k_ptr->flags & TR_NORM_ART)) continue; /* Skip "uncreated" artifacts */ if (!k_ptr->artifact) continue; @@ -3085,7 +3093,7 @@ void do_cmd_knowledge_artifacts(void) if (object_known_p(o_ptr)) continue; /* Note the artifact */ - if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { okayk[o_ptr->k_idx] = FALSE; } @@ -3118,7 +3126,7 @@ void do_cmd_knowledge_artifacts(void) if (object_known_p(o_ptr)) continue; /* Note the artifact */ - if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { okayk[o_ptr->k_idx] = FALSE; } @@ -3147,7 +3155,7 @@ void do_cmd_knowledge_artifacts(void) if (object_known_p(o_ptr)) continue; /* Note the artifact */ - if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { okayk[o_ptr->k_idx] = FALSE; } @@ -3157,10 +3165,13 @@ void do_cmd_knowledge_artifacts(void) } } + /* Output buffer */ + fmt::MemoryWriter w; + /* Scan the artifacts */ - for (k = 0; k < max_a_idx; k++) + for (std::size_t k = 0; k < a_info.size(); k++) { - artifact_type *a_ptr = &a_info[k]; + auto a_ptr = &a_info[k]; /* List "dead" ones */ if (!okay[k]) continue; @@ -3176,7 +3187,6 @@ void do_cmd_knowledge_artifacts(void) { object_type forge; object_type *q_ptr; - u32b f1, f2, f3, f4, f5, esp; /* Get local object */ q_ptr = &forge; @@ -3188,19 +3198,21 @@ void do_cmd_knowledge_artifacts(void) q_ptr->name1 = k; /* Spell in it ? no ! */ - object_flags(q_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f5 & TR5_SPELL_CONTAIN) + auto const flags = object_flags(q_ptr); + if (flags & TR_SPELL_CONTAIN) + { q_ptr->pval2 = -1; + } /* Describe the artifact */ object_desc_store(base_name, q_ptr, FALSE, 0); } /* Hack -- Build the artifact name */ - fprintf(fff, " The %s\n", base_name); + w.write(" The {}\n", base_name); } - for (k = 0; k < max_k_idx; k++) + for (std::size_t k = 0; k < k_info.size(); k++) { /* List "dead" ones */ if (!okayk[k]) continue; @@ -3225,68 +3237,18 @@ void do_cmd_knowledge_artifacts(void) } /* Hack -- Build the artifact name */ - fprintf(fff, " The %s\n", base_name); + w.write(" The {}\n", base_name); } - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Artifacts Seen", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + /* Display */ + show_string(w.c_str(), "Artifacts Seen"); } -/* - * Check the status of traps - */ -void do_cmd_knowledge_traps(void) +static int monster_get_race_level(int r_idx) { - int k; - - FILE *fff; - - trap_type *t_ptr; - - char file_name[1024]; - + auto const &r_info = game->edit_data.r_info; - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - /* Scan the traps */ - for (k = 0; k < max_t_idx; k++) - { - /* Get the trap */ - t_ptr = &t_info[k]; - - /* Skip "empty" traps */ - if (!t_ptr->name) continue; - - /* Skip unidentified traps */ - if (!t_ptr->ident) continue; - - /* Hack -- Build the trap name */ - fprintf(fff, " %s\n", t_ptr->name); - } - - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Traps known", 0, 0); - - /* Remove the file */ - fd_kill(file_name); -} - - -static int monster_get_race_level(int r_idx) { /* Hack -- Morgoth is always last */ if (r_idx == 862) { return 20000; @@ -3295,40 +3257,23 @@ static int monster_get_race_level(int r_idx) { return r_info[r_idx].level; } -static bool compare_monster_level(int r_idx1, int r_idx2) { - return monster_get_race_level(r_idx1) < monster_get_race_level(r_idx2); -} - /* * Display known uniques - * - * Note that the player ghosts are ignored. XXX XXX XXX */ -static void do_cmd_knowledge_uniques(void) +static void do_cmd_knowledge_uniques() { - int k; - - FILE *fff; - - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); + auto const &r_info = game->edit_data.r_info; // Extract the unique race indexes. - std::vector<int> unique_r_idxs; - for (k = 1; k < max_r_idx; k++) + std::vector<std::size_t> unique_r_idxs; + for (std::size_t k = 1; k < r_info.size(); k++) { - monster_race *r_ptr = &r_info[k]; + auto r_ptr = &r_info[k]; /* Only print Uniques */ - if (r_ptr->flags1 & (RF1_UNIQUE) && - !(r_ptr->flags7 & RF7_PET) && - !(r_ptr->flags7 & RF7_NEUTRAL)) + if ((r_ptr->flags & RF_UNIQUE) && + !(r_ptr->flags & RF_PET) && + !(r_ptr->flags & RF_NEUTRAL)) { unique_r_idxs.push_back(k); } @@ -3337,48 +3282,41 @@ static void do_cmd_knowledge_uniques(void) // Sort races by level. std::sort(std::begin(unique_r_idxs), std::end(unique_r_idxs), - compare_monster_level); + [](auto r_idx1, auto r_idx2) -> bool { + return monster_get_race_level(r_idx1) < monster_get_race_level(r_idx2); + }); - /* Scan the monster races */ - for (int r_idx : unique_r_idxs) + // Scan the monster races + fmt::MemoryWriter w; + for (std::size_t r_idx : unique_r_idxs) { - monster_race *r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; /* Only print Uniques */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { bool_ dead = (r_ptr->max_num == 0); - /* Only display "known" uniques */ - if (dead || cheat_know || r_ptr->r_sights) + /* Print a message */ + if (dead) { - /* Print a message */ - if (dead) - { - fprintf(fff, "[[[[[%c%c] [[[[[R%-68s is dead]\n", - conv_color[r_ptr->d_attr], - r_ptr->d_char, - r_ptr->name); - } - else - { - fprintf(fff, "[[[[[%c%c] [[[[[w%-68s is alive]\n", - conv_color[r_ptr->d_attr], - r_ptr->d_char, - r_ptr->name); - } + w.write("[[[[[{}{}] [[[[[R{:<68} is dead]\n", + static_cast<char>(conv_color[r_ptr->d_attr]), + static_cast<char>(r_ptr->d_char), + r_ptr->name); + } + else + { + w.write("[[[[[{}{}] [[[[[w{:<68} is alive]\n", + static_cast<char>(conv_color[r_ptr->d_attr]), + static_cast<char>(r_ptr->d_char), + r_ptr->name); } } } - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Known Uniques", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + // Display + show_string(w.c_str(), "Known Uniques"); } @@ -3438,29 +3376,29 @@ static void plural_aux(char *name) } /* Broken plurals are, well, broken */ - else if (name[name_len - 1] == 'y') + else if (name_len >= 1 && name[name_len - 1] == 'y') { strcpy(&name[name_len - 1], "ies"); } - else if (streq(&name[name_len - 4], "ouse")) + else if (name_len >= 4 && streq(&name[name_len - 4], "ouse")) { strcpy(&name[name_len - 4], "ice"); } - else if (streq(&name[name_len - 6], "kelman")) + else if (name_len >= 6 && streq(&name[name_len - 6], "kelman")) { strcpy(&name[name_len - 6], "kelmen"); } - else if (streq(&name[name_len - 2], "ex")) + else if (name_len >= 2 && streq(&name[name_len - 2], "ex")) { strcpy(&name[name_len - 2], "ices"); } - else if (streq(&name[name_len - 3], "olf")) + else if (name_len >= 3 && streq(&name[name_len - 3], "olf")) { strcpy(&name[name_len - 3], "olves"); } /* Now begins sane cases */ - else if ((streq(&name[name_len - 2], "ch")) || (name[name_len - 1] == 's')) + else if ((name_len >= 2 && streq(&name[name_len - 2], "ch")) || (name_len >= 1 && name[name_len - 1] == 's')) { strcpy(&name[name_len], "es"); } @@ -3474,38 +3412,19 @@ static void plural_aux(char *name) /* * Display current pets */ -static void do_cmd_knowledge_pets(void) +static void do_cmd_knowledge_pets() { - int i; - - FILE *fff; - - monster_type *m_ptr; - int t_friends = 0; - int t_levels = 0; - int show_upkeep = 0; - - int upkeep_divider = 20; - - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - if (has_ability(AB_PERFECT_CASTING)) upkeep_divider = 15; + // Buffer + fmt::MemoryWriter w; /* Process the monsters (backwards) */ - for (i = m_max - 1; i >= 1; i--) + for (int i = m_max - 1; i >= 1; i--) { /* Access the monster */ - m_ptr = &m_list[i]; + monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ if (!m_ptr->r_idx) continue; @@ -3521,13 +3440,17 @@ static void do_cmd_knowledge_pets(void) char pet_name[80]; monster_desc(pet_name, m_ptr, 0x88); - fprintf(fff, "%s%s (%s)\n", - (r_ptr->flags1 & RF1_UNIQUE) ? "#####G" : "", - pet_name, - (m_ptr->status < MSTATUS_COMPANION) ? "pet" : "companion"); + w.write("{}{} ({})\n", + (r_ptr->flags & RF_UNIQUE) ? "#####G" : "", + pet_name, + (m_ptr->status < MSTATUS_COMPANION) ? "pet" : "companion"); } } + // Calculate upkeep + int show_upkeep = 0; + int upkeep_divider = p_ptr->has_ability(AB_PERFECT_CASTING) ? 15 : 20; + if (t_friends > 1 + (p_ptr->lev / (upkeep_divider))) { show_upkeep = (t_levels); @@ -3536,104 +3459,78 @@ static void do_cmd_knowledge_pets(void) else if (show_upkeep < 10) show_upkeep = 10; } + // Summary + w.write("----------------------------------------------\n"); + w.write(" Total: {} pet{}.\n", t_friends, (t_friends == 1 ? "" : "s")); + w.write(" Upkeep: {}% mana.\n", show_upkeep); - fprintf(fff, "----------------------------------------------\n"); - fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s")); - fprintf(fff, " Upkeep: %d%% mana.\n", show_upkeep); - - - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Current Pets", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + // Display + show_string(w.c_str(), "Current Pets"); } /* * Total kill count - * - * Note that the player ghosts are ignored. XXX XXX XXX */ -static void do_cmd_knowledge_kill_count(void) +static void do_cmd_knowledge_kill_count() { - int k; - - FILE *fff; - - char file_name[1024]; + auto const &r_info = game->edit_data.r_info; s32b Total = 0; + // Buffer + fmt::MemoryWriter w; - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - + // Summary of monsters slain { - /* Monsters slain */ - int kk; - /* For all monsters */ - for (kk = 1; kk < max_r_idx; kk++) + for (auto const &r_ref: r_info) { - monster_race *r_ptr = &r_info[kk]; + auto r_ptr = &r_ref; - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { - bool_ dead = (r_ptr->max_num == 0); - - if (dead) + if (r_ptr->max_num == 0) { Total++; } } else { - s16b This = r_ptr->r_pkills; - - if (This > 0) - { - Total += This; - } + Total += std::max<s16b>(r_ptr->r_pkills, 0); } } if (Total < 1) { - fprintf(fff, "You have defeated no enemies yet.\n\n"); + w.write("You have defeated no enemies yet.\n\n"); } else if (Total == 1) { - fprintf(fff, "You have defeated one enemy.\n\n"); + w.write("You have defeated one enemy.\n\n"); } else { - fprintf(fff, "You have defeated " FMTs32b " enemies.\n\n", Total); + w.write("You have defeated {} enemies.\n\n", Total); } } Total = 0; /* Scan the monster races */ - for (k = 0; k < max_r_idx; k++) + for (auto const &r_ref: r_info) { - monster_race *r_ptr = &r_info[k]; + auto r_ptr = &r_ref; - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { bool_ dead = (r_ptr->max_num == 0); if (dead) { /* Print a message */ - fprintf(fff, " %s\n", r_ptr->name); + w.write(" {}\n", r_ptr->name); Total++; } } @@ -3647,11 +3544,11 @@ static void do_cmd_knowledge_kill_count(void) { if (strstr(r_ptr->name, "coins")) { - fprintf(fff, " 1 pile of %s\n", r_ptr->name); + w.write(" 1 pile of {}\n", r_ptr->name); } else { - fprintf(fff, " 1 %s\n", r_ptr->name); + w.write(" 1 {}\n", r_ptr->name); } } else @@ -3659,7 +3556,7 @@ static void do_cmd_knowledge_kill_count(void) char to_plural[80]; strcpy(to_plural, r_ptr->name); plural_aux(to_plural); - fprintf(fff, " %d %s\n", This, to_plural); + w.write(" {} {}\n", This, to_plural); } Total += This; @@ -3667,147 +3564,100 @@ static void do_cmd_knowledge_kill_count(void) } } - fprintf(fff, "----------------------------------------------\n"); - fprintf(fff, " Total: " FMTs32b " creature%s killed.\n", Total, (Total == 1 ? "" : "s")); - - /* Close the file */ - my_fclose(fff); + w.write("----------------------------------------------\n"); + w.write(" Total: {} creature{} killed.\n", Total, (Total == 1 ? "" : "s")); /* Display the file contents */ - show_file(file_name, "Kill Count", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + show_string(w.c_str(), "Kill Count"); } /* * Display known objects */ -static void do_cmd_knowledge_objects(void) +static void do_cmd_knowledge_objects() { - int k; - - FILE *fff; - - char o_name[80]; + auto const &k_info = game->edit_data.k_info; - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); + fmt::MemoryWriter w; /* Scan the object kinds */ - for (k = 1; k < max_k_idx; k++) + for (std::size_t k = 1; k < k_info.size(); k++) { - object_kind *k_ptr = &k_info[k]; + auto k_ptr = &k_info[k]; /* Hack -- skip artifacts */ - if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; + if (k_ptr->flags & (TR_INSTA_ART)) continue; /* List known flavored objects */ if (k_ptr->flavor && k_ptr->aware) { - object_type *i_ptr; object_type object_type_body; /* Get local object */ - i_ptr = &object_type_body; + object_type *i_ptr = &object_type_body; /* Create fake object */ object_prep(i_ptr, k); /* Describe the object */ + char o_name[80]; object_desc_store(o_name, i_ptr, FALSE, 0); /* Print a message */ - fprintf(fff, " %s\n", o_name); + w.write(" {}\n", o_name); } } - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Known Objects", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + // Display + show_string(w.c_str(), "Known Objects"); } /* * List recall depths */ -static void do_cmd_knowledge_dungeons(void) +static void do_cmd_knowledge_dungeons() { - int y; - char file_name[1024]; - FILE *fff; + auto const &d_info = game->edit_data.d_info; - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - /* Oops */ - if (fff == NULL) return; + fmt::MemoryWriter w; /* Scan all dungeons */ - for (y = 1; y < max_d_idx; y++) + for (std::size_t y = 1; y < d_info.size(); y++) { /* The dungeon has a valid recall depth set */ if (max_dlv[y]) { /* Describe the recall depth */ - fprintf(fff, " %c%s: Level %d (%d')\n", - (p_ptr->recall_dungeon == y) ? '*' : ' ', + w.write(" {}{}: Level {}\n", + (p_ptr->recall_dungeon == y) ? '*' : ' ', d_info[y].name, - max_dlv[y], 50 * (max_dlv[y])); + max_dlv[y]); } } - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Recall Depths", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + // Display + show_string(w.c_str(), "Recall Depths"); } /* * List known towns */ -void do_cmd_knowledge_towns(void) +void do_cmd_knowledge_towns() { - int i, j; - char file_name[1024]; - FILE *fff; - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; + auto const &d_info = game->edit_data.d_info; - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - /* Oops */ - if (fff == NULL) return; + fmt::MemoryWriter w; /* Scan all dungeons */ - for (i = 0; i < max_d_idx; i++) + for (auto const &d_ref: d_info) { - dungeon_info_type *d_ptr = &d_info[i]; + auto d_ptr = &d_ref; /* Scan all dungeon town slots */ - for (j = 0; j < TOWN_DUNGEON; j++) + for (int j = 0; j < TOWN_DUNGEON; j++) { int town_idx = d_ptr->t_idx[j]; @@ -3818,127 +3668,51 @@ void do_cmd_knowledge_towns(void) if (!(town_info[town_idx].flags & (TOWN_KNOWN))) continue; /* Describe the dungeon town */ - fprintf(fff, " %s: Level %d (%d')\n", + w.write(" {}: Level {}\n", d_ptr->name, - d_ptr->t_level[j], - 50 * d_ptr->t_level[j]); + d_ptr->t_level[j]); } } - /* Close the file */ - my_fclose(fff); - /* Display the file contents */ - show_file(file_name, "Dungeon Towns", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + show_string(w.c_str(), "Dungeon Towns"); } /* * List corruptions */ -static void do_cmd_knowledge_corruptions(void) +static void do_cmd_knowledge_corruptions() { - FILE *fff; - - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - /* Dump the corruptions to file */ - if (fff) - { - dump_corruptions(fff, TRUE, FALSE); - } - - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Corruptions", 0, 0); - - /* Remove the file */ - fd_kill(file_name); -} - - -/* - * Helper function for do_cmd_knowledge_quests - */ -static void insert_sort_quest(int *order, int *num, int q_idx) -{ - int i, j; - - quest_type *q_ptr = &quest[q_idx]; - - int level = q_ptr->level; - - - /* Find the place */ - for (i = 0; i < *num; i++) - { - quest_type *q2_ptr = &quest[order[i]]; - int level2 = q2_ptr->level; - - if (level < level2) break; - } - - /* Move the remaining items */ - for (j = *num - 1; j >= i; j--) - { - order[j + 1] = order[j]; - } - - /* Insert it */ - order[i] = q_idx; - (*num)++; + show_string(dump_corruptions(true, false).c_str(), "Corruptions"); } /* * Print quest status of all active quests */ -static void do_cmd_knowledge_quests(void) +static void do_cmd_knowledge_quests() { - FILE *fff; - - char file_name[1024]; - - int order[MAX_Q_IDX] = { }; - - int num = 0; - - int i, j, z; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - for (i = 0; i < MAX_Q_IDX; i++) - { - insert_sort_quest(order, &num, i); - } - - for (z = 0; z < MAX_Q_IDX; z++) + /* Figure out display order of quests */ + int order[MAX_Q_IDX]; + std::iota(order, order + MAX_Q_IDX, 0); // Start with order of definition + std::sort(order, order + MAX_Q_IDX, [](int qi, int qj) -> bool { + return (quest[qi].level < quest[qj].level); + }); + + /* Write */ + fmt::MemoryWriter w; + for (int z = 0; z < MAX_Q_IDX; z++) { - i = order[z]; + int const i = order[z]; /* Dynamic descriptions */ if (quest[i].gen_desc != NULL) { - if (!quest[i].gen_desc(fff)) + auto s = quest[i].gen_desc(); + if (!s.empty()) { - continue; + w.write("{}\n\n", s); } } @@ -3948,68 +3722,42 @@ static void do_cmd_knowledge_quests(void) if (quest[i].status == QUEST_STATUS_TAKEN) { /* Print the quest info */ - fprintf(fff, "#####y%s (Danger level: %d)\n", + w.write("#####y{} (Danger level: {})\n", quest[i].name, quest[i].level); - j = 0; + int j = 0; while ((j < 10) && (quest[i].desc[j][0] != '\0')) { - fprintf(fff, "%s\n", quest[i].desc[j++]); + w.write("{}\n", quest[i].desc[j++]); } - fprintf(fff, "\n"); + w.write("\n"); } else if (quest[i].status == QUEST_STATUS_COMPLETED) { - fprintf(fff , "#####G%s Completed - Unrewarded\n", quest[i].name); - fprintf(fff, "\n"); + w.write("#####G{} Completed - Unrewarded\n", quest[i].name); + w.write("\n"); } } } - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Quest status", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + /* Display */ + show_string(w.c_str(), "Quest status"); } /* * Print fate status */ -static void do_cmd_knowledge_fates(void) +static void do_cmd_knowledge_fates() { - FILE *fff; - - char file_name[1024]; - - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - dump_fates(fff); - - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Fate status", 0, 0); - - /* Remove the file */ - fd_kill(file_name); + show_string(dump_fates().c_str(), "Fate status"); } /* * Print the note file */ -void do_cmd_knowledge_notes(void) +void do_cmd_knowledge_notes() { /* Spawn */ show_notes_file(); @@ -4022,7 +3770,7 @@ void do_cmd_knowledge_notes(void) /* * Interact with "knowledge" */ -void do_cmd_knowledge(void) +void do_cmd_knowledge() { int i; @@ -4052,12 +3800,11 @@ void do_cmd_knowledge(void) prt("(7) Display current pets", 10, 5); prt("(8) Display current quests", 11, 5); prt("(9) Display current fates", 12, 5); - prt("(0) Display known traps", 13, 5); - prt("(A) Display known dungeon towns", 14, 5); - prt("(B) Display notes", 15, 5); + prt("(0) Display known dungeon towns", 13, 5); + prt("(A) Display notes", 14, 5); /* Prompt */ - prt("Command: ", 17, 0); + prt("Command: ", 16, 0); /* Prompt */ i = inkey(); @@ -4139,17 +3886,8 @@ void do_cmd_knowledge(void) break; } - /* Traps */ - case '0': - { - do_cmd_knowledge_traps(); - - break; - } - /* Dungeon towns */ - case 'A': - case 'a': + case '0': { do_cmd_knowledge_towns(); @@ -4157,8 +3895,8 @@ void do_cmd_knowledge(void) } /* Notes */ - case 'B': - case 'b': + case 'A': + case 'a': { do_cmd_knowledge_notes(); @@ -4190,7 +3928,7 @@ void do_cmd_knowledge(void) * Check on the status of an active quest -KMW- * TODO: Spill out status when not a simple kill # monster. */ -void do_cmd_checkquest(void) +void do_cmd_checkquest() { /* Enter "icky" mode */ character_icky = TRUE; @@ -4267,9 +4005,10 @@ void do_cmd_time() strcpy(desc, "It is a strange time."); /* Display day */ - u32b days = bst(DAY, turn) + 1; + auto days = bst(DAY, turn) + 1; + auto days_str = get_day(days); msg_format("This is the %s day of your adventure.", - get_day(days)); + days_str.c_str()); /* Message */ msg_format("The time is %d:%02d %s.", diff --git a/src/cmd4.hpp b/src/cmd4.hpp index 4470c94f..39f1c16c 100644 --- a/src/cmd4.hpp +++ b/src/cmd4.hpp @@ -2,27 +2,27 @@ #include "h-basic.h" -extern void macro_recorder_start(void); -extern void macro_recorder_add(char c); -extern void macro_recorder_stop(void); -extern void do_cmd_macro_recorder(void); -extern void do_cmd_redraw(void); -extern void do_cmd_change_name(void); -extern void do_cmd_message_one(void); -extern void do_cmd_messages(void); -extern void do_cmd_options(void); -extern void do_cmd_pref(void); -extern void do_cmd_macros(void); -extern void do_cmd_visuals(void); -extern void do_cmd_colors(void); -extern void do_cmd_note(void); -extern void do_cmd_version(void); -extern void do_cmd_feeling(void); -extern void do_cmd_load_screen(void); -extern void do_cmd_save_screen(void); -extern void do_cmd_knowledge(void); -extern void do_cmd_checkquest(void); -extern void do_cmd_change_tactic(int i); -extern void do_cmd_change_movement(int i); -extern void do_cmd_time(void); -extern void do_cmd_options_aux(int page, cptr info, bool_ read_only); +void macro_recorder_start(); +void macro_recorder_add(char c); +void macro_recorder_stop(); +void do_cmd_macro_recorder(); +void do_cmd_redraw(); +void do_cmd_change_name(); +void do_cmd_message_one(); +void do_cmd_messages(); +void do_cmd_options(); +void do_cmd_pref(); +void do_cmd_macros(); +void do_cmd_visuals(); +void do_cmd_colors(); +void do_cmd_note(); +void do_cmd_version(); +void do_cmd_feeling(); +void do_cmd_load_screen(); +void do_cmd_save_screen(); +void do_cmd_knowledge(); +void do_cmd_checkquest(); +void do_cmd_change_tactic(int i); +void do_cmd_change_movement(int i); +void do_cmd_time(); +void do_cmd_options_aux(int page, cptr info, bool_ read_only); diff --git a/src/cmd5.cc b/src/cmd5.cc index a1dd5cbf..a93759b0 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,11 +12,16 @@ #include "cave.hpp" #include "cave_type.hpp" #include "corrupt.hpp" +#include "dungeon_flag.hpp" +#include "game.hpp" #include "lua_bind.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_type.hpp" #include "player_class.hpp" #include "player_race.hpp" @@ -35,7 +40,6 @@ #include "util.h" #include "variable.h" #include "variable.hpp" -#include "quark.hpp" #include "wizard2.hpp" #include "xtra1.hpp" #include "xtra2.hpp" @@ -69,7 +73,7 @@ static object_filter_t const &hook_school_spellable() static auto instance = Or( is_school_book(), And( - HasFlag5(TR5_SPELL_CONTAIN), + HasFlags(TR_SPELL_CONTAIN), has_pval2)); return instance; } @@ -221,22 +225,21 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) * and in the dark, primarily to allow browsing in stores. */ -extern void do_cmd_browse_aux(object_type *o_ptr) +void do_cmd_browse_aux(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); if (is_school_book()(o_ptr)) { browse_school_spell(o_ptr->sval, o_ptr->pval, o_ptr); } - else if (f5 & TR5_SPELL_CONTAIN && o_ptr->pval2 != -1) + else if ((flags & TR_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) { browse_school_spell(255, o_ptr->pval2, o_ptr); } } -void do_cmd_browse(void) +void do_cmd_browse() { /* Get an item */ int item; @@ -283,8 +286,10 @@ static void do_poly_wounds() } } -void do_poly_self(void) +void do_poly_self() { + auto const &race_info = game->edit_data.race_info; + int power = p_ptr->lev; int poly_power; @@ -298,25 +303,6 @@ void do_poly_self(void) /* Some form of racial polymorph... */ power -= 10; - if ((power > rand_int(5)) && (rand_int(4) == 0)) - { - /* sex change */ - power -= 2; - - if (p_ptr->psex == SEX_MALE) - { - p_ptr->psex = SEX_FEMALE; - sp_ptr = &sex_info[p_ptr->psex]; - strcpy(effect_msg, "female"); - } - else - { - p_ptr->psex = SEX_MALE; - sp_ptr = &sex_info[p_ptr->psex]; - strcpy(effect_msg, "male"); - } - } - if ((power > rand_int(30)) && (rand_int(5) == 0)) { int tmp = 0; @@ -328,14 +314,14 @@ void do_poly_self(void) { if ( rand_int(2) == 0) { - (void)dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); + dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); power -= 1; } tmp++; } /* Deformities are discriminated against! */ - (void)dec_stat(A_CHR, randint(6), TRUE); + dec_stat(A_CHR, randint(6), TRUE); if (effect_msg[0]) { @@ -374,34 +360,34 @@ void do_poly_self(void) /* Roll until an appropriate selection is made */ while (1) { - new_race = rand_int(max_rp_idx); - expfact = race_info[new_race].r_exp; + new_race = rand_int(race_info.size()); + expfact = race_info[new_race].ps.exp; - if ((new_race != p_ptr->prace) && (expfact <= goalexpfact)) break; + if ((new_race != p_ptr->prace) && (expfact <= goalexpfact)) + { + break; + } } if (effect_msg[0]) { msg_format("You turn into a%s %s!", - ((is_a_vowel(*race_info[new_race].title)) ? "n" : ""), - race_info[new_race].title); + (is_a_vowel(race_info[new_race].title[0]) ? "n" : ""), + race_info[new_race].title.c_str()); } else { msg_format("You turn into a %s %s!", effect_msg, - race_info[new_race].title); + race_info[new_race].title.c_str()); } p_ptr->prace = new_race; rp_ptr = &race_info[p_ptr->prace]; /* Experience factor */ - p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp; - - /* Calculate the height/weight */ - get_height_weight(); - + p_ptr->expfact = rp_ptr->ps.exp + rmp_ptr->ps.exp + cp_ptr->ps.exp; + /* Level up if necessary */ check_experience(); p_ptr->max_plv = p_ptr->lev; @@ -423,7 +409,7 @@ void do_poly_self(void) msg_print("Your internal organs are rearranged!"); while (tmp < 6) { - (void)dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); + dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); tmp++; } if (rand_int(6) == 0) @@ -552,179 +538,141 @@ void fetch(int dir, int wgt, bool_ require_los) /* - * Handle random effects of player shrieking - */ -void shriek_effect() -{ - switch (randint(9)) - { - case 1: - case 5: - case 8: - case 9: - { - msg_print("You make a high-pitched shriek!"); - aggravate_monsters(1); - - break; - } - case 2: - case 6: - { - msg_print("Oops! You call a monster."); - summon_specific(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0); - - break; - } - case 3: - case 7: - { - msg_print("The dungeon collapses!"); - earthquake(p_ptr->py, p_ptr->px, 5); - - break; - } - case 4: - { - msg_print("Your shriek is so horrible that you damage your health!"); - take_hit(damroll(p_ptr->lev / 5, 8), "inner hemorrhaging"); - - break; - } - } -} - -/* * Return the symbiote's name or description. */ -cptr symbiote_name(bool_ capitalize) +std::string symbiote_name(bool capitalize) { + auto const &r_info = game->edit_data.r_info; + object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY]; - static char buf[80]; - /* Make sure there actually is a symbiote there... */ + std::string buf; + buf.reserve(32); + + // Fallback; shouldn't ever be necessary if (!o_ptr->k_idx) { - strcpy(buf, "A non-existent symbiote"); + buf += "A non-existent symbiote"; } else { - monster_race *r_ptr = &r_info[o_ptr->pval]; - cptr s = NULL; + auto r_ptr = &r_info[o_ptr->pval]; + std::size_t i = 0; - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { - /* Unique monster; no preceding "your", and ignore our name. */ - strncpy(buf, r_ptr->name, sizeof(buf)); + // Unique monster; no preceding "your" and ignore name + buf += r_ptr->name; } - else if (o_ptr->note && - (s = strstr(quark_str(o_ptr->note), "#named ")) != NULL) + else if ((i = o_ptr->inscription.find("#named ")) != std::string::npos) { - /* We've named it. */ - strncpy(buf, s + 7, sizeof(buf)); + // We've named it; extract the name */ + buf += o_ptr->inscription.substr(i); } else { - /* No special cases, just return "Your <monster type>". */ - strcpy(buf, "your "); - strncpy(buf + 5, r_ptr->name, sizeof(buf) - 5); + // No special cases; just return "Your <monster type>". + buf += "your "; + buf += r_ptr->name; } } - /* Just in case... */ - buf[sizeof(buf) - 1] = '\0'; - if (capitalize) buf[0] = toupper(buf[0]); + // Capitalize? + if (capitalize) + { + buf[0] = toupper(buf[0]); + } + + // Done return buf; } + /* - * Use a power of the monster in symbiosis + * Find monster power */ -int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost) +monster_power const *lookup_monster_power(std::size_t idx) { - int power = -1; - - int num = 0, dir = 0 , i; - - int powers[96]; - - bool_ flag; - - int ask, plev = p_ptr->lev; - - char choice; - - char out_val[160]; - - monster_race *r_ptr = &r_info[r_idx]; - - int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); - - int x = p_ptr->px, y = p_ptr->py, k; - - int rad; - - int label; - - - /* List the monster powers -- RF4_* */ - for (i = 0; i < 32; i++) + for (auto const &p: monster_powers) { - if (r_ptr->flags4 & BIT(i)) + if (p.monster_spell_index == idx) { - if (monster_powers[i].great && (!great)) continue; - if (!monster_powers[i].power) continue; - powers[num++] = i; + return &p; } } + return nullptr; +} - /* List the monster powers -- RF5_* */ - for (i = 0; i < 32; i++) - { - if (r_ptr->flags5 & BIT(i)) - { - if (monster_powers[i + 32].great && (!great)) continue; - if (!monster_powers[i + 32].power) continue; - powers[num++] = i + 32; - } - } - /* List the monster powers -- RF6_* */ - for (i = 0; i < 32; i++) +/* + * Extract powers + */ +std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great) +{ + std::vector<monster_power const *> powers; + powers.reserve(MONSTER_POWERS_MAX); + + for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++) { - if (r_ptr->flags6 & BIT(i)) + if (r_ptr->spells.bit(i)) { - if (monster_powers[i + 64].great && (!great)) continue; - if (!monster_powers[i + 64].power) continue; - powers[num++] = i + 64; + if (auto power = lookup_monster_power(i)) + { + if (power->great && (!great)) + { + continue; + } + powers.push_back(power); + } } } + return powers; +} + +/** + * Calculate mana required for a given monster power. + */ +static int calc_monster_spell_mana(monster_power const *mp_ptr) +{ + int mana = mp_ptr->mana / 10; + if (mana > p_ptr->msp) mana = p_ptr->msp; + if (!mana) mana = 1; + return mana; +} + +/** + * Choose a monster power + */ +static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool great, bool symbiosis) +{ + /* Extract available monster powers */ + auto powers = extract_monster_powers(r_ptr, great); + int const num = powers.size(); // Avoid signed/unsigned warnings + if (!num) { msg_print("You have no powers you can use."); - return (0); + return std::make_tuple(0, num); } - if (only_number) return (num); - - /* Nothing chosen yet */ - flag = FALSE; - /* Get the last label */ - label = (num <= 26) ? I2A(num - 1) : I2D(num - 1 - 26); + int label = (num <= 26) ? I2A(num - 1) : I2D(num - 1 - 26); /* Build a prompt (accept all spells) */ /* Mega Hack -- if no_cost is false, we're actually a Possessor -dsb */ + char out_val[160]; strnfmt(out_val, 78, "(Powers a-%c, ESC=exit) Use which power of your %s? ", - label, (no_cost ? "symbiote" : "body")); + label, (symbiosis ? "symbiote" : "body")); /* Save the screen */ character_icky = TRUE; Term_save(); /* Get a spell from the user */ + monster_power const *power = nullptr; + bool_ flag = FALSE; // Nothing chosen yet while (!flag) { /* Show the list */ @@ -732,26 +680,26 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost byte y = 1, x = 0; int ctr = 0; char dummy[80]; - strcpy(dummy, ""); prt ("", y++, x); while (ctr < num) { - monster_power *mp_ptr = &monster_powers[powers[ctr]]; - int mana = mp_ptr->mana / 10; - - if (mana > p_ptr->msp) mana = p_ptr->msp; - - if (!mana) mana = 1; + monster_power const *mp_ptr = powers[ctr]; label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26); - if (!no_cost) + byte color = TERM_L_GREEN; + if (!symbiosis) { + int mana = calc_monster_spell_mana(mp_ptr); strnfmt(dummy, 80, " %c) %2d %s", label, mana, mp_ptr->name); + // Gray out if player doesn't have enough mana to cast. + if (mana > p_ptr->csp) { + color = TERM_L_DARK; + } } else { @@ -761,11 +709,11 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost if (ctr < 17) { - prt(dummy, y + ctr, x); + c_prt(color, dummy, y + ctr, x); } else { - prt(dummy, y + ctr - 17, x + 40); + c_prt(color, dummy, y + ctr - 17, x + 40); } ctr++; @@ -781,6 +729,7 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost } } + char choice; if (!get_com(out_val, &choice)) { flag = FALSE; @@ -792,6 +741,8 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost choice = 'a'; } + int i; + int ask; if (isalpha(choice)) { /* Note verify */ @@ -818,16 +769,26 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost continue; } - /* Save the spell index */ + /* Save the spell */ power = powers[i]; + /* Make sure it's actually possible for the player to cast */ + if (!symbiosis) + { + if (p_ptr->csp < calc_monster_spell_mana(power)) + { + bell(); + continue; + } + } + /* Verify it */ if (ask) { char tmp_val[160]; /* Prompt */ - strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name); + strnfmt(tmp_val, 78, "Use %s? ", power->name); /* Belay that order */ if (!get_check(tmp_val)) continue; @@ -842,55 +803,60 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost character_icky = FALSE; /* Abort if needed */ - if (!flag) + if (!flag || (power == nullptr)) { - energy_use = 0; - return -1; + return std::make_tuple(-1, num); } - /* 'Powerful' monsters have wider radii */ - if (r_ptr->flags2 & RF2_POWERFUL) - { - rad = 1 + (p_ptr->lev / 15); - } - else - { - rad = 1 + (p_ptr->lev / 20); - } + return std::make_tuple(power->monster_spell_index, num); +} + +/* + * Apply the effect of a monster power + */ +static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_spell_idx) +{ + assert(monster_spell_idx < monster_spell_flag_set::nbits); + + /* Shorthand */ + int const x = p_ptr->px; + int const y = p_ptr->py; + int const plev = p_ptr->lev; + int const rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); + + /* 'Powerful' monsters have wider radii */ + int rad = (r_ptr->flags & RF_POWERFUL) + ? 1 + (p_ptr->lev / 15) + : 1 + (p_ptr->lev / 20); /* Analyse power */ - switch (power) + switch (monster_spell_idx) { - /**** RF4 (bit position) ****/ - - /* SHRIEK */ - case 0: + case SF_SHRIEK_IDX: { aggravate_monsters( -1); break; } - /* MULTIPLY */ - case 1: + case SF_MULTIPLY_IDX: { do_cmd_wiz_named_friendly(p_ptr->body_monster, FALSE); break; } - /* S_ANIMAL */ - case 2: + case SF_S_ANIMAL_IDX: { summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); break; } - /* ROCKET */ - case 3: + case SF_ROCKET_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ROCKET, dir, p_ptr->lev * 12, 1 + (p_ptr->lev / 20)); @@ -898,9 +864,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_1 */ - case 4: + case SF_ARROW_1_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(1, 6)); @@ -908,9 +874,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_2 */ - case 5: + case SF_ARROW_2_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(3, 6)); @@ -918,9 +884,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_3 */ - case 6: + case SF_ARROW_3_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(5, 6)); @@ -928,9 +894,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_4 */ - case 7: + case SF_ARROW_4_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(7, 6)); @@ -938,9 +904,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_ACID */ - case 8: + case SF_BR_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ACID, dir, p_ptr->lev * 5, rad); @@ -948,9 +914,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_ELEC */ - case 9: + case SF_BR_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ELEC, dir, p_ptr->lev * 5, rad); @@ -958,9 +924,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_FIRE */ - case 10: + case SF_BR_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FIRE, dir, p_ptr->lev * 5, rad); @@ -968,9 +934,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_COLD */ - case 11: + case SF_BR_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_COLD, dir, p_ptr->lev * 5, rad); @@ -978,9 +944,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_POIS */ - case 12: + case SF_BR_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_POIS, dir, p_ptr->lev * 5, rad); @@ -988,9 +954,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NETH */ - case 13: + case SF_BR_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NETHER, dir, p_ptr->lev * 5, rad); @@ -998,9 +964,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_LITE */ - case 14: + case SF_BR_LITE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_LITE, dir, p_ptr->lev * 8, rad); @@ -1008,9 +974,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DARK */ - case 15: + case SF_BR_DARK_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DARK, dir, p_ptr->lev * 8, rad); @@ -1018,9 +984,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_CONF */ - case 16: + case SF_BR_CONF_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CONFUSION, dir, p_ptr->lev * 8, rad); @@ -1028,9 +994,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_SOUN */ - case 17: + case SF_BR_SOUN_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_SOUND, dir, p_ptr->lev * 8, rad); @@ -1038,9 +1004,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_CHAO */ - case 18: + case SF_BR_CHAO_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CHAOS, dir, p_ptr->lev * 7, rad); @@ -1048,9 +1014,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DISE */ - case 19: + case SF_BR_DISE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DISENCHANT, dir, p_ptr->lev * 7, rad); @@ -1058,9 +1024,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NEXU */ - case 20: + case SF_BR_NEXU_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NEXUS, dir, p_ptr->lev * 5, rad); @@ -1068,9 +1034,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_TIME */ - case 21: + case SF_BR_TIME_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_TIME, dir, p_ptr->lev * 3, rad); @@ -1078,9 +1044,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_INER */ - case 22: + case SF_BR_INER_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_INERTIA, dir, p_ptr->lev * 4, rad); @@ -1088,9 +1054,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_GRAV */ - case 23: + case SF_BR_GRAV_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_GRAVITY, dir, p_ptr->lev * 4, rad); @@ -1098,9 +1064,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_SHAR */ - case 24: + case SF_BR_SHAR_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_SHARDS, dir, p_ptr->lev * 8, rad); @@ -1108,9 +1074,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_PLAS */ - case 25: + case SF_BR_PLAS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_PLASMA, dir, p_ptr->lev * 3, rad); @@ -1118,9 +1084,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_WALL */ - case 26: + case SF_BR_WALL_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FORCE, dir, p_ptr->lev * 4, rad); @@ -1128,9 +1094,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_MANA */ - case 27: + case SF_BR_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_MANA, dir, p_ptr->lev * 5, rad); @@ -1138,9 +1104,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_NUKE */ - case 28: + case SF_BA_NUKE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); @@ -1148,9 +1114,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NUKE */ - case 29: + case SF_BR_NUKE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); @@ -1158,9 +1124,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_CHAO */ - case 30: + case SF_BA_CHAO_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CHAOS, dir, p_ptr->lev * 4, 2); @@ -1168,9 +1134,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DISI */ - case 31: + case SF_BR_DISI_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DISINTEGRATE, dir, p_ptr->lev * 5, 1 + (p_ptr->lev / 20)); @@ -1178,12 +1144,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - - /**** RF5 (bit position + 32) ****/ - - /* BA_ACID */ - case 32: + case SF_BA_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ACID, dir, randint(p_ptr->lev * 6) + 20, 2); @@ -1191,9 +1154,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_ELEC */ - case 33: + case SF_BA_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ELEC, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1201,9 +1164,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_FIRE */ - case 34: + case SF_BA_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FIRE, dir, randint(p_ptr->lev * 7) + 20, 2); @@ -1211,9 +1174,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_COLD */ - case 35: + case SF_BA_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_COLD, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1221,9 +1184,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_POIS */ - case 36: + case SF_BA_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_POIS, dir, damroll(12, 2), 2); @@ -1231,9 +1194,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_NETH */ - case 37: + case SF_BA_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NETHER, dir, randint(p_ptr->lev * 4) + 20, 2); @@ -1241,9 +1204,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_WATE */ - case 38: + case SF_BA_WATE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_WATER, dir, randint(p_ptr->lev * 4) + 20, 2); @@ -1251,9 +1214,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_MANA */ - case 39: + case SF_BA_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_MANA, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1261,9 +1224,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_DARK */ - case 40: + case SF_BA_DARK_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DARK, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1271,15 +1234,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* 41 DRAIN_MANA -- Not available */ - - /* 42 MIND_BLAST -- Not available */ - - /* 43 BRAIN_SMASH -- Not available */ - - /* CAUSE_1 */ - case 44: + case SF_CAUSE_1_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(3, 8)); @@ -1287,9 +1244,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_2 */ - case 45: + case SF_CAUSE_2_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(8, 8)); @@ -1297,9 +1254,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_3 */ - case 46: + case SF_CAUSE_3_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(10, 15)); @@ -1307,9 +1264,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_4 */ - case 47: + case SF_CAUSE_4_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(15, 15)); @@ -1317,9 +1274,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ACID */ - case 48: + case SF_BO_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ACID, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1327,9 +1284,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ELEC */ - case 49: + case SF_BO_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ELEC, dir, damroll(4, 8) + (p_ptr->lev / 3)); @@ -1337,9 +1294,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_FIRE */ - case 50: + case SF_BO_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_FIRE, dir, damroll(9, 8) + (p_ptr->lev / 3)); @@ -1347,9 +1304,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_COLD */ - case 51: + case SF_BO_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_COLD, dir, damroll(6, 8) + (p_ptr->lev / 3)); @@ -1357,9 +1314,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_POIS */ - case 52: + case SF_BO_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_POIS, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1367,9 +1324,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_NETH */ - case 53: + case SF_BO_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_NETHER, dir, damroll(5, 5) + (p_ptr->lev / 3)); @@ -1377,9 +1334,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_WATE */ - case 54: + case SF_BO_WATE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_WATER, dir, damroll(10, 10) + (p_ptr->lev / 3)); @@ -1387,9 +1344,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_MANA */ - case 55: + case SF_BO_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(3, 8) + (p_ptr->lev / 3)); @@ -1397,9 +1354,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_PLAS */ - case 56: + case SF_BO_PLAS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_PLASMA, dir, damroll(8, 8) + (p_ptr->lev / 3)); @@ -1407,9 +1364,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ICEE */ - case 57: + case SF_BO_ICEE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ICE, dir, damroll(6, 6) + (p_ptr->lev / 3)); @@ -1417,9 +1374,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* MISSILE */ - case 58: + case SF_MISSILE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MISSILE, dir, damroll(2, 6) + (p_ptr->lev / 3)); @@ -1427,9 +1384,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* SCARE */ - case 59: + case SF_SCARE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fear_monster(dir, plev); @@ -1437,9 +1394,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BLIND */ - case 60: + case SF_BLIND_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_CONFUSION, dir, damroll(1, 8) + (p_ptr->lev / 3)); @@ -1447,9 +1404,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CONF */ - case 61: + case SF_CONF_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_CONFUSION, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1457,9 +1414,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* SLOW */ - case 62: + case SF_SLOW_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_OLD_SLOW, dir, damroll(6, 8) + (p_ptr->lev / 3)); @@ -1467,9 +1424,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* HOLD */ - case 63: + case SF_HOLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_OLD_SLEEP, dir, damroll(5, 8) + (p_ptr->lev / 3)); @@ -1477,27 +1434,23 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - - /**** RF6 (bit position + 64) ****/ - - /* HASTE */ - case 64: + case SF_HASTE_IDX: { if (!p_ptr->fast) { - (void)set_fast(randint(20 + (plev) ) + plev, 10); + set_fast(randint(20 + (plev) ) + plev, 10); } else { - (void)set_fast(p_ptr->fast + randint(5), 10); + set_fast(p_ptr->fast + randint(5), 10); } break; } - /* HAND_DOOM */ - case 65: + case SF_HAND_DOOM_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(10, 8) + (p_ptr->lev)); @@ -1505,18 +1458,16 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* HEAL */ - case 66: + case SF_HEAL_IDX: { hp_player(damroll(8, 5)); break; } - /* S_ANIMALS */ - case 67: + case SF_S_ANIMALS_IDX: { - for (k = 0; k < 4; k++) + for (int k = 0; k < 4; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); } @@ -1524,10 +1475,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BLINK */ - case 68: + case SF_BLINK_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1538,10 +1488,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TPORT */ - case 69: + case SF_TPORT_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1552,12 +1501,11 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TELE_TO */ - case 70: + case SF_TELE_TO_IDX: { int ii, ij; - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1570,8 +1518,8 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost p_ptr->energy -= 60 - plev; if (!cave_empty_bold(ij, ii) || - (cave[ij][ii].info & CAVE_ICKY) || - (distance(ij, ii, p_ptr->py, p_ptr->px) > plev * 20 + 2)) + (cave[ij][ii].info & CAVE_ICKY) || + (distance(ij, ii, p_ptr->py, p_ptr->px) > plev * 20 + 2)) { msg_print("You fail to show the destination correctly!"); p_ptr->energy -= 100; @@ -1582,26 +1530,25 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TELE_AWAY */ - case 71: + case SF_TELE_AWAY_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; } + int dir; if (!get_aim_dir(&dir)) break; - (void)fire_beam(GF_AWAY_ALL, dir, plev); + fire_beam(GF_AWAY_ALL, dir, plev); break; } - /* TELE_LEVEL */ - case 72: + case SF_TELE_LEVEL_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1612,11 +1559,10 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* DARKNESS */ - case 73: + case SF_DARKNESS_IDX: { - (void)project( -1, 3, p_ptr->py, p_ptr->px, 0, GF_DARK_WEAK, - PROJECT_GRID | PROJECT_KILL); + project( -1, 3, p_ptr->py, p_ptr->px, 0, GF_DARK_WEAK, + PROJECT_GRID | PROJECT_KILL); /* Unlite the room */ unlite_room(p_ptr->py, p_ptr->px); @@ -1624,34 +1570,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TRAPS */ - case 74: + case SF_S_THUNDERLORD_IDX: { - trap_creation(); - - break; - } - - /* 75 FORGET -- Not available */ - - /* ANIM_DEAD -- Use the same code as the nether spell */ - case 76: - { - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_RAISE, dir, 1, 0); - - break; - } - - /* 77 S_BUG -- Not available, well we do that anyway ;) */ - - /* 78 S_RNG -- Not available, who dares? */ - - /* S_THUNDERLORD */ - case 79: - { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, TRUE); } @@ -1659,13 +1580,12 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_KIN -- Summon Kin, because we code bugs :) */ - case 80: + case SF_S_KIN_IDX: { /* Big hack */ summon_kin_type = r_ptr->d_char; - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_KIN, TRUE); } @@ -1673,10 +1593,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_DEMON */ - case 81: + case SF_S_HI_DEMON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, TRUE); } @@ -1684,10 +1603,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_MONSTER */ - case 82: + case SF_S_MONSTER_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, 0, TRUE); } @@ -1695,10 +1613,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_MONSTERS */ - case 83: + case SF_S_MONSTERS_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, 0, TRUE); } @@ -1706,10 +1623,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_ANT */ - case 84: + case SF_S_ANT_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANT, TRUE); } @@ -1717,10 +1633,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_SPIDER */ - case 85: + case SF_S_SPIDER_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, TRUE); } @@ -1728,10 +1643,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HOUND */ - case 86: + case SF_S_HOUND_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HOUND, TRUE); } @@ -1739,10 +1653,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HYDRA */ - case 87: + case SF_S_HYDRA_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, TRUE); } @@ -1750,10 +1663,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_ANGEL */ - case 88: + case SF_S_ANGEL_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, TRUE); } @@ -1761,10 +1673,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_DEMON */ - case 89: + case SF_S_DEMON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_DEMON, TRUE); } @@ -1772,10 +1683,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_UNDEAD */ - case 90: + case SF_S_UNDEAD_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, TRUE); } @@ -1783,10 +1693,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_DRAGON */ - case 91: + case SF_S_DRAGON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, TRUE); } @@ -1794,10 +1703,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_UNDEAD */ - case 92: + case SF_S_HI_UNDEAD_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE); } @@ -1805,10 +1713,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_DRAGON */ - case 93: + case SF_S_HI_DRAGON_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, TRUE); } @@ -1816,38 +1723,43 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_WRAITH */ - case 94: + case SF_S_WRAITH_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_WRAITH, TRUE); } break; } - - /* 95 S_UNIQUE -- Not available */ } +} - /* Take some SP */ - if (!no_cost) - { - int chance, pchance; - - chance = (monster_powers[power].mana + r_ptr->level); - pchance = adj_str_wgt[p_ptr->stat_ind[A_WIS]] / 2 + get_skill(SKILL_POSSESSION); - if (rand_int(chance) >= pchance) - { - int m = monster_powers[power].mana / 10; +/* + * Use a monster power and call the given callback. + */ +static int use_monster_power_aux(monster_race const *r_ptr, bool great, bool symbiosis, std::function<void(monster_power const *power)> f) +{ + int power; + int num; + std::tie(power, num) = choose_monster_power(r_ptr, great, symbiosis); + + // Early exit? + if (power == 0) { + // No powers available + return 0; + } else if (power < 0) { + // Canceled by user + energy_use = 0; + return -1; + } - if (m > p_ptr->msp) m = p_ptr->msp; - if (!m) m = 1; + // Apply the effect + apply_monster_power(r_ptr, power); - p_ptr->csp -= m; - } - } + // Post-processing + f(&monster_powers[power]); /* Redraw mana */ p_ptr->redraw |= (PR_FRAME); @@ -1858,6 +1770,38 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost return (num); } +/** + * Use a power of the monster in symbiosis + */ +int use_symbiotic_power(int r_idx, bool great) +{ + auto const &r_info = game->edit_data.r_info; + + monster_race const *r_ptr = &r_info[r_idx]; + return use_monster_power_aux(r_ptr, great, true, [](monster_power const *) { + // Don't need to do anything post-cast. + }); +} + +/** + * Use a power of a possessed body. + */ +void use_monster_power(int r_idx, bool great) +{ + auto const &r_info = game->edit_data.r_info; + + monster_race const *r_ptr = &r_info[r_idx]; + use_monster_power_aux(r_ptr, great, false, [r_ptr](monster_power const *power) { + // Sometimes give a free cast. + int chance = (power->mana + r_ptr->level); + int pchance = adj_str_wgt[p_ptr->stat_ind[A_WIS]] / 2 + get_skill(SKILL_POSSESSION); + if (rand_int(chance) >= pchance) + { + p_ptr->csp -= calc_monster_spell_mana(power); + } + }); +} + /* * Schooled magic */ @@ -1888,11 +1832,10 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &) object_type *o_ptr = &p_ptr->inventory[i]; /* Extract object flags */ - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Must we wield it to cast from it? */ - if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) + if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (flags & TR_WIELD_CAST)) { continue; } @@ -1901,7 +1844,7 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &) if (!is_school_book()(o_ptr)) { /* Does it contain the appropriate spell? */ - if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) + if ((flags & TR_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) { hack_force_spell = spell; hack_force_spell_pval = o_ptr->pval; @@ -1961,7 +1904,6 @@ s32b get_school_spell(cptr do_what, s16b force_book) object_type *o_ptr, forge; int tmp; int sval, pval; - u32b f1, f2, f3, f4, f5, esp; hack_force_spell = -1; hack_force_spell_pval = -1; @@ -1987,10 +1929,10 @@ s32b get_school_spell(cptr do_what, s16b force_book) /* Get the item */ o_ptr = get_object(item); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); /* If it can be wielded, it must */ - if ((wield_slot(o_ptr) != -1) && (item < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) + if ((wield_slot(o_ptr) != -1) && (item < INVEN_WIELD) && (f & TR_WIELD_CAST)) { msg_format("You cannot %s from that object; it must be wielded first.", do_what); return -1; @@ -2178,10 +2120,9 @@ void cast_school_spell() /* Can it contains a schooled spell ? */ static bool hook_school_can_spellable(object_type const *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); - return ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1)); + return ((f & TR_SPELL_CONTAIN) && (o_ptr->pval2 == -1)); } /* diff --git a/src/cmd5.hpp b/src/cmd5.hpp index 1b3b062a..d25efb73 100644 --- a/src/cmd5.hpp +++ b/src/cmd5.hpp @@ -2,15 +2,22 @@ #include "h-basic.h" #include "object_type_fwd.hpp" +#include "monster_race_fwd.hpp" +#include "monster_power_fwd.hpp" -extern bool_ is_magestaff(void); -extern void do_cmd_browse_aux(object_type *o_ptr); -extern void do_cmd_browse(void); -extern void fetch(int dir, int wgt, bool_ require_los); -extern void do_poly_self(void); -extern cptr symbiote_name(bool_ capitalize); -extern int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost); -extern bool_ is_ok_spell(s32b spell_idx, s32b pval); -extern s32b get_school_spell(cptr do_what, s16b force_book); -extern void do_cmd_copy_spell(void); -extern void cast_school_spell(void); +#include <string> +#include <vector> + +bool_ is_magestaff(); +void do_cmd_browse_aux(object_type *o_ptr); +void do_cmd_browse(); +void fetch(int dir, int wgt, bool_ require_los); +void do_poly_self(); +std::string symbiote_name(bool capitalize); +int use_symbiotic_power(int r_idx, bool great); +void use_monster_power(int r_idx, bool great); +bool_ is_ok_spell(s32b spell_idx, s32b pval); +s32b get_school_spell(cptr do_what, s16b force_book); +void do_cmd_copy_spell(); +void cast_school_spell(); +std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great); diff --git a/src/cmd6.cc b/src/cmd6.cc index 0a5595fa..e36f0cb6 100644 --- a/src/cmd6.cc +++ b/src/cmd6.cc @@ -14,9 +14,11 @@ #include "cmd1.hpp" #include "cmd7.hpp" #include "corrupt.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "ego_item_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hook_eat_in.hpp" #include "hook_eat_out.hpp" #include "hooks.hpp" @@ -24,12 +26,16 @@ #include "mimic.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 "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" +#include "player_race_flag.hpp" #include "player_type.hpp" #include "randart.hpp" #include "skills.hpp" @@ -55,12 +61,6 @@ using boost::algorithm::iequals; /* - * Forward declare - */ -static bool_ activate_spell(object_type * o_ptr, byte choice); - - -/* * General function to find an item by its name */ static select_by_name_t select_object_by_name(std::string const &prompt) @@ -148,7 +148,9 @@ static select_by_name_t select_object_by_name(std::string const &prompt) */ static void corpse_effect(object_type *o_ptr, bool_ cutting) { - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[o_ptr->pval2]; /* Assume no bad effects */ bool_ harmful = FALSE; @@ -538,7 +540,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) */ /* Acid */ - if (r_ptr->flags4 & RF4_BR_ACID && brpow > 0) + if ((r_ptr->spells & SF_BR_ACID) && brpow > 0) { brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); @@ -553,13 +555,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } o_ptr->pval = 1; } - else if (r_ptr->flags4 & RF4_BR_ACID) + else if (r_ptr->spells & SF_BR_ACID) { set_oppose_acid(p_ptr->oppose_acid + rand_int(10) + 10); } /* Electricity */ - if (r_ptr->flags4 & RF4_BR_ELEC && brpow > 0) + if ((r_ptr->spells & SF_BR_ELEC) && brpow > 0) { brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); @@ -575,13 +577,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) o_ptr->weight = o_ptr->weight - brpow; o_ptr->pval = o_ptr->weight; } - else if (r_ptr->flags4 & RF4_BR_ELEC) + else if (r_ptr->spells & SF_BR_ELEC) { set_oppose_elec(p_ptr->oppose_elec + rand_int(10) + 10); } /* Fire */ - if (r_ptr->flags4 & RF4_BR_FIRE && brpow > 0) + if ((r_ptr->spells & SF_BR_FIRE) && brpow > 0) { brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); @@ -596,13 +598,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } o_ptr->pval = 1; } - else if (r_ptr->flags4 & RF4_BR_FIRE) + else if (r_ptr->spells & SF_BR_FIRE) { set_oppose_fire(p_ptr->oppose_fire + rand_int(10) + 10); } /* Cold */ - if (r_ptr->flags4 & RF4_BR_COLD && brpow > 0) + if ((r_ptr->spells & SF_BR_COLD) && brpow > 0) { brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); @@ -618,13 +620,13 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) o_ptr->weight = o_ptr->weight - brpow; o_ptr->pval = o_ptr->weight; } - else if (r_ptr->flags4 & RF4_BR_COLD) + else if (r_ptr->spells & SF_BR_COLD) { set_oppose_cold(p_ptr->oppose_cold + rand_int(10) + 10); } /* Poison */ - if (r_ptr->flags4 & RF4_BR_POIS && brpow > 0) + if ((r_ptr->spells & SF_BR_POIS) && brpow > 0) { brdam = ((brpow / 3) > 800 ? 800 : (brpow / 3)); @@ -636,7 +638,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { - (void)set_poisoned(p_ptr->poisoned + rand_int(brdam) + 10); + set_poisoned(p_ptr->poisoned + rand_int(brdam) + 10); } /* Take damage */ @@ -647,7 +649,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Nether */ - if (r_ptr->flags4 & RF4_BR_NETH && brpow > 0) + if ((r_ptr->spells & SF_BR_NETH) && brpow > 0) { brdam = ((brpow / 6) > 550 ? 550 : (brpow / 6)); @@ -684,7 +686,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Confusion */ - if (r_ptr->flags4 & RF4_BR_CONF && brpow > 0) + if ((r_ptr->spells & SF_BR_CONF) && brpow > 0) { msg_print("A strange liquid splashes on you!"); @@ -697,7 +699,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Chaos */ - if (r_ptr->flags4 & RF4_BR_CHAO && brpow > 0) + if ((r_ptr->spells & SF_BR_CHAO) && brpow > 0) { brdam = ((brpow / 6) > 600 ? 600 : (brpow / 6)); @@ -711,12 +713,12 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(20) + 10); + set_confused(p_ptr->confused + rand_int(20) + 10); } if (!p_ptr->resist_chaos) { - (void)set_image(p_ptr->image + randint(10)); + set_image(p_ptr->image + randint(10)); } if (!p_ptr->resist_neth && !p_ptr->resist_chaos) @@ -743,7 +745,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Disenchantment */ - if (r_ptr->flags4 & RF4_BR_DISE && brpow > 0) + if ((r_ptr->spells & SF_BR_DISE) && brpow > 0) { brdam = ((brpow / 6) > 500 ? 500 : (brpow / 6)); @@ -756,7 +758,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } else { - (void)apply_disenchant(0); + apply_disenchant(0); } /* Take damage */ @@ -765,7 +767,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Plasma */ - if (r_ptr->flags4 & RF4_BR_PLAS && brpow > 0) + if ((r_ptr->spells & SF_BR_PLAS) && brpow > 0) { brdam = ((brpow / 6) > 150 ? 150 : (brpow / 6)); @@ -777,7 +779,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) if (!p_ptr->resist_sound) { int k = (randint((brdam > 40) ? 35 : (brdam * 3 / 4 + 5))); - (void)set_stun(p_ptr->stun + k); + set_stun(p_ptr->stun + k); } /* Take damage */ @@ -787,7 +789,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) } /* Hack -- Jellies are immune to acid only if they are already acidic */ - if (strchr("j", r_ptr->d_char) && (r_ptr->flags3 & RF3_IM_ACID)) + if (strchr("j", r_ptr->d_char) && (r_ptr->flags & RF_IM_ACID)) { dam = damroll(8, 8); @@ -809,7 +811,7 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) * are immune to poison because their body already contains * poisonous chemicals. */ - if (strchr("ijkmS,", r_ptr->d_char) && (r_ptr->flags3 & RF3_IM_POIS)) + if (strchr("ijkmS,", r_ptr->d_char) && (r_ptr->flags & RF_IM_POIS)) { if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { @@ -824,82 +826,82 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) */ if (!harmful && !cutting && (o_ptr->sval != SV_CORPSE_MEAT)) { - if (r_ptr->flags3 & RF3_IM_ACID) + if (r_ptr->flags & RF_IM_ACID) { set_oppose_acid(p_ptr->oppose_acid + rand_int(10) + 10); } - if (r_ptr->flags3 & RF3_IM_ELEC) + if (r_ptr->flags & RF_IM_ELEC) { set_oppose_elec(p_ptr->oppose_elec + rand_int(10) + 10); } - if (r_ptr->flags3 & RF3_IM_FIRE) + if (r_ptr->flags & RF_IM_FIRE) { set_oppose_fire(p_ptr->oppose_fire + rand_int(10) + 10); } - if (r_ptr->flags3 & RF3_IM_COLD) + if (r_ptr->flags & RF_IM_COLD) { set_oppose_cold(p_ptr->oppose_cold + rand_int(10) + 10); } - if (r_ptr->flags3 & RF3_IM_POIS) + if (r_ptr->flags & RF_IM_POIS) { set_oppose_pois(p_ptr->oppose_pois + rand_int(10) + 10); } - if (r_ptr->flags3 & RF3_RES_NETH) + if (r_ptr->flags & RF_RES_NETH) { set_protevil(p_ptr->protevil + rand_int(25) + 3 * r_ptr->level); } - if (r_ptr->flags3 & RF3_RES_PLAS) + if (r_ptr->flags & RF_RES_PLAS) { set_oppose_fire(p_ptr->oppose_fire + rand_int(20) + 20); } - if (r_ptr->flags2 & RF2_SHAPECHANGER) + if (r_ptr->flags & RF_SHAPECHANGER) { - /* DGDGDG (void)set_mimic(20 , rand_int(MIMIC_VALAR)); */ + /* DGDGDG set_mimic(20 , rand_int(MIMIC_VALAR)); */ } - if (r_ptr->flags3 & RF3_DEMON) + if (r_ptr->flags & RF_DEMON) { - /* DGDGDG (void)set_mimic(30 , MIMIC_DEMON); */ + /* DGDGDG set_mimic(30 , MIMIC_DEMON); */ } - if (r_ptr->flags3 & RF3_UNDEAD) + if (r_ptr->flags & RF_UNDEAD) { - /* DGDGDG (void)set_mimic(30 , MIMIC_VAMPIRE); */ + /* DGDGDG set_mimic(30 , MIMIC_VAMPIRE); */ } - if (r_ptr->flags3 & RF3_NO_FEAR) + if (r_ptr->flags & RF_NO_FEAR) { - (void)set_afraid(0); + set_afraid(0); } - if (r_ptr->flags3 & RF3_NO_STUN) + if (r_ptr->flags & RF_NO_STUN) { - (void)set_stun(0); + set_stun(0); } - if (r_ptr->flags3 & RF3_NO_CONF) + if (r_ptr->flags & RF_NO_CONF) { - (void)set_confused(0); + set_confused(0); } - if (r_ptr->flags6 & RF6_S_THUNDERLORD) + if (r_ptr->spells & SF_S_THUNDERLORD) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_THUNDERLORD, FALSE); } - if (r_ptr->flags6 & RF6_S_DEMON) + if (r_ptr->spells & SF_S_DEMON) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE); } - if (r_ptr->flags6 & RF6_S_KIN) + if (r_ptr->spells & SF_S_KIN) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_KIN, FALSE); } - if (r_ptr->flags6 & RF6_S_HI_DEMON) + if (r_ptr->spells & SF_S_HI_DEMON) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DEMON, FALSE); } - if (r_ptr->flags6 & RF6_S_MONSTER) + if (r_ptr->spells & SF_S_MONSTER) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE); } - if (r_ptr->flags6 & RF6_S_MONSTERS) + if (r_ptr->spells & SF_S_MONSTERS) { int k; for (k = 0; k < 8; k++) @@ -907,47 +909,47 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting) summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE); } } - if (r_ptr->flags6 & RF6_S_UNDEAD) + if (r_ptr->spells & SF_S_UNDEAD) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE); } - if (r_ptr->flags6 & RF6_S_DRAGON) + if (r_ptr->spells & SF_S_DRAGON) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON, FALSE); } - if (r_ptr->flags6 & RF6_S_ANT) + if (r_ptr->spells & SF_S_ANT) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT, FALSE); } - if (r_ptr->flags6 & RF6_S_SPIDER) + if (r_ptr->spells & SF_S_SPIDER) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER, FALSE); } - if (r_ptr->flags6 & RF6_S_HOUND) + if (r_ptr->spells & SF_S_HOUND) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND, FALSE); } - if (r_ptr->flags6 & RF6_S_HYDRA) + if (r_ptr->spells & SF_S_HYDRA) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA, FALSE); } - if (r_ptr->flags6 & RF6_S_ANGEL) + if (r_ptr->spells & SF_S_ANGEL) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL, FALSE); } - if (r_ptr->flags6 & RF6_S_HI_DRAGON) + if (r_ptr->spells & SF_S_HI_DRAGON) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON, FALSE); } - if (r_ptr->flags6 & RF6_S_HI_UNDEAD) + if (r_ptr->spells & SF_S_HI_UNDEAD) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD, FALSE); } - if (r_ptr->flags6 & RF6_S_WRAITH) + if (r_ptr->spells & SF_S_WRAITH) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH, FALSE); } - if (r_ptr->flags6 & RF6_S_UNIQUE) + if (r_ptr->spells & SF_S_UNIQUE) { summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE, FALSE); } @@ -972,14 +974,15 @@ static object_filter_t const &item_tester_hook_eatable() /* * Eat some food (from the pack or floor) */ -void do_cmd_eat_food(void) +void do_cmd_eat_food() { + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + int ident, lev, fval = 0; object_type *q_ptr, forge; - monster_race *r_ptr; - bool_ destroy = TRUE; /* Get an item */ @@ -997,10 +1000,6 @@ void do_cmd_eat_food(void) /* Get the item */ object_type *o_ptr = get_object(item); - /* Sound */ - sound(SOUND_EAT); - - /* Take a turn */ energy_use = 100; @@ -1114,7 +1113,7 @@ void do_cmd_eat_food(void) case SV_FOOD_WEAKNESS: { take_hit(damroll(6, 6), "poisonous food"); - (void)do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_STR, STAT_DEC_NORMAL); ident = TRUE; @@ -1124,7 +1123,7 @@ void do_cmd_eat_food(void) case SV_FOOD_SICKNESS: { take_hit(damroll(6, 6), "poisonous food"); - (void)do_dec_stat(A_CON, STAT_DEC_NORMAL); + do_dec_stat(A_CON, STAT_DEC_NORMAL); ident = TRUE; @@ -1134,7 +1133,7 @@ void do_cmd_eat_food(void) case SV_FOOD_STUPIDITY: { take_hit(damroll(8, 8), "poisonous food"); - (void)do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); ident = TRUE; @@ -1144,7 +1143,7 @@ void do_cmd_eat_food(void) case SV_FOOD_NAIVETY: { take_hit(damroll(8, 8), "poisonous food"); - (void)do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); ident = TRUE; @@ -1154,7 +1153,7 @@ void do_cmd_eat_food(void) case SV_FOOD_UNHEALTH: { take_hit(damroll(10, 10), "poisonous food"); - (void)do_dec_stat(A_CON, STAT_DEC_NORMAL); + do_dec_stat(A_CON, STAT_DEC_NORMAL); ident = TRUE; @@ -1164,7 +1163,7 @@ void do_cmd_eat_food(void) case SV_FOOD_DISEASE: { take_hit(damroll(10, 10), "poisonous food"); - (void)do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_STR, STAT_DEC_NORMAL); ident = TRUE; @@ -1308,8 +1307,8 @@ void do_cmd_eat_food(void) case SV_FOOD_WAYBREAD: { msg_print("That tastes very good."); - (void)set_poisoned(0); - (void)hp_player(damroll(4, 8)); + set_poisoned(0); + hp_player(damroll(4, 8)); set_food(PY_FOOD_MAX - 1); ident = TRUE; @@ -1330,7 +1329,7 @@ void do_cmd_eat_food(void) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); break; } @@ -1339,9 +1338,9 @@ void do_cmd_eat_food(void) { msg_print("A fresh, clean essence rises, driving away wounds and poison."); - (void)set_poisoned(0); - (void)set_stun(0); - (void)set_cut(0); + set_poisoned(0); + set_stun(0); + set_cut(0); if (p_ptr->black_breath) { msg_print("The hold of the Black Breath on you is broken!"); @@ -1358,7 +1357,7 @@ void do_cmd_eat_food(void) /* Corpses... */ else { - r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; /* Analyse the corpse */ switch (o_ptr->sval) @@ -1370,7 +1369,7 @@ void do_cmd_eat_food(void) /* Not all is edible. Apologies if messy. */ /* Check weight -- they have to have some meat left */ - if (r_ptr->flags9 & RF9_DROP_SKELETON) + if (r_ptr->flags & RF_DROP_SKELETON) { if (o_ptr->weight <= (r_ptr->weight * 3) / 5) { @@ -1491,10 +1490,10 @@ void do_cmd_eat_food(void) /* Food can feed the player, in a different ways */ /* Vampires */ - if ((race_flags1_p(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))) + if ((race_flags_p(PR_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))) { /* Reduced nutritional benefit */ - /* (void)set_food(p_ptr->food + (fval / 10)); -- No more */ + /* set_food(p_ptr->food + (fval / 10)); -- No more */ msg_print("Mere victuals hold scant sustenance for a being such as yourself."); /* Hungry */ @@ -1504,9 +1503,9 @@ void do_cmd_eat_food(void) } } - else if (race_flags1_p(PR1_NO_FOOD)) + else if (race_flags_p(PR_NO_FOOD)) { - if (race_flags1_p(PR1_UNDEAD)) + if (race_flags_p(PR_UNDEAD)) { msg_print("The food of mortals is poor sustenance for you."); } @@ -1520,7 +1519,7 @@ void do_cmd_eat_food(void) /* Those living in fresh */ else { - (void)set_food(p_ptr->food + fval); + set_food(p_ptr->food + fval); } @@ -1535,8 +1534,10 @@ void do_cmd_eat_food(void) /* * Cut a corpse up for convenient storage */ -void do_cmd_cut_corpse(void) +void do_cmd_cut_corpse() { + auto const &r_info = game->edit_data.r_info; + int item, meat = 0, not_meat = 0; /* Get an item */ @@ -1552,7 +1553,7 @@ void do_cmd_cut_corpse(void) /* Get the item */ object_type *o_ptr = get_object(item); - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_HEAD)) { @@ -1564,7 +1565,7 @@ void do_cmd_cut_corpse(void) { case SV_CORPSE_CORPSE: { - if (r_ptr->flags9 & RF9_DROP_SKELETON) + if (r_ptr->flags & RF_DROP_SKELETON) { not_meat = (r_ptr->weight * 3) / 5; } @@ -1634,7 +1635,7 @@ void do_cmd_cut_corpse(void) * * Salt water works well. */ -void do_cmd_cure_meat(void) +void do_cmd_cure_meat() { int item, num, cure; @@ -1813,9 +1814,9 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) case SV_POTION_SALT_WATER: { msg_print("The potion makes you vomit!"); - (void)set_food(PY_FOOD_STARVE - 1); - (void)set_poisoned(0); - (void)set_paralyzed(4); + set_food(PY_FOOD_STARVE - 1); + set_poisoned(0); + set_paralyzed(4); ident = TRUE; break; @@ -1907,12 +1908,12 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) { msg_print("Your nerves and muscles feel weak and lifeless!"); take_hit(damroll(10, 10), "a potion of Ruination"); - (void)dec_stat(A_DEX, 25, TRUE); - (void)dec_stat(A_WIS, 25, TRUE); - (void)dec_stat(A_CON, 25, TRUE); - (void)dec_stat(A_STR, 25, TRUE); - (void)dec_stat(A_CHR, 25, TRUE); - (void)dec_stat(A_INT, 25, TRUE); + dec_stat(A_DEX, 25, TRUE); + dec_stat(A_WIS, 25, TRUE); + dec_stat(A_CON, 25, TRUE); + dec_stat(A_STR, 25, TRUE); + dec_stat(A_CHR, 25, TRUE); + dec_stat(A_INT, 25, TRUE); ident = TRUE; break; @@ -1964,8 +1965,8 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) { msg_print("Massive explosions rupture your body!"); take_hit(damroll(50, 20), "a potion of Detonation"); - (void)set_stun(p_ptr->stun + 75); - (void)set_cut(p_ptr->cut + 5000); + set_stun(p_ptr->stun + 75); + set_cut(p_ptr->cut + 5000); ident = TRUE; break; @@ -2029,7 +2030,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } break; @@ -2133,18 +2134,18 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) msg_print("You feel life flow through your body!"); restore_level(); hp_player(5000); - (void)set_poisoned(0); - (void)set_blind(0); - (void)set_confused(0); - (void)set_image(0); - (void)set_stun(0); - (void)set_cut(0); - (void)do_res_stat(A_STR, TRUE); - (void)do_res_stat(A_CON, TRUE); - (void)do_res_stat(A_DEX, TRUE); - (void)do_res_stat(A_WIS, TRUE); - (void)do_res_stat(A_INT, TRUE); - (void)do_res_stat(A_CHR, TRUE); + set_poisoned(0); + set_blind(0); + set_confused(0); + set_image(0); + set_stun(0); + set_cut(0); + do_res_stat(A_STR, TRUE); + do_res_stat(A_CON, TRUE); + do_res_stat(A_DEX, TRUE); + do_res_stat(A_WIS, TRUE); + do_res_stat(A_INT, TRUE); + do_res_stat(A_CHR, TRUE); if (p_ptr->black_breath) { msg_print("The hold of the Black Breath on you is broken!"); @@ -2287,26 +2288,14 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) msg_print("You begin to feel more enlightened..."); msg_print(NULL); wiz_lite_extra(); - (void)do_inc_stat(A_INT); - (void)do_inc_stat(A_WIS); - (void)detect_traps(DEFAULT_RADIUS); - (void)detect_doors(DEFAULT_RADIUS); - (void)detect_stairs(DEFAULT_RADIUS); - (void)detect_treasure(DEFAULT_RADIUS); - (void)detect_objects_gold(DEFAULT_RADIUS); - (void)detect_objects_normal(DEFAULT_RADIUS); + do_inc_stat(A_INT); + do_inc_stat(A_WIS); + detect_doors(DEFAULT_RADIUS); + detect_stairs(DEFAULT_RADIUS); + detect_treasure(DEFAULT_RADIUS); + detect_objects_gold(DEFAULT_RADIUS); + detect_objects_normal(DEFAULT_RADIUS); identify_pack(); - self_knowledge(NULL); - ident = TRUE; - - break; - } - - case SV_POTION_SELF_KNOWLEDGE: - { - msg_print("You begin to know yourself a little better..."); - msg_print(NULL); - self_knowledge(NULL); ident = TRUE; break; @@ -2326,11 +2315,11 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) case SV_POTION_RESISTANCE: { - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); + set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); + set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); + set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); + set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); + set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); ident = TRUE; break; @@ -2352,7 +2341,7 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) case SV_POTION_INVULNERABILITY: { - (void)set_invuln(p_ptr->invuln + randint(7) + 7); + set_invuln(p_ptr->invuln + randint(7) + 7); ident = TRUE; break; @@ -2489,8 +2478,10 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2) /* * Quaff a potion (from the pack or the floor) */ -void do_cmd_quaff_potion(void) +void do_cmd_quaff_potion() { + auto const &k_info = game->edit_data.k_info; + int ident, lev; /* Get an item */ @@ -2509,10 +2500,6 @@ void do_cmd_quaff_potion(void) object_type *o_ptr = get_object(item); - /* Sound */ - sound(SOUND_QUAFF); - - /* Take a turn */ energy_use = 100; @@ -2552,7 +2539,7 @@ void do_cmd_quaff_potion(void) /* Potions can feed the player */ - (void)set_food(p_ptr->food + o_ptr->pval); + set_food(p_ptr->food + o_ptr->pval); /* Destroy potion */ @@ -2563,7 +2550,7 @@ void do_cmd_quaff_potion(void) /* * Fill an empty bottle */ -static void do_cmd_fill_bottle(void) +static void do_cmd_fill_bottle() { cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px]; @@ -2649,16 +2636,16 @@ static void do_cmd_fill_bottle(void) /* * Drink from a fountain */ -void do_cmd_drink_fountain(void) +void do_cmd_drink_fountain() { + auto const &k_info = game->edit_data.k_info; + cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px]; bool_ ident; int tval, sval, pval = 0; - int i; - char ch; @@ -2695,9 +2682,9 @@ void do_cmd_drink_fountain(void) sval = c_ptr->special - SV_POTION_LAST; } - for (i = 0; i < max_k_idx; i++) + for (auto const &k_ref: k_info) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_ref; if (k_ptr->tval != tval) continue; if (k_ptr->sval != sval) continue; @@ -2724,7 +2711,7 @@ void do_cmd_drink_fountain(void) /* * Curse the players armor */ -bool_ curse_armor(void) +bool_ curse_armor() { object_type *o_ptr; @@ -2742,7 +2729,7 @@ bool_ curse_armor(void) object_desc(o_name, o_ptr, FALSE, 3); /* Attempt a saving throw for artifacts */ - if (((o_ptr->art_name) || artifact_p(o_ptr)) && (rand_int(100) < 50)) + if (artifact_p(o_ptr) && (rand_int(100) < 50)) { /* Cool */ msg_format("A terrible black aura tries to surround your armour, " @@ -2764,10 +2751,7 @@ bool_ curse_armor(void) o_ptr->ac = 0; o_ptr->dd = 0; o_ptr->ds = 0; - o_ptr->art_flags1 = 0; - o_ptr->art_flags2 = 0; - o_ptr->art_flags3 = 0; - o_ptr->art_flags4 = 0; + o_ptr->art_flags = object_flag_set(); /* Curse it */ o_ptr->ident |= (IDENT_CURSED); @@ -2789,7 +2773,7 @@ bool_ curse_armor(void) /* * Curse the players weapon */ -bool_ curse_weapon(void) +bool_ curse_weapon() { object_type *o_ptr; @@ -2807,7 +2791,7 @@ bool_ curse_weapon(void) object_desc(o_name, o_ptr, FALSE, 3); /* Attempt a saving throw */ - if ((artifact_p(o_ptr) || o_ptr->art_name) && (rand_int(100) < 50)) + if (artifact_p(o_ptr) && (rand_int(100) < 50)) { /* Cool */ msg_format("A terrible black aura tries to surround your weapon, " @@ -2829,10 +2813,7 @@ bool_ curse_weapon(void) o_ptr->ac = 0; o_ptr->dd = 0; o_ptr->ds = 0; - o_ptr->art_flags1 = 0; - o_ptr->art_flags2 = 0; - o_ptr->art_flags3 = 0; - o_ptr->art_flags4 = 0; + o_ptr->art_flags = object_flag_set(); /* Curse it */ @@ -2874,8 +2855,12 @@ static object_filter_t const &item_tester_hook_readable() * include scrolls with no effects but recharge or identify, which are * cancelled before use. XXX Reading them still takes a turn, though. */ -void do_cmd_read_scroll(void) +void do_cmd_read_scroll() { + auto const &d_info = game->edit_data.d_info; + auto const &k_info = game->edit_data.k_info; + auto &r_info = game->edit_data.r_info; + /* Check some conditions */ if (p_ptr->blind) { @@ -2942,12 +2927,12 @@ void do_cmd_read_scroll(void) msg_print("You feel the souls of the dead coming back " "from the Halls of Mandos."); - for (int k = 0; k < max_r_idx; k++) + for (auto &r_ref: r_info) { - monster_race *r_ptr = &r_info[k]; + auto r_ptr = &r_ref; - if (r_ptr->flags1 & RF1_UNIQUE && - !(r_ptr->flags9 & RF9_SPECIAL_GENE)) + if (r_ptr->flags & RF_UNIQUE && + !(r_ptr->flags & RF_SPECIAL_GENE)) { r_ptr->max_num = 1; } @@ -2983,7 +2968,7 @@ void do_cmd_read_scroll(void) } msg_format("Recall reset to %s at level %d.", - d_info[p_ptr->recall_dungeon].name, + d_info[p_ptr->recall_dungeon].name.c_str(), max_dlv[p_ptr->recall_dungeon]); ident = TRUE; @@ -2995,7 +2980,6 @@ void do_cmd_read_scroll(void) case SV_SCROLL_DIVINATION: { int i, count = 0; - char buf[120]; while (count < 1000) { @@ -3007,8 +2991,7 @@ void do_cmd_read_scroll(void) msg_print("A message appears on the scroll. It says:"); msg_print(NULL); - fate_desc(buf, i); - msg_format("%s", buf); + msg_format("%s", fate_desc(i).c_str()); msg_print(NULL); msg_print("The scroll disappears in a puff of smoke!"); @@ -3026,7 +3009,7 @@ void do_cmd_read_scroll(void) { if (!(p_ptr->resist_blind) && !(p_ptr->resist_dark)) { - (void)set_blind(p_ptr->blind + 3 + randint(5)); + set_blind(p_ptr->blind + 3 + randint(5)); } if (unlite_area(10, 3)) ident = TRUE; @@ -3093,13 +3076,6 @@ void do_cmd_read_scroll(void) break; } - case SV_SCROLL_TRAP_CREATION: - { - if (trap_creation()) ident = TRUE; - - break; - } - case SV_SCROLL_PHASE_DOOR: { teleport_player(10); @@ -3120,7 +3096,7 @@ void do_cmd_read_scroll(void) case SV_SCROLL_TELEPORT_LEVEL: { - (void)teleport_player_level(); + teleport_player_level(); ident = TRUE; @@ -3129,7 +3105,7 @@ void do_cmd_read_scroll(void) case SV_SCROLL_WORD_OF_RECALL: { - if ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) + if ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) { used_up = FALSE; } @@ -3174,9 +3150,11 @@ void do_cmd_read_scroll(void) case SV_SCROLL_STAR_REMOVE_CURSE: { - remove_all_curse(); - - ident = TRUE; + if (remove_all_curse()) + { + msg_print("You feel as if someone is watching over you."); + ident = TRUE; + } break; } @@ -3275,13 +3253,6 @@ void do_cmd_read_scroll(void) break; } - case SV_SCROLL_DETECT_TRAP: - { - if (detect_traps(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - case SV_SCROLL_DETECT_DOOR: { if (detect_doors(DEFAULT_RADIUS)) ident = TRUE; @@ -3357,13 +3328,6 @@ void do_cmd_read_scroll(void) break; } - case SV_SCROLL_TRAP_DOOR_DESTRUCTION: - { - if (destroy_doors_touch()) ident = TRUE; - - break; - } - case SV_SCROLL_STAR_DESTRUCTION: { /* Prevent destruction of quest levels and town */ @@ -3390,7 +3354,7 @@ void do_cmd_read_scroll(void) case SV_SCROLL_GENOCIDE: { - (void)genocide(TRUE); + genocide(TRUE); ident = TRUE; @@ -3399,7 +3363,7 @@ void do_cmd_read_scroll(void) case SV_SCROLL_MASS_GENOCIDE: { - (void)mass_genocide(TRUE); + mass_genocide(TRUE); ident = TRUE; @@ -3586,14 +3550,15 @@ void do_cmd_read_scroll(void) cptr q = format("book-%d.txt", o_ptr->sval); /* Peruse the help file */ - (void)show_file(q, NULL, 0, 0); + show_file(q, NULL); /* Load screen */ screen_load(); + /* Inscriptions become known upon reading */ if (o_ptr->sval >= 100) { - inscription_info[o_ptr->sval - 100].know = TRUE; + p_ptr->inscriptions[o_ptr->sval - 100] = TRUE; } used_up = FALSE; @@ -3621,8 +3586,6 @@ void do_cmd_read_scroll(void) /* Hack -- allow certain scrolls to be "preserved" */ if (!used_up) return; - sound(SOUND_SCROLL); - /* Destroy scroll */ inc_stack_size(item, -1); } @@ -3694,12 +3657,10 @@ static void activate_stick(object_type *o_ptr, bool_ *obvious, bool_ *use_charge * * Hack -- staffs of identify can be "cancelled". */ -void do_cmd_use_staff(void) +void do_cmd_use_staff() { bool_ obvious, use_charge; - u32b f1, f2, f3, f4, f5, esp; - /* No magic */ if (p_ptr->antimagic) { @@ -3746,10 +3707,10 @@ void do_cmd_use_staff(void) unset_stick_mode(); /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) + if (flags & TR_EASY_USE) { chance /= 3; } @@ -3763,25 +3724,21 @@ void do_cmd_use_staff(void) /* Roll for usage */ if (magik(chance)) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("You failed to use the staff properly."); - sound(SOUND_FAIL); return; } /* Notice empty staffs */ if (o_ptr->pval <= 0) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("The staff has no charges left."); o_ptr->ident |= (IDENT_EMPTY); return; } - /* Sound */ - sound(SOUND_ZAP); - /* Analyze the staff */ activate_stick(o_ptr, &obvious, &use_charge); @@ -3871,13 +3828,10 @@ void do_cmd_use_staff(void) * basic "bolt" rods, but the basic "ball" wands do the same damage * as the basic "ball" rods. */ -void do_cmd_aim_wand(void) +void do_cmd_aim_wand() { bool_ obvious, use_charge; - u32b f1, f2, f3, f4, f5, esp; - - /* No magic */ if (p_ptr->antimagic) { @@ -3924,10 +3878,10 @@ void do_cmd_aim_wand(void) unset_stick_mode(); /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) + if (flags & TR_EASY_USE) { chance /= 3; } @@ -3935,24 +3889,20 @@ void do_cmd_aim_wand(void) /* Roll for usage */ if (magik(chance)) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("You failed to use the wand properly."); - sound(SOUND_FAIL); return; } /* The wand is already empty! */ if (o_ptr->pval <= 0) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("The wand has no charges left."); o_ptr->ident |= (IDENT_EMPTY); return; } - /* Sound */ - sound(SOUND_ZAP); - /* Analyze the wand */ activate_stick(o_ptr, &obvious, &use_charge); @@ -4038,12 +3988,6 @@ static bool item_tester_hook_attachable(object_type const *o_ptr) */ void zap_combine_rod_tip(object_type *q_ptr, int tip_item) { - int item; - - u32b f1, f2, f3, f4, f5, esp; - s32b cost; - - /* No magic */ if (p_ptr->antimagic) { @@ -4052,6 +3996,7 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item) } /* Get an item */ + int item; if (!get_item(&item, "Attach the rod tip with which rod? ", "You have no rod to attach to.", @@ -4065,12 +4010,11 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item) object_type *o_ptr = get_object(item); /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Calculate rod tip's mana cost */ - cost = q_ptr->pval; - - if (f4 & TR4_CHEAPNESS) + s32b cost = q_ptr->pval; + if (flags & TR_CHEAPNESS) { cost /= 2; } @@ -4096,18 +4040,16 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item) /* * Zap a rod, or attack a rod tip to a rod */ -void do_cmd_zap_rod(void) +void do_cmd_zap_rod() { + auto const &k_info = game->edit_data.k_info; + int item, ident, chance, dir, lev; int cost; bool_ require_dir; - object_kind *tip_ptr; - - u32b f1, f2, f3, f4, f5, esp; - /* Hack -- let perception get aborted */ bool_ use_charge = TRUE; @@ -4161,7 +4103,6 @@ void do_cmd_zap_rod(void) { switch (o_ptr->pval) { - case SV_ROD_DETECT_TRAP: case SV_ROD_HAVOC: case SV_ROD_HOME: { @@ -4188,15 +4129,18 @@ void do_cmd_zap_rod(void) energy_use = 100; /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); - if (f4 & TR4_FAST_CAST) energy_use /= 2; + if (flags & TR_FAST_CAST) + { + energy_use /= 2; + } /* Not identified yet */ ident = FALSE; /* Extract the item level */ - tip_ptr = &k_info[lookup_kind(TV_ROD, o_ptr->pval)]; + auto tip_ptr = &k_info[lookup_kind(TV_ROD, o_ptr->pval)]; lev = k_info[lookup_kind(TV_ROD, o_ptr->pval)].level; /* Base chance of success */ @@ -4214,7 +4158,7 @@ void do_cmd_zap_rod(void) } /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) + if (flags & TR_EASY_USE) { chance *= 10; } @@ -4229,13 +4173,11 @@ void do_cmd_zap_rod(void) if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { /* Flush input if necessary */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("You failed to use the rod properly."); - sound(SOUND_FAIL); - return; } @@ -4243,13 +4185,13 @@ void do_cmd_zap_rod(void) cost = tip_ptr->pval; /* "Cheapness" ego halven the cost */ - if (f4 & TR4_CHEAPNESS) cost = cost / 2; + if (flags & TR_CHEAPNESS) cost = cost / 2; /* A single rod is still charging */ if (o_ptr->timeout < cost) { /* Flush input if necessary */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("The rod does not have enough mana yet."); @@ -4260,9 +4202,6 @@ void do_cmd_zap_rod(void) /* Increase the timeout by the rod kind's pval. */ o_ptr->timeout -= cost; - /* Sound */ - sound(SOUND_ZAP); - /* Analyze the rod */ switch (o_ptr->pval) { @@ -4275,13 +4214,6 @@ void do_cmd_zap_rod(void) break; } - case SV_ROD_DETECT_TRAP: - { - if (detect_traps(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - case SV_ROD_DETECT_DOOR: { if (detect_doors(DEFAULT_RADIUS)) ident = TRUE; @@ -4301,7 +4233,7 @@ void do_cmd_zap_rod(void) case SV_ROD_RECALL: { - if ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) + if ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) { use_charge = FALSE; } @@ -4340,15 +4272,6 @@ void do_cmd_zap_rod(void) break; } - case SV_ROD_PROBING: - { - probing(); - - ident = TRUE; - - break; - } - case SV_ROD_CURING: { if (set_blind(0)) ident = TRUE; @@ -4391,7 +4314,7 @@ void do_cmd_zap_rod(void) } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } break; @@ -4404,13 +4327,6 @@ void do_cmd_zap_rod(void) break; } - case SV_ROD_DISARMING: - { - if (disarm_trap(dir)) ident = TRUE; - - break; - } - case SV_ROD_LITE: { msg_print("A line of blue shimmering light appears."); @@ -4571,7 +4487,7 @@ static object_filter_t const &item_tester_hook_activate() using namespace object_filter; static auto instance = And( IsKnown(), - HasFlag3(TR3_ACTIVATE)); + HasFlags(TR_ACTIVATE)); return instance; } @@ -4672,7 +4588,7 @@ int ring_of_power() /* * Enchant some bolts */ -bool_ brand_bolts(void) +bool_ brand_bolts() { int i; @@ -4686,7 +4602,7 @@ bool_ brand_bolts(void) if (o_ptr->tval != TV_BOLT) continue; /* Skip artifacts and ego-items */ - if (o_ptr->art_name || artifact_p(o_ptr) || ego_item_p(o_ptr)) continue; + if (artifact_p(o_ptr) || ego_item_p(o_ptr)) continue; /* Skip cursed/broken items */ if (cursed_p(o_ptr)) continue; @@ -4711,7 +4627,7 @@ bool_ brand_bolts(void) } /* Flush */ - if (flush_failure) flush(); + flush_on_failure(); /* Fail */ msg_print("The fiery enchantment failed."); @@ -4878,13 +4794,12 @@ static void activate_valaroma() * Note that it always takes a turn to activate an object, even if * the user hits "escape" at the "direction" prompt. */ -void do_cmd_activate(void) +void do_cmd_activate() { - int item, lev, chance; - - char ch, spell_choice; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; - u32b f1, f2, f3, f4, f5, esp; + int item, lev, chance; /* Get an item */ command_wrk = USE_EQUIP; @@ -4901,10 +4816,10 @@ void do_cmd_activate(void) object_type *o_ptr = get_object(item); /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Wearable items have to be worn */ - if (!(f5 & TR5_ACTIVATE_NO_WIELD)) + if (!(flags & TR_ACTIVATE_NO_WIELD)) { if (item < INVEN_WIELD) { @@ -4924,7 +4839,7 @@ void do_cmd_activate(void) { if (o_ptr->tval == TV_RANDART) { - lev = random_artifacts[o_ptr->sval].level; + lev = game->random_artifacts[o_ptr->sval].level; } else { @@ -4947,7 +4862,7 @@ void do_cmd_activate(void) } /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) + if (flags & TR_EASY_USE) { chance *= 10; } @@ -4961,24 +4876,16 @@ void do_cmd_activate(void) /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { - if (flush_failure) flush(); + flush_on_failure(); msg_print("You failed to activate it properly."); - sound(SOUND_FAIL); return; } /* Check the recharge */ if (o_ptr->timeout) { - /* Mage Staff of Spells -- Have another timeout in xtra2 */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL) && o_ptr->xtra2) - { - msg_print("It whines, glows and fades..."); - return; - } - /* Monster eggs */ - else if (o_ptr->tval == TV_EGG) + if (o_ptr->tval == TV_EGG) { msg_print("You resume the development of the egg."); o_ptr->timeout = 0; @@ -5002,9 +4909,6 @@ void do_cmd_activate(void) /* Activate the item */ msg_print("You activate it..."); - /* Sound */ - sound(SOUND_ZAP); - /* New mostly unified activation code This has to be early to allow artifacts to override normal items -- neil */ @@ -5017,61 +4921,6 @@ void do_cmd_activate(void) return; } - /* Mage Staff of Spells */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - while (TRUE) - { - if (!get_com("Use Spell [1] or [2]?", &ch)) - { - return; - } - - if (ch == '1') - { - spell_choice = 1; - break; - } - - if (ch == '2') - { - spell_choice = 2; - break; - } - } - - if (spell_choice == 1) - { - /* Still need to check timeouts because there is another counter */ - if (o_ptr->timeout) - { - msg_print("The first spell is still charging!"); - return; - } - - /* Cast spell 1 */ - activate_spell(o_ptr, spell_choice); - } - else if (spell_choice == 2) - { - /* Still need to check timeouts because there is another counter */ - if (o_ptr->xtra2) - { - msg_print("The second spell is still charging!"); - return; - } - - /* Cast spell 2 */ - activate_spell(o_ptr, spell_choice); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Success */ - return; - } - /* Monster eggs */ if (o_ptr->tval == TV_EGG) { @@ -5108,6 +4957,10 @@ void do_cmd_activate(void) const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; + int plev = get_skill(SKILL_DEVICE); int i = 0, ii = 0, ij = 0, k, dir, dummy = 0; @@ -5125,7 +4978,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) spell = a_info[o_ptr->name1].activate; /* Random Artifacts */ - if (!spell && o_ptr->art_name) + if (!spell && (!o_ptr->artifact_name.empty())) spell = o_ptr->xtra2; /* Ego Items */ @@ -5227,67 +5080,6 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) break; } - case ACT_NUMENOR: - { - /* Give full knowledge */ - /* Hack -- Maximal info */ - monster_race *r_ptr; - cave_type *c_ptr; - int x, y, m; - - if (!doit) return "analyze monster every 500+d200 turns"; - - if (!tgt_pt(&x, &y)) break; - - c_ptr = &cave[y][x]; - if (!c_ptr->m_idx) break; - - r_ptr = &r_info[c_ptr->m_idx]; - - /* 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_flags7 = r_ptr->flags7; - r_ptr->r_flags8 = r_ptr->flags8; - r_ptr->r_flags9 = r_ptr->flags9; - - o_ptr->timeout = rand_int(200) + 500; - - break; - } - case ACT_KNOWLEDGE: { if (!doit) return "whispers from beyond(sanity drain) every 100+d200 turns"; @@ -5305,12 +5097,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("The phial wells with dark light..."); unlite_area(damroll(2, 15), 3); take_hit(damroll(10, 10), "activating The Phial of Undeath"); - (void)dec_stat(A_DEX, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_WIS, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_CON, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_STR, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_CHR, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_INT, 25, STAT_DEC_PERMANENT); + dec_stat(A_DEX, 25, STAT_DEC_PERMANENT); + dec_stat(A_WIS, 25, STAT_DEC_PERMANENT); + dec_stat(A_CON, 25, STAT_DEC_PERMANENT); + dec_stat(A_STR, 25, STAT_DEC_PERMANENT); + dec_stat(A_CHR, 25, STAT_DEC_PERMANENT); + dec_stat(A_INT, 25, STAT_DEC_PERMANENT); o_ptr->timeout = rand_int(10) + 10; @@ -5332,7 +5124,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "dispel small life every 55+d55 turns"; msg_print("You exterminate small life."); - (void)dispel_monsters(4); + dispel_monsters(4); o_ptr->timeout = rand_int(55) + 55; @@ -5345,11 +5137,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("The ring glows brightly..."); if (!p_ptr->fast) { - (void)set_fast(randint(75) + 75, 10); + set_fast(randint(75) + 75, 10); } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } o_ptr->timeout = rand_int(150) + 150; @@ -5428,7 +5220,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("The stone reveals hidden mysteries..."); if (!ident_spell()) break; - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) { /* Sufficient mana */ if (20 <= p_ptr->csp) @@ -5450,10 +5242,10 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("You are too weak to control the stone!"); /* Hack -- Bypass free action */ - (void)set_paralyzed(randint(5 * oops + 1)); + set_paralyzed(randint(5 * oops + 1)); /* Confusing. */ - (void)set_confused(p_ptr->confused + + set_confused(p_ptr->confused + randint(5 * oops + 1)); } @@ -5466,7 +5258,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) /* Confusing. */ if (rand_int(5) == 0) { - (void)set_confused(p_ptr->confused + randint(10)); + set_confused(p_ptr->confused + randint(10)); } /* Exercise a little care... */ @@ -5508,15 +5300,15 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("You breathe the elements."); fire_ball(GF_MISSILE, dir, 300, 4); msg_print("Your armor glows many colours..."); - (void)set_afraid(0); - (void)set_shero(p_ptr->shero + randint(50) + 50); - (void)hp_player(30); - (void)set_blessed(p_ptr->blessed + randint(50) + 50); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(50) + 50); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(50) + 50); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(50) + 50); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(50) + 50); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(50) + 50); + set_afraid(0); + set_shero(p_ptr->shero + randint(50) + 50); + hp_player(30); + set_blessed(p_ptr->blessed + randint(50) + 50); + set_oppose_acid(p_ptr->oppose_acid + randint(50) + 50); + set_oppose_elec(p_ptr->oppose_elec + randint(50) + 50); + set_oppose_fire(p_ptr->oppose_fire + randint(50) + 50); + set_oppose_cold(p_ptr->oppose_cold + randint(50) + 50); + set_oppose_pois(p_ptr->oppose_pois + randint(50) + 50); o_ptr->timeout = 400; @@ -5527,13 +5319,13 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return ("heal (777), curing and heroism every 300 turns"); msg_print("A heavenly choir sings..."); - (void)set_poisoned(0); - (void)set_cut(0); - (void)set_stun(0); - (void)set_confused(0); - (void)set_blind(0); - (void)set_hero(p_ptr->hero + randint(25) + 25); - (void)hp_player(777); + set_poisoned(0); + set_cut(0); + set_stun(0); + set_confused(0); + set_blind(0); + set_hero(p_ptr->hero + randint(25) + 25); + hp_player(777); o_ptr->timeout = 300; @@ -5554,11 +5346,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "resistance (20+d20 turns) every 111 turns"; msg_print("Your cloak glows many colours..."); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); + set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); + set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); + set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); + set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); + set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); o_ptr->timeout = 111; @@ -5608,7 +5400,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case 11: case 12: { - (void)stair_creation(); + stair_creation(); break; } @@ -5654,7 +5446,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "summon the Legion of the Dawn every 500+d500 turns"; msg_print("You summon the Legion of the Dawn."); - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE); + summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE); o_ptr->timeout = 500 + randint(500); @@ -5689,7 +5481,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "fire branding of bolts every 999 turns"; msg_print("Your crossbow glows deep red..."); - (void)brand_bolts(); + brand_bolts(); o_ptr->timeout = 999; @@ -5760,9 +5552,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return "clairvoyance every 100+d100 turns"; msg_print("The stone glows a deep green..."); wiz_lite_extra(); - (void)detect_traps(DEFAULT_RADIUS); - (void)detect_doors(DEFAULT_RADIUS); - (void)detect_stairs(DEFAULT_RADIUS); + detect_doors(DEFAULT_RADIUS); + detect_stairs(DEFAULT_RADIUS); o_ptr->timeout = rand_int(100) + 100; @@ -5847,11 +5638,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return "berserker and +10 to speed (50) every 100+d200 turns"; if (!p_ptr->fast) { - (void)set_fast(randint(50) + 50, 10); + set_fast(randint(50) + 50, 10); } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } hp_player(30); set_afraid(0); @@ -5927,7 +5718,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "detect orcs every 10 turns"; msg_print("Your weapon glows brightly..."); - (void)detect_monsters_xxx(RF3_ORC, DEFAULT_RADIUS); + detect_monsters_orcs(DEFAULT_RADIUS); o_ptr->timeout = 10; @@ -6306,7 +6097,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "teleport away every 200 turns"; if (!get_aim_dir(&dir)) break; - (void)fire_beam(GF_AWAY_ALL, dir, plev); + fire_beam(GF_AWAY_ALL, dir, plev); o_ptr->timeout = 200; @@ -6330,7 +6121,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "genocide every 500 turns"; msg_print("It glows deep blue..."); - (void)genocide(TRUE); + genocide(TRUE); o_ptr->timeout = 500; @@ -6341,7 +6132,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "mass genocide every 1000 turns"; msg_print("It lets out a long, shrill note..."); - (void)mass_genocide(TRUE); + mass_genocide(TRUE); o_ptr->timeout = 1000; @@ -6354,7 +6145,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "charm animal every 300 turns"; if (!get_aim_dir(&dir)) break; - (void) charm_animal(dir, plev); + charm_animal(dir, plev); o_ptr->timeout = 300; @@ -6365,7 +6156,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "enslave undead every 333 turns"; if (!get_aim_dir(&dir)) break; - (void)control_one_undead(dir, plev); + control_one_undead(dir, plev); o_ptr->timeout = 333; @@ -6376,7 +6167,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "charm monster every 400 turns"; if (!get_aim_dir(&dir)) break; - (void) charm_monster(dir, plev); + charm_monster(dir, plev); o_ptr->timeout = 400; @@ -6386,7 +6177,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_CHARM_ANIMALS: { if (!doit) return "animal friendship every 500 turns"; - (void) charm_animals(plev * 2); + charm_animals(plev * 2); o_ptr->timeout = 500; @@ -6406,7 +6197,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_SUMMON_ANIMAL: { if (!doit) return "summon animal every 200+d300 turns"; - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE); + summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE); o_ptr->timeout = 200 + randint(300); @@ -6417,7 +6208,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "summon phantasmal servant every 200+d200 turns"; msg_print("You summon a phantasmal servant."); - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE); + summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE); o_ptr->timeout = 200 + randint(200); @@ -6509,8 +6300,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_CURE_LW: { if (!doit) return format("cure light wounds every %d turns", (is_junkart ? 50 : 10)); - (void)set_afraid(0); - (void)hp_player(30); + set_afraid(0); + hp_player(30); o_ptr->timeout = 10; @@ -6522,7 +6313,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return format("cure serious wounds every %s turns", (is_junkart? "75" : "3+d3")); msg_print("It radiates deep purple..."); hp_player(damroll(4, 8)); - (void)set_cut((p_ptr->cut / 2) - 50); + set_cut((p_ptr->cut / 2) - 50); o_ptr->timeout = rand_int(3) + 3; @@ -6533,8 +6324,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "remove fear and cure poison every 5 turns"; msg_print("It glows deep blue..."); - (void)set_afraid(0); - (void)set_poisoned(0); + set_afraid(0); + set_poisoned(0); o_ptr->timeout = 5; @@ -6556,13 +6347,13 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return format("restore stats and life levels every %d turns", (is_junkart ? 200 : 750)); msg_print("It glows a deep green..."); - (void)do_res_stat(A_STR, TRUE); - (void)do_res_stat(A_INT, TRUE); - (void)do_res_stat(A_WIS, TRUE); - (void)do_res_stat(A_DEX, TRUE); - (void)do_res_stat(A_CON, TRUE); - (void)do_res_stat(A_CHR, TRUE); - (void)restore_level(); + do_res_stat(A_STR, TRUE); + do_res_stat(A_INT, TRUE); + do_res_stat(A_WIS, TRUE); + do_res_stat(A_DEX, TRUE); + do_res_stat(A_CON, TRUE); + do_res_stat(A_CHR, TRUE); + restore_level(); o_ptr->timeout = 750; @@ -6574,8 +6365,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return format("heal 700 hit points every %d turns", (is_junkart ? 100 : 250)); msg_print("It glows deep blue..."); msg_print("You feel a warm tingling inside..."); - (void)hp_player(700); - (void)set_cut(0); + hp_player(700); + set_cut(0); o_ptr->timeout = 250; @@ -6587,8 +6378,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return "heal 1000 hit points every 888 turns"; msg_print("It glows a bright white..."); msg_print("You feel much better..."); - (void)hp_player(1000); - (void)set_cut(0); + hp_player(1000); + set_cut(0); o_ptr->timeout = 888; @@ -6598,7 +6389,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_ESP: { if (!doit) return "temporary ESP (dur 25+d30) every 200 turns"; - (void)set_tim_esp(p_ptr->tim_esp + randint(30) + 25); + set_tim_esp(p_ptr->tim_esp + randint(30) + 25); o_ptr->timeout = 200; @@ -6608,8 +6399,8 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_BERSERK: { if (!doit) return "heroism and berserk (dur 50+d50) every 100+d100 turns"; - (void)set_shero(p_ptr->shero + randint(50) + 50); - (void)set_blessed(p_ptr->blessed + randint(50) + 50); + set_shero(p_ptr->shero + randint(50) + 50); + set_blessed(p_ptr->blessed + randint(50) + 50); o_ptr->timeout = 100 + randint(100); @@ -6621,7 +6412,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!doit) return "protection from evil (dur level*3 + d25) every 225+d225 turns"; msg_print("It lets out a shrill wail..."); k = 3 * p_ptr->lev; - (void)set_protevil(p_ptr->protevil + randint(25) + k); + set_protevil(p_ptr->protevil + randint(25) + k); o_ptr->timeout = rand_int(225) + 225; @@ -6632,11 +6423,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "resist elements (dur 40+d40) every 200 turns"; msg_print("It glows many colours..."); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(40) + 40); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(40) + 40); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(40) + 40); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(40) + 40); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(40) + 40); + set_oppose_acid(p_ptr->oppose_acid + randint(40) + 40); + set_oppose_elec(p_ptr->oppose_elec + randint(40) + 40); + set_oppose_fire(p_ptr->oppose_fire + randint(40) + 40); + set_oppose_cold(p_ptr->oppose_cold + randint(40) + 40); + set_oppose_pois(p_ptr->oppose_pois + randint(40) + 40); o_ptr->timeout = 200; @@ -6649,11 +6440,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("It glows bright green..."); if (!p_ptr->fast) { - (void)set_fast(randint(20) + 20, 10); + set_fast(randint(20) + 20, 10); } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } o_ptr->timeout = 250; @@ -6667,11 +6458,11 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("It glows brightly..."); if (!p_ptr->fast) { - (void)set_fast(randint(75) + 75, 10); + set_fast(randint(75) + 75, 10); } else { - (void)set_fast(p_ptr->fast + 5, 10); + set_fast(p_ptr->fast + 5, 10); } o_ptr->timeout = rand_int(200) + 200; @@ -6692,7 +6483,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_INVULN: { if (!doit) return "invulnerability (dur 8+d8) every 1000 turns"; - (void)set_invuln(p_ptr->invuln + randint(8) + 8); + set_invuln(p_ptr->invuln + randint(8) + 8); o_ptr->timeout = 1000; @@ -6738,10 +6529,9 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_DETECT_XTRA: { - if (!doit) return "detection, probing and identify true every 1000 turns"; + if (!doit) return "detection and identify true every 1000 turns"; msg_print("It glows brightly..."); detect_all(DEFAULT_RADIUS); - probing(); identify_fully(); o_ptr->timeout = 1000; @@ -6795,7 +6585,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_SATIATE: { if (!doit) return "satisfy hunger every 200 turns"; - (void)set_food(PY_FOOD_MAX - 1); + set_food(PY_FOOD_MAX - 1); o_ptr->timeout = 200; @@ -6839,7 +6629,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) { if (!doit) return "alchemy every 500 turns"; msg_print("It glows bright yellow..."); - (void) alchemy(); + alchemy(); o_ptr->timeout = 500; @@ -6849,7 +6639,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_DIM_DOOR: { if (!doit) return "dimension door every 100 turns"; - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("Not on special levels!"); break; @@ -6892,7 +6682,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_RECALL: { - if (!(dungeon_flags2 & DF2_ASK_LEAVE) || ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? "))) + if (!(dungeon_flags & DF_ASK_LEAVE) || ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? "))) { if (!doit) return "word of recall every 200 turns"; msg_print("It glows soft white..."); @@ -6920,12 +6710,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("Your nerves and muscles feel weak and lifeless!"); take_hit(damroll(10, 10), "activating Ruination"); - (void)dec_stat(A_DEX, 25, TRUE); - (void)dec_stat(A_WIS, 25, TRUE); - (void)dec_stat(A_CON, 25, TRUE); - (void)dec_stat(A_STR, 25, TRUE); - (void)dec_stat(A_CHR, 25, TRUE); - (void)dec_stat(A_INT, 25, TRUE); + dec_stat(A_DEX, 25, TRUE); + dec_stat(A_WIS, 25, TRUE); + dec_stat(A_CON, 25, TRUE); + dec_stat(A_STR, 25, TRUE); + dec_stat(A_CHR, 25, TRUE); + dec_stat(A_INT, 25, TRUE); /* Timeout is set before return */ @@ -6945,7 +6735,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNINT: { if (!doit) return "decreasing Intelligence"; - (void)dec_stat(A_INT, 25, FALSE); + dec_stat(A_INT, 25, FALSE); /* Timeout is set before return */ @@ -6955,7 +6745,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNSTR: { if (!doit) return "decreasing Strength"; - (void)dec_stat(A_STR, 25, FALSE); + dec_stat(A_STR, 25, FALSE); /* Timeout is set before return */ @@ -6965,7 +6755,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNCON: { if (!doit) return "decreasing Constitution"; - (void)dec_stat(A_CON, 25, FALSE); + dec_stat(A_CON, 25, FALSE); /* Timeout is set before return */ @@ -6975,7 +6765,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNCHR: { if (!doit) return "decreasing Charisma"; - (void)dec_stat(A_CHR, 25, FALSE); + dec_stat(A_CHR, 25, FALSE); /* Timeout is set before return */ @@ -6985,7 +6775,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNDEX: { if (!doit) return "decreasing Dexterity"; - (void)dec_stat(A_DEX, 25, FALSE); + dec_stat(A_DEX, 25, FALSE); /* Timeout is set before return */ @@ -6995,7 +6785,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_UNWIS: { if (!doit) return "decreasing Wisdom"; - (void)dec_stat(A_WIS, 25, FALSE); + dec_stat(A_WIS, 25, FALSE); /* Timeout is set before return */ @@ -7005,12 +6795,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_STATLOSS: { if (!doit) return "stat loss"; - (void)dec_stat(A_STR, 15, FALSE); - (void)dec_stat(A_INT, 15, FALSE); - (void)dec_stat(A_WIS, 15, FALSE); - (void)dec_stat(A_DEX, 15, FALSE); - (void)dec_stat(A_CON, 15, FALSE); - (void)dec_stat(A_CHR, 15, FALSE); + dec_stat(A_STR, 15, FALSE); + dec_stat(A_INT, 15, FALSE); + dec_stat(A_WIS, 15, FALSE); + dec_stat(A_DEX, 15, FALSE); + dec_stat(A_CON, 15, FALSE); + dec_stat(A_CHR, 15, FALSE); /* Timeout is set before return */ @@ -7020,12 +6810,12 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_HISTATLOSS: { if (!doit) return "high stat loss"; - (void)dec_stat(A_STR, 25, FALSE); - (void)dec_stat(A_INT, 25, FALSE); - (void)dec_stat(A_WIS, 25, FALSE); - (void)dec_stat(A_DEX, 25, FALSE); - (void)dec_stat(A_CON, 25, FALSE); - (void)dec_stat(A_CHR, 25, FALSE); + dec_stat(A_STR, 25, FALSE); + dec_stat(A_INT, 25, FALSE); + dec_stat(A_WIS, 25, FALSE); + dec_stat(A_DEX, 25, FALSE); + dec_stat(A_CON, 25, FALSE); + dec_stat(A_CHR, 25, FALSE); /* Timeout is set before return */ @@ -7095,7 +6885,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_HUNGER: { if (!doit) return "create hunger"; - (void)set_food(PY_FOOD_WEAK); + set_food(PY_FOOD_WEAK); /* Timeout is set before return */ @@ -7196,7 +6986,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) case ACT_CURE_HUNGER: { if (!doit) return "satisfy hunger every 100 turns"; - (void)set_food(PY_FOOD_MAX - 1); + set_food(PY_FOOD_MAX - 1); /* Timeout is set before return */ @@ -7373,8 +7163,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) c_ptr->info &= ~(CAVE_GLOW); /* Hack -- Forget "boring" grids */ - if (cave_plain_floor_grid(c_ptr) && - !(c_ptr->info & (CAVE_TRDT))) + if (cave_plain_floor_grid(c_ptr)) { /* Forget the grid */ c_ptr->info &= ~(CAVE_MARK); @@ -7561,7 +7350,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!get_aim_dir(&dir)) break; fire_ball(GF_COLD, dir, 50, 2); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); + set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); o_ptr->timeout = rand_int(50) + 50; @@ -7575,7 +7364,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!get_aim_dir(&dir)) break; fire_ball(GF_FIRE, dir, 50, 2); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); + set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); o_ptr->timeout = rand_int(50) + 50; @@ -7588,7 +7377,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!get_aim_dir(&dir)) break; fire_ball(GF_ACID, dir, 50, 2); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); + set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); o_ptr->timeout = rand_int(50) + 50; @@ -7602,7 +7391,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) if (!get_aim_dir(&dir)) break; fire_ball(GF_ELEC, dir, 50, 2); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); + set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); o_ptr->timeout = rand_int(50) + 50; @@ -7892,37 +7681,3 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) return NULL; } - - -static bool_ activate_spell(object_type * o_ptr, byte choice) -{ - int mana = 0, gf = 0, mod = 0; - - rune_spell s_ptr; - - - if (choice == 1) - { - gf = o_ptr->pval & 0xFFFF; - mod = o_ptr->pval3 & 0xFFFF; - mana = o_ptr->pval2 & 0xFF; - } - else if (choice == 2) - { - gf = o_ptr->pval >> 16; - mod = o_ptr->pval3 >> 16; - mana = o_ptr->pval2 >> 8; - } - - s_ptr.type = gf; - s_ptr.rune2 = 1 << mod; - s_ptr.mana = mana; - - /* Execute */ - rune_exec(&s_ptr, 0); - - if (choice == 1) o_ptr->timeout = mana * 5; - if (choice == 2) o_ptr->xtra2 = mana * 5; - - return (TRUE); -} diff --git a/src/cmd6.hpp b/src/cmd6.hpp index ad6619f6..076a9abb 100644 --- a/src/cmd6.hpp +++ b/src/cmd6.hpp @@ -3,16 +3,16 @@ #include "h-basic.h" #include "object_type_fwd.hpp" -extern void set_stick_mode(object_type *o_ptr); -extern void unset_stick_mode(void); -extern void do_cmd_eat_food(void); -extern void do_cmd_quaff_potion(void); -extern void do_cmd_read_scroll(void); -extern void do_cmd_aim_wand(void); -extern void do_cmd_use_staff(void); -extern void do_cmd_zap_rod(void); -extern const char *activation_aux(object_type *o_ptr, bool_ desc, int item); -extern void do_cmd_activate(void); -extern void do_cmd_cut_corpse(void); -extern void do_cmd_cure_meat(void); -extern void do_cmd_drink_fountain(void); +void set_stick_mode(object_type *o_ptr); +void unset_stick_mode(); +void do_cmd_eat_food(); +void do_cmd_quaff_potion(); +void do_cmd_read_scroll(); +void do_cmd_aim_wand(); +void do_cmd_use_staff(); +void do_cmd_zap_rod(); +const char *activation_aux(object_type *o_ptr, bool_ desc, int item); +void do_cmd_activate(); +void do_cmd_cut_corpse(); +void do_cmd_cure_meat(); +void do_cmd_drink_fountain(); diff --git a/src/cmd7.cc b/src/cmd7.cc index 2317f8b9..ec13c908 100644 --- a/src/cmd7.cc +++ b/src/cmd7.cc @@ -13,19 +13,22 @@ #include "cmd1.hpp" #include "cmd5.hpp" #include "cmd6.hpp" +#include "dungeon_flag.hpp" #include "ego_item_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hooks.hpp" #include "mimic.hpp" #include "monster2.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_type.hpp" -#include "quark.hpp" #include "skills.hpp" #include "spells1.hpp" #include "spells2.hpp" @@ -39,6 +42,8 @@ #include "xtra2.hpp" #include "z-rand.hpp" +#include <fmt/format.h> + /* * Describe class powers of Mindcrafters * @@ -107,6 +112,8 @@ void mindcraft_info(char *p, int power) */ void mimic_info(char *p, int power) { + auto const &k_info = game->edit_data.k_info; + int plev = get_skill(SKILL_MIMICRY); object_type *o_ptr = &p_ptr->inventory[INVEN_OUTER]; @@ -340,7 +347,7 @@ static bool_ get_magic_power(int *sn, magic_power *powers, int max_powers, * do_cmd_cast calls this function if the player's class * is 'mindcrafter'. */ -void do_cmd_mindcraft(void) +void do_cmd_mindcraft() { int n = 0, b = 0; @@ -417,12 +424,10 @@ void do_cmd_mindcraft(void) /* Failed spell */ if (rand_int(100) < chance) { - if (flush_failure) flush(); + flush_on_failure(); msg_format("You failed to concentrate hard enough!"); - sound(SOUND_FAIL); - if (randint(100) < (chance / 2)) { /* Backfire */ @@ -460,8 +465,6 @@ void do_cmd_mindcraft(void) /* Successful spells */ else { - sound(SOUND_ZAP); - /* spell code */ switch (n) { @@ -483,7 +486,6 @@ void do_cmd_mindcraft(void) { b = detect_monsters_normal(DEFAULT_RADIUS); if (plev > 14) b |= detect_monsters_invis(DEFAULT_RADIUS); - if (plev > 4) b |= detect_traps(DEFAULT_RADIUS); } else { @@ -531,7 +533,7 @@ void do_cmd_mindcraft(void) { int ii, ij; - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("Not on special levels!"); break; @@ -627,7 +629,7 @@ void do_cmd_mindcraft(void) } else { - (void)mindblast_monsters(plev * ((plev - 5) / 10 + 1)); + mindblast_monsters(plev * ((plev - 5) / 10 + 1)); } break; @@ -654,11 +656,11 @@ void do_cmd_mindcraft(void) if (!p_ptr->fast) { /* Haste */ - (void)set_fast(b, plev / 5); + set_fast(b, plev / 5); } else { - (void)set_fast(p_ptr->fast + b, plev / 5); + set_fast(p_ptr->fast + b, plev / 5); } break; @@ -722,7 +724,7 @@ void do_cmd_mindcraft(void) msg_print("You faint from the effort!"); /* Hack -- Bypass free action */ - (void)set_paralyzed(randint(5 * oops + 1)); + set_paralyzed(randint(5 * oops + 1)); /* Damage WIS (possibly permanently) */ if (rand_int(100) < 50) @@ -733,7 +735,7 @@ void do_cmd_mindcraft(void) msg_print("You have damaged your mind!"); /* Reduce constitution */ - (void)dec_stat(A_WIS, 15 + randint(10), perm); + dec_stat(A_WIS, 15 + randint(10), perm); } } @@ -762,6 +764,8 @@ static int get_mimic_chance(int mimic) void do_cmd_mimic_lore() { + auto const &k_info = game->edit_data.k_info; + int fail; object_type *o_ptr; @@ -840,7 +844,7 @@ void do_cmd_mimic_lore() p_ptr->update |= (PU_BONUS); } -static bool_ mimic_forbid_travel(void *, void *, void *) +static bool mimic_forbid_travel(void *, void *, void *) { u32b value = p_ptr->mimic_extra >> 16; u32b att = p_ptr->mimic_extra & 0xFFFF; @@ -848,17 +852,17 @@ static bool_ mimic_forbid_travel(void *, void *, void *) if(value > 0 && (att & CLASS_ARMS || att & CLASS_LEGS)) { msg_print("You had best not travel with your extra limbs."); - return TRUE; + return true; } - return FALSE; + return false; } /* * do_cmd_cast calls this function if the player's class * is 'mimic'. */ -void do_cmd_mimic(void) +void do_cmd_mimic() { int n = 0, b = 0; @@ -946,12 +950,10 @@ void do_cmd_mimic(void) /* Failed spell */ if (rand_int(100) < fail) { - if (flush_failure) flush(); + flush_on_failure(); msg_format("You failed to concentrate hard enough!"); - sound(SOUND_FAIL); - if (randint(100) < (fail / 2)) { /* Backfire */ @@ -982,8 +984,6 @@ void do_cmd_mimic(void) /* Successful spells */ else { - sound(SOUND_ZAP); - /* spell code */ switch (n) { @@ -1131,7 +1131,7 @@ void do_cmd_mimic(void) msg_print("You faint from the effort!"); /* Hack -- Bypass free action */ - (void)set_paralyzed(randint(5 * oops + 1)); + set_paralyzed(randint(5 * oops + 1)); /* Damage WIS (possibly permanently) */ if (rand_int(100) < 50) @@ -1142,7 +1142,7 @@ void do_cmd_mimic(void) msg_print("You have damaged your mind!"); /* Reduce constitution */ - (void)dec_stat(A_DEX, 15 + randint(10), perm); + dec_stat(A_DEX, 15 + randint(10), perm); } } @@ -1158,7 +1158,7 @@ void do_cmd_mimic(void) * do_cmd_cast calls this function if the player's class * is 'beastmaster'. */ -void do_cmd_beastmaster(void) +void do_cmd_beastmaster() { int plev = p_ptr->lev, i, num; @@ -1200,7 +1200,7 @@ void do_cmd_beastmaster(void) /* * Command to ask favors from your god. */ -void do_cmd_pray(void) +void do_cmd_pray() { if (p_ptr->pgod == GOD_NONE) { @@ -1228,7 +1228,7 @@ void do_cmd_pray(void) /* * Return percentage chance of spell failure. */ -int spell_chance_random(random_spell* rspell) +int spell_chance_random(random_spell const *rspell) { int chance, minfail; @@ -1263,29 +1263,28 @@ int spell_chance_random(random_spell* rspell) */ static void print_spell_batch(int batch, int max) { - char buff[80]; - - random_spell* rspell; - - int i; - + auto const &random_spells = p_ptr->random_spells; prt(format(" %-30s Lev Fail Mana Damage ", "Name"), 1, 20); + int i; for (i = 0; i < max; i++) { - rspell = &random_spells[batch * 10 + i]; + auto rspell = &random_spells[batch * 10 + i]; + + std::string buff; + std::string name = name_spell(rspell); if (rspell->untried) { - strnfmt(buff, 80, " %c) %-30s (Spell untried) ", - I2A(i), rspell->name); + buff = fmt::format(" {:c}) {:<30} (Spell untried) ", + (char) I2A(i), name); } else { - strnfmt(buff, 80, " %c) %-30s %3d %4d%% %3d %3dd%d ", - I2A(i), rspell->name, + buff = fmt::format(" {:c}) {:<30} {:>3d} {:>4d}% {:>3d} {:>3d}d{:d} ", + (char) I2A(i), name, rspell->level, spell_chance_random(rspell), rspell->mana, rspell->dam_dice, rspell->dam_sides); } @@ -1301,18 +1300,13 @@ static void print_spell_batch(int batch, int max) /* * List ten random spells and ask to pick one. */ -static random_spell* select_spell_from_batch(int batch) +static random_spell* select_spell_from_batch(std::size_t batch) { - char tmp[160]; - - char out_val[30]; + auto &random_spells = p_ptr->random_spells; + char tmp[160]; char which; - - int mut_max = 10; - - random_spell* ret; - + random_spell* ret = nullptr; /* Enter "icky" mode */ character_icky = TRUE; @@ -1320,13 +1314,12 @@ static random_spell* select_spell_from_batch(int batch) /* Save the screen */ Term_save(); - if (spell_num < (batch + 1) * 10) - { - mut_max = spell_num - batch * 10; - } + int const mut_max = (random_spells.size() < (batch + 1) * 10) + ? random_spells.size() - batch * 10 + : 10; - strnfmt(tmp, 160, "(a-%c, A-%c to browse, / to rename, - to comment) Select a power: ", - I2A(mut_max - 1), I2A(mut_max - 1) - 'a' + 'A'); + strnfmt(tmp, 160, "(a-%c) Select a power: ", + I2A(mut_max - 1)); prt(tmp, 0, 0); @@ -1365,65 +1358,7 @@ static random_spell* select_spell_from_batch(int batch) continue; } - /* Rename */ - if (which == '/') - { - prt("Rename which power: ", 0, 0); - which = tolower(inkey()); - - if (isalpha(which) && (A2I(which) <= mut_max)) - { - strcpy(out_val, random_spells[batch*10 + A2I(which)].name); - if (get_string("Name this power: ", out_val, 29)) - { - strcpy(random_spells[batch*10 + A2I(which)].name, out_val); - } - prt(tmp, 0, 0); - } - else - { - bell(); - prt(tmp, 0, 0); - } - - /* Wait for next command */ - continue; - } - - /* Comment */ - if (which == '-') - { - prt("Comment which power: ", 0, 0); - which = tolower(inkey()); - - if (isalpha(which) && (A2I(which) <= mut_max)) - { - strcpy(out_val, random_spells[batch*10 + A2I(which)].desc); - if (get_string("Comment this power: ", out_val, 29)) - { - strcpy(random_spells[batch*10 + A2I(which)].desc, out_val); - } - prt(tmp, 0, 0); - } - else - { - bell(); - prt(tmp, 0, 0); - } - - /* Wait for next command */ - continue; - } - - if (isalpha(which) && isupper(which)) - { - which = tolower(which); - c_prt(TERM_L_BLUE, format("%s : %s", random_spells[batch*10 + A2I(which)].name, random_spells[batch*10 + A2I(which)].desc), 0, 0); - inkey(); - prt(tmp, 0, 0); - continue; - } - else if (isalpha(which) && (A2I(which) < mut_max)) + if (isalpha(which) && (A2I(which) < mut_max)) { /* Pick the power */ ret = &random_spells[batch * 10 + A2I(which)]; @@ -1453,12 +1388,11 @@ static random_spell* select_spell_from_batch(int batch) */ static random_spell* select_spell() { - char tmp[160]; + auto const &random_spells = p_ptr->random_spells; + char tmp[160]; char which; - int batch_max = (spell_num - 1) / 10; - random_spell *ret; @@ -1470,12 +1404,15 @@ static random_spell* select_spell() } /* No spells available */ - if (spell_num == 0) + if (random_spells.empty()) { msg_print("There are no spells you can cast."); return NULL; } + /* How many spells in the last batch? */ + int batch_max = (random_spells.size() - 1) / 10; + /* Enter "icky" mode */ character_icky = TRUE; @@ -1535,7 +1472,7 @@ static random_spell* select_spell() } -void do_cmd_powermage(void) +void do_cmd_powermage() { random_spell *s_ptr; @@ -1581,7 +1518,7 @@ void do_cmd_powermage(void) char sfail[80]; /* Flush input if told so */ - if (flush_failure) flush(); + flush_on_failure(); /* Insane players can see something strange */ if (rand_int(100) < insanity) @@ -1596,8 +1533,6 @@ void do_cmd_powermage(void) msg_print("You failed to get the spell off!"); } - sound(SOUND_FAIL); - /* Let time pass */ if (is_magestaff()) energy_use = 80; else energy_use = 100; @@ -1615,7 +1550,7 @@ void do_cmd_powermage(void) p_ptr->csp -= s_ptr->mana; - s_ptr->untried = FALSE; + s_ptr->untried = false; proj_flags = s_ptr->proj_flags; /* Hack -- Spell needs a target */ @@ -1761,7 +1696,7 @@ void brand_ammo(int brand_type, int bolts_only) } else { - if (flush_failure) flush(); + flush_on_failure(); msg_print("The enchantment failed."); } } @@ -1792,6 +1727,8 @@ void summon_monster(int sumtype) */ void do_cmd_possessor() { + auto const &r_info = game->edit_data.r_info; + char ch, ext; @@ -1831,8 +1768,6 @@ void do_cmd_possessor() if (ext == 1) { - bool_ use_great = FALSE; - if (p_ptr->disembodied) { msg_print("You don't currently own a body to use."); @@ -1840,26 +1775,11 @@ void do_cmd_possessor() } /* Do we have access to all the powers ? */ - if (get_skill_scale(SKILL_POSSESSION, 100) >= r_info[p_ptr->body_monster].level) - use_great = TRUE; + bool use_great = (get_skill_scale(SKILL_POSSESSION, 100) >= r_info[p_ptr->body_monster].level); - use_symbiotic_power(p_ptr->body_monster, use_great, FALSE, FALSE); - - if (p_ptr->csp < 0) - { - msg_print("You lose control of your body!"); - if (!do_cmd_leave_body(FALSE)) - { - cmsg_print(TERM_VIOLET, - "You are forced back into your body by your cursed items, " - "you suffer a system shock!"); - - p_ptr->chp = 1; - - /* Display the hitpoints */ - p_ptr->redraw |= (PR_FRAME); - } - } + /* Select power */ + use_monster_power(p_ptr->body_monster, use_great); + assert(p_ptr->csp >= 0); // Sanity check } else if (ext == 2) { @@ -1900,7 +1820,7 @@ static object_filter_t const &item_tester_hook_convertible() * do_cmd_cast calls this function if the player's class * is 'archer'. */ -void do_cmd_archer(void) +void do_cmd_archer() { int ext = 0; char ch; @@ -1992,11 +1912,11 @@ void do_cmd_archer(void) q_ptr->discount = 90; q_ptr->found = OBJ_FOUND_SELFMADE; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); msg_print("You make some ammo."); - (void)wall_to_mud(dir); + wall_to_mud(dir); p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE); p_ptr->window |= (PW_OVERHEAD); } @@ -2035,7 +1955,7 @@ void do_cmd_archer(void) inc_stack_size(item, -1); - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); } /**********Create bolts*********/ @@ -2071,14 +1991,14 @@ void do_cmd_archer(void) inc_stack_size(item, -1); - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); } } /* * Control whether shots are allowed to pierce */ -void do_cmd_set_piercing(void) +void do_cmd_set_piercing() { char ch; char com[80]; @@ -2148,7 +2068,7 @@ void necro_info(char *p, int power) /* * Cast a Necromancy spell */ -void do_cmd_necromancer(void) +void do_cmd_necromancer() { int n = 0, b = 0; int chance; @@ -2223,9 +2143,8 @@ void do_cmd_necromancer(void) /* Failed spell */ if (rand_int(100) < chance) { - if (flush_failure) flush(); + flush_on_failure(); msg_format("You failed to concentrate hard enough!"); - sound(SOUND_FAIL); if (randint(100) < (chance / 2)) { @@ -2269,8 +2188,6 @@ void do_cmd_necromancer(void) } else { - sound(SOUND_ZAP); - /* spell code */ switch (n) { @@ -2326,7 +2243,7 @@ void do_cmd_necromancer(void) object_prep(o_ptr, k_idx); apply_magic(o_ptr, plev * 2, TRUE, TRUE, TRUE); - o_ptr->art_flags5 |= TR5_TEMPORARY; + o_ptr->art_flags |= TR_TEMPORARY; o_ptr->timeout = dur; /* These objects are "storebought" */ @@ -2335,7 +2252,7 @@ void do_cmd_necromancer(void) object_aware(o_ptr); object_known(o_ptr); - (void)inven_carry(o_ptr, FALSE); + inven_carry(o_ptr, FALSE); k_allow_special[k_idx] = FALSE; @@ -2425,7 +2342,7 @@ void do_cmd_necromancer(void) msg_print("You faint from the effort!"); /* Hack -- Bypass free action */ - (void)set_paralyzed(randint(5 * oops + 1)); + set_paralyzed(randint(5 * oops + 1)); /* Damage CON (possibly permanently) */ if (rand_int(100) < 50) @@ -2436,7 +2353,7 @@ void do_cmd_necromancer(void) msg_print("You have damaged your body!"); /* Reduce constitution */ - (void)dec_stat(A_CON, 15 + randint(10), perm); + dec_stat(A_CON, 15 + randint(10), perm); } } @@ -2448,23 +2365,6 @@ void do_cmd_necromancer(void) } /* - * Hook to determine if an object is "runestone" - */ -static bool item_tester_hook_runestone(object_type const *o_ptr) -{ - return ((o_ptr->tval == TV_RUNE2) && - (o_ptr->sval == RUNE_STONE) && - (o_ptr->pval == 0)); -} - -static bool item_tester_hook_runestone_full(object_type const *o_ptr) -{ - return ((o_ptr->tval == TV_RUNE2) && - (o_ptr->sval == RUNE_STONE) && - (o_ptr->pval != 0)); -} - -/* * math.h(sqrt) is banned of angband so ... :) */ s32b sroot(s32b n) @@ -2486,1054 +2386,6 @@ s32b sroot(s32b n) } -/* - * Damage formula, for runes - */ -void rune_calc_power(s32b *power, s32b *powerdiv) -{ - /* Not too weak power(paranoia) */ - *power = (*power < 1) ? 1 : *power; - *power += 3; - - *power = 37 * sroot(*power) / 10; - - /* To reduce the high level power, while increasing the low levels */ - *powerdiv = *power / 3; - if (*powerdiv < 1) *powerdiv = 1; - - /* Use the spell multiplicator */ - *power *= (p_ptr->to_s / 2) ? (p_ptr->to_s / 2) : 1; -} - - -/* - * Return percentage chance of runespell failure. - */ -int spell_chance_rune(rune_spell* spell) -{ - int chance, minfail; - - s32b power = spell->mana, power_rune = 0, powerdiv = 0; - - - if (spell->rune2 & RUNE_POWER_SURGE) - { - power_rune += 4; - } - if (spell->rune2 & RUNE_ARMAGEDDON) - { - power_rune += 3; - } - if (spell->rune2 & RUNE_SPHERE) - { - power_rune += 2; - } - if (spell->rune2 & RUNE_RAY) - { - power_rune += 1; - } - - rune_calc_power(&power, &powerdiv); - - chance = (5 * power_rune) + (power); - - /* Reduce failure rate by INT/WIS adjustment */ - chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[A_DEX]] - 1); - - /* Extract the minimum failure rate */ - minfail = adj_mag_fail[p_ptr->stat_ind[A_DEX]]; - - /* Return the chance */ - return clamp_failure_chance(chance, minfail); -} - - -/* - * Combine the Runes - */ -int rune_exec(rune_spell *spell, int cost) -{ - int dir, power_rune = 0, mana_used, plev = get_skill(SKILL_RUNECRAFT); - - int chance; - - s32b power, powerdiv; - - int rad = 0, ty = -1, tx = -1, dam = 0, flg = 0; - - - if (spell->rune2 & RUNE_POWER_SURGE) - { - power_rune += 4; - } - if (spell->rune2 & RUNE_ARMAGEDDON) - { - power_rune += 3; - } - if (spell->rune2 & RUNE_SPHERE) - { - power_rune += 2; - } - if (spell->rune2 & RUNE_RAY) - { - power_rune += 1; - } - - - power = spell->mana; - - if (cost && ((power * cost / 100) > p_ptr->csp - (power_rune * (plev / 5)))) - { - power = p_ptr->csp - (power_rune * (plev / 5)); - mana_used = power + (power_rune * (plev / 5)); - } - else - { - mana_used = (power * cost / 100) + (power_rune * (plev / 5)); - } - - rune_calc_power(&power, &powerdiv); - - dam = damroll(powerdiv, power); - - if (wizard) msg_format("Rune %dd%d = dam %d", powerdiv, power, dam); - - /* Extract the base spell failure rate */ - chance = spell_chance_rune(spell); - - /* Failure ? */ - if (rand_int(100) < chance) - { - int insanity = (p_ptr->msane - p_ptr->csane) * 100 / p_ptr->msane; - char sfail[80]; - - /* Flush input if told so */ - if (flush_failure) flush(); - - /* Insane players can see something strange */ - if (rand_int(100) < insanity) - { - get_rnd_line("sfail.txt", sfail); - msg_format("A cloud of %s appears above you.", sfail); - } - - /* Normal failure messages */ - else - { - msg_print("You failed to get the spell off!"); - } - - sound(SOUND_FAIL); - - if (is_magestaff()) energy_use = 80; - else energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); - return (mana_used); - } - - if (spell->rune2 & RUNE_POWER_SURGE) - { - flg |= (PROJECT_VIEWABLE); - ty = p_ptr->py; - tx = p_ptr->px; - } - - if (spell->rune2 & RUNE_ARMAGEDDON) - { - flg |= (PROJECT_THRU); - flg |= (PROJECT_KILL); - flg |= (PROJECT_ITEM); - flg |= (PROJECT_GRID); - flg |= (PROJECT_METEOR_SHOWER); - rad = (power / 8 == 0) ? 1 : power / 8; - rad = (rad > 10) ? 10 : rad; - ty = p_ptr->py; - tx = p_ptr->px; - } - - if (spell->rune2 & RUNE_SPHERE) - { - flg |= (PROJECT_THRU); - flg |= (PROJECT_KILL); - flg |= (PROJECT_ITEM); - flg |= (PROJECT_GRID); - rad = (power / 8 == 0) ? 1 : power / 8; - rad = (rad > 10) ? 10 : rad; - ty = p_ptr->py; - tx = p_ptr->px; - } - - if (spell->rune2 & RUNE_RAY) - { - flg |= (PROJECT_THRU); - flg |= (PROJECT_KILL); - flg |= (PROJECT_BEAM); - ty = -1; - tx = -1; - } - if (spell->rune2 & RUNE_ARROW) - { - flg |= (PROJECT_THRU); - flg |= (PROJECT_STOP); - flg |= (PROJECT_KILL); - ty = -1; - tx = -1; - } - if (spell->rune2 & RUNE_SELF) - { - flg |= (PROJECT_THRU); - flg |= (PROJECT_STOP); - flg |= (PROJECT_KILL); - ty = p_ptr->py; - tx = p_ptr->px; - unsafe = TRUE; - } - - if ((ty == -1) && (tx == -1)) - { - if (!get_aim_dir(&dir)) return (mana_used); - - /* Use the given direction */ - tx = p_ptr->px + ddx[dir]; - ty = p_ptr->py + ddy[dir]; - - /* Hack -- Use an actual "target" */ - if ((dir == 5) && target_okay()) - { - tx = target_col; - ty = target_row; - } - } - - if (flg & PROJECT_VIEWABLE) - { - project_hack(spell->type, dam); - } - else if (flg & PROJECT_METEOR_SHOWER) - { - project_meteor(rad, spell->type, dam, flg); - } - else project(0, rad, ty, tx, dam, spell->type, flg); - - if (unsafe) unsafe = FALSE; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); - - return (mana_used); -} - - -/* - * Test if all runes needed at in the player p_ptr->inventory - */ -bool_ test_runespell(rune_spell *spell) -{ - int i; - - object_type *o_ptr; - - bool_ typeok = FALSE; - - int rune2 = 0; - - - for (i = 0; i < INVEN_WIELD; i++) - { - o_ptr = &p_ptr->inventory[i]; - - if (!o_ptr->k_idx) continue; - - /* Does the rune1(type) match ? */ - if ((o_ptr->tval == TV_RUNE1) && (o_ptr->sval == spell->type)) - { - typeok = TRUE; - } - - if ((o_ptr->tval == TV_RUNE2) && (o_ptr->sval != RUNE_STONE)) - { - /* Add it to the list */ - rune2 |= 1 << o_ptr->sval; - } - } - - /* Need all runes to be present */ - return (typeok && ((rune2 & spell->rune2) == spell->rune2)); -} - - -/* - * Ask for rune, rune2 and mana - */ -bool_ get_runespell(rune_spell *spell) -{ - s32b rune_combine = 0; - - /* Lambda to use for selecting the secondary rune(s) */ - auto rune2_filter = [&](object_type const *o_ptr) -> bool { - return ((o_ptr->tval == TV_RUNE2) && - (o_ptr->sval != RUNE_STONE) && - (!(rune_combine & BIT(o_ptr->sval)))); - }; - - /* Prompt */ - const char *const q = "Use which rune? "; - const char *const s = "You have no rune to use."; - - /* Extract first rune for the base effect */ - int type = 0; - { - int item; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), object_filter::TVal(TV_RUNE1))) - { - return FALSE; - } - - object_type *o_ptr = get_object(item); - type = o_ptr->sval; - } - - /* Choose secondary rune(s) */ - int rune2 = 0; - while (1) - { - int item; - if (!get_item(&item, q, nullptr, (USE_INVEN | USE_FLOOR), rune2_filter)) - { - break; - } - - object_type *o_ptr = get_object(item); - - rune_combine |= 1 << o_ptr->sval; - rune2 |= 1 << o_ptr->sval; - } - - if (!rune2) - { - msg_print("You have not selected a second rune!"); - return (FALSE); - } - - int power_rune = 0; - int plev = get_skill(SKILL_RUNECRAFT); - s32b power = get_quantity("Which amount of Mana? ", - p_ptr->csp - (power_rune * (plev / 5))); - if (power < 1) - { - power = 1; - } - - spell->mana = power; - spell->type = type; - spell->rune2 = rune2; - - return (TRUE); -} - - -void do_cmd_rune(void) -{ - rune_spell spell; - - - /* Require some mana */ - if (p_ptr->csp <= 0) - { - msg_print("You have no mana!"); - return; - } - - /* Require lite */ - if (p_ptr->blind || no_lite()) - { - msg_print("You cannot see!"); - return; - } - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - if (!get_runespell(&spell)) return; - - /* Execute at normal mana cost */ - p_ptr->csp -= rune_exec(&spell, 100); - - /* Safety :) */ - if (p_ptr->csp < 0) p_ptr->csp = 0; - - /* Take a turn */ - if (is_magestaff()) energy_use = 80; - else energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -/* - * Print a batch of runespells. - */ -static void print_runespell_batch(int batch, int max) -{ - char buff[80]; - - rune_spell* spell; - - int i; - - s32b power, powerdiv; - - int p, dp; - - - prt(format(" %-30s Fail Mana Power", "Name"), 1, 20); - - for (i = 0; i < max; i++) - { - spell = &rune_spells[batch * 10 + i]; - - power = spell->mana; - rune_calc_power(&power, &powerdiv); - p = power; - dp = powerdiv; - - strnfmt(buff, 80, " %c) %-30s %4d%% %4d %dd%d ", I2A(i), spell->name, - spell_chance_rune(spell), spell->mana, dp, p); - - prt(buff, 2 + i, 20); - } - prt("", 2 + i, 20); -} - - - -/* - * List ten random spells and ask to pick one. - */ - -static rune_spell* select_runespell_from_batch(int batch, int *s_idx) -{ - char tmp[160]; - - char out_val[30]; - - char which; - - int mut_max = 10; - - rune_spell* ret; - - - character_icky = TRUE; - - if (rune_num < (batch + 1) * 10) - { - mut_max = rune_num - batch * 10; - } - - strnfmt(tmp, 160, "(a-%c, * to list, / to rename, - to comment) Select a power: ", - I2A(mut_max - 1)); - - prt(tmp, 0, 0); - - while (1) - { - Term_save(); - - print_runespell_batch(batch, mut_max); - - which = inkey(); - - Term_load(); - - if (which == ESCAPE) - { - *s_idx = -1; - ret = NULL; - break; - } - else if ((which == '*') || (which == '?') || (which == ' ')) - { - print_runespell_batch(batch, mut_max); - } - else if ((which == '\r') && (mut_max == 1)) - { - *s_idx = batch * 10; - ret = &rune_spells[batch * 10]; - break; - } - else if (which == '/') - { - prt("Rename which power: ", 0, 0); - which = tolower(inkey()); - - if (isalpha(which) && (A2I(which) <= mut_max)) - { - strcpy(out_val, rune_spells[batch*10 + A2I(which)].name); - if (get_string("Name this power: ", out_val, 29)) - { - strcpy(rune_spells[batch*10 + A2I(which)].name, out_val); - } - prt(tmp, 0, 0); - } - else - { - bell(); - prt(tmp, 0, 0); - } - } - else - { - which = tolower(which); - if (isalpha(which) && (A2I(which) < mut_max)) - { - *s_idx = batch * 10 + A2I(which); - ret = &rune_spells[batch * 10 + A2I(which)]; - break; - } - else - { - bell(); - } - } - } - - character_icky = FALSE; - - return (ret); -} - - -/* - * Pick a random spell from a menu - */ - -rune_spell* select_runespell(int *s_idx) -{ - char tmp[160]; - - char which; - - int batch_max = (rune_num - 1) / 10; - - if (rune_num == 0) - { - msg_print("There are no runespells you can cast."); - return (NULL); - } - - character_icky = TRUE; - Term_save(); - - strnfmt(tmp, 160, "(a-%c) Select batch of powers: ", I2A(batch_max)); - - prt(tmp, 0, 0); - - while (1) - { - which = inkey(); - - if (which == ESCAPE) - { - Term_load(); - character_icky = FALSE; - return (NULL); - } - else if ((which == '\r') && (batch_max == 0)) - { - Term_load(); - character_icky = FALSE; - return (select_runespell_from_batch(0, s_idx)); - - } - else - { - which = tolower(which); - if (isalpha(which) && (A2I(which) <= batch_max)) - { - Term_load(); - character_icky = FALSE; - return (select_runespell_from_batch(A2I(which), s_idx)); - } - else - { - bell(); - } - } - } -} - - -/* - * Cast a memorized runespell - * Note that the only limits are antimagic & conf, NOT blind - */ -void do_cmd_rune_cast() -{ - rune_spell *s_ptr; - - int s_idx; - - - /* Require some mana */ - if (p_ptr->csp <= 0) - { - msg_print("You have no mana!"); - return; - } - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - /* No magic */ - if (p_ptr->anti_magic) - { - msg_print("Your anti-magic shell disrupts any magic attempts."); - return; - } - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - s_ptr = select_runespell(&s_idx); - - if (s_ptr == NULL) return; - - /* Need the runes */ - if (!test_runespell(s_ptr)) - { - msg_print("You lack some essential rune(s) for this runespell!"); - return; - } - - /* Execute at normal mana cost */ - p_ptr->csp -= rune_exec(s_ptr, 100); - - /* Safety :) */ - if (p_ptr->csp < 0) p_ptr->csp = 0; - - /* Take a turn */ - if (is_magestaff()) energy_use = 80; - else energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -/* - * Cast a runespell from a carved runestone - */ -void do_cmd_runestone() -{ - rune_spell s_ptr; - - int item; - - - /* Require some mana */ - if (p_ptr->csp <= 0) - { - msg_print("You have no mana!"); - return; - } - - /* Require lite */ - if (p_ptr->blind || no_lite()) - { - msg_print("You cannot see!"); - return; - } - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - /* No magic */ - if (p_ptr->anti_magic) - { - msg_print("Your anti-magic shell disrupts any magic attempts."); - return; - } - - /* Get an item */ - if (!get_item(&item, - "Cast from which runestone? ", - "You have no runestone to cast from.", - (USE_INVEN | USE_FLOOR), - item_tester_hook_runestone_full)) - { - return; - } - - /* Get the item */ - object_type *o_ptr = get_object(item); - - s_ptr.type = o_ptr->pval; - s_ptr.rune2 = o_ptr->pval2; - s_ptr.mana = o_ptr->pval3; - - /* Execute less mana */ - p_ptr->csp -= rune_exec(&s_ptr, 75); - - /* Safety :) */ - if (p_ptr->csp < 0) p_ptr->csp = 0; - - /* Take a turn */ - energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -/* - * Add a runespell to the list - */ -void do_cmd_rune_add_mem() -{ - rune_spell s_ptr; - - rune_spell *ds_ptr = &rune_spells[rune_num]; - - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - - if (rune_num >= MAX_RUNES) - { - msg_print("You have already learned the maximum number of runespells!"); - return; - } - - if (!get_runespell(&s_ptr)) return; - - ds_ptr->type = s_ptr.type; - ds_ptr->rune2 = s_ptr.rune2; - ds_ptr->mana = s_ptr.mana; - strcpy(ds_ptr->name, "Unnamed Runespell"); - - get_string("Name this runespell: ", ds_ptr->name, 29); - - rune_num++; - - /* Take a turn */ - energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -/* - * Carve a runespell onto a Runestone - */ -void do_cmd_rune_carve() -{ - rune_spell s_ptr; - - int item, i; - - char out_val[80]; - - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - /* Require lite */ - if (p_ptr->blind || no_lite()) - { - msg_print("You cannot see!"); - return; - } - - if (!get_check("Beware, this will destroy the involved runes, continue?")) - { - return; - } - - if (!get_runespell(&s_ptr)) return; - - /* Get an item */ - if (!get_item(&item, - "Use which runestone? ", - "You have no runestone to use.", - (USE_INVEN | USE_FLOOR), - item_tester_hook_runestone)) - { - return; - } - - /* Get the item */ - object_type *o_ptr = get_object(item); - - o_ptr->pval = s_ptr.type; - o_ptr->pval2 = s_ptr.rune2; - o_ptr->pval3 = s_ptr.mana; - - /* Start with nothing */ - strcpy(out_val, ""); - - /* Use old inscription */ - if (o_ptr->note) - { - /* Start with the old inscription */ - strcpy(out_val, quark_str(o_ptr->note)); - } - - /* Get a new inscription (possibly empty) */ - if (get_string("Name this runestone: ", out_val, 80)) - { - /* Save the inscription */ - o_ptr->note = quark_add(out_val); - - /* Combine the pack */ - p_ptr->notice |= (PN_COMBINE); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - } - - /* Delete the runes */ - for (i = 0; i < INVEN_WIELD; i++) - { - o_ptr = &p_ptr->inventory[i]; - - if (o_ptr->k_idx) - { - bool_ do_del = FALSE; - - if ((o_ptr->tval == TV_RUNE1) && (o_ptr->sval == s_ptr.type)) do_del = TRUE; - if ((o_ptr->tval == TV_RUNE2) && (BIT(o_ptr->sval) & s_ptr.rune2)) do_del = TRUE; - - if (do_del) - { - inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - } - } - } - - /* Take a turn -- Carving takes a LONG time */ - energy_use = 400; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -/* - * Remove a runespell - */ -void do_cmd_rune_del() -{ - rune_spell *s_ptr; - - int s_idx; - - int i; - - - /* Not when confused */ - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - s_ptr = select_runespell(&s_idx); - - if (s_ptr == NULL) return; - - /* Delete and move */ - for (i = s_idx + 1; i < rune_num; i++) - { - rune_spells[i - 1].type = rune_spells[i].type; - rune_spells[i - 1].rune2 = rune_spells[i].rune2; - rune_spells[i - 1].mana = rune_spells[i].mana; - strcpy(rune_spells[i - 1].name, rune_spells[i].name); - } - rune_num--; - - /* Take a turn */ - energy_use = 100; - - /* Window stuff */ - p_ptr->window |= (PW_PLAYER); - p_ptr->redraw |= (PR_FRAME); -} - - -void do_cmd_rune_add() -{ - int ext = 0; - - char ch; - - - /* Select what to do */ - while (TRUE) - { - if (!get_com("Add to [M]emory(need runes to cast) or " - "Carve a [R]unestone(less mana to cast)", &ch)) - { - ext = 0; - break; - } - if ((ch == 'M') || (ch == 'm')) - { - ext = 1; - break; - } - if ((ch == 'R') || (ch == 'r')) - { - ext = 2; - break; - } - } - - switch (ext) - { - /* Create a Spell in memory */ - case 1: - { - do_cmd_rune_add_mem(); - break; - } - - /* Carve a Runestone */ - case 2: - { - do_cmd_rune_carve(); - break; - } - } -} - - -void do_cmd_runecrafter() -{ - int ext = 0; - - char ch; - - - /* Select what to do */ - while (TRUE) - { - if (!get_com("Rune Spell:[C]reate, [D]elete, C[a]st, D[i]rectly Cast " - "or Use [R]unestone", &ch)) - { - ext = 0; - break; - } - if ((ch == 'C') || (ch == 'c')) - { - ext = 1; - break; - } - if ((ch == 'D') || (ch == 'd')) - { - ext = 2; - break; - } - if ((ch == 'A') || (ch == 'a')) - { - ext = 3; - break; - } - if ((ch == 'I') || (ch == 'i')) - { - ext = 4; - break; - } - if ((ch == 'R') || (ch == 'r')) - { - ext = 5; - break; - } - } - - switch (ext) - { - /* Create a Spell */ - case 1: - { - do_cmd_rune_add(); - break; - } - - /* Delete a Spell */ - case 2: - { - do_cmd_rune_del(); - break; - } - - /* Cast a Spell */ - case 3: - { - do_cmd_rune_cast(); - break; - } - - /* Directly Cast a Spell */ - case 4: - { - do_cmd_rune(); - break; - } - - /* Cast a Runestone */ - case 5: - { - do_cmd_runestone(); - break; - } - } -} - - void do_cmd_unbeliever_antimagic() { if (get_skill(SKILL_ANTIMAGIC) < 20) @@ -3572,7 +2424,7 @@ void do_cmd_unbeliever() /* Select what to do */ while (TRUE) { - if (!get_com("Disrupt [C]ontinuum or [D]etect Traps", &ch)) + if (!get_com("Disrupt [C]ontinuum or [D]estroy Doors", &ch)) { ext = 0; break; @@ -3598,20 +2450,18 @@ void do_cmd_unbeliever() break; } - /* Detect Traps */ + /* Destroy Doors */ case 2: { s16b skill = get_skill(SKILL_ANTIMAGIC); if (skill < 25) { - msg_print("You cannot use your detection abilities yet."); + msg_print("You cannot use your door destruction abilities yet."); break; } - detect_traps(DEFAULT_RADIUS); - - if (skill >= 35) destroy_doors_touch(); + destroy_doors_touch(); break; } @@ -3638,6 +2488,8 @@ static object_filter_t const &item_tester_hook_totemable() */ void do_cmd_summoner_extract() { + auto const &r_info = game->edit_data.r_info; + object_type forge, *q_ptr; /* Not when confused */ @@ -3669,7 +2521,7 @@ void do_cmd_summoner_extract() object_type *o_ptr = get_object(item); bool_ partial; - if (r_info[o_ptr->pval2].flags1 & RF1_UNIQUE) + if (r_info[o_ptr->pval2].flags & RF_UNIQUE) { partial = FALSE; } @@ -3701,7 +2553,7 @@ void do_cmd_summoner_extract() object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_MENTAL; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); msg_print("You extract a totem from the dead corpse."); energy_use += 100; @@ -3710,15 +2562,17 @@ void do_cmd_summoner_extract() void summon_true(int r_idx, int item) { + auto const &r_info = game->edit_data.r_info; + int i, status, x = 1, y = 1, rx, ry = 0, chance; bool_ used; - monster_race *r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; /* Uniques are less likely to be nice */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { /* Because it's unique, it will always be destroyed */ used = TRUE; @@ -3877,7 +2731,7 @@ void do_cmd_summoner_summon() } -void do_cmd_summoner(void) +void do_cmd_summoner() { int ext = 0; @@ -3951,7 +2805,7 @@ void do_cmd_summoner(void) /* * Dodge Chance Feedback. */ -void use_ability_blade(void) +void use_ability_blade() { int chance = p_ptr->dodge_chance - ((dun_level * 5) / 6); @@ -4017,7 +2871,7 @@ void symbiotic_info(char *p, int power) /* * Cast a symbiotic spell */ -void do_cmd_symbiotic(void) +void do_cmd_symbiotic() { int n = 0; int chance; @@ -4089,14 +2943,11 @@ void do_cmd_symbiotic(void) /* Failed spell */ if (rand_int(100) < chance) { - if (flush_failure) flush(); + flush_on_failure(); msg_format("You failed to concentrate hard enough!"); - sound(SOUND_FAIL); } else { - sound(SOUND_ZAP); - /* spell code */ switch (n) { @@ -4118,7 +2969,7 @@ void do_cmd_symbiotic(void) m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if (!(r_ptr->flags1 & RF1_NEVER_MOVE)) + if (!(r_ptr->flags & RF_NEVER_MOVE)) { msg_print("You can only hypnotise monsters that cannot move."); } @@ -4126,7 +2977,7 @@ void do_cmd_symbiotic(void) { msg_print("You can only hypnotise pets and companions."); } - else if (r_ptr->flags9 & RF9_SPECIAL_GENE) + else if (r_ptr->flags & RF_SPECIAL_GENE) { msg_print("You cannot hypnotise this monster."); } @@ -4270,7 +3121,7 @@ void do_cmd_symbiotic(void) break; } - if (0 > use_symbiotic_power(o_ptr->pval, FALSE, FALSE, TRUE)) + if (0 > use_symbiotic_power(o_ptr->pval, false)) return; break; @@ -4291,7 +3142,7 @@ void do_cmd_symbiotic(void) o_ptr->pval2 += hp; if (o_ptr->pval2 > o_ptr->pval3) o_ptr->pval2 = o_ptr->pval3; - msg_format("%s is healed.", symbiote_name(TRUE)); + msg_format("%s is healed.", symbiote_name(true).c_str()); /* Display the monster hitpoints */ p_ptr->redraw |= (PR_FRAME); @@ -4309,7 +3160,7 @@ void do_cmd_symbiotic(void) break; } - if(0 > use_symbiotic_power(o_ptr->pval, TRUE, FALSE, TRUE)) + if(0 > use_symbiotic_power(o_ptr->pval, true)) return; break; @@ -4327,17 +3178,14 @@ void do_cmd_symbiotic(void) case 8: { int y, x; - cave_type *c_ptr; - monster_type *m_ptr; - if (!tgt_pt(&x, &y)) return; - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; if (!c_ptr->m_idx) break; - m_ptr = &m_list[c_ptr->m_idx]; - use_symbiotic_power(m_ptr->r_idx, TRUE, FALSE, TRUE); + monster_type *m_ptr = &m_list[c_ptr->m_idx]; + use_symbiotic_power(m_ptr->r_idx, true); break; } @@ -4375,7 +3223,7 @@ void do_cmd_symbiotic(void) msg_print("You faint from the effort!"); /* Hack -- Bypass free action */ - (void)set_paralyzed(randint(5 * oops + 1)); + set_paralyzed(randint(5 * oops + 1)); /* Damage CON (possibly permanently) */ if (rand_int(100) < 50) @@ -4386,7 +3234,7 @@ void do_cmd_symbiotic(void) msg_print("You have damaged your body!"); /* Reduce constitution */ - (void)dec_stat(A_CHR, 15 + randint(10), perm); + dec_stat(A_CHR, 15 + randint(10), perm); } } @@ -4419,7 +3267,7 @@ void do_cmd_create_boulder() object_type forge; object_type *q_ptr; - (void)wall_to_mud(dir); + wall_to_mud(dir); /* Get local object */ q_ptr = &forge; @@ -4433,7 +3281,7 @@ void do_cmd_create_boulder() q_ptr->discount = 90; q_ptr->found = OBJ_FOUND_SELFMADE; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); msg_print("You make some boulders."); @@ -4448,7 +3296,7 @@ void do_cmd_create_boulder() /* * Clamp failure chance */ -extern int clamp_failure_chance(int chance, int minfail) +int clamp_failure_chance(int chance, int minfail) { if (minfail < 0) minfail = 0; diff --git a/src/cmd7.hpp b/src/cmd7.hpp index 162e5461..b9d518b2 100644 --- a/src/cmd7.hpp +++ b/src/cmd7.hpp @@ -1,28 +1,25 @@ #pragma once #include "h-basic.h" -#include "rune_spell_fwd.hpp" #include "object_type_fwd.hpp" -extern void do_cmd_pray(void); -extern void do_cmd_create_boulder(void); -extern int rune_exec(rune_spell *spell, int cost); -extern void necro_info(char *p, int power); -extern void mindcraft_info(char *p, int power); -extern void symbiotic_info(char *p, int power); -extern void mimic_info(char *p, int power); -extern void do_cmd_summoner(void); -extern void do_cmd_mindcraft(void); -extern void do_cmd_mimic(void); -extern void use_ability_blade(void); -extern void do_cmd_beastmaster(void); -extern void do_cmd_powermage(void); -extern void do_cmd_possessor(void); -extern void do_cmd_archer(void); -extern void do_cmd_set_piercing(void); -extern void do_cmd_necromancer(void); -extern void do_cmd_unbeliever(void); -extern void do_cmd_runecrafter(void); -extern void do_cmd_symbiotic(void); -extern s32b sroot(s32b n); -extern int clamp_failure_chance(int chance, int minfail); +void do_cmd_pray(); +void do_cmd_create_boulder(); +void necro_info(char *p, int power); +void mindcraft_info(char *p, int power); +void symbiotic_info(char *p, int power); +void mimic_info(char *p, int power); +void do_cmd_summoner(); +void do_cmd_mindcraft(); +void do_cmd_mimic(); +void use_ability_blade(); +void do_cmd_beastmaster(); +void do_cmd_powermage(); +void do_cmd_possessor(); +void do_cmd_archer(); +void do_cmd_set_piercing(); +void do_cmd_necromancer(); +void do_cmd_unbeliever(); +void do_cmd_symbiotic(); +s32b sroot(s32b n); +int clamp_failure_chance(int chance, int minfail); diff --git a/src/corrupt.cc b/src/corrupt.cc index f182a9e2..bd3ae5f0 100644 --- a/src/corrupt.cc +++ b/src/corrupt.cc @@ -1,7 +1,10 @@ #include "corrupt.hpp" +#include "game.hpp" #include "init1.hpp" +#include "object_flag.hpp" #include "player_race.hpp" +#include "player_race_flag.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" #include "stats.hpp" @@ -12,6 +15,7 @@ #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> /** * Corruptions @@ -38,45 +42,40 @@ struct corruption_type static void subrace_add_power(player_race_mod *rmp_ptr, int power) { - int i; - - for (i=0; i<4; i++) - { - if (rmp_ptr->powers[i] == -1) - { - rmp_ptr->powers[i] = power; - return; - } - } + rmp_ptr->ps.powers.push_back(power); } static void player_gain_vampire_teeth() { + auto &race_mod_info = game->edit_data.race_mod_info; + player_race_mod *rmp_ptr = NULL; switch_subrace(SUBRACE_SAVE, TRUE); rmp_ptr = &race_mod_info[SUBRACE_SAVE]; subrace_add_power(rmp_ptr, PWR_VAMPIRISM); - rmp_ptr->flags1 = rmp_ptr->flags1 - | PR1_VAMPIRE - | PR1_UNDEAD - | PR1_NO_SUBRACE_CHANGE; + rmp_ptr->flags = rmp_ptr->flags + | PR_VAMPIRE + | PR_UNDEAD + | PR_NO_SUBRACE_CHANGE; } static void player_gain_vampire_strength() { + auto &race_mod_info = game->edit_data.race_mod_info; + player_race_mod *rmp_ptr = &race_mod_info[SUBRACE_SAVE]; - /* Apply the bonuses/penalities */ - rmp_ptr->r_mhp = rmp_ptr->r_mhp + 1; - rmp_ptr->r_exp = rmp_ptr->r_exp + 100; - rmp_ptr->r_adj[A_STR] = rmp_ptr->r_adj[A_STR] + 3; - rmp_ptr->r_adj[A_INT] = rmp_ptr->r_adj[A_INT] + 2; - rmp_ptr->r_adj[A_WIS] = rmp_ptr->r_adj[A_WIS] - 3; - rmp_ptr->r_adj[A_DEX] = rmp_ptr->r_adj[A_DEX] - 2; - rmp_ptr->r_adj[A_CON] = rmp_ptr->r_adj[A_CON] + 1; - rmp_ptr->r_adj[A_CHR] = rmp_ptr->r_adj[A_CHR] - 4; + rmp_ptr->ps.mhp += +1; + rmp_ptr->ps.exp += +100; + + rmp_ptr->ps.adj[A_STR] += +3; + rmp_ptr->ps.adj[A_INT] += +2; + rmp_ptr->ps.adj[A_WIS] += -3; + rmp_ptr->ps.adj[A_DEX] += -2; + rmp_ptr->ps.adj[A_CON] += +1; + rmp_ptr->ps.adj[A_CHR] += -4; /* be reborn! */ do_rebirth(); @@ -85,33 +84,29 @@ static void player_gain_vampire_strength() static void player_gain_vampire() { + auto &race_mod_info = game->edit_data.race_mod_info; + player_race_mod *rmp_ptr = &race_mod_info[SUBRACE_SAVE]; - /* Be a Vampire and be proud of it */ - cptr title = rmp_ptr->title; - if (streq(title, "Vampire")) + if (rmp_ptr->title == "Vampire") { - title = "Vampire"; rmp_ptr->place = FALSE; - set_subrace_title(rmp_ptr, title); } else { - char buf[512]; - sprintf(buf, "Vampire %s", title); - set_subrace_title(rmp_ptr, buf); + rmp_ptr->title = fmt::format("Vampire {}", rmp_ptr->title); } /* Bonus/and .. not bonus :) */ - rmp_ptr->flags1 = rmp_ptr->flags1 | PR1_HURT_LITE; - rmp_ptr->oflags2[2] = rmp_ptr->oflags2[2] - | TR2_RES_POIS - | TR2_RES_NETHER - | TR2_RES_COLD - | TR2_RES_DARK - | TR2_HOLD_LIFE; - rmp_ptr->oflags3[2] = rmp_ptr->oflags3[2] - | TR3_LITE1; + rmp_ptr->flags |= PR_HURT_LITE; + rmp_ptr->lflags[1].oflags |= + ( TR_RES_POIS + | TR_RES_NETHER + | TR_RES_COLD + | TR_RES_DARK + | TR_HOLD_LIFE + | TR_LITE1 + ); } /** @@ -706,7 +701,7 @@ static bool_ player_can_gain_corruption(int corruption_idx) if (corruption_idx == CORRUPT_TROLL_BLOOD) { /* Ok trolls should not get this one. never. */ - if (streq(rp_ptr->title, "Troll")) + if (rp_ptr->title == "Troll") { allowed = FALSE; } @@ -716,7 +711,7 @@ static bool_ player_can_gain_corruption(int corruption_idx) if (game_module_idx == MODULE_THEME) { - if (streq(rp_ptr->title, "Maia")) + if (rp_ptr->title == "Maia") { /* We use a whitelist of corruptions for Maiar */ bool_ allow = FALSE; @@ -764,7 +759,7 @@ static bool_ player_allow_corruption(int corruption_idx) /* Vampire teeth is special */ if (corruption_idx == CORRUPT_VAMPIRE_TEETH) { - if (race_flags1_p(PR1_NO_SUBRACE_CHANGE)) + if (race_flags_p(PR_NO_SUBRACE_CHANGE)) { return TRUE; } @@ -944,20 +939,18 @@ void lose_corruption() /* * Dump the corruption list */ -void dump_corruptions(FILE *fff, bool_ color, bool_ header) +std::string dump_corruptions(bool color, bool header) { - int i; + fmt::MemoryWriter w; - assert(fff != NULL); - - for (i = 0; i < CORRUPTIONS_MAX; i++) + for (int i = 0; i < CORRUPTIONS_MAX; i++) { - corruption_type *c_ptr = &corruptions[i]; + corruption_type const *c_ptr = &corruptions[i]; if (header) { - fprintf(fff, "\n Corruption list:\n"); - header = FALSE; + w.write("\nCorruption list:\n\n"); + header = false; } if (p_ptr->corruptions[i]) @@ -966,16 +959,18 @@ void dump_corruptions(FILE *fff, bool_ color, bool_ header) if (color) { - fprintf(fff, "#####%c%s:\n", conv_color[c], c_ptr->name); + w.write("#####{}{}:\n", static_cast<char>(conv_color[c]), c_ptr->name); } else { - fprintf(fff, "%s:\n", c_ptr->name); + w.write("{}:\n", c_ptr->name); } - fprintf(fff, "%s\n", c_ptr->desc); + w.write("{}\n\n", c_ptr->desc); } } + + return w.str(); } /* diff --git a/src/corrupt.hpp b/src/corrupt.hpp index c200762e..77a7496e 100644 --- a/src/corrupt.hpp +++ b/src/corrupt.hpp @@ -1,11 +1,13 @@ #include "h-basic.h" -extern void gain_random_corruption(); -extern void dump_corruptions(FILE *OutFile, bool_ color, bool_ header); -extern void lose_corruption(); -extern bool_ player_has_corruption(int corruption_idx); -extern void player_gain_corruption(int corruption_idx); -extern s16b get_corruption_power(int corruption_idx); +#include <string> + +void gain_random_corruption(); +std::string dump_corruptions(bool color, bool header); +void lose_corruption(); +bool_ player_has_corruption(int corruption_idx); +void player_gain_corruption(int corruption_idx); +s16b get_corruption_power(int corruption_idx); /* * Corruptions diff --git a/src/defines.h b/src/defines.h index fc1f61f5..4a2ad0e0 100644 --- a/src/defines.h +++ b/src/defines.h @@ -37,8 +37,8 @@ */ #ifndef IS_CVS -/* #define IS_CVS " (ah)" */ -#define IS_CVS " (ah, git)" +#define IS_CVS " (ah)" +/* #define IS_CVS " (ah, git)" */ #endif #define USER_PATH_VERSION "/2.4" @@ -114,26 +114,19 @@ */ #define DEFAULT_RADIUS 25 - -#define CHANCE_TRAP_JAMMED_DOOR 2500 -#define CHANCE_TRAP_SECRET_DOOR 1500 -#define CHANCE_TRAP_LOCKED_DOOR 1000 -#define CHANCE_TRAP_DOOR 500 /* in 10000 */ -#define CHANCE_TRAP_FLOOR 4 /* in 10000 chance of placing a trap */ - #define MAX_SPELLS 100 #define MAX_RUNES 100 /* - * Total number of stores (see "store.c", etc) + * Total number of monster powers */ -#define STORE_GENERAL 0 -#define STORE_HOME 7 +#define MONSTER_POWERS_MAX 96 /* - * Maximum number of player "sex" types (see "table.c", etc) + * Total number of stores (see "store.c", etc) */ -#define MAX_SEXES 3 +#define STORE_GENERAL 0 +#define STORE_HOME 7 /* Number of Random Artifacts */ #define MAX_RANDARTS 84 @@ -383,63 +376,14 @@ #define MAX_STACK_SIZE 100 -/* - * Player sex constants (hard-coded by save-files, arrays, etc) - */ -#define SEX_FEMALE 0 -#define SEX_MALE 1 -#define SEX_NEUTER 2 - - -/* Race flags */ -#define PR1_EXPERIMENTAL 0x00000001L /* Is still under developemnt */ -/* XXX */ -#define PR1_RESIST_BLACK_BREATH 0x00000004L /* Resist black breath */ -#define PR1_NO_STUN 0x00000008L /* Never stunned */ -#define PR1_XTRA_MIGHT_BOW 0x00000010L /* Xtra might with bows */ -#define PR1_XTRA_MIGHT_XBOW 0x00000020L /* Xtra might with xbows */ -#define PR1_XTRA_MIGHT_SLING 0x00000040L /* Xtra might with slings */ -#define PR1_AC_LEVEL 0x00000080L /* More AC with levels */ -#define PR1_HURT_LITE 0x00000100L /* Hurt by light */ -#define PR1_VAMPIRE 0x00000200L /* Vampire */ -#define PR1_UNDEAD 0x00000400L /* Undead */ -#define PR1_NO_CUT 0x00000800L /* no cuts */ -#define PR1_CORRUPT 0x00001000L /* hack-- corrupted */ -#define PR1_NO_FOOD 0x00002000L /* little gain from food */ -#define PR1_NO_GOD 0x00004000L /* cannot worship */ -/* XXX */ -#define PR1_ELF 0x00010000L /* Is an elf */ -#define PR1_SEMI_WRAITH 0x00020000L /* Takes damage when going in walls */ -#define PR1_NO_SUBRACE_CHANGE 0x00040000L /* Impossible to change subrace */ -/* XXX */ -#define PR1_ANTIMAGIC 0x00100000L /* antimagic ... hack */ -#define PR1_MOLD_FRIEND 0x00200000L /* Not attacked by molds wielded */ -#define PR1_GOD_FRIEND 0x00400000L /* Better grace */ -/* XXX */ -#define PR1_INNATE_SPELLS 0x01000000L /* KNown all spells, only need books */ -/* XXX */ -/* XXX */ -#define PR1_EASE_STEAL 0x08000000L /* Gain xp by stealing */ -/* XXX */ -/* XXX */ -/* XXX */ -/* XXX */ - -/* XXX */ -#define PR2_ASTRAL 0x00000002L /* Is it an astral being coming from th halls of mandos ? */ -/* XXX */ - -/* XXX */ #define MKEY_MINDCRAFT 2 #define MKEY_ANTIMAGIC 3 #define MKEY_MIMIC 6 #define MKEY_NECRO 7 #define MKEY_POWER_MAGE 8 -#define MKEY_RUNE 9 #define MKEY_FORGING 10 #define MKEY_INCARNATION 11 #define MKEY_SUMMON 13 -#define MKEY_TRAP 14 #define MKEY_STEAL 15 #define MKEY_DODGE 16 #define MKEY_SCHOOL 17 @@ -535,9 +479,6 @@ /* Feature 0x10 -- web */ -/* Traps */ -#define FEAT_TRAP 0x11 - /* Features 0x12 - 0x1F -- unused */ /* Doors */ @@ -621,7 +562,6 @@ #define FEAT_MARKER 0xAC /* 172 */ /* Feature 0xAD -- Underground Tunnel */ #define FEAT_TAINTED_WATER 0xAE /* 174 */ -#define FEAT_MON_TRAP 0xAF /* 175 */ #define FEAT_BETWEEN2 0xB0 /* 176 */ #define FEAT_LAVA_WALL 0xB1 /* 177 */ #define FEAT_GREAT_FIRE 0xB2 /* 178 */ @@ -686,208 +626,13 @@ /*** Artifact indexes (see "lib/edit/a_info.txt") ***/ - -/* Lites */ -#define ART_GALADRIEL 1 -#define ART_ELENDIL 2 -#define ART_THRAIN 3 -#define ART_PALANTIR 202 -#define ART_UNDEATH 200 -#define ART_STONE_LORE 15 -#define ART_PALANTIR_ITHIL 208 - -/* Amulets */ -#define ART_CARLAMMAS 4 -#define ART_INGWE 5 -#define ART_DWARVES 6 #define ART_ANCHOR 14 -#define ART_ELESSAR 206 -#define ART_EVENSTAR 207 - -/* Rings */ -#define ART_FLAR 7 -#define ART_BARAHIR 8 -#define ART_TULKAS 9 -#define ART_NARYA 10 -#define ART_NENYA 11 -#define ART_VILYA 12 #define ART_POWER 13 -/* 14 used by the anchor of space-time */ -/* 15 used by the stone of lore */ - -/* Dragon Scale */ -#define ART_RAZORBACK 16 -#define ART_BLADETURNER 17 -#define ART_MEDIATOR 166 - -/* Hard Armour */ -#define ART_HIMRING 167 -#define ART_SOULKEEPER 19 -#define ART_ISILDUR 20 -#define ART_ROHIRRIM 21 -#define ART_BELEGENNON 22 -#define ART_CELEBORN 23 -#define ART_ARVEDUI 24 -#define ART_CASPANION 25 - -/* Thunderlord flying suit */ -#define ART_MARDA 26 -#define ART_TRON 27 - -/* Soft Armour */ -#define ART_THALKETTOTH 28 - -/* Shields */ -#define ART_THORIN 30 -#define ART_CELEGORM 31 -#define ART_ANARION 32 -#define ART_GILGALAD 169 -#define ART_HARADRIM 176 - -/* Helms and Crowns */ #define ART_MORGOTH 34 -#define ART_BERUTHIEL 35 -#define ART_THRANDUIL 36 -#define ART_THENGEL 37 -#define ART_HAMMERHAND 38 -#define ART_DOR 39 -#define ART_HOLHENNETH 40 -#define ART_GORLIM 41 -#define ART_GONDOR 42 -#define ART_KNOWLEDGE 160 -#define ART_NUMENOR 43 -#define ART_CELEBRIMBOR 170 - -/* Cloaks */ -#define ART_COLLUIN 44 -#define ART_HOLCOLLETH 45 -#define ART_THINGOL 46 -#define ART_THORONGIL 47 -#define ART_COLANNON 48 -#define ART_LUTHIEN 49 -#define ART_TUOR 50 - -/* Gloves */ -#define ART_CAMBELEG 52 -#define ART_CAMMITHRIM 53 -#define ART_PAURHACH 54 -#define ART_PAURNIMMEN 55 -#define ART_PAURAEGEN 56 -#define ART_PAURNEN 57 -#define ART_CAMLOST 58 -#define ART_FINGOLFIN 59 -#define ART_EOL 178 - -/* Boots */ -#define ART_FEANOR 60 -#define ART_DAL 61 -#define ART_THROR 62 - -/* Swords */ #define ART_NARSIL 164 -#define ART_MAEDHROS 64 -#define ART_ANGRIST 65 -#define ART_NARTHANC 66 -#define ART_NIMTHANC 67 -#define ART_DETHANC 68 -#define ART_RILIA 69 -#define ART_BELANGIL 70 -#define ART_CALRIS 71 -#define ART_ARUNRUTH 72 #define ART_GLAMDRING 73 -#define ART_AEGLIN 74 -#define ART_ORCRIST 75 -#define ART_GURTHANG 76 -#define ART_ZARCUTHRA 77 -#define ART_MORMEGIL 78 -#define ART_GONDRICAM 79 -#define ART_CRISDURIAN 80 -#define ART_AGLARANG 81 -#define ART_RINGIL 82 #define ART_ANDURIL 83 -#define ART_ANGUIREL 84 -#define ART_ELVAGIL 85 -#define ART_FORASGIL 86 -#define ART_CARETH 87 -#define ART_STING 88 -#define ART_HARADEKKET 89 -#define ART_GILETTAR 90 -#define ART_DOOMCALLER 91 -#define ART_VORPAL_BLADE 92 -#define ART_ERU 147 - -/* Polearms */ -#define ART_THEODEN 93 -#define ART_PAIN 94 -#define ART_OSONDIR 95 -#define ART_TIL 96 -#define ART_AEGLOS 97 -#define ART_OROME 98 -#define ART_NIMLOTH 99 -#define ART_EORLINGAS 100 -#define ART_DURIN 101 -#define ART_EONWE 102 -#define ART_BALLI 103 -#define ART_LOTHARANG 104 -#define ART_MUNDWINE 105 -#define ART_BARUKKHELED 106 -#define ART_WRATH 107 -#define ART_ULMO 108 -#define ART_AVAVIR 109 -#define ART_FUNDIN 175 - -/* The sword of the Dawn */ -#define ART_DAWN 110 - -/* Hafted */ -#define ART_MELKOR 18 -#define ART_HURIN 33 #define ART_GROND 111 -#define ART_TOTILA 112 -#define ART_THUNDERFIST 113 -#define ART_BLOODSPIKE 114 -#define ART_FIRESTAR 115 -#define ART_TARATOL 116 -#define ART_AULE 117 -#define ART_NAR 118 -#define ART_ERIRIL 119 -#define ART_OLORIN 120 -#define ART_DEATHWREAKER 121 -#define ART_TURMIL 122 -#define ART_GOTHMOG 123 -#define ART_AXE_GOTHMOG 145 -#define ART_SKULLCLEAVER 177 - -#define ART_NAIN 174 - -/* Bows */ -#define ART_BELTHRONDING 124 -#define ART_BARD 125 -#define ART_CUBRAGOL 126 -#define ART_UMBAR 171 - -/* Mage Staffs */ -#define ART_GANDALF 127 - -/* Boomerangs */ -#define ART_BEOR 128 -#define ART_GLIMDRIR 129 - -/* Musical Instrument */ -#define ART_MAGLOR 137 -#define ART_SKY 138 -#define ART_DAERON 139 -#define ART_DRUEDAIN 141 -#define ART_ROHAN 142 -#define ART_HELM 143 -#define ART_BOROMIR 144 - -/* Diggers */ -#define ART_EREBOR 140 - -#define ART_ORCHAST 156 -#define ART_NIGHT 157 -#define ART_NATUREBANE 158 /* Spell for various object */ #define SPELL_ID_PLAIN 1 @@ -908,7 +653,6 @@ #define EGO_MANA 1 #define EGO_POWER 2 #define EGO_MANA_POWER 3 -#define EGO_MSTAFF_SPELL 4 #define EGO_BRAND_POIS 77 #define EGO_BRAND_ELEC 74 #define EGO_BRAND_FIRE 75 @@ -991,7 +735,6 @@ #define ACT_FUNDIN 30 #define ACT_EOL 31 #define ACT_UMBAR 32 -#define ACT_NUMENOR 33 #define ACT_KNOWLEDGE 34 #define ACT_UNDEATH 35 #define ACT_THRAIN 36 @@ -1037,10 +780,6 @@ #define ACT_GANDALF 76 #define ACT_MARDA 77 #define ACT_PALANTIR 78 -/* - 79 - 80 -*/ #define ACT_CURE_LW 81 #define ACT_CURE_MW 82 #define ACT_CURE_POISON 83 @@ -1048,9 +787,6 @@ #define ACT_REST_ALL 85 #define ACT_CURE_700 86 #define ACT_CURE_1000 87 -/* - 88 -*/ #define ACT_EREBOR 89 #define ACT_DRUEDAIN 90 #define ACT_ESP 91 @@ -1221,7 +957,6 @@ #define TV_LITE 39 /* Lites (including Specials) */ #define TV_AMULET 40 /* Amulets (including Specials) */ #define TV_RING 45 /* Rings (including Specials) */ -#define TV_TRAPKIT 46 /* Trapkits */ #define TV_TOTEM 54 /* Summoner totems */ #define TV_STAFF 55 #define TV_WAND 65 @@ -1235,8 +970,6 @@ #define TV_HYPNOS 99 /* To wield monsters !:) */ #define TV_GOLD 100 /* Gold can only be picked up by players */ #define TV_RANDART 102 /* Random Artifacts */ -#define TV_RUNE1 104 /* Base runes */ -#define TV_RUNE2 105 /* Modifier runes */ #define TV_BOOK 111 #define TV_SYMBIOTIC_BOOK 112 @@ -1265,14 +998,6 @@ #define SV_HARP 59 #define SV_HORN 60 -/* The "sval" codes for TV_TRAPKIT */ -#define SV_TRAPKIT_SLING 1 -#define SV_TRAPKIT_BOW 2 -#define SV_TRAPKIT_XBOW 3 -#define SV_TRAPKIT_POTION 4 -#define SV_TRAPKIT_SCROLL 5 -#define SV_TRAPKIT_DEVICE 6 - /* The "sval" codes for TV_BOOMERANG */ #define SV_BOOM_S_WOOD 1 /* 1d4 */ #define SV_BOOM_WOOD 2 /* 1d8 */ @@ -1475,10 +1200,8 @@ /* The "sval" codes for TV_AMULET */ #define SV_AMULET_DOOM 0 #define SV_AMULET_TELEPORT 1 -#define SV_AMULET_ADORNMENT 2 #define SV_AMULET_SLOW_DIGEST 3 #define SV_AMULET_RESIST_ACID 4 -#define SV_AMULET_SEARCHING 5 #define SV_AMULET_BRILLANCE 6 #define SV_AMULET_CHARISMA 7 #define SV_AMULET_THE_MAGI 8 @@ -1529,7 +1252,6 @@ #define SV_RING_RESIST_POIS 20 #define SV_RING_FREE_ACTION 21 #define SV_RING_SEE_INVIS 22 -#define SV_RING_SEARCHING 23 #define SV_RING_STR 24 #define SV_RING_INT 25 #define SV_RING_DEX 26 @@ -1631,14 +1353,11 @@ #define SV_ROD_ILLUMINATION 4 #define SV_ROD_MAPPING 5 #define SV_ROD_DETECTION 6 -#define SV_ROD_PROBING 7 #define SV_ROD_CURING 8 #define SV_ROD_HEALING 9 #define SV_ROD_RESTORATION 10 #define SV_ROD_SPEED 11 -/* xxx (aimed) */ #define SV_ROD_TELEPORT_AWAY 13 -#define SV_ROD_DISARMING 14 #define SV_ROD_LITE 15 #define SV_ROD_SLEEP_MONSTER 16 #define SV_ROD_SLOW_MONSTER 17 @@ -1653,7 +1372,6 @@ #define SV_ROD_FIRE_BALL 26 #define SV_ROD_COLD_BALL 27 #define SV_ROD_HAVOC 28 -#define SV_ROD_DETECT_TRAP 29 #define SV_ROD_HOME 30 @@ -1679,7 +1397,6 @@ #define SV_SCROLL_SUMMON_MONSTER 4 #define SV_SCROLL_SUMMON_UNDEAD 5 #define SV_SCROLL_SUMMON_MINE 6 -#define SV_SCROLL_TRAP_CREATION 7 #define SV_SCROLL_PHASE_DOOR 8 #define SV_SCROLL_TELEPORT 9 #define SV_SCROLL_TELEPORT_LEVEL 10 @@ -1700,7 +1417,6 @@ #define SV_SCROLL_MAPPING 25 #define SV_SCROLL_DETECT_GOLD 26 #define SV_SCROLL_DETECT_ITEM 27 -#define SV_SCROLL_DETECT_TRAP 28 #define SV_SCROLL_DETECT_DOOR 29 #define SV_SCROLL_DETECT_INVIS 30 #define SV_SCROLL_DIVINATION 31 @@ -1711,7 +1427,6 @@ #define SV_SCROLL_MONSTER_CONFUSION 36 #define SV_SCROLL_PROTECTION_FROM_EVIL 37 #define SV_SCROLL_RUNE_OF_PROTECTION 38 -#define SV_SCROLL_TRAP_DOOR_DESTRUCTION 39 #define SV_SCROLL_DEINCARNATION 40 #define SV_SCROLL_STAR_DESTRUCTION 41 #define SV_SCROLL_DISPEL_UNDEAD 42 @@ -1743,7 +1458,6 @@ #define SV_POTION_SLEEP 11 #define SV_POTION_LEARNING 12 #define SV_POTION_LOSE_MEMORIES 13 -/* xxx */ #define SV_POTION_RUINATION 15 #define SV_POTION_DEC_STR 16 #define SV_POTION_DEC_INT 17 @@ -1783,11 +1497,9 @@ #define SV_POTION_INC_DEX 51 #define SV_POTION_INC_CON 52 #define SV_POTION_INC_CHR 53 -/* xxx */ #define SV_POTION_AUGMENTATION 55 #define SV_POTION_ENLIGHTENMENT 56 #define SV_POTION_STAR_ENLIGHTENMENT 57 -#define SV_POTION_SELF_KNOWLEDGE 58 #define SV_POTION_EXPERIENCE 59 #define SV_POTION_RESISTANCE 60 #define SV_POTION_CURING 61 @@ -1871,13 +1583,6 @@ */ #define SV_BOOK_MAX_GOOD 49 -/* flags for operation in get_random_trap in object3.c */ - -#define TRAP_EXISTS 0x00000001L -#define TRAP_FOUND 0x00000002L -#define TRAP_NOTFOUND 0x00000004L -#define TRAP_IDENTIFIED 0x00000008L - /*** General flag values ***/ @@ -1892,11 +1597,9 @@ #define CAVE_VIEW 0x0020 /* view flag */ #define CAVE_TEMP 0x0040 /* temp flag */ #define CAVE_WALL 0x0080 /* wall flag */ -#define CAVE_TRDT 0x0100 /* trap detected */ #define CAVE_IDNT 0x0200 /* grid identified (fountains) */ #define CAVE_SPEC 0x0400 /* special mark(quests) */ #define CAVE_FREE 0x0800 /* no random generation on it */ -#define CAVE_DETECT 0x1000 /* Traps detected here */ #define CAVE_PLIT 0x2000 /* Player lit grid */ #define CAVE_MLIT 0x4000 /* Monster lit grid */ @@ -1979,7 +1682,6 @@ #define SM_OPP_POIS 0x00100000 #define SM_OPP_XXX1 0x00200000 #define SM_CLONED 0x00400000 -#define SM_NOTE_TRAP 0x00800000 #define SM_IMM_ACID 0x01000000 #define SM_IMM_ELEC 0x02000000 #define SM_IMM_FIRE 0x04000000 @@ -2026,17 +1728,12 @@ #define PU_MANA 0x00000020L /* Calculate csp and msp */ #define PU_SPELLS 0x00000040L /* Calculate spells */ #define PU_POWERS 0x00000080L /* Calculate powers */ -/* xxx (many) */ #define PU_UN_VIEW 0x00010000L /* Forget view */ -/* xxx (many) */ #define PU_VIEW 0x00100000L /* Update view */ #define PU_MON_LITE 0x00200000L /* Update monster light */ -/* xxx */ #define PU_MONSTERS 0x01000000L /* Update monsters */ #define PU_DISTANCE 0x02000000L /* Update distances */ -/* xxx */ #define PU_FLOW 0x10000000L /* Update flow */ -/* xxx (many) */ /* @@ -2051,225 +1748,19 @@ */ #define PW_INVEN 0x00000001L /* Display inven/equip */ #define PW_EQUIP 0x00000002L /* Display equip/inven */ -/* xxx */ #define PW_PLAYER 0x00000008L /* Display character */ #define PW_M_LIST 0x00000010L /* Show monster list */ -/* xxx */ #define PW_MESSAGE 0x00000040L /* Display messages */ #define PW_OVERHEAD 0x00000080L /* Display overhead view */ #define PW_MONSTER 0x00000100L /* Display monster recall */ #define PW_OBJECT 0x00000200L /* Display object recall */ -/* xxx */ -#define PW_SNAPSHOT 0x00000800L /* Display snap-shot */ -/* xxx */ -/* xxx */ -#define PW_BORG_1 0x00004000L /* Display borg messages */ -#define PW_BORG_2 0x00008000L /* Display borg status */ /* jk */ -#define FTRAP_CHEST 0x000000001 /* may appear on chests */ -#define FTRAP_DOOR 0x000000002 /* may appear on doors/floors */ -#define FTRAP_FLOOR 0x000000004 /* may appear on floor */ -#define FTRAP_CHANGE 0x000000008 /* Color changing */ -#define FTRAP_XXX5 0x000000010 -#define FTRAP_XXX6 0x000000020 -#define FTRAP_XXX7 0x000000040 -#define FTRAP_XXX8 0x000000080 -#define FTRAP_XXX9 0x000000100 -#define FTRAP_XXX10 0x000000200 -#define FTRAP_XXX11 0x000000400 -#define FTRAP_XXX12 0x000000800 -#define FTRAP_XXX13 0x000001000 -#define FTRAP_XXX14 0x000002000 -#define FTRAP_XXX15 0x000004000 -#define FTRAP_XXX16 0x000008000 -#define FTRAP_LEVEL1 0x000010000 /* low level ball/bolt trap */ -#define FTRAP_LEVEL2 0x000020000 /* medium level ball/bolt trap */ -#define FTRAP_LEVEL3 0x000040000 /* high level ball/bolt trap */ -#define FTRAP_LEVEL4 0x000080000 /* oops level ball/bolt trap */ -#define FTRAP_XXX21 0x000100000 -#define FTRAP_XXX22 0x000200000 -#define FTRAP_XXX23 0x000400000 -#define FTRAP_XXX24 0x000800000 -#define FTRAP_XXX25 0x001000000 -#define FTRAP_XXX26 0x002000000 -#define FTRAP_XXX27 0x004000000 -#define FTRAP_XXX28 0x008000000 -#define FTRAP_XXX29 0x010000000 -#define FTRAP_XXX30 0x020000000 -#define FTRAP_XXX31 0x040000000 -#define FTRAP_XXX32 0x080000000 - -/* jk */ #define STAT_DEC_TEMPORARY 1 #define STAT_DEC_NORMAL 2 #define STAT_DEC_PERMANENT 3 -/* jk - which trap is which number */ -#define TRAP_OF_WEAKNESS_I 1 -#define TRAP_OF_WEAKNESS_II 2 -#define TRAP_OF_WEAKNESS_III 3 -#define TRAP_OF_INTELLIGENCE_I 4 -#define TRAP_OF_INTELLIGENCE_II 5 -#define TRAP_OF_INTELLIGENCE_III 6 -#define TRAP_OF_WISDOM_I 7 -#define TRAP_OF_WISDOM_II 8 -#define TRAP_OF_WISDOM_III 9 -#define TRAP_OF_FUMBLING_I 10 -#define TRAP_OF_FUMBLING_II 11 -#define TRAP_OF_FUMBLING_III 12 -#define TRAP_OF_WASTING_I 13 -#define TRAP_OF_WASTING_II 14 -#define TRAP_OF_WASTING_III 15 -#define TRAP_OF_BEAUTY_I 16 -#define TRAP_OF_BEAUTY_II 17 -#define TRAP_OF_BEAUTY_III 18 - -#define TRAP_OF_CURSE_WEAPON 20 -#define TRAP_OF_CURSE_ARMOR 21 -#define TRAP_OF_EARTHQUAKE 22 -#define TRAP_OF_POISON_NEEDLE 23 -#define TRAP_OF_SUMMON_MONSTER 24 -#define TRAP_OF_SUMMON_UNDEAD 25 -#define TRAP_OF_SUMMON_GREATER_UNDEAD 26 -#define TRAP_OF_TELEPORT 27 -#define TRAP_OF_PARALYZING 28 -#define TRAP_OF_EXPLOSIVE_DEVICE 29 -#define TRAP_OF_TELEPORT_AWAY 30 -#define TRAP_OF_LOSE_MEMORY 31 -#define TRAP_OF_BITTER_REGRET 32 -#define TRAP_OF_BOWEL_CRAMPS 33 -#define TRAP_OF_BLINDNESS_CONFUSION 34 -#define TRAP_OF_AGGRAVATION 35 -#define TRAP_OF_MULTIPLICATION 36 -#define TRAP_OF_STEAL_ITEM 37 -#define TRAP_OF_SUMMON_FAST_QUYLTHULGS 38 -#define TRAP_OF_SINKING 39 -#define TRAP_OF_MANA_DRAIN 40 -#define TRAP_OF_MISSING_MONEY 41 -#define TRAP_OF_NO_RETURN 42 -#define TRAP_OF_SILENT_SWITCHING 43 -#define TRAP_OF_WALLS 44 -#define TRAP_OF_CALLING_OUT 45 -#define TRAP_OF_SLIDING 46 -#define TRAP_OF_CHARGES_DRAIN 47 -#define TRAP_OF_STAIR_MOVEMENT 48 -#define TRAP_OF_NEW 49 -#define TRAP_OF_SCATTER_ITEMS 50 -#define TRAP_OF_DECAY 51 -#define TRAP_OF_WASTING_WANDS 52 -#define TRAP_OF_FILLING 53 -#define TRAP_OF_DRAIN_SPEED 54 - -#define TRAP_OF_ELEC_BOLT 60 -#define TRAP_OF_POIS_BOLT 61 -#define TRAP_OF_ACID_BOLT 62 -#define TRAP_OF_COLD_BOLT 63 -#define TRAP_OF_FIRE_BOLT 64 -#define TRAP_OF_PLASMA_BOLT 65 -#define TRAP_OF_WATER_BOLT 66 -#define TRAP_OF_LITE_BOLT 67 -#define TRAP_OF_DARK_BOLT 68 -#define TRAP_OF_SHARDS_BOLT 69 -#define TRAP_OF_SOUND_BOLT 70 -#define TRAP_OF_CONFUSION_BOLT 71 -#define TRAP_OF_FORCE_BOLT 72 -#define TRAP_OF_INERTIA_BOLT 73 -#define TRAP_OF_MANA_BOLT 74 -#define TRAP_OF_ICE_BOLT 75 -#define TRAP_OF_CHAOS_BOLT 76 -#define TRAP_OF_NETHER_BOLT 77 -#define TRAP_OF_DISENCHANT_BOLT 78 -#define TRAP_OF_NEXUS_BOLT 79 -#define TRAP_OF_TIME_BOLT 80 -#define TRAP_OF_GRAVITY_BOLT 81 - -#define TRAP_OF_ELEC_BALL 82 -#define TRAP_OF_POIS_BALL 83 -#define TRAP_OF_ACID_BALL 84 -#define TRAP_OF_COLD_BALL 85 -#define TRAP_OF_FIRE_BALL 86 -#define TRAP_OF_PLASMA_BALL 87 -#define TRAP_OF_WATER_BALL 88 -#define TRAP_OF_LITE_BALL 89 -#define TRAP_OF_DARK_BALL 90 -#define TRAP_OF_SHARDS_BALL 91 -#define TRAP_OF_SOUND_BALL 92 -#define TRAP_OF_CONFUSION_BALL 93 -#define TRAP_OF_FORCE_BALL 94 -#define TRAP_OF_INERTIA_BALL 95 -#define TRAP_OF_MANA_BALL 96 -#define TRAP_OF_ICE_BALL 97 -#define TRAP_OF_CHAOS_BALL 98 -#define TRAP_OF_NETHER_BALL 99 -#define TRAP_OF_DISENCHANT_BALL 100 -#define TRAP_OF_NEXUS_BALL 101 -#define TRAP_OF_TIME_BALL 102 -#define TRAP_OF_GRAVITY_BALL 103 - -#define TRAP_OF_ARROW_I 110 -#define TRAP_OF_ARROW_II 111 -#define TRAP_OF_ARROW_III 112 -#define TRAP_OF_ARROW_IV 113 -#define TRAP_OF_POISON_ARROW_I 114 -#define TRAP_OF_POISON_ARROW_II 115 -#define TRAP_OF_POISON_ARROW_III 116 -#define TRAP_OF_POISON_ARROW_IV 117 -#define TRAP_OF_DAGGER_I 118 -#define TRAP_OF_DAGGER_II 119 -#define TRAP_OF_POISON_DAGGER_I 120 -#define TRAP_OF_POISON_DAGGER_II 121 -#define TRAP_OF_ARROWS_I 122 -#define TRAP_OF_ARROWS_II 123 -#define TRAP_OF_ARROWS_III 124 -#define TRAP_OF_ARROWS_IV 125 -#define TRAP_OF_POISON_ARROWS_I 126 -#define TRAP_OF_POISON_ARROWS_II 127 -#define TRAP_OF_POISON_ARROWS_III 128 -#define TRAP_OF_POISON_ARROWS_IV 129 -#define TRAP_OF_DAGGERS_I 130 -#define TRAP_OF_DAGGERS_II 131 -#define TRAP_OF_POISON_DAGGERS_I 132 -#define TRAP_OF_POISON_DAGGERS_II 133 - -#define TRAP_OF_DROP_ITEMS 140 -#define TRAP_OF_DROP_ALL_ITEMS 141 -#define TRAP_OF_DROP_EVERYTHING 142 - -/* -SC- */ -#define TRAP_OF_FEMINITY 150 -#define TRAP_OF_MASCULINITY 151 -#define TRAP_OF_NEUTRALITY 152 -#define TRAP_OF_AGING 153 -#define TRAP_OF_GROWING 154 -#define TRAP_OF_SHRINKING 155 -#define TRAP_OF_ELDRITCH_HORROR 156 -/* XXX */ -#define TRAP_OF_DIVINE_ANGER 158 -#define TRAP_OF_DIVINE_WRATH 159 -#define TRAP_OF_HALLUCINATION 160 - -#define TRAP_OF_ROCKET 161 -#define TRAP_OF_NUKE_BOLT 162 -#define TRAP_OF_DEATH_RAY 163 -#define TRAP_OF_HOLY_FIRE 164 -#define TRAP_OF_HELL_FIRE 165 -#define TRAP_OF_PSI_BOLT 166 -#define TRAP_OF_PSI_DRAIN 167 -#define TRAP_OF_NUKE_BALL 168 -#define TRAP_OF_PSI_BALL 169 - -/* DG */ -#define TRAP_OF_ACQUIREMENT 170 - -/* Runescrye */ -#define TRAP_G_ELEC_BOLT 171 -#define TRAP_G_POIS_BOLT 172 -#define TRAP_G_ACID_BOLT 173 -#define TRAP_G_COLD_BOLT 174 -#define TRAP_G_FIRE_BOLT 175 - /*** General index values ***/ @@ -2350,10 +1841,8 @@ #define GF_GRAVITY 35 #define GF_KILL_WALL 40 #define GF_KILL_DOOR 41 -#define GF_KILL_TRAP 42 #define GF_MAKE_WALL 45 #define GF_MAKE_DOOR 46 -#define GF_MAKE_TRAP 47 #define GF_OLD_CLONE 51 #define GF_OLD_POLY 52 #define GF_OLD_HEAL 53 @@ -2392,7 +1881,6 @@ #define GF_JAM_DOOR 88 #define GF_DOMINATION 89 #define GF_DISP_GOOD 90 -#define GF_IDENTIFY 91 #define GF_RAISE 92 #define GF_STAR_IDENTIFY 93 #define GF_DESTRUCTION 94 @@ -2419,6 +1907,7 @@ /* * Some things which induce learning */ +#define DRS_NONE 0 #define DRS_ACID 1 #define DRS_ELEC 2 #define DRS_FIRE 3 @@ -2460,9 +1949,6 @@ /* High resist */ #define EGO_XTRA_POWER 2 -/* Special ability */ -#define EGO_XTRA_ABILITY 3 - /*** Object flag values ***/ @@ -2496,333 +1982,8 @@ MFLAG_PARTIAL | MFLAG_CONTROL | MFLAG_NO_DROP \ ) - -/* - * As of 2.7.8, the "object flags" are valid for all objects, and as - * of 2.7.9, these flags are not actually stored with the object. - * - * Note that "flags1" contains all flags dependant on "pval" (including - * stat bonuses, but NOT stat sustainers), plus all "extra attack damage" - * flags (SLAY_XXX and BRAND_XXX). - * - * Note that "flags2" contains all "resistances" (including "Stat Sustainers", - * actual immunities, and resistances). Note that "Hold Life" is really an - * "immunity" to ExpLoss, and "Free Action" is "immunity to paralysis". - * - * Note that "flags3" contains everything else -- including the three "CURSED" - * flags, and the "BLESSED" flag, several "item display" parameters, some new - * flags for powerful Bows, and flags which affect the player in a "general" - * way (LITE, TELEPATHY, SEE_INVIS, SLOW_DIGEST, REGEN, FEATHER), including - * all the "general" curses (TELEPORT, AGGRAVATE, EXP_DRAIN). It also has - * four new flags called "ITEM_IGNORE_XXX" which lets an item specify that - * it can not be affected by various forms of destruction. This is NOT as - * powerful as actually granting resistance/immunity to the wearer. - */ - -#define TR1_STR 0x00000001L /* STR += "pval" */ -#define TR1_INT 0x00000002L /* INT += "pval" */ -#define TR1_WIS 0x00000004L /* WIS += "pval" */ -#define TR1_DEX 0x00000008L /* DEX += "pval" */ -#define TR1_CON 0x00000010L /* CON += "pval" */ -#define TR1_CHR 0x00000020L /* CHR += "pval" */ -#define TR1_MANA 0x00000040L /* Mana multipler */ -#define TR1_SPELL 0x00000080L /* Spell power increase */ -#define TR1_STEALTH 0x00000100L /* Stealth += "pval" */ -#define TR1_SEARCH 0x00000200L /* Search += "pval" */ -#define TR1_INFRA 0x00000400L /* Infra += "pval" */ -#define TR1_TUNNEL 0x00000800L /* Tunnel += "pval" */ -#define TR1_SPEED 0x00001000L /* Speed += "pval" */ -#define TR1_BLOWS 0x00002000L /* Blows += "pval" */ -#define TR1_CHAOTIC 0x00004000L -#define TR1_VAMPIRIC 0x00008000L -#define TR1_SLAY_ANIMAL 0x00010000L -#define TR1_SLAY_EVIL 0x00020000L -#define TR1_SLAY_UNDEAD 0x00040000L -#define TR1_SLAY_DEMON 0x00080000L -#define TR1_SLAY_ORC 0x00100000L -#define TR1_SLAY_TROLL 0x00200000L -#define TR1_SLAY_GIANT 0x00400000L -#define TR1_SLAY_DRAGON 0x00800000L -#define TR1_KILL_DRAGON 0x01000000L /* Execute Dragon */ -#define TR1_VORPAL 0x02000000L /* Later */ -#define TR1_IMPACT 0x04000000L /* Cause Earthquakes */ -#define TR1_BRAND_POIS 0x08000000L -#define TR1_BRAND_ACID 0x10000000L -#define TR1_BRAND_ELEC 0x20000000L -#define TR1_BRAND_FIRE 0x40000000L -#define TR1_BRAND_COLD 0x80000000L -#define TR1_NULL_MASK 0x00000000L - -#define TRAP2_AUTOMATIC_5 0x00000001L /* Trap automatically rearms itself, 1 in 5 failure */ -#define TRAP2_AUTOMATIC_99 0x00000002L /* Trap automatically rearms itself */ -#define TRAP2_KILL_GHOST 0x00000004L /* Trap also affects PASS_WALL creatures */ -#define TRAP2_TELEPORT_TO 0x00000008L /* After everything else, teleport to player */ -#define TRAP2_ONLY_DRAGON 0x00000010L /* Affect only dragons & other AFFECTed creatures */ -#define TRAP2_ONLY_DEMON 0x00000020L /* Affect only demons & other AFFECTed creatures */ -#define TRAP2_ONLY_ANIMAL 0x00000100L /* Affect only animals & other AFFECTed creatures */ -#define TRAP2_ONLY_UNDEAD 0x00000200L /* Affect only undead & others */ -#define TRAP2_ONLY_EVIL 0x00000400L /* Affect only evil creatures &c. */ - -#define TRAP2_ONLY_MASK (TRAP2_ONLY_DRAGON | TRAP2_ONLY_DEMON | TRAP2_ONLY_ANIMAL | \ - TRAP2_ONLY_UNDEAD | TRAP2_ONLY_EVIL ) - -#define TR2_SUST_STR 0x00000001L -#define TR2_SUST_INT 0x00000002L -#define TR2_SUST_WIS 0x00000004L -#define TR2_SUST_DEX 0x00000008L -#define TR2_SUST_CON 0x00000010L -#define TR2_SUST_CHR 0x00000020L -#define TR2_INVIS 0x00000040L /* Invisibility */ -#define TR2_LIFE 0x00000080L /* Life multiplier */ -#define TR2_IM_ACID 0x00000100L -#define TR2_IM_ELEC 0x00000200L -#define TR2_IM_FIRE 0x00000400L -#define TR2_IM_COLD 0x00000800L -#define TR2_SENS_FIRE 0x00001000L /* Sensibility to fire */ -#define TR2_REFLECT 0x00002000L /* Reflect 'bolts' */ -#define TR2_FREE_ACT 0x00004000L /* Free Action */ -#define TR2_HOLD_LIFE 0x00008000L /* Hold Life */ -#define TR2_RES_ACID 0x00010000L -#define TR2_RES_ELEC 0x00020000L -#define TR2_RES_FIRE 0x00040000L -#define TR2_RES_COLD 0x00080000L -#define TR2_RES_POIS 0x00100000L -#define TR2_RES_FEAR 0x00200000L -#define TR2_RES_LITE 0x00400000L -#define TR2_RES_DARK 0x00800000L -#define TR2_RES_BLIND 0x01000000L -#define TR2_RES_CONF 0x02000000L -#define TR2_RES_SOUND 0x04000000L -#define TR2_RES_SHARDS 0x08000000L -#define TR2_RES_NETHER 0x10000000L -#define TR2_RES_NEXUS 0x20000000L -#define TR2_RES_CHAOS 0x40000000L -#define TR2_RES_DISEN 0x80000000L -#define TR2_NULL_MASK 0x00000000L - -#define TR3_SH_FIRE 0x00000001L /* Immolation (Fire) */ -#define TR3_SH_ELEC 0x00000002L /* Electric Sheath */ -#define TR3_AUTO_CURSE 0x00000004L /* The obj will recurse itself */ -#define TR3_DECAY 0x00000008L /* Decay */ -#define TR3_NO_TELE 0x00000010L /* Anti-teleportation */ -#define TR3_NO_MAGIC 0x00000020L /* Anti-magic */ -#define TR3_WRAITH 0x00000040L /* Wraithform */ -#define TR3_TY_CURSE 0x00000080L /* The Ancient Curse */ -#define TR3_EASY_KNOW 0x00000100L /* Aware -> Known */ -#define TR3_HIDE_TYPE 0x00000200L /* Hide "pval" description */ -#define TR3_SHOW_MODS 0x00000400L /* Always show Tohit/Todam */ -#define TR3_INSTA_ART 0x00000800L /* Item must be an artifact */ -#define TR3_FEATHER 0x00001000L /* Feather Falling */ -#define TR3_LITE1 0x00002000L /* lite radius 1 */ -#define TR3_SEE_INVIS 0x00004000L /* See Invisible */ -#define TR3_NORM_ART 0x00008000L /* Artifact in k_info */ -#define TR3_SLOW_DIGEST 0x00010000L /* Item slows down digestion */ -#define TR3_REGEN 0x00020000L /* Item induces regeneration */ -#define TR3_XTRA_MIGHT 0x00040000L /* Bows get extra multiplier */ -#define TR3_XTRA_SHOTS 0x00080000L /* Bows get extra shots */ -#define TR3_IGNORE_ACID 0x00100000L /* Item ignores Acid Damage */ -#define TR3_IGNORE_ELEC 0x00200000L /* Item ignores Elec Damage */ -#define TR3_IGNORE_FIRE 0x00400000L /* Item ignores Fire Damage */ -#define TR3_IGNORE_COLD 0x00800000L /* Item ignores Cold Damage */ -#define TR3_ACTIVATE 0x01000000L /* Item can be activated */ -#define TR3_DRAIN_EXP 0x02000000L /* Item drains Experience */ -#define TR3_TELEPORT 0x04000000L /* Item teleports player */ -#define TR3_AGGRAVATE 0x08000000L /* Item aggravates monsters */ -#define TR3_BLESSED 0x10000000L /* Item is Blessed */ -#define TR3_CURSED 0x20000000L /* Item is Cursed */ -#define TR3_HEAVY_CURSE 0x40000000L /* Item is Heavily Cursed */ -#define TR3_PERMA_CURSE 0x80000000L /* Item is Perma Cursed */ -#define TR3_NULL_MASK 0x00000000L - - -#define TR4_NEVER_BLOW 0x00000001L /* Weapon can't attack */ -#define TR4_PRECOGNITION 0x00000002L /* Like activating the cheat mode */ -#define TR4_BLACK_BREATH 0x00000004L /* Tolkien's Black Breath */ -#define TR4_RECHARGE 0x00000008L /* For artifact Wands and Staffs */ -#define TR4_FLY 0x00000010L /* This one and ONLY this one allow you to fly over trees */ -#define TR4_DG_CURSE 0x00000020L /* The Ancient Morgothian Curse */ -#define TR4_COULD2H 0x00000040L /* Can wield it 2 Handed */ -#define TR4_MUST2H 0x00000080L /* Must wield it 2 Handed */ -#define TR4_LEVELS 0x00000100L /* Can gain exp/exp levels !! */ -#define TR4_CLONE 0x00000200L /* Can clone monsters */ -#define TR4_SPECIAL_GENE 0x00000400L /* The object can only be generated in special conditions like quests, special dungeons, ... */ -#define TR4_CLIMB 0x00000800L /* Allow climbing mountains */ -#define TR4_FAST_CAST 0x00001000L /* Rod is x2 time faster to use */ -#define TR4_CAPACITY 0x00002000L /* Rod can take x2 mana */ -#define TR4_CHARGING 0x00004000L /* Rod recharge faster */ -#define TR4_CHEAPNESS 0x00008000L /* Rod spells are cheaper(in mana cost) to cast */ -#define TR4_FOUNTAIN 0x00010000L /* Available as fountain (for potions) */ -#define TR4_ANTIMAGIC_50 0x00020000L /* Forbid magic */ -#define TR4_EASY_USE 0x00200000L /* Easily activable */ -#define TR4_IM_NETHER 0x00400000L /* Immunity to nether */ -#define TR4_RECHARGED 0x00800000L /* Object has been recharged once */ -#define TR4_ULTIMATE 0x01000000L /* ULTIMATE artifact */ -#define TR4_AUTO_ID 0x02000000L /* Id stuff on floor */ -#define TR4_LITE2 0x04000000L /* lite radius 2 */ -#define TR4_LITE3 0x08000000L /* lite radius 3 */ -#define TR4_FUEL_LITE 0x10000000L /* fuelable lite */ -#define TR4_CURSE_NO_DROP 0x40000000L /* The obj wont be dropped */ -#define TR4_NO_RECHARGE 0x80000000L /* Object Cannot be recharged */ -#define TR4_NULL_MASK 0xFFFFFFFCL - -#define TR5_TEMPORARY 0x00000001L /* In timeout turns it is destroyed */ -#define TR5_DRAIN_MANA 0x00000002L /* Drains mana */ -#define TR5_DRAIN_HP 0x00000004L /* Drains hp */ -#define TR5_KILL_DEMON 0x00000008L /* Execute Demon */ -#define TR5_KILL_UNDEAD 0x00000010L /* Execute Undead */ -#define TR5_CRIT 0x00000020L /* More critical hits */ -#define TR5_ATTR_MULTI 0x00000040L /* Object shimmer -- only allowed in k_info */ -#define TR5_WOUNDING 0x00000080L /* Wounds monsters */ -#define TR5_FULL_NAME 0x00000100L /* Uses direct name from k_info */ -#define TR5_LUCK 0x00000200L /* Luck += pval */ -#define TR5_IMMOVABLE 0x00000400L /* Cannot move */ -#define TR5_SPELL_CONTAIN 0x00000800L /* Can contain a spell */ -#define TR5_RES_MORGUL 0x00001000L /* Is not shattered by morgul fiends(nazguls) */ -#define TR5_ACTIVATE_NO_WIELD 0x00002000L /* Can be 'A'ctivated without being wielded */ -#define TR5_MAGIC_BREATH 0x00004000L /* Can breath anywere */ -#define TR5_WATER_BREATH 0x00008000L /* Can breath underwater */ -#define TR5_WIELD_CAST 0x00010000L /* Need to be wielded to cast spelsl fomr it(if it can be wiekded) */ - -/* ESP defines */ -#define ESP_ORC 0x00000001L -#define ESP_TROLL 0x00000002L -#define ESP_DRAGON 0x00000004L -#define ESP_GIANT 0x00000008L -#define ESP_DEMON 0x00000010L -#define ESP_UNDEAD 0x00000020L -#define ESP_EVIL 0x00000040L -#define ESP_ANIMAL 0x00000080L -#define ESP_THUNDERLORD 0x00000100L -#define ESP_GOOD 0x00000200L -#define ESP_NONLIVING 0x00000400L -#define ESP_UNIQUE 0x00000800L -#define ESP_SPIDER 0x00001000L -#define ESP_ALL 0x80000000L - -/* Number of group of flags to choose from */ -#define MAX_FLAG_GROUP 12 #define NEW_GROUP_CHANCE 40 /* Chance to get a new group */ -/* - * Hack masks for "pval-dependant" flags. - */ -#define TR1_PVAL_MASK \ - (TR1_STR | TR1_INT | TR1_WIS | TR1_DEX | \ - TR1_CON | TR1_CHR | \ - TR1_STEALTH | TR1_SEARCH | TR1_INFRA | TR1_TUNNEL | \ - TR1_SPEED | TR1_BLOWS | TR1_SPELL) - -#define TR5_PVAL_MASK \ - (TR5_CRIT | TR5_LUCK) - - -/*** Ego flags ***/ -#define ETR4_SUSTAIN 0x00000001L /* Ego-Item gives a Random Sustain */ -#define ETR4_OLD_RESIST 0x00000002L /* The old "extra power" random high resist */ -#define ETR4_ABILITY 0x00000004L /* Ego-Item has a random Sustain */ -#define ETR4_R_ELEM 0x00000008L /* Item resists Acid/Fire/Cold/Elec or Poison */ -#define ETR4_R_LOW 0x00000010L /* Item has a random low resist */ -#define ETR4_R_HIGH 0x00000020L /* Item has a random high resist */ -#define ETR4_R_ANY 0x00000040L /* Item has one additional resist */ -#define ETR4_R_DRAGON 0x00000080L /* Item gets "Dragon" Resist */ -#define ETR4_SLAY_WEAP 0x00000100L /* Special 'Slaying' bonus */ -#define ETR4_DAM_DIE 0x00000200L /* Item has an additional dam die */ -#define ETR4_DAM_SIZE 0x00000400L /* Item has greater damage dice */ -#define ETR4_PVAL_M1 0x00000800L /* Item has +1 to pval */ -#define ETR4_PVAL_M2 0x00001000L /* Item has +(up to 2) to pval */ -#define ETR4_PVAL_M3 0x00002000L /* Item has +(up to 3) to pval */ -#define ETR4_PVAL_M5 0x00004000L /* Item has +(up to 5) to pval */ -#define ETR4_AC_M1 0x00008000L /* Item has +1 to AC */ -#define ETR4_AC_M2 0x00010000L /* Item has +(up to 2) to AC */ -#define ETR4_AC_M3 0x00020000L /* Item has +(up to 3) to AC */ -#define ETR4_AC_M5 0x00040000L /* Item has +(up to 5) to AC */ -#define ETR4_TH_M1 0x00080000L /* Item has +1 to hit */ -#define ETR4_TH_M2 0x00100000L /* Item has +(up to 2) to hit */ -#define ETR4_TH_M3 0x00200000L /* Item has +(up to 3) to hit */ -#define ETR4_TH_M5 0x00400000L /* Item has +(up to 5) to hit */ -#define ETR4_TD_M1 0x00800000L /* Item has +1 to dam */ -#define ETR4_TD_M2 0x01000000L /* Item has +(up to 2) to dam */ -#define ETR4_TD_M3 0x02000000L /* Item has +(up to 3) to dam */ -#define ETR4_TD_M5 0x04000000L /* Item has +(up to 5) to dam */ -#define ETR4_R_P_ABILITY 0x08000000L /* Item has a random pval-affected ability */ -#define ETR4_R_STAT 0x10000000L /* Item affects a random stat */ -#define ETR4_R_STAT_SUST 0x20000000L /* Item affects a random stat & sustains it */ -#define ETR4_R_IMMUNITY 0x40000000L /* Item gives a random immunity */ -#define ETR4_LIMIT_BLOWS 0x80000000L /* switch the "limit blows" feature */ - -/*** Features flags -- DG ***/ -#define FF1_NO_WALK 0x00000001L -#define FF1_NO_VISION 0x00000002L -#define FF1_CAN_LEVITATE 0x00000004L -#define FF1_CAN_PASS 0x00000008L -#define FF1_FLOOR 0x00000010L -#define FF1_WALL 0x00000020L -#define FF1_PERMANENT 0x00000040L -#define FF1_CAN_FLY 0x00000080L -#define FF1_REMEMBER 0x00000100L -#define FF1_NOTICE 0x00000200L -#define FF1_DONT_NOTICE_RUNNING 0x00000400L -#define FF1_CAN_RUN 0x00000800L -#define FF1_DOOR 0x00001000L -#define FF1_SUPPORT_LIGHT 0x00002000L -#define FF1_CAN_CLIMB 0x00004000L -#define FF1_TUNNELABLE 0x00008000L -#define FF1_WEB 0x00010000L -#define FF1_ATTR_MULTI 0x00020000L -#define FF1_SUPPORT_GROWTH 0x00040000L - -/*** Dungeon type flags -- DG ***/ -#define DF1_PRINCIPAL 0x00000001L /* Is a principal dungeon */ -#define DF1_MAZE 0x00000002L /* Is a maze-type dungeon */ -#define DF1_SMALLEST 0x00000004L /* Creates VERY small levels like The Maze */ -#define DF1_SMALL 0x00000008L /* Creates small levels like Dol Goldor */ -#define DF1_BIG 0x00000010L /* Creates big levels like Moria, and Angband dungeons */ -#define DF1_NO_DOORS 0x00000020L /* No doors on rooms, like Barrowdowns, Old Forest etc) */ -#define DF1_WATER_RIVER 0x00000040L /* Allow a single water streamer on a level */ -#define DF1_LAVA_RIVER 0x00000080L /* Allow a single lava streamer on a level */ -#define DF1_WATER_RIVERS 0x00000100L /* Allow multiple water streamers on a level */ -#define DF1_LAVA_RIVERS 0x00000200L /* Allow multiple lava streamers on a level */ -#define DF1_CAVE 0x00000400L /* Allow rooms */ -#define DF1_CAVERN 0x00000800L /* Allow cavern rooms */ -#define DF1_NO_UP 0x00001000L /* Disallow up stairs */ -#define DF1_HOT 0x00002000L /* Corpses on ground and in pack decay quicker through heat */ -#define DF1_COLD 0x00004000L /* Corpses on ground and in pack decay quicker through cold */ -#define DF1_FORCE_DOWN 0x00008000L /* No up stairs generated */ -#define DF1_FORGET 0x00010000L /* Features are forgotten, like the Maze and Illusory Castle */ -#define DF1_NO_DESTROY 0x00020000L /* No destroyed levels in dungeon */ -#define DF1_SAND_VEIN 0x00040000L /* Like in the sandworm lair */ -#define DF1_CIRCULAR_ROOMS 0x00080000L /* Allow circular rooms */ -#define DF1_EMPTY 0x00100000L /* Allow arena levels */ -#define DF1_DAMAGE_FEAT 0x00200000L -#define DF1_FLAT 0x00400000L /* Creates paths to next areas at edge of level, like Barrowdowns */ -#define DF1_TOWER 0x00800000L /* You start at bottom and go up rather than the reverse */ -#define DF1_RANDOM_TOWNS 0x01000000L /* Allow random towns */ -#define DF1_DOUBLE 0x02000000L /* Creates double-walled dungeon like Helcaraxe and Erebor */ -#define DF1_LIFE_LEVEL 0x04000000L /* Creates dungeon level on modified 'game of life' algorithm */ -#define DF1_EVOLVE 0x08000000L /* Evolving, pulsing levels like Heart of the Earth */ -#define DF1_ADJUST_LEVEL_1 0x10000000L /* Minimum monster level will be equal to dungeon level */ -#define DF1_ADJUST_LEVEL_2 0x20000000L /* Minimum monster level will be double the dungeon level */ -#define DF1_NO_RECALL 0x40000000L /* No recall allowed */ -#define DF1_NO_STREAMERS 0x80000000L /* No streamers */ - -#define DF2_ADJUST_LEVEL_1_2 0x00000001L /* Minimum monster level will be half the dungeon level */ -#define DF2_NO_SHAFT 0x00000002L /* No shafts */ -#define DF2_ADJUST_LEVEL_PLAYER 0x00000004L /* Uses player level*2 instead of dungeon level for other ADJUST_LEVEL flags */ -#define DF2_NO_TELEPORT 0x00000008L -#define DF2_ASK_LEAVE 0x00000010L -#define DF2_NO_STAIR 0x00000020L -#define DF2_SPECIAL 0x00000040L -#define DF2_NO_NEW_MONSTER 0x00000080L -#define DF2_DESC 0x00000100L -#define DF2_NO_GENO 0x00000200L -#define DF2_NO_BREATH 0x00000400L /* Oups, cannot breath here */ -#define DF2_WATER_BREATH 0x00000800L /* Oups, cannot breath here, need water breathing */ -#define DF2_ELVEN 0x00001000L /* Try to create elven monster ego */ -#define DF2_DWARVEN 0x00002000L /* Try to create dwarven monster ego */ -#define DF2_NO_EASY_MOVE 0x00004000L /* Forbid stuff like teleport level, probability travel, ... */ -#define DF2_NO_RECALL_OUT 0x00008000L /* Cannot recall out of the place */ -#define DF2_DESC_ALWAYS 0x00010000L /* Always shows the desc */ - /*** Town flags ***/ #define TOWN_REAL 0x01 /* Town is really present */ #define TOWN_KNOWN 0x02 /* Town is found by the player */ @@ -2903,341 +2064,6 @@ #define MONSTER_LEVEL_MAX 150 -/* - * New monster race bit flags - */ -#define RF1_UNIQUE 0x00000001 /* Unique Monster */ -#define RF1_QUESTOR 0x00000002 /* Quest Monster */ -#define RF1_MALE 0x00000004 /* Male gender */ -#define RF1_FEMALE 0x00000008 /* Female gender */ -#define RF1_CHAR_CLEAR 0x00000010 /* Absorbs symbol */ -#define RF1_CHAR_MULTI 0x00000020 /* Changes symbol */ -#define RF1_ATTR_CLEAR 0x00000040 /* Absorbs color */ -#define RF1_ATTR_MULTI 0x00000080 /* Changes color */ -#define RF1_FORCE_DEPTH 0x00000100 /* Start at "correct" depth */ -#define RF1_FORCE_MAXHP 0x00000200 /* Start with max hitpoints */ -#define RF1_FORCE_SLEEP 0x00000400 /* Start out sleeping */ -#define RF1_FORCE_EXTRA 0x00000800 /* Start out something */ -#define RF1_FRIEND 0x00001000 /* Arrive with a friend */ -#define RF1_FRIENDS 0x00002000 /* Arrive with some friends */ -#define RF1_ESCORT 0x00004000 /* Arrive with an escort */ -#define RF1_ESCORTS 0x00008000 /* Arrive with some escorts */ -#define RF1_NEVER_BLOW 0x00010000 /* Never make physical blow */ -#define RF1_NEVER_MOVE 0x00020000 /* Never make physical move */ -#define RF1_RAND_25 0x00040000 /* Moves randomly (25%) */ -#define RF1_RAND_50 0x00080000 /* Moves randomly (50%) */ -#define RF1_ONLY_GOLD 0x00100000 /* Drop only gold */ -#define RF1_ONLY_ITEM 0x00200000 /* Drop only items */ -#define RF1_DROP_60 0x00400000 /* Drop an item/gold (60%) */ -#define RF1_DROP_90 0x00800000 /* Drop an item/gold (90%) */ -#define RF1_DROP_1D2 0x01000000 /* Drop 1d2 items/gold */ -#define RF1_DROP_2D2 0x02000000 /* Drop 2d2 items/gold */ -#define RF1_DROP_3D2 0x04000000 /* Drop 3d2 items/gold */ -#define RF1_DROP_4D2 0x08000000 /* Drop 4d2 items/gold */ -#define RF1_DROP_GOOD 0x10000000 /* Drop good items */ -#define RF1_DROP_GREAT 0x20000000 /* Drop great items */ -#define RF1_DROP_USEFUL 0x40000000 /* Drop "useful" items */ -#define RF1_DROP_CHOSEN 0x80000000 /* Drop "chosen" items */ - -/* - * New monster race bit flags - */ -#define RF2_STUPID 0x00000001 /* Monster is stupid */ -#define RF2_SMART 0x00000002 /* Monster is smart */ -#define RF2_CAN_SPEAK 0x00000004 /* TY: can speak */ -#define RF2_REFLECTING 0x00000008 /* Reflects bolts */ -#define RF2_INVISIBLE 0x00000010 /* Monster avoids vision */ -#define RF2_COLD_BLOOD 0x00000020 /* Monster avoids infra */ -#define RF2_EMPTY_MIND 0x00000040 /* Monster avoids telepathy */ -#define RF2_WEIRD_MIND 0x00000080 /* Monster avoids telepathy? */ -#define RF2_DEATH_ORB 0x00000100 /* Death Orb */ -#define RF2_REGENERATE 0x00000200 /* Monster regenerates */ -#define RF2_SHAPECHANGER 0x00000400 /* TY: shapechanger */ -#define RF2_ATTR_ANY 0x00000800 /* TY: Attr_any */ -#define RF2_POWERFUL 0x00001000 /* Monster has strong breath */ -#define RF2_ELDRITCH_HORROR 0x00002000 /* Sanity-blasting horror */ -#define RF2_AURA_FIRE 0x00004000 /* Burns in melee */ -#define RF2_AURA_ELEC 0x00008000 /* Shocks in melee */ -#define RF2_OPEN_DOOR 0x00010000 /* Monster can open doors */ -#define RF2_BASH_DOOR 0x00020000 /* Monster can bash doors */ -#define RF2_PASS_WALL 0x00040000 /* Monster can pass walls */ -#define RF2_KILL_WALL 0x00080000 /* Monster can destroy walls */ -#define RF2_MOVE_BODY 0x00100000 /* Monster can move monsters */ -#define RF2_KILL_BODY 0x00200000 /* Monster can kill monsters */ -#define RF2_TAKE_ITEM 0x00400000 /* Monster can pick up items */ -#define RF2_KILL_ITEM 0x00800000 /* Monster can crush items */ -#define RF2_BRAIN_1 0x01000000 -#define RF2_BRAIN_2 0x02000000 -#define RF2_BRAIN_3 0x04000000 -#define RF2_BRAIN_4 0x08000000 -#define RF2_BRAIN_5 0x10000000 -#define RF2_BRAIN_6 0x20000000 -#define RF2_BRAIN_7 0x40000000 -#define RF2_BRAIN_8 0x80000000 - -/* - * New monster race bit flags - */ -#define RF3_ORC 0x00000001 /* Orc */ -#define RF3_TROLL 0x00000002 /* Troll */ -#define RF3_GIANT 0x00000004 /* Giant */ -#define RF3_DRAGON 0x00000008 /* Dragon */ -#define RF3_DEMON 0x00000010 /* Demon */ -#define RF3_UNDEAD 0x00000020 /* Undead */ -#define RF3_EVIL 0x00000040 /* Evil */ -#define RF3_ANIMAL 0x00000080 /* Animal */ -#define RF3_THUNDERLORD 0x00000100 /* DG: Thunderlord */ -#define RF3_GOOD 0x00000200 /* Good */ -#define RF3_AURA_COLD 0x00000400 /* Freezes in melee */ -#define RF3_NONLIVING 0x00000800 /* TY: Non-Living (?) */ -#define RF3_HURT_LITE 0x00001000 /* Hurt by lite */ -#define RF3_HURT_ROCK 0x00002000 /* Hurt by rock remover */ -#define RF3_SUSCEP_FIRE 0x00004000 /* Hurt badly by fire */ -#define RF3_SUSCEP_COLD 0x00008000 /* Hurt badly by cold */ -#define RF3_IM_ACID 0x00010000 /* Resist acid a lot */ -#define RF3_IM_ELEC 0x00020000 /* Resist elec a lot */ -#define RF3_IM_FIRE 0x00040000 /* Resist fire a lot */ -#define RF3_IM_COLD 0x00080000 /* Resist cold a lot */ -#define RF3_IM_POIS 0x00100000 /* Resist poison a lot */ -#define RF3_RES_TELE 0x00200000 /* Resist teleportation */ -#define RF3_RES_NETH 0x00400000 /* Resist nether a lot */ -#define RF3_RES_WATE 0x00800000 /* Resist water */ -#define RF3_RES_PLAS 0x01000000 /* Resist plasma */ -#define RF3_RES_NEXU 0x02000000 /* Resist nexus */ -#define RF3_RES_DISE 0x04000000 /* Resist disenchantment */ -#define RF3_UNIQUE_4 0x08000000 /* Is a "Nazgul" unique */ -#define RF3_NO_FEAR 0x10000000 /* Cannot be scared */ -#define RF3_NO_STUN 0x20000000 /* Cannot be stunned */ -#define RF3_NO_CONF 0x40000000 /* Cannot be confused */ -#define RF3_NO_SLEEP 0x80000000 /* Cannot be slept */ - -/* - * New monster race bit flags - */ -#define RF4_SHRIEK 0x00000001 /* Shriek for help */ -#define RF4_MULTIPLY 0x00000002 /* Monster reproduces */ -#define RF4_S_ANIMAL 0x00000004 /* Summon animals */ -#define RF4_ROCKET 0x00000008 /* TY: Rocket */ -#define RF4_ARROW_1 0x00000010 /* Fire an arrow (light) */ -#define RF4_ARROW_2 0x00000020 /* Fire an arrow (heavy) */ -#define RF4_ARROW_3 0x00000040 /* Fire missiles (light) */ -#define RF4_ARROW_4 0x00000080 /* Fire missiles (heavy) */ -#define RF4_BR_ACID 0x00000100 /* Breathe Acid */ -#define RF4_BR_ELEC 0x00000200 /* Breathe Elec */ -#define RF4_BR_FIRE 0x00000400 /* Breathe Fire */ -#define RF4_BR_COLD 0x00000800 /* Breathe Cold */ -#define RF4_BR_POIS 0x00001000 /* Breathe Poison */ -#define RF4_BR_NETH 0x00002000 /* Breathe Nether */ -#define RF4_BR_LITE 0x00004000 /* Breathe Lite */ -#define RF4_BR_DARK 0x00008000 /* Breathe Dark */ -#define RF4_BR_CONF 0x00010000 /* Breathe Confusion */ -#define RF4_BR_SOUN 0x00020000 /* Breathe Sound */ -#define RF4_BR_CHAO 0x00040000 /* Breathe Chaos */ -#define RF4_BR_DISE 0x00080000 /* Breathe Disenchant */ -#define RF4_BR_NEXU 0x00100000 /* Breathe Nexus */ -#define RF4_BR_TIME 0x00200000 /* Breathe Time */ -#define RF4_BR_INER 0x00400000 /* Breathe Inertia */ -#define RF4_BR_GRAV 0x00800000 /* Breathe Gravity */ -#define RF4_BR_SHAR 0x01000000 /* Breathe Shards */ -#define RF4_BR_PLAS 0x02000000 /* Breathe Plasma */ -#define RF4_BR_WALL 0x04000000 /* Breathe Force */ -#define RF4_BR_MANA 0x08000000 /* Breathe Mana */ -#define RF4_BA_NUKE 0x10000000 /* TY: Nuke Ball */ -#define RF4_BR_NUKE 0x20000000 /* TY: Toxic Breath */ -#define RF4_BA_CHAO 0x40000000 /* Chaos Ball */ -#define RF4_BR_DISI 0x80000000 /* Breathe Disintegration */ - -/* - * New monster race bit flags - */ -#define RF5_BA_ACID 0x00000001 /* Acid Ball */ -#define RF5_BA_ELEC 0x00000002 /* Elec Ball */ -#define RF5_BA_FIRE 0x00000004 /* Fire Ball */ -#define RF5_BA_COLD 0x00000008 /* Cold Ball */ -#define RF5_BA_POIS 0x00000010 /* Poison Ball */ -#define RF5_BA_NETH 0x00000020 /* Nether Ball */ -#define RF5_BA_WATE 0x00000040 /* Water Ball */ -#define RF5_BA_MANA 0x00000080 /* Mana Storm */ -#define RF5_BA_DARK 0x00000100 /* Darkness Storm */ -#define RF5_DRAIN_MANA 0x00000200 /* Drain Mana */ -#define RF5_MIND_BLAST 0x00000400 /* Blast Mind */ -#define RF5_BRAIN_SMASH 0x00000800 /* Smash Brain */ -#define RF5_CAUSE_1 0x00001000 /* Cause Light Wound */ -#define RF5_CAUSE_2 0x00002000 /* Cause Serious Wound */ -#define RF5_CAUSE_3 0x00004000 /* Cause Critical Wound */ -#define RF5_CAUSE_4 0x00008000 /* Cause Mortal Wound */ -#define RF5_BO_ACID 0x00010000 /* Acid Bolt */ -#define RF5_BO_ELEC 0x00020000 /* Elec Bolt (unused) */ -#define RF5_BO_FIRE 0x00040000 /* Fire Bolt */ -#define RF5_BO_COLD 0x00080000 /* Cold Bolt */ -#define RF5_BO_POIS 0x00100000 /* Poison Bolt (unused) */ -#define RF5_BO_NETH 0x00200000 /* Nether Bolt */ -#define RF5_BO_WATE 0x00400000 /* Water Bolt */ -#define RF5_BO_MANA 0x00800000 /* Mana Bolt */ -#define RF5_BO_PLAS 0x01000000 /* Plasma Bolt */ -#define RF5_BO_ICEE 0x02000000 /* Ice Bolt */ -#define RF5_MISSILE 0x04000000 /* Magic Missile */ -#define RF5_SCARE 0x08000000 /* Frighten Player */ -#define RF5_BLIND 0x10000000 /* Blind Player */ -#define RF5_CONF 0x20000000 /* Confuse Player */ -#define RF5_SLOW 0x40000000 /* Slow Player */ -#define RF5_HOLD 0x80000000 /* Paralyze Player */ - -/* - * New monster race bit flags - */ -#define RF6_HASTE 0x00000001 /* Speed self */ -#define RF6_HAND_DOOM 0x00000002 /* Hand of Doom */ -#define RF6_HEAL 0x00000004 /* Heal self */ -#define RF6_S_ANIMALS 0x00000008 /* Summon animals */ -#define RF6_BLINK 0x00000010 /* Teleport Short */ -#define RF6_TPORT 0x00000020 /* Teleport Long */ -#define RF6_TELE_TO 0x00000040 /* Move player to monster */ -#define RF6_TELE_AWAY 0x00000080 /* Move player far away */ -#define RF6_TELE_LEVEL 0x00000100 /* Move player vertically */ -#define RF6_DARKNESS 0x00000200 /* Create Darkness */ -#define RF6_TRAPS 0x00000400 /* Create Traps */ -#define RF6_FORGET 0x00000800 /* Cause amnesia */ -#define RF6_RAISE_DEAD 0x00001000 /* Raise Dead */ -#define RF6_S_BUG 0x00002000 /* Summon Software bug */ -#define RF6_S_RNG 0x00004000 /* Summon RNG */ -#define RF6_S_THUNDERLORD 0x00008000 /* Summon Thunderlords */ -#define RF6_S_KIN 0x00010000 /* Summon "kin" */ -#define RF6_S_HI_DEMON 0x00020000 /* Summon greater demons! */ -#define RF6_S_MONSTER 0x00040000 /* Summon Monster */ -#define RF6_S_MONSTERS 0x00080000 /* Summon Monsters */ -#define RF6_S_ANT 0x00100000 /* Summon Ants */ -#define RF6_S_SPIDER 0x00200000 /* Summon Spiders */ -#define RF6_S_HOUND 0x00400000 /* Summon Hounds */ -#define RF6_S_HYDRA 0x00800000 /* Summon Hydras */ -#define RF6_S_ANGEL 0x01000000 /* Summon Angel */ -#define RF6_S_DEMON 0x02000000 /* Summon Demon */ -#define RF6_S_UNDEAD 0x04000000 /* Summon Undead */ -#define RF6_S_DRAGON 0x08000000 /* Summon Dragon */ -#define RF6_S_HI_UNDEAD 0x10000000 /* Summon Greater Undead */ -#define RF6_S_HI_DRAGON 0x20000000 /* Summon Ancient Dragon */ -#define RF6_S_WRAITH 0x40000000 /* Summon Unique Wraith */ -#define RF6_S_UNIQUE 0x80000000 /* Summon Unique Monster */ - -/* - * New monster race bit flags - */ -#define RF7_AQUATIC 0x00000001 /* Aquatic monster */ -#define RF7_CAN_SWIM 0x00000002 /* Monster can swim */ -#define RF7_CAN_FLY 0x00000004 /* Monster can fly */ -#define RF7_FRIENDLY 0x00000008 /* Monster is friendly */ -#define RF7_PET 0x00000010 /* Monster is a pet */ -#define RF7_MORTAL 0x00000020 /* Monster is a mortal being */ -#define RF7_SPIDER 0x00000040 /* Monster is a spider (can pass webs) */ -#define RF7_NAZGUL 0x00000080 /* Monster is a Nazgul */ -#define RF7_DG_CURSE 0x00000100 /* If killed the monster grant a DG Curse to the player */ -#define RF7_POSSESSOR 0x00000200 /* Is it a dreaded possessor monster ? */ -#define RF7_NO_DEATH 0x00000400 /* Cannot be killed */ -#define RF7_NO_TARGET 0x00000800 /* Cannot be targeted */ -#define RF7_AI_ANNOY 0x00001000 /* Try to tease the player */ -#define RF7_AI_SPECIAL 0x00002000 /* For quests */ -#define RF7_NEUTRAL 0x00004000 /* Monster is neutral */ -#define RF7_DROP_ART 0x00008000 /* Monster drop one art */ -#define RF7_DROP_RANDART 0x00010000 /* Monster drop one randart */ -#define RF7_AI_PLAYER 0x00020000 /* Controlled by the player */ -#define RF7_NO_THEFT 0x00040000 /* Monster is immune to theft */ -#define RF7_SPIRIT 0x00080000 /* This is a Spirit, coming from the Void */ - - -/* - * Monster race flags - */ -#define RF8_DUNGEON 0x00000001 -#define RF8_WILD_TOWN 0x00000002 -#define RF8_XXX8X02 0x00000004 -#define RF8_WILD_SHORE 0x00000008 -#define RF8_WILD_OCEAN 0x00000010 -#define RF8_WILD_WASTE 0x00000020 -#define RF8_WILD_WOOD 0x00000040 -#define RF8_WILD_VOLCANO 0x00000080 -#define RF8_XXX8X08 0x00000100 -#define RF8_WILD_MOUNTAIN 0x00000200 -#define RF8_WILD_GRASS 0x00000400 -#define RF8_NO_CUT 0x00000800 -#define RF8_CTHANGBAND 0x00001000 /* Not used in ToME */ -/* XXX */ -#define RF8_ZANGBAND 0x00004000 /* Not used in ToME */ -#define RF8_JOKEANGBAND 0x00008000 -#define RF8_ANGBAND 0x00010000 - -#define RF8_WILD_TOO 0x80000000 - - -/* - * Monster race flags - */ -#define RF9_DROP_CORPSE 0x00000001 -#define RF9_DROP_SKELETON 0x00000002 -#define RF9_HAS_LITE 0x00000004 /* Carries a lite */ -#define RF9_MIMIC 0x00000008 /* *REALLY* looks like an object ... only nastier */ -#define RF9_HAS_EGG 0x00000010 /* Can be monster's eggs */ -#define RF9_IMPRESED 0x00000020 /* The monster can follow you on each level until he dies */ -#define RF9_SUSCEP_ACID 0x00000040 /* Susceptible to acid */ -#define RF9_SUSCEP_ELEC 0x00000080 /* Susceptible to lightning */ -#define RF9_SUSCEP_POIS 0x00000100 /* Susceptible to poison */ -#define RF9_KILL_TREES 0x00000200 /* Monster can eat trees */ -#define RF9_WYRM_PROTECT 0x00000400 /* The monster is protected by great wyrms of power: They'll be summoned if it's killed */ -#define RF9_DOPPLEGANGER 0x00000800 /* The monster looks like you */ -#define RF9_ONLY_DEPTH 0x00001000 /* The monster can only be generated at the GIVEN depth */ -#define RF9_SPECIAL_GENE 0x00002000 /* The monster can only be generated in special conditions like quests, special dungeons, ... */ -#define RF9_NEVER_GENE 0x00004000 /* The monster cannot be normaly generated */ - - -/* - * Hack -- choose "intelligent" spells when desperate - */ - -#define RF4_INT_MASK \ - (RF4_S_ANIMAL) - -#define RF5_INT_MASK \ - (RF5_HOLD | RF5_SLOW | RF5_CONF | RF5_BLIND | RF5_SCARE) - -#define RF6_INT_MASK \ - (RF6_BLINK | RF6_TPORT | RF6_TELE_LEVEL | RF6_TELE_AWAY | \ - RF6_HEAL | RF6_HASTE | RF6_TRAPS | \ - RF6_S_KIN | RF6_S_HI_DEMON | RF6_S_MONSTER | RF6_S_MONSTERS | \ - RF6_S_ANT | RF6_S_SPIDER | RF6_S_HOUND | RF6_S_HYDRA | \ - RF6_S_ANGEL | RF6_S_DRAGON | RF6_S_UNDEAD | RF6_S_DEMON | \ - RF6_S_HI_DRAGON | RF6_S_HI_UNDEAD | RF6_S_WRAITH | RF6_S_UNIQUE | \ - RF6_S_THUNDERLORD | RF6_S_BUG | RF6_S_RNG | RF6_S_ANIMALS) - - -/* - * Hack -- "bolt" spells that may hurt fellow monsters - */ -#define RF4_BOLT_MASK \ - (RF4_ARROW_1 | RF4_ARROW_2 | RF4_ARROW_3 | RF4_ARROW_4) - -#define RF5_BOLT_MASK \ - (RF5_BO_ACID | RF5_BO_ELEC | RF5_BO_FIRE | RF5_BO_COLD | \ - RF5_BO_POIS | RF5_BO_NETH | RF5_BO_WATE | RF5_BO_MANA | \ - RF5_BO_PLAS | RF5_BO_ICEE | RF5_MISSILE) - -#define RF6_BOLT_MASK \ - 0L - - -/* Hack -- summon spells */ - -#define RF4_SUMMON_MASK \ - (RF4_S_ANIMAL) - -#define RF5_SUMMON_MASK \ - 0L - -#define RF6_SUMMON_MASK \ - (RF6_S_KIN | RF6_S_HI_DEMON | RF6_S_MONSTER | RF6_S_MONSTERS | RF6_S_ANT | \ - RF6_S_SPIDER | RF6_S_HOUND | RF6_S_HYDRA | RF6_S_ANGEL | RF6_S_DEMON | \ - RF6_S_UNDEAD | RF6_S_DRAGON | RF6_S_HI_UNDEAD | RF6_S_HI_DRAGON | \ - RF6_S_WRAITH | RF6_S_UNIQUE | RF6_S_THUNDERLORD | RF6_S_BUG | RF6_S_RNG | \ - RF6_S_ANIMALS) - /*** Macro Definitions ***/ @@ -3249,83 +2075,6 @@ -/*** Sound constants ***/ - - -#define SOUND_HIT 1 -#define SOUND_MISS 2 -#define SOUND_FLEE 3 -#define SOUND_DROP 4 -#define SOUND_KILL 5 -#define SOUND_LEVEL 6 -#define SOUND_DEATH 7 -#define SOUND_STUDY 8 -#define SOUND_TELEPORT 9 -#define SOUND_SHOOT 10 -#define SOUND_QUAFF 11 -#define SOUND_ZAP 12 -#define SOUND_WALK 13 -#define SOUND_TPOTHER 14 -#define SOUND_HITWALL 15 -#define SOUND_EAT 16 -#define SOUND_STORE1 17 -#define SOUND_STORE2 18 -#define SOUND_STORE3 19 -#define SOUND_STORE4 20 -#define SOUND_DIG 21 -#define SOUND_OPENDOOR 22 -#define SOUND_SHUTDOOR 23 -#define SOUND_TPLEVEL 24 -#define SOUND_SCROLL 25 -#define SOUND_BUY 26 -#define SOUND_SELL 27 -#define SOUND_WARN 28 -#define SOUND_ROCKET 29 /* Somebody's shooting rockets */ -#define SOUND_N_KILL 30 /* The player kills a non-living/undead monster */ -#define SOUND_U_KILL 31 /* The player kills a unique */ -#define SOUND_QUEST 32 /* The player has just completed a quest */ -#define SOUND_HEAL 33 /* The player was healed a little bit */ -#define SOUND_X_HEAL 34 /* The player was healed full health */ -#define SOUND_BITE 35 /* A monster bites you */ -#define SOUND_CLAW 36 /* A monster claws you */ -#define SOUND_M_SPELL 37 /* A monster casts a miscellaneous spell */ -#define SOUND_SUMMON 38 /* A monster casts a summoning spell */ -#define SOUND_BREATH 39 /* A monster breathes */ -#define SOUND_BALL 40 /* A monster casts a ball / bolt spell */ -#define SOUND_M_HEAL 41 /* A monster heals itself somehow */ -#define SOUND_ATK_SPELL 42 /* A monster casts a misc. offensive spell */ -#define SOUND_EVIL 43 /* Something nasty has just happened! */ -#define SOUND_TOUCH 44 /* A monster touches you */ -#define SOUND_STING 45 /* A monster stings you */ -#define SOUND_CRUSH 46 /* A monster crushes / envelopes you */ -#define SOUND_SLIME 47 /* A monster drools/spits/etc on you */ -#define SOUND_WAIL 48 /* A monster wails */ -#define SOUND_WINNER 49 /* Just won the game! */ -#define SOUND_FIRE 50 /* An item was burned */ -#define SOUND_ACID 51 /* An item was destroyed by acid */ -#define SOUND_ELEC 52 /* An item was destroyed by electricity */ -#define SOUND_COLD 53 /* An item was shattered */ -#define SOUND_ILLEGAL 54 /* Illegal command attempted */ -#define SOUND_FAIL 55 /* Fail to get a spell off / activate an item */ -#define SOUND_WAKEUP 56 /* A monster wakes up */ -#define SOUND_INVULN 57 /* Invulnerability! */ -#define SOUND_FALL 58 /* Falling through a trapdoor... */ -#define SOUND_PAIN 59 /* A monster is in pain! */ -#define SOUND_DESTITEM 60 /* An item was destroyed by misc. means */ -#define SOUND_MOAN 61 /* A monster makes a moan/beg/insult attack */ -#define SOUND_SHOW 62 /* A monster makes a "show" attack */ -#define SOUND_UNUSED 63 /* (no sound for gaze attacks) */ -#define SOUND_EXPLODE 64 /* Something (or somebody) explodes */ - -/* - * Mega-Hack -- maximum known sounds - */ -#define SOUND_MAX 65 - - - -/*** Hack ***/ - /* * Road flags @@ -3351,7 +2100,6 @@ #define BACT_REST 17 #define BACT_FOOD 18 #define BACT_RUMORS 19 -#define BACT_RESEARCH_MONSTER 20 #define BACT_COMPARE_WEAPONS 21 #define BACT_ENCHANT_WEAPON 23 #define BACT_ENCHANT_ARMOR 24 @@ -3420,19 +2168,6 @@ #define FATE_DIE 6 /* - * Runes definition - */ -#define RUNE_SELF 0x00000001 -#define RUNE_ARROW 0x00000002 -#define RUNE_RAY 0x00000004 -#define RUNE_SPHERE 0x00000008 -#define RUNE_POWER_SURGE 0x00000010 -#define RUNE_ARMAGEDDON 0x00000020 -#define RUNE_MOD_MAX 6 -#define RUNE_STONE 0x000000FF - - -/* * Defines of the different dungeon types */ #define DUNGEON_WILDERNESS 0 @@ -3464,7 +2199,7 @@ */ #define level_or_feat(DTYPE, DLEVEL) \ ((DTYPE) == DUNGEON_WILDERNESS ? \ - wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat : \ + (game->wilderness)(p_ptr->wilderness_x, p_ptr->wilderness_y).feat : \ (DLEVEL) ) @@ -3541,12 +2276,6 @@ #define MEGO_CHANCE 18 /* % chances of getting ego monsters */ -/* Object generation */ -#define OBJ_GENE_TREASURE 20 -#define OBJ_GENE_COMBAT 20 -#define OBJ_GENE_MAGIC 20 -#define OBJ_GENE_TOOL 20 - /* * Used (or should be) by various functions and tables needing access to * single bits @@ -3559,21 +2288,6 @@ /* - * Store flags - */ -#define SF1_DEPEND_LEVEL 0x00000001L -#define SF1_SHALLOW_LEVEL 0x00000002L -#define SF1_MEDIUM_LEVEL 0x00000004L -#define SF1_DEEP_LEVEL 0x00000008L -#define SF1_RARE 0x00000010L -#define SF1_VERY_RARE 0x00000020L -#define SF1_COMMON 0x00000040L -#define SF1_ALL_ITEM 0x00000080L /* Works as the BM */ -#define SF1_RANDOM 0x00000100L -#define SF1_FORCE_LEVEL 0x00000200L -#define SF1_MUSEUM 0x00000400L - -/* * Shield effect options */ #define SHIELD_NONE 0x0000 @@ -3747,11 +2461,6 @@ /* Number of skill choices for Lost Sword quests. */ #define LOST_SWORD_NSKILLS 4 -/* SKill flags */ -#define SKF1_HIDDEN 0x00000001 /* Starts hidden */ -#define SKF1_AUTO_HIDE 0x00000002 /* Tries to rehide at calc_bonus */ -#define SKF1_RANDOM_GAIN 0x00000004 /* Can be randomly gained by certain quests & such */ - #define MAX_MELEE 3 @@ -3795,7 +2504,6 @@ #define CMD_DUMP_HTML -8186 #define CMD_MACRO -8185 #define CMD_QUEST -8184 -#define CMD_BLUNDER -8183 #define CMD_SHOW_ABILITY -8182 #define CLI_MAX 128 @@ -3818,7 +2526,6 @@ #define AB_AMMO_CREATION 5 #define AB_DEATH_TOUCH 6 #define AB_FAR_REACHING 8 -#define AB_TRAPPING 9 #define AB_UNDEAD_FORM 10 /** diff --git a/src/dungeon.cc b/src/dungeon.cc index 3ec79068..f8671387 100644 --- a/src/dungeon.cc +++ b/src/dungeon.cc @@ -10,7 +10,6 @@ #include "dungeon.h" #include "birth.hpp" -#include "birth.h" #include "cave.hpp" #include "cave_type.hpp" #include "cmd1.hpp" @@ -21,10 +20,13 @@ #include "cmd6.hpp" #include "cmd7.hpp" #include "corrupt.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.h" #include "files.hpp" +#include "game.hpp" #include "generate.hpp" #include "gen_evol.hpp" #include "gods.hpp" @@ -40,21 +42,23 @@ #include "monster2.hpp" #include "monster3.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "modules.hpp" #include "notes.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" #include "player_race.hpp" +#include "player_race_flag.hpp" #include "player_race_mod.hpp" #include "player_spec.hpp" #include "player_type.hpp" #include "powers.hpp" #include "quest.hpp" -#include "quark.hpp" #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" @@ -130,7 +134,9 @@ static byte value_check_aux1(object_type const *o_ptr) static byte value_check_aux1_magic(object_type const *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[o_ptr->k_idx]; switch (o_ptr->tval) @@ -219,7 +225,9 @@ static byte value_check_aux2(object_type const *o_ptr) static byte value_check_aux2_magic(object_type const *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[o_ptr->k_idx]; switch (o_ptr->tval) @@ -284,7 +292,7 @@ static byte value_check_aux2_magic(object_type const *o_ptr) /* * Can a player be resurrected? */ -static bool_ granted_resurrection(void) +static bool_ granted_resurrection() { if (praying_to(GOD_ERU)) { @@ -321,7 +329,6 @@ static sense_function_t select_sense(object_type *o_ptr, sense_function_t combat case TV_HARD_ARMOR: case TV_DRAG_ARMOR: case TV_BOOMERANG: - case TV_TRAPKIT: { return combat; } @@ -473,7 +480,7 @@ void sense_objects(std::vector<int> const &object_idxs) squeltch_inventory(); } -void sense_inventory(void) +void sense_inventory() { static std::vector<int> idxs; // Initialize static vector if necessary @@ -491,7 +498,7 @@ void sense_inventory(void) /* * Go to any level (ripped off from wiz_jump) */ -static void pattern_teleport(void) +static void pattern_teleport() { /* Ask for level */ if (get_check("Teleport level? ")) @@ -544,27 +551,27 @@ static void pattern_teleport(void) /* * Returns TRUE if we are on the Straight Road... */ -static bool_ pattern_effect(void) +static bool_ pattern_effect() { if ((cave[p_ptr->py][p_ptr->px].feat < FEAT_PATTERN_START) || (cave[p_ptr->py][p_ptr->px].feat > FEAT_PATTERN_XTRA2)) return (FALSE); if (cave[p_ptr->py][p_ptr->px].feat == FEAT_PATTERN_END) { - (void)set_poisoned(0); - (void)set_image(0); - (void)set_stun(0); - (void)set_cut(0); - (void)set_blind(0); - (void)set_afraid(0); - (void)do_res_stat(A_STR, TRUE); - (void)do_res_stat(A_INT, TRUE); - (void)do_res_stat(A_WIS, TRUE); - (void)do_res_stat(A_DEX, TRUE); - (void)do_res_stat(A_CON, TRUE); - (void)do_res_stat(A_CHR, TRUE); - (void)restore_level(); - (void)hp_player(1000); + set_poisoned(0); + set_image(0); + set_stun(0); + set_cut(0); + set_blind(0); + set_afraid(0); + do_res_stat(A_STR, TRUE); + do_res_stat(A_INT, TRUE); + do_res_stat(A_WIS, TRUE); + do_res_stat(A_DEX, TRUE); + do_res_stat(A_CON, TRUE); + do_res_stat(A_CHR, TRUE); + restore_level(); + hp_player(1000); cave_set_feat(p_ptr->py, p_ptr->px, FEAT_PATTERN_OLD); msg_print("This section of the Straight Road looks less powerful."); } @@ -606,16 +613,14 @@ static bool_ pattern_effect(void) */ static void recharged_notice(object_type *o_ptr) { - char o_name[80]; - - cptr s; - - /* No inscription */ - if (!o_ptr->note) return; + if (o_ptr->inscription.empty()) + { + return; + } /* Find a '!' */ - s = strchr(quark_str(o_ptr->note), '!'); + auto s = strchr(o_ptr->inscription.c_str(), '!'); /* Process notification request. */ while (s) @@ -624,6 +629,7 @@ static void recharged_notice(object_type *o_ptr) if (s[1] == '!') { /* Describe (briefly) */ + char o_name[80]; object_desc(o_name, o_ptr, FALSE, 0); /* Notify the player */ @@ -770,8 +776,10 @@ static void regenmana(int percent) * * XXX XXX XXX Should probably be done during monster turns. */ -static void regen_monsters(void) +static void regen_monsters() { + auto const &r_info = game->edit_data.r_info; + int i, frac; object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY]; @@ -779,7 +787,7 @@ static void regen_monsters(void) if (o_ptr->k_idx) { - monster_race *r_ptr = &r_info[o_ptr->pval]; + auto r_ptr = &r_info[o_ptr->pval]; /* Allow regeneration (if needed) */ if (o_ptr->pval2 < o_ptr->pval3) @@ -791,7 +799,7 @@ static void regen_monsters(void) if (!frac) frac = 1; /* Hack -- Some monsters regenerate quickly */ - if (r_ptr->flags2 & (RF2_REGENERATE)) frac *= 2; + if (r_ptr->flags & RF_REGENERATE) frac *= 2; /* Hack -- Regenerate */ @@ -828,7 +836,7 @@ static void regen_monsters(void) /* Hack -- Some monsters regenerate quickly */ auto const r_ptr = m_ptr->race(); - if (r_ptr->flags2 & (RF2_REGENERATE)) frac *= 2; + if (r_ptr->flags & RF_REGENERATE) frac *= 2; /* Hack -- Regenerate */ m_ptr->hp += frac; @@ -848,17 +856,10 @@ static void regen_monsters(void) * * Should belong to object1.c, renamed to object_decays() -- pelpel */ -static bool_ decays(object_type *o_ptr) +static bool decays(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - - - /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if (f3 & TR3_DECAY) return (TRUE); - - return (FALSE); + auto const flags = object_flags(o_ptr); + return bool(flags & TR_DECAY); } @@ -900,9 +901,11 @@ static void check_music() */ static void apply_effect(int y, int x) { + auto const &f_info = game->edit_data.f_info; + cave_type *c_ptr = &cave[y][x]; - feature_type *f_ptr = &f_info[c_ptr->feat]; + auto f_ptr = &f_info[c_ptr->feat]; if (f_ptr->d_frequency[0] != 0) @@ -963,7 +966,7 @@ static void process_world_corruptions() } else { - disturb(0); + disturb(); msg_print("Your corruption takes over you, you teleport!"); teleport_player(50); } @@ -1018,8 +1021,8 @@ static bool_ grace_delay_trigger() */ static void process_world_gods() { - const char *race_name = rp_ptr->title; - const char *subrace_name = rmp_ptr->title; + auto const &race_name = rp_ptr->title; + auto const &subrace_name = rmp_ptr->title; if (p_ptr->pgod == GOD_VARDA) { @@ -1031,10 +1034,10 @@ static void process_world_gods() inc_piety(GOD_ALL, 2); } - if (streq(race_name, "Orc") || - streq(race_name, "Troll") || - streq(race_name, "Dragon") || - streq(race_name, "Demon")) + if ((race_name == "Orc") || + (race_name == "Troll") || + (race_name == "Dragon") || + (race_name == "Demon")) { /* Varda hates evil races */ inc_piety(GOD_ALL, -2); @@ -1057,16 +1060,16 @@ static void process_world_gods() { int i; /* Ulmo likes the Edain (except Easterlings) */ - if (streq(race_name, "Human") || - streq(race_name, "Dunadan") || - streq(race_name, "Druadan") || - streq(race_name, "RohanKnight")) + if ((race_name == "Human") || + (race_name == "Dunadan") || + (race_name == "Druadan") || + (race_name == "RohanKnight")) { inc_piety(GOD_ALL, 2); } - else if (streq(race_name, "Easterling") || - streq(race_name, "Demon") || - streq(race_name, "Orc")) + else if ((race_name == "Easterling") || + (race_name == "Demon") || + (race_name == "Orc")) { /* hated races */ inc_piety(GOD_ALL, -2); @@ -1101,10 +1104,10 @@ static void process_world_gods() /* Aule likes Dwarves and Dark Elves (Eol's * influence here) */ - if (!(streq(race_name, "Dwarf") || - streq(race_name, "Petty-dwarf") || - streq(race_name, "Gnome") || - streq(race_name, "Dark-Elf"))) + if (!((race_name == "Dwarf") || + (race_name == "Petty-dwarf") || + (race_name == "Gnome") || + (race_name == "Dark-Elf"))) { inc_piety(GOD_ALL, -1); } @@ -1180,20 +1183,20 @@ static void process_world_gods() if (grace_delay_trigger()) { /* He loves astral beings */ - if (streq(subrace_name, "LostSoul")) + if (subrace_name == "LostSoul") { inc_piety(GOD_ALL, 1); } /* He likes High Elves only, though, as races */ - if (!streq(race_name, "High-Elf")) + if (!(race_name == "High-Elf")) { inc_piety(GOD_ALL, -1); } /* Really hates vampires and demons */ - if (streq(subrace_name, "Vampire") || - streq(race_name, "Demon")) + if ((subrace_name == "Vampire") || + (race_name == "Demon")) { inc_piety(GOD_ALL, -10); } @@ -1217,9 +1220,12 @@ static void process_world_gods() * Note that a single movement in the overhead wilderness mode * consumes 132 times as much energy as a normal one... */ -static void process_world(void) +static void process_world() { - timer_type *t_ptr; + 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; + auto &timers = game->timers; int x, y, i, j; @@ -1227,13 +1233,11 @@ static void process_world(void) bool_ cave_no_regen = FALSE; int upkeep_factor = 0; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; cave_type *c_ptr; object_type *o_ptr; - u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5 = 0, esp = 0; - /* * Every 10 game turns -- which means this section is invoked once @@ -1264,22 +1268,14 @@ static void process_world(void) check_music(); } - /* Handle the timers */ - for (t_ptr = gl_timers; t_ptr != NULL; t_ptr = t_ptr->next) + /* Process timers */ + for (auto &&timer: timers) { - if (!t_ptr->enabled) continue; - - t_ptr->countdown--; - if (!t_ptr->countdown) - { - t_ptr->countdown = t_ptr->delay; - assert(t_ptr->callback != NULL); - t_ptr->callback(); - } + timer->count_down(); } /* Check the fate */ - if (fate_option && (p_ptr->lev > 10)) + if (options->fate_option && (p_ptr->lev > 10)) { /* * WAS: == 666 against randint(50000). @@ -1295,20 +1291,20 @@ static void process_world(void) if (o_ptr->k_idx) { - monster_race *r_ptr = &r_info[o_ptr->pval]; + auto r_ptr = &r_info[o_ptr->pval]; if ((randint(1000) < r_ptr->level - ((p_ptr->lev * 2) + get_skill(SKILL_SYMBIOTIC)))) { msg_format("%s breaks free from hypnosis!", - symbiote_name(TRUE)); + symbiote_name(true).c_str()); carried_make_attack_normal(o_ptr->pval); } } /*** Attempt timed autosave ***/ - if (autosave_t && autosave_freq) + if (options->autosave_t && options->autosave_freq) { - if ((turn % ((s32b)autosave_freq * 10)) == 0) + if ((turn % (static_cast<s32b>(options->autosave_freq) * 10)) == 0) { is_autosave = TRUE; msg_print("Autosaving the game..."); @@ -1346,10 +1342,13 @@ static void process_world(void) c_ptr = &cave[y][x]; /* Assume lit */ - c_ptr->info |= (CAVE_GLOW); + c_ptr->info |= CAVE_GLOW; /* Hack -- Memorize lit grids if allowed */ - if (view_perma_grids) c_ptr->info |= (CAVE_MARK); + if (options->view_perma_grids) + { + c_ptr->info |= CAVE_MARK; + } /* Hack -- Notice spot */ note_spot(y, x); @@ -1403,9 +1402,9 @@ static void process_world(void) (rand_int(d_info[(dun_level) ? dungeon_type : DUNGEON_WILDERNESS].max_m_alloc_chance) == 0)) { /* Make a new monster */ - if (!(dungeon_flags2 & DF2_NO_NEW_MONSTER)) + if (!(dungeon_flags & DF_NO_NEW_MONSTER)) { - (void)alloc_monster(MAX_SIGHT + 5, FALSE); + alloc_monster(MAX_SIGHT + 5, FALSE); } } @@ -1491,16 +1490,16 @@ static void process_world(void) int feature = cave[p_ptr->py][p_ptr->px].feat; /* Player can walk through or fly over trees */ - if ((has_ability(AB_TREE_WALK) || p_ptr->fly) && (feature == FEAT_TREES)) + if ((p_ptr->has_ability(AB_TREE_WALK) || p_ptr->fly) && (feature == FEAT_TREES)) { /* Do nothing */ } /* Player can climb over mountains */ - else if ((p_ptr->climb) && (f_info[feature].flags1 & FF1_CAN_CLIMB)) + else if ((p_ptr->climb) && (f_info[feature].flags & FF_CAN_CLIMB)) { /* Do nothing */ } - else if (race_flags1_p(PR1_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_CAN_PASS)) + else if (race_flags_p(PR_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags & FF_CAN_PASS)) { int amt = 1 + ((p_ptr->lev) / 5); @@ -1581,10 +1580,10 @@ static void process_world(void) o_ptr = &p_ptr->inventory[INVEN_WIELD]; /* Examine the sword */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hitpoints multiplier consume a lot of food */ - if (o_ptr->k_idx && (f2 & (TR2_LIFE))) i += o_ptr->pval * 5; + if (o_ptr->k_idx && (flags & TR_LIFE)) i += o_ptr->pval * 5; /* Slow digestion takes less food */ if (p_ptr->slow_digest) i -= 10; @@ -1593,7 +1592,7 @@ static void process_world(void) if (i < 1) i = 1; /* Digest some food */ - (void)set_food(p_ptr->food - i); + set_food(p_ptr->food - i); } } @@ -1601,7 +1600,7 @@ static void process_world(void) else { /* Digest a lot of food */ - (void)set_food(p_ptr->food - 100); + set_food(p_ptr->food - 100); } /* Starve to death (slowly) */ @@ -1642,10 +1641,10 @@ static void process_world(void) { /* Message */ msg_print("You faint from the lack of food."); - disturb(1); + disturb(); /* Hack -- faint (bypass free action) */ - (void)set_paralyzed(1 + rand_int(5)); + set_paralyzed(1 + rand_int(5)); } } } @@ -1665,8 +1664,8 @@ static void process_world(void) } - /* Searching or Resting */ - if (p_ptr->searching || resting) + /* Resting boosts regeneration */ + if (resting) { regen_amount = regen_amount * 2; } @@ -1675,7 +1674,7 @@ static void process_world(void) { int upkeep_divider = 20; - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) upkeep_divider = 15; if (total_friends > 1 + (p_ptr->lev / (upkeep_divider))) @@ -1725,7 +1724,7 @@ static void process_world(void) dec++; } - if (race_flags1_p(PR1_ELF)) + if (race_flags_p(PR_ELF)) { dec -= wisdom_scale(2); } @@ -1744,7 +1743,7 @@ static void process_world(void) dec++; } - if (race_flags1_p(PR1_ELF)) + if (race_flags_p(PR_ELF)) { dec += 5 - wisdom_scale(4); } @@ -1769,7 +1768,7 @@ static void process_world(void) int dec = 5 - wisdom_scale(3); /* Blech what an hideous hack */ - if (!strcmp(rp_ptr->title, "Ent")) + if (!(rp_ptr->title == "Ent")) { dec -= wisdom_scale(2); } @@ -1833,26 +1832,26 @@ static void process_world(void) /* Hack -- Hallucinating */ if (p_ptr->image) { - (void)set_image(p_ptr->image - 1); + set_image(p_ptr->image - 1); } /* Holy Aura */ if (p_ptr->holy) { - (void)set_holy(p_ptr->holy - 1); + set_holy(p_ptr->holy - 1); } /* Soul absorbtion */ if (p_ptr->absorb_soul) { - (void)set_absorb_soul(p_ptr->absorb_soul - 1); + set_absorb_soul(p_ptr->absorb_soul - 1); } /* Undead loose Death Points */ if (p_ptr->necro_extra & CLASS_UNDEAD) { int old_chp = p_ptr->chp; - int warning = (p_ptr->mhp * hitpoint_warn / 10); + int warning = (p_ptr->mhp * options->hitpoint_warn / 10); /* Bypass invulnerability and wraithform */ p_ptr->chp--; @@ -1866,13 +1865,10 @@ static void process_world(void) /* Dead player */ if (p_ptr->chp < 0) { - bool_ old_quick = quick_messages; - - /* Sound */ - sound(SOUND_DEATH); + bool_ old_quick = options->quick_messages; /* Hack -- Note death */ - if (!last_words) + if (!options->last_words) { msg_print("You die."); msg_print(NULL); @@ -1881,14 +1877,16 @@ static void process_world(void) { char death_message[80]; - (void)get_rnd_line("death.txt", death_message); + get_rnd_line("death.txt", death_message); msg_print(death_message); } - /* Note cause of death */ - (void)strcpy(died_from, "being undead too long"); - - if (p_ptr->image) strcat(died_from, "(?)"); + /* Note cause of death; hallucinating characters don't get to know. */ + game->died_from = "being undead too long"; + if (p_ptr->image) + { + game->died_from = "(?)"; + } /* No longer a winner */ total_winner = FALSE; @@ -1899,12 +1897,12 @@ static void process_world(void) /* Note death */ death = TRUE; - quick_messages = FALSE; + options->quick_messages = FALSE; if (get_check("Make a last screenshot? ")) { do_cmd_html_dump(); } - quick_messages = old_quick; + options->quick_messages = old_quick; /* Dead */ return; @@ -1914,9 +1912,10 @@ static void process_world(void) if (p_ptr->chp < warning) { /* Hack -- bell on first notice */ - if (alert_hitpoint && (old_chp > warning)) bell(); - - sound(SOUND_WARN); + if (old_chp > warning) + { + bell(); + } /* Message */ msg_print("*** LOW DEATHPOINT WARNING! ***"); @@ -1927,29 +1926,29 @@ static void process_world(void) /* True Strike */ if (p_ptr->strike) { - (void)set_strike(p_ptr->strike - 1); + set_strike(p_ptr->strike - 1); } /* Timed project */ if (p_ptr->tim_project) { - (void)set_project(p_ptr->tim_project - 1, p_ptr->tim_project_gf, p_ptr->tim_project_dam, p_ptr->tim_project_rad, p_ptr->tim_project_flag); + set_project(p_ptr->tim_project - 1, p_ptr->tim_project_gf, p_ptr->tim_project_dam, p_ptr->tim_project_rad, p_ptr->tim_project_flag); } /* Timed roots */ if (p_ptr->tim_roots) { - (void)set_roots(p_ptr->tim_roots - 1, p_ptr->tim_roots_ac, p_ptr->tim_roots_dam); + set_roots(p_ptr->tim_roots - 1, p_ptr->tim_roots_ac, p_ptr->tim_roots_dam); } /* Timed breath */ if (p_ptr->tim_water_breath) { - (void)set_tim_breath(p_ptr->tim_water_breath - 1, FALSE); + set_tim_breath(p_ptr->tim_water_breath - 1, FALSE); } if (p_ptr->tim_magic_breath) { - (void)set_tim_breath(p_ptr->tim_magic_breath - 1, TRUE); + set_tim_breath(p_ptr->tim_magic_breath - 1, TRUE); } /* Timed precognition */ @@ -1961,41 +1960,41 @@ static void process_world(void) /* Timed regen */ if (p_ptr->tim_regen) { - (void)set_tim_regen(p_ptr->tim_regen - 1, p_ptr->tim_regen_pow); + set_tim_regen(p_ptr->tim_regen - 1, p_ptr->tim_regen_pow); } /* Timed Disrupt shield */ if (p_ptr->disrupt_shield) { - (void)set_disrupt_shield(p_ptr->disrupt_shield - 1); + set_disrupt_shield(p_ptr->disrupt_shield - 1); } /* Timed Parasite */ if (p_ptr->parasite) { - (void)set_parasite(p_ptr->parasite - 1, p_ptr->parasite_r_idx); + set_parasite(p_ptr->parasite - 1, p_ptr->parasite_r_idx); } /* Timed Reflection */ if (p_ptr->tim_reflect) { - (void)set_tim_reflect(p_ptr->tim_reflect - 1); + set_tim_reflect(p_ptr->tim_reflect - 1); } /* Timed Prob Travel */ if (p_ptr->prob_travel) { - (void)set_prob_travel(p_ptr->prob_travel - 1); + set_prob_travel(p_ptr->prob_travel - 1); } /* Timed Levitation */ if (p_ptr->tim_ffall) { - (void)set_tim_ffall(p_ptr->tim_ffall - 1); + set_tim_ffall(p_ptr->tim_ffall - 1); } if (p_ptr->tim_fly) { - (void)set_tim_fly(p_ptr->tim_fly - 1); + set_tim_fly(p_ptr->tim_fly - 1); } /* Thunderstorm */ @@ -2037,37 +2036,37 @@ static void process_world(void) PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE); } - (void)set_tim_thunder(p_ptr->tim_thunder - 1, p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2); + set_tim_thunder(p_ptr->tim_thunder - 1, p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2); } /* Poisonned hands */ if (p_ptr->tim_poison) { - (void)set_poison(p_ptr->tim_poison - 1); + set_poison(p_ptr->tim_poison - 1); } /* Brightness */ if (p_ptr->tim_lite) { - (void)set_lite(p_ptr->tim_lite - 1); + set_lite(p_ptr->tim_lite - 1); } /* Blindness */ if (p_ptr->blind) { - (void)set_blind(p_ptr->blind - 1); + set_blind(p_ptr->blind - 1); } /* Timed no_breeds */ if (no_breeds) { - (void)set_no_breeders(no_breeds - 1); + set_no_breeders(no_breeds - 1); } /* Timed mimic */ if (p_ptr->tim_mimic) { - (void)set_mimic(p_ptr->tim_mimic - 1, p_ptr->mimic_form, p_ptr->mimic_level); + set_mimic(p_ptr->tim_mimic - 1, p_ptr->mimic_form, p_ptr->mimic_level); } /* Timed special move commands */ @@ -2079,25 +2078,25 @@ static void process_world(void) /* Timed invisibility */ if (p_ptr->tim_invisible) { - (void)set_invis(p_ptr->tim_invisible - 1, p_ptr->tim_inv_pow); + set_invis(p_ptr->tim_invisible - 1, p_ptr->tim_inv_pow); } /* Times see-invisible */ if (p_ptr->tim_invis) { - (void)set_tim_invis(p_ptr->tim_invis - 1); + set_tim_invis(p_ptr->tim_invis - 1); } /* Timed esp */ if (p_ptr->tim_esp) { - (void)set_tim_esp(p_ptr->tim_esp - 1); + set_tim_esp(p_ptr->tim_esp - 1); } /* Timed infra-vision */ if (p_ptr->tim_infra) { - (void)set_tim_infra(p_ptr->tim_infra - 1); + set_tim_infra(p_ptr->tim_infra - 1); } /* Paralysis */ @@ -2109,139 +2108,109 @@ static void process_world(void) /* Confusion */ if (p_ptr->confused) { - (void)set_confused(p_ptr->confused - 1); + set_confused(p_ptr->confused - 1); } /* Afraid */ if (p_ptr->afraid) { - (void)set_afraid(p_ptr->afraid - 1); + set_afraid(p_ptr->afraid - 1); } /* Fast */ if (p_ptr->fast) { - (void)set_fast(p_ptr->fast - 1, p_ptr->speed_factor); + set_fast(p_ptr->fast - 1, p_ptr->speed_factor); } /* Light speed */ if (p_ptr->lightspeed) { - (void)set_light_speed(p_ptr->lightspeed - 1); + set_light_speed(p_ptr->lightspeed - 1); } /* Slow */ if (p_ptr->slow) { - (void)set_slow(p_ptr->slow - 1); + set_slow(p_ptr->slow - 1); } /* Protection from evil */ if (p_ptr->protevil) { - (void)set_protevil(p_ptr->protevil - 1); - } - - /* Protection from good */ - if (p_ptr->protgood) - { - (void)set_protgood(p_ptr->protgood - 1); - } - - /* Protection from undead */ - if (p_ptr->protundead) - { - (void)set_protundead(p_ptr->protundead - 1); + set_protevil(p_ptr->protevil - 1); } /* Invulnerability */ if (p_ptr->invuln) { - (void)set_invuln(p_ptr->invuln - 1); + set_invuln(p_ptr->invuln - 1); } /* Wraith form */ if (p_ptr->tim_wraith) { - (void)set_shadow(p_ptr->tim_wraith - 1); + set_shadow(p_ptr->tim_wraith - 1); } /* Heroism */ if (p_ptr->hero) { - (void)set_hero(p_ptr->hero - 1); + set_hero(p_ptr->hero - 1); } /* Super Heroism */ if (p_ptr->shero) { - (void)set_shero(p_ptr->shero - 1); + set_shero(p_ptr->shero - 1); } /* Blessed */ if (p_ptr->blessed) { - (void)set_blessed(p_ptr->blessed - 1); + set_blessed(p_ptr->blessed - 1); } /* Shield */ if (p_ptr->shield) { - (void)set_shield(p_ptr->shield - 1, p_ptr->shield_power, p_ptr->shield_opt, p_ptr->shield_power_opt, p_ptr->shield_power_opt2); + set_shield(p_ptr->shield - 1, p_ptr->shield_power, p_ptr->shield_opt, p_ptr->shield_power_opt, p_ptr->shield_power_opt2); } /* Oppose Acid */ if (p_ptr->oppose_acid) { - (void)set_oppose_acid(p_ptr->oppose_acid - 1); + set_oppose_acid(p_ptr->oppose_acid - 1); } /* Oppose Lightning */ if (p_ptr->oppose_elec) { - (void)set_oppose_elec(p_ptr->oppose_elec - 1); + set_oppose_elec(p_ptr->oppose_elec - 1); } /* Oppose Fire */ if (p_ptr->oppose_fire) { - (void)set_oppose_fire(p_ptr->oppose_fire - 1); + set_oppose_fire(p_ptr->oppose_fire - 1); } /* Oppose Cold */ if (p_ptr->oppose_cold) { - (void)set_oppose_cold(p_ptr->oppose_cold - 1); + set_oppose_cold(p_ptr->oppose_cold - 1); } /* Oppose Poison */ if (p_ptr->oppose_pois) { - (void)set_oppose_pois(p_ptr->oppose_pois - 1); - } - - /* Oppose Light & Dark */ - if (p_ptr->oppose_ld) - { - (void)set_oppose_ld(p_ptr->oppose_ld - 1); + set_oppose_pois(p_ptr->oppose_pois - 1); } /* Oppose Chaos & Confusion */ if (p_ptr->oppose_cc) { - (void)set_oppose_cc(p_ptr->oppose_cc - 1); - } - - /* Oppose Sound & Shards */ - if (p_ptr->oppose_ss) - { - (void)set_oppose_ss(p_ptr->oppose_ss - 1); - } - - /* Oppose Nexus */ - if (p_ptr->oppose_nex) - { - (void)set_oppose_nex(p_ptr->oppose_nex - 1); + set_oppose_cc(p_ptr->oppose_cc - 1); } /* Timed mimicry */ @@ -2266,7 +2235,7 @@ static void process_world(void) att &= ~(CLASS_LEGS); att &= ~(CLASS_WALL); - if (disturb_state) disturb(0); + disturb_on_state(); } p_ptr->update |= (PU_BODY); @@ -2283,7 +2252,7 @@ static void process_world(void) int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + 1); /* Apply some healing */ - (void)set_poisoned(p_ptr->poisoned - adjust); + set_poisoned(p_ptr->poisoned - adjust); } /* Stun */ @@ -2292,7 +2261,7 @@ static void process_world(void) int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + 1); /* Apply some healing */ - (void)set_stun(p_ptr->stun - adjust); + set_stun(p_ptr->stun - adjust); } /* Cut */ @@ -2304,7 +2273,7 @@ static void process_world(void) if (p_ptr->cut > 1000) adjust = 0; /* Apply some healing */ - (void)set_cut(p_ptr->cut - adjust); + set_cut(p_ptr->cut - adjust); } /* Hack - damage done by the dungeon -SC- */ @@ -2327,7 +2296,7 @@ static void process_world(void) { int l, dam = 0; - if (!(dungeon_flags1 & DF1_DAMAGE_FEAT)) + if (!(dungeon_flags & DF_DAMAGE_FEAT)) { /* If the grid is empty, skip it */ if ((cave[j][k].o_idxs.empty()) && @@ -2560,14 +2529,14 @@ static void process_world(void) } /* Arg cannot breath? */ - if ((dungeon_flags2 & DF2_WATER_BREATH) && (!p_ptr->water_breath)) + if ((dungeon_flags & DF_WATER_BREATH) && (!p_ptr->water_breath)) { cmsg_print(TERM_L_RED, "You cannot breathe water! You suffocate!"); take_hit(damroll(3, p_ptr->lev), "suffocating"); } - if ((dungeon_flags2 & DF2_NO_BREATH) && (!p_ptr->magical_breath)) + if ((dungeon_flags & DF_NO_BREATH) && (!p_ptr->magical_breath)) { - cmsg_print(TERM_L_RED, "There is no air there! You suffocate!"); + cmsg_print(TERM_L_RED, "There is no air here! You suffocate!"); take_hit(damroll(3, p_ptr->lev), "suffocating"); } @@ -2579,8 +2548,6 @@ static void process_world(void) */ if (((turn % 3000) == 0) && p_ptr->black_breath) { - u32b f1, f2, f3, f4, f5; - bool_ be_silent = FALSE; /* check all equipment for the Black Breath flag. */ @@ -2592,10 +2559,10 @@ static void process_world(void) if (!o_ptr->k_idx) continue; /* Extract the item flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* No messages if object has the flag, to avoid annoyance. */ - if (f4 & (TR4_BLACK_BREATH)) be_silent = TRUE; + if (flags & TR_BLACK_BREATH) be_silent = TRUE; } /* If we are allowed to speak, warn and disturb. */ @@ -2603,7 +2570,7 @@ static void process_world(void) if (!be_silent) { cmsg_print(TERM_L_DARK, "The Black Breath saps your soul!"); - disturb(0); + disturb(); } } @@ -2617,10 +2584,10 @@ static void process_world(void) if (o_ptr->tval == TV_LITE) { /* Extract the item flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack -- Use some fuel */ - if ((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0)) + if ((flags & TR_FUEL_LITE) && (o_ptr->timeout > 0)) { /* Decrease life-span */ o_ptr->timeout--; @@ -2642,14 +2609,17 @@ static void process_world(void) /* The light is now out */ else if (o_ptr->timeout < 1) { - disturb(0); + disturb(); cmsg_print(TERM_YELLOW, "Your light has gone out!"); } /* The light is getting dim */ else if ((o_ptr->timeout < 100) && (o_ptr->timeout % 10 == 0)) { - if (disturb_minor) disturb(0); + if (options->disturb_minor) + { + disturb(); + } cmsg_print(TERM_YELLOW, "Your light is growing faint."); } } @@ -2671,14 +2641,14 @@ static void process_world(void) byte chance = 0; int plev = p_ptr->lev; - if (race_flags1_p(PR1_RESIST_BLACK_BREATH)) chance = 2; + if (race_flags_p(PR_RESIST_BLACK_BREATH)) chance = 2; else chance = 5; if ((rand_int(100) < chance) && (p_ptr->exp > 0)) { p_ptr->exp -= 1 + plev / 5; p_ptr->max_exp -= 1 + plev / 5; - (void)do_dec_stat(rand_int(6), STAT_DEC_NORMAL); + do_dec_stat(rand_int(6), STAT_DEC_NORMAL); check_experience(); } } @@ -2692,7 +2662,7 @@ static void process_world(void) if (p_ptr->csp < 0) { p_ptr->csp = 0; - disturb(0); + disturb(); } /* Redraw */ @@ -2711,7 +2681,7 @@ static void process_world(void) if (p_ptr->csp < 0) { p_ptr->csp = 0; - disturb(0); + disturb(); p_ptr->maintain_sum = 0; } @@ -2738,7 +2708,7 @@ static void process_world(void) if (p_ptr->chp == 0) { - disturb(0); + disturb(); } /* Redraw */ @@ -2766,17 +2736,17 @@ static void process_world(void) /* Get the object */ o_ptr = &p_ptr->inventory[i]; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* TY Curse */ - if ((f3 & TR3_TY_CURSE) && (rand_int(TY_CURSE_CHANCE) == 0)) + if ((flags & TR_TY_CURSE) && (rand_int(TY_CURSE_CHANCE) == 0)) { activate_ty_curse(); } /* DG Curse */ - if ((f4 & TR4_DG_CURSE) && (rand_int(DG_CURSE_CHANCE) == 0)) + if ((flags & TR_DG_CURSE) && (rand_int(DG_CURSE_CHANCE) == 0)) { activate_dg_curse(); @@ -2785,7 +2755,7 @@ static void process_world(void) } /* Auto Curse */ - if ((f3 & TR3_AUTO_CURSE) && (rand_int(AUTO_CURSE_CHANCE) == 0)) + if ((flags & TR_AUTO_CURSE) && (rand_int(AUTO_CURSE_CHANCE) == 0)) { /* The object recurse itself ! */ o_ptr->ident |= IDENT_CURSED; @@ -2795,26 +2765,24 @@ static void process_world(void) * Hack: Uncursed teleporting items (e.g. Dragon Weapons) * can actually be useful! */ - if ((f3 & TR3_TELEPORT) && (rand_int(100) < 1)) + if ((flags & TR_TELEPORT) && (rand_int(100) < 1)) { if ((o_ptr->ident & IDENT_CURSED) && !p_ptr->anti_tele) { - disturb(0); + disturb(); /* Teleport player */ teleport_player(40); } else { - if (p_ptr->wild_mode || - (o_ptr->note && strchr(quark_str(o_ptr->note), '.'))) + if (p_ptr->wild_mode || strchr(o_ptr->inscription.c_str(), '.')) { - /* Do nothing */ - /* msg_print("Teleport aborted.") */; + /* Suppress teleportation */ } else if (get_check("Teleport? ")) { - disturb(0); + disturb(); teleport_player(50); } } @@ -2825,7 +2793,7 @@ static void process_world(void) if (!o_ptr->k_idx) continue; /* Hack: Skip wielded lights that need fuel (already handled above) */ - if ((i == INVEN_LITE) && (o_ptr->tval == TV_LITE) && (f4 & TR4_FUEL_LITE)) continue; + if ((i == INVEN_LITE) && (o_ptr->tval == TV_LITE) && (flags & TR_FUEL_LITE)) continue; /* Recharge activatable objects */ if (o_ptr->timeout > 0) @@ -2840,16 +2808,6 @@ static void process_world(void) j++; } } - - /* Recharge second spell in Mage Staffs of Spells */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL) && (o_ptr->xtra2 > 0)) - { - /* Recharge */ - o_ptr->xtra2--; - - /* Notice changes */ - if (o_ptr->xtra2 == 0) j++; - } } /* Notice changes */ @@ -2868,10 +2826,10 @@ static void process_world(void) if (!o_ptr->k_idx) continue; /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Temporary items are destroyed */ - if (f5 & TR5_TEMPORARY) + if (flags & TR_TEMPORARY) { o_ptr->timeout--; @@ -2888,7 +2846,7 @@ static void process_world(void) if ((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->timeout < o_ptr->pval2)) { /* Increase the rod's mana. */ - o_ptr->timeout += (f4 & TR4_CHARGING) ? 2 : 1; + o_ptr->timeout += (flags & TR_CHARGING) ? 2 : 1; /* Always notice */ j++; @@ -2902,7 +2860,7 @@ static void process_world(void) } /* Examine all charging random artifacts */ - if ((f5 & TR5_ACTIVATE_NO_WIELD) && (o_ptr->timeout > 0)) + if ((flags & TR_ACTIVATE_NO_WIELD) && (o_ptr->timeout > 0)) { /* Charge it */ o_ptr->timeout--; @@ -2923,11 +2881,11 @@ static void process_world(void) { if (o_ptr->timeout > 0) { - if (dungeon_flags1 & DF1_HOT) + if (dungeon_flags & DF_HOT) { o_ptr->pval -= 2; } - else if ((dungeon_flags1 & DF1_COLD) && rand_int(2)) + else if ((dungeon_flags & DF_COLD) && rand_int(2)) { if (magik(50)) o_ptr->pval--; } @@ -2967,7 +2925,7 @@ static void process_world(void) monster_type *m_ptr = &m_list[cave[my][mx].m_idx]; auto const r_ptr = m_ptr->race(); - if ((r_ptr->flags9 & RF9_IMPRESED) && can_create_companion()) + if ((r_ptr->flags & RF_IMPRESED) && can_create_companion()) { msg_format("And you have given the imprint to your %s!", r_ptr->name); m_ptr->status = MSTATUS_COMPANION; @@ -3003,10 +2961,10 @@ static void process_world(void) if (!o_ptr->k_idx) continue; /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Temporary items are destroyed */ - if (f5 & TR5_TEMPORARY) + if (flags & TR_TEMPORARY) { o_ptr->timeout--; @@ -3024,7 +2982,7 @@ static void process_world(void) if ((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->timeout < o_ptr->pval2)) { /* Increase the rod's mana. */ - o_ptr->timeout += (f4 & TR4_CHARGING) ? 2 : 1; + o_ptr->timeout += (flags & TR_CHARGING) ? 2 : 1; /* Do not overflow */ if (o_ptr->timeout >= o_ptr->pval2) @@ -3041,11 +2999,11 @@ static void process_world(void) { if (o_ptr->timeout > 0) { - if (dungeon_flags1 & DF1_HOT) + if (dungeon_flags & DF_HOT) { o_ptr->pval -= 2; } - else if ((dungeon_flags1 & DF1_COLD) && rand_int(2)) + else if ((dungeon_flags & DF_COLD) && rand_int(2)) { if (magik(50)) o_ptr->pval--; } @@ -3099,7 +3057,7 @@ static void process_world(void) } /* No recall. sorry */ - else if (dungeon_flags2 & DF2_NO_RECALL_OUT) + else if (dungeon_flags & DF_NO_RECALL_OUT) { cmsg_print(TERM_L_DARK, "You cannot recall from here."); p_ptr->word_recall = 0; @@ -3147,7 +3105,7 @@ static void process_world(void) if (p_ptr->word_recall == 0) { /* Disturbing! */ - disturb(0); + disturb(); /* Determine the level */ if (p_ptr->inside_quest) @@ -3186,9 +3144,6 @@ static void process_world(void) p_ptr->leaving = TRUE; p_ptr->wild_mode = FALSE; } - - /* Sound */ - sound(SOUND_TPLEVEL); } } } @@ -3198,7 +3153,7 @@ static void process_world(void) /* * Verify use of "wizard" mode */ -static bool_ enter_wizard_mode(void) +static bool_ enter_wizard_mode() { /* Ask first time, but not while loading a dead char with the -w option */ if (!noscore && !(p_ptr->chp < 0)) @@ -3226,7 +3181,7 @@ static bool_ enter_wizard_mode(void) /* * Verify use of "debug" commands */ -static bool_ enter_debug_mode(void) +static bool_ enter_debug_mode() { /* Ask first time */ if (!noscore && !wizard) @@ -3257,8 +3212,10 @@ static bool_ enter_debug_mode(void) * * XXX XXX XXX Make some "blocks" */ -static void process_command(void) +static void process_command() { + auto const &wf_info = game->edit_data.wf_info; + char error_m[80]; /* Handle repeating the last command */ @@ -3412,7 +3369,7 @@ static void process_command(void) { if (do_control_walk()) break; - do_cmd_walk(always_pickup, TRUE); + do_cmd_walk(options->always_pickup); break; } @@ -3422,7 +3379,7 @@ static void process_command(void) { if (do_control_walk()) break; - do_cmd_walk(!always_pickup, TRUE); + do_cmd_walk(!options->always_pickup); break; } @@ -3442,7 +3399,7 @@ static void process_command(void) case ',': { if (do_control_pickup()) break; - do_cmd_stay(always_pickup); + do_cmd_stay(options->always_pickup); break; } @@ -3450,7 +3407,7 @@ static void process_command(void) case 'g': { if (p_ptr->control) break; - do_cmd_stay(!always_pickup); + do_cmd_stay(!options->always_pickup); break; } @@ -3462,23 +3419,6 @@ static void process_command(void) break; } - /* Search for traps/doors */ - case 's': - { - if (p_ptr->control) break; - do_cmd_search(); - break; - } - - /* Toggle search mode */ - case 'S': - { - if (p_ptr->control) break; - do_cmd_toggle_search(); - break; - } - - /*** Stairs and Doors and Chests and Traps ***/ /* Enter store */ @@ -3492,16 +3432,8 @@ static void process_command(void) /* Go up staircase */ case '<': { - object_type *o_ptr; - u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5 = 0, esp = 0; - - - /* Check for light being wielded */ - o_ptr = &p_ptr->inventory[INVEN_LITE]; - /* Burn some fuel in the current lite */ - if (o_ptr->tval == TV_LITE) - /* Extract the item flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + /* Get the light being wielded */ + auto o_ptr = &p_ptr->inventory[INVEN_LITE]; /* Cannot move if rooted in place */ if (p_ptr->tim_roots) break; @@ -3572,8 +3504,9 @@ static void process_command(void) /* Special cases */ else { - if ((wf_info[wild_map[p_ptr->py][p_ptr->px].feat].entrance >= 1000) || - (wild_map[p_ptr->py][p_ptr->px].entrance > 1000)) + auto const &wilderness = game->wilderness; + auto const &tile = wilderness(p_ptr->px, p_ptr->py); + if ((wf_info[tile.feat].entrance >= 1000) || (tile.entrance > 1000)) { p_ptr->wilderness_x = p_ptr->px; p_ptr->wilderness_y = p_ptr->py; @@ -3650,15 +3583,6 @@ static void process_command(void) break; } - /* Disarm a trap or chest */ - case 'D': - { - if (p_ptr->control) break; - if (!p_ptr->wild_mode) do_cmd_disarm(); - break; - } - - /*** Magic and Prayers ***/ /* Interact with skills */ @@ -3924,7 +3848,7 @@ static void process_command(void) if (p_ptr->control) break; if (p_ptr->wild_mode) break; - if (race_flags1_p(PR1_NO_GOD)) + if (race_flags_p(PR_NO_GOD)) { msg_print("You cannot worship gods."); } @@ -4186,12 +4110,7 @@ static void process_command(void) do_cmd_macro_recorder(); break; } - case CMD_BLUNDER: - { - if (do_control_walk()) break; - do_cmd_walk(always_pickup, FALSE); - break; - } + /* Hack -- Unknown command */ default: { @@ -4201,7 +4120,6 @@ static void process_command(void) if (rand_int(100) < insanity) { get_rnd_line("error.txt", error_m); - sound(SOUND_ILLEGAL); msg_print(error_m); } else @@ -4224,8 +4142,11 @@ static void process_command(void) * must come first just in case somebody manages to corrupt * the savefiles by clever use of menu commands or something. */ -static void process_player(void) +static void process_player() { + auto const &f_info = game->edit_data.f_info; + auto const &k_info = game->edit_data.k_info; + int i, j; int speed_use; @@ -4266,7 +4187,7 @@ static void process_player(void) /* Stop resting */ if ((p_ptr->chp == p_ptr->mhp) && (p_ptr->csp >= p_ptr->msp)) { - disturb(0); + disturb(); } } @@ -4297,14 +4218,14 @@ static void process_player(void) if (stop) { - disturb(0); + disturb(); } p_ptr->redraw |= (PR_FRAME); } } /* Handle "abort" */ - if (!avoid_abort) + if (!options->avoid_abort) { /* Check for "player abort" (semi-efficiently for resting) */ if (running || command_rep || (resting && !(resting & 0x0F))) @@ -4316,7 +4237,7 @@ static void process_player(void) flush(); /* Disturb */ - disturb(0); + disturb(); /* Hack -- Show a Message */ msg_print("Cancelled."); @@ -4344,14 +4265,17 @@ static void process_player(void) /* Hack -- mark current wilderness location as known */ if (!p_ptr->wild_mode && dun_level == 0) - wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].known = TRUE; + { + auto &wilderness = game->wilderness; + wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).known = TRUE; + } /* Place the cursor on the player */ move_cursor_relative(p_ptr->py, p_ptr->px); /* Refresh (optional) */ - if (fresh_before) Term_fresh(); + if (options->fresh_before) Term_fresh(); /* Hack -- Pack Overflow */ if (p_ptr->inventory[INVEN_PACK].k_idx) @@ -4366,7 +4290,7 @@ static void process_player(void) o_ptr = &p_ptr->inventory[item]; /* Disturbing */ - disturb(0); + disturb(); /* Warning */ msg_print("Your pack overflows!"); @@ -4494,7 +4418,7 @@ static void process_player(void) /* Shimmer monsters if needed */ - if (!avoid_other && shimmer_monsters) + if (!options->avoid_other && shimmer_monsters) { /* Clear the flag */ shimmer_monsters = FALSE; @@ -4512,7 +4436,7 @@ static void process_player(void) auto const r_ptr = m_ptr->race(); /* Skip non-multi-hued monsters */ - if (!(r_ptr->flags1 & (RF1_ATTR_MULTI))) continue; + if (!(r_ptr->flags & RF_ATTR_MULTI)) continue; /* Reset the flag */ shimmer_monsters = TRUE; @@ -4523,7 +4447,7 @@ static void process_player(void) } /* Shimmer objects if needed and requested */ - if (!avoid_other && !avoid_shimmer && shimmer_objects) + if (!options->avoid_other && !options->avoid_shimmer && shimmer_objects) { /* Clear the flag */ shimmer_objects = FALSE; @@ -4533,13 +4457,13 @@ static void process_player(void) { /* Acquire object -- for speed only base items are allowed to shimmer */ object_type *o_ptr = &o_list[i]; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Skip dead or carried objects */ if ((!o_ptr->k_idx) || (!o_ptr->ix)) continue; /* Skip non-multi-hued monsters */ - if (!(k_ptr->flags5 & (TR5_ATTR_MULTI))) continue; + if (!(k_ptr->flags & TR_ATTR_MULTI)) continue; /* Reset the flag */ shimmer_objects = TRUE; @@ -4559,7 +4483,7 @@ static void process_player(void) * fast, and that's why shimmering has been limited to small * number of monsters -- pelpel */ - if (!avoid_other && !avoid_shimmer && + if (!options->avoid_other && !options->avoid_shimmer && !resting && !running) { for (j = panel_row_min; j <= panel_row_max; j++) @@ -4567,21 +4491,16 @@ static void process_player(void) for (i = panel_col_min; i <= panel_col_max; i++) { cave_type *c_ptr = &cave[j][i]; - feature_type *f_ptr; + auto f_ptr = c_ptr->mimic + ? &f_info[c_ptr->mimic] + : &f_info[f_info[c_ptr->feat].mimic]; - /* Apply terrain feature mimics */ - if (c_ptr->mimic) - { - f_ptr = &f_info[c_ptr->mimic]; - } - else + /* Skip normal features */ + if (!(f_ptr->flags & FF_ATTR_MULTI)) { - f_ptr = &f_info[f_info[c_ptr->feat].mimic]; + continue; } - /* Skip normal features */ - if (!(f_ptr->flags1 & (FF1_ATTR_MULTI))) continue; - /* Redraw a shimmering spot */ lite_spot(j, i); } @@ -4652,7 +4571,7 @@ static void process_player(void) * * Forget everything when requested hehe I'm *NASTY* */ - if (dun_level && (dungeon_flags1 & DF1_FORGET)) + if (dun_level && (dungeon_flags & DF_FORGET)) { wiz_dark(); } @@ -4675,8 +4594,10 @@ static void process_player(void) * This function will not exit until the level is completed, * the user dies, or the game is terminated. */ -static void dungeon(void) +static void dungeon() { + auto const &d_info = game->edit_data.d_info; + /* Reset various flags */ hack_mind = FALSE; @@ -4707,7 +4628,7 @@ static void dungeon(void) /* Disturb */ - disturb(1); + disturb(); /* Track maximum player level */ if (p_ptr->max_plv < p_ptr->lev) @@ -4733,12 +4654,12 @@ static void dungeon(void) if (!dun_level) create_down_shaft = create_up_shaft = FALSE; /* Option -- no connected stairs */ - if (!dungeon_stair) create_down_stair = create_up_stair = FALSE; - if (!dungeon_stair) create_down_shaft = create_up_shaft = FALSE; + if (!options->dungeon_stair) create_down_stair = create_up_stair = FALSE; + if (!options->dungeon_stair) create_down_shaft = create_up_shaft = FALSE; /* no connecting stairs on special levels */ - if (!(dungeon_flags2 & DF2_NO_STAIR)) create_down_stair = create_up_stair = FALSE; - if (!(dungeon_flags2 & DF2_NO_STAIR)) create_down_shaft = create_up_shaft = FALSE; + if (!(dungeon_flags & DF_NO_STAIR)) create_down_stair = create_up_stair = FALSE; + if (!(dungeon_flags & DF_NO_STAIR)) create_down_shaft = create_up_shaft = FALSE; /* Make a stairway. */ if ((create_up_stair || create_down_stair || @@ -4754,19 +4675,19 @@ static void dungeon(void) /* Make stairs */ if (create_down_stair) { - cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE); + cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags & DF_FLAT) ? FEAT_WAY_MORE : FEAT_MORE); } else if (create_down_shaft) { - cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN); + cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags & DF_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN); } else if (create_up_shaft) { - cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP); + cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags & DF_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP); } else { - cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS); + cave_set_feat(p_ptr->py, p_ptr->px, (dungeon_flags & DF_FLAT) ? FEAT_WAY_LESS : FEAT_LESS); } } @@ -4941,7 +4862,7 @@ static void dungeon(void) move_cursor_relative(p_ptr->py, p_ptr->px); /* Optional fresh */ - if (fresh_after) Term_fresh(); + if (options->fresh_after) Term_fresh(); /* Hack -- Notice death or departure */ if (!alive || death) break; @@ -4969,7 +4890,7 @@ static void dungeon(void) move_cursor_relative(p_ptr->py, p_ptr->px); /* Optional fresh */ - if (fresh_after) Term_fresh(); + if (options->fresh_after) Term_fresh(); /* Hack -- Notice death or departure */ if (!alive || death) break; @@ -4982,7 +4903,7 @@ static void dungeon(void) process_hooks_new(HOOK_END_TURN, NULL, NULL); /* Make it pulsate and live !!!! */ - if ((dungeon_flags1 & DF1_EVOLVE) && dun_level) + if ((dungeon_flags & DF_EVOLVE) && dun_level) { if (!(turn % 10)) evolve_level(TRUE); } @@ -5003,7 +4924,7 @@ static void dungeon(void) move_cursor_relative(p_ptr->py, p_ptr->px); /* Optional fresh */ - if (fresh_after) Term_fresh(); + if (options->fresh_after) Term_fresh(); /* Hack -- Notice death or departure */ if (!alive || death) break; @@ -5051,13 +4972,14 @@ static void dungeon(void) /* * Load some "user pref files" */ -static void load_all_pref_files(void) +static void load_all_pref_files() { char buf[1024]; + std::string const &player_name = game->player_name; /* Access the "race" pref file */ - sprintf(buf, "%s.prf", rp_ptr->title); + sprintf(buf, "%s.prf", rp_ptr->title.c_str()); /* Process that file */ process_pref_file(buf); @@ -5069,7 +4991,7 @@ static void load_all_pref_files(void) process_pref_file(buf); /* Access the "character" pref file */ - sprintf(buf, "%s.prf", player_name); + sprintf(buf, "%s.prf", player_name.c_str()); /* Process that file */ process_pref_file(buf); @@ -5080,7 +5002,7 @@ static void load_all_pref_files(void) * the providence of rules and such to avoid the same * duplication problems as caused when saving macros/keymaps. */ boost::filesystem::path userDirectory(ANGBAND_DIR_USER); - if (automatizer_load(userDirectory / (std::string(player_name) + ".atm"))) + if (automatizer_load(userDirectory / (player_name + ".atm"))) { // Done } @@ -5092,13 +5014,11 @@ static void load_all_pref_files(void) /* * Actually play a game - * - * If the "new_game" parameter is true, then, after loading the - * savefile, we will commit suicide, if necessary, to allow the - * player to start a new game. */ -void play_game(bool_ new_game) +void play_game() { + auto const &d_info = game->edit_data.d_info; + int i, tmp_dun; bool_ cheat_death = FALSE; @@ -5126,10 +5046,11 @@ void play_game(bool_ new_game) /* Hack -- turn off the cursor */ - (void)Term_set_cursor(0); + Term_set_cursor(0); /* Character list */ - if (!new_game && !no_begin_screen) new_game = begin_screen(); + bool_ new_game = FALSE; + if (!no_begin_screen) new_game = begin_screen(); no_begin_screen = FALSE; /* Attempt to load */ @@ -5148,20 +5069,6 @@ void play_game(bool_ new_game) /* The dungeon is not ready */ character_dungeon = FALSE; } - else - { - int i; - - /* Init new skills to their defaults */ - for (i = old_max_s_idx; i < max_s_idx; i++) - { - s32b value = 0, mod = 0; - - compute_skills(&value, &mod, i); - - init_skill(value, mod, i); - } - } /* Process old character */ if (!new_game) @@ -5170,52 +5077,8 @@ void play_game(bool_ new_game) process_player_name(FALSE); } - /* Init the RNG */ - if (Rand_quick) - { - u32b seed; - - /* Basic seed */ - seed = (time(NULL)); - -#ifdef SET_UID - - /* Mutate the seed on Unix machines */ - seed = ((seed >> 3) * (getpid() << 1)); - -#endif - - /* Use the complex RNG */ - Rand_quick = FALSE; - - /* Seed the "complex" RNG */ - Rand_state_init(seed); - } - - /* Extract the options */ - for (i = 0; option_info[i].o_desc; i++) - { - int os = option_info[i].o_page; - int ob = option_info[i].o_bit; - - /* Set the "default" options */ - if (option_info[i].o_var) - { - /* Set */ - if (option_flag[os] & (1L << ob)) - { - /* Set */ - (*option_info[i].o_var) = TRUE; - } - - /* Clear */ - else - { - /* Clear */ - (*option_info[i].o_var) = FALSE; - } - } - } + /* Force "complex" RNG */ + set_complex_rng(); /* Roll new character */ if (new_game) @@ -5226,8 +5089,8 @@ void play_game(bool_ new_game) /* The dungeon is not ready */ character_dungeon = FALSE; - /* Hack -- seed for flavors */ - seed_flavor = rand_int(0x10000000); + /* Set the seed for flavors */ + seed_flavor() = seed_t::system(); /* Roll up a new character */ player_birth(); @@ -5239,7 +5102,7 @@ void play_game(bool_ new_game) /* Hack -- enter the world */ /* Mega-hack Vampires and Spectres start at midnight */ - if (race_flags1_p(PR1_UNDEAD)) + if (race_flags_p(PR_UNDEAD)) { turn = (10L * DAY / 2) + 1; } @@ -5283,8 +5146,8 @@ void play_game(bool_ new_game) load_all_pref_files(); /* Set or clear "rogue_like_commands" if requested */ - if (arg_force_original) rogue_like_commands = FALSE; - if (arg_force_roguelike) rogue_like_commands = TRUE; + if (arg_force_original) options->rogue_like_commands = FALSE; + if (arg_force_roguelike) options->rogue_like_commands = TRUE; /* Initialize vault info */ if (init_v_info()) quit("Cannot initialize vaults"); @@ -5460,16 +5323,10 @@ void play_game(bool_ new_game) } /* Cheat death option */ - else if ((wizard || cheat_live) && !get_check("Die? ")) + else if ((wizard || options->cheat_live) && !get_check("Die? ")) { cheat_death = TRUE; - /* Mark social class, reset age, if needed */ - if (p_ptr->sc) p_ptr->sc = p_ptr->age = 0; - - /* Increase age */ - p_ptr->age++; - /* Mark savefile */ noscore |= 0x0001; msg_print("You invoke wizard mode and cheat death."); @@ -5497,14 +5354,14 @@ void play_game(bool_ new_game) p_ptr->csp_frac = 0; /* Hack -- Healing */ - (void)set_blind(0); - (void)set_confused(0); - (void)set_poisoned(0); - (void)set_afraid(0); - (void)set_paralyzed(0); - (void)set_image(0); - (void)set_stun(0); - (void)set_cut(0); + set_blind(0); + set_confused(0); + set_poisoned(0); + set_afraid(0); + set_paralyzed(0); + set_image(0); + set_stun(0); + set_cut(0); /* accounting for a new ailment. -LM- */ p_ptr->black_breath = FALSE; @@ -5513,7 +5370,7 @@ void play_game(bool_ new_game) p_ptr->necro_extra &= ~CLASS_UNDEAD; /* Hack -- Prevent starvation */ - (void)set_food(PY_FOOD_MAX - 1); + set_food(PY_FOOD_MAX - 1); /* Hack -- cancel recall */ if (p_ptr->word_recall) @@ -5526,8 +5383,8 @@ void play_game(bool_ new_game) p_ptr->word_recall = 0; } - /* Note cause of death XXX XXX XXX */ - (void)strcpy(died_from, "Cheating death"); + /* Note cause of death */ + game->died_from = "Cheating death"; /* Do not die */ death = FALSE; diff --git a/src/dungeon.h b/src/dungeon.h index 1ce166d1..b5a81a59 100644 --- a/src/dungeon.h +++ b/src/dungeon.h @@ -1,13 +1,11 @@ #pragma once -#include "h-basic.h" - // C linkage required for these functions since main-* code uses them. #ifdef __cplusplus extern "C" { #endif -extern void play_game(bool_ new_game); +void play_game(); #ifdef __cplusplus } // extern "C" diff --git a/src/dungeon.hpp b/src/dungeon.hpp index bbe6da87..e14f4a12 100644 --- a/src/dungeon.hpp +++ b/src/dungeon.hpp @@ -2,5 +2,5 @@ #include <vector> -extern void sense_inventory(); -extern void sense_objects(std::vector<int> const &object_idxs); +void sense_inventory(); +void sense_objects(std::vector<int> const &object_idxs); diff --git a/src/dungeon_flag.hpp b/src/dungeon_flag.hpp new file mode 100644 index 00000000..bf8d77d8 --- /dev/null +++ b/src/dungeon_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "dungeon_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define DF(tier, index, name) \ + DECLARE_FLAG(dungeon_flag_set, BOOST_PP_CAT(DF_,name), tier, index) +#include "dungeon_flag_list.hpp" +#undef DF diff --git a/src/dungeon_flag_list.hpp b/src/dungeon_flag_list.hpp new file mode 100644 index 00000000..8fdefc95 --- /dev/null +++ b/src/dungeon_flag_list.hpp @@ -0,0 +1,55 @@ +/** + * X-macro list of all the dungeon flags + */ + +/* DF(<tier>, <index>, <name>) */ +DF(1, 0, PRINCIPAL) +DF(1, 1, MAZE) +DF(1, 2, SMALLEST) +DF(1, 3, SMALL) +DF(1, 4, BIG) +DF(1, 5, NO_DOORS) +DF(1, 6, WATER_RIVER) +DF(1, 7, LAVA_RIVER) +DF(1, 8, WATER_RIVERS) +DF(1, 9, LAVA_RIVERS) +DF(1, 10, CAVE) +DF(1, 11, CAVERN) +DF(1, 12, NO_UP) +DF(1, 13, HOT) +DF(1, 14, COLD) +DF(1, 15, FORCE_DOWN) +DF(1, 16, FORGET) +DF(1, 17, NO_DESTROY) +DF(1, 18, SAND_VEIN) +DF(1, 19, CIRCULAR_ROOMS) +DF(1, 20, EMPTY) +DF(1, 21, DAMAGE_FEAT) +DF(1, 22, FLAT) +DF(1, 23, TOWER) +DF(1, 24, RANDOM_TOWNS) +DF(1, 25, DOUBLE) +DF(1, 26, LIFE_LEVEL) +DF(1, 27, EVOLVE) +DF(1, 28, ADJUST_LEVEL_1) +DF(1, 29, ADJUST_LEVEL_2) +DF(1, 30, NO_RECALL) +DF(1, 31, NO_STREAMERS) + +DF(2, 0, ADJUST_LEVEL_1_2) +DF(2, 1, NO_SHAFT) +DF(2, 2, ADJUST_LEVEL_PLAYER) +DF(2, 3, NO_TELEPORT) +DF(2, 4, ASK_LEAVE) +DF(2, 5, NO_STAIR) +DF(2, 6, SPECIAL) +DF(2, 7, NO_NEW_MONSTER) +DF(2, 8, DESC) +DF(2, 9, NO_GENO) +DF(2, 10, NO_BREATH) +DF(2, 11, WATER_BREATH) +DF(2, 12, ELVEN) +DF(2, 13, DWARVEN) +DF(2, 14, NO_EASY_MOVE) +DF(2, 15, NO_RECALL_OUT) +DF(2, 16, DESC_ALWAYS) diff --git a/src/dungeon_flag_set.hpp b/src/dungeon_flag_set.hpp new file mode 100644 index 00000000..539a574a --- /dev/null +++ b/src/dungeon_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t DF_MAX_TIERS = 2; + +typedef flag_set<DF_MAX_TIERS> dungeon_flag_set; diff --git a/src/dungeon_info_type.hpp b/src/dungeon_info_type.hpp index 5f6fc9d0..2f8fefde 100644 --- a/src/dungeon_info_type.hpp +++ b/src/dungeon_info_type.hpp @@ -3,6 +3,10 @@ #include "h-basic.h" #include "rule_type.hpp" #include "obj_theme.hpp" +#include "dungeon_flag_set.hpp" + +#include <array> +#include <string> /** * Maximum number of towns per dungeon @@ -12,61 +16,63 @@ constexpr int TOWN_DUNGEON = 4; /* A structure for the != dungeon types */ struct dungeon_info_type { - const char *name; /* Name */ - char *text; /* Description */ - char short_name[3]; /* Short name */ - - char generator[30]; /* Name of the level generator */ - - s16b floor1; /* Floor tile 1 */ - byte floor_percent1[2]; /* Chance of type 1 */ - s16b floor2; /* Floor tile 2 */ - byte floor_percent2[2]; /* Chance of type 2 */ - s16b floor3; /* Floor tile 3 */ - byte floor_percent3[2]; /* Chance of type 3 */ - s16b outer_wall; /* Outer wall tile */ - s16b inner_wall; /* Inner wall tile */ - s16b fill_type1; /* Cave tile 1 */ - byte fill_percent1[2]; /* Chance of type 1 */ - s16b fill_type2; /* Cave tile 2 */ - byte fill_percent2[2]; /* Chance of type 2 */ - s16b fill_type3; /* Cave tile 3 */ - byte fill_percent3[2]; /* Chance of type 3 */ - byte fill_method; /* Smoothing parameter for the above */ - - s16b mindepth; /* Minimal depth */ - s16b maxdepth; /* Maximal depth */ - - bool_ principal; /* If it's a part of the main dungeon */ - byte next; /* The next part of the main dungeon */ - byte min_plev; /* Minimal plev needed to enter -- it's an anti-cheating mesure */ - - int min_m_alloc_level; /* Minimal number of monsters per level */ - int max_m_alloc_chance; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */ - - u32b flags1; /* Flags 1 */ - u32b flags2; /* Flags 1 */ - - int size_x, size_y; /* Desired numers of panels */ - - byte rule_percents[100]; /* Flat rule percents */ - rule_type rules[5]; /* Monster generation rules */ - - int final_object; /* The object you'll find at the bottom */ - int final_artifact; /* The artifact you'll find at the bottom */ - int final_guardian; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */ - - int ix, iy, ox, oy; /* Wilderness coordinates of the entrance/output of the dungeon */ - - obj_theme objs; /* The drops type */ - - int d_dice[4]; /* Number of dices */ - int d_side[4]; /* Number of sides */ - int d_frequency[4]; /* Frequency of damage (1 is the minimum) */ - int d_type[4]; /* Type of damage */ - - s16b t_idx[TOWN_DUNGEON]; /* The towns */ - s16b t_level[TOWN_DUNGEON]; /* The towns levels */ - s16b t_num; /* Number of towns */ + std::string name; /* Name */ + std::string text; /* Description */ + std::string short_name; /* Short name */ + + std::string generator; /* Name of the level generator */ + + s16b floor1 = 0; /* Floor tile 1 */ + byte floor_percent1[2] = { 0 }; /* Chance of type 1 */ + s16b floor2 = 0; /* Floor tile 2 */ + byte floor_percent2[2] = { 0 }; /* Chance of type 2 */ + s16b floor3 = 0; /* Floor tile 3 */ + byte floor_percent3[2] = { 0 }; /* Chance of type 3 */ + s16b outer_wall = 0; /* Outer wall tile */ + s16b inner_wall = 0; /* Inner wall tile */ + s16b fill_type1 = 0; /* Cave tile 1 */ + byte fill_percent1[2] = { 0 }; /* Chance of type 1 */ + s16b fill_type2 = 0; /* Cave tile 2 */ + byte fill_percent2[2] = { 0 }; /* Chance of type 2 */ + s16b fill_type3 = 0; /* Cave tile 3 */ + byte fill_percent3[2] = { 0 }; /* Chance of type 3 */ + byte fill_method = 0; /* Smoothing parameter for the above */ + + s16b mindepth = 0; /* Minimal depth */ + s16b maxdepth = 0; /* Maximal depth */ + + bool_ principal = 0; /* If it's a part of the main dungeon */ + byte min_plev = 0; /* Minimal plev needed to enter -- it's an anti-cheating mesure */ + + int min_m_alloc_level = 0; /* Minimal number of monsters per level */ + int max_m_alloc_chance = 0; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */ + + dungeon_flag_set flags { }; /* Dungeon flags */ + + int size_x = 0; + int size_y = 0; + + byte rule_percents[100] = {0}; /* Flat rule percents */ + std::array<rule_type, 5> rules { }; /* Monster generation rules */ + + int final_object = 0; /* The object you'll find at the bottom */ + int final_artifact = 0; /* The artifact you'll find at the bottom */ + int final_guardian = 0; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */ + + int ix = 0; /* Wilderness coordinates of entrance */ + int iy = 0; /* Wilderness coordinates of entrance */ + int ox = 0; /* Wilderness coordinates of exit */ + int oy = 0; /* Wilderness coordinates of exit */ + + obj_theme objs; /* The drops type */ + + int d_dice[4] = { 0 }; /* Number of dices */ + int d_side[4] = { 0 }; /* Number of sides */ + int d_frequency[4] = { 0 }; /* Frequency of damage (1 is the minimum) */ + int d_type[4] = { 0 }; /* Type of damage */ + + s16b t_idx[TOWN_DUNGEON] = { 0 }; /* The towns */ + s16b t_level[TOWN_DUNGEON] = { 0 }; /* The towns levels */ + s16b t_num = 0; /* Number of towns */ }; diff --git a/src/ego_flag.hpp b/src/ego_flag.hpp new file mode 100644 index 00000000..8afb6b19 --- /dev/null +++ b/src/ego_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "ego_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define ETR(tier, index, name) \ + DECLARE_FLAG(ego_flag_set, BOOST_PP_CAT(ETR_,name), tier, index) +#include "ego_flag_list.hpp" +#undef ETR diff --git a/src/ego_flag_list.hpp b/src/ego_flag_list.hpp new file mode 100644 index 00000000..b05fb9b1 --- /dev/null +++ b/src/ego_flag_list.hpp @@ -0,0 +1,38 @@ +/** + * X-macro list of all the ego flags + */ + +/* ETR(<tier>, <index>, <name>) */ + +ETR(1, 0, SUSTAIN ) /* Ego-Item gives a Random Sustain */ +ETR(1, 1, OLD_RESIST ) /* The old "extra power" random high resist */ +ETR(1, 2, ABILITY ) /* Ego-Item has a random Sustain */ +ETR(1, 3, R_ELEM ) /* Item resists Acid/Fire/Cold/Elec or Poison */ +ETR(1, 4, R_LOW ) /* Item has a random low resist */ +ETR(1, 5, R_HIGH ) /* Item has a random high resist */ +ETR(1, 6, R_ANY ) /* Item has one additional resist */ +ETR(1, 7, R_DRAGON ) /* Item gets "Dragon" Resist */ +ETR(1, 8, SLAY_WEAP ) /* Special 'Slaying' bonus */ +ETR(1, 9, DAM_DIE ) /* Item has an additional dam die */ +ETR(1, 10, DAM_SIZE ) /* Item has greater damage dice */ +ETR(1, 11, PVAL_M1 ) /* Item has +1 to pval */ +ETR(1, 12, PVAL_M2 ) /* Item has +(up to 2) to pval */ +ETR(1, 13, PVAL_M3 ) /* Item has +(up to 3) to pval */ +ETR(1, 14, PVAL_M5 ) /* Item has +(up to 5) to pval */ +ETR(1, 15, AC_M1 ) /* Item has +1 to AC */ +ETR(1, 16, AC_M2 ) /* Item has +(up to 2) to AC */ +ETR(1, 17, AC_M3 ) /* Item has +(up to 3) to AC */ +ETR(1, 18, AC_M5 ) /* Item has +(up to 5) to AC */ +ETR(1, 19, TH_M1 ) /* Item has +1 to hit */ +ETR(1, 20, TH_M2 ) /* Item has +(up to 2) to hit */ +ETR(1, 21, TH_M3 ) /* Item has +(up to 3) to hit */ +ETR(1, 22, TH_M5 ) /* Item has +(up to 5) to hit */ +ETR(1, 23, TD_M1 ) /* Item has +1 to dam */ +ETR(1, 24, TD_M2 ) /* Item has +(up to 2) to dam */ +ETR(1, 25, TD_M3 ) /* Item has +(up to 3) to dam */ +ETR(1, 26, TD_M5 ) /* Item has +(up to 5) to dam */ +ETR(1, 27, R_P_ABILITY) /* Item has a random pval-affected ability */ +ETR(1, 28, R_STAT ) /* Item affects a random stat */ +ETR(1, 29, R_STAT_SUST) /* Item affects a random stat & sustains it */ +ETR(1, 30, R_IMMUNITY ) /* Item gives a random immunity */ +ETR(1, 31, LIMIT_BLOWS) /* switch the "limit blows" feature */ diff --git a/src/ego_flag_set.hpp b/src/ego_flag_set.hpp new file mode 100644 index 00000000..0e77d5e0 --- /dev/null +++ b/src/ego_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t ETR_MAX_TIERS = 1; + +typedef flag_set<ETR_MAX_TIERS> ego_flag_set; diff --git a/src/ego_item_type.hpp b/src/ego_item_type.hpp index f9b6970a..2082c083 100644 --- a/src/ego_item_type.hpp +++ b/src/ego_item_type.hpp @@ -1,6 +1,10 @@ #pragma once +#include "ego_flag_set.hpp" #include "h-basic.h" +#include "object_flag_set.hpp" + +#include <array> /* * Size of flag rarity tables @@ -12,57 +16,47 @@ constexpr int FLAG_RARITY_MAX = 6; */ struct ego_item_type { - const char *name; /* Name (offset) */ - - bool_ before; /* Before or after the object name ? */ - - byte tval[10]; - byte min_sval[10]; - byte max_sval[10]; - - byte rating; /* Rating boost */ - - byte level; /* Minimum level */ - byte rarity; /* Object rarity */ - byte mrarity; /* Object rarity */ - - s16b max_to_h; /* Maximum to-hit bonus */ - s16b max_to_d; /* Maximum to-dam bonus */ - s16b max_to_a; /* Maximum to-ac bonus */ - - s16b activate; /* Activation Number */ - - s32b max_pval; /* Maximum pval */ - - s32b cost; /* Ego-item "cost" */ - - byte rar[FLAG_RARITY_MAX]; - u32b flags1[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 1 */ - u32b flags2[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 2 */ - u32b flags3[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 3 */ - u32b flags4[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 4 */ - u32b flags5[FLAG_RARITY_MAX]; /* Ego-Item Flags, set 5 */ - u32b esp[FLAG_RARITY_MAX]; /* ESP flags */ - u32b oflags1[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 1 */ - u32b oflags2[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 2 */ - u32b oflags3[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 3 */ - u32b oflags4[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 4 */ - u32b oflags5[FLAG_RARITY_MAX]; /* Ego-Item Obvious Flags, set 5 */ - u32b oesp[FLAG_RARITY_MAX]; /* Obvious ESP flags */ - u32b fego[FLAG_RARITY_MAX]; /* ego flags */ - - u32b need_flags1; /* Ego-Item Flags, set 1 */ - u32b need_flags2; /* Ego-Item Flags, set 2 */ - u32b need_flags3; /* Ego-Item Flags, set 3 */ - u32b need_flags4; /* Ego-Item Flags, set 4 */ - u32b need_flags5; /* Ego-Item Flags, set 5 */ - u32b need_esp; /* ESP flags */ - u32b forbid_flags1; /* Ego-Item Flags, set 1 */ - u32b forbid_flags2; /* Ego-Item Flags, set 2 */ - u32b forbid_flags3; /* Ego-Item Flags, set 3 */ - u32b forbid_flags4; /* Ego-Item Flags, set 4 */ - u32b forbid_flags5; /* Ego-Item Flags, set 5 */ - u32b forbid_esp; /* ESP flags */ - - s16b power; /* Power granted(if any) */ + const char *name = nullptr; /* Name */ + + bool_ before = FALSE; /* Before or after the object name ? */ + + byte tval[10] = { 0 }; + byte min_sval[10] = { 0 }; + byte max_sval[10] = { 0 }; + + byte rating = 0; /* Rating boost */ + + byte level = 0; /* Minimum level */ + byte rarity = 0; /* Object rarity */ + byte mrarity = 0; /* Object rarity */ + + s16b max_to_h = 0; /* Maximum to-hit bonus */ + s16b max_to_d = 0; /* Maximum to-dam bonus */ + s16b max_to_a = 0; /* Maximum to-ac bonus */ + + s16b activate = 0; /* Activation Number */ + + s32b max_pval = 0; /* Maximum pval */ + + s32b cost = 0; /* Ego-item "cost" */ + + byte rar[FLAG_RARITY_MAX] = { 0 }; + + std::array<object_flag_set, FLAG_RARITY_MAX> flags; + std::array<object_flag_set, FLAG_RARITY_MAX> oflags; + + std::array<ego_flag_set, FLAG_RARITY_MAX> fego; + + object_flag_set need_flags; + object_flag_set forbid_flags; + + s16b power = -1; /* Power granted, if any */ + +public: + ego_item_type() + { + std::fill(std::begin(tval), + std::end(tval), + 255); + } }; diff --git a/src/ego_item_type_fwd.hpp b/src/ego_item_type_fwd.hpp deleted file mode 100644 index 795f4403..00000000 --- a/src/ego_item_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct ego_item_type; diff --git a/src/feature_flag.hpp b/src/feature_flag.hpp new file mode 100644 index 00000000..09aa5b43 --- /dev/null +++ b/src/feature_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "feature_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define FF(tier, index, name) \ + DECLARE_FLAG(feature_flag_set, BOOST_PP_CAT(FF_,name), tier, index) +#include "feature_flag_list.hpp" +#undef FF diff --git a/src/feature_flag_list.hpp b/src/feature_flag_list.hpp new file mode 100644 index 00000000..0a433c3a --- /dev/null +++ b/src/feature_flag_list.hpp @@ -0,0 +1,25 @@ +/** + * X-macro list of all the feature flags + */ + +/* FF(<tier>, <index>, <name>) */ + +FF(1, 0, NO_WALK) +FF(1, 1, NO_VISION) +FF(1, 2, CAN_LEVITATE) +FF(1, 3, CAN_PASS) +FF(1, 4, FLOOR) +FF(1, 5, WALL) +FF(1, 6, PERMANENT) +FF(1, 7, CAN_FLY) +FF(1, 8, REMEMBER) +FF(1, 9, NOTICE) +FF(1, 10, DONT_NOTICE_RUNNING) +FF(1, 11, CAN_RUN) +FF(1, 12, DOOR) +FF(1, 13, SUPPORT_LIGHT) +FF(1, 14, CAN_CLIMB) +FF(1, 15, TUNNELABLE) +FF(1, 16, WEB) +FF(1, 17, ATTR_MULTI) +FF(1, 18, SUPPORT_GROWTH) diff --git a/src/feature_flag_set.hpp b/src/feature_flag_set.hpp new file mode 100644 index 00000000..abc4f47d --- /dev/null +++ b/src/feature_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t FF_MAX_TIERS = 1; + +typedef flag_set<FF_MAX_TIERS> feature_flag_set; diff --git a/src/feature_type.hpp b/src/feature_type.hpp index 1a79aeb3..e818f17a 100644 --- a/src/feature_type.hpp +++ b/src/feature_type.hpp @@ -2,36 +2,33 @@ #include "h-basic.h" +#include "feature_flag_set.hpp" + /** * Terrain feature descriptor. */ struct feature_type { - char *name; /* Name */ - - const char *text; /* Text. May point to shared read-only memory, DO NOT FREE! */ - const char *tunnel; /* Text for tunneling. May point to shared read-only memory, DO NOT FREE! */ - const char *block; /* Text for blocking. May point to shared read-only memory, DO NOT FREE! */ - - byte mimic; /* Feature to mimic */ - - u32b flags1; /* First set of flags */ + char *name = nullptr; /* Name */ - byte extra; /* Extra byte (unused) */ + const char *text = nullptr; /* Text. May point to shared read-only memory, DO NOT FREE! */ + const char *tunnel = nullptr; /* Text for tunneling. May point to shared read-only memory, DO NOT FREE! */ + const char *block = nullptr; /* Text for blocking. May point to shared read-only memory, DO NOT FREE! */ - s16b unused; /* Extra bytes (unused) */ + byte mimic = 0; /* Feature to mimic */ - byte d_attr; /* Default feature attribute */ - char d_char; /* Default feature character */ + feature_flag_set flags; /* First set of flags */ + byte d_attr = 0; /* Default feature attribute */ + char d_char = '\0'; /* Default feature character */ - byte x_attr; /* Desired feature attribute */ - char x_char; /* Desired feature character */ + byte x_attr = 0; /* Desired feature attribute */ + char x_char = '\0'; /* Desired feature character */ - byte shimmer[7]; /* Shimmer colors */ + byte shimmer[7]; /* Shimmer colors */ - int d_dice[4]; /* Number of dices */ - int d_side[4]; /* Number of sides */ - int d_frequency[4]; /* Frequency of damage (1 is the minimum) */ - int d_type[4]; /* Type of damage */ + int d_dice[4] = { 0 }; /* Number of dice */ + int d_side[4] = { 0 }; /* Number of sides */ + int d_frequency[4] = { 0 }; /* Frequency of damage (1 is the minimum) */ + int d_type[4] = { 0 }; /* Type of damage */ }; diff --git a/src/feature_type_fwd.hpp b/src/feature_type_fwd.hpp deleted file mode 100644 index 168ec6c7..00000000 --- a/src/feature_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct feature_type; diff --git a/src/files.cc b/src/files.cc index cc168ba5..6b3de0f0 100644 --- a/src/files.cc +++ b/src/files.cc @@ -15,6 +15,7 @@ #include "cmd3.hpp" #include "dungeon_info_type.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hiscore.hpp" #include "hook_chardump_in.hpp" #include "hooks.hpp" @@ -23,18 +24,23 @@ #include "loadsave.h" #include "loadsave.hpp" #include "mimic.hpp" +#include "monoid.hpp" #include "monster2.hpp" #include "monster3.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "notes.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" +#include "object_flag_meta.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_spec.hpp" #include "player_type.hpp" @@ -44,7 +50,6 @@ #include "store_type.hpp" #include "tables.hpp" #include "town_type.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -54,6 +59,12 @@ #include "xtra1.hpp" #include "z-rand.hpp" +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <iostream> +#include <fmt/format.h> +#include <fstream> +#include <limits> #include <memory> #include <unordered_set> @@ -204,6 +215,13 @@ s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2) */ errr process_pref_file_aux(char *buf) { + auto &race_mod_info = game->edit_data.race_mod_info; + auto &st_info = game->edit_data.st_info; + auto &re_info = game->edit_data.re_info; + auto &r_info = game->edit_data.r_info; + auto &f_info = game->edit_data.f_info; + auto &k_info = game->edit_data.k_info; + int i, j, n1, n2; char *zz[16]; @@ -235,17 +253,26 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 2, 3, zz, ':', '/') == 3) { - monster_race *r_ptr; - i = (huge)strtol(zz[0], NULL, 0); + std::size_t i = strtoul(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_r_idx) return (1); - r_ptr = &r_info[i]; - if (n1) r_ptr->x_attr = n1; + + if (i >= r_info.size()) + { + return (1); + } + + auto r_ptr = &r_info[i]; + + if (n1) + { + r_ptr->x_attr = n1; + } if (n2) { r_ptr->x_char = n2; } + return (0); } } @@ -259,18 +286,27 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 4, 3, zz, ':', '/') == 3) { - monster_ego *re_ptr; - i = (huge)strtol(zz[0], NULL, 0); + std::size_t i = strtoul(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_re_idx) return (1); - re_ptr = &re_info[i]; - if (n1) re_ptr->g_attr = n1; + + if (i >= re_info.size()) + { + return 1; + } + + auto re_ptr = &re_info[i]; + + if (n1) + { + re_ptr->g_attr = n1; + } if (n2) { re_ptr->g_char = n2; } - return (0); + + return 0; } } @@ -283,7 +319,7 @@ errr process_pref_file_aux(char *buf) i = (huge)strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_rmp_idx) return (1); + if (i >= static_cast<int>(race_mod_info.size())) return (1); rmp_ptr = &race_mod_info[i]; if (n1) rmp_ptr->g_attr = n1; if (n2) @@ -293,26 +329,6 @@ errr process_pref_file_aux(char *buf) return (0); } } - - /* Process "G:T:<num>:<a>/<c>" -- attr/char for traps */ - if (buf[2] == 'T') - { - if (tokenize(buf + 4, 3, zz, ':', '/') == 3) - { - trap_type *t_ptr; - i = (huge)strtol(zz[0], NULL, 0); - n1 = strtol(zz[1], NULL, 0); - n2 = strtol(zz[2], NULL, 0); - if (i >= max_t_idx) return (1); - t_ptr = &t_info[i]; - if (n1) t_ptr->g_attr = n1; - if (n2) - { - t_ptr->g_char = n2; - } - return (0); - } - } } @@ -321,13 +337,21 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 2, 3, zz, ':', '/') == 3) { - object_kind *k_ptr; - i = (huge)strtol(zz[0], NULL, 0); + std::size_t i = strtoul(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_k_idx) return (1); - k_ptr = &k_info[i]; - if (n1) k_ptr->x_attr = n1; + + if (i >= k_info.size()) + { + return (1); + } + + auto k_ptr = &k_info[i]; + + if (n1) + { + k_ptr->x_attr = n1; + } if (n2) { k_ptr->x_char = n2; @@ -342,13 +366,18 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 2, 3, zz, ':', '/') == 3) { - feature_type *f_ptr; - i = (huge)strtol(zz[0], NULL, 0); + std::size_t f_idx = strtoul(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_f_idx) return (1); - f_ptr = &f_info[i]; - if (n1) f_ptr->x_attr = n1; + + if (f_idx >= f_info.size()) return (1); + + auto f_ptr = &f_info[f_idx]; + + if (n1) + { + f_ptr->x_attr = n1; + } if (n2) { f_ptr->x_char = n2; @@ -362,12 +391,13 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 2, 3, zz, ':', '/') == 3) { - store_info_type *st_ptr; - i = (huge)strtol(zz[0], NULL, 0); + std::size_t i = std::stoul(zz[0], 0, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - if (i >= max_st_idx) return (1); - st_ptr = &st_info[i]; + + if (i >= st_info.size()) return (1); + + auto st_ptr = &st_info[i]; if (n1) st_ptr->x_attr = n1; if (n2) st_ptr->x_char = n2; return (0); @@ -393,16 +423,23 @@ errr process_pref_file_aux(char *buf) { if (tokenize(buf + 2, 3, zz, ':', '/') == 3) { - j = (huge)strtol(zz[0], NULL, 0); + j = strtoul(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); - for (i = 1; i < max_k_idx; i++) + + for (auto &k_ref: k_info) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_ref; if (k_ptr->tval == j) { - if (n1) k_ptr->d_attr = n1; - if (n2) k_ptr->d_char = n2; + if (n1) + { + k_ref.d_attr = n1; + } + if (n2) + { + k_ref.d_char = n2; + } } } return (0); @@ -585,14 +622,12 @@ errr process_pref_file_aux(char *buf) /* Process "X:<str>" -- turn option off */ else if (buf[0] == 'X') { - for (i = 0; option_info[i].o_desc; i++) + for (auto const &option: options->standard_options) { - if (option_info[i].o_var && - option_info[i].o_text && - streq(option_info[i].o_text, buf + 2)) + if (option.o_var && streq(option.o_text, buf + 2)) { - (*option_info[i].o_var) = FALSE; - return (0); + *option.o_var = FALSE; + return 0; } } } @@ -600,14 +635,12 @@ errr process_pref_file_aux(char *buf) /* Process "Y:<str>" -- turn option on */ else if (buf[0] == 'Y') { - for (i = 0; option_info[i].o_desc; i++) + for (auto const &option: options->standard_options) { - if (option_info[i].o_var && - option_info[i].o_text && - streq(option_info[i].o_text, buf + 2)) + if (option.o_var && streq(option.o_text, buf + 2)) { - (*option_info[i].o_var) = TRUE; - return (0); + *option.o_var = TRUE; + return 0; } } } @@ -885,13 +918,13 @@ static cptr process_pref_file_expr(char **sp, char *fp) /* Race */ else if (streq(b + 1, "RACE")) { - v = rp_ptr->title; + v = rp_ptr->title.c_str(); // The string SHOULD be stable enough for this } /* Race */ else if (streq(b + 1, "RACEMOD")) { - v = rmp_ptr->title; + v = rmp_ptr->title.c_str(); // The string SHOULD be stable enough for this } /* Class */ @@ -903,7 +936,7 @@ static cptr process_pref_file_expr(char **sp, char *fp) /* Player */ else if (streq(b + 1, "PLAYER")) { - v = player_base; + v = game->player_base.c_str(); // The string SHOULD be stable enough for this } } @@ -1012,7 +1045,7 @@ errr process_pref_file(cptr name) if (buf[0] == '%') { /* Process that file if allowed */ - (void)process_pref_file(buf + 2); + process_pref_file(buf + 2); /* Continue */ continue; @@ -1055,7 +1088,7 @@ static void prt_lnum(cptr header, s32b num, int row, int col, byte color) char out_val[32]; put_str(header, row, col); - (void)sprintf(out_val, "%9ld", (long)num); + sprintf(out_val, "%9ld", (long)num); c_put_str(color, out_val, row, col + len); } @@ -1071,7 +1104,7 @@ static void prt_num(cptr header, int num, int row, int col, byte color, put_str(header, row, col); put_str(space, row, col + len); - (void)sprintf(out_val, "%6ld", (long)num); + sprintf(out_val, "%6ld", (long)num); c_put_str(color, out_val, row, col + len + strlen(space)); } @@ -1086,7 +1119,7 @@ static void prt_str(cptr header, cptr str, int row, int col, byte color) put_str(header, row, col); put_str(" ", row, col + len); - (void)sprintf(out_val, "%6s", str); + sprintf(out_val, "%6s", str); c_put_str(color, out_val, row, col + len + 3); } @@ -1097,7 +1130,7 @@ static void prt_str(cptr header, cptr str, int row, int col, byte color) * For this to look right, the following should be spaced the * same as in the prt_lnum code... -CFT */ -static void display_player_middle(void) +static void display_player_middle() { int show_tohit = p_ptr->dis_to_h; int show_todam = p_ptr->dis_to_d; @@ -1145,7 +1178,7 @@ static void display_player_middle(void) prt_lnum("Max Exp ", p_ptr->max_exp, 11, 28, TERM_L_GREEN); - if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev)) + if (p_ptr->lev >= PY_MAX_LEVEL) { put_str("Exp to Adv.", 12, 28); c_put_str(TERM_L_GREEN, " *****", 12, 28 + 11); @@ -1166,7 +1199,7 @@ static void display_player_middle(void) { color = TERM_L_BLUE; } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) + else if (p_ptr->chp > (p_ptr->mhp * options->hitpoint_warn) / 10) { color = TERM_VIOLET; } @@ -1174,10 +1207,10 @@ static void display_player_middle(void) { color = TERM_L_RED; } - (void)sprintf(num, "%6ld", (long)p_ptr->chp); + sprintf(num, "%6ld", (long)p_ptr->chp); c_put_str(color, num, 9, 65); put_str("/", 9, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->mhp); + sprintf(num, "%6ld", (long)p_ptr->mhp); c_put_str(TERM_L_BLUE, num, 9, 72); } else @@ -1187,7 +1220,7 @@ static void display_player_middle(void) { color = TERM_L_GREEN; } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) + else if (p_ptr->chp > (p_ptr->mhp * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -1195,10 +1228,10 @@ static void display_player_middle(void) { color = TERM_RED; } - (void)sprintf(num, "%6ld", (long)p_ptr->chp); + sprintf(num, "%6ld", (long)p_ptr->chp); c_put_str(color, num, 9, 65); put_str("/", 9, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->mhp); + sprintf(num, "%6ld", (long)p_ptr->mhp); c_put_str(TERM_L_GREEN, num, 9, 72); } @@ -1207,7 +1240,7 @@ static void display_player_middle(void) { color = TERM_L_GREEN; } - else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10) + else if (p_ptr->csp > (p_ptr->msp * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -1215,10 +1248,10 @@ static void display_player_middle(void) { color = TERM_RED; } - (void)sprintf(num, "%6ld", (long)p_ptr->csp); + sprintf(num, "%6ld", (long)p_ptr->csp); c_put_str(color, num, 10, 65); put_str("/", 10, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->msp); + sprintf(num, "%6ld", (long)p_ptr->msp); c_put_str(TERM_L_GREEN, num, 10, 72); put_str("Sanity ", 11, 52); @@ -1226,7 +1259,7 @@ static void display_player_middle(void) { color = TERM_L_GREEN; } - else if (p_ptr->csane > (p_ptr->msane * hitpoint_warn) / 10) + else if (p_ptr->csane > (p_ptr->msane * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -1234,10 +1267,10 @@ static void display_player_middle(void) { color = TERM_RED; } - (void)sprintf(num, "%6ld", (long)p_ptr->csane); + sprintf(num, "%6ld", (long)p_ptr->csane); c_put_str(color, num, 11, 65); put_str("/", 11, 71); - (void)sprintf(num, "%6ld", (long)p_ptr->msane); + sprintf(num, "%6ld", (long)p_ptr->msane); c_put_str(TERM_L_GREEN, num, 11, 72); if (p_ptr->pgod != GOD_NONE) @@ -1247,18 +1280,16 @@ static void display_player_middle(void) put_str("Speed ", 13, 52); speed = p_ptr->pspeed; - /* Hack -- Visually "undo" the Search Mode Slowdown */ - if (p_ptr->searching) speed += 10; if (speed > 110) { char s[11]; - (void)sprintf(s, "Fast (+%d)", speed - 110); + sprintf(s, "Fast (+%d)", speed - 110); c_put_str(TERM_L_GREEN, s, 13, (speed >= 120) ? 68 : 69); } else if (speed < 110) { char s[11]; - (void)sprintf(s, "Slow (-%d)", 110 - speed); + sprintf(s, "Slow (-%d)", 110 - speed); c_put_str(TERM_L_UMBER, s, 13, (speed <= 100) ? 68 : 69); } else @@ -1361,11 +1392,13 @@ static cptr likert(int x, int y) * * This code is "imitated" elsewhere to "dump" a character sheet. */ -static void display_player_various(void) +static void display_player_various() { + auto const &r_info = game->edit_data.r_info; + int tmp, tmp2, damdice, damsides, dambonus, blows; - int xthn, xthb, xfos, xsrh; - int xdis, xdev, xsav, xstl; + int xthn, xthb; + int xdev, xsav, xstl; cptr desc; int i; @@ -1387,12 +1420,9 @@ static void display_player_various(void) blows = p_ptr->num_blow; /* Basic abilities */ - xdis = p_ptr->skill_dis; xdev = p_ptr->skill_dev; xsav = p_ptr->skill_sav; xstl = p_ptr->skill_stl; - xsrh = p_ptr->skill_srh; - xfos = p_ptr->skill_fos; put_str("Fighting :", 16, 1); @@ -1412,21 +1442,9 @@ static void display_player_various(void) c_put_str(likert_color, desc, 19, 15); - put_str("Perception :", 16, 28); - desc = likert(xfos, 6); - c_put_str(likert_color, desc, 16, 42); - - put_str("Searching :", 17, 28); - desc = likert(xsrh, 6); - c_put_str(likert_color, desc, 17, 42); - - put_str("Disarming :", 18, 28); - desc = likert(xdis, 8); - c_put_str(likert_color, desc, 18, 42); - - put_str("Magic Device:", 19, 28); + put_str("Magic Device:", 20, 1); desc = likert(xdev, 6); - c_put_str(likert_color, desc, 19, 42); + c_put_str(likert_color, desc, 20, 15); put_str("Blows/Round:", 16, 55); @@ -1473,7 +1491,7 @@ static void display_player_various(void) } else if (!r_info[p_ptr->body_monster].body_parts[BODY_WEAPON]) { - if (r_info[p_ptr->body_monster].flags1 & RF1_NEVER_BLOW) + if (r_info[p_ptr->body_monster].flags & RF_NEVER_BLOW) desc = "nil!"; else { @@ -1542,29 +1560,38 @@ static void display_player_various(void) * Obtain the "flags" of the wielded symbiote */ -void wield_monster_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) +static object_flag_set wield_monster_flags() { - object_type *o_ptr; - monster_race *r_ptr; + auto const &r_info = game->edit_data.r_info; - /* Clear */ - (*f1) = (*f2) = (*f3) = (*f4) = (*f5) = (*esp) = 0L; + object_flag_set flags; /* Get the carried monster */ - o_ptr = &p_ptr->inventory[INVEN_CARRY]; - + auto o_ptr = &p_ptr->inventory[INVEN_CARRY]; if (o_ptr->k_idx) { - r_ptr = &r_info[o_ptr->pval]; + auto r_ptr = &r_info[o_ptr->pval]; + + if (r_ptr->flags & RF_INVISIBLE) + flags |= TR_INVIS; + if (r_ptr->flags & RF_REFLECTING) + flags |= TR_REFLECT; + if (r_ptr->flags & RF_CAN_FLY) + flags |= TR_FEATHER; + if (r_ptr->flags & RF_AQUATIC) + flags |= TR_WATER_BREATH; + } + + return flags; +} - if (r_ptr->flags2 & RF2_INVISIBLE) - (*f2) |= TR2_INVIS; - if (r_ptr->flags2 & RF2_REFLECTING) - (*f2) |= TR2_REFLECT; - if (r_ptr->flags7 & RF7_CAN_FLY) - (*f3) |= TR3_FEATHER; - if (r_ptr->flags7 & RF7_AQUATIC) - (*f5) |= TR5_WATER_BREATH; + +template<class LF> +static void apply_lflags(LF const &lflags, object_flag_set *f) +{ + for (int i = 1; i <= p_ptr->lev; i++) + { + (*f) |= lflags[i].oflags; } } @@ -1572,607 +1599,620 @@ void wield_monster_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b /* * Obtain the "flags" for the player as if he was an item */ -void player_flags(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) +object_flag_set player_flags() { - int i; + auto const &r_info = game->edit_data.r_info; /* Clear */ - (*f1) = (*f2) = (*f3) = (*f4) = (*f5) = (*esp) = 0L; + object_flag_set f; /* Astral chars */ if (p_ptr->astral) { - (*f3) |= TR3_WRAITH; + f |= TR_WRAITH; } /* Skills */ - if (get_skill(SKILL_DAEMON) > 20) (*f2) |= TR2_RES_CONF; - if (get_skill(SKILL_DAEMON) > 30) (*f2) |= TR2_RES_FEAR; - if (get_skill(SKILL_MINDCRAFT) >= 40) (*esp) |= ESP_ALL; + if (get_skill(SKILL_DAEMON) > 20) f |= TR_RES_CONF; + if (get_skill(SKILL_DAEMON) > 30) f |= TR_RES_FEAR; + if (get_skill(SKILL_MINDCRAFT) >= 40) f |= ESP_ALL; if (p_ptr->melee_style == SKILL_HAND && get_skill(SKILL_HAND) > 24 && !monk_heavy_armor()) - (*f2) |= TR2_FREE_ACT; -/* Hack - from Lua */ - if (get_skill(SKILL_MANA) >= 35) (*f1) |= TR1_MANA; - if (get_skill(SKILL_AIR) >= 50) (*f5) |= (TR5_MAGIC_BREATH | TR5_WATER_BREATH); - if (get_skill(SKILL_WATER) >= 30) (*f5) |= TR5_WATER_BREATH; + { + f |= TR_FREE_ACT; + } + if (get_skill(SKILL_MANA) >= 35) f |= TR_MANA; + if (get_skill(SKILL_AIR) >= 50) f |= (TR_MAGIC_BREATH | TR_WATER_BREATH); + if (get_skill(SKILL_WATER) >= 30) f |= TR_WATER_BREATH; /* Gods */ if (p_ptr->pgod == GOD_ERU) { - if ((p_ptr->grace >= 100) || (p_ptr->grace <= -100)) (*f1) |= TR1_MANA; - if (p_ptr->grace > 10000) (*f1) |= TR1_WIS; + if ((p_ptr->grace >= 100) || (p_ptr->grace <= -100)) f |= TR_MANA; + if (p_ptr->grace > 10000) f |= TR_WIS; } if (p_ptr->pgod == GOD_MELKOR) { - (*f2) |= TR2_RES_FIRE; - if (p_ptr->melkor_sacrifice > 0) (*f2) |= TR2_LIFE; - if (p_ptr->grace > 10000) (*f1) |= (TR1_STR | TR1_CON | TR1_INT | TR1_WIS | TR1_CHR); + f |= TR_RES_FIRE; + if (p_ptr->melkor_sacrifice > 0) f |= TR_LIFE; + if (p_ptr->grace > 10000) f |= (TR_STR | TR_CON | TR_INT | TR_WIS | TR_CHR); if (p_ptr->praying) { - if (p_ptr->grace > 5000) (*f2) |= TR2_INVIS; - if (p_ptr->grace > 15000) (*f2) |= TR2_IM_FIRE; + if (p_ptr->grace > 5000) f |= TR_INVIS; + if (p_ptr->grace > 15000) f |= TR_IM_FIRE; } } if (p_ptr->pgod == GOD_MANWE) { - if (p_ptr->grace >= 2000) (*f3) |= TR3_FEATHER; + if (p_ptr->grace >= 2000) f |= TR_FEATHER; if (p_ptr->praying) { - if (p_ptr->grace >= 7000) (*f2) |= TR2_FREE_ACT; - if (p_ptr->grace >= 15000) (*f4) |= TR4_FLY; - if ((p_ptr->grace >= 5000) || (p_ptr->grace <= -5000)) (*f1) |= TR1_SPEED; + if (p_ptr->grace >= 7000) f |= TR_FREE_ACT; + if (p_ptr->grace >= 15000) f |= TR_FLY; + if ((p_ptr->grace >= 5000) || (p_ptr->grace <= -5000)) f |= TR_SPEED; } } if (p_ptr->pgod == GOD_TULKAS) { - if (p_ptr->grace > 5000) (*f1) |= TR1_CON; - if (p_ptr->grace > 10000) (*f1) |= TR1_STR; + if (p_ptr->grace > 5000) f |= TR_CON; + if (p_ptr->grace > 10000) f |= TR_STR; } if (p_ptr->pgod == GOD_AULE) { if (p_ptr->grace > 5000) { - (*f2) |= TR2_RES_FIRE; + f |= TR_RES_FIRE; } } if (p_ptr->pgod == GOD_MANDOS) { - (*f2) |= TR2_RES_NETHER; + f |= TR_RES_NETHER; if ((p_ptr->grace > 10000) && (p_ptr->praying == TRUE)) { - (*f3) |= TR3_NO_TELE; + f |= TR_NO_TELE; } if ((p_ptr->grace > 20000) && (p_ptr->praying == TRUE)) { - (*f4) |= TR4_IM_NETHER; + f |= TR_IM_NETHER; } } if (p_ptr->pgod == GOD_ULMO) { - (*f5) |= TR5_WATER_BREATH; + f |= TR_WATER_BREATH; if ((p_ptr->grace > 1000) && (p_ptr->praying == TRUE)) { - (*f2) |= TR2_RES_POIS; + f |= TR_RES_POIS; } if ((p_ptr->grace > 15000) && (p_ptr->praying == TRUE)) { - (*f5) |= TR5_MAGIC_BREATH; + f |= TR_MAGIC_BREATH; } } /* Classes */ - for (i = 1; i <= p_ptr->lev; i++) - { - (*f1) |= cp_ptr->oflags1[i]; - (*f2) |= cp_ptr->oflags2[i]; - (*f3) |= cp_ptr->oflags3[i]; - (*f4) |= cp_ptr->oflags4[i]; - (*f5) |= cp_ptr->oflags5[i]; - (*esp) |= cp_ptr->oesp[i]; - } + apply_lflags(cp_ptr->lflags, &f); /* Races */ if ((!p_ptr->mimic_form) && (!p_ptr->body_monster)) { - for (i = 1; i <= p_ptr->lev; i++) - { - (*f1) |= rp_ptr->oflags1[i]; - (*f2) |= rp_ptr->oflags2[i]; - (*f3) |= rp_ptr->oflags3[i]; - (*f4) |= rp_ptr->oflags4[i]; - (*f5) |= rp_ptr->oflags5[i]; - (*esp) |= rp_ptr->oesp[i]; - - (*f1) |= rmp_ptr->oflags1[i]; - (*f2) |= rmp_ptr->oflags2[i]; - (*f3) |= rmp_ptr->oflags3[i]; - (*f4) |= rmp_ptr->oflags4[i]; - (*f5) |= rmp_ptr->oflags5[i]; - (*esp) |= rmp_ptr->oesp[i]; - } + apply_lflags(rp_ptr->lflags, &f); + apply_lflags(rmp_ptr->lflags, &f); } else { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - - if (r_ptr->flags2 & RF2_REFLECTING) (*f2) |= TR2_REFLECT; - if (r_ptr->flags2 & RF2_REGENERATE) (*f3) |= TR3_REGEN; - if (r_ptr->flags2 & RF2_AURA_FIRE) (*f3) |= TR3_SH_FIRE; - if (r_ptr->flags2 & RF2_AURA_ELEC) (*f3) |= TR3_SH_ELEC; - if (r_ptr->flags2 & RF2_PASS_WALL) (*f3) |= TR3_WRAITH; - if (r_ptr->flags3 & RF3_SUSCEP_FIRE) (*f2) |= TR2_SENS_FIRE; - if (r_ptr->flags3 & RF3_IM_ACID) (*f2) |= TR2_RES_ACID; - if (r_ptr->flags3 & RF3_IM_ELEC) (*f2) |= TR2_RES_ELEC; - if (r_ptr->flags3 & RF3_IM_FIRE) (*f2) |= TR2_RES_FIRE; - if (r_ptr->flags3 & RF3_IM_POIS) (*f2) |= TR2_RES_POIS; - if (r_ptr->flags3 & RF3_IM_COLD) (*f2) |= TR2_RES_COLD; - if (r_ptr->flags3 & RF3_RES_NETH) (*f2) |= TR2_RES_NETHER; - if (r_ptr->flags3 & RF3_RES_NEXU) (*f2) |= TR2_RES_NEXUS; - if (r_ptr->flags3 & RF3_RES_DISE) (*f2) |= TR2_RES_DISEN; - if (r_ptr->flags3 & RF3_NO_FEAR) (*f2) |= TR2_RES_FEAR; - if (r_ptr->flags3 & RF3_NO_SLEEP) (*f2) |= TR2_FREE_ACT; - if (r_ptr->flags3 & RF3_NO_CONF) (*f2) |= TR2_RES_CONF; - if (r_ptr->flags7 & RF7_CAN_FLY) (*f3) |= TR3_FEATHER; - } - - (*f1) |= p_ptr->xtra_f1; - (*f2) |= p_ptr->xtra_f2; - (*f3) |= p_ptr->xtra_f3; - (*f4) |= p_ptr->xtra_f4; - (*f5) |= p_ptr->xtra_f5; - (*esp) |= p_ptr->xtra_esp; + auto &r_ref = r_info[p_ptr->body_monster]; + + if (r_ref.flags & RF_REFLECTING) f |= TR_REFLECT; + if (r_ref.flags & RF_REGENERATE) f |= TR_REGEN; + if (r_ref.flags & RF_AURA_FIRE) f |= TR_SH_FIRE; + if (r_ref.flags & RF_AURA_ELEC) f |= TR_SH_ELEC; + if (r_ref.flags & RF_PASS_WALL) f |= TR_WRAITH; + if (r_ref.flags & RF_SUSCEP_FIRE) f |= TR_SENS_FIRE; + if (r_ref.flags & RF_IM_ACID) f |= TR_RES_ACID; + if (r_ref.flags & RF_IM_ELEC) f |= TR_RES_ELEC; + if (r_ref.flags & RF_IM_FIRE) f |= TR_RES_FIRE; + if (r_ref.flags & RF_IM_POIS) f |= TR_RES_POIS; + if (r_ref.flags & RF_IM_COLD) f |= TR_RES_COLD; + if (r_ref.flags & RF_RES_NETH) f |= TR_RES_NETHER; + if (r_ref.flags & RF_RES_NEXU) f |= TR_RES_NEXUS; + if (r_ref.flags & RF_RES_DISE) f |= TR_RES_DISEN; + if (r_ref.flags & RF_NO_FEAR) f |= TR_RES_FEAR; + if (r_ref.flags & RF_NO_SLEEP) f |= TR_FREE_ACT; + if (r_ref.flags & RF_NO_CONF) f |= TR_RES_CONF; + if (r_ref.flags & RF_CAN_FLY) f |= TR_FEATHER; + } + + f |= p_ptr->xtra_flags; if (p_ptr->black_breath) { - (*f4) |= TR4_BLACK_BREATH; + f |= TR_BLACK_BREATH; } if (p_ptr->hp_mod != 0) { - (*f2) |= TR2_LIFE; + f |= TR_LIFE; } + + return f; } +namespace { // <anonymous> + /* - * Object flag names + * Build an return a (static) index of all the object_flag_meta + * information indexed by page->column->row. */ -static cptr object_flag_names[192] = +static std::vector<object_flag_meta const *> const &object_flag_metas_by_pcr(int page, int column, int row) { - "Add Str", - "Add Int", - "Add Wis", - "Add Dex", - "Add Con", - "Add Chr", - "Mul Mana", - "Mul SPower", - "Add Stea.", - "Add Sear.", - "Add Infra", - "Add Tun..", - "Add Speed", - "Add Blows", - "Chaotic", - "Vampiric", - "Slay Anim.", - "Slay Evil", - "Slay Und.", - "Slay Demon", - "Slay Orc", - "Slay Troll", - "Slay Giant", - "Slay Drag.", - "Kill Drag.", - "Sharpness", - "Impact", - "Poison Brd", - "Acid Brand", - "Elec Brand", - "Fire Brand", - "Cold Brand", - - "Sust Str", - "Sust Int", - "Sust Wis", - "Sust Dex", - "Sust Con", - "Sust Chr", - "Invisible", - "Mul life", - "Imm Acid", - "Imm Elec", - "Imm Fire", - "Imm Cold", - "Sens Fire", - "Reflect", - "Free Act", - "Hold Life", - "Res Acid", - "Res Elec", - "Res Fire", - "Res Cold", - "Res Pois", - "Res Fear", - "Res Light", - "Res Dark", - "Res Blind", - "Res Conf", - "Res Sound", - "Res Shard", - "Res Neth", - "Res Nexus", - "Res Chaos", - "Res Disen", - - - - "Aura Fire", - "Aura Elec", - "Auto Curse", - NULL, - "NoTeleport", - "AntiMagic", - "WraithForm", - "EvilCurse", - NULL, - NULL, - NULL, - NULL, - "Levitate", - "Lite", - "See Invis", - NULL, - "Digestion", - "Regen", - "Xtra Might", - "Xtra Shots", - NULL, - NULL, - NULL, - NULL, - "Activate", - "Drain Exp", - "Teleport", - "Aggravate", - "Blessed", - "Cursed", - "Hvy Curse", - "Prm Curse", - - "No blows", - "Precogn.", - "B.Breath", - "Recharge", - "Fly", - "Mrg.Curse", - NULL, - NULL, - "Sentient", - "Clone", - NULL, - "Climb", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Imm Neth", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - "Orc.ESP", - "Troll.ESP", - "Dragon.ESP", - "Giant.ESP", - "Demon.ESP", - "Undead.ESP", - "Evil.ESP", - "Animal.ESP", - "TLord.ESP", - "Good.ESP", - "Nlive.ESP", - "Unique.ESP", - "Spider ESP", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Full ESP", + static std::vector<std::vector<std::vector<std::vector<object_flag_meta const *>>>> instance; + + if (instance.empty()) + { + // Find number of pages, columns and rows. + std::size_t n_pages = 0; + std::size_t n_columns = 0; + std::size_t n_rows = 0; + + for (auto const &object_flag_meta: object_flags_meta()) + { + n_pages = std::max<std::size_t>(n_pages, object_flag_meta->c_page + 1); + n_columns = std::max<std::size_t>(n_columns, object_flag_meta->c_column + 1); + n_rows = std::max<std::size_t>(n_rows, object_flag_meta->c_row + 1); + } + + // Sanity check; we should always have enough data. + assert(n_pages > 0); + assert(n_columns > 0); + assert(n_rows > 0); + + // Build the scaffolding structure without the actual data. + instance.reserve(n_pages); + for (std::size_t i = 0; i < n_pages; i++) + { + std::vector<std::vector<std::vector<object_flag_meta const *>>> page; + page.reserve(n_columns); + + for (std::size_t j = 0; j < n_columns; j++) + { + std::vector<std::vector<object_flag_meta const *>> column; + column.reserve(n_rows); + + for (std::size_t k = 0; k < n_rows; k++) + { + std::vector<object_flag_meta const *> row; + column.push_back(row); + } + + page.push_back(column); + } + + instance.push_back(page); + } + + // Insert all the data. + for (auto const object_flag_meta: object_flags_meta()) + { + // Ignore if not mapped to any page. + if (!object_flag_meta->c_name) + { + continue; + } + + // Find the row + auto &row = instance + .at(object_flag_meta->c_page) + .at(object_flag_meta->c_column) + .at(object_flag_meta->c_row); + + // Insert + row.push_back(object_flag_meta); + } + } + + return instance.at(page).at(column).at(row); +} + + +/** + * Convert a number to a digit, capping at '9'. Ignores the sign of the number. + */ +static char number_to_digit(int n) { + // Throw away sign. + n = std::abs(n); + // Convert to digit or '*' + return (n > 9 ? '*' : I2D(n)); }; -/* - * Summarize resistances + +/** + * Check that two object_flag types are compatible. */ -static void display_player_ben_one(int mode) +static bool object_flag_types_are_compatible(char type_a, char type_b) { - int i, n, x, y, z, dispx, modetemp, xtemp; + switch (type_a) + { + case 'n': + return (type_b == 'n'); + case 'b': + return (type_b == 'b'); + case '+': + case '*': + return (type_b == '+') || (type_b == '*'); + case 'f': + return (type_b == 'f'); + case '\0': + return true; + default: + abort(); + } +} - object_type *o_ptr; +/** + * Object flag data for calculating cells on the character sheet. + */ +struct object_flag_cell { + /** + * Type designator for the cell, if any. + */ + char type; - char dummy[80], c; + /** + * Associated PVAL, if any. + */ + int pval; + + /** + * Label for the cell, given its current contents. + */ + const char *label; - u32b f1, f2, f3, f4, f5, esp; + /** + * Create object_flag_cell from object_flag_meta. + */ + static object_flag_cell from_object_flag_meta(object_flag_meta const &object_flag_meta, int pval) + { + // The FIXED type flags require special handling. + if ((object_flag_meta.c_type == '1') || (object_flag_meta.c_type == '2') || (object_flag_meta.c_type == '3')) + { + return object_flag_cell { + 'f', + D2I(object_flag_meta.c_type), + object_flag_meta.c_name + }; + } + else + { + return object_flag_cell { + object_flag_meta.c_type, + pval, + object_flag_meta.c_name + }; + } + } - u16b b[INVEN_TOTAL - INVEN_WIELD + 1][10]; +}; - int d[INVEN_TOTAL - INVEN_WIELD + 1]; +namespace detail { // "hide" from surrounding scope; should only be accessed through the monoid - bool_ got; +static object_flag_cell object_flag_cell_append(object_flag_cell const &a, object_flag_cell const &b) +{ + // The "empty" value automatically gets swallowed, whatever + // "side" of the append it's on. + if (a.type == '\0') + { + return b; + } - byte a; + if (b.type == '\0') + { + return a; + } - cptr name; + // The rest of the code assumes compatible types, so we + // assert this to a) avoid over-complicated logic, and + // b) breaking under 'unexpected' changes to the object + // flag list. + if (!object_flag_types_are_compatible(a.type, b.type)) + { + abort(); + } - /* Scan equipment */ - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) + // Any boolean flag which is "set" overrides the previous + // flag. (If the flag was already set we won't lose any + // information.) + if (b.type == 'b') { - /* Index */ - n = (i - INVEN_WIELD); + return b; + } - /* Object */ - o_ptr = &p_ptr->inventory[i]; + // Flags with a numerical value get added together. + if (b.type == 'n') // (a.type == 'n') by symmetry and object_flag_types_are_compatible() + { + // Arbitrary choice of label -- the labels *should* be the same, by definition + return object_flag_cell { 'n', a.pval + b.pval, a.label }; + } - /* Known object flags */ - object_flags_known(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + // Fixed-value flags. + if (a.type == 'f') // (b.type == 'f') by symmetry and object_flag_types_are_compatible() + { + // Arbitrary choice of label -- the labels *should* be the same, by definition + return object_flag_cell { 'f', a.pval + b.pval, a.label }; + } - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); - d[n] = o_ptr->pval; + // Flags of the TERNARY variety have a "supercedes" rule + // where immunity supercedes resistance. + if (a.type == '*') + { + return object_flag_cell { '*', 0, a.label }; + } + else if (b.type == '*') + { + return object_flag_cell { '*', 0, b.label }; + } + else // Both must be '+' + { + // Arbitrary choice of label -- the labels *should* be the same, by definition + return object_flag_cell { '+', 0, a.label }; } +} - /* Carried symbiote */ - n = INVEN_CARRY - INVEN_WIELD; +constexpr object_flag_cell object_flag_cell_empty { '\0', 0, nullptr }; - /* Player flags */ - wield_monster_flags(&f1, &f2, &f3, &f4, &f5, &esp); +} // namespace "detail" - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); +using object_flag_cell_monoid = monoid<object_flag_cell, detail::object_flag_cell_append, detail::object_flag_cell_empty>; - /* Index */ - n = INVEN_TOTAL - INVEN_WIELD; +} // namespace <anonymous> - /* Player flags */ - player_flags(&f1, &f2, &f3, &f4, &f5, &esp); +namespace { // <anonymous> - /* Incorporate */ - b[n][0] = (u16b)(f1 & 0xFFFF); - b[n][1] = (u16b)(f1 >> 16); - b[n][2] = (u16b)(f2 & 0xFFFF); - b[n][3] = (u16b)(f2 >> 16); - b[n][4] = (u16b)(f3 & 0xFFFF); - b[n][5] = (u16b)(f3 >> 16); - b[n][6] = (u16b)(f4 & 0xFFFF); - b[n][7] = (u16b)(f4 >> 16); - b[n][8] = (u16b)(esp & 0xFFFF); - b[n][9] = (u16b)(esp >> 16); +static object_flag_meta const *get_lowest_priority_object_flag_meta(std::vector<object_flag_meta const *> const &object_flag_metas) +{ + object_flag_meta const *found = nullptr; - /* Generate the equip chars */ - sprintf(dummy, " "); - for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++) + for (auto object_flag_meta: object_flag_metas) { - /* If you have that body part then show it */ - if (p_ptr->body_parts[i]) + if ((!found) || (found->c_priority > object_flag_meta->c_priority)) { - strcat(dummy, format("%c", i + 'a')); + found = object_flag_meta; } } - strcat(dummy, "@"); - /* Scan cols */ - for (x = 1; x > -1; x--) + return found; +} + + +static std::tuple<char, int> object_flag_cell_to_char(object_flag_cell const &object_flag_cell) +{ + switch (object_flag_cell.type) { - /* Label */ - Term_putstr(x * 40 + 11, 3, -1, TERM_WHITE, dummy); + case 'n': + case 'f': + // If we have no pval, we use a simple '+'. This applies + // to the 'player' slot. + if (object_flag_cell.pval == 0) + { + return std::make_tuple('+', 1); + } + else + { + return std::make_tuple( + number_to_digit(object_flag_cell.pval), + (object_flag_cell.pval >= 0) ? 1 : -1); + } + break; + + case 'b': + case '+': + return std::make_tuple('+', 1); + break; - /* Scan rows */ - for (y = 0; y < 16; y++) + case '*': + return std::make_tuple('*', 1); + break; + + default: + return std::make_tuple('.', 0); + break; + } + + abort(); +} + + +/* + * Output a slot + */ +static void display_flag_row( + int y, + int x0, + std::vector<std::tuple<char, int, object_flag_set>> const &slots, + std::vector<object_flag_meta const *> const &object_flag_metas_at_pcr) +{ + assert(!object_flag_metas_at_pcr.empty()); + + // Accumulated value of all of the slots + auto acc = object_flag_cell_monoid::empty; + + // Go through each slot + for (std::size_t i = 0; i < slots.size(); i++) + { + object_flag_cell combined = object_flag_cell_monoid::empty; + + // Go through all flags that are actually set for this 'cell'. { - if (mode == 3 && x == 1) - { - modetemp = 4; - xtemp = 0; - } - else + auto const &slot = slots[i]; + auto const pval = std::get<1>(slot); + auto const flags = std::get<2>(slot); + + for (auto const object_flag_meta: object_flag_metas_at_pcr) { - modetemp = mode; - xtemp = x; + if (object_flag_meta->flag_set & flags) + { + combined = object_flag_cell_monoid::append( + combined, + object_flag_cell::from_object_flag_meta(*object_flag_meta, pval)); + } } + } - for (z = mode; z <= modetemp; z++) - { - if (mode == 3 && x == 1 && z == modetemp) xtemp = 1; - name = object_flag_names[32 * modetemp + 16 * xtemp + y]; - got = FALSE; + // Accumulate into the global accumulator + acc = object_flag_cell_monoid::append(acc, combined); - /* No name */ - if (!name) continue; + // Write the cell's value. + auto const char_and_rating = object_flag_cell_to_char(combined); + auto const ch = std::get<0>(char_and_rating); + auto const rating = std::get<1>(char_and_rating); - /* Dump colon */ - if (!(modetemp == 1 && x == 0 && y > 7 && y < 12)) - { - Term_putch(x * 40 + 10, y + 4, TERM_WHITE, ':'); - } + // Convert good flag into a color. + byte a; + if (rating == 0) + { + a = (i & 0x02) ? TERM_GREEN : TERM_SLATE; + } + else if (rating < 0) + { + a = TERM_RED; + } + else + { + a = TERM_L_GREEN; + } - /* Check flags */ - dispx = 0; - for (n = 0; n < INVEN_TOTAL - INVEN_WIELD + 1; n++) - { - /* Change colour every two columns */ - bool_ is_green = (dispx & 0x02); - a = (is_green ? TERM_GREEN : TERM_SLATE); - c = '.'; + // Output the flag + Term_putch(x0 + 11 + i, y, a, ch); + } - /* If the body part doesn't exists then skip it :) */ - if ((n < INVEN_TOTAL - INVEN_WIELD) && (!p_ptr->body_parts[n])) continue; + // Extract the label. If the flag isn't set at all then we don't have + // an actual label, so we'll use the one from the meta-level object + // flag definition. Note that the prioritization is crucial for the + // labeling to work properly; e.g. IMM_FIRE comes *before* the + // RES_FIRE flag in the object flag list, but we don't want the *label* + // from IMM_FIRE to be used when the flag is not set at all. + auto const label = (acc.label != nullptr) + ? acc.label + : get_lowest_priority_object_flag_meta(object_flag_metas_at_pcr)->c_name; - /* Increment the drawing coordinates */ - dispx++; + // Get the "rating" for the label. + auto const rating = std::get<1>(object_flag_cell_to_char(acc)); - /* Check flag */ - if (b[n][2 * modetemp + xtemp] & (1 << y)) - { - a = (is_green ? TERM_L_GREEN : TERM_WHITE); - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - c = '*'; - } - else if (modetemp == 0 && x == 0 && y < 14 && (y < 6 || y > 7)) - { - if (n == INVEN_TOTAL - INVEN_WIELD) - { - c = '+'; - } - else - { - c = d[n]; - if (c < 0) - { - c = -c; - a = TERM_RED; - } - c = (c > 9 ? '*' : I2D(c)); - } - } - else - { - c = '+'; - } - got = TRUE; - } + byte label_attr; + if (rating == 0) { + label_attr = TERM_WHITE; + } else if (rating < 0) { + label_attr = TERM_RED; + } else { + label_attr = TERM_L_GREEN; + } - /* HACK - Check for nether immunity and - apply to Res Neth line */ - if (modetemp == 1 && x == 1 && y == 12) - { - if (b[n][7] & (1 << 6)) - { - a = (is_green ? TERM_L_GREEN : TERM_WHITE); - c = '*'; - got = TRUE; - } - } + Term_putch(x0 + 10, y, TERM_WHITE, ':'); + Term_putstr(x0, y, -1, label_attr, label); +} - /* Dump flag */ - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - if (c == '*') Term_putch(40 + 11 + dispx, y - 4, a, c); - } - else - { - Term_putch(x * 40 + 11 + dispx, y + 4, a, c); - } - } +/* + * Summarize resistances + */ +static void display_player_ben_one(int page) +{ + // Slots of flags to show. + std::vector<std::tuple<char, int, object_flag_set>> slots; + slots.reserve(INVEN_TOTAL - INVEN_WIELD + 1); - a = TERM_WHITE; - if (got) - { - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - a = TERM_L_GREEN; - } - else if (modetemp != 0) - { - a = TERM_GREEN; - } - } + // Scan equipment + for (std::size_t i = INVEN_WIELD; i < INVEN_TOTAL; i++) + { + // Skip inventory slots that don't exist on the body. + auto n = i - INVEN_WIELD; + if ((n < INVEN_TOTAL - INVEN_WIELD) && (!p_ptr->body_parts[n])) continue; - /* HACK - Check for nether immunity and change "Res Neth" */ - if (modetemp == 1 && x == 1 && y == 12 && p_ptr->immune_neth) - { - name = "Imm Neth"; - a = TERM_L_GREEN; - } + // Extract object flags + auto const o_ptr = &p_ptr->inventory[i]; + auto const flags = object_flags_known(o_ptr); + // Add slot + slots.emplace_back( + std::make_tuple('a' + i - INVEN_WIELD, o_ptr->pval, flags)); + } - /* Dump name */ - if (modetemp == 1 && x == 0 && y > 7 && y < 12) - { - if (got) Term_putstr(40, y - 4, -1, a, name); - } - else - { - Term_putstr(x * 40, y + 4, -1, a, name); - } + // Carried symbiote + { + // Extract flags + auto const flags = wield_monster_flags(); + // Add slot + slots.emplace_back( + std::make_tuple('z', 0, flags)); + } + + // Player + slots.emplace_back( + std::make_tuple('@', 0, player_flags())); + + // Go through each column + for (int col = 0; col < 2; col++) + { + // Base coordinate for output + const auto x0 = col * 40; + const auto y0 = 3; + + // Add slot headings. + { + std::string buf; + buf.reserve(slots.size()); + + for (auto const &slot: slots) + { + buf += std::get<0>(slot); + } + + Term_putstr(x0 + 11, y0, -1, TERM_WHITE, buf.c_str()); + } + + // Scan rows + for (int row = 0; row < 16; row++) + { + // Extract the flag metadata for the current page/col/row + auto const object_flag_metas_at_pcr = + object_flag_metas_by_pcr(page, col, row); + + // Ignore flags which we don't actually map to anything. + if (object_flag_metas_at_pcr.empty()) + { + continue; } + + // Y coordinate for the row + auto const y = y0 + 1 + row; + + // Show the row + display_flag_row(y, x0, slots, object_flag_metas_at_pcr); } } } +} // namespace <anonymous> /* - * Display the character on the screen (various modes) - * - * The top two and bottom two lines are left blank. - * - * Mode 0 = standard display with skills - * Mode 1 = standard display with history - * Mode 2 = current flags (part 1) - * Mode 3 = current flags (part 2) - * Mode 4 = current flags (part 3) - * Mode 5 = current flags (part 4) - * Mode 6 = current flags (part 5 -- esp) + * Display the character on the screen */ void display_player(int mode) { - int i; + auto const &r_info = game->edit_data.r_info; + + assert(mode >= 0); + assert(mode < 5); char buf[80]; @@ -2181,47 +2221,29 @@ void display_player(int mode) clear_from(0); /* Standard */ - if ((mode == 0) || (mode == 1)) + if (mode == 0) { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; /* Name, Sex, Race, Class */ put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class :", 5, 1); - put_str("Body :", 6, 1); - put_str("God :", 7, 1); - c_put_str(TERM_L_BLUE, player_name, 2, 9); - if (p_ptr->body_monster != 0) - { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - char tmp[12]; - - if ((r_ptr->flags1 & RF1_MALE) != 0) - strcpy(tmp, "Male"); - else if ((r_ptr->flags1 & RF1_FEMALE) != 0) - strcpy(tmp, "Female"); - else - strcpy(tmp, "Neuter"); - c_put_str(TERM_L_BLUE, tmp, 3, 9); - } - else - c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9); - sprintf(buf, "%s", get_player_race_name(p_ptr->prace, p_ptr->pracem)); - c_put_str(TERM_L_BLUE, buf, 4, 9); - c_put_str(TERM_L_BLUE, spp_ptr->title, 5, 9); - c_put_str(TERM_L_BLUE, r_ptr->name, 6, 9); - c_put_str(TERM_L_BLUE, deity_info[p_ptr->pgod].name, 7, 9); - - /* Age, Height, Weight, Social */ - prt_num("Age ", (int)p_ptr->age + bst(YEAR, turn), 2, 32, TERM_L_BLUE, " "); - prt_num("Height ", (int)p_ptr->ht, 3, 32, TERM_L_BLUE, " "); - prt_num("Weight ", (int)p_ptr->wt, 4, 32, TERM_L_BLUE, " "); - prt_num("Social Class ", (int)p_ptr->sc, 5, 32, TERM_L_BLUE, " "); + 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); + + put_str("Class :", 4, 1); + c_put_str(TERM_L_BLUE, spp_ptr->title, 4, 9); + + put_str("Body :", 5, 1); + c_put_str(TERM_L_BLUE, r_ptr->name, 5, 9); + + put_str("God :", 6, 1); + c_put_str(TERM_L_BLUE, deity_info[p_ptr->pgod].name, 6, 9); /* Display the stats */ - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { char punctuation = p_ptr->stat_max[i] == 18 + 100 ? '!' : ':'; /* Special treatment of "injured" stats */ @@ -2274,30 +2296,15 @@ void display_player(int mode) /* Extra info */ display_player_middle(); - /* Display "history" info */ - if (mode == 1) - { - put_str("(Character Background)", 15, 25); - - for (i = 0; i < 4; i++) - { - put_str(history[i], i + 16, 10); - } - } - /* Display "various" info */ - else - { - put_str("(Miscellaneous Abilities)", 15, 25); - - display_player_various(); - } + put_str("(Miscellaneous Abilities)", 15, 25); + display_player_various(); } /* Special */ else { - display_player_ben_one(mode - 2); + display_player_ben_one(mode - 1); } } @@ -2307,25 +2314,29 @@ void display_player(int mode) * Describe the player's location -- either by dungeon level, town, or in * wilderness with landmark reference. */ -cptr describe_player_location() +std::string describe_player_location() { - int i; - static char desc[80]; + auto const &wilderness = game->wilderness; + auto const &d_info = game->edit_data.d_info; + auto const &wf_info = game->edit_data.wf_info; + + std::string desc; + int pwx = (p_ptr->wild_mode ? p_ptr->px : p_ptr->wilderness_x); int pwy = (p_ptr->wild_mode ? p_ptr->py : p_ptr->wilderness_y); - int feat = wild_map[pwy][pwx].feat; + int feat = wilderness(pwx, pwy).feat; if (dungeon_type != DUNGEON_WILDERNESS && dun_level > 0) { - sprintf(desc, "on level %d of %s", dun_level, d_info[dungeon_type].name); + desc += fmt::format("on level {:d} of {}", dun_level, d_info[dungeon_type].name); } else if (wf_info[feat].terrain_idx == TERRAIN_TOWN) { - sprintf(desc, "in the town of %s", wf_info[feat].name); + desc += fmt::format("in the town of {}", wf_info[feat].name); } else if (wf_info[feat].entrance) { - sprintf(desc, "near %s", wf_info[feat].name); + desc += fmt::format("near {}", wf_info[feat].name); } else { @@ -2338,21 +2349,19 @@ cptr describe_player_location() */ int landmark = 0, lwx = 0, lwy = 0; int l_dist = -1; - int i; - for (i = 0; i < max_wf_idx; i++) + for (std::size_t i = 0; i < wf_info.size(); i++) { int wx = wf_info[i].wild_x; int wy = wf_info[i].wild_y; - int dist; /* Skip if not a landmark */ if (!wf_info[i].entrance) continue; /* Skip if we haven't seen it */ - if (!wild_map[wy][wx].known) continue; + if (!wilderness(wx, wy).known) continue; - dist = distance(wy, wx, pwy, pwx); + int dist = distance(wy, wx, pwy, pwx); if (dist < l_dist || l_dist < 0) { landmark = i; @@ -2364,12 +2373,12 @@ cptr describe_player_location() if (!landmark) { - sprintf(desc, "in %s", wf_info[feat].text); + desc += fmt::format("in {}", wf_info[feat].text); } else if (pwx == lwx && pwy == lwy) { /* Paranoia; this should have been caught above */ - sprintf(desc, "near %s", wf_info[feat].name); + desc += fmt::format("near {}", wf_info[feat].name); } else { @@ -2391,7 +2400,8 @@ cptr describe_player_location() if (dy * 81 < dx * 31) ns = ""; if (dx * 81 < dy * 31) ew = ""; - sprintf(desc, "in %s %s%s of %s", + desc += fmt::format( + "in {} {}{} of {}", wf_info[feat].text, ns, ew, @@ -2399,10 +2409,8 @@ cptr describe_player_location() } } - /* strip trailing whitespace */ - for (i = 0; desc[i]; ++i); - while (desc[--i] == ' ') - desc[i] = 0; + /* Strip trailing whitespace */ + boost::trim_right(desc); return desc; } @@ -2446,7 +2454,7 @@ static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_leg { for (x = 0; x < 40; x++) { - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); buf[x] = c; } @@ -2459,7 +2467,7 @@ static void file_character_print_grid(FILE *fff, bool_ show_gaps, bool_ show_leg { for (x = 40; x < 80; x++) { - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); buf[x - 40] = c; } @@ -2494,19 +2502,20 @@ void file_character_print_item(FILE *fff, char label, object_type *obj, bool_ fu * * Prints out one "store" (for Home and Mathom-house) */ -void file_character_print_store(FILE *fff, wilderness_type_info *place, int store, bool_ full) +static void file_character_print_store(FILE *fff, wilderness_type_info const *place, std::size_t store, bool_ full) { - int i; + auto const &st_info = game->edit_data.st_info; + town_type *town = &town_info[place->entrance]; store_type *st_ptr = &town->store[store]; - if (st_ptr->stock_num) + if (st_ptr->stock.size()) { /* Header with name of the town */ - fprintf(fff, " [%s Inventory - %s]\n\n", st_info[store].name, place->name); + fprintf(fff, " [%s Inventory - %s]\n\n", st_info[store].name.c_str(), place->name); /* Dump all available items */ - for (i = 0; i < st_ptr->stock_num; i++) + for (std::size_t i = 0; i < st_ptr->stock.size(); i++) { file_character_print_item(fff, I2A(i%24), &st_ptr->stock[i], full); } @@ -2523,7 +2532,7 @@ void file_character_print_store(FILE *fff, wilderness_type_info *place, int stor * was not already there. XXX This is an ugly workaround for the double Gondolin * problem. */ -static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_stores, wilderness_type_info *place, int store) +static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_stores, wilderness_type_info const *place, int store) { town_type *town = &town_info[place->entrance]; store_type *st_ptr = &town->store[store]; @@ -2547,7 +2556,11 @@ static bool_ file_character_check_stores(std::unordered_set<store_type *> *seen_ */ errr file_character(cptr name, bool_ full) { - int i, j, x, y; + auto const &d_info = game->edit_data.d_info; + auto const &wf_info = game->edit_data.wf_info; + auto const &r_info = game->edit_data.r_info; + + int i, x, y; byte a; char c; int fd = -1; @@ -2566,10 +2579,10 @@ errr file_character(cptr name, bool_ full) char out_val[160]; /* Close the file */ - (void)fd_close(fd); + fd_close(fd); /* Build query */ - (void)sprintf(out_val, "Replace existing file %s? ", buf); + sprintf(out_val, "Replace existing file %s? ", buf); /* Ask */ if (get_check(out_val)) fd = -1; @@ -2604,7 +2617,7 @@ errr file_character(cptr name, bool_ full) for (x = 0; x < 79; x++) { /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; @@ -2627,7 +2640,7 @@ errr file_character(cptr name, bool_ full) for (x = 0; x < 79; x++) { /* Get the attr/char */ - (void)(Term_what(x, y, &a, &c)); + (Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; @@ -2642,52 +2655,52 @@ errr file_character(cptr name, bool_ full) /* List the patches */ fprintf(fff, "\n\n [Miscellaneous information]\n"); - if (joke_monsters) + if (options->joke_monsters) fprintf(fff, "\n Joke monsters: ON"); else fprintf(fff, "\n Joke monsters: OFF"); - if (p_ptr->preserve) + if (options->preserve) fprintf(fff, "\n Preserve Mode: ON"); else fprintf(fff, "\n Preserve Mode: OFF"); - if (auto_scum) + if (options->auto_scum) fprintf(fff, "\n Autoscum: ON"); else fprintf(fff, "\n Autoscum: OFF"); - if (always_small_level) + if (options->always_small_level) fprintf(fff, "\n Small Levels: ALWAYS"); - else if (small_levels) + else if (options->small_levels) fprintf(fff, "\n Small Levels: ON"); else fprintf(fff, "\n Small Levels: OFF"); - if (empty_levels) + if (options->empty_levels) fprintf(fff, "\n Arena Levels: ON"); else fprintf(fff, "\n Arena Levels: OFF"); - if (ironman_rooms) + if (options->ironman_rooms) fprintf(fff, "\n Always unusual rooms: ON"); else fprintf(fff, "\n Always unusual rooms: OFF"); fprintf(fff, "\n\n Recall Depth:"); - for (y = 1; y < max_d_idx; y++) + for (y = 1; y < static_cast<int>(d_info.size()); y++) { if (max_dlv[y]) - fprintf(fff, "\n %s: Level %d (%d')", - d_info[y].name, - max_dlv[y], 50 * (max_dlv[y])); + fprintf(fff, "\n %s: Level %d", + d_info[y].name.c_str(), + max_dlv[y]); } fprintf(fff, "\n"); if (noscore) fprintf(fff, "\n You have done something illegal."); - if (race_flags1_p(PR1_EXPERIMENTAL)) + if (race_flags_p(PR_EXPERIMENTAL)) fprintf(fff, "\n You have done something experimental."); { @@ -2705,18 +2718,20 @@ errr file_character(cptr name, bool_ full) } /* Where we are, if we're alive */ - if (!death) fprintf(fff, "\n You are currently %s.", describe_player_location()); + if (!death) + { + fprintf(fff, "\n You are currently %s.", describe_player_location().c_str()); + } /* Monsters slain */ { - int k; s32b Total = 0; - for (k = 1; k < max_r_idx; k++) + for (auto const &r_ref: r_info) { - monster_race *r_ptr = &r_info[k]; + auto r_ptr = &r_ref; - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { bool_ dead = (r_ptr->max_num == 0); if (dead) @@ -2755,33 +2770,24 @@ errr file_character(cptr name, bool_ full) fprintf (fff, "\n\n"); - /* Emit the self-knowledge lines, even though they duplicate the - information in the grids (below), because they contain information - that's not in the grids (racial abilities, luck, etc.). */ - if (full) - { - self_knowledge(fff); - fprintf(fff, "\n\n"); - } - /* adds and slays */ - display_player (2); + display_player(1); file_character_print_grid(fff, FALSE, TRUE); /* sustains and resistances */ - display_player (3); + display_player(2); file_character_print_grid(fff, TRUE, FALSE); /* stuff */ - display_player (4); + display_player(3); file_character_print_grid(fff, FALSE, FALSE); /* a little bit of stuff */ - display_player (5); + display_player(4); file_character_print_grid(fff, FALSE, FALSE); /* Dump corruptions */ - dump_corruptions(fff, FALSE, TRUE); + fprintf(fff, "\n%s\n", dump_corruptions(false, true).c_str()); /* Dump skills */ dump_skills(fff); @@ -2803,7 +2809,7 @@ errr file_character(cptr name, bool_ full) if ((fates[i].fate) && (fates[i].know)) { fprintf(fff, "\n\n [Fates]\n\n"); - dump_fates(fff); + fprintf(fff, "%s", dump_fates().c_str()); break; } } @@ -2837,12 +2843,12 @@ errr file_character(cptr name, bool_ full) /* Print all homes in the different towns */ { std::unordered_set<store_type *> seen_stores; - for (j = 0; j < max_wf_idx; j++) + for (auto const &wf_ref: wf_info) { - if (wf_info[j].feat == FEAT_TOWN && - file_character_check_stores(&seen_stores, &wf_info[j], 7)) + if (wf_ref.feat == FEAT_TOWN && + file_character_check_stores(&seen_stores, &wf_ref, 7)) { - file_character_print_store(fff, &wf_info[j], 7, full); + file_character_print_store(fff, &wf_ref, 7, full); } } } @@ -2850,12 +2856,12 @@ errr file_character(cptr name, bool_ full) /* Print all Mathom-houses in the different towns */ { std::unordered_set<store_type *> seen_stores; - for (j = 0; j < max_wf_idx; j++) + for (auto const &wf_ref: wf_info) { - if (wf_info[j].feat == FEAT_TOWN && - file_character_check_stores(&seen_stores, &wf_info[j], 57)) + if (wf_ref.feat == FEAT_TOWN && + file_character_check_stores(&seen_stores, &wf_ref, 57)) { - file_character_print_store(fff, &wf_info[j], 57, full); + file_character_print_store(fff, &wf_ref, 57, full); } } } @@ -2917,7 +2923,7 @@ struct hyperlink typedef struct hyperlink hyperlink_type; -bool_ show_file(cptr name, cptr what, int line, int mode) +static bool_ show_file_aux(cptr name, cptr what, int line) { int i, k, x; @@ -3375,7 +3381,7 @@ bool_ show_file(cptr name, cptr what, int line, int mode) { /* Get "h_ptr->shower" */ prt("Show: ", hgt - 1, 0); - (void)askfor_aux(h_ptr->shower, 80); + askfor_aux(h_ptr->shower, 80); } /* Hack -- try finding */ @@ -3415,7 +3421,7 @@ bool_ show_file(cptr name, cptr what, int line, int mode) strcpy(tmp, "help.hlp"); if (askfor_aux(tmp, 80)) { - if (!show_file(tmp, NULL, 0, mode)) k = ESCAPE; + if (!show_file_aux(tmp, NULL, 0)) k = ESCAPE; } } @@ -3469,7 +3475,7 @@ bool_ show_file(cptr name, cptr what, int line, int mode) if (h_ptr->link_x[cur_link] != -1) { /* Recurse on that file */ - if (!show_file(h_ptr->link[cur_link], NULL, h_ptr->link_line[cur_link], mode)) k = ESCAPE; + if (!show_file_aux(h_ptr->link[cur_link], NULL, h_ptr->link_line[cur_link])) k = ESCAPE; } } @@ -3482,7 +3488,7 @@ bool_ show_file(cptr name, cptr what, int line, int mode) if (h_ptr->link_key[i] == k) { /* Recurse on that file */ - if (!show_file(h_ptr->link[i], NULL, h_ptr->link_line[i], mode)) k = ESCAPE; + if (!show_file_aux(h_ptr->link[i], NULL, h_ptr->link_line[i])) k = ESCAPE; break; } } @@ -3498,316 +3504,27 @@ bool_ show_file(cptr name, cptr what, int line, int mode) return (TRUE); } -bool_ txt_to_html(cptr head, cptr foot, cptr base, cptr ext, bool_ force, bool_ recur) +void show_string(const char *lines, const char *title, int line) { - int i, x; - - /* Number of "real" lines passed by */ - int next = 0; - - char buf_name[80]; + // Temporary file + auto const file_name = boost::filesystem::unique_path().string(); - /* Color of the next line */ - byte color = TERM_WHITE; - - /* Current help file */ - FILE *fff = NULL; + // Open a new file + std::ofstream ofs(file_name); + ofs.exceptions(std::ofstream::failbit); + ofs << lines; + ofs.close(); - /* Current aux file */ - FILE *aux = NULL; - - /* Current html file */ - FILE *htm = NULL; - - cptr file_ext = "html"; - cptr link_prefix = ""; - cptr link_suffix = ""; - - /* Pointer to general buffer in the above */ - char *buf; - - /* Allocate hyperlink data */ - std::unique_ptr<hyperlink_type> h_ptr(new hyperlink_type); - memset(h_ptr.get(), 0, sizeof(hyperlink_type)); + // Display the file contents + show_file_aux(file_name.c_str(), title, line); - /* Setup buffer pointer */ - buf = h_ptr->rbuf; - - /* Wipe the links */ - for (i = 0; i < MAX_LINKS; i++) - { - h_ptr->link_x[i] = -1; - } - - sprintf(buf_name, "%s.%s", base, file_ext); - - if ((!force) && file_exist(buf_name)) return FALSE; - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, buf_name); - - /* Open the file */ - htm = my_fopen(h_ptr->path, "w"); - - sprintf(buf_name, "%s.%s", base, ext); - - /* h_ptr->caption */ - sprintf(h_ptr->caption, "Help file '%s'", buf_name); - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, buf_name); - - /* Open the file */ - fff = my_fopen(h_ptr->path, "r"); - - /* Oops */ - if (!fff || !htm) - { - my_fclose(fff); - my_fclose(htm); - - /* Oops */ - return (TRUE); - } - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, head); - - /* Open the file */ - aux = my_fopen(h_ptr->path, "r"); - - /* Copy the header */ - if (aux) - { - while (TRUE) - { - char *find; - - if (my_fgets(aux, h_ptr->rbuf, 1024)) break; - find = strstr(h_ptr->rbuf, "%t"); - if (find != NULL) - { - *find = '\0'; - find += 2; - fprintf(htm, "%s", h_ptr->rbuf); - fprintf(htm, "%s", base); - fprintf(htm, "%s\n", find); - } - else - fprintf(htm, "%s\n", h_ptr->rbuf); - } - my_fclose(aux); - } - - /* Display the file */ - while (TRUE) - { - bool_ do_color = FALSE; - - /* Skip a line */ - if (my_fgets(fff, h_ptr->rbuf, 1024)) break; - - color = TERM_WHITE; - - { - int print_x; - - /* Get a color */ - if (prefix(h_ptr->rbuf, "#####")) - { - color = color_char_to_attr(h_ptr->rbuf[5]); - do_color = TRUE; - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - buf = &h_ptr->rbuf[6]; - } - else buf = h_ptr->rbuf; - - /* Count the "real" lines */ - next++; - - /* Skip link colors */ - if (prefix(buf, "|||||")) continue; - - /* Skip tags */ - if (prefix(buf, "~~~~~")) - { - int i; - - for (i = 5; (buf[i] >= '0') && (buf[i] <= '9'); i++) - ; - buf[i] = '\0'; - fprintf(htm, "<A NAME=\"%s\"></A>", buf + 5); - continue; - } - - /* Dump the line */ - print_x = 0; - if (!prefix(buf, "&&&&&")) - { - x = 0; - while (buf[x]) - { - /* Hyperlink ? */ - if (prefix(buf + x, "*****")) - { - int xx = x + 5, z = 0; - char buff[80]; - char link_line[80], *s; - - if (buf[xx] == '/') xx += 2; - - /* Zap the link info */ - while (buf[xx] != '*') - { - buff[z++] = buf[xx]; - xx++; - } - xx++; - buff[z] = '\0'; - - /* Zap the link info */ - z = 0; - while (buf[xx] != '[') - { - link_line[z++] = buf[xx]; - xx++; - } - xx++; - link_line[z] = '\0'; - - /* parse it */ - s = buff; - while (*s != '.') s++; - *s = '\0'; - s++; - if (recur) txt_to_html(head, foot, buff, s, FALSE, recur); - - if (atoi(link_line)) fprintf(htm, "<A HREF=\"%s%s.%s%s#%d\">", link_prefix, buff, file_ext, link_suffix, atoi(link_line)); - else fprintf(htm, "<A HREF=\"%s%s.%s%s\">", link_prefix, buff, file_ext, link_suffix); - - /* Ok print the link name */ - while (buf[xx] != ']') - { - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - fprintf(htm, "%c", buf[xx]); - xx++; - print_x++; - } - x = xx; - - fprintf(htm, "</A>"); - } - /* Color ? */ - else if (prefix(buf + x, "[[[[[")) - { - int xx = x + 6; - - color = color_char_to_attr(buf[x + 5]); - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - - /* Ok print the link name */ - while (buf[xx] != ']') - { - /* Now we treat the next char as printable */ - if (buf[xx] == '\\') - xx++; - fprintf(htm, "%c", buf[xx]); - xx++; - print_x++; - } - x++; - x = xx; - - fprintf(htm, "</FONT>"); - } - /* Hidden HTML tag? */ - else if (prefix(buf + x, "{{{{{")) - { - int xx = x + 5; - - /* Ok output the tag inside */ - while (buf[xx] != '}') - { - fprintf(htm, "%c", buf[xx]); - xx++; - } - x++; - x = xx; - } - else - { - fprintf(htm, "%c", buf[x]); - print_x++; - } - - x++; - } - } - /* Verbatim mode: i.e: acacacac */ - else - { - byte old_color; - - x = 5; - old_color = color_char_to_attr(buf[x]); - fprintf(htm, "<FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - while (buf[x]) - { - color = color_char_to_attr(buf[x]); - if (color != old_color) - fprintf(htm, "</FONT><FONT COLOR=\"#%02X%02X%02X\">", - angband_color_table[color][1], - angband_color_table[color][2], - angband_color_table[color][3]); - - fprintf(htm, "%c", buf[x + 1]); - print_x++; - x += 2; - } - fprintf(htm, "</FONT>"); - } - } - if (do_color) - { - fprintf(htm, "</FONT>"); - } - fprintf(htm, "\n"); - } - - /* Build the filename */ - path_build(h_ptr->path, 1024, ANGBAND_DIR_HELP, foot); - - /* Open the file */ - aux = my_fopen(h_ptr->path, "r"); - - /* Copy the footer */ - if (aux) - { - while (TRUE) - { - if (my_fgets(aux, h_ptr->rbuf, 1024)) break; - fprintf(htm, "%s\n", h_ptr->rbuf); - } - my_fclose(aux); - } - - /* Close the file */ - my_fclose(htm); - my_fclose(fff); + // Remove the file + fd_kill(file_name.c_str()); +} - /* Normal return */ - return (TRUE); +void show_file(cptr name, cptr what, int line) +{ + show_file_aux(name, what, line); } static void cmovie_clean_line(int y, char *abuf, char *cbuf) @@ -4001,13 +3718,13 @@ void html_screenshot(cptr name) /* * Peruse the On-Line-Help */ -void do_cmd_help(void) +void do_cmd_help() { /* Save screen */ screen_save(); /* Peruse the main help file */ - (void)show_file("help.hlp", NULL, 0, 0); + show_file("help.hlp", NULL); /* Load screen */ screen_load(); @@ -4016,72 +3733,53 @@ void do_cmd_help(void) -/* - * Process the player name. - * Extract a clean "base name". - * Build the savefile name if needed. - */ void process_player_base() { - char temp[128]; - - /* Rename the savefile, using the player_base */ - (void)sprintf(temp, "%s", player_base); - - /* Build the filename */ - path_build(savefile, 1024, ANGBAND_DIR_SAVE, temp); + path_build(savefile, 1024, ANGBAND_DIR_SAVE, game->player_base.c_str()); } void process_player_name(bool_ sf) { - int i, k = 0; - char tmp[50]; - /* Cannot be too long */ - if (strlen(player_base) > 15) + if (game->player_base.size() > 15) { - /* Name too long */ - quit_fmt("The name '%s' is too long!", player_base); + quit_fmt("The name '%s' is too long!", game->player_base.c_str()); } - /* Cannot contain "icky" characters */ - for (i = 0; player_base[i]; i++) + /* Cannot contain control characters */ + for (auto c : game->player_base) { - /* No control characters */ - if (iscntrl(player_base[i])) + if (iscntrl(c)) { - /* Illegal characters */ - quit_fmt("The name '%s' contains control chars!", player_base); + quit_fmt("The name '%s' contains control chars!", game->player_base.c_str()); } } /* Extract "useful" letters */ - for (i = 0; player_base[i]; i++) + std::string buf; + for (auto c : game->player_base) { - char c = player_base[i]; - /* Accept some letters */ - if (isalpha(c) || isdigit(c)) tmp[k++] = c; + if (isalpha(c) || isdigit(c)) + { + buf += c; + } /* Convert space, dot, and underscore to underscore */ - else if (strchr("@. _", c)) tmp[k++] = '_'; + else if (strchr("@. _", c)) + { + buf += '_'; + } } - -#if defined(WINDOWS) - - /* Hack -- max length */ - if (k > 8) k = 8; - -#endif - /* Terminate */ - tmp[k] = '\0'; - sprintf(player_base, "%s", tmp); + game->player_base = buf; /* Require a "base" name */ - if (!player_base[0]) strcpy(player_base, "PLAYER"); - + if (game->player_base.empty()) + { + game->player_base = "PLAYER"; + } /* Change the savefile name */ if (sf) @@ -4101,7 +3799,7 @@ void process_player_name(bool_ sf) * * What a horrible name for a global function. XXX XXX XXX */ -void get_name(void) +void get_name() { char tmp[32]; @@ -4118,10 +3816,13 @@ void get_name(void) move_cursor(2, 9); /* Save the player name */ - strcpy(tmp, player_name); + strcpy(tmp, game->player_name.c_str()); /* Get an input, ignore "Escape" */ - if (askfor_aux(tmp, 31)) strcpy(player_name, tmp); + if (askfor_aux(tmp, 31)) + { + game->player_name = tmp; + } /* Process the player name */ process_player_name(FALSE); @@ -4131,7 +3832,7 @@ void get_name(void) } /* Pad the name (to clear junk) */ - sprintf(tmp, "%-31.31s", player_name); + sprintf(tmp, "%-31.31s", game->player_name.c_str()); /* Re-Draw the name (in light blue) */ c_put_str(TERM_L_BLUE, tmp, 2, 9); @@ -4145,7 +3846,7 @@ void get_name(void) /* * Hack -- commit suicide */ -void do_cmd_suicide(void) +void do_cmd_suicide() { int i; @@ -4186,7 +3887,7 @@ void do_cmd_suicide(void) p_ptr->leaving = TRUE; /* Cause of death */ - (void)strcpy(died_from, "Quitting"); + game->died_from = "Quitting"; } @@ -4222,7 +3923,7 @@ void remove_cave_view(bool_ remove) /* * Save the game */ -void do_cmd_save_game(void) +void do_cmd_save_game() { remove_cave_view(TRUE); @@ -4233,7 +3934,7 @@ void do_cmd_save_game(void) if (!is_autosave) { /* Disturb the player */ - disturb(1); + disturb(); } /* Clear messages */ @@ -4249,7 +3950,7 @@ void do_cmd_save_game(void) Term_fresh(); /* The player is not dead */ - (void)strcpy(died_from, "(saved)"); + game->died_from = "(saved)"; /* Save the player */ if (save_player()) @@ -4269,7 +3970,7 @@ void do_cmd_save_game(void) Term_fresh(); /* Note that the player is not dead */ - (void)strcpy(died_from, "(alive and well)"); + game->died_from = "(alive and well)"; } /* @@ -4277,7 +3978,7 @@ void do_cmd_save_game(void) */ void autosave_checkpoint() { - if (autosave_l) + if (options->autosave_l) { is_autosave = TRUE; msg_print("Autosaving the game..."); @@ -4289,28 +3990,36 @@ void autosave_checkpoint() /* * Hack -- Calculates the total number of points earned -JWT- */ -static long total_points(void) +static long total_points() { - s16b max_dl = 0, i, k; + auto const &d_info = game->edit_data.d_info; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + + s16b max_dl = 0; long temp, Total = 0; long mult = 20; /* was 100. Divided values by 5 because of an overflow error */ long comp_death = (p_ptr->companion_killed * 2 / 5); if (!comp_death) comp_death = 1; - if (p_ptr->preserve) mult -= 1; /* Penalize preserve, maximize modes */ + if (options->preserve) mult -= 1; /* Penalize preserve, maximize modes */ mult -= 1; /* maximize pentalty, always on */ - if (auto_scum) mult -= 4; - if (small_levels) mult += ((always_small_level) ? 4 : 10); - if (empty_levels) mult += 2; - if (smart_learn) mult += 4; + if (options->auto_scum) mult -= 4; + if (options->small_levels) mult += ((options->always_small_level) ? 4 : 10); + if (options->empty_levels) mult += 2; + if (options->smart_learn) mult += 4; if (mult < 2) mult = 2; /* At least 10% of the original score */ /* mult is now between 2 and 40, i.e. 10% and 200% */ - for (i = 0; i < max_d_idx; i++) + for (std::size_t i = 0; i < d_info.size(); i++) + { if (max_dlv[i] > max_dl) + { max_dl = max_dlv[i]; + } + } temp = p_ptr->lev * p_ptr->lev * p_ptr->lev * p_ptr->lev + (100 * max_dl); @@ -4322,7 +4031,7 @@ static long total_points(void) temp += p_ptr->au / 5; /* Completing quest increase score */ - for (i = 0; i < MAX_Q_IDX; i++) + for (std::size_t i = 0; i < MAX_Q_IDX; i++) { if (quest[i].status >= QUEST_STATUS_COMPLETED) { @@ -4334,14 +4043,13 @@ static long total_points(void) /* Death of a companion is BAD */ temp /= comp_death; - /* The know objects increase the score */ - /* Scan the object kinds */ - for (k = 1; k < max_k_idx; k++) + /* The known objects increase the score */ + for (std::size_t k = 1; k < k_info.size(); k++) { - object_kind *k_ptr = &k_info[k]; + auto k_ptr = &k_info[k]; /* Hack -- skip artifacts */ - if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; + if (k_ptr->flags & TR_INSTA_ART) continue; /* List known flavored objects */ if (k_ptr->flavor && k_ptr->aware) @@ -4359,11 +4067,11 @@ static long total_points(void) } } - for (k = 1; k < max_r_idx; k++) + for (auto const &r_ref: r_info) { - monster_race *r_ptr = &r_info[k]; + auto r_ptr = &r_ref; - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { bool_ dead = (r_ptr->max_num == 0); @@ -4393,50 +4101,26 @@ static long total_points(void) } - -/* - * Centers a string within a 31 character string -JWT- - */ -static void center_string(char *buf, cptr str) -{ - int i, j; - - /* Total length */ - i = strlen(str); - - /* Necessary border */ - j = 15 - i / 2; - - /* Mega-Hack */ - (void)sprintf(buf, "%*s%s%*s", j, "", str, 31 - i - j, ""); -} - - /* * Display a "tomb-stone" */ -static void print_tomb(void) +static void print_tomb() { - cptr p; - - char tmp[160]; - - char buf[1024]; - char dummy[80]; - - FILE *fp; - time_t ct = time(nullptr); + auto center = [](std::string const &s) -> std::string { + return fmt::format("{:^31s}", s); + }; /* Clear screen */ Term_clear(); /* Build the filename */ + char buf[1024]; path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt"); /* Open the News file */ - fp = my_fopen(buf, "r"); + FILE *fp = my_fopen(buf, "r"); /* Dump */ if (fp) @@ -4454,81 +4138,38 @@ static void print_tomb(void) my_fclose(fp); } - - /* King or Queen */ + std::string p_title; if (total_winner || (p_ptr->lev > PY_MAX_LEVEL)) { - p = "Magnificent"; + p_title = "Magnificent"; } - - /* Normal */ else { - p = cp_ptr->titles[(p_ptr->lev - 1) / 5]; - } - - center_string(buf, player_name); - put_str(buf, 6, 11); - - center_string(buf, "the"); - put_str(buf, 7, 11); - - center_string(buf, p); - put_str(buf, 8, 11); - - - center_string(buf, spp_ptr->title); - put_str(buf, 10, 11); - - (void)sprintf(tmp, "Level: %d", (int)p_ptr->lev); - center_string(buf, tmp); - put_str(buf, 11, 11); - - (void)sprintf(tmp, "Exp: %ld", (long)p_ptr->exp); - center_string(buf, tmp); - put_str(buf, 12, 11); - - (void)sprintf(tmp, "AU: %ld", (long)p_ptr->au); - center_string(buf, tmp); - put_str(buf, 13, 11); - - (void)sprintf(tmp, "Killed on Level %d", dun_level); - center_string(buf, tmp); - put_str(buf, 14, 11); - - - if (strlen(died_from) > 24) - { - strncpy(dummy, died_from, 24); - dummy[24] = '\0'; - (void)sprintf(tmp, "by %s.", dummy); + p_title = cp_ptr->titles[(p_ptr->lev - 1) / 5]; } - else - (void)sprintf(tmp, "by %s.", died_from); - center_string(buf, tmp); - put_str(buf, 15, 11); - - - (void)sprintf(tmp, "%-.24s", ctime(&ct)); - center_string(buf, tmp); - put_str(buf, 17, 11); + put_str(center(game->player_name), 6, 11); + put_str(center("the"), 7, 11); + put_str(center(p_title), 8, 11); + put_str(center(spp_ptr->title), 10, 11); + put_str(center(fmt::format("Level: {}", p_ptr->lev)), 11, 11); + put_str(center(fmt::format("Exp: {}", p_ptr->exp)), 12, 11); + put_str(center(fmt::format("AU: {}", p_ptr->au)), 13, 11); + put_str(center(fmt::format("Killed on Level {}", dun_level)), 14, 11); + put_str(center(fmt::format("by {}.", game->died_from.substr(0, 24))), 15, 11); + put_str(center(std::string(ctime(&ct)).substr(0, 24)), 17, 11); } /* * Display some character info */ -static void show_info(void) +static void show_info() { - int i, j, k; - object_type *o_ptr; - store_type *st_ptr; - /* Hack -- Know everything in the inven/equip */ - for (i = 0; i < INVEN_TOTAL; i++) + for (auto &o_ref: p_ptr->inventory) { - o_ptr = &p_ptr->inventory[i]; + auto o_ptr = &o_ref; /* Skip non-objects */ if (!o_ptr->k_idx) continue; @@ -4538,14 +4179,13 @@ static void show_info(void) object_known(o_ptr); } - for (i = 1; i < max_towns; i++) + /* Hack -- Know everything in the home */ + for (int i = 1; i < max_towns; i++) { - st_ptr = &town_info[i].store[7]; - - /* Hack -- Know everything in the home */ - for (j = 0; j < st_ptr->stock_num; j++) + auto st_ptr = &town_info[i].store[7]; + for (auto &o_ref: st_ptr->stock) { - o_ptr = &st_ptr->stock[j]; + auto o_ptr = &o_ref; /* Skip non-objects */ if (!o_ptr->k_idx) continue; @@ -4595,7 +4235,7 @@ static void show_info(void) Term_save(); /* Dump a character file */ - (void)file_character(out_val, TRUE); + file_character(out_val, TRUE); /* Load screen */ Term_load(); @@ -4634,27 +4274,28 @@ static void show_info(void) } /* Homes in the different towns */ - for (k = 1; k < max_towns; k++) + for (int k = 1; k < max_towns; k++) { - st_ptr = &town_info[k].store[7]; + store_type *st_ptr = &town_info[k].store[7]; /* Home -- if anything there */ - if (st_ptr->stock_num) + if (!st_ptr->stock.empty()) { + std::size_t i; /* Display contents of the home */ - for (k = 0, i = 0; i < st_ptr->stock_num; k++) + for (k = 0, i = 0; i < st_ptr->stock.size(); k++) { /* Clear screen */ Term_clear(); /* Show 12 items */ - for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++) + for (int j = 0; (j < 12) && (i < st_ptr->stock.size()); j++, i++) { char o_name[80]; char tmp_val[80]; /* Acquire item */ - o_ptr = &st_ptr->stock[i]; + auto o_ptr = &st_ptr->stock[i]; /* Print header, clear line */ sprintf(tmp_val, "%c) ", I2A(j)); @@ -4688,6 +4329,8 @@ static void show_info(void) */ static void display_scores_aux(int highscore_fd, int from, int to, int note, high_score *score) { + auto const &class_info = game->edit_data.class_info; + int i, j, k, n, place; byte attr; char out_val[256]; @@ -4788,11 +4431,12 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig for (aged = the_score.turns; isspace(*aged); aged++) /* loop */; /* Dump some info */ + auto const player_race_name = get_player_race_name(pr, ps); sprintf(out_val, "%3d.%9s %s the %s %s, Level %d", place, the_score.pts, the_score.who, - get_player_race_name(pr, ps), + player_race_name.c_str(), class_info[pc].spec[pcs].title, clev); @@ -4851,11 +4495,12 @@ static void display_scores_aux(int highscore_fd, int from, int to, int note, hig */ void show_highclass(int building) { + auto const &race_info = game->edit_data.race_info; int i = 0, j, m = 0; int pr, pc, clev; high_score the_score; - char buf[1024], out_val[256]; + char buf[1024]; int highscore_fd; switch (building) @@ -4914,6 +4559,9 @@ void show_highclass(int building) j = 0; clev = 0; + auto const format_num = "{:>3d}) {} the {} (Level {:>2d})"; // See also race_score() + auto const format_you = "You) {} the {} (Level {:>2d})"; + while ((m < 9) || (j < MAX_HISCORES)) { if (highscore_seek(highscore_fd, j)) break; @@ -4924,9 +4572,9 @@ void show_highclass(int building) if (((pc == (building - 10)) && (building != 1)) || ((building == 1) && (clev >= PY_MAX_LEVEL))) { - sprintf(out_val, "%3d) %s the %s (Level %2d)", + auto out_val = fmt::format(format_num, (m + 1), the_score.who, race_info[pr].title, clev); - prt(out_val, (m + 7), 0); + prt(out_val.c_str(), (m + 7), 0); m++; } j++; @@ -4935,17 +4583,21 @@ void show_highclass(int building) /* Now, list the active player if they qualify */ if ((building == 1) && (p_ptr->lev >= PY_MAX_LEVEL)) { - sprintf(out_val, "You) %s the %s (Level %2d)", - player_name, race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); + auto out_val = fmt::format(format_you, + game->player_name, + race_info[p_ptr->prace].title, + p_ptr->lev); + prt(out_val.c_str(), (m + 8), 0); } else if ((building != 1)) { if ((p_ptr->lev > clev) && (p_ptr->pclass == (building - 10))) { - sprintf(out_val, "You) %s the %s (Level %2d)", - player_name, race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); + auto out_val = fmt::format(format_you, + game->player_name, + race_info[p_ptr->prace].title, + p_ptr->lev); + prt(out_val.c_str(), (m + 8), 0); } } @@ -4964,16 +4616,18 @@ void show_highclass(int building) */ void race_score(int race_num) { + auto const &race_info = game->edit_data.race_info; + int i = 0, j, m = 0; int pr, clev, lastlev; high_score the_score; - char buf[1024], out_val[256], tmp_str[80]; + char buf[1024], tmp_str[80]; int highscore_fd; lastlev = 0; /* rr9: TODO - pluralize the race */ - sprintf(tmp_str, "The Greatest of all the %s", race_info[race_num].title); + sprintf(tmp_str, "The Greatest of all the %s", race_info[race_num].title.c_str()); prt(tmp_str, 5, 3); /* Build the filename */ @@ -4999,6 +4653,9 @@ void race_score(int race_num) m = 0; j = 0; + auto const format_num = "{:>3d}) {} the {} (Level {:>2d})"; // See also show_highclass() + auto const format_you = "You) {} the {} (Level {:>2d})"; + while ((m < 10) && (j < i)) { if (highscore_seek(highscore_fd, j)) break; @@ -5007,10 +4664,12 @@ void race_score(int race_num) clev = atoi(the_score.cur_lev); if (pr == race_num) { - sprintf(out_val, "%3d) %s the %s (Level %3d)", - (m + 1), the_score.who, - race_info[pr].title, clev); - prt(out_val, (m + 7), 0); + auto out_val = fmt::format(format_num, + (m + 1), + the_score.who, + race_info[pr].title, + clev); + prt(out_val.c_str(), (m + 7), 0); m++; lastlev = clev; } @@ -5020,9 +4679,11 @@ void race_score(int race_num) /* add player if qualified */ if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev)) { - sprintf(out_val, "You) %s the %s (Level %3d)", - player_name, race_info[p_ptr->prace].title, p_ptr->lev); - prt(out_val, (m + 8), 0); + auto out_val = fmt::format(format_you, + game->player_name, + race_info[p_ptr->prace].title, + p_ptr->lev); + prt(out_val.c_str(), (m + 8), 0); } fd_close(highscore_fd); @@ -5033,17 +4694,19 @@ void race_score(int race_num) * Race Legends * -KMW- */ -void race_legends(void) +void race_legends() { - int i, j; + auto const &race_info = game->edit_data.race_info; - for (i = 0; i < max_rp_idx; i++) + for (size_t i = 0; i < race_info.size(); i++) { race_score(i); msg_print("Hit any key to continue"); msg_print(NULL); - for (j = 5; j < 19; j++) + for (int j = 5; j < 19; j++) + { prt("", j, 0); + } } } @@ -5054,7 +4717,7 @@ void race_legends(void) * Enters a players name on a hi-score table, if "legal", and in any * case, displays some relevant portion of the high score list. */ -static errr top_twenty(void) +static errr top_twenty() { int j; @@ -5091,15 +4754,6 @@ static errr top_twenty(void) goto out; } - /* Borg-mode pre-empts scoring */ - if (noscore & 0x00F0) - { - msg_print("Score not registered for borgs."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - /* Cheaters are not scored */ if (noscore & 0xFF00) { @@ -5109,17 +4763,8 @@ static errr top_twenty(void) goto out; } - /* Interupted */ - if (!total_winner && streq(died_from, "Interrupting")) - { - msg_print("Score not registered due to interruption."); - msg_print(NULL); - display_scores_aux(highscore_fd, 0, 10, -1, NULL); - goto out; - } - /* Quitter */ - if (!total_winner && streq(died_from, "Quitting")) + if (!total_winner && (game->died_from == "Quitting")) { msg_print("Score not registered due to quitting."); msg_print(NULL); @@ -5153,10 +4798,9 @@ static errr top_twenty(void) strftime(the_score.day, 9, "%m/%d/%y", localtime(&ct)); /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", player_name); + sprintf(the_score.who, "%-.15s", game->player_name.c_str()); /* Save the player info XXX XXX XXX */ - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); sprintf(the_score.p_r, "%2d", p_ptr->prace); sprintf(the_score.p_s, "%2d", p_ptr->pracem); sprintf(the_score.p_c, "%2d", p_ptr->pclass); @@ -5171,7 +4815,7 @@ static errr top_twenty(void) sprintf(the_score.inside_quest, "%3d", p_ptr->inside_quest); /* Save the cause of death (31 chars) */ - sprintf(the_score.how, "%-.31s", died_from); + sprintf(the_score.how, "%-.31s", game->died_from.c_str()); /* Add a new entry to the score list, see where it went */ @@ -5206,7 +4850,7 @@ out: /* * Predict the players location, and display it. */ -static errr predict_score(void) +static errr predict_score() { int j; @@ -5254,10 +4898,9 @@ static errr predict_score(void) strcpy(the_score.day, "TODAY"); /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", player_name); + sprintf(the_score.who, "%-.15s", game->player_name.c_str()); /* Save the player info XXX XXX XXX */ - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); sprintf(the_score.p_r, "%2d", p_ptr->prace); sprintf(the_score.p_s, "%2d", p_ptr->pracem); sprintf(the_score.p_c, "%2d", p_ptr->pclass); @@ -5346,7 +4989,7 @@ void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p) } /* Close the high score file */ - (void)fd_close(highscore_fd); + fd_close(highscore_fd); /* Forget the fd */ highscore_fd = -1; @@ -5365,13 +5008,13 @@ void predict_score_gui(bool_ *initialized_p, bool_ *game_in_progress_p) /* * Change the player into a King! -RAK- */ -static void kingly(void) +static void kingly() { /* Hack -- retire in town */ dun_level = 0; /* Fake death */ - (void)strcpy(died_from, "Ripe Old Age"); + game->died_from = "Ripe Old Age"; /* Restore the experience */ p_ptr->exp = p_ptr->max_exp; @@ -5404,7 +5047,7 @@ static void kingly(void) /* Display a message */ put_str("Veni, Vidi, Vici!", 15, 26); put_str("I came, I saw, I conquered!", 16, 21); - put_str(format("All Hail the Mighty %s!", sp_ptr->winner), 17, 22); + put_str(format("All Hail the Mighty %s!", game->player_name.c_str()), 17, 22); /* Flush input */ flush(); @@ -5419,13 +5062,16 @@ static void kingly(void) */ void wipe_saved() { - int d, l, od = dungeon_type, ol = dun_level; + auto const &d_info = game->edit_data.d_info; + + int od = dungeon_type; + int ol = dun_level; - for (d = 0; d < max_d_idx; d++) + for (std::size_t d = 0; d < d_info.size(); d++) { - dungeon_info_type *d_ptr = &d_info[d]; + auto d_ptr = &d_info[d]; - for (l = d_ptr->mindepth; l <= d_ptr->maxdepth; l++) + for (auto l = d_ptr->mindepth; l <= d_ptr->maxdepth; l++) { char buf[10]; @@ -5433,10 +5079,10 @@ void wipe_saved() dungeon_type = d; if (get_dungeon_save(buf)) { - char tmp[80], name[1024]; + auto tmp = fmt::format("{}.{}", game->player_base, buf); - sprintf(tmp, "%s.%s", player_base, buf); - path_build(name, 1024, ANGBAND_DIR_SAVE, tmp); + char name[1024]; + path_build(name, 1024, ANGBAND_DIR_SAVE, tmp.c_str()); /* Remove the dungeon save file */ fd_kill(name); @@ -5454,7 +5100,7 @@ void wipe_saved() * * This function is called only from "main.c" and "signals.c". */ -void close_game(void) +void close_game() { /* Handle stuff */ handle_stuff(); @@ -5497,7 +5143,6 @@ void close_game(void) /* Make a note */ { char long_day[30]; - char buf[80]; time_t ct = time((time_t*)NULL); /* Get the date */ @@ -5505,11 +5150,13 @@ void close_game(void) "%Y-%m-%d at %H:%M:%S", localtime(&ct)); /* Create string */ - sprintf(buf, "\n%s was killed by %s on %s\n", player_name, - died_from, long_day); + auto buf = fmt::format("\n{} was killed by {} on {}\n", + game->player_name, + game->died_from, + long_day); /* Output to the notes file */ - output_note(buf); + output_note(buf.c_str()); } /* Handle score, show Top scores */ @@ -5556,7 +5203,7 @@ errr get_rnd_line(const char *file_name, char *output) strcpy(output, ""); /* test hack */ - if (wizard && cheat_xtra) msg_print(file_name); + if (wizard && options->cheat_xtra) msg_print(file_name); /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_FILE, file_name); @@ -5678,7 +5325,7 @@ errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output) strcpy(output, ""); /* test and DEBUG hack */ - if (wizard && cheat_xtra) + if (wizard && options->cheat_xtra) { msg_print(file_name); } @@ -5757,7 +5404,7 @@ errr get_xtra_line(const char *file_name, monster_type *m_ptr, char *output) line = rand_int(num_entries); /* test and DEBUG hack */ - if (wizard && cheat_xtra) + if (wizard && options->cheat_xtra) { sprintf(buf, "Line number %d", line); msg_print(buf); diff --git a/src/files.h b/src/files.h index e3df5636..78521f4c 100644 --- a/src/files.h +++ b/src/files.h @@ -7,10 +7,8 @@ extern "C" { #endif -extern bool_ txt_to_html(cptr head, cptr food, cptr base, cptr ext, bool_ force, bool_ recur); -extern void process_player_name(bool_ sf); -extern void do_cmd_save_game(void); -extern void predict_score_gui(bool_ *initialized, bool_ *game_in_progress); +void do_cmd_save_game(); +void predict_score_gui(bool_ *initialized, bool_ *game_in_progress); #ifdef __cplusplus } // extern "C" diff --git a/src/files.hpp b/src/files.hpp index 52206d12..f431eb69 100644 --- a/src/files.hpp +++ b/src/files.hpp @@ -2,26 +2,32 @@ #include "h-basic.h" #include "monster_type_fwd.hpp" +#include "object_flag_set.hpp" -extern void html_screenshot(cptr name); -extern void help_file_screenshot(cptr name); -extern void player_flags(u32b* f1, u32b* f2, u32b* f3, u32b* f4, u32b* f5, u32b* esp); -extern void wipe_saved(void); -extern s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2); -extern void display_player(int mode); -extern cptr describe_player_location(void); -extern errr file_character(cptr name, bool_ full); -extern errr process_pref_file_aux(char *buf); -extern errr process_pref_file(cptr name); -extern bool_ show_file(cptr name, cptr what, int line, int mode); -extern void do_cmd_help(void); -extern void process_player_base(void); -extern void get_name(void); -extern void do_cmd_suicide(void); -extern void autosave_checkpoint(); -extern void close_game(void); -extern errr get_rnd_line(const char * file_name, char * output); -extern char *get_line(const char* fname, cptr fdir, char *linbuf, int line); -extern void race_legends(void); -extern void show_highclass(int building); -extern errr get_xtra_line(const char * file_name, monster_type *m_ptr, char * output); +#include <string> +#include <vector> + +void html_screenshot(cptr name); +void help_file_screenshot(cptr name); +object_flag_set player_flags(); +void wipe_saved(); +s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2); +void display_player(int mode); +std::string describe_player_location(); +errr file_character(cptr name, bool_ full); +errr process_pref_file_aux(char *buf); +errr process_pref_file(cptr name); +void show_string(const char *lines, const char *title, int line = 0); +void show_file(cptr name, cptr what, int line = 0); +void do_cmd_help(); +void process_player_base(); +void get_name(); +void do_cmd_suicide(); +void autosave_checkpoint(); +void close_game(); +errr get_rnd_line(const char * file_name, char * output); +char *get_line(const char* fname, cptr fdir, char *linbuf, int line); +void race_legends(); +void show_highclass(int building); +errr get_xtra_line(const char * file_name, monster_type *m_ptr, char * output); +void process_player_name(bool_ sf); diff --git a/src/flag_set.hpp b/src/flag_set.hpp new file mode 100644 index 00000000..7960de42 --- /dev/null +++ b/src/flag_set.hpp @@ -0,0 +1,201 @@ +#pragma once + +#include <array> +#include <cassert> +#include <cstdint> + +#include "tome/pp/global_constexpr.hpp" + +/** + * Set of binary flags. + */ +template<std::size_t Tiers> struct flag_set +{ +private: + static constexpr std::size_t tiers = Tiers; + std::uint32_t m_data[tiers]; + +public: + static constexpr const std::size_t nbits = tiers * 32; + +public: + + constexpr flag_set() + : m_data { 0 } + { + // It is *extremely* important that there are absolutely + // NO dependencies on any global objects in here; lest we + // fall into SIOF territory; see DECLARE_FLAG_ZERO_IMPL + } + + // This method is a workaround for a a segmentation fault + // when compiling with GCC 5.3.0 (Arch Linux). We should be + // able to use make() directly in DECLARE_FLAG_MAKE_INIT, + // but GCC segfaults. + template<std::uint32_t tier, std::size_t index> static constexpr flag_set make_static() + { + static_assert(tier < tiers, "tier >= tiers"); + static_assert(index < 32, "index >= 32"); + flag_set f; + f.m_data[tier] = (1UL << index); + return f; + } + + static constexpr flag_set make(std::uint32_t tier, std::size_t index) + { + assert(tier < tiers); + assert(index < 32); + flag_set f; + f.m_data[tier] = (1UL << index); + return f; + } + + static constexpr flag_set make_bit(std::size_t ibit) + { + assert(ibit < nbits); + flag_set f; + f.m_data[ibit / 32] = (1UL << (ibit % 32)); + return f; + } + + constexpr std::size_t size() const + { + return tiers; + } + + constexpr bool empty() const + { + for (std::size_t i = 0; i < tiers; i++) + { + if (m_data[i]) + { + return false; + } + } + return true; + } + + constexpr std::size_t count() const + { + std::size_t n = 0; + for (std::size_t i = 0; i < nbits; i++) + { + if (bit(i)) + { + n += 1; + } + } + return n; + } + + uint32_t &operator[](std::size_t i) + { + assert(i < tiers); + return m_data[i]; + } + + constexpr uint32_t const &operator [](std::size_t i) const + { + assert(i < tiers); + return m_data[i]; + } + + explicit constexpr operator bool() const + { + return !empty(); + } + + constexpr bool operator == (flag_set const &other) const + { + for (std::size_t i = 0; i < tiers; i++) + { + if (m_data[i] != other.m_data[i]) + { + return false; + } + } + return true; + } + + constexpr bool operator != (flag_set const &other) const + { + return !(*this == other); + } + + constexpr bool bit(std::size_t i) const + { + assert(i < nbits); + return (m_data[i / 32] & (1UL << (i % 32))); + } + + flag_set &operator |= (flag_set const &other) + { + for (std::size_t i = 0; i < tiers; i++) + { + m_data[i] |= other.m_data[i]; + } + return *this; + } + + constexpr flag_set operator | (flag_set const &other) const + { + flag_set f; + for (std::size_t i = 0; i < tiers; i++) + { + f.m_data[i] = m_data[i] | other.m_data[i]; + } + return f; + } + + flag_set &operator &= (flag_set const &other) + { + for (std::size_t i = 0; i < tiers; i++) + { + m_data[i] &= other.m_data[i]; + } + return *this; + } + + constexpr flag_set operator & (flag_set const &other) const + { + flag_set f; + for (std::size_t i = 0; i < tiers; i++) + { + f.m_data[i] = m_data[i] & other.m_data[i]; + } + return f; + } + + constexpr flag_set operator ~ () const + { + flag_set f; + for (std::size_t i = 0; i < tiers; i++) + { + f.m_data[i] = ~m_data[i]; + } + return f; + } + +}; + +// Implementation details, because preprocessor. +#define DECLARE_FLAG_MAKE_INIT(type, tier, index) \ + type::make_static<tier-1,index>() + +/** + * Macro for declaring a "flag" constant. + */ +#define DECLARE_FLAG(type, name, tier, index) \ + PP_GLOBAL_CONSTEXPR_CONST(type, name, DECLARE_FLAG_MAKE_INIT(type, tier, index)) + +/** + * Macro for declaring a zero'ed "flag" variable. + */ +#define DECLARE_FLAG_ZERO_INTF(type, name) \ + extern type name + +/** + * Macro for declaring the implementation of a zero'ed "flag" variable. + */ +#define DECLARE_FLAG_ZERO_IMPL(type, name) \ + type name { }; diff --git a/src/flags_group.hpp b/src/flags_group.hpp index bdf5216b..84809e37 100644 --- a/src/flags_group.hpp +++ b/src/flags_group.hpp @@ -1,20 +1,17 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" /** * For level gaining artifacts */ struct flags_group { - char name[30]; /* Name */ - byte color; /* Color */ + char name[30] { }; /* Name */ + byte color = 0; /* Color */ - byte price; /* Price to "buy" it */ + byte price = 0; /* Price to "buy" it */ - u32b flags1; /* Flags set 1 */ - u32b flags2; /* Flags set 2 */ - u32b flags3; /* Flags set 3 */ - u32b flags4; /* Flags set 4 */ - u32b esp; /* ESP flags set */ + object_flag_set flags; /* Flags set */ }; diff --git a/src/game.cc b/src/game.cc new file mode 100644 index 00000000..284c9ccc --- /dev/null +++ b/src/game.cc @@ -0,0 +1,3 @@ +#include "game.hpp" + +Game *game; diff --git a/src/game.hpp b/src/game.hpp new file mode 100644 index 00000000..4f84f52c --- /dev/null +++ b/src/game.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "game_fwd.hpp" + +#include "alloc.hpp" +#include "birther.hpp" +#include "game_edit_data.hpp" +#include "grid.hpp" +#include "h-basic.h" +#include "level_marker.hpp" +#include "messages.hpp" +#include "player_defs.hpp" +#include "random_artifact.hpp" +#include "skill_type.hpp" +#include "timer_type_fwd.hpp" +#include "wilderness_map.hpp" + +#include <boost/multi_array.hpp> + +/** + * All structures for the game itself. + */ +struct Game { + + /** + * Player character name + */ + std::string player_name; + + /* + * Stripped version of "player_name" + */ + std::string player_base; + + /** + * What did the player die from? + */ + std::string died_from; + + /** + * Previous character + */ + birther previous_char; + + /** + * Wilderness map + */ + grid<wilderness_map> wilderness; + + /** + * Random artifacts + */ + std::vector<random_artifact> random_artifacts; + + /** + * Allocations + */ + Alloc alloc; + + /** + * Player's un-adjusted HP at every level. + * Stored to avoid shenanigans with draininging levels + * and restoring them back, &c. + */ + std::array<s16b, PY_MAX_LEVEL> player_hp { }; + + /** + * Message buffer. + */ + Messages messages { 2048 }; + + /** + * Game edit data + */ + GameEditData edit_data; + + /** + * Current skill values. + */ + std::vector<skill_type> s_info; + + /** + * Timers + */ + std::vector<timer_type *> timers; + + /** + * Level markers for 'special' levels. + */ + boost::multi_array<level_marker, 2> level_markers { }; + + /** + * Generate a special level feeling? + */ + bool generate_special_feeling = false; + +}; diff --git a/src/game_edit_data.hpp b/src/game_edit_data.hpp new file mode 100644 index 00000000..a4727d90 --- /dev/null +++ b/src/game_edit_data.hpp @@ -0,0 +1,138 @@ +#pragma once + +#include "ability_type.hpp" +#include "artifact_type.hpp" +#include "dungeon_info_type.hpp" +#include "ego_item_type.hpp" +#include "feature_type.hpp" +#include "monster_ego.hpp" +#include "monster_race.hpp" +#include "object_kind.hpp" +#include "owner_type.hpp" +#include "player_class.hpp" +#include "player_race.hpp" +#include "player_race_mod.hpp" +#include "randart_gen_type.hpp" +#include "randart_part_type.hpp" +#include "set_type.hpp" +#include "skill_descriptor.hpp" +#include "store_action_type.hpp" +#include "store_info_type.hpp" +#include "vault_type.hpp" +#include "wilderness_type_info.hpp" + +#include <vector> + +/** + * Game edit data, i.e. the parsed contents of the edit .txt + * files. + */ +struct GameEditData { + + /** + * Dungeons + */ + std::vector<dungeon_info_type> d_info; + + /** + * Vaults + */ + std::vector<vault_type> v_info; + + /** + * Random artifact part descriptors, i.e. the bits that + * randarts are made up of. + */ + std::vector<randart_part_type> ra_info; + + /** + * Random artifact generation parameters. + */ + std::vector<randart_gen_type> ra_gen; + + /** + * Artifacts + */ + std::vector<artifact_type> a_info; + + /** + * Ego items + */ + std::vector<ego_item_type> e_info; + + /** + * Artifact sets + */ + std::vector<set_type> set_info; + + /** + * Object kinds + */ + std::vector<object_kind> k_info; + + /** + * Building actions. + */ + std::vector<store_action_type> ba_info; + + /** + * Buildings + */ + std::vector<store_info_type> st_info; + + /** + * Building owners. + */ + std::vector<owner_type> ow_info; + + /** + * Player classes. + */ + std::vector<player_class> class_info; + + /** + * Player races. + */ + std::vector<player_race> race_info; + + /** + * Player subraces. + */ + std::vector<player_race_mod> race_mod_info; + + /** + * Player skills + */ + std::vector<skill_descriptor> s_descriptors; + + /* + * The monster races + */ + std::vector<monster_race> r_info; + + /** + * Monster race egos + */ + std::vector<monster_ego> re_info; + + /* + * Terrain features + */ + std::vector<feature_type> f_info; + + /** + * Wilderness features + */ + std::vector<wilderness_type_info> wf_info; + + /** + * Base skills for all characters. + */ + skill_modifiers gen_skill; + + /** + * Player abilities. + */ + std::vector<ability_type> ab_info; + +}; diff --git a/src/game_edit_data_fwd.hpp b/src/game_edit_data_fwd.hpp new file mode 100644 index 00000000..3c986dfa --- /dev/null +++ b/src/game_edit_data_fwd.hpp @@ -0,0 +1,3 @@ +#pragma once + +struct GameEditData; diff --git a/src/game_fwd.hpp b/src/game_fwd.hpp new file mode 100644 index 00000000..840e5f3b --- /dev/null +++ b/src/game_fwd.hpp @@ -0,0 +1,4 @@ +#pragma once + +struct Game; +extern Game *game; diff --git a/src/gen_evol.cc b/src/gen_evol.cc index 6f3fbcba..7dca5b9a 100644 --- a/src/gen_evol.cc +++ b/src/gen_evol.cc @@ -10,7 +10,9 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "generate.hpp" #include "levels.hpp" #include "player_type.hpp" @@ -22,6 +24,8 @@ */ void evolve_level(bool_ noise) { + auto const &f_info = game->edit_data.f_info; + int i, j; int cw = 0, cf = 0; @@ -34,8 +38,8 @@ void evolve_level(bool_ noise) { for (j = 1; j < cur_hgt - 1; j++) { - if (f_info[cave[j][i].feat].flags1 & FF1_WALL) cw++; - if (f_info[cave[j][i].feat].flags1 & FF1_FLOOR) cf++; + if (f_info[cave[j][i].feat].flags & FF_WALL) cw++; + if (f_info[cave[j][i].feat].flags & FF_FLOOR) cf++; } } @@ -49,7 +53,7 @@ void evolve_level(bool_ noise) c_ptr = &cave[j][i]; /* Permanent features should stay */ - if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue; + if (f_info[c_ptr->feat].flags & FF_PERMANENT) continue; /* Avoid evolving grids with object or monster */ if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue; @@ -83,7 +87,7 @@ void evolve_level(bool_ noise) c_ptr = &cave[j][i]; /* Permanent features should stay */ - if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue; + if (f_info[c_ptr->feat].flags & FF_PERMANENT) continue; /* Avoid evolving grids with object or monster */ if ((!c_ptr->o_idxs.empty()) || c_ptr->m_idx) continue; @@ -101,7 +105,7 @@ void evolve_level(bool_ noise) for (y = j - 1; y <= j + 1; y++) { if ((x == i) && (y == j)) continue; - if (f_info[cave[y][x].feat].flags1 & FF1_WALL) c++; + if (f_info[cave[y][x].feat].flags & FF_WALL) c++; } } @@ -112,7 +116,7 @@ void evolve_level(bool_ noise) /* Starved or suffocated */ if ((c < 4) || (c >= 7)) { - if (f_info[c_ptr->feat].flags1 & FF1_WALL) + if (f_info[c_ptr->feat].flags & FF_WALL) { place_floor(j, i); } @@ -121,7 +125,7 @@ void evolve_level(bool_ noise) /* Spawned */ else if ((c == 4) || (c == 5)) { - if (!(f_info[c_ptr->feat].flags1 & FF1_WALL)) + if (!(f_info[c_ptr->feat].flags & FF_WALL)) { place_filler(j, i); } diff --git a/src/gen_evol.hpp b/src/gen_evol.hpp index 65b1320d..6e5087c8 100644 --- a/src/gen_evol.hpp +++ b/src/gen_evol.hpp @@ -2,5 +2,5 @@ #include "h-basic.h" -extern bool_ level_generate_life(); -extern void evolve_level(bool_ noise); +bool_ level_generate_life(); +void evolve_level(bool_ noise); diff --git a/src/gen_maze.hpp b/src/gen_maze.hpp index 28c092e3..bc03b575 100644 --- a/src/gen_maze.hpp +++ b/src/gen_maze.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -extern bool_ level_generate_maze(); +bool_ level_generate_maze(); diff --git a/src/generate.cc b/src/generate.cc index b5733682..ba485faf 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -12,7 +12,10 @@ #include "cave.hpp" #include "cave_type.hpp" #include "dungeon_info_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_build_room1_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -20,8 +23,11 @@ #include "loadsave.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "monster_type.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "options.hpp" #include "player_type.hpp" @@ -29,7 +35,6 @@ #include "spells1.hpp" #include "tables.hpp" #include "town_type.hpp" -#include "traps.hpp" #include "util.hpp" #include "variable.hpp" #include "vault_type.hpp" @@ -192,7 +197,6 @@ * Hack -- Dungeon allocation "types" */ #define ALLOC_TYP_RUBBLE 1 /* Rubble */ -#define ALLOC_TYP_TRAP 3 /* Trap */ #define ALLOC_TYP_GOLD 4 /* Gold */ #define ALLOC_TYP_OBJECT 5 /* Object */ #define ALLOC_TYP_ALTAR 6 /* Altar */ @@ -406,7 +410,7 @@ static void place_up_stairs(int y, int x) cave_type *c_ptr = &cave[y][x]; /* Create up stairs */ - if ((rand_int(3) != 0) || (dungeon_flags2 & DF2_NO_SHAFT)) + if ((rand_int(3) != 0) || (dungeon_flags & DF_NO_SHAFT)) { cave_set_feat(y, x, FEAT_LESS); } @@ -420,23 +424,12 @@ static void place_up_stairs(int y, int x) /* - * Convert existing terrain type to "down stairs" with dungeon changing. - */ -static void place_magical_stairs(int y, int x, byte next) -{ - cave_type *c_ptr = &cave[y][x]; - - /* Create up stairs */ - cave_set_feat(y, x, FEAT_MORE); - c_ptr->special = next; -} - - -/* * Convert existing terrain type to "down stairs" */ static void place_down_stairs(int y, int x) { + auto const &d_info = game->edit_data.d_info; + cave_type *c_ptr = &cave[y][x]; /* @@ -444,7 +437,7 @@ static void place_down_stairs(int y, int x) * All thoses tests are necesary because a shaft can jump up to 4 levels */ if ((dun_level + 4 > d_info[dungeon_type].maxdepth) || - (rand_int(3) != 0) || (dungeon_flags2 & DF2_NO_SHAFT)) + (rand_int(3) != 0) || (dungeon_flags & DF_NO_SHAFT)) { cave_set_feat(y, x, FEAT_MORE); } @@ -463,7 +456,9 @@ static void place_down_stairs(int y, int x) */ static bool_ is_safe_floor(int y, int x) { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto const &d_info = game->edit_data.d_info; + + auto d_ptr = &d_info[dungeon_type]; byte feat = cave[y][x].feat; /* One of the legal floor types */ @@ -481,6 +476,8 @@ static bool_ is_safe_floor(int y, int x) */ void place_new_way(int *y, int *x) { + auto const &f_info = game->edit_data.f_info; + int xx, yy; int x0, x1, x2; int y0, y1, y2; @@ -569,8 +566,8 @@ void place_new_way(int *y, int *x) if (c_ptr->info & (CAVE_ICKY)) continue; /* Reject permanent features */ - if ((f_info[c_ptr->feat].flags1 & (FF1_PERMANENT)) && - (f_info[c_ptr->feat].flags1 & (FF1_FLOOR))) continue; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT) && + (f_info[c_ptr->feat].flags & FF_FLOOR)) continue; /* Reject room walls */ if ((c_ptr->info & (CAVE_ROOM)) && @@ -719,7 +716,7 @@ bool_ new_player_spot(int branch) int max_attempts = 5000; /* Place the player */ - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { place_new_way(&y, &x); } @@ -752,13 +749,13 @@ bool_ new_player_spot(int branch) p_ptr->px = x; /* XXX XXX XXX */ - if (dungeon_stair && !(dungeon_flags2 & DF2_NO_STAIR) && dun_level && + if (options->dungeon_stair && !(dungeon_flags & DF_NO_STAIR) && dun_level && (!is_quest(dun_level) || (old_dun_level < dun_level)) && !branch) { if (old_dun_level < dun_level) { place_up_stairs(p_ptr->py , p_ptr->px); - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { cave_set_feat(p_ptr->py, p_ptr->px, FEAT_WAY_LESS); } @@ -766,7 +763,7 @@ bool_ new_player_spot(int branch) else { place_down_stairs(p_ptr->py , p_ptr->px); - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { cave_set_feat(p_ptr->py, p_ptr->px, FEAT_WAY_MORE); } @@ -787,12 +784,14 @@ bool_ new_player_spot(int branch) */ static int next_to_walls(int y, int x) { - int k = 0; + auto const &f_info = game->edit_data.f_info; - if (f_info[cave[y + 1][x].feat].flags1 & FF1_WALL) k++; - if (f_info[cave[y - 1][x].feat].flags1 & FF1_WALL) k++; - if (f_info[cave[y][x + 1].feat].flags1 & FF1_WALL) k++; - if (f_info[cave[y][x - 1].feat].flags1 & FF1_WALL) k++; + int k = 0; + + if (f_info[cave[y + 1][x].feat].flags & FF_WALL) k++; + if (f_info[cave[y - 1][x].feat].flags & FF_WALL) k++; + if (f_info[cave[y][x + 1].feat].flags & FF_WALL) k++; + if (f_info[cave[y][x - 1].feat].flags & FF_WALL) k++; return (k); } @@ -824,19 +823,28 @@ static void place_altar(int y, int x) */ static void place_fountain(int y, int x) { + auto const &k_info = game->edit_data.k_info; + cave_type *c_ptr = &cave[y][x]; - int svals[SV_POTION_LAST + SV_POTION2_LAST + 1], maxsval = 0, k; + int svals[SV_POTION_LAST + SV_POTION2_LAST + 1]; + int maxsval = 0; /* List of usable svals */ - for (k = 1; k < max_k_idx; k++) + for (auto const &k_ref: k_info) { - object_kind *k_ptr = &k_info[k]; + auto k_ptr = &k_ref; if (((k_ptr->tval == TV_POTION) || (k_ptr->tval == TV_POTION2)) && - (k_ptr->level <= dun_level) && (k_ptr->flags4 & TR4_FOUNTAIN)) + (k_ptr->level <= dun_level) && (k_ptr->flags & TR_FOUNTAIN)) { - if (k_ptr->tval == TV_POTION2) svals[maxsval] = k_ptr->sval + SV_POTION_LAST; - else svals[maxsval] = k_ptr->sval; + if (k_ptr->tval == TV_POTION2) + { + svals[maxsval] = k_ptr->sval + SV_POTION_LAST; + } + else + { + svals[maxsval] = k_ptr->sval; + } maxsval++; } } @@ -893,6 +901,8 @@ static void place_between(int y, int x) */ static void place_random_stairs(int y, int x) { + auto const &d_info = game->edit_data.d_info; + /* Paranoia */ if (!cave_clean_bold(y, x)) return; @@ -907,14 +917,7 @@ static void place_random_stairs(int y, int x) } else if (dun_level >= d_info[dungeon_type].maxdepth) { - if (d_info[dungeon_type].next) - { - place_magical_stairs(y, x, d_info[dungeon_type].next); - } - else - { - place_up_stairs(y, x); - } + place_up_stairs(y, x); } else if (rand_int(100) < 50) { @@ -938,45 +941,6 @@ static void place_locked_door(int y, int x) /* - * Place a secret door at the given location - */ -static void place_secret_door(int y, int x) -{ - cave_type *c_ptr = &cave[y][x]; - - /* Vaults */ - if (c_ptr->info & CAVE_ICKY) - { - c_ptr->mimic = FEAT_WALL_INNER; - } - - /* Ordinary room -- use current outer or inner wall */ - else if (c_ptr->info & CAVE_ROOM) - { - /* Determine if it's inner or outer XXX XXX XXX */ - if ((cave[y - 1][x].info & CAVE_ROOM) && - (cave[y + 1][x].info & CAVE_ROOM) && - (cave[y][x - 1].info & CAVE_ROOM) && - (cave[y][x + 1].info & CAVE_ROOM)) - { - c_ptr->mimic = feat_wall_inner; - } - else - { - c_ptr->mimic = feat_wall_outer; - } - } - else - { - c_ptr->mimic = fill_type[rand_int(100)]; - } - - /* Create secret door */ - cave_set_feat(y, x, FEAT_SECRET); -} - - -/* * Place a random type of door at the given location */ static void place_random_door(int y, int x) @@ -1000,11 +964,11 @@ static void place_random_door(int y, int x) cave_set_feat(y, x, FEAT_BROKEN); } - /* Secret doors (200/1000) */ + /* Secret doors (200/1000) - now locked instead */ else if (tmp < 600) { - /* Create secret door */ - place_secret_door(y, x); + /* Create locked door */ + place_locked_door(y, x); } /* Closed doors (300/1000) */ @@ -1036,6 +1000,8 @@ static void place_random_door(int y, int x) */ static void alloc_stairs(int feat, int num, int walls, int branch) { + auto const &d_info = game->edit_data.d_info; + int y, x, i, j, cnt; /* Place "num" stairs */ @@ -1044,7 +1010,7 @@ static void alloc_stairs(int feat, int num, int walls, int branch) /* Try several times, then decrease "walls" */ for (j = 0; j <= SAFE_MAX_ATTEMPTS; j++) { - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { place_new_way(&y, &x); } @@ -1065,11 +1031,11 @@ static void alloc_stairs(int feat, int num, int walls, int branch) if (!dun_level) { /* Clear previous contents, add down stairs */ - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { cave_set_feat(y, x, FEAT_WAY_MORE); } - else if ((rand_int(3) == 0) && (!(dungeon_flags2 & DF2_NO_SHAFT))) + else if ((rand_int(3) == 0) && (!(dungeon_flags & DF_NO_SHAFT))) { cave_set_feat(y, x, FEAT_SHAFT_DOWN); } @@ -1082,14 +1048,14 @@ static void alloc_stairs(int feat, int num, int walls, int branch) /* Quest -- must go up */ else if ((is_quest(dun_level) && (dun_level >= 1)) || ((dun_level >= d_info[dungeon_type].maxdepth) && - (!(dungeon_flags1 & DF1_FORCE_DOWN)))) + (!(dungeon_flags & DF_FORCE_DOWN)))) { /* Clear previous contents, add up stairs */ - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { cave_set_feat(y, x, FEAT_WAY_LESS); } - else if ((rand_int(3) == 0) && (!(dungeon_flags2 & DF2_NO_SHAFT))) + else if ((rand_int(3) == 0) && (!(dungeon_flags & DF_NO_SHAFT))) { cave_set_feat(y, x, FEAT_SHAFT_UP); } @@ -1163,7 +1129,7 @@ static void alloc_object(int set, int typ, int num) if (dummy >= SAFE_MAX_ATTEMPTS) { - if (cheat_room) + if (options->cheat_room) { msg_format("Warning! Could not place object, type : %d!", typ); } @@ -1181,12 +1147,6 @@ static void alloc_object(int set, int typ, int num) break; } - case ALLOC_TYP_TRAP: - { - place_trap(y, x); - break; - } - case ALLOC_TYP_GOLD: { place_gold(y, x); @@ -1427,6 +1387,8 @@ static void add_river(int feat1, int feat2) */ static void build_streamer(int feat, int chance) { + auto const &d_info = game->edit_data.d_info; + int i, tx, ty; int y, x, dir; int dummy = 0; @@ -1484,7 +1446,7 @@ static void build_streamer(int feat, int chance) if (dummy >= SAFE_MAX_ATTEMPTS) { - if (cheat_room) + if (options->cheat_room) { msg_print("Warning! Could not place streamer!"); } @@ -1510,6 +1472,8 @@ static void build_streamer(int feat, int chance) */ static void build_streamer2(int feat, int killwall) { + auto const &f_info = game->edit_data.f_info; + int i, j, mid, tx, ty; int y, x, dir; int poolchance; @@ -1550,13 +1514,13 @@ static void build_streamer2(int feat, int killwall) if (c_ptr->info & (CAVE_ICKY)) continue; /* Reject permanent features */ - if ((f_info[c_ptr->feat].flags1 & (FF1_PERMANENT)) && - (f_info[c_ptr->feat].flags1 & (FF1_FLOOR))) continue; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT) && + (f_info[c_ptr->feat].flags & FF_FLOOR)) continue; /* Avoid converting walls when told so */ if (killwall == 0) { - if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue; + if (f_info[c_ptr->feat].flags & FF_WALL) continue; } /* Clear mimic feature to avoid nasty consequences */ @@ -1613,7 +1577,7 @@ static void build_streamer2(int feat, int killwall) continue; /* Only convert non-permanent features */ - if (f_info[cave[ty][tx].feat].flags1 & FF1_PERMANENT) continue; + if (f_info[cave[ty][tx].feat].flags & FF_PERMANENT) continue; /* Clear mimic feature to avoid nasty consequences */ cave[ty][tx].mimic = 0; @@ -1630,14 +1594,14 @@ static void build_streamer2(int feat, int killwall) /* * Build a destroyed level */ -static void destroy_level(void) +static void destroy_level() { int y1, x1, y, x, k, t, n; cave_type *c_ptr; /* Note destroyed levels */ - if ((cheat_room) || (p_ptr->precognition)) msg_print("Destroyed Level"); + if ((options->cheat_room) || (p_ptr->precognition)) msg_print("Destroyed Level"); /* Drop a few epi-centers (usually about two) */ for (n = 0; n < randint(5); n++) @@ -1727,11 +1691,13 @@ static void destroy_level(void) */ static bool_ get_is_floor(int x, int y) { + auto const &f_info = game->edit_data.f_info; + /* Out of bounds */ if (!in_bounds(y, x)) return (FALSE); /* Do the real check: */ - if (f_info[cave[y][x].feat].flags1 & FF1_FLOOR) return (TRUE); + if (f_info[cave[y][x].feat].flags & FF_FLOOR) return (TRUE); return (FALSE); } @@ -1746,7 +1712,7 @@ static void check_room_boundary(int x1, int y1, int x2, int y2) bool_ old_is_floor, new_is_floor; /* Avoid doing this in irrelevant places -- pelpel */ - if (!(dungeon_flags1 & DF1_CAVERN)) return; + if (!(dungeon_flags & DF_CAVERN)) return; /* Initialize */ count = 0; @@ -1847,7 +1813,7 @@ static void vault_objects(int y, int x, int num) if (dummy >= SAFE_MAX_ATTEMPTS) { - if (cheat_room) + if (options->cheat_room) { msg_print("Warning! Could not place vault object!"); } @@ -1877,61 +1843,6 @@ static void vault_objects(int y, int x, int num) /* - * Place a trap with a given displacement of point - */ -static void vault_trap_aux(int y, int x, int yd, int xd) -{ - int count = 0, y1 = y, x1 = x; - int dummy = 0; - - /* Place traps */ - for (count = 0; count <= 5; count++) - { - /* Get a location */ - while (dummy < SAFE_MAX_ATTEMPTS) - { - y1 = rand_spread(y, yd); - x1 = rand_spread(x, xd); - dummy++; - if (in_bounds(y1, x1)) break; - } - - if (dummy >= SAFE_MAX_ATTEMPTS) - { - if (cheat_room) - { - msg_print("Warning! Could not place vault trap!"); - } - } - - - /* Require "naked" floor grids */ - if (!cave_naked_bold(y1, x1)) continue; - - /* Place the trap */ - place_trap(y1, x1); - - /* Done */ - break; - } -} - - -/* - * Place some traps with a given displacement of given location - */ -static void vault_traps(int y, int x, int yd, int xd, int num) -{ - int i; - - for (i = 0; i < num; i++) - { - vault_trap_aux(y, x, yd, xd); - } -} - - -/* * Hack -- Place some sleeping monsters near the given location */ static void vault_monsters(int y1, int x1, int num) @@ -1954,7 +1865,7 @@ static void vault_monsters(int y1, int x1, int num) /* Place the monster (allow groups) */ monster_level = dun_level + 2; - (void)place_monster(y, x, TRUE, TRUE); + place_monster(y, x, TRUE, TRUE); monster_level = dun_level; } } @@ -2277,20 +2188,20 @@ static void build_type3(int by0, int bx0) /* Build the vault */ build_rectangle(y1b, x1a, y2b, x2a, feat_wall_inner, info); - /* Place a secret door on the inner room */ + /* Place a locked door on the inner room */ switch (rand_int(4)) { case 0: - place_secret_door(y1b, xval); + place_locked_door(y1b, xval); break; case 1: - place_secret_door(y2b, xval); + place_locked_door(y2b, xval); break; case 2: - place_secret_door(yval, x1a); + place_locked_door(yval, x1a); break; case 3: - place_secret_door(yval, x2a); + place_locked_door(yval, x2a); break; } @@ -2300,9 +2211,6 @@ static void build_type3(int by0, int bx0) /* Let's guard the treasure well */ vault_monsters(yval, xval, rand_int(2) + 3); - /* Traps naturally */ - vault_traps(yval, xval, 4, 4, rand_int(3) + 2); - break; } @@ -2328,13 +2236,13 @@ static void build_type3(int by0, int bx0) cave_set_feat(y2b + 1, x, feat_wall_inner); } - /* Sometimes shut using secret doors */ + /* Sometimes shut using locked doors */ if (rand_int(3) == 0) { - place_secret_door(yval, x1a - 1); - place_secret_door(yval, x2a + 1); - place_secret_door(y1b - 1, xval); - place_secret_door(y2b + 1, xval); + place_locked_door(yval, x1a - 1); + place_locked_door(yval, x2a + 1); + place_locked_door(y1b - 1, xval); + place_locked_door(y2b + 1, xval); } } @@ -2414,20 +2322,20 @@ static void build_type4(int by0, int bx0) /* Just an inner room with a monster */ case 1: { - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -2440,20 +2348,20 @@ static void build_type4(int by0, int bx0) /* Treasure Vault (with a door) */ case 2: { - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -2493,29 +2401,26 @@ static void build_type4(int by0, int bx0) place_random_stairs(yval, xval); } - /* Traps to protect the treasure */ - vault_traps(yval, xval, 4, 10, 2 + randint(3)); - break; } /* Inner pillar(s). */ case 3: { - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -2559,9 +2464,9 @@ static void build_type4(int by0, int bx0) cave_set_feat(yval, xval - 5, feat_wall_inner); cave_set_feat(yval, xval + 5, feat_wall_inner); - /* Secret doors (random top/bottom) */ - place_secret_door(yval - 3 + (randint(2) * 2), xval - 3); - place_secret_door(yval - 3 + (randint(2) * 2), xval + 3); + /* Locked doors (random top/bottom) */ + place_locked_door(yval - 3 + (randint(2) * 2), xval - 3); + place_locked_door(yval - 3 + (randint(2) * 2), xval + 3); /* Monsters */ vault_monsters(yval, xval - 2, randint(2)); @@ -2578,20 +2483,20 @@ static void build_type4(int by0, int bx0) /* Maze inside. */ case 4: { - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -2611,10 +2516,6 @@ static void build_type4(int by0, int bx0) vault_monsters(yval, xval - 5, randint(3)); vault_monsters(yval, xval + 5, randint(3)); - /* Traps make them entertaining. */ - vault_traps(yval, xval - 3, 2, 8, randint(3)); - vault_traps(yval, xval + 3, 2, 8, randint(3)); - /* Mazes should have some treasure too. */ vault_objects(yval, xval, 3); @@ -2639,18 +2540,18 @@ static void build_type4(int by0, int bx0) if (rand_int(100) < 50) { int i = randint(10); - place_secret_door(y1 - 1, xval - i); - place_secret_door(y1 - 1, xval + i); - place_secret_door(y2 + 1, xval - i); - place_secret_door(y2 + 1, xval + i); + place_locked_door(y1 - 1, xval - i); + place_locked_door(y1 - 1, xval + i); + place_locked_door(y2 + 1, xval - i); + place_locked_door(y2 + 1, xval + i); } else { int i = randint(3); - place_secret_door(yval + i, x1 - 1); - place_secret_door(yval - i, x1 - 1); - place_secret_door(yval + i, x2 + 1); - place_secret_door(yval - i, x2 + 1); + place_locked_door(yval + i, x1 - 1); + place_locked_door(yval - i, x1 - 1); + place_locked_door(yval + i, x2 + 1); + place_locked_door(yval - i, x2 + 1); } /* Treasure, centered at the center of the cross */ @@ -2689,13 +2590,15 @@ static void build_type4(int by0, int bx0) */ static bool_ vault_aux_jelly(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Also decline evil jellies (like death molds and shoggoths) */ - if (r_ptr->flags3 & (RF3_EVIL)) return (FALSE); + if (r_ptr->flags & RF_EVIL) return (FALSE); /* Require icky thing, jelly, mold, or mushroom */ if (!strchr("ijm,", r_ptr->d_char)) return (FALSE); @@ -2710,13 +2613,15 @@ static bool_ vault_aux_jelly(int r_idx) */ static bool_ vault_aux_animal(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Require "animal" flag */ - if (!(r_ptr->flags3 & (RF3_ANIMAL))) return (FALSE); + if (!(r_ptr->flags & RF_ANIMAL)) return (FALSE); /* Okay */ return (TRUE); @@ -2728,13 +2633,15 @@ static bool_ vault_aux_animal(int r_idx) */ static bool_ vault_aux_undead(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Require Undead */ - if (!(r_ptr->flags3 & (RF3_UNDEAD))) return (FALSE); + if (!(r_ptr->flags & RF_UNDEAD)) return (FALSE); /* Okay */ return (TRUE); @@ -2746,10 +2653,12 @@ static bool_ vault_aux_undead(int r_idx) */ static bool_ vault_aux_chapel(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Require "priest" or Angel */ if (!((r_ptr->d_char == 'A') || strstr(r_ptr->name, "riest"))) @@ -2767,10 +2676,12 @@ static bool_ vault_aux_chapel(int r_idx) */ static bool_ vault_aux_kennel(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Require a Zephyr Hound or a dog */ return ((r_ptr->d_char == 'Z') || (r_ptr->d_char == 'C')); @@ -2783,10 +2694,12 @@ static bool_ vault_aux_kennel(int r_idx) */ static bool_ vault_aux_treasure(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Require "priest" or Angel */ if (!((r_ptr->d_char == '!') || (r_ptr->d_char == '|') || @@ -2815,8 +2728,10 @@ static bool_ vault_aux_clone(int r_idx) */ static bool_ vault_aux_symbol(int r_idx) { + auto const &r_info = game->edit_data.r_info; + return ((r_info[r_idx].d_char == (r_info[template_race].d_char)) - && !(r_info[r_idx].flags1 & RF1_UNIQUE)); + && !(r_info[r_idx].flags & RF_UNIQUE)); } @@ -2825,10 +2740,12 @@ static bool_ vault_aux_symbol(int r_idx) */ static bool_ vault_aux_orc(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Hack -- Require "o" monsters */ if (!strchr("o", r_ptr->d_char)) return (FALSE); @@ -2844,10 +2761,12 @@ static bool_ vault_aux_orc(int r_idx) */ static bool_ vault_aux_troll(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Hack -- Require "T" monsters */ if (!strchr("T", r_ptr->d_char)) return (FALSE); @@ -2862,10 +2781,12 @@ static bool_ vault_aux_troll(int r_idx) */ static bool_ vault_aux_giant(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Hack -- Require "P" monsters */ if (!strchr("P", r_ptr->d_char)) return (FALSE); @@ -2876,41 +2797,16 @@ static bool_ vault_aux_giant(int r_idx) /* - * Hack -- breath type for "vault_aux_dragon()" - */ -static u32b vault_aux_dragon_mask4; - - -/* - * Helper function for "monster pit (dragon)" - */ -static bool_ vault_aux_dragon(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); - - /* Hack -- Require "d" or "D" monsters */ - if (!strchr("Dd", r_ptr->d_char)) return (FALSE); - - /* Hack -- Require correct "breath attack" */ - if (r_ptr->flags4 != vault_aux_dragon_mask4) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/* * Helper function for "monster pit (demon)" */ static bool_ vault_aux_demon(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Decline unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Hack -- Require "U" monsters */ if (!strchr("U", r_ptr->d_char)) return (FALSE); @@ -2946,6 +2842,8 @@ static bool_ vault_aux_demon(int r_idx) */ static void build_type5(int by0, int bx0) { + auto const &r_info = game->edit_data.r_info; + int y, x, y1, x1, y2, x2, xval, yval; int tmp, i; cptr name; @@ -2984,20 +2882,20 @@ static void build_type5(int by0, int bx0) /* The inner walls */ build_rectangle(y1 - 1, x1 - 1, y2 + 1, x2 + 1, feat_wall_inner, CAVE_ROOM); - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -3010,10 +2908,10 @@ static void build_type5(int by0, int bx0) { while (1) { - template_race = randint(max_r_idx - 2); + template_race = rand_int(r_info.size()); /* Reject uniques */ - if (r_info[template_race].flags1 & RF1_UNIQUE) continue; + if (r_info[template_race].flags & RF_UNIQUE) continue; /* Reject OoD monsters in a loose fashion */ if (((r_info[template_race].level) + randint(5)) > @@ -3109,7 +3007,7 @@ static void build_type5(int by0, int bx0) if (empty) return; /* Describe */ - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { /* Room type */ msg_format("Monster nest (%s)", name); @@ -3132,7 +3030,7 @@ static void build_type5(int by0, int bx0) int r_idx = what[rand_int(64)]; /* Place that "random" monster (no groups) */ - (void)place_monster_aux(y, x, r_idx, FALSE, FALSE, MSTATUS_ENEMY); + place_monster_aux(y, x, r_idx, FALSE, FALSE, MSTATUS_ENEMY); } } } @@ -3184,6 +3082,8 @@ static void build_type5(int by0, int bx0) */ static void build_type6(int by0, int bx0) { + auto const &r_info = game->edit_data.r_info; + int tmp, what[16]; int i, j, y, x, y1, x1, y2, x2, xval, yval; bool_ empty = FALSE; @@ -3221,20 +3121,20 @@ static void build_type6(int by0, int bx0) /* The inner walls */ build_rectangle(y1 - 1, x1 - 1, y2 + 1, x2 + 1, feat_wall_outer, CAVE_ROOM); - /* Place a secret door */ + /* Place a locked door */ switch (randint(4)) { case 1: - place_secret_door(y1 - 1, xval); + place_locked_door(y1 - 1, xval); break; case 2: - place_secret_door(y2 + 1, xval); + place_locked_door(y2 + 1, xval); break; case 3: - place_secret_door(yval, x1 - 1); + place_locked_door(yval, x1 - 1); break; case 4: - place_secret_door(yval, x2 + 1); + place_locked_door(yval, x2 + 1); break; } @@ -3282,9 +3182,9 @@ static void build_type6(int by0, int bx0) do { - template_race = randint(max_r_idx - 2); + template_race = rand_int(r_info.size() - 1); } - while ((r_info[template_race].flags1 & RF1_UNIQUE) + while ((r_info[template_race].flags & RF_UNIQUE) || (((r_info[template_race].level) + randint(5)) > (dun_level + randint(5)))); @@ -3302,93 +3202,73 @@ static void build_type6(int by0, int bx0) /* Dragon pit */ else if (tmp < 80) { + /* Hack - get_mon_num_hook needs a plain function */ + static monster_spell_flag_set mask; + /* Pick dragon type */ switch (rand_int(6)) { - /* Black */ case 0: { - /* Message */ name = "acid dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_ACID; - - /* Done */ + mask = SF_BR_ACID; break; } - - /* Blue */ case 1: { - /* Message */ name = "electric dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_ELEC; - - /* Done */ + mask = SF_BR_ELEC; break; } - /* Red */ case 2: { - /* Message */ name = "fire dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_FIRE; - - /* Done */ + mask = SF_BR_FIRE; break; } - /* White */ case 3: { - /* Message */ name = "cold dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_COLD; - - /* Done */ + mask = SF_BR_COLD; break; } - /* Green */ case 4: { - /* Message */ name = "poison dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_POIS; - - /* Done */ + mask = SF_BR_POIS; break; } - /* Multi-hued */ default: { - /* Message */ name = "multi-hued dragon"; - - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = (RF4_BR_ACID | RF4_BR_ELEC | - RF4_BR_FIRE | RF4_BR_COLD | - RF4_BR_POIS); - - /* Done */ + mask = SF_BR_ACID | SF_BR_ELEC | SF_BR_FIRE | SF_BR_COLD | SF_BR_POIS; break; } } /* Restrict monster selection */ - get_mon_num_hook = vault_aux_dragon; + get_mon_num_hook = [](int r_idx) -> bool_ { + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; + + /* Decline unique monsters */ + if (r_ptr->flags & RF_UNIQUE) return (FALSE); + + /* Hack -- Require "d" or "D" monsters */ + if (!strchr("Dd", r_ptr->d_char)) return (FALSE); + + /* Hack -- Require correct "breath attack" */ + if ((r_ptr->spells & mask) != mask) return (FALSE); + + /* Okay */ + return (TRUE); + }; } /* Demon pit */ @@ -3454,12 +3334,12 @@ static void build_type6(int by0, int bx0) } /* Message */ - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { /* Room type */ msg_format("Monster pit (%s)", name); - if (cheat_hear || p_ptr->precognition) + if (options->cheat_hear || p_ptr->precognition) { /* Contents */ for (i = 0; i < 8; i++) @@ -3532,264 +3412,270 @@ static void build_type6(int by0, int bx0) /* * Hack -- fill in "vault" rooms */ -static void build_vault(int yval, int xval, int ymax, int xmax, cptr data) +static void build_vault(int yval, int xval, int ymax, int xmax, std::string const &data) { - int dx, dy, x, y, bwy[8], bwx[8], i; - - cptr t; - - cave_type *c_ptr; + int bwy[8], bwx[8]; /* Clean the between gates arrays */ - for (i = 0; i < 8; i++) + for (std::size_t i = 0; i < 8; i++) { bwy[i] = bwx[i] = 9999; } /* Place dungeon features and objects */ - for (t = data, dy = 0; dy < ymax; dy++) { - for (dx = 0; dx < xmax; dx++, t++) + std::size_t t = 0; + for (int dy = 0; dy < ymax; dy++) { - /* Extract the location */ - x = xval - (xmax / 2) + dx; - y = yval - (ymax / 2) + dy; + for (int dx = 0; dx < xmax; dx++, t++) + { + auto d = data[t]; - /* Hack -- skip "non-grids" */ - if (*t == ' ') continue; + /* Hack -- skip "non-grids" */ + if (d == ' ') continue; - /* Access the grid */ - c_ptr = &cave[y][x]; + /* Extract the location */ + int x = xval - (xmax / 2) + dx; + int y = yval - (ymax / 2) + dy; - /* Lay down a floor */ - place_floor(y, x); + /* Access the grid */ + auto c_ptr = &cave[y][x]; - /* Part of a vault */ - c_ptr->info |= (CAVE_ROOM | CAVE_ICKY); + /* Lay down a floor */ + place_floor(y, x); - /* Analyze the grid */ - switch (*t) - { - /* Granite wall (outer) */ - case '%': - { - cave_set_feat(y, x, FEAT_WALL_OUTER); - break; - } + /* Part of a vault */ + c_ptr->info |= (CAVE_ROOM | CAVE_ICKY); - /* Granite wall (inner) */ - case '#': + /* Analyze the grid */ + switch (d) { - cave_set_feat(y, x, FEAT_WALL_INNER); - break; - } + /* Granite wall (outer) */ + case '%': + { + cave_set_feat(y, x, FEAT_WALL_OUTER); + break; + } - /* Permanent wall (inner) */ - case 'X': - { - cave_set_feat(y, x, FEAT_PERM_INNER); - break; - } + /* Granite wall (inner) */ + case '#': + { + cave_set_feat(y, x, FEAT_WALL_INNER); + break; + } - /* Treasure/trap */ - case '*': - { - if (rand_int(100) < 75) + /* Permanent wall (inner) */ + case 'X': { - place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT); + cave_set_feat(y, x, FEAT_PERM_INNER); + break; } - else + + /* Treasure/trap */ + case '*': { - place_trap(y, x); + if (rand_int(100) < 75) + { + place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT); + } + else + { + /* Do nothing */ + } + break; } - break; - } - /* Secret doors */ - case '+': - { - place_secret_door(y, x); - break; - } + /* locked doors */ + case '+': + { + place_locked_door(y, x); + break; + } - /* Trap */ - case '^': - { - place_trap(y, x); - break; - } + /* Trap */ + case '^': + { + /* Do nothing */ + break; + } - /* Glass wall */ - case 'G': - { - cave_set_feat(y, x, FEAT_GLASS_WALL); - break; - } + /* Glass wall */ + case 'G': + { + cave_set_feat(y, x, FEAT_GLASS_WALL); + break; + } - /* Illusion wall */ - case 'I': - { - cave_set_feat(y, x, FEAT_ILLUS_WALL); - break; + /* Illusion wall */ + case 'I': + { + cave_set_feat(y, x, FEAT_ILLUS_WALL); + break; + } } } } } /* Place dungeon monsters and objects */ - for (t = data, dy = 0; dy < ymax; dy++) { - for (dx = 0; dx < xmax; dx++, t++) + std::size_t t = 0; + for (int dy = 0; dy < ymax; dy++) { - /* Extract the grid */ - x = xval - (xmax / 2) + dx; - y = yval - (ymax / 2) + dy; - - /* Hack -- skip "non-grids" */ - if (*t == ' ') continue; - - /* Access the grid */ - c_ptr = &cave[y][x]; - - /* Analyze the symbol */ - switch (*t) + for (int dx = 0; dx < xmax; dx++, t++) { - /* Monster */ - case '&': - { - monster_level = dun_level + 5; - place_monster(y, x, TRUE, TRUE); - monster_level = dun_level; - break; - } + auto d = data[t]; - /* Meaner monster */ - case '@': - { - monster_level = dun_level + 11; - place_monster(y, x, TRUE, TRUE); - monster_level = dun_level; - break; - } + /* Hack -- skip "non-grids" */ + if (d == ' ') continue; - /* Meaner monster, plus treasure */ - case '9': - { - monster_level = dun_level + 9; - place_monster(y, x, TRUE, TRUE); - monster_level = dun_level; - object_level = dun_level + 7; - place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT); - object_level = dun_level; - break; - } + /* Extract the grid */ + int x = xval - (xmax / 2) + dx; + int y = yval - (ymax / 2) + dy; - /* Nasty monster and treasure */ - case '8': - { - monster_level = dun_level + 40; - place_monster(y, x, TRUE, TRUE); - monster_level = dun_level; - object_level = dun_level + 20; - place_object(y, x, TRUE, TRUE, OBJ_FOUND_VAULT); - object_level = dun_level; - break; - } + /* Access the grid */ + auto c_ptr = &cave[y][x]; - /* Monster and/or object */ - case ',': + /* Analyze the symbol */ + switch (d) { - if (rand_int(100) < 50) + /* Monster */ + case '&': { - monster_level = dun_level + 3; + monster_level = dun_level + 5; place_monster(y, x, TRUE, TRUE); monster_level = dun_level; + break; } - if (rand_int(100) < 50) + + /* Meaner monster */ + case '@': + { + monster_level = dun_level + 11; + place_monster(y, x, TRUE, TRUE); + monster_level = dun_level; + break; + } + + /* Meaner monster, plus treasure */ + case '9': { + monster_level = dun_level + 9; + place_monster(y, x, TRUE, TRUE); + monster_level = dun_level; object_level = dun_level + 7; - place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT); + place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT); object_level = dun_level; + break; } - break; - } - case 'p': - { - cave_set_feat(y, x, FEAT_PATTERN_START); - break; - } + /* Nasty monster and treasure */ + case '8': + { + monster_level = dun_level + 40; + place_monster(y, x, TRUE, TRUE); + monster_level = dun_level; + object_level = dun_level + 20; + place_object(y, x, TRUE, TRUE, OBJ_FOUND_VAULT); + object_level = dun_level; + break; + } - case 'a': - { - cave_set_feat(y, x, FEAT_PATTERN_1); - break; - } + /* Monster and/or object */ + case ',': + { + if (rand_int(100) < 50) + { + monster_level = dun_level + 3; + place_monster(y, x, TRUE, TRUE); + monster_level = dun_level; + } + if (rand_int(100) < 50) + { + object_level = dun_level + 7; + place_object(y, x, FALSE, FALSE, OBJ_FOUND_VAULT); + object_level = dun_level; + } + break; + } - case 'b': - { - cave_set_feat(y, x, FEAT_PATTERN_2); - break; - } + case 'p': + { + cave_set_feat(y, x, FEAT_PATTERN_START); + break; + } - case 'c': - { - cave_set_feat(y, x, FEAT_PATTERN_3); - break; - } + case 'a': + { + cave_set_feat(y, x, FEAT_PATTERN_1); + break; + } - case 'd': - { - cave_set_feat(y, x, FEAT_PATTERN_4); - break; - } + case 'b': + { + cave_set_feat(y, x, FEAT_PATTERN_2); + break; + } - case 'P': - { - cave_set_feat(y, x, FEAT_PATTERN_END); - break; - } + case 'c': + { + cave_set_feat(y, x, FEAT_PATTERN_3); + break; + } - case 'B': - { - cave_set_feat(y, x, FEAT_PATTERN_XTRA1); - break; - } + case 'd': + { + cave_set_feat(y, x, FEAT_PATTERN_4); + break; + } - case 'A': - { - object_level = dun_level + 12; - place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT); - object_level = dun_level; - break; - } + case 'P': + { + cave_set_feat(y, x, FEAT_PATTERN_END); + break; + } + case 'B': + { + cave_set_feat(y, x, FEAT_PATTERN_XTRA1); + break; + } - /* Between gates */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - /* Not found before */ - if (bwy[*t - '0'] == 9999) + case 'A': { - cave_set_feat(y, x, FEAT_BETWEEN); - bwy[*t - '0'] = y; - bwx[*t - '0'] = x; + object_level = dun_level + 12; + place_object(y, x, TRUE, FALSE, OBJ_FOUND_VAULT); + object_level = dun_level; + break; } - /* The second time */ - else + + + /* Between gates */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { - cave_set_feat(y, x, FEAT_BETWEEN); - c_ptr->special = bwx[*t - '0'] + (bwy[*t - '0'] << 8); - cave[bwy[*t - '0']][bwx[*t - '0']].special = x + (y << 8); + /* Not found before */ + if (bwy[d - '0'] == 9999) + { + cave_set_feat(y, x, FEAT_BETWEEN); + bwy[d - '0'] = y; + bwx[d - '0'] = x; + } + /* The second time */ + else + { + cave_set_feat(y, x, FEAT_BETWEEN); + c_ptr->special = bwx[d - '0'] + (bwy[d - '0'] << 8); + cave[bwy[d - '0']][bwx[d - '0']].special = x + (y << 8); + } + break; } - break; } } } @@ -3801,8 +3687,10 @@ static void build_vault(int yval, int xval, int ymax, int xmax, cptr data) */ static void build_type7(int by0, int bx0) { - vault_type *v_ptr = NULL; - int dummy = 0, xval, yval; + auto const &v_info = game->edit_data.v_info; + + auto v_ptr(v_info.end()); + int dummy = 0; /* Pick a lesser vault */ while (dummy < SAFE_MAX_ATTEMPTS) @@ -3810,22 +3698,27 @@ static void build_type7(int by0, int bx0) dummy++; /* Access a random vault record */ - v_ptr = &v_info[rand_int(max_v_idx)]; + v_ptr = uniform_element(v_info); /* Accept the first lesser vault */ if (v_ptr->typ == 7) break; } /* Try to allocate space for room. If fails, exit */ + int xval; + int yval; if (!room_alloc(v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval)) { - if (cheat_room) msg_print("Could not allocate this vault here"); + if (options->cheat_room) + { + msg_print("Could not allocate this vault here"); + } return; } if (dummy >= SAFE_MAX_ATTEMPTS) { - if (cheat_room) + if (options->cheat_room) { msg_print("Warning! Could not place lesser vault!"); } @@ -3834,7 +3727,10 @@ static void build_type7(int by0, int bx0) /* Message */ - if (cheat_room || p_ptr->precognition) msg_print("Lesser Vault"); + if (options->cheat_room || p_ptr->precognition) + { + msg_print("Lesser Vault"); + } /* Boost the rating */ rating += v_ptr->rat; @@ -3857,8 +3753,10 @@ static void build_type7(int by0, int bx0) */ static void build_type8(int by0, int bx0) { - vault_type *v_ptr = NULL; - int dummy = 0, xval, yval; + auto const &v_info = game->edit_data.v_info; + + auto v_ptr(v_info.end()); + int dummy = 0; /* Pick a lesser vault */ while (dummy < SAFE_MAX_ATTEMPTS) @@ -3866,22 +3764,27 @@ static void build_type8(int by0, int bx0) dummy++; /* Access a random vault record */ - v_ptr = &v_info[rand_int(max_v_idx)]; + v_ptr = uniform_element(v_info); /* Accept the first greater vault */ if (v_ptr->typ == 8) break; } /* Try to allocate space for room. If fails, exit */ + int xval; + int yval; if (!room_alloc(v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval)) { - if (cheat_room) msg_print("Could not allocate this vault here"); + if (options->cheat_room) + { + msg_print("Could not allocate this vault here"); + } return; } if (dummy >= SAFE_MAX_ATTEMPTS) { - if (cheat_room) + if (options->cheat_room) { msg_print("Warning! Could not place greater vault!"); } @@ -3890,7 +3793,10 @@ static void build_type8(int by0, int bx0) /* Message */ - if (cheat_room || p_ptr->precognition) msg_print("Greater Vault"); + if (options->cheat_room || p_ptr->precognition) + { + msg_print("Greater Vault"); + } /* Boost the rating */ rating += v_ptr->rat; @@ -4297,6 +4203,8 @@ static void fill_hack(int y0, int x0, int y, int x, int xsize, int ysize, bool_ generate_fracave(int y0, int x0, int xsize, int ysize, int cutoff, bool_ light, bool_ room) { + auto const &f_info = game->edit_data.f_info; + int x, y, i, amount, xhsize, yhsize; cave_type *c_ptr; @@ -4469,7 +4377,7 @@ bool_ generate_fracave(int y0, int x0, int xsize, int ysize, c_ptr = &cave[y + y0 - yhsize][x + x0 - xhsize]; /* A floor grid to be converted */ - if ((f_info[c_ptr->feat].flags1 & FF1_FLOOR) && + if ((f_info[c_ptr->feat].flags & FF_FLOOR) && (c_ptr->info & CAVE_ICKY)) { @@ -4527,7 +4435,7 @@ bool_ generate_fracave(int y0, int x0, int xsize, int ysize, /* * Makes a cave system in the center of the dungeon */ -static void build_cavern(void) +static void build_cavern() { int grd, roug, cutoff, xsize, ysize, x0, y0; bool_ done, light, room; @@ -4627,30 +4535,30 @@ static void build_small_room(int x0, int y0) { build_rectangle(y0 - 1, x0 - 1, y0 + 1, x0 + 1, feat_wall_inner, CAVE_ROOM); - /* Place a secret door on one side */ + /* Place a locked door on one side */ switch (rand_int(4)) { case 0: { - place_secret_door(y0, x0 - 1); + place_locked_door(y0, x0 - 1); break; } case 1: { - place_secret_door(y0, x0 + 1); + place_locked_door(y0, x0 + 1); break; } case 2: { - place_secret_door(y0 - 1, x0); + place_locked_door(y0 - 1, x0); break; } case 3: { - place_secret_door(y0 + 1, x0); + place_locked_door(y0 + 1, x0); break; } } @@ -4686,8 +4594,8 @@ static void add_door(int x, int y) (cave[y][x - 1].feat == feat_wall_outer) && (cave[y][x + 1].feat == feat_wall_outer)) { - /* secret door */ - place_secret_door(y, x); + /* locked door */ + place_locked_door(y, x); /* set boundarys so don't get wide doors */ place_filler(y, x - 1); @@ -4708,8 +4616,8 @@ static void add_door(int x, int y) (cave[y + 1][x].feat == feat_wall_outer) && get_is_floor(x - 1, y) && get_is_floor(x + 1, y)) { - /* secret door */ - place_secret_door(y, x); + /* locked door */ + place_locked_door(y, x); /* set boundarys so don't get wide doors */ place_filler(y - 1, x); @@ -4798,18 +4706,13 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty) { place_object(y, x, FALSE, FALSE, OBJ_FOUND_FLOOR); } - else - { - place_trap(y, x); - } } else if (value < 30) { - /* Monster and trap */ + /* Monster */ monster_level = dun_level + 5; place_monster(y, x, TRUE, TRUE); monster_level = dun_level; - place_trap(y, x); } else if (value < 40) { @@ -4829,8 +4732,7 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty) } else if (value < 50) { - /* Trap */ - place_trap(y, x); + /* Do nothing */ } else { @@ -4843,7 +4745,7 @@ static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty) } else if (rand_int(100) < 50) { - place_trap(y, x); + /* Do nothing */ } else if (rand_int(100) < 50) { @@ -4886,7 +4788,10 @@ static void build_bubble_vault(int x0, int y0, int xsize, int ysize) int xhsize = xsize / 2; int yhsize = ysize / 2; - if (cheat_room) msg_print("Bubble Vault"); + if (options->cheat_room) + { + msg_print("Bubble Vault"); + } /* Allocate center of bubbles */ center[0].x = randint(xsize - 3) + 1; @@ -5088,7 +4993,10 @@ static void build_room_vault(int x0, int y0, int xsize, int ysize) xhsize = xsize / 2; yhsize = ysize / 2; - if (cheat_room) msg_print("Room Vault"); + if (options->cheat_room) + { + msg_print("Room Vault"); + } /* Fill area so don't get problems with arena levels */ for (x1 = 0; x1 <= xsize; x1++) @@ -5146,7 +5054,10 @@ static void build_cave_vault(int x0, int y0, int xsiz, int ysiz) xsize = xhsize * 2; ysize = yhsize * 2; - if (cheat_room) msg_print("Cave Vault"); + if (options->cheat_room) + { + msg_print("Cave Vault"); + } light = done = FALSE; room = TRUE; @@ -5313,7 +5224,10 @@ static void build_maze_vault(int x0, int y0, int xsize, int ysize) cave_type *c_ptr; - if (cheat_room) msg_print("Maze Vault"); + if (options->cheat_room) + { + msg_print("Maze Vault"); + } /* Choose lite or dark */ light = (dun_level <= randint(25)); @@ -5379,7 +5293,10 @@ static void build_mini_c_vault(int x0, int y0, int xsize, int ysize) int y1, x1, y2, x2, y, x, total; int m, n, num_vertices; - if (cheat_room) msg_print("Mini Checker Board Vault"); + if (options->cheat_room) + { + msg_print("Mini Checker Board Vault"); + } /* Pick a random room size */ dy = ysize / 2 - 1; @@ -5685,7 +5602,10 @@ static void build_castle_vault(int x0, int y0, int xsize, int ysize) y2 = y0 + dy; x2 = x0 + dx; - if (cheat_room) msg_print("Castle Vault"); + if (options->cheat_room) + { + msg_print("Castle Vault"); + } /* Generate the room */ for (y = y1 - 1; y <= y2 + 1; y++) @@ -5809,7 +5729,10 @@ static void build_target_vault(int x0, int y0, int xsize, int ysize) h3 = randint(32); h4 = randint(32) - 16; - if (cheat_room) msg_print("Target Vault"); + if (options->cheat_room) + { + msg_print("Target Vault"); + } /* Work out outer radius */ if (xsize > ysize) @@ -6099,9 +6022,6 @@ static void build_type12(int by0, int bx0) /* Let's guard the treasure well */ vault_monsters(y0, x0, rand_int(2) + 3); - - /* Traps naturally */ - vault_traps(y0, x0, 4, 4, rand_int(3) + 2); } } @@ -6142,6 +6062,8 @@ static void build_type12(int by0, int bx0) */ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water) { + auto const &d_info = game->edit_data.d_info; + int i, y, x; int tmp_row, tmp_col; int row_dir, col_dir; @@ -6373,7 +6295,7 @@ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water) place_floor(y, x); /* Occasional doorway */ - if (!(dungeon_flags1 & DF1_NO_DOORS) && + if (!(dungeon_flags & DF_NO_DOORS) && (rand_int(100) < DUN_TUN_PEN)) { /* Place a random door */ @@ -6396,6 +6318,8 @@ static void build_tunnel(int row1, int col1, int row2, int col2, bool_ water) */ static int next_to_corr(int y1, int x1) { + auto const &d_info = game->edit_data.d_info; + int i, y, x, k = 0; cave_type *c_ptr; @@ -6441,19 +6365,21 @@ static int next_to_corr(int y1, int x1) */ static bool_ possible_doorway(int y, int x) { + auto const &f_info = game->edit_data.f_info; + /* Count the adjacent corridors */ if (next_to_corr(y, x) >= 2) { /* Check Vertical */ - if ((f_info[cave[y - 1][x].feat].flags1 & FF1_WALL) && - (f_info[cave[y + 1][x].feat].flags1 & FF1_WALL)) + if ((f_info[cave[y - 1][x].feat].flags & FF_WALL) && + (f_info[cave[y + 1][x].feat].flags & FF_WALL)) { return (TRUE); } /* Check Horizontal */ - if ((f_info[cave[y][x - 1].feat].flags1 & FF1_WALL) && - (f_info[cave[y][x + 1].feat].flags1 & FF1_WALL)) + if ((f_info[cave[y][x - 1].feat].flags & FF_WALL) && + (f_info[cave[y][x + 1].feat].flags & FF_WALL)) { return (TRUE); } @@ -6469,6 +6395,8 @@ static bool_ possible_doorway(int y, int x) */ static void try_doors(int y, int x) { + auto const &f_info = game->edit_data.f_info; + bool_ dir_ok[4]; int i, k, n; int yy, xx; @@ -6477,7 +6405,7 @@ static void try_doors(int y, int x) /* if (!in_bounds(y, x)) return; */ /* Some dungeons don't have doors at all */ - if (dungeon_flags1 & (DF1_NO_DOORS)) return; + if (dungeon_flags & DF_NO_DOORS) return; /* Reset tally */ n = 0; @@ -6496,7 +6424,7 @@ static void try_doors(int y, int x) if (!in_bounds(yy, xx)) continue; /* Ignore walls */ - if (f_info[cave[yy][xx].feat].flags1 & (FF1_WALL)) continue; + if (f_info[cave[yy][xx].feat].flags & FF_WALL) continue; /* Ignore room grids */ if (cave[yy][xx].info & (CAVE_ROOM)) continue; @@ -6541,7 +6469,7 @@ static void try_doors(int y, int x) /* Clear OK flags XXX */ for (i = 0; i < 4; i++) dir_ok[i] = FALSE; - /* Put one or two secret doors */ + /* Put one or two locked doors */ dir_ok[rand_int(4)] = TRUE; dir_ok[rand_int(4)] = TRUE; } @@ -6559,7 +6487,7 @@ static void try_doors(int y, int x) } } - /* Place secret door(s) */ + /* Place locked door(s) */ for (i = 0; i < 4; i++) { /* Bad location */ @@ -6569,8 +6497,8 @@ static void try_doors(int y, int x) yy = y + ddy_ddd[i]; xx = x + ddx_ddd[i]; - /* Place a secret door */ - place_secret_door(yy, xx); + /* Place a locked door */ + place_locked_door(yy, xx); } } } @@ -6585,7 +6513,7 @@ static void try_doors(int y, int x) static bool_ room_build(int y, int x, int typ) { /* Restrict level */ - if ((dun_level < roomdep[typ]) && !ironman_rooms) return (FALSE); + if ((dun_level < roomdep[typ]) && !options->ironman_rooms) return (FALSE); /* Restrict "crowded" rooms */ if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE); @@ -6700,8 +6628,10 @@ static void fill_level(bool_ use_floor, byte smooth); */ bool_ level_generate_dungeon() { + auto const &d_info = game->edit_data.d_info; + int i, k, y, x, y1, x1, branch = get_branch(); - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; int max_vault_ok = 2; @@ -6717,12 +6647,12 @@ bool_ level_generate_dungeon() } /* Check for arena level */ - if ((dungeon_flags1 & (DF1_EMPTY)) || - (empty_levels && (rand_int(EMPTY_LEVEL) == 0))) + if ((dungeon_flags & DF_EMPTY) || + (options->empty_levels && (rand_int(EMPTY_LEVEL) == 0))) { empty_level = TRUE; - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { msg_print("Arena level."); } @@ -6732,12 +6662,12 @@ bool_ level_generate_dungeon() } /* Possible cavern */ - if ((dungeon_flags1 & DF1_CAVERN) && (rand_int(dun_level / 2) > DUN_CAVERN)) + if ((dungeon_flags & DF_CAVERN) && (rand_int(dun_level / 2) > DUN_CAVERN)) { cavern = TRUE; /* Make a large fractal cave in the middle of the dungeon */ - if (cheat_room) + if (options->cheat_room) { msg_print("Cavern on level."); } @@ -6758,7 +6688,7 @@ bool_ level_generate_dungeon() if ((cur_wid != MAX_WID) || (cur_hgt != MAX_HGT)) destroyed = FALSE; /* Hack -- No destroyed levels */ - if (dungeon_flags1 & DF1_NO_DESTROY) destroyed = FALSE; + if (dungeon_flags & DF_NO_DESTROY) destroyed = FALSE; /* Actual maximum number of rooms on this level */ dun->row_rooms = cur_hgt / BLOCK_HGT; @@ -6785,7 +6715,7 @@ bool_ level_generate_dungeon() x = rand_int(dun->col_rooms); /* Align dungeon rooms */ - if (dungeon_align) + if (options->dungeon_align) { /* Slide some rooms right */ if ((x % 3) == 0) x++; @@ -6808,7 +6738,7 @@ bool_ level_generate_dungeon() x = rand_int(dun->col_rooms); /* Align dungeon rooms */ - if (dungeon_align) + if (options->dungeon_align) { /* Slide some rooms right */ if ((x % 3) == 0) x++; @@ -6833,7 +6763,7 @@ bool_ level_generate_dungeon() else { /* Attempt a "trivial" room */ - if ((dungeon_flags1 & DF1_CIRCULAR_ROOMS) && + if ((dungeon_flags & DF_CIRCULAR_ROOMS) && room_build(y, x, 9)) { continue; @@ -6847,13 +6777,13 @@ bool_ level_generate_dungeon() /* Attempt an "unusual" room -- no vaults on town levels */ if (!town_level && - (ironman_rooms || (rand_int(DUN_UNUSUAL) < dun_level))) + (options->ironman_rooms || (rand_int(DUN_UNUSUAL) < dun_level))) { /* Roll for room type */ - k = (ironman_rooms ? 0 : rand_int(100)); + k = (options->ironman_rooms ? 0 : rand_int(100)); /* Attempt a very unusual room */ /* test hack */ - if (ironman_rooms || (rand_int(DUN_UNUSUAL) < dun_level)) + if (options->ironman_rooms || (rand_int(DUN_UNUSUAL) < dun_level)) { /* Type 8 -- Greater vault (10%) */ if (k < 10) @@ -6864,7 +6794,10 @@ bool_ level_generate_dungeon() } else { - if (cheat_room) msg_print("Refusing a greater vault."); + if (options->cheat_room) + { + msg_print("Refusing a greater vault."); + } } } @@ -6877,7 +6810,10 @@ bool_ level_generate_dungeon() } else { - if (cheat_room) msg_print("Refusing a lesser vault."); + if (options->cheat_room) + { + msg_print("Refusing a lesser vault."); + } } } @@ -6908,7 +6844,7 @@ bool_ level_generate_dungeon() /* Hack - build standard rectangular rooms if needed */ if (k < 90) { - if ((dungeon_flags1 & DF1_CIRCULAR_ROOMS) && room_build(y, x, 1)) continue; + if ((dungeon_flags & DF_CIRCULAR_ROOMS) && room_build(y, x, 1)) continue; else if (room_build(y, x, 9)) continue; } @@ -6917,13 +6853,13 @@ bool_ level_generate_dungeon() } /* Attempt a trivial room */ - if (dungeon_flags1 & DF1_CAVE) + if (dungeon_flags & DF_CAVE) { if (room_build(y, x, 10)) continue; } else { - if ((dungeon_flags1 & DF1_CIRCULAR_ROOMS) && room_build(y, x, 9)) continue; + if ((dungeon_flags & DF_CIRCULAR_ROOMS) && room_build(y, x, 9)) continue; else if (room_build(y, x, 1)) continue; } } @@ -6932,7 +6868,7 @@ bool_ level_generate_dungeon() while (dun->cent_n == 0) { /* ...force the creation of a small rectangular room */ - (void)room_build(0, 0, 1); + room_build(0, 0, 1); } /* Hack -- Scramble the room order */ @@ -7007,9 +6943,12 @@ bool_ level_generate_dungeon() } /* Add some sand streamers */ - if ((dungeon_flags1 & DF1_SAND_VEIN) && !rand_int(4)) + if ((dungeon_flags & DF_SAND_VEIN) && !rand_int(4)) { - if ((cheat_room) || (p_ptr->precognition)) msg_print("Sand vein."); + if (options->cheat_room || p_ptr->precognition) + { + msg_print("Sand vein."); + } build_streamer(FEAT_SANDWALL, DUN_STR_SC); } @@ -7023,18 +6962,24 @@ bool_ level_generate_dungeon() } /* Hack -- Add some rivers if requested */ - if ((dungeon_flags1 & DF1_WATER_RIVER) && !rand_int(4)) + if ((dungeon_flags & DF_WATER_RIVER) && !rand_int(4)) { - if (cheat_room || p_ptr->precognition) msg_print("River of water."); + if (options->cheat_room || p_ptr->precognition) + { + msg_print("River of water."); + } add_river(FEAT_DEEP_WATER, FEAT_SHAL_WATER); } - if ((dungeon_flags1 & DF1_LAVA_RIVER) && !rand_int(4)) + if ((dungeon_flags & DF_LAVA_RIVER) && !rand_int(4)) { - if ((cheat_room) || (p_ptr->precognition)) msg_print("River of lava."); + if (options->cheat_room || p_ptr->precognition) + { + msg_print("River of lava."); + } add_river(FEAT_DEEP_LAVA, FEAT_SHAL_LAVA); } - if (dungeon_flags1 & DF1_WATER_RIVERS) + if (dungeon_flags & DF_WATER_RIVERS) { int max = 3 + rand_int(2); bool_ said = FALSE; @@ -7044,13 +6989,16 @@ bool_ level_generate_dungeon() if (rand_int(3) == 0) { add_river(FEAT_DEEP_WATER, FEAT_SHAL_WATER); - if (!said && ((cheat_room) || (p_ptr->precognition))) msg_print("Rivers of water."); + if (!said && (options->cheat_room || p_ptr->precognition)) + { + msg_print("Rivers of water."); + } said = TRUE; } } } - if (dungeon_flags1 & DF1_LAVA_RIVERS) + if (dungeon_flags & DF_LAVA_RIVERS) { int max = 2 + rand_int(2); bool_ said = FALSE; @@ -7060,14 +7008,17 @@ bool_ level_generate_dungeon() if (rand_int(3) == 0) { add_river(FEAT_DEEP_LAVA, FEAT_SHAL_LAVA); - if (!said && ((cheat_room) || (p_ptr->precognition))) msg_print("Rivers of lava."); + if (!said && (options->cheat_room || p_ptr->precognition)) + { + msg_print("Rivers of lava."); + } said = TRUE; } } } /* Add streamers of trees, water, or lava -KMW- */ - if (!(dungeon_flags1 & DF1_NO_STREAMERS)) + if (!(dungeon_flags & DF_NO_STREAMERS)) { int num; @@ -7076,7 +7027,7 @@ bool_ level_generate_dungeon() * * Small trees (penetrate walls) */ - if ((dungeon_flags1 & DF1_FLAT) && (randint(20) > 15)) + if ((dungeon_flags & DF_FLAT) && (randint(20) > 15)) { num = randint(DUN_STR_QUA); @@ -7233,9 +7184,11 @@ static void save_all_friends() * *hint* *hint* with this made extern, and we no longer have to * store fill_type and floor_type in the savefile... */ -static void init_feat_info(void) +static void init_feat_info() { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto const &d_info = game->edit_data.d_info; + + auto d_ptr = &d_info[dungeon_type]; int i; int cur_depth, max_depth; int p1, p2; @@ -7341,6 +7294,8 @@ static void init_feat_info(void) static void fill_level(bool_ use_floor, byte smooth) { + auto const &d_info = game->edit_data.d_info; + int y, x; int step; int shift; @@ -7591,9 +7546,15 @@ static void supersize_grid_tile(int sy, int sx, int ty, int tx) * * Note that "dun_body" adds about 4000 bytes of memory to the stack. */ -static bool_ cave_gen(void) +static bool_ cave_gen() { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto const &d_info = game->edit_data.d_info; + auto const &r_info = game->edit_data.r_info; + auto const &a_info = game->edit_data.a_info; + auto &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; + + auto d_ptr = &d_info[dungeon_type]; int max_vault_ok = 2; @@ -7606,14 +7567,16 @@ static bool_ cave_gen(void) char generator_name[100]; if (!get_dungeon_generator(generator_name)) - strnfmt(generator_name, 99, "%s", d_ptr->generator); + { + strnfmt(generator_name, sizeof(generator_name)-1, "%s", d_ptr->generator.c_str()); + } /* * We generate a double dungeon. First we should halve the desired * width/height, generate the dungeon normally, then double it * in both directions */ - if (dungeon_flags1 & DF1_DOUBLE) + if (dungeon_flags & DF_DOUBLE) { cur_wid /= 2; cur_hgt /= 2; @@ -7676,22 +7639,22 @@ static bool_ cave_gen(void) alloc_stairs(FEAT_LESS, 5, 3, branch); } - if ((dun_level < d_ptr->maxdepth) || ((dun_level == d_ptr->maxdepth) && (dungeon_flags1 & DF1_FORCE_DOWN))) + if ((dun_level < d_ptr->maxdepth) || ((dun_level == d_ptr->maxdepth) && (dungeon_flags & DF_FORCE_DOWN))) { /* Place 3 or 4 down stairs near some walls */ - alloc_stairs((dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, rand_range(3, 4), 3, 0); + alloc_stairs((dungeon_flags & DF_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, rand_range(3, 4), 3, 0); /* Place 0 or 1 down shafts near some walls */ - if (!(dungeon_flags2 & DF2_NO_SHAFT)) alloc_stairs((dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN, rand_range(0, 1), 3, 0); + if (!(dungeon_flags & DF_NO_SHAFT)) alloc_stairs((dungeon_flags & DF_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN, rand_range(0, 1), 3, 0); } - if ((dun_level > d_ptr->mindepth) || ((dun_level == d_ptr->mindepth) && (!(dungeon_flags1 & DF1_NO_UP)))) + if ((dun_level > d_ptr->mindepth) || ((dun_level == d_ptr->mindepth) && (!(dungeon_flags & DF_NO_UP)))) { /* Place 1 or 2 up stairs near some walls */ - alloc_stairs((dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, rand_range(1, 2), 3, 0); + alloc_stairs((dungeon_flags & DF_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, rand_range(1, 2), 3, 0); /* Place 0 or 1 up shafts near some walls */ - if (!(dungeon_flags2 & DF2_NO_SHAFT)) alloc_stairs((dungeon_flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP, rand_range(0, 1), 3, 0); + if (!(dungeon_flags & DF_NO_SHAFT)) alloc_stairs((dungeon_flags & DF_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP, rand_range(0, 1), 3, 0); } } @@ -7719,8 +7682,11 @@ static bool_ cave_gen(void) i = (i * cur_wid) / MAX_WID; i += 1; - if (i > small_tester) i = small_tester; - else if (cheat_hear) + if (i > small_tester) + { + i = small_tester; + } + else if (options->cheat_hear) { msg_format("Reduced monsters base from %d to %d", small_tester, i); } @@ -7731,7 +7697,7 @@ static bool_ cave_gen(void) /* Put some monsters in the dungeon */ for (i = i + k; i > 0; i--) { - (void)alloc_monster(0, TRUE); + alloc_monster(0, TRUE); } } @@ -7818,7 +7784,7 @@ static bool_ cave_gen(void) get_obj_num_hook = kind_is_legal; /* Invalidate the allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; /* Get a local object */ q_ptr = &forge; @@ -7839,7 +7805,7 @@ static bool_ cave_gen(void) /* Grant a normal artefact */ else if (a_info[fates[i].a_idx].cur_num == 0) { - artifact_type *a_ptr = &a_info[fates[i].a_idx]; + auto a_ptr = &a_info[fates[i].a_idx]; s16b I_kind; /* Get local object */ @@ -7881,20 +7847,14 @@ static bool_ cave_gen(void) } case FATE_FIND_R: { - if ((r_info[fates[i].r_idx].cur_num == 1) && (r_info[fates[i].r_idx].flags1 & RF1_UNIQUE)) fates[i].icky = TRUE; + if ((r_info[fates[i].r_idx].cur_num == 1) && (r_info[fates[i].r_idx].flags & RF_UNIQUE)) fates[i].icky = TRUE; break; } } } - /* Place traps and rubble */ - { - /* Place some traps in the dungeon */ - alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint(k * 2)); - - /* Put some rubble in corridors */ - alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k)); - } + /* Put some rubble in corridors */ + alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k)); /* Place objects and treasure */ { @@ -7956,7 +7916,7 @@ static bool_ cave_gen(void) if (m_idx && d_ptr->final_artifact && (a_info[d_ptr->final_artifact].cur_num == 0)) { - artifact_type *a_ptr = &a_info[d_ptr->final_artifact]; + auto a_ptr = &a_info[d_ptr->final_artifact]; object_type *q_ptr, forge, *o_ptr; int I_kind, o_idx; @@ -8065,7 +8025,7 @@ static bool_ cave_gen(void) wiz_lite(); /* Now double the generated dungeon */ - if (dungeon_flags1 & DF1_DOUBLE) + if (dungeon_flags & DF_DOUBLE) { /* * We begin at the bottom-right corner and move upwards @@ -8107,18 +8067,30 @@ static bool_ cave_gen(void) /* Mega-Hack */ #define REGEN_HACK 0x02 -bool_ build_special_level(void) +bool_ build_special_level() { - char buf[80]; - int y, x, ystart = 2, xstart = 2; - s16b level; + auto const &d_info = game->edit_data.d_info; + auto &level_markers = game->level_markers; /* No special levels on the surface */ - if (!dun_level) return FALSE; + if (!dun_level) + { + return FALSE; + } + + auto const level = dun_level - d_info[dungeon_type].mindepth; + + char buf[80]; + + if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type])) + { + return FALSE; + } - level = dun_level - d_info[dungeon_type].mindepth; - if ((!get_dungeon_save(buf)) && (special_lvl[level][dungeon_type])) return FALSE; - if (!get_dungeon_special(buf)) return FALSE; + if (!get_dungeon_special(buf)) + { + return FALSE; + } /* Big town */ cur_hgt = MAX_HGT; @@ -8133,9 +8105,9 @@ bool_ build_special_level(void) panel_col_min = max_panel_cols * (SCREEN_WID / 2); /* Start with perm walls */ - for (y = 0; y < cur_hgt; y++) + for (int y = 0; y < cur_hgt; y++) { - for (x = 0; x < cur_wid; x++) + for (int x = 0; x < cur_wid; x++) { cave_set_feat(y, x, FEAT_PERM_SOLID); } @@ -8147,10 +8119,12 @@ bool_ build_special_level(void) get_mon_num_prep(); init_flags = INIT_CREATE_DUNGEON | INIT_POSITION; + int ystart = 2; + int xstart = 2; process_dungeon_file(buf, &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); - special_lvl[level][dungeon_type] = REGEN_HACK; - generate_special_feeling = TRUE; + game->level_markers[level][dungeon_type] = level_marker::REGENERATE; + game->generate_special_feeling = true; /* Special feeling because it's special */ good_item_flag = TRUE; @@ -8168,53 +8142,77 @@ bool_ build_special_level(void) * Prepare regeneration of a special level, which should not happen, * but just in case... */ -static void wipe_special_level(void) +static void wipe_special_level() { - s16b level; - char buf[80]; + auto const &d_info = game->edit_data.d_info; + auto &level_markers = game->level_markers; /* No special levels on the surface */ - if (!dun_level) return; + if (!dun_level) + { + return; + } + /* Fire off hooks */ process_hooks_new(HOOK_LEVEL_REGEN, NULL, NULL); /* Calculate relative depth */ - level = dun_level - d_info[dungeon_type].mindepth; + auto const level = dun_level - d_info[dungeon_type].mindepth; - /* No special level at this depth */ - if ((!get_dungeon_save(buf)) && - special_lvl[level][dungeon_type]) return; - if (!get_dungeon_special(buf)) return; + /* No special level at this depth? */ + char buf[80]; + if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type])) + { + return; + } + if (!get_dungeon_special(buf)) + { + return; + } /* Clear the Mega-Hack flag */ - if (special_lvl[level][dungeon_type] == REGEN_HACK) - special_lvl[level][dungeon_type] = FALSE; + if (level_markers[level][dungeon_type] == level_marker::REGENERATE) + { + level_markers[level][dungeon_type] = level_marker::NORMAL; + } } /* * Finalise generation of a special level */ -static void finalise_special_level(void) +static void finalise_special_level() { - s16b level; - char buf[80]; + auto const &d_info = game->edit_data.d_info; + auto &level_markers = game->level_markers; /* No special levels on the surface */ - if (!dun_level) return; + if (!dun_level) + { + return; + } + /* Fire hooks */ process_hooks_new(HOOK_LEVEL_END_GEN, NULL, NULL); /* Calculate relative depth */ - level = dun_level - d_info[dungeon_type].mindepth; + auto const level = dun_level - d_info[dungeon_type].mindepth; - /* No special level at this depth */ - if ((!get_dungeon_save(buf)) && - special_lvl[level][dungeon_type]) return; - if (!get_dungeon_special(buf)) return; + /* No special level at this depth? */ + char buf[80]; + if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type])) + { + return; + } + if (!get_dungeon_special(buf)) + { + return; + } /* Set the "generated" flag */ - if (special_lvl[level][dungeon_type] == REGEN_HACK) - special_lvl[level][dungeon_type] = TRUE; + if (level_markers[level][dungeon_type] == level_marker::REGENERATE) + { + level_markers[level][dungeon_type] = level_marker::SPECIAL; + } } /* @@ -8229,7 +8227,7 @@ static void generate_grid_mana() { xtra_magic = TRUE; - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { msg_print("Magical level"); } @@ -8264,9 +8262,13 @@ static void generate_grid_mana() * * Hack -- allow auto-scumming via a gameplay option. */ -void generate_cave(void) +void generate_cave() { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto const &d_info = game->edit_data.d_info; + auto &a_info = game->edit_data.a_info; + auto const &level_markers = game->level_markers; + + auto d_ptr = &d_info[dungeon_type]; int tester_1, tester_2; int y, x, num, i; bool_ loaded = FALSE; @@ -8275,18 +8277,16 @@ void generate_cave(void) /* The dungeon is not ready */ character_dungeon = FALSE; - generate_special_feeling = FALSE; + game->generate_special_feeling = false; /* Initialize the flags with the basic dungeon flags */ if (!dun_level) { - dungeon_flags1 = d_info[DUNGEON_WILDERNESS].flags1; - dungeon_flags2 = d_info[DUNGEON_WILDERNESS].flags2; + dungeon_flags = d_info[DUNGEON_WILDERNESS].flags; } else { - dungeon_flags1 = d_ptr->flags1; - dungeon_flags2 = d_ptr->flags2; + dungeon_flags = d_ptr->flags; } /* Is it a town level ? */ @@ -8302,8 +8302,7 @@ void generate_cave(void) /* Seed the RNG if appropriate */ if (town_level) { - Rand_quick = TRUE; - Rand_value = town_info[town_level].seed; + set_quick_rng(town_info[town_level].seed); } process_hooks_new(HOOK_GEN_LEVEL_BEGIN, NULL, NULL); @@ -8336,8 +8335,8 @@ void generate_cave(void) /* No saved level -- generate new one */ if (!loaded) { - if (!get_dungeon_special(buf) || - !special_lvl[dun_level - d_info[dungeon_type].mindepth][dungeon_type]) + auto const level = dun_level - d_info[dungeon_type].mindepth; + if (!get_dungeon_special(buf) || is_normal_level(level_markers[level][dungeon_type])) { get_level_flags(); } @@ -8454,7 +8453,7 @@ void generate_cave(void) /* Requested size level */ if (d_ptr->size_x != -1) { - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { msg_print ("A 'size' dungeon level."); } @@ -8470,16 +8469,16 @@ void generate_cave(void) panel_row_min = max_panel_rows * (SCREEN_HGT / 2); panel_col_min = max_panel_cols * (SCREEN_WID / 2); - if (cheat_room) + if (options->cheat_room) { msg_format("X:%d, Y:%d.", max_panel_cols, max_panel_rows); } } /* Very small (1 x 1 panel) level */ - else if (!(dungeon_flags1 & DF1_BIG) && - (dungeon_flags1 & DF1_SMALLEST)) + else if (!(dungeon_flags & DF_BIG) && + (dungeon_flags & DF_SMALLEST)) { - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { msg_print ("A 'small' dungeon level."); } @@ -8495,19 +8494,19 @@ void generate_cave(void) panel_row_min = max_panel_rows * (SCREEN_HGT / 2); panel_col_min = max_panel_cols * (SCREEN_WID / 2); - if (cheat_room) + if (options->cheat_room) { msg_format("X:1, Y:1."); } } /* Small level */ - else if (!(dungeon_flags1 & DF1_BIG) && - (always_small_level || - (dungeon_flags1 & DF1_SMALL) || - (small_levels && rand_int(SMALL_LEVEL) == 0))) + else if (!(dungeon_flags & DF_BIG) && + (options->always_small_level || + (dungeon_flags & DF_SMALL) || + (options->small_levels && rand_int(SMALL_LEVEL) == 0))) { - if (cheat_room || p_ptr->precognition) + if (options->cheat_room || p_ptr->precognition) { msg_print ("A 'small' dungeon level."); } @@ -8526,7 +8525,7 @@ void generate_cave(void) panel_row_min = max_panel_rows * (SCREEN_HGT / 2); panel_col_min = max_panel_cols * (SCREEN_WID / 2); - if (cheat_room) + if (options->cheat_room) { msg_format("X:%d, Y:%d.", max_panel_cols, max_panel_rows); } @@ -8568,7 +8567,7 @@ void generate_cave(void) else feeling = 10; /* Hack -- Have a special feeling sometimes */ - if (good_item_flag && !p_ptr->preserve) feeling = 1; + if (good_item_flag && !options->preserve) feeling = 1; /* It takes 1000 game turns for "feelings" to recharge */ if ((turn - old_turn) < 1000) feeling = 0; @@ -8598,7 +8597,7 @@ void generate_cave(void) } /* Mega-Hack -- "auto-scum" */ - if (auto_scum && (num < 100) && !p_ptr->inside_quest && dun_level) + if (options->auto_scum && (num < 100) && !p_ptr->inside_quest && dun_level) { /* Require "goodness" */ if ((feeling > 9) || @@ -8608,8 +8607,8 @@ void generate_cave(void) ((dun_level >= 40) && (feeling > 5))) { /* Give message to cheaters */ - if (cheat_room || cheat_hear || - cheat_peek || cheat_xtra || p_ptr->precognition) + if (options->cheat_room || options->cheat_hear || + options->cheat_peek || options->cheat_xtra || p_ptr->precognition) { /* Message */ why = "boring level"; diff --git a/src/generate.hpp b/src/generate.hpp index d09907b5..a21ba069 100644 --- a/src/generate.hpp +++ b/src/generate.hpp @@ -2,11 +2,11 @@ #include "h-basic.h" -extern bool_ new_player_spot(int branch); -extern void add_level_generator(cptr name, bool_ (*generator)()); -extern bool_ level_generate_dungeon(); -extern bool_ generate_fracave(int y0, int x0,int xsize,int ysize,int cutoff,bool_ light,bool_ room); -extern void generate_hmap(int y0, int x0,int xsiz,int ysiz,int grd,int roug,int cutoff); -extern bool_ room_alloc(int x,int y,bool_ crowded,int by0,int bx0,int *xx,int *yy); -extern void generate_cave(void); -extern void build_rectangle(int y1, int x1, int y2, int x2, int feat, int info); +bool_ new_player_spot(int branch); +void add_level_generator(cptr name, bool_ (*generator)()); +bool_ level_generate_dungeon(); +bool_ generate_fracave(int y0, int x0,int xsize,int ysize,int cutoff,bool_ light,bool_ room); +void generate_hmap(int y0, int x0,int xsiz,int ysiz,int grd,int roug,int cutoff); +bool_ room_alloc(int x,int y,bool_ crowded,int by0,int bx0,int *xx,int *yy); +void generate_cave(); +void build_rectangle(int y1, int x1, int y2, int x2, int feat, int info); diff --git a/src/gods.cc b/src/gods.cc index 1163e9b6..82d8d300 100644 --- a/src/gods.cc +++ b/src/gods.cc @@ -7,6 +7,7 @@ */ #include "gods.hpp" +#include "game.hpp" #include "player_type.hpp" #include "skills.hpp" #include "skill_type.hpp" @@ -79,6 +80,8 @@ static bool_ may_follow_god(int god) */ void follow_god(int god, bool_ silent) { + auto &s_info = game->s_info; + /* Poor unbelievers, i'm so mean ... BOUHAHAHA */ if (get_skill(SKILL_ANTIMAGIC)) { @@ -97,8 +100,11 @@ void follow_god(int god, bool_ silent) /* Melkor offer Udun magic */ if (p_ptr->pgod == GOD_MELKOR) { - s_info[SKILL_UDUN].hidden = FALSE; - if (!silent) msg_print("You feel the dark powers of Melkor in you. You can now use the Udun skill."); + s_info[SKILL_UDUN].hidden = false; + if (!silent) + { + msg_print("You feel the dark powers of Melkor in you. You can now use the Udun skill."); + } } } } @@ -159,7 +165,6 @@ int wisdom_scale(int max) */ deity_type *god_at(byte god_idx) { - assert(god_idx >= 0); assert(god_idx < MAX_GODS); if (god_idx == 0) diff --git a/src/gods.hpp b/src/gods.hpp index 7035dd14..2a5f2bb5 100644 --- a/src/gods.hpp +++ b/src/gods.hpp @@ -2,12 +2,12 @@ #include "h-basic.h" -extern void inc_piety(int god, s32b amt); -extern void abandon_god(int god); -extern int wisdom_scale(int max); -extern int find_god(cptr name); -extern void follow_god(int god, bool_ silent); -extern bool_ god_enabled(struct deity_type *deity); -extern deity_type *god_at(byte god_idx); -extern bool_ show_god_info(); -extern bool praying_to(int god); +void inc_piety(int god, s32b amt); +void abandon_god(int god); +int wisdom_scale(int max); +int find_god(cptr name); +void follow_god(int god, bool_ silent); +bool_ god_enabled(struct deity_type *deity); +deity_type *god_at(byte god_idx); +bool_ show_god_info(); +bool praying_to(int god); diff --git a/src/grid.hpp b/src/grid.hpp new file mode 100644 index 00000000..4708811d --- /dev/null +++ b/src/grid.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include <boost/multi_array.hpp> + +/** + * 2D grid of T's. + */ +template <typename T> +struct grid { + +private: + boost::multi_array<T, 2> impl; + +public: + /** + * Get reference to tile. + */ + T &operator ()(std::size_t x, std::size_t y) + { + return impl[y][x]; + } + + /** + * Get const reference to tile. + */ + T const &operator ()(std::size_t x, std::size_t y) const + { + return impl[y][x]; + } + + /** + * Resize grid. There is no guarantee whether + * existing elements will be preserved or not. + */ + void resize(std::size_t width, std::size_t height) + { + impl.resize(boost::extents[height][width]); + } + + /** + * Get current width. + */ + std::size_t width() const + { + return impl.shape()[1]; + } + + /** + * Get current height. + */ + std::size_t height() const + { + return impl.shape()[0]; + } + + /** + * Set width. Same caveats apply as for resize(). + */ + void width(std::size_t width) + { + resize(width, height()); + } + + /** + * Set height. Same caveats apply as for resize(). + */ + void height(std::size_t height) + { + resize(width(), height); + } + +}; diff --git a/src/help.cc b/src/help.cc index a6d83079..08956f70 100644 --- a/src/help.cc +++ b/src/help.cc @@ -16,6 +16,7 @@ #include "hook_move_in.hpp" #include "hooks.hpp" #include "object1.hpp" +#include "object_flag.hpp" #include "options.hpp" #include "player_type.hpp" #include "skills.hpp" @@ -23,26 +24,24 @@ #include "variable.hpp" #define DESC_MAX 14 -#define TRIGGERED_HELP_MAX 18 +#define TRIGGERED_HELP_MAX 16 #define HELP_VOID_JUMPGATE 0 #define HELP_FOUNTAIN 1 #define HELP_FOUND_OBJECT 2 #define HELP_FOUND_ALTAR 3 #define HELP_FOUND_STAIR 4 -#define HELP_GET_RUNE 5 -#define HELP_GET_ROD 6 -#define HELP_GET_ROD_TIP 7 -#define HELP_GET_TRAP_KIT 8 -#define HELP_GET_DEVICE 9 -#define HELP_WILDERNESS 10 -#define HELP_GAME_TOME 11 -#define HELP_GAME_THEME 12 -#define HELP_1ST_LEVEL 13 -#define HELP_20TH_LEVEL 14 -#define HELP_ID_SPELL_ITM 15 -#define HELP_MELEE_SKILLS 16 -#define HELP_MON_ASK_HELP 17 +#define HELP_GET_ROD 5 +#define HELP_GET_ROD_TIP 6 +#define HELP_GET_DEVICE 7 +#define HELP_WILDERNESS 8 +#define HELP_GAME_TOME 9 +#define HELP_GAME_THEME 10 +#define HELP_1ST_LEVEL 11 +#define HELP_20TH_LEVEL 12 +#define HELP_ID_SPELL_ITM 13 +#define HELP_MELEE_SKILLS 14 +#define HELP_MON_ASK_HELP 15 /** * Game started? @@ -179,7 +178,6 @@ context_help_type class_table[] = { "Priest(Manwe)", "c_pr_man.txt", 0 }, { "Ranger", "c_ranger.txt", 0 }, { "Rogue", "c_rogue.txt", 0 }, - { "Runecrafter", "c_runecr.txt", 0 }, { "Sorceror", "c_sorcer.txt", 0 }, { "Summoner", "c_summon.txt", 0 }, { "Swordmaster", "c_swordm.txt", 0 }, @@ -199,7 +197,6 @@ context_help_type class_table[] = { "Priest(Varda)", "c_pr_varda.txt", 0 }, { "Sniper", "c_sniper.txt", 0 }, { "Stonewright", "c_stonewr.txt", 0 }, - { "Trapper", "c_trapper.txt", 0 }, { "Wainrider", "c_wainrid.txt", 0 }, { "War-mage", "c_warmage.txt", 0 }, /* End of list */ @@ -268,7 +265,6 @@ context_help_type skill_table[] = { "Polearm-mastery", "skills.txt", 7 }, { "Possession", "skills.txt", 45 }, { "Prayer", "skills.txt", 39 }, - { "Runecraft", "skills.txt", 36 }, { "Sling-mastery", "skills.txt", 9 }, { "Sneakiness", "skills.txt", 14 }, { "Spell-power", "skills.txt", 22 }, @@ -301,7 +297,6 @@ context_help_type ability_table[] = { "Ammo creation", "ability.txt", 7 }, { "Touch of death", "ability.txt", 8 }, { "Far reaching attack", "ability.txt", 10 }, - { "Trapping", "ability.txt", 11 }, { "Undead Form", "ability.txt", 12 }, { NULL, NULL, 0 }, }; @@ -335,12 +330,6 @@ static bool_ trigger_found_stairs(void *in, void *out) { return (cave[p->y][p->x].feat == FEAT_MORE); } -static bool_ trigger_get_rune(void *in, void *out) { - hook_get_in *g = (hook_get_in *) in; - return ((g->o_ptr->tval == TV_RUNE1) || - (g->o_ptr->tval == TV_RUNE2)); -} - static bool_ trigger_get_rod(void *in, void *out) { hook_get_in *g = (hook_get_in *) in; return (g->o_ptr->tval == TV_ROD_MAIN); @@ -351,11 +340,6 @@ static bool_ trigger_get_rod_tip(void *in, void *out) { return (g->o_ptr->tval == TV_ROD); } -static bool_ trigger_get_trap_kit(void *in, void *out) { - hook_get_in *g = (hook_get_in *) in; - return (g->o_ptr->tval == TV_TRAPKIT); -} - static bool_ trigger_get_magic_device(void *in, void *out) { hook_get_in *g = (hook_get_in *) in; return ((g->o_ptr->tval == TV_WAND) || @@ -389,9 +373,8 @@ static bool_ trigger_identify_spell_item(void *in_, void *out) { if (in->mode == IDENT_FULL) { - u32b f1, f2, f3, f4, f5, esp; - object_flags(in->o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f5 & TR5_SPELL_CONTAIN) + auto const f = object_flags(in->o_ptr); + if (f & TR_SPELL_CONTAIN) { return TRUE; } @@ -452,14 +435,6 @@ static triggered_help_type triggered_help[TRIGGERED_HELP_MAX] = "But be ready to fight what lies within, for it might not be too friendly.", NULL } }, - { HELP_GET_RUNE, - HOOK_GET, - trigger_get_rune, - { "Ah, a rune! Runes are used with the Runecraft skill to allow you to", - "create spells on your own.", - NULL - } - }, { HELP_GET_ROD, HOOK_GET, trigger_get_rod, @@ -479,16 +454,6 @@ static triggered_help_type triggered_help[TRIGGERED_HELP_MAX] = NULL } }, - { HELP_GET_TRAP_KIT, - HOOK_GET, - trigger_get_trap_kit, - { "Ooooh, a trapping kit. If you have ability in the trapping skill,", - "you can lay this trap (via the 'm' key) to harm unsuspecting foes.", - "You'll generally need either some ammo or magic device depending", - "on the exact type of trap kit.", - NULL - } - }, { HELP_GET_DEVICE, HOOK_GET, trigger_get_magic_device, @@ -593,33 +558,31 @@ static triggered_help_type triggered_help[TRIGGERED_HELP_MAX] = } }; -static bool_ triggered_help_hook(void *data, void *in, void *out) +static bool triggered_help_hook(void *data, void *in, void *out) { triggered_help_type *triggered_help = (triggered_help_type *) data; /* Not triggered before and trigger now? */ - if ((option_ingame_help) && + if (options->ingame_help && (!p_ptr->help.activated[triggered_help->help_index]) && triggered_help->trigger_func(in,out)) { - int i; - /* Triggered */ - p_ptr->help.activated[triggered_help->help_index] = TRUE; + p_ptr->help.activated[triggered_help->help_index] = true; /* Show the description */ - for (i = 0; (i < DESC_MAX) && (triggered_help->desc[i] != NULL); i++) + for (std::size_t i = 0; (i < DESC_MAX) && (triggered_help->desc[i] != NULL); i++) { cmsg_print(TERM_YELLOW, triggered_help->desc[i]); } } /* Don't stop processing */ - return FALSE; + return false; } -static bool_ hook_game_start(void *data, void *in, void *out) +static bool hook_game_start(void *data, void *in, void *out) { game_started = TRUE; - return FALSE; + return false; } static void setup_triggered_help_hook(int i) @@ -674,7 +637,7 @@ static void show_context_help(context_help_type *context_help) screen_save(); - show_file(context_help->file_name, 0, -context_help->anchor, 0); + show_file(context_help->file_name, 0, -context_help->anchor); screen_load(); } @@ -705,19 +668,19 @@ static context_help_type *find_context_help(context_help_type table[], cptr key) /* * Racial help */ -void help_race(cptr race) +void help_race(std::string const &race) { - show_context_help(find_context_help(race_table, race)); + show_context_help(find_context_help(race_table, race.c_str())); } -void help_subrace(cptr subrace) +void help_subrace(std::string const &subrace) { - show_context_help(find_context_help(subrace_table, subrace)); + show_context_help(find_context_help(subrace_table, subrace.c_str())); } -void help_class(cptr klass) +void help_class(std::string const &klass) { - show_context_help(find_context_help(class_table, klass)); + show_context_help(find_context_help(class_table, klass.c_str())); } void help_god(cptr god) @@ -731,12 +694,12 @@ void help_god(cptr god) } } -void help_skill(cptr skill) +void help_skill(const std::string &skill) { - show_context_help(find_context_help(skill_table, skill)); + show_context_help(find_context_help(skill_table, skill.c_str())); } -void help_ability(cptr ability) +void help_ability(std::string const &ability) { - show_context_help(find_context_help(ability_table, ability)); + show_context_help(find_context_help(ability_table, ability.c_str())); } diff --git a/src/help.hpp b/src/help.hpp index 7c057a01..a805a62b 100644 --- a/src/help.hpp +++ b/src/help.hpp @@ -2,10 +2,12 @@ #include "h-basic.h" -extern void init_hooks_help(); -extern void help_race(cptr race); -extern void help_subrace(cptr subrace); -extern void help_class(cptr klass); -extern void help_god(cptr god); -extern void help_skill(cptr skill); -extern void help_ability(cptr ability); +#include <string> + +void init_hooks_help(); +void help_race(std::string const &race); +void help_subrace(std::string const &subrace); +void help_class(std::string const &klass); +void help_god(cptr god); +void help_skill(std::string const &skill); +void help_ability(std::string const &ability); diff --git a/src/help_info.hpp b/src/help_info.hpp index ea440bb9..1b4a3757 100644 --- a/src/help_info.hpp +++ b/src/help_info.hpp @@ -12,6 +12,6 @@ constexpr int HELP_MAX = 64; */ struct help_info { - bool_ enabled; /* ingame help enabled */ - bool_ activated[HELP_MAX]; /* help item #i activated? */ + bool enabled = false; /* ingame help enabled */ + bool activated[HELP_MAX] = { false }; /* help item #i activated? */ }; diff --git a/src/hiscore.hpp b/src/hiscore.hpp index 0b1b713d..990c91aa 100644 --- a/src/hiscore.hpp +++ b/src/hiscore.hpp @@ -36,7 +36,6 @@ struct high_score char unused_1[8]; /* Kept for compatibility only */ - char sex[2]; /* Player Sex (string) */ char p_r[3]; /* Player Race (number) */ char p_s[3]; /* Player Subrace (number) */ char p_c[3]; /* Player Class (number) */ diff --git a/src/hist_type.hpp b/src/hist_type.hpp deleted file mode 100644 index 2da47b7c..00000000 --- a/src/hist_type.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "h-basic.h" - -/** - * Player background descriptor. - */ -struct hist_type -{ - char *info; /* Textual History */ - - byte roll; /* Frequency of this entry */ - s16b chart; /* Chart index */ - s16b next; /* Next chart index */ - byte bonus; /* Social Class Bonus + 50 */ -}; diff --git a/src/hist_type_fwd.hpp b/src/hist_type_fwd.hpp deleted file mode 100644 index d1cbce91..00000000 --- a/src/hist_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct hist_type; diff --git a/src/hooks.cc b/src/hooks.cc index 4fcc39d3..bd2ea905 100644 --- a/src/hooks.cc +++ b/src/hooks.cc @@ -81,7 +81,7 @@ void del_hook_new(int h_idx, hook_func_t hook_func) } } -bool_ process_hooks_new(int h_idx, void *in, void *out) +bool process_hooks_new(int h_idx, void *in, void *out) { auto const &hooks = hooks_instance()[h_idx]; @@ -94,7 +94,7 @@ bool_ process_hooks_new(int h_idx, void *in, void *out) returns TRUE */ if (hook_data.invoke(in, out)) { - return TRUE; + return true; } /* Should we restart processing at the beginning? */ @@ -109,5 +109,5 @@ bool_ process_hooks_new(int h_idx, void *in, void *out) } } - return FALSE; + return false; } diff --git a/src/hooks.hpp b/src/hooks.hpp index b6124e6a..7cf4285b 100644 --- a/src/hooks.hpp +++ b/src/hooks.hpp @@ -2,9 +2,9 @@ #include "h-basic.h" -typedef bool_ (*hook_func_t)(void *, void *, void *); +typedef bool (*hook_func_t)(void *, void *, void *); -extern void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data); -extern void del_hook_new(int h_idx, hook_func_t hook_func); +void add_hook_new(int h_idx, hook_func_t hook_func, cptr name, void *data); +void del_hook_new(int h_idx, hook_func_t hook_func); extern int process_hooks_restart; -extern bool_ process_hooks_new(int h_idx, void *in, void *out); +bool process_hooks_new(int h_idx, void *in, void *out); diff --git a/src/include/tome/enum_string_map.hpp b/src/include/tome/enum_string_map.hpp index 8ae1e115..814827fe 100644 --- a/src/include/tome/enum_string_map.hpp +++ b/src/include/tome/enum_string_map.hpp @@ -29,20 +29,20 @@ public: assert(bimap.size() == in.size()); } - const char *stringify(E e) { + const char *stringify(E e) const { auto i = bimap.left.find(e); assert(i != bimap.left.end() && "Missing mapping for enumerated value"); return i->second.c_str(); } - E parse(const char *s) { + E parse(const char *s) const { E e; bool result = parse(s, &e); assert(result && "Missing string->enum mapping"); return e; } - bool parse(const char *s, E *e) { + bool parse(const char *s, E *e) const { auto i = bimap.right.find(s); if (i == bimap.right.end()) { diff --git a/src/include/tome/pp/global_constexpr.hpp b/src/include/tome/pp/global_constexpr.hpp new file mode 100644 index 00000000..83168c59 --- /dev/null +++ b/src/include/tome/pp/global_constexpr.hpp @@ -0,0 +1,21 @@ +#pragma once + +/** + * Macro for declaring a global constexpr variable without + * violating the ODR and without running into the SIOF. + * + * Shamelessly cribbed from http://stackoverflow.com/a/20374473 + */ +#define PP_GLOBAL_CONSTEXPR_CONST(type, var, value) \ +namespace global_constexpr { namespace var { \ +template<class = void> \ +struct wrapper \ +{ \ + static constexpr type var = value; \ +}; \ +template<class T> \ +constexpr type wrapper<T>::var; \ +} } \ +namespace { \ +auto const& var = global_constexpr::var::wrapper<>::var; \ +} diff --git a/src/include/tome/squelch/automatizer.hpp b/src/include/tome/squelch/automatizer.hpp index 786ca1ae..833b5648 100644 --- a/src/include/tome/squelch/automatizer.hpp +++ b/src/include/tome/squelch/automatizer.hpp @@ -2,8 +2,8 @@ #include <boost/noncopyable.hpp> #include <memory> +#include <jsoncons/json.hpp> #include <vector> -#include <jansson.h> #include "tome/squelch/rule_fwd.hpp" #include "tome/squelch/cursor_fwd.hpp" @@ -44,15 +44,14 @@ public: bool apply_rules(object_type *o_ptr, int item_idx) const; /** - * Build a JSON data structure to represent - * all the rules. + * Build a JSON document to represent all the rules. */ - std::shared_ptr<json_t> to_json() const; + jsoncons::json to_json() const; /** - * Load rules from a JSON data structure. + * Load rules from a JSON document. */ - void load_json(json_t *json); + void load_json(jsoncons::json const &); /** * Remove currently selected condition or rule. @@ -115,10 +114,9 @@ public: void add_new_condition(std::function<std::shared_ptr<Condition> ()> factory); /** - * Get rule names. The names are not stable across multiple - * calls to methods on this class. + * Get rule names. */ - void get_rule_names(std::vector<const char *> *names) const; + std::vector<std::string> get_rule_names() const; /** * Get current number of rules. diff --git a/src/include/tome/squelch/condition.hpp b/src/include/tome/squelch/condition.hpp index 5d1240f5..584ecb0e 100644 --- a/src/include/tome/squelch/condition.hpp +++ b/src/include/tome/squelch/condition.hpp @@ -3,10 +3,10 @@ #include "tome/squelch/condition_fwd.hpp" #include <boost/noncopyable.hpp> +#include <cstdint> #include <functional> #include <memory> -#include <cstdint> -#include <jansson.h> +#include <jsoncons/json.hpp> #include "tome/squelch/cursor_fwd.hpp" #include "tome/squelch/tree_printer_fwd.hpp" @@ -60,7 +60,7 @@ public: } public: - json_t *to_json() const; + jsoncons::json to_json() const; virtual void add_child(ConditionFactory const &factory) { // Default is to not support children. @@ -88,16 +88,16 @@ public: /** * Parse condition from JSON */ - static std::shared_ptr<Condition> parse_condition(json_t *); + static std::shared_ptr<Condition> parse_condition(jsoncons::json const &); /** * Convert an (optional) condition to JSON. */ - static json_t *optional_to_json(std::shared_ptr<Condition> condition); + static jsoncons::json optional_to_json(std::shared_ptr<Condition> condition); protected: virtual void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const = 0; - virtual void to_json(json_t *) const = 0; + virtual void to_json(jsoncons::json &) const = 0; // What do we want to match? match_type match; @@ -116,12 +116,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: uint8_t m_tval; @@ -140,12 +140,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_name; @@ -164,12 +164,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_contain; @@ -189,12 +189,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: uint8_t m_min; @@ -228,10 +228,10 @@ public: virtual std::shared_ptr<Condition> next_child(Condition *current) override; // Parse a list of conditions from JSON property - static std::vector< std::shared_ptr<Condition> > parse_conditions(json_t *); + static std::vector< std::shared_ptr<Condition> > parse_conditions(jsoncons::json const &); protected: - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; protected: std::vector< std::shared_ptr<Condition> > m_conditions; @@ -248,7 +248,7 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; @@ -265,7 +265,7 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; @@ -285,12 +285,12 @@ public: public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: status_type m_status; @@ -309,12 +309,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_race; @@ -333,12 +333,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_subrace; @@ -357,12 +357,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_class; @@ -381,12 +381,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: std::string m_inscription; @@ -406,12 +406,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: int m_min; @@ -432,12 +432,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: int m_min; @@ -459,12 +459,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: uint16_t m_skill_idx; @@ -485,12 +485,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: identification_state m_state; @@ -509,12 +509,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: char m_symbol; @@ -533,12 +533,12 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; private: uint16_t m_ability_idx; @@ -563,10 +563,10 @@ public: virtual std::shared_ptr<Condition> first_child() override; protected: - void to_json(json_t *) const override; + void to_json(jsoncons::json &) const override; static std::shared_ptr<Condition> parse_single_subcondition( - json_t *condition_json); + jsoncons::json const &condition_json); protected: std::shared_ptr<Condition> m_subcondition; @@ -584,7 +584,7 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; @@ -603,7 +603,7 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: @@ -623,7 +623,7 @@ public: bool is_match(object_type *) const override; - static std::shared_ptr<Condition> from_json(json_t *); + static std::shared_ptr<Condition> from_json(jsoncons::json const &); protected: void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override; diff --git a/src/include/tome/squelch/rule.hpp b/src/include/tome/squelch/rule.hpp index 63f1b6c0..af86dfc8 100644 --- a/src/include/tome/squelch/rule.hpp +++ b/src/include/tome/squelch/rule.hpp @@ -1,7 +1,7 @@ #pragma once -#include <jansson.h> #include <memory> +#include <jsoncons/json.hpp> #include "tome/squelch/condition_fwd.hpp" #include "tome/squelch/cursor_fwd.hpp" @@ -40,12 +40,12 @@ public: /** * Set the name of the rule */ - void set_name(const char *new_name); + void set_name(const std::string &new_name); /** * Get the name of the rule */ - const char *get_name() const; + std::string get_name() const; /** * Get condition @@ -75,14 +75,14 @@ public: bool apply_rule(object_type *o_ptr, int item_idx) const; /** - * Convert rule to JSON + * Convert rule to JSON. */ - virtual json_t *to_json() const; + virtual jsoncons::json to_json() const; /** * Parse rule from JSON */ - static std::shared_ptr<Rule> parse_rule(json_t *); + static std::shared_ptr<Rule> parse_rule(jsoncons::json const &); protected: virtual bool do_apply_rule(object_type *, int) const = 0; @@ -148,7 +148,7 @@ public: , m_inscription(inscription) { } - json_t *to_json() const override; + jsoncons::json to_json() const override; protected: virtual void do_write_tree(TreePrinter *p) const override; diff --git a/src/include/tome/squelch/tree_printer.hpp b/src/include/tome/squelch/tree_printer.hpp index e8ee1e56..c9e79af2 100644 --- a/src/include/tome/squelch/tree_printer.hpp +++ b/src/include/tome/squelch/tree_printer.hpp @@ -3,6 +3,7 @@ #include <boost/noncopyable.hpp> #include <cstdint> +#include <string> namespace squelch { @@ -30,7 +31,8 @@ public: void scroll_right(); - void write(uint8_t color, const char *line); + void write(uint8_t color, const char *); + void write(uint8_t color, std::string const &); private: int m_indent; diff --git a/src/init1.cc b/src/init1.cc index 7083a5f3..e367f603 100644 --- a/src/init1.cc +++ b/src/init1.cc @@ -5,53 +5,69 @@ #include "cave.hpp" #include "cave_type.hpp" #include "dungeon_info_type.hpp" +#include "dungeon_flag.hpp" +#include "ego_flag.hpp" #include "ego_item_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "gods.hpp" -#include "hist_type.hpp" #include "init2.hpp" -#include "meta_class_type.hpp" #include "monster2.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell.hpp" #include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" +#include "object_flag_meta.hpp" #include "object_kind.hpp" -#include "owner_type.hpp" #include "player_class.hpp" #include "player_race.hpp" +#include "player_race_flag.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" -#include "randart_gen_type.hpp" -#include "randart_part_type.hpp" #include "set_type.hpp" +#include "skill_flag.hpp" #include "skill_type.hpp" #include "skills.hpp" #include "spells5.hpp" -#include "store_action_type.hpp" +#include "store_flag.hpp" #include "store_info_type.hpp" -#include "store_type.hpp" #include "tables.hpp" #include "town_type.hpp" -#include "trap_type.hpp" -#include "traps.hpp" #include "util.hpp" #include "util.h" #include "variable.h" #include "variable.hpp" -#include "vault_type.hpp" -#include "wilderness_map.hpp" #include "wilderness_type_info.hpp" #include "z-rand.hpp" #include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/split.hpp> using boost::algorithm::iequals; using boost::algorithm::ends_with; +/** + * Expand vector such that it has room for an item at index i. + * If the vector is already large enough, nothing happens. + */ +template <class T> typename std::vector<T>::reference expand_to_fit_index(std::vector<T> &v, std::size_t i) +{ + if (v.size() < i + 1) + { + v.resize(i + 1); + } + return v[i]; +} + + /* * This file is used to initialize various variables and arrays for the * Angband game. Note the use of "fd_read()" and "fd_write()" to bypass @@ -151,981 +167,77 @@ static cptr r_info_blow_effect[] = /* - * Monster race flags - */ -static cptr r_info_flags1[] = -{ - "UNIQUE", - "QUESTOR", - "MALE", - "FEMALE", - "CHAR_CLEAR", - "CHAR_MULTI", - "ATTR_CLEAR", - "ATTR_MULTI", - "FORCE_DEPTH", - "FORCE_MAXHP", - "FORCE_SLEEP", - "FORCE_EXTRA", - "FRIEND", - "FRIENDS", - "ESCORT", - "ESCORTS", - "NEVER_BLOW", - "NEVER_MOVE", - "RAND_25", - "RAND_50", - "ONLY_GOLD", - "ONLY_ITEM", - "DROP_60", - "DROP_90", - "DROP_1D2", - "DROP_2D2", - "DROP_3D2", - "DROP_4D2", - "DROP_GOOD", - "DROP_GREAT", - "DROP_USEFUL", - "DROP_CHOSEN" -}; - -/* - * Monster race flags - */ -static cptr r_info_flags2[] = -{ - "STUPID", - "SMART", - "CAN_SPEAK", - "REFLECTING", - "INVISIBLE", - "COLD_BLOOD", - "EMPTY_MIND", - "WEIRD_MIND", - "DEATH_ORB", - "REGENERATE", - "SHAPECHANGER", - "ATTR_ANY", - "POWERFUL", - "ELDRITCH_HORROR", - "AURA_FIRE", - "AURA_ELEC", - "OPEN_DOOR", - "BASH_DOOR", - "PASS_WALL", - "KILL_WALL", - "MOVE_BODY", - "KILL_BODY", - "TAKE_ITEM", - "KILL_ITEM", - "BRAIN_1", - "BRAIN_2", - "BRAIN_3", - "BRAIN_4", - "BRAIN_5", - "BRAIN_6", - "BRAIN_7", - "BRAIN_8" -}; - -/* - * Monster race flags - */ -static cptr r_info_flags3[] = -{ - "ORC", - "TROLL", - "GIANT", - "DRAGON", - "DEMON", - "UNDEAD", - "EVIL", - "ANIMAL", - "THUNDERLORD", - "GOOD", - "AURA_COLD", /* TODO: Implement aura_cold */ - "NONLIVING", - "HURT_LITE", - "HURT_ROCK", - "SUSCEP_FIRE", - "SUSCEP_COLD", - "IM_ACID", - "IM_ELEC", - "IM_FIRE", - "IM_COLD", - "IM_POIS", - "RES_TELE", - "RES_NETH", - "RES_WATE", - "RES_PLAS", - "RES_NEXU", - "RES_DISE", - "UNIQUE_4", - "NO_FEAR", - "NO_STUN", - "NO_CONF", - "NO_SLEEP" -}; - -/* - * Monster race flags - */ -static cptr r_info_flags4[] = -{ - "SHRIEK", - "MULTIPLY", - "S_ANIMAL", - "ROCKET", - "ARROW_1", - "ARROW_2", - "ARROW_3", - "ARROW_4", - "BR_ACID", - "BR_ELEC", - "BR_FIRE", - "BR_COLD", - "BR_POIS", - "BR_NETH", - "BR_LITE", - "BR_DARK", - "BR_CONF", - "BR_SOUN", - "BR_CHAO", - "BR_DISE", - "BR_NEXU", - "BR_TIME", - "BR_INER", - "BR_GRAV", - "BR_SHAR", - "BR_PLAS", - "BR_WALL", - "BR_MANA", - "BA_NUKE", - "BR_NUKE", - "BA_CHAO", - "BR_DISI", -}; - -/* - * Monster race flags - */ -static cptr r_info_flags5[] = -{ - "BA_ACID", - "BA_ELEC", - "BA_FIRE", - "BA_COLD", - "BA_POIS", - "BA_NETH", - "BA_WATE", - "BA_MANA", - "BA_DARK", - "DRAIN_MANA", - "MIND_BLAST", - "BRAIN_SMASH", - "CAUSE_1", - "CAUSE_2", - "CAUSE_3", - "CAUSE_4", - "BO_ACID", - "BO_ELEC", - "BO_FIRE", - "BO_COLD", - "BO_POIS", - "BO_NETH", - "BO_WATE", - "BO_MANA", - "BO_PLAS", - "BO_ICEE", - "MISSILE", - "SCARE", - "BLIND", - "CONF", - "SLOW", - "HOLD" -}; - -/* - * Monster race flags - */ -static cptr r_info_flags6[] = -{ - "HASTE", - "HAND_DOOM", - "HEAL", - "S_ANIMALS", - "BLINK", - "TPORT", - "TELE_TO", - "TELE_AWAY", - "TELE_LEVEL", - "DARKNESS", - "TRAPS", - "FORGET", - "ANIM_DEAD", /* ToDo: Implement ANIM_DEAD */ - "S_BUG", - "S_RNG", - "S_THUNDERLORD", /* DG : Summon Thunderlord */ - "S_KIN", - "S_HI_DEMON", - "S_MONSTER", - "S_MONSTERS", - "S_ANT", - "S_SPIDER", - "S_HOUND", - "S_HYDRA", - "S_ANGEL", - "S_DEMON", - "S_UNDEAD", - "S_DRAGON", - "S_HI_UNDEAD", - "S_HI_DRAGON", - "S_WRAITH", - "S_UNIQUE" -}; - - -/* - * Monster race flags - */ -static cptr r_info_flags7[] = -{ - "AQUATIC", - "CAN_SWIM", - "CAN_FLY", - "FRIENDLY", - "PET", - "MORTAL", - "SPIDER", - "NAZGUL", - "DG_CURSE", - "POSSESSOR", - "NO_DEATH", - "NO_TARGET", - "AI_ANNOY", - "AI_SPECIAL", - "NEUTRAL", - "DROP_ART", - "DROP_RANDART", - "AI_PLAYER", - "NO_THEFT", - "SPIRIT", - "XXX7X20", - "XXX7X21", - "XXX7X22", - "XXX7X23", - "XXX7X24", - "XXX7X25", - "XXX7X26", - "XXX7X27", - "XXX7X28", - "XXX7X29", - "XXX7X30", - "XXX7X31", -}; - -/* - * Monster race flags - */ -static cptr r_info_flags8[] = -{ - "WILD_ONLY", - "WILD_TOWN", - "XXX8X02", - "WILD_SHORE", - "WILD_OCEAN", - "WILD_WASTE", - "WILD_WOOD", - "WILD_VOLCANO", - "XXX8X08", - "WILD_MOUNTAIN", - "WILD_GRASS", - "NO_CUT", - "CTHANGBAND", - "XXX8X13", - "ZANGBAND", - "JOKEANGBAND", - "BASEANGBAND", - "XXX8X17", - "XXX8X18", - "XXX8X19", - "XXX8X20", - "XXX8X21", - "XXX8X22", - "XXX8X23", - "XXX8X24", - "XXX8X25", - "XXX8X26", - "XXX8X27", - "XXX8X28", - "XXX8X29", - "WILD_SWAMP", /* ToDo: Implement Swamp */ - "WILD_TOO", -}; - - -/* - * Monster race flags - Drops - */ -static cptr r_info_flags9[] = -{ - "DROP_CORPSE", - "DROP_SKELETON", - "HAS_LITE", - "MIMIC", - "HAS_EGG", - "IMPRESED", - "SUSCEP_ACID", - "SUSCEP_ELEC", - "SUSCEP_POIS", - "KILL_TREES", - "WYRM_PROTECT", - "DOPPLEGANGER", - "ONLY_DEPTH", - "SPECIAL_GENE", - "NEVER_GENE", - "XXX9X15", - "XXX9X16", - "XXX9X17", - "XXX9X18", - "XXX9X19", - "XXX9X20", - "XXX9X21", - "XXX9X22", - "XXX9X23", - "XXX9X24", - "XXX9X25", - "XXX9X26", - "XXX9X27", - "XXX9X28", - "XXX9X29", - "XXX9X30", - "XXX9X31", -}; - - -/* - * Object flags + * Helpers for looking up flags in the above arrays + * and extracting "bitmasks" from them. */ -cptr k_info_flags1[] = -{ - "STR", - "INT", - "WIS", - "DEX", - "CON", - "CHR", - "MANA", - "SPELL", - "STEALTH", - "SEARCH", - "INFRA", - "TUNNEL", - "SPEED", - "BLOWS", - "CHAOTIC", - "VAMPIRIC", - "SLAY_ANIMAL", - "SLAY_EVIL", - "SLAY_UNDEAD", - "SLAY_DEMON", - "SLAY_ORC", - "SLAY_TROLL", - "SLAY_GIANT", - "SLAY_DRAGON", - "KILL_DRAGON", - "VORPAL", - "IMPACT", - "BRAND_POIS", - "BRAND_ACID", - "BRAND_ELEC", - "BRAND_FIRE", - "BRAND_COLD" -}; -/* - * Object flags - */ -cptr k_info_flags2[] = -{ - "SUST_STR", - "SUST_INT", - "SUST_WIS", - "SUST_DEX", - "SUST_CON", - "SUST_CHR", - "INVIS", - "LIFE", - "IM_ACID", - "IM_ELEC", - "IM_FIRE", - "IM_COLD", - "SENS_FIRE", - "REFLECT", - "FREE_ACT", - "HOLD_LIFE", - "RES_ACID", - "RES_ELEC", - "RES_FIRE", - "RES_COLD", - "RES_POIS", - "RES_FEAR", - "RES_LITE", - "RES_DARK", - "RES_BLIND", - "RES_CONF", - "RES_SOUND", - "RES_SHARDS", - "RES_NETHER", - "RES_NEXUS", - "RES_CHAOS", - "RES_DISEN" -}; +namespace { // anonymous -/* - * Trap flags - */ -cptr k_info_flags2_trap[] = -{ - "AUTOMATIC_5", - "AUTOMATIC_99", - "KILL_GHOST", - "TELEPORT_TO", - "ONLY_DRAGON", - "ONLY_DEMON", - "XXX3", - "XXX3", - "ONLY_ANIMAL", - "ONLY_UNDEAD", - "ONLY_EVIL", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", - "XXX3", -}; +namespace detail { - -/* - * Object flags - */ -cptr k_info_flags3[] = -{ - "SH_FIRE", - "SH_ELEC", - "AUTO_CURSE", - "DECAY", - "NO_TELE", - "NO_MAGIC", - "WRAITH", - "TY_CURSE", - "EASY_KNOW", - "HIDE_TYPE", - "SHOW_MODS", - "INSTA_ART", - "FEATHER", - "LITE1", - "SEE_INVIS", - "NORM_ART", - "SLOW_DIGEST", - "REGEN", - "XTRA_MIGHT", - "XTRA_SHOTS", - "IGNORE_ACID", - "IGNORE_ELEC", - "IGNORE_FIRE", - "IGNORE_COLD", - "ACTIVATE", - "DRAIN_EXP", - "TELEPORT", - "AGGRAVATE", - "BLESSED", - "CURSED", - "HEAVY_CURSE", - "PERMA_CURSE" -}; - -/* - * Object flags - */ -cptr k_info_flags4[] = -{ - "NEVER_BLOW", - "PRECOGNITION", - "BLACK_BREATH", - "RECHARGE", - "FLY", - "DG_CURSE", - "COULD2H", - "MUST2H", - "LEVELS", - "CLONE", - "SPECIAL_GENE", - "CLIMB", - "FAST_CAST", - "CAPACITY", - "CHARGING", - "CHEAPNESS", - "FOUNTAIN", - "ANTIMAGIC_50", - "XXX5", - "XXX5", - "XXX5", - "EASY_USE", - "IM_NETHER", - "RECHARGED", - "ULTIMATE", - "AUTO_ID", - "LITE2", - "LITE3", - "FUEL_LITE", - "XXX5", - "CURSE_NO_DROP", - "NO_RECHARGE" -}; - -/* - * Object flags - */ -cptr k_info_flags5[] = -{ - "TEMPORARY", - "DRAIN_MANA", - "DRAIN_HP", - "KILL_DEMON", - "KILL_UNDEAD", - "CRIT", - "ATTR_MULTI", - "WOUNDING", - "FULL_NAME", - "LUCK", - "IMMOVABLE", - "SPELL_CONTAIN", - "RES_MORGUL", - "ACTIVATE_NO_WIELD", - "MAGIC_BREATH", - "WATER_BREATH", - "WIELD_CAST", - "XXX8X17", - "XXX8X18", - "XXX8X19", - "XXX8X20", - "XXX8X21", - "XXX8X22", - "XXX8X23", - "XXX8X24", - "XXX8X25", - "XXX8X26", - "XXX8X27", - "XXX8X28", - "XXX8X29", - "XXX8X02", - "XXX8X22", -}; - -/* - * ESP flags +/** + * A "tie" (see e.g. std::tuple) between a "flags" value pointer and its + * corresponding array of text strings. Implementation detail. */ -cptr esp_flags[] = -{ - "ESP_ORC", - "ESP_TROLL", - "ESP_DRAGON", - "ESP_GIANT", - "ESP_DEMON", - "ESP_UNDEAD", - "ESP_EVIL", - "ESP_ANIMAL", - "ESP_THUNDERLORD", - "ESP_GOOD", - "ESP_NONLIVING", - "ESP_UNIQUE", - "ESP_SPIDER", - "XXX8X02", - "XXX8X02", - "XXX8X02", - "XXX8X02", - "XXX8X17", - "XXX8X18", - "XXX8X19", - "XXX8X20", - "XXX8X21", - "XXX8X22", - "XXX8X23", - "XXX8X24", - "XXX8X25", - "XXX8X26", - "XXX8X27", - "XXX8X28", - "XXX8X29", - "XXX8X02", - "ESP_ALL", -}; - -/* Specially handled properties for ego-items */ +template <size_t N> struct flag_tie_impl { +private: + u32b *m_mask; + cptr (&m_flags)[N]; +public: + flag_tie_impl(u32b *mask, cptr (&flags)[N]): m_mask(mask), m_flags(flags) { + // Empty + } -static cptr ego_flags[] = -{ - "SUSTAIN", - "OLD_RESIST", - "ABILITY", - "R_ELEM", - "R_LOW", - "R_HIGH", - "R_ANY", - "R_DRAGON", - "SLAY_WEAP", - "DAM_DIE", - "DAM_SIZE", - "PVAL_M1", - "PVAL_M2", - "PVAL_M3", - "PVAL_M5", - "AC_M1", - "AC_M2", - "AC_M3", - "AC_M5", - "TH_M1", - "TH_M2", - "TH_M3", - "TH_M5", - "TD_M1", - "TD_M2", - "TD_M3", - "TD_M5", - "R_P_ABILITY", - "R_STAT", - "R_STAT_SUST", - "R_IMMUNITY", - "LIMIT_BLOWS" + bool match(cptr flag) { + for (unsigned int i = 0; i < N; i++) + { + if (streq(flag, m_flags[i])) + { + *m_mask |= (1L << i); + return true; + } + } + return false; + } }; -/* - * Feature flags - */ -static cptr f_info_flags1[] = -{ - "NO_WALK", - "NO_VISION", - "CAN_LEVITATE", - "CAN_PASS", - "FLOOR", - "WALL", - "PERMANENT", - "CAN_FLY", - "REMEMBER", - "NOTICE", - "DONT_NOTICE_RUNNING", - "CAN_RUN", - "DOOR", - "SUPPORT_LIGHT", - "CAN_CLIMB", - "TUNNELABLE", - "WEB", - "ATTR_MULTI", - "SUPPORT_GROWTH", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1" -}; +} // namespace detail -/* - * Dungeon flags +/** + * Tie a flags value pointer and its corresponding array + * of text strings. */ -static cptr d_info_flags1[] = -{ - "PRINCIPAL", - "MAZE", - "SMALLEST", - "SMALL", - "BIG", - "NO_DOORS", - "WATER_RIVER", - "LAVA_RIVER", - "WATER_RIVERS", - "LAVA_RIVERS", - "CAVE", - "CAVERN", - "NO_UP", - "HOT", - "COLD", - "FORCE_DOWN", - "FORGET", - "NO_DESTROY", - "SAND_VEIN", - "CIRCULAR_ROOMS", - "EMPTY", - "DAMAGE_FEAT", - "FLAT", - "TOWER", - "RANDOM_TOWNS", - "DOUBLE", - "LIFE_LEVEL", - "EVOLVE", - "ADJUST_LEVEL_1", - "ADJUST_LEVEL_2", - "NO_RECALL", - "NO_STREAMERS" -}; - -static cptr d_info_flags2[] = -{ - "ADJUST_LEVEL_1_2", - "NO_SHAFT", - "ADJUST_LEVEL_PLAYER", - "NO_TELEPORT", - "ASK_LEAVE", - "NO_STAIR", - "SPECIAL", - "NO_NEW_MONSTER", - "DESC", - "NO_GENO", - "NO_BREATH", - "WATER_BREATH", - "ELVEN", - "DWARVEN", - "NO_EASY_MOVE", - "NO_RECALL_OUT", - "DESC_ALWAYS", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1" -}; +template<size_t N> detail::flag_tie_impl<N> flag_tie(u32b *mask, cptr (&flags)[N]) { + static_assert(N <= 32, "Array too large to represent result"); + return detail::flag_tie_impl<N>(mask, flags); +} -/* - * Trap flags +/** + * Look up flag in array of flags. */ -static cptr t_info_flags[] = +template<size_t N> bool lookup_flags(cptr) { - "CHEST", - "DOOR", - "FLOOR", - "XXX4", - "XXX5", - "XXX6", - "XXX7", - "XXX8", - "XXX9", - "XXX10", - "XXX11", - "XXX12", - "XXX13", - "XXX14", - "XXX15", - "XXX16", - "LEVEL1", - "LEVEL2", - "LEVEL3", - "LEVEL4", - "XXX21", - "XXX22", - "XXX23", - "XXX24", - "XXX25", - "XXX26", - "XXX27", - "XXX28", - "XXX29", - "XXX30", - "XXX31", - "XXX32" -}; + // Base case: No match + return false; +} -/* - * Stores flags +/** + * Look up flag in array of flags. */ -static cptr st_info_flags1[] = -{ - "DEPEND_LEVEL", - "SHALLOW_LEVEL", - "MEDIUM_LEVEL", - "DEEP_LEVEL", - "RARE", - "VERY_RARE", - "COMMON", - "ALL_ITEM", - "RANDOM", - "FORCE_LEVEL", - "MUSEUM", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1" -}; +template<size_t N, typename... Pairs> bool lookup_flags(cptr flag, detail::flag_tie_impl<N> tie, Pairs&&...rest) { + // Inductive case: Check against current "tie" + if (tie.match(flag)) { + // Match + return true; + } else { + // No match; check against rest of the array of flags + return lookup_flags<N>(flag, rest...); + } +} -/* - * Race flags - */ -cptr rp_info_flags1[] = -{ - "EXPERIMENTAL", - "XXX", - "RESIST_BLACK_BREATH", - "NO_STUN", - "XTRA_MIGHT_BOW", - "XTRA_MIGHT_XBOW", - "XTRA_MIGHT_SLING", - "AC_LEVEL", - "HURT_LITE", - "VAMPIRE", - "UNDEAD", - "NO_CUT", - "CORRUPT", - "NO_FOOD", - "NO_GOD", - "XXX", - "ELF", - "SEMI_WRAITH", - "NO_SUBRACE_CHANGE", - "XXX", - "XXX", - "MOLD_FRIEND", - "GOD_FRIEND", - "XXX", - "INNATE_SPELLS", - "XXX", - "XXX", - "EASE_STEAL", - "XXX", - "XXX", - "XXX", - "XXX" -}; +} // namespace anonymous -/* - * Race flags - */ -cptr rp_info_flags2[] = -{ - "XXX", - "ASTRAL", - "XXX", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1" -}; -/* Skill flags */ -static cptr s_info_flags1[] = -{ - "HIDDEN", - "AUTO_HIDE", - "RANDOM_GAIN", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1", - "XXX1" -}; /* * Dungeon effect types (used in E:damage:frequency:type entry in d_info.txt) @@ -1527,13 +639,12 @@ static void strappend(char **s, const char *t) static bool_ unknown_shut_up = FALSE; static errr grab_one_class_flag(u32b *choice, cptr what) { - int i; - cptr s; + auto const &class_info = game->edit_data.class_info; /* Scan classes flags */ - for (i = 0; i < max_c_idx && (s = class_info[i].title); i++) + for (std::size_t i = 0; i < class_info.size(); i++) { - if (streq(what, s)) + if (class_info[i].title == what) { (choice[i / 32]) |= (1L << i); return (0); @@ -1546,15 +657,15 @@ static errr grab_one_class_flag(u32b *choice, cptr what) /* Failure */ return (1); } + static errr grab_one_race_allow_flag(u32b *choice, cptr what) { - int i; - cptr s; + auto const &race_info = game->edit_data.race_info; /* Scan classes flags */ - for (i = 0; i < max_rp_idx && (s = race_info[i].title); i++) + for (std::size_t i = 0; i < race_info.size(); i++) { - if (streq(what, s)) + if (race_info[i].title == what) { (choice[i / 32]) |= (1L << i); return (0); @@ -1571,19 +682,16 @@ static errr grab_one_race_allow_flag(u32b *choice, cptr what) /* * Grab one flag from a textual string */ -static errr grab_one_skill_flag(u32b *f1, cptr what) +static errr grab_one_skill_flag(skill_flag_set *flags, cptr what) { - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, s_info_flags1[i])) - { - (*f1) |= (1L << i); - return (0); - } - } +#define SKF(tier, index, name) \ + if (streq(what, #name)) \ + { \ + *flags |= BOOST_PP_CAT(SKF_,name); \ + return 0; \ + }; +#include "skill_flag_list.hpp" +#undef SKF /* Oops */ msg_format("(2)Unknown skill flag '%s'.", what); @@ -1594,29 +702,16 @@ static errr grab_one_skill_flag(u32b *f1, cptr what) /* * Grab one flag from a textual string */ -static errr grab_one_player_race_flag(u32b *f1, u32b *f2, cptr what) +static errr grab_one_player_race_flag(player_race_flag_set *flags, cptr what) { - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, rp_info_flags1[i])) - { - (*f1) |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, rp_info_flags2[i])) - { - (*f2) |= (1L << i); - return (0); - } - } +#define PR(tier, index, name) \ + if (streq(what, #name)) \ + { \ + *flags |= BOOST_PP_CAT(PR_,name); \ + return 0; \ + }; +#include "player_race_flag_list.hpp" +#undef PR /* Oops */ msg_format("(2)Unknown race flag '%s'.", what); @@ -1642,109 +737,159 @@ static int get_activation(char *activation) } /* - * Grab one flag in an object_kind from a textual string + * Convert string to object_flag_set value */ -static errr grab_one_race_kind_flag(u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp, cptr what) +static object_flag_set object_flag_set_from_string(cptr what) { - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) + for (auto const flag_meta: object_flags_meta()) { - if (streq(what, k_info_flags1[i])) + if (streq(what, flag_meta->e_name)) { - (*f1) |= (1L << i); - return (0); - } + return flag_meta->flag_set; + }; } - /* Check flags2 */ - for (i = 0; i < 32; i++) + return object_flag_set(); +} + +/* + * Grab one flag in an object_kind from a textual string + */ +static errr grab_object_flag(object_flag_set *flags, cptr what) +{ + if (object_flag_set f = object_flag_set_from_string(what)) { - if (streq(what, k_info_flags2[i])) - { - (*f2) |= (1L << i); - return (0); - } + *flags |= f; + return 0; } - /* Check flags2 -- traps*/ - for (i = 0; i < 32; i++) + /* Oops */ + msg_format("Unknown object flag '%s'.", what); + + /* Error */ + return (1); +} + +/* + * Read skill values + */ +static int read_skill_modifiers(skill_modifiers *skill_modifiers, cptr buf) +{ + long val, mod; + char v, m; + char name[200]; + + if (5 != sscanf(buf, "%c%ld:%c%ld:%s", &v, &val, &m, &mod, name)) { - if (streq(what, k_info_flags2_trap[i])) - { - (*f3) |= (1L << i); - return (0); - } + return 1; } - /* Check flags3 */ - for (i = 0; i < 32; i++) + long i; + if ((i = find_skill(name)) == -1) { - if (streq(what, k_info_flags3[i])) - { - (*f3) |= (1L << i); - return (0); - } + return 1; } - /* Check flags4 */ - for (i = 0; i < 32; i++) + auto s = &expand_to_fit_index(skill_modifiers->modifiers, i); + + s->basem = monster_ego_modify(v); + s->base = val; + s->modm = monster_ego_modify(m); + s->mod = mod; + + return 0; +} + + +/* + * Read prototype objects + */ +static int read_proto_object(std::vector<object_proto> *protos, cptr buf) +{ + int s0, s1, s2, s3, s4; + + if (5 != sscanf(buf, "%d:%d:%d:%dd%d", &s0, &s1, &s4, &s2, &s3)) { - if (streq(what, k_info_flags4[i])) + s4 = 0; + + if (4 != sscanf(buf, "%d:%d:%dd%d", &s0, &s1, &s2, &s3)) { - (*f4) |= (1L << i); - return (0); + return 1; } } - /* Check flags5 */ - for (i = 0; i < 32; i++) + object_proto proto; + proto.pval = s4; + proto.tval = s0; + proto.sval = s1; + proto.dd = s2; + proto.ds = s3; + + protos->emplace_back(proto); + + return 0; +} + + +/* + * Read an ability assignment + */ +static int read_ability(std::vector<player_race_ability_type> *abilities, char *buf) +{ + int level = 0; + char *name = nullptr; + + // Find the ':' separator + if (!(name = strchr(buf, ':'))) { - if (streq(what, k_info_flags5[i])) - { - (*f5) |= (1L << i); - return (0); - } + return 1; } - /* Check esp_flags */ - for (i = 0; i < 32; i++) + // Split the buffer there and advance to point at the ability name + name++; + + // Extract the level + if (1 != sscanf(buf, "%d:", &level)) { - if (streq(what, esp_flags[i])) - { - (*esp) |= (1L << i); - return (0); - } + return 1; } - /* Oops */ - msg_format("Unknown object flag '%s'.", what); + // Try to find the ability by name + int idx = find_ability(name); + if (idx < 0) + { + return 1; + } - /* Error */ - return (1); + // Insert + player_race_ability_type ability; + ability.ability = idx; + ability.level = level; + abilities->emplace_back(ability); + + return 0; } + /* * Initialize the "player" arrays, by parsing an ascii "template" file */ errr init_player_info_txt(FILE *fp) { - int i = 0, z; - int powers = 0; + auto &class_info = game->edit_data.class_info; + auto &race_info = game->edit_data.race_info; + auto &race_mod_info = game->edit_data.race_mod_info; + auto &gen_skill = game->edit_data.gen_skill; + int lev = 1; int tit_idx = 0; - int spec_idx = 0; - int cur_ab = -1; char buf[1024]; - char *s, *t; /* Current entry */ player_race *rp_ptr = NULL; player_race_mod *rmp_ptr = NULL; player_class *c_ptr = NULL; player_spec *s_ptr = NULL; - meta_class_type *mc_ptr = NULL; /* Just before the first record */ @@ -1753,15 +898,6 @@ errr init_player_info_txt(FILE *fp) /* Just before the first line */ error_line = -1; - /* Init general skills */ - for (z = 0; z < MAX_SKILLS; z++) - { - gen_skill_basem[z] = 0; - gen_skill_base[z] = 0; - gen_skill_modm[z] = 0; - gen_skill_mod[z] = 0; - } - /* Parse */ while (0 == my_fgets(fp, buf, 1024)) { @@ -1781,44 +917,13 @@ errr init_player_info_txt(FILE *fp) continue; } - /* Process 'H' for "History" */ - if (buf[0] == 'H') - { - int idx; - char *zz[6]; - - /* Scan for the values */ - if (tokenize(buf + 2, 6, zz, ':', ':') != 6) return (1); - - idx = atoi(zz[0]); - bg[idx].roll = atoi(zz[1]); - bg[idx].chart = atoi(zz[2]); - bg[idx].next = atoi(zz[3]); - bg[idx].bonus = atoi(zz[4]); - - /* Copy text */ - assert(!bg[idx].info); - bg[idx].info = my_strdup(zz[5]); - - /* Next... */ - continue; - } - /* Process 'G:k' for "General skills" */ if ((buf[0] == 'G') && (buf[2] == 'k')) { - long val, mod, i; - char name[200], v, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%c%ld:%c%ld:%s", - &v, &val, &m, &mod, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - gen_skill_basem[i] = monster_ego_modify(v); - gen_skill_base[i] = val; - gen_skill_modm[i] = monster_ego_modify(m); - gen_skill_mod[i] = mod; + if (read_skill_modifiers(&gen_skill, buf + 4)) + { + return 1; + } /* Next... */ continue; @@ -1828,7 +933,7 @@ errr init_player_info_txt(FILE *fp) if ((buf[0] == 'R') && (buf[2] == 'N')) { /* Find the colon before the name */ - s = strchr(buf + 4, ':'); + char *s = strchr(buf + 4, ':'); /* Verify that colon */ if (!s) return (1); @@ -1840,31 +945,23 @@ errr init_player_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 4); + int i = atoi(buf + 4); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_rp_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - rp_ptr = &race_info[i]; + rp_ptr = &expand_to_fit_index(race_info, i); + assert(rp_ptr->title.empty()); /* Copy title */ - assert(!rp_ptr->title); - rp_ptr->title = my_strdup(s); + rp_ptr->title = s; /* Initialize */ - rp_ptr->powers[0] = rp_ptr->powers[1] = rp_ptr->powers[2] = rp_ptr->powers[3] = -1; - powers = 0; lev = 1; - cur_ab = 0; - for (z = 0; z < 10; z++) - rp_ptr->abilities[z].level = -1; /* Next... */ continue; @@ -1873,18 +970,15 @@ errr init_player_info_txt(FILE *fp) /* Process 'D' for "Description" */ if ((buf[0] == 'R') && (buf[2] == 'D')) { - /* Acquire the text */ - s = buf + 4; - - if (!rp_ptr->desc) + // Need newline? + if (!rp_ptr->desc.empty()) { - rp_ptr->desc = my_strdup(s); - } - else - { - strappend(&rp_ptr->desc, format("\n%s", s)); + rp_ptr->desc += '\n'; } + // Append + rp_ptr->desc += (buf + 4); + /* Next... */ continue; } @@ -1915,7 +1009,7 @@ errr init_player_info_txt(FILE *fp) &s[0], &s[1])) return (1); lev = s[0]; - rp_ptr->opval[lev] = s[1]; + rp_ptr->lflags[lev].pval = s[1]; /* Next... */ continue; @@ -1932,7 +1026,9 @@ errr init_player_info_txt(FILE *fp) rp_ptr->luck = s[6]; for (z = 0; z < 6; z++) - rp_ptr->r_adj[z] = s[z]; + { + rp_ptr->ps.adj[z] = s[z]; + } /* Next... */ continue; @@ -1941,12 +1037,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'Z' for "powers" */ if ((buf[0] == 'R') && (buf[2] == 'Z')) { - int i; - /* Acquire the text */ - s = buf + 4; + char const *s = buf + 4; /* Find it in the list */ + int i; for (i = 0; i < POWER_MAX; i++) { if (iequals(s, powers_type[i].name)) break; @@ -1954,29 +1049,7 @@ errr init_player_info_txt(FILE *fp) if (i == POWER_MAX) return (6); - rp_ptr->powers[powers++] = i; - - /* Next... */ - continue; - } - - /* Process 'K' for "sKills" */ - if ((buf[0] == 'R') && (buf[2] == 'K')) - { - int s[8]; - - /* Scan for the values */ - if (8 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7])) return (1); - - rp_ptr->r_dis = s[0]; - rp_ptr->r_dev = s[1]; - rp_ptr->r_sav = s[2]; - rp_ptr->r_stl = s[3]; - rp_ptr->r_srh = s[4]; - rp_ptr->r_fos = s[5]; - rp_ptr->r_thn = s[6]; - rp_ptr->r_thb = s[7]; + rp_ptr->ps.powers.push_back(i); /* Next... */ continue; @@ -1985,18 +1058,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'k' for "skills" */ if ((buf[0] == 'R') && (buf[2] == 'k')) { - long val, mod, i; - char name[200], v, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%c%ld:%c%ld:%s", - &v, &val, &m, &mod, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - rp_ptr->skill_basem[i] = monster_ego_modify(v); - rp_ptr->skill_base[i] = val; - rp_ptr->skill_modm[i] = monster_ego_modify(m); - rp_ptr->skill_mod[i] = mod; + if (read_skill_modifiers(&rp_ptr->skill_modifiers, buf + 4)) + { + return 1; + } /* Next... */ continue; @@ -2005,46 +1070,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'b' for "abilities" */ if ((buf[0] == 'R') && (buf[2] == 'b')) { - char *sec; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 4, ':'))) + if (read_ability(&rp_ptr->abilities, buf + 4)) { - return (1); + return 1; } - *sec = '\0'; - sec++; - if (!*sec) return (1); - - if ((i = find_ability(sec)) == -1) return (1); - - rp_ptr->abilities[cur_ab].ability = i; - rp_ptr->abilities[cur_ab].level = atoi(buf + 4); - cur_ab++; - - /* Next... */ - continue; - } - - /* Process 'M' for "Mods" */ - if ((buf[0] == 'R') && (buf[2] == 'M')) - { - int s[10]; - - /* Scan for the values */ - if (10 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7], &s[8], &s[9])) return (1); - - rp_ptr->b_age = s[0]; - rp_ptr->m_age = s[1]; - rp_ptr->m_b_ht = s[2]; - rp_ptr->m_m_ht = s[3]; - rp_ptr->m_b_wt = s[4]; - rp_ptr->m_m_wt = s[5]; - rp_ptr->f_b_ht = s[6]; - rp_ptr->f_m_ht = s[7]; - rp_ptr->f_b_wt = s[8]; - rp_ptr->f_m_wt = s[9]; /* Next... */ continue; @@ -2053,16 +1082,15 @@ errr init_player_info_txt(FILE *fp) /* Process 'P' for "xtra" */ if ((buf[0] == 'R') && (buf[2] == 'P')) { - int s[4]; + int s[3]; /* Scan for the values */ - if (4 != sscanf(buf + 4, "%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3])) return (1); + if (3 != sscanf(buf + 4, "%d:%d:%d", + &s[0], &s[1], &s[2])) return (1); - rp_ptr->r_mhp = s[0]; - rp_ptr->r_exp = s[1]; + rp_ptr->ps.mhp = s[0]; + rp_ptr->ps.exp = s[1]; rp_ptr->infra = s[2]; - rp_ptr->chart = s[3]; /* Next... */ continue; @@ -2071,24 +1099,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'G' for "Player flags" (multiple lines) */ if ((buf[0] == 'R') && (buf[2] == 'G')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_one_player_race_flag(&rp_ptr->flags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_player_race_flag(&rp_ptr->flags1, &rp_ptr->flags2, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2098,24 +1111,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'F' for "level Flags" (multiple lines) */ if ((buf[0] == 'R') && (buf[2] == 'F')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (grab_object_flag(&rp_ptr->lflags[lev].oflags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_kind_flag(&rp_ptr->oflags1[lev], &rp_ptr->oflags2[lev], &rp_ptr->oflags3[lev], &rp_ptr->oflags4[lev], &rp_ptr->oflags5[lev], &rp_ptr->oesp[lev], s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2125,27 +1123,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'O' for "Object birth" */ if ((buf[0] == 'R') && (buf[2] == 'O')) { - int s[5]; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%d:%d:%d:%dd%d", - &s[0], &s[1], &s[4], &s[2], &s[3])) + if (read_proto_object(&rp_ptr->object_protos, buf + 4)) { - s[4] = 0; - - if (4 != sscanf(buf + 4, "%d:%d:%dd%d", - &s[0], &s[1], &s[2], &s[3])) - { - return (1); - } + return 1; } - rp_ptr->obj_pval[rp_ptr->obj_num] = s[4]; - rp_ptr->obj_tval[rp_ptr->obj_num] = s[0]; - rp_ptr->obj_sval[rp_ptr->obj_num] = s[1]; - rp_ptr->obj_dd[rp_ptr->obj_num] = s[2]; - rp_ptr->obj_ds[rp_ptr->obj_num++] = s[3]; - /* Next... */ continue; } @@ -2153,24 +1135,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'C' for "Class choice flags" (multiple lines) */ if ((buf[0] == 'R') && (buf[2] == 'C')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_one_class_flag(rp_ptr->choice, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_class_flag(rp_ptr->choice, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2181,7 +1148,7 @@ errr init_player_info_txt(FILE *fp) if ((buf[0] == 'S') && (buf[2] == 'N')) { /* Find the colon before the name */ - s = strchr(buf + 4, ':'); + char *s = strchr(buf + 4, ':'); /* Verify that colon */ if (!s) return (1); @@ -2193,31 +1160,23 @@ errr init_player_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 4); + int i = atoi(buf + 4); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_rmp_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - rmp_ptr = &race_mod_info[i]; + rmp_ptr = &expand_to_fit_index(race_mod_info, i); + assert(rmp_ptr->title.empty()); /* Copy title */ - assert(!rmp_ptr->title); - rmp_ptr->title = my_strdup(s); + rmp_ptr->title = s; /* Initialize */ - rmp_ptr->powers[0] = rmp_ptr->powers[1] = rmp_ptr->powers[2] = rmp_ptr->powers[3] = -1; - powers = 0; lev = 1; - cur_ab = 0; - for (z = 0; z < 10; z++) - rmp_ptr->abilities[z].level = -1; /* Next... */ continue; @@ -2227,7 +1186,7 @@ errr init_player_info_txt(FILE *fp) if ((buf[0] == 'S') && (buf[2] == 'D')) { /* Acquire the text */ - s = buf + 6; + char const *s = buf + 6; /* Place */ if (buf[4] == 'A') @@ -2240,15 +1199,11 @@ errr init_player_info_txt(FILE *fp) } /* Description */ - if (!rmp_ptr->desc) - { - rmp_ptr->desc = my_strdup(s); - } - else + if (!rmp_ptr->description.empty()) { - /* Append chars to the name */ - strappend(&rmp_ptr->desc, format("\n%s", s)); + rmp_ptr->description += '\n'; } + rmp_ptr->description += s; /* Next... */ continue; @@ -2280,7 +1235,7 @@ errr init_player_info_txt(FILE *fp) &s[0], &s[1])) return (1); lev = s[0]; - rmp_ptr->opval[lev] = s[1]; + rmp_ptr->lflags[lev].pval = s[1]; /* Next... */ continue; @@ -2298,7 +1253,9 @@ errr init_player_info_txt(FILE *fp) rmp_ptr->mana = s[7]; rmp_ptr->luck = s[6]; for (z = 0; z < 6; z++) - rmp_ptr->r_adj[z] = s[z]; + { + rmp_ptr->ps.adj[z] = s[z]; + } /* Next... */ continue; @@ -2307,12 +1264,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'Z' for "powers" */ if ((buf[0] == 'S') && (buf[2] == 'Z')) { - int i; - /* Acquire the text */ - s = buf + 4; + char const *s = buf + 4; /* Find it in the list */ + int i; for (i = 0; i < POWER_MAX; i++) { if (iequals(s, powers_type[i].name)) break; @@ -2320,7 +1276,7 @@ errr init_player_info_txt(FILE *fp) if (i == POWER_MAX) return (6); - rmp_ptr->powers[powers++] = i; + rmp_ptr->ps.powers.push_back(i); /* Next... */ continue; @@ -2329,18 +1285,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'k' for "skills" */ if ((buf[0] == 'S') && (buf[2] == 'k')) { - long val, mod, i; - char name[200], v, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%c%ld:%c%ld:%s", - &v, &val, &m, &mod, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - rmp_ptr->skill_basem[i] = monster_ego_modify(v); - rmp_ptr->skill_base[i] = val; - rmp_ptr->skill_modm[i] = monster_ego_modify(m); - rmp_ptr->skill_mod[i] = mod; + if (read_skill_modifiers(&rmp_ptr->skill_modifiers, buf + 4)) + { + return 1; + } /* Next... */ continue; @@ -2349,70 +1297,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'b' for "abilities" */ if ((buf[0] == 'S') && (buf[2] == 'b')) { - char *sec; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 4, ':'))) + if (read_ability(&rmp_ptr->abilities, buf + 4)) { return (1); } - *sec = '\0'; - sec++; - if (!*sec) return (1); - - if ((i = find_ability(sec)) == -1) return (1); - rmp_ptr->abilities[cur_ab].ability = i; - rmp_ptr->abilities[cur_ab].level = atoi(buf + 4); - cur_ab++; - - /* Next... */ - continue; - } - - /* Process 'K' for "sKills" */ - if ((buf[0] == 'S') && (buf[2] == 'K')) - { - int s[8]; - - /* Scan for the values */ - if (8 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7])) return (1); - - rmp_ptr->r_dis = s[0]; - rmp_ptr->r_dev = s[1]; - rmp_ptr->r_sav = s[2]; - rmp_ptr->r_stl = s[3]; - rmp_ptr->r_srh = s[4]; - rmp_ptr->r_fos = s[5]; - rmp_ptr->r_thn = s[6]; - rmp_ptr->r_thb = s[7]; - - /* Next... */ - continue; - } - - /* Process 'M' for "Mods" */ - if ((buf[0] == 'S') && (buf[2] == 'M')) - { - int s[10]; - - /* Scan for the values */ - if (10 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7], &s[8], &s[9])) return (1); - - rmp_ptr->b_age = s[0]; - rmp_ptr->m_age = s[1]; - rmp_ptr->m_b_ht = s[2]; - rmp_ptr->m_m_ht = s[3]; - rmp_ptr->m_b_wt = s[4]; - rmp_ptr->m_m_wt = s[5]; - rmp_ptr->f_b_ht = s[6]; - rmp_ptr->f_m_ht = s[7]; - rmp_ptr->f_b_wt = s[8]; - rmp_ptr->f_m_wt = s[9]; - - /* Next... */ continue; } @@ -2425,8 +1314,8 @@ errr init_player_info_txt(FILE *fp) if (3 != sscanf(buf + 4, "%d:%d:%d", &s[0], &s[1], &s[2])) return (1); - rmp_ptr->r_mhp = s[0]; - rmp_ptr->r_exp = s[1]; + rmp_ptr->ps.mhp = s[0]; + rmp_ptr->ps.exp = s[1]; rmp_ptr->infra = s[2]; /* Next... */ @@ -2436,24 +1325,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'G' for "Player flags" (multiple lines) */ if ((buf[0] == 'S') && (buf[2] == 'G')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_one_player_race_flag(&rmp_ptr->flags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_player_race_flag(&rmp_ptr->flags1, &rmp_ptr->flags2, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2463,24 +1337,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'F' for "level Flags" (multiple lines) */ if ((buf[0] == 'S') && (buf[2] == 'F')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_object_flag(&rmp_ptr->lflags[lev].oflags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_kind_flag(&rmp_ptr->oflags1[lev], &rmp_ptr->oflags2[lev], &rmp_ptr->oflags3[lev], &rmp_ptr->oflags4[lev], &rmp_ptr->oflags5[lev], &rmp_ptr->oesp[lev], s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2490,27 +1349,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'O' for "Object birth" */ if ((buf[0] == 'S') && (buf[2] == 'O')) { - int s[5]; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%d:%d:%d:%dd%d", - &s[0], &s[1], &s[4], &s[2], &s[3])) + if (read_proto_object(&rmp_ptr->object_protos, buf + 4)) { - s[4] = 0; - - if (4 != sscanf(buf + 4, "%d:%d:%dd%d", - &s[0], &s[1], &s[2], &s[3])) - { - return (1); - } + return 1; } - rmp_ptr->obj_pval[rmp_ptr->obj_num] = s[4]; - rmp_ptr->obj_tval[rmp_ptr->obj_num] = s[0]; - rmp_ptr->obj_sval[rmp_ptr->obj_num] = s[1]; - rmp_ptr->obj_dd[rmp_ptr->obj_num] = s[2]; - rmp_ptr->obj_ds[rmp_ptr->obj_num++] = s[3]; - /* Next... */ continue; } @@ -2518,24 +1361,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'A' for "Allowed races" (multiple lines) */ if ((buf[0] == 'S') && (buf[2] == 'A')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_one_race_allow_flag(rmp_ptr->choice, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_allow_flag(rmp_ptr->choice, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2545,32 +1373,23 @@ errr init_player_info_txt(FILE *fp) /* Process 'C' for "Class choice flags" (multiple lines) */ if ((buf[0] == 'S') && (buf[2] == 'C')) { - u32b choice[2] = {0, 0}, z; - - /* Parse every entry */ - for (s = buf + 6; *s; ) + u32b choice[2] = {0, 0}; + if (0 != grab_one_class_flag(choice, buf + 6)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_class_flag(choice, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } - for (z = 0; z < 2; z++) + /* Combine into the class flags */ + for (int z = 0; z < 2; z++) { - if (buf[4] == 'A') rmp_ptr->pclass[z] |= choice[z]; - else rmp_ptr->mclass[z] |= choice[z]; + if (buf[4] == 'A') + { + rmp_ptr->pclass[z] |= choice[z]; + } + else + { + rmp_ptr->mclass[z] |= choice[z]; + } } /* Next... */ @@ -2580,51 +1399,41 @@ errr init_player_info_txt(FILE *fp) /* Process 'N' for "New/Number/Name" */ if ((buf[0] == 'C') && (buf[2] == 'N')) { - int z; - - /* Find the colon before the name */ - s = strchr(buf + 4, ':'); + /* Advance beyond prefix */ + char *s = strchr(buf + 4, ':'); /* Verify that colon */ if (!s) return (1); - /* Nuke the colon, advance to the name */ - *s++ = '\0'; + /* Extract the suffix */ + std::string suffix(s + 1); + if (suffix.empty()) return (1); - /* Paranoia -- require a name */ - if (!*s) return (1); + /* Split suffix into fields */ + std::vector<std::string> fields; + boost::algorithm::split(fields, suffix, boost::is_any_of(":")); - /* Get the index */ - i = atoi(buf + 4); + /* Make sure we have two fields */ + if (fields.size() < 2) return (1); - /* Verify information */ + /* Get the entry index */ + int i = atoi(buf + 4); if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_c_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - c_ptr = &class_info[i]; + c_ptr = &expand_to_fit_index(class_info, i); + assert(c_ptr->title.empty()); - /* Copy name */ - assert(!c_ptr->title); - c_ptr->title = my_strdup(s); + /* Initialize */ + c_ptr->display_order_idx = std::stoi(fields[0]); + c_ptr->title = fields[1]; /* Initialize */ - c_ptr->powers[0] = c_ptr->powers[1] = c_ptr->powers[2] = c_ptr->powers[3] = -1; - powers = 0; lev = 1; - for (z = 0; z < 10; z++) - c_ptr->abilities[z].level = -1; - cur_ab = 0; - c_ptr->obj_num = 0; tit_idx = 0; - spec_idx = -1; - for (z = 0; z < MAX_SPEC; z++) - c_ptr->spec[z].title = 0; /* Next... */ continue; @@ -2634,20 +1443,18 @@ errr init_player_info_txt(FILE *fp) if ((buf[0] == 'C') && (buf[2] == 'D')) { /* Acquire the text */ - s = buf + 6; + char const *s = buf + 6; switch (buf[4]) { case '0': /* Class description */ - if (!c_ptr->desc) + // Need newline? + if (!c_ptr->desc.empty()) { - - c_ptr->desc = my_strdup(s); - } - else - { - strappend(&c_ptr->desc, format("\n%s", s)); + c_ptr->desc += '\n'; } + // Append + c_ptr->desc += s; break; case '1': /* Class title */ @@ -2672,27 +1479,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'O' for "Object birth" */ if ((buf[0] == 'C') && (buf[2] == 'O')) { - int s[5]; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%d:%d:%d:%dd%d", - &s[0], &s[1], &s[4], &s[2], &s[3])) + if (read_proto_object(&c_ptr->object_protos, buf + 4)) { - s[4] = 0; - - if (4 != sscanf(buf + 4, "%d:%d:%dd%d", - &s[0], &s[1], &s[2], &s[3])) - { - return (1); - } + return 1; } - c_ptr->obj_pval[c_ptr->obj_num] = s[4]; - c_ptr->obj_tval[c_ptr->obj_num] = s[0]; - c_ptr->obj_sval[c_ptr->obj_num] = s[1]; - c_ptr->obj_dd[c_ptr->obj_num] = s[2]; - c_ptr->obj_ds[c_ptr->obj_num++] = s[3]; - /* Next... */ continue; } @@ -2723,7 +1514,7 @@ errr init_player_info_txt(FILE *fp) &s[0], &s[1])) return (1); lev = s[0]; - c_ptr->opval[lev] = s[1]; + c_ptr->lflags[lev].pval = s[1]; /* Next... */ continue; @@ -2741,7 +1532,9 @@ errr init_player_info_txt(FILE *fp) c_ptr->mana = s[6]; c_ptr->extra_blows = s[7]; for (z = 0; z < 6; z++) - c_ptr->c_adj[z] = s[z]; + { + c_ptr->ps.adj[z] = s[z]; + } /* Next... */ continue; @@ -2750,18 +1543,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'k' for "skills" */ if ((buf[0] == 'C') && (buf[2] == 'k')) { - long val, mod, i; - char name[200], v, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%c%ld:%c%ld:%s", - &v, &val, &m, &mod, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - c_ptr->skill_basem[i] = monster_ego_modify(v); - c_ptr->skill_base[i] = val; - c_ptr->skill_modm[i] = monster_ego_modify(m); - c_ptr->skill_mod[i] = mod; + if (read_skill_modifiers(&c_ptr->skill_modifiers, buf + 4)) + { + return 1; + } /* Next... */ continue; @@ -2770,22 +1555,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'b' for "abilities" */ if ((buf[0] == 'C') && (buf[2] == 'b')) { - char *sec; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 4, ':'))) + if (read_ability(&c_ptr->abilities, buf + 4)) { - return (1); + return 1; } - *sec = '\0'; - sec++; - if (!*sec) return (1); - - if ((i = find_ability(sec)) == -1) return (1); - - c_ptr->abilities[cur_ab].ability = i; - c_ptr->abilities[cur_ab].level = atoi(buf + 4); - cur_ab++; /* Next... */ continue; @@ -2811,12 +1584,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'Z' for "powers" */ if ((buf[0] == 'C') && (buf[2] == 'Z')) { - int i; - /* Acquire the text */ - s = buf + 4; + char const *s = buf + 4; /* Find it in the list */ + int i; for (i = 0; i < POWER_MAX; i++) { if (iequals(s, powers_type[i].name)) break; @@ -2824,51 +1596,7 @@ errr init_player_info_txt(FILE *fp) if (i == POWER_MAX) return (6); - c_ptr->powers[powers++] = i; - - /* Next... */ - continue; - } - - /* Process 'K' for "sKills" */ - if ((buf[0] == 'C') && (buf[2] == 'K')) - { - int s[8]; - - /* Scan for the values */ - if (8 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7])) return (1); - - c_ptr->c_dis = s[0]; - c_ptr->c_dev = s[1]; - c_ptr->c_sav = s[2]; - c_ptr->c_stl = s[3]; - c_ptr->c_srh = s[4]; - c_ptr->c_fos = s[5]; - c_ptr->c_thn = s[6]; - c_ptr->c_thb = s[7]; - - /* Next... */ - continue; - } - - /* Process 'x' for "Xtra skills" */ - if ((buf[0] == 'C') && (buf[2] == 'X')) - { - int s[8]; - - /* Scan for the values */ - if (8 != sscanf(buf + 4, "%d:%d:%d:%d:%d:%d:%d:%d", - &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7])) return (1); - - c_ptr->x_dis = s[0]; - c_ptr->x_dev = s[1]; - c_ptr->x_sav = s[2]; - c_ptr->x_stl = s[3]; - c_ptr->x_srh = s[4]; - c_ptr->x_fos = s[5]; - c_ptr->x_thn = s[6]; - c_ptr->x_thb = s[7]; + c_ptr->ps.powers.push_back(i); /* Next... */ continue; @@ -2883,28 +1611,8 @@ errr init_player_info_txt(FILE *fp) if (2 != sscanf(buf + 4, "%d:%d", &s[0], &s[1])) return (1); - c_ptr->c_mhp = s[0]; - c_ptr->c_exp = s[1]; - - /* Next... */ - continue; - } - - /* Process 'C' for "sensing" */ - if ((buf[0] == 'C') && (buf[2] == 'C')) - { - long int s[3]; - char h, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 4, "%c:%c:%ld:%ld:%ld", - &h, &m, &s[0], &s[1], &s[2])) return (1); - - c_ptr->sense_heavy = (h == 'H') ? TRUE : FALSE; - c_ptr->sense_heavy_magic = (m == 'H') ? TRUE : FALSE; - c_ptr->sense_base = s[0]; - c_ptr->sense_pl = s[1]; - c_ptr->sense_plus = s[2]; + c_ptr->ps.mhp = s[0]; + c_ptr->ps.exp = s[1]; /* Next... */ continue; @@ -2930,24 +1638,9 @@ errr init_player_info_txt(FILE *fp) /* Process 'G' for "Player flags" (multiple lines) */ if ((buf[0] == 'C') && (buf[2] == 'G')) { - /* Parse every entry */ - for (s = buf + 4; *s; ) + if (0 != grab_one_player_race_flag(&c_ptr->flags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_player_race_flag(&c_ptr->flags1, &c_ptr->flags2, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -2958,8 +1651,10 @@ errr init_player_info_txt(FILE *fp) if ((buf[0] == 'C') && (buf[2] == 'F')) { /* Parse every entry */ - for (s = buf + 4; *s; ) + for (char *s = buf + 4; *s; ) { + char *t; + /* Find the end of this entry */ for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; @@ -2971,7 +1666,10 @@ errr init_player_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_race_kind_flag(&c_ptr->oflags1[lev], &c_ptr->oflags2[lev], &c_ptr->oflags3[lev], &c_ptr->oflags4[lev], &c_ptr->oflags5[lev], &c_ptr->oesp[lev], s)) return (5); + if (0 != grab_object_flag(&c_ptr->lflags[lev].oflags, s)) + { + return (5); + } /* Start the next entry */ s = t; @@ -2988,29 +1686,18 @@ errr init_player_info_txt(FILE *fp) if (buf[4] == 'N') { /* Find the colon before the name */ - s = buf + 6; + char const *s = buf + 6; /* Paranoia -- require a name */ if (!*s) return (1); - /* Get the index */ - spec_idx++; - /* Verify information */ - if (spec_idx >= MAX_SPEC) return (2); + /* Create the spec entry */ + c_ptr->spec.emplace_back(player_spec()); - /* Point at the "info" */ - s_ptr = &c_ptr->spec[spec_idx]; - - /* Copy title */ - assert(!s_ptr->title); + /* Fill in initial values */ + s_ptr = &c_ptr->spec.back(); s_ptr->title = my_strdup(s); - /* Initialize */ - s_ptr->obj_num = 0; - cur_ab = 0; - for (z = 0; z < 10; z++) - s_ptr->abilities[z].level = -1; - /* Next... */ continue; } @@ -3019,7 +1706,7 @@ errr init_player_info_txt(FILE *fp) if (buf[4] == 'D') { /* Acquire the text */ - s = buf + 6; + char const *s = buf + 6; if (!s_ptr->desc) { @@ -3037,27 +1724,11 @@ errr init_player_info_txt(FILE *fp) /* Process 'O' for "Object birth" */ if (buf[4] == 'O') { - int s[5]; - - /* Scan for the values */ - if (5 != sscanf(buf + 6, "%d:%d:%d:%dd%d", - &s[0], &s[1], &s[4], &s[2], &s[3])) + if (read_proto_object(&s_ptr->object_protos, buf + 6)) { - s[4] = 0; - - if (4 != sscanf(buf + 6, "%d:%d:%dd%d", - &s[0], &s[1], &s[2], &s[3])) - { - return (1); - } + return 1; } - s_ptr->obj_pval[s_ptr->obj_num] = s[4]; - s_ptr->obj_tval[s_ptr->obj_num] = s[0]; - s_ptr->obj_sval[s_ptr->obj_num] = s[1]; - s_ptr->obj_dd[s_ptr->obj_num] = s[2]; - s_ptr->obj_ds[s_ptr->obj_num++] = s[3]; - /* Next... */ continue; } @@ -3082,18 +1753,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'k' for "skills" */ if (buf[4] == 'k') { - long val, mod, i; - char name[200], v, m; - - /* Scan for the values */ - if (5 != sscanf(buf + 6, "%c%ld:%c%ld:%s", - &v, &val, &m, &mod, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - s_ptr->skill_basem[i] = monster_ego_modify(v); - s_ptr->skill_base[i] = val; - s_ptr->skill_modm[i] = monster_ego_modify(m); - s_ptr->skill_mod[i] = mod; + if (read_skill_modifiers(&s_ptr->skill_modifiers, buf + 6)) + { + return 1; + } /* Next... */ continue; @@ -3102,22 +1765,10 @@ errr init_player_info_txt(FILE *fp) /* Process 'b' for "abilities" */ if (buf[4] == 'b') { - char *sec; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 6, ':'))) + if (read_ability(&s_ptr->abilities, buf + 6)) { - return (1); + return 1; } - *sec = '\0'; - sec++; - if (!*sec) return (1); - - if ((i = find_ability(sec)) == -1) return (1); - - s_ptr->abilities[cur_ab].ability = i; - s_ptr->abilities[cur_ab].level = atoi(buf + 6); - cur_ab++; /* Next... */ continue; @@ -3127,8 +1778,10 @@ errr init_player_info_txt(FILE *fp) if (buf[4] == 'G') { /* Parse every entry */ - for (s = buf + 6; *s; ) + for (char *s = buf + 6; *s; ) { + char *t; + /* Find the end of this entry */ for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; @@ -3140,7 +1793,10 @@ errr init_player_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_player_race_flag(&s_ptr->flags1, &s_ptr->flags2, s)) return (5); + if (0 != grab_one_player_race_flag(&s_ptr->flags, s)) + { + return (5); + } /* Start the next entry */ s = t; @@ -3149,90 +1805,6 @@ errr init_player_info_txt(FILE *fp) /* Next... */ continue; } - - - /* Process 'K' for "desired skills" */ - if (buf[4] == 'K') - { - long val; - char name[200]; - - /* Scan for the values */ - if (2 != sscanf(buf + 6, "%ld:%s", - &val, name)) return (1); - - if ((i = find_skill(name)) == -1) return (1); - s_ptr->skill_ideal[i] = val; - - /* Next... */ - continue; - } - } - - /* Process 'N' for "New/Number/Name" */ - if ((buf[0] == 'M') && (buf[2] == 'N')) - { - /* Find the colon before the name */ - s = strchr(buf + 4, ':'); - - /* Verify that colon */ - if (!s) return (1); - - /* Nuke the colon, advance to the name */ - *s++ = '\0'; - - /* Paranoia -- require a name */ - if (!*s) return (1); - - /* Get the index */ - i = atoi(buf + 4); - - /* Verify information */ - if (i < error_idx) return (4); - - /* Verify information */ - if (i >= max_mc_idx) return (2); - - /* Save the index */ - error_idx = i; - - /* Point at the "info" */ - mc_ptr = &meta_class_info[i]; - - /* Append chars to the name */ - strcpy(mc_ptr->name, s + 2); - mc_ptr->color = color_char_to_attr(s[0]); - for (powers = 0; powers < max_c_idx; powers++) - mc_ptr->classes[powers] = -1; - powers = 0; - - /* Next... */ - continue; - } - - /* Process 'C' for "Classes" */ - if ((buf[0] == 'M') && (buf[2] == 'C')) - { - int i; - - /* Acquire the text */ - s = buf + 4; - - /* Find it in the list */ - for (i = 0; i < max_c_idx; i++) - { - if (class_info[i].title && iequals(s, class_info[i].title)) - { - break; - } - } - - if (i == max_c_idx) return (6); - - mc_ptr->classes[powers++] = i; - - /* Next... */ - continue; } /* Oops */ @@ -3249,12 +1821,12 @@ errr init_player_info_txt(FILE *fp) */ errr init_v_info_txt(FILE *fp) { - int i; char buf[1024]; - char *s; + + auto &v_info = game->edit_data.v_info; /* Current entry */ - vault_type *v_ptr = NULL; + vault_type *v_ptr = nullptr; /* Just before the first record */ error_idx = -1; @@ -3279,7 +1851,7 @@ errr init_v_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -3291,23 +1863,16 @@ errr init_v_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i <= error_idx) return (4); - /* Verify information */ - if (i >= max_v_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - v_ptr = &v_info[i]; - - /* Initialize data -- we ignore the name, it's not - * used for anything */ - v_ptr->data = my_strdup(""); + v_ptr = &expand_to_fit_index(v_info, i); /* Next... */ continue; @@ -3320,10 +1885,10 @@ errr init_v_info_txt(FILE *fp) if (buf[0] == 'D') { /* Acquire the text */ - s = buf + 2; + cptr s = buf + 2; /* Append data */ - strappend(&v_ptr->data, s); + v_ptr->data += s; /* Next... */ continue; @@ -3398,22 +1963,19 @@ errr init_v_info_txt(FILE *fp) /* * Grab one flag in an feature_type from a textual string */ -static errr grab_one_feature_flag(feature_type *f_ptr, cptr what) +static int grab_one_feature_flag(cptr what, feature_flag_set *flags) { - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, f_info_flags1[i])) - { - f_ptr->flags1 |= (1L << i); - return (0); - } - } +#define FF(tier, index, name) \ + if (streq(what, #name)) \ + { \ + *flags |= BOOST_PP_CAT(FF_,name); \ + return 0; \ + }; +#include "feature_flag_list.hpp" +#undef FF /* Oops */ - msg_format("Unknown object flag '%s'.", what); + msg_format("Unknown feature flag '%s'.", what); /* Error */ return (1); @@ -3425,9 +1987,9 @@ static errr grab_one_feature_flag(feature_type *f_ptr, cptr what) */ errr init_f_info_txt(FILE *fp) { - int i; + auto &f_info = game->edit_data.f_info; + char buf[1024]; - char *s, *t; /* Current entry */ feature_type *f_ptr = NULL; @@ -3454,7 +2016,7 @@ errr init_f_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -3466,19 +2028,16 @@ errr init_f_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i <= error_idx) return (4); - /* Verify information */ - if (i >= max_f_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - f_ptr = &f_info[i]; + f_ptr = &expand_to_fit_index(f_info, i); /* Copy name */ assert(!f_ptr->name); @@ -3502,7 +2061,7 @@ errr init_f_info_txt(FILE *fp) if (buf[0] == 'D') { /* Acquire the text */ - s = buf + 4; + const char *s = buf + 4; switch (buf[2]) { @@ -3595,6 +2154,7 @@ errr init_f_info_txt(FILE *fp) { int side, dice, freq, type; cptr tmp; + int i; /* Find the next empty blow slot (if any) */ for (i = 0; i < 4; i++) if ((!f_ptr->d_side[i]) && @@ -3648,32 +2208,15 @@ errr init_f_info_txt(FILE *fp) /* Hack -- Process 'F' for flags */ if (buf[0] == 'F') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_one_feature_flag(buf + 2, &f_ptr->flags)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_feature_flag(f_ptr, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ continue; } - - /* Oops */ return (6); } @@ -3684,115 +2227,12 @@ errr init_f_info_txt(FILE *fp) /* - * Grab one flag in an object_kind from a textual string - */ -static errr grab_one_kind_flag(object_kind *k_ptr, cptr what, bool_ obvious) -{ - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - if (obvious) - k_ptr->oflags1 |= (1L << i); - else - k_ptr->flags1 |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2[i])) - { - if (obvious) - k_ptr->oflags2 |= (1L << i); - else - k_ptr->flags2 |= (1L << i); - return (0); - } - } - - /* Check flags2 -- traps*/ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2_trap[i])) - { - if (obvious) - k_ptr->oflags2 |= (1L << i); - else - k_ptr->flags2 |= (1L << i); - return (0); - } - } - - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - if (obvious) - k_ptr->oflags3 |= (1L << i); - else - k_ptr->flags3 |= (1L << i); - return (0); - } - } - - /* Check flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags4[i])) - { - if (obvious) - k_ptr->oflags4 |= (1L << i); - else - k_ptr->flags4 |= (1L << i); - return (0); - } - } - - /* Check flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags5[i])) - { - if (obvious) - k_ptr->oflags5 |= (1L << i); - else - k_ptr->flags5 |= (1L << i); - return (0); - } - } - - /* Check esp_flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, esp_flags[i])) - { - if (obvious) - k_ptr->oesp |= (1L << i); - else - k_ptr->esp |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown object flag '%s'.", what); - - /* Error */ - return (1); -} - -/* * Initialize the "k_info" array, by parsing an ascii "template" file */ errr init_k_info_txt(FILE *fp) { + auto &k_info = game->edit_data.k_info; + int i; char buf[1024]; char *s, *t; @@ -3842,14 +2282,11 @@ errr init_k_info_txt(FILE *fp) /* Verify information */ if (i <= error_idx) return (4); - /* Verify information */ - if (i >= max_k_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - k_ptr = &k_info[i]; + k_ptr = &expand_to_fit_index(k_info, i); /* Advance and Save the name index */ assert(!k_ptr->name); @@ -3859,7 +2296,6 @@ errr init_k_info_txt(FILE *fp) k_ptr->text = my_strdup(""); /* Needed hack */ - k_ptr->esp = 0; k_ptr->power = -1; /* Next... */ @@ -3875,8 +2311,14 @@ errr init_k_info_txt(FILE *fp) /* Acquire the text */ s = buf + 2; - /* Append description */ - strappend(&k_ptr->text, s); + if (!k_ptr->text) + { + k_ptr->text = my_strdup(s); + } + else + { + strappend(&k_ptr->text, format("\n%s", s)); + } /* Next... */ continue; @@ -4079,24 +2521,9 @@ errr init_k_info_txt(FILE *fp) /* Hack -- Process 'F' for flags */ if (buf[0] == 'F') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_object_flag(&k_ptr->flags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_kind_flag(k_ptr, s, FALSE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -4106,24 +2533,9 @@ errr init_k_info_txt(FILE *fp) /* Hack -- Process 'f' for obvious flags */ if (buf[0] == 'f') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_object_flag(&k_ptr->oflags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_kind_flag(k_ptr, s, TRUE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -4139,112 +2551,6 @@ errr init_k_info_txt(FILE *fp) return (0); } -/* - * Grab one flag in an artifact_type from a textual string - */ -static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what, bool_ obvious) -{ - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - if (obvious) - a_ptr->oflags1 |= (1L << i); - else - a_ptr->flags1 |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2[i])) - { - if (obvious) - a_ptr->oflags2 |= (1L << i); - else - a_ptr->flags2 |= (1L << i); - return (0); - } - } - - /* Check flags2 -- traps*/ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2_trap[i])) - { - if (obvious) - a_ptr->oflags2 |= (1L << i); - else - a_ptr->flags2 |= (1L << i); - return (0); - } - } - - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - if (obvious) - a_ptr->oflags3 |= (1L << i); - else - a_ptr->flags3 |= (1L << i); - return (0); - } - } - - /* Check flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags4[i])) - { - if (obvious) - a_ptr->oflags4 |= (1L << i); - else - a_ptr->flags4 |= (1L << i); - return (0); - } - } - - /* Check flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags5[i])) - { - if (obvious) - a_ptr->oflags5 |= (1L << i); - else - a_ptr->flags5 |= (1L << i); - return (0); - } - } - - /* Check esp_flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, esp_flags[i])) - { - if (obvious) - a_ptr->oesp |= (1L << i); - else - a_ptr->esp |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown artifact flag '%s'.", what); - - /* Error */ - return (1); -} - - /* @@ -4252,9 +2558,11 @@ static errr grab_one_artifact_flag(artifact_type *a_ptr, cptr what, bool_ obviou */ errr init_a_info_txt(FILE *fp) { + auto &a_info = game->edit_data.a_info; + int i; char buf[1024]; - char *s, *t; + char *s; /* Current entry */ artifact_type *a_ptr = NULL; @@ -4300,14 +2608,11 @@ errr init_a_info_txt(FILE *fp) /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_a_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - a_ptr = &a_info[i]; + a_ptr = &expand_to_fit_index(a_info, i); /* Copy name */ assert(!a_ptr->name); @@ -4317,17 +2622,16 @@ errr init_a_info_txt(FILE *fp) a_ptr->text = my_strdup(""); /* Ignore everything */ - a_ptr->flags3 |= (TR3_IGNORE_ACID); - a_ptr->flags3 |= (TR3_IGNORE_ELEC); - a_ptr->flags3 |= (TR3_IGNORE_FIRE); - a_ptr->flags3 |= (TR3_IGNORE_COLD); + a_ptr->flags |= TR_IGNORE_ACID | + TR_IGNORE_ELEC | + TR_IGNORE_FIRE | + TR_IGNORE_COLD; /* Needed hack */ - a_ptr->esp = 0; a_ptr->power = -1; /*Require activating artifacts to have a activation type */ - if (a_ptr && a_ptr->flags3 & TR3_ACTIVATE && !a_ptr->activate) + if (a_ptr && (a_ptr->flags & TR_ACTIVATE) && !a_ptr->activate) { msg_print("Activate flag without activate type"); return 1; @@ -4447,24 +2751,9 @@ errr init_a_info_txt(FILE *fp) /* Hack -- Process 'F' for flags */ if (buf[0] == 'F') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (grab_object_flag(&a_ptr->flags, buf+2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_artifact_flag(a_ptr, s, FALSE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -4474,24 +2763,9 @@ errr init_a_info_txt(FILE *fp) /* Hack -- Process 'f' for obvious flags */ if (buf[0] == 'f') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (grab_object_flag(&a_ptr->oflags, buf+2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_artifact_flag(a_ptr, s, TRUE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -4525,12 +2799,11 @@ errr init_a_info_txt(FILE *fp) */ errr init_set_info_txt(FILE *fp) { - int i; + auto &set_info = game->edit_data.set_info; + int cur_art = 0, cur_num = 0; char buf[1024]; - char *s, *t; - /* Current entry */ set_type *set_ptr = NULL; @@ -4557,10 +2830,8 @@ errr init_set_info_txt(FILE *fp) /* Process 'N' for "New/Number/Name" */ if (buf[0] == 'N') { - int z, y; - /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -4572,42 +2843,20 @@ errr init_set_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_set_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - set_ptr = &set_info[i]; + set_ptr = &expand_to_fit_index(set_info, i); + assert(set_ptr->name.empty()); /* Copy name */ - assert(!set_ptr->name); - set_ptr->name = my_strdup(s); - - /* Initialize */ - set_ptr->num = 0; - set_ptr->num_use = 0; - for (z = 0; z < 6; z++) - { - set_ptr->arts[z].a_idx = 0; - set_ptr->arts[z].present = FALSE; - for (y = 0; y < 6; y++) - { - set_ptr->arts[z].flags1[y] = 0; - set_ptr->arts[z].flags2[y] = 0; - set_ptr->arts[z].flags3[y] = 0; - set_ptr->arts[z].flags4[y] = 0; - set_ptr->arts[z].flags5[y] = 0; - set_ptr->arts[z].esp[y] = 0; - set_ptr->arts[z].pval[y] = 0; - } - } + set_ptr->name = s; /* Next... */ continue; @@ -4619,11 +2868,14 @@ errr init_set_info_txt(FILE *fp) /* Process 'D' for "Description" */ if (buf[0] == 'D') { - /* Acquire the text */ - s = buf + 2; + /* Need newline? */ + if (!set_ptr->desc.empty()) + { + set_ptr->desc += '\n'; + } - /* Append chars to the description */ - strappend(&set_ptr->desc, s); + /* Append */ + set_ptr->desc += (buf + 2); /* Next... */ continue; @@ -4662,30 +2914,9 @@ errr init_set_info_txt(FILE *fp) /* Process 'F' for flags */ if (buf[0] == 'F') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (grab_object_flag(&set_ptr->arts[cur_art].flags[cur_num], buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_kind_flag(&set_ptr->arts[cur_art].flags1[cur_num], - &set_ptr->arts[cur_art].flags2[cur_num], - &set_ptr->arts[cur_art].flags3[cur_num], - &set_ptr->arts[cur_art].flags4[cur_num], - &set_ptr->arts[cur_art].flags5[cur_num], - &set_ptr->arts[cur_art].esp[cur_num], - s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -4707,12 +2938,14 @@ errr init_set_info_txt(FILE *fp) */ errr init_s_info_txt(FILE *fp) { - int i, z, order = 1; + auto &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; + + int order = 1; char buf[1024]; - char *s; /* Current entry */ - skill_type *s_ptr = NULL; + skill_descriptor *s_ptr = NULL; /* Just before the first record */ @@ -4753,8 +2986,8 @@ errr init_s_info_txt(FILE *fp) s2 = find_skill(sec); if (s2 == -1) return (1); - s_info[s2].father = s1; - s_info[s2].order = order++; + s_descriptors[s2].father = s1; + s_descriptors[s2].order = order++; /* Next... */ continue; @@ -4779,46 +3012,17 @@ errr init_s_info_txt(FILE *fp) s2 = find_skill(sec); if ((s1 == -1) || (s2 == -1)) return (1); - s_info[s1].action[s2] = SKILL_EXCLUSIVE; - s_info[s2].action[s1] = SKILL_EXCLUSIVE; + // The "exclusive" relation is symmetric, so + // add summetrically so we don't have to specify + // twice in data files. + s_descriptors[s1].excludes.push_back(s2); + s_descriptors[s2].excludes.push_back(s1); /* Next... */ continue; } - /* Process 'O' for "Opposite" */ - if (buf[0] == 'O') - { - char *sec, *cval; - s16b s1, s2; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 2, ':'))) - { - return (1); - } - *sec = '\0'; - sec++; - if (!*sec) return (1); - if (NULL == (cval = strchr(sec, '%'))) - { - return (1); - } - *cval = '\0'; - cval++; - if (!*cval) return (1); - - s1 = find_skill(buf + 2); - s2 = find_skill(sec); - if ((s1 == -1) || (s2 == -1)) return (1); - - s_info[s1].action[s2] = -atoi(cval); - - /* Next... */ - continue; - } - /* Process 'A' for "Amical/friendly" */ if (buf[0] == 'f') { @@ -4845,7 +3049,8 @@ errr init_s_info_txt(FILE *fp) s2 = find_skill(sec); if ((s1 == -1) || (s2 == -1)) return (1); - s_info[s1].action[s2] = atoi(cval); + s_descriptors[s1].increases.emplace_back( + std::make_tuple(s2, atoi(cval))); /* Next... */ continue; @@ -4855,7 +3060,7 @@ errr init_s_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -4867,30 +3072,21 @@ errr init_s_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); - - /* Verify information */ - if (i >= max_s_idx) return (2); + int i = atoi(buf + 2); /* Save the index */ error_idx = i; /* Point at the "info" */ - s_ptr = &s_info[i]; + s_ptr = &expand_to_fit_index(s_descriptors, i); + assert(s_ptr->name.empty()); + + /* Make sure s_info also expands appropriately */ + expand_to_fit_index(s_info, i); /* Copy name */ - assert(!s_ptr->name); s_ptr->name = my_strdup(s); - /* Init */ - s_ptr->action_mkey = 0; - s_ptr->dev = FALSE; - s_ptr->random_gain_chance = 100; - for (z = 0; z < max_s_idx; z++) - { - s_ptr->action[z] = 0; - } - /* Next... */ continue; } @@ -4901,19 +3097,15 @@ errr init_s_info_txt(FILE *fp) /* Process 'D' for "Description" */ if (buf[0] == 'D') { - /* Acquire the text */ - s = buf + 2; - - /* Description */ - if (!s_ptr->desc) + /* Need newline? */ + if (!s_ptr->desc.empty()) { - s_ptr->desc = my_strdup(s); - } - else - { - strappend(&s_ptr->desc, format("\n%s", s)); + s_ptr->desc += '\n'; } + /* Append */ + s_ptr->desc += (buf + 2); + /* Next... */ continue; } @@ -4924,15 +3116,15 @@ errr init_s_info_txt(FILE *fp) char *txt; /* Acquire the text */ - s = buf + 2; + char *s = buf + 2; if (NULL == (txt = strchr(s, ':'))) return (1); *txt = '\0'; txt++; /* Copy action description */ - assert(!s_ptr->action_desc); - s_ptr->action_desc = my_strdup(txt); + assert(s_ptr->action_desc.empty()); + s_ptr->action_desc = txt; /* Copy mkey index */ s_ptr->action_mkey = atoi(s); @@ -4941,24 +3133,6 @@ errr init_s_info_txt(FILE *fp) continue; } - /* Process 'I' for "Info" (one line only) */ - if (buf[0] == 'I') - { - int rate; - - /* Scan for the values */ - if (1 != sscanf(buf + 2, "%d", &rate)) - { - return (1); - } - - /* Save the values */ - s_ptr->rate = rate; - - /* Next... */ - continue; - } - /* Process 'G' for "random Gain" (one line only) */ if (buf[0] == 'G') { @@ -4980,26 +3154,9 @@ errr init_s_info_txt(FILE *fp) /* Process 'F' for flags */ if (buf[0] == 'F') { - char *t; - - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_one_skill_flag(&s_ptr->flags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_skill_flag(&(s_ptr->flags1), s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -5019,9 +3176,9 @@ errr init_s_info_txt(FILE *fp) */ errr init_ab_info_txt(FILE *fp) { - int i, z; + auto &ab_info = game->edit_data.ab_info; + char buf[1024]; - char *s; /* Current entry */ ability_type *ab_ptr = NULL; @@ -5050,7 +3207,7 @@ errr init_ab_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -5062,34 +3219,17 @@ errr init_ab_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); - - /* Verify information */ - if (i >= max_ab_idx) return (2); + int i = atoi(buf + 2); /* Save the index */ error_idx = i; /* Point at the "info" */ - ab_ptr = &ab_info[i]; + ab_ptr = &expand_to_fit_index(ab_info, i); + assert(ab_ptr->name.empty()); /* Copy name */ - assert(!ab_ptr->name); - ab_ptr->name = my_strdup(s); - - /* Init */ - ab_ptr->action_mkey = 0; - ab_ptr->acquired = FALSE; - for (z = 0; z < 10; z++) - { - ab_ptr->skills[z] = -1; - ab_ptr->need_abilities[z] = -1; - ab_ptr->forbid_abilities[z] = -1; - } - for (z = 0; z < 6; z++) - { - ab_ptr->stat[z] = -1; - } + ab_ptr->name = s; /* Next... */ continue; @@ -5101,19 +3241,15 @@ errr init_ab_info_txt(FILE *fp) /* Process 'D' for "Description" */ if (buf[0] == 'D') { - /* Acquire the text */ - s = buf + 2; - - /* Append description */ - if (!ab_ptr->desc) - { - ab_ptr->desc = my_strdup(s); - } - else + /* Need newline? */ + if (!ab_ptr->desc.empty()) { - strappend(&ab_ptr->desc, format("\n%s", s)); + ab_ptr->desc += '\n'; } + /* Append */ + ab_ptr->desc += (buf + 2); + /* Next... */ continue; } @@ -5124,15 +3260,15 @@ errr init_ab_info_txt(FILE *fp) char *txt; /* Acquire the text */ - s = buf + 2; + char *s = buf + 2; if (NULL == (txt = strchr(s, ':'))) return (1); *txt = '\0'; txt++; /* Copy name */ - assert(!ab_ptr->action_desc); - ab_ptr->action_desc = my_strdup(txt); + assert(ab_ptr->action_desc.empty()); + ab_ptr->action_desc = txt; /* Set mkey */ ab_ptr->action_mkey = atoi(s); @@ -5163,7 +3299,6 @@ errr init_ab_info_txt(FILE *fp) if (buf[0] == 'k') { char *sec; - s16b level, skill; /* Scan for the values */ if (NULL == (sec = strchr(buf + 2, ':'))) @@ -5174,19 +3309,15 @@ errr init_ab_info_txt(FILE *fp) sec++; if (!*sec) return (1); - level = atoi(buf + 2); - skill = find_skill(sec); - + s16b level = atoi(buf + 2); + s16b skill = find_skill(sec); if (skill == -1) return (1); - for (z = 0; z < 10; z++) - if (ab_ptr->skills[z] == -1) break; + ability_type::skill_requirement req; + req.skill_idx = skill; + req.level = level; - if (z < 10) - { - ab_ptr->skills[z] = skill; - ab_ptr->skill_levels[z] = level; - } + ab_ptr->need_skills.emplace_back(req); /* Next... */ continue; @@ -5195,20 +3326,14 @@ errr init_ab_info_txt(FILE *fp) /* Process 'a' for "needed ability" */ if (buf[0] == 'a') { - s16b ab; - - ab = find_ability(buf + 2); - - if (ab == -1) return (1); - - for (z = 0; z < 10; z++) - if (ab_ptr->need_abilities[z] == -1) break; - - if (z < 10) + s16b ab = find_ability(buf + 2); + if (ab == -1) { - ab_ptr->need_abilities[z] = ab; + return (1); } + ab_ptr->need_abilities.push_back(ab); + /* Next... */ continue; } @@ -5242,44 +3367,6 @@ errr init_ab_info_txt(FILE *fp) continue; } - /* Process 'E' for "Excluding ability" */ - if (buf[0] == 'E') - { - char *sec; - s16b ab1, ab2; - - /* Scan for the values */ - if (NULL == (sec = strchr(buf + 2, ':'))) - { - return (1); - } - *sec = '\0'; - sec++; - if (!*sec) return (1); - - ab1 = find_ability(buf + 2); - ab2 = find_ability(sec); - - if ((ab1 == -1) || (ab2 == -1)) return (1); - - for (z = 0; z < 10; z++) - if (ab_info[ab1].forbid_abilities[z] == -1) break; - if (z < 10) - { - ab_info[ab1].forbid_abilities[z] = ab2; - } - - for (z = 0; z < 10; z++) - if (ab_info[ab2].forbid_abilities[z] == -1) break; - if (z < 10) - { - ab_info[ab2].forbid_abilities[z] = ab1; - } - - /* Next... */ - continue; - } - /* Oops */ return (6); } @@ -5290,218 +3377,47 @@ errr init_ab_info_txt(FILE *fp) /* - * Grab one flag in a ego-item_type from a textual string + * Look up ego flag */ -static bool_ grab_one_ego_item_flag(ego_item_type *e_ptr, cptr what, int n, bool_ obvious) +static ego_flag_set lookup_ego_flag(const char *what) { - int i; - assert(n < FLAG_RARITY_MAX); - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - if (obvious) - e_ptr->oflags1[n] |= (1L << i); - else - e_ptr->flags1[n] |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2[i])) - { - if (obvious) - e_ptr->oflags2[n] |= (1L << i); - else - e_ptr->flags2[n] |= (1L << i); - return (0); - } - } - - /* Check flags2 -- traps */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2_trap[i])) - { - if (obvious) - e_ptr->oflags2[n] |= (1L << i); - else - e_ptr->flags2[n] |= (1L << i); - return (0); - } - } - - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - if (obvious) - e_ptr->oflags3[n] |= (1L << i); - else - e_ptr->flags3[n] |= (1L << i); - return (0); - } - } - - /* Check flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags4[i])) - { - if (obvious) - e_ptr->oflags4[n] |= (1L << i); - else - e_ptr->flags4[n] |= (1L << i); - return (0); - } - } - - /* Check flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags5[i])) - { - if (obvious) - e_ptr->oflags5[n] |= (1L << i); - else - e_ptr->flags5[n] |= (1L << i); - return (0); - } - } - - /* Check esp_flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, esp_flags[i])) - { - if (obvious) - e_ptr->oesp[n] |= (1L << i); - else - e_ptr->esp[n] |= (1L << i); - return (0); - } - } - - /* Check ego_flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, ego_flags[i])) - { - e_ptr->fego[n] |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown ego-item flag '%s'.", what); - - /* Error */ - return (1); +#define ETR(tier, index, name) \ + if (streq(what, #name)) \ + { \ + return BOOST_PP_CAT(ETR_,name); \ + }; +#include "ego_flag_list.hpp" +#undef ETR + return ego_flag_set(); } -static bool_ grab_one_ego_item_flag_restrict(ego_item_type *e_ptr, cptr what, bool_ need) -{ - int i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - if (need) - e_ptr->need_flags1 |= (1L << i); - else - e_ptr->forbid_flags1 |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2[i])) - { - if (need) - e_ptr->need_flags2 |= (1L << i); - else - e_ptr->forbid_flags2 |= (1L << i); - return (0); - } - } - - /* Check flags2 -- traps */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2_trap[i])) - { - if (need) - e_ptr->need_flags2 |= (1L << i); - else - e_ptr->forbid_flags2 |= (1L << i); - return (0); - } - } - - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - if (need) - e_ptr->need_flags3 |= (1L << i); - else - e_ptr->forbid_flags3 |= (1L << i); - return (0); - } - } - - /* Check flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags4[i])) - { - if (need) - e_ptr->need_flags4 |= (1L << i); - else - e_ptr->forbid_flags4 |= (1L << i); - return (0); - } - } - /* Check flags5 */ - for (i = 0; i < 32; i++) +/* + * Grab one flag in a ego-item_type from a textual string. + * + * We explicitly allow nullptr for the "ego" parameter. + */ +static bool_ grab_one_ego_item_flag(object_flag_set *flags, ego_flag_set *ego, cptr what) +{ + /* Lookup as an object_flag */ + if (auto f = object_flag_set_from_string(what)) { - if (streq(what, k_info_flags5[i])) - { - if (need) - e_ptr->need_flags5 |= (1L << i); - else - e_ptr->forbid_flags5 |= (1L << i); - return (0); - } + *flags |= f; + return 0; } - /* Check esp_flags */ - for (i = 0; i < 32; i++) + /* Lookup as ego flag */ + if (ego) { - if (streq(what, esp_flags[i])) + if (auto f = lookup_ego_flag(what)) { - if (need) - e_ptr->need_esp |= (1L << i); - else - e_ptr->forbid_esp |= (1L << i); + *ego |= f; return (0); } } /* Oops */ - msg_format("Unknown ego-item restrict flag '%s'.", what); + msg_format("Unknown ego-item flag '%s'.", what); /* Error */ return (1); @@ -5509,13 +3425,14 @@ static bool_ grab_one_ego_item_flag_restrict(ego_item_type *e_ptr, cptr what, bo - /* * Initialize the "e_info" array, by parsing an ascii "template" file */ errr init_e_info_txt(FILE *fp) { - int i, cur_r = -1, cur_t = 0, j; + auto &e_info = game->edit_data.e_info; + + int i, cur_r = -1, cur_t = 0; char buf[1024]; char *s, *t; @@ -5563,46 +3480,20 @@ errr init_e_info_txt(FILE *fp) /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_e_idx) return (2); - /* Save the index */ error_idx = i; + /* Reset cur_* variables */ + cur_r = -1; + cur_t = 0; + /* Point at the "info" */ - e_ptr = &e_info[i]; + e_ptr = &expand_to_fit_index(e_info, i); /* Copy name */ assert(!e_ptr->name); e_ptr->name = my_strdup(s); - /* Needed hack */ - e_ptr->power = -1; - cur_r = -1; - cur_t = 0; - - for (j = 0; j < 10; j++) - { - e_ptr->tval[j] = 255; - } - for (j = 0; j < FLAG_RARITY_MAX; j++) - { - e_ptr->rar[j] = 0; - e_ptr->flags1[j] = 0; - e_ptr->flags2[j] = 0; - e_ptr->flags3[j] = 0; - e_ptr->flags4[j] = 0; - e_ptr->flags5[j] = 0; - e_ptr->esp[j] = 0; - e_ptr->oflags1[j] = 0; - e_ptr->oflags2[j] = 0; - e_ptr->oflags3[j] = 0; - e_ptr->oflags4[j] = 0; - e_ptr->oflags5[j] = 0; - e_ptr->oesp[j] = 0; - e_ptr->fego[j] = 0; - } - /* Next... */ continue; } @@ -5763,7 +3654,10 @@ errr init_e_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_ego_item_flag_restrict(e_ptr, s, TRUE)) return (5); + if (grab_object_flag(&e_ptr->need_flags, s)) + { + return (5); + } /* Start the next entry */ s = t; @@ -5776,24 +3670,9 @@ errr init_e_info_txt(FILE *fp) /* Hack -- Process 'r:F' for forbidden flags */ if ((buf[0] == 'r') && (buf[2] == 'F')) { - /* Parse every entry textually */ - for (s = buf + 4; *s; ) + if (grab_object_flag(&e_ptr->forbid_flags, buf + 4)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_ego_item_flag_restrict(e_ptr, s, FALSE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -5819,7 +3698,14 @@ errr init_e_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_ego_item_flag(e_ptr, s, cur_r, FALSE)) return (5); + assert(cur_r < FLAG_RARITY_MAX); + if (0 != grab_one_ego_item_flag( + &e_ptr->flags[cur_r], + &e_ptr->fego[cur_r], + s)) + { + return (5); + } /* Start the next entry */ s = t; @@ -5848,7 +3734,14 @@ errr init_e_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_ego_item_flag(e_ptr, s, cur_r, TRUE)) return (5); + assert(cur_r < FLAG_RARITY_MAX); + if (0 != grab_one_ego_item_flag( + &e_ptr->oflags[cur_r], + nullptr, + s)) + { + return (5); + } /* Start the next entry */ s = t; @@ -5866,124 +3759,6 @@ errr init_e_info_txt(FILE *fp) return (0); } -/* - * Grab one flag in a randart_part_type from a textual string - */ -static bool_ grab_one_randart_item_flag(randart_part_type *ra_ptr, cptr what, char c) -{ - int i; - u32b *f1, *f2, *f3, *f4, *f5, *esp; - - if (c == 'F') - { - f1 = &ra_ptr->flags1; - f2 = &ra_ptr->flags2; - f3 = &ra_ptr->flags3; - f4 = &ra_ptr->flags4; - f5 = &ra_ptr->flags5; - esp = &ra_ptr->esp; - } - else - { - f1 = &ra_ptr->aflags1; - f2 = &ra_ptr->aflags2; - f3 = &ra_ptr->aflags3; - f4 = &ra_ptr->aflags4; - f5 = &ra_ptr->aflags5; - esp = &ra_ptr->aesp; - } - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags1[i])) - { - *f1 |= (1L << i); - return (0); - } - } - - /* Check flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2[i])) - { - *f2 |= (1L << i); - return (0); - } - } - - /* Check flags2 -- traps */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags2_trap[i])) - { - *f2 |= (1L << i); - return (0); - } - } - - /* Check flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags3[i])) - { - *f3 |= (1L << i); - return (0); - } - } - - /* Check flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags4[i])) - { - *f4 |= (1L << i); - return (0); - } - } - - /* Check flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, k_info_flags5[i])) - { - *f5 |= (1L << i); - return (0); - } - } - - /* Check esp_flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, esp_flags[i])) - { - *esp |= (1L << i); - return (0); - } - } - - /* Check ego_flags */ - if (c == 'F') - { - for (i = 0; i < 32; i++) - { - if (streq(what, ego_flags[i])) - { - ra_ptr->fego |= (1L << i); - return (0); - } - } - } - - /* Oops */ - msg_format("Unknown ego-item flag '%s'.", what); - - /* Error */ - return (1); -} - - /* @@ -5991,9 +3766,10 @@ static bool_ grab_one_randart_item_flag(randart_part_type *ra_ptr, cptr what, ch */ errr init_ra_info_txt(FILE *fp) { - int i, cur_t = 0, j, cur_g = 0; + auto &ra_gen = game->edit_data.ra_gen; + auto &ra_info = game->edit_data.ra_info; + char buf[1024]; - char *s, *t; /* Current entry */ randart_part_type *ra_ptr = NULL; @@ -6028,11 +3804,14 @@ errr init_ra_info_txt(FILE *fp) &chance, &dd, &ds, &plus)) return (1); /* Save the values */ - ra_gen[cur_g].chance = chance; - ra_gen[cur_g].dd = dd; - ra_gen[cur_g].ds = ds; - ra_gen[cur_g].plus = plus; - cur_g++; + randart_gen_type gen; + gen.chance = chance; + gen.dd = dd; + gen.ds = ds; + gen.plus = plus; + + /* Add to data */ + ra_gen.emplace_back(gen); /* Next... */ continue; @@ -6042,35 +3821,16 @@ errr init_ra_info_txt(FILE *fp) if (buf[0] == 'N') { /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_ra_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - ra_ptr = &ra_info[i]; - - /* Needed hack */ - ra_ptr->power = -1; - cur_t = 0; - - for (j = 0; j < 20; j++) - { - ra_ptr->tval[j] = 255; - } - ra_ptr->flags1 = 0; - ra_ptr->flags2 = 0; - ra_ptr->flags3 = 0; - ra_ptr->flags4 = 0; - ra_ptr->flags5 = 0; - ra_ptr->esp = 0; - ra_ptr->fego = 0; + ra_ptr = &expand_to_fit_index(ra_info, i); /* Next... */ continue; @@ -6082,20 +3842,19 @@ errr init_ra_info_txt(FILE *fp) /* Process 'T' for "Tval/Sval" (up to 5 lines) */ if (buf[0] == 'T') { - int tv, minsv, maxsv; - - if (cur_t == 20) return 1; - /* Scan for the values */ + int tv, minsv, maxsv; if (3 != sscanf(buf + 2, "%d:%d:%d", &tv, &minsv, &maxsv)) return (1); - /* Save the values */ - ra_ptr->tval[cur_t] = tv; - ra_ptr->min_sval[cur_t] = minsv; - ra_ptr->max_sval[cur_t] = maxsv; + /* Set up filter */ + randart_part_type::kind_filter_t filter; + filter.tval = tv; + filter.min_sval = minsv; + filter.max_sval = maxsv; - cur_t++; + /* Add filter */ + ra_ptr->kind_filter.emplace_back(filter); /* Next... */ continue; @@ -6157,18 +3916,21 @@ errr init_ra_info_txt(FILE *fp) /* Process 'Z' for "Granted power" */ if (buf[0] == 'Z') { - int i; - /* Acquire the text */ - s = buf + 2; + char const *s = buf + 2; /* Find it in the list */ + std::size_t i; for (i = 0; i < POWER_MAX; i++) { if (iequals(s, powers_type[i].name)) break; } - if (i == POWER_MAX) return (6); + /* Not present? Fail */ + if (i == POWER_MAX) + { + return (6); + } ra_ptr->power = i; @@ -6176,54 +3938,30 @@ errr init_ra_info_txt(FILE *fp) continue; } - /* Hack -- Process 'F' for flags */ + /* Process 'F' for flags */ if (buf[0] == 'F') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_one_ego_item_flag( + &ra_ptr->flags, + &ra_ptr->fego, + buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_randart_item_flag(ra_ptr, s, 'F')) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ continue; } - /* Hack -- Process 'A' for antagonic flags */ + /* Process 'A' for antagonic flags */ if (buf[0] == 'A') { - /* Parse every entry textually */ - for (s = buf + 2; *s; ) + if (0 != grab_one_ego_item_flag( + &ra_ptr->aflags, + nullptr, + buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_randart_item_flag(ra_ptr, s, 'A')) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -6238,72 +3976,17 @@ errr init_ra_info_txt(FILE *fp) return (0); } -/* - * Grab one (basic) flag in a monster_race from a textual string - */ -static errr grab_one_basic_flag(monster_race *r_ptr, cptr what) -{ - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - r_ptr->flags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - r_ptr->flags2 |= (1L << i); - return (0); - } - } - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - r_ptr->flags3 |= (1L << i); - return (0); - } - } - - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - r_ptr->flags7 |= (1L << i); - return (0); - } - } - - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - r_ptr->flags8 |= (1L << i); - return (0); - } - } - - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - r_ptr->flags9 |= (1L << i); - return (0); - } - } +static errr grab_monster_race_flag(monster_race_flag_set *flags, cptr what) +{ +#define RF(tier, index, name) \ + if (streq(what, #name)) \ + { \ + *flags |= BOOST_PP_CAT(RF_,name); \ + return 0; \ + }; +#include "monster_race_flag_list.hpp" +#undef RF /* Oops */ msg_format("Unknown monster flag '%s'.", what); @@ -6316,37 +3999,14 @@ static errr grab_one_basic_flag(monster_race *r_ptr, cptr what) /* * Grab one (spell) flag in a monster_race from a textual string */ -static errr grab_one_spell_flag(monster_race *r_ptr, cptr what) +static errr grab_one_monster_spell_flag(monster_spell_flag_set *flags, cptr what) { - int i; - - /* Scan flags4 */ - for (i = 0; i < 32; i++) + for (auto const &monster_spell: monster_spells()) { - if (streq(what, r_info_flags4[i])) + if (streq(what, monster_spell->name)) { - r_ptr->flags4 |= (1L << i); - return (0); - } - } - - /* Scan flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags5[i])) - { - r_ptr->flags5 |= (1L << i); - return (0); - } - } - - /* Scan flags6 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags6[i])) - { - r_ptr->flags6 |= (1L << i); - return (0); + *flags |= monster_spell->flag_set; + return 0; } } @@ -6363,9 +4023,9 @@ static errr grab_one_spell_flag(monster_race *r_ptr, cptr what) */ errr init_r_info_txt(FILE *fp) { - int i; + auto &r_info = game->edit_data.r_info; + char buf[1024]; - char *s, *t; /* Current entry */ monster_race *r_ptr = NULL; @@ -6394,7 +4054,7 @@ errr init_r_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -6406,19 +4066,16 @@ errr init_r_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_r_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - r_ptr = &r_info[i]; + r_ptr = &expand_to_fit_index(r_info, i); /* Allocate name string. */ assert(!r_ptr->name); // Sanity check that we aren't overwriting anything @@ -6427,12 +4084,11 @@ errr init_r_info_txt(FILE *fp) /* Ensure empty description */ r_ptr->text = my_strdup(""); - /* HACK -- Those ones HAVE to have a set default value */ - r_ptr->drops.treasure = OBJ_GENE_TREASURE; - r_ptr->drops.combat = OBJ_GENE_COMBAT; - r_ptr->drops.magic = OBJ_GENE_MAGIC; - r_ptr->drops.tools = OBJ_GENE_TOOL; - r_ptr->freq_inate = r_ptr->freq_spell = 0; + /* Set default drop theme */ + r_ptr->drops = obj_theme::defaults(); + + r_ptr->freq_inate = 0; + r_ptr->freq_spell = 0; /* Next... */ continue; @@ -6445,11 +4101,8 @@ errr init_r_info_txt(FILE *fp) /* Process 'D' for "Description" */ if (buf[0] == 'D') { - /* Acquire the text */ - s = buf + 2; - /* Append to description */ - strappend(&r_ptr->text, s); + strappend(&r_ptr->text, buf + 2); /* Next... */ continue; @@ -6547,6 +4200,25 @@ errr init_r_info_txt(FILE *fp) continue; } + /* Process 'A' for standard artifact drop (one line only) */ + if (buf[0] == 'A') + { + int artifact_idx; + int artifact_chance; + + /* Scan for values */ + if (2 != sscanf(buf + 2, "%d:%d", + &artifact_idx, + &artifact_chance)) return (1); + + /* Save the values */ + r_ptr->artifact_idx = artifact_idx; + r_ptr->artifact_chance = artifact_chance; + + /* Next... */ + continue; + } + /* Process 'W' for "More Info" (one line only) */ if (buf[0] == 'W') { @@ -6572,7 +4244,9 @@ errr init_r_info_txt(FILE *fp) /* Process 'B' for "Blows" (up to four lines) */ if (buf[0] == 'B') { - int n1, n2; + int i, n1, n2; + char *s; + char *t; /* Find the next empty blow slot (if any) */ for (i = 0; i < 4; i++) if (!r_ptr->blow[i].method) break; @@ -6633,24 +4307,9 @@ errr init_r_info_txt(FILE *fp) /* Process 'F' for "Basic Flags" (multiple lines) */ if (buf[0] == 'F') { - /* Parse every entry */ - for (s = buf + 2; *s; ) + if (0 != grab_monster_race_flag(&r_ptr->flags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_basic_flag(r_ptr, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -6660,37 +4319,23 @@ errr init_r_info_txt(FILE *fp) /* Process 'S' for "Spell Flags" (multiple lines) */ if (buf[0] == 'S') { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + char const *s = buf + 2; + int i; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + /* XXX XXX XXX Hack -- Read spell frequency */ + if (1 == sscanf(s, "1_IN_%d", &i)) + { + /* Extract a "frequency" */ + r_ptr->freq_spell = r_ptr->freq_inate = 100 / i; + } - /* XXX XXX XXX Hack -- Read spell frequency */ - if (1 == sscanf(s, "1_IN_%d", &i)) + /* Parse this entry */ + else + { + if (0 != grab_one_monster_spell_flag(&r_ptr->spells, s)) { - /* Extract a "frequency" */ - r_ptr->freq_spell = r_ptr->freq_inate = 100 / i; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_spell_flag(r_ptr, s)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -6701,259 +4346,22 @@ errr init_r_info_txt(FILE *fp) return (6); } - /* Postprocessing */ - for (i = 1; i < max_r_idx; i++) - { - /* Invert flag WILD_ONLY <-> RF8_DUNGEON */ - r_info[i].flags8 ^= 1L; - - /* WILD_TOO without any other wilderness flags enables all flags */ - if ((r_info[i].flags8 & RF8_WILD_TOO) && !(r_info[i].flags8 & 0x7FFFFFFE)) - r_info[i].flags8 = 0x0463; - } - /* Success */ return (0); } /* - * Grab one (basic) flag in a monster_race from a textual string - */ -static errr grab_one_basic_ego_flag(monster_ego *re_ptr, cptr what, bool_ add) -{ - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - if (add) - re_ptr->mflags1 |= (1L << i); - else - re_ptr->nflags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - if (add) - re_ptr->mflags2 |= (1L << i); - else - re_ptr->nflags2 |= (1L << i); - return (0); - } - } - - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - if (add) - re_ptr->mflags3 |= (1L << i); - else - re_ptr->nflags3 |= (1L << i); - return (0); - } - } - - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - if (add) - re_ptr->mflags7 |= (1L << i); - else - re_ptr->nflags7 |= (1L << i); - return (0); - } - } - - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - if (add) - re_ptr->mflags8 |= (1L << i); - else - re_ptr->nflags8 |= (1L << i); - return (0); - } - } - - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - if (add) - re_ptr->mflags9 |= (1L << i); - else - re_ptr->nflags9 |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown monster flag '%s'.", what); - - /* Failure */ - return (1); -} - - -/* - * Grab one (spell) flag in a monster_race from a textual string - */ -static errr grab_one_spell_ego_flag(monster_ego *re_ptr, cptr what, bool_ add) -{ - int i; - - /* Scan flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags4[i])) - { - if (add) - re_ptr->mflags4 |= (1L << i); - else - re_ptr->nflags4 |= (1L << i); - return (0); - } - } - - /* Scan flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags5[i])) - { - if (add) - re_ptr->mflags5 |= (1L << i); - else - re_ptr->nflags5 |= (1L << i); - return (0); - } - } - - /* Scan flags6 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags6[i])) - { - if (add) - re_ptr->mflags6 |= (1L << i); - else - re_ptr->nflags6 |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown monster flag '%s'.", what); - - /* Failure */ - return (1); -} - -/* - * Grab one (basic) flag in a monster_race from a textual string - */ -static errr grab_one_ego_flag(monster_ego *re_ptr, cptr what, bool_ must) -{ - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - if (must) re_ptr->flags1 |= (1L << i); - else re_ptr->hflags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - if (must) re_ptr->flags2 |= (1L << i); - else re_ptr->hflags2 |= (1L << i); - return (0); - } - } - - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - if (must) re_ptr->flags3 |= (1L << i); - else re_ptr->hflags3 |= (1L << i); - return (0); - } - } - - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - if (must) re_ptr->flags7 |= (1L << i); - else re_ptr->hflags7 |= (1L << i); - return (0); - } - } - - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - if (must) re_ptr->flags8 |= (1L << i); - else re_ptr->hflags8 |= (1L << i); - return (0); - } - } - - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - if (must) re_ptr->flags9 |= (1L << i); - else re_ptr->hflags9 |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown monster flag '%s'.", what); - - /* Failure */ - return (1); -} - -/* * Initialize the "re_info" array, by parsing an ascii "template" file */ errr init_re_info_txt(FILE *fp) { - int i, j; + auto &re_info = game->edit_data.re_info; + char buf[1024]; byte blow_num = 0; - int r_char_number = 0, nr_char_number = 0; - - char *s, *t; + int r_char_number = 0; + int nr_char_number = 0; /* Current entry */ monster_ego *re_ptr = NULL; @@ -6981,7 +4389,7 @@ errr init_re_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -6993,19 +4401,16 @@ errr init_re_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_re_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - re_ptr = &re_info[i]; + re_ptr = &expand_to_fit_index(re_info, i); /* Copy name */ assert(!re_ptr->name); @@ -7015,9 +4420,8 @@ errr init_re_info_txt(FILE *fp) blow_num = 0; r_char_number = 0; nr_char_number = 0; - for (j = 0; j < 5; j++) re_ptr->r_char[j] = 0; - for (j = 0; j < 5; j++) re_ptr->nr_char[j] = 0; - for (j = 0; j < 4; j++) + + for (std::size_t j = 0; j < 4; j++) { re_ptr->blow[j].method = 0; re_ptr->blow[j].effect = 0; @@ -7113,6 +4517,8 @@ errr init_re_info_txt(FILE *fp) { int n1, n2, dice, side; char mdice, mside; + char *s; + char *t; /* Oops, no more slots */ if (blow_num == 4) return (1); @@ -7173,39 +4579,24 @@ errr init_re_info_txt(FILE *fp) char r_char; /* Parse every entry */ - for (s = buf + 2; *s; ) + char const *s = buf + 2; + + /* XXX XXX XXX Hack -- Read monster symbols */ + if (1 == sscanf(s, "R_CHAR_%c", &r_char)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + /* Limited to 5 races */ + if (r_char_number >= 5) continue; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + /* Extract a "frequency" */ + re_ptr->r_char[r_char_number++] = r_char; + } - /* XXX XXX XXX Hack -- Read monster symbols */ - if (1 == sscanf(s, "R_CHAR_%c", &r_char)) + /* Parse this entry */ + else { + if (0 != grab_monster_race_flag(&re_ptr->flags, s)) { - /* Limited to 5 races */ - if (r_char_number >= 5) continue; - - /* Extract a "frequency" */ - re_ptr->r_char[r_char_number++] = r_char; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_ego_flag(re_ptr, s, TRUE)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -7218,39 +4609,24 @@ errr init_re_info_txt(FILE *fp) char r_char; /* Parse every entry */ - for (s = buf + 2; *s; ) + char const *s = buf + 2; + + /* XXX XXX XXX Hack -- Read monster symbols */ + if (1 == sscanf(s, "R_CHAR_%c", &r_char)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + /* Limited to 5 races */ + if (nr_char_number >= 5) continue; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + /* Extract a "frequency" */ + re_ptr->nr_char[nr_char_number++] = r_char; + } - /* XXX XXX XXX Hack -- Read monster symbols */ - if (1 == sscanf(s, "R_CHAR_%c", &r_char)) + /* Parse this entry */ + else { + if (0 != grab_monster_race_flag(&re_ptr->hflags, s)) { - /* Limited to 5 races */ - if (nr_char_number >= 5) continue; - - /* Extract a "frequency" */ - re_ptr->nr_char[nr_char_number++] = r_char; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_ego_flag(re_ptr, s, FALSE)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -7260,24 +4636,9 @@ errr init_re_info_txt(FILE *fp) /* Process 'M' for "Basic Monster Flags" (multiple lines) */ if (buf[0] == 'M') { - /* Parse every entry */ - for (s = buf + 2; *s; ) + if (0 != grab_monster_race_flag(&re_ptr->mflags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_basic_ego_flag(re_ptr, s, TRUE)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -7287,37 +4648,20 @@ errr init_re_info_txt(FILE *fp) /* Process 'O' for "Basic Monster -Flags" (multiple lines) */ if (buf[0] == 'O') { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + char const *s = buf + 2; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + /* XXX XXX XXX Hack -- Read no flags */ + if (!strcmp(s, "MF_ALL")) + { + re_ptr->nflags = ~monster_race_flag_set(); + } - /* XXX XXX XXX Hack -- Read no flags */ - if (!strcmp(s, "MF_ALL")) + /* Parse this entry */ + else { + if (0 != grab_monster_race_flag(&re_ptr->nflags, s)) { - /* No flags */ - re_ptr->nflags1 = re_ptr->nflags2 = re_ptr->nflags3 = re_ptr->nflags7 = re_ptr->nflags8 = re_ptr->nflags9 = 0xFFFFFFFF; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_basic_ego_flag(re_ptr, s, FALSE)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -7327,37 +4671,22 @@ errr init_re_info_txt(FILE *fp) /* Process 'S' for "Spell Flags" (multiple lines) */ if (buf[0] == 'S') { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + char const *s = buf + 2; + int i; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } + /* XXX XXX XXX Hack -- Read spell frequency */ + if (1 == sscanf(s, "1_IN_%d", &i)) + { + /* Extract a "frequency" */ + re_ptr->freq_spell = re_ptr->freq_inate = 100 / i; + } - /* XXX XXX XXX Hack -- Read spell frequency */ - if (1 == sscanf(s, "1_IN_%d", &i)) + /* Parse this entry */ + else { + if (0 != grab_one_monster_spell_flag(&re_ptr->mspells, s)) { - /* Extract a "frequency" */ - re_ptr->freq_spell = re_ptr->freq_inate = 100 / i; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_spell_ego_flag(re_ptr, s, TRUE)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -7368,8 +4697,10 @@ errr init_re_info_txt(FILE *fp) if (buf[0] == 'T') { /* Parse every entry */ - for (s = buf + 2; *s; ) + for (char *s = buf + 2; *s; ) { + char *t; + /* Find the end of this entry */ for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; @@ -7384,7 +4715,7 @@ errr init_re_info_txt(FILE *fp) if (!strcmp(s, "MF_ALL")) { /* No flags */ - re_ptr->nflags4 = re_ptr->nflags5 = re_ptr->nflags6 = 0xFFFFFFFF; + re_ptr->nspells = ~monster_spell_flag_set(); /* Start at next entry */ s = t; @@ -7394,7 +4725,7 @@ errr init_re_info_txt(FILE *fp) } /* Parse this entry */ - if (0 != grab_one_spell_ego_flag(re_ptr, s, FALSE)) return (5); + if (0 != grab_one_monster_spell_flag(&re_ptr->nspells, s)) return (5); /* Start the next entry */ s = t; @@ -7414,287 +4745,17 @@ errr init_re_info_txt(FILE *fp) /* - * Grab one flag in an trap_type from a textual string - */ -static errr grab_one_trap_type_flag(trap_type *t_ptr, cptr what) -{ - s16b i; - - /* Check flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, t_info_flags[i])) - { - t_ptr->flags |= (1L << i); - return (0); - } - } - /* Oops */ - msg_format("Unknown trap_type flag '%s'.", what); - - /* Error */ - return (1); -} - - -/* - * Initialize the "tr_info" array, by parsing an ascii "template" file - */ -errr init_t_info_txt(FILE *fp) -{ - int i; - char buf[1024]; - char *s, *t; - - /* Current entry */ - trap_type *t_ptr = NULL; - - /* Just before the first record */ - error_idx = -1; - - /* Just before the first line */ - error_line = -1; - - /* Parse */ - while (0 == my_fgets(fp, buf, 1024)) - { - /* Advance the line number */ - error_line++; - - /* Skip comments and blank lines */ - if (!buf[0] || (buf[0] == '#')) continue; - - /* Verify correct "colon" format */ - if (buf[1] != ':') return (1); - - /* Process 'N' for "New/Number/Name" */ - if (buf[0] == 'N') - { - /* Find the colon before the name */ - s = strchr(buf + 2, ':'); - - /* Verify that colon */ - if (!s) return (1); - - /* Nuke the colon, advance to the name */ - *s++ = '\0'; - - /* Paranoia -- require a name */ - if (!*s) return (1); - - /* Get the index */ - i = atoi(buf + 2); - - /* Verify information */ - if (i <= error_idx) return (4); - - /* Verify information */ - if (i >= max_t_idx) return (2); - - /* Save the index */ - error_idx = i; - - /* Point at the "info" */ - t_ptr = &t_info[i]; - - /* Copy name */ - t_ptr->name = my_strdup(s); - - /* Initialize */ - t_ptr->text = my_strdup(""); - - /* Next... */ - continue; - } - - /* There better be a current t_ptr */ - if (!t_ptr) return (3); - - - /* Process 'I' for "Information" */ - if (buf[0] == 'I') - { - int probability, another, p1valinc, difficulty; - int minlevel; - int dd, ds; - char color; - - /* Scan for the values */ - if (8 != sscanf(buf + 2, "%d:%d:%d:%d:%d:%dd%d:%c", - &difficulty, &probability, &another, - &p1valinc, &minlevel, &dd, &ds, - &color)) return (1); - - t_ptr->difficulty = (byte)difficulty; - t_ptr->probability = (s16b)probability; - t_ptr->another = (s16b)another; - t_ptr->p1valinc = (s16b)p1valinc; - t_ptr->minlevel = (byte)minlevel; - t_ptr->dd = (s16b)dd; - t_ptr->ds = (s16b)ds; - t_ptr->color = color_char_to_attr(color); - - /* Next... */ - continue; - } - - - /* Process 'D' for "Description" */ - if (buf[0] == 'D') - { - /* Acquire the text */ - s = buf + 2; - - /* Append chars to the name */ - strappend(&t_ptr->text, s); - - /* Next... */ - continue; - } - - - /* Hack -- Process 'F' for flags */ - if (buf[0] == 'F') - { - - t_ptr->flags = 0; - - /* Parse every entry textually */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_trap_type_flag(t_ptr, s)) return (5); - - /* Start the next entry */ - s = t; - } - - /* Next... */ - continue; - } - - - /* Oops */ - return (6); - } - - /* Success */ - return (0); -} - -/* * Grab one flag for a dungeon type from a textual string */ -errr grab_one_dungeon_flag(u32b *flags1, u32b *flags2, cptr what) +errr grab_one_dungeon_flag(dungeon_flag_set *flags, const char *str) { - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, d_info_flags1[i])) - { - *flags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, d_info_flags2[i])) - { - *flags2 |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown dungeon type flag '%s'.", what); - - /* Failure */ - return (1); -} - -/* - * Grab one (basic) flag in a monster_race from a textual string - */ -static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what, byte rule) -{ - int i; - - /* Scan flags1 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags1[i])) - { - d_ptr->rules[rule].mflags1 |= (1L << i); - return (0); - } - } - - /* Scan flags2 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags2[i])) - { - d_ptr->rules[rule].mflags2 |= (1L << i); - return (0); - } - } - - /* Scan flags3 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags3[i])) - { - d_ptr->rules[rule].mflags3 |= (1L << i); - return (0); - } - } - - /* Scan flags7 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags7[i])) - { - d_ptr->rules[rule].mflags7 |= (1L << i); - return (0); - } - } - - /* Scan flags8 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags8[i])) - { - d_ptr->rules[rule].mflags8 |= (1L << i); - return (0); - } - } - - /* Scan flags9 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags9[i])) - { - d_ptr->rules[rule].mflags9 |= (1L << i); - return (0); - } - } +#define DF(tier, index, name) \ + if (streq(str, #name)) { *flags |= DF_##name; return 0; } +#include "dungeon_flag_list.hpp" +#undef DF /* Oops */ - msg_format("Unknown monster flag '%s'.", what); + msg_format("Unknown dungeon type flag '%s'.", str); /* Failure */ return (1); @@ -7702,63 +4763,18 @@ static errr grab_one_basic_monster_flag(dungeon_info_type *d_ptr, cptr what, byt /* - * Grab one (spell) flag in a monster_race from a textual string - */ -static errr grab_one_spell_monster_flag(dungeon_info_type *d_ptr, cptr what, byte rule) -{ - int i; - - /* Scan flags4 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags4[i])) - { - d_ptr->rules[rule].mflags4 |= (1L << i); - return (0); - } - } - - /* Scan flags5 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags5[i])) - { - d_ptr->rules[rule].mflags5 |= (1L << i); - return (0); - } - } - - /* Scan flags6 */ - for (i = 0; i < 32; i++) - { - if (streq(what, r_info_flags6[i])) - { - d_ptr->rules[rule].mflags6 |= (1L << i); - return (0); - } - } - - /* Oops */ - msg_format("Unknown monster flag '%s'.", what); - - /* Failure */ - return (1); -} - -/* * Initialize the "d_info" array, by parsing an ascii "template" file */ errr init_d_info_txt(FILE *fp) { - int i, j; + auto &d_info = game->edit_data.d_info; + char buf[1024]; s16b rule_num = 0; byte r_char_number = 0; - char *s, *t; - /* Current entry */ dungeon_info_type *d_ptr = NULL; @@ -7785,7 +4801,7 @@ errr init_d_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -7797,26 +4813,20 @@ errr init_d_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_d_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - d_ptr = &d_info[i]; + d_ptr = &expand_to_fit_index(d_info, i); + assert(d_ptr->name.empty()); /* Copy name */ - assert(!d_ptr->name); - d_ptr->name = my_strdup(s); - - /* Initialize description */ - d_ptr->text = my_strdup(""); + d_ptr->name = s; /* HACK -- Those ones HAVE to have a set default value */ d_ptr->size_x = -1; @@ -7828,24 +4838,22 @@ errr init_d_info_txt(FILE *fp) d_ptr->fill_method = 1; rule_num = -1; r_char_number = 0; - for (j = 0; j < 5; j++) + for (std::size_t j = 0; j < 5; j++) { - int k; - d_ptr->rules[j].mode = DUNGEON_MODE_NONE; d_ptr->rules[j].percent = 0; - for (k = 0; k < 5; k++) d_ptr->rules[j].r_char[k] = 0; + for (std::size_t k = 0; k < 5; k++) + { + d_ptr->rules[j].r_char[k] = 0; + } } - /* HACK -- Those ones HAVE to have a set default value */ - d_ptr->objs.treasure = OBJ_GENE_TREASURE; - d_ptr->objs.combat = OBJ_GENE_COMBAT; - d_ptr->objs.magic = OBJ_GENE_MAGIC; - d_ptr->objs.tools = OBJ_GENE_TOOL; + /* Set default drop theme */ + d_ptr->objs = obj_theme::defaults(); /* The default generator */ - strcpy(d_ptr->generator, "dungeon"); + d_ptr->generator = "dungeon"; /* Next... */ continue; @@ -7858,15 +4866,12 @@ errr init_d_info_txt(FILE *fp) if (buf[0] == 'D') { /* Acquire short name */ - d_ptr->short_name[0] = buf[2]; - d_ptr->short_name[1] = buf[3]; - d_ptr->short_name[2] = buf[4]; - - /* Acquire the text */ - s = buf + 6; + d_ptr->short_name += buf[2]; + d_ptr->short_name += buf[3]; + d_ptr->short_name += buf[4]; /* Append to description */ - strappend(&d_ptr->text, s); + d_ptr->text += (buf + 6); /* Next... */ continue; @@ -7876,18 +4881,17 @@ errr init_d_info_txt(FILE *fp) if (buf[0] == 'W') { int min_lev, max_lev; - int min_plev, next; + int min_plev; int min_alloc, max_chance; /* Scan for the values */ - if (6 != sscanf(buf + 2, "%d:%d:%d:%d:%d:%d", - &min_lev, &max_lev, &min_plev, &next, &min_alloc, &max_chance)) return (1); + if (5 != sscanf(buf + 2, "%d:%d:%d:%d:%d", + &min_lev, &max_lev, &min_plev, &min_alloc, &max_chance)) return (1); /* Save the values */ d_ptr->mindepth = min_lev; d_ptr->maxdepth = max_lev; d_ptr->min_plev = min_plev; - d_ptr->next = next; d_ptr->min_m_alloc_level = min_alloc; d_ptr->max_m_alloc_chance = max_chance; @@ -7956,7 +4960,7 @@ errr init_d_info_txt(FILE *fp) /* Process 'G' for "Generator" (one line only) */ if (buf[0] == 'G') { - strnfmt(d_ptr->generator, 30, "%s", buf + 2); + d_ptr->generator = (buf + 2); /* Next... */ continue; @@ -8010,8 +5014,15 @@ errr init_d_info_txt(FILE *fp) cptr tmp; /* Find the next empty blow slot (if any) */ - for (i = 0; i < 4; i++) if ((!d_ptr->d_side[i]) && - (!d_ptr->d_dice[i])) break; + std::size_t i; + for (i = 0; i < 4; i++) + { + if ((!d_ptr->d_side[i]) && + (!d_ptr->d_dice[i])) + { + break; + } + } /* Oops, no more slots */ if (i == 4) return (1); @@ -8065,103 +5076,57 @@ errr init_d_info_txt(FILE *fp) int ix = -1, iy = -1, ox = -1, oy = -1; int fill_method; - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Read dungeon in/out coords */ - if (4 == sscanf(s, "WILD_%d_%d__%d_%d", &ix, &iy, &ox, &oy)) - { - d_ptr->ix = ix; - d_ptr->iy = iy; - d_ptr->ox = ox; - d_ptr->oy = oy; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; - } - - /* Read dungeon size */ - if (2 == sscanf(s, "SIZE_%d_%d", &ix, &iy)) - { - d_ptr->size_x = ix; - d_ptr->size_y = iy; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; - } - - /* Read dungeon fill method */ - if (1 == sscanf(s, "FILL_METHOD_%d", &fill_method)) - { - d_ptr->fill_method = fill_method; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; - } + char const *s = buf + 2; - /* Read Final Object */ - if (1 == sscanf(s, "FINAL_OBJECT_%d", &obj)) - { - /* Extract a "Final Artifact" */ - d_ptr->final_object = obj; + /* Read dungeon in/out coords */ + if (4 == sscanf(s, "WILD_%d_%d__%d_%d", &ix, &iy, &ox, &oy)) + { + d_ptr->ix = ix; + d_ptr->iy = iy; + d_ptr->ox = ox; + d_ptr->oy = oy; + } - /* Start at next entry */ - s = t; + /* Read dungeon size */ + else if (2 == sscanf(s, "SIZE_%d_%d", &ix, &iy)) + { + d_ptr->size_x = ix; + d_ptr->size_y = iy; + } - /* Continue */ - continue; - } + /* Read dungeon fill method */ + else if (1 == sscanf(s, "FILL_METHOD_%d", &fill_method)) + { + d_ptr->fill_method = fill_method; + } - /* Read Final Artifact */ - if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif )) - { - /* Extract a "Final Artifact" */ - d_ptr->final_artifact = artif ; + /* Read Final Object */ + else if (1 == sscanf(s, "FINAL_OBJECT_%d", &obj)) + { + /* Extract a "Final Artifact" */ + d_ptr->final_object = obj; + } - /* Start at next entry */ - s = t; + /* Read Final Artifact */ + else if (1 == sscanf(s, "FINAL_ARTIFACT_%d", &artif )) + { + /* Extract a "Final Artifact" */ + d_ptr->final_artifact = artif ; + } - /* Continue */ - continue; - } + /* Read Artifact Guardian */ + else if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) + { + /* Extract a "Artifact Guardian" */ + d_ptr->final_guardian = monst; + } - /* Read Artifact Guardian */ - if (1 == sscanf(s, "FINAL_GUARDIAN_%d", &monst)) + /* Parse this entry */ + else { + if (0 != grab_one_dungeon_flag(&d_ptr->flags, s)) { - /* Extract a "Artifact Guardian" */ - d_ptr->final_guardian = monst; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_dungeon_flag(&(d_ptr->flags1), &(d_ptr->flags2), s)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -8207,41 +5172,24 @@ errr init_d_info_txt(FILE *fp) if (buf[0] == 'M') { byte r_char; + char const *s = buf + 2; - /* Parse every entry */ - for (s = buf + 2; *s; ) + /* Read monster symbols */ + if (1 == sscanf(s, "R_CHAR_%c", &r_char)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; + /* Limited to 5 races */ + if (r_char_number >= 5) continue; - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } + /* Extract a "frequency" */ + d_ptr->rules[rule_num].r_char[r_char_number++] = r_char; + } - /* Read monster symbols */ - if (1 == sscanf(s, "R_CHAR_%c", &r_char)) + /* Parse this entry */ + else { + if (0 != grab_monster_race_flag(&d_ptr->rules[rule_num].mflags, s)) { - /* Limited to 5 races */ - if (r_char_number >= 5) continue; - - /* Extract a "frequency" */ - d_ptr->rules[rule_num].r_char[r_char_number++] = r_char; - - /* Start at next entry */ - s = t; - - /* Continue */ - continue; + return (5); } - - /* Parse this entry */ - if (0 != grab_one_basic_monster_flag(d_ptr, s, rule_num)) return (5); - - /* Start the next entry */ - s = t; } /* Next... */ @@ -8251,24 +5199,12 @@ errr init_d_info_txt(FILE *fp) /* Process 'S' for "Spell Flags" (multiple lines) */ if (buf[0] == 'S') { - /* Parse every entry */ - for (s = buf + 2; *s; ) - { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while ((*t == ' ') || (*t == '|')) t++; - } - - /* Parse this entry */ - if (0 != grab_one_spell_monster_flag(d_ptr, s, rule_num)) return (5); + char const *s = buf + 2; - /* Start the next entry */ - s = t; + /* Parse this entry */ + if (0 != grab_one_monster_spell_flag(&d_ptr->rules[rule_num].mspells, s)) + { + return (5); } /* Next... */ @@ -8288,9 +5224,6 @@ errr init_d_info_txt(FILE *fp) */ static errr grab_one_race_flag(owner_type *ow_ptr, int state, cptr what) { - /* int i; - cptr s; */ - /* Scan race flags */ unknown_shut_up = TRUE; if (!grab_one_race_allow_flag(ow_ptr->races[state], what)) @@ -8317,19 +5250,15 @@ static errr grab_one_race_flag(owner_type *ow_ptr, int state, cptr what) /* * Grab one store flag from a textual string */ -static errr grab_one_store_flag(store_info_type *st_ptr, cptr what) +static errr grab_one_store_flag(store_flag_set *flags, cptr what) { - int i; - - /* Scan store flags */ - for (i = 0; i < 32; i++) - { - if (streq(what, st_info_flags1[i])) - { - st_ptr->flags1 |= (1L << i); - return (0); - } - } +#define STF(tier, index, name) \ + if (streq(what, #name)) { \ + *flags |= BOOST_PP_CAT(STF_,name); \ + return 0; \ + } +#include "store_flag_list.hpp" +#undef STF /* Oops */ msg_format("Unknown store flag '%s'.", what); @@ -8343,9 +5272,9 @@ static errr grab_one_store_flag(store_info_type *st_ptr, cptr what) */ errr init_st_info_txt(FILE *fp) { - int i = 0, item_idx = 0; + auto &st_info = game->edit_data.st_info; + char buf[1024]; - char *s, *t; /* Current entry */ store_info_type *st_ptr = NULL; @@ -8373,7 +5302,7 @@ errr init_st_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -8385,26 +5314,20 @@ errr init_st_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_st_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - st_ptr = &st_info[i]; + st_ptr = &expand_to_fit_index(st_info, i); + assert(st_ptr->name.empty()); /* Copy name */ - assert(!st_ptr->name); - st_ptr->name = my_strdup(s); - - /* We are ready for a new set of objects */ - item_idx = 0; + st_ptr->name = s; /* Next... */ continue; @@ -8417,7 +5340,7 @@ errr init_st_info_txt(FILE *fp) if (buf[0] == 'I') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -8428,14 +5351,11 @@ errr init_st_info_txt(FILE *fp) /* Paranoia -- require a name */ if (!*s) return (1); - /* Get the index */ - st_ptr->table[item_idx][1] = atoi(buf + 2); - - /* Append chars to the name */ - st_ptr->table[item_idx++][0] = test_item_name(s); - - st_ptr->table_num = item_idx; - assert(st_ptr->table_num <= STORE_CHOICES); + /* Add to items array */ + store_item item; + item.chance = atoi(buf + 2); + item.kind = test_item_name(s); + st_ptr->items.emplace_back(item); /* Next... */ continue; @@ -8450,12 +5370,13 @@ errr init_st_info_txt(FILE *fp) if (3 != sscanf(buf + 2, "%d:%d:%d", &rar1, &tv1, &sv1)) return (1); - /* Get the index */ - st_ptr->table[item_idx][1] = rar1; - /* Hack -- 256 as a sval means all possible items */ - st_ptr->table[item_idx++][0] = (sv1 < 256) ? lookup_kind(tv1, sv1) : tv1 + 10000; - - st_ptr->table_num = item_idx; + /* Add to the items array */ + store_item item; + item.chance = rar1; + item.kind = (sv1 < 256) + ? lookup_kind(tv1, sv1) + : tv1 + 10000; /* An SVAL of 256 means all possible items. */ + st_ptr->items.emplace_back(item); /* Next... */ continue; @@ -8495,12 +5416,18 @@ errr init_st_info_txt(FILE *fp) &a1, &a2, &a3, &a4, &a5, &a6)) return (1); /* Save the values */ - st_ptr->actions[0] = a1; - st_ptr->actions[1] = a2; - st_ptr->actions[2] = a3; - st_ptr->actions[3] = a4; - st_ptr->actions[4] = a5; - st_ptr->actions[5] = a6; + st_ptr->actions.push_back(a1); + st_ptr->actions.push_back(a2); + st_ptr->actions.push_back(a3); + st_ptr->actions.push_back(a4); + st_ptr->actions.push_back(a5); + st_ptr->actions.push_back(a6); + + /* Remove zero entries since they have no effect */ + st_ptr->actions.erase( + std::remove(st_ptr->actions.begin(), st_ptr->actions.end(), 0), + st_ptr->actions.end() + ); /* Next... */ continue; @@ -8509,24 +5436,9 @@ errr init_st_info_txt(FILE *fp) /* Process 'F' for "store Flags" (multiple lines) */ if (buf[0] == 'F') { - /* Parse every entry */ - for (s = buf + 2; *s; ) + if (0 != grab_one_store_flag(&st_ptr->flags, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_store_flag(st_ptr, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -8540,13 +5452,23 @@ errr init_st_info_txt(FILE *fp) /* Scan for the values */ if (4 != sscanf(buf + 2, "%d:%d:%d:%d", - &a1, &a2, &a3, &a4)) return (1); + &a1, &a2, &a3, &a4)) + { + return 1; + } + + /* Get a reference to the owners */ + auto owners = &st_ptr->owners; /* Save the values */ - st_ptr->owners[0] = a1; - st_ptr->owners[1] = a2; - st_ptr->owners[2] = a3; - st_ptr->owners[3] = a4; + owners->push_back(a1); + owners->push_back(a2); + owners->push_back(a3); + owners->push_back(a4); + + /* Sort and remove duplicates */ + std::sort(owners->begin(), owners->end()); + owners->erase(std::unique(owners->begin(), owners->end()), owners->end()); /* Next... */ continue; @@ -8582,9 +5504,9 @@ errr init_st_info_txt(FILE *fp) */ errr init_ba_info_txt(FILE *fp) { - int i = 0; + auto &ba_info = game->edit_data.ba_info; + char buf[1024]; - char *s; /* Current entry */ store_action_type *ba_ptr = NULL; @@ -8612,7 +5534,7 @@ errr init_ba_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -8624,23 +5546,19 @@ errr init_ba_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_ba_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - ba_ptr = &ba_info[i]; + ba_ptr = &expand_to_fit_index(ba_info, i); /* Copy name */ - assert(!ba_ptr->name); - ba_ptr->name = my_strdup(s); + ba_ptr->name = s; /* Next... */ continue; @@ -8701,9 +5619,9 @@ errr init_ba_info_txt(FILE *fp) */ errr init_ow_info_txt(FILE *fp) { - int i; + auto &ow_info = game->edit_data.ow_info; + char buf[1024]; - char *s, *t; /* Current entry */ owner_type *ow_ptr = NULL; @@ -8730,7 +5648,7 @@ errr init_ow_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -8742,23 +5660,19 @@ errr init_ow_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_ow_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - ow_ptr = &ow_info[i]; + ow_ptr = &expand_to_fit_index(ow_info, i); /* Copy name */ - assert(!ow_ptr->name); - ow_ptr->name = my_strdup(s); + ow_ptr->name = s; /* Next... */ continue; @@ -8806,24 +5720,9 @@ errr init_ow_info_txt(FILE *fp) /* Process 'L' for "Liked races/classes" (multiple lines) */ if (buf[0] == 'L') { - /* Parse every entry */ - for (s = buf + 2; *s; ) + if (0 != grab_one_race_flag(ow_ptr, STORE_LIKED, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_flag(ow_ptr, STORE_LIKED, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -8832,24 +5731,9 @@ errr init_ow_info_txt(FILE *fp) /* Process 'H' for "Hated races/classes" (multiple lines) */ if (buf[0] == 'H') { - /* Parse every entry */ - for (s = buf + 2; *s; ) + if (0 != grab_one_race_flag(ow_ptr, STORE_HATED, buf + 2)) { - /* Find the end of this entry */ - for (t = s; *t && (*t != ' ') && (*t != '|'); ++t) /* loop */; - - /* Nuke and skip any dividers */ - if (*t) - { - *t++ = '\0'; - while (*t == ' ' || *t == '|') t++; - } - - /* Parse this entry */ - if (0 != grab_one_race_flag(ow_ptr, STORE_HATED, s)) return (5); - - /* Start the next entry */ - s = t; + return (5); } /* Next... */ @@ -8869,9 +5753,9 @@ errr init_ow_info_txt(FILE *fp) */ errr init_wf_info_txt(FILE *fp) { - int i; + auto &wf_info = game->edit_data.wf_info; + char buf[1024]; - char *s; /* Current entry */ wilderness_type_info *wf_ptr = NULL; @@ -8898,7 +5782,7 @@ errr init_wf_info_txt(FILE *fp) if (buf[0] == 'N') { /* Find the colon before the name */ - s = strchr(buf + 2, ':'); + char *s = strchr(buf + 2, ':'); /* Verify that colon */ if (!s) return (1); @@ -8910,19 +5794,16 @@ errr init_wf_info_txt(FILE *fp) if (!*s) return (1); /* Get the index */ - i = atoi(buf + 2); + int i = atoi(buf + 2); /* Verify information */ if (i < error_idx) return (4); - /* Verify information */ - if (i >= max_wf_idx) return (2); - /* Save the index */ error_idx = i; /* Point at the "info" */ - wf_ptr = &wf_info[i]; + wf_ptr = &expand_to_fit_index(wf_info, i); /* Copy the name */ assert(!wf_ptr->name); @@ -8939,7 +5820,7 @@ errr init_wf_info_txt(FILE *fp) if (buf[0] == 'D') { /* Acquire the text */ - s = buf + 2; + char *s = buf + 2; /* Copy description */ assert(!wf_ptr->text); @@ -9014,7 +5895,6 @@ errr init_wf_info_txt(FILE *fp) #define RANDOM_OBJECT 0x04 #define RANDOM_EGO 0x08 #define RANDOM_ARTIFACT 0x10 -#define RANDOM_TRAP 0x20 typedef struct dungeon_grid dungeon_grid; @@ -9026,7 +5906,6 @@ struct dungeon_grid int object; /* Object */ int ego; /* Ego-Item */ int artifact; /* Artifact */ - int trap; /* Trap */ int cave_info; /* Flags for CAVE_MARK, CAVE_GLOW, CAVE_ICKY, CAVE_ROOM */ int special; /* Reserved for special terrain info */ int random; /* Number of the random effect */ @@ -9045,6 +5924,10 @@ static dungeon_grid letter[255]; */ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalstart, int ymax, int xmax, bool_ full) { + auto &wilderness = game->wilderness; + auto &wf_info = game->edit_data.wf_info; + auto &a_info = game->edit_data.a_info; + int i; char *zz[33]; @@ -9083,12 +5966,12 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst return (0); } - /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<trap>:<special>:<mimic>:<mflag>" -- info for dungeon grid */ + /* Process "F:<letter>:<terrain>:<cave_info>:<monster>:<object>:<ego>:<artifact>:<special>:<mimic>:<mflag>" -- info for dungeon grid */ if (buf[0] == 'F') { int num; - if ((num = tokenize(buf + 2, 11, zz, ':', '/')) > 1) + if ((num = tokenize(buf + 2, 10, zz, ':', '/')) > 1) { int index = zz[0][0]; @@ -9098,7 +5981,6 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst letter[index].object = 0; letter[index].ego = 0; letter[index].artifact = 0; - letter[index].trap = 0; letter[index].cave_info = 0; letter[index].special = 0; letter[index].random = 0; @@ -9204,34 +6086,17 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst if (num > 7) { - if (zz[7][0] == '*') - { - letter[index].random |= RANDOM_TRAP; - - if (zz[7][1]) - { - zz[7]++; - letter[index].trap = atoi(zz[7]); - } - } - else - letter[index].trap = atoi(zz[7]); - } - - if (num > 8) - { + char *field = zz[7]; /* Quests can be defined by name only */ - if (zz[8][0] == '"') + if (field[0] == '"') { - int i; - /* Hunt & shoot the ending " */ - i = strlen(zz[8]) - 1; - if (zz[8][i] == '"') zz[8][i] = '\0'; + int i = strlen(field) - 1; + if (field[i] == '"') field[i] = '\0'; letter[index].special = 0; for (i = 0; i < MAX_Q_IDX; i++) { - if (!strcmp(&zz[8][1], quest[i].name)) + if (!strcmp(&field[1], quest[i].name)) { letter[index].special = i; break; @@ -9239,17 +6104,17 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst } } else - letter[index].special = atoi(zz[8]); + letter[index].special = atoi(field); } - if (num > 9) + if (num > 8) { - letter[index].mimic = atoi(zz[9]); + letter[index].mimic = atoi(zz[8]); } - if (num > 10) + if (num > 9) { - letter[index].mflag = atoi(zz[10]); + letter[index].mflag = atoi(zz[9]); } return (0); @@ -9275,7 +6140,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst } /* Parse this entry */ - if (0 != grab_one_dungeon_flag(&dungeon_flags1, &dungeon_flags2, s)) return 1; + if (0 != grab_one_dungeon_flag(&dungeon_flags, s)) return 1; /* Start the next entry */ s = t; @@ -9351,28 +6216,7 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst if (m_idx) m_list[m_idx].mflag |= letter[idx].mflag; /* Object (and possible trap) */ - if ((random & RANDOM_OBJECT) && (random & RANDOM_TRAP)) - { - int level = object_level; - - object_level = quest[p_ptr->inside_quest].level; - - /* - * Random trap and random treasure defined - * 25% chance for trap and 75% chance for object - */ - if (rand_int(100) < 75) - { - place_object(y, x, FALSE, FALSE, OBJ_FOUND_SPECIAL); - } - else - { - place_trap(y, x); - } - - object_level = level; - } - else if (random & RANDOM_OBJECT) + if (random & RANDOM_OBJECT) { /* Create an out of deep object */ if (object_index) @@ -9402,11 +6246,6 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst place_object(y, x, TRUE, TRUE, OBJ_FOUND_SPECIAL); } } - /* Random trap */ - else if (random & RANDOM_TRAP) - { - place_trap(y, x); - } else if (object_index) { /* Get local object */ @@ -9432,11 +6271,10 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst { int I_kind = 0; - artifact_type *a_ptr = &a_info[artifact_index]; - - object_type forge; + auto a_ptr = &a_info[artifact_index]; /* Get local object */ + object_type forge; object_type *q_ptr = &forge; a_allow_special[artifact_index] = TRUE; @@ -9475,10 +6313,11 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst Let's just HACK around one observed bug: Shadow Cloak of Luthien [Globe of Light] */ { - u32b f1, f2, f3, f4, f5, esp; - object_flags(q_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f5 & TR5_SPELL_CONTAIN) + auto const flags = object_flags(q_ptr); + if (flags & TR_SPELL_CONTAIN) + { q_ptr->pval2 = -1; + } } /* Drop the artifact */ @@ -9518,29 +6357,32 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst /* Layout of the wilderness */ if (buf[2] == 'D') { - int x; - char i; - /* Acquire the text */ char *s = buf + 4; int y = *yval; - for (x = 0; x < max_wild_x; x++) + for (std::size_t x = 0; x < wilderness.width(); x++) { - if (1 != sscanf(s + x, "%c", &i)) return (1); - wild_map[y][x].feat = wildc2i[(int)i]; + char i; + if (1 != sscanf(s + x, "%c", &i)) + { + return (1); + } + + auto const wi = wildc2i[(int)i]; + + wilderness(x, y).feat = wi; /* * If this is a town/dungeon entrance, note * its coordinates. (Have to check for * duplicate Morias...) */ - if (wf_info[wildc2i[(int)i]].entrance && - wf_info[wildc2i[(int)i]].wild_x == 0) + if (wf_info[wi].entrance && wf_info[wi].wild_x == 0) { - wf_info[wildc2i[(int)i]].wild_x = x; - wf_info[wildc2i[(int)i]].wild_y = y; + wf_info[wi].wild_x = x; + wf_info[wi].wild_y = y; } } @@ -9592,7 +6434,9 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst { if (tokenize(buf + 4, 3, zz, ':', '/') == 3) { - wild_map[atoi(zz[1])][atoi(zz[2])].entrance = 1000 + atoi(zz[0]); + int y = atoi(zz[1]); + int x = atoi(zz[2]); + wilderness(x, y).entrance = 1000 + atoi(zz[0]); } else { @@ -9645,156 +6489,28 @@ static errr process_dungeon_file_aux(char *buf, int *yval, int *xval, int xvalst max_real_towns = atoi(zz[1]); } - /* Maximum r_idx */ - else if (zz[0][0] == 'R') - { - max_r_idx = atoi(zz[1]); - } - - /* Maximum re_idx */ - else if (zz[0][0] == 'r') - { - max_re_idx = atoi(zz[1]); - } - - /* Maximum s_idx */ - else if (zz[0][0] == 'k') - { - max_s_idx = atoi(zz[1]); - if (max_s_idx > MAX_SKILLS) return (1); - } - - /* Maximum ab_idx */ - else if (zz[0][0] == 'b') - { - max_ab_idx = atoi(zz[1]); - } - - /* Maximum k_idx */ - else if (zz[0][0] == 'K') - { - max_k_idx = atoi(zz[1]); - } - - /* Maximum v_idx */ - else if (zz[0][0] == 'V') - { - max_v_idx = atoi(zz[1]); - } - - /* Maximum f_idx */ - else if (zz[0][0] == 'F') - { - max_f_idx = atoi(zz[1]); - } - - /* Maximum a_idx */ - else if (zz[0][0] == 'A') - { - max_a_idx = atoi(zz[1]); - } - - /* Maximum e_idx */ - else if (zz[0][0] == 'E') - { - max_e_idx = atoi(zz[1]); - } - - /* Maximum ra_idx */ - else if (zz[0][0] == 'Z') - { - max_ra_idx = atoi(zz[1]); - } - /* Maximum o_idx */ else if (zz[0][0] == 'O') { max_o_idx = atoi(zz[1]); } - /* Maximum player types */ - else if (zz[0][0] == 'P') - { - if (zz[1][0] == 'R') - { - max_rp_idx = atoi(zz[2]); - } - else if (zz[1][0] == 'S') - { - max_rmp_idx = atoi(zz[2]); - } - else if (zz[1][0] == 'C') - { - max_c_idx = atoi(zz[2]); - } - else if (zz[1][0] == 'M') - { - max_mc_idx = atoi(zz[2]); - } - else if (zz[1][0] == 'H') - { - max_bg_idx = atoi(zz[2]); - } - } - /* Maximum m_idx */ else if (zz[0][0] == 'M') { max_m_idx = atoi(zz[1]); } - /* Maximum tr_idx */ - else if (zz[0][0] == 'U') - { - max_t_idx = atoi(zz[1]); - } - - /* Maximum wf_idx */ - else if (zz[0][0] == 'W') - { - max_wf_idx = atoi(zz[1]); - } - - /* Maximum ba_idx */ - else if (zz[0][0] == 'B') - { - max_ba_idx = atoi(zz[1]); - } - - /* Maximum st_idx */ - else if (zz[0][0] == 'S') - { - max_st_idx = atoi(zz[1]); - } - - /* Maximum set_idx */ - else if (zz[0][0] == 's') - { - max_set_idx = atoi(zz[1]); - } - - /* Maximum ow_idx */ - else if (zz[0][0] == 'N') - { - max_ow_idx = atoi(zz[1]); - } - /* Maximum wilderness x size */ else if (zz[0][0] == 'X') { - max_wild_x = atoi(zz[1]); + wilderness.width(atoi(zz[1])); } /* Maximum wilderness y size */ else if (zz[0][0] == 'Y') { - max_wild_y = atoi(zz[1]); - } - - /* Maximum d_idx */ - else if (zz[0][0] == 'D') - { - max_d_idx = atoi(zz[1]); + wilderness.height(atoi(zz[1])); } return (0); @@ -9989,25 +6705,25 @@ static cptr process_dungeon_file_expr(char **sp, char *fp) /* Race */ else if (streq(b + 1, "RACE")) { - v = rp_ptr->title; + v = rp_ptr->title.c_str(); // The string SHOULD be stable enough for this } /* Race Mod */ else if (streq(b + 1, "RACEMOD")) { - v = rmp_ptr->title; + v = rmp_ptr->title.c_str(); // The string SHOULD be stable enough for this } /* Class */ else if (streq(b + 1, "CLASS")) { - v = cp_ptr->title; + v = cp_ptr->title.c_str(); // The string SHOULD be stable enough for this } /* Player */ else if (streq(b + 1, "PLAYER")) { - v = player_base; + v = game->player_base.c_str(); // The string SHOULD be stable enough for this } /* Town */ @@ -10194,7 +6910,7 @@ errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, b if (buf[0] == '%') { /* Process that file if allowed */ - (void)process_dungeon_file(buf + 2, yval, xval, ymax, xmax, FALSE, full); + process_dungeon_file(buf + 2, yval, xval, ymax, xmax, FALSE, full); /* Continue */ continue; diff --git a/src/init1.hpp b/src/init1.hpp index 766e467d..1c417285 100644 --- a/src/init1.hpp +++ b/src/init1.hpp @@ -1,26 +1,27 @@ #pragma once #include "h-basic.h" +#include "dungeon_flag_set.hpp" -extern int color_char_to_attr(char c); +int color_char_to_attr(char c); extern byte conv_color[16]; -extern errr init_player_info_txt(FILE *fp); -extern errr init_ab_info_txt(FILE *fp); -extern errr init_s_info_txt(FILE *fp); -extern errr init_set_info_txt(FILE *fp); -extern errr init_v_info_txt(FILE *fp); -extern errr init_f_info_txt(FILE *fp); -extern errr init_k_info_txt(FILE *fp); -extern errr init_a_info_txt(FILE *fp); -extern errr init_ra_info_txt(FILE *fp); -extern errr init_e_info_txt(FILE *fp); -extern errr init_r_info_txt(FILE *fp); -extern errr init_re_info_txt(FILE *fp); -extern errr init_d_info_txt(FILE *fp); -extern errr init_t_info_txt(FILE *fp); -extern errr init_ba_info_txt(FILE *fp); -extern errr init_st_info_txt(FILE *fp); -extern errr init_ow_info_txt(FILE *fp); -extern errr init_wf_info_txt(FILE *fp); -extern errr grab_one_dungeon_flag(u32b *flags1, u32b *flags2, cptr what); -extern errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full); +errr init_player_info_txt(FILE *fp); +errr init_ab_info_txt(FILE *fp); +errr init_s_info_txt(FILE *fp); +errr init_set_info_txt(FILE *fp); +errr init_v_info_txt(FILE *fp); +errr init_f_info_txt(FILE *fp); +errr init_k_info_txt(FILE *fp); +errr init_a_info_txt(FILE *fp); +errr init_ra_info_txt(FILE *fp); +errr init_e_info_txt(FILE *fp); +errr init_r_info_txt(FILE *fp); +errr init_re_info_txt(FILE *fp); +errr init_d_info_txt(FILE *fp); +errr init_t_info_txt(FILE *fp); +errr init_ba_info_txt(FILE *fp); +errr init_st_info_txt(FILE *fp); +errr init_ow_info_txt(FILE *fp); +errr init_wf_info_txt(FILE *fp); +errr grab_one_dungeon_flag(dungeon_flag_set *flags, const char *str); +errr process_dungeon_file(cptr name, int *yval, int *xval, int ymax, int xmax, bool_ init, bool_ full); diff --git a/src/init2.cc b/src/init2.cc index 338ebf10..894e4767 100644 --- a/src/init2.cc +++ b/src/init2.cc @@ -11,37 +11,40 @@ #include "ego_item_type.hpp" #include "files.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "generate.hpp" #include "gen_evol.hpp" #include "gen_maze.hpp" -#include "hist_type.hpp" #include "hooks.hpp" #include "init1.hpp" #include "lua_bind.hpp" #include "messages.hpp" -#include "meta_class_type.hpp" #include "modules.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" +#include "object_type.hpp" #include "owner_type.hpp" #include "player_class.hpp" #include "player_race.hpp" #include "player_race_mod.hpp" -#include "quark.hpp" +#include "q_library.hpp" #include "randart.hpp" #include "randart_part_type.hpp" -#include "script.h" #include "set_type.hpp" #include "skill_type.hpp" #include "spells3.hpp" +#include "spells4.hpp" +#include "spells5.hpp" +#include "spells6.hpp" #include "squeltch.hpp" #include "store_action_type.hpp" #include "store_info_type.hpp" #include "store_type.hpp" #include "tables.hpp" -#include "trap_type.hpp" #include "tome/make_array.hpp" #include "town_type.hpp" #include "util.hpp" @@ -228,41 +231,6 @@ void init_file_paths(char *path) /* - * Initialize and verify the file paths, and the score file. - * - * Use the ANGBAND_PATH environment var if possible, else use - * DEFAULT_PATH, and in either case, branch off appropriately. - * - * First, we'll look for the ANGBAND_PATH environment variable, - * and then look for the files in there. If that doesn't work, - * we'll try the DEFAULT_PATH constant. So be sure that one of - * these two things works... - * - * We must ensure that the path ends with "PATH_SEP" if needed, - * since the "init_file_paths()" function will simply append the - * relevant "sub-directory names" to the given path. - */ -void init_file_paths_with_env() -{ - char path[1024]; - - cptr tail; - - /* Get the environment variable */ - tail = getenv("TOME_PATH"); - - /* Use the angband_path, or a default */ - strcpy(path, tail ? tail : DEFAULT_PATH); - - /* Hack -- Add a path separator (only if needed) */ - if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP); - - /* Initialize */ - init_file_paths(path); -} - - -/* * Hack -- help give useful error messages */ s16b error_idx; @@ -306,11 +274,6 @@ namespace { static constexpr char const *name = "f_info.txt"; - static void allocate() - { - f_info = make_array<feature_type>(max_f_idx); - } - static errr parse(FILE *fp) { return init_f_info_txt(fp); @@ -322,11 +285,6 @@ namespace { static constexpr char const *name = "k_info.txt"; - static void allocate() - { - k_info = make_array<object_kind>(max_k_idx); - } - static errr parse(FILE *fp) { return init_k_info_txt(fp); @@ -338,11 +296,6 @@ namespace { static constexpr char const *name = "set_info.txt"; - static void allocate() - { - set_info = make_array<set_type>(max_set_idx); - } - static errr parse(FILE *fp) { return init_set_info_txt(fp); @@ -354,11 +307,6 @@ namespace { static constexpr char const *name = "a_info.txt"; - static void allocate() - { - a_info = make_array<artifact_type>(max_a_idx); - } - static errr parse(FILE *fp) { return init_a_info_txt(fp); @@ -370,11 +318,6 @@ namespace { static constexpr char const *name = "s_info.txt"; - static void allocate() - { - s_info = make_array<skill_type>(max_s_idx); - } - static errr parse(FILE *fp) { return init_s_info_txt(fp); @@ -386,11 +329,6 @@ namespace { static constexpr char const *name = "ab_info.txt"; - static void allocate() - { - ab_info = make_array<ability_type>(max_ab_idx); - } - static errr parse(FILE *fp) { return init_ab_info_txt(fp); @@ -402,11 +340,6 @@ namespace { static constexpr char const *name = "e_info.txt"; - static void allocate() - { - e_info = make_array<ego_item_type>(max_e_idx); - } - static errr parse(FILE *fp) { return init_e_info_txt(fp); @@ -418,11 +351,6 @@ namespace { static constexpr char const *name = "ra_info.txt"; - static void allocate() - { - ra_info = make_array<randart_part_type>(max_ra_idx); - } - static errr parse(FILE *fp) { return init_ra_info_txt(fp); @@ -434,11 +362,6 @@ namespace { static constexpr char const *name = "r_info.txt"; - static void allocate() - { - r_info = make_array<monster_race>(max_r_idx); - } - static errr parse(FILE *fp) { return init_r_info_txt(fp); @@ -450,11 +373,6 @@ namespace { static constexpr char const *name = "re_info.txt"; - static void allocate() - { - re_info = make_array<monster_ego>(max_re_idx); - } - static errr parse(FILE *fp) { return init_re_info_txt(fp); @@ -466,11 +384,6 @@ namespace { static constexpr char const *name = "d_info.txt"; - static void allocate() - { - d_info = make_array<dungeon_info_type>(max_d_idx); - } - static errr parse(FILE *fp) { return init_d_info_txt(fp); @@ -482,11 +395,6 @@ namespace { static constexpr char const *name = "st_info.txt"; - static void allocate() - { - st_info = make_array<store_info_type>(max_st_idx); - } - static errr parse(FILE *fp) { return init_st_info_txt(fp); @@ -498,11 +406,6 @@ namespace { static constexpr char const *name = "ow_info.txt"; - static void allocate() - { - ow_info = make_array<owner_type>(max_ow_idx); - } - static errr parse(FILE *fp) { return init_ow_info_txt(fp); @@ -514,11 +417,6 @@ namespace { static constexpr char const *name = "ba_info.txt"; - static void allocate() - { - ba_info = make_array<store_action_type>(max_ba_idx); - } - static errr parse(FILE *fp) { return init_ba_info_txt(fp); @@ -530,11 +428,6 @@ namespace { static constexpr char const *name = "wf_info.txt"; - static void allocate() - { - wf_info = make_array<wilderness_type_info>(max_wf_idx); - } - static errr parse(FILE *fp) { return init_wf_info_txt(fp); @@ -542,31 +435,10 @@ namespace { }; - struct tr_info_traits { - - static constexpr char const *name = "tr_info.txt"; - - static void allocate() - { - t_info = make_array<trap_type>(max_t_idx); - } - - static errr parse(FILE *fp) - { - return init_t_info_txt(fp); - } - - }; - struct v_info_traits { static constexpr char const *name = "v_info.txt"; - static void allocate() - { - v_info = make_array<vault_type>(max_v_idx); - } - static errr parse(FILE *fp) { return init_v_info_txt(fp); @@ -578,19 +450,6 @@ namespace { static constexpr char const *name = "p_info.txt"; - static void allocate() - { - race_info = make_array<player_race>(max_rp_idx); - race_mod_info = make_array<player_race_mod>(max_rmp_idx); - class_info = make_array<player_class>(max_c_idx); - bg = make_array<hist_type>(max_bg_idx); - meta_class_info = make_array<meta_class_type>(max_mc_idx); - for (std::size_t i = 0; i < max_mc_idx; i++) - { - meta_class_info[i].classes = make_array<s16b>(max_c_idx); - } - } - static errr parse(FILE *fp) { return init_player_info_txt(fp); @@ -602,9 +461,6 @@ namespace { template<typename T> static errr init_x_info() { - /* Allocate the data array */ - T::allocate(); - /* Build the filename */ boost::filesystem::path path(ANGBAND_DIR_EDIT); path /= T::name; @@ -663,13 +519,16 @@ static void init_basic() /* Extended trigger macros */ cli_info = make_array<cli_comm>(CLI_MAX); + + /* Options */ + options = new struct options(); } /* * Initialise misc. values */ -static errr init_misc(void) +static errr init_misc() { int xstart = 0; int ystart = 0; @@ -677,12 +536,6 @@ static errr init_misc(void) /*** Prepare the various "bizarre" arrays ***/ - /* Initialize quark subsystem */ - quark_init(); - - /* Initialize messages subsystem */ - message_init(); - /* Initialise the values */ process_dungeon_file("misc.txt", &ystart, &xstart, 0, 0, TRUE, FALSE); @@ -705,26 +558,24 @@ static errr init_misc(void) /* * Initialise town array */ -static errr init_towns(void) +static errr init_towns() { - int i = 0, j = 0; + auto const &st_info = game->edit_data.st_info; - /*** Prepare the Towns ***/ + town_info = new town_type[max_towns]; - /* Allocate the towns */ - town_info = make_array<town_type>(max_towns); - - for (i = 1; i < max_towns; i++) + for (std::size_t i = 1; i < max_towns; i++) { - if (i <= max_real_towns) town_info[i].flags |= (TOWN_REAL); - - /* Allocate the stores */ - town_info[i].store = make_array<store_type>(max_st_idx); + if (i <= max_real_towns) + { + town_info[i].flags |= TOWN_REAL; + } /* Fill in each store */ - for (j = 0; j < max_st_idx; j++) + for (std::size_t j = 0; j < st_info.size(); j++) { - /* Access the store */ + /* Create the store */ + town_info[i].store.emplace_back(store_type()); store_type *st_ptr = &town_info[i].store[j]; /* Know who we are */ @@ -734,74 +585,59 @@ static errr init_towns(void) st_ptr->stock_size = 0; } } + return 0; } void create_stores_stock(int t) { - int j; + auto const &st_info = game->edit_data.st_info; + town_type *t_ptr = &town_info[t]; if (t_ptr->stocked) return; - for (j = 0; j < max_st_idx; j++) + for (std::size_t j = 0; j < st_info.size(); j++) { store_type *st_ptr = &t_ptr->store[j]; /* Assume full stock */ st_ptr->stock_size = st_info[j].max_obj; - /* Allocate the stock */ - st_ptr->stock = make_array<object_type>(st_ptr->stock_size); - } - t_ptr->stocked = TRUE; -} - -/* - * Initialise wilderness map array - */ -static errr init_wilderness(void) -{ - int i; - - /* Allocate the wilderness (two-dimension array) */ - wild_map = make_array<wilderness_map *>(max_wild_y); - - /* Init the other pointers */ - for (i = 0; i < max_wild_y; i++) - { - wild_map[i] = make_array<wilderness_map>(max_wild_x); + /* Reserve space for stock */ + st_ptr->stock.reserve(st_ptr->stock_size); } - /* No encounter right now */ - generate_encounter = FALSE; - - return 0; + t_ptr->stocked = TRUE; } /* * Initialise some other arrays */ -static errr init_other(void) +static errr init_other() { - int i, n; + auto const &d_info = game->edit_data.d_info; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + auto &level_markers = game->level_markers; /*** Prepare the "dungeon" information ***/ /* Allocate and Wipe the special gene flags */ - m_allow_special = make_array<bool_>(max_r_idx); - k_allow_special = make_array<bool_>(max_k_idx); - a_allow_special = make_array<bool_>(max_a_idx); + m_allow_special = make_array<bool_>(r_info.size()); + k_allow_special = make_array<bool_>(k_info.size()); + a_allow_special = make_array<bool_>(a_info.size()); /*** Prepare "vinfo" array ***/ /* Used by "update_view()" */ - (void)vinfo_init(); + vinfo_init(); /* Allocate and Wipe the object list */ - o_list = make_array<object_type>(max_o_idx); + o_list = new object_type[max_o_idx]; /* Allocate and Wipe the monster list */ m_list = new monster_type[max_m_idx]; @@ -810,76 +646,24 @@ static errr init_other(void) km_list = new monster_type[max_m_idx]; /* Allocate and Wipe the max dungeon level */ - max_dlv = make_array<s16b>(max_d_idx); + max_dlv = make_array<s16b>(d_info.size()); - /* Allocate and Wipe the special levels */ - for (i = 0; i < MAX_DUNGEON_DEPTH; i++) - { - special_lvl[i] = make_array<bool_>(max_d_idx); - } + /* Allocate level markers */ + level_markers.resize(boost::extents[MAX_DUNGEON_DEPTH][d_info.size()]); /* Allocate and wipe each line of the cave */ cave = new cave_type *[MAX_HGT]; - for (i = 0; i < MAX_HGT; i++) + for (std::size_t i = 0; i < MAX_HGT; i++) { /* Allocate one row of the cave */ cave[i] = new cave_type[MAX_WID]; } - /*** Pre-allocate the basic "auto-inscriptions" ***/ - - /* The "basic" feelings */ - (void)quark_add("cursed"); - (void)quark_add("broken"); - (void)quark_add("average"); - (void)quark_add("good"); - - /* The "extra" feelings */ - (void)quark_add("excellent"); - (void)quark_add("worthless"); - (void)quark_add("special"); - (void)quark_add("terrible"); - - /* Some extra strings */ - (void)quark_add("uncursed"); - (void)quark_add("on sale"); - - - /*** Prepare the options ***/ - - /* Scan the options */ - for (i = 0; option_info[i].o_desc; i++) - { - int os = option_info[i].o_page; - int ob = option_info[i].o_bit; - - /* Set the "default" options */ - if (option_info[i].o_var) - { - /* Accept */ - option_mask[os] |= (1L << ob); - - /* Set */ - if (option_info[i].o_norm) - { - /* Set */ - option_flag[os] |= (1L << ob); - } - - /* Clear */ - else - { - /* Clear */ - option_flag[os] &= ~(1L << ob); - } - } - } - /* Analyze the windows */ - for (n = 0; n < 8; n++) + for (std::size_t n = 0; n < 8; n++) { /* Analyze the options */ - for (i = 0; i < 32; i++) + for (std::size_t i = 0; i < 32; i++) { /* Accept */ if (window_flag_desc[i]) @@ -901,7 +685,7 @@ static errr init_other(void) /*** Pre-allocate space for the "format()" buffer ***/ /* Hack -- Just call the "format()" function */ - (void)format("%s (%s).", "Dark God <darkgod@t-o-m-e.net>", MAINTAINER); + format("%s (%s).", "Dark God <darkgod@t-o-m-e.net>", MAINTAINER); /* Success */ return (0); @@ -912,15 +696,11 @@ static errr init_other(void) /* * Initialise some other arrays */ -static errr init_alloc(void) +static errr init_alloc() { - int i, j; - - object_kind *k_ptr; - - monster_race *r_ptr; - - alloc_entry *table; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; s16b num[MAX_DEPTH_MONSTER]; @@ -934,22 +714,20 @@ static errr init_alloc(void) /* Clear the "num" array */ memset(num, 0, MAX_DEPTH_MONSTER * sizeof(s16b)); - /* Size of "alloc_kind_table" */ - alloc_kind_size = 0; - /* Scan the objects */ - for (i = 1; i < max_k_idx; i++) + std::size_t kind_size = 0; + for (auto const &k_ref: k_info) { - k_ptr = &k_info[i]; + auto k_ptr = &k_ref; /* Scan allocation pairs */ - for (j = 0; j < ALLOCATION_MAX; j++) + for (std::size_t j = 0; j < ALLOCATION_MAX; j++) { /* Count the "legal" entries */ if (k_ptr->chance[j]) { /* Count the entries */ - alloc_kind_size++; + kind_size++; /* Group by level */ num[k_ptr->locale[j]]++; @@ -958,7 +736,7 @@ static errr init_alloc(void) } /* Collect the level indexes */ - for (i = 1; i < MAX_DEPTH_MONSTER; i++) + for (std::size_t i = 1; i < MAX_DEPTH_MONSTER; i++) { /* Group by level */ num[i] += num[i - 1]; @@ -971,18 +749,16 @@ static errr init_alloc(void) /*** Initialise object allocation info ***/ /* Allocate the alloc_kind_table */ - alloc_kind_table = make_array<alloc_entry>(alloc_kind_size); - - /* Access the table entry */ - table = alloc_kind_table; + alloc.kind_table.clear(); + alloc.kind_table.resize(kind_size); /* Scan the objects */ - for (i = 1; i < max_k_idx; i++) + for (std::size_t i = 1; i < k_info.size(); i++) { - k_ptr = &k_info[i]; + auto k_ptr = &k_info[i]; /* Scan allocation pairs */ - for (j = 0; j < ALLOCATION_MAX; j++) + for (std::size_t j = 0; j < ALLOCATION_MAX; j++) { /* Count the "legal" entries */ if (k_ptr->chance[j]) @@ -1002,11 +778,12 @@ static errr init_alloc(void) z = y + aux[x]; /* Load the entry */ - table[z].index = i; - table[z].level = x; - table[z].prob1 = p; - table[z].prob2 = p; - table[z].prob3 = p; + auto &entry = alloc.kind_table[z]; + entry.index = i; + entry.level = x; + entry.prob1 = p; + entry.prob2 = p; + entry.prob3 = p; /* Another entry complete for this locale */ aux[x]++; @@ -1023,20 +800,18 @@ static errr init_alloc(void) /* Clear the "num" array */ memset(num, 0, MAX_DEPTH_MONSTER * sizeof(s16b)); - /* Size of "alloc_race_table" */ - alloc_race_size = 0; - /* Scan the monsters */ - for (i = 1; i < max_r_idx; i++) + std::size_t race_size = 0; + for (auto &r_ref: r_info) { /* Get the i'th race */ - r_ptr = &r_info[i]; + auto r_ptr = &r_ref; /* Legal monsters */ if (r_ptr->rarity) { /* Count the entries */ - alloc_race_size++; + race_size++; /* Group by level */ num[r_ptr->level]++; @@ -1044,7 +819,7 @@ static errr init_alloc(void) } /* Collect the level indexes */ - for (i = 1; i < MAX_DEPTH_MONSTER; i++) + for (std::size_t i = 1; i < MAX_DEPTH_MONSTER; i++) { /* Group by level */ num[i] += num[i - 1]; @@ -1057,16 +832,14 @@ static errr init_alloc(void) /*** Initialise monster allocation info ***/ /* Allocate the alloc_race_table */ - alloc_race_table = make_array<alloc_entry>(alloc_race_size); - - /* Access the table entry */ - table = alloc_race_table; + alloc.race_table.clear(); + alloc.race_table.resize(race_size); /* Scan the monsters */ - for (i = 1; i < max_r_idx; i++) + for (std::size_t i = 1; i < r_info.size(); i++) { /* Get the i'th race */ - r_ptr = &r_info[i]; + auto r_ptr = &r_info[i]; /* Count valid pairs */ if (r_ptr->rarity) @@ -1086,11 +859,12 @@ static errr init_alloc(void) z = y + aux[x]; /* Load the entry */ - table[z].index = i; - table[z].level = x; - table[z].prob1 = p; - table[z].prob2 = p; - table[z].prob3 = p; + auto &entry = alloc.race_table[z]; + entry.index = i; + entry.level = x; + entry.prob1 = p; + entry.prob2 = p; + entry.prob3 = p; /* Another entry complete for this locale */ aux[x]++; @@ -1105,15 +879,21 @@ static errr init_alloc(void) /* Init the sets in a_info */ static void init_sets_aux() { - int i, j; + auto const &set_info = game->edit_data.set_info; + auto &a_info = game->edit_data.a_info; - for (i = 0; i < max_a_idx; i++) - a_info[i].set = -1; - for (i = 0; i < max_set_idx; i++) + for (auto &a_ref: a_info) { - for (j = 0; j < set_info[i].num; j++) + a_ref.set = -1; + } + + for (std::size_t i = 0; i < set_info.size(); i++) + { + auto const &set_ref = set_info[i]; + + for (std::size_t j = 0; j < set_ref.num; j++) { - a_info[set_info[i].arts[j].a_idx].set = i; + a_info[set_ref.arts[j].a_idx].set = i; } } } @@ -1121,42 +901,43 @@ static void init_sets_aux() /* * Mark guardians and their artifacts with SPECIAL_GENE flag */ -static void init_guardians(void) +static void init_guardians() { - int i; + 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; /* Scan 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]; /* Mark the guadian monster */ if (d_ptr->final_guardian) { - monster_race *r_ptr = &r_info[d_ptr->final_guardian]; + auto r_ptr = &r_info[d_ptr->final_guardian]; - r_ptr->flags9 |= RF9_SPECIAL_GENE; + r_ptr->flags |= RF_SPECIAL_GENE; /* Mark the final artifact */ if (d_ptr->final_artifact) { - artifact_type *a_ptr = &a_info[d_ptr->final_artifact]; - - a_ptr->flags4 |= TR4_SPECIAL_GENE; + auto a_ptr = &a_info[d_ptr->final_artifact]; + a_ptr->flags |= TR_SPECIAL_GENE; } /* Mark the final object */ if (d_ptr->final_object) { - object_kind *k_ptr = &k_info[d_ptr->final_object]; - - k_ptr->flags4 |= TR4_SPECIAL_GENE; + auto k_ptr = &k_info[d_ptr->final_object]; + k_ptr->flags |= TR_SPECIAL_GENE; } /* Give randart if there are no final artifacts */ if (!(d_ptr->final_artifact) && !(d_ptr->final_object)) { - r_ptr->flags7 |= RF7_DROP_RANDART; + r_ptr->flags |= RF_DROP_RANDART; } } } @@ -1236,7 +1017,7 @@ static void init_angband_aux(cptr why) * Note that the "graf-xxx.prf" file must be loaded separately, * if needed, in the first (?) pass through "TERM_XTRA_REACT". */ -void init_angband(void) +void init_angband() { int fd = -1; @@ -1293,7 +1074,7 @@ void init_angband(void) } /* Close it */ - (void)fd_close(fd); + fd_close(fd); /*** Display the "news" file ***/ @@ -1355,8 +1136,7 @@ void init_angband(void) } /* Close it */ - (void)fd_close(fd); - + fd_close(fd); /*** Initialise some arrays ***/ @@ -1365,8 +1145,20 @@ void init_angband(void) if (init_misc()) quit("Cannot initialise misc. values"); /* Initialise some other arrays */ - note("[Initialising scripting... (script)]"); - init_lua_init(); + { + note("[Initialising scripting... (script)]"); + + /* Initialize schooled spells */ + schools_init(); + school_spells_init(); + init_school_books(); + + /* Post-spell creation initialization */ + initialize_bookable_spells(); + + /* Finish up the corruptions */ + init_corruptions(); + } /* Initialise skills info */ note("[Initialising arrays... (skills)]"); @@ -1434,18 +1226,10 @@ void init_angband(void) note("[Initialising arrays... (wilderness features)]"); if (init_x_info<wf_info_traits>()) quit("Cannot initialise wilderness features"); - /* Initialise wilderness map array */ - note("[Initialising arrays... (wilderness map)]"); - if (init_wilderness()) quit("Cannot initialise wilderness map"); - /* Initialise town array */ note("[Initialising arrays... (towns)]"); if (init_towns()) quit("Cannot initialise towns"); - /* Initialise trap info */ - note("[Initialising arrays... (traps)]"); - if (init_x_info<tr_info_traits>()) quit("Cannot initialise traps"); - /* Initialise some other arrays */ note("[Initialising arrays... (other)]"); if (init_other()) quit("Cannot initialise other stuff"); diff --git a/src/init2.h b/src/init2.h index 5697e4ef..bdc525bf 100644 --- a/src/init2.h +++ b/src/init2.h @@ -5,9 +5,8 @@ extern "C" { #endif -extern void init_file_paths(char *path); -extern void init_file_paths_with_env(); -extern void init_angband(void); +void init_file_paths(char *path); +void init_angband(); #ifdef __cplusplus } // extern "C" diff --git a/src/init2.hpp b/src/init2.hpp index 707a2706..de575e77 100644 --- a/src/init2.hpp +++ b/src/init2.hpp @@ -2,8 +2,8 @@ #include "h-basic.h" -extern void init_corruptions(); -extern void create_stores_stock(int t); -extern errr init_v_info(void); +void init_corruptions(); +void create_stores_stock(int t); +errr init_v_info(); extern s16b error_idx; extern s16b error_line; diff --git a/src/inscription_info_type.hpp b/src/inscription_info_type.hpp index 6dbb67f1..4e1e4c32 100644 --- a/src/inscription_info_type.hpp +++ b/src/inscription_info_type.hpp @@ -9,6 +9,5 @@ struct inscription_info_type { char text[40]; /* The inscription itself */ byte when; /* When it is executed */ - bool_ know; /* Is the inscription know ? */ byte mana; /* Grid mana needed */ }; diff --git a/src/joke.cc b/src/joke.cc index be272115..07149b3f 100644 --- a/src/joke.cc +++ b/src/joke.cc @@ -22,9 +22,9 @@ static void gen_joke_place_monster(int r_idx) } } -bool_ gen_joke_monsters(void *data, void *in, void *out) +bool gen_joke_monsters(void *data, void *in, void *out) { - if (joke_monsters) + if (options->joke_monsters) { if ((dungeon_type == 20) && (dun_level == 72)) diff --git a/src/joke.hpp b/src/joke.hpp index 05ac1843..2721636e 100644 --- a/src/joke.hpp +++ b/src/joke.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -extern bool_ gen_joke_monsters(void *data, void *in, void *out); +bool gen_joke_monsters(void *data, void *in, void *out); diff --git a/src/level_marker.cc b/src/level_marker.cc new file mode 100644 index 00000000..ee1d8ebe --- /dev/null +++ b/src/level_marker.cc @@ -0,0 +1,12 @@ +#include "level_marker.hpp" + +EnumStringMap<level_marker> const &level_marker_values() +{ + auto static instance = new EnumStringMap<level_marker> { + { level_marker::NORMAL, "normal" }, + { level_marker::SPECIAL, "special" }, + { level_marker::REGENERATE, "regenerate" } + }; + + return *instance; +} diff --git a/src/level_marker.hpp b/src/level_marker.hpp new file mode 100644 index 00000000..07925b70 --- /dev/null +++ b/src/level_marker.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include <tome/enum_string_map.hpp> + +/** + * Markers for 'special' levels. + */ +enum class level_marker { + NORMAL, + SPECIAL, + REGENERATE +}; + +/** + * Is the level "normal"? + */ +inline bool is_normal_level(level_marker m) +{ + return m == level_marker::NORMAL; +} + +/** + * Bidrectional map between enum and strings. + */ +EnumStringMap<level_marker> const &level_marker_values(); diff --git a/src/levels.cc b/src/levels.cc index ac3aa3d3..2a1bb3ab 100644 --- a/src/levels.cc +++ b/src/levels.cc @@ -9,6 +9,7 @@ #include "levels.hpp" #include "dungeon_info_type.hpp" +#include "game.hpp" #include "init1.hpp" #include "util.hpp" #include "util.h" @@ -78,6 +79,8 @@ static bool_ get_command(const char *file, char comm, char *param) */ int get_branch() { + auto const &d_info = game->edit_data.d_info; + char file[20], buf[5]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); @@ -95,6 +98,8 @@ int get_branch() */ int get_fbranch() { + auto const &d_info = game->edit_data.d_info; + char file[20], buf[5]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); @@ -112,6 +117,8 @@ int get_fbranch() */ int get_flevel() { + auto const &d_info = game->edit_data.d_info; + char file[20], buf[5]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); @@ -129,6 +136,8 @@ int get_flevel() */ bool_ get_dungeon_save(char *buf) { + auto const &d_info = game->edit_data.d_info; + char file[20]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); @@ -144,8 +153,9 @@ bool_ get_dungeon_save(char *buf) */ bool_ get_dungeon_generator(char *buf) { - char file[20]; + auto const &d_info = game->edit_data.d_info; + char file[20]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); /* Get and return the level */ @@ -159,8 +169,9 @@ bool_ get_dungeon_generator(char *buf) */ bool_ get_dungeon_special(char *buf) { - char file[20]; + auto const &d_info = game->edit_data.d_info; + char file[20]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); /* Get and return the level */ @@ -174,8 +185,9 @@ bool_ get_dungeon_special(char *buf) */ bool_ get_dungeon_name(char *buf) { - char file[20]; + auto const &d_info = game->edit_data.d_info; + char file[20]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); /* Get and return the level */ @@ -189,6 +201,8 @@ bool_ get_dungeon_name(char *buf) */ void get_level_flags() { + auto const &d_info = game->edit_data.d_info; + char file[20]; char buf[1024], *s, *t; @@ -213,7 +227,7 @@ void get_level_flags() } /* Parse this entry */ - if (0 != grab_one_dungeon_flag(&dungeon_flags1, &dungeon_flags2, s)) return; + if (0 != grab_one_dungeon_flag(&dungeon_flags, s)) return; /* Start the next entry */ s = t; @@ -226,8 +240,9 @@ void get_level_flags() */ bool_ get_level_desc(char *buf) { - char file[20]; + auto const &d_info = game->edit_data.d_info; + char file[20]; sprintf(file, "dun%d.%d", dungeon_type, dun_level - d_info[dungeon_type].mindepth); /* Get and return the level */ diff --git a/src/levels.hpp b/src/levels.hpp index 187092b1..a48f1d95 100644 --- a/src/levels.hpp +++ b/src/levels.hpp @@ -2,12 +2,12 @@ #include "h-basic.h" -extern bool_ get_dungeon_generator(char *buf); -extern bool_ get_level_desc(char *buf); -extern void get_level_flags(void); -extern bool_ get_dungeon_name(char *buf); -extern bool_ get_dungeon_special(char *buf); -extern int get_branch(void); -extern int get_fbranch(void); -extern int get_flevel(void); -extern bool_ get_dungeon_save(char *buf); +bool_ get_dungeon_generator(char *buf); +bool_ get_level_desc(char *buf); +void get_level_flags(); +bool_ get_dungeon_name(char *buf); +bool_ get_dungeon_special(char *buf); +int get_branch(); +int get_fbranch(); +int get_flevel(); +bool_ get_dungeon_save(char *buf); diff --git a/src/loadsave.cc b/src/loadsave.cc index 1806d7c8..3c843a36 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -1,12 +1,12 @@ #include "loadsave.hpp" #include "loadsave.h" -#include "ability_type.hpp" #include "artifact_type.hpp" #include "birth.hpp" #include "cave_type.hpp" #include "dungeon_info_type.hpp" #include "ego_item_type.hpp" +#include "game.hpp" #include "init1.hpp" #include "init2.hpp" #include "levels.hpp" @@ -18,18 +18,18 @@ #include "object1.hpp" #include "object2.hpp" #include "object_kind.hpp" +#include "options.hpp" #include "player_class.hpp" +#include "player_level_flag.hpp" #include "player_race.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "hooks.hpp" #include "skill_type.hpp" #include "store_type.hpp" #include "tables.hpp" #include "timer_type.hpp" #include "town_type.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "wilderness_map.hpp" @@ -38,12 +38,33 @@ #include "xtra2.hpp" #include "z-rand.hpp" +#include <boost/filesystem.hpp> #include <cassert> +#include <fmt/format.h> #include <memory> static u32b vernum; /* Version flag */ static FILE *fff; /* Local savefile ptr */ +/* + * Show information on the screen, one line at a time. + * + * Avoid the top two lines, to avoid interference with "msg_print()". + */ +static void note(cptr msg) +{ + static int y = 2; + + /* Draw the message */ + prt(msg, y, 0); + + /* Advance one line (wrap if needed) */ + if (++y >= 24) y = 2; + + /* Flush it */ + Term_fresh(); +} + /** * Load/save flag */ @@ -52,22 +73,23 @@ enum class ls_flag_t { SAVE = 7 }; -/* - * Basic byte-level reading from savefile. This provides a single point - * of interface to the pseudoencryption that ToME (and Angband) - * uses. I'm thinking about if it might be faster/better to modify all - * the do_* functions to directly do this stuff -- it'd make the code - * somewhat uglier to maintain, but concievably might be much faster. Or - * is it better maybe to scrap the pseudoencryption entirely and adopt - * some other means of obfuscation, should it still prove useful in any - * way? -- Improv - * - * What's the point of encryption on savefiles anyway? If I wanted to - * make a cheater savefile, I'd activate debug mode, and hack the game - * not to save it. There's no point. -- takkaria +/** + * Structure for loading/saving option values */ +namespace { + +struct option_value { + std::string name; + bool_ value; +}; -static byte sf_get(void) +} // namespace (anonymous) + + +/* + * Basic byte-level reading from savefile. + */ +static byte sf_get() { byte c; @@ -81,7 +103,7 @@ static byte sf_get(void) static void sf_put(byte v) { - (void)putc((int)v, fff); + putc((int)v, fff); } /* @@ -106,6 +128,11 @@ static void do_byte(byte *v, ls_flag_t flag) } } +static void do_char(char *c, ls_flag_t flag) +{ + do_byte((byte *) c, flag); +} + static void do_bool(bool_ *f, ls_flag_t flag) { byte b = *f; @@ -116,6 +143,24 @@ static void do_bool(bool_ *f, ls_flag_t flag) } } +static void do_std_bool(bool *x, ls_flag_t flag) +{ + switch (flag) + { + case ls_flag_t::LOAD: + { + *x = (sf_get() != 0); + return; + } + case ls_flag_t::SAVE: + { + byte val = (*x) ? 1 : 0; + sf_put(val); + return; + } + } +} + static void do_u16b(u16b *v, ls_flag_t flag) { switch (flag) @@ -171,95 +216,145 @@ static void do_s32b(s32b *ip, ls_flag_t flag) do_u32b((u32b *)ip, flag); } -/* - * Do object memory and similar stuff - */ -static void do_xtra(int k_idx, ls_flag_t flag) +static void save_std_string(std::string const *s) { - byte tmp8u = 0; - object_kind *k_ptr = &k_info[k_idx]; - - switch(flag) + // Length prefix. + u32b saved_size = s->size(); + do_u32b(&saved_size, ls_flag_t::SAVE); + // Save each character + for (auto c: *s) { - case ls_flag_t::SAVE: - { - if (k_ptr->aware) tmp8u |= 0x01; - if (k_ptr->tried) tmp8u |= 0x02; - if (k_ptr->artifact) tmp8u |= 0x80; - - do_byte(&tmp8u, flag); - return; + sf_put(c); } - case ls_flag_t::LOAD: +} + +static std::string load_std_string() +{ + // Length prefix. + u32b saved_size; + do_u32b(&saved_size, ls_flag_t::LOAD); + // Convert to size_t + std::size_t n = saved_size; + // Make sure we reserve space rather than resizing as we go. + std::string s; + s.reserve(n); + // Read each character + for (std::size_t i = 0; i < n; i++) + { + s += sf_get(); + } + // Done + return s; +} + + +static void do_std_string(std::string &s, ls_flag_t flag) +{ + switch (flag) { - do_byte(&tmp8u, flag); - k_ptr->aware = ((tmp8u & 0x01) ? TRUE : FALSE); - k_ptr->tried = ((tmp8u & 0x02) ? TRUE : FALSE); - k_ptr->artifact = ((tmp8u & 0x80) ? TRUE : FALSE); - return; - } + case ls_flag_t::LOAD: + s = load_std_string(); + break; + case ls_flag_t::SAVE: + save_std_string(&s); + break; } } -static void save_string(const char *str) +static void do_option_value(option_value *option_value, ls_flag_t flag) { - while (*str) + do_std_string(option_value->name, flag); + do_bool(&option_value->value, flag); +} + + +namespace { + +/** + * Load/save flag set + */ +template<std::size_t Tiers> void do_flag_set(flag_set<Tiers> *flags, ls_flag_t flag) +{ + for (std::size_t i = 0; i < flags->size(); i++) { - do_byte((byte*)str, ls_flag_t::SAVE); - str++; + do_u32b(&(*flags)[i], flag); } - do_byte((byte*)str, ls_flag_t::SAVE); } -static void load_string(char *str, int max) +template<typename T, typename F> void do_vector(ls_flag_t flag, std::vector<T> &v, F f) { - int i; + u32b n = v.size(); - /* Read the string */ - for (i = 0; TRUE; i++) + do_u32b(&n, flag); + + if (flag == ls_flag_t::LOAD) { - byte tmp8u; + v.clear(); // Make sure it's empty + v.reserve(n); + std::fill_n(std::back_inserter(v), n, T()); + } - /* Read a byte */ - do_byte(&tmp8u, ls_flag_t::LOAD); + for (std::size_t i = 0; i < n; i++) + { + f(&v[i], flag); + } +} - /* Collect string while legal */ - if (i < max) str[i] = tmp8u; +template<typename A, typename F> void do_array(std::string const &what, ls_flag_t flag, A &array, std::size_t size, F f) +{ + // Save/load size. + u32b n = size; + do_u32b(&n, flag); - /* End of string */ - if (!tmp8u) break; + // Check that we don't overflow the array. + if (flag == ls_flag_t::LOAD) + { + if (n > size) + { + note(fmt::format("Too many {:s}: {:d} > {:d}! Game may act strangely or crash.", what, n, size).c_str()); + } + } + + // Load/save the contents of the array. + for (std::size_t i = 0; i < n; i++) + { + f(&array[i], flag); } - /* Terminate */ - str[max - 1] = '\0'; } -static void do_string(char *str, int max, ls_flag_t flag) -/* Max is ignored for writing */ +static void do_bytes(ls_flag_t flag, std::uint8_t *buf, std::size_t n) { - switch(flag) { - case ls_flag_t::LOAD: + for (std::size_t i = 0; i < n; i++) { - load_string(str, max); - return; + do_byte(&buf[i], flag); } - case ls_flag_t::SAVE: +}; + +static void do_seed(seed_t *seed, ls_flag_t flag) +{ + uint8_t buf[seed_t::n_bytes]; + + if (flag == ls_flag_t::SAVE) { - save_string(str); - return; + seed->to_bytes(buf); } + + do_bytes(flag, buf, sizeof(buf)); + + if (flag == ls_flag_t::LOAD) + { + *seed = seed_t::from_bytes(buf); } } +} // namespace (anonymous) + + /* * Load/Save quick start data */ -static void do_quick_start(ls_flag_t flag) +static void do_quick_start(ls_flag_t flag, birther &previous_char) { - s16b tmp16s; - u32b tmp32u; - int i; - - do_s16b(&previous_char.sex, flag); do_s16b(&previous_char.race, flag); do_s16b(&previous_char.rmod, flag); do_s16b(&previous_char.pclass, flag); @@ -267,20 +362,34 @@ static void do_quick_start(ls_flag_t flag) do_byte(&previous_char.quests, flag); do_byte(&previous_char.god, flag); do_s32b(&previous_char.grace, flag); - do_s16b(&previous_char.age, flag); - do_s16b(&previous_char.wt, flag); - do_s16b(&previous_char.ht, flag); - do_s16b(&previous_char.sc, flag); do_s32b(&previous_char.au, flag); - for (i = 0; i < 6; i++) do_s16b(&(previous_char.stat[i]), flag); + for (std::size_t i = 0; i < 6; i++) + { + do_s16b(&(previous_char.stat[i]), flag); + } do_s16b(&previous_char.luck, flag); - do_s16b(&tmp16s, flag); - do_u32b(&tmp32u, flag); - do_byte((byte*)&previous_char.quick_ok, flag); + do_bool(&previous_char.quick_ok, flag); +} + +static void do_skill_modifier(skill_modifier *s, ls_flag_t flag) +{ + do_char(&s->basem, flag); + do_u32b(&s->base, flag); + do_char(&s->modm, flag); + do_s16b(&s->mod, flag); +} + +static void do_skill_modifiers(skill_modifiers *skill_modifiers, ls_flag_t flag) +{ + do_vector(flag, skill_modifiers->modifiers, do_skill_modifier); +} - for (i = 0; i < 4; i++) do_string(previous_char.history[i], 60, flag); +static void do_player_level_flag(player_level_flag *lflag, ls_flag_t flag) +{ + do_flag_set(&lflag->oflags, flag); + do_s16b(&lflag->pval, flag); } /* @@ -288,106 +397,52 @@ static void do_quick_start(ls_flag_t flag) */ static void do_subrace(ls_flag_t flag) { + auto &race_mod_info = game->edit_data.race_mod_info; + player_race_mod *sr_ptr = &race_mod_info[SUBRACE_SAVE]; int i; - char buf[81]; - buf[80] = '\0'; // Make sure string is always NUL terminated + do_std_string(sr_ptr->title, flag); + do_std_string(sr_ptr->description, flag); - if (flag == ls_flag_t::SAVE) - { - strncpy(buf, sr_ptr->title, 80); - } - do_string(buf, 80, flag); - if (flag == ls_flag_t::LOAD) - { - set_subrace_title(sr_ptr, buf); - } + do_bool(&sr_ptr->place, flag); - if (flag == ls_flag_t::SAVE) - { - strncpy(buf, sr_ptr->desc, 80); - } - do_string(buf, 80, flag); - if (flag == ls_flag_t::LOAD) + for (i = 0; i < 6; i++) { - set_subrace_description(sr_ptr, buf); + do_s16b(&sr_ptr->ps.adj[i], flag); } - do_byte((byte*)&sr_ptr->place, flag); - - for (i = 0; i < 6; i++) - do_s16b(&sr_ptr->r_adj[i], flag); - - do_byte((byte*)&sr_ptr->luck, flag); + do_char(&sr_ptr->luck, flag); do_s16b(&sr_ptr->mana, flag); - do_s16b(&sr_ptr->r_dis, flag); - do_s16b(&sr_ptr->r_dev, flag); - do_s16b(&sr_ptr->r_sav, flag); - do_s16b(&sr_ptr->r_stl, flag); - do_s16b(&sr_ptr->r_srh, flag); - do_s16b(&sr_ptr->r_fos, flag); - do_s16b(&sr_ptr->r_thn, flag); - do_s16b(&sr_ptr->r_thb, flag); + do_s16b(&sr_ptr->ps.mhp, flag); + do_s16b(&sr_ptr->ps.exp, flag); - do_byte((byte*)&sr_ptr->r_mhp, flag); - do_s16b(&sr_ptr->r_exp, flag); + do_char(&sr_ptr->infra, flag); - do_byte((byte*)&sr_ptr->b_age, flag); - do_byte((byte*)&sr_ptr->m_age, flag); - - do_byte((byte*)&sr_ptr->m_b_ht, flag); - do_byte((byte*)&sr_ptr->m_m_ht, flag); - do_byte((byte*)&sr_ptr->f_b_ht, flag); - do_byte((byte*)&sr_ptr->f_m_ht, flag); - - do_byte((byte*)&sr_ptr->m_b_wt, flag); - do_byte((byte*)&sr_ptr->m_m_wt, flag); - do_byte((byte*)&sr_ptr->f_b_wt, flag); - do_byte((byte*)&sr_ptr->f_m_wt, flag); - - do_byte((byte*)&sr_ptr->infra, flag); - - for (i = 0; i < 4; i++) - do_s16b(&sr_ptr->powers[i], flag); + do_vector(flag, sr_ptr->ps.powers, do_s16b); for (i = 0; i < BODY_MAX; i++) - do_byte((byte*)&sr_ptr->body_parts[i], flag); + { + do_char(&sr_ptr->body_parts[i], flag); + } - do_u32b(&sr_ptr->flags1, flag); - do_u32b(&sr_ptr->flags2, flag); + do_flag_set(&sr_ptr->flags, flag); for (i = 0; i < PY_MAX_LEVEL + 1; i++) { - do_u32b(&sr_ptr->oflags1[i], flag); - do_u32b(&sr_ptr->oflags2[i], flag); - do_u32b(&sr_ptr->oflags3[i], flag); - do_u32b(&sr_ptr->oflags4[i], flag); - do_u32b(&sr_ptr->oflags5[i], flag); - do_u32b(&sr_ptr->oesp[i], flag); - do_s16b(&sr_ptr->opval[i], flag); + do_player_level_flag(&sr_ptr->lflags[i], flag); } do_byte(&sr_ptr->g_attr, flag); - do_byte((byte*)&sr_ptr->g_char, flag); + do_char(&sr_ptr->g_char, flag); - for (i = 0; i < MAX_SKILLS; i++) - { - do_byte((byte*)&sr_ptr->skill_basem[i], flag); - do_u32b(&sr_ptr->skill_base[i], flag); - do_byte((byte*)&sr_ptr->skill_modm[i], flag); - do_s16b(&sr_ptr->skill_mod[i], flag); - } + do_skill_modifiers(&sr_ptr->skill_modifiers, flag); } -/* Load/Save the random spells info */ -static void do_spells(int i, ls_flag_t flag) +static void do_random_spell(random_spell *s_ptr, ls_flag_t flag) { - random_spell *s_ptr = &random_spells[i]; - do_string(s_ptr->name, 30, flag); - do_string(s_ptr->desc, 30, flag); do_s16b(&s_ptr->mana, flag); do_s16b(&s_ptr->fail, flag); do_u32b(&s_ptr->proj_flags, flag); @@ -396,113 +451,82 @@ static void do_spells(int i, ls_flag_t flag) do_byte(&s_ptr->dam_sides, flag); do_byte(&s_ptr->dam_dice, flag); do_byte(&s_ptr->level, flag); - do_byte((byte*)&s_ptr->untried, flag); + do_std_bool(&s_ptr->untried, flag); } - -/* - * Show information on the screen, one line at a time. - * - * Avoid the top two lines, to avoid interference with "msg_print()". - */ -static void note(cptr msg) +static void do_level_marker(level_marker *marker, ls_flag_t flag) { - static int y = 2; - - /* Draw the message */ - prt(msg, y, 0); - - /* Advance one line (wrap if needed) */ - if (++y >= 24) y = 2; - - /* Flush it */ - Term_fresh(); -} + std::string v; - -static void skip_ver_byte(u32b version, ls_flag_t flag) -/* Reads and discards a byte if the savefile is as old as/older than version */ -{ - if ((flag == ls_flag_t::LOAD) && (vernum <= version)) + if (flag == ls_flag_t::SAVE) { - byte forget; - do_byte(&forget, flag); + v = level_marker_values().stringify(*marker); } - return; -} -static void do_ver_s16b(s16b *v, u32b version, s16b defval, ls_flag_t flag) -{ - if ((flag == ls_flag_t::LOAD) && (vernum < version)) + do_std_string(v, flag); + + if (flag == ls_flag_t::LOAD) { - *v = defval; - return; + bool valid = level_marker_values().parse(v.c_str(), marker); + if (!valid) + { + note(fmt::format("Bad level marker: {}!", v).c_str()); + abort(); + } } - do_s16b(v, flag); } /* * Misc. other data */ -static char loaded_game_module[80]; static bool_ do_extra(ls_flag_t flag) { - int i, j; - byte tmp8u = 0; - s16b tmp16s = 0; - u32b tmp32u = 0; - s32b tmp32s = 0; - u16b tmp16b = 0; - u32b dummy32u = 0; + auto const &d_info = game->edit_data.d_info; + auto &s_info = game->s_info; - do_string(player_name, 32, flag); + do_std_string(game->player_name, flag); - do_string(died_from, 80, flag); - - for (i = 0; i < 4; i++) - { - do_string(history[i], 60, flag); - } + do_std_string(game->died_from, flag); /* Handle the special levels info */ - if (flag == ls_flag_t::SAVE) { - tmp8u = max_d_idx; - tmp16s = MAX_DUNGEON_DEPTH; - } - do_byte(&tmp8u, flag); + byte tmp8u = d_info.size(); + u16b tmp16u = MAX_DUNGEON_DEPTH; - if (flag == ls_flag_t::LOAD) - { - if (tmp8u > max_d_idx) + do_byte(&tmp8u, flag); + + if (flag == ls_flag_t::LOAD) { - note(format("Too many (%d) dungeon types!", tmp8u)); + if (tmp8u > d_info.size()) + { + note(format("Too many dungeon types!", static_cast<int>(tmp8u))); + } } - } - do_s16b(&tmp16s, flag); + do_u16b(&tmp16u, flag); - if (flag == ls_flag_t::LOAD) - { - if (tmp16s > MAX_DUNGEON_DEPTH) + if (flag == ls_flag_t::LOAD) { - note(format("Too many (%d) max level by dungeon type!", tmp16s)); + if (tmp16u > MAX_DUNGEON_DEPTH) + { + note(format("Too many (%d) max level by dungeon type!", static_cast<int>(tmp16u))); + } } - } - /* Load the special levels history */ - for (i = 0; i < tmp8u; i++) - { - for (j = 0; j < tmp16s; j++) + /* Load the special levels history */ + for (std::size_t i = 0; i < tmp8u; i++) { - do_byte((byte*)&special_lvl[j][i], flag); + for (std::size_t j = 0; j < tmp16u; j++) + { + do_level_marker(&game->level_markers[j][i], flag); + } } } - do_byte((byte*)&generate_special_feeling, flag); + do_std_bool(&game->generate_special_feeling, flag); /* Load the quick start data */ - do_quick_start(flag); + do_quick_start(flag, game->previous_char); /* Load/save the special subrace */ do_subrace(flag); @@ -513,75 +537,39 @@ static bool_ do_extra(ls_flag_t flag) do_byte(&p_ptr->pracem, flag); do_byte(&p_ptr->pclass, flag); do_byte(&p_ptr->pspec, flag); - do_byte(&p_ptr->psex, flag); - do_u16b(&tmp16b, flag); - do_u16b(&tmp16b, flag); do_byte(&p_ptr->mimic_form, flag); do_s16b(&p_ptr->mimic_level, flag); - if (flag == ls_flag_t::SAVE) tmp8u = 0; do_byte(&p_ptr->hitdie, flag); do_u16b(&p_ptr->expfact, flag); - do_s16b(&p_ptr->age, flag); - do_s16b(&p_ptr->ht, flag); - do_s16b(&p_ptr->wt, flag); - /* Dump the stats (maximum and current) */ - for (i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_max[i], flag); - for (i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_cur[i], flag); - for (i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_cnt[i], flag); - for (i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_los[i], flag); - - /* Dump the skills */ - do_s16b(&p_ptr->skill_points, flag); - do_s16b(&p_ptr->skill_last_level, flag); - do_s16b(&p_ptr->melee_style, flag); - do_s16b(&p_ptr->use_piercing_shots, flag); - - tmp16s = MAX_SKILLS; - do_s16b(&tmp16s, flag); - - if ((flag == ls_flag_t::LOAD) && (tmp16s > MAX_SKILLS)) - { - quit("Too many skills"); - } - - if (flag == ls_flag_t::SAVE) old_max_s_idx = max_s_idx; - do_u16b(&old_max_s_idx, flag); - for (i = 0; i < tmp16s; ++i) - { - if (i < old_max_s_idx) - { - do_s32b(&s_info[i].value, flag); - do_s32b(&s_info[i].mod, flag); - do_byte((byte*)&s_info[i].dev, flag); - do_byte((byte*)&s_info[i].hidden, flag); - do_u32b(&s_info[i].uses, flag); - } - else - { - do_u32b(&tmp32u, flag); - do_s16b(&tmp16s, flag); - do_byte(&tmp8u, flag); - do_byte(&tmp8u, flag); - do_u32b(&tmp32u, flag); - } - } - - tmp16s = max_ab_idx; - do_s16b(&tmp16s, flag); - - if ((flag == ls_flag_t::LOAD) && (tmp16s > max_ab_idx)) - { - quit("Too many abilities"); + for (std::size_t i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_max[i], flag); + for (std::size_t i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_cur[i], flag); + for (std::size_t i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_cnt[i], flag); + for (std::size_t i = 0; i < 6; ++i) do_s16b(&p_ptr->stat_los[i], flag); + + // Skills + { + do_s16b(&p_ptr->skill_points, flag); + do_s16b(&p_ptr->skill_last_level, flag); + do_s16b(&p_ptr->melee_style, flag); + do_s16b(&p_ptr->use_piercing_shots, flag); + + do_array("skills", flag, s_info, s_info.size(), + [](auto skill, auto flag) -> void { + do_s32b(&skill->value, flag); + do_s32b(&skill->mod, flag); + do_std_bool(&skill->dev, flag); + do_std_bool(&skill->hidden, flag); + } + ); } - for (i = 0; i < tmp16s; ++i) - { - do_byte((byte*)&ab_info[i].acquired, flag); - } + // Abilities + do_vector(flag, p_ptr->abilities, do_u16b); + // Miscellaneous do_s16b(&p_ptr->luck_base, flag); do_s16b(&p_ptr->luck_max, flag); @@ -595,48 +583,28 @@ static bool_ do_extra(ls_flag_t flag) do_s16b(&p_ptr->town_num, flag); /* -KMW- */ /* Write arena and rewards information -KMW- */ - do_s16b(&tmp16s, flag); - do_s16b(&tmp16s, flag); do_s16b(&p_ptr->inside_quest, flag); - do_byte(&tmp8u, flag); /* Save/load spellbinder */ - do_byte(&p_ptr->spellbinder_num, flag); - do_byte(&p_ptr->spellbinder_trigger, flag); - for (i = 0; i < 4; i++) - do_u32b(&p_ptr->spellbinder[i], flag); + do_byte(&p_ptr->spellbinder.trigger, flag); + do_vector(flag, p_ptr->spellbinder.spell_idxs, do_u32b); - - do_byte(&tmp8u, flag); /* tmp8u should be 0 at this point */ - - if (flag == ls_flag_t::SAVE) tmp8u = MAX_PLOTS; - do_byte(&tmp8u, flag); - - if ((flag == ls_flag_t::LOAD) && (tmp8u > MAX_PLOTS)) - { - quit(format("Too many plots, %d %d", tmp8u, MAX_PLOTS)); - } - - for (i = 0; i < tmp8u; i++) - { - do_s16b(&plots[i], flag); - } - - if (flag == ls_flag_t::SAVE) - { - tmp8u = MAX_RANDOM_QUEST; - } - do_byte(&tmp8u, flag); - - if ((flag == ls_flag_t::LOAD) && - (tmp8u > MAX_RANDOM_QUEST)) quit("Too many random quests"); - for (i = 0; i < tmp8u; i++) - { - do_byte(&random_quests[i].type, flag); - do_s16b(&random_quests[i].r_idx, flag); - do_byte((byte*)&random_quests[i].done, flag); - } + // Quest status + do_array("plot quests", flag, plots, MAX_PLOTS, + [](auto plot, auto flag) -> void { + do_s16b(plot, flag); + } + ); + + // Random quests + do_array("random quests", flag, random_quests, MAX_RANDOM_QUEST, + [](auto q, auto flag) -> void { + do_byte(&q->type, flag); + do_s16b(&q->r_idx, flag); + do_std_bool(&q->done, flag); + } + ); do_s16b(&p_ptr->oldpx, flag); do_s16b(&p_ptr->oldpy, flag); @@ -654,49 +622,48 @@ static bool_ do_extra(ls_flag_t flag) do_s16b(&p_ptr->csp, flag); do_u16b(&p_ptr->csp_frac, flag); - /* XXX - Here's where tank points were. - Those who run the estate of you-know-who is really stupid. - I'll never even consider reading her books now. -- neil */ - do_s16b(&tmp16s, flag); - do_s16b(&tmp16s, flag); - do_s16b(&tmp16s, flag); - do_s16b(&tmp16s, flag); - /* Gods */ do_s32b(&p_ptr->grace, flag); do_s32b(&p_ptr->grace_delay, flag); - do_byte((byte*)&p_ptr->praying, flag); + do_bool(&p_ptr->praying, flag); do_s16b(&p_ptr->melkor_sacrifice, flag); do_byte(&p_ptr->pgod, flag); - /* Max Player and Dungeon Levels */ do_s16b(&p_ptr->max_plv, flag); - if (flag == ls_flag_t::SAVE) - tmp8u = max_d_idx; - do_byte(&tmp8u, flag); - for (i = 0; i < tmp8u; i++) + // Max dungeon levels { - if (flag == ls_flag_t::SAVE) - tmp16s = max_dlv[i]; - do_s16b(&tmp16s, flag); - if ((flag == ls_flag_t::LOAD) && (i <= max_d_idx)) - max_dlv[i] = tmp16s; + byte tmp8u = d_info.size(); + + do_byte(&tmp8u, flag); + + for (std::size_t i = 0; i < tmp8u; i++) + { + s16b tmp16s = max_dlv[i]; + + do_s16b(&tmp16s, flag); + + if ((flag == ls_flag_t::LOAD) && (i <= d_info.size())) + { + max_dlv[i] = tmp16s; + } + } } + /* Repair max player level??? */ if ((flag == ls_flag_t::LOAD) && (p_ptr->max_plv < p_ptr->lev)) + { p_ptr->max_plv = p_ptr->lev; + } - do_byte((byte*)&(p_ptr->help.enabled), flag); - for (i = 0; i < HELP_MAX; i++) + /* Help */ + do_std_bool(&p_ptr->help.enabled, flag); + for (std::size_t i = 0; i < HELP_MAX; i++) { - do_bool(&(p_ptr->help.activated[i]), flag); + do_std_bool(&p_ptr->help.activated[i], flag); } /* More info */ - tmp16s = 0; - do_s16b(&p_ptr->sc, flag); do_s16b(&p_ptr->blind, flag); do_s16b(&p_ptr->paralyzed, flag); do_s16b(&p_ptr->confused, flag); @@ -711,7 +678,6 @@ static bool_ do_extra(ls_flag_t flag) do_s16b(&p_ptr->poisoned, flag); do_s16b(&p_ptr->image, flag); do_s16b(&p_ptr->protevil, flag); - do_s16b(&p_ptr->protundead, flag); do_s16b(&p_ptr->invuln, flag); do_s16b(&p_ptr->hero, flag); do_s16b(&p_ptr->shero, flag); @@ -742,7 +708,7 @@ static bool_ do_extra(ls_flag_t flag) do_s16b(&p_ptr->tim_invis, flag); do_s16b(&p_ptr->word_recall, flag); - do_s16b(&p_ptr->recall_dungeon, flag); + do_byte(&p_ptr->recall_dungeon, flag); do_s16b(&p_ptr->see_infra, flag); do_s16b(&p_ptr->tim_infra, flag); do_s16b(&p_ptr->oppose_fire, flag); @@ -750,182 +716,97 @@ static bool_ do_extra(ls_flag_t flag) do_s16b(&p_ptr->oppose_acid, flag); do_s16b(&p_ptr->oppose_elec, flag); do_s16b(&p_ptr->oppose_pois, flag); - do_s16b(&p_ptr->oppose_ld, flag); do_s16b(&p_ptr->oppose_cc, flag); - do_s16b(&p_ptr->oppose_ss, flag); - do_s16b(&p_ptr->oppose_nex, flag); do_s16b(&p_ptr->tim_esp, flag); do_s16b(&p_ptr->tim_wraith, flag); do_s16b(&p_ptr->tim_ffall, flag); - do_ver_s16b(&p_ptr->tim_fly, SAVEFILE_VERSION, 0, flag); - do_s16b(&tmp16s, flag); - do_ver_s16b(&p_ptr->tim_poison, SAVEFILE_VERSION, 0, flag); - do_s16b(&tmp16s, flag); + do_s16b(&p_ptr->tim_fly, flag); + do_s16b(&p_ptr->tim_poison, flag); do_s16b(&p_ptr->tim_invisible, flag); do_s16b(&p_ptr->tim_inv_pow, flag); do_s16b(&p_ptr->tim_mimic, flag); do_s16b(&p_ptr->lightspeed, flag); do_s16b(&p_ptr->tim_lite, flag); - do_ver_s16b(&p_ptr->tim_regen, SAVEFILE_VERSION, 0, flag); - do_ver_s16b(&p_ptr->tim_regen_pow, SAVEFILE_VERSION, 0, flag); + do_s16b(&p_ptr->tim_regen, flag); + do_s16b(&p_ptr->tim_regen_pow, flag); do_s16b(&p_ptr->holy, flag); - do_s16b(&tmp16s, flag); - do_s16b(&tmp16s, flag); do_s16b(&p_ptr->immov_cntr, flag); do_s16b(&p_ptr->strike, flag); - do_s16b(&tmp16s, flag); do_s16b(&p_ptr->tim_reflect, flag); - do_s16b(&tmp16s, flag); do_s16b(&p_ptr->tim_deadly, flag); do_s16b(&p_ptr->prob_travel, flag); do_s16b(&p_ptr->disrupt_shield, flag); do_s16b(&p_ptr->parasite, flag); do_s16b(&p_ptr->parasite_r_idx, flag); - do_s32b(&tmp32s, flag); - do_s32b(&tmp32s, flag); do_s16b(&p_ptr->absorb_soul, flag); do_s32b(&p_ptr->inertia_controlled_spell, flag); do_s16b(&p_ptr->last_rewarded_level, flag); - do_s16b(&tmp16s, flag); /* compat */ - - if (flag == ls_flag_t::SAVE) { tmp16s = CORRUPTIONS_MAX; } - do_s16b(&tmp16s, flag); - if (tmp16s > CORRUPTIONS_MAX) { - quit("Too many corruptions"); - } - - for (i = 0; i < tmp16s; i++) - { - if (flag == ls_flag_t::SAVE) - tmp8u = p_ptr->corruptions[i]; - - do_byte(&tmp8u, flag); - - if (flag == ls_flag_t::LOAD) - p_ptr->corruptions[i] = tmp8u; - } + do_array("corruptions", flag, p_ptr->corruptions, CORRUPTIONS_MAX, + [](auto corruption, auto flag) -> void { + do_bool(corruption, flag); + } + ); - do_byte((byte*)&p_ptr->corrupt_anti_teleport_stopped, flag); + do_bool(&p_ptr->corrupt_anti_teleport_stopped, flag); do_byte(&p_ptr->confusing, flag); - do_byte((byte*)&p_ptr->black_breath, flag); - do_byte((byte*)&fate_flag, flag); - do_byte(&p_ptr->searching, flag); - do_byte(&tmp8u, flag); - do_byte(&p_ptr->preserve, flag); - do_byte(&p_ptr->special, flag); - do_byte((byte*)&ambush_flag, flag); + do_bool(&p_ptr->black_breath, flag); + do_bool(&fate_flag, flag); + do_bool(&ambush_flag, flag); do_byte(&p_ptr->allow_one_death, flag); - do_s16b(&tmp16s, flag); - - do_byte(&tmp8u, flag); do_s16b(&no_breeds, flag); - do_s16b(&p_ptr->protgood, flag); /* Auxilliary variables */ do_u32b(&p_ptr->mimic_extra, flag); do_u32b(&p_ptr->antimagic_extra, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); do_u32b(&p_ptr->music_extra, flag); - do_u32b(&tmp32u, flag); do_u32b(&p_ptr->necro_extra, flag); do_u32b(&p_ptr->necro_extra2, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u32b(&tmp32u, flag); - do_u16b(&p_ptr->body_monster, flag); - do_byte((byte*)&p_ptr->disembodied, flag); + do_bool(&p_ptr->disembodied, flag); /* Are we in astral mode? */ - do_byte((byte*)&p_ptr->astral, flag); - - if (flag == ls_flag_t::SAVE) tmp16s = POWER_MAX; - do_s16b(&tmp16s, flag); - if ((flag == ls_flag_t::LOAD) && (tmp16s > POWER_MAX)) - note(format("Too many (%u) powers!", tmp16s)); - for (i = 0; i < POWER_MAX; i++) - do_byte((byte*)&p_ptr->powers_mod[i], flag); + do_bool(&p_ptr->astral, flag); - skip_ver_byte(100, flag); + // Powers + do_array("powers", flag, p_ptr->powers_mod, POWER_MAX, + [](auto pwr, auto flag) -> void { + do_bool(pwr, flag); + } + ); /* The tactic */ - do_byte((byte*)&p_ptr->tactic, flag); + do_char(&p_ptr->tactic, flag); /* The movement */ - do_byte((byte*)&p_ptr->movement, flag); + do_char(&p_ptr->movement, flag); /* The comapnions killed */ do_s16b(&p_ptr->companion_killed, flag); /* The fate */ - do_byte((byte*)&p_ptr->no_mortal, flag); - - /* The bounties -- kept only for load-compatibility with old savefiles. */ - for (i = 0; i < 24; i++) { - tmp16s = 0; do_s16b(&tmp16s, flag); - tmp16s = 0; do_s16b(&tmp16s, flag); - } - tmp32u = 0; do_u32b(&tmp32u, flag); + do_bool(&p_ptr->no_mortal, flag); - /* Spells */ - do_s16b(&spell_num, flag); - for (i = 0; i < MAX_SPELLS; i++) - do_spells(i, flag); - do_s16b(&rune_num, flag); - for (i = 0; i < MAX_RUNES; i++) - { - do_string(rune_spells[i].name, 30, flag); - do_s16b(&rune_spells[i].type, flag); - do_s16b(&rune_spells[i].rune2, flag); - do_s16b(&rune_spells[i].mana, flag); - } + /* Random spells */ + do_vector(flag, p_ptr->random_spells, do_random_spell); - /* Load random seeds */ - do_u32b(&dummy32u, flag); /* Load-compatibility with old savefiles. */ - do_u32b(&seed_flavor, flag); /* For consistent object flavors. */ - do_u32b(&dummy32u, flag); /* Load-compatibility with old savefiles. */ + /* Random seed for object flavors. */ + do_seed(&seed_flavor(), flag); /* Special stuff */ - do_u16b(&tmp16b, flag); /* Dummy */ do_u16b(&total_winner, flag); do_u16b(&has_won, flag); do_u16b(&noscore, flag); /* Write death */ - if (flag == ls_flag_t::SAVE) tmp8u = death; - do_byte(&tmp8u, flag); - if (flag == ls_flag_t::LOAD) death = tmp8u; - - /* Incompatible module? */ - if (flag == ls_flag_t::LOAD) - { - s32b ok; - - ok = module_savefile_loadable(loaded_game_module); - - /* Argh bad game module! */ - if (!ok) - { - note(format("Bad game module. Savefile was saved with module '%s' but game is '%s'.", loaded_game_module, game_module)); - return (FALSE); - } - } + do_bool(&death, flag); - /* Write feeling */ - if (flag == ls_flag_t::SAVE) tmp8u = feeling; - do_byte(&tmp8u, flag); - if (flag == ls_flag_t::LOAD) feeling = tmp8u; + /* Level feeling */ + do_s16b(&feeling, flag); /* Turn of last "feeling" */ do_s32b(&old_turn, flag); @@ -942,8 +823,6 @@ static bool_ do_extra(ls_flag_t flag) */ static void do_monster(monster_type *m_ptr, ls_flag_t flag) { - int i; - /* Read the monster race */ do_s16b(&m_ptr->r_idx, flag); @@ -976,16 +855,20 @@ static void do_monster(monster_type *m_ptr, ls_flag_t flag) do_s32b(&m_ptr->mflag, flag); - if (flag == ls_flag_t::LOAD) m_ptr->mflag &= PERM_MFLAG_MASK; - - /* Attacks */ - for (i = 0; i < 4; i++) + if (flag == ls_flag_t::LOAD) { - do_byte(&m_ptr->blow[i].method, flag); - do_byte(&m_ptr->blow[i].effect, flag); - do_byte(&m_ptr->blow[i].d_dice, flag); - do_byte(&m_ptr->blow[i].d_side, flag); + m_ptr->mflag &= PERM_MFLAG_MASK; } + + /* Attacks */ + do_array("attacks", flag, m_ptr->blow, 4, + [](auto blow, auto flag) { + do_byte(&blow->method, flag); + do_byte(&blow->effect, flag); + do_byte(&blow->d_dice, flag); + do_byte(&blow->d_side, flag); + } + ); } @@ -1031,7 +914,6 @@ static bool_ wearable_p(object_type *o_ptr) case TV_HYPNOS: case TV_INSTRUMENT: case TV_DAEMON_BOOK: - case TV_TRAPKIT: case TV_TOOL: { return (TRUE); @@ -1045,19 +927,16 @@ static bool_ wearable_p(object_type *o_ptr) /* * rd/wr an object - * - * FIXME! This code probably has a lot of cruft from the old Z/V codebase. - * */ static void do_item(object_type *o_ptr, ls_flag_t flag) { + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &e_info = game->edit_data.e_info; + byte old_dd; byte old_ds; - u32b f1, f2, f3, f4, f5, esp; - - object_kind *k_ptr; - /* Kind */ do_s16b(&o_ptr->k_idx, flag); @@ -1110,20 +989,10 @@ static void do_item(object_type *o_ptr, ls_flag_t flag) do_byte(&o_ptr->marked, flag); /* flags */ - do_u32b(&o_ptr->art_flags1, flag); - do_u32b(&o_ptr->art_flags2, flag); - do_u32b(&o_ptr->art_flags3, flag); - do_u32b(&o_ptr->art_flags4, flag); - do_u32b(&o_ptr->art_flags5, flag); - do_u32b(&o_ptr->art_esp, flag); + do_flag_set(&o_ptr->art_flags, flag); /* obvious flags */ - do_u32b(&o_ptr->art_oflags1, flag); - do_u32b(&o_ptr->art_oflags2, flag); - do_u32b(&o_ptr->art_oflags3, flag); - do_u32b(&o_ptr->art_oflags4, flag); - do_u32b(&o_ptr->art_oflags5, flag); - do_u32b(&o_ptr->art_oesp, flag); + do_flag_set(&o_ptr->art_oflags, flag); /* Monster holding object */ do_s16b(&o_ptr->held_m_idx, flag); @@ -1145,50 +1014,22 @@ static void do_item(object_type *o_ptr, ls_flag_t flag) do_s16b(&o_ptr->found_aux3, flag); do_s16b(&o_ptr->found_aux4, flag); - if (flag == ls_flag_t::LOAD) - { - char buf[128]; - /* Inscription */ - load_string(buf, 128); - if (buf[0]) - { - o_ptr->note = quark_add(buf); - } - /* Artifact name */ - load_string(buf, 128); - if (buf[0]) - { - o_ptr->art_name = quark_add(buf); - } - } - if (flag == ls_flag_t::SAVE) - { - /* Save the inscription (if any) */ - if (o_ptr->note) - { - save_string(quark_str(o_ptr->note)); - } - else - { - save_string(""); - } - if (o_ptr->art_name) - { - save_string(quark_str(o_ptr->art_name)); - } - else - { - save_string(""); - } - } + // Inscription + do_std_string(o_ptr->inscription, flag); + + // Artifact name + do_std_string(o_ptr->artifact_name, flag); + + /* Stick any more shared code before this. The rest + of this function is reserved for ls_flag_t::LOAD's + cleanup functions */ + + if (flag == ls_flag_t::SAVE) return; - if (flag == ls_flag_t::SAVE) return ; /* Stick any more shared code before this. The rest - of this function is reserved for ls_flag_t::LOAD's - cleanup functions */ /*********** END OF ls_flag_t::SAVE ***************/ /* Obtain the "kind" template */ - k_ptr = &k_info[o_ptr->k_idx]; + object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Obtain tval/sval from k_info */ o_ptr->tval = k_ptr->tval; @@ -1213,16 +1054,11 @@ static void do_item(object_type *o_ptr, ls_flag_t flag) } - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - /* Paranoia */ if (o_ptr->name1) { - artifact_type *a_ptr; - /* Obtain the artifact info */ - a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; /* Verify that artifact */ if (!a_ptr->name) o_ptr->name1 = 0; @@ -1270,7 +1106,7 @@ static void do_item(object_type *o_ptr, ls_flag_t flag) o_ptr->ds = old_ds; } - if (o_ptr->art_name) /* A random artifact */ + if (!o_ptr->artifact_name.empty()) /* A random artifact */ { o_ptr->dd = old_dd; o_ptr->ds = old_ds; @@ -1284,7 +1120,6 @@ static void do_cave_type(cave_type *c_ptr, ls_flag_t flag) do_byte(&c_ptr->mimic, flag); do_s16b(&c_ptr->special, flag); do_s16b(&c_ptr->special2, flag); - do_s16b(&c_ptr->t_idx, flag); do_s16b(&c_ptr->inscription, flag); do_byte(&c_ptr->mana, flag); do_s16b(&c_ptr->effect, flag); @@ -1301,307 +1136,287 @@ static void do_grid(ls_flag_t flag) } } -static void my_sentinel(const char *place, u16b value, ls_flag_t flag) -/* This function lets us know exactly where a savefile is - broken by reading/writing conveniently a sentinel at this - spot */ +static bool do_objects(ls_flag_t flag, bool no_companions) { if (flag == ls_flag_t::SAVE) { - do_u16b(&value, flag); - return; + // Compact everything before saving + compact_objects(0); + compact_monsters(0); } - if (flag == ls_flag_t::LOAD) - { - u16b found; - do_u16b(&found, flag); - if (found == value) /* All is good */ - return; - /* All is bad */ - note(format("Savefile broken %s", place)); - return; - } - note(format("Impossible has occurred")); /* Programmer error */ - exit(0); -} - + u16b n_objects = o_max; -/* - * Handle dungeon - * - * The monsters/objects must be loaded in the same order - * that they were stored, since the actual indexes matter. - */ -static bool_ do_dungeon(ls_flag_t flag, bool_ no_companions) -{ - int i; - - cave_type *c_ptr; - - /* Read specific */ - u16b tmp16b = 0; - - my_sentinel("Before do_dungeon", 324, flag); - - /* Header info */ - do_s16b(&dun_level, flag); - do_byte(&dungeon_type, flag); - do_s16b(&num_repro, flag); - do_s16b(&p_ptr->py, flag); - do_s16b(&p_ptr->px, flag); - do_s16b(&cur_hgt, flag); - do_s16b(&cur_wid, flag); - do_s16b(&max_panel_rows, flag); - do_s16b(&max_panel_cols, flag); - - do_u32b(&dungeon_flags1, flag); - do_u32b(&dungeon_flags2, flag); - - /* Last teleportation */ - do_s16b(&last_teleportation_y, flag); - do_s16b(&last_teleportation_y, flag); - - /* Spell effects */ - tmp16b = MAX_EFFECTS; - do_u16b(&tmp16b, flag); - - if ((flag == ls_flag_t::LOAD) && (tmp16b > MAX_EFFECTS)) - { - quit("Too many spell effects"); - } - - for (i = 0; i < tmp16b; ++i) - { - do_s16b(&effects[i].type, flag); - do_s16b(&effects[i].dam, flag); - do_s16b(&effects[i].time, flag); - do_u32b(&effects[i].flags, flag); - do_s16b(&effects[i].cx, flag); - do_s16b(&effects[i].cy, flag); - do_s16b(&effects[i].rad, flag); - } - - /* TO prevent bugs with evolving dungeons */ - for (i = 0; i < 100; i++) - { - do_s16b(&floor_type[i], flag); - do_s16b(&fill_type[i], flag); - } - - if ((flag == ls_flag_t::LOAD) && (!dun_level && !p_ptr->inside_quest)) - { - int xstart = 0; - int ystart = 0; - /* Init the wilderness */ - process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, - TRUE, FALSE); - - /* Init the town */ - xstart = 0; - ystart = 0; - init_flags = 0; - process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid, - TRUE, FALSE); - } - - do_grid(flag); - - /*** Objects ***/ - - if (flag == ls_flag_t::SAVE) compact_objects(0); - if (flag == ls_flag_t::SAVE) compact_monsters(0); if (flag == ls_flag_t::SAVE) { - tmp16b = o_max; + u16b tmp16u = n_objects; if (no_companions) { - for (i = 1; i < o_max; i++) + for (int i = 1; i < o_max; i++) { object_type *o_ptr = &o_list[i]; - if (o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) tmp16b--; + if (o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) + { + tmp16u--; + } } } - /* Item count */ - do_u16b(&tmp16b, flag); - - tmp16b = o_max; + do_u16b(&tmp16u, flag); } else - /* Read item count */ - do_u16b(&tmp16b, flag); + { + do_u16b(&n_objects, flag); + } /* Verify maximum */ - if ((flag == ls_flag_t::LOAD) && (tmp16b > max_o_idx)) + if ((flag == ls_flag_t::LOAD) && (n_objects > max_o_idx)) { - note(format("Too many (%d) object entries!", tmp16b)); - return (FALSE); + note("Too many object entries!"); + return false; } /* Dungeon items */ - for (i = 1; i < tmp16b; i++) + if (flag == ls_flag_t::SAVE) { - int o_idx; - - object_type *o_ptr; - - if (flag == ls_flag_t::SAVE) + for (std::size_t i = 1; i < n_objects; i++) { - o_ptr = &o_list[i]; - /* Don't save objects held by companions when no_companions is set */ - if (no_companions && o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) continue; + auto o_ptr = &o_list[i]; + // Skip objects held by companions when no_companions is set + if (no_companions && o_ptr->held_m_idx && (m_list[o_ptr->held_m_idx].status == MSTATUS_COMPANION)) + { + continue; + } do_item(o_ptr, ls_flag_t::SAVE); - continue; /* Saving is easy */ } - /* Until the end of the loop, this is all ls_flag_t::LOAD */ - - /* Get a new record */ - o_idx = o_pop(); - - /* Oops */ - if (i != o_idx) + } + else if (flag == ls_flag_t::LOAD) + { + for (int i = 1; i < n_objects; i++) { - note(format("Object allocation error (%d <> %d)", i, o_idx)); - return (FALSE); - } + /* Get a new record */ + int o_idx = o_pop(); + /* Oops */ + if (i != o_idx) + { + note(format("Object allocation error (%d <> %d)", i, o_idx)); + return false; + } - /* Acquire place */ - o_ptr = &o_list[o_idx]; + /* Acquire place */ + auto o_ptr = &o_list[o_idx]; - /* Read the item */ - do_item(o_ptr, ls_flag_t::LOAD); + /* Read the item */ + do_item(o_ptr, ls_flag_t::LOAD); - /* Monster */ - if (o_ptr->held_m_idx) - { /* Monster */ - monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; + if (o_ptr->held_m_idx) + { + /* Monster */ + monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; - /* Place the object */ - m_ptr->hold_o_idxs.push_back(o_idx); - } + /* Place the object */ + m_ptr->hold_o_idxs.push_back(o_idx); + } - /* Dungeon */ - else - { - /* Access the item location */ - c_ptr = &cave[o_ptr->iy][o_ptr->ix]; + /* Dungeon */ + else + { + /* Access the item location */ + auto c_ptr = &cave[o_ptr->iy][o_ptr->ix]; - /* Place the object */ - c_ptr->o_idxs.push_back(o_idx); + /* Place the object */ + c_ptr->o_idxs.push_back(o_idx); + } } } - /*** Monsters ***/ + return true; +} + + +static bool do_monsters(ls_flag_t flag, bool no_companions) +{ + auto &r_info = game->edit_data.r_info; + + u16b n_monsters = m_max; if (flag == ls_flag_t::SAVE) { - tmp16b = m_max; + u16b tmp16u = m_max; if (no_companions) { - for (i = 1; i < m_max; i++) + for (int i = 1; i < m_max; i++) { monster_type *m_ptr = &m_list[i]; - if (m_ptr->status == MSTATUS_COMPANION) tmp16b--; + if (m_ptr->status == MSTATUS_COMPANION) + { + tmp16u--; + } } } - /* Write the monster count */ - do_u16b(&tmp16b, flag); - - tmp16b = m_max; + do_u16b(&tmp16u, flag); } else - /* Read the monster count */ - do_u16b(&tmp16b, flag); + { + do_u16b(&n_monsters, flag); + } /* Validate */ - if ((flag == ls_flag_t::LOAD) && (tmp16b > max_m_idx)) + if ((flag == ls_flag_t::LOAD) && (n_monsters > max_m_idx)) { - note(format("Too many (%d) monster entries!", tmp16b)); - return (FALSE); + note("Too many monster entries!"); + return false; } - /* Read the monsters */ - for (i = 1; i < tmp16b; i++) - { - int m_idx; - monster_type *m_ptr; - monster_race *r_ptr; + /* Load/save the monsters */ - if (flag == ls_flag_t::SAVE) + if (flag == ls_flag_t::SAVE) + { + for (std::size_t i = 1; i < n_monsters; i++) { - m_ptr = &m_list[i]; + auto m_ptr = &m_list[i]; - /* Don't save companions when no_companions is set */ - if (no_companions && m_ptr->status == MSTATUS_COMPANION) continue; + // Skip companions when no_companions is set + if (no_companions && m_ptr->status == MSTATUS_COMPANION) + { + continue; + } do_monster(m_ptr, ls_flag_t::SAVE); - continue; /* Easy to save a monster */ } - /* From here on, it's all ls_flag_t::LOAD */ - /* Get a new record */ - m_idx = m_pop(); - - /* Oops */ - if (i != m_idx) + } + else if (flag == ls_flag_t::LOAD) + { + for (int i = 1; i < n_monsters; i++) { - note(format("Monster allocation error (%d <> %d)", i, m_idx)); - return (FALSE); - } + /* Get a new record */ + int m_idx = m_pop(); + + /* Oops */ + if (i != m_idx) + { + note(format("Monster allocation error (%d <> %d)", i, m_idx)); + return false; + } - /* Acquire monster */ - m_ptr = &m_list[m_idx]; + /* Acquire monster */ + auto m_ptr = &m_list[m_idx]; - /* Read the monster */ - do_monster(m_ptr, ls_flag_t::LOAD); + /* Read the monster */ + do_monster(m_ptr, ls_flag_t::LOAD); - /* Access grid */ - c_ptr = &cave[m_ptr->fy][m_ptr->fx]; + /* Place in grid */ + auto c_ptr = &cave[m_ptr->fy][m_ptr->fx]; + c_ptr->m_idx = m_idx; - /* Mark the location */ - c_ptr->m_idx = m_idx; + /* Controlled? */ + if (m_ptr->mflag & MFLAG_CONTROL) + { + p_ptr->control = m_idx; + } - /* Controlled ? */ - if (m_ptr->mflag & MFLAG_CONTROL) - p_ptr->control = m_idx; + /* Count as an alive member of race */ + auto r_ptr = &r_info[m_ptr->r_idx]; + r_ptr->cur_num++; + } + } - /* Access race */ - r_ptr = &r_info[m_ptr->r_idx]; + /* Save/load pets */ + { + const std::size_t sz = + (flag == ls_flag_t::SAVE && !no_companions) ? max_m_idx : 0; - /* Count XXX XXX XXX */ - r_ptr->cur_num++; + do_array("pets", flag, km_list, sz, + [](auto m_ptr, auto flag) { + do_monster(m_ptr, flag); + } + ); } - /* Read the kept monsters */ + return true; +} - tmp16b = (flag == ls_flag_t::SAVE && !no_companions) ? max_m_idx : 0; +/* + * Handle dungeon + * + * The monsters/objects must be loaded in the same order + * that they were stored, since the actual indexes matter. + */ +static bool_ do_dungeon(ls_flag_t flag, bool no_companions) +{ + /* Header info */ + do_s16b(&dun_level, flag); + do_byte(&dungeon_type, flag); + do_s16b(&num_repro, flag); + do_s16b(&p_ptr->py, flag); + do_s16b(&p_ptr->px, flag); + do_s16b(&cur_hgt, flag); + do_s16b(&cur_wid, flag); + do_s16b(&max_panel_rows, flag); + do_s16b(&max_panel_cols, flag); + + do_flag_set(&dungeon_flags, flag); - /* Read the monster count */ - do_u16b(&tmp16b, flag); + /* Last teleportation */ + do_s16b(&last_teleportation_y, flag); + do_s16b(&last_teleportation_y, flag); + + /* Spell effects */ + do_array("spell effects", flag, effects, MAX_EFFECTS, + [](auto effect, auto flag) -> void { + do_s16b(&effect->type, flag); + do_s16b(&effect->dam, flag); + do_s16b(&effect->time, flag); + do_u32b(&effect->flags, flag); + do_s16b(&effect->cx, flag); + do_s16b(&effect->cy, flag); + do_s16b(&effect->rad, flag); + } + ); - /* Hack -- verify */ - if ((flag == ls_flag_t::LOAD) && (tmp16b > max_m_idx)) + /* To prevent bugs with evolving dungeons */ + for (std::size_t i = 0; i < 100; i++) { - note(format("Too many (%d) monster entries!", tmp16b)); - return (FALSE); + do_s16b(&floor_type[i], flag); + do_s16b(&fill_type[i], flag); } - for (i = 1; i < tmp16b; i++) + + if ((flag == ls_flag_t::LOAD) && (!dun_level && !p_ptr->inside_quest)) { - monster_type *m_ptr; + int xstart = 0; + int ystart = 0; + /* Init the wilderness */ + process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, + TRUE, FALSE); + + /* Init the town */ + xstart = 0; + ystart = 0; + init_flags = 0; + process_dungeon_file("t_info.txt", &ystart, &xstart, cur_hgt, cur_wid, + TRUE, FALSE); + } + + do_grid(flag); - /* Acquire monster */ - m_ptr = &km_list[i]; + /*** Objects ***/ + if (!do_objects(flag, no_companions)) + { + return FALSE; + } - /* Read the monster */ - do_monster(m_ptr, flag); + /*** Monsters ***/ + if (!do_monsters(flag, no_companions)) + { + return FALSE; } /*** Success ***/ @@ -1614,7 +1429,7 @@ static bool_ do_dungeon(ls_flag_t flag, bool_ no_companions) } /* Save the current persistent dungeon -SC- */ -void save_dungeon(void) +void save_dungeon() { char tmp[16]; char name[1024], buf[5]; @@ -1623,145 +1438,58 @@ void save_dungeon(void) if (!get_dungeon_save(buf) || (!dun_level)) return; /* Construct filename */ - sprintf(tmp, "%s.%s", player_base, buf); + sprintf(tmp, "%s.%s", game->player_base.c_str(), buf); path_build(name, 1024, ANGBAND_DIR_SAVE, tmp); /* Open the file */ fff = my_fopen(name, "wb"); /* Save the dungeon */ - do_dungeon(ls_flag_t::SAVE, TRUE); + do_dungeon(ls_flag_t::SAVE, true); my_fclose(fff); } -bool_ file_exist(cptr buf) -{ - int fd; - bool_ result; - - /* Open savefile */ - fd = fd_open(buf, O_RDONLY); - - /* File exists */ - if (fd >= 0) - { - fd_close(fd); - result = TRUE; - } - else - result = FALSE; - - return result; -} - - -/* - * Handle monster lore - */ -static void do_lore(int r_idx, ls_flag_t flag) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Count sights/deaths/kills */ - do_s16b(&r_ptr->r_sights, flag); - do_s16b(&r_ptr->r_deaths, flag); - do_s16b(&r_ptr->r_pkills, flag); - do_s16b(&r_ptr->r_tkills, flag); - - /* Count wakes and ignores */ - do_byte(&r_ptr->r_wake, flag); - do_byte(&r_ptr->r_ignore, flag); - - /* Extra stuff */ - do_byte(&r_ptr->r_xtra1, flag); - do_byte(&r_ptr->r_xtra2, flag); - - /* Count drops */ - do_byte(&r_ptr->r_drop_gold, flag); - do_byte(&r_ptr->r_drop_item, flag); - - /* Count spells */ - do_byte(&r_ptr->r_cast_inate, flag); - do_byte(&r_ptr->r_cast_spell, flag); - - /* Count blows of each type */ - do_byte(&r_ptr->r_blows[0], flag); - do_byte(&r_ptr->r_blows[1], flag); - do_byte(&r_ptr->r_blows[2], flag); - do_byte(&r_ptr->r_blows[3], flag); - - /* Memorize flags */ - do_u32b(&r_ptr->r_flags1, flag); /* Just to remind you */ - do_u32b(&r_ptr->r_flags2, flag); /* flag is unrelated to */ - do_u32b(&r_ptr->r_flags3, flag); /* the other argument */ - do_u32b(&r_ptr->r_flags4, flag); - do_u32b(&r_ptr->r_flags5, flag); - do_u32b(&r_ptr->r_flags6, flag); - do_u32b(&r_ptr->r_flags7, flag); - do_u32b(&r_ptr->r_flags8, flag); - do_u32b(&r_ptr->r_flags9, flag); - - /* Read the "Racial" monster tmp16b per level */ - do_s16b(&r_ptr->max_num, flag); - - do_byte((byte*)&r_ptr->on_saved, flag); - - if (flag == ls_flag_t::LOAD) - { - /* Lore flag repair? */ - 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; - } -} - - - /* * Read a store */ static void do_store(store_type *str, ls_flag_t flag) { - byte store_inven_max = STORE_INVEN_MAX; - - /* Some basic info */ + // Store state do_s32b(&str->store_open, flag); do_u16b(&str->owner, flag); - - /* Could be cleaner, done this way for benefit of the for loop later on */ - byte num; - if (flag == ls_flag_t::SAVE) num = str->stock_num; - do_byte(&num, flag); - - /* Last visit */ do_s32b(&str->last_visit, flag); - /* Items */ - for (int j = 0; j < num; j++) + // Items in store { - if (flag == ls_flag_t::LOAD) - /* Can't this be cleaner? */ + byte num = str->stock.size(); + + do_byte(&num, flag); + + if (flag == ls_flag_t::SAVE) { - object_type forge; - /* Wipe the object */ - object_wipe(&forge); - /* Read the item */ - do_item(&forge, ls_flag_t::LOAD); - /* Acquire valid items */ - if ((str->stock_num < store_inven_max) && (str->stock_num < str->stock_size)) + for (std::size_t i = 0; i < num; i++) { - int k = str->stock_num++; + do_item(&str->stock[i], ls_flag_t::SAVE); + } + } + else if (flag == ls_flag_t::LOAD) + { + for (std::size_t i = 0; i < num; i++) + { + object_type forge; + object_wipe(&forge); + do_item(&forge, ls_flag_t::LOAD); - /* Acquire the item */ - object_copy(&str->stock[k], &forge); + if ((str->stock.size() < STORE_INVEN_MAX) && (str->stock.size() < str->stock_size)) + { + object_type stock_obj; + object_copy(&stock_obj, &forge); + str->stock.push_back(stock_obj); + } } } - if (flag == ls_flag_t::SAVE) do_item(&str->stock[j], flag); } } @@ -1770,26 +1498,24 @@ static void do_store(store_type *str, ls_flag_t flag) */ static void do_randomizer(ls_flag_t flag) { - int i; - - u16b tmp16u = 0; + std::string state; - /* Tmp */ - do_u16b(&tmp16u, flag); + if (flag == ls_flag_t::SAVE) + { + state = get_complex_rng_state(); + } - /* Place */ - do_u16b(&Rand_place, flag); + do_std_string(state, flag); - /* State */ - for (i = 0; i < RAND_DEG; i++) + if (flag == ls_flag_t::LOAD) { - do_u32b(&Rand_state[i], flag); + set_complex_rng_state(state); } /* Accept */ if (flag == ls_flag_t::LOAD) { - Rand_quick = FALSE; + set_complex_rng(); } } @@ -1815,90 +1541,92 @@ static void do_options(ls_flag_t flag) /*** Special info */ /* Read "delay_factor" */ - do_byte(&delay_factor, flag); + do_byte(&options->delay_factor, flag); /* Read "hitpoint_warn" */ - do_byte(&hitpoint_warn, flag); + do_byte(&options->hitpoint_warn, flag); /*** Cheating options ***/ - if (flag == ls_flag_t::LOAD) /* There *MUST* be some nice way to unify this! */ - { - u16b c; - do_u16b(&c, ls_flag_t::LOAD); - if (c & 0x0002) wizard = TRUE; - cheat_peek = (c & 0x0100) ? TRUE : FALSE; - cheat_hear = (c & 0x0200) ? TRUE : FALSE; - cheat_room = (c & 0x0400) ? TRUE : FALSE; - cheat_xtra = (c & 0x0800) ? TRUE : FALSE; - cheat_know = (c & 0x1000) ? TRUE : FALSE; - cheat_live = (c & 0x2000) ? TRUE : FALSE; - } - if (flag == ls_flag_t::SAVE) - { - u16b c = 0; - if (wizard) c |= 0x0002; - if (cheat_peek) c |= 0x0100; - if (cheat_hear) c |= 0x0200; - if (cheat_room) c |= 0x0400; - if (cheat_xtra) c |= 0x0800; - if (cheat_know) c |= 0x1000; - if (cheat_live) c |= 0x2000; - do_u16b(&c, ls_flag_t::SAVE); - } + do_bool(&wizard, flag); + do_bool(&options->cheat_peek, flag); + do_bool(&options->cheat_hear, flag); + do_bool(&options->cheat_room, flag); + do_bool(&options->cheat_xtra, flag); + do_bool(&options->cheat_live, flag); - do_byte((byte*)&autosave_l, flag); - do_byte((byte*)&autosave_t, flag); - do_s16b(&autosave_freq, flag); + /*** Autosave options */ + do_bool(&options->autosave_l, flag); + do_bool(&options->autosave_t, flag); + do_s16b(&options->autosave_freq, flag); - if (flag == ls_flag_t::LOAD) + // Standard options { - /* Read the option flags */ - for (n = 0; n < 8; n++) do_u32b(&oflag[n], flag); + std::vector<option_value> option_values; - /* Read the option masks */ - for (n = 0; n < 8; n++) do_u32b(&mask[n], flag); + // If we're saving we need to map to a vector of key-value pairs. + if (flag == ls_flag_t::SAVE) + { + for (auto const &option: options->standard_options) + { + option_values.emplace_back( + option_value { + option.o_text, + *option.o_var + } + ); + } + } - /* Analyze the options */ - for (n = 0; n < 8; n++) + // Read/write the option values + do_vector(flag, option_values, do_option_value); + + // If we're loading we need to set options based of the key-value pairs. + if (flag == ls_flag_t::LOAD) { - /* Analyze the options */ - for (i = 0; i < 32; i++) + // Go through all the options that were loaded. + for (auto const &option_value: option_values) { - /* Process valid flags */ - if (mask[n] & (1L << i)) + // We need to search through all the options + // that are actually in the game; we'll ignore + // saved options that are now gone. + const option_type *found_option; + for (auto const &option: options->standard_options) { - /* Process valid flags */ - if (option_mask[n] & (1L << i)) + if (option_value.name == option.o_text) { - /* Set */ - if (oflag[n] & (1L << i)) - { - /* Set */ - option_flag[n] |= (1L << i); - } - - /* Clear */ - else - { - /* Clear */ - option_flag[n] &= ~(1L << i); - } + found_option = &option; + break; } } + + // If we found the option, we'll set the value. + if (found_option) + { + *(*found_option).o_var = option_value.value; + } } } + } + if (flag == ls_flag_t::LOAD) + { /*** Window Options ***/ /* Read the window flags */ - for (n = 0; n < 8; n++) do_u32b(&oflag[n], flag); + for (n = 0; n < ANGBAND_TERM_MAX; n++) + { + do_u32b(&oflag[n], flag); + } /* Read the window masks */ - for (n = 0; n < 8; n++) do_u32b(&mask[n], flag); + for (n = 0; n < ANGBAND_TERM_MAX; n++) + { + do_u32b(&mask[n], flag); + } /* Analyze the options */ - for (n = 0; n < 8; n++) + for (n = 0; n < ANGBAND_TERM_MAX; n++) { /* Analyze the options */ for (i = 0; i < 32; i++) @@ -1927,61 +1655,34 @@ static void do_options(ls_flag_t flag) } } } + if (flag == ls_flag_t::SAVE) { - /* Analyze the options */ - for (i = 0; option_info[i].o_desc; i++) - { - int os = option_info[i].o_page; - int ob = option_info[i].o_bit; - - /* Process real entries */ - if (option_info[i].o_var) - { - /* Set */ - if (*option_info[i].o_var) - { - /* Set */ - option_flag[os] |= (1L << ob); - } - - /* Clear */ - else - { - /* Clear */ - option_flag[os] &= ~(1L << ob); - } - } - } - - - /*** Normal options ***/ - - /* Dump the flags */ - for (i = 0; i < 8; i++) do_u32b(&option_flag[i], flag); - - /* Dump the masks */ - for (i = 0; i < 8; i++) do_u32b(&option_mask[i], flag); - /*** Window options ***/ /* Dump the flags */ - for (i = 0; i < 8; i++) do_u32b(&window_flag[i], flag); + for (i = 0; i < ANGBAND_TERM_MAX; i++) + { + do_u32b(&window_flag[i], flag); + } /* Dump the masks */ - for (i = 0; i < 8; i++) do_u32b(&window_mask[i], flag); + for (i = 0; i < ANGBAND_TERM_MAX; i++) + { + do_u32b(&window_mask[i], flag); + } } } /* - * Handle player inventory - * - * FIXME! This function probably could be unified better - * Note that the inventory is "re-sorted" later by "dungeon()". + * Handle player inventory. Note that the inventory is + * "re-sorted" later by "dungeon()". */ static bool_ do_inventory(ls_flag_t flag) { + auto const &a_info = game->edit_data.a_info; + if (flag == ls_flag_t::LOAD) { int slot = 0; @@ -2058,63 +1759,56 @@ static bool_ do_inventory(ls_flag_t flag) } if (flag == ls_flag_t::SAVE) { - u16b i; - u16b sent = 0xFFFF; - for (i = 0; i < INVEN_TOTAL; i++) + for (u16b i = 0; i < INVEN_TOTAL; i++) { object_type *o_ptr = &p_ptr->inventory[i]; if (!o_ptr->k_idx) continue; do_u16b(&i, flag); do_item(o_ptr, flag); } - do_u16b(&sent, ls_flag_t::SAVE); /* Sentinel */ + // Sentinel + u16b sent = 0xFFFF; + do_u16b(&sent, ls_flag_t::SAVE); } /* Success */ return (TRUE); } +static void do_message(message &msg, ls_flag_t flag) +{ + do_std_string(msg.text, flag); + do_u32b(&msg.count, flag); + do_byte(&msg.color, flag); +} + /* * Read the saved messages */ -static void do_messages(ls_flag_t flag) /* FIXME! We should be able to unify this better */ +static void do_messages(ls_flag_t flag) { - int i; - char buf[128]; - byte color; + auto &messages = game->messages; - s16b num; - - /* Total */ - if (flag == ls_flag_t::SAVE) num = message_num(); + /* Save/load number of messages */ + s16b num = messages.size(); do_s16b(&num, flag); /* Read the messages */ - if (flag == ls_flag_t::LOAD) + for (int i = 0; i < num; i++) { - byte tmp8u = 0; - for (i = 0; i < num; i++) - { - /* Read the message */ - do_string(buf, 128, ls_flag_t::LOAD); - do_byte(&color, flag); - do_byte(&tmp8u, flag); + message message; - /* Save the message */ - message_add(buf, color); + if (flag == ls_flag_t::SAVE) + { + message = messages.at(i); } - } - if (flag == ls_flag_t::SAVE) - { - byte holder; - byte zero = 0; - for (i = num - 1; i >= 0; i--) + + do_message(message, flag); + + if (flag == ls_flag_t::LOAD) { - do_string((char *)message_str((s16b)i), 0, ls_flag_t::SAVE); - holder = message_color((s16b)i); - do_byte(&holder, flag); - do_byte(&zero, flag); + messages.add(message); } } } @@ -2128,7 +1822,7 @@ bool_ load_dungeon(char *ext) s16b old_dun = dun_level; /* Construct name */ - sprintf(tmp, "%s.%s", player_base, ext); + sprintf(tmp, "%s.%s", game->player_base.c_str(), ext); path_build(name, 1024, ANGBAND_DIR_SAVE, tmp); /* Open the file */ @@ -2144,7 +1838,7 @@ bool_ load_dungeon(char *ext) } /* Read the dungeon */ - if (!do_dungeon(ls_flag_t::LOAD, FALSE)) + if (!do_dungeon(ls_flag_t::LOAD, false)) { dun_level = old_dun; dungeon_type = old_dungeon_type; @@ -2161,35 +1855,16 @@ bool_ load_dungeon(char *ext) return (TRUE); } -void do_fate(int i, ls_flag_t flag) -{ - if ((flag == ls_flag_t::LOAD) && (i >= MAX_FATES)) i = MAX_FATES - 1; - - do_byte(&fates[i].fate, flag); - do_byte(&fates[i].level, flag); - do_byte(&fates[i].serious, flag); - do_s16b(&fates[i].o_idx, flag); - do_s16b(&fates[i].e_idx, flag); - do_s16b(&fates[i].a_idx, flag); - do_s16b(&fates[i].v_idx, flag); - do_s16b(&fates[i].r_idx, flag); - do_s16b(&fates[i].count, flag); - do_s16b(&fates[i].time, flag); - do_byte((byte*)&fates[i].know, flag); -} - /* * Load/save timers. */ static void do_timers(ls_flag_t flag) { - timer_type *t_ptr; - - for (t_ptr = gl_timers; t_ptr != NULL; t_ptr = t_ptr->next) + for (auto &&t_ptr: game->timers) { - do_bool(&t_ptr->enabled, flag); - do_s32b(&t_ptr->delay, flag); - do_s32b(&t_ptr->countdown, flag); + do_std_bool(&t_ptr->m_enabled, flag); + do_s32b(&t_ptr->m_delay, flag); + do_s32b(&t_ptr->m_countdown, flag); } } @@ -2198,41 +1873,41 @@ static void do_timers(ls_flag_t flag) */ static void do_stores(ls_flag_t flag) { - u16b tmp16u; - u16b real_max = 0; + auto const &st_info = game->edit_data.st_info; - /* Note that this forbids max_towns from shrinking, but that is fine */ - std::unique_ptr<byte[]> reals(new byte[max_towns]); + // Indexes for "real" towns. + std::vector<byte> reals; + reals.reserve(max_towns); - /* Find the real towns */ + // Fill in the "real" towns if necessary. if (flag == ls_flag_t::SAVE) { for (int i = 1; i < max_towns; i++) { - if (!(town_info[i].flags & (TOWN_REAL))) continue; - reals[real_max++] = i; + if (!(town_info[i].flags & TOWN_REAL)) + { + continue; + } + reals.emplace_back(i); } } - do_u16b(&real_max, flag); - for (int i = 0; i < real_max; i++) - { - do_byte((byte*)&reals[i], flag); - } + + // Load/save + do_vector(flag, reals, do_byte); /* Read the stores */ - if (flag == ls_flag_t::SAVE) tmp16u = max_st_idx; - do_u16b(&tmp16u, flag); - assert(tmp16u <= max_st_idx); + u16b n_stores = st_info.size(); + do_u16b(&n_stores, flag); + assert(n_stores <= st_info.size()); - /* Ok now read the real towns */ - for (int i = 0; i < real_max; i++) + for (auto const z: reals) { - int z = reals[i]; - - /* Ultra paranoia */ - if (!town_info[z].stocked) create_stores_stock(z); + if (!town_info[z].stocked) + { + create_stores_stock(z); + } - for (int j = 0; j < tmp16u; j++) + for (int j = 0; j < n_stores; j++) { do_store(&town_info[z].store[j], flag); } @@ -2240,395 +1915,398 @@ static void do_stores(ls_flag_t flag) } /* - * Note that this function may not be needed at all. - * It was taken out of load_player_aux(). Do we need it? + * Monster memory */ -static void junkinit(void) +static bool do_monster_lore(ls_flag_t flag) { - int i, j; - p_ptr->inside_quest = 0; - p_ptr->town_num = 1; - p_ptr->wilderness_x = 4; - p_ptr->wilderness_y = 4; - for (i = 0; i < max_wild_x; i++) - { - for (j = 0; j < max_wild_y; j++) - { - wild_map[j][i].seed = rand_int(0x10000000); + auto &r_info = game->edit_data.r_info; + + do_array("monster races", flag, r_info, r_info.size(), + [](auto r_ptr, auto flag) -> void { + do_s16b(&r_ptr->r_pkills, flag); + do_s16b(&r_ptr->max_num, flag); + do_bool(&r_ptr->on_saved, flag); } - } -} + ); -static void morejunk(void) -{ - sp_ptr = &sex_info[p_ptr->psex]; /* Sex */ - rp_ptr = &race_info[p_ptr->prace]; /* Raceclass */ - rmp_ptr = &race_mod_info[p_ptr->pracem]; - cp_ptr = &class_info[p_ptr->pclass]; - spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec]; + return true; } /* - * Actually read the savefile + * Object memory */ -static bool_ do_savefile_aux(ls_flag_t flag) +static bool do_object_lore(ls_flag_t flag) { - int i, j; + auto &k_info = game->edit_data.k_info; - byte tmp8u; - u16b tmp16u; + do_array("object kinds", flag, k_info, k_info.size(), + [](auto k_ptr, auto flag) -> void { + do_bool(&k_ptr->aware, flag); + do_bool(&k_ptr->tried, flag); + do_bool(&k_ptr->artifact, flag); + } + ); - /* Mention the savefile version */ - if (flag == ls_flag_t::LOAD) + return true; +} + + +static bool do_towns(ls_flag_t flag) +{ + auto &d_info = game->edit_data.d_info; + + u16b max_towns_ldsv = max_towns; + + do_u16b(&max_towns_ldsv, flag); + + if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > max_towns)) { - if (vernum < 100) - { - note(format("Savefile version %lu too old! ", vernum)); - return FALSE; - } - else - { - note(format("Loading version %lu savefile... ", vernum)); - } + note("Too many towns!"); + return false; } + if (flag == ls_flag_t::SAVE) { - sf_when = time((time_t *) 0); /* Note when file was saved */ - sf_saves++; /* Increment the saves ctr */ + max_towns_ldsv = TOWN_RANDOM; } - /* Handle version bytes. FIXME! DG wants me to change this all around */ - if (flag == ls_flag_t::LOAD) - { - u32b mt32b; - byte mtbyte; + do_u16b(&max_towns_ldsv, flag); - /* Discard all this, we've already read it */ - do_u32b(&mt32b, flag); - do_byte(&mtbyte, flag); - } - if (flag == ls_flag_t::SAVE) + if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv != TOWN_RANDOM)) { - u32b saver; - saver = SAVEFILE_VERSION; - do_u32b(&saver, flag); - tmp8u = (byte)rand_int(256); - do_byte(&tmp8u, flag); /* 'encryption' */ + note("Different random towns base!"); + return false; } - /* Kept only for compatibility; always set to 0 */ + for (std::size_t i = 0; i < max_towns; i++) { - u32b tmp32u = 0; - do_u32b(&tmp32u, flag); - } + auto town = &town_info[i]; - /* Time of last save */ - do_u32b(&sf_when, flag); + do_bool(&town->destroyed, flag); - /* Number of past lives */ - do_u16b(&sf_lives, flag); + if (i >= TOWN_RANDOM) + { + do_seed(&town->seed, flag); + do_byte(&town->flags, flag); - /* Number of times saved */ - do_u16b(&sf_saves, flag); + // Create stock if necessary + if ((town_info->flags & TOWN_REAL) && (flag == ls_flag_t::LOAD)) + { + create_stores_stock(i); + } + } + } - /* Game module */ if (flag == ls_flag_t::SAVE) - strcpy(loaded_game_module, game_module); - do_string(loaded_game_module, 80, flag); - - /* Timers */ - do_timers(flag); - - /* Read RNG state */ - do_randomizer(flag); - - /* Automatizer state */ - do_byte((byte*)&automatizer_enabled, flag); + { + max_towns_ldsv = d_info.size(); + } - /* Then the options */ - do_options(flag); + do_u16b(&max_towns_ldsv, flag); - /* Then the "messages" */ - do_messages(flag); + if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > d_info.size())) + { + note("Too many dungeon types!"); + return false; + } - /* Monster Memory */ - if (flag == ls_flag_t::SAVE) tmp16u = max_r_idx; - do_u16b(&tmp16u, flag); + // Town quest entrances + u16b max_quests_ldsv = TOWN_DUNGEON; + do_u16b(&max_quests_ldsv, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > max_r_idx)) + if ((flag == ls_flag_t::LOAD) && (max_quests_ldsv > TOWN_DUNGEON)) { - note(format("Too many (%u) monster races!", tmp16u)); - return (FALSE); + note("Too many town per dungeons!"); + return false; } - /* Read the available records */ - for (i = 0; i < tmp16u; i++) + for (std::size_t i = 0; i < max_towns_ldsv; i++) { - /* Read the lore */ - do_lore(i, flag); + for (std::size_t j = 0; j < max_quests_ldsv; j++) + { + do_s16b(&(d_info[i].t_idx[j]), flag); + do_s16b(&(d_info[i].t_level[j]), flag); + } + do_s16b(&(d_info[i].t_num), flag); } - /* Object Memory */ - if (flag == ls_flag_t::SAVE) tmp16u = max_k_idx; - do_u16b(&tmp16u, flag); + return true; +} - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > max_k_idx)) - { - note(format("Too many (%u) object kinds!", tmp16u)); - return (FALSE); - } +static bool do_quests(ls_flag_t flag) +{ + do_array("quests", flag, quest, MAX_Q_IDX, + [](auto q, auto flag) { + // Load/save the data + do_s16b(&q->status, flag); + for (auto &quest_data : q->data) + { + do_s32b(&quest_data, flag); + } + // Initialize if necessary + if ((flag == ls_flag_t::LOAD) && (q->init != NULL)) + { + q->init(); + } + } + ); + + return true; +} + +static bool do_wilderness(ls_flag_t flag) +{ + auto &wilderness = game->wilderness; + + // Player position and "mode" wrt. wilderness + do_s32b(&p_ptr->wilderness_x, flag); + do_s32b(&p_ptr->wilderness_y, flag); + do_bool(&p_ptr->wild_mode, flag); + do_bool(&p_ptr->old_wild_mode, flag); - /* Read the object memory */ - for (i = 0; i < tmp16u; i++) do_xtra(i, flag); - if (flag == ls_flag_t::LOAD) junkinit(); + // Size of the wilderness + u16b wild_x_size = wilderness.width(); + u16b wild_y_size = wilderness.height(); + do_u16b(&wild_x_size, flag); + do_u16b(&wild_y_size, flag); + if (flag == ls_flag_t::LOAD) { - u16b max_towns_ldsv; - u16b max_quests_ldsv; - if (flag == ls_flag_t::SAVE) max_towns_ldsv = max_towns; - /* Number of towns */ - do_u16b(&max_towns_ldsv, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > max_towns)) + if ((wild_x_size > wilderness.width()) || (wild_y_size > wilderness.height())) { - note(format("Too many (%u) towns!", max_towns_ldsv)); - return (FALSE); + note("Wilderness is too big!"); + return false; } - /* Min of random towns */ - if (flag == ls_flag_t::SAVE) max_towns_ldsv = TOWN_RANDOM; - do_u16b(&max_towns_ldsv, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv != TOWN_RANDOM)) + } + + // Save/load wilderness tile state + for (std::size_t x = 0; x < wild_x_size; x++) + { + for (std::size_t y = 0; y < wild_y_size; y++) { - note(format("Different random towns base (%u)!", max_towns_ldsv)); - return (FALSE); + auto w = &wilderness(x, y); + do_seed(&w->seed, flag); + do_u16b(&w->entrance, flag); + do_bool(&w->known, flag); } + } - for (i = 0; i < max_towns; i++) - { - do_byte((byte*)&town_info[i].destroyed, flag); + return true; +} - if (i >= TOWN_RANDOM) - { - do_u32b(&town_info[i].seed, flag); - do_byte(&town_info[i].numstores, flag); - do_byte(&town_info[i].flags, flag); +static void do_randart(random_artifact *ra_ptr, ls_flag_t flag) +{ + do_std_string(ra_ptr->name_full, flag); + do_std_string(ra_ptr->name_short, flag); + do_byte(&ra_ptr->level, flag); + do_byte(&ra_ptr->attr, flag); + do_u32b(&ra_ptr->cost, flag); + do_byte(&ra_ptr->activation, flag); + do_byte(&ra_ptr->generated, flag); +} - /* If the town is realy used create a sock */ - if ((town_info[i].flags & (TOWN_REAL)) && (flag == ls_flag_t::LOAD)) - { - create_stores_stock(i); - } - } +static bool do_randarts(ls_flag_t flag) +{ + do_vector(flag, game->random_artifacts, do_randart); + return true; +} + +static bool do_artifacts(ls_flag_t flag) +{ + auto &a_info = game->edit_data.a_info; + + do_array("artifacts", flag, a_info, a_info.size(), + [](auto a_ptr, auto flag) { + do_byte(&a_ptr->cur_num, flag); } + ); - /* Number of dungeon */ - if (flag == ls_flag_t::SAVE) max_towns_ldsv = max_d_idx; - do_u16b(&max_towns_ldsv, flag); + return true; +} - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (max_towns_ldsv > max_d_idx)) - { - note(format("Too many dungeon types (%u)!", max_towns_ldsv)); - return (FALSE); +static bool do_fates(ls_flag_t flag) +{ + do_array("fates", flag, fates, MAX_FATES, + [](auto fate, auto flag) { + do_byte(&fate->fate, flag); + do_byte(&fate->level, flag); + do_byte(&fate->serious, flag); + do_s16b(&fate->o_idx, flag); + do_s16b(&fate->e_idx, flag); + do_s16b(&fate->a_idx, flag); + do_s16b(&fate->v_idx, flag); + do_s16b(&fate->r_idx, flag); + do_s16b(&fate->count, flag); + do_s16b(&fate->time, flag); + do_bool(&fate->know, flag); } + ); - /* Number of towns per dungeon */ - if (flag == ls_flag_t::SAVE) max_quests_ldsv = TOWN_DUNGEON; - do_u16b(&max_quests_ldsv, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (max_quests_ldsv > TOWN_DUNGEON)) - { - note(format("Too many town per dungeons (%u)!", max_quests_ldsv)); - return (FALSE); + return true; +} + +static bool do_floor_inscriptions(ls_flag_t flag) +{ + do_array("inscriptions", flag, p_ptr->inscriptions, MAX_INSCRIPTIONS, + [](auto i_ptr, auto flag) { + do_std_bool(i_ptr, flag); } + ); - for (i = 0; i < max_towns_ldsv; i++) - { - for (j = 0; j < max_quests_ldsv; j++) - { - do_s16b(&(d_info[i].t_idx[j]), flag); - do_s16b(&(d_info[i].t_level[j]), flag); - } - do_s16b(&(d_info[i].t_num), flag); + return true; +} + +static bool do_player_hd(ls_flag_t flag) +{ + auto &player_hp = game->player_hp; + + do_array("hit dice entries", flag, player_hp, PY_MAX_LEVEL, + [](auto hp_ptr, auto flag) { + do_s16b(hp_ptr, flag); } + ); - /* Sanity check number of quests */ - if (flag == ls_flag_t::SAVE) max_quests_ldsv = MAX_Q_IDX; - do_u16b(&max_quests_ldsv, flag); + return true; +} + + +/* + * Actually read the savefile + */ +static bool_ do_savefile_aux(ls_flag_t flag) +{ + 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; - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (max_quests_ldsv != MAX_Q_IDX)) + /* Mention the savefile version */ + if (flag == ls_flag_t::LOAD) + { + if (vernum != SAVEFILE_VERSION) { - note(format("Invalid number of quests (%u)!", max_quests_ldsv)); - return (FALSE); + note("Incompatible save file version"); + return FALSE; } + } - for (i = 0; i < MAX_Q_IDX; i++) - { - do_s16b(&quest[i].status, flag); - for (auto &quest_data : quest[i].data) - { - do_s32b(&quest_data, flag); - } + /* Handle version bytes */ + if (flag == ls_flag_t::LOAD) + { + /* Discard all this, we've already read it */ + u32b mt32b; + do_u32b(&mt32b, flag); + } + if (flag == ls_flag_t::SAVE) + { + u32b saver; + saver = SAVEFILE_VERSION; + do_u32b(&saver, flag); + } - /* Init the hooks */ - if ((flag == ls_flag_t::LOAD) && (quest[i].init != NULL)) - { - quest[i].init(i); - } - } + /* Game module */ + { + std::string loaded_game_module; - /* Position in the wilderness */ - do_s32b(&p_ptr->wilderness_x, flag); - do_s32b(&p_ptr->wilderness_y, flag); - do_byte((byte*)&p_ptr->wild_mode, flag); - do_byte((byte*)&p_ptr->old_wild_mode, flag); + if (flag == ls_flag_t::SAVE) + { + loaded_game_module = game_module; + } + do_std_string(loaded_game_module, flag); + // Check for incompatible module + if (flag == ls_flag_t::LOAD) { - s32b wild_x_size, wild_y_size; - if (flag == ls_flag_t::SAVE) + if (!module_savefile_loadable(loaded_game_module)) { - wild_x_size = max_wild_x; - wild_y_size = max_wild_y; - } - /* Size of the wilderness */ - do_s32b(&wild_x_size, flag); - do_s32b(&wild_y_size, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && - ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y))) - { - note(format("Wilderness is too big (%u/%u)!", - wild_x_size, wild_y_size)); - return (FALSE); - } - /* Wilderness seeds */ - for (i = 0; i < wild_x_size; i++) - { - for (j = 0; j < wild_y_size; j++) - { - do_u32b(&wild_map[j][i].seed, flag); - do_u16b(&wild_map[j][i].entrance, flag); - do_byte((byte*)&wild_map[j][i].known, flag); - } + note(fmt::format("Bad game module. Savefile was saved with module '{:s}' but game is '{:s}'.", + loaded_game_module, + game_module).c_str()); + return FALSE; } } } - /* Load the random artifacts. */ - if (flag == ls_flag_t::SAVE) tmp16u = MAX_RANDARTS; - do_u16b(&tmp16u, flag); - if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_RANDARTS)) + /* Timers */ + do_timers(flag); + + /* Read RNG state */ + do_randomizer(flag); + + /* Automatizer state */ + do_bool(&automatizer_enabled, flag); + + /* Then the options */ + do_options(flag); + + /* Then the "messages" */ + do_messages(flag); + + if (!do_monster_lore(flag)) { - note(format("Too many (%u) random artifacts!", tmp16u)); - return (FALSE); + return FALSE; } - for (i = 0; i < tmp16u; i++) - { - random_artifact *ra_ptr = &random_artifacts[i]; - do_string(ra_ptr->name_full, 80, flag); - do_string(ra_ptr->name_short, 80, flag); - do_byte(&ra_ptr->level, flag); - do_byte(&ra_ptr->attr, flag); - do_u32b(&ra_ptr->cost, flag); - do_byte(&ra_ptr->activation, flag); - do_byte(&ra_ptr->generated, flag); + if (!do_object_lore(flag)) + { + return FALSE; } - /* Load the Artifacts */ - if (flag == ls_flag_t::SAVE) tmp16u = max_a_idx; - do_u16b(&tmp16u, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > max_a_idx)) + if (!do_towns(flag)) { - note(format("Too many (%u) artifacts!", tmp16u)); - return (FALSE); + return FALSE; } - /* Read the artifact flags */ - for (i = 0; i < tmp16u; i++) + if (!do_quests(flag)) { - do_byte(&(&a_info[i])->cur_num, flag); + return FALSE; } - /* Fates */ - if (flag == ls_flag_t::SAVE) tmp16u = MAX_FATES; - do_u16b(&tmp16u, flag); - - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_FATES)) + if (!do_wilderness(flag)) { - note(format("Too many (%u) fates!", tmp16u)); - return (FALSE); + return FALSE; } - /* Read the fate flags */ - for (i = 0; i < tmp16u; i++) + if (!do_randarts(flag)) { - do_fate(i, flag); + return FALSE; } - /* Load the Traps */ - if (flag == ls_flag_t::SAVE) tmp16u = max_t_idx; - do_u16b(&tmp16u, flag); - - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > max_t_idx)) + if (!do_artifacts(flag)) { - note(format("Too many (%u) traps!", tmp16u)); - return (FALSE); + return FALSE; } - /* fate flags */ - for (i = 0; i < tmp16u; i++) + if (!do_fates(flag)) { - do_byte((byte*)&t_info[i].ident, flag); + return FALSE; } - /* inscription knowledge */ - if (flag == ls_flag_t::SAVE) tmp16u = MAX_INSCRIPTIONS; - do_u16b(&tmp16u, flag); - - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > MAX_INSCRIPTIONS)) + if (!do_floor_inscriptions(flag)) { - note(format("Too many (%u) inscriptions!", tmp16u)); - return (FALSE); + return FALSE; } - /* Read the inscription flag */ - for (i = 0; i < tmp16u; i++) - do_byte((byte*)&inscription_info[i].know, flag); - - - /* Read the extra stuff */ if (!do_extra(flag)) + { return FALSE; + } - - /* player_hp array */ - if (flag == ls_flag_t::SAVE) tmp16u = PY_MAX_LEVEL; - do_u16b(&tmp16u, flag); - /* Incompatible save files */ - if ((flag == ls_flag_t::LOAD) && (tmp16u > PY_MAX_LEVEL)) + if (!do_player_hd(flag)) { - note(format("Too many (%u) hitpoint entries!", tmp16u)); - return (FALSE); + return FALSE; } - /* Read the player_hp array */ - for (i = 0; i < tmp16u; i++) + if (flag == ls_flag_t::LOAD) { - do_s16b(&player_hp[i], flag); + // Make sure that the auxiliary pointers for player + // class, race, etc. point to the right places. + rp_ptr = &race_info[p_ptr->prace]; + rmp_ptr = &race_mod_info[p_ptr->pracem]; + cp_ptr = &class_info[p_ptr->pclass]; + spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec]; } - if (flag == ls_flag_t::LOAD) morejunk(); - /* Read the pet command settings */ do_byte(&p_ptr->pet_follow_distance, flag); do_byte(&p_ptr->pet_open_doors, flag); @@ -2638,10 +2316,13 @@ static bool_ do_savefile_aux(ls_flag_t flag) do_s16b(&p_ptr->dripping_tread, flag); /* Read the inventory */ - if (!do_inventory(flag) && (flag == ls_flag_t::LOAD)) /* do NOT reverse this ordering */ + if (!do_inventory(flag)) { - note("Unable to read inventory"); - return (FALSE); + if (flag == ls_flag_t::LOAD) + { + note("Unable to read inventory"); + return FALSE; + } } /* Stores */ @@ -2651,35 +2332,25 @@ static bool_ do_savefile_aux(ls_flag_t flag) if (!death) { /* Dead players have no dungeon */ - if (flag == ls_flag_t::LOAD) note("Restoring Dungeon..."); - if ((flag == ls_flag_t::LOAD) && (!do_dungeon(ls_flag_t::LOAD, FALSE))) + if (flag == ls_flag_t::LOAD) + { + note("Restoring Dungeon..."); + } + + if ((flag == ls_flag_t::LOAD) && (!do_dungeon(ls_flag_t::LOAD, false))) { note("Error reading dungeon data"); - return (FALSE); + return FALSE; } - if (flag == ls_flag_t::SAVE) do_dungeon(ls_flag_t::SAVE, FALSE); - my_sentinel("Before ghost data", 435, flag); - my_sentinel("After ghost data", 320, flag); - } - { - byte foo = 0; if (flag == ls_flag_t::SAVE) { - /* - * Safety Padding. It's there - * for a good reason. Trust me on - * this. Keep this at the *END* - * of the file, and do *NOT* try to - * read it. Insert any new stuff before - * this position. - */ - do_byte(&foo, ls_flag_t::SAVE); + do_dungeon(ls_flag_t::SAVE, false); } } /* Success */ - return (TRUE); + return TRUE; } @@ -2687,7 +2358,7 @@ static bool_ do_savefile_aux(ls_flag_t flag) /* * Actually read the savefile */ -static errr rd_savefile(void) +static errr rd_savefile() { errr err = 0; @@ -2725,10 +2396,8 @@ static errr rd_savefile(void) * Note that we always try to load the "current" savefile, even if * there is no such file, so we must check for "empty" savefile names. */ -bool_ load_player(void) +bool_ load_player() { - int fd = -1; - errr err = 0; cptr what = "generic"; @@ -2747,7 +2416,7 @@ bool_ load_player(void) /* XXX XXX XXX Fix this */ /* Verify the existance of the savefile */ - if (!file_exist(savefile)) + if (!boost::filesystem::exists(savefile)) { /* Give a message */ msg_format("Savefile does not exist: %s", savefile); @@ -2761,45 +2430,34 @@ bool_ load_player(void) if (!err) { /* Open the savefile */ - fd = fd_open(savefile, O_RDONLY); + int fd = fd_open(savefile, O_RDONLY); /* No file */ if (fd < 0) err = -1; /* Message (below) */ if (err) what = "Cannot open savefile"; + + /* Close the file */ + if (!err) fd_close(fd); } /* Process file */ if (!err) { - byte tmp8u = 0; - /* Open the file XXX XXX XXX XXX Should use Angband file interface */ fff = my_fopen(savefile, "rb"); -/* fff = fdopen(fd, "r"); */ /* Read the first four bytes */ do_u32b(&vernum, ls_flag_t::LOAD); - do_byte(&tmp8u, ls_flag_t::LOAD); // For comatibility with old savefiles - /* XXX XXX XXX XXX Should use Angband file interface */ my_fclose(fff); - /* fclose(fff) */ - /* Close the file */ - fd_close(fd); } /* Process file */ if (!err) { - - /* Extract version */ - sf_major = VERSION_MAJOR; - sf_minor = VERSION_MINOR; - sf_patch = VERSION_PATCH; - /* Clear screen */ Term_clear(); @@ -2840,9 +2498,6 @@ bool_ load_player(void) return (TRUE); } - /* Count lives */ - sf_lives++; - /* Forget turns */ turn = old_turn = 0; @@ -2857,7 +2512,7 @@ bool_ load_player(void) if (p_ptr->chp >= 0) { /* Reset cause of death */ - (void)strcpy(died_from, "(alive and well)"); + game->died_from = "(alive and well)"; } /* Success */ @@ -2866,8 +2521,8 @@ bool_ load_player(void) /* Message */ - msg_format("Error (%s) reading %d.%d.%d savefile.", - what, sf_major, sf_minor, sf_patch); + msg_format("Error (%s) reading savefile (version " FMTu32b ").", + what, vernum); msg_print(NULL); /* Oops */ @@ -2895,7 +2550,7 @@ static bool_ save_player_aux(char *name) if (fd >= 0) { /* Close the "fd" */ - (void)fd_close(fd); + fd_close(fd); /* Open the savefile */ fff = my_fopen(name, "wb"); @@ -2914,7 +2569,7 @@ static bool_ save_player_aux(char *name) if (!ok) { /* Remove "broken" files */ - (void)fd_kill(name); + fd_kill(name); } } @@ -2928,7 +2583,7 @@ static bool_ save_player_aux(char *name) /* * Attempt to save the player in a savefile */ -bool_ save_player(void) +bool_ save_player() { int result = FALSE; char safe[1024]; diff --git a/src/loadsave.h b/src/loadsave.h index 61bfced7..52782dac 100644 --- a/src/loadsave.h +++ b/src/loadsave.h @@ -7,9 +7,8 @@ extern "C" { #endif -/* loadsave.c */ -extern void save_dungeon(void); -extern bool_ save_player(void); +void save_dungeon(); +bool_ save_player(); #ifdef __cplusplus } // extern "C" diff --git a/src/loadsave.hpp b/src/loadsave.hpp index a9eb9dc8..d28d437e 100644 --- a/src/loadsave.hpp +++ b/src/loadsave.hpp @@ -2,6 +2,5 @@ #include "h-basic.h" -extern bool_ file_exist(cptr buf); -extern bool_ load_dungeon(char *ext); -extern bool_ load_player(void); +bool_ load_dungeon(char *ext); +bool_ load_player(); diff --git a/src/lua_bind.cc b/src/lua_bind.cc index aa2c3a2a..3ca43716 100644 --- a/src/lua_bind.cc +++ b/src/lua_bind.cc @@ -10,6 +10,7 @@ #include "cmd7.hpp" #include "corrupt.hpp" +#include "game.hpp" #include "init1.hpp" #include "monster2.hpp" #include "player_type.hpp" @@ -85,6 +86,8 @@ s32b lua_get_level(spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus) static s32b get_level_device_1(spell_type *spell, s32b max, s32b min) { + auto const &s_info = game->s_info; + // Must be in "device" mode. assert(get_level_use_stick > -1); // Delegate @@ -146,7 +149,7 @@ static s32b spell_chance_school(s32b s) minfail = adj_mag_fail[stat_ind]; /* Must have Perfect Casting to get below 5% */ - if (!(has_ability(AB_PERFECT_CASTING))) + if (!(p_ptr->has_ability(AB_PERFECT_CASTING))) { if (minfail < 5) minfail = 5; } @@ -185,7 +188,7 @@ s32b spell_chance_book(s32b s) return spell_chance_school(s); } -s32b get_level(s32b s, s32b max, s32b min) +static s32b get_level_full(s32b s, s32b max, s32b min) { auto spell = spell_at(s); /** Ahah shall we use Magic device instead ? */ @@ -196,6 +199,16 @@ s32b get_level(s32b s, s32b max, s32b min) } } +s32b get_level(s32b s, s32b max) +{ + return get_level_full(s, max, 0); +} + +s32b get_level_s(int sp, int max) +{ + return get_level_full(sp, max, 1); +} + /* Level gen */ void get_map_size(const char *name, int *ysize, int *xsize) { @@ -217,31 +230,6 @@ void load_map(const char *name, int *y, int *x) process_dungeon_file(name, y, x, cur_hgt, cur_wid, TRUE, TRUE); } -/* - * Some misc functions - */ -char *lua_input_box(cptr title, int max) -{ - static char buf[80]; - int wid, hgt; - - strcpy(buf, ""); - Term_get_size(&wid, &hgt); - if (!input_box(title, hgt / 2, wid / 2, buf, (max > 79) ? 79 : max)) - return buf; - return buf; -} - -char lua_msg_box(cptr title) -{ - int wid, hgt; - - Term_get_size(&wid, &hgt); - return msg_box(title, hgt / 2, wid / 2); -} - - - void increase_mana(int delta) { p_ptr->csp += delta; @@ -261,7 +249,7 @@ timer_type *TIMER_AGGRAVATE_EVIL = 0; void timer_aggravate_evil_enable() { - TIMER_AGGRAVATE_EVIL->enabled = TRUE; + TIMER_AGGRAVATE_EVIL->enable(); } void timer_aggravate_evil_callback() diff --git a/src/lua_bind.hpp b/src/lua_bind.hpp index b2a6c9a7..39fc2159 100644 --- a/src/lua_bind.hpp +++ b/src/lua_bind.hpp @@ -5,28 +5,26 @@ #include "timer_type_fwd.hpp" /** Calculate spell failure rate for a device, i.e. a wand or staff. */ -extern s32b spell_chance_device(spell_type *spell_ptr); +s32b spell_chance_device(spell_type *spell_ptr); /** Calculate spell failure rate for a spell book. */ -extern s32b spell_chance_book(s32b s); +s32b spell_chance_book(s32b s); -extern s32b lua_get_level(struct spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus); -extern int get_mana(s32b s); -extern s32b get_power(s32b s); -extern s32b get_level(s32b s, s32b max, s32b min); -extern void get_level_school(struct spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na); +s32b lua_get_level(struct spell_type *spell, s32b lvl, s32b max, s32b min, s32b bonus); +int get_mana(s32b s); +s32b get_power(s32b s); +s32b get_level(s32b s, s32b max); +s32b get_level_s(int sp, int max); +void get_level_school(struct spell_type *spell, s32b max, s32b min, s32b *level, bool_ *na); extern s32b get_level_max_stick; extern s32b get_level_use_stick; -extern void get_map_size(const char *name, int *ysize, int *xsize); -extern void load_map(const char *name, int *y, int *x); +void get_map_size(const char *name, int *ysize, int *xsize); +void load_map(const char *name, int *y, int *x); -extern char *lua_input_box(cptr title, int max); -extern char lua_msg_box(cptr title); - -extern void increase_mana(int delta); +void increase_mana(int delta); extern timer_type *TIMER_AGGRAVATE_EVIL; diff --git a/src/main-gcu.c b/src/main-gcu.c index c253daf2..ac41272c 100644 --- a/src/main-gcu.c +++ b/src/main-gcu.c @@ -38,12 +38,11 @@ * Consider the use of "savetty()" and "resetty()". XXX XXX XXX */ +#include "main.h" #include "util.h" #include "variable.h" -#ifdef USE_GCU - #include <limits.h> /* @@ -794,7 +793,7 @@ static void hook_quit(cptr str) * * Someone should really check the semantics of "initscr()" */ -errr init_gcu(int argc, char **argv) +int init_gcu(int argc, char **argv) { int i; @@ -1015,7 +1014,12 @@ errr init_gcu(int argc, char **argv) return (0); } - -#endif /* USE_GCU */ - - +int main(int argc, char *argv[]) +{ + return main_real( + argc, + argv, + "gcu", + init_gcu, + " -- -b Requests big screen\n"); +} diff --git a/src/main-gtk2.c b/src/main-gtk2.c index ca3eff60..124802c3 100644 --- a/src/main-gtk2.c +++ b/src/main-gtk2.c @@ -31,16 +31,11 @@ */ #include "files.h" +#include "main.h" #include "util.h" #include "variable.h" -/* - * Activate variant-specific features - */ - -#ifdef USE_GTK2 - /* Force ANSI standard */ /* #define __STRICT_ANSI__ */ @@ -1897,7 +1892,7 @@ static void hook_quit(cptr str) /* * Initialization function */ -errr init_gtk2(int argc, char **argv) +int init_gtk2(int argc, char **argv) { int i; @@ -1974,4 +1969,17 @@ errr init_gtk2(int argc, char **argv) return (0); } -#endif /* USE_GTK2 */ +/** + * Main + */ +int main(int argc, char *argv[]) +{ + return main_real( + argc, + argv, + "gtk2", + init_gtk2, + // Usage: + " -- -n# Number of terms to use\n" + " -- -b Turn off software backing store\n"); +} diff --git a/src/main-sdl.c b/src/main-sdl.c index 9a177cbb..e9aec927 100644 --- a/src/main-sdl.c +++ b/src/main-sdl.c @@ -23,9 +23,8 @@ // in this Software without prior written authorization from the author(s). */ -#ifdef USE_SDL - #include "loadsave.h" +#include "main.h" #include "util.h" #include "variable.h" @@ -1824,7 +1823,7 @@ void dumpWindowSettings(void) /* The main-sdl initialization routine! This routine processes arguments, opens the SDL window, loads fonts, etc. */ -errr init_sdl(int argc, char **argv) +int init_sdl(int argc, char **argv) { int i; char filename[PATH_MAX + 1]; @@ -2097,4 +2096,18 @@ errr init_sdl(int argc, char **argv) return 0; } -#endif +int main(int argc, char *argv[]) +{ + return main_real( + argc, + argv, + "sdl", + init_sdl, + " -- -n # Number of virtual consoles to use\n" + " -- -w # Request screen width in pixels\n" + " -- -h # Request screen height in pixels\n" + " -- -bpp # Request screen color depth in bits\n" + " -- -fs Start with full-screen display\n" + " -- -s # Request font size\n" + " -- -f <font> Request true-type font by name\n"); +} diff --git a/src/main-win.c b/src/main-win.c index a2daffbe..54336a37 100644 --- a/src/main-win.c +++ b/src/main-win.c @@ -74,9 +74,6 @@ #include "util.h" #include "variable.h" -#ifdef WINDOWS - - /* * Extract the "WIN32" flag from the compiler */ @@ -2066,7 +2063,7 @@ static void check_for_save_file(LPSTR cmd_line) game_in_progress = TRUE; /* Play game */ - play_game(FALSE); + play_game(); } @@ -2099,7 +2096,7 @@ static void process_menus(WORD wCmd) { game_in_progress = TRUE; Term_flush(); - play_game(TRUE); + play_game(); quit(NULL); } break; @@ -2138,7 +2135,7 @@ ofn.lStructSize = sizeof(OPENFILENAME); validate_file(savefile); game_in_progress = TRUE; Term_flush(); - play_game(FALSE); + play_game(); quit(NULL); } } @@ -3326,7 +3323,7 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, check_for_save_file(lpCmdLine); game_in_progress = TRUE; - play_game(FALSE); + play_game(); /* Prompt the user */ Term_fresh(); @@ -3349,8 +3346,3 @@ int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, /* Paranoia */ return (0); } - - -#endif /* WINDOWS */ - - diff --git a/src/main-x11.c b/src/main-x11.c index b4b242e5..19d2ac94 100644 --- a/src/main-x11.c +++ b/src/main-x11.c @@ -93,11 +93,10 @@ */ #include "loadsave.h" +#include "main.h" #include "util.h" #include "variable.h" -#ifdef USE_X11 - #ifndef __MAKEDEPEND__ #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -556,7 +555,7 @@ int Term_queue_space(void) * * NB: The keys added here will be interpreted by any macros or keymaps. */ -errr type_string(char *str, uint len) +static errr type_string(char *str, uint len) { char *s; @@ -1741,8 +1740,6 @@ error: XSendEvent(DPY, rq->requestor, FALSE, NoEventMask, &event); } -extern errr type_string(char *str, uint len); - /* * Add the contents of the PRIMARY buffer to the input queue. * @@ -2584,5 +2581,13 @@ errr init_x11(int argc, char *argv[]) return (0); } -#endif /* USE_X11 */ - +int main(int argc, char *argv[]) +{ + return main_real( + argc, + argv, + "x11", + init_x11, + " -- -n# Number of terms to use\n" + " -- -d<name> Display to use\n"); +} diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 680e5c5a..00000000 --- a/src/main.c +++ /dev/null @@ -1,374 +0,0 @@ -/* File: main.c */ - -/* - * Copyright (c) 1997 Ben Harrison, and others - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. - */ - -#include "birth.h" -#include "dungeon.h" -#include "files.h" -#include "init2.h" -#include "modules.h" -#include "script.h" -#include "util.h" -#include "variable.h" - - - -/* - * Some machines have a "main()" function in their "main-xxx.c" file, - * all the others use this file for their "main()" function. - */ - - -#if !defined(WINDOWS) - - -/* - * A hook for "quit()". - * - * Close down, then fall back into "quit()". - */ -static void quit_hook(cptr s) -{ - int j; - - /* Scan windows */ - for (j = 8 - 1; j >= 0; j--) - { - /* Unused */ - if (!angband_term[j]) continue; - - /* Nuke it */ - term_nuke(angband_term[j]); - } -} - - - -/* - * Check existence of ".ToME/" directory in the user's - * home directory or try to create it if it doesn't exist. - * Returns FALSE if all the attempts fail. - */ -static void init_save_dir(void) -{ - char dirpath[1024]; - char versionpath[1024]; - char savepath[1024]; - - /* Get an absolute path from the filename */ - path_parse(dirpath, 1024, PRIVATE_USER_PATH); - strcpy(versionpath, dirpath); - strcat(versionpath, USER_PATH_VERSION); - strcpy(savepath, versionpath); - strcat(savepath, "/save"); - - if (!private_check_user_directory(dirpath)) - { - quit_fmt("Cannot create directory '%s'", dirpath); - } - - if (!private_check_user_directory(versionpath)) - { - quit_fmt("Cannot create directory '%s'", versionpath); - } - - if (!private_check_user_directory(savepath)) - { - quit_fmt("Cannot create directory '%s'", savepath); - } -} - - -static void init_player_name() -{ - /* Get the user id (?) */ - int player_uid = getuid(); - - /* Acquire the "user name" as a default player name */ - user_name(player_name, player_uid); -} - - - -/* - * Simple "main" function for multiple platforms. - * - * Note the special "--" option which terminates the processing of - * standard options. All non-standard options (if any) are passed - * directly to the "init_xxx()" function. - */ -int main(int argc, char *argv[]) -{ - int i; - - bool_ done = FALSE; - - bool_ new_game = FALSE; - - cptr mstr = NULL; - - bool_ args = TRUE; - - /* Get the file paths */ - init_file_paths_with_env(); - - /* Initialize the player name */ - init_player_name(); - - /* Make sure save directory exists */ - init_save_dir(); - - - /* Process the command line arguments */ - for (i = 1; args && (i < argc); i++) - { - /* Require proper options */ - if (argv[i][0] != '-') goto usage; - - /* Analyze option */ - switch (argv[i][1]) - { - case 'N': - case 'n': - { - new_game = TRUE; - break; - } - - case 'W': - case 'w': - { - arg_wizard = TRUE; - break; - } - - case 'R': - case 'r': - { - arg_force_roguelike = TRUE; - break; - } - - case 'O': - case 'o': - { - arg_force_original = TRUE; - break; - } - - case 'u': - case 'U': - { - if (!argv[i][2]) goto usage; - strcpy(player_name, &argv[i][2]); - strcpy(player_base, &argv[i][2]); - no_begin_screen = TRUE; - break; - } - - case 'm': - { - if (!argv[i][2]) goto usage; - mstr = &argv[i][2]; - break; - } - - case 'M': - { - if (!argv[i][2]) goto usage; - force_module = &argv[i][2]; - break; - } - - case 'h': - { - goto usage; - break; - } - - case 'H': - { - char *s; - int j; - - init_lua_init(); - - for (j = i + 1; j < argc; j++) - { - s = argv[j]; - - while (*s != '.') s++; - *s = '\0'; - s++; - txt_to_html("head.aux", "foot.aux", argv[j], s, FALSE, FALSE); - } - - return 0; - } - - case '-': - { - if (argv[i][2] == 'h' && !strcmp((argv[i] + 2), "help")) - goto usage; - else - { - argv[i] = argv[0]; - argc = argc - i; - argv = argv + i; - args = FALSE; - break; - } - } - - default: -usage: - { - int j; - - /* Dump usage information */ - for (j = 0; j < argc; j++) printf("%s ", argv[j]); - printf("\n"); - puts("Usage: tome [options] [-- subopts]"); - puts(" -h This help"); - puts(" -n Start a new character"); - puts(" -w Request wizard mode"); - puts(" -o Request original keyset"); - puts(" -r Request rogue-like keyset"); - puts(" -H <list of files> Convert helpfile to html"); - puts(" -u<who> Use your <who> savefile"); - puts(" -M<which> Use the <which> module"); - puts(" -m<sys> Force 'main-<sys>.c' usage"); - -#ifdef USE_GTK2 - puts(" -mgtk2 To use GTK2"); - puts(" -- Sub options"); - puts(" -- -n# Number of terms to use"); - puts(" -- -b Turn off software backing store"); -#endif /* USE_GTK2 */ - -#ifdef USE_X11 - puts(" -mx11 To use X11"); - puts(" -- Sub options"); - puts(" -- -n# Number of terms to use"); - puts(" -- -d<name> Display to use"); -#endif /* USE_X11 */ - -#ifdef USE_GCU - puts(" -mgcu To use curses"); - puts(" -- Sub options"); - puts(" -- -b Requests big screen"); -#endif /* USE_GCU */ - -#ifdef USE_SDL - puts(" -msdl To use SDL"); - puts(" -- Sub options"); - puts(" -- -n # Number of virtual consoles to use"); - puts(" -- -w # Request screen width in pixels"); - puts(" -- -h # Request screen height in pixels"); - puts(" -- -bpp # Request screen color depth in bits"); - puts(" -- -fs Start with full-screen display"); - puts(" -- -s # Request font size"); - puts(" -- -f <font> Request true-type font by name"); -#endif /* USE_SDL */ - - /* Actually abort the process */ - quit(NULL); - } - } - } - - /* Hack -- Forget standard args */ - if (args) - { - argc = 1; - argv[1] = NULL; - } - - - /* Process the player name */ - process_player_name(TRUE); - - - /* Install "quit" hook */ - quit_aux = quit_hook; - - -#ifdef USE_GTK2 - /* Attempt to use the "main-gtk2.c" support */ - if (!done && (!mstr || (streq(mstr, "gtk2")))) - { - extern errr init_gtk2(int, char**); - if (0 == init_gtk2(argc, argv)) - { - ANGBAND_SYS = "gtk2"; - done = TRUE; - } - } -#endif - -#ifdef USE_X11 - /* Attempt to use the "main-x11.c" support */ - if (!done && (!mstr || (streq(mstr, "x11")))) - { - extern errr init_x11(int, char**); - if (0 == init_x11(argc, argv)) - { - ANGBAND_SYS = "x11"; - done = TRUE; - } - } -#endif - -#ifdef USE_GCU - /* Attempt to use the "main-gcu.c" support */ - if (!done && (!mstr || (streq(mstr, "gcu")))) - { - extern errr init_gcu(int, char**); - if (0 == init_gcu(argc, argv)) - { - ANGBAND_SYS = "gcu"; - done = TRUE; - } - } -#endif - -#ifdef USE_SDL - /* Attempt to use the "main-sdl.c" support */ - if (!done && (!mstr || (streq(mstr, "sdl")))) - { - extern errr init_sdl(int, char**); - if (0 == init_sdl(argc, argv)) - { - ANGBAND_SYS = "sdl"; - done = TRUE; - } - } -#endif - - /* Make sure we have a display! */ - if (!done) quit("Unable to prepare any 'display module'!"); - - - /* Initialize */ - init_angband(); - - /* Wait for response */ - pause_line(23); - - /* Play the game */ - play_game(new_game); - - /* Quit */ - quit(NULL); - - /* Exit */ - return (0); -} - -#endif diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 00000000..c0ac3826 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,270 @@ +/* + * Copyright (c) 1997 Ben Harrison, and others + * + * This software may be copied and distributed for educational, research, + * and not for profit purposes provided that this copyright and statement + * are included in all such copies. + */ + +#include "main.h" + +#include "birth.hpp" +#include "dungeon.h" +#include "files.hpp" +#include "game.hpp" +#include "init2.h" +#include "modules.hpp" +#include "util.h" +#include "util.hpp" +#include "variable.h" +#include "variable.hpp" + + +/* + * A hook for "quit()". + * + * Close down, then fall back into "quit()". + */ +static void quit_hook(cptr s) +{ + int j; + + /* Scan windows */ + for (j = 8 - 1; j >= 0; j--) + { + /* Unused */ + if (!angband_term[j]) continue; + + /* Nuke it */ + term_nuke(angband_term[j]); + } +} + + + +/* + * Check existence of ".ToME/" directory in the user's + * home directory or try to create it if it doesn't exist. + * Returns FALSE if all the attempts fail. + */ +static void init_save_dir() +{ + char dirpath[1024]; + char versionpath[1024]; + char savepath[1024]; + + /* Get an absolute path from the filename */ + path_parse(dirpath, 1024, PRIVATE_USER_PATH); + strcpy(versionpath, dirpath); + strcat(versionpath, USER_PATH_VERSION); + strcpy(savepath, versionpath); + strcat(savepath, "/save"); + + if (!private_check_user_directory(dirpath)) + { + quit_fmt("Cannot create directory '%s'", dirpath); + } + + if (!private_check_user_directory(versionpath)) + { + quit_fmt("Cannot create directory '%s'", versionpath); + } + + if (!private_check_user_directory(savepath)) + { + quit_fmt("Cannot create directory '%s'", savepath); + } +} + +/* + * Initialize and verify the file paths, and the score file. + * + * Use the ANGBAND_PATH environment var if possible, else use + * DEFAULT_PATH, and in either case, branch off appropriately. + * + * First, we'll look for the ANGBAND_PATH environment variable, + * and then look for the files in there. If that doesn't work, + * we'll try the DEFAULT_PATH constant. So be sure that one of + * these two things works... + * + * We must ensure that the path ends with "PATH_SEP" if needed, + * since the "init_file_paths()" function will simply append the + * relevant "sub-directory names" to the given path. + */ +static void init_file_paths_with_env() +{ + char path[1024]; + + /* Get the environment variable */ + cptr tail = getenv("TOME_PATH"); + + /* Use the angband_path, or a default */ + strcpy(path, tail ? tail : DEFAULT_PATH); + + /* Hack -- Add a path separator (only if needed) */ + if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP); + + /* Initialize */ + init_file_paths(path); +} + + +/* + * Simple "main" function for multiple platforms. + * + * Note the special "--" option which terminates the processing of + * standard options. All non-standard options (if any) are passed + * directly to the platform initialization function. + */ +int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platform)(int, char *[]), char const *platform_usage) +{ + int i; + + bool_ args = TRUE; + + // Initialize game structure + game = new Game(); + + /* Get the file paths */ + init_file_paths_with_env(); + + /* Initialize the player name */ + game->player_name = user_name(); + + /* Make sure save directory exists */ + init_save_dir(); + + + /* Process the command line arguments */ + for (i = 1; args && (i < argc); i++) + { + /* Require proper options */ + if (argv[i][0] != '-') goto usage; + + /* Analyze option */ + switch (argv[i][1]) + { + case 'W': + case 'w': + { + arg_wizard = TRUE; + break; + } + + case 'R': + case 'r': + { + arg_force_roguelike = TRUE; + break; + } + + case 'O': + case 'o': + { + arg_force_original = TRUE; + break; + } + + case 'u': + case 'U': + { + if (!argv[i][2]) goto usage; + game->player_name = &argv[i][2]; + game->player_base = &argv[i][2]; + no_begin_screen = TRUE; + break; + } + + case 'M': + { + if (!argv[i][2]) goto usage; + force_module = &argv[i][2]; + break; + } + + case 'h': + { + goto usage; + } + + case '-': + { + if (argv[i][2] == 'h' && !strcmp((argv[i] + 2), "help")) + { + goto usage; + } + else + { + argv[i] = argv[0]; + argc = argc - i; + argv = argv + i; + args = FALSE; + break; + } + } + + default: +usage: + { + int j; + + /* Dump usage information */ + for (j = 0; j < argc; j++) printf("%s ", argv[j]); + printf("\n"); + puts("Usage: tome [options] [-- subopts]"); + puts(" -h This help"); + puts(" -w Request wizard mode"); + puts(" -o Request original keyset"); + puts(" -r Request rogue-like keyset"); + puts(" -u<who> Use your <who> savefile"); + puts(" -M<which> Use the <which> module"); + + puts(" -- Sub options"); + puts(platform_usage); + + /* Actually abort the process */ + quit(NULL); + } + } + } + + /* Hack -- Forget standard args */ + if (args) + { + argc = 1; + argv[1] = NULL; + } + + + /* Process the player name */ + process_player_name(TRUE); + + + /* Install "quit" hook */ + quit_aux = quit_hook; + + /* Run the platform main initialization */ + if (init_platform(argc, argv)) + { + quit("Unable to prepare any 'display module'!"); + } + else + { + ANGBAND_SYS = platform_sys; + + /* Initialize */ + init_angband(); + + /* Wait for response */ + pause_line(23); + + /* Play the game */ + play_game(); + + /* Quit */ + quit(NULL); + + } + /* Exit */ + return (0); +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 00000000..edc590b3 --- /dev/null +++ b/src/main.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int main_real(int argc, char *argv[], char const *platform_sys, int (*init_platform)(int, char *[]), char const *platform_usage); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/src/melee1.cc b/src/melee1.cc index bb4c06d1..58ebfbaa 100644 --- a/src/melee1.cc +++ b/src/melee1.cc @@ -10,11 +10,13 @@ #include "cave.hpp" #include "cmd5.hpp" +#include "game.hpp" #include "gods.hpp" #include "mimic.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" @@ -222,7 +224,9 @@ int get_attack_power(int effect) */ bool_ carried_make_attack_normal(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; int ap_cnt; @@ -230,12 +234,12 @@ bool_ carried_make_attack_normal(int r_idx) int do_cut, do_stun; char ddesc[80] = "your symbiote"; - cptr sym_name = symbiote_name(TRUE); + auto sym_name = symbiote_name(true); - bool_ touched = FALSE, alive = TRUE; + bool_ alive = TRUE; /* Not allowed to attack */ - if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); + if (r_ptr->flags & RF_NEVER_BLOW) return (FALSE); /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; @@ -246,9 +250,6 @@ bool_ carried_make_attack_normal(int r_idx) /* 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; @@ -271,9 +272,6 @@ bool_ carried_make_attack_normal(int r_idx) /* Handle "leaving" */ if (p_ptr->leaving) break; - /* Extract visibility (before blink) */ - visible = TRUE; - /* Extract the attack "power" */ power = get_attack_power(effect); @@ -282,35 +280,16 @@ bool_ carried_make_attack_normal(int r_idx) if (!effect || check_hit(power, rlev)) { /* Always disturbing */ - disturb(1); + disturb(); /* Hack -- Apply "protection from evil" */ if ((p_ptr->protevil > 0) && - (r_ptr->flags3 & (RF3_EVIL)) && + (r_ptr->flags & RF_EVIL) && (p_ptr->lev >= rlev) && ((rand_int(100) + p_ptr->lev) > 50)) { - /* Remember the Evil-ness */ - r_ptr->r_flags3 |= (RF3_EVIL); - /* Message */ - msg_format("%s is repelled.", sym_name); - - /* Hack -- Next attack */ - continue; - } - - /* Hack -- Apply "protection from good" */ - if ((p_ptr->protgood > 0) && - (r_ptr->flags3 & (RF3_GOOD)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Good-ness */ - r_ptr->r_flags3 |= (RF3_GOOD); - - /* Message */ - msg_format("%s is repelled.", sym_name); + msg_format("%s is repelled.", sym_name.c_str()); /* Hack -- Next attack */ continue; @@ -326,43 +305,33 @@ bool_ carried_make_attack_normal(int r_idx) { act = "hits you."; do_cut = do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); break; } case RBM_TOUCH: { act = "touches you."; - touched = TRUE; - sound(SOUND_TOUCH); break; } case RBM_PUNCH: { act = "punches you."; - touched = TRUE; do_stun = 1; - sound(SOUND_HIT); break; } case RBM_KICK: { act = "kicks you."; - touched = TRUE; do_stun = 1; - sound(SOUND_HIT); break; } case RBM_CLAW: { act = "claws you."; - touched = TRUE; do_cut = 1; - sound(SOUND_CLAW); break; } @@ -370,16 +339,12 @@ bool_ carried_make_attack_normal(int r_idx) { act = "bites you."; do_cut = 1; - touched = TRUE; - sound(SOUND_BITE); break; } case RBM_STING: { act = "stings you."; - touched = TRUE; - sound(SOUND_STING); break; } @@ -393,8 +358,6 @@ bool_ carried_make_attack_normal(int r_idx) { act = "butts you."; do_stun = 1; - touched = TRUE; - sound(SOUND_HIT); break; } @@ -402,46 +365,36 @@ bool_ carried_make_attack_normal(int r_idx) { act = "crushes you."; do_stun = 1; - touched = TRUE; - sound(SOUND_CRUSH); break; } case RBM_ENGULF: { act = "engulfs you."; - touched = TRUE; - sound(SOUND_CRUSH); break; } case RBM_CHARGE: { act = "charges you."; - touched = TRUE; - sound(SOUND_BUY); /* Note! This is "charges", not "charges at". */ break; } case RBM_CRAWL: { act = "crawls on you."; - touched = TRUE; - sound(SOUND_SLIME); break; } case RBM_DROOL: { act = "drools on you."; - sound(SOUND_SLIME); break; } case RBM_SPIT: { act = "spits on you."; - sound(SOUND_SLIME); break; } @@ -460,14 +413,12 @@ bool_ carried_make_attack_normal(int r_idx) case RBM_WAIL: { act = "wails at you."; - sound(SOUND_WAIL); break; } case RBM_SPORE: { act = "releases spores at you."; - sound(SOUND_SLIME); break; } @@ -480,21 +431,18 @@ bool_ carried_make_attack_normal(int r_idx) case RBM_BEG: { act = "begs you for money."; - sound(SOUND_MOAN); break; } case RBM_INSULT: { act = desc_insult[rand_int(8)]; - sound(SOUND_MOAN); break; } case RBM_MOAN: { act = desc_moan[rand_int(4)]; - sound(SOUND_MOAN); break; } @@ -504,18 +452,14 @@ bool_ carried_make_attack_normal(int r_idx) act = "sings 'We are a happy family.'"; else act = "sings 'I love you, you love me.'"; - sound(SOUND_SHOW); break; } } /* Message */ - if (act) msg_format("%s %s", sym_name, act); + if (act) msg_format("%s %s", sym_name.c_str(), act); - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side); @@ -524,9 +468,6 @@ bool_ carried_make_attack_normal(int r_idx) { case 0: { - /* Hack -- Assume obvious */ - obvious = TRUE; - /* Hack -- No damage */ damage = 0; @@ -535,9 +476,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_HURT: { - /* Obvious */ - obvious = TRUE; - /* Hack -- Player armor reduces total damage */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); @@ -550,9 +488,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_ABOMINATION: { - /* Obvious */ - obvious = TRUE; - /* Morph, but let mimicry skill have a chance to stop this */ if (magik(60 - get_skill(SKILL_MIMICRY))) { @@ -572,8 +507,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_SANITY: { - obvious = TRUE; - take_sanity_hit(damage, ddesc); break; } @@ -587,10 +520,7 @@ bool_ carried_make_attack_normal(int r_idx) /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } + set_poisoned(p_ptr->poisoned + randint(rlev) + 5); } break; @@ -606,7 +536,7 @@ bool_ carried_make_attack_normal(int r_idx) if (!p_ptr->resist_disen) { /* Apply disenchantment */ - if (apply_disenchant(0)) obvious = TRUE; + apply_disenchant(0); } break; @@ -654,9 +584,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_ACID: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are covered in acid!"); @@ -669,9 +596,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_ELEC: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are struck by electricity!"); @@ -685,9 +609,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_FIRE: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are enveloped in flames!"); @@ -701,9 +622,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_COLD: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are covered with frost!"); @@ -724,10 +642,7 @@ bool_ carried_make_attack_normal(int r_idx) /* Increase "blind" */ if (!p_ptr->resist_blind) { - if (set_blind(p_ptr->blind + 10 + randint(rlev))) - { - obvious = TRUE; - } + set_blind(p_ptr->blind + 10 + randint(rlev)); } @@ -743,10 +658,7 @@ bool_ carried_make_attack_normal(int r_idx) /* Increase "confused" */ if (!p_ptr->resist_conf) { - if (set_confused(p_ptr->confused + 3 + randint(rlev))) - { - obvious = TRUE; - } + set_confused(p_ptr->confused + 3 + randint(rlev)); } @@ -763,19 +675,14 @@ bool_ carried_make_attack_normal(int r_idx) if (p_ptr->resist_fear) { msg_print("You stand your ground!"); - obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You stand your ground!"); - obvious = TRUE; } else { - if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) - { - obvious = TRUE; - } + set_afraid(p_ptr->afraid + 3 + randint(rlev)); } @@ -795,19 +702,14 @@ bool_ carried_make_attack_normal(int r_idx) if (p_ptr->free_act) { msg_print("You are unaffected!"); - obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You resist the effects!"); - obvious = TRUE; } else { - if (set_paralyzed(3 + randint(rlev))) - { - obvious = TRUE; - } + set_paralyzed(3 + randint(rlev)); } @@ -821,7 +723,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_STR, STAT_DEC_NORMAL); break; } @@ -833,7 +735,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_INT, STAT_DEC_NORMAL); break; } @@ -845,7 +747,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_WIS, STAT_DEC_NORMAL); break; } @@ -857,7 +759,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_DEX, STAT_DEC_NORMAL); break; } @@ -869,7 +771,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_CON, STAT_DEC_NORMAL); break; } @@ -881,7 +783,7 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_CHR, STAT_DEC_NORMAL); break; } @@ -893,21 +795,18 @@ bool_ carried_make_attack_normal(int r_idx) take_hit(damage, ddesc); /* Damage (stats) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_DEX, STAT_DEC_NORMAL); + do_dec_stat(A_CON, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_CHR, STAT_DEC_NORMAL); break; } case RBE_SHATTER: { - /* Obvious */ - obvious = TRUE; - /* Hack -- Reduce damage based on the player armor class */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); @@ -928,9 +827,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_EXP_10: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ carried_monster_hit = TRUE; take_hit(damage, ddesc); @@ -958,9 +854,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_EXP_20: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ carried_monster_hit = TRUE; take_hit(damage, ddesc); @@ -988,9 +881,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_EXP_40: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ carried_monster_hit = TRUE; take_hit(damage, ddesc); @@ -1018,9 +908,6 @@ bool_ carried_make_attack_normal(int r_idx) case RBE_EXP_80: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ carried_monster_hit = TRUE; take_hit(damage, ddesc); @@ -1055,10 +942,7 @@ bool_ carried_make_attack_normal(int r_idx) /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } + set_poisoned(p_ptr->poisoned + randint(rlev) + 5); } /* Damage CON (10% chance)*/ @@ -1066,16 +950,13 @@ bool_ carried_make_attack_normal(int r_idx) { /* 1% chance for perm. damage */ bool_ perm = (randint(10) == 1); - if (dec_stat(A_CON, randint(10), perm)) obvious = TRUE; + dec_stat(A_CON, randint(10), perm); } break; } case RBE_PARASITE: { - /* Obvious */ - obvious = TRUE; - if (!p_ptr->parasite) set_parasite(damage, r_idx); break; @@ -1088,10 +969,7 @@ bool_ carried_make_attack_normal(int r_idx) /* Increase "image" */ if (!p_ptr->resist_chaos) { - if (set_image(p_ptr->image + 3 + randint(rlev / 2))) - { - obvious = TRUE; - } + set_image(p_ptr->image + 3 + randint(rlev / 2)); } break; @@ -1222,7 +1100,7 @@ bool_ carried_make_attack_normal(int r_idx) } /* Apply the cut */ - if (k) (void)set_cut(p_ptr->cut + k); + if (k) set_cut(p_ptr->cut + k); } /* Handle stun */ @@ -1263,21 +1141,7 @@ bool_ carried_make_attack_normal(int r_idx) } /* Apply the stun */ - if (k) (void)set_stun(p_ptr->stun + k); - } - - if (touched) - { - if (p_ptr->sh_fire && alive) - { - r_ptr->r_flags3 |= RF3_IM_FIRE; - } - - if (p_ptr->sh_elec && alive) - { - r_ptr->r_flags3 |= RF3_IM_ELEC; - } - touched = FALSE; + if (k) set_stun(p_ptr->stun + k); } } @@ -1301,29 +1165,14 @@ bool_ carried_make_attack_normal(int r_idx) case RBM_CHARGE: /* Disturbing */ - disturb(1); + disturb(); /* Message */ - msg_format("%s misses you.", sym_name); + msg_format("%s misses you.", sym_name.c_str()); 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]++; - } - } - } } /* Assume we attacked */ return (TRUE); @@ -1335,7 +1184,7 @@ bool_ carried_make_attack_normal(int r_idx) */ void black_breath_attack(int chance) { - if (!p_ptr->protundead && randint(chance) == 1) + if (randint(chance) == 1) { msg_print("Your foe calls upon your soul!"); msg_print("You feel the Black Breath slowly draining you of life..."); @@ -1353,7 +1202,7 @@ bool_ make_attack_normal(int m_idx, byte divis) int ap_cnt; int i, j, k, tmp, ac, rlev; - int do_cut, do_stun, do_vampire; + int do_cut, do_stun; s32b gold; @@ -1371,7 +1220,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Not allowed to attack? */ auto r_ptr = m_ptr->race(); - if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); + if (r_ptr->flags & RF_NEVER_BLOW) return (FALSE); /* ...nor if friendly */ if (is_friend(m_ptr) >= 0) @@ -1381,7 +1230,7 @@ bool_ make_attack_normal(int m_idx, byte divis) } /* Cannot attack the player if mortal and player fated to never die by the ... */ - if ((r_ptr->flags7 & RF7_MORTAL) && (p_ptr->no_mortal)) return (FALSE); + if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return (FALSE); /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; @@ -1403,9 +1252,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* 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; @@ -1428,9 +1274,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Handle "leaving" */ if (p_ptr->leaving) break; - /* Extract visibility (before blink) */ - if (m_ptr->ml) visible = TRUE; - /* Extract the attack "power" */ switch (effect) { @@ -1545,7 +1388,7 @@ bool_ make_attack_normal(int m_idx, byte divis) int chance = p_ptr->dodge_chance - ((rlev * 5) / 6); /* Always disturbing */ - disturb(1); + disturb(); if ((chance > 0) && magik(chance)) { @@ -1563,11 +1406,8 @@ bool_ make_attack_normal(int m_idx, byte divis) if (chance > 50000) chance = 50000; chance -= rlev * 300; - if ((randint(100000) < chance) && (r_ptr->flags3 & (RF3_EVIL))) + if ((randint(100000) < chance) && (r_ptr->flags & RF_EVIL)) { - /* Remember the Evil-ness */ - r_ptr->r_flags3 |= (RF3_EVIL); - /* Message */ msg_format("The hand of Eru Iluvatar stops %s blow.", m_name); @@ -1578,35 +1418,10 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Hack -- Apply "protection from evil" */ if ((p_ptr->protevil > 0) && - (r_ptr->flags3 & (RF3_EVIL)) && + (r_ptr->flags & RF_EVIL) && (p_ptr->lev >= rlev) && ((rand_int(100) + p_ptr->lev) > 50)) { - /* Remember the Evil-ness */ - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_EVIL); - } - - /* Message */ - msg_format("%^s is repelled.", m_name); - - /* Hack -- Next attack */ - continue; - } - - /* Hack -- Apply "protection from good" */ - if ((p_ptr->protgood > 0) && - (r_ptr->flags3 & (RF3_GOOD)) && - (p_ptr->lev >= rlev) && - ((rand_int(100) + p_ptr->lev) > 50)) - { - /* Remember the Good-ness */ - if (m_ptr->ml) - { - r_ptr->r_flags3 |= (RF3_GOOD); - } - /* Message */ msg_format("%^s is repelled.", m_name); @@ -1615,7 +1430,7 @@ bool_ make_attack_normal(int m_idx, byte divis) } /* Assume no cut or stun */ - do_cut = do_stun = do_vampire = 0; + do_cut = do_stun = 0; /* Describe the attack method */ switch (method) @@ -1625,7 +1440,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "hits you."; do_cut = do_stun = 1; touched = TRUE; - sound(SOUND_HIT); break; } @@ -1633,7 +1447,6 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "touches you."; touched = TRUE; - sound(SOUND_TOUCH); break; } @@ -1642,7 +1455,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "punches you."; touched = TRUE; do_stun = 1; - sound(SOUND_HIT); break; } @@ -1651,7 +1463,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "kicks you."; touched = TRUE; do_stun = 1; - sound(SOUND_HIT); break; } @@ -1660,7 +1471,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "claws you."; touched = TRUE; do_cut = 1; - sound(SOUND_CLAW); break; } @@ -1668,10 +1478,7 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "bites you."; do_cut = 1; - if (magik(5) && iequals(r_ptr->name, "vampire")) - do_vampire = TRUE; touched = TRUE; - sound(SOUND_BITE); break; } @@ -1679,7 +1486,6 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "stings you."; touched = TRUE; - sound(SOUND_STING); break; } @@ -1694,7 +1500,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "butts you."; do_stun = 1; touched = TRUE; - sound(SOUND_HIT); break; } @@ -1703,7 +1508,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "crushes you."; do_stun = 1; touched = TRUE; - sound(SOUND_CRUSH); break; } @@ -1711,7 +1515,6 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "engulfs you."; touched = TRUE; - sound(SOUND_CRUSH); break; } @@ -1719,7 +1522,6 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "charges you."; touched = TRUE; - sound(SOUND_BUY); /* Note! This is "charges", not "charges at". */ break; } @@ -1727,21 +1529,18 @@ bool_ make_attack_normal(int m_idx, byte divis) { act = "crawls on you."; touched = TRUE; - sound(SOUND_SLIME); break; } case RBM_DROOL: { act = "drools on you."; - sound(SOUND_SLIME); break; } case RBM_SPIT: { act = "spits on you."; - sound(SOUND_SLIME); break; } @@ -1761,14 +1560,12 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBM_WAIL: { act = "wails at you."; - sound(SOUND_WAIL); break; } case RBM_SPORE: { act = "releases spores at you."; - sound(SOUND_SLIME); break; } @@ -1781,14 +1578,12 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBM_BEG: { act = "begs you for money."; - sound(SOUND_MOAN); break; } case RBM_INSULT: { act = desc_insult[rand_int(8)]; - sound(SOUND_MOAN); break; } @@ -1798,7 +1593,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = desc_moan[rand_int(3) + 4]; else act = desc_moan[rand_int(4)]; - sound(SOUND_MOAN); break; } @@ -1808,7 +1602,6 @@ bool_ make_attack_normal(int m_idx, byte divis) act = "sings 'We are a happy family.'"; else act = "sings 'I love you, you love me.'"; - sound(SOUND_SHOW); break; } } @@ -1820,23 +1613,20 @@ bool_ make_attack_normal(int m_idx, byte divis) * a successful blow. Uniques have a better chance. -LM- * Nazgul have a 25% chance */ - if (r_ptr->flags7 & RF7_NAZGUL) + if (r_ptr->flags & RF_NAZGUL) { black_breath_attack(4); } - else if ((m_ptr->level >= 35) && (r_ptr->flags3 & (RF3_UNDEAD)) && - (r_ptr->flags1 & (RF1_UNIQUE))) + else if ((m_ptr->level >= 35) && (r_ptr->flags & RF_UNDEAD) && + (r_ptr->flags & RF_UNIQUE)) { black_breath_attack(300 - m_ptr->level); } - else if ((m_ptr->level >= 40) && (r_ptr->flags3 & (RF3_UNDEAD))) + else if ((m_ptr->level >= 40) && (r_ptr->flags & RF_UNDEAD)) { black_breath_attack(450 - m_ptr->level); } - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side); @@ -1848,9 +1638,6 @@ bool_ make_attack_normal(int m_idx, byte divis) { case 0: { - /* Hack -- Assume obvious */ - obvious = TRUE; - /* Hack -- No damage */ damage = 0; @@ -1859,9 +1646,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_HURT: { - /* Obvious */ - obvious = TRUE; - /* Hack -- Player armor reduces total damage */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); @@ -1873,9 +1657,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_ABOMINATION: { - /* Obvious */ - obvious = TRUE; - /* Morph, but let mimicry skill have a chance to stop this */ if (magik(60 - get_skill(SKILL_MIMICRY))) { @@ -1895,8 +1676,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_SANITY: { - obvious = TRUE; - take_sanity_hit(damage, ddesc); break; } @@ -1909,10 +1688,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } + set_poisoned(p_ptr->poisoned + randint(rlev) + 5); } /* Learn about the player */ @@ -1929,8 +1705,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Allow complete resist */ if (!p_ptr->resist_disen) { - /* Apply disenchantment */ - if (apply_disenchant(0)) obvious = TRUE; + apply_disenchant(0); } /* Learn about the player */ @@ -1966,9 +1741,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Message */ msg_print("Energy drains from your pack!"); - /* Obvious */ - obvious = TRUE; - /* Heal */ j = rlev; m_ptr->hp += j * o_ptr->pval * o_ptr->number; @@ -1999,9 +1771,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Take some damage */ take_hit(damage, ddesc); - /* Obvious */ - obvious = TRUE; - /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + @@ -2084,9 +1853,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Occasional "blink" anyway */ blinked = TRUE; - /* Obvious */ - obvious = TRUE; - /* Done */ break; } @@ -2104,7 +1870,7 @@ bool_ make_attack_normal(int m_idx, byte divis) if (!o_ptr->k_idx) continue; /* Skip artifacts */ - if (artifact_p(o_ptr) || o_ptr->art_name) continue; + if (artifact_p(o_ptr)) continue; /* Get a description */ object_desc(o_name, o_ptr, FALSE, 3); @@ -2159,9 +1925,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Steal the items */ inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - /* Obvious */ - obvious = TRUE; - /* Blink away */ blinked = TRUE; @@ -2203,9 +1966,6 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Steal the items */ inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - /* Obvious */ - obvious = TRUE; - /* Done */ break; } @@ -2232,7 +1992,6 @@ bool_ make_attack_normal(int m_idx, byte divis) if (!p_ptr->blind) { msg_print("Your light dims."); - obvious = TRUE; } /* Window stuff */ @@ -2244,9 +2003,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_ACID: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are covered in acid!"); @@ -2261,9 +2017,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_ELEC: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are struck by electricity!"); @@ -2278,9 +2031,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_FIRE: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are enveloped in flames!"); @@ -2295,9 +2045,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_COLD: { - /* Obvious */ - obvious = TRUE; - /* Message */ msg_print("You are covered with frost!"); @@ -2318,10 +2065,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Increase "blind" */ if (!p_ptr->resist_blind) { - if (set_blind(p_ptr->blind + 10 + randint(rlev))) - { - obvious = TRUE; - } + set_blind(p_ptr->blind + 10 + randint(rlev)); } /* Learn about the player */ @@ -2338,10 +2082,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Increase "confused" */ if (!p_ptr->resist_conf) { - if (set_confused(p_ptr->confused + 3 + randint(rlev))) - { - obvious = TRUE; - } + set_confused(p_ptr->confused + 3 + randint(rlev)); } /* Learn about the player */ @@ -2359,19 +2100,14 @@ bool_ make_attack_normal(int m_idx, byte divis) if (p_ptr->resist_fear) { msg_print("You stand your ground!"); - obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You stand your ground!"); - obvious = TRUE; } else { - if (set_afraid(p_ptr->afraid + 3 + randint(rlev))) - { - obvious = TRUE; - } + set_afraid(p_ptr->afraid + 3 + randint(rlev)); } /* Learn about the player */ @@ -2392,19 +2128,14 @@ bool_ make_attack_normal(int m_idx, byte divis) if (p_ptr->free_act) { msg_print("You are unaffected!"); - obvious = TRUE; } else if (rand_int(100) < p_ptr->skill_sav) { msg_print("You resist the effects!"); - obvious = TRUE; } else { - if (set_paralyzed(3 + randint(rlev))) - { - obvious = TRUE; - } + set_paralyzed(3 + randint(rlev)); } /* Learn about the player */ @@ -2419,7 +2150,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_STR, STAT_DEC_NORMAL); break; } @@ -2430,7 +2161,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_INT, STAT_DEC_NORMAL); break; } @@ -2441,7 +2172,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_WIS, STAT_DEC_NORMAL); break; } @@ -2452,7 +2183,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_DEX, STAT_DEC_NORMAL); break; } @@ -2463,7 +2194,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_CON, STAT_DEC_NORMAL); break; } @@ -2474,7 +2205,7 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stat) */ - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_CHR, STAT_DEC_NORMAL); break; } @@ -2485,21 +2216,18 @@ bool_ make_attack_normal(int m_idx, byte divis) take_hit(damage, ddesc); /* Damage (stats) */ - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) obvious = TRUE; - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) obvious = TRUE; + do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_DEX, STAT_DEC_NORMAL); + do_dec_stat(A_CON, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_CHR, STAT_DEC_NORMAL); break; } case RBE_SHATTER: { - /* Obvious */ - obvious = TRUE; - /* Hack -- Reduce damage based on the player armor class */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); @@ -2519,9 +2247,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_EXP_10: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ take_hit(damage, ddesc); @@ -2548,9 +2273,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_EXP_20: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ take_hit(damage, ddesc); @@ -2577,9 +2299,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_EXP_40: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ take_hit(damage, ddesc); @@ -2606,9 +2325,6 @@ bool_ make_attack_normal(int m_idx, byte divis) case RBE_EXP_80: { - /* Obvious */ - obvious = TRUE; - /* Take damage */ take_hit(damage, ddesc); @@ -2641,10 +2357,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Take "poison" effect */ if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) { - if (set_poisoned(p_ptr->poisoned + randint(rlev) + 5)) - { - obvious = TRUE; - } + set_poisoned(p_ptr->poisoned + randint(rlev) + 5); } /* Damage CON (10% chance)*/ @@ -2652,7 +2365,7 @@ bool_ make_attack_normal(int m_idx, byte divis) { /* 1% chance for perm. damage */ bool_ perm = (randint(10) == 1); - if (dec_stat(A_CON, randint(10), perm)) obvious = TRUE; + dec_stat(A_CON, randint(10), perm); } break; @@ -2665,10 +2378,7 @@ bool_ make_attack_normal(int m_idx, byte divis) /* Increase "image" */ if (!p_ptr->resist_chaos) { - if (set_image(p_ptr->image + 3 + randint(rlev / 2))) - { - obvious = TRUE; - } + set_image(p_ptr->image + 3 + randint(rlev / 2)); } /* Learn about the player */ @@ -2747,9 +2457,6 @@ bool_ make_attack_normal(int m_idx, byte divis) } case RBE_PARASITE: { - /* Obvious */ - obvious = TRUE; - if (!p_ptr->parasite) set_parasite(damage, m_ptr->r_idx); break; @@ -2811,7 +2518,7 @@ bool_ make_attack_normal(int m_idx, byte divis) } /* Apply the cut */ - if (k) (void)set_cut(p_ptr->cut + k); + if (k) set_cut(p_ptr->cut + k); } /* Handle stun */ @@ -2852,20 +2559,11 @@ bool_ make_attack_normal(int m_idx, byte divis) } /* Apply the stun */ - if (k) (void)set_stun(p_ptr->stun + k); - } - - /* Do vampiric thingies */ - if (do_vampire) - { - /* Change to resist(but never total protection) */ -/* if (magik(3) || (magik(m_ptr->level - (p_ptr->lev / 2)))) - gain_corruption("Vampire");*/ + if (k) set_stun(p_ptr->stun + k); } if (explode) { - sound(SOUND_EXPLODE); if (mon_take_hit(m_idx, m_ptr->hp + 1, &fear, NULL)) { blinked = FALSE; @@ -2877,7 +2575,7 @@ bool_ make_attack_normal(int m_idx, byte divis) { if (p_ptr->sh_fire && alive) { - if (!(r_ptr->flags3 & RF3_IM_FIRE)) + if (!(r_ptr->flags & RF_IM_FIRE)) { msg_format("%^s is suddenly very hot!", m_name); if (mon_take_hit(m_idx, damroll(2, 6), &fear, @@ -2887,16 +2585,11 @@ bool_ make_attack_normal(int m_idx, byte divis) alive = FALSE; } } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_FIRE; - } } if (p_ptr->sh_elec && alive) { - if (!(r_ptr->flags3 & RF3_IM_ELEC)) + if (!(r_ptr->flags & RF_IM_ELEC)) { msg_format("%^s gets zapped!", m_name); if (mon_take_hit(m_idx, damroll(2, 6), &fear, @@ -2906,12 +2599,8 @@ bool_ make_attack_normal(int m_idx, byte divis) alive = FALSE; } } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_ELEC; - } } + if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_COUNTER) && alive) { msg_format("%^s gets bashed by your mystic shield!", m_name); @@ -2922,9 +2611,10 @@ bool_ make_attack_normal(int m_idx, byte divis) alive = FALSE; } } + if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_FIRE) && alive) { - if (!(r_ptr->flags3 & RF3_IM_FIRE)) + if (!(r_ptr->flags & RF_IM_FIRE)) { msg_format("%^s gets burned by your fiery shield!", m_name); if (mon_take_hit(m_idx, damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2), &fear, @@ -2934,12 +2624,8 @@ bool_ make_attack_normal(int m_idx, byte divis) alive = FALSE; } } - else - { - if (m_ptr->ml) - r_ptr->r_flags3 |= RF3_IM_FIRE; - } } + if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_GREAT_FIRE) && alive) { msg_format("%^s gets burned by your fiery shield!", m_name); @@ -2950,11 +2636,12 @@ bool_ make_attack_normal(int m_idx, byte divis) alive = FALSE; } } + if (p_ptr->shield && (p_ptr->shield_opt & SHIELD_FEAR) && alive) { int tmp; - if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2) - m_ptr->level > 0)) + if ((!(r_ptr->flags & RF_UNIQUE)) && (damroll(p_ptr->shield_power_opt, p_ptr->shield_power_opt2) - m_ptr->level > 0)) { msg_format("%^s gets scared away!", m_name); @@ -2994,7 +2681,7 @@ bool_ make_attack_normal(int m_idx, byte divis) if (m_ptr->ml) { /* Disturbing */ - disturb(1); + disturb(); /* Message */ msg_format("%^s misses you.", m_name); @@ -3003,21 +2690,6 @@ bool_ make_attack_normal(int m_idx, byte divis) 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]++; - } - } - } } @@ -3028,16 +2700,9 @@ bool_ make_attack_normal(int m_idx, byte divis) teleport_away(m_idx, MAX_SIGHT * 2 + 5); } - - /* Always notice cause of death */ - if (death && (r_ptr->r_deaths < MAX_SHORT)) - { - r_ptr->r_deaths++; - } - + /* Fear */ if (m_ptr->ml && fear) { - sound (SOUND_FLEE); msg_format("%^s flees in terror!", m_name); } diff --git a/src/melee1.hpp b/src/melee1.hpp index e84c8f03..90ece431 100644 --- a/src/melee1.hpp +++ b/src/melee1.hpp @@ -2,6 +2,6 @@ #include "h-basic.h" -extern int get_attack_power(int effect); -extern bool_ carried_make_attack_normal(int r_idx); -extern bool_ make_attack_normal(int m_idx, byte divis); +int get_attack_power(int effect); +bool_ carried_make_attack_normal(int r_idx); +bool_ make_attack_normal(int m_idx, byte divis); diff --git a/src/melee2.cc b/src/melee2.cc index b3aa5c61..d769355a 100644 --- a/src/melee2.cc +++ b/src/melee2.cc @@ -16,8 +16,11 @@ #include "cave.hpp" #include "cave_type.hpp" #include "cmd1.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hook_mon_speak_in.hpp" #include "hook_monster_ai_in.hpp" #include "hook_monster_ai_out.hpp" @@ -27,18 +30,20 @@ #include "monster2.hpp" #include "monster3.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell.hpp" +#include "monster_spell_flag.hpp" #include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "options.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "skills.hpp" #include "spells1.hpp" #include "spells2.hpp" #include "stats.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "variable.hpp" #include "xtra2.hpp" @@ -51,7 +56,6 @@ #define FOLLOW_DISTANCE 6 -static void cmonster_msg(char a, cptr fmt, ...); /* * Based on mon_take_hit... all monster attacks on @@ -61,12 +65,34 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note) { monster_type *m_ptr = &m_list[m_idx], *s_ptr = &m_list[s_idx]; + /* Output */ + auto cmonster_msg = [m_ptr](std::string const &suffix) { + auto &messages = game->messages; + // Build monster name + char m_name[80]; + monster_desc(m_name, m_ptr, 0); + capitalize(m_name); + // Add suffix + auto msg = std::string(m_name); + msg += suffix; + // Display + if (options->disturb_other) + { + cmsg_print(TERM_L_RED, msg); + } + else + { + messages.add(msg, TERM_L_RED); + p_ptr->window |= PW_MESSAGE; + } + }; + /* Redraw (later) if needed */ if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME); /* Some monsters are immune to death */ auto const r_ptr = m_ptr->race(); - if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE; + if (r_ptr->flags & RF_NO_DEATH) return FALSE; /* Wake it up */ m_ptr->csleep = 0; @@ -77,39 +103,24 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note) /* It is dead now... or is it? */ if (m_ptr->hp < 0) { - if (((r_ptr->flags1 & RF1_UNIQUE) && (m_ptr->status <= MSTATUS_NEUTRAL_P)) || + if (((r_ptr->flags & RF_UNIQUE) && (m_ptr->status <= MSTATUS_NEUTRAL_P)) || (m_ptr->mflag & MFLAG_QUEST)) { m_ptr->hp = 1; } else { - char m_name[80]; s32b dive = s_ptr->level; - if (!dive) dive = 1; - - /* Extract monster name */ - monster_desc(m_name, m_ptr, 0); - - /* Make a sound */ - if ((r_ptr->flags3 & RF3_DEMON) || - (r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags2 & RF2_STUPID) || - (r_ptr->flags3 & RF3_NONLIVING) || - (strchr("Evg", r_ptr->d_char))) - { - sound(SOUND_N_KILL); - } - else + if (!dive) { - sound(SOUND_KILL); + dive = 1; } /* Death by Missile/Spell attack */ if (note) { - cmonster_msg(TERM_L_RED, "%^s%s", m_name, note); + cmonster_msg(note); } /* Death by Physical attack -- living monster */ else if (!m_ptr->ml) @@ -117,17 +128,17 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note) /* Do nothing */ } /* Death by Physical attack -- non-living monster */ - else if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || - (r_ptr->flags3 & (RF3_NONLIVING)) || + else if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || + (r_ptr->flags & RF_NONLIVING) || (strchr("Evg", r_ptr->d_char))) { - cmonster_msg(TERM_L_RED, "%^s is destroyed.", m_name); + cmonster_msg(" is destroyed."); } else { - cmonster_msg(TERM_L_RED, "%^s is killed.", m_name); + cmonster_msg(" is killed."); } dive = r_ptr->mexp * m_ptr->level / dive; @@ -171,7 +182,7 @@ bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note) } /* When an Unique dies, it stays dead */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { r_ptr->max_num = 0; } @@ -228,7 +239,7 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear) /* Sometimes a monster gets scared by damage */ auto const r_ptr = m_ptr->race(); - if (!m_ptr->monfear && !(r_ptr->flags3 & (RF3_NO_FEAR))) + if (!m_ptr->monfear && !(r_ptr->flags & RF_NO_FEAR)) { int percentage; @@ -289,7 +300,7 @@ void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear) static bool_ int_outof(std::shared_ptr<monster_race> r_ptr, int prob) { /* Non-Smart monsters are half as "smart" */ - if (!(r_ptr->flags2 & (RF2_SMART))) prob = prob / 2; + if (!(r_ptr->flags & RF_SMART)) prob = prob / 2; /* Roll the dice */ return (rand_int(100) < prob); @@ -300,36 +311,32 @@ static bool_ int_outof(std::shared_ptr<monster_race> r_ptr, int prob) /* * Remove the "bad" spells from a spell list */ -static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p) +static void remove_bad_spells(int m_idx, monster_spell_flag_set *spells_p) { monster_type *m_ptr = &m_list[m_idx]; - - u32b f4 = (*f4p); - u32b f5 = (*f5p); - u32b f6 = (*f6p); - u32b smart = 0L; + // Shorthand + auto spells(*spells_p); /* Too stupid to know anything? */ auto const r_ptr = m_ptr->race(); - if (r_ptr->flags2 & (RF2_STUPID)) return; - + if (r_ptr->flags & RF_STUPID) + { + return; + } /* Must be cheating or learning */ - if (!smart_learn) return; - - - /* Update acquired knowledge */ - if (smart_learn) + if (!options->smart_learn) { - /* Hack -- Occasionally forget player status */ - if (m_ptr->smart && magik(1)) m_ptr->smart = 0L; - - /* Use the memorized flags */ - smart = m_ptr->smart; + return; } + /* Hack -- Occasionally forget player status */ + if (m_ptr->smart && magik(1)) m_ptr->smart = 0L; + + /* Use the memorized flags */ + smart = m_ptr->smart; /* Nothing known */ if (!smart) return; @@ -337,201 +344,199 @@ static void remove_bad_spells(int m_idx, u32b *f4p, u32b *f5p, u32b *f6p) if (smart & (SM_IMM_ACID)) { - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_BR_ACID); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BA_ACID); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ACID); + if (int_outof(r_ptr, 100)) spells &= ~SF_BR_ACID; + if (int_outof(r_ptr, 100)) spells &= ~SF_BA_ACID; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ACID; } else if ((smart & (SM_OPP_ACID)) && (smart & (SM_RES_ACID))) { - if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ACID); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ACID); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ACID); + if (int_outof(r_ptr, 80)) spells &= ~SF_BR_ACID; + if (int_outof(r_ptr, 80)) spells &= ~SF_BA_ACID; + if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ACID; } else if ((smart & (SM_OPP_ACID)) || (smart & (SM_RES_ACID))) { - if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ACID); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ACID); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ACID); + if (int_outof(r_ptr, 30)) spells &= ~SF_BR_ACID; + if (int_outof(r_ptr, 30)) spells &= ~SF_BA_ACID; + if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ACID; } if (smart & (SM_IMM_ELEC)) { - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_BR_ELEC); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BA_ELEC); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ELEC); + if (int_outof(r_ptr, 100)) spells &= ~SF_BR_ELEC; + if (int_outof(r_ptr, 100)) spells &= ~SF_BA_ELEC; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ELEC; } else if ((smart & (SM_OPP_ELEC)) && (smart & (SM_RES_ELEC))) { - if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_ELEC); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_ELEC); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ELEC); + if (int_outof(r_ptr, 80)) spells &= ~SF_BR_ELEC; + if (int_outof(r_ptr, 80)) spells &= ~SF_BA_ELEC; + if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ELEC; } else if ((smart & (SM_OPP_ELEC)) || (smart & (SM_RES_ELEC))) { - if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_ELEC); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_ELEC); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ELEC); + if (int_outof(r_ptr, 30)) spells &= ~SF_BR_ELEC; + if (int_outof(r_ptr, 30)) spells &= ~SF_BA_ELEC; + if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ELEC; } if (smart & (SM_IMM_FIRE)) { - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_BR_FIRE); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BA_FIRE); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_FIRE); + if (int_outof(r_ptr, 100)) spells &= ~SF_BR_FIRE; + if (int_outof(r_ptr, 100)) spells &= ~SF_BA_FIRE; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_FIRE; } else if ((smart & (SM_OPP_FIRE)) && (smart & (SM_RES_FIRE))) { - if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_FIRE); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_FIRE); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_FIRE); + if (int_outof(r_ptr, 80)) spells &= ~SF_BR_FIRE; + if (int_outof(r_ptr, 80)) spells &= ~SF_BA_FIRE; + if (int_outof(r_ptr, 80)) spells &= ~SF_BO_FIRE; } else if ((smart & (SM_OPP_FIRE)) || (smart & (SM_RES_FIRE))) { - if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_FIRE); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_FIRE); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_FIRE); + if (int_outof(r_ptr, 30)) spells &= ~SF_BR_FIRE; + if (int_outof(r_ptr, 30)) spells &= ~SF_BA_FIRE; + if (int_outof(r_ptr, 30)) spells &= ~SF_BO_FIRE; } if (smart & (SM_IMM_COLD)) { - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_BR_COLD); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BA_COLD); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_COLD); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ICEE); + if (int_outof(r_ptr, 100)) spells &= ~SF_BR_COLD; + if (int_outof(r_ptr, 100)) spells &= ~SF_BA_COLD; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_COLD; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ICEE; } else if ((smart & (SM_OPP_COLD)) && (smart & (SM_RES_COLD))) { - if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_COLD); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_COLD); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_COLD); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BO_ICEE); + if (int_outof(r_ptr, 80)) spells &= ~SF_BR_COLD; + if (int_outof(r_ptr, 80)) spells &= ~SF_BA_COLD; + if (int_outof(r_ptr, 80)) spells &= ~SF_BO_COLD; + if (int_outof(r_ptr, 80)) spells &= ~SF_BO_ICEE; } else if ((smart & (SM_OPP_COLD)) || (smart & (SM_RES_COLD))) { - if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_COLD); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_COLD); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_COLD); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BO_ICEE); + if (int_outof(r_ptr, 30)) spells &= ~SF_BR_COLD; + if (int_outof(r_ptr, 30)) spells &= ~SF_BA_COLD; + if (int_outof(r_ptr, 30)) spells &= ~SF_BO_COLD; + if (int_outof(r_ptr, 30)) spells &= ~SF_BO_ICEE; } if ((smart & (SM_OPP_POIS)) && (smart & (SM_RES_POIS))) { - if (int_outof(r_ptr, 80)) f4 &= ~(RF4_BR_POIS); - if (int_outof(r_ptr, 80)) f5 &= ~(RF5_BA_POIS); - if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BA_NUKE); - if (int_outof(r_ptr, 40)) f4 &= ~(RF4_BR_NUKE); + if (int_outof(r_ptr, 80)) spells &= ~SF_BR_POIS; + if (int_outof(r_ptr, 80)) spells &= ~SF_BA_POIS; + if (int_outof(r_ptr, 40)) spells &= ~SF_BA_NUKE; + if (int_outof(r_ptr, 40)) spells &= ~SF_BR_NUKE; } else if ((smart & (SM_OPP_POIS)) || (smart & (SM_RES_POIS))) { - if (int_outof(r_ptr, 30)) f4 &= ~(RF4_BR_POIS); - if (int_outof(r_ptr, 30)) f5 &= ~(RF5_BA_POIS); + if (int_outof(r_ptr, 30)) spells &= ~SF_BR_POIS; + if (int_outof(r_ptr, 30)) spells &= ~SF_BA_POIS; } if (smart & (SM_RES_NETH)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_NETH); - if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_NETH); - if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BO_NETH); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_NETH; + if (int_outof(r_ptr, 50)) spells &= ~SF_BA_NETH; + if (int_outof(r_ptr, 50)) spells &= ~SF_BO_NETH; } if (smart & (SM_RES_LITE)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_LITE); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_LITE; } if (smart & (SM_RES_DARK)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_DARK); - if (int_outof(r_ptr, 50)) f5 &= ~(RF5_BA_DARK); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_DARK; + if (int_outof(r_ptr, 50)) spells &= ~SF_BA_DARK; } if (smart & (SM_RES_FEAR)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_SCARE); + if (int_outof(r_ptr, 100)) spells &= ~SF_SCARE; } if (smart & (SM_RES_CONF)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_CONF); - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_CONF); + if (int_outof(r_ptr, 100)) spells &= ~SF_CONF; + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CONF; } if (smart & (SM_RES_CHAOS)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_CONF); - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_CONF); - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_CHAO); - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BA_CHAO); + if (int_outof(r_ptr, 100)) spells &= ~SF_CONF; + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CONF; + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_CHAO; + if (int_outof(r_ptr, 50)) spells &= ~SF_BA_CHAO; } if (smart & (SM_RES_DISEN)) { - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_BR_DISE); + if (int_outof(r_ptr, 100)) spells &= ~SF_BR_DISE; } if (smart & (SM_RES_BLIND)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BLIND); + if (int_outof(r_ptr, 100)) spells &= ~SF_BLIND; } if (smart & (SM_RES_NEXUS)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_NEXU); - if (int_outof(r_ptr, 50)) f6 &= ~(RF6_TELE_LEVEL); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_NEXU; + if (int_outof(r_ptr, 50)) spells &= ~SF_TELE_LEVEL; } if (smart & (SM_RES_SOUND)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_SOUN); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_SOUN; } if (smart & (SM_RES_SHARD)) { - if (int_outof(r_ptr, 50)) f4 &= ~(RF4_BR_SHAR); - if (int_outof(r_ptr, 20)) f4 &= ~(RF4_ROCKET); + if (int_outof(r_ptr, 50)) spells &= ~SF_BR_SHAR; + if (int_outof(r_ptr, 20)) spells &= ~SF_ROCKET; } if (smart & (SM_IMM_REFLECT)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_COLD); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_FIRE); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ACID); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ELEC); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_POIS); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_NETH); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_WATE); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_MANA); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_PLAS); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_BO_ICEE); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_MISSILE); - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_1); - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_2); - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_3); - if (int_outof(r_ptr, 100)) f4 &= ~(RF4_ARROW_4); + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_COLD; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_FIRE; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ACID; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ELEC; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_POIS; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_NETH; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_WATE; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_MANA; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_PLAS; + if (int_outof(r_ptr, 100)) spells &= ~SF_BO_ICEE; + if (int_outof(r_ptr, 100)) spells &= ~SF_MISSILE; + if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_1); + if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_2); + if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_3); + if (int_outof(r_ptr, 100)) spells &= ~(SF_ARROW_4); } if (smart & (SM_IMM_FREE)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_HOLD); - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_SLOW); + if (int_outof(r_ptr, 100)) spells &= ~SF_HOLD; + if (int_outof(r_ptr, 100)) spells &= ~SF_SLOW; } if (smart & (SM_IMM_MANA)) { - if (int_outof(r_ptr, 100)) f5 &= ~(RF5_DRAIN_MANA); + if (int_outof(r_ptr, 100)) spells &= ~SF_DRAIN_MANA; } /* XXX XXX XXX No spells left? */ /* if (!f4 && !f5 && !f6) ... */ - (*f4p) = f4; - (*f5p) = f5; - (*f6p) = f6; + *spells_p = spells; } @@ -622,122 +627,75 @@ static void bolt(int m_idx, int typ, int dam_hp) int flg = PROJECT_STOP | PROJECT_KILL; /* Target the player with a bolt attack */ - (void)project(m_idx, 0, p_ptr->py, p_ptr->px, dam_hp, typ, flg); -} - - -/* - * Return TRUE if a spell is good for hurting the player (directly). - */ -static bool_ spell_attack(byte spell) -{ - /* All RF4 spells hurt (except for shriek, multiply, summon animal) */ - if (spell >= 96 + 3 && spell <= 96 + 31) return (TRUE); - - /* Various "ball" spells */ - if (spell >= 128 && spell <= 128 + 8) return (TRUE); - - /* "Cause wounds" and "bolt" spells */ - if (spell >= 128 + 12 && spell <= 128 + 26) return (TRUE); - - /* Hand of Doom */ - if (spell == 160 + 1) return (TRUE); - - /* Doesn't hurt */ - return (FALSE); + project(m_idx, 0, p_ptr->py, p_ptr->px, dam_hp, typ, flg); } /* - * Return TRUE if a spell is good for escaping. + * Calculate the mask for "bolt" spells */ -static bool_ spell_escape(byte spell) +static monster_spell_flag_set compute_bolt_mask() { - /* Blink or Teleport */ - if (spell == 160 + 4 || spell == 160 + 5) return (TRUE); - - /* Teleport the player away */ - if (spell == 160 + 7 || spell == 160 + 8) return (TRUE); - - /* Isn't good for escaping */ - return (FALSE); -} - -/* - * Return TRUE if a spell is good for annoying the player. - */ -static bool_ spell_annoy(byte spell) -{ - /* Shriek */ - if (spell == 96 + 0) return (TRUE); - - /* Brain smash, et al (added curses) */ - if (spell >= 128 + 9 && spell <= 128 + 14) return (TRUE); - - /* Scare, confuse, blind, slow, paralyze */ - if (spell >= 128 + 27 && spell <= 128 + 31) return (TRUE); - - /* Teleport to */ - if (spell == 160 + 6) return (TRUE); - - /* Darkness, make traps, cause amnesia */ - if (spell >= 160 + 9 && spell <= 160 + 11) return (TRUE); - - /* Doesn't annoy */ - return (FALSE); -} - -/* - * Return TRUE if a spell summons help. - */ -static bool_ spell_summon(byte spell) -{ - /* RF4_S_ANIMAL, RF6_S_ANIMALS */ - if (spell == 96 + 2 || spell == 160 + 3) return (TRUE); - /* All other summon spells */ - if (spell >= 160 + 13 && spell <= 160 + 31) return (TRUE); - - /* Doesn't summon */ - return (FALSE); + monster_spell_flag_set flags; + for (auto const &monster_spell: monster_spells()) + { + if (monster_spell->is_bolt) + { + flags |= monster_spell->flag_set; + } + } + return flags; } /* - * Return TRUE if a spell is good in a tactical situation. + * Calculate mask for summoning spells */ -static bool_ spell_tactic(byte spell) +static monster_spell_flag_set compute_summoning_mask() { - /* Blink */ - if (spell == 160 + 4) return (TRUE); - - /* Not good */ - return (FALSE); + monster_spell_flag_set flags; + for (auto const &monster_spell: monster_spells()) + { + if (monster_spell->is_summon) + { + flags |= monster_spell->flag_set; + } + } + return flags; } /* - * Return TRUE if a spell hastes. + * Calculate mask for spells requiring SMART flag */ -static bool_ spell_haste(byte spell) +static monster_spell_flag_set compute_smart_mask() { - /* Haste self */ - if (spell == 160 + 0) return (TRUE); - - /* Not a haste spell */ - return (FALSE); + monster_spell_flag_set flags; + for (auto const &monster_spell: monster_spells()) + { + if (monster_spell->is_smart) + { + flags |= monster_spell->flag_set; + } + } + return flags; } /* - * Return TRUE if a spell is good for healing. + * Calculate mask for spells requiring SMART flag */ -static bool_ spell_heal(byte spell) +static monster_spell_flag_set compute_innate_mask() { - /* Heal */ - if (spell == 160 + 2) return (TRUE); - - /* No healing */ - return (FALSE); + monster_spell_flag_set flags; + for (auto const &monster_spell: monster_spells()) + { + if (monster_spell->is_innate) + { + flags |= monster_spell->flag_set; + } + } + return flags; } @@ -755,49 +713,71 @@ static bool_ spell_heal(byte spell) * * This function may well be an efficiency bottleneck. */ -static int choose_attack_spell(int m_idx, byte spells[], byte num) +static monster_spell const *choose_attack_spell(int m_idx, std::vector<monster_spell const *> const &spells) { monster_type *m_ptr = &m_list[m_idx]; - byte escape[96], escape_num = 0; - byte attack[96], attack_num = 0; - byte summon[96], summon_num = 0; - byte tactic[96], tactic_num = 0; - byte annoy[96], annoy_num = 0; - byte haste[96], haste_num = 0; - byte heal[96], heal_num = 0; - /* Stupid monsters choose randomly */ auto const r_ptr = m_ptr->race(); - if (r_ptr->flags2 & (RF2_STUPID)) + if (r_ptr->flags & RF_STUPID) { /* Pick at random */ - return (spells[rand_int(num)]); + return spells[rand_int(spells.size())]; } + /* Spells by category */ + std::vector<monster_spell const *> escape; escape.reserve(spells.size()); + std::vector<monster_spell const *> attack; attack.reserve(spells.size()); + std::vector<monster_spell const *> summon; summon.reserve(spells.size()); + std::vector<monster_spell const *> tactic; tactic.reserve(spells.size()); + std::vector<monster_spell const *> annoy ; annoy.reserve(spells.size()); + std::vector<monster_spell const *> haste ; haste.reserve(spells.size()); + std::vector<monster_spell const *> heal ; heal.reserve(spells.size()); + /* Categorize spells */ - for (int i = 0; i < num; i++) + for (std::size_t i = 0; i < spells.size(); i++) { /* Escape spell? */ - if (spell_escape(spells[i])) escape[escape_num++] = spells[i]; + if (spells[i]->is_escape) + { + escape.push_back(spells[i]); + } /* Attack spell? */ - if (spell_attack(spells[i])) attack[attack_num++] = spells[i]; + if (spells[i]->is_damage) + { + attack.push_back(spells[i]); + } /* Summon spell? */ - if (spell_summon(spells[i])) summon[summon_num++] = spells[i]; + if (spells[i]->is_summon) + { + summon.push_back(spells[i]); + } /* Tactical spell? */ - if (spell_tactic(spells[i])) tactic[tactic_num++] = spells[i]; + if (spells[i]->is_tactic) + { + tactic.push_back(spells[i]); + } /* Annoyance spell? */ - if (spell_annoy(spells[i])) annoy[annoy_num++] = spells[i]; + if (spells[i]->is_annoy) + { + annoy.push_back(spells[i]); + } /* Haste spell? */ - if (spell_haste(spells[i])) haste[haste_num++] = spells[i]; + if (spells[i]->is_haste) + { + haste.push_back(spells[i]); + } /* Heal spell? */ - if (spell_heal(spells[i])) heal[heal_num++] = spells[i]; + if (spells[i]->is_heal) + { + heal.push_back(spells[i]); + } } /*** Try to pick an appropriate spell type ***/ @@ -805,68 +785,59 @@ static int choose_attack_spell(int m_idx, byte spells[], byte num) /* Hurt badly or afraid, attempt to flee */ if ((m_ptr->hp < m_ptr->maxhp / 3) || m_ptr->monfear) { - /* Choose escape spell if possible */ - if (escape_num) return (escape[rand_int(escape_num)]); + if (!escape.empty()) return escape[rand_int(escape.size())]; } /* Still hurt badly, couldn't flee, attempt to heal */ if (m_ptr->hp < m_ptr->maxhp / 3) { - /* Choose heal spell if possible */ - if (heal_num) return (heal[rand_int(heal_num)]); + if (!heal.empty()) return heal[rand_int(heal.size())]; } /* Player is close and we have attack spells, blink away */ - if ((distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) < 4) && attack_num && (rand_int(100) < 75)) + if ((distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) < 4) && !attack.empty() && (rand_int(100) < 75)) { - /* Choose tactical spell */ - if (tactic_num) return (tactic[rand_int(tactic_num)]); + if (!tactic.empty()) return tactic[rand_int(tactic.size())]; } /* We're hurt (not badly), try to heal */ if ((m_ptr->hp < m_ptr->maxhp * 3 / 4) && (rand_int(100) < 75)) { - /* Choose heal spell if possible */ - if (heal_num) return (heal[rand_int(heal_num)]); + if (!heal.empty()) return heal[rand_int(heal.size())]; } /* Summon if possible (sometimes) */ - if (summon_num && (rand_int(100) < 50)) + if (!summon.empty() && (rand_int(100) < 50)) { - /* Choose summon spell */ - return (summon[rand_int(summon_num)]); + return summon[rand_int(summon.size())]; } /* Attack spell (most of the time) */ - if (attack_num && (rand_int(100) < 85)) + if (!attack.empty() && (rand_int(100) < 85)) { - /* Choose attack spell */ - return (attack[rand_int(attack_num)]); + return attack[rand_int(attack.size())]; } /* Try another tactical spell (sometimes) */ - if (tactic_num && (rand_int(100) < 50)) + if (!tactic.empty() && (rand_int(100) < 50)) { - /* Choose tactic spell */ - return (tactic[rand_int(tactic_num)]); + return tactic[rand_int(tactic.size())]; } /* Haste self if we aren't already somewhat hasted (rarely) */ - if (haste_num && (rand_int(100) < (20 + m_ptr->speed - m_ptr->mspeed))) + if (!haste.empty() && (rand_int(100) < (20 + m_ptr->speed - m_ptr->mspeed))) { - /* Choose haste spell */ - return (haste[rand_int(haste_num)]); + return haste[rand_int(haste.size())]; } /* Annoy player (most of the time) */ - if (annoy_num && (rand_int(100) < 85)) + if (!annoy.empty() && (rand_int(100) < 85)) { - /* Choose annoyance spell */ - return (annoy[rand_int(annoy_num)]); + return annoy[rand_int(annoy.size())]; } /* Choose no spell */ - return (0); + return nullptr; } @@ -883,10 +854,10 @@ static void breath(int m_idx, int typ, int dam_hp, int rad) auto const r_ptr = m_ptr->race(); /* Determine the radius of the blast */ - if (rad < 1) rad = (r_ptr->flags2 & (RF2_POWERFUL)) ? 3 : 2; + if (rad < 1) rad = (r_ptr->flags & RF_POWERFUL) ? 3 : 2; /* Target the player with a ball attack */ - (void)project(m_idx, rad, p_ptr->py, p_ptr->px, dam_hp, typ, flg); + project(m_idx, rad, p_ptr->py, p_ptr->px, dam_hp, typ, flg); } @@ -903,9 +874,9 @@ static void monst_breath_monst(int m_idx, int y, int x, int typ, int dam_hp, int auto const r_ptr = m_ptr->race(); /* Determine the radius of the blast */ - if (rad < 1) rad = (r_ptr->flags2 & (RF2_POWERFUL)) ? 3 : 2; + if (rad < 1) rad = (r_ptr->flags & RF_POWERFUL) ? 3 : 2; - (void)project(m_idx, rad, y, x, dam_hp, typ, flg); + project(m_idx, rad, y, x, dam_hp, typ, flg); } @@ -918,7 +889,7 @@ static void monst_bolt_monst(int m_idx, int y, int x, int typ, int dam_hp) { int flg = PROJECT_STOP | PROJECT_KILL; - (void)project(m_idx, 0, y, x, dam_hp, typ, flg); + project(m_idx, 0, y, x, dam_hp, typ, flg); } @@ -932,7 +903,7 @@ static void monster_msg(cptr fmt, ...) va_start(vp, fmt); /* Format the args, save the length */ - (void)vstrnfmt(buf, 1024, fmt, vp); + vstrnfmt(buf, 1024, fmt, vp); /* End the Varargs Stuff */ va_end(vp); @@ -943,43 +914,38 @@ static void monster_msg(cptr fmt, ...) void monster_msg_simple(cptr s) { + auto &messages = game->messages; + /* Display */ - if (disturb_other) + if (options->disturb_other) { msg_print(s); } else { - message_add(s, TERM_WHITE); + messages.add(s, TERM_WHITE); p_ptr->window |= PW_MESSAGE; } } -void cmonster_msg(char a, cptr fmt, ...) +/** + * Extract list of spell indexes from a flag set. + */ +static std::vector<monster_spell const *> extract_spells(monster_spell_flag_set const &spell_flag_set) { - va_list vp; - - char buf[1024]; - - /* Begin the Varargs Stuff */ - va_start(vp, fmt); - - /* Format the args, save the length */ - (void)vstrnfmt(buf, 1024, fmt, vp); + auto result = std::vector<monster_spell const *>(); + result.reserve(spell_flag_set.nbits); - /* End the Varargs Stuff */ - va_end(vp); - - /* Display */ - if (disturb_other) - cmsg_print(a, buf); - else + for (auto const &monster_spell: monster_spells()) { - message_add(buf, a); - p_ptr->window |= PW_MESSAGE; + if (bool(spell_flag_set & monster_spell->flag_set)) + { + result.push_back(monster_spell); + } } -} + return result; +} /* * Monster tries to 'cast a spell' (or breath, etc) @@ -988,15 +954,13 @@ void cmonster_msg(char a, cptr fmt, ...) int monst_spell_monst_spell = -1; static bool_ monst_spell_monst(int m_idx) { + static const monster_spell_flag_set SF_INT_MASK = compute_smart_mask(); + int y = 0, x = 0; - int i = 1; - int thrown_spell; - byte spell[96], num = 0; char m_name[80], t_name[80]; char m_poss[80]; char ddesc[80]; monster_type *m_ptr = &m_list[m_idx]; /* Attacker */ - u32b f4, f5, f6; /* racial spell flags */ bool_ direct = TRUE; bool_ wake_up = FALSE; @@ -1027,20 +991,14 @@ static bool_ monst_spell_monst(int m_idx) if ((rand_int(100) >= chance) && (monst_spell_monst_spell == -1)) return (FALSE); - /* Target location */ - if (m_ptr->target > -1) + /* Make sure monster actually has a target */ + if (m_ptr->target <= 0) { - if (m_ptr->target > 0) - { - i = m_ptr->target; - } - else return FALSE; + return FALSE; } - else return FALSE; - { - int t_idx = i; + int t_idx = m_ptr->target; monster_type *t_ptr = &m_list[t_idx]; auto const tr_ptr = t_ptr->race(); @@ -1058,45 +1016,26 @@ static bool_ monst_spell_monst(int m_idx) /* Extract the monster level */ const int rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1); - /* Extract the racial spell flags */ - f4 = r_ptr->flags4; - f5 = r_ptr->flags5; - f6 = r_ptr->flags6; + /* Which spells are allowed? */ + monster_spell_flag_set allowed_spells = r_ptr->spells; /* Hack -- allow "desperate" spells */ - if ((r_ptr->flags2 & (RF2_SMART)) && + if ((r_ptr->flags & RF_SMART) && (m_ptr->hp < m_ptr->maxhp / 10) && (rand_int(100) < 50)) { /* Require intelligent spells */ - f4 &= (RF4_INT_MASK); - f5 &= (RF5_INT_MASK); - f6 &= (RF6_INT_MASK); - - /* No spells left */ - if ((!f4 && !f5 && !f6) && (monst_spell_monst_spell == -1)) return (FALSE); - } - - /* Extract the "inate" spells */ - for (int k = 0; k < 32; k++) - { - if (f4 & (1L << k)) spell[num++] = k + 32 * 3; - } + allowed_spells &= SF_INT_MASK; - /* Extract the "normal" spells */ - for (int k = 0; k < 32; k++) - { - if (f5 & (1L << k)) spell[num++] = k + 32 * 4; + /* No spells left? */ + if ((!allowed_spells) && (monst_spell_monst_spell == -1)) return (FALSE); } - /* Extract the "bizarre" spells */ - for (int k = 0; k < 32; k++) - { - if (f6 & (1L << k)) spell[num++] = k + 32 * 5; - } + /* Extract spells */ + auto spell = extract_spells(allowed_spells); - /* No spells left */ - if (!num) return (FALSE); + /* No spells left? */ + if (spell.empty()) return (FALSE); /* Stop if player is dead or gone */ if (!alive || death) return (FALSE); @@ -1117,12 +1056,12 @@ static bool_ monst_spell_monst(int m_idx) monster_desc(ddesc, m_ptr, 0x88); /* Choose a spell to cast */ - thrown_spell = spell[rand_int(num)]; + auto thrown_spell = spell[rand_int(spell.size())]; /* Force a spell ? */ if (monst_spell_monst_spell > -1) { - thrown_spell = monst_spell_monst_spell; + thrown_spell = spell[monst_spell_monst_spell]; monst_spell_monst_spell = -1; } @@ -1131,47 +1070,115 @@ static bool_ monst_spell_monst(int m_idx) see_either = (see_m || see_t); see_both = (see_m && see_t); - int count = 0; - switch (thrown_spell) + /* Do a breath */ + auto do_breath = [&](char const *element, int gf, s32b max, int divisor) -> void { + // Interrupt + disturb_on_other(); + // Message + if (!see_either) + { + monster_msg("You hear breathing noise."); + } + else if (blind) + { + monster_msg("%^s breathes.", m_name); + } + else + { + monster_msg("%^s breathes %s at %s.", m_name, element, t_name); + } + // Breathe + monst_breath_monst(m_idx, y, x, gf, std::min(max, m_ptr->hp / divisor), 0); + }; + + /* Messages for summoning */ + struct summon_messages { + char const *singular; + char const *plural; + }; + + /* Default message for summoning when player is blinded */ + auto blind_msg_default = summon_messages { + "You hear something appear nearby.", + "You hear many things appear nearby." + }; + + /* Do a summoning spell */ + auto do_summon = [&](char const *action, int n, int friendly_type, int hostile_type, summon_messages const &blind_msg) -> void { + // Interrupt + disturb_on_other(); + + // Message + if (blind || !see_m) + { + monster_msg("%^s mumbles.", m_name); + } + else + { + monster_msg("%^s magically %s", m_name, action); + } + + // Do the actual summoning + int count = 0; + for (int k = 0; k < n; k++) + { + if (friendly) + { + count += summon_specific_friendly(m_ptr->fy, m_ptr->fx, rlev, friendly_type, TRUE); + } + else if (!friendly) + { + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, hostile_type); + } + } + // Message for blinded characters + if (blind) + { + if (count == 1) + { + monster_msg(blind_msg.singular); + } + else if (count > 1) + { + monster_msg(blind_msg.plural); + } + } + }; + + /* There's no summoning friendly uniques or Nazgul */ + auto spell_idx = thrown_spell->spell_idx; + + if (friendly) + { + if ((thrown_spell->spell_idx == SF_S_UNIQUE_IDX) && + (thrown_spell->spell_idx == SF_S_WRAITH_IDX)) + { + // Summon high undead instead + spell_idx = SF_S_HI_UNDEAD_IDX; + } + } + + /* Spell effect */ + switch (spell_idx) { - /* RF4_SHRIEK */ - case 96 + 0: + case SF_SHRIEK_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_m) monster_msg("You hear a shriek."); else monster_msg("%^s shrieks at %s.", m_name, t_name); wake_up = TRUE; break; } - /* RF4_MULTIPLY */ - case 96 + 1: - { - break; - } - - /* RF4_S_ANIMAL */ - case 96 + 2: + case SF_MULTIPLY_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons an animal!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_ANIMAL); - } - if (blind && count) monster_msg("You hear something appear nearby."); break; } - /* RF4_ROCKET */ - case 96 + 3: + case SF_ROCKET_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear an explosion!"); else if (blind) monster_msg("%^s shoots something.", m_name); else monster_msg("%^s fires a rocket at %s.", m_name, t_name); @@ -1180,371 +1187,204 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF4_ARROW_1 */ - case 96 + 4: + case SF_ARROW_1_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear a strange noise."); else if (blind) monster_msg("%^s makes a strange noise.", m_name); else monster_msg("%^s fires an arrow at %s.", m_name, t_name); - sound(SOUND_SHOOT); monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(1, 6)); break; } - /* RF4_ARROW_2 */ - case 96 + 5: + case SF_ARROW_2_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear a strange noise."); else if (blind) monster_msg("%^s makes a strange noise.", m_name); else monster_msg("%^s fires an arrow at %s.", m_name, t_name); - sound(SOUND_SHOOT); monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(3, 6)); break; } - /* RF4_ARROW_3 */ - case 96 + 6: + case SF_ARROW_3_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear a strange noise."); else if (blind) monster_msg("%^s makes a strange noise.", m_name); else monster_msg("%^s fires a missile at %s.", m_name, t_name); - sound(SOUND_SHOOT); monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(5, 6)); break; } - /* RF4_ARROW_4 */ - case 96 + 7: + case SF_ARROW_4_IDX: { if (!see_either) monster_msg("You hear a strange noise."); - else if (disturb_other) disturb(1); + else disturb_on_other(); if (blind) monster_msg("%^s makes a strange noise.", m_name); else monster_msg("%^s fires a missile at %s.", m_name, t_name); - sound(SOUND_SHOOT); monst_bolt_monst(m_idx, y, x, GF_ARROW, damroll(7, 6)); break; } - /* RF4_BR_ACID */ - case 96 + 8: + case SF_BR_ACID_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes acid at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_ACID, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); + do_breath("acid", GF_ACID, 1600, 3); break; } - /* RF4_BR_ELEC */ - case 96 + 9: + case SF_BR_ELEC_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes lightning at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_ELEC, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); + do_breath("lightning", GF_ELEC, 1600, 3); break; } - /* RF4_BR_FIRE */ - case 96 + 10: + case SF_BR_FIRE_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes fire at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_FIRE, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); + do_breath("fire", GF_FIRE, 1600, 3); break; } - /* RF4_BR_COLD */ - case 96 + 11: + case SF_BR_COLD_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes frost at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_COLD, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); + do_breath("frost", GF_COLD, 1600, 3); break; } - /* RF4_BR_POIS */ - case 96 + 12: + case SF_BR_POIS_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes gas at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_POIS, - ((m_ptr->hp / 3) > 800 ? 800 : (m_ptr->hp / 3)), 0); + do_breath("gas", GF_POIS, 800, 3); break; } - /* RF4_BR_NETH */ - case 96 + 13: + case SF_BR_NETH_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes nether at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_NETHER, - ((m_ptr->hp / 6) > 550 ? 550 : (m_ptr->hp / 6)), 0); + do_breath("nether", GF_NETHER, 550, 6); break; } - /* RF4_BR_LITE */ - case 96 + 14: + case SF_BR_LITE_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes light at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_LITE, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); + do_breath("light", GF_LITE, 400, 6); break; } - /* RF4_BR_DARK */ - case 96 + 15: + case SF_BR_DARK_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes darkness at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_DARK, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); + do_breath("darkness", GF_DARK, 400, 6); break; } - /* RF4_BR_CONF */ - case 96 + 16: + case SF_BR_CONF_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes confusion at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_CONFUSION, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); + do_breath("confusion", GF_CONFUSION, 400, 6); break; } - /* RF4_BR_SOUN */ - case 96 + 17: + case SF_BR_SOUN_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes sound at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_SOUND, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); + do_breath("sound", GF_SOUND, 400, 6); break; } - /* RF4_BR_CHAO */ - case 96 + 18: + case SF_BR_CHAO_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes chaos at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_CHAOS, - ((m_ptr->hp / 6) > 600 ? 600 : (m_ptr->hp / 6)), 0); + do_breath("chaos", GF_CHAOS, 600, 6); break; } - /* RF4_BR_DISE */ - case 96 + 19: + case SF_BR_DISE_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes disenchantment at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_DISENCHANT, - ((m_ptr->hp / 6) > 500 ? 500 : (m_ptr->hp / 6)), 0); + do_breath("disenchantment", GF_DISENCHANT, 500, 6); break; } - /* RF4_BR_NEXU */ - case 96 + 20: + case SF_BR_NEXU_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes nexus at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_NEXUS, - ((m_ptr->hp / 3) > 250 ? 250 : (m_ptr->hp / 3)), 0); + do_breath("nexus", GF_NEXUS, 250, 3); break; } - /* RF4_BR_TIME */ - case 96 + 21: + case SF_BR_TIME_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes time at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_TIME, - ((m_ptr->hp / 3) > 150 ? 150 : (m_ptr->hp / 3)), 0); + do_breath("time", GF_TIME, 150, 3); break; } - /* RF4_BR_INER */ - case 96 + 22: + case SF_BR_INER_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes inertia at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_INERTIA, - ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)), 0); + do_breath("inertia", GF_INERTIA, 200, 6); break; } - /* RF4_BR_GRAV */ - case 96 + 23: + case SF_BR_GRAV_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes gravity at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_GRAVITY, - ((m_ptr->hp / 3) > 200 ? 200 : (m_ptr->hp / 3)), 0); + do_breath("gravity", GF_GRAVITY, 200, 3); break; } - /* RF4_BR_SHAR */ - case 96 + 24: + case SF_BR_SHAR_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes shards at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_SHARDS, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); + do_breath("shards", GF_SHARDS, 400, 6); break; } - /* RF4_BR_PLAS */ - case 96 + 25: + case SF_BR_PLAS_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes plasma at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_PLASMA, - ((m_ptr->hp / 6) > 150 ? 150 : (m_ptr->hp / 6)), 0); + do_breath("plasma", GF_PLASMA, 150, 6); break; } - /* RF4_BR_WALL */ - case 96 + 26: + case SF_BR_WALL_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes force at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_FORCE, - ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)), 0); + do_breath("force", GF_FORCE, 200, 6); break; } - /* RF4_BR_MANA */ - case 96 + 27: + case SF_BR_MANA_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes magical energy at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_MANA, - ((m_ptr->hp / 3) > 250 ? 250 : (m_ptr->hp / 3)), 0); + do_breath("magical energy", GF_MANA, 250, 3); break; } - /* RF4_BA_NUKE */ - case 96 + 28: + case SF_BA_NUKE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a ball of radiation at %s.", m_name, t_name); - sound(SOUND_BREATH); monst_breath_monst(m_idx, y, x, GF_NUKE, (rlev + damroll(10, 6)), 2); break; } - /* RF4_BR_NUKE */ - case 96 + 29: + case SF_BR_NUKE_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes toxic waste at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_NUKE, - ((m_ptr->hp / 3) > 800 ? 800 : (m_ptr->hp / 3)), 0); + do_breath("toxic waste", GF_NUKE, 800, 3); break; } - /* RF4_BA_CHAO */ - case 96 + 30: + case SF_BA_CHAO_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg("You hear someone mumble frighteningly."); else if (blind) monster_msg("%^s mumbles frighteningly.", m_name); else monster_msg("%^s invokes a raw Chaos upon %s.", m_name, t_name); - sound(SOUND_BREATH); monst_breath_monst(m_idx, y, x, GF_CHAOS, (rlev * 2) + damroll(10, 10), 4); break; } - /* RF4_BR_DISI -> Breathe Disintegration */ - case 96 + 31: + case SF_BR_DISI_IDX: { - if (disturb_other) disturb(1); - if (!see_either) monster_msg("You hear breathing noise."); - else if (blind) monster_msg("%^s breathes.", m_name); - else monster_msg("%^s breathes disintegration at %s.", m_name, t_name); - sound(SOUND_BREATH); - monst_breath_monst(m_idx, y, x, GF_DISINTEGRATE, - ((m_ptr->hp / 3) > 300 ? 300 : (m_ptr->hp / 3)), 0); + do_breath("disintegration", GF_DISINTEGRATE, 300, 3); break; } - /* RF5_BA_ACID */ - case 128 + 0: + case SF_BA_ACID_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts an acid ball at %s.", m_name, t_name); @@ -1552,10 +1392,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_ELEC */ - case 128 + 1: + case SF_BA_ELEC_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1564,10 +1403,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_FIRE */ - case 128 + 2: + case SF_BA_FIRE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1576,10 +1414,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_COLD */ - case 128 + 3: + case SF_BA_COLD_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1588,10 +1425,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_POIS */ - case 128 + 4: + case SF_BA_POIS_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1600,10 +1436,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_NETH */ - case 128 + 5: + case SF_BA_NETH_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1612,10 +1447,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_WATE */ - case 128 + 6: + case SF_BA_WATE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble."); else if (blind) monster_msg("%^s mumbles.", m_name); @@ -1625,10 +1459,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_MANA */ - case 128 + 7: + case SF_BA_MANA_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble powerfully."); else if (blind) monster_msg("%^s mumbles powerfully.", m_name); @@ -1637,10 +1470,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BA_DARK */ - case 128 + 8: + case SF_BA_DARK_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_either) monster_msg ("You hear someone mumble powerfully."); else if (blind) monster_msg("%^s mumbles powerfully.", m_name); @@ -1649,8 +1481,7 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_DRAIN_MANA */ - case 128 + 9: + case SF_DRAIN_MANA_IDX: { /* Attack power */ int r1 = (randint(rlev) / 2) + 1; @@ -1664,7 +1495,7 @@ static bool_ monst_spell_monst(int m_idx) /* Heal the monster */ if (m_ptr->hp < m_ptr->maxhp) { - if (!(tr_ptr->flags4 || tr_ptr->flags5 || tr_ptr->flags6)) + if (!tr_ptr->spells) { if (see_both) monster_msg("%^s is unaffected!", t_name); @@ -1690,12 +1521,11 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_MIND_BLAST */ - case 128 + 10: + case SF_MIND_BLAST_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!seen) { @@ -1707,16 +1537,10 @@ static bool_ monst_spell_monst(int m_idx) } /* Attempt a saving throw */ - if ((tr_ptr->flags1 & (RF1_UNIQUE)) || - (tr_ptr->flags3 & (RF3_NO_CONF)) || + if ((tr_ptr->flags & RF_UNIQUE) || + (tr_ptr->flags & RF_NO_CONF) || (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)) { - /* Memorize a flag */ - if (tr_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) tr_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* No obvious effect */ if (see_t) { @@ -1736,11 +1560,10 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BRAIN_SMASH */ - case 128 + 11: + case SF_BRAIN_SMASH_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!seen) { /* */ @@ -1751,15 +1574,10 @@ static bool_ monst_spell_monst(int m_idx) } /* Attempt a saving throw */ - if ((tr_ptr->flags1 & (RF1_UNIQUE)) || - (tr_ptr->flags3 & (RF3_NO_CONF)) || + if ((tr_ptr->flags & RF_UNIQUE) || + (tr_ptr->flags & RF_NO_CONF) || (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10)) { - /* Memorize a flag */ - if (tr_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) tr_ptr->r_flags3 |= (RF3_NO_CONF); - } /* No obvious effect */ if (see_t) { @@ -1782,11 +1600,10 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_CAUSE_1 */ - case 128 + 12: + case SF_CAUSE_1_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s points at %s and curses.", m_name, t_name); if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10) @@ -1803,11 +1620,10 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_CAUSE_2 */ - case 128 + 13: + case SF_CAUSE_2_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s points at %s and curses horribly.", m_name, t_name); if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10) @@ -1823,11 +1639,10 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_CAUSE_3 */ - case 128 + 14: + case SF_CAUSE_3_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s points at %s, incanting terribly!", m_name, t_name); if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10) @@ -1843,11 +1658,10 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_CAUSE_4 */ - case 128 + 15: + case SF_CAUSE_4_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s points at %s, screaming the word 'DIE!'", m_name, t_name); if (t_ptr->level > randint((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10) @@ -1863,10 +1677,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_ACID */ - case 128 + 16: + case SF_BO_ACID_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts an acid bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_ACID, @@ -1874,10 +1687,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_ELEC */ - case 128 + 17: + case SF_BO_ELEC_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a lightning bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_ELEC, @@ -1885,10 +1697,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_FIRE */ - case 128 + 18: + case SF_BO_FIRE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a fire bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_FIRE, @@ -1896,10 +1707,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_COLD */ - case 128 + 19: + case SF_BO_COLD_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a frost bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_COLD, @@ -1907,17 +1717,15 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_POIS */ - case 128 + 20: + case SF_BO_POIS_IDX: { /* XXX XXX XXX */ break; } - /* RF5_BO_NETH */ - case 128 + 21: + case SF_BO_NETH_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a nether bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_NETHER, @@ -1925,10 +1733,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_WATE */ - case 128 + 22: + case SF_BO_WATE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a water bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_WATER, @@ -1936,10 +1743,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_MANA */ - case 128 + 23: + case SF_BO_MANA_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a mana bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_MANA, @@ -1947,10 +1753,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_PLAS */ - case 128 + 24: + case SF_BO_PLAS_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a plasma bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_PLASMA, @@ -1958,10 +1763,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BO_ICEE */ - case 128 + 25: + case SF_BO_ICEE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts an ice bolt at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_ICE, @@ -1969,10 +1773,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_MISSILE */ - case 128 + 26: + case SF_MISSILE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a magic missile at %s.", m_name, t_name); monst_bolt_monst(m_idx, y, x, GF_MISSILE, @@ -1980,14 +1783,13 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_SCARE */ - case 128 + 27: + case SF_SCARE_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles, and you hear scary noises.", m_name); else monster_msg("%^s casts a fearful illusion at %s.", m_name, t_name); - if (tr_ptr->flags3 & RF3_NO_FEAR) + if (tr_ptr->flags & RF_NO_FEAR) { if (see_t) monster_msg("%^s refuses to be frightened.", t_name); } @@ -2004,15 +1806,14 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_BLIND */ - case 128 + 28: + case SF_BLIND_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s casts a spell, burning %s%s eyes.", m_name, t_name, (!strcmp(t_name, "it") ? "s" : "'s")); - if (tr_ptr->flags3 & RF3_NO_CONF) /* Simulate blindness with confusion */ + if (tr_ptr->flags & RF_NO_CONF) /* Simulate blindness with confusion */ { if (see_t) monster_msg("%^s is unaffected.", t_name); } @@ -2030,14 +1831,13 @@ static bool_ monst_spell_monst(int m_idx) } - /* RF5_CONF */ - case 128 + 29: + case SF_CONF_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) monster_msg("%^s mumbles, and you hear puzzling noises.", m_name); else monster_msg("%^s creates a mesmerising illusion in front of %s.", m_name, t_name); - if (tr_ptr->flags3 & RF3_NO_CONF) + if (tr_ptr->flags & RF_NO_CONF) { if (see_t) monster_msg("%^s disbelieves the feeble spell.", t_name); } @@ -2054,14 +1854,13 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_SLOW */ - case 128 + 30: + case SF_SLOW_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!blind && see_either) monster_msg("%^s drains power from %s%s muscles.", m_name, t_name, (!strcmp(t_name, "it") ? "s" : "'s")); - if (tr_ptr->flags1 & RF1_UNIQUE) + if (tr_ptr->flags & RF_UNIQUE) { if (see_t) monster_msg("%^s is unaffected.", t_name); } @@ -2078,14 +1877,13 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF5_HOLD */ - case 128 + 31: + case SF_HOLD_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!blind && see_m) monster_msg("%^s stares intently at %s.", m_name, t_name); - if ((tr_ptr->flags1 & RF1_UNIQUE) || - (tr_ptr->flags3 & RF3_NO_STUN)) + if ((tr_ptr->flags & RF_UNIQUE) || + (tr_ptr->flags & RF_NO_STUN)) { if (see_t) monster_msg("%^s is unaffected.", t_name); } @@ -2102,11 +1900,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - - /* RF6_HASTE */ - case 160 + 0: + case SF_HASTE_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); if (blind || !see_m) { monster_msg("%^s mumbles.", m_name); @@ -2133,16 +1929,15 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF6_HAND_DOOM */ - case 160 + 1: + case SF_HAND_DOOM_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (!see_m) monster_msg("You hear someone invoke the Hand of Doom!"); else if (!blind) monster_msg("%^s invokes the Hand of Doom on %s.", m_name, t_name); else monster_msg ("You hear someone invoke the Hand of Doom!"); - if (tr_ptr->flags1 & RF1_UNIQUE) + if (tr_ptr->flags & RF_UNIQUE) { if (!blind && see_t) monster_msg("^%s is unaffected!", t_name); } @@ -2165,10 +1960,9 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF6_HEAL */ - case 160 + 2: + case SF_HEAL_IDX: { - if (disturb_other) disturb(1); + disturb_on_other(); /* Message */ if (blind || !see_m) @@ -2230,72 +2024,59 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF6_S_ANIMALS */ - case 160 + 3: + case SF_BLINK_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons some animals!", m_name); - for (int k = 0; k < 4; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_ANIMAL); - } - if (blind && count) monster_msg("You hear many things appear nearby."); - break; - } - - /* RF6_BLINK */ - case 160 + 4: - { - if (disturb_other) disturb(1); + disturb_on_other(); if (see_m) monster_msg("%^s blinks away.", m_name); teleport_away(m_idx, 10); break; } - /* RF6_TPORT */ - case 160 + 5: + case SF_TPORT_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */ + if (dungeon_flags & DF_NO_TELEPORT) + { + break; /* No teleport on special levels */ + } else { - if (disturb_other) disturb(1); + disturb_on_other(); if (see_m) monster_msg("%^s teleports away.", m_name); teleport_away(m_idx, MAX_SIGHT * 2 + 5); break; } } - /* RF6_TELE_TO */ - case 160 + 6: + case SF_TELE_TO_IDX: { /* Not implemented */ break; } - /* RF6_TELE_AWAY */ - case 160 + 7: + case SF_TELE_AWAY_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) break; + if (dungeon_flags & DF_NO_TELEPORT) + { + break; + } - if (!direct) break; + if (!direct) + { + break; + } else { bool_ resists_tele = FALSE; - if (disturb_other) disturb(1); + disturb_on_other(); monster_msg("%^s teleports %s away.", m_name, t_name); - if (tr_ptr->flags3 & (RF3_RES_TELE)) + if (tr_ptr->flags & RF_RES_TELE) { - if (tr_ptr->flags1 & (RF1_UNIQUE)) + if (tr_ptr->flags & RF_UNIQUE) { if (see_t) { - tr_ptr->r_flags3 |= RF3_RES_TELE; monster_msg("%^s is unaffected!", t_name); } resists_tele = TRUE; @@ -2304,7 +2085,6 @@ static bool_ monst_spell_monst(int m_idx) { if (see_t) { - tr_ptr->r_flags3 |= RF3_RES_TELE; monster_msg("%^s resists!", t_name); } resists_tele = TRUE; @@ -2320,388 +2100,212 @@ static bool_ monst_spell_monst(int m_idx) break; } - /* RF6_TELE_LEVEL */ - case 160 + 8: + case SF_TELE_LEVEL_IDX: { /* Not implemented */ break; } - /* RF6_DARKNESS */ - case 160 + 9: + case SF_DARKNESS_IDX: { if (!direct) break; - if (disturb_other) disturb(1); + disturb_on_other(); if (blind) monster_msg("%^s mumbles.", m_name); else monster_msg("%^s gestures in shadow.", m_name); if (seen) monster_msg("%^s is surrounded by darkness.", t_name); - (void)project(m_idx, 3, y, x, 0, GF_DARK_WEAK, PROJECT_GRID | PROJECT_KILL); + project(m_idx, 3, y, x, 0, GF_DARK_WEAK, PROJECT_GRID | PROJECT_KILL); /* Lite up the room */ unlite_room(y, x); break; } - /* RF6_TRAPS */ - case 160 + 10: + case SF_FORGET_IDX: { /* Not implemented */ break; } - /* RF6_FORGET */ - case 160 + 11: - { - /* Not implemented */ + case SF_S_ANIMAL_IDX: + { + do_summon("summons an animal!", 1, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default); break; - } + } + + case SF_S_ANIMALS_IDX: + { + do_summon("summons some animals!", 4, SUMMON_ANIMAL, SUMMON_ANIMAL, blind_msg_default); + break; + } - /* RF6_ANIM_DEAD */ - case 160 + 12: + case SF_S_BUG_IDX: { + do_summon("codes some software bugs.", 6, SUMMON_BUG, SUMMON_BUG, blind_msg_default); break; } - /* RF6_S_BUG */ - case 160 + 13: + case SF_S_RNG_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically codes some software bugs.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_BUG, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_BUG); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("codes some RNGs.", 6, SUMMON_RNG, SUMMON_RNG, blind_msg_default); break; } - /* RF6_S_RNG */ - case 160 + 14: + case SF_S_THUNDERLORD_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically codes some RNGs.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_RNG, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_RNG); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons a Thunderlord!", 1, SUMMON_THUNDERLORD, SUMMON_THUNDERLORD, blind_msg_default); break; } - - /* RF6_S_THUNDERLORD */ - case 160 + 15: + case SF_S_KIN_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons a Thunderlord!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_THUNDERLORD); - } - if (blind && count) monster_msg("You hear something appear nearby."); + // Describe the summons + char action[256]; + sprintf(action, + "summons %s %s.", + m_poss, + (r_ptr->flags & RF_UNIQUE ? "minions" : "kin")); + // Force the right type of "kin" + summon_kin_type = r_ptr->d_char; + // Summon + do_summon(action, 6, SUMMON_KIN, SUMMON_KIN, blind_msg_default); break; } - /* RF6_SUMMON_KIN */ - case 160 + 16: + case SF_S_HI_DEMON_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons %s %s.", - m_name, m_poss, - ((r_ptr->flags1) & RF1_UNIQUE ? - "minions" : "kin")); - summon_kin_type = r_ptr->d_char; /* Big hack */ - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_KIN, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_KIN); - } - if (blind && count) monster_msg("You hear many things appear nearby."); - - + do_summon("summons greater demons!", 8, SUMMON_HI_DEMON, SUMMON_HI_DEMON, blind_msg_default); break; - } + } - /* RF6_S_HI_DEMON */ - case 160 + 17: + case SF_S_MONSTER_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons greater demons!", m_name); - if (blind && count) monster_msg("You hear heavy steps nearby."); - if (friendly) - summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, TRUE); - else - summon_cyber(); + do_summon("summons help!", 1, SUMMON_NO_UNIQUES, 0, blind_msg_default); break; } - /* RF6_S_MONSTER */ - case 160 + 18: + case SF_S_MONSTERS_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons help!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_NO_UNIQUES, TRUE); - else - count += summon_specific(y, x, rlev, 0); - } - if (blind && count) monster_msg("You hear something appear nearby."); + do_summon("summons monsters!", 8, SUMMON_NO_UNIQUES, 0, blind_msg_default); break; } - /* RF6_S_MONSTERS */ - case 160 + 19: + case SF_S_ANT_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons monsters!", m_name); - for (int k = 0; k < 8; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_NO_UNIQUES, TRUE); - else - count += summon_specific(y, x, rlev, 0); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons ants.", 6, SUMMON_ANT, SUMMON_ANT, blind_msg_default); break; } - /* RF6_S_ANT */ - case 160 + 20: + case SF_S_SPIDER_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons ants.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_ANT, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_ANT); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons spiders.", 6, SUMMON_SPIDER, SUMMON_SPIDER, blind_msg_default); break; } - /* RF6_S_SPIDER */ - case 160 + 21: + case SF_S_HOUND_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons spiders.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_SPIDER); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons hounds.", 6, SUMMON_HOUND, SUMMON_HOUND, blind_msg_default); break; } - /* RF6_S_HOUND */ - case 160 + 22: + case SF_S_HYDRA_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons hounds.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_HOUND, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_HOUND); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons hydras.", 6, SUMMON_HYDRA, SUMMON_HYDRA, blind_msg_default); break; } - /* RF6_S_HYDRA */ - case 160 + 23: + case SF_S_ANGEL_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons hydras.", m_name); - for (int k = 0; k < 6; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_HYDRA); - } - if (blind && count) monster_msg("You hear many things appear nearby."); + do_summon("summons an angel!", 1, SUMMON_ANGEL, SUMMON_ANGEL, blind_msg_default); break; } - /* RF6_S_ANGEL */ - case 160 + 24: + case SF_S_DEMON_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons an angel!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_ANGEL); - } - if (blind && count) monster_msg("You hear something appear nearby."); + do_summon("summons a demon!", 1, SUMMON_DEMON, SUMMON_DEMON, blind_msg_default); break; } - /* RF6_S_DEMON */ - case 160 + 25: + case SF_S_UNDEAD_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons a demon!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_DEMON, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_DEMON); - } - if (blind && count) monster_msg("You hear something appear nearby."); + do_summon("summons an undead adversary!", 1, SUMMON_UNDEAD, SUMMON_UNDEAD, blind_msg_default); break; } - /* RF6_S_UNDEAD */ - case 160 + 26: + case SF_S_DRAGON_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons an undead adversary!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_UNDEAD); - } - if (blind && count) monster_msg("You hear something appear nearby."); + do_summon("summons a dragon!", 1, SUMMON_DRAGON, SUMMON_DRAGON, blind_msg_default); break; } - /* RF6_S_DRAGON */ - case 160 + 27: + case SF_S_HI_UNDEAD_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons a dragon!", m_name); - for (int k = 0; k < 1; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_DRAGON); - } - if (blind && count) monster_msg("You hear something appear nearby."); + summon_messages blind_msg { + "You hear a creepy thing appear nearby.", + "You hear many creepy things appear nearby." + }; + do_summon("summons greater undead!", 8, SUMMON_HI_UNDEAD_NO_UNIQUES, SUMMON_HI_UNDEAD, blind_msg); break; } - /* RF6_S_HI_UNDEAD */ - case 160 + 28: + case SF_S_HI_DRAGON_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons greater undead!", m_name); - for (int k = 0; k < 8; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_HI_UNDEAD); - } - if (blind && count) - { - monster_msg("You hear many creepy things appear nearby."); - } + summon_messages blind_msg { + "You hear many a powerful thing appear nearby.", + "You hear many powerful things appear nearby." + }; + do_summon("summons ancient dragons!", 8, SUMMON_HI_DRAGON_NO_UNIQUES, SUMMON_HI_DRAGON, blind_msg); break; } - /* RF6_S_HI_DRAGON */ - case 160 + 29: + case SF_S_WRAITH_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons ancient dragons!", m_name); - for (int k = 0; k < 8; k++) - { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_HI_DRAGON); - } - if (blind && count) - { - monster_msg("You hear many powerful things appear nearby."); - } + // No summoning Nazgul; see the remapping code above the switch. + assert(!friendly); + // Summon + summon_messages blind_msg { + "You hear an immortal being appear nearby.", + "You hear immortal beings appear nearby." + }; + do_summon("summons a wraith!", 8, 0 /* not used */, SUMMON_WRAITH, blind_msg); break; } - /* RF6_S_WRAITH */ - case 160 + 30: + case SF_S_UNIQUE_IDX: { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons a wraith!", m_name); - - - for (int k = 0; k < 8; k++) + // No summoning uniques; see the remapping code above the switch. + assert(!friendly); + // Interrupt + disturb_on_other(); + // Message + if (blind || !see_m) { - count += summon_specific(y, x, rlev, SUMMON_WRAITH); + monster_msg("%^s mumbles.", m_name); } - - if (blind && count) + else { - monster_msg("You hear immortal beings appear nearby."); + monster_msg("%^s magically summons special opponents!", m_name); } - break; - } - - /* RF6_S_UNIQUE */ - case 160 + 31: - { - if (disturb_other) disturb(1); - if (blind || !see_m) monster_msg("%^s mumbles.", m_name); - else monster_msg("%^s magically summons special opponents!", m_name); + // Summon + int count = 0; for (int k = 0; k < 8; k++) { - if (!friendly) - count += summon_specific(y, x, rlev, SUMMON_UNIQUE); + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_UNIQUE); } for (int k = 0; k < 8; k++) { - if (friendly) - count += summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE); - else - count += summon_specific(y, x, rlev, SUMMON_HI_UNDEAD); + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_HI_UNDEAD); } - if (blind && count) + // Message + if (blind) { - monster_msg("You hear many powerful things appear nearby."); + if (count == 1) + { + monster_msg("You hear a powerful thing appear nearby."); + } + else if (count > 1) + { + monster_msg("You hear many powerful things appear nearby."); + } } break; } @@ -2712,39 +2316,6 @@ static bool_ monst_spell_monst(int m_idx) t_ptr->csleep = 0; } - - /* Remember what the monster did, if we saw it */ - if (seen) - { - /* Inate spell */ - if (thrown_spell < 32*4) - { - r_ptr->r_flags4 |= (1L << (thrown_spell - 32 * 3)); - if (r_ptr->r_cast_inate < MAX_UCHAR) r_ptr->r_cast_inate++; - } - - /* Bolt or Ball */ - else if (thrown_spell < 32*5) - { - r_ptr->r_flags5 |= (1L << (thrown_spell - 32 * 4)); - if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++; - } - - /* Special spell */ - else if (thrown_spell < 32*6) - { - r_ptr->r_flags6 |= (1L << (thrown_spell - 32 * 5)); - if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++; - } - } - - /* Always take note of monsters that kill you --- - * even accidentally */ - if (death && (r_ptr->r_deaths < MAX_SHORT)) - { - r_ptr->r_deaths++; - } - /* A spell was cast */ return (TRUE); } @@ -2757,7 +2328,6 @@ static bool_ monst_spell_monst(int m_idx) void curse_equipment(int chance, int heavy_chance) { bool_ changed = FALSE; - u32b o1, o2, o3, o4, esp, o5; object_type * o_ptr = &p_ptr->inventory[rand_range(INVEN_WIELD, INVEN_TOTAL - 1)]; @@ -2765,11 +2335,11 @@ void curse_equipment(int chance, int heavy_chance) if (!(o_ptr->k_idx)) return; - object_flags(o_ptr, &o1, &o2, &o3, &o4, &o5, &esp); + auto const flags = object_flags(o_ptr); /* Extra, biased saving throw for blessed items */ - if ((o3 & (TR3_BLESSED)) && (randint(888) > chance)) + if ((flags & TR_BLESSED) && (randint(888) > chance)) { char o_name[256]; object_desc(o_name, o_ptr, FALSE, 0); @@ -2780,31 +2350,28 @@ void curse_equipment(int chance, int heavy_chance) } if ((randint(100) <= heavy_chance) && - (o_ptr->name1 || o_ptr->name2 || o_ptr->art_name)) + (o_ptr->name1 || o_ptr->name2 || (!o_ptr->artifact_name.empty()))) { - if (!(o3 & TR3_HEAVY_CURSE)) + if (!(flags & TR_HEAVY_CURSE)) changed = TRUE; - o_ptr->art_flags3 |= TR3_HEAVY_CURSE; - o_ptr->art_flags3 |= TR3_CURSED; + o_ptr->art_flags |= TR_HEAVY_CURSE; + o_ptr->art_flags |= TR_CURSED; o_ptr->ident |= IDENT_CURSED; } else { - if (!(o_ptr->ident & (IDENT_CURSED))) + if (!(o_ptr->ident & IDENT_CURSED)) changed = TRUE; - o_ptr->art_flags3 |= TR3_CURSED; + o_ptr->art_flags |= TR_CURSED; o_ptr->ident |= IDENT_CURSED; } if (changed) { msg_print("There is a malignant black aura surrounding you..."); - if (o_ptr->note) + if (o_ptr->inscription == "uncursed") { - if (streq(quark_str(o_ptr->note), "uncursed")) - { - o_ptr->note = 0; - } + o_ptr->inscription.clear(); } } } @@ -2813,7 +2380,7 @@ void curse_equipment(int chance, int heavy_chance) void curse_equipment_dg(int chance, int heavy_chance) { bool_ changed = FALSE; - u32b o1, o2, o3, o4, esp, o5; + object_type * o_ptr = &p_ptr->inventory[rand_range(INVEN_WIELD, INVEN_TOTAL - 1)]; @@ -2821,49 +2388,44 @@ void curse_equipment_dg(int chance, int heavy_chance) if (!(o_ptr->k_idx)) return; - object_flags(o_ptr, &o1, &o2, &o3, &o4, &o5, &esp); + auto const flags = object_flags(o_ptr); /* Extra, biased saving throw for blessed items */ - if ((o3 & (TR3_BLESSED)) && (randint(888) > chance)) + if ((flags & TR_BLESSED) && (randint(888) > chance)) { char o_name[256]; object_desc(o_name, o_ptr, FALSE, 0); msg_format("Your %s resist%s cursing!", o_name, ((o_ptr->number > 1) ? "" : "s")); - /* Hmmm -- can we wear multiple items? If not, this is unnecessary */ - /* DG -- Yes we can, in the quiver */ return; } if ((randint(100) <= heavy_chance) && - (o_ptr->name1 || o_ptr->name2 || o_ptr->art_name)) + (o_ptr->name1 || o_ptr->name2 || (!o_ptr->artifact_name.empty()))) { - if (!(o3 & TR3_HEAVY_CURSE)) + if (!(flags & TR_HEAVY_CURSE)) changed = TRUE; - o_ptr->art_flags3 |= TR3_HEAVY_CURSE; - o_ptr->art_flags3 |= TR3_CURSED; - o_ptr->art_flags4 |= TR4_DG_CURSE; + o_ptr->art_flags |= TR_HEAVY_CURSE; + o_ptr->art_flags |= TR_CURSED; + o_ptr->art_flags |= TR_DG_CURSE; o_ptr->ident |= IDENT_CURSED; } else { - if (!(o_ptr->ident & (IDENT_CURSED))) + if (!(o_ptr->ident & IDENT_CURSED)) changed = TRUE; - o_ptr->art_flags3 |= TR3_CURSED; - o_ptr->art_flags4 |= TR4_DG_CURSE; + o_ptr->art_flags |= TR_CURSED; + o_ptr->art_flags |= TR_DG_CURSE; o_ptr->ident |= IDENT_CURSED; } if (changed) { msg_print("There is a malignant black aura surrounding you..."); - if (o_ptr->note) + if (o_ptr->inscription == "uncursed") { - if (streq(quark_str(o_ptr->note), "uncursed")) - { - o_ptr->note = 0; - } + o_ptr->inscription.clear(); } } } @@ -2911,15 +2473,14 @@ void curse_equipment_dg(int chance, int heavy_chance) */ static bool_ make_attack_spell(int m_idx) { - int k, chance, thrown_spell, rlev, failrate; - byte spell[96], num = 0; - u32b f4, f5, f6; + static const auto SF_BOLT_MASK = compute_bolt_mask(); + static const auto SF_SUMMON_MASK = compute_summoning_mask(); + static const auto SF_INT_MASK = compute_smart_mask(); + static const auto SF_INNATE_MASK = compute_innate_mask(); + + int chance, rlev, failrate; char m_name[80]; bool_ no_inate = FALSE; - int x, y; - - /* Summon count */ - int count = 0; /* Extract the blind-ness */ bool_ blind = (p_ptr->blind ? TRUE : FALSE); @@ -2930,23 +2491,13 @@ static bool_ make_attack_spell(int m_idx) /* Extract the "see-able-ness" */ bool_ seen = (!blind && m_ptr->ml); - /* Assume "normal" target */ - bool_ normal = TRUE; - /* Target location */ - if (m_ptr->target > -1) + if (m_ptr->target != 0) { - if (!m_ptr->target) - { - y = p_ptr->py; - x = p_ptr->px; - } - else - { - return (FALSE); - } + return FALSE; } - else return FALSE; + int y = p_ptr->py; + int x = p_ptr->px; /* Cannot cast spells when confused */ if (m_ptr->confused) return (FALSE); @@ -2957,7 +2508,7 @@ static bool_ make_attack_spell(int m_idx) /* Cannot attack the player if mortal and player fated to never die by the ... */ auto const r_ptr = m_ptr->race(); - if ((r_ptr->flags7 & RF7_MORTAL) && (p_ptr->no_mortal)) return (FALSE); + if ((r_ptr->flags & RF_MORTAL) && (p_ptr->no_mortal)) return (FALSE); /* Hack -- Extract the spell probability */ chance = (r_ptr->freq_inate + r_ptr->freq_spell) / 2; @@ -2971,8 +2522,7 @@ static bool_ make_attack_spell(int m_idx) /* Sometimes forbid inate attacks (breaths) */ if (rand_int(100) >= (chance * 2)) no_inate = TRUE; - /* Hack -- require projectable player */ - if (normal) + /* Require projectable player */ { /* Check range */ if (m_ptr->cdis > MAX_RANGE) return (FALSE); @@ -2985,80 +2535,58 @@ static bool_ make_attack_spell(int m_idx) rlev = ((m_ptr->level >= 1) ? m_ptr->level : 1); /* Extract the racial spell flags */ - f4 = r_ptr->flags4; - f5 = r_ptr->flags5; - f6 = r_ptr->flags6; + monster_spell_flag_set allowed_spells = r_ptr->spells; /* Forbid inate attacks sometimes */ - if (no_inate) f4 = 0L; + if (no_inate) + { + allowed_spells &= ~SF_INNATE_MASK; + } /* Hack -- allow "desperate" spells */ - if ((r_ptr->flags2 & (RF2_SMART)) && + if ((r_ptr->flags & RF_SMART) && (m_ptr->hp < m_ptr->maxhp / 10) && (rand_int(100) < 50)) { /* Require intelligent spells */ - f4 &= (RF4_INT_MASK); - f5 &= (RF5_INT_MASK); - f6 &= (RF6_INT_MASK); + allowed_spells &= SF_INT_MASK; - /* No spells left */ - if (!f4 && !f5 && !f6) return (FALSE); + /* No spells left? */ + if (!allowed_spells) return (FALSE); } /* Remove the "ineffective" spells */ - remove_bad_spells(m_idx, &f4, &f5, &f6); + remove_bad_spells(m_idx, &allowed_spells); /* No spells left */ - if (!f4 && !f5 && !f6) return (FALSE); + if (!allowed_spells) return (FALSE); /* Check for a clean bolt shot */ - if ((f4&(RF4_BOLT_MASK) || f5 & (RF5_BOLT_MASK) || - f6&(RF6_BOLT_MASK)) && - !(r_ptr->flags2 & (RF2_STUPID)) && + if ((allowed_spells & SF_BOLT_MASK) && + !(r_ptr->flags & RF_STUPID) && !clean_shot(m_ptr->fy, m_ptr->fx, y, x)) { /* Remove spells that will only hurt friends */ - f4 &= ~(RF4_BOLT_MASK); - f5 &= ~(RF5_BOLT_MASK); - f6 &= ~(RF6_BOLT_MASK); + allowed_spells &= ~SF_BOLT_MASK; } /* Check for a possible summon */ - if ((f4 & (RF4_SUMMON_MASK) || f5 & (RF5_SUMMON_MASK) || - f6 & (RF6_SUMMON_MASK)) && - !(r_ptr->flags2 & (RF2_STUPID)) && + if ((allowed_spells & SF_SUMMON_MASK) && + !(r_ptr->flags & RF_STUPID) && !(summon_possible(y, x))) { /* Remove summoning spells */ - f4 &= ~(RF4_SUMMON_MASK); - f5 &= ~(RF5_SUMMON_MASK); - f6 &= ~(RF6_SUMMON_MASK); + allowed_spells &= ~SF_SUMMON_MASK; } /* No spells left */ - if (!f4 && !f5 && !f6) return (FALSE); + if (!allowed_spells) return (FALSE); /* Extract the "inate" spells */ - for (k = 0; k < 32; k++) - { - if (f4 & (1L << k)) spell[num++] = k + 32 * 3; - } - - /* Extract the "normal" spells */ - for (k = 0; k < 32; k++) - { - if (f5 & (1L << k)) spell[num++] = k + 32 * 4; - } - - /* Extract the "bizarre" spells */ - for (k = 0; k < 32; k++) - { - if (f6 & (1L << k)) spell[num++] = k + 32 * 5; - } + auto spell = extract_spells(allowed_spells); /* No spells left */ - if (!num) return (FALSE); + if (spell.empty()) return (FALSE); /* Stop if player is dead or gone */ if (!alive || death) return (FALSE); @@ -3070,7 +2598,7 @@ static bool_ make_attack_spell(int m_idx) monster_desc(m_name, m_ptr, 0x00); /* Choose a spell to cast */ - thrown_spell = choose_attack_spell(m_idx, spell, num); + auto thrown_spell = choose_attack_spell(m_idx, spell); /* Abort if no spell was chosen */ if (!thrown_spell) return (FALSE); @@ -3079,10 +2607,10 @@ static bool_ make_attack_spell(int m_idx) failrate = 25 - (rlev + 3) / 4; /* Hack -- Stupid monsters will never fail (for jellies and such) */ - if (r_ptr->flags2 & (RF2_STUPID)) failrate = 0; + if (r_ptr->flags & RF_STUPID) failrate = 0; /* Check for spell failure (inate attacks never fail) */ - if ((thrown_spell >= 128) && (rand_int(100) < failrate)) + if ((!thrown_spell->is_innate) && (rand_int(100) < failrate)) { /* Message */ msg_format("%^s tries to cast a spell, but fails.", m_name); @@ -3091,7 +2619,7 @@ static bool_ make_attack_spell(int m_idx) } /* Can the player disrupt its puny attempts? */ - if ((p_ptr->antimagic_dis >= m_ptr->cdis) && (magik(p_ptr->antimagic)) && (thrown_spell >= 128)) + if ((p_ptr->antimagic_dis >= m_ptr->cdis) && magik(p_ptr->antimagic) && thrown_spell->is_magic) { char m_poss[80]; @@ -3111,42 +2639,89 @@ static bool_ make_attack_spell(int m_idx) /* Hack -- Get the "died from" name */ monster_desc(ddesc, m_ptr, 0x88); + /* Do a breath */ + auto do_breath = [&](char const *element, int gf, s32b max, int divisor, int smart_learn) -> void { + // Interrupt + disturb(); + // Message + if (blind) + { + msg_format("%^s breathes.", m_name); + } + else + { + msg_format("%^s breathes %s.", m_name, element); + } + // Breathe + breath(m_idx, gf, std::min(m_ptr->hp / divisor, max), 0); + // Update "smart" monster knowledge + update_smart_learn(m_idx, smart_learn); + }; + + /* Messages for summoning */ + struct summon_messages { + char const *singular; + char const *plural; + }; + + /* Default message for summoning when player is blinded */ + summon_messages blind_msg_default { + "You hear something appear nearby.", + "You hear many things appear nearby." + }; + + /* Do a summoning spell */ + auto do_summon = [&](char const *action, int n, int type, summon_messages const &blind_msg) -> void { + // Interrupt + disturb(); + // Message + if (blind) + { + msg_format("%^s mumbles.", m_name); + } + else + { + msg_format("%^s magically %s", m_name, action); + } + // Do the actual summoning + int count = 0; + for (int k = 0; k < n; k++) + { + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, type); + } + // Message for blinded characters + if (blind) + { + if (count == 1) + { + msg_print(blind_msg.singular); + } + else if (count > 1) + { + msg_print(blind_msg.plural); + } + } + }; + /* Cast the spell. */ - switch (thrown_spell) + switch (thrown_spell->spell_idx) { - /* RF4_SHRIEK */ - case 96 + 0: + case SF_SHRIEK_IDX: { - disturb(1); + disturb(); msg_format("%^s makes a high pitched shriek.", m_name); aggravate_monsters(m_idx); break; } - /* RF4_MULTIPLY */ - case 96 + 1: + case SF_MULTIPLY_IDX: { break; } - /* RF4_S_ANIMAL */ - case 96 + 2: + case SF_ROCKET_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons an animal!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_ANIMAL); - } - if (blind && count) msg_print("You hear something appear nearby."); - break; - } - - /* RF4_ROCKET */ - case 96 + 3: - { - disturb(1); + disturb(); if (blind) msg_format("%^s shoots something.", m_name); else msg_format("%^s fires a rocket.", m_name); breath(m_idx, GF_ROCKET, @@ -3155,10 +2730,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_ARROW_1 */ - case 96 + 4: + case SF_ARROW_1_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s makes a strange noise.", m_name); else msg_format("%^s fires an arrow.", m_name); bolt(m_idx, GF_ARROW, damroll(1, 6)); @@ -3166,10 +2740,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_ARROW_2 */ - case 96 + 5: + case SF_ARROW_2_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s makes a strange noise.", m_name); else msg_format("%^s fires an arrow!", m_name); bolt(m_idx, GF_ARROW, damroll(3, 6)); @@ -3177,10 +2750,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_ARROW_3 */ - case 96 + 6: + case SF_ARROW_3_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s makes a strange noise.", m_name); else msg_format("%^s fires a missile.", m_name); bolt(m_idx, GF_ARROW, damroll(5, 6)); @@ -3188,10 +2760,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_ARROW_4 */ - case 96 + 7: + case SF_ARROW_4_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s makes a strange noise.", m_name); else msg_format("%^s fires a missile!", m_name); bolt(m_idx, GF_ARROW, damroll(7, 6)); @@ -3199,245 +2770,129 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_BR_ACID */ - case 96 + 8: + case SF_BR_ACID_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes acid.", m_name); - breath(m_idx, GF_ACID, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_ACID); + do_breath("acid", GF_ACID, 1600, 3, DRS_ACID); break; } - /* RF4_BR_ELEC */ - case 96 + 9: + case SF_BR_ELEC_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes lightning.", m_name); - breath(m_idx, GF_ELEC, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_ELEC); + do_breath("lightning", GF_ELEC, 1600, 3, DRS_ELEC); break; } - /* RF4_BR_FIRE */ - case 96 + 10: + case SF_BR_FIRE_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes fire.", m_name); - breath(m_idx, GF_FIRE, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_FIRE); + do_breath("fire", GF_FIRE, 1600, 3, DRS_FIRE); break; } - /* RF4_BR_COLD */ - case 96 + 11: + case SF_BR_COLD_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes frost.", m_name); - breath(m_idx, GF_COLD, - ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_COLD); + do_breath("frost", GF_COLD, 1600, 3, DRS_COLD); break; } - /* RF4_BR_POIS */ - case 96 + 12: + case SF_BR_POIS_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes gas.", m_name); - breath(m_idx, GF_POIS, - ((m_ptr->hp / 3) > 800 ? 800 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_POIS); + do_breath("gas", GF_POIS, 800, 3, DRS_POIS); break; } - - /* RF4_BR_NETH */ - case 96 + 13: + case SF_BR_NETH_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes nether.", m_name); - breath(m_idx, GF_NETHER, - ((m_ptr->hp / 6) > 550 ? 550 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_NETH); + do_breath("nether", GF_NETHER, 550, 6, DRS_NETH); break; } - /* RF4_BR_LITE */ - case 96 + 14: + case SF_BR_LITE_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes light.", m_name); - breath(m_idx, GF_LITE, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_LITE); + do_breath("light", GF_LITE, 400, 6, DRS_LITE); break; } - /* RF4_BR_DARK */ - case 96 + 15: + case SF_BR_DARK_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes darkness.", m_name); - breath(m_idx, GF_DARK, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_DARK); + do_breath("darkness", GF_DARK, 400, 6, DRS_DARK); break; } - /* RF4_BR_CONF */ - case 96 + 16: + case SF_BR_CONF_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes confusion.", m_name); - breath(m_idx, GF_CONFUSION, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_CONF); + do_breath("confusion", GF_CONFUSION, 400, 6, DRS_CONF); break; } - /* RF4_BR_SOUN */ - case 96 + 17: + case SF_BR_SOUN_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes sound.", m_name); - breath(m_idx, GF_SOUND, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_SOUND); + do_breath("sound", GF_SOUND, 400, 6, DRS_SOUND); break; } - /* RF4_BR_CHAO */ - case 96 + 18: + case SF_BR_CHAO_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes chaos.", m_name); - breath(m_idx, GF_CHAOS, - ((m_ptr->hp / 6) > 600 ? 600 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_CHAOS); + do_breath("chaos", GF_CHAOS, 600, 6, DRS_CHAOS); break; } - /* RF4_BR_DISE */ - case 96 + 19: + case SF_BR_DISE_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes disenchantment.", m_name); - breath(m_idx, GF_DISENCHANT, - ((m_ptr->hp / 6) > 500 ? 500 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_DISEN); + do_breath("disenchantment", GF_DISENCHANT, 500, 6, DRS_DISEN); break; } - /* RF4_BR_NEXU */ - case 96 + 20: + case SF_BR_NEXU_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes nexus.", m_name); - breath(m_idx, GF_NEXUS, - ((m_ptr->hp / 3) > 250 ? 250 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_NEXUS); + do_breath("nexus", GF_NEXUS, 250, 3, DRS_NEXUS); break; } - /* RF4_BR_TIME */ - case 96 + 21: + case SF_BR_TIME_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes time.", m_name); - breath(m_idx, GF_TIME, - ((m_ptr->hp / 3) > 150 ? 150 : (m_ptr->hp / 3)), 0); + do_breath("time", GF_TIME, 150, 3, DRS_NONE); break; } - /* RF4_BR_INER */ - case 96 + 22: + case SF_BR_INER_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes inertia.", m_name); - breath(m_idx, GF_INERTIA, - ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)), 0); + do_breath("inertia", GF_INERTIA, 200, 6, DRS_NONE); break; } - /* RF4_BR_GRAV */ - case 96 + 23: + case SF_BR_GRAV_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes gravity.", m_name); - breath(m_idx, GF_GRAVITY, - ((m_ptr->hp / 3) > 200 ? 200 : (m_ptr->hp / 3)), 0); + do_breath("gravity", GF_GRAVITY, 200, 3, DRS_NONE); break; } - /* RF4_BR_SHAR */ - case 96 + 24: + case SF_BR_SHAR_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes shards.", m_name); - breath(m_idx, GF_SHARDS, - ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), 0); - update_smart_learn(m_idx, DRS_SHARD); + do_breath("shards", GF_SHARDS, 400, 6, DRS_SHARD); break; } - /* RF4_BR_PLAS */ - case 96 + 25: + case SF_BR_PLAS_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes plasma.", m_name); - breath(m_idx, GF_PLASMA, - ((m_ptr->hp / 6) > 150 ? 150 : (m_ptr->hp / 6)), 0); + do_breath("plasma", GF_PLASMA, 150, 6, DRS_NONE); break; } - /* RF4_BR_WALL */ - case 96 + 26: + case SF_BR_WALL_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes force.", m_name); - breath(m_idx, GF_FORCE, - ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)), 0); + do_breath("force", GF_FORCE, 200, 6, DRS_NONE); break; } - /* RF4_BR_MANA */ - case 96 + 27: + case SF_BR_MANA_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes magical energy.", m_name); - breath(m_idx, GF_MANA, - ((m_ptr->hp / 3) > 250 ? 250 : (m_ptr->hp / 3)), 0); + do_breath("magical energy", GF_MANA, 250, 3, DRS_NONE); break; } - /* RF4_BA_NUKE */ - case 96 + 28: + case SF_BA_NUKE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a ball of radiation.", m_name); breath(m_idx, GF_NUKE, (rlev + damroll(10, 6)), 2); @@ -3445,22 +2900,15 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_BR_NUKE */ - case 96 + 29: + case SF_BR_NUKE_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes toxic waste.", m_name); - breath(m_idx, GF_NUKE, - ((m_ptr->hp / 3) > 800 ? 800 : (m_ptr->hp / 3)), 0); - update_smart_learn(m_idx, DRS_POIS); + do_breath("toxic waste", GF_NUKE, 800, 3, DRS_POIS); break; } - /* RF4_BA_CHAO */ - case 96 + 30: + case SF_BA_CHAO_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles frighteningly.", m_name); else msg_format("%^s invokes a raw chaos.", m_name); breath(m_idx, GF_CHAOS, (rlev * 2) + damroll(10, 10), 4); @@ -3468,23 +2916,15 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF4_BR_DISI -> Disintegration breath! */ - case 96 + 31: + case SF_BR_DISI_IDX: { - disturb(1); - if (blind) msg_format("%^s breathes.", m_name); - else msg_format("%^s breathes disintegration.", m_name); - breath(m_idx, GF_DISINTEGRATE, - ((m_ptr->hp / 3) > 300 ? 300 : (m_ptr->hp / 3)), 0); + do_breath("disintegration", GF_DISINTEGRATE, 300, 3, DRS_NONE); break; } - - - /* RF5_BA_ACID */ - case 128 + 0: + case SF_BA_ACID_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts an acid ball.", m_name); breath(m_idx, GF_ACID, @@ -3493,10 +2933,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_ELEC */ - case 128 + 1: + case SF_BA_ELEC_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a lightning ball.", m_name); breath(m_idx, GF_ELEC, @@ -3505,10 +2944,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_FIRE */ - case 128 + 2: + case SF_BA_FIRE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a fire ball.", m_name); breath(m_idx, GF_FIRE, @@ -3517,10 +2955,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_COLD */ - case 128 + 3: + case SF_BA_COLD_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a frost ball.", m_name); breath(m_idx, GF_COLD, @@ -3529,10 +2966,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_POIS */ - case 128 + 4: + case SF_BA_POIS_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a stinking cloud.", m_name); breath(m_idx, GF_POIS, @@ -3541,10 +2977,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_NETH */ - case 128 + 5: + case SF_BA_NETH_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a nether ball.", m_name); breath(m_idx, GF_NETHER, @@ -3553,10 +2988,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_WATE */ - case 128 + 6: + case SF_BA_WATE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s gestures fluidly.", m_name); msg_print("You are engulfed in a whirlpool."); @@ -3565,10 +2999,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_MANA */ - case 128 + 7: + case SF_BA_MANA_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles powerfully.", m_name); else msg_format("%^s invokes a mana storm.", m_name); breath(m_idx, GF_MANA, @@ -3576,10 +3009,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BA_DARK */ - case 128 + 8: + case SF_BA_DARK_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles powerfully.", m_name); else msg_format("%^s invokes a darkness storm.", m_name); breath(m_idx, GF_DARK, @@ -3588,15 +3020,14 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_DRAIN_MANA */ - case 128 + 9: + case SF_DRAIN_MANA_IDX: { if (p_ptr->csp) { int r1; /* Disturb if legal */ - disturb(1); + disturb(); /* Basic message */ msg_format("%^s draws psychic energy from you!", m_name); @@ -3645,10 +3076,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_MIND_BLAST */ - case 128 + 10: + case SF_MIND_BLAST_IDX: { - disturb(1); + disturb(); if (!seen) { msg_print("You feel something focusing on your mind."); @@ -3668,12 +3098,12 @@ static bool_ make_attack_spell(int m_idx) if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(4) + 4); + set_confused(p_ptr->confused + rand_int(4) + 4); } if ((!p_ptr->resist_chaos) && (randint(3) == 1)) { - (void) set_image(p_ptr->image + rand_int(250) + 150); + set_image(p_ptr->image + rand_int(250) + 150); } take_sanity_hit(damroll(8, 8), ddesc); @@ -3681,10 +3111,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BRAIN_SMASH */ - case 128 + 11: + case SF_BRAIN_SMASH_IDX: { - disturb(1); + disturb(); if (!seen) { msg_print("You feel something focusing on your mind."); @@ -3704,35 +3133,34 @@ static bool_ make_attack_spell(int m_idx) take_sanity_hit(damroll(12, 15), ddesc); if (!p_ptr->resist_blind) { - (void)set_blind(p_ptr->blind + 8 + rand_int(8)); + set_blind(p_ptr->blind + 8 + rand_int(8)); } if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(4) + 4); + set_confused(p_ptr->confused + rand_int(4) + 4); } if (!p_ptr->free_act) { - (void)set_paralyzed(rand_int(4) + 4); + set_paralyzed(rand_int(4) + 4); } - (void)set_slow(p_ptr->slow + rand_int(4) + 4); + set_slow(p_ptr->slow + rand_int(4) + 4); while (rand_int(100) > p_ptr->skill_sav) - (void)do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); while (rand_int(100) > p_ptr->skill_sav) - (void)do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); if (!p_ptr->resist_chaos) { - (void) set_image(p_ptr->image + rand_int(250) + 150); + set_image(p_ptr->image + rand_int(250) + 150); } } break; } - /* RF5_CAUSE_1 */ - case 128 + 12: + case SF_CAUSE_1_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s points at you and curses.", m_name); if (rand_int(100) < p_ptr->skill_sav) @@ -3747,10 +3175,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_CAUSE_2 */ - case 128 + 13: + case SF_CAUSE_2_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s points at you and curses horribly.", m_name); if (rand_int(100) < p_ptr->skill_sav) @@ -3765,10 +3192,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_CAUSE_3 */ - case 128 + 14: + case SF_CAUSE_3_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles loudly.", m_name); else msg_format("%^s points at you, incanting terribly!", m_name); if (rand_int(100) < p_ptr->skill_sav) @@ -3783,10 +3209,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_CAUSE_4 */ - case 128 + 15: + case SF_CAUSE_4_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s screams the word 'DIE!'", m_name); else msg_format("%^s points at you, screaming the word DIE!", m_name); if (rand_int(100) < p_ptr->skill_sav) @@ -3796,15 +3221,14 @@ static bool_ make_attack_spell(int m_idx) else { take_hit(damroll(15, 15), ddesc); - (void)set_cut(p_ptr->cut + damroll(10, 10)); + set_cut(p_ptr->cut + damroll(10, 10)); } break; } - /* RF5_BO_ACID */ - case 128 + 16: + case SF_BO_ACID_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a acid bolt.", m_name); bolt(m_idx, GF_ACID, damroll(7, 8) + (rlev / 3)); @@ -3813,10 +3237,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_ELEC */ - case 128 + 17: + case SF_BO_ELEC_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a lightning bolt.", m_name); bolt(m_idx, GF_ELEC, damroll(4, 8) + (rlev / 3)); @@ -3825,10 +3248,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_FIRE */ - case 128 + 18: + case SF_BO_FIRE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a fire bolt.", m_name); bolt(m_idx, GF_FIRE, damroll(9, 8) + (rlev / 3)); @@ -3837,10 +3259,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_COLD */ - case 128 + 19: + case SF_BO_COLD_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a frost bolt.", m_name); bolt(m_idx, GF_COLD, damroll(6, 8) + (rlev / 3)); @@ -3849,17 +3270,15 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_POIS */ - case 128 + 20: + case SF_BO_POIS_IDX: { /* XXX XXX XXX */ break; } - /* RF5_BO_NETH */ - case 128 + 21: + case SF_BO_NETH_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a nether bolt.", m_name); bolt(m_idx, GF_NETHER, 30 + damroll(5, 5) + (rlev * 3) / 2); @@ -3868,10 +3287,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_WATE */ - case 128 + 22: + case SF_BO_WATE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a water bolt.", m_name); bolt(m_idx, GF_WATER, damroll(10, 10) + (rlev)); @@ -3879,10 +3297,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_MANA */ - case 128 + 23: + case SF_BO_MANA_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a mana bolt.", m_name); bolt(m_idx, GF_MANA, randint(rlev * 7 / 2) + 50); @@ -3890,10 +3307,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_PLAS */ - case 128 + 24: + case SF_BO_PLAS_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a plasma bolt.", m_name); bolt(m_idx, GF_PLASMA, 10 + damroll(8, 7) + (rlev)); @@ -3901,10 +3317,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_BO_ICEE */ - case 128 + 25: + case SF_BO_ICEE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts an ice bolt.", m_name); bolt(m_idx, GF_ICE, damroll(6, 6) + (rlev)); @@ -3913,10 +3328,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_MISSILE */ - case 128 + 26: + case SF_MISSILE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a magic missile.", m_name); bolt(m_idx, GF_MISSILE, damroll(2, 6) + (rlev / 3)); @@ -3924,10 +3338,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF5_SCARE */ - case 128 + 27: + case SF_SCARE_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles, and you hear scary noises.", m_name); else msg_format("%^s casts a fearful illusion.", m_name); if (p_ptr->resist_fear) @@ -3940,16 +3353,15 @@ static bool_ make_attack_spell(int m_idx) } else { - (void)set_afraid(p_ptr->afraid + rand_int(4) + 4); + set_afraid(p_ptr->afraid + rand_int(4) + 4); } update_smart_learn(m_idx, DRS_FEAR); break; } - /* RF5_BLIND */ - case 128 + 28: + case SF_BLIND_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s casts a spell, burning your eyes!", m_name); if (p_ptr->resist_blind) @@ -3962,16 +3374,15 @@ static bool_ make_attack_spell(int m_idx) } else { - (void)set_blind(12 + rand_int(4)); + set_blind(12 + rand_int(4)); } update_smart_learn(m_idx, DRS_BLIND); break; } - /* RF5_CONF */ - case 128 + 29: + case SF_CONF_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles, and you hear puzzling noises.", m_name); else msg_format("%^s creates a mesmerizing illusion.", m_name); if (p_ptr->resist_conf) @@ -3984,16 +3395,15 @@ static bool_ make_attack_spell(int m_idx) } else { - (void)set_confused(p_ptr->confused + rand_int(4) + 4); + set_confused(p_ptr->confused + rand_int(4) + 4); } update_smart_learn(m_idx, DRS_CONF); break; } - /* RF5_SLOW */ - case 128 + 30: + case SF_SLOW_IDX: { - disturb(1); + disturb(); msg_format("%^s drains power from your muscles!", m_name); if (p_ptr->free_act) { @@ -4005,16 +3415,15 @@ static bool_ make_attack_spell(int m_idx) } else { - (void)set_slow(p_ptr->slow + rand_int(4) + 4); + set_slow(p_ptr->slow + rand_int(4) + 4); } update_smart_learn(m_idx, DRS_FREE); break; } - /* RF5_HOLD */ - case 128 + 31: + case SF_HOLD_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s stares deep into your eyes!", m_name); if (p_ptr->free_act) @@ -4027,18 +3436,15 @@ static bool_ make_attack_spell(int m_idx) } else { - (void)set_paralyzed(rand_int(4) + 4); + set_paralyzed(rand_int(4) + 4); } update_smart_learn(m_idx, DRS_FREE); break; } - - - /* RF6_HASTE */ - case 160 + 0: + case SF_HASTE_IDX: { - disturb(1); + disturb(); if (blind) { msg_format("%^s mumbles.", m_name); @@ -4065,10 +3471,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF6_HAND_DOOM */ - case 160 + 1: + case SF_HAND_DOOM_IDX: { - disturb(1); + disturb(); msg_format("%^s invokes the Hand of Doom!", m_name); if (rand_int(100) < p_ptr->skill_sav) { @@ -4086,10 +3491,9 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF6_HEAL */ - case 160 + 2: + case SF_HEAL_IDX: { - disturb(1); + disturb(); /* Message */ if (blind) @@ -4150,60 +3554,41 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF6_S_ANIMALS */ - case 160 + 3: - { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons some animals!", m_name); - for (k = 0; k < 4; k++) - { - count += summon_specific(y, x, rlev, SUMMON_ANIMAL); - } - if (blind && count) msg_print("You hear something appear nearby."); - break; - } - - /* RF6_BLINK */ - case 160 + 4: + case SF_BLINK_IDX: { - disturb(1); + disturb(); msg_format("%^s blinks away.", m_name); teleport_away(m_idx, 10); break; } - /* RF6_TPORT */ - case 160 + 5: + case SF_TPORT_IDX: { - disturb(1); + disturb(); msg_format("%^s teleports away.", m_name); teleport_away(m_idx, MAX_SIGHT * 2 + 5); break; } - /* RF6_TELE_TO */ - case 160 + 6: + case SF_TELE_TO_IDX: { - disturb(1); + disturb(); msg_format("%^s commands you to return.", m_name); teleport_player_to(m_ptr->fy, m_ptr->fx); break; } - /* RF6_TELE_AWAY */ - case 160 + 7: + case SF_TELE_AWAY_IDX: { - disturb(1); + disturb(); msg_format("%^s teleports you away.", m_name); teleport_player(100); break; } - /* RF6_TELE_LEVEL */ - case 160 + 8: + case SF_TELE_LEVEL_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles strangely.", m_name); else msg_format("%^s gestures at your feet.", m_name); if (p_ptr->resist_nexus) @@ -4222,30 +3607,18 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF6_DARKNESS */ - case 160 + 9: + case SF_DARKNESS_IDX: { - disturb(1); + disturb(); if (blind) msg_format("%^s mumbles.", m_name); else msg_format("%^s gestures in shadow.", m_name); - (void)unlite_area(0, 3); - break; - } - - /* RF6_TRAPS */ - case 160 + 10: - { - disturb(1); - if (blind) msg_format("%^s mumbles, and then cackles evilly.", m_name); - else msg_format("%^s casts a spell and cackles evilly.", m_name); - (void)trap_creation(); + unlite_area(0, 3); break; } - /* RF6_FORGET */ - case 160 + 11: + case SF_FORGET_IDX: { - disturb(1); + disturb(); msg_format("%^s tries to blank your mind.", m_name); if (rand_int(100) < p_ptr->skill_sav) @@ -4259,332 +3632,187 @@ static bool_ make_attack_spell(int m_idx) break; } - /* RF6_ANIM_DEAD */ - case 160 + 12: - break; + case SF_S_ANIMAL_IDX: + { + do_summon("summons an animal!", 1, SUMMON_ANIMAL, blind_msg_default); + break; + } - /* RF6_S_BUG */ - case 160 + 13: + case SF_S_ANIMALS_IDX: + { + do_summon("summons some animals!", 4, SUMMON_ANIMAL, blind_msg_default); + break; + } + + case SF_S_BUG_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically codes some software bugs.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_BUG); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("codes some software bugs.", 6, SUMMON_BUG, blind_msg_default); break; } - /* RF6_S_RNG */ - case 160 + 14: + case SF_S_RNG_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically codes some RNGs.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_RNG); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("codes some RNGs.", 6, SUMMON_RNG, blind_msg_default); break; } - /* RF6_S_THUNDERLORD */ - case 160 + 15: + case SF_S_THUNDERLORD_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons a Thunderlord!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_THUNDERLORD); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons a Thunderlord!", 1, SUMMON_THUNDERLORD, blind_msg_default); break; } - /* RF6_SUMMON_KIN */ - case 160 + 16: + case SF_S_KIN_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons %s %s.", - m_name, m_poss, - ((r_ptr->flags1) & RF1_UNIQUE ? - "minions" : "kin")); - summon_kin_type = r_ptr->d_char; /* Big hack */ - - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_KIN); - } - if (blind && count) msg_print("You hear many things appear nearby."); - + // Describe the summons + char action[256]; + sprintf(action, + "summons %s %s.", + m_poss, + (r_ptr->flags & RF_UNIQUE) ? "minions" : "kin"); + // Force the correct type of "kin" + summon_kin_type = r_ptr->d_char; + // Summon + do_summon(action, 6, SUMMON_KIN, blind_msg_default); break; } - /* RF6_S_HI_DEMON */ - case 160 + 17: + case SF_S_HI_DEMON_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons greater demons!", m_name); - if (blind && count) msg_print("You hear heavy steps nearby."); - summon_cyber(); + do_summon("summons greater demons!", 8, SUMMON_HI_DEMON, blind_msg_default); break; } - /* RF6_S_MONSTER */ - case 160 + 18: + case SF_S_MONSTER_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons help!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, 0); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons help!", 1, 0, blind_msg_default); break; } - /* RF6_S_MONSTERS */ - case 160 + 19: + case SF_S_MONSTERS_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons monsters!", m_name); - for (k = 0; k < 8; k++) - { - count += summon_specific(y, x, rlev, 0); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("summons monsters!", 8, 0, blind_msg_default); break; } - /* RF6_S_ANT */ - case 160 + 20: + case SF_S_ANT_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons ants.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_ANT); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("summons ants.", 6, SUMMON_ANT, blind_msg_default); break; } - /* RF6_S_SPIDER */ - case 160 + 21: + case SF_S_SPIDER_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons spiders.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_SPIDER); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("summons spiders.", 6, SUMMON_SPIDER, blind_msg_default); break; } - /* RF6_S_HOUND */ - case 160 + 22: + case SF_S_HOUND_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons hounds.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_HOUND); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("summons hounds.", 6, SUMMON_HOUND, blind_msg_default); break; } - /* RF6_S_HYDRA */ - case 160 + 23: + case SF_S_HYDRA_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons hydras.", m_name); - for (k = 0; k < 6; k++) - { - count += summon_specific(y, x, rlev, SUMMON_HYDRA); - } - if (blind && count) msg_print("You hear many things appear nearby."); + do_summon("summons hydras.", 6, SUMMON_HYDRA, blind_msg_default); break; } - /* RF6_S_ANGEL */ - case 160 + 24: + case SF_S_ANGEL_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons an angel!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_ANGEL); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons an angel!", 1, SUMMON_ANGEL, blind_msg_default); break; } - /* RF6_S_DEMON */ - case 160 + 25: + case SF_S_DEMON_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons a demon!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_DEMON); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons a demon!", 1, SUMMON_DEMON, blind_msg_default); break; } - /* RF6_S_UNDEAD */ - case 160 + 26: + case SF_S_UNDEAD_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons an undead adversary!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_UNDEAD); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons an undead adversary!", 1, SUMMON_UNDEAD, blind_msg_default); break; } - /* RF6_S_DRAGON */ - case 160 + 27: + case SF_S_DRAGON_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons a dragon!", m_name); - for (k = 0; k < 1; k++) - { - count += summon_specific(y, x, rlev, SUMMON_DRAGON); - } - if (blind && count) msg_print("You hear something appear nearby."); + do_summon("summons a dragon!", 1, SUMMON_DRAGON, blind_msg_default); break; } - /* RF6_S_HI_UNDEAD */ - case 160 + 28: + case SF_S_HI_UNDEAD_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons greater undead!", m_name); - for (k = 0; k < 8; k++) - { - count += summon_specific(y, x, rlev, SUMMON_HI_UNDEAD); - } - if (blind && count) - { - msg_print("You hear many creepy things appear nearby."); - } + summon_messages blind_msg { + "You hear a creepy thing appear nearby.", + "You hear many creepy things appear nearby." + }; + do_summon("summons greater undead!", 8, SUMMON_HI_UNDEAD, blind_msg); break; } - /* RF6_S_HI_DRAGON */ - case 160 + 29: + case SF_S_HI_DRAGON_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons ancient dragons!", m_name); - for (k = 0; k < 8; k++) - { - count += summon_specific(y, x, rlev, SUMMON_HI_DRAGON); - } - if (blind && count) - { - msg_print("You hear many powerful things appear nearby."); - } + summon_messages blind_msg { + "You hear a powerful thing appear nearby.", + "You hear many powerful things appear nearby." + }; + do_summon("summons ancient dragons!", 8, SUMMON_HI_DRAGON, blind_msg); break; } - /* RF6_S_WRAITH */ - case 160 + 30: + case SF_S_WRAITH_IDX: { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons Wraith!", m_name); - + summon_messages blind_msg { + "You hear an immortal being appear nearby.", + "You hear immortal beings appear nearby." + }; + do_summon("summons Wraiths!", 8, SUMMON_WRAITH, blind_msg); + break; + } - for (k = 0; k < 8; k++) + case SF_S_UNIQUE_IDX: + { + // Interrupt + disturb(); + // Message + if (blind) { - count += summon_specific(y, x, rlev, SUMMON_WRAITH); + msg_format("%^s mumbles.", m_name); } - - if (blind && count) + else { - msg_print("You hear immortal beings appear nearby."); + msg_format("%^s magically summons special opponents!", m_name); } - break; - } - - /* RF6_S_UNIQUE */ - case 160 + 31: - { - disturb(1); - if (blind) msg_format("%^s mumbles.", m_name); - else msg_format("%^s magically summons special opponents!", m_name); - for (k = 0; k < 8; k++) + // Summon + int count = 0; + for (int k = 0; k < 8; k++) { - count += summon_specific(y, x, rlev, SUMMON_UNIQUE); + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_UNIQUE); } - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { - count += summon_specific(y, x, rlev, SUMMON_HI_UNDEAD); + count += summon_specific(m_ptr->fy, m_ptr->fx, rlev, SUMMON_HI_UNDEAD); } - if (blind && count) + // Message + if (blind) { - msg_print("You hear many powerful things appear nearby."); + if (count == 1) + { + msg_print("You hear a powerful thing appear nearby."); + } + else if (count > 1) + { + msg_print("You hear many powerful things appear nearby."); + } } break; } } } - /* Remember what the monster did to us */ - if (seen) - { - /* Inate spell */ - if (thrown_spell < 32*4) - { - r_ptr->r_flags4 |= (1L << (thrown_spell - 32 * 3)); - if (r_ptr->r_cast_inate < MAX_UCHAR) r_ptr->r_cast_inate++; - } - - /* Bolt or Ball */ - else if (thrown_spell < 32*5) - { - r_ptr->r_flags5 |= (1L << (thrown_spell - 32 * 4)); - if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++; - } - - /* Special spell */ - else if (thrown_spell < 32*6) - { - r_ptr->r_flags6 |= (1L << (thrown_spell - 32 * 5)); - if (r_ptr->r_cast_spell < MAX_UCHAR) r_ptr->r_cast_spell++; - } - } - - - /* Always take note of monsters that kill you */ - if (death && (r_ptr->r_deaths < MAX_SHORT)) - { - r_ptr->r_deaths++; - } - /* A spell was cast */ return (TRUE); } @@ -4688,7 +3916,10 @@ static int mon_will_run(int m_idx) static bool_ get_fear_moves_aux(int m_idx, int *yp, int *xp) { /* Monster flowing disabled */ - if (!flow_by_sound) return (FALSE); + if (!options->flow_by_sound) + { + return (FALSE); + } /* Monster location */ monster_type *m_ptr = &m_list[m_idx]; @@ -4806,7 +4037,7 @@ static bool_ find_safety(int m_idx, int *yp, int *xp) if (distance(y, x, fy, fx) != d) continue; /* Check for "availability" (if monsters can flow) */ - if (flow_by_sound) + if (options->flow_by_sound) { /* Ignore grids very far from the player */ if (cave[y][x].when < cave[p_ptr->py][p_ptr->px].when) continue; @@ -4924,19 +4155,20 @@ static bool_ find_hiding(int m_idx, int *yp, int *xp) /* Find an appropriate corpse */ void find_corpse(monster_type *m_ptr, int *y, int *x) { + auto const &r_info = game->edit_data.r_info; + int k, last = -1; for (k = 0; k < max_o_idx; k++) { object_type *o_ptr = &o_list[k]; - monster_race *rt_ptr, *rt2_ptr; if (!o_ptr->k_idx) continue; if (o_ptr->tval != TV_CORPSE) continue; if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_SKELETON)) continue; - rt_ptr = &r_info[o_ptr->pval2]; + auto rt_ptr = &r_info[o_ptr->pval2]; /* Cannot incarnate into a higher level monster */ if (rt_ptr->level > m_ptr->level) continue; @@ -4946,9 +4178,16 @@ void find_corpse(monster_type *m_ptr, int *y, int *x) if (last != -1) { - rt2_ptr = &r_info[o_list[last].pval2]; - if (rt_ptr->level > rt2_ptr->level) last = k; - else continue; + auto rt2_ptr = &r_info[o_list[last].pval2]; + + if (rt_ptr->level > rt2_ptr->level) + { + last = k; + } + else + { + continue; + } } else { @@ -4969,6 +4208,8 @@ void find_corpse(monster_type *m_ptr, int *y, int *x) */ static void get_target_monster(int m_idx) { + auto const &r_info = game->edit_data.r_info; + monster_type *m_ptr = &m_list[m_idx]; int i, t = -1, d = 9999; @@ -4978,7 +4219,7 @@ static void get_target_monster(int m_idx) /* Access the monster */ monster_type *t_ptr = &m_list[i]; /* hack should call the function for ego monsters ... but no_target i not meant to be added by ego and it speeds up the code */ - monster_race *rt_ptr = &r_info[t_ptr->r_idx]; + auto rt_ptr = &r_info[t_ptr->r_idx]; int dd; /* Ignore "dead" monsters */ @@ -4987,7 +4228,7 @@ static void get_target_monster(int m_idx) if (m_idx == i) continue; /* Cannot be targeted */ - if (rt_ptr->flags7 & RF7_NO_TARGET) continue; + if (rt_ptr->flags & RF_NO_TARGET) continue; if (is_enemy(m_ptr, t_ptr) && (los(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx) && ((dd = distance(m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) < d))) @@ -5047,13 +4288,13 @@ static bool_ get_moves(int m_idx, int *mm) const auto r_ptr = m_ptr->race(); /* A possessor is not interrested in the player, it only wants a corpse */ - if (r_ptr->flags7 & RF7_POSSESSOR) + if (r_ptr->flags & RF_POSSESSOR) { find_corpse(m_ptr, &y2, &x2); } /* Let quests redefine AI */ - if (r_ptr->flags7 & RF7_AI_SPECIAL) + if (r_ptr->flags & RF_AI_SPECIAL) { struct hook_monster_ai_in in = { m_idx, &m_list[m_idx] }; struct hook_monster_ai_out out = { 0, 0 }; @@ -5066,7 +4307,7 @@ static bool_ get_moves(int m_idx, int *mm) if (m_idx == p_ptr->control) { - if ((r_ptr->flags7 & RF7_AI_PLAYER) || magik(85)) + if ((r_ptr->flags & RF_AI_PLAYER) || magik(85)) { if (distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) < 50) { @@ -5081,7 +4322,7 @@ static bool_ get_moves(int m_idx, int *mm) int x = m_ptr->fx - x2; /* Tease the player */ - if (r_ptr->flags7 & RF7_AI_ANNOY) + if (r_ptr->flags & RF_AI_ANNOY) { if (distance(m_ptr->fy, m_ptr->fx, y2, x2) < 4) { @@ -5091,7 +4332,7 @@ static bool_ get_moves(int m_idx, int *mm) } /* Death orbs .. */ - if (r_ptr->flags2 & RF2_DEATH_ORB) + if (r_ptr->flags & RF_DEATH_ORB) { if (!los(m_ptr->fy, m_ptr->fx, y2, x2)) { @@ -5107,10 +4348,10 @@ static bool_ get_moves(int m_idx, int *mm) * Animal packs try to get the player out of corridors * (...unless they can move through walls -- TY) */ - if ((r_ptr->flags1 & RF1_FRIENDS) && - (r_ptr->flags3 & RF3_ANIMAL) && - !((r_ptr->flags2 & (RF2_PASS_WALL)) || - (r_ptr->flags2 & (RF2_KILL_WALL)))) + if ((r_ptr->flags & RF_FRIENDS) && + (r_ptr->flags & RF_ANIMAL) && + !((r_ptr->flags & RF_PASS_WALL) || + (r_ptr->flags & RF_KILL_WALL))) { int i, room = 0; @@ -5134,7 +4375,7 @@ static bool_ get_moves(int m_idx, int *mm) } /* Monster groups try to surround the player */ - if (!done && (r_ptr->flags1 & RF1_FRIENDS)) + if (!done && (r_ptr->flags & RF_FRIENDS)) { int i; @@ -5194,10 +4435,10 @@ static bool_ get_moves(int m_idx, int *mm) else { /* Attempt to avoid the player */ - if (flow_by_sound) + if (options->flow_by_sound) { /* Adjust movement */ - (void)get_fear_moves_aux(m_idx, &y, &x); + get_fear_moves_aux(m_idx, &y, &x); } } } @@ -5417,7 +4658,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) const auto tr_ptr = t_ptr->race(); /* Not allowed to attack */ - if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE; + if (r_ptr->flags & RF_NEVER_BLOW) return FALSE; /* Total armor */ const int ac = t_ptr->ac; @@ -5448,9 +4689,6 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) /* Scan through all four blows */ for (int ap_cnt = 0; ap_cnt < 4; ap_cnt++) { - bool_ visible = FALSE; - bool_ obvious = FALSE; - int power = 0; int damage = 0; @@ -5481,9 +4719,6 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) /* break; */ } - /* Extract visibility (before blink) */ - if (m_ptr->ml) visible = TRUE; - /* Extract the attack "power" */ power = get_attack_power(effect); @@ -5492,7 +4727,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) if (!effect || check_hit2(power, rlev, ac)) { /* Always disturbing */ - if (disturb_other) disturb(1); + disturb_on_other(); /* Describe the attack method */ switch (method) @@ -5679,9 +4914,6 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) } - /* Hack -- assume all attacks are obvious */ - obvious = TRUE; - /* Roll out the damage */ damage = damroll(d_dice, d_side); @@ -5838,15 +5070,13 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) 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 (m_ptr->ml || t_ptr->ml) { blinked = FALSE; monster_msg("%^s is suddenly very hot!", m_name); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_FIRE; } project(t_idx, 0, m_ptr->fy, m_ptr->fx, damroll (1 + ((t_ptr->level) / 26), @@ -5855,14 +5085,12 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) } /* 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 (m_ptr->ml || t_ptr->ml) { blinked = FALSE; monster_msg("%^s gets zapped!", m_name); - if (t_ptr->ml) - tr_ptr->r_flags2 |= RF2_AURA_ELEC; } project(t_idx, 0, m_ptr->fy, m_ptr->fx, damroll (1 + ((t_ptr->level) / 26), @@ -5897,7 +5125,7 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) if (m_ptr->ml) { /* Disturbing */ - disturb(1); + disturb(); /* Message */ monster_msg("%^s misses %s.", m_name, t_name); @@ -5907,26 +5135,10 @@ static bool_ monst_attack_monst(int m_idx, int t_idx) } } } - - - /* 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]++; - } - } - } } if (explode) { - sound(SOUND_EXPLODE); mon_take_hit_mon(m_idx, m_idx, m_ptr->hp + 1, &fear, " explodes into tiny shreds."); blinked = FALSE; @@ -5964,27 +5176,27 @@ static bool_ player_invis(monster_type * m_ptr) s16b inv = p_ptr->invis; s16b mlv = m_ptr->level; - if (r_ptr->flags3 & RF3_NO_SLEEP) + if (r_ptr->flags & RF_NO_SLEEP) mlv += 10; - if (r_ptr->flags3 & RF3_DRAGON) + if (r_ptr->flags & RF_DRAGON) mlv += 20; - if (r_ptr->flags3 & RF3_UNDEAD) + if (r_ptr->flags & RF_UNDEAD) mlv += 15; - if (r_ptr->flags3 & RF3_DEMON) + if (r_ptr->flags & RF_DEMON) mlv += 15; - if (r_ptr->flags3 & RF3_ANIMAL) + if (r_ptr->flags & RF_ANIMAL) mlv += 15; - if (r_ptr->flags3 & RF3_ORC) + if (r_ptr->flags & RF_ORC) mlv -= 15; - if (r_ptr->flags3 & RF3_TROLL) + if (r_ptr->flags & RF_TROLL) mlv -= 10; - if (r_ptr->flags2 & RF2_STUPID) + if (r_ptr->flags & RF_STUPID) mlv /= 2; - if (r_ptr->flags2 & RF2_SMART) + if (r_ptr->flags & RF_SMART) mlv = (mlv * 5) / 4; if (m_ptr->mflag & MFLAG_QUEST) inv = 0; - if (r_ptr->flags2 & RF2_INVISIBLE) + if (r_ptr->flags & RF_INVISIBLE) inv = 0; if (m_ptr->mflag & MFLAG_CONTROL) inv = 0; @@ -6021,6 +5233,8 @@ static bool_ player_invis(monster_type * m_ptr) */ static void process_monster(int m_idx, bool_ is_frien) { + auto const &f_info = game->edit_data.f_info; + int i, d, oy, ox, ny, nx; int mm[8]; @@ -6029,7 +5243,7 @@ static void process_monster(int m_idx, bool_ is_frien) const bool_ inv = player_invis(m_ptr); auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = m_idx; + if (r_ptr->flags & RF_DOPPLEGANGER) doppleganger = m_idx; /* Handle "bleeding" */ if (m_ptr->bleeding) @@ -6136,18 +5350,7 @@ static void process_monster(int m_idx, bool_ is_frien) { /* Monster wakes up "a little bit" */ m_ptr->csleep -= d; - - /* Notice the "not waking up" */ - if (m_ptr->ml) - { - /* Hack -- Count the ignores */ - if (r_ptr->r_ignore < MAX_UCHAR) - { - r_ptr->r_ignore++; - } - } } - /* Just woke up */ else { @@ -6164,12 +5367,6 @@ static void process_monster(int m_idx, bool_ is_frien) /* Dump a message */ msg_format("%^s wakes up.", m_name); - - /* Hack -- Count the wakings */ - if (r_ptr->r_wake < MAX_UCHAR) - { - r_ptr->r_wake++; - } } } } @@ -6259,12 +5456,12 @@ static void process_monster(int m_idx, bool_ is_frien) bool_ gets_angry = FALSE; /* No one wants to be your friend if you're aggravating */ - if ((m_ptr->status > MSTATUS_NEUTRAL) && (m_ptr->status < MSTATUS_COMPANION) && (p_ptr->aggravate) && !(r_ptr->flags7 & RF7_PET)) + if ((m_ptr->status > MSTATUS_NEUTRAL) && (m_ptr->status < MSTATUS_COMPANION) && (p_ptr->aggravate) && !(r_ptr->flags & RF_PET)) gets_angry = TRUE; /* Paranoia... no friendly uniques outside wizard mode -- TY */ if ((m_ptr->status > MSTATUS_NEUTRAL) && (m_ptr->status < MSTATUS_COMPANION) && !(wizard) && - (r_ptr->flags1 & (RF1_UNIQUE)) && !(r_ptr->flags7 & RF7_PET)) + (r_ptr->flags & RF_UNIQUE) && !(r_ptr->flags & RF_PET)) gets_angry = TRUE; if (gets_angry) @@ -6320,17 +5517,17 @@ static void process_monster(int m_idx, bool_ is_frien) ox = m_ptr->fx; /* Attempt to "multiply" if able and allowed */ - if ((r_ptr->flags4 & (RF4_MULTIPLY)) && (num_repro < MAX_REPRO)) + if ((r_ptr->spells & SF_MULTIPLY) && (num_repro < MAX_REPRO)) { if (ai_multiply(m_idx)) return; } if (randint(SPEAK_CHANCE) == 1) { - if (player_has_los_bold(oy, ox) && (r_ptr->flags2 & RF2_CAN_SPEAK)) + if (player_has_los_bold(oy, ox) && (r_ptr->flags & RF_CAN_SPEAK)) { char m_name[80]; - char monmessage[80]; + char monmessage[1024]; /* Acquire the monster name/poss */ if (m_ptr->ml) @@ -6394,36 +5591,26 @@ static void process_monster(int m_idx, bool_ is_frien) } /* 75% random movement */ - else if ((r_ptr->flags1 & (RF1_RAND_50)) && - (r_ptr->flags1 & (RF1_RAND_25)) && + else if ((r_ptr->flags & RF_RAND_50) && + (r_ptr->flags & RF_RAND_25) && (rand_int(100) < 75)) { - /* Memorize flags */ - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50); - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_25); - /* Try four "random" directions */ mm[0] = mm[1] = mm[2] = mm[3] = 5; } /* 50% random movement */ - else if ((r_ptr->flags1 & (RF1_RAND_50)) && + else if ((r_ptr->flags & RF_RAND_50) && (rand_int(100) < 50)) { - /* Memorize flags */ - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_50); - /* Try four "random" directions */ mm[0] = mm[1] = mm[2] = mm[3] = 5; } /* 25% random movement */ - else if ((r_ptr->flags1 & (RF1_RAND_25)) && + else if ((r_ptr->flags & RF_RAND_25) && (rand_int(100) < 25)) { - /* Memorize flags */ - if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_RAND_25); - /* Try four "random" directions */ mm[0] = mm[1] = mm[2] = mm[3] = 5; } @@ -6447,12 +5634,6 @@ static void process_monster(int m_idx, bool_ is_frien) /* Assume nothing */ bool_ did_open_door = FALSE; bool_ did_bash_door = FALSE; - bool_ did_take_item = FALSE; - bool_ did_kill_item = FALSE; - bool_ did_move_body = FALSE; - bool_ did_kill_body = FALSE; - bool_ did_pass_wall = FALSE; - bool_ did_kill_wall = FALSE; /* Take a zero-terminated array of "directions" */ for (i = 0; mm[i]; i++) @@ -6481,16 +5662,9 @@ static void process_monster(int m_idx, bool_ is_frien) do_move = TRUE; } - /* Floor is trapped? */ - else if (c_ptr->feat == FEAT_MON_TRAP) - { - /* Go ahead and move */ - do_move = TRUE; - } - /* Hack -- check for Glyph of Warding */ if ((c_ptr->feat == FEAT_GLYPH) && - !(r_ptr->flags1 & RF1_NEVER_BLOW)) + !(r_ptr->flags & RF_NEVER_BLOW)) { /* Assume no move allowed */ do_move = FALSE; @@ -6516,7 +5690,7 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Hack -- trees are obstacle */ - else if ((cave[ny][nx].feat == FEAT_TREES) && (r_ptr->flags9 & RF9_KILL_TREES)) + else if ((cave[ny][nx].feat == FEAT_TREES) && (r_ptr->flags & RF_KILL_TREES)) { do_move = TRUE; @@ -6540,45 +5714,39 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Permanent wall */ - else if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) + else if (f_info[c_ptr->feat].flags & FF_PERMANENT) { /* Nothing */ } /* Some monsters can fly */ - else if ((f_info[c_ptr->feat].flags1 & FF1_CAN_LEVITATE) && (r_ptr->flags7 & (RF7_CAN_FLY))) + else if ((f_info[c_ptr->feat].flags & FF_CAN_LEVITATE) && (r_ptr->flags & RF_CAN_FLY)) { /* Pass through walls/doors/rubble */ do_move = TRUE; } /* Some monsters can fly */ - else if ((f_info[c_ptr->feat].flags1 & FF1_CAN_FLY) && (r_ptr->flags7 & (RF7_CAN_FLY))) + else if ((f_info[c_ptr->feat].flags & FF_CAN_FLY) && (r_ptr->flags & RF_CAN_FLY)) { /* Pass through trees/... */ do_move = TRUE; } /* Monster moves through walls (and doors) */ - else if ((f_info[c_ptr->feat].flags1 & FF1_CAN_PASS) && (r_ptr->flags2 & (RF2_PASS_WALL))) + else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_PASS_WALL)) { /* Pass through walls/doors/rubble */ do_move = TRUE; - - /* Monster went through a wall */ - did_pass_wall = TRUE; } /* Monster destroys walls (and doors) */ - else if ((f_info[c_ptr->feat].flags1 & FF1_CAN_PASS) && (r_ptr->flags2 & (RF2_KILL_WALL))) + else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_KILL_WALL)) { /* Eat through walls/doors/rubble */ do_move = TRUE; - /* Monster destroyed a wall */ - did_kill_wall = TRUE; - if (randint(GRINDNOISE) == 1) { msg_print("There is a grinding sound."); @@ -6595,18 +5763,15 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Monster moves through walls (and doors) */ - else if ((f_info[c_ptr->feat].flags1 & FF1_CAN_PASS) && (r_ptr->flags2 & (RF2_PASS_WALL))) + else if ((f_info[c_ptr->feat].flags & FF_CAN_PASS) && (r_ptr->flags & RF_PASS_WALL)) { /* Pass through walls/doors/rubble */ do_move = TRUE; - - /* Monster went through a wall */ - did_pass_wall = TRUE; } /* Monster moves through webs */ - else if ((f_info[c_ptr->feat].flags1 & FF1_WEB) && - (r_ptr->flags7 & RF7_SPIDER)) + else if ((f_info[c_ptr->feat].flags & FF_WEB) && + (r_ptr->flags & RF_SPIDER)) { /* Pass through webs */ do_move = TRUE; @@ -6622,7 +5787,7 @@ static void process_monster(int m_idx, bool_ is_frien) /* Take a turn */ do_turn = TRUE; - if ((r_ptr->flags2 & (RF2_OPEN_DOOR)) && + if ((r_ptr->flags & RF_OPEN_DOOR) && ((is_friend(m_ptr) <= 0) || p_ptr->pet_open_doors)) { /* Closed doors and secret doors */ @@ -6657,7 +5822,7 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Stuck doors -- attempt to bash them down if allowed */ - if (may_bash && (r_ptr->flags2 & RF2_BASH_DOOR) && + if (may_bash && (r_ptr->flags & RF_BASH_DOOR) && ((is_friend(m_ptr) <= 0) || p_ptr->pet_open_doors)) { int k; @@ -6672,7 +5837,10 @@ static void process_monster(int m_idx, bool_ is_frien) msg_print("You hear a door burst open!"); /* Disturb (sometimes) */ - if (disturb_minor) disturb(0); + if (options->disturb_minor) + { + disturb(); + } /* The door was bashed open */ did_bash_door = TRUE; @@ -6706,7 +5874,7 @@ static void process_monster(int m_idx, bool_ is_frien) } } else if (do_move && (c_ptr->feat == FEAT_MINOR_GLYPH) - && !(r_ptr->flags1 & RF1_NEVER_BLOW)) + && !(r_ptr->flags & RF_NEVER_BLOW)) { /* Assume no move allowed */ do_move = FALSE; @@ -6751,7 +5919,7 @@ static void process_monster(int m_idx, bool_ is_frien) /* Access that cave grid's contents */ y_ptr = &m_list[c_ptr->m_idx]; - if (!(r_ptr->flags3 & RF3_IM_COLD)) + if (!(r_ptr->flags & RF_IM_COLD)) { if ((m_ptr->hp - distance(ny, nx, oy, ox)*2) <= 0) { @@ -6791,7 +5959,7 @@ static void process_monster(int m_idx, bool_ is_frien) /* Some monsters never attack */ if (do_move && (ny == p_ptr->py) && (nx == p_ptr->px) && - (r_ptr->flags1 & RF1_NEVER_BLOW)) + (r_ptr->flags & RF_NEVER_BLOW)) { /* Do not move */ do_move = FALSE; @@ -6801,7 +5969,7 @@ static void process_monster(int m_idx, bool_ is_frien) if (do_move && (ny == p_ptr->py) && (nx == p_ptr->px)) { /* Do the attack */ - (void)make_attack_normal(m_idx, 1); + make_attack_normal(m_idx, 1); /* Do not move */ do_move = FALSE; @@ -6828,12 +5996,12 @@ static void process_monster(int m_idx, bool_ is_frien) do_move = FALSE; /* Kill weaker monsters */ - if ((r_ptr->flags2 & RF2_KILL_BODY) && + if ((r_ptr->flags & RF_KILL_BODY) && (r_ptr->mexp > z_ptr->mexp) && (cave_floor_bold(ny, nx)) && /* Friends don't kill friends... */ !((is_friend(m_ptr) > 0) && (is_friend(m2_ptr) > 0)) && /* Uniques aren't faceless monsters in a crowd */ - !(z_ptr->flags1 & RF1_UNIQUE) && + !(z_ptr->flags & RF_UNIQUE) && /* Don't wreck quests */ !(m2_ptr->mflag & (MFLAG_QUEST | MFLAG_QUEST2)) && /* Don't punish summoners for relying on their friends */ @@ -6842,11 +6010,6 @@ static void process_monster(int m_idx, bool_ is_frien) /* Allow movement */ do_move = TRUE; - /* Monster ate another monster */ - did_kill_body = TRUE; - - /* XXX XXX XXX Message */ - /* Kill the monster */ delete_monster(ny, nx); @@ -6872,17 +6035,12 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Push past weaker monsters (unless leaving a wall) */ - else if ((r_ptr->flags2 & RF2_MOVE_BODY) && + else if ((r_ptr->flags & RF_MOVE_BODY) && (r_ptr->mexp > z_ptr->mexp) && cave_floor_bold(ny, nx) && (cave_floor_bold(m_ptr->fy, m_ptr->fx))) { /* Allow movement */ do_move = TRUE; - - /* Monster pushed past another monster */ - did_move_body = TRUE; - - /* XXX XXX XXX Message */ } } @@ -6899,11 +6057,8 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Some monsters never move */ - if (do_move && (r_ptr->flags1 & RF1_NEVER_MOVE)) + if (do_move && (r_ptr->flags & RF_NEVER_MOVE)) { - /* Hack -- memorize lack of attacks */ - /* if (m_ptr->ml) r_ptr->r_flags1 |= (RF1_NEVER_MOVE); */ - /* Do not move */ do_move = FALSE; } @@ -6966,150 +6121,130 @@ static void process_monster(int m_idx, bool_ is_frien) } /* Possible disturb */ - if (m_ptr->ml && (disturb_move || + if (m_ptr->ml && (options->disturb_move || ((m_ptr->mflag & (MFLAG_VIEW)) && - disturb_near))) + options->disturb_near))) { /* Disturb */ - if ((is_friend(m_ptr) < 0) || disturb_pets) - disturb(0); - } - - /* Check for monster trap */ - if (c_ptr->feat == FEAT_MON_TRAP) - { - if (mon_hit_trap(m_idx)) return; + if ((is_friend(m_ptr) < 0) || options->disturb_pets) + disturb(); } - else - { - /* Copy list of objects; we need a copy because we're mutating the list. */ - auto const object_idxs(c_ptr->o_idxs); - - /* Scan all objects in the grid */ - for (auto const this_o_idx: object_idxs) - { - /* Acquire object */ - object_type * o_ptr = &o_list[this_o_idx]; - /* Skip gold */ - if (o_ptr->tval == TV_GOLD) continue; - /* Incarnate ? */ - if ((o_ptr->tval == TV_CORPSE) && (r_ptr->flags7 & RF7_POSSESSOR) && - ((o_ptr->sval == SV_CORPSE_CORPSE) || (o_ptr->sval == SV_CORPSE_SKELETON))) - { - if (ai_possessor(m_idx, this_o_idx)) return; - } - - /* Take or Kill objects on the floor */ - /* rr9: Pets will no longer pick up/destroy items */ - if ((((r_ptr->flags2 & (RF2_TAKE_ITEM)) && - ((is_friend(m_ptr) <= 0) || p_ptr->pet_pickup_items)) || - (r_ptr->flags2 & (RF2_KILL_ITEM))) && - (is_friend(m_ptr) <= 0)) - { - u32b f1, f2, f3, f4, f5, esp; + /* Copy list of objects; we need a copy because we're mutating the list. */ + auto const object_idxs(c_ptr->o_idxs); - u32b flg3 = 0L; + /* Scan all objects in the grid */ + for (auto const this_o_idx: object_idxs) + { + /* Acquire object */ + object_type * o_ptr = &o_list[this_o_idx]; - char m_name[80]; - char o_name[80]; + /* Skip gold */ + if (o_ptr->tval == TV_GOLD) continue; - /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + /* Incarnate ? */ + if ((o_ptr->tval == TV_CORPSE) && (r_ptr->flags & RF_POSSESSOR) && + ((o_ptr->sval == SV_CORPSE_CORPSE) || (o_ptr->sval == SV_CORPSE_SKELETON))) + { + if (ai_possessor(m_idx, this_o_idx)) return; + } - /* Acquire the object name */ - object_desc(o_name, o_ptr, TRUE, 3); + /* Take or Kill objects on the floor */ + /* rr9: Pets will no longer pick up/destroy items */ + if ((((r_ptr->flags & RF_TAKE_ITEM) && + ((is_friend(m_ptr) <= 0) || p_ptr->pet_pickup_items)) || + (r_ptr->flags & RF_KILL_ITEM)) && + (is_friend(m_ptr) <= 0)) + { + char m_name[80]; + char o_name[80]; - /* Acquire the monster name */ - monster_desc(m_name, m_ptr, 0x04); + /* Extract some flags */ + auto const flags = object_flags(o_ptr); - /* React to objects that hurt the monster */ - if (f5 & (TR5_KILL_DEMON)) flg3 |= (RF3_DEMON); - if (f5 & (TR5_KILL_UNDEAD)) flg3 |= (RF3_UNDEAD); - if (f1 & (TR1_SLAY_DRAGON)) flg3 |= (RF3_DRAGON); - if (f1 & (TR1_SLAY_TROLL)) flg3 |= (RF3_TROLL); - if (f1 & (TR1_SLAY_GIANT)) flg3 |= (RF3_GIANT); - if (f1 & (TR1_SLAY_ORC)) flg3 |= (RF3_ORC); - if (f1 & (TR1_SLAY_DEMON)) flg3 |= (RF3_DEMON); - if (f1 & (TR1_SLAY_UNDEAD)) flg3 |= (RF3_UNDEAD); - if (f1 & (TR1_SLAY_ANIMAL)) flg3 |= (RF3_ANIMAL); - if (f1 & (TR1_SLAY_EVIL)) flg3 |= (RF3_EVIL); + /* Acquire the object name */ + object_desc(o_name, o_ptr, TRUE, 3); - /* The object cannot be picked up by the monster */ - if (artifact_p(o_ptr) || (r_ptr->flags3 & flg3) || - (o_ptr->art_name)) + /* Acquire the monster name */ + monster_desc(m_name, m_ptr, 0x04); + + /* React to objects that hurt the monster */ + monster_race_flag_set flg; + if (flags & TR_KILL_DEMON) flg |= RF_DEMON; + if (flags & TR_KILL_UNDEAD) flg |= RF_UNDEAD; + if (flags & TR_SLAY_DRAGON) flg |= RF_DRAGON; + if (flags & TR_SLAY_TROLL) flg |= RF_TROLL; + if (flags & TR_SLAY_GIANT) flg |= RF_GIANT; + if (flags & TR_SLAY_ORC) flg |= RF_ORC; + if (flags & TR_SLAY_DEMON) flg |= RF_DEMON; + if (flags & TR_SLAY_UNDEAD) flg |= RF_UNDEAD; + if (flags & TR_SLAY_ANIMAL) flg |= RF_ANIMAL; + if (flags & TR_SLAY_EVIL) flg |= RF_EVIL; + + /* The object cannot be picked up by the monster */ + if (artifact_p(o_ptr) || (r_ptr->flags & flg)) + { + /* Only give a message for "take_item" */ + if (r_ptr->flags & RF_TAKE_ITEM) { - /* Only give a message for "take_item" */ - if (r_ptr->flags2 & (RF2_TAKE_ITEM)) + /* Describe observable situations */ + if (m_ptr->ml && player_has_los_bold(ny, nx)) { - /* Take note */ - did_take_item = TRUE; - - /* Describe observable situations */ - if (m_ptr->ml && player_has_los_bold(ny, nx)) - { - /* Dump a message */ - msg_format("%^s tries to pick up %s, but fails.", - m_name, o_name); - } + /* Dump a message */ + msg_format("%^s tries to pick up %s, but fails.", + m_name, o_name); } } + } - /* Pick up the item */ - else if (r_ptr->flags2 & (RF2_TAKE_ITEM)) + /* Pick up the item */ + else if (r_ptr->flags & RF_TAKE_ITEM) + { + /* Describe observable situations */ + if (player_has_los_bold(ny, nx)) { - /* Take note */ - did_take_item = TRUE; - - /* Describe observable situations */ - if (player_has_los_bold(ny, nx)) - { - /* Dump a message */ - msg_format("%^s picks up %s.", m_name, o_name); - } + /* Dump a message */ + msg_format("%^s picks up %s.", m_name, o_name); + } - /* Put into inventory of monster */ - { - /* Excise the object */ - excise_object_idx(this_o_idx); + /* Put into inventory of monster */ + { + /* Excise the object */ + excise_object_idx(this_o_idx); - /* Forget mark */ - o_ptr->marked = FALSE; + /* Forget mark */ + o_ptr->marked = FALSE; - /* Forget location */ - o_ptr->iy = o_ptr->ix = 0; + /* Forget location */ + o_ptr->iy = o_ptr->ix = 0; - /* Memorize monster */ - o_ptr->held_m_idx = m_idx; + /* Memorize monster */ + o_ptr->held_m_idx = m_idx; - /* Carry object */ - m_ptr->hold_o_idxs.push_back(this_o_idx); - } + /* Carry object */ + m_ptr->hold_o_idxs.push_back(this_o_idx); } + } - /* Destroy the item */ - else + /* Destroy the item */ + else + { + /* Describe observable situations */ + if (player_has_los_bold(ny, nx)) { - /* Take note */ - did_kill_item = TRUE; - - /* Describe observable situations */ - if (player_has_los_bold(ny, nx)) - { - /* Dump a message */ - msg_format("%^s crushes %s.", m_name, o_name); - } - - /* Delete the object */ - delete_object_idx(this_o_idx); + /* Dump a message */ + msg_format("%^s crushes %s.", m_name, o_name); } + + /* Delete the object */ + delete_object_idx(this_o_idx); } } } /* Update monster light */ - if (r_ptr->flags9 & RF9_HAS_LITE) p_ptr->update |= (PU_MON_LITE); + if (r_ptr->flags & RF_HAS_LITE) p_ptr->update |= (PU_MON_LITE); } /* Stop when done */ @@ -7134,35 +6269,6 @@ static void process_monster(int m_idx, bool_ is_frien) } - /* Learn things from observable monster */ - if (m_ptr->ml) - { - /* Monster opened a door */ - if (did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR); - - /* Monster bashed a door */ - if (did_bash_door) r_ptr->r_flags2 |= (RF2_BASH_DOOR); - - /* Monster tried to pick something up */ - if (did_take_item) r_ptr->r_flags2 |= (RF2_TAKE_ITEM); - - /* Monster tried to crush something */ - if (did_kill_item) r_ptr->r_flags2 |= (RF2_KILL_ITEM); - - /* Monster pushed past another monster */ - if (did_move_body) r_ptr->r_flags2 |= (RF2_MOVE_BODY); - - /* Monster ate another monster */ - if (did_kill_body) r_ptr->r_flags2 |= (RF2_KILL_BODY); - - /* Monster passed through a wall */ - if (did_pass_wall) r_ptr->r_flags2 |= (RF2_PASS_WALL); - - /* Monster destroyed a wall */ - if (did_kill_wall) r_ptr->r_flags2 |= (RF2_KILL_WALL); - } - - /* Hack -- get "bold" if out of options */ if (!do_turn && !do_move && m_ptr->monfear) { @@ -7259,8 +6365,10 @@ void summon_maint(int m_idx) * changes (flags, attacks, spells), we induce a redraw of the monster * recall window. */ -void process_monsters(void) +void process_monsters() { + auto const &r_info = game->edit_data.r_info; + int i, e; int fx, fy; @@ -7269,56 +6377,10 @@ void process_monsters(void) monster_type *m_ptr; - int old_monster_race_idx; - - u32b old_r_flags1 = 0L; - u32b old_r_flags2 = 0L; - u32b old_r_flags3 = 0L; - u32b old_r_flags4 = 0L; - u32b old_r_flags5 = 0L; - u32b old_r_flags6 = 0L; - - byte old_r_blows0 = 0; - byte old_r_blows1 = 0; - byte old_r_blows2 = 0; - byte old_r_blows3 = 0; - - byte old_r_cast_inate = 0; - byte old_r_cast_spell = 0; - /* Check the doppleganger */ - if (doppleganger && !(r_info[m_list[doppleganger].r_idx].flags9 & RF9_DOPPLEGANGER)) + if (doppleganger && !(r_info[m_list[doppleganger].r_idx].flags & RF_DOPPLEGANGER)) doppleganger = 0; - /* Memorize old race */ - old_monster_race_idx = monster_race_idx; - - /* Acquire knowledge */ - if (monster_race_idx) - { - /* Acquire current monster */ - monster_race *r_ptr = &r_info[monster_race_idx]; - - /* Memorize flags */ - old_r_flags1 = r_ptr->r_flags1; - old_r_flags2 = r_ptr->r_flags2; - old_r_flags3 = r_ptr->r_flags3; - old_r_flags4 = r_ptr->r_flags4; - old_r_flags5 = r_ptr->r_flags5; - old_r_flags6 = r_ptr->r_flags6; - - /* Memorize blows */ - old_r_blows0 = r_ptr->r_blows[0]; - old_r_blows1 = r_ptr->r_blows[1]; - old_r_blows2 = r_ptr->r_blows[2]; - old_r_blows3 = r_ptr->r_blows[3]; - - /* Memorize castings */ - old_r_cast_inate = r_ptr->r_cast_inate; - old_r_cast_spell = r_ptr->r_cast_spell; - } - - /* Hack -- calculate the "player noise" */ noise = (1L << (30 - p_ptr->skill_stl)); @@ -7411,7 +6473,7 @@ void process_monsters(void) /* Hack -- Monsters can "smell" the player from far away */ /* Note that most monsters have "aaf" of "20" or so */ - else if (flow_by_sound && + else if (options->flow_by_sound && (cave[p_ptr->py][p_ptr->px].when == cave[fy][fx].when) && (cave[fy][fx].cost < MONSTER_FLOW_DEPTH) && (cave[fy][fx].cost < r_ptr->aaf)) @@ -7446,30 +6508,4 @@ void process_monsters(void) /* Reset global index */ hack_m_idx = 0; - - - /* Tracking a monster race (the same one we were before) */ - if (monster_race_idx && (monster_race_idx == old_monster_race_idx)) - { - /* Acquire monster race */ - monster_race *r_ptr = &r_info[monster_race_idx]; - - /* Check for knowledge change */ - if ((old_r_flags1 != r_ptr->r_flags1) || - (old_r_flags2 != r_ptr->r_flags2) || - (old_r_flags3 != r_ptr->r_flags3) || - (old_r_flags4 != r_ptr->r_flags4) || - (old_r_flags5 != r_ptr->r_flags5) || - (old_r_flags6 != r_ptr->r_flags6) || - (old_r_blows0 != r_ptr->r_blows[0]) || - (old_r_blows1 != r_ptr->r_blows[1]) || - (old_r_blows2 != r_ptr->r_blows[2]) || - (old_r_blows3 != r_ptr->r_blows[3]) || - (old_r_cast_inate != r_ptr->r_cast_inate) || - (old_r_cast_spell != r_ptr->r_cast_spell)) - { - /* Window stuff */ - p_ptr->window |= (PW_MONSTER); - } - } } diff --git a/src/melee2.hpp b/src/melee2.hpp index fece0564..d5106850 100644 --- a/src/melee2.hpp +++ b/src/melee2.hpp @@ -4,9 +4,9 @@ #include "monster_type_fwd.hpp" extern int monst_spell_monst_spell; -extern bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note); -extern void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear); -extern int check_hit2(int power, int level, int ac); -extern void process_monsters(void); -extern void curse_equipment(int chance, int heavy_chance); -extern void curse_equipment_dg(int chance, int heavy_chance); +bool_ mon_take_hit_mon(int s_idx, int m_idx, int dam, bool_ *fear, cptr note); +void mon_handle_fear(monster_type *m_ptr, int dam, bool_ *fear); +int check_hit2(int power, int level, int ac); +void process_monsters(); +void curse_equipment(int chance, int heavy_chance); +void curse_equipment_dg(int chance, int heavy_chance); diff --git a/src/message.cc b/src/message.cc new file mode 100644 index 00000000..a0f46f22 --- /dev/null +++ b/src/message.cc @@ -0,0 +1,15 @@ +#include "message.hpp" + +#include <fmt/format.h> + +std::string message::text_with_count() const +{ + if (count > 1) + { + return fmt::format("{} <{}x>", text, count); + } + else + { + return text; + } +} diff --git a/src/message.hpp b/src/message.hpp new file mode 100644 index 00000000..7b47a9db --- /dev/null +++ b/src/message.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "h-basic.h" + +#include <string> + +/** + * Message + */ +struct message { + /** + * Message color. + */ + byte color = 0; + + /** + * Repetation count for this message. + */ + u32b count = 0; + + /** + * Message text. + */ + std::string text; + + /** + * Get message text with count + */ + std::string text_with_count() const; + +}; diff --git a/src/messages.cc b/src/messages.cc index a4ce949d..071dc66e 100644 --- a/src/messages.cc +++ b/src/messages.cc @@ -1,368 +1,53 @@ #include "messages.hpp" -#include "tome/make_array.hpp" +#include "game.hpp" -#include "z-term.h" -#include "z-form.h" -#include "z-util.h" +#include <fmt/format.h> +#include <string> -/* - * OPTION: Maximum number of messages to remember (see "io.c") - * Default: assume maximal memorization of 2048 total messages - */ -#define MESSAGE_MAX 2048 - -/* - * OPTION: Maximum space for the message text buffer (see "io.c") - * Default: assume that each of the 2048 messages is repeated an - * average of three times, and has an average length of 48 - */ -#define MESSAGE_BUF 32768 - - - - -/* - * The next "free" index to use - */ -static u16b message__next; - -/* - * The index of the oldest message (none yet) - */ -static u16b message__last; - -/* - * The next "free" offset - */ -static u16b message__head; - -/* - * The offset to the oldest used char (none yet) - */ -static u16b message__tail; - -/* - * The array of offsets, by index [MESSAGE_MAX] - */ -static u16b *message__ptr; - -/* - * The array of colors, by index [MESSAGE_MAX] - */ -static byte *message__color; - -/* - * The array of message counts, by index [MESSAGE_MAX] - */ -static u16b *message__count; - -/* - * The array of chars, by offset [MESSAGE_BUF] - */ -static char *message__buf; - - -/* -* Second try for the "message" handling routines. -* -* Each call to "message_add(s)" will add a new "most recent" message -* to the "message recall list", using the contents of the string "s". -* -* The messages will be stored in such a way as to maximize "efficiency", -* that is, we attempt to maximize the number of sequential messages that -* can be retrieved, given a limited amount of storage space. -* -* We keep a buffer of chars to hold the "text" of the messages, not -* necessarily in "order", and an array of offsets into that buffer, -* representing the actual messages. This is made more complicated -* by the fact that both the array of indexes, and the buffer itself, -* are both treated as "circular arrays" for efficiency purposes, but -* the strings may not be "broken" across the ends of the array. -* -* The "message_add()" function is rather "complex", because it must be -* extremely efficient, both in space and time, for use with the Borg. -*/ - -void message_init() +s16b Messages::size() const { - /* Message variables */ - message__ptr = make_array<u16b>(MESSAGE_MAX); - message__color = make_array<byte>(MESSAGE_MAX); - message__count = make_array<u16b>(MESSAGE_MAX); - message__buf = make_array<char>(MESSAGE_BUF); - - /* Hack -- No messages yet */ - message__tail = MESSAGE_BUF; + return buffer.size(); } -/* -* How many messages are "available"? -*/ -s16b message_num(void) +message const &Messages::at(int age) const { - int last, next, n; - - /* Extract the indexes */ - last = message__last; - next = message__next; + assert(age >= 0); + assert(age < size()); - /* Handle "wrap" */ - if (next < last) next += MESSAGE_MAX; + // Age indexes backward through history and is zero-based, so... + std::size_t i = buffer.size() - 1 - age; - /* Extract the space */ - n = (next - last); - - /* Return the result */ - return (n); + // Get the message + return buffer.at(i); } - - -/* -* Recall the "text" of a saved message -*/ -cptr message_str(int age) +void Messages::add(cptr msg, byte color) { - static char buf[1024]; - s16b x; - s16b o; - cptr s; - - /* Forgotten messages have no text */ - if ((age < 0) || (age >= message_num())) return (""); - - /* Acquire the "logical" index */ - x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX; - - /* Get the "offset" for the message */ - o = message__ptr[x]; - - /* Access the message text */ - s = &message__buf[o]; - - /* Hack -- Handle repeated messages */ - if (message__count[x] > 1) - { - strnfmt(buf, 1024, "%s <%dx>", s, message__count[x]); - s = buf; - } - - /* Return the message text */ - return (s); + assert(msg != nullptr); + add(std::string(msg), color); } -/* -* Recall the color of a saved message -*/ -byte message_color(int age) +void Messages::add(std::string const &msg, byte color) { - s16b x; - byte color = TERM_WHITE; - - /* Forgotten messages have no text */ - if ((age < 0) || (age >= message_num())) return (TERM_WHITE); - - /* Acquire the "logical" index */ - x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX; - - /* Get the "offset" for the message */ - color = message__color[x]; - - /* Return the message text */ - return (color); -} - - -/* -* Add a new message, with great efficiency -*/ -void message_add(cptr str, byte color) -{ - int i, k, x, n; - cptr s; - - - /*** Step 1 -- Analyze the message ***/ - - /* Hack -- Ignore "non-messages" */ - if (!str) return; - - /* Message length */ - n = strlen(str); - - /* Important Hack -- Ignore "long" messages */ - if (n >= MESSAGE_BUF / 4) return; - - - /*** Step 2 -- Handle repeated messages ***/ - - /* Acquire the "logical" last index */ - x = (message__next + MESSAGE_MAX - 1) % MESSAGE_MAX; - - /* Get the last message text */ - s = &message__buf[message__ptr[x]]; - - /* Last message repeated? */ - if (streq(str, s)) + // If the message is the same as the last message, + // we just increment the counter instead of adding + // the message. + if ((!buffer.empty()) && (buffer.back().text == msg)) { - /* Increase the message count */ - message__count[x]++; - - /* Success */ + buffer.back().count += 1; return; } + // Push onto the end of the buffer. + message message; + message.color = color; + message.count = 1; + message.text = msg; + buffer.push_back(message); +} - /*** Step 3 -- Attempt to optimize ***/ - - /* Limit number of messages to check */ - k = message_num() / 4; - - /* Limit number of messages to check */ - if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32; - - /* Check the last few messages (if any to count) */ - for (i = message__next; k; k--) - { - u16b q; - - cptr old; - - /* Back up and wrap if needed */ - if (i-- == 0) i = MESSAGE_MAX - 1; - - /* Stop before oldest message */ - if (i == message__last) break; - - /* Extract "distance" from "head" */ - q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF; - - /* Do not optimize over large distance */ - if (q > MESSAGE_BUF / 2) continue; - - /* Access the old string */ - old = &message__buf[message__ptr[i]]; - - /* Compare */ - if (!streq(old, str)) continue; - - /* Get the next message index, advance */ - x = message__next++; - - /* Handle wrap */ - if (message__next == MESSAGE_MAX) message__next = 0; - - /* Kill last message if needed */ - if (message__next == message__last) message__last++; - - /* Handle wrap */ - if (message__last == MESSAGE_MAX) message__last = 0; - - /* Assign the starting address */ - message__ptr[x] = message__ptr[i]; - message__color[x] = color; - message__count[x] = 1; - - /* Success */ - return; - } - - - /*** Step 4 -- Ensure space before end of buffer ***/ - - /* Kill messages and Wrap if needed */ - if (message__head + n + 1 >= MESSAGE_BUF) - { - /* Kill all "dead" messages */ - for (i = message__last; TRUE; i++) - { - /* Wrap if needed */ - if (i == MESSAGE_MAX) i = 0; - - /* Stop before the new message */ - if (i == message__next) break; - - /* Kill "dead" messages */ - if (message__ptr[i] >= message__head) - { - /* Track oldest message */ - message__last = i + 1; - } - } - - /* Wrap "tail" if needed */ - if (message__tail >= message__head) message__tail = 0; - - /* Start over */ - message__head = 0; - } - - - /*** Step 5 -- Ensure space before next message ***/ - - /* Kill messages if needed */ - if (message__head + n + 1 > message__tail) - { - /* Grab new "tail" */ - message__tail = message__head + n + 1; - - /* Advance tail while possible past first "nul" */ - while (message__buf[message__tail - 1]) message__tail++; - - /* Kill all "dead" messages */ - for (i = message__last; TRUE; i++) - { - /* Wrap if needed */ - if (i == MESSAGE_MAX) i = 0; - - /* Stop before the new message */ - if (i == message__next) break; - - /* Kill "dead" messages */ - if ((message__ptr[i] >= message__head) && - (message__ptr[i] < message__tail)) - { - /* Track oldest message */ - message__last = i + 1; - } - } - } - - - /*** Step 6 -- Grab a new message index ***/ - - /* Get the next message index, advance */ - x = message__next++; - - /* Handle wrap */ - if (message__next == MESSAGE_MAX) message__next = 0; - - /* Kill last message if needed */ - if (message__next == message__last) message__last++; - - /* Handle wrap */ - if (message__last == MESSAGE_MAX) message__last = 0; - - - - /*** Step 7 -- Insert the message text ***/ - - /* Assign the starting address */ - message__ptr[x] = message__head; - message__color[x] = color; - message__count[x] = 1; - - /* Append the new part of the message */ - for (i = 0; i < n; i++) - { - /* Copy the message */ - message__buf[message__head + i] = str[i]; - } - - /* Terminate */ - message__buf[message__head + i] = '\0'; - - /* Advance the "head" pointer */ - message__head += n + 1; +void Messages::add(message const &m) +{ + buffer.push_back(m); } diff --git a/src/messages.hpp b/src/messages.hpp index 22943ab9..0443a6c8 100644 --- a/src/messages.hpp +++ b/src/messages.hpp @@ -1,9 +1,56 @@ #pragma once #include "h-basic.h" +#include "message.hpp" -void message_init(); -s16b message_num(); -cptr message_str(int age); -byte message_color(int age); -void message_add(cptr msg, byte color); +#include <boost/circular_buffer.hpp> + +/** + * Game message buffer + */ +class Messages final { + +private: + boost::circular_buffer<message> buffer; + +public: + + /** + * Create message buffer with space for given + * number of messages. + */ + explicit Messages(std::size_t n) + : buffer(n) + { + } + + /** + * Get the current number of messages. + */ + s16b size() const; + + /** + * Get message of given age. Age must be + * in the half-open interval [0, message_num). + * + * The reference is only valid as long as + * no messages are added. + */ + message const &at(int age) const; + + /** + * Add a message. + */ + void add(cptr msg, byte color); + + /** + * Add a message. + */ + void add(std::string const &msg, byte color); + + /** + * Add a message. + */ + void add(message const &); + +}; diff --git a/src/meta_class_type.hpp b/src/meta_class_type.hpp deleted file mode 100644 index e74e75b3..00000000 --- a/src/meta_class_type.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "h-basic.h" - -struct meta_class_type -{ - char name[80]; /* Name */ - byte color; - s16b *classes; /* list of classes */ -}; diff --git a/src/meta_class_type_fwd.hpp b/src/meta_class_type_fwd.hpp deleted file mode 100644 index 2d0e482a..00000000 --- a/src/meta_class_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct meta_class_type; diff --git a/src/mimic.cc b/src/mimic.cc index edf79f4b..6ce7b180 100644 --- a/src/mimic.cc +++ b/src/mimic.cc @@ -1,5 +1,7 @@ #include "mimic.hpp" +#include "game.hpp" +#include "object_flag.hpp" #include "player_type.hpp" #include "skill_type.hpp" #include "stats.hpp" @@ -37,8 +39,8 @@ struct mimic_form_type static s32b abomination_calc() { - apply_flags(TR1_SPEED + TR1_STR + TR1_INT + TR1_WIS + TR1_DEX + TR1_CON + TR1_CHR, 0, 0, 0, 0, 0, -10, 0, 0, 0, 0); - p_ptr->xtra_f3 |= TR3_AGGRAVATE; + apply_flags(TR_SPEED | TR_STR | TR_INT | TR_WIS | TR_DEX | TR_CON | TR_CHR, -10, 0, 0, 0, 0); + p_ptr->xtra_flags |= TR_AGGRAVATE; return 0; } @@ -89,23 +91,23 @@ static s32b eagle_calc() if (p_ptr->mimic_level >= 20) { - p_ptr->xtra_f4 |= TR4_FLY; - p_ptr->xtra_f3 |= TR3_SEE_INVIS; + p_ptr->xtra_flags |= TR_FLY; + p_ptr->xtra_flags |= TR_SEE_INVIS; } if (p_ptr->mimic_level >= 25) { - p_ptr->xtra_f2 |= TR2_FREE_ACT; + p_ptr->xtra_flags |= TR_FREE_ACT; } if (p_ptr->mimic_level >= 30) { - p_ptr->xtra_f2 |= TR2_RES_ELEC; + p_ptr->xtra_flags |= TR_RES_ELEC; } if (p_ptr->mimic_level >= 35) { - p_ptr->xtra_f3 |= TR3_SH_ELEC; + p_ptr->xtra_flags |= TR_SH_ELEC; } return 0; @@ -120,27 +122,27 @@ static s32b wolf_calc() p_ptr->pspeed = p_ptr->pspeed + 10 + (p_ptr->mimic_level / 5); - p_ptr->xtra_f2 |= TR2_FREE_ACT; - p_ptr->xtra_f2 |= TR2_RES_FEAR; + p_ptr->xtra_flags |= TR_FREE_ACT; + p_ptr->xtra_flags |= TR_RES_FEAR; if (p_ptr->mimic_level >= 10) { - p_ptr->xtra_f2 |= TR2_RES_COLD; + p_ptr->xtra_flags |= TR_RES_COLD; } if (p_ptr->mimic_level >= 15) { - p_ptr->xtra_f3 |= TR3_SEE_INVIS; + p_ptr->xtra_flags |= TR_SEE_INVIS; } if (p_ptr->mimic_level >= 30) { - p_ptr->xtra_f2 |= TR2_RES_DARK; + p_ptr->xtra_flags |= TR_RES_DARK; } if (p_ptr->mimic_level >= 35) { - p_ptr->xtra_f2 |= TR2_RES_CONF; + p_ptr->xtra_flags |= TR_RES_CONF; } return 0; @@ -157,13 +159,13 @@ static s32b spider_calc() p_ptr->pspeed = p_ptr->pspeed + 5; - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f2 |= TR2_RES_FEAR; - p_ptr->xtra_f2 |= TR2_RES_DARK; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_RES_FEAR; + p_ptr->xtra_flags |= TR_RES_DARK; if (p_ptr->mimic_level >= 40) { - p_ptr->xtra_f4 |= TR4_CLIMB; + p_ptr->xtra_flags |= TR_CLIMB; } return 0; @@ -191,12 +193,12 @@ static s32b ent_calc() p_ptr->stat_add[A_CON] += p_ptr->mimic_level / 5; p_ptr->stat_add[A_CHR] += -7; - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f2 |= TR2_RES_COLD; - p_ptr->xtra_f2 |= TR2_FREE_ACT; - p_ptr->xtra_f3 |= TR3_REGEN; - p_ptr->xtra_f3 |= TR3_SEE_INVIS; - p_ptr->xtra_f2 |= TR2_SENS_FIRE; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_RES_COLD; + p_ptr->xtra_flags |= TR_FREE_ACT; + p_ptr->xtra_flags |= TR_REGEN; + p_ptr->xtra_flags |= TR_SEE_INVIS; + p_ptr->xtra_flags |= TR_SENS_FIRE; return 0; } @@ -226,14 +228,14 @@ static s32b vapour_calc() /* But they are stealthy */ p_ptr->skill_stl = p_ptr->skill_stl + 10 + (p_ptr->mimic_level / 5); - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f2 |= TR2_RES_SHARDS; - p_ptr->xtra_f2 |= TR2_IM_COLD; - p_ptr->xtra_f2 |= TR2_FREE_ACT; - p_ptr->xtra_f3 |= TR3_REGEN; - p_ptr->xtra_f3 |= TR3_SEE_INVIS; - p_ptr->xtra_f2 |= TR2_SENS_FIRE; - p_ptr->xtra_f3 |= TR3_FEATHER; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_RES_SHARDS; + p_ptr->xtra_flags |= TR_IM_COLD; + p_ptr->xtra_flags |= TR_FREE_ACT; + p_ptr->xtra_flags |= TR_REGEN; + p_ptr->xtra_flags |= TR_SEE_INVIS; + p_ptr->xtra_flags |= TR_SENS_FIRE; + p_ptr->xtra_flags |= TR_FEATHER; return 0; } @@ -252,10 +254,10 @@ static s32b serpent_calc() p_ptr->stat_add[A_CON] += p_ptr->mimic_level / 7; p_ptr->stat_add[A_CHR] += -6; - p_ptr->xtra_f2 |= TR2_RES_POIS; + p_ptr->xtra_flags |= TR_RES_POIS; if (p_ptr->mimic_level >= 25) { - p_ptr->xtra_f2 |= TR2_FREE_ACT; + p_ptr->xtra_flags |= TR_FREE_ACT; } return 0; @@ -279,22 +281,22 @@ static s32b mumak_calc() if (p_ptr->mimic_level >= 10) { - p_ptr->xtra_f2 |= TR2_RES_FEAR; + p_ptr->xtra_flags |= TR_RES_FEAR; } if (p_ptr->mimic_level >= 25) { - p_ptr->xtra_f2 |= TR2_RES_CONF; + p_ptr->xtra_flags |= TR_RES_CONF; } if (p_ptr->mimic_level >= 30) { - p_ptr->xtra_f2 |= TR2_FREE_ACT; + p_ptr->xtra_flags |= TR_FREE_ACT; } if (p_ptr->mimic_level >= 35) { - p_ptr->xtra_f2 |= TR2_RES_NEXUS; + p_ptr->xtra_flags |= TR_RES_NEXUS; } return 0; @@ -302,6 +304,8 @@ static s32b mumak_calc() static s32b bear_calc() { + auto &s_info = game->s_info; + p_ptr->pspeed = p_ptr->pspeed - 5 + (p_ptr->mimic_level / 5); p_ptr->to_a = p_ptr->to_a + 5 + ((p_ptr->mimic_level * 2) / 3); @@ -316,26 +320,26 @@ static s32b bear_calc() if (p_ptr->mimic_level >= 10) { - p_ptr->xtra_f2 |= TR2_FREE_ACT; + p_ptr->xtra_flags |= TR_FREE_ACT; } if (p_ptr->mimic_level >= 20) { - p_ptr->xtra_f3 |= TR3_REGEN; + p_ptr->xtra_flags |= TR_REGEN; } if (p_ptr->mimic_level >= 30) { - p_ptr->xtra_f2 |= TR2_RES_CONF; + p_ptr->xtra_flags |= TR_RES_CONF; } if (p_ptr->mimic_level >= 35) { - p_ptr->xtra_f2 |= TR2_RES_NEXUS; + p_ptr->xtra_flags |= TR_RES_NEXUS; } /* activate the skill */ - s_info[SKILL_BEAR].hidden = FALSE; + s_info[SKILL_BEAR].hidden = false; return 0; } @@ -349,17 +353,17 @@ static s32b balrog_calc() p_ptr->stat_add[A_CON] += 5 + p_ptr->mimic_level / 5; p_ptr->stat_add[A_CHR] += - ( 5 + p_ptr->mimic_level / 10); - p_ptr->xtra_f2 |= TR2_IM_ACID; - p_ptr->xtra_f2 |= TR2_IM_FIRE; - p_ptr->xtra_f2 |= TR2_IM_ELEC; - p_ptr->xtra_f2 |= TR2_RES_DARK; - p_ptr->xtra_f2 |= TR2_RES_CHAOS; - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f2 |= TR2_HOLD_LIFE; - p_ptr->xtra_f3 |= TR3_FEATHER; - p_ptr->xtra_f3 |= TR3_REGEN; - p_ptr->xtra_f3 |= TR3_SH_FIRE; - p_ptr->xtra_f3 |= TR3_LITE1; + p_ptr->xtra_flags |= TR_IM_ACID; + p_ptr->xtra_flags |= TR_IM_FIRE; + p_ptr->xtra_flags |= TR_IM_ELEC; + p_ptr->xtra_flags |= TR_RES_DARK; + p_ptr->xtra_flags |= TR_RES_CHAOS; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_HOLD_LIFE; + p_ptr->xtra_flags |= TR_FEATHER; + p_ptr->xtra_flags |= TR_REGEN; + p_ptr->xtra_flags |= TR_SH_FIRE; + p_ptr->xtra_flags |= TR_LITE1; return 1; /* Adds a blow */ } @@ -373,17 +377,17 @@ static s32b maia_calc() p_ptr->stat_add[A_CON] += 5 + p_ptr->mimic_level / 5; p_ptr->stat_add[A_CHR] += 5 + p_ptr->mimic_level / 5; - p_ptr->xtra_f2 |= TR2_IM_FIRE; - p_ptr->xtra_f2 |= TR2_IM_ELEC; - p_ptr->xtra_f2 |= TR2_IM_ACID; - p_ptr->xtra_f2 |= TR2_IM_COLD; - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f2 |= TR2_RES_LITE; - p_ptr->xtra_f2 |= TR2_RES_DARK; - p_ptr->xtra_f2 |= TR2_RES_CHAOS; - p_ptr->xtra_f2 |= TR2_HOLD_LIFE; - p_ptr->xtra_f3 |= TR3_FEATHER; - p_ptr->xtra_f3 |= TR3_REGEN; + p_ptr->xtra_flags |= TR_IM_FIRE; + p_ptr->xtra_flags |= TR_IM_ELEC; + p_ptr->xtra_flags |= TR_IM_ACID; + p_ptr->xtra_flags |= TR_IM_COLD; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_RES_LITE; + p_ptr->xtra_flags |= TR_RES_DARK; + p_ptr->xtra_flags |= TR_RES_CHAOS; + p_ptr->xtra_flags |= TR_HOLD_LIFE; + p_ptr->xtra_flags |= TR_FEATHER; + p_ptr->xtra_flags |= TR_REGEN; return 2; /* Add two blows */ } @@ -394,10 +398,10 @@ static s32b fire_elemental_calc() p_ptr->stat_add[A_DEX] += 5 + (p_ptr->mimic_level / 5); p_ptr->stat_add[A_WIS] += -5 - (p_ptr->mimic_level / 5); - p_ptr->xtra_f2 |= TR2_IM_FIRE; - p_ptr->xtra_f2 |= TR2_RES_POIS; - p_ptr->xtra_f3 |= TR3_SH_FIRE; - p_ptr->xtra_f3 |= TR3_LITE1; + p_ptr->xtra_flags |= TR_IM_FIRE; + p_ptr->xtra_flags |= TR_RES_POIS; + p_ptr->xtra_flags |= TR_SH_FIRE; + p_ptr->xtra_flags |= TR_LITE1; return 0; } @@ -588,11 +592,9 @@ static mimic_form_type mimic_forms[MIMIC_FORMS_MAX] = /* * Is the mimicry form enabled for the current module? */ -static bool_ mimic_form_enabled(mimic_form_type *f) +static bool mimic_form_enabled(mimic_form_type const *f) { - int i; - - for (i = 0; f->modules[i] >= 0; i++) + for (int i = 0; f->modules[i] >= 0; i++) { if (f->modules[i] == game_module_idx) { @@ -618,11 +620,9 @@ static mimic_form_type *get_mimic_form(int mf_idx) */ s16b resolve_mimic_name(cptr name) { - s16b i; - - for (i = 0; i < MIMIC_FORMS_MAX; i++) + for (s16b i = 0; i < MIMIC_FORMS_MAX; i++) { - mimic_form_type *mf_ptr = get_mimic_form(i); + auto const mf_ptr = get_mimic_form(i); if (mimic_form_enabled(mf_ptr) && streq(mf_ptr->name, name)) { return i; @@ -641,13 +641,10 @@ s16b find_random_mimic_shape(byte level, bool_ limit) while (tries > 0) { - int mf_idx = 0; - mimic_form_type *mf_ptr = NULL; - tries = tries - 1; - mf_idx = rand_int(MIMIC_FORMS_MAX); - mf_ptr = get_mimic_form(mf_idx); + int mf_idx = rand_int(MIMIC_FORMS_MAX); + auto const mf_ptr = get_mimic_form(mf_idx); if (mimic_form_enabled(mf_ptr)) { @@ -695,7 +692,7 @@ byte get_mimic_level(s16b mf_idx) */ s32b get_mimic_random_duration(s16b mf_idx) { - mimic_form_type *mf_ptr = get_mimic_form(mf_idx); + auto const mf_ptr = get_mimic_form(mf_idx); return rand_range(mf_ptr->duration.min, mf_ptr->duration.max); } @@ -704,7 +701,7 @@ s32b get_mimic_random_duration(s16b mf_idx) */ byte calc_mimic() { - mimic_form_type *mf_ptr = get_mimic_form(p_ptr->mimic_form); + auto const mf_ptr = get_mimic_form(p_ptr->mimic_form); if (mf_ptr->calc != NULL) { return mf_ptr->calc(); diff --git a/src/mimic.hpp b/src/mimic.hpp index d9c8f3bd..4ce9a6e8 100644 --- a/src/mimic.hpp +++ b/src/mimic.hpp @@ -1,10 +1,10 @@ #include "h-basic.h" -extern s16b resolve_mimic_name(cptr name); -extern s16b find_random_mimic_shape(byte level, bool_ limit); -extern cptr get_mimic_name(s16b mf_idx); -extern cptr get_mimic_object_name(s16b mf_idx); -extern byte get_mimic_level(s16b mf_idx); -extern s32b get_mimic_random_duration(s16b mf_idx); -extern byte calc_mimic(); -extern void calc_mimic_power(); +s16b resolve_mimic_name(cptr name); +s16b find_random_mimic_shape(byte level, bool_ limit); +cptr get_mimic_name(s16b mf_idx); +cptr get_mimic_object_name(s16b mf_idx); +byte get_mimic_level(s16b mf_idx); +s32b get_mimic_random_duration(s16b mf_idx); +byte calc_mimic(); +void calc_mimic_power(); diff --git a/src/module_type.hpp b/src/module_type.hpp index 96938856..1b75d84c 100644 --- a/src/module_type.hpp +++ b/src/module_type.hpp @@ -42,9 +42,6 @@ struct module_type s32b jewelry_chance; } randarts; - /* Max player level. */ - int max_plev; - /* Skills */ struct { /* Skill points per level */ diff --git a/src/modules.cc b/src/modules.cc index c5d065f4..de9ad1ad 100644 --- a/src/modules.cc +++ b/src/modules.cc @@ -7,7 +7,6 @@ */ #include "modules.hpp" -#include "modules.h" #include "birth.hpp" #include "cave.hpp" @@ -25,6 +24,7 @@ #include "lua_bind.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "object2.hpp" #include "object_type.hpp" @@ -195,8 +195,6 @@ static void activate_module(int module_idx) game_module_idx = module_idx; /* Do misc inits */ - max_plev = module_ptr->max_plev; - RANDART_WEAPON = module_ptr->randarts.weapon_chance; RANDART_ARMOR = module_ptr->randarts.armor_chance; RANDART_JEWEL = module_ptr->randarts.jewelry_chance; @@ -204,9 +202,6 @@ static void activate_module(int module_idx) VERSION_MAJOR = module_ptr->meta.version.major; VERSION_MINOR = module_ptr->meta.version.minor; VERSION_PATCH = module_ptr->meta.version.patch; - version_major = VERSION_MAJOR; - version_minor = VERSION_MINOR; - version_patch = VERSION_PATCH; /* Change window name if needed */ if (strcmp(game_module, "ToME")) @@ -237,9 +232,9 @@ static void init_module(module_type *module_ptr) } } -bool_ module_savefile_loadable(cptr savefile_mod) +bool module_savefile_loadable(std::string const &tag) { - return (strcmp(savefile_mod, modules[game_module_idx].meta.save_file_tag) == 0); + return tag == modules[game_module_idx].meta.save_file_tag; } /* Did the player force a module on command line */ @@ -562,7 +557,7 @@ exit: screen_load(); } -static bool_ auto_stat_gain_hook(void *data, void *in, void *out) +static bool auto_stat_gain_hook(void *data, void *in, void *out) { while (p_ptr->last_rewarded_level * 5 <= p_ptr->lev) { @@ -576,10 +571,10 @@ static bool_ auto_stat_gain_hook(void *data, void *in, void *out) p_ptr->last_rewarded_level += 1; } - return FALSE; + return false; } -static bool_ drunk_takes_wine(void *data, void *in_, void *out) +static bool drunk_takes_wine(void *, void *in_, void *) { hook_give_in *in = (hook_give_in *) in_; monster_type *m_ptr = &m_list[in->m_idx]; @@ -609,7 +604,7 @@ static bool_ drunk_takes_wine(void *data, void *in_, void *out) } } -static bool_ hobbit_food(void *data, void *in_, void *out) +static bool hobbit_food(void *, void *in_, void *) { hook_give_in *in = (hook_give_in *) in_; monster_type *m_ptr = &m_list[in->m_idx]; @@ -622,15 +617,15 @@ static bool_ hobbit_food(void *data, void *in_, void *out) inc_stack_size_ex(in->item, -1, OPTIMIZE, NO_DESCRIBE); - return TRUE; + return true; } else { - return FALSE; + return false; } } -static bool_ smeagol_ring(void *data, void *in_, void *out) +static bool smeagol_ring(void *data, void *in_, void *out) { hook_give_in *in = (hook_give_in *) in_; monster_type *m_ptr = &m_list[in->m_idx]; @@ -643,15 +638,15 @@ static bool_ smeagol_ring(void *data, void *in_, void *out) inc_stack_size_ex(in->item, -1, OPTIMIZE, NO_DESCRIBE); - return TRUE; + return true; } else { - return FALSE; + return false; } } -static bool_ longbottom_leaf(void *data, void *in_, void *out_) +static bool longbottom_leaf(void *, void *in_, void *) { hook_eat_in *in = (hook_eat_in *) in_; @@ -660,13 +655,13 @@ static bool_ longbottom_leaf(void *data, void *in_, void *out_) { msg_print("What a stress reliever!"); heal_insanity(1000); - return TRUE; + return true; } - return FALSE; + return false; } -static bool_ food_vessel(void *data, void *in_, void *out) +static bool food_vessel(void *, void *in_, void *ut) { hook_eat_in *in = (hook_eat_in *) in_; @@ -680,16 +675,16 @@ static bool_ food_vessel(void *data, void *in_, void *out) forge.ident |= IDENT_MENTAL | IDENT_KNOWN; inven_carry(&forge, FALSE); - return TRUE; + return true; } - return FALSE; + return false; } /* * Player must have appropriate keys to enter Erebor. */ -static bool_ erebor_stair(void *data, void *in_, void *out_) +static bool erebor_stair(void *, void *in_, void *out_) { hook_stair_in *in = (hook_stair_in *) in_; hook_stair_out *out = (hook_stair_out *) out_; @@ -724,13 +719,13 @@ static bool_ erebor_stair(void *data, void *in_, void *out_) } } - return FALSE; + return false; } /* * Orthanc requires a key. */ -static bool_ orthanc_stair(void *data, void *in_, void *out_) +static bool orthanc_stair(void *, void *in_, void *out_) { hook_stair_in *in = (hook_stair_in *) in_; hook_stair_out *out = (hook_stair_out *) out_; @@ -762,13 +757,13 @@ static bool_ orthanc_stair(void *data, void *in_, void *out_) } } - return FALSE; + return false; } /* * Movement from Theme */ -static bool_ theme_push_past(void *data, void *in_, void *out_) +static bool theme_push_past(void *data, void *in_, void *out_) { hook_move_in *p = (hook_move_in *) in_; cave_type *c_ptr = &cave[p->y][p->x]; @@ -781,7 +776,7 @@ static bool_ theme_push_past(void *data, void *in_, void *out_) if (m_ptr->status >= MSTATUS_NEUTRAL) { if (cave_floor_bold(p->y, p->x) || - (mr_ptr->flags2 == RF2_PASS_WALL)) + (mr_ptr->flags == RF_PASS_WALL)) { char buf[128]; @@ -801,19 +796,19 @@ static bool_ theme_push_past(void *data, void *in_, void *out_) msg_print(format("%s is in your way!", buf)); energy_use = 0; - return TRUE; + return true; } } } - return FALSE; + return false; } /* * Check if monster race is in list. The list is terminated * with a -1. */ -static bool_ race_in_list(int r_idx, int race_idxs[]) +static bool race_in_list(int r_idx, int race_idxs[]) { int i; @@ -821,11 +816,11 @@ static bool_ race_in_list(int r_idx, int race_idxs[]) { if (r_idx == race_idxs[i]) { - return TRUE; + return true; } } - return FALSE; + return false; } /* @@ -1160,11 +1155,9 @@ s16b *theme_race_status(int r_idx) return NULL; } -static bool_ theme_level_end_gen(void *data, void *in, void *out) +static bool theme_level_end_gen(void *, void *, void *) { - int i = 0; - - for (i = 0; i < m_max; i++) + for (int i = 0; i < m_max; i++) { monster_type *m_ptr = &m_list[i]; int r_idx = m_ptr->r_idx; @@ -1175,10 +1168,10 @@ static bool_ theme_level_end_gen(void *data, void *in, void *out) } } - return FALSE; + return false; } -static bool_ theme_new_monster_end(void *data, void *in_, void *out) +static bool theme_new_monster_end(void *, void *in_, void *) { hook_new_monster_end_in *in = (hook_new_monster_end_in *) in_; s16b *status = theme_race_status(in->m_ptr->r_idx); @@ -1188,7 +1181,7 @@ static bool_ theme_new_monster_end(void *data, void *in_, void *out) in->m_ptr->status = *status; } - return FALSE; + return false; } void init_hooks_module() diff --git a/src/modules.h b/src/modules.h deleted file mode 100644 index 8a3b88b0..00000000 --- a/src/modules.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "h-basic.h" - -// C linkage required for these functions since main-* code uses them. -#ifdef __cplusplus -extern "C" { -#endif - -extern bool_ private_check_user_directory(cptr dirpath); -extern cptr force_module; - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/src/modules.hpp b/src/modules.hpp index d83e3e2e..867955c9 100644 --- a/src/modules.hpp +++ b/src/modules.hpp @@ -1,11 +1,14 @@ #pragma once #include "h-basic.h" +#include <string> -extern bool_ select_module(void); -extern bool_ module_savefile_loadable(cptr savefile_mod); -extern void tome_intro(); -extern void theme_intro(); -extern s16b *theme_race_status(int r_idx); -extern void init_hooks_module(); -extern int find_module(cptr name); +bool_ select_module(); +bool module_savefile_loadable(std::string const &savefile_mod); +void tome_intro(); +void theme_intro(); +s16b *theme_race_status(int r_idx); +void init_hooks_module(); +int find_module(cptr name); +bool_ private_check_user_directory(cptr dirpath); +extern cptr force_module; diff --git a/src/monoid.hpp b/src/monoid.hpp new file mode 100644 index 00000000..465e58af --- /dev/null +++ b/src/monoid.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <numeric> +#include <vector> + +/** + * A monoid is an algebraic structure with a single associative + * binary operation ('append') and an identity element ('empty'). + * + * See https://en.wikipedia.org/wiki/Monoid + * + * Shamelessly adapted from: + * + * https://gist.github.com/evincarofautumn/2b5f004ca81e33c62ff0 + */ +template<typename T, T append_(T const&, T const&), const T &empty_> +struct monoid { + /* Access the type the monoid operates on */ + typedef T type; + + /* Append two T's */ + static T append(T const& a, T const& b) { + return append_(a, b); + } + + /* The value of an empty T */ + static constexpr T empty = empty_; +}; + +/** + * mconcat :: (Monoid m mappend) -> [m] -> m + * mconcat = fold mappend mempty + */ +template<typename M> +typename M::type mconcat(const std::vector<typename M::type>& xs) { + return std::accumulate(std::begin(xs), std::end(xs), M::empty, M::append); +} diff --git a/src/monster1.cc b/src/monster1.cc index 4e3e2c42..50c8c548 100644 --- a/src/monster1.cc +++ b/src/monster1.cc @@ -9,9 +9,12 @@ #include "monster1.hpp" #include "cave_type.hpp" +#include "game.hpp" #include "monster2.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "player_type.hpp" #include "util.hpp" #include "variable.hpp" @@ -33,63 +36,6 @@ static cptr wd_his[3] = { "its", "his", "her" }; - - - -/* - * Determine if the "armor" is known - * The higher the level, the fewer kills needed. - */ -static bool_ know_armour(std::shared_ptr<monster_race const> r_ptr) -{ - s32b level = r_ptr->level; - - s32b kills = r_ptr->r_tkills; - - /* Normal monsters */ - if (kills > 304 / (4 + level)) return (TRUE); - - /* Skip non-uniques */ - if (!(r_ptr->flags1 & (RF1_UNIQUE))) return (FALSE); - - /* Unique monsters */ - if (kills > 304 / (38 + (5*level) / 4)) return (TRUE); - - /* Assume false */ - return (FALSE); -} - - -/* - * Determine if the "damage" of the given attack is known - * the higher the level of the monster, the fewer the attacks you need, - * the more damage an attack does, the more attacks you need - */ -static bool_ know_damage(std::shared_ptr<monster_race const> r_ptr, int i) -{ - s32b level = r_ptr->level; - - s32b a = r_ptr->r_blows[i]; - - s32b d1 = r_ptr->blow[i].d_dice; - s32b d2 = r_ptr->blow[i].d_side; - - s32b d = d1 * d2; - - /* Normal monsters */ - if ((4 + level) * a > 80 * d) return (TRUE); - - /* Skip non-uniques */ - if (!(r_ptr->flags1 & (RF1_UNIQUE))) return (FALSE); - - /* Unique monsters */ - if ((4 + level) * (2 * a) > 80 * d) return (TRUE); - - /* Assume false */ - return (FALSE); -} - - /* * Hack -- display monster information using "text_out()" * @@ -102,7 +48,7 @@ static bool_ know_damage(std::shared_ptr<monster_race const> r_ptr, int i) * left edge of the screen, on a cleared line, in which the recall is * to take place. One extra blank line is left after the recall. */ -static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) +static void roff_aux(std::shared_ptr<monster_race const> r_ptr) { bool_ old = FALSE; bool_ sin = FALSE; @@ -111,194 +57,37 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) cptr p, q; - int msex = 0; - bool_ breath = FALSE; bool_ magic = FALSE; - u32b flags1; - u32b flags2; - u32b flags3; - u32b flags4; - u32b flags5; - u32b flags6; - u32b flags7; - u32b flags9; - int vn = 0; byte color[64]; cptr vp[64]; - monster_race save_mem; + /* Shorthand */ + auto const flags = r_ptr->flags; + monster_spell_flag_set spells = r_ptr->spells; - /* Cheat -- Know everything */ - if (cheat_know) + /* Extract a gender (if applicable) */ + int msex = 0; + if (flags & RF_FEMALE) { - /* XXX XXX XXX */ - - /* Save the "old" memory */ - save_mem = *r_ptr; - - /* Hack -- Maximal kills */ - r_ptr->r_tkills = MAX_SHORT; - - /* Hack -- Maximal info */ - 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_flags7 = r_ptr->flags7; - r_ptr->r_flags8 = r_ptr->flags8; - r_ptr->r_flags9 = r_ptr->flags9; + msex = 2; } - - - /* Extract a gender (if applicable) */ - if (r_ptr->flags1 & (RF1_FEMALE)) msex = 2; - else if (r_ptr->flags1 & (RF1_MALE)) msex = 1; - - - /* Obtain a copy of the "known" flags */ - flags1 = (r_ptr->flags1 & r_ptr->r_flags1); - flags2 = (r_ptr->flags2 & r_ptr->r_flags2); - flags3 = (r_ptr->flags3 & r_ptr->r_flags3); - flags4 = (r_ptr->flags4 & r_ptr->r_flags4); - flags5 = (r_ptr->flags5 & r_ptr->r_flags5); - flags6 = (r_ptr->flags6 & r_ptr->r_flags6); - flags7 = (r_ptr->flags7 & r_ptr->r_flags7); - flags9 = (r_ptr->flags9 & r_ptr->r_flags9); - - - /* Assume some "obvious" flags */ - if (r_ptr->flags1 & (RF1_UNIQUE)) flags1 |= (RF1_UNIQUE); - if (r_ptr->flags1 & (RF1_MALE)) flags1 |= (RF1_MALE); - if (r_ptr->flags1 & (RF1_FEMALE)) flags1 |= (RF1_FEMALE); - - /* Assume some "creation" flags */ - if (r_ptr->flags1 & (RF1_FRIEND)) flags1 |= (RF1_FRIEND); - if (r_ptr->flags1 & (RF1_FRIENDS)) flags1 |= (RF1_FRIENDS); - if (r_ptr->flags1 & (RF1_ESCORT)) flags1 |= (RF1_ESCORT); - if (r_ptr->flags1 & (RF1_ESCORTS)) flags1 |= (RF1_ESCORTS); - - /* Killing a monster reveals some properties */ - if (r_ptr->r_tkills) - { - /* Know "race" flags */ - if (r_ptr->flags3 & (RF3_ORC)) flags3 |= (RF3_ORC); - if (r_ptr->flags3 & (RF3_TROLL)) flags3 |= (RF3_TROLL); - if (r_ptr->flags3 & (RF3_GIANT)) flags3 |= (RF3_GIANT); - if (r_ptr->flags3 & (RF3_DRAGON)) flags3 |= (RF3_DRAGON); - if (r_ptr->flags3 & (RF3_DEMON)) flags3 |= (RF3_DEMON); - if (r_ptr->flags3 & (RF3_UNDEAD)) flags3 |= (RF3_UNDEAD); - if (r_ptr->flags3 & (RF3_EVIL)) flags3 |= (RF3_EVIL); - if (r_ptr->flags3 & (RF3_GOOD)) flags3 |= (RF3_GOOD); - if (r_ptr->flags3 & (RF3_ANIMAL)) flags3 |= (RF3_ANIMAL); - if (r_ptr->flags3 & (RF3_THUNDERLORD)) flags3 |= (RF3_THUNDERLORD); - if (r_ptr->flags7 & (RF7_SPIDER)) flags7 |= (RF7_SPIDER); - - /* Know "forced" flags */ - if (r_ptr->flags1 & (RF1_FORCE_DEPTH)) flags1 |= (RF1_FORCE_DEPTH); - if (r_ptr->flags1 & (RF1_FORCE_MAXHP)) flags1 |= (RF1_FORCE_MAXHP); + else if (flags & RF_MALE) + { + msex = 1; } - /* Treat uniques differently */ - if (flags1 & (RF1_UNIQUE)) + if (flags & RF_UNIQUE) { - /* Hack -- Determine if the unique is "dead" */ - bool_ dead = (r_ptr->max_num == 0) ? TRUE : FALSE; - - /* We've been killed... */ - if (r_ptr->r_deaths) - { - /* Killed ancestors */ - text_out(format("%^s has slain %d of your ancestors", - wd_he[msex], r_ptr->r_deaths)); - - /* But we've also killed it */ - if (dead) - { - text_out(format(", but you have avenged them! ") ); - } - - /* Unavenged (ever) */ - else - { - text_out(format(", who %s unavenged. ", - plural(r_ptr->r_deaths, "remains", "remain"))); - } - } - - /* Dead unique who never hurt us */ - else if (dead) + if (r_ptr->max_num == 0) { text_out("You have slain this foe. "); } } - /* Not unique, but killed us */ - else if (r_ptr->r_deaths) - { - /* Dead ancestors */ - text_out(format("%d of your ancestors %s been killed by this creature, ", - r_ptr->r_deaths, plural(r_ptr->r_deaths, "has", "have"))); - - /* Some kills this life */ - if (r_ptr->r_pkills) - { - text_out("and you have exterminated at least "); - text_out_c(TERM_L_GREEN, format("%d", r_ptr->r_pkills)); - text_out(" of the creatures. "); - } - - /* Some kills past lives */ - else if (r_ptr->r_tkills) - { - text_out(format("and %s have exterminated at least %d of the creatures. ", - "your ancestors", r_ptr->r_tkills)); - } - - /* No kills */ - else - { - text_out(format("and %s is not ever known to have been defeated. ", - wd_he[msex])); - } - } - /* Normal monsters */ else { @@ -310,13 +99,6 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) text_out(" of these creatures. "); } - /* Killed some last life */ - else if (r_ptr->r_tkills) - { - text_out(format("Your ancestors have killed at least %d of these creatures. ", - r_ptr->r_tkills)); - } - /* Killed none */ else { @@ -327,13 +109,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Descriptions */ { - char buf[2048]; - - /* Simple method */ - strcpy(buf, r_ptr->text); - - /* Dump it */ - text_out(buf); + text_out(r_ptr->text); text_out(" "); } @@ -342,7 +118,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) old = FALSE; /* Describe location */ - if (r_ptr->flags7 & RF7_PET) + if (r_ptr->flags & RF_PET) { text_out(format("%^s is ", wd_he[msex])); text_out_c(TERM_L_BLUE, "friendly"); @@ -360,7 +136,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) text_out_c(TERM_L_GREEN, "lives in the town or the wilderness"); old = TRUE; } - else if (r_ptr->r_tkills) + else { if (old) text_out(", "); @@ -382,7 +158,6 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Describe movement */ - if (TRUE) { /* Introduction */ if (old) @@ -397,18 +172,18 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) text_out("moves"); /* Random-ness */ - if ((flags1 & (RF1_RAND_50)) || (flags1 & (RF1_RAND_25))) + if ((flags & RF_RAND_50) || (flags & RF_RAND_25)) { /* Adverb */ - if ((flags1 & (RF1_RAND_50)) && (flags1 & (RF1_RAND_25))) + if ((flags & RF_RAND_50) && (flags & RF_RAND_25)) { text_out(" extremely"); } - else if (flags1 & (RF1_RAND_50)) + else if (flags & RF_RAND_50) { text_out(" somewhat"); } - else if (flags1 & (RF1_RAND_25)) + else if (flags & RF_RAND_25) { text_out(" a bit"); } @@ -440,7 +215,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } /* The code above includes "attack speed" */ - if (flags1 & (RF1_NEVER_MOVE)) + if (flags & RF_NEVER_MOVE) { /* Introduce */ if (old) @@ -466,10 +241,9 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Describe experience if known */ - if (r_ptr->r_tkills) { /* Introduction */ - if (flags1 & (RF1_UNIQUE)) + if (flags & RF_UNIQUE) { text_out("Killing this"); } @@ -479,21 +253,21 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } /* Describe the "quality" */ - if (flags2 & (RF2_ELDRITCH_HORROR)) text_out_c(TERM_VIOLET, " sanity-blasting"); - if (flags3 & (RF3_ANIMAL)) text_out_c(TERM_VIOLET, " natural"); - if (flags3 & (RF3_EVIL)) text_out_c(TERM_VIOLET, " evil"); - if (flags3 & (RF3_GOOD)) text_out_c(TERM_VIOLET, " good"); - if (flags3 & (RF3_UNDEAD)) text_out_c(TERM_VIOLET, " undead"); + if (flags & RF_ELDRITCH_HORROR) text_out_c(TERM_VIOLET, " sanity-blasting"); + if (flags & RF_ANIMAL) text_out_c(TERM_VIOLET, " natural"); + if (flags & RF_EVIL) text_out_c(TERM_VIOLET, " evil"); + if (flags & RF_GOOD) text_out_c(TERM_VIOLET, " good"); + if (flags & RF_UNDEAD) text_out_c(TERM_VIOLET, " undead"); /* Describe the "race" */ - if (flags3 & (RF3_DRAGON)) text_out_c(TERM_VIOLET, " dragon"); - else if (flags3 & (RF3_DEMON)) text_out_c(TERM_VIOLET, " demon"); - else if (flags3 & (RF3_GIANT)) text_out_c(TERM_VIOLET, " giant"); - else if (flags3 & (RF3_TROLL)) text_out_c(TERM_VIOLET, " troll"); - else if (flags3 & (RF3_ORC)) text_out_c(TERM_VIOLET, " orc"); - else if (flags3 & (RF3_THUNDERLORD))text_out_c(TERM_VIOLET, " Thunderlord"); - else if (flags7 & (RF7_SPIDER)) text_out_c(TERM_VIOLET, " spider"); - else if (flags7 & (RF7_NAZGUL)) text_out_c(TERM_VIOLET, " Nazgul"); + if (flags & RF_DRAGON) text_out_c(TERM_VIOLET, " dragon"); + else if (flags & RF_DEMON) text_out_c(TERM_VIOLET, " demon"); + else if (flags & RF_GIANT) text_out_c(TERM_VIOLET, " giant"); + else if (flags & RF_TROLL) text_out_c(TERM_VIOLET, " troll"); + else if (flags & RF_ORC) text_out_c(TERM_VIOLET, " orc"); + else if (flags & RF_THUNDERLORD)text_out_c(TERM_VIOLET, " Thunderlord"); + else if (flags & RF_SPIDER) text_out_c(TERM_VIOLET, " spider"); + else if (flags & RF_NAZGUL) text_out_c(TERM_VIOLET, " Nazgul"); else text_out(" creature"); /* Group some variables */ @@ -534,26 +308,26 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } } - if ((flags2 & (RF2_AURA_FIRE)) && (flags2 & (RF2_AURA_ELEC))) + if ((flags & RF_AURA_FIRE) && (flags & RF_AURA_ELEC)) { text_out(format("%^s is surrounded by ", wd_he[msex])); text_out_c(TERM_VIOLET, "flames and electricity"); text_out(". "); } - else if (flags2 & (RF2_AURA_FIRE)) + else if (flags & RF_AURA_FIRE) { text_out(format("%^s is surrounded by ", wd_he[msex])); text_out_c(TERM_ORANGE, "flames"); text_out(". "); } - else if (flags2 & (RF2_AURA_ELEC)) + else if (flags & RF_AURA_ELEC) { text_out(format("%^s is surrounded by ", wd_he[msex])); text_out_c(TERM_L_BLUE, "electricity"); text_out(". "); } - if (flags2 & (RF2_REFLECTING)) + if (flags & RF_REFLECTING) { text_out(format("%^s ", wd_he[msex])); text_out_c(TERM_L_UMBER, "reflects"); @@ -562,14 +336,14 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Describe escorts */ - if ((flags1 & (RF1_ESCORT)) || (flags1 & (RF1_ESCORTS))) + if ((flags & RF_ESCORT) || (flags & RF_ESCORTS)) { text_out(format("%^s usually appears with escorts. ", wd_he[msex])); } /* Describe friends */ - else if ((flags1 & (RF1_FRIEND)) || (flags1 & (RF1_FRIENDS))) + else if ((flags & RF_FRIEND) || (flags & RF_FRIENDS)) { text_out(format("%^s usually appears in groups. ", wd_he[msex])); @@ -578,12 +352,12 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect inate attacks */ vn = 0; - if (flags4 & (RF4_SHRIEK)) vp[vn++] = "shriek for help"; - if (flags4 & (RF4_ROCKET)) vp[vn++] = "shoot a rocket"; - if (flags4 & (RF4_ARROW_1)) vp[vn++] = "fire an arrow"; - if (flags4 & (RF4_ARROW_2)) vp[vn++] = "fire arrows"; - if (flags4 & (RF4_ARROW_3)) vp[vn++] = "fire a missile"; - if (flags4 & (RF4_ARROW_4)) vp[vn++] = "fire missiles"; + if (spells & SF_SHRIEK) vp[vn++] = "shriek for help"; + if (spells & SF_ROCKET) vp[vn++] = "shoot a rocket"; + if (spells & SF_ARROW_1) vp[vn++] = "fire an arrow"; + if (spells & SF_ARROW_2) vp[vn++] = "fire arrows"; + if (spells & SF_ARROW_3) vp[vn++] = "fire a missile"; + if (spells & SF_ARROW_4) vp[vn++] = "fire missiles"; /* Describe inate attacks */ if (vn) @@ -610,28 +384,28 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect breaths */ vn = 0; - if (flags4 & (RF4_BR_ACID)) vp[vn++] = "acid"; - if (flags4 & (RF4_BR_ELEC)) vp[vn++] = "lightning"; - if (flags4 & (RF4_BR_FIRE)) vp[vn++] = "fire"; - if (flags4 & (RF4_BR_COLD)) vp[vn++] = "frost"; - if (flags4 & (RF4_BR_POIS)) vp[vn++] = "poison"; - if (flags4 & (RF4_BR_NETH)) vp[vn++] = "nether"; - if (flags4 & (RF4_BR_LITE)) vp[vn++] = "light"; - if (flags4 & (RF4_BR_DARK)) vp[vn++] = "darkness"; - if (flags4 & (RF4_BR_CONF)) vp[vn++] = "confusion"; - if (flags4 & (RF4_BR_SOUN)) vp[vn++] = "sound"; - if (flags4 & (RF4_BR_CHAO)) vp[vn++] = "chaos"; - if (flags4 & (RF4_BR_DISE)) vp[vn++] = "disenchantment"; - if (flags4 & (RF4_BR_NEXU)) vp[vn++] = "nexus"; - if (flags4 & (RF4_BR_TIME)) vp[vn++] = "time"; - if (flags4 & (RF4_BR_INER)) vp[vn++] = "inertia"; - if (flags4 & (RF4_BR_GRAV)) vp[vn++] = "gravity"; - if (flags4 & (RF4_BR_SHAR)) vp[vn++] = "shards"; - if (flags4 & (RF4_BR_PLAS)) vp[vn++] = "plasma"; - if (flags4 & (RF4_BR_WALL)) vp[vn++] = "force"; - if (flags4 & (RF4_BR_MANA)) vp[vn++] = "mana"; - if (flags4 & (RF4_BR_NUKE)) vp[vn++] = "toxic waste"; - if (flags4 & (RF4_BR_DISI)) vp[vn++] = "disintegration"; + if (spells & SF_BR_ACID) vp[vn++] = "acid"; + if (spells & SF_BR_ELEC) vp[vn++] = "lightning"; + if (spells & SF_BR_FIRE) vp[vn++] = "fire"; + if (spells & SF_BR_COLD) vp[vn++] = "frost"; + if (spells & SF_BR_POIS) vp[vn++] = "poison"; + if (spells & SF_BR_NETH) vp[vn++] = "nether"; + if (spells & SF_BR_LITE) vp[vn++] = "light"; + if (spells & SF_BR_DARK) vp[vn++] = "darkness"; + if (spells & SF_BR_CONF) vp[vn++] = "confusion"; + if (spells & SF_BR_SOUN) vp[vn++] = "sound"; + if (spells & SF_BR_CHAO) vp[vn++] = "chaos"; + if (spells & SF_BR_DISE) vp[vn++] = "disenchantment"; + if (spells & SF_BR_NEXU) vp[vn++] = "nexus"; + if (spells & SF_BR_TIME) vp[vn++] = "time"; + if (spells & SF_BR_INER) vp[vn++] = "inertia"; + if (spells & SF_BR_GRAV) vp[vn++] = "gravity"; + if (spells & SF_BR_SHAR) vp[vn++] = "shards"; + if (spells & SF_BR_PLAS) vp[vn++] = "plasma"; + if (spells & SF_BR_WALL) vp[vn++] = "force"; + if (spells & SF_BR_MANA) vp[vn++] = "mana"; + if (spells & SF_BR_NUKE) vp[vn++] = "toxic waste"; + if (spells & SF_BR_DISI) vp[vn++] = "disintegration"; /* Describe breaths */ if (vn) @@ -658,73 +432,72 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect spells */ vn = 0; - if (flags5 & (RF5_BA_ACID)) vp[vn++] = "produce acid balls"; - if (flags5 & (RF5_BA_ELEC)) vp[vn++] = "produce lightning balls"; - if (flags5 & (RF5_BA_FIRE)) vp[vn++] = "produce fire balls"; - if (flags5 & (RF5_BA_COLD)) vp[vn++] = "produce frost balls"; - if (flags5 & (RF5_BA_POIS)) vp[vn++] = "produce poison balls"; - if (flags5 & (RF5_BA_NETH)) vp[vn++] = "produce nether balls"; - if (flags5 & (RF5_BA_WATE)) vp[vn++] = "produce water balls"; - if (flags4 & (RF4_BA_NUKE)) vp[vn++] = "produce balls of radiation"; - if (flags5 & (RF5_BA_MANA)) vp[vn++] = "invoke mana storms"; - if (flags5 & (RF5_BA_DARK)) vp[vn++] = "invoke darkness storms"; - if (flags4 & (RF4_BA_CHAO)) vp[vn++] = "invoke raw chaos"; - if (flags6 & (RF6_HAND_DOOM)) vp[vn++] = "invoke the Hand of Doom"; - if (flags5 & (RF5_DRAIN_MANA)) vp[vn++] = "drain mana"; - if (flags5 & (RF5_MIND_BLAST)) vp[vn++] = "cause mind blasting"; - if (flags5 & (RF5_BRAIN_SMASH)) vp[vn++] = "cause brain smashing"; - if (flags5 & (RF5_CAUSE_1)) vp[vn++] = "cause light wounds and cursing"; - if (flags5 & (RF5_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing"; - if (flags5 & (RF5_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing"; - if (flags5 & (RF5_CAUSE_4)) vp[vn++] = "cause mortal wounds"; - if (flags5 & (RF5_BO_ACID)) vp[vn++] = "produce acid bolts"; - if (flags5 & (RF5_BO_ELEC)) vp[vn++] = "produce lightning bolts"; - if (flags5 & (RF5_BO_FIRE)) vp[vn++] = "produce fire bolts"; - if (flags5 & (RF5_BO_COLD)) vp[vn++] = "produce frost bolts"; - if (flags5 & (RF5_BO_POIS)) vp[vn++] = "produce poison bolts"; - if (flags5 & (RF5_BO_NETH)) vp[vn++] = "produce nether bolts"; - if (flags5 & (RF5_BO_WATE)) vp[vn++] = "produce water bolts"; - if (flags5 & (RF5_BO_MANA)) vp[vn++] = "produce mana bolts"; - if (flags5 & (RF5_BO_PLAS)) vp[vn++] = "produce plasma bolts"; - if (flags5 & (RF5_BO_ICEE)) vp[vn++] = "produce ice bolts"; - if (flags5 & (RF5_MISSILE)) vp[vn++] = "produce magic missiles"; - if (flags5 & (RF5_SCARE)) vp[vn++] = "terrify"; - if (flags5 & (RF5_BLIND)) vp[vn++] = "blind"; - if (flags5 & (RF5_CONF)) vp[vn++] = "confuse"; - if (flags5 & (RF5_SLOW)) vp[vn++] = "slow"; - if (flags5 & (RF5_HOLD)) vp[vn++] = "paralyze"; - if (flags6 & (RF6_HASTE)) vp[vn++] = "haste-self"; - if (flags6 & (RF6_HEAL)) vp[vn++] = "heal-self"; - if (flags6 & (RF6_BLINK)) vp[vn++] = "blink-self"; - if (flags6 & (RF6_TPORT)) vp[vn++] = "teleport-self"; - if (flags6 & (RF6_S_BUG)) vp[vn++] = "summon software bugs"; - if (flags6 & (RF6_S_RNG)) vp[vn++] = "summon RNG"; - if (flags6 & (RF6_TELE_TO)) vp[vn++] = "teleport to"; - if (flags6 & (RF6_TELE_AWAY)) vp[vn++] = "teleport away"; - if (flags6 & (RF6_TELE_LEVEL)) vp[vn++] = "teleport level"; - if (flags6 & (RF6_S_THUNDERLORD)) vp[vn++] = "summon a Thunderlord"; - if (flags6 & (RF6_DARKNESS)) vp[vn++] = "create darkness"; - if (flags6 & (RF6_TRAPS)) vp[vn++] = "create traps"; - if (flags6 & (RF6_FORGET)) vp[vn++] = "cause amnesia"; - if (flags6 & (RF6_RAISE_DEAD)) vp[vn++] = "raise dead"; - if (flags6 & (RF6_S_MONSTER)) vp[vn++] = "summon a monster"; - if (flags6 & (RF6_S_MONSTERS)) vp[vn++] = "summon monsters"; - if (flags6 & (RF6_S_KIN)) vp[vn++] = "summon aid"; - if (flags6 & (RF6_S_ANT)) vp[vn++] = "summon ants"; - if (flags6 & (RF6_S_SPIDER)) vp[vn++] = "summon spiders"; - if (flags6 & (RF6_S_HOUND)) vp[vn++] = "summon hounds"; - if (flags6 & (RF6_S_HYDRA)) vp[vn++] = "summon hydras"; - if (flags6 & (RF6_S_ANGEL)) vp[vn++] = "summon an angel"; - if (flags6 & (RF6_S_DEMON)) vp[vn++] = "summon a demon"; - if (flags6 & (RF6_S_UNDEAD)) vp[vn++] = "summon an undead"; - if (flags6 & (RF6_S_DRAGON)) vp[vn++] = "summon a dragon"; - if (flags4 & (RF4_S_ANIMAL)) vp[vn++] = "summon animal"; - if (flags6 & (RF6_S_ANIMALS)) vp[vn++] = "summon animals"; - if (flags6 & (RF6_S_HI_UNDEAD)) vp[vn++] = "summon Greater Undead"; - if (flags6 & (RF6_S_HI_DRAGON)) vp[vn++] = "summon Ancient Dragons"; - if (flags6 & (RF6_S_HI_DEMON)) vp[vn++] = "summon Greater Demons"; - if (flags6 & (RF6_S_WRAITH)) vp[vn++] = "summon Ringwraith"; - if (flags6 & (RF6_S_UNIQUE)) vp[vn++] = "summon Unique Monsters"; + if (spells & SF_BA_ACID) vp[vn++] = "produce acid balls"; + if (spells & SF_BA_ELEC) vp[vn++] = "produce lightning balls"; + if (spells & SF_BA_FIRE) vp[vn++] = "produce fire balls"; + if (spells & SF_BA_COLD) vp[vn++] = "produce frost balls"; + if (spells & SF_BA_POIS) vp[vn++] = "produce poison balls"; + if (spells & SF_BA_NETH) vp[vn++] = "produce nether balls"; + if (spells & SF_BA_WATE) vp[vn++] = "produce water balls"; + if (spells & SF_BA_NUKE) vp[vn++] = "produce balls of radiation"; + if (spells & SF_BA_MANA) vp[vn++] = "invoke mana storms"; + if (spells & SF_BA_DARK) vp[vn++] = "invoke darkness storms"; + if (spells & SF_BA_CHAO) vp[vn++] = "invoke raw chaos"; + if (spells & SF_HAND_DOOM) vp[vn++] = "invoke the Hand of Doom"; + if (spells & SF_DRAIN_MANA) vp[vn++] = "drain mana"; + if (spells & SF_MIND_BLAST) vp[vn++] = "cause mind blasting"; + if (spells & SF_BRAIN_SMASH) vp[vn++] = "cause brain smashing"; + if (spells & (SF_CAUSE_1)) vp[vn++] = "cause light wounds and cursing"; + if (spells & (SF_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing"; + if (spells & (SF_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing"; + if (spells & (SF_CAUSE_4)) vp[vn++] = "cause mortal wounds"; + if (spells & SF_BO_ACID) vp[vn++] = "produce acid bolts"; + if (spells & SF_BO_ELEC) vp[vn++] = "produce lightning bolts"; + if (spells & SF_BO_FIRE) vp[vn++] = "produce fire bolts"; + if (spells & SF_BO_COLD) vp[vn++] = "produce frost bolts"; + if (spells & SF_BO_POIS) vp[vn++] = "produce poison bolts"; + if (spells & SF_BO_NETH) vp[vn++] = "produce nether bolts"; + if (spells & SF_BO_WATE) vp[vn++] = "produce water bolts"; + if (spells & SF_BO_MANA) vp[vn++] = "produce mana bolts"; + if (spells & SF_BO_PLAS) vp[vn++] = "produce plasma bolts"; + if (spells & SF_BO_ICEE) vp[vn++] = "produce ice bolts"; + if (spells & SF_MISSILE) vp[vn++] = "produce magic missiles"; + if (spells & SF_SCARE) vp[vn++] = "terrify"; + if (spells & SF_BLIND) vp[vn++] = "blind"; + if (spells & SF_CONF) vp[vn++] = "confuse"; + if (spells & SF_SLOW) vp[vn++] = "slow"; + if (spells & SF_HOLD) vp[vn++] = "paralyze"; + if (spells & SF_HASTE) vp[vn++] = "haste-self"; + if (spells & SF_HEAL) vp[vn++] = "heal-self"; + if (spells & SF_BLINK) vp[vn++] = "blink-self"; + if (spells & SF_TPORT) vp[vn++] = "teleport-self"; + if (spells & SF_S_BUG) vp[vn++] = "summon software bugs"; + if (spells & SF_S_RNG) vp[vn++] = "summon RNG"; + if (spells & SF_TELE_TO) vp[vn++] = "teleport to"; + if (spells & SF_TELE_AWAY) vp[vn++] = "teleport away"; + if (spells & SF_TELE_LEVEL) vp[vn++] = "teleport level"; + if (spells & SF_S_THUNDERLORD) vp[vn++] = "summon a Thunderlord"; + if (spells & SF_DARKNESS) vp[vn++] = "create darkness"; + if (spells & SF_FORGET) vp[vn++] = "cause amnesia"; + if (spells & SF_RAISE_DEAD) vp[vn++] = "raise dead"; + if (spells & SF_S_MONSTER) vp[vn++] = "summon a monster"; + if (spells & SF_S_MONSTERS) vp[vn++] = "summon monsters"; + if (spells & SF_S_KIN) vp[vn++] = "summon aid"; + if (spells & SF_S_ANT) vp[vn++] = "summon ants"; + if (spells & SF_S_SPIDER) vp[vn++] = "summon spiders"; + if (spells & SF_S_HOUND) vp[vn++] = "summon hounds"; + if (spells & SF_S_HYDRA) vp[vn++] = "summon hydras"; + if (spells & SF_S_ANGEL) vp[vn++] = "summon an angel"; + if (spells & SF_S_DEMON) vp[vn++] = "summon a demon"; + if (spells & SF_S_UNDEAD) vp[vn++] = "summon an undead"; + if (spells & SF_S_DRAGON) vp[vn++] = "summon a dragon"; + if (spells & SF_S_ANIMAL) vp[vn++] = "summon animal"; + if (spells & SF_S_ANIMALS) vp[vn++] = "summon animals"; + if (spells & SF_S_HI_UNDEAD) vp[vn++] = "summon Greater Undead"; + if (spells & SF_S_HI_DRAGON) vp[vn++] = "summon Ancient Dragons"; + if (spells & SF_S_HI_DEMON) vp[vn++] = "summon Greater Demons"; + if (spells & SF_S_WRAITH) vp[vn++] = "summon Ringwraith"; + if (spells & SF_S_UNIQUE) vp[vn++] = "summon Unique Monsters"; /* Describe spells */ if (vn) @@ -746,7 +519,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) text_out(" magical, casting spells"); /* Adverb */ - if (flags2 & (RF2_SMART)) text_out_c(TERM_YELLOW, " intelligently"); + if (flags & RF_SMART) text_out_c(TERM_YELLOW, " intelligently"); /* Scan */ for (n = 0; n < vn; n++) @@ -765,30 +538,14 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* End the sentence about inate/other spells */ if (breath || magic) { - /* Total casting */ - m = r_ptr->r_cast_inate + r_ptr->r_cast_spell; - /* Average frequency */ n = (r_ptr->freq_inate + r_ptr->freq_spell) / 2; /* Describe the spell frequency */ - if (m > 100) - { - text_out("; "); - text_out_c(TERM_L_GREEN, "1"); - text_out(" time in "); - text_out_c(TERM_L_GREEN, format("%d", 100 / n)); - } - - /* Guess at the frequency */ - else if (m) - { - n = ((n + 9) / 10) * 10; - text_out("; about "); - text_out_c(TERM_L_GREEN, "1"); - text_out(" time in "); - text_out_c(TERM_L_GREEN, format("%d", 100 / n)); - } + text_out("; "); + text_out_c(TERM_L_GREEN, "1"); + text_out(" time in "); + text_out_c(TERM_L_GREEN, format("%d", 100 / n)); /* End this sentence */ text_out(". "); @@ -796,14 +553,13 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Describe monster "toughness" */ - if (know_armour(r_ptr)) { /* Armor */ text_out(format("%^s has an armor rating of ", wd_he[msex])); text_out_c(TERM_L_GREEN, format("%d", r_ptr->ac)); /* Maximized hitpoints */ - if (flags1 & (RF1_FORCE_MAXHP)) + if (flags & RF_FORCE_MAXHP) { text_out(" and a life rating of "); text_out_c(TERM_L_GREEN, format("%d", r_ptr->hdice * r_ptr->hside)); @@ -823,15 +579,15 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect special abilities. */ vn = 0; - if (flags2 & (RF2_OPEN_DOOR)) vp[vn++] = "open doors"; - if (flags2 & (RF2_BASH_DOOR)) vp[vn++] = "bash down doors"; - if (flags2 & (RF2_PASS_WALL)) vp[vn++] = "pass through walls"; - if (flags2 & (RF2_KILL_WALL)) vp[vn++] = "bore through walls"; - if (flags2 & (RF2_MOVE_BODY)) vp[vn++] = "push past weaker monsters"; - if (flags2 & (RF2_KILL_BODY)) vp[vn++] = "destroy weaker monsters"; - if (flags2 & (RF2_TAKE_ITEM)) vp[vn++] = "pick up objects"; - if (flags2 & (RF2_KILL_ITEM)) vp[vn++] = "destroy objects"; - if (flags9 & (RF9_HAS_LITE)) vp[vn++] = "illuminate the dungeon"; + if (flags & RF_OPEN_DOOR) vp[vn++] = "open doors"; + if (flags & RF_BASH_DOOR) vp[vn++] = "bash down doors"; + if (flags & RF_PASS_WALL) vp[vn++] = "pass through walls"; + if (flags & RF_KILL_WALL) vp[vn++] = "bore through walls"; + if (flags & RF_MOVE_BODY) vp[vn++] = "push past weaker monsters"; + if (flags & RF_KILL_BODY) vp[vn++] = "destroy weaker monsters"; + if (flags & RF_TAKE_ITEM) vp[vn++] = "pick up objects"; + if (flags & RF_KILL_ITEM) vp[vn++] = "destroy objects"; + if (flags & RF_HAS_LITE) vp[vn++] = "illuminate the dungeon"; /* Describe special abilities. */ if (vn) @@ -857,31 +613,32 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Describe special abilities. */ - if (flags2 & (RF2_INVISIBLE)) + if (flags & RF_INVISIBLE) { text_out_c(TERM_GREEN, format("%^s is invisible. ", wd_he[msex])); } - if (flags2 & (RF2_COLD_BLOOD)) + if (flags & RF_COLD_BLOOD) { text_out(format("%^s is cold blooded. ", wd_he[msex])); } - if (flags2 & (RF2_EMPTY_MIND)) + if (flags & RF_EMPTY_MIND) { text_out(format("%^s is not detected by telepathy. ", wd_he[msex])); } - if (flags2 & (RF2_WEIRD_MIND)) + if (flags & RF_WEIRD_MIND) { text_out(format("%^s is rarely detected by telepathy. ", wd_he[msex])); } - if (flags4 & (RF4_MULTIPLY)) + if (spells & SF_MULTIPLY) { text_out_c(TERM_L_UMBER, format("%^s breeds explosively. ", wd_he[msex])); } - if (flags2 & (RF2_REGENERATE)) + if (flags & RF_REGENERATE) { text_out_c(TERM_L_WHITE, format("%^s regenerates quickly. ", wd_he[msex])); } - if (r_ptr->flags7 & (RF7_MORTAL)) + + if (r_ptr->flags & RF_MORTAL) { text_out_c(TERM_RED, format("%^s is a mortal being. ", wd_he[msex])); } @@ -893,37 +650,37 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect susceptibilities */ vn = 0; - if (flags3 & (RF3_HURT_ROCK)) + if (flags & RF_HURT_ROCK) { vp[vn++] = "rock remover"; color[vn - 1] = TERM_UMBER; } - if (flags3 & (RF3_HURT_LITE)) + if (flags & RF_HURT_LITE) { vp[vn++] = "bright light"; color[vn - 1] = TERM_YELLOW; } - if (flags3 & (RF3_SUSCEP_FIRE)) + if (flags & RF_SUSCEP_FIRE) { vp[vn++] = "fire"; color[vn - 1] = TERM_RED; } - if (flags3 & (RF3_SUSCEP_COLD)) + if (flags & RF_SUSCEP_COLD) { vp[vn++] = "cold"; color[vn - 1] = TERM_L_WHITE; } - if (flags9 & (RF9_SUSCEP_ACID)) + if (flags & RF_SUSCEP_ACID) { vp[vn++] = "acid"; color[vn - 1] = TERM_GREEN; } - if (flags9 & (RF9_SUSCEP_ELEC)) + if (flags & RF_SUSCEP_ELEC) { vp[vn++] = "lightning"; color[vn - 1] = TERM_L_BLUE; } - if (flags9 & (RF9_SUSCEP_POIS)) + if (flags & RF_SUSCEP_POIS) { vp[vn++] = "poison"; color[vn - 1] = TERM_L_GREEN; @@ -954,27 +711,27 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect immunities */ vn = 0; - if (flags3 & (RF3_IM_ACID)) + if (flags & RF_IM_ACID) { vp[vn++] = "acid"; color[vn - 1] = TERM_L_GREEN; } - if (flags3 & (RF3_IM_ELEC)) + if (flags & RF_IM_ELEC) { vp[vn++] = "lightning"; color[vn - 1] = TERM_L_BLUE; } - if (flags3 & (RF3_IM_FIRE)) + if (flags & RF_IM_FIRE) { vp[vn++] = "fire"; color[vn - 1] = TERM_L_RED; } - if (flags3 & (RF3_IM_COLD)) + if (flags & RF_IM_COLD) { vp[vn++] = "cold"; color[vn - 1] = TERM_L_BLUE; } - if (flags3 & (RF3_IM_POIS)) + if (flags & RF_IM_POIS) { vp[vn++] = "poison"; color[vn - 1] = TERM_L_GREEN; @@ -1005,12 +762,12 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect resistances */ vn = 0; - if (flags3 & (RF3_RES_NETH)) vp[vn++] = "nether"; - if (flags3 & (RF3_RES_WATE)) vp[vn++] = "water"; - if (flags3 & (RF3_RES_PLAS)) vp[vn++] = "plasma"; - if (flags3 & (RF3_RES_NEXU)) vp[vn++] = "nexus"; - if (flags3 & (RF3_RES_DISE)) vp[vn++] = "disenchantment"; - if (flags3 & (RF3_RES_TELE)) vp[vn++] = "teleportation"; + if (flags & RF_RES_NETH) vp[vn++] = "nether"; + if (flags & RF_RES_WATE) vp[vn++] = "water"; + if (flags & RF_RES_PLAS) vp[vn++] = "plasma"; + if (flags & RF_RES_NEXU) vp[vn++] = "nexus"; + if (flags & RF_RES_DISE) vp[vn++] = "disenchantment"; + if (flags & RF_RES_TELE) vp[vn++] = "teleportation"; /* Describe resistances */ if (vn) @@ -1037,10 +794,10 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Collect non-effects */ vn = 0; - if (flags3 & (RF3_NO_STUN)) vp[vn++] = "stunned"; - if (flags3 & (RF3_NO_FEAR)) vp[vn++] = "frightened"; - if (flags3 & (RF3_NO_CONF)) vp[vn++] = "confused"; - if (flags3 & (RF3_NO_SLEEP)) vp[vn++] = "slept"; + if (flags & RF_NO_STUN) vp[vn++] = "stunned"; + if (flags & RF_NO_FEAR) vp[vn++] = "frightened"; + if (flags & RF_NO_CONF) vp[vn++] = "confused"; + if (flags & RF_NO_SLEEP) vp[vn++] = "slept"; /* Describe non-effects */ if (vn) @@ -1065,10 +822,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } - /* Do we know how aware it is? */ - if (((static_cast<int>(r_ptr->r_wake) * static_cast<int>(r_ptr->r_wake)) > r_ptr->sleep) || - (r_ptr->r_ignore == MAX_UCHAR) || - ((r_ptr->sleep == 0) && (r_ptr->r_tkills >= 10))) + /* How aware is it? */ { cptr act; @@ -1123,45 +877,57 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Drops gold and/or items */ - if (r_ptr->r_drop_gold || r_ptr->r_drop_item) { + /* Calculate drops */ + byte drop_gold; + byte drop_item; + + drop_gold = drop_item = + (((r_ptr->flags & RF_DROP_4D2) ? 8 : 0) + + ((r_ptr->flags & RF_DROP_3D2) ? 6 : 0) + + ((r_ptr->flags & RF_DROP_2D2) ? 4 : 0) + + ((r_ptr->flags & RF_DROP_1D2) ? 2 : 0) + + ((r_ptr->flags & RF_DROP_90) ? 1 : 0) + + ((r_ptr->flags & RF_DROP_60) ? 1 : 0)); + + if (r_ptr->flags & RF_ONLY_GOLD) drop_item = 0; + if (r_ptr->flags & RF_ONLY_ITEM) drop_gold = 0; + /* No "n" needed */ sin = FALSE; - /* Intro */ - text_out(format("%^s may carry", wd_he[msex])); - /* Count maximum drop */ - n = MAX(r_ptr->r_drop_gold, r_ptr->r_drop_item); + n = MAX(drop_gold, drop_item); - /* One drop (may need an "n") */ - if (n == 1) + /* Intro text */ + if (n == 0) { - text_out(" a"); + text_out(format("%^s carries no items", wd_he[msex])); + + } + else if (n == 1) + { + text_out(format("%^s may carry a", wd_he[msex])); sin = TRUE; } - - /* Two drops */ else if (n == 2) { - text_out(" one or two"); + text_out(format("%^s may carry one or two", wd_he[msex])); } - - /* Many drops */ else { - text_out(format(" up to %d", n)); + text_out(format("%^s may carry up to %d", wd_he[msex], n)); } /* Great */ - if (flags1 & (RF1_DROP_GREAT)) + if (flags & RF_DROP_GREAT) { p = " exceptional"; } /* Good (no "n" needed) */ - else if (flags1 & (RF1_DROP_GOOD)) + else if (flags & RF_DROP_GOOD) { p = " good"; sin = FALSE; @@ -1175,7 +941,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* Objects */ - if (r_ptr->r_drop_item) + if (drop_item) { /* Handle singular "an" */ if (sin) text_out("n"); @@ -1191,7 +957,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } /* Treasures */ - if (r_ptr->r_drop_gold) + if (drop_gold) { /* Cancel prefix */ if (!p) sin = FALSE; @@ -1211,33 +977,27 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } - /* Count the number of "known" attacks */ + /* Count the number of attacks */ for (n = 0, m = 0; m < 4; m++) { /* Skip non-attacks */ if (!r_ptr->blow[m].method) continue; /* Count known attacks */ - if (r_ptr->r_blows[m]) n++; + n++; } - /* Examine (and count) the actual attacks */ + /* Examine the actual attacks */ for (r = 0, m = 0; m < 4; m++) { - int method, effect, d1, d2; - /* Skip non-attacks */ if (!r_ptr->blow[m].method) continue; - /* Skip unknown attacks */ - if (!r_ptr->r_blows[m]) continue; - - /* Extract the attack info */ - method = r_ptr->blow[m].method; - effect = r_ptr->blow[m].effect; - d1 = r_ptr->blow[m].d_dice; - d2 = r_ptr->blow[m].d_side; + int method = r_ptr->blow[m].method; + int effect = r_ptr->blow[m].effect; + int d1 = r_ptr->blow[m].d_dice; + int d2 = r_ptr->blow[m].d_side; /* No method yet */ @@ -1457,7 +1217,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) text_out_c(TERM_YELLOW, q); /* Describe damage (if known) */ - if (d1 && d2 && know_damage(r_ptr, m)) + if (d1 && d2) { /* Display the damage */ text_out(" with damage"); @@ -1477,7 +1237,7 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) } /* Notice lack of attacks */ - else if (flags1 & (RF1_NEVER_BLOW)) + else if (flags & RF_NEVER_BLOW) { text_out(format("%^s has no physical attacks. ", wd_he[msex])); } @@ -1491,13 +1251,6 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) /* All done */ text_out("\n"); - - /* Cheat -- know everything */ - if ((cheat_know) && (remem == 0)) - { - /* Hack -- restore memory */ - *r_ptr = save_mem; - } } /* @@ -1505,6 +1258,8 @@ static void roff_aux(std::shared_ptr<monster_race> r_ptr, int remem) */ static void roff_name(int r_idx, int ego) { + const auto &re_info = game->edit_data.re_info; + const auto r_ptr = race_info_idx(r_idx, ego); /* Access the chars */ @@ -1516,7 +1271,7 @@ static void roff_name(int r_idx, int ego) const byte a2 = r_ptr->x_attr; /* A title (use "The" for non-uniques) */ - if (!(r_ptr->flags1 & (RF1_UNIQUE))) + if (!(r_ptr->flags & RF_UNIQUE)) { Term_addstr( -1, TERM_WHITE, "The "); } @@ -1566,7 +1321,7 @@ static void roff_top(int r_idx, int ego) /* * Hack -- describe the given monster race at the top of the screen */ -void screen_roff(int r_idx, int ego, int remember) +void screen_roff(int r_idx, int ego) { auto r_ptr = race_info_idx(r_idx, ego); @@ -1577,7 +1332,7 @@ void screen_roff(int r_idx, int ego, int remember) Term_erase(0, 1, 255); /* Recall monster */ - roff_aux(r_ptr, remember); + roff_aux(r_ptr); /* Describe monster */ roff_top(r_idx, ego); @@ -1590,7 +1345,7 @@ void monster_description_out(int r_idx, int ego) { auto r_ptr = race_info_idx(r_idx, ego); roff_name(r_idx, ego); - roff_aux(r_ptr, 0); + roff_aux(r_ptr); } /* @@ -1614,7 +1369,7 @@ void display_roff(int r_idx, int ego) /* Recall monster */ auto r_ptr = race_info_idx(r_idx, ego); - roff_aux(r_ptr, 0); + roff_aux(r_ptr); /* Describe monster */ roff_top(r_idx, ego); @@ -1623,16 +1378,18 @@ void display_roff(int r_idx, int ego) bool_ monster_quest(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Random quests are in the dungeon */ - if (!(r_ptr->flags8 & RF8_DUNGEON)) return FALSE; + if (r_ptr->flags & RF_WILD_ONLY) return FALSE; /* No random quests for aquatic monsters */ - if (r_ptr->flags7 & RF7_AQUATIC) return FALSE; + if (r_ptr->flags & RF_AQUATIC) return FALSE; /* No random quests for multiplying monsters */ - if (r_ptr->flags4 & RF4_MULTIPLY) return FALSE; + if (r_ptr->spells & SF_MULTIPLY) return FALSE; return TRUE; } @@ -1640,9 +1397,11 @@ bool_ monster_quest(int r_idx) bool_ monster_dungeon(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags8 & RF8_DUNGEON) + auto r_ptr = &r_info[r_idx]; + + if (!(r_ptr->flags & RF_WILD_ONLY)) return TRUE; else return FALSE; @@ -1651,9 +1410,11 @@ bool_ monster_dungeon(int r_idx) static bool_ monster_ocean(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; - if (r_ptr->flags8 & RF8_WILD_OCEAN) + if (r_ptr->flags & RF_WILD_OCEAN) return TRUE; else return FALSE; @@ -1662,9 +1423,11 @@ static bool_ monster_ocean(int r_idx) static bool_ monster_shore(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags8 & RF8_WILD_SHORE) + auto r_ptr = &r_info[r_idx]; + + if (r_ptr->flags & RF_WILD_SHORE) return TRUE; else return FALSE; @@ -1673,9 +1436,11 @@ static bool_ monster_shore(int r_idx) static bool_ monster_waste(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; - if (r_ptr->flags8 & RF8_WILD_WASTE) + if (r_ptr->flags & RF_WILD_WASTE) return TRUE; else return FALSE; @@ -1684,9 +1449,11 @@ static bool_ monster_waste(int r_idx) static bool_ monster_town(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags8 & RF8_WILD_TOWN) + auto r_ptr = &r_info[r_idx]; + + if (r_ptr->flags & RF_WILD_TOWN) return TRUE; else return FALSE; @@ -1695,9 +1462,11 @@ static bool_ monster_town(int r_idx) static bool_ monster_wood(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; - if (r_ptr->flags8 & RF8_WILD_WOOD) + if (r_ptr->flags & RF_WILD_WOOD) return TRUE; else return FALSE; @@ -1706,9 +1475,11 @@ static bool_ monster_wood(int r_idx) static bool_ monster_volcano(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags8 & RF8_WILD_VOLCANO) + auto r_ptr = &r_info[r_idx]; + + if (r_ptr->flags & RF_WILD_VOLCANO) return TRUE; else return FALSE; @@ -1717,9 +1488,11 @@ static bool_ monster_volcano(int r_idx) static bool_ monster_mountain(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; - if (r_ptr->flags8 & RF8_WILD_MOUNTAIN) + if (r_ptr->flags & RF_WILD_MOUNTAIN) return TRUE; else return FALSE; @@ -1728,9 +1501,11 @@ static bool_ monster_mountain(int r_idx) static bool_ monster_grass(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags8 & RF8_WILD_GRASS) + auto r_ptr = &r_info[r_idx]; + + if (r_ptr->flags & RF_WILD_GRASS) return TRUE; else return FALSE; @@ -1739,11 +1514,13 @@ static bool_ monster_grass(int r_idx) static bool_ monster_deep_water(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; if (!monster_dungeon(r_idx)) return FALSE; - if (r_ptr->flags7 & RF7_AQUATIC) + if (r_ptr->flags & RF_AQUATIC) return TRUE; else return FALSE; @@ -1752,11 +1529,13 @@ static bool_ monster_deep_water(int r_idx) static bool_ monster_shallow_water(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; if (!monster_dungeon(r_idx)) return FALSE; - if (r_ptr->flags2 & RF2_AURA_FIRE) + if (r_ptr->flags & RF_AURA_FIRE) return FALSE; else return TRUE; @@ -1765,24 +1544,29 @@ static bool_ monster_shallow_water(int r_idx) static bool_ monster_lava(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; if (!monster_dungeon(r_idx)) return FALSE; - if (((r_ptr->flags3 & RF3_IM_FIRE) || - (r_ptr->flags7 & RF7_CAN_FLY)) && - !(r_ptr->flags3 & RF3_AURA_COLD)) + if (((r_ptr->flags & RF_IM_FIRE) || + (r_ptr->flags & RF_CAN_FLY)) && + !(r_ptr->flags & RF_AURA_COLD)) return TRUE; else return FALSE; } -void set_mon_num_hook(void) +void set_mon_num_hook() { + auto const &wf_info = game->edit_data.wf_info; + if (!dun_level) { - switch (wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].terrain_idx) + auto const &wilderness = game->wilderness; + switch (wf_info[wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).feat].terrain_idx) { case TERRAIN_TOWN: get_mon_num_hook = monster_town; @@ -1829,9 +1613,9 @@ bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr) /* Deep water */ if (feat == FEAT_DEEP_WATER) { - if ((r_ptr->flags7 & RF7_AQUATIC) || - (r_ptr->flags7 & RF7_CAN_FLY) || - (r_ptr->flags7 & RF7_CAN_SWIM)) + if ((r_ptr->flags & RF_AQUATIC) || + (r_ptr->flags & RF_CAN_FLY) || + (r_ptr->flags & RF_CAN_SWIM)) return TRUE; else return FALSE; @@ -1839,14 +1623,14 @@ bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr) /* Shallow water */ else if (feat == FEAT_SHAL_WATER) { - if (r_ptr->flags2 & RF2_AURA_FIRE) + if (r_ptr->flags & RF_AURA_FIRE) return FALSE; else return TRUE; } /* Aquatic monster */ - else if ((r_ptr->flags7 & RF7_AQUATIC) && - !(r_ptr->flags7 & RF7_CAN_FLY)) + else if ((r_ptr->flags & RF_AQUATIC) && + !(r_ptr->flags & RF_CAN_FLY)) { return FALSE; } @@ -1854,8 +1638,8 @@ bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr) else if ((feat == FEAT_SHAL_LAVA) || (feat == FEAT_DEEP_LAVA)) { - if ((r_ptr->flags3 & RF3_IM_FIRE) || - (r_ptr->flags7 & RF7_CAN_FLY)) + if ((r_ptr->flags & RF_IM_FIRE) || + (r_ptr->flags & RF_CAN_FLY)) return TRUE; else return FALSE; diff --git a/src/monster1.hpp b/src/monster1.hpp index 1d71fef1..34f54346 100644 --- a/src/monster1.hpp +++ b/src/monster1.hpp @@ -1,5 +1,5 @@ #pragma once -extern void screen_roff(int r_idx, int ego, int remember); -extern void display_roff(int r_idx, int ego); -extern void monster_description_out(int r_idx, int ego); +void screen_roff(int r_idx, int ego); +void display_roff(int r_idx, int ego); +void monster_description_out(int r_idx, int ego); diff --git a/src/monster2.cc b/src/monster2.cc index 3debb27a..624dca53 100644 --- a/src/monster2.cc +++ b/src/monster2.cc @@ -11,8 +11,10 @@ #include "artifact_type.hpp" #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hook_new_monster_in.hpp" #include "hook_new_monster_end_in.hpp" #include "hooks.hpp" @@ -21,12 +23,16 @@ #include "monster3.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" +#include "player_race_flag.hpp" #include "player_type.hpp" #include "randart.hpp" #include "spells1.hpp" @@ -59,8 +65,10 @@ s32b monster_exp(s16b level) /* Monster gain a few levels ? */ void monster_check_experience(int m_idx, bool_ silent) { + auto const &r_info = game->edit_data.r_info; + monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; + auto r_ptr = &r_info[m_ptr->r_idx]; char m_name[80]; /* Get the name */ @@ -166,25 +174,17 @@ s32b modify_aux(s32b a, s32b b, char mod) /* Is this ego ok for this monster ? */ bool_ mego_ok(monster_race const *r_ptr, int ego) { - monster_ego *re_ptr = &re_info[ego]; + const auto &re_info = game->edit_data.re_info; + + auto re_ptr = &re_info[ego]; bool_ ok = FALSE; int i; /* needed flags */ - if (re_ptr->flags1 && ((re_ptr->flags1 & r_ptr->flags1) != re_ptr->flags1)) return FALSE; - if (re_ptr->flags2 && ((re_ptr->flags2 & r_ptr->flags2) != re_ptr->flags2)) return FALSE; - if (re_ptr->flags3 && ((re_ptr->flags3 & r_ptr->flags3) != re_ptr->flags3)) return FALSE; - if (re_ptr->flags7 && ((re_ptr->flags7 & r_ptr->flags7) != re_ptr->flags7)) return FALSE; - if (re_ptr->flags8 && ((re_ptr->flags8 & r_ptr->flags8) != re_ptr->flags8)) return FALSE; - if (re_ptr->flags9 && ((re_ptr->flags9 & r_ptr->flags9) != re_ptr->flags9)) return FALSE; + if (re_ptr->flags && ((re_ptr->flags & r_ptr->flags) != re_ptr->flags)) return FALSE; /* unwanted flags */ - if (re_ptr->hflags1 && (re_ptr->hflags1 & r_ptr->flags1)) return FALSE; - if (re_ptr->hflags2 && (re_ptr->hflags2 & r_ptr->flags2)) return FALSE; - if (re_ptr->hflags3 && (re_ptr->hflags3 & r_ptr->flags3)) return FALSE; - if (re_ptr->hflags7 && (re_ptr->hflags7 & r_ptr->flags7)) return FALSE; - if (re_ptr->hflags8 && (re_ptr->hflags8 & r_ptr->flags8)) return FALSE; - if (re_ptr->hflags9 && (re_ptr->hflags9 & r_ptr->flags9)) return FALSE; + if (re_ptr->hflags && (re_ptr->hflags & r_ptr->flags)) return FALSE; /* Need good race -- IF races are specified */ if (re_ptr->r_char[0]) @@ -210,12 +210,13 @@ bool_ mego_ok(monster_race const *r_ptr, int ego) /* Choose an ego type */ static int pick_ego_monster(monster_race const *r_ptr) { + const auto &re_info = game->edit_data.re_info; + /* Assume no ego */ int ego = 0, lvl; - int tries = max_re_idx + 10; - monster_ego *re_ptr; + int tries = re_info.size() + 10; - if ((!(dungeon_flags2 & DF2_ELVEN)) && (!(dungeon_flags2 & DF2_DWARVEN))) + if ((!(dungeon_flags & DF_ELVEN)) && (!(dungeon_flags & DF_DWARVEN))) { /* No townspeople ego */ if (!r_ptr->level) return 0; @@ -227,8 +228,8 @@ static int pick_ego_monster(monster_race const *r_ptr) while (tries--) { /* Pick one */ - ego = rand_range(1, max_re_idx - 1); - re_ptr = &re_info[ego]; + ego = rand_range(1, re_info.size() - 1); + auto re_ptr = &re_info[ego]; /* No hope so far */ if (!mego_ok(r_ptr, ego)) continue; @@ -250,9 +251,9 @@ static int pick_ego_monster(monster_race const *r_ptr) /* Bypass restrictions for themed townspeople */ else { - if (dungeon_flags2 & DF2_ELVEN) + if (dungeon_flags & DF_ELVEN) ego = test_mego_name("Elven"); - else if (dungeon_flags2 & DF2_DWARVEN) + else if (dungeon_flags & DF_DWARVEN) ego = test_mego_name("Dwarven"); if (mego_ok(r_ptr, ego)) @@ -269,7 +270,10 @@ static int pick_ego_monster(monster_race const *r_ptr) */ std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &re_info = game->edit_data.re_info; + auto &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* We don't need to allocate anything if it's an ordinary monster. */ if (!ego) { @@ -283,7 +287,7 @@ std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego) *nr_ptr = *r_ptr; /* Get a reference to the ego monster modifiers */ - monster_ego *re_ptr = &re_info[ego]; + auto re_ptr = &re_info[ego]; /* Adjust the values */ for (int i = 0; i < 4; i++) @@ -329,26 +333,12 @@ std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego) MODIFY(nr_ptr->level, re_ptr->level, 1); /* Take off some flags */ - nr_ptr->flags1 &= ~(re_ptr->nflags1); - nr_ptr->flags2 &= ~(re_ptr->nflags2); - nr_ptr->flags3 &= ~(re_ptr->nflags3); - nr_ptr->flags4 &= ~(re_ptr->nflags4); - nr_ptr->flags5 &= ~(re_ptr->nflags5); - nr_ptr->flags6 &= ~(re_ptr->nflags6); - nr_ptr->flags7 &= ~(re_ptr->nflags7); - nr_ptr->flags8 &= ~(re_ptr->nflags8); - nr_ptr->flags9 &= ~(re_ptr->nflags9); + nr_ptr->flags &= ~re_ptr->nflags; + nr_ptr->spells &= ~(re_ptr->nspells); /* Add some flags */ - nr_ptr->flags1 |= re_ptr->mflags1; - nr_ptr->flags2 |= re_ptr->mflags2; - nr_ptr->flags3 |= re_ptr->mflags3; - nr_ptr->flags4 |= re_ptr->mflags4; - nr_ptr->flags5 |= re_ptr->mflags5; - nr_ptr->flags6 |= re_ptr->mflags6; - nr_ptr->flags7 |= re_ptr->mflags7; - nr_ptr->flags8 |= re_ptr->mflags8; - nr_ptr->flags9 |= re_ptr->mflags9; + nr_ptr->flags |= re_ptr->mflags; + nr_ptr->spells |= re_ptr->mspells; /* Change the char/attr is needed */ if (re_ptr->d_char != MEGO_CHAR_ANY) @@ -440,6 +430,10 @@ static cptr funny_comments[MAX_COMMENT] = */ void delete_monster_idx(int i) { + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &random_artifacts = game->random_artifacts; + /* Get location */ monster_type *m_ptr = &m_list[i]; int y = m_ptr->fy; @@ -451,11 +445,11 @@ void delete_monster_idx(int i) r_ptr->on_saved = FALSE; /* Hack -- count the number of "reproducers" */ - if (r_ptr->flags4 & (RF4_MULTIPLY)) num_repro--; + if (r_ptr->spells & SF_MULTIPLY) num_repro--; /* XXX XXX XXX remove monster light source */ bool_ had_lite = FALSE; - if (r_ptr->flags9 & (RF9_HAS_LITE)) had_lite = TRUE; + if (r_ptr->flags & RF_HAS_LITE) had_lite = TRUE; /* Hack -- remove target monster */ @@ -495,7 +489,7 @@ void delete_monster_idx(int i) /* Hack -- efficiency */ o_ptr->held_m_idx = 0; - if ( p_ptr->preserve ) + if (options->preserve) { /* Hack -- Preserve unknown artifacts */ if (artifact_p(o_ptr) && !object_known_p(o_ptr)) @@ -505,7 +499,7 @@ void delete_monster_idx(int i) { random_artifacts[o_ptr->sval].generated = FALSE; } - else if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { k_info[o_ptr->k_idx].artifact = FALSE; } @@ -681,7 +675,7 @@ void compact_monsters(int size) if ((m_ptr->mflag & MFLAG_QUEST) && (cnt < 1000)) chance = 100; /* Try not to compact Unique Monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) chance = 99; + if (r_ptr->flags & RF_UNIQUE) chance = 99; /* All monsters get a saving throw */ if (rand_int(100) < chance) continue; @@ -718,7 +712,7 @@ void compact_monsters(int size) * This is an efficient method of simulating multiple calls to the * "delete_monster()" function, with no visual effects. */ -void wipe_m_list(void) +void wipe_m_list() { int i; @@ -730,8 +724,6 @@ void wipe_m_list(void) /* Skip dead monsters */ if (!m_ptr->r_idx) continue; - /* Mega-Hack -- preserve Unique's XXX XXX XXX */ - /* Hack -- Reduce the racial counter */ auto r_ptr = m_ptr->race(); r_ptr->cur_num--; @@ -768,7 +760,7 @@ void wipe_m_list(void) * * This routine should almost never fail, but it *can* happen. */ -s16b m_pop(void) +s16b m_pop() { int i; @@ -822,29 +814,26 @@ s16b m_pop(void) /* * Apply a "monster restriction function" to the "monster allocation table" */ -errr get_mon_num_prep(void) +errr get_mon_num_prep() { - int i; + auto &alloc = game->alloc; /* Scan the allocation table */ - for (i = 0; i < alloc_race_size; i++) + for (auto &&entry: alloc.race_table) { - /* Get the entry */ - alloc_entry *entry = &alloc_race_table[i]; - /* Accept monsters which pass the restriction, if any */ - if ((!get_mon_num_hook || (*get_mon_num_hook)(entry->index)) && - (!get_mon_num2_hook || (*get_mon_num2_hook)(entry->index))) + if ((!get_mon_num_hook || (*get_mon_num_hook)(entry.index)) && + (!get_mon_num2_hook || (*get_mon_num2_hook)(entry.index))) { /* Accept this monster */ - entry->prob2 = entry->prob1; + entry.prob2 = entry.prob1; } /* Do not use this monster */ else { /* Decline this monster */ - entry->prob2 = 0; + entry.prob2 = 0; } } @@ -856,9 +845,11 @@ errr get_mon_num_prep(void) * Some dungeon types restrict the possible monsters. * Return TRUE is the monster is OK and FALSE otherwise */ -bool_ apply_rule(monster_race *r_ptr, byte rule) +static bool_ apply_rule(monster_race const *r_ptr, byte rule) { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto const &d_info = game->edit_data.d_info; + + auto d_ptr = &d_info[dungeon_type]; if (d_ptr->rules[rule].mode == DUNGEON_MODE_NONE) { @@ -868,49 +859,14 @@ bool_ apply_rule(monster_race *r_ptr, byte rule) { int a; - if (d_ptr->rules[rule].mflags1) - { - if ((d_ptr->rules[rule].mflags1 & r_ptr->flags1) != d_ptr->rules[rule].mflags1) - return FALSE; - } - if (d_ptr->rules[rule].mflags2) - { - if ((d_ptr->rules[rule].mflags2 & r_ptr->flags2) != d_ptr->rules[rule].mflags2) - return FALSE; - } - if (d_ptr->rules[rule].mflags3) - { - if ((d_ptr->rules[rule].mflags3 & r_ptr->flags3) != d_ptr->rules[rule].mflags3) - return FALSE; - } - if (d_ptr->rules[rule].mflags4) + if (d_ptr->rules[rule].mflags) { - if ((d_ptr->rules[rule].mflags4 & r_ptr->flags4) != d_ptr->rules[rule].mflags4) + if ((d_ptr->rules[rule].mflags & r_ptr->flags) != d_ptr->rules[rule].mflags) return FALSE; } - if (d_ptr->rules[rule].mflags5) + if (d_ptr->rules[rule].mspells) { - if ((d_ptr->rules[rule].mflags5 & r_ptr->flags5) != d_ptr->rules[rule].mflags5) - return FALSE; - } - if (d_ptr->rules[rule].mflags6) - { - if ((d_ptr->rules[rule].mflags6 & r_ptr->flags6) != d_ptr->rules[rule].mflags6) - return FALSE; - } - if (d_ptr->rules[rule].mflags7) - { - if ((d_ptr->rules[rule].mflags7 & r_ptr->flags7) != d_ptr->rules[rule].mflags7) - return FALSE; - } - if (d_ptr->rules[rule].mflags8) - { - if ((d_ptr->rules[rule].mflags8 & r_ptr->flags8) != d_ptr->rules[rule].mflags8) - return FALSE; - } - if (d_ptr->rules[rule].mflags9) - { - if ((d_ptr->rules[rule].mflags9 & r_ptr->flags9) != d_ptr->rules[rule].mflags9) + if ((d_ptr->rules[rule].mspells & r_ptr->spells) != d_ptr->rules[rule].mspells) return FALSE; } for (a = 0; a < 5; a++) @@ -925,15 +881,8 @@ bool_ apply_rule(monster_race *r_ptr, byte rule) { int a; - if (d_ptr->rules[rule].mflags1 && (r_ptr->flags1 & d_ptr->rules[rule].mflags1)) return TRUE; - if (d_ptr->rules[rule].mflags2 && (r_ptr->flags2 & d_ptr->rules[rule].mflags2)) return TRUE; - if (d_ptr->rules[rule].mflags3 && (r_ptr->flags3 & d_ptr->rules[rule].mflags3)) return TRUE; - if (d_ptr->rules[rule].mflags4 && (r_ptr->flags4 & d_ptr->rules[rule].mflags4)) return TRUE; - if (d_ptr->rules[rule].mflags5 && (r_ptr->flags5 & d_ptr->rules[rule].mflags5)) return TRUE; - if (d_ptr->rules[rule].mflags6 && (r_ptr->flags6 & d_ptr->rules[rule].mflags6)) return TRUE; - if (d_ptr->rules[rule].mflags7 && (r_ptr->flags7 & d_ptr->rules[rule].mflags7)) return TRUE; - if (d_ptr->rules[rule].mflags8 && (r_ptr->flags8 & d_ptr->rules[rule].mflags8)) return TRUE; - if (d_ptr->rules[rule].mflags9 && (r_ptr->flags9 & d_ptr->rules[rule].mflags9)) return TRUE; + if (d_ptr->rules[rule].mflags && (r_ptr->flags & d_ptr->rules[rule].mflags)) return TRUE; + if (d_ptr->rules[rule].mspells && (r_ptr->spells & d_ptr->rules[rule].mspells)) return TRUE; for (a = 0; a < 5; a++) if (d_ptr->rules[rule].r_char[a] == r_ptr->d_char) return TRUE; @@ -948,8 +897,11 @@ bool_ apply_rule(monster_race *r_ptr, byte rule) bool_ restrict_monster_to_dungeon(int r_idx) { - dungeon_info_type *d_ptr = &d_info[dungeon_type]; - monster_race *r_ptr = &r_info[r_idx]; + auto const &d_info = game->edit_data.d_info; + auto const &r_info = game->edit_data.r_info; + + auto d_ptr = &d_info[dungeon_type]; + auto r_ptr = &r_info[r_idx]; /* Select a random rule */ byte rule = d_ptr->rule_percents[rand_int(100)]; @@ -994,15 +946,13 @@ bool_ summon_hack = FALSE; */ s16b get_mon_num(int level) { - int i, j, p; - - int r_idx; - - long value, total; - - monster_race *r_ptr; + auto const &r_info = game->edit_data.r_info; + auto &alloc = game->alloc; - alloc_entry *table = alloc_race_table; + std::size_t i, j; + int p; + int r_idx; + long value, total; int in_tome; @@ -1038,59 +988,52 @@ s16b get_mon_num(int level) in_tome = strcmp(game_module, "ToME") == 0; /* Process probabilities */ - for (i = 0; i < alloc_race_size; i++) + for (i = 0; i < alloc.race_table.size(); i++) { + auto &entry = alloc.race_table[i]; + /* Monsters are sorted by depth */ - if (table[i].level > level) break; + if (entry.level > level) break; /* Default */ - table[i].prob3 = 0; + entry.prob3 = 0; /* Access the "r_idx" of the chosen monster */ - r_idx = table[i].index; + r_idx = entry.index; /* Access the actual race */ - r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; /* Hack -- "unique" monsters must be "unique" */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) && + if ((r_ptr->flags & RF_UNIQUE) && (r_ptr->cur_num >= r_ptr->max_num)) { continue; } /* Depth Monsters never appear out of depth */ - if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) && (r_ptr->level > dun_level)) + if ((r_ptr->flags & RF_FORCE_DEPTH) && (r_ptr->level > dun_level)) { continue; } /* Depth Monsters never appear out of their depth */ - if ((r_ptr->flags9 & (RF9_ONLY_DEPTH)) && (r_ptr->level != dun_level)) + if ((r_ptr->flags & RF_ONLY_DEPTH) && (r_ptr->level != dun_level)) { continue; } - if(in_tome) - { - /* Zangbandish monsters not allowed */ - if (r_ptr->flags8 & RF8_ZANGBAND) continue; - - /* Lovecraftian monsters not allowed */ - if (r_ptr->flags8 & RF8_CTHANGBAND) continue; - } - /* Joke monsters allowed ? or not ? */ - if (!joke_monsters && (r_ptr->flags8 & RF8_JOKEANGBAND)) continue; + if (!options->joke_monsters && (r_ptr->flags & RF_JOKEANGBAND)) continue; /* Some dungeon types restrict the possible monsters */ if (!summon_hack && !restrict_monster_to_dungeon(r_idx) && dun_level) continue; /* Accept */ - table[i].prob3 = table[i].prob2; + entry.prob3 = entry.prob2; /* Total */ - total += table[i].prob3; + total += entry.prob3; } /* No legal monsters */ @@ -1101,19 +1044,24 @@ s16b get_mon_num(int level) value = rand_int(total); /* Find the monster */ - for (i = 0; i < alloc_race_size; i++) + for (i = 0; i < alloc.race_table.size(); i++) { + auto &entry = alloc.race_table[i]; + /* Found the entry */ - if (value < table[i].prob3) break; + if (value < entry.prob3) break; /* Decrement */ - value = value - table[i].prob3; + value = value - entry.prob3; } /* Power boost */ p = rand_int(100); + /* Shorthand */ + auto &table = alloc.race_table; + /* Try for a "harder" monster once (50%) or twice (10%) */ if (p < 60) { @@ -1124,7 +1072,7 @@ s16b get_mon_num(int level) value = rand_int(total); /* Find the monster */ - for (i = 0; i < alloc_race_size; i++) + for (i = 0; i < table.size(); i++) { /* Found the entry */ if (value < table[i].prob3) break; @@ -1147,7 +1095,7 @@ s16b get_mon_num(int level) value = rand_int(total); /* Find the monster */ - for (i = 0; i < alloc_race_size; i++) + for (i = 0; i < table.size(); i++) { /* Found the entry */ if (value < table[i].prob3) break; @@ -1217,6 +1165,9 @@ s16b get_mon_num(int level) */ void monster_desc(char *desc, monster_type *m_ptr, int mode) { + auto const &re_info = game->edit_data.re_info; + auto const &r_info = game->edit_data.r_info; + auto r_ptr = m_ptr->race(); char silly_name[80], name[100]; bool_ seen, pron; @@ -1224,13 +1175,15 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) if (m_ptr->ego) { - if (re_info[m_ptr->ego].before) + auto const &monster_ego = re_info[m_ptr->ego]; + + if (monster_ego.before) { - sprintf(name, "%s %s", re_info[m_ptr->ego].name, r_ptr->name); + sprintf(name, "%s %s", monster_ego.name, r_ptr->name); } else { - sprintf(name, "%s %s", r_ptr->name, re_info[m_ptr->ego].name); + sprintf(name, "%s %s", r_ptr->name, monster_ego.name); } } else @@ -1246,13 +1199,13 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) { if (rand_int(2) == 0) { - monster_race *hallu_race; + monster_race const *hallu_race; do { - hallu_race = &r_info[randint(max_r_idx - 2)]; + hallu_race = &*uniform_element(r_info); } - while (hallu_race->flags1 & RF1_UNIQUE); + while ((!hallu_race->name) || (hallu_race->flags & RF_UNIQUE)); strcpy(silly_name, hallu_race->name); } @@ -1277,8 +1230,8 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) int kind = 0x00; /* Extract the gender (if applicable) */ - if (r_ptr->flags1 & (RF1_FEMALE)) kind = 0x20; - else if (r_ptr->flags1 & (RF1_MALE)) kind = 0x10; + if (r_ptr->flags & RF_FEMALE) kind = 0x20; + else if (r_ptr->flags & RF_MALE) kind = 0x10; /* Ignore the gender (if desired) */ if (!m_ptr || !pron) kind = 0x00; @@ -1370,7 +1323,7 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) } /* Copy the result */ - (void)strcpy(desc, res); + strcpy(desc, res); } @@ -1378,8 +1331,8 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) else if ((mode & 0x02) && (mode & 0x01)) { /* The monster is visible, so use its gender */ - if (r_ptr->flags1 & (RF1_FEMALE)) strcpy(desc, "herself"); - else if (r_ptr->flags1 & (RF1_MALE)) strcpy(desc, "himself"); + if (r_ptr->flags & RF_FEMALE) strcpy(desc, "herself"); + else if (r_ptr->flags & RF_MALE) strcpy(desc, "himself"); else strcpy(desc, "itself"); } @@ -1388,10 +1341,10 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) else { /* It could be a Unique */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) && !(p_ptr->image)) + if ((r_ptr->flags & RF_UNIQUE) && !(p_ptr->image)) { /* Start with the name (thus nominative and objective) */ - (void)strcpy(desc, name); + strcpy(desc, name); } /* It could be an indefinite monster */ @@ -1400,8 +1353,8 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) /* XXX Check plurality for "some" */ /* Indefinite monsters need an indefinite article */ - (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a "); - (void)strcat(desc, name); + strcpy(desc, is_a_vowel(name[0]) ? "an " : "a "); + strcat(desc, name); } /* It could be a normal, definite, monster */ @@ -1409,11 +1362,11 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) { /* Definite monsters need a definite article */ if (m_ptr->status >= MSTATUS_PET) - (void)strcpy(desc, "your "); + strcpy(desc, "your "); else - (void)strcpy(desc, "the "); + strcpy(desc, "the "); - (void)strcat(desc, name); + strcat(desc, name); } /* Handle the Possessive as a special afterthought */ @@ -1422,25 +1375,30 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode) /* XXX Check for trailing "s" */ /* Simply append "apostrophe" and "s" */ - (void)strcat(desc, "'s"); + strcat(desc, "'s"); } } } void monster_race_desc(char *desc, int r_idx, int ego) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &re_info = game->edit_data.re_info; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; char name[80]; if (ego) { - if (re_info[ego].before) + auto const &monster_ego = re_info[ego]; + + if (monster_ego.before) { - sprintf(name, "%s %s", re_info[ego].name, r_ptr->name); + sprintf(name, "%s %s", monster_ego.name, r_ptr->name); } else { - sprintf(name, "%s %s", r_ptr->name, re_info[ego].name); + sprintf(name, "%s %s", r_ptr->name, monster_ego.name); } } else @@ -1449,79 +1407,19 @@ void monster_race_desc(char *desc, int r_idx, int ego) } /* It could be a Unique */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { /* Start with the name (thus nominative and objective) */ - (void)strcpy(desc, name); + strcpy(desc, name); } /* It could be a normal, definite, monster */ else { /* Definite monsters need a definite article */ - (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a "); - - (void)strcat(desc, name); - } -} - + strcpy(desc, is_a_vowel(name[0]) ? "an " : "a "); - -/* - * Learn about a monster (by "probing" it) - */ -void lore_do_probe(int m_idx) -{ - monster_type *m_ptr = &m_list[m_idx]; - - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - - /* Hack -- Memorize some flags */ - r_ptr->r_flags1 = r_ptr->flags1; - r_ptr->r_flags2 = r_ptr->flags2; - r_ptr->r_flags3 = r_ptr->flags3; - - /* Update monster recall window */ - if (monster_race_idx == m_ptr->r_idx) - { - /* Window stuff */ - p_ptr->window |= (PW_MONSTER); - } -} - - -/* - * Take note that the given monster just dropped some treasure - * - * Note that learning the "GOOD"/"GREAT" flags gives information - * about the treasure (even when the monster is killed for the first - * time, such as uniques, and the treasure has not been examined yet). - * - * This "indirect" method is used to prevent the player from learning - * exactly how much treasure a monster can drop from observing only - * a single example of a drop. This method actually observes how much - * gold and items are dropped, and remembers that information to be - * described later by the monster recall code. - */ -void lore_treasure(int m_idx, int num_item, int num_gold) -{ - monster_type *m_ptr = &m_list[m_idx]; - - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - - /* Note the number of things dropped */ - if (num_item > r_ptr->r_drop_item) r_ptr->r_drop_item = num_item; - if (num_gold > r_ptr->r_drop_gold) r_ptr->r_drop_gold = num_gold; - - /* Hack -- memorize the good/great flags */ - if (r_ptr->flags1 & (RF1_DROP_GOOD)) r_ptr->r_flags1 |= (RF1_DROP_GOOD); - if (r_ptr->flags1 & (RF1_DROP_GREAT)) r_ptr->r_flags1 |= (RF1_DROP_GREAT); - - /* Update monster recall window */ - if (monster_race_idx == m_ptr->r_idx) - { - /* Window stuff */ - p_ptr->window |= (PW_MONSTER); + strcat(desc, name); } } @@ -1547,9 +1445,9 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro) char m_name[80]; monster_desc(m_name, m_ptr, 0); - if (!(r_ptr->flags1 & RF1_UNIQUE)) + if (!(r_ptr->flags & RF_UNIQUE)) { - if (r_ptr->flags1 & RF1_FRIENDS) + if (r_ptr->flags & RF_FRIENDS) power /= 2; } else power *= 2; @@ -1560,7 +1458,7 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro) if (!(m_ptr->ml)) return ; /* Cannot see it for some reason */ - if (!(r_ptr->flags2 & RF2_ELDRITCH_HORROR)) + if (!(r_ptr->flags & RF_ELDRITCH_HORROR)) return ; /* oops */ @@ -1591,13 +1489,10 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro) /* Something frightening happens... */ msg_format("You behold the %s visage of %s!", horror_desc[(randint(MAX_HORROR)) - 1], m_name); - - r_ptr->r_flags2 |= RF2_ELDRITCH_HORROR; - } /* Undead characters are 50% likely to be unaffected */ - if ((race_flags1_p(PR1_UNDEAD)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))) + if ((race_flags_p(PR_UNDEAD)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))) { if (randint(100) < (25 + (p_ptr->lev))) return; } @@ -1611,11 +1506,11 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro) { if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(4) + 4); + set_confused(p_ptr->confused + rand_int(4) + 4); } if ((!p_ptr->resist_chaos) && (randint(3) == 1)) { - (void) set_image(p_ptr->image + rand_int(250) + 150); + set_image(p_ptr->image + rand_int(250) + 150); } return; } @@ -1632,19 +1527,19 @@ static void sanity_blast(monster_type * m_ptr, bool_ necro) { if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(4) + 4); + set_confused(p_ptr->confused + rand_int(4) + 4); } if (!p_ptr->free_act) { - (void)set_paralyzed(rand_int(4) + 4); + set_paralyzed(rand_int(4) + 4); } while (rand_int(100) > p_ptr->skill_sav) - (void)do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); while (rand_int(100) > p_ptr->skill_sav) - (void)do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); if (!p_ptr->resist_chaos) { - (void) set_image(p_ptr->image + rand_int(250) + 150); + set_image(p_ptr->image + rand_int(250) + 150); } return; } @@ -1741,15 +1636,6 @@ void update_mon(int m_idx, bool_ full) /* Seen by vision */ bool_ easy = FALSE; - /* Seen by telepathy */ - bool_ hard = FALSE; - - /* Various extra flags */ - bool_ do_empty_mind = FALSE; - bool_ do_weird_mind = FALSE; - bool_ do_invisible = FALSE; - bool_ do_cold_blood = FALSE; - auto const r_ptr = m_ptr->race(); /* Calculate distance */ @@ -1788,61 +1674,59 @@ void update_mon(int m_idx, bool_ full) { /* Infravision only works on "warm" creatures */ /* Below, we will need to know that infravision failed */ - if (r_ptr->flags2 & (RF2_COLD_BLOOD)) do_cold_blood = TRUE; - - /* Infravision works */ - if (!do_cold_blood) easy = flag = TRUE; + if (!(r_ptr->flags & RF_COLD_BLOOD)) + { + /* Infravision works */ + easy = flag = TRUE; + } } /* Use "illumination" */ if (player_can_see_bold(fy, fx)) { - /* Take note of invisibility */ - if (r_ptr->flags2 & (RF2_INVISIBLE)) do_invisible = TRUE; - /* Visible, or detectable, monsters get seen */ - if (!do_invisible || p_ptr->see_inv) easy = flag = TRUE; + if (p_ptr->see_inv || !(r_ptr->flags & RF_INVISIBLE)) + { + easy = flag = TRUE; + } } } /* Telepathy can see all "nearby" monsters with "minds" */ - if (p_ptr->telepathy) { /* Assume we cant see */ - bool_ can_esp = FALSE; + bool can_esp = false; /* Different ESP */ - if ((p_ptr->telepathy & ESP_ORC) && (r_ptr->flags3 & RF3_ORC)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_SPIDER) && (r_ptr->flags7 & RF7_SPIDER)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_TROLL) && (r_ptr->flags3 & RF3_TROLL)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_DRAGON) && (r_ptr->flags3 & RF3_DRAGON)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_GIANT) && (r_ptr->flags3 & RF3_GIANT)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_DEMON) && (r_ptr->flags3 & RF3_DEMON)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_UNDEAD) && (r_ptr->flags3 & RF3_UNDEAD)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_EVIL) && (r_ptr->flags3 & RF3_EVIL)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_ANIMAL) && (r_ptr->flags3 & RF3_ANIMAL)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_THUNDERLORD) && (r_ptr->flags3 & RF3_THUNDERLORD)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_GOOD) && (r_ptr->flags3 & RF3_GOOD)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_NONLIVING) && (r_ptr->flags3 & RF3_NONLIVING)) can_esp = TRUE; - if ((p_ptr->telepathy & ESP_UNIQUE) && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags3 & RF3_UNIQUE_4))) can_esp = TRUE; - if (p_ptr->telepathy & ESP_ALL) can_esp = TRUE; + can_esp |= ((p_ptr->computed_flags & ESP_ORC) && (r_ptr->flags & RF_ORC)); + can_esp |= ((p_ptr->computed_flags & ESP_SPIDER) && (r_ptr->flags & RF_SPIDER)); + can_esp |= ((p_ptr->computed_flags & ESP_TROLL) && (r_ptr->flags & RF_TROLL)); + can_esp |= ((p_ptr->computed_flags & ESP_DRAGON) && (r_ptr->flags & RF_DRAGON)); + can_esp |= ((p_ptr->computed_flags & ESP_GIANT) && (r_ptr->flags & RF_GIANT)); + can_esp |= ((p_ptr->computed_flags & ESP_DEMON) && (r_ptr->flags & RF_DEMON)); + can_esp |= ((p_ptr->computed_flags & ESP_UNDEAD) && (r_ptr->flags & RF_UNDEAD)); + can_esp |= ((p_ptr->computed_flags & ESP_EVIL) && (r_ptr->flags & RF_EVIL)); + can_esp |= ((p_ptr->computed_flags & ESP_ANIMAL) && (r_ptr->flags & RF_ANIMAL)); + can_esp |= ((p_ptr->computed_flags & ESP_THUNDERLORD) && (r_ptr->flags & RF_THUNDERLORD)); + can_esp |= ((p_ptr->computed_flags & ESP_GOOD) && (r_ptr->flags & RF_GOOD)); + can_esp |= ((p_ptr->computed_flags & ESP_NONLIVING) && (r_ptr->flags & RF_NONLIVING)); + can_esp |= ((p_ptr->computed_flags & ESP_UNIQUE) && ((r_ptr->flags & RF_UNIQUE))); + can_esp |= bool(p_ptr->computed_flags & ESP_ALL); /* Only do this when we can really detect monster */ if (can_esp) { /* Empty mind, no telepathy */ - if (r_ptr->flags2 & (RF2_EMPTY_MIND)) + if (r_ptr->flags & RF_EMPTY_MIND) { - do_empty_mind = TRUE; + /* No telepathy */ } /* Weird mind, occasional telepathy */ - else if (r_ptr->flags2 & (RF2_WEIRD_MIND)) + else if (r_ptr->flags & RF_WEIRD_MIND) { - do_weird_mind = TRUE; if (rand_int(100) < 10) { - hard = TRUE; flag = TRUE; } } @@ -1850,7 +1734,6 @@ void update_mon(int m_idx, bool_ full) /* Normal mind, allow telepathy */ else { - hard = TRUE; flag = TRUE; } } @@ -1882,29 +1765,15 @@ void update_mon(int m_idx, bool_ full) /* Update monster list window */ p_ptr->window |= (PW_M_LIST); - /* Hack -- Count "fresh" sightings */ - if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++; - /* Disturb on appearance */ - if (disturb_move) + if (options->disturb_move) { - if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1); + if (options->disturb_pets || (is_friend(m_ptr) <= 0)) + { + disturb(); + } } } - - /* Apply telepathy */ - if (hard) - { - /* Hack -- Memorize mental flags */ - if (r_ptr->flags2 & (RF2_SMART)) r_ptr->r_flags2 |= (RF2_SMART); - if (r_ptr->flags2 & (RF2_STUPID)) r_ptr->r_flags2 |= (RF2_STUPID); - } - - /* Memorize various observable flags */ - if (do_empty_mind) r_ptr->r_flags2 |= (RF2_EMPTY_MIND); - if (do_weird_mind) r_ptr->r_flags2 |= (RF2_WEIRD_MIND); - if (do_cold_blood) r_ptr->r_flags2 |= (RF2_COLD_BLOOD); - if (do_invisible) r_ptr->r_flags2 |= (RF2_INVISIBLE); } /* The monster is not visible */ @@ -1926,9 +1795,12 @@ void update_mon(int m_idx, bool_ full) p_ptr->window |= (PW_M_LIST); /* Disturb on disappearance*/ - if (disturb_move) + if (options->disturb_move) { - if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1); + if (options->disturb_pets || (is_friend(m_ptr) <= 0)) + { + disturb(); + } } } } @@ -1940,7 +1812,7 @@ void update_mon(int m_idx, bool_ full) if (m_ptr->ml != old_ml) { - if (r_ptr->flags2 & RF2_ELDRITCH_HORROR) + if (r_ptr->flags & RF_ELDRITCH_HORROR) { sanity_blast(m_ptr, FALSE); } @@ -1953,9 +1825,12 @@ void update_mon(int m_idx, bool_ full) m_ptr->mflag |= (MFLAG_VIEW); /* Disturb on appearance */ - if (disturb_near) + if (options->disturb_near) { - if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1); + if (options->disturb_pets || (is_friend(m_ptr) <= 0)) + { + disturb(); + } } } @@ -1974,9 +1849,12 @@ void update_mon(int m_idx, bool_ full) p_ptr->window |= (PW_M_LIST); /* Disturb on disappearance */ - if (disturb_near) + if (options->disturb_near) { - if (disturb_pets || (is_friend(m_ptr) <= 0)) disturb(1); + if (options->disturb_pets || (is_friend(m_ptr) <= 0)) + { + disturb(); + } } } } @@ -2008,7 +1886,9 @@ void update_monsters(bool_ full) void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr) { - object_type *o_ptr; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &random_artifacts = game->random_artifacts; /* Get new object */ int o_idx = o_pop(); @@ -2016,7 +1896,7 @@ void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr) if (o_idx) { /* Get the item */ - o_ptr = &o_list[o_idx]; + object_type *o_ptr = &o_list[o_idx]; /* Structure copy */ object_copy(o_ptr, q_ptr); @@ -2036,7 +1916,7 @@ void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr) { a_info[q_ptr->name1].cur_num = 0; } - else if (k_info[q_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[q_ptr->k_idx].flags & TR_NORM_ART) { k_info[q_ptr->k_idx].artifact = 0; } @@ -2074,8 +1954,10 @@ static int possible_randart[] = bool_ kind_is_randart(int k_idx) { + auto const &k_info = game->edit_data.k_info; + int max; - object_kind *k_ptr = &k_info[k_idx]; + auto k_ptr = &k_info[k_idx]; if (!kind_is_legal(k_idx)) return (FALSE); @@ -2111,6 +1993,9 @@ bool_ place_monster_one_no_drop = FALSE; static s16b hack_m_idx_ii = 0; s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) { + auto &r_info = game->edit_data.r_info; + auto &alloc = game->alloc; + int i; char dummy[5]; bool_ add_level = FALSE; @@ -2180,7 +2065,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) /* Check for original monster race flags */ { - monster_race *r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; /* Paranoia */ if (!r_ptr->name) @@ -2198,7 +2083,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Ego Uniques are NOT to be created */ - if ((r_ptr->flags1 & RF1_UNIQUE) && ego) + if ((r_ptr->flags & RF_UNIQUE) && ego) { return 0; } @@ -2215,28 +2100,28 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Unallow some uniques to be generated outside of their quests/special levels/dungeons */ - if ((r_ptr->flags9 & RF9_SPECIAL_GENE) && (!m_allow_special[r_idx])) + if ((r_ptr->flags & RF_SPECIAL_GENE) && (!m_allow_special[r_idx])) { if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): SPECIAL_GENE", r_idx); return 0; } /* Disallow Spirits in The Void, now this *IS* an ugly hack, I hate to do it ... */ - if ((r_ptr->flags7 & RF7_SPIRIT) && (dungeon_type != DUNGEON_VOID)) + if ((r_ptr->flags & RF_SPIRIT) && (dungeon_type != DUNGEON_VOID)) { if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster(%d): SPIRIT in non VOID", r_idx); return 0; } /* Fully forbid it */ - if (r_ptr->flags9 & RF9_NEVER_GENE) + if (r_ptr->flags & RF_NEVER_GENE) { if (wizard) cmsg_print(TERM_L_RED, "WARNING: Refused monster: NEVER_GENE"); return 0; } /* Hack -- "unique" monsters must be "unique" */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) && (r_ptr->max_num == -1) && (!m_allow_special[r_idx])) + if ((r_ptr->flags & RF_UNIQUE) && (r_ptr->max_num == -1) && (!m_allow_special[r_idx])) { /* Cannot create */ if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster %d: unique not unique", r_idx); @@ -2251,7 +2136,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Hack -- "unique" monsters must be "unique" */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) && (r_ptr->cur_num >= r_ptr->max_num) && (r_ptr->max_num != -1) && (!bypass_r_ptr_max_num)) + if ((r_ptr->flags & RF_UNIQUE) && (r_ptr->cur_num >= r_ptr->max_num) && (r_ptr->max_num != -1) && (!bypass_r_ptr_max_num)) { /* Cannot create */ if (wizard) cmsg_format(TERM_L_RED, "WARNING: Refused monster %d: cur_num >= max_num", r_idx); @@ -2259,7 +2144,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Depth monsters may NOT be created out of depth */ - if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) && (dun_level < r_ptr->level)) + if ((r_ptr->flags & RF_FORCE_DEPTH) && (dun_level < r_ptr->level)) { /* Cannot create */ if (wizard) cmsg_print(TERM_L_RED, "WARNING: FORCE_DEPTH"); @@ -2270,10 +2155,13 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) if (r_ptr->level > dun_level) { /* Unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { /* Message for cheaters */ - if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Unique (%s).", r_ptr->name); + if (options->cheat_hear || p_ptr->precognition) + { + msg_format("Deep Unique (%s).", r_ptr->name); + } /* Boost rating by twice delta-depth */ rating += (r_ptr->level - dun_level) * 2; @@ -2283,7 +2171,10 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) else { /* Message for cheaters */ - if ((cheat_hear) || (p_ptr->precognition)) msg_format("Deep Monster (%s).", r_ptr->name); + if (options->cheat_hear || p_ptr->precognition) + { + msg_format("Deep Monster (%s).", r_ptr->name); + } /* Boost rating by delta-depth */ rating += (r_ptr->level - dun_level); @@ -2291,10 +2182,13 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Note the monster */ - else if (r_ptr->flags1 & (RF1_UNIQUE)) + else if (r_ptr->flags & RF_UNIQUE) { /* Unique monsters induce message */ - if ((cheat_hear) || (p_ptr->precognition)) msg_format("Unique (%s).", r_ptr->name); + if (options->cheat_hear || p_ptr->precognition) + { + msg_format("Unique (%s).", r_ptr->name); + } } @@ -2346,11 +2240,11 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) m_ptr->status = status; /* Friendly? */ - if (m_ptr->status < MSTATUS_FRIEND && r_ptr->flags7 & RF7_PET) + if (m_ptr->status < MSTATUS_FRIEND && r_ptr->flags & RF_PET) { m_ptr->status = MSTATUS_FRIEND; } - if (m_ptr->status < MSTATUS_NEUTRAL && r_ptr->flags7 & RF7_NEUTRAL) + if (m_ptr->status < MSTATUS_NEUTRAL && r_ptr->flags & RF_NEUTRAL) { m_ptr->status = MSTATUS_NEUTRAL; } @@ -2369,12 +2263,12 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) /* Only if not fated to die */ if ((dungeon_type != DUNGEON_DEATH) && (!place_monster_one_no_drop)) { - const bool_ good = (r_ptr->flags1 & (RF1_DROP_GOOD)) ? TRUE : FALSE; - const bool_ great = (r_ptr->flags1 & (RF1_DROP_GREAT)) ? TRUE : FALSE; + const bool_ good = (r_ptr->flags & RF_DROP_GOOD) ? TRUE : FALSE; + const bool_ great = (r_ptr->flags & RF_DROP_GREAT) ? TRUE : FALSE; - const bool_ do_gold = (!(r_ptr->flags1 & (RF1_ONLY_ITEM))); - const bool_ do_item = (!(r_ptr->flags1 & (RF1_ONLY_GOLD))); - const bool_ do_mimic = (r_ptr->flags9 & (RF9_MIMIC)); + auto const do_gold = (r_ptr->flags & RF_ONLY_ITEM).empty(); + auto const do_item = (r_ptr->flags & RF_ONLY_GOLD).empty(); + auto const do_mimic = bool(r_ptr->flags & RF_MIMIC); const int force_coin = get_coin_type(r_ptr); @@ -2389,31 +2283,25 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) object_level = (dun_level + r_ptr->level) / 2; /* Determine how much we can drop */ - if ((r_ptr->flags1 & (RF1_DROP_60)) && (rand_int(100) < 60)) number++; - if ((r_ptr->flags1 & (RF1_DROP_90)) && (rand_int(100) < 90)) number++; - if (r_ptr->flags1 & (RF1_DROP_1D2)) number += damroll(1, 2); - if (r_ptr->flags1 & (RF1_DROP_2D2)) number += damroll(2, 2); - if (r_ptr->flags1 & (RF1_DROP_3D2)) number += damroll(3, 2); - if (r_ptr->flags1 & (RF1_DROP_4D2)) number += damroll(4, 2); - if (r_ptr->flags9 & (RF9_MIMIC)) number = 1; + if ((r_ptr->flags & RF_DROP_60) && (rand_int(100) < 60)) number++; + if ((r_ptr->flags & RF_DROP_90) && (rand_int(100) < 90)) number++; + if (r_ptr->flags & RF_DROP_1D2) number += damroll(1, 2); + if (r_ptr->flags & RF_DROP_2D2) number += damroll(2, 2); + if (r_ptr->flags & RF_DROP_3D2) number += damroll(3, 2); + if (r_ptr->flags & RF_DROP_4D2) number += damroll(4, 2); + if (r_ptr->flags & RF_MIMIC) number = 1; /* Hack -- handle creeping coins */ coin_type = force_coin; - if (r_ptr->flags7 & RF7_DROP_RANDART) + if (r_ptr->flags & RF_DROP_RANDART) { int tries = 1000; - obj_theme theme; - /* Get local object */ q_ptr = &forge; - theme.treasure = 101; - theme.combat = 101; - theme.magic = 101; - theme.tools = 101; - - init_match_theme(theme); + /* No theme */ + init_match_theme(obj_theme::no_theme()); /* Apply restriction */ get_obj_num_hook = kind_is_legal; @@ -2433,7 +2321,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } /* Invalidate the cached allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; if (tries) { @@ -2511,7 +2399,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) /* Assign maximal hitpoints */ - if (r_ptr->flags1 & (RF1_FORCE_MAXHP)) + if (r_ptr->flags & RF_FORCE_MAXHP) { m_ptr->maxhp = maxroll(r_ptr->hdice, r_ptr->hside); } @@ -2540,7 +2428,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) m_ptr->mspeed = m_ptr->speed; /* Hack -- small racial variety */ - if (!(r_ptr->flags1 & (RF1_UNIQUE))) + if (!(r_ptr->flags & RF_UNIQUE)) { /* Allow some small variation per monster */ i = extract_energy[m_ptr->speed] / 10; @@ -2548,18 +2436,18 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) } - if (dungeon_flags2 & DF2_ADJUST_LEVEL_1_2) + if (dungeon_flags & DF_ADJUST_LEVEL_1_2) { min_level = max_level = dun_level / 2; add_level = TRUE; } - if (dungeon_flags1 & DF1_ADJUST_LEVEL_1) + if (dungeon_flags & DF_ADJUST_LEVEL_1) { if (!min_level) min_level = dun_level; max_level = dun_level; add_level = TRUE; } - if (dungeon_flags1 & DF1_ADJUST_LEVEL_2) + if (dungeon_flags & DF_ADJUST_LEVEL_2) { if (!min_level) min_level = dun_level * 2; max_level = dun_level * 2; @@ -2571,7 +2459,7 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) m_ptr->energy = (byte)rand_int(100); /* Force monster to wait for player */ - if (r_ptr->flags1 & (RF1_FORCE_SLEEP)) + if (r_ptr->flags & RF_FORCE_SLEEP) { /* Monster is still being nice */ m_ptr->mflag |= (MFLAG_NICE); @@ -2593,23 +2481,23 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) /* Hack -- Count the number of "reproducers" */ - if (r_ptr->flags4 & (RF4_MULTIPLY)) num_repro++; + if (r_ptr->spells & SF_MULTIPLY) num_repro++; /* Hack -- Notice new multi-hued monsters */ - if (r_ptr->flags1 & (RF1_ATTR_MULTI)) shimmer_monsters = TRUE; + if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE; /* Count monsters on the level */ { /* Hack -- we need to modify the REAL r_info, not the fake one */ - monster_race *r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; /* Hack -- Count the monsters on the level */ r_ptr->cur_num++; } /* Unique monsters on saved levels should be "marked" */ - if ((r_ptr->flags1 & RF1_UNIQUE) && get_dungeon_save(dummy)) + if ((r_ptr->flags & RF_UNIQUE) && get_dungeon_save(dummy)) { r_ptr->on_saved = TRUE; } @@ -2636,7 +2524,9 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status) */ static bool_ place_monster_group(int y, int x, int r_idx, bool_ slp, int status) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; int old, n, i; int total = 0, extra = 0; @@ -2731,9 +2621,10 @@ static int place_monster_idx = 0; */ static bool_ place_monster_okay(int r_idx) { - monster_race *r_ptr = &r_info[place_monster_idx]; + auto const &r_info = game->edit_data.r_info; - monster_race *z_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[place_monster_idx]; + auto z_ptr = &r_info[r_idx]; /* Hack - Escorts have to have the same dungeon flag */ if (monster_dungeon(place_monster_idx) != monster_dungeon(r_idx)) return (FALSE); @@ -2745,7 +2636,7 @@ static bool_ place_monster_okay(int r_idx) if (z_ptr->level > r_ptr->level) return (FALSE); /* Skip unique monsters */ - if (z_ptr->flags1 & (RF1_UNIQUE)) return (FALSE); + if (z_ptr->flags & RF_UNIQUE) return (FALSE); /* Paranoia -- Skip identical monsters */ if (place_monster_idx == r_idx) return (FALSE); @@ -2775,8 +2666,10 @@ static bool_ place_monster_okay(int r_idx) */ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status) { + auto const &r_info = game->edit_data.r_info; + int i; - monster_race *r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; bool_ (*old_get_mon_num_hook)(int r_idx); @@ -2789,15 +2682,15 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu /* Friends for certain monsters */ - if (r_ptr->flags1 & (RF1_FRIENDS)) + if (r_ptr->flags & RF_FRIENDS) { /* Attempt to place a group */ - (void)place_monster_group(y, x, r_idx, slp, status); + place_monster_group(y, x, r_idx, slp, status); } /* Escorts for certain monsters */ - if (r_ptr->flags1 & (RF1_ESCORT)) + if (r_ptr->flags & RF_ESCORT) { old_get_mon_num_hook = get_mon_num_hook; @@ -2842,11 +2735,11 @@ bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int statu place_monster_one(ny, nx, z, pick_ego_monster(&r_info[z]), slp, status); /* Place a "group" of escorts if needed */ - if ((r_info[z].flags1 & (RF1_FRIENDS)) || - (r_ptr->flags1 & (RF1_ESCORTS))) + if ((r_info[z].flags & RF_FRIENDS) || + (r_ptr->flags & RF_ESCORTS)) { /* Place a group of monsters */ - (void)place_monster_group(ny, nx, z, slp, status); + place_monster_group(ny, nx, z, slp, status); } } @@ -2899,9 +2792,11 @@ bool_ place_monster(int y, int x, bool_ slp, bool_ grp) bool_ alloc_horde(int y, int x) { + auto const &r_info = game->edit_data.r_info; + int r_idx = 0; - monster_race * r_ptr = NULL; - monster_type * m_ptr; + monster_race const *r_ptr = NULL; + monster_type *m_ptr; int attempts = 1000; set_mon_num2_hook(y, x); @@ -2919,8 +2814,8 @@ bool_ alloc_horde(int y, int x) r_ptr = &r_info[r_idx]; - if (!(r_ptr->flags1 & (RF1_UNIQUE)) - && !(r_ptr->flags1 & (RF1_ESCORTS))) + if (!(r_ptr->flags & RF_UNIQUE) + && !(r_ptr->flags & RF_ESCORTS)) break; } @@ -2948,7 +2843,7 @@ bool_ alloc_horde(int y, int x) for (attempts = randint(10) + 5; attempts; attempts--) { - (void) summon_specific(m_ptr->fy, m_ptr->fx, dun_level, SUMMON_KIN); + summon_specific(m_ptr->fy, m_ptr->fx, dun_level, SUMMON_KIN); } return TRUE; @@ -2984,7 +2879,7 @@ bool_ alloc_monster(int dis, bool_ slp) if (!attempts_left) { - if (cheat_xtra || cheat_hear) + if (options->cheat_xtra || options->cheat_hear) { msg_print("Warning! Could not allocate a new monster. Small level?"); } @@ -2997,7 +2892,10 @@ bool_ alloc_monster(int dis, bool_ slp) { if (alloc_horde(y, x)) { - if ((cheat_hear) || (p_ptr->precognition)) msg_print("Monster horde."); + if (options->cheat_hear || p_ptr->precognition) + { + msg_print("Monster horde."); + } return (TRUE); } } @@ -3027,7 +2925,9 @@ static int summon_specific_type = 0; */ static bool_ summon_specific_okay(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; bool_ okay = FALSE; @@ -3043,56 +2943,56 @@ static bool_ summon_specific_okay(int r_idx) case SUMMON_ANT: { okay = ((r_ptr->d_char == 'a') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_SPIDER: { okay = ((r_ptr->d_char == 'S') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_HOUND: { okay = (((r_ptr->d_char == 'C') || (r_ptr->d_char == 'Z')) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_HYDRA: { okay = ((r_ptr->d_char == 'M') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_ANGEL: { okay = ((r_ptr->d_char == 'A') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_DEMON: { - okay = ((r_ptr->flags3 & (RF3_DEMON)) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + okay = ((r_ptr->flags & RF_DEMON) && + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_UNDEAD: { - okay = ((r_ptr->flags3 & (RF3_UNDEAD)) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + okay = ((r_ptr->flags & RF_UNDEAD) && + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_DRAGON: { - okay = ((r_ptr->flags3 & (RF3_DRAGON)) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + okay = ((r_ptr->flags & RF_DRAGON) && + !(r_ptr->flags & RF_UNIQUE)); break; } @@ -3124,40 +3024,40 @@ static bool_ summon_specific_okay(int r_idx) case SUMMON_UNIQUE: { - okay = (r_ptr->flags1 & (RF1_UNIQUE)) ? TRUE : FALSE; + okay = (r_ptr->flags & RF_UNIQUE) ? TRUE : FALSE; break; } case SUMMON_BIZARRE1: { okay = ((r_ptr->d_char == 'm') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_BIZARRE2: { okay = ((r_ptr->d_char == 'b') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_BIZARRE3: { okay = ((r_ptr->d_char == 'Q') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_BIZARRE4: { okay = ((r_ptr->d_char == 'v') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_BIZARRE5: { okay = ((r_ptr->d_char == '$') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } @@ -3168,15 +3068,15 @@ static bool_ summon_specific_okay(int r_idx) (r_ptr->d_char == '=') || (r_ptr->d_char == '$') || (r_ptr->d_char == '|')) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_HI_DEMON: { - okay = ((r_ptr->flags3 & (RF3_DEMON)) && + okay = ((r_ptr->flags & RF_DEMON) && (r_ptr->d_char == 'U') && - !(r_ptr->flags1 & RF1_UNIQUE)); + !(r_ptr->flags & RF_UNIQUE)); break; } @@ -3184,34 +3084,34 @@ static bool_ summon_specific_okay(int r_idx) case SUMMON_KIN: { okay = ((r_ptr->d_char == summon_kin_type) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_DAWN: { okay = ((strstr(r_ptr->name, "the Dawn")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_ANIMAL: { - okay = ((r_ptr->flags3 & (RF3_ANIMAL)) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + okay = ((r_ptr->flags & RF_ANIMAL) && + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_ANIMAL_RANGER: { - okay = ((r_ptr->flags3 & (RF3_ANIMAL)) && + okay = ((r_ptr->flags & RF_ANIMAL) && (strchr("abcflqrwBCIJKMRS", r_ptr->d_char)) && - !(r_ptr->flags3 & (RF3_DRAGON)) && - !(r_ptr->flags3 & (RF3_EVIL)) && - !(r_ptr->flags3 & (RF3_UNDEAD)) && - !(r_ptr->flags3 & (RF3_DEMON)) && - !(r_ptr->flags4 || r_ptr->flags5 || r_ptr->flags6) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_DRAGON) && + !(r_ptr->flags & RF_EVIL) && + !(r_ptr->flags & RF_UNDEAD) && + !(r_ptr->flags & RF_DEMON) && + !r_ptr->spells && + !(r_ptr->flags & RF_UNIQUE)); break; } @@ -3220,87 +3120,87 @@ static bool_ summon_specific_okay(int r_idx) okay = (((r_ptr->d_char == 'L') || (r_ptr->d_char == 'V') || (r_ptr->d_char == 'W')) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_HI_DRAGON_NO_UNIQUES: { okay = ((r_ptr->d_char == 'D') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_NO_UNIQUES: { - okay = (!(r_ptr->flags1 & (RF1_UNIQUE))); + okay = (!(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_PHANTOM: { okay = ((strstr(r_ptr->name, "Phantom")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_ELEMENTAL: { okay = ((strstr(r_ptr->name, "lemental")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_THUNDERLORD: { - okay = (r_ptr->flags3 & RF3_THUNDERLORD) ? TRUE : FALSE; + okay = (r_ptr->flags & RF_THUNDERLORD) ? TRUE : FALSE; break; } case SUMMON_BLUE_HORROR: { okay = ((strstr(r_ptr->name, "lue horror")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_BUG: { okay = ((strstr(r_ptr->name, "Software bug")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_RNG: { okay = ((strstr(r_ptr->name, "Random Number Generator")) && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_MINE: { - okay = (r_ptr->flags1 & RF1_NEVER_MOVE) ? TRUE : FALSE; + okay = (r_ptr->flags & RF_NEVER_MOVE) ? TRUE : FALSE; break; } case SUMMON_HUMAN: { okay = ((r_ptr->d_char == 'p') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_SHADOWS: { okay = ((r_ptr->d_char == 'G') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } case SUMMON_QUYLTHULG: { okay = ((r_ptr->d_char == 'Q') && - !(r_ptr->flags1 & (RF1_UNIQUE))); + !(r_ptr->flags & RF_UNIQUE)); break; } @@ -3602,14 +3502,16 @@ void monster_swap(int y1, int x1, int y2, int x2) */ static bool_ mutate_monster_okay(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; bool_ okay = FALSE; /* Hack - Only summon dungeon monsters */ if (!monster_dungeon(r_idx)) return (FALSE); - okay = ((r_ptr->d_char == summon_kin_type) && !(r_ptr->flags1 & (RF1_UNIQUE)) + okay = ((r_ptr->d_char == summon_kin_type) && !(r_ptr->flags & RF_UNIQUE) && (r_ptr->level >= dun_level)); return okay; @@ -3822,22 +3724,33 @@ void message_pain(int m_idx, int dam) */ void update_smart_learn(int m_idx, int what) { - monster_type *m_ptr = &m_list[m_idx]; - /* Not allowed to learn */ - if (!smart_learn) return; + if (!options->smart_learn) + { + return; + } + + /* Fast path for DRS_NONE */ + if (what == DRS_NONE) + { + return; + } /* Get racial flags */ + auto m_ptr = &m_list[m_idx]; auto const r_ptr = m_ptr->race(); /* Too stupid to learn anything */ - if (r_ptr->flags2 & (RF2_STUPID)) return; + if (r_ptr->flags & RF_STUPID) + { + return; + } /* Not intelligent, only learn sometimes */ - if (!(r_ptr->flags2 & (RF2_SMART)) && magik(50)) return; - - - /* XXX XXX XXX */ + if (!(r_ptr->flags & RF_SMART) && magik(50)) + { + return; + } /* Analyze the knowledge */ switch (what) diff --git a/src/monster2.hpp b/src/monster2.hpp index 84f79e36..ddd0b6bc 100644 --- a/src/monster2.hpp +++ b/src/monster2.hpp @@ -6,47 +6,45 @@ #include "object_type_fwd.hpp" #include <memory> -extern s32b monster_exp(s16b level); -extern void monster_set_level(int m_idx, int level); -extern s32b modify_aux(s32b a, s32b b, char mod); -extern void monster_msg_simple(cptr s); -extern bool_ mego_ok(monster_race const *r_ptr, int ego); -extern void monster_check_experience(int m_idx, bool_ silent); -extern void monster_gain_exp(int m_idx, u32b exp, bool_ silent); -extern std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego); -extern void delete_monster_idx(int i); -extern void delete_monster(int y, int x); -extern void compact_monsters(int size); -extern void wipe_m_list(void); -extern s16b m_pop(void); -extern errr get_mon_num_prep(void); -extern s16b get_mon_num(int level); -extern void monster_desc(char *desc, monster_type *m_ptr, int mode); -extern void monster_race_desc(char *desc, int r_idx, int ego); -extern void lore_do_probe(int m_idx); -extern void lore_treasure(int m_idx, int num_item, int num_gold); -extern void update_mon(int m_idx, bool_ full); -extern void update_monsters(bool_ full); -extern void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr); +s32b monster_exp(s16b level); +void monster_set_level(int m_idx, int level); +s32b modify_aux(s32b a, s32b b, char mod); +void monster_msg_simple(cptr s); +bool_ mego_ok(monster_race const *r_ptr, int ego); +void monster_check_experience(int m_idx, bool_ silent); +void monster_gain_exp(int m_idx, u32b exp, bool_ silent); +std::shared_ptr<monster_race> race_info_idx(int r_idx, int ego); +void delete_monster_idx(int i); +void delete_monster(int y, int x); +void compact_monsters(int size); +void wipe_m_list(); +s16b m_pop(); +errr get_mon_num_prep(); +s16b get_mon_num(int level); +void monster_desc(char *desc, monster_type *m_ptr, int mode); +void monster_race_desc(char *desc, int r_idx, int ego); +void update_mon(int m_idx, bool_ full); +void update_monsters(bool_ full); +void monster_carry(monster_type *m_ptr, int m_idx, object_type *q_ptr); extern bool_ bypass_r_ptr_max_num ; -extern bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status); -extern bool_ place_monster(int y, int x, bool_ slp, bool_ grp); -extern bool_ alloc_horde(int y, int x); -extern bool_ alloc_monster(int dis, bool_ slp); +bool_ place_monster_aux(int y, int x, int r_idx, bool_ slp, bool_ grp, int status); +bool_ place_monster(int y, int x, bool_ slp, bool_ grp); +bool_ alloc_horde(int y, int x); +bool_ alloc_monster(int dis, bool_ slp); extern int summon_specific_level; -extern bool_ summon_specific(int y1, int x1, int lev, int type); -extern void monster_swap(int y1, int x1, int y2, int x2); -extern bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone); +bool_ summon_specific(int y1, int x1, int lev, int type); +void monster_swap(int y1, int x1, int y2, int x2); +bool_ multiply_monster(int m_idx, bool_ charm, bool_ clone); extern bool_ hack_message_pain_may_silent; -extern void message_pain(int m_idx, int dam); -extern void update_smart_learn(int m_idx, int what); -extern bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok); +void message_pain(int m_idx, int dam); +void update_smart_learn(int m_idx, int what); +bool_ summon_specific_friendly(int y1, int x1, int lev, int type, bool_ Group_ok); extern bool_ place_monster_one_no_drop; -extern s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status); -extern s16b player_place(int y, int x); -extern void monster_drop_carried_objects(monster_type *m_ptr); -extern bool_ monster_dungeon(int r_idx); -extern bool_ monster_quest(int r_idx); -extern void set_mon_num_hook(void); -extern void set_mon_num2_hook(int y, int x); -extern bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr); +s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status); +s16b player_place(int y, int x); +void monster_drop_carried_objects(monster_type *m_ptr); +bool_ monster_dungeon(int r_idx); +bool_ monster_quest(int r_idx); +void set_mon_num_hook(); +void set_mon_num2_hook(int y, int x); +bool_ monster_can_cross_terrain(byte feat, std::shared_ptr<monster_race> r_ptr); diff --git a/src/monster3.cc b/src/monster3.cc index 0d26538c..6dd1f74e 100644 --- a/src/monster3.cc +++ b/src/monster3.cc @@ -10,10 +10,14 @@ #include "cave_type.hpp" #include "cmd2.hpp" +#include "cmd5.hpp" +#include "game.hpp" #include "gods.hpp" #include "melee2.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "monster_type.hpp" #include "object2.hpp" #include "player_type.hpp" @@ -57,12 +61,16 @@ int is_friend(monster_type *m_ptr) /* Should they attack each others */ bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr) { - monster_race *r_ptr = &r_info[m_ptr->r_idx], *rt_ptr = &r_info[t_ptr->r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[m_ptr->r_idx]; + auto rt_ptr = &r_info[t_ptr->r_idx]; + int s1 = is_friend(m_ptr), s2 = is_friend(t_ptr); /* Monsters hates breeders */ - if ((m_ptr->status != MSTATUS_NEUTRAL) && (rt_ptr->flags4 & RF4_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE; - if ((t_ptr->status != MSTATUS_NEUTRAL) && (r_ptr->flags4 & RF4_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE; + if ((m_ptr->status != MSTATUS_NEUTRAL) && (rt_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE; + if ((t_ptr->status != MSTATUS_NEUTRAL) && (r_ptr->spells & SF_MULTIPLY) && (num_repro > MAX_REPRO * 2 / 3) && (r_ptr->d_char != rt_ptr->d_char)) return TRUE; /* No special conditions, lets test normal flags */ if (s1 && s2 && (s1 == -s2)) return TRUE; @@ -80,7 +88,7 @@ bool_ change_side(monster_type *m_ptr) { case MSTATUS_FRIEND: m_ptr->status = MSTATUS_ENEMY; - if ((r_ptr->flags3 & RF3_ANIMAL) && (!(r_ptr->flags3 & RF3_EVIL))) + if ((r_ptr->flags & RF_ANIMAL) && (!(r_ptr->flags & RF_EVIL))) inc_piety(GOD_YAVANNA, -m_ptr->level * 4); break; case MSTATUS_NEUTRAL_P: @@ -91,7 +99,7 @@ bool_ change_side(monster_type *m_ptr) break; case MSTATUS_PET: m_ptr->status = MSTATUS_ENEMY; - if ((r_ptr->flags3 & RF3_ANIMAL) && (!(r_ptr->flags3 & RF3_EVIL))) + if ((r_ptr->flags & RF_ANIMAL) && (!(r_ptr->flags & RF_EVIL))) inc_piety(GOD_YAVANNA, -m_ptr->level * 4); break; case MSTATUS_COMPANION: @@ -106,7 +114,6 @@ bool_ change_side(monster_type *m_ptr) bool_ ai_multiply(int m_idx) { monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; int k, y, x, oy = m_ptr->fy, ox = m_ptr->fx; bool_ is_frien = (is_friend(m_ptr) > 0); @@ -134,12 +141,6 @@ bool_ ai_multiply(int m_idx) /* Try to multiply */ if (multiply_monster(m_idx, (is_frien), FALSE)) { - /* Take note if visible */ - if (m_ptr->ml) - { - r_ptr->r_flags4 |= (RF4_MULTIPLY); - } - /* Multiplying takes energy */ return TRUE; } @@ -150,11 +151,13 @@ bool_ ai_multiply(int m_idx) /* Possessor incarnates */ bool_ ai_possessor(int m_idx, int o_idx) { + auto &r_info = game->edit_data.r_info; + object_type *o_ptr = &o_list[o_idx]; monster_type *m_ptr = &m_list[m_idx]; int r_idx = m_ptr->r_idx, r2_idx = o_ptr->pval2; int i; - monster_race *r_ptr = &r_info[r2_idx]; + auto r_ptr = &r_info[r2_idx]; char m_name[80], m_name2[80]; monster_desc(m_name, m_ptr, 0x00); @@ -180,7 +183,7 @@ bool_ ai_possessor(int m_idx, int o_idx) m_ptr->csleep = 0; /* Assign maximal hitpoints */ - if (r_ptr->flags1 & (RF1_FORCE_MAXHP)) + if (r_ptr->flags & RF_FORCE_MAXHP) { m_ptr->maxhp = maxroll(r_ptr->hdice, r_ptr->hside); } @@ -211,10 +214,10 @@ bool_ ai_possessor(int m_idx, int o_idx) m_ptr->energy = 0; /* Hack -- Count the number of "reproducers" */ - if (r_ptr->flags4 & (RF4_MULTIPLY)) num_repro++; + if (r_ptr->spells & SF_MULTIPLY) num_repro++; /* Hack -- Notice new multi-hued monsters */ - if (r_ptr->flags1 & (RF1_ATTR_MULTI)) shimmer_monsters = TRUE; + if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE; /* Hack -- Count the monsters on the level */ r_ptr->cur_num++; @@ -230,9 +233,11 @@ bool_ ai_possessor(int m_idx, int o_idx) void ai_deincarnate(int m_idx) { + auto &r_info = game->edit_data.r_info; + monster_type *m_ptr = &m_list[m_idx]; int r2_idx = m_ptr->possessor, r_idx = m_ptr->r_idx; - monster_race *r_ptr = &r_info[r2_idx]; + auto r_ptr = &r_info[r2_idx]; int i; char m_name[80]; @@ -255,7 +260,7 @@ void ai_deincarnate(int m_idx) m_ptr->csleep = 0; /* Assign maximal hitpoints */ - if (r_ptr->flags1 & (RF1_FORCE_MAXHP)) + if (r_ptr->flags & RF_FORCE_MAXHP) { m_ptr->maxhp = maxroll(r_ptr->hdice, r_ptr->hside); } @@ -286,10 +291,10 @@ void ai_deincarnate(int m_idx) m_ptr->energy = 0; /* Hack -- Count the number of "reproducers" */ - if (r_ptr->flags4 & (RF4_MULTIPLY)) num_repro++; + if (r_ptr->spells & SF_MULTIPLY) num_repro++; /* Hack -- Notice new multi-hued monsters */ - if (r_ptr->flags1 & (RF1_ATTR_MULTI)) shimmer_monsters = TRUE; + if (r_ptr->flags & RF_ATTR_MULTI) shimmer_monsters = TRUE; /* Hack -- Count the monsters on the level */ r_ptr->cur_num++; @@ -302,7 +307,7 @@ void ai_deincarnate(int m_idx) } /* Returns if a new companion is allowed */ -bool_ can_create_companion(void) +bool_ can_create_companion() { int i, mcnt = 0; @@ -323,7 +328,7 @@ bool_ can_create_companion(void) /* Player controlled monsters */ -bool_ do_control_walk(void) +bool_ do_control_walk() { /* Get a "repeated" direction */ if (p_ptr->control) @@ -344,18 +349,18 @@ bool_ do_control_walk(void) return FALSE; } -bool_ do_control_inven(void) +bool_ do_control_inven() { if (!p_ptr->control) return FALSE; screen_save(); prt("Carried items", 0, 0); - (void) show_monster_inven(p_ptr->control); + show_monster_inven(p_ptr->control); inkey(); screen_load(); return TRUE; } -bool_ do_control_pickup(void) +bool_ do_control_pickup() { if (!p_ptr->control) return FALSE; @@ -406,7 +411,7 @@ bool_ do_control_pickup(void) return TRUE; } -bool_ do_control_drop(void) +bool_ do_control_drop() { monster_type *m_ptr = &m_list[p_ptr->control]; @@ -415,16 +420,16 @@ bool_ do_control_drop(void) return TRUE; } -bool_ do_control_magic(void) +bool_ do_control_magic() { - int power = -1; - int num = 0, i; - int powers[96]; + auto const &r_info = game->edit_data.r_info; + + int i; bool_ flag, redraw; int ask; char choice; char out_val[160]; - monster_race *r_ptr = &r_info[m_list[p_ptr->control].r_idx]; + auto r_ptr = &r_info[m_list[p_ptr->control].r_idx]; int label; if (!p_ptr->control) return FALSE; @@ -437,36 +442,11 @@ bool_ do_control_magic(void) return TRUE; } - /* List the monster powers -- RF4_* */ - for (i = 0; i < 32; i++) - { - if (r_ptr->flags4 & BIT(i)) - { - if (!monster_powers[i].power) continue; - powers[num++] = i; - } - } - - /* List the monster powers -- RF5_* */ - for (i = 0; i < 32; i++) - { - if (r_ptr->flags5 & BIT(i)) - { - if (!monster_powers[i + 32].power) continue; - powers[num++] = i + 32; - } - } - - /* List the monster powers -- RF6_* */ - for (i = 0; i < 32; i++) - { - if (r_ptr->flags6 & BIT(i)) - { - if (!monster_powers[i + 64].power) continue; - powers[num++] = i + 64; - } - } + /* Extract available monster powers */ + auto powers = extract_monster_powers(r_ptr, true); + int const num = powers.size(); // Avoid signed/unsigned warnings + /* Are any powers available? */ if (!num) { msg_print("You have no powers you can use."); @@ -475,6 +455,7 @@ bool_ do_control_magic(void) /* Nothing chosen yet */ flag = FALSE; + monster_power const *power = nullptr; /* No redraw yet */ redraw = FALSE; @@ -513,7 +494,7 @@ bool_ do_control_magic(void) while (ctr < num) { - monster_power *mp_ptr = &monster_powers[powers[ctr]]; + monster_power const *mp_ptr = powers[ctr]; label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26); @@ -597,7 +578,7 @@ bool_ do_control_magic(void) char tmp_val[160]; /* Prompt */ - strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name); + strnfmt(tmp_val, 78, "Use %s? ", power->name); /* Belay that order */ if (!get_check(tmp_val)) continue; @@ -618,7 +599,7 @@ bool_ do_control_magic(void) if (flag) { energy_use = 100; - monst_spell_monst_spell = power + 96; + monst_spell_monst_spell = power->monster_spell_index; } return TRUE; } diff --git a/src/monster3.hpp b/src/monster3.hpp index 7cf8ccd0..ac26b102 100644 --- a/src/monster3.hpp +++ b/src/monster3.hpp @@ -3,18 +3,18 @@ #include "h-basic.h" #include "monster_type_fwd.hpp" -extern void dump_companions(FILE *outfile); -extern void do_cmd_companion(void); -extern bool_ do_control_reconnect(void); -extern bool_ do_control_drop(void); -extern bool_ do_control_magic(void); -extern bool_ do_control_pickup(void); -extern bool_ do_control_inven(void); -extern bool_ do_control_walk(void); -extern bool_ can_create_companion(void); -extern void ai_deincarnate(int m_idx); -extern bool_ ai_possessor(int m_idx, int o_idx); -extern bool_ ai_multiply(int m_idx); -extern bool_ change_side(monster_type *m_ptr); -extern int is_friend(monster_type *m_ptr); -extern bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr); +void dump_companions(FILE *outfile); +void do_cmd_companion(); +bool_ do_control_reconnect(); +bool_ do_control_drop(); +bool_ do_control_magic(); +bool_ do_control_pickup(); +bool_ do_control_inven(); +bool_ do_control_walk(); +bool_ can_create_companion(); +void ai_deincarnate(int m_idx); +bool_ ai_possessor(int m_idx, int o_idx); +bool_ ai_multiply(int m_idx); +bool_ change_side(monster_type *m_ptr); +int is_friend(monster_type *m_ptr); +bool_ is_enemy(monster_type *m_ptr, monster_type *t_ptr); diff --git a/src/monster_blow.hpp b/src/monster_blow.hpp index 0f19f64c..6e0ee6e5 100644 --- a/src/monster_blow.hpp +++ b/src/monster_blow.hpp @@ -12,8 +12,8 @@ */ struct monster_blow { - byte method; - byte effect; - byte d_dice; - byte d_side; + byte method = 0; + byte effect = 0; + byte d_dice = 0; + byte d_side = 0; }; diff --git a/src/monster_ego.hpp b/src/monster_ego.hpp index 00464c2e..b578d03e 100644 --- a/src/monster_ego.hpp +++ b/src/monster_ego.hpp @@ -2,80 +2,68 @@ #include "h-basic.h" #include "monster_blow.hpp" +#include "monster_race_flag_set.hpp" +#include "monster_spell_flag_set.hpp" + +#include <array> /** * Monster ego descriptors. */ struct monster_ego { - const char *name; /* Name */ - bool_ before; /* Display ego before or after */ + const char *name = nullptr; /* Name */ + bool_ before = false; /* Display ego before or after */ - monster_blow blow[4]; /* Up to four blows per round */ - byte blowm[4][2]; + std::array<monster_blow, 4> blow { }; /* Up to four blows per round */ + byte blowm[4][2] = { + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 } + }; - s16b hdice; /* Creatures hit dice count */ - s16b hside; /* Creatures hit dice sides */ + s16b hdice = 0; /* Creatures hit dice count */ + s16b hside = 0; /* Creatures hit dice sides */ - s16b ac; /* Armour Class */ + s16b ac = 0; /* Armour Class */ - s16b sleep; /* Inactive counter (base) */ - s16b aaf; /* Area affect radius (1-100) */ - s16b speed; /* Speed (normally 110) */ + s16b sleep = 0; /* Inactive counter (base) */ + s16b aaf = 0; /* Area affect radius (1-100) */ + s16b speed = 0; /* Speed (normally 110) */ - s32b mexp; /* Exp value for kill */ + s32b mexp = 0; /* Exp value for kill */ - s32b weight; /* Weight of the monster */ + s32b weight = 0; /* Weight of the monster */ - byte freq_inate; /* Inate spell frequency */ - byte freq_spell; /* Other spell frequency */ + byte freq_inate = 0; /* Inate spell frequency */ + byte freq_spell = 0; /* Other spell frequency */ /* Ego flags */ - u32b flags1; /* Flags 1 */ - u32b flags2; /* Flags 1 */ - u32b flags3; /* Flags 1 */ - u32b flags7; /* Flags 1 */ - u32b flags8; /* Flags 1 */ - u32b flags9; /* Flags 1 */ - u32b hflags1; /* Flags 1 */ - u32b hflags2; /* Flags 1 */ - u32b hflags3; /* Flags 1 */ - u32b hflags7; /* Flags 1 */ - u32b hflags8; /* Flags 1 */ - u32b hflags9; /* Flags 1 */ + monster_race_flag_set flags; + monster_race_flag_set hflags; /* Monster flags */ - u32b mflags1; /* Flags 1 (general) */ - u32b mflags2; /* Flags 2 (abilities) */ - u32b mflags3; /* Flags 3 (race/resist) */ - u32b mflags4; /* Flags 4 (inate/breath) */ - u32b mflags5; /* Flags 5 (normal spells) */ - u32b mflags6; /* Flags 6 (special spells) */ - u32b mflags7; /* Flags 7 (movement related abilities) */ - u32b mflags8; /* Flags 8 (wilderness info) */ - u32b mflags9; /* Flags 9 (drops info) */ - - /* Negative Flags, to be removed from the monster flags */ - u32b nflags1; /* Flags 1 (general) */ - u32b nflags2; /* Flags 2 (abilities) */ - u32b nflags3; /* Flags 3 (race/resist) */ - u32b nflags4; /* Flags 4 (inate/breath) */ - u32b nflags5; /* Flags 5 (normal spells) */ - u32b nflags6; /* Flags 6 (special spells) */ - u32b nflags7; /* Flags 7 (movement related abilities) */ - u32b nflags8; /* Flags 8 (wilderness info) */ - u32b nflags9; /* Flags 9 (drops info) */ - - s16b level; /* Level of creature */ - s16b rarity; /* Rarity of creature */ - - - byte d_attr; /* Default monster attribute */ - char d_char; /* Default monster character */ - - byte g_attr; /* Overlay graphic attribute */ - char g_char; /* Overlay graphic character */ - - char r_char[5]; /* Monster race allowed */ - char nr_char[5]; /* Monster race not allowed */ + monster_race_flag_set mflags; + + /* Monster spells */ + monster_spell_flag_set mspells; + + /* Negative flags, to be removed from the monster flags */ + monster_race_flag_set nflags; + + /* Negative spells; to be removed from the monster spells */ + monster_spell_flag_set nspells; + + s16b level = 0; /* Level of creature */ + s16b rarity = 0; /* Rarity of creature */ + + byte d_attr = 0; /* Default monster attribute */ + char d_char = '\0'; /* Default monster character */ + + byte g_attr = 0; /* Overlay graphic attribute */ + char g_char = '\0'; /* Overlay graphic character */ + + char r_char[5] = { '\0' }; /* Monster race allowed */ + char nr_char[5] = { '\0' }; /* Monster race not allowed */ }; diff --git a/src/monster_ego_fwd.hpp b/src/monster_ego_fwd.hpp deleted file mode 100644 index 5b47f3e9..00000000 --- a/src/monster_ego_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct monster_ego; diff --git a/src/monster_power.hpp b/src/monster_power.hpp index 03d0f8a9..440d5ba1 100644 --- a/src/monster_power.hpp +++ b/src/monster_power.hpp @@ -1,5 +1,7 @@ #pragma once +#include "monster_power_fwd.hpp" + #include "h-basic.h" /** @@ -7,7 +9,7 @@ */ struct monster_power { - u32b power; /* Power RF?_xxx */ + u32b monster_spell_index; cptr name; /* Name of it */ int mana; /* Mana needed */ bool_ great; /* Need the use of great spells */ diff --git a/src/monster_power_fwd.hpp b/src/monster_power_fwd.hpp new file mode 100644 index 00000000..975d2d2f --- /dev/null +++ b/src/monster_power_fwd.hpp @@ -0,0 +1,3 @@ +#pragma once + +struct monster_power; diff --git a/src/monster_race.hpp b/src/monster_race.hpp index 7e5d5082..eb398a3d 100644 --- a/src/monster_race.hpp +++ b/src/monster_race.hpp @@ -3,8 +3,12 @@ #include "body.hpp" #include "h-basic.h" #include "monster_blow.hpp" +#include "monster_race_flag_set.hpp" +#include "monster_spell_flag_set.hpp" #include "obj_theme.hpp" +#include <array> + /** * Monster race descriptors and runtime data, including racial memories. * @@ -26,91 +30,55 @@ */ struct monster_race { - const char *name; /* Name */ - char *text; /* Text */ - - u16b hdice; /* Creatures hit dice count */ - u16b hside; /* Creatures hit dice sides */ - - s16b ac; /* Armour Class */ - - s16b sleep; /* Inactive counter (base) */ - byte aaf; /* Area affect radius (1-100) */ - byte speed; /* Speed (normally 110) */ - - s32b mexp; /* Exp value for kill */ - - s32b weight; /* Weight of the monster */ - - byte freq_inate; /* Inate spell frequency */ - byte freq_spell; /* Other spell frequency */ - - u32b flags1; /* Flags 1 (general) */ - u32b flags2; /* Flags 2 (abilities) */ - u32b flags3; /* Flags 3 (race/resist) */ - u32b flags4; /* Flags 4 (inate/breath) */ - u32b flags5; /* Flags 5 (normal spells) */ - u32b flags6; /* Flags 6 (special spells) */ - u32b flags7; /* Flags 7 (movement related abilities) */ - u32b flags8; /* Flags 8 (wilderness info) */ - u32b flags9; /* Flags 9 (drops info) */ - - monster_blow blow[4]; /* Up to four blows per round */ - - byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */ + const char *name = nullptr; /* Name */ + char *text = nullptr; /* Text */ - byte level; /* Level of creature */ - byte rarity; /* Rarity of creature */ + u16b hdice = 0; /* Creatures hit dice count */ + u16b hside = 0; /* Creatures hit dice sides */ + s16b ac = 0; /* Armour Class */ - byte d_attr; /* Default monster attribute */ - char d_char; /* Default monster character */ + s16b sleep = 0; /* Inactive counter (base) */ + byte aaf = 0; /* Area affect radius (1-100) */ + byte speed = 0; /* Speed (normally 110) */ + s32b mexp = 0; /* Exp value for kill */ - byte x_attr; /* Desired monster attribute */ - char x_char; /* Desired monster character */ + s32b weight = 0; /* Weight of the monster */ + byte freq_inate = 0; /* Inate spell frequency */ + byte freq_spell = 0; /* Other spell frequency */ - s16b max_num; /* Maximum population allowed per level */ + monster_race_flag_set flags; /* Flags */ - byte cur_num; /* Monster population on current level */ + monster_spell_flag_set spells; /* Spells */ + std::array<monster_blow, 4> blow { }; /* Up to four blows per round */ - s16b r_sights; /* Count sightings of this monster */ - s16b r_deaths; /* Count deaths from this monster */ + byte body_parts[BODY_MAX] = { 0 }; /* To help to decide what to use when body changing */ - s16b r_pkills; /* Count monsters killed in this life */ - s16b r_tkills; /* Count monsters killed in all lives */ + byte artifact_idx = 0; /* Artifact index of standard artifact dropped; 0 if none. */ + int artifact_chance = 0; /* Percentage chance of dropping the artifact. */ - byte r_wake; /* Number of times woken up (?) */ - byte r_ignore; /* Number of times ignored (?) */ + byte level = 0; /* Level of creature */ + byte rarity = 0; /* Rarity of creature */ - byte r_xtra1; /* Something (unused) */ - byte r_xtra2; /* Something (unused) */ + byte d_attr = 0; /* Default monster attribute */ + char d_char = 0; /* Default monster character */ - byte r_drop_gold; /* Max number of gold dropped at once */ - byte r_drop_item; /* Max number of item dropped at once */ - byte r_cast_inate; /* Max number of inate spells seen */ - byte r_cast_spell; /* Max number of other spells seen */ + byte x_attr = 0; /* Desired monster attribute */ + char x_char = 0; /* Desired monster character */ - byte r_blows[4]; /* Number of times each blow type was seen */ + s16b max_num = 0; /* Maximum population allowed per level */ + byte cur_num = 0; /* Monster population on current level */ - u32b r_flags1; /* Observed racial flags */ - u32b r_flags2; /* Observed racial flags */ - u32b r_flags3; /* Observed racial flags */ - u32b r_flags4; /* Observed racial flags */ - u32b r_flags5; /* Observed racial flags */ - u32b r_flags6; /* Observed racial flags */ - u32b r_flags7; /* Observed racial flags */ - u32b r_flags8; /* Observed racial flags */ - u32b r_flags9; /* Observed racial flags */ + s16b r_pkills = 0; /* Count monsters killed in this life */ - bool_ on_saved; /* Is the (unique) on a saved level ? */ + bool_ on_saved = 0; /* Is the (unique) on a saved level ? */ - byte total_visible; /* Amount of this race that are visible */ + obj_theme drops; /* The drops type */ - obj_theme drops; /* The drops type */ }; diff --git a/src/monster_race_flag.hpp b/src/monster_race_flag.hpp new file mode 100644 index 00000000..098e8176 --- /dev/null +++ b/src/monster_race_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "monster_race_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define RF(tier, index, name) \ + DECLARE_FLAG(monster_race_flag_set, BOOST_PP_CAT(RF_,name), tier, index) +#include "monster_race_flag_list.hpp" +#undef RF diff --git a/src/monster_race_flag_list.hpp b/src/monster_race_flag_list.hpp new file mode 100644 index 00000000..b9d2b079 --- /dev/null +++ b/src/monster_race_flag_list.hpp @@ -0,0 +1,152 @@ +/** + * X-macro list of all the monster race flags + */ + +/* RF(<tier>, <index>, <name>) */ + +RF(1, 0, UNIQUE) +RF(1, 1, QUESTOR) +RF(1, 2, MALE) +RF(1, 3, FEMALE) +RF(1, 4, CHAR_CLEAR) +RF(1, 5, CHAR_MULTI) +RF(1, 6, ATTR_CLEAR) +RF(1, 7, ATTR_MULTI) +RF(1, 8, FORCE_DEPTH) +RF(1, 9, FORCE_MAXHP) +RF(1, 10, FORCE_SLEEP) +RF(1, 11, FORCE_EXTRA) +RF(1, 12, FRIEND) +RF(1, 13, FRIENDS) +RF(1, 14, ESCORT) +RF(1, 15, ESCORTS) +RF(1, 16, NEVER_BLOW) +RF(1, 17, NEVER_MOVE) +RF(1, 18, RAND_25) +RF(1, 19, RAND_50) +RF(1, 20, ONLY_GOLD) +RF(1, 21, ONLY_ITEM) +RF(1, 22, DROP_60) +RF(1, 23, DROP_90) +RF(1, 24, DROP_1D2) +RF(1, 25, DROP_2D2) +RF(1, 26, DROP_3D2) +RF(1, 27, DROP_4D2) +RF(1, 28, DROP_GOOD) +RF(1, 29, DROP_GREAT) +RF(1, 30, DROP_USEFUL) +RF(1, 31, DROP_CHOSEN) + +RF(2, 0, STUPID) +RF(2, 1, SMART) +RF(2, 2, CAN_SPEAK) +RF(2, 3, REFLECTING) +RF(2, 4, INVISIBLE) +RF(2, 5, COLD_BLOOD) +RF(2, 6, EMPTY_MIND) +RF(2, 7, WEIRD_MIND) +RF(2, 8, DEATH_ORB) +RF(2, 9, REGENERATE) +RF(2, 10, SHAPECHANGER) +RF(2, 11, ATTR_ANY) +RF(2, 12, POWERFUL) +RF(2, 13, ELDRITCH_HORROR) +RF(2, 14, AURA_FIRE) +RF(2, 15, AURA_ELEC) +RF(2, 16, OPEN_DOOR) +RF(2, 17, BASH_DOOR) +RF(2, 18, PASS_WALL) +RF(2, 19, KILL_WALL) +RF(2, 20, MOVE_BODY) +RF(2, 21, KILL_BODY) +RF(2, 22, TAKE_ITEM) +RF(2, 23, KILL_ITEM) +RF(2, 24, BRAIN_1) +RF(2, 25, BRAIN_2) +RF(2, 26, BRAIN_3) +RF(2, 27, BRAIN_4) +RF(2, 28, BRAIN_5) +RF(2, 29, BRAIN_6) +RF(2, 30, BRAIN_7) +RF(2, 31, BRAIN_8) + +RF(3, 0, ORC) +RF(3, 1, TROLL) +RF(3, 2, GIANT) +RF(3, 3, DRAGON) +RF(3, 4, DEMON) +RF(3, 5, UNDEAD) +RF(3, 6, EVIL) +RF(3, 7, ANIMAL) +RF(3, 8, THUNDERLORD) +RF(3, 9, GOOD) +RF(3, 10, AURA_COLD) +RF(3, 11, NONLIVING) +RF(3, 12, HURT_LITE) +RF(3, 13, HURT_ROCK) +RF(3, 14, SUSCEP_FIRE) +RF(3, 15, SUSCEP_COLD) +RF(3, 16, IM_ACID) +RF(3, 17, IM_ELEC) +RF(3, 18, IM_FIRE) +RF(3, 19, IM_COLD) +RF(3, 20, IM_POIS) +RF(3, 21, RES_TELE) +RF(3, 22, RES_NETH) +RF(3, 23, RES_WATE) +RF(3, 24, RES_PLAS) +RF(3, 25, RES_NEXU) +RF(3, 26, RES_DISE) +RF(3, 28, NO_FEAR) +RF(3, 29, NO_STUN) +RF(3, 30, NO_CONF) +RF(3, 31, NO_SLEEP) + +RF(4, 0, AQUATIC) +RF(4, 1, CAN_SWIM) +RF(4, 2, CAN_FLY) +RF(4, 3, FRIENDLY) +RF(4, 4, PET) +RF(4, 5, MORTAL) +RF(4, 6, SPIDER) +RF(4, 7, NAZGUL) +RF(4, 8, DG_CURSE) +RF(4, 9, POSSESSOR) +RF(4, 10, NO_DEATH) +RF(4, 11, NO_TARGET) +RF(4, 12, AI_ANNOY) +RF(4, 13, AI_SPECIAL) +RF(4, 14, NEUTRAL) +RF(4, 16, DROP_RANDART) +RF(4, 17, AI_PLAYER) +RF(4, 18, NO_THEFT) +RF(4, 19, SPIRIT) + +RF(5, 0, WILD_ONLY) +RF(5, 1, WILD_TOWN) +RF(5, 3, WILD_SHORE) +RF(5, 4, WILD_OCEAN) +RF(5, 5, WILD_WASTE) +RF(5, 6, WILD_WOOD) +RF(5, 7, WILD_VOLCANO) +RF(5, 9, WILD_MOUNTAIN) +RF(5, 10, WILD_GRASS) +RF(5, 11, NO_CUT) +RF(5, 15, JOKEANGBAND) +RF(5, 31, WILD_TOO) + +RF(6, 0, DROP_CORPSE) +RF(6, 1, DROP_SKELETON) +RF(6, 2, HAS_LITE) +RF(6, 3, MIMIC) +RF(6, 4, HAS_EGG) +RF(6, 5, IMPRESED) +RF(6, 6, SUSCEP_ACID) +RF(6, 7, SUSCEP_ELEC) +RF(6, 8, SUSCEP_POIS) +RF(6, 9, KILL_TREES) +RF(6, 10, WYRM_PROTECT) +RF(6, 11, DOPPLEGANGER) +RF(6, 12, ONLY_DEPTH) +RF(6, 13, SPECIAL_GENE) +RF(6, 14, NEVER_GENE) diff --git a/src/monster_race_flag_set.hpp b/src/monster_race_flag_set.hpp new file mode 100644 index 00000000..958201b1 --- /dev/null +++ b/src/monster_race_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t RF_MAX_TIERS = 6; + +typedef flag_set<RF_MAX_TIERS> monster_race_flag_set; diff --git a/src/monster_spell.cc b/src/monster_spell.cc new file mode 100644 index 00000000..08627916 --- /dev/null +++ b/src/monster_spell.cc @@ -0,0 +1,36 @@ +#include "monster_spell.hpp" + +#include "monster_spell_flag.hpp" + +#include <boost/preprocessor/cat.hpp> + +std::vector<monster_spell const *> const &monster_spells() +{ + // Static instance for one-time initialization. + static std::vector<monster_spell const *> instance; + + if (instance.empty()) + { +#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \ + instance.emplace_back(new monster_spell { \ + BOOST_PP_CAT(SF_, BOOST_PP_CAT(name, _IDX)), \ + BOOST_PP_CAT(SF_, name), \ + #name, \ + is_summon, \ + is_annoy, \ + is_damage, \ + is_bolt, \ + is_smart, \ + is_innate, \ + is_escape, \ + is_tactic, \ + is_haste, \ + is_heal, \ + !is_innate, \ + }); +#include "monster_spell_flag_list.hpp" +#undef SF + }; + + return instance; +} diff --git a/src/monster_spell.hpp b/src/monster_spell.hpp new file mode 100644 index 00000000..4dfaf974 --- /dev/null +++ b/src/monster_spell.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include "monster_spell_flag_set.hpp" + +#include <vector> + +struct monster_spell { + + /** + * The global index of the spell. + */ + const std::size_t spell_idx; + + /** + * Flag set representation of the spell. + */ + const monster_spell_flag_set flag_set; + + /** + * System name of the spell as a string. + */ + const char *name; + + /** + * Is the spell a summoning spell? + */ + const bool is_summon; + + /** + * Is the spell an "annoyance" spell? + */ + const bool is_annoy; + + /** + * Is the spell a direct damage spell? + */ + const bool is_damage; + + /** + * Is the spell a bolt spell, i.e. would it + * affect any creature along the trajectory from + * the source to its target? + */ + const bool is_bolt; + + /** + * Does the spell require an intelligent caster? + */ + const bool is_smart; + + /** + * Is the spell an innate attack? For example, breaths + * are innate attacks. + */ + const bool is_innate; + + /** + * Is the spell an escape spell? + */ + const bool is_escape; + + /** + * Is the spell a "tactical" spell? + */ + const bool is_tactic; + + /** + * Does the spell apply haste? + */ + const bool is_haste; + + /** + * Does the spell apply any healing? + */ + const bool is_heal; + + /** + * Is the spell "magical" in nature? Magical spells + * can be stopped by the anti-magic field, and non-magical + * ones cannot. + * + * This is the inverse of the "innate" flag. + */ + const bool is_magic; + +}; + +/** + * Get a vector of all the spells. + */ +std::vector<monster_spell const *> const &monster_spells(); diff --git a/src/monster_spell_flag.hpp b/src/monster_spell_flag.hpp new file mode 100644 index 00000000..3de649ec --- /dev/null +++ b/src/monster_spell_flag.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "monster_spell_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \ + DECLARE_FLAG(monster_spell_flag_set, BOOST_PP_CAT(SF_,name), tier, index) +#include "monster_spell_flag_list.hpp" +#undef SF + +// +// Define index for each flag. +// +#define SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) \ + constexpr std::size_t BOOST_PP_CAT(BOOST_PP_CAT(SF_,name), _IDX) = (tier - 1) * 32 + index; +#include "monster_spell_flag_list.hpp" +#undef SF diff --git a/src/monster_spell_flag_list.hpp b/src/monster_spell_flag_list.hpp new file mode 100644 index 00000000..42d8a5e9 --- /dev/null +++ b/src/monster_spell_flag_list.hpp @@ -0,0 +1,101 @@ +/** + * X-macro list of all the monster race flags + */ + +/* SF(tier, index, name, is_summon, is_annoy, is_damage, is_bolt, is_smart, is_innate, is_escape, is_tactic, is_haste, is_heal) */ + +SF(1, 0, SHRIEK , false, true , false, false, false, true , false, false, false, false) +SF(1, 1, MULTIPLY , false, false, false, false, false, true , false, false, false, false) +SF(1, 2, S_ANIMAL , true , false, false, false, true , false, false, false, false, false) +SF(1, 3, ROCKET , false, false, true , false, false, true , false, false, false, false) +SF(1, 4, ARROW_1 , false, false, true , true , false, true , false, false, false, false) +SF(1, 5, ARROW_2 , false, false, true , true , false, true , false, false, false, false) +SF(1, 6, ARROW_3 , false, false, true , true , false, true , false, false, false, false) +SF(1, 7, ARROW_4 , false, false, true , true , false, true , false, false, false, false) +SF(1, 8, BR_ACID , false, false, true , false, false, true , false, false, false, false) +SF(1, 9, BR_ELEC , false, false, true , false, false, true , false, false, false, false) +SF(1, 10, BR_FIRE , false, false, true , false, false, true , false, false, false, false) +SF(1, 11, BR_COLD , false, false, true , false, false, true , false, false, false, false) +SF(1, 12, BR_POIS , false, false, true , false, false, true , false, false, false, false) +SF(1, 13, BR_NETH , false, false, true , false, false, true , false, false, false, false) +SF(1, 14, BR_LITE , false, false, true , false, false, true , false, false, false, false) +SF(1, 15, BR_DARK , false, false, true , false, false, true , false, false, false, false) +SF(1, 16, BR_CONF , false, false, true , false, false, true , false, false, false, false) +SF(1, 17, BR_SOUN , false, false, true , false, false, true , false, false, false, false) +SF(1, 18, BR_CHAO , false, false, true , false, false, true , false, false, false, false) +SF(1, 19, BR_DISE , false, false, true , false, false, true , false, false, false, false) +SF(1, 20, BR_NEXU , false, false, true , false, false, true , false, false, false, false) +SF(1, 21, BR_TIME , false, false, true , false, false, true , false, false, false, false) +SF(1, 22, BR_INER , false, false, true , false, false, true , false, false, false, false) +SF(1, 23, BR_GRAV , false, false, true , false, false, true , false, false, false, false) +SF(1, 24, BR_SHAR , false, false, true , false, false, true , false, false, false, false) +SF(1, 25, BR_PLAS , false, false, true , false, false, true , false, false, false, false) +SF(1, 26, BR_WALL , false, false, true , false, false, true , false, false, false, false) +SF(1, 27, BR_MANA , false, false, true , false, false, true , false, false, false, false) +SF(1, 28, BA_NUKE , false, false, true , false, false, false, false, false, false, false) +SF(1, 29, BR_NUKE , false, false, true , false, false, true , false, false, false, false) +SF(1, 30, BA_CHAO , false, false, true , false, false, false, false, false, false, false) +SF(1, 31, BR_DISI , false, false, true , false, false, true , false, false, false, false) +SF(2, 0, BA_ACID , false, false, true , false, false, false, false, false, false, false) +SF(2, 1, BA_ELEC , false, false, true , false, false, false, false, false, false, false) +SF(2, 2, BA_FIRE , false, false, true , false, false, false, false, false, false, false) +SF(2, 3, BA_COLD , false, false, true , false, false, false, false, false, false, false) +SF(2, 4, BA_POIS , false, false, true , false, false, false, false, false, false, false) +SF(2, 5, BA_NETH , false, false, true , false, false, false, false, false, false, false) +SF(2, 6, BA_WATE , false, false, true , false, false, false, false, false, false, false) +SF(2, 7, BA_MANA , false, false, true , false, false, false, false, false, false, false) +SF(2, 8, BA_DARK , false, false, true , false, false, false, false, false, false, false) +SF(2, 9, DRAIN_MANA , false, true , false, false, false, false, false, false, false, false) +SF(2, 10, MIND_BLAST , false, true , false, false, false, false, false, false, false, false) +SF(2, 11, BRAIN_SMASH , false, true , false, false, false, false, false, false, false, false) +SF(2, 12, CAUSE_1 , false, true , true , false, false, false, false, false, false, false) +SF(2, 13, CAUSE_2 , false, true , true , false, false, false, false, false, false, false) +SF(2, 14, CAUSE_3 , false, true , true , false, false, false, false, false, false, false) +SF(2, 15, CAUSE_4 , false, true , true , false, false, false, false, false, false, false) +SF(2, 16, BO_ACID , false, false, true , true , false, false, false, false, false, false) +SF(2, 17, BO_ELEC , false, false, true , true , false, false, false, false, false, false) +SF(2, 18, BO_FIRE , false, false, true , true , false, false, false, false, false, false) +SF(2, 19, BO_COLD , false, false, true , true , false, false, false, false, false, false) +SF(2, 20, BO_POIS , false, false, true , true , false, false, false, false, false, false) +SF(2, 21, BO_NETH , false, false, true , true , false, false, false, false, false, false) +SF(2, 22, BO_WATE , false, false, true , true , false, false, false, false, false, false) +SF(2, 23, BO_MANA , false, false, true , true , false, false, false, false, false, false) +SF(2, 24, BO_PLAS , false, false, true , true , false, false, false, false, false, false) +SF(2, 25, BO_ICEE , false, false, true , true , false, false, false, false, false, false) +SF(2, 26, MISSILE , false, false, true , true , false, false, false, false, false, false) +SF(2, 27, SCARE , false, true , false, false, true , false, false, false, false, false) +SF(2, 28, BLIND , false, true , false, false, true , false, false, false, false, false) +SF(2, 29, CONF , false, true , false, false, true , false, false, false, false, false) +SF(2, 30, SLOW , false, true , false, false, true , false, false, false, false, false) +SF(2, 31, HOLD , false, true , false, false, true , false, false, false, false, false) +SF(3, 0, HASTE , false, false, false, false, true , false, false, false, true , false) +SF(3, 1, HAND_DOOM , false, false, true , false, false, false, false, false, false, false) +SF(3, 2, HEAL , false, false, false, false, true , false, false, false, false, true ) +SF(3, 3, S_ANIMALS , true , false, false, false, true , false, false, false, false, false) +SF(3, 4, BLINK , false, false, false, false, true , false, true , true , false, false) +SF(3, 5, TPORT , false, false, false, false, true , false, true , false, false, false) +SF(3, 6, TELE_TO , false, true , false, false, false, false, false, false, false, false) +SF(3, 7, TELE_AWAY , false, false, false, false, true , false, true , false, false, false) +SF(3, 8, TELE_LEVEL , false, false, false, false, true , false, true , false, false, false) +SF(3, 9, DARKNESS , false, true , false, false, false, false, false, false, false, false) +SF(3, 11, FORGET , false, true , false, false, false, false, false, false, false, false) +SF(3, 12, RAISE_DEAD , false, false, false, false, false, false, false, false, false, false) +SF(3, 13, S_BUG , true , false, false, false, true , false, false, false, false, false) +SF(3, 14, S_RNG , true , false, false, false, true , false, false, false, false, false) +SF(3, 15, S_THUNDERLORD, true , false, false, false, true , false, false, false, false, false) +SF(3, 16, S_KIN , true , false, false, false, true , false, false, false, false, false) +SF(3, 17, S_HI_DEMON , true , false, false, false, true , false, false, false, false, false) +SF(3, 18, S_MONSTER , true , false, false, false, true , false, false, false, false, false) +SF(3, 19, S_MONSTERS , true , false, false, false, true , false, false, false, false, false) +SF(3, 20, S_ANT , true , false, false, false, true , false, false, false, false, false) +SF(3, 21, S_SPIDER , true , false, false, false, true , false, false, false, false, false) +SF(3, 22, S_HOUND , true , false, false, false, true , false, false, false, false, false) +SF(3, 23, S_HYDRA , true , false, false, false, true , false, false, false, false, false) +SF(3, 24, S_ANGEL , true , false, false, false, true , false, false, false, false, false) +SF(3, 25, S_DEMON , true , false, false, false, true , false, false, false, false, false) +SF(3, 26, S_UNDEAD , true , false, false, false, true , false, false, false, false, false) +SF(3, 27, S_DRAGON , true , false, false, false, true , false, false, false, false, false) +SF(3, 28, S_HI_UNDEAD , true , false, false, false, true , false, false, false, false, false) +SF(3, 29, S_HI_DRAGON , true , false, false, false, true , false, false, false, false, false) +SF(3, 30, S_WRAITH , true , false, false, false, true , false, false, false, false, false) +SF(3, 31, S_UNIQUE , true , false, false, false, true , false, false, false, false, false) diff --git a/src/monster_spell_flag_set.hpp b/src/monster_spell_flag_set.hpp new file mode 100644 index 00000000..37d31665 --- /dev/null +++ b/src/monster_spell_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t SF_MAX_TIERS = 3; + +typedef flag_set<SF_MAX_TIERS> monster_spell_flag_set; diff --git a/src/monster_type.hpp b/src/monster_type.hpp index 8353f228..ed6d3d2a 100644 --- a/src/monster_type.hpp +++ b/src/monster_type.hpp @@ -4,6 +4,7 @@ #include "monster_blow.hpp" #include "monster_race_fwd.hpp" +#include <array> #include <cassert> #include <vector> #include <memory> @@ -28,12 +29,7 @@ struct monster_type s32b hp = 0; /* Current Hit points */ s32b maxhp = 0; /* Max Hit points */ - monster_blow blow[4] = { /* Up to four blows per round */ - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 }, - }; + std::array<monster_blow, 4> blow {};/* Up to four blows per round */ byte speed = 0; /* Speed (normally 110) */ byte level = 0; /* Level of creature */ diff --git a/src/notes.cc b/src/notes.cc index 326381c9..17990992 100644 --- a/src/notes.cc +++ b/src/notes.cc @@ -10,6 +10,7 @@ #include "notes.hpp" #include "files.hpp" +#include "game.hpp" #include "player_class.hpp" #include "player_type.hpp" #include "util.hpp" @@ -20,14 +21,14 @@ /* * Show the notes file on the screen */ -void show_notes_file(void) +void show_notes_file() { char basename[13]; char buf[1024]; char caption[10 + 13]; /* Hack -- extract first 8 characters of name and append an extension */ - (void)strnfmt(basename, sizeof(basename), "%.8s.nte", player_base); + strnfmt(basename, sizeof(basename), "%.8s.nte", game->player_base.c_str()); basename[sizeof(basename) - 1] = '\0'; /* Build the path */ @@ -37,7 +38,7 @@ void show_notes_file(void) sprintf(caption, "Note file %s", basename); /* Invoke show_file */ - (void)show_file(buf, caption, 0, 0); + show_file(buf, caption); /* Done */ return; @@ -47,14 +48,14 @@ void show_notes_file(void) * Output a string to the notes file. * This is the only function that references that file. */ -void output_note(char *final_note) +void output_note(const char *final_note) { FILE *fff; char basename[13]; char buf[1024]; /* Hack -- extract first 8 characters of name and append an extension */ - (void)strnfmt(basename, sizeof(basename), "%.8s.nte", player_base); + strnfmt(basename, sizeof(basename), "%.8s.nte", game->player_base.c_str()); basename[sizeof(basename) - 1] = '\0'; /* Build the path */ @@ -113,6 +114,8 @@ void add_note(char *note, char code) */ void add_note_type(int note_number) { + auto const &class_info = game->edit_data.class_info; + char true_long_day[50]; char buf[1024]; time_t ct = time((time_t*)0); @@ -129,9 +132,10 @@ void add_note_type(int note_number) char player[100]; /* Build the string containing the player information */ + auto const player_race_name = get_player_race_name(p_ptr->prace, p_ptr->pracem); sprintf(player, "the %s %s", - get_player_race_name(p_ptr->prace, p_ptr->pracem), + player_race_name.c_str(), class_info[p_ptr->pclass].spec[p_ptr->pspec].title); /* Add in "character start" information */ @@ -141,7 +145,7 @@ void add_note_type(int note_number) "%s %s\n" "Born on %s\n" "================================================\n", - player_name, player, true_long_day); + game->player_name.c_str(), player, true_long_day); break; } @@ -152,7 +156,7 @@ void add_note_type(int note_number) "%s slew Morgoth on %s\n" "Long live %s!\n" "================================================", - player_name, true_long_day, player_name); + game->player_name.c_str(), true_long_day, game->player_name.c_str()); break; } diff --git a/src/notes.hpp b/src/notes.hpp index e8c22bb7..5c182858 100644 --- a/src/notes.hpp +++ b/src/notes.hpp @@ -1,6 +1,6 @@ #pragma once -extern void show_notes_file(void); -extern void output_note(char *final_note); -extern void add_note(char *note, char code); -extern void add_note_type(int note_number); +void show_notes_file(); +void output_note(char const *final_note); +void add_note(char *note, char code); +void add_note_type(int note_number); diff --git a/src/obj_theme.hpp b/src/obj_theme.hpp index 13f185e8..d10d17fa 100644 --- a/src/obj_theme.hpp +++ b/src/obj_theme.hpp @@ -8,8 +8,45 @@ */ struct obj_theme { - byte treasure; - byte combat; - byte magic; - byte tools; + byte treasure = 0; + byte combat = 0; + byte magic = 0; + byte tools = 0; + + bool operator == (obj_theme const &other) const + { + return + (treasure == other.treasure) && + (combat == other.combat) && + (magic == other.magic) && + (tools == other.tools); + } + + bool operator != (obj_theme const &other) const + { + return !(*this == other); + } + + static constexpr obj_theme no_theme() + { + return equal_spread(100); + } + + static constexpr obj_theme defaults() + { + return equal_spread(20); + } + +private: + + static constexpr obj_theme equal_spread(byte v) + { + obj_theme ot; + ot.treasure = v; + ot.combat = v; + ot.magic = v; + ot.tools = v; + return ot; + } + }; diff --git a/src/object1.cc b/src/object1.cc index 6bbf23e9..3fb2ef26 100644 --- a/src/object1.cc +++ b/src/object1.cc @@ -18,6 +18,7 @@ #include "ego_item_type.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hook_get_in.hpp" #include "hooks.hpp" #include "lua_bind.hpp" @@ -26,15 +27,18 @@ #include "monster2.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "object2.hpp" +#include "object_flag.hpp" +#include "object_flag_meta.hpp" +#include "object_flag_set.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" #include "player_race.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "set_type.hpp" #include "skills.hpp" #include "spell_type.hpp" @@ -43,7 +47,6 @@ #include "stats.hpp" #include "store_info_type.hpp" #include "tables.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -52,10 +55,15 @@ #include "xtra1.hpp" #include "z-rand.hpp" +#include <boost/algorithm/string/join.hpp> +#include <boost/algorithm/string/predicate.hpp> #include <cassert> +#include <fmt/format.h> +#include <utility> -static bool_ apply_flags_set(s16b a_idx, s16b set_idx, - u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp); +using boost::starts_with; + +static void apply_flags_set(s16b a_idx, s16b set_idx, object_flag_set *f); /* * Hack -- note that "TERM_MULTI" is now just "TERM_VIOLET". @@ -322,14 +330,8 @@ static char scroll_adj[MAX_TITLES][16]; static byte scroll_col[MAX_TITLES]; -/* - * Certain items have a flavor - * This function is used only by "flavor_init()" - */ -static byte object_flavor(int k_idx) +static byte object_flavor(object_kind const *k_ptr) { - object_kind *k_ptr = &k_info[k_idx]; - /* Analyze the item */ switch (k_ptr->tval) { @@ -381,7 +383,7 @@ static byte object_flavor(int k_idx) } /* No flavor */ - return (0); + return 0; } @@ -391,10 +393,8 @@ static byte object_flavor(int k_idx) * * XXX XXX XXX Add "EASY_KNOW" flag to "k_info.txt" file */ -static bool_ object_easy_know(int i) +static bool_ object_easy_know(object_kind const *k_ptr) { - object_kind *k_ptr = &k_info[i]; - /* Analyze the "tval" */ switch (k_ptr->tval) { @@ -427,7 +427,7 @@ static bool_ object_easy_know(int i) case TV_ROD: case TV_ROD_MAIN: { - if (k_ptr->flags3 & TR3_NORM_ART) + if (k_ptr->flags & TR_NORM_ART) return ( FALSE ); return (TRUE); } @@ -437,7 +437,7 @@ static bool_ object_easy_know(int i) case TV_AMULET: case TV_LITE: { - if (k_ptr->flags3 & (TR3_EASY_KNOW)) return (TRUE); + if (k_ptr->flags & TR_EASY_KNOW) return (TRUE); return (FALSE); } } @@ -446,6 +446,25 @@ static bool_ object_easy_know(int i) return (FALSE); } + + +/** + * Shuffle flavor arrays into a random permutation + */ +template <std::size_t N> +static void shuffle_flavors(cptr adj[], byte col[]) +{ + // The classic Fisher-Yates shuffle + for (std::size_t i = N - 1; i > 0; i--) + { + int j = rand_int(i + 1); + std::swap(adj[i], adj[j]); + std::swap(col[i], col[j]); + } +} + + + /* * Prepare the "variable" part of the "k_info" array. * @@ -477,165 +496,73 @@ static bool_ object_easy_know(int i) * * Note that the "hacked seed" may provide an RNG with alternating parity! */ -void flavor_init(void) +void flavor_init() { - int i, j; - - byte temp_col; - - cptr temp_adj; - - - /* Hack -- Use the "simple" RNG */ - Rand_quick = TRUE; + auto &k_info = game->edit_data.k_info; /* Hack -- Induce consistant flavors */ - Rand_value = seed_flavor; - + set_quick_rng(seed_flavor()); /* Efficiency -- Rods/Wands share initial array */ - for (i = 0; i < MAX_METALS; i++) + for (std::size_t i = 0; i < MAX_METALS; i++) { rod_adj[i] = wand_adj[i]; rod_col[i] = wand_col[i]; } - /* Rings have "ring colors" */ - for (i = 0; i < MAX_ROCKS; i++) - { - j = rand_int(MAX_ROCKS); - temp_adj = ring_adj[i]; - ring_adj[i] = ring_adj[j]; - ring_adj[j] = temp_adj; - temp_col = ring_col[i]; - ring_col[i] = ring_col[j]; - ring_col[j] = temp_col; - } - - /* Amulets have "amulet colors" */ - for (i = 0; i < MAX_AMULETS; i++) - { - j = rand_int(MAX_AMULETS); - temp_adj = amulet_adj[i]; - amulet_adj[i] = amulet_adj[j]; - amulet_adj[j] = temp_adj; - temp_col = amulet_col[i]; - amulet_col[i] = amulet_col[j]; - amulet_col[j] = temp_col; - } - - /* Staffs */ - for (i = 0; i < MAX_WOODS; i++) - { - j = rand_int(MAX_WOODS); - temp_adj = staff_adj[i]; - staff_adj[i] = staff_adj[j]; - staff_adj[j] = temp_adj; - temp_col = staff_col[i]; - staff_col[i] = staff_col[j]; - staff_col[j] = temp_col; - } - - /* Wands */ - for (i = 0; i < MAX_METALS; i++) - { - j = rand_int(MAX_METALS); - temp_adj = wand_adj[i]; - wand_adj[i] = wand_adj[j]; - wand_adj[j] = temp_adj; - temp_col = wand_col[i]; - wand_col[i] = wand_col[j]; - wand_col[j] = temp_col; - } - - /* Rods */ - for (i = 0; i < MAX_METALS; i++) - { - j = rand_int(MAX_METALS); - temp_adj = rod_adj[i]; - rod_adj[i] = rod_adj[j]; - rod_adj[j] = temp_adj; - temp_col = rod_col[i]; - rod_col[i] = rod_col[j]; - rod_col[j] = temp_col; - } - - /* Foods (Mushrooms) */ - for (i = 0; i < MAX_SHROOM; i++) - { - j = rand_int(MAX_SHROOM); - temp_adj = food_adj[i]; - food_adj[i] = food_adj[j]; - food_adj[j] = temp_adj; - temp_col = food_col[i]; - food_col[i] = food_col[j]; - food_col[j] = temp_col; - } - - /* Potions */ - for (i = 4; i < MAX_COLORS; i++) - { - j = rand_int(MAX_COLORS - 4) + 4; - temp_adj = potion_adj[i]; - potion_adj[i] = potion_adj[j]; - potion_adj[j] = temp_adj; - temp_col = potion_col[i]; - potion_col[i] = potion_col[j]; - potion_col[j] = temp_col; - } + /* Object flavors */ + shuffle_flavors<MAX_ROCKS>(ring_adj, ring_col); + shuffle_flavors<MAX_AMULETS>(amulet_adj, amulet_col); + shuffle_flavors<MAX_WOODS>(staff_adj, staff_col); + shuffle_flavors<MAX_METALS>(wand_adj, wand_col); + shuffle_flavors<MAX_METALS>(rod_adj, rod_col); + shuffle_flavors<MAX_SHROOM>(food_adj, food_col); + shuffle_flavors<MAX_COLORS - 4>(potion_adj + 4, potion_col + 4); /* Scrolls (random titles, always white) */ - for (i = 0; i < MAX_TITLES; i++) + for (std::size_t i = 0; i < MAX_TITLES; i++) { /* Get a new title */ while (TRUE) { - char buf[80]; - - bool_ okay; - - /* Start a new title */ - buf[0] = '\0'; + std::string buf; /* Collect words until done */ while (1) { - int q, s; - - char tmp[80]; - - /* Start a new word */ - tmp[0] = '\0'; - /* Choose one or two syllables */ - s = ((rand_int(100) < 30) ? 1 : 2); + int s = ((rand_int(100) < 30) ? 1 : 2); /* Add a one or two syllable word */ - for (q = 0; q < s; q++) + std::string tmp; + for (int q = 0; q < s; q++) { - /* Add the syllable */ - strcat(tmp, syllables[rand_int(MAX_SYLLABLES)]); + tmp += syllables[rand_int(MAX_SYLLABLES)]; } /* Stop before getting too long */ - if (strlen(buf) + 1 + strlen(tmp) > 15) break; - - /* Add a space */ - strcat(buf, " "); + if (buf.size() + tmp.size() + 1 > 15) + { + break; + } - /* Add the word */ - strcat(buf, tmp); + /* Add the word with separator */ + if (buf.size() > 0) + { + buf += " "; + } + buf += tmp; } /* Save the title */ - strcpy(scroll_adj[i], buf + 1); + strcpy(scroll_adj[i], buf.c_str()); /* Assume okay */ - okay = TRUE; + bool_ okay = TRUE; /* Check for "duplicate" scroll titles */ - for (j = 0; j < i; j++) + for (std::size_t j = 0; j < i; j++) { cptr hack1 = scroll_adj[j]; cptr hack2 = scroll_adj[i]; @@ -661,26 +588,28 @@ void flavor_init(void) scroll_col[i] = TERM_WHITE; } - /* Hack -- Use the "complex" RNG */ - Rand_quick = FALSE; + set_complex_rng(); /* Analyze every object */ - for (i = 1; i < max_k_idx; i++) + for (auto &k_ref: k_info) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_ref; /* Skip "empty" objects */ if (!k_ptr->name) continue; /* Extract "flavor" (if any) */ - k_ptr->flavor = object_flavor(i); + k_ptr->flavor = object_flavor(k_ptr); /* No flavor yields aware */ - if ((!k_ptr->flavor) && (k_ptr->tval != TV_ROD_MAIN)) k_ptr->aware = TRUE; + if ((!k_ptr->flavor) && (k_ptr->tval != TV_ROD_MAIN)) + { + k_ptr->aware = TRUE; + } /* Check for "easily known" */ - k_ptr->easy_know = object_easy_know(i); + k_ptr->easy_know = object_easy_know(k_ptr); } } @@ -698,81 +627,62 @@ void flavor_init(void) * * The "prefs" parameter is no longer meaningful. XXX XXX XXX */ -void reset_visuals(void) +void reset_visuals() { - int i; + auto &st_info = game->edit_data.st_info; + auto &race_mod_info = game->edit_data.race_mod_info; + auto &re_info = game->edit_data.re_info; + auto &r_info = game->edit_data.r_info; + auto &f_info = game->edit_data.f_info; + auto &k_info = game->edit_data.k_info; /* Extract some info about terrain features */ - for (i = 0; i < max_f_idx; i++) + for (auto &f_ref: f_info) { - feature_type *f_ptr = &f_info[i]; - - /* Assume we will use the underlying values */ - f_ptr->x_attr = f_ptr->d_attr; - f_ptr->x_char = f_ptr->d_char; + f_ref.x_attr = f_ref.d_attr; + f_ref.x_char = f_ref.d_char; } /* Extract default attr/char code for stores */ - for (i = 0; i < max_st_idx; i++) + for (auto &st_ref: st_info) { - store_info_type *st_ptr = &st_info[i]; - /* Default attr/char */ - st_ptr->x_attr = st_ptr->d_attr; - st_ptr->x_char = st_ptr->d_char; + st_ref.x_attr = st_ref.d_attr; + st_ref.x_char = st_ref.d_char; } /* Extract default attr/char code for objects */ - for (i = 0; i < max_k_idx; i++) + for (auto &k_ref: k_info) { - object_kind *k_ptr = &k_info[i]; - /* Default attr/char */ - k_ptr->x_attr = k_ptr->d_attr; - k_ptr->x_char = k_ptr->d_char; + k_ref.x_attr = k_ref.d_attr; + k_ref.x_char = k_ref.d_char; } /* Extract default attr/char code for monsters */ - for (i = 0; i < max_r_idx; i++) + for (auto &r_ref: r_info) { - monster_race *r_ptr = &r_info[i]; - /* Default attr/char */ - r_ptr->x_attr = r_ptr->d_attr; - r_ptr->x_char = r_ptr->d_char; + r_ref.x_attr = r_ref.d_attr; + r_ref.x_char = r_ref.d_char; } /* Reset attr/char code for ego monster overlay graphics */ - for (i = 0; i < max_re_idx; i++) + for (auto &re_ref: re_info) { - monster_ego *re_ptr = &re_info[i]; - /* Default attr/char */ - re_ptr->g_attr = 0; - re_ptr->g_char = 0; + re_ref.g_attr = 0; + re_ref.g_char = 0; } /* Reset attr/char code for race modifier overlay graphics */ - for (i = 0; i < max_rmp_idx; i++) - { - player_race_mod *rmp_ptr = &race_mod_info[i]; - - /* Default attr/char */ - rmp_ptr->g_attr = 0; - rmp_ptr->g_char = 0; - } - - /* Reset attr/char code for trap overlay graphics */ - for (i = 0; i < max_rmp_idx; i++) + for (auto &rmp: race_mod_info) { - trap_type *t_ptr = &t_info[i]; - /* Default attr/char */ - t_ptr->g_attr = 0; - t_ptr->g_char = 0; + rmp.g_attr = 0; + rmp.g_char = 0; } - /* Normal symbols */ process_pref_file("font.prf"); } @@ -781,8 +691,15 @@ void reset_visuals(void) /* * Extract "xtra" flags from object. */ -static void object_flags_xtra(object_type const *o_ptr, u32b *f2, u32b *f3, u32b *esp) +static void object_flags_xtra(object_type const *o_ptr, object_flag_set *f) { + // Artifacts don't get *ego* extra powers. + if (!o_ptr->artifact_name.empty()) + { + return; + } + + // Add sustain or power. switch (o_ptr->xtra1) { case EGO_XTRA_SUSTAIN: @@ -791,22 +708,22 @@ static void object_flags_xtra(object_type const *o_ptr, u32b *f2, u32b *f3, u32b switch (o_ptr->xtra2 % 6) { case 0: - (*f2) |= (TR2_SUST_STR); + (*f) |= TR_SUST_STR; break; case 1: - (*f2) |= (TR2_SUST_INT); + (*f) |= TR_SUST_INT; break; case 2: - (*f2) |= (TR2_SUST_WIS); + (*f) |= TR_SUST_WIS; break; case 3: - (*f2) |= (TR2_SUST_DEX); + (*f) |= TR_SUST_DEX; break; case 4: - (*f2) |= (TR2_SUST_CON); + (*f) |= TR_SUST_CON; break; case 5: - (*f2) |= (TR2_SUST_CHR); + (*f) |= TR_SUST_CHR; break; } @@ -819,135 +736,94 @@ static void object_flags_xtra(object_type const *o_ptr, u32b *f2, u32b *f3, u32b switch (o_ptr->xtra2 % 11) { case 0: - (*f2) |= (TR2_RES_BLIND); + (*f) |= TR_RES_BLIND; break; case 1: - (*f2) |= (TR2_RES_CONF); + (*f) |= TR_RES_CONF; break; case 2: - (*f2) |= (TR2_RES_SOUND); + (*f) |= TR_RES_SOUND; break; case 3: - (*f2) |= (TR2_RES_SHARDS); + (*f) |= TR_RES_SHARDS; break; case 4: - (*f2) |= (TR2_RES_NETHER); + (*f) |= TR_RES_NETHER; break; case 5: - (*f2) |= (TR2_RES_NEXUS); + (*f) |= TR_RES_NEXUS; break; case 6: - (*f2) |= (TR2_RES_CHAOS); + (*f) |= TR_RES_CHAOS; break; case 7: - (*f2) |= (TR2_RES_DISEN); + (*f) |= TR_RES_DISEN; break; case 8: - (*f2) |= (TR2_RES_POIS); + (*f) |= TR_RES_POIS; break; case 9: - (*f2) |= (TR2_RES_DARK); + (*f) |= TR_RES_DARK; break; case 10: - (*f2) |= (TR2_RES_LITE); + (*f) |= TR_RES_LITE; break; } break; } - case EGO_XTRA_ABILITY: - { - /* Choose an ability */ - switch (o_ptr->xtra2 % 8) - { - case 0: - (*f3) |= (TR3_FEATHER); - break; - case 1: - (*f3) |= (TR3_LITE1); - break; - case 2: - (*f3) |= (TR3_SEE_INVIS); - break; - case 3: - (*esp) |= (ESP_ALL); - break; - case 4: - (*f3) |= (TR3_SLOW_DIGEST); - break; - case 5: - (*f3) |= (TR3_REGEN); - break; - case 6: - (*f2) |= (TR2_FREE_ACT); - break; - case 7: - (*f2) |= (TR2_HOLD_LIFE); - break; - } - - break; - } - } } +/* + * Disregard sets when calculating flags? + */ +bool_ object_flags_no_set = FALSE; /* * Obtain the "flags" for an item */ -bool_ object_flags_no_set = FALSE; -void object_flags(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) +object_flag_set object_flags(object_type const *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + + auto k_ptr = &k_info[o_ptr->k_idx]; /* Base object */ - (*f1) = k_ptr->flags1; - (*f2) = k_ptr->flags2; - (*f3) = k_ptr->flags3; - (*f4) = k_ptr->flags4; - (*f5) = k_ptr->flags5; - (*esp) = k_ptr->esp; + auto f = k_ptr->flags; /* Artifact */ if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; - (*f1) = a_ptr->flags1; - (*f2) = a_ptr->flags2; - (*f3) = a_ptr->flags3; - (*f4) = a_ptr->flags4; - (*f5) = a_ptr->flags5; - (*esp) = a_ptr->esp; + f = a_ptr->flags; if ((!object_flags_no_set) && (a_ptr->set != -1)) - apply_flags_set(o_ptr->name1, a_ptr->set, f1, f2, f3, f4, f5, esp); + { + apply_flags_set(o_ptr->name1, a_ptr->set, &f); + } } - /* Random artifact ! */ - if (o_ptr->art_flags1 || o_ptr->art_flags2 || o_ptr->art_flags3 || o_ptr->art_flags4 || o_ptr->art_flags5 || o_ptr->art_esp) - { - (*f1) |= o_ptr->art_flags1; - (*f2) |= o_ptr->art_flags2; - (*f3) |= o_ptr->art_flags3; - (*f4) |= o_ptr->art_flags4; - (*f5) |= o_ptr->art_flags5; - (*esp) |= o_ptr->art_esp; - } + /* Mix in art_{flags,esp} */ + f |= o_ptr->art_flags; /* Extra powers */ - if (!(o_ptr->art_name)) - { - object_flags_xtra(o_ptr, f2, f3, esp); - } + object_flags_xtra(o_ptr, &f); + + return f; } /* Return object granted power */ int object_power(object_type *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; + + auto k_ptr = &k_info[o_ptr->k_idx]; int power = -1; /* Base object */ @@ -956,24 +832,33 @@ int object_power(object_type *o_ptr) /* Ego-item */ if (o_ptr->name2) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; + auto e_ptr = &e_info[o_ptr->name2]; - if (power == -1) power = e_ptr->power; + if (power == -1) + { + power = e_ptr->power; + } if (o_ptr->name2b) { - ego_item_type *e_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2b]; - if (power == -1) power = e_ptr->power; + if (power == -1) + { + power = e_ptr->power; + } } } /* Artifact */ if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; - if (power == -1) power = a_ptr->power; + if (power == -1) + { + power = a_ptr->power; + } } return (power); @@ -984,210 +869,107 @@ int object_power(object_type *o_ptr) /* * Obtain the "flags" for an item which are known to the player */ -void object_flags_known(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) +object_flag_set object_flags_known(object_type const *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; - /* Clear */ - (*f1) = (*f2) = (*f3) = (*f4) = (*esp) = (*f5) = 0L; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Must be identified */ - if (!object_known_p(o_ptr)) return; + if (!object_known_p(o_ptr)) + { + return object_flag_set(); + } /* Base object */ - (*f1) = k_ptr->flags1; - (*f2) = k_ptr->flags2; - (*f3) = k_ptr->flags3; - (*f4) = k_ptr->flags4; - (*f5) = k_ptr->flags5; - (*esp) = k_ptr->esp; - - (*f1) |= k_ptr->oflags1; - (*f2) |= k_ptr->oflags2; - (*f3) |= k_ptr->oflags3; - (*f4) |= k_ptr->oflags4; - (*f5) |= k_ptr->oflags5; - (*esp) |= k_ptr->oesp; + auto flags = k_ptr->flags; + + /* Obvious flags */ + flags |= k_ptr->oflags; /* Artifact */ if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; /* Need full knowledge or spoilers */ if ((o_ptr->ident & IDENT_MENTAL)) { - (*f1) = a_ptr->flags1; - (*f2) = a_ptr->flags2; - (*f3) = a_ptr->flags3; - (*f4) = a_ptr->flags4; - (*f5) = a_ptr->flags5; - (*esp) = a_ptr->esp; + flags = a_ptr->flags; if ((!object_flags_no_set) && (a_ptr->set != -1)) - apply_flags_set(o_ptr->name1, a_ptr->set, f1, f2, f3, f4, f5, esp); + { + apply_flags_set(o_ptr->name1, a_ptr->set, &flags); + } } else { - (*f1) = (*f2) = (*f3) = (*f4) = (*esp) = (*f5) = 0L; + flags = object_flag_set(); } - (*f1) |= a_ptr->oflags1; - (*f2) |= a_ptr->oflags2; - (*f3) |= a_ptr->oflags3; - (*f4) |= a_ptr->oflags4; - (*f5) |= a_ptr->oflags5; - (*esp) |= a_ptr->oesp; + flags |= a_ptr->oflags; } /* Random artifact or ego item! */ - if (o_ptr->art_flags1 || o_ptr->art_flags2 || o_ptr->art_flags3 || o_ptr->art_flags4 || o_ptr->art_flags5 || o_ptr->art_esp) + if (o_ptr->art_flags) { /* Need full knowledge or spoilers */ if ((o_ptr->ident & IDENT_MENTAL)) { - (*f1) |= o_ptr->art_flags1; - (*f2) |= o_ptr->art_flags2; - (*f3) |= o_ptr->art_flags3; - (*f4) |= o_ptr->art_flags4; - (*f5) |= o_ptr->art_flags5; - (*esp) |= o_ptr->art_esp; + flags |= o_ptr->art_flags; } - (*f1) |= o_ptr->art_oflags1; - (*f2) |= o_ptr->art_oflags2; - (*f3) |= o_ptr->art_oflags3; - (*f4) |= o_ptr->art_oflags4; - (*f5) |= o_ptr->art_oflags5; - (*esp) |= o_ptr->art_oesp; + flags |= o_ptr->art_oflags; } /* Full knowledge for *identified* objects */ - if (!(o_ptr->ident & IDENT_MENTAL)) return; - - if (!(o_ptr->art_name)) + if (!(o_ptr->ident & IDENT_MENTAL)) { - object_flags_xtra(o_ptr, f2, f3, esp); + return flags; } - /* Hack - Res Chaos -> Res Confusion */ - if (*f2 & TR2_RES_CHAOS) (*f2) |= (TR2_RES_CONF); -} - - - - - -/* - * Print a char "c" into a string "t", as if by sprintf(t, "%c", c), - * and return a pointer to the terminator (t + 1). - */ -static char *object_desc_chr(char *t, char c) -{ - /* Copy the char */ - *t++ = c; + /* Extra powers */ + object_flags_xtra(o_ptr, &flags); - /* Terminate */ - *t = '\0'; + /* Hack - Res Chaos -> Res Confusion */ + if (flags & TR_RES_CHAOS) + { + flags |= TR_RES_CONF; + } - /* Result */ - return (t); + // Done + return flags; } -/* - * Print a string "s" into a string "t", as if by strcpy(t, s), - * and return a pointer to the terminator. +/** + * Calculate amount of EXP needed for the given object to + * level, assuming it's a sentient object. */ -static char *object_desc_str(char *t, cptr s) +s32b calc_object_need_exp(object_type const *o_ptr) { - /* Copy the string */ - while (*s) *t++ = *s++; - - /* Terminate */ - *t = '\0'; - - /* Result */ - return (t); + return (player_exp[o_ptr->elevel - 1] * 5 / 2); } -/* - * Do the actual conversion of a number for object_desc_num() and - * object_desc_int(). - */ -static char *convert_number(char *result, u32b num) -{ - char *tp; - char temp[11]; - - tp = temp; - *tp = '0' + (num % 10); - for (num /= 10; num != 0; num /= 10) - { - *++tp = '0' + (num % 10); - } - while (tp != temp) - { - *result++ = *tp--; - } - *result++ = *tp; - *result = '\0'; - - return result; -} - -/* - * Print a nnumber "n" into a string "t", as if by - * sprintf(t, "%u", n), and return a pointer to the terminator. +/** + * Calculate the PVAL mask. */ -static char *object_desc_num(char *result, s32b num) +static object_flag_set compute_pval_mask() { - u32b n; - - if (num < 0) + object_flag_set f; + for (auto const object_flag_meta: object_flags_meta()) { - *result++ = '-'; - n = -num; + if (object_flag_meta->is_pval) + { + f |= object_flag_meta->flag_set; + } } - else - n = num; - - /* Result */ - return convert_number(result, n); + return f; } -/* - * Print an signed number "num" into a string "result", as if by - * sprintf(t, "%+d", n), and return a pointer to the terminator. - * Note that we always print a sign, either "+" or "-". - */ -static char *object_desc_int(char *result, s32b num) -{ - u32b n; - - /* Negative */ - if (num < 0) - { - /* Take the absolute value */ - n = -num; - - /* Use a "minus" sign */ - *result++ = '-'; - } - /* Positive (or zero) */ - else - { - /* Use the actual number */ - n = num; - - /* Use a "plus" sign */ - *result++ = '+'; - } - /* Result */ - return convert_number(result, n); -} /* * Creates a description of the item "o_ptr", and stores it in "out_val". @@ -1234,55 +1016,41 @@ static char *object_desc_int(char *result, s32b num) * 2 -- The Cloak of Death [1,+3] (+2 to Stealth) * 3 -- The Cloak of Death [1,+3] (+2 to Stealth) {nifty} */ -void object_desc(char *buf, object_type *o_ptr, int pref, int mode) +static std::string object_desc_aux(object_type const *o_ptr, int pref, int mode) { - bool_ hack_name = FALSE; - cptr basenm, modstr; - int indexx; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; + auto const &random_artifacts = game->random_artifacts; + static auto const TR_PVAL_MASK = compute_pval_mask(); - bool_ aware = FALSE; - bool_ known = FALSE; + bool_ hack_name = FALSE; bool_ append_name = FALSE; bool_ show_weapon = FALSE; bool_ show_armour = FALSE; - cptr s, u; - char *t; - - char p1 = '(', p2 = ')'; - char b1 = '[', b2 = ']'; - char c1 = '{', c2 = '}'; - - char tmp_val[160]; - char tmp_val2[90]; - - s32b power; - u32b f1, f2, f3, f4, f5, esp; - - object_kind *k_ptr = &k_info[o_ptr->k_idx]; - - cptr str; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - + auto const flags = object_flags(o_ptr); /* See if the object is "aware" */ - if (object_aware_p(o_ptr)) aware = TRUE; + bool_ aware = object_aware_p(o_ptr); /* See if the object is "known" */ - if (object_known_p(o_ptr)) known = TRUE; + bool_ known = object_known_p(o_ptr); /* Hack -- Extract the sub-type "indexx" */ - indexx = o_ptr->sval; + auto const indexx = o_ptr->sval; /* Extract default "base" string */ - basenm = k_ptr->name; + std::string basenm(k_ptr->name); /* Assume no "modifier" string */ - modstr = ""; + std::string modstr; /* Analyze the object */ switch (o_ptr->tval) @@ -1318,14 +1086,6 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) break; } - /* Trapping Kits */ - case TV_TRAPKIT: - { - modstr = basenm; - basenm = "& # Trap Set~"; - break; - } - /* Armour */ case TV_BOOTS: case TV_GLOVES: @@ -1359,7 +1119,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) else basenm = aware ? "& # Amulet~" : "& # Amulet~"; - if (known && !o_ptr->art_name && artifact_p(o_ptr)) + if (known && o_ptr->artifact_name.empty() && artifact_p(o_ptr)) { basenm = k_ptr->name; } @@ -1382,7 +1142,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Hack -- The One Ring */ if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold"; - if (known && !o_ptr->art_name && artifact_p(o_ptr)) + if (known && o_ptr->artifact_name.empty() && artifact_p(o_ptr)) { basenm = k_ptr->name; } @@ -1530,53 +1290,57 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Hack -- Gold/Gems */ case TV_GOLD: { - strcpy(buf, basenm); - return; + return basenm; } case TV_CORPSE: { - monster_race* r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; + modstr = basenm; - if (r_ptr->flags1 & RF1_UNIQUE) - basenm = format("& %s's #~", r_ptr->name); + if (r_ptr->flags & RF_UNIQUE) + { + basenm = fmt::format("& {}'s #~", r_ptr->name); + } else - basenm = format("& %s #~", r_ptr->name); + { + basenm = fmt::format("& {} #~", r_ptr->name); + } break; } case TV_EGG: { - monster_race* r_ptr = &r_info[o_ptr->pval2]; - modstr = basenm; + auto r_ptr = &r_info[o_ptr->pval2]; - basenm = format("& %s #~", r_ptr->name); + modstr = basenm; + basenm = fmt::format("& {} #~", r_ptr->name); break; } case TV_HYPNOS: { /* We print hit points further down. --dsb */ - monster_race* r_ptr = &r_info[o_ptr->pval]; + auto r_ptr = &r_info[o_ptr->pval]; + modstr = basenm; - basenm = format("& %s~", r_ptr->name); + basenm = fmt::format("& {}~", r_ptr->name); break; } case TV_TOTEM: { - char name[80]; monster_type monster; - monster.r_idx = o_ptr->pval; monster.ego = o_ptr->pval2; monster.ml = TRUE; monster.status = MSTATUS_ENEMY; + char name[80]; monster_desc(name, &monster, 0x188); modstr = basenm; - basenm = format("& #~ of %s", name); + basenm = fmt::format("& #~ of {}", name); break; } @@ -1595,23 +1359,6 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) break; } - case TV_RUNE2: - { - if (o_ptr->sval != RUNE_STONE) - { - modstr = basenm; - basenm = "& Rune~ [#]"; - } - break; - } - - case TV_RUNE1: - { - modstr = basenm; - basenm = "& Rune~ [#]"; - break; - } - case TV_DAEMON_BOOK: case TV_BOOK: { @@ -1625,36 +1372,31 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Used in the "inventory" routine */ default: - { - strcpy(buf, "(nothing)"); - return; - } + return "(nothing)"; } /* Mega Hack */ - if ((!hack_name) && known && (k_ptr->flags5 & TR5_FULL_NAME)) + if ((!hack_name) && known && (k_ptr->flags & TR_FULL_NAME)) { basenm = k_ptr->name; } + /* Copy of the base string _without_ a prefix */ + std::string s; /* Start dumping the result */ - t = tmp_val; + std::string t; /* The object "expects" a "number" */ - if (basenm[0] == '&') + if (starts_with(basenm, "&")) { - monster_race* r_ptr; cptr ego = NULL; - if (o_ptr->tval == TV_CORPSE) r_ptr = &r_info[o_ptr->pval2]; - else r_ptr = &r_info[o_ptr->pval]; - /* Grab any ego-item name */ if (known && (o_ptr->name2 || o_ptr->name2b) && (o_ptr->tval != TV_ROD_MAIN)) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; - ego_item_type *e2_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2]; + auto e2_ptr = &e_info[o_ptr->name2b]; if (e_ptr->before) { @@ -1667,7 +1409,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) } /* Skip the ampersand (and space) */ - s = basenm + 2; + s = basenm.substr(2); /* No prefix */ if (pref <= 0) @@ -1678,74 +1420,77 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Hack -- None left */ else if (o_ptr->number <= 0) { - t = object_desc_str(t, "no more "); + t += "no more "; } /* Extract the number */ else if (o_ptr->number > 1) { - t = object_desc_num(t, o_ptr->number); - t = object_desc_chr(t, ' '); + t += std::to_string(o_ptr->number); + t += ' '; } - else if ((o_ptr->tval == TV_CORPSE) && (r_ptr->flags1 & RF1_UNIQUE)) - {} - + else if ((o_ptr->tval == TV_CORPSE) && (r_info[o_ptr->pval2].flags & RF_UNIQUE)) + { + /* Nothing */ + } - else if ((o_ptr->tval == TV_HYPNOS) && (r_ptr->flags1 & RF1_UNIQUE)) - {} + else if ((o_ptr->tval == TV_HYPNOS) && (r_info[o_ptr->pval].flags & RF_UNIQUE)) + { + /* Nothing */ + } /* Hack -- The only one of its kind */ - else if (known && (artifact_p(o_ptr) || o_ptr->art_name)) + else if (known && artifact_p(o_ptr)) { - t = object_desc_str(t, "The "); + t += "The "; } else if (ego != NULL) { if (is_a_vowel(ego[0])) { - t = object_desc_str(t, "an "); + t += "an "; } else { - t = object_desc_str(t, "a "); + t += "a "; } } /* A single one, with a vowel in the modifier */ - else if ((*s == '#') && (is_a_vowel(modstr[0]))) + else if ((s[0] == '#') && (is_a_vowel(modstr[0]))) { - t = object_desc_str(t, "an "); + t += "an "; } /* A single one, with a vowel */ - else if (is_a_vowel(*s)) + else if (is_a_vowel(s[0])) { - t = object_desc_str(t, "an "); + t += "an "; } /* A single one, without a vowel */ else { - t = object_desc_str(t, "a "); + t += "a "; } /* Grab any ego-item name */ if (known && (o_ptr->name2 || o_ptr->name2b) && (o_ptr->tval != TV_ROD_MAIN)) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; - ego_item_type *e2_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2]; + auto e2_ptr = &e_info[o_ptr->name2b]; if (e_ptr->before) { - t = object_desc_str(t, e_ptr->name); - t = object_desc_chr(t, ' '); + t += e_ptr->name; + t += ' '; } if (e2_ptr->before) { - t = object_desc_str(t, e2_ptr->name); - t = object_desc_chr(t, ' '); + t += e2_ptr->name; + t += ' '; } } @@ -1753,16 +1498,10 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Dagger inscribed {@w0%Smelly} will be named * Smelly Dagger {@w0} */ - if (o_ptr->note) + if (auto str = strchr(o_ptr->inscription.c_str(), '%')) { - str = strchr(quark_str(o_ptr->note), '%'); - - /* Add the false name */ - if (str) - { - t = object_desc_str(t, &str[1]); - t = object_desc_chr(t, ' '); - } + t += &str[1]; + t += ' '; } } @@ -1782,14 +1521,14 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Hack -- all gone */ else if (o_ptr->number <= 0) { - t = object_desc_str(t, "no more "); + t += "no more "; } /* Prefix a number if required */ else if (o_ptr->number > 1) { - t = object_desc_num(t, o_ptr->number); - t = object_desc_chr(t, ' '); + t += std::to_string(o_ptr->number); + t += ' '; } else if (o_ptr->tval == TV_RANDART) @@ -1798,9 +1537,9 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) } /* Hack -- The only one of its kind */ - else if (known && (artifact_p(o_ptr) || o_ptr->art_name)) + else if (known && artifact_p(o_ptr)) { - t = object_desc_str(t, "The "); + t += "The "; } /* Hack -- single items get no prefix */ @@ -1812,100 +1551,91 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Grab any ego-item name */ if (known && (o_ptr->name2 || o_ptr->name2b) && (o_ptr->tval != TV_ROD_MAIN)) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; - ego_item_type *e2_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2]; + auto e2_ptr = &e_info[o_ptr->name2b]; if (e_ptr->before) { - t = object_desc_str(t, e_ptr->name); - t = object_desc_chr(t, ' '); + t += e_ptr->name; + t += ' '; } if (e2_ptr->before) { - t = object_desc_str(t, e2_ptr->name); - t = object_desc_chr(t, ' '); + t += e2_ptr->name; + t += ' '; } } } - /* Paranoia -- skip illegal tildes */ - /* while (*s == '~') s++; */ - /* Copy the string */ - for (; *s; s++) + for (auto const c: s) { /* Pluralizer */ - if (*s == '~') + if (c == '~') { /* Add a plural if needed */ if ((o_ptr->number != 1) && (pref >= 0)) { - char k = t[ -1]; + assert(t.size() > 0); + char k = t[t.size() - 1]; /* XXX XXX XXX Mega-Hack */ /* Hack -- "Cutlass-es" and "Torch-es" */ - if ((k == 's') || (k == 'h')) *t++ = 'e'; + if ((k == 's') || (k == 'h')) { + t += "e"; + } /* Add an 's' */ - *t++ = 's'; + t += "s"; } } /* Modifier */ - else if (*s == '#') + else if (c == '#') { /* Grab any ego-item name */ if (o_ptr->tval == TV_ROD_MAIN) { - t = object_desc_chr(t, ' '); + t += ' '; if (known && o_ptr->name2) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; - t = object_desc_str(t, e_ptr->name); + auto e_ptr = &e_info[o_ptr->name2]; + t += e_ptr->name; } } /* Insert the modifier */ - for (u = modstr; *u; u++) *t++ = *u; + t += modstr; } /* Normal */ else { /* Copy */ - *t++ = *s; + t += c; } } - /* Terminate */ - *t = '\0'; - - /* Append the "kind name" to the "base name" */ if ((append_name) && (!artifact_p(o_ptr))) { - t = object_desc_str(t, " of "); + t += " of "; if (((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF))) { - t = object_desc_str(t, spell_type_name(spell_at(o_ptr->pval2))); + t += spell_type_name(spell_at(o_ptr->pval2)); if (mode >= 1) { s32b bonus = o_ptr->pval3 & 0xFFFF; s32b max = o_ptr->pval3 >> 16; - - t = object_desc_chr(t, '['); - t = object_desc_num(t, bonus); - t = object_desc_chr(t, '|'); - t = object_desc_num(t, max); - t = object_desc_chr(t, ']'); + t += fmt::format("[{:d}|{:d}]", bonus, max); } } else { - t = object_desc_str(t, k_ptr->name); + t += k_ptr->name; } } @@ -1916,93 +1646,77 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* -TM- Hack -- Add false-artifact names */ /* Dagger inscribed {@w0#of Smell} will be named * Dagger of Smell {@w0} */ - if (o_ptr->note) + if (auto str = strchr(o_ptr->inscription.c_str(), '#')) { - str = strchr(quark_str(o_ptr->note), '#'); - - /* Add the false name */ - if (str) - { - t = object_desc_chr(t, ' '); - t = object_desc_str(t, &str[1]); - } + t += ' '; + t += &str[1]; } /* Is it a new random artifact ? */ - if (o_ptr->art_name) + if (!o_ptr->artifact_name.empty()) { - t = object_desc_chr(t, ' '); - - t = object_desc_str(t, quark_str(o_ptr->art_name)); + t += ' '; + t += o_ptr->artifact_name; } /* Grab any artifact name */ else if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; /* Unique corpses don't require another name */ if (o_ptr->tval != TV_CORPSE) { - t = object_desc_chr(t, ' '); - t = object_desc_str(t, a_ptr->name); + t += ' '; + t += a_ptr->name; } } /* Grab any ego-item name */ else if ((o_ptr->name2 || o_ptr->name2b) && (o_ptr->tval != TV_ROD_MAIN)) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; - ego_item_type *e2_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2]; + auto e2_ptr = &e_info[o_ptr->name2b]; if (o_ptr->name2 && !e_ptr->before) { - t = object_desc_chr(t, ' '); - t = object_desc_str(t, e_ptr->name); + t += ' '; + t += e_ptr->name; } if (o_ptr->name2b && !e2_ptr->before) { - t = object_desc_chr(t, ' '); - t = object_desc_str(t, e2_ptr->name); + t += ' '; + t += e2_ptr->name; } } } /* It contains a spell */ - if ((known) && (f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) + if (known && (flags & TR_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) { - t = object_desc_str(t, format(" [%s]", spell_type_name(spell_at(o_ptr->pval2)))); + t += fmt::format(" [{}]", spell_type_name(spell_at(o_ptr->pval2))); } /* Add symbiote hp here, after the "fake-artifact" name. --dsb */ if (o_ptr->tval == TV_HYPNOS) { - t = object_desc_str(t, " ("); - t = object_desc_num(t, o_ptr->pval2); - t = object_desc_str(t, " hp)"); + t += fmt::format(" ({:d} hp)", o_ptr->pval2); } /* No more details wanted */ - if (mode < 1) goto copyback; + if (mode < 1) + { + return t; + } /* Hack -- Some objects can have an exp level */ - if ((f4 & TR4_LEVELS) && known) + if ((flags & TR_LEVELS) && known) { - t = object_desc_str(t, " (E:"); - if (o_ptr->elevel < PY_MAX_LEVEL) - { - /* Formula from check_experience_obj(). */ - s32b need = player_exp[o_ptr->elevel - 1] * 5 / 2; - t = object_desc_num(t, need - o_ptr->exp); - } - else - { - t = object_desc_str(t, "*****"); - } - t = object_desc_str(t, ", L:"); - t = object_desc_num(t, o_ptr->elevel); - t = object_desc_chr(t, ')'); + auto need_exp = (o_ptr->elevel < PY_MAX_LEVEL) + ? std::to_string(calc_object_need_exp(o_ptr) - o_ptr->exp) + : "*****"; + t += fmt::format(" (E:{}, L:{})", need_exp, o_ptr->elevel); } /* Hack -- Chests must be described in detail */ @@ -2017,35 +1731,13 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* May be "empty" */ else if (!o_ptr->pval) { - t = object_desc_str(t, " (empty)"); - } - - /* May be "disarmed" */ - else if (o_ptr->pval < 0) - { - t = object_desc_str(t, " (disarmed)"); - } - - /* Describe the traps, if any */ - else - { - /* Describe the traps */ - t = object_desc_str(t, " ("); - if (t_info[o_ptr->pval].ident) - { - t = object_desc_str(t, t_info[o_ptr->pval].name); - } - else - { - t = object_desc_str(t, "trapped"); - } - t = object_desc_str(t, ")"); + t += " (empty)"; } } /* Display the item like a weapon */ - if (f3 & (TR3_SHOW_MODS)) show_weapon = TRUE; + if (flags & TR_SHOW_MODS) show_weapon = TRUE; /* Display the item like a weapon */ if (o_ptr->to_h && o_ptr->to_d) show_weapon = TRUE; @@ -2062,7 +1754,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) case TV_ARROW: /* Exploding arrow? */ if (o_ptr->pval2 != 0) - t = object_desc_str(t, " (exploding)"); + t += " (exploding)"; /* No break, we want to continue the description */ case TV_BOOMERANG: @@ -2076,12 +1768,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) break; /* Append a "damage" string */ - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_num(t, o_ptr->dd); - t = object_desc_chr(t, 'd'); - t = object_desc_num(t, o_ptr->ds); - t = object_desc_chr(t, p2); + t += fmt::format(" ({:d}d{:d})", o_ptr->dd, o_ptr->ds); /* All done */ break; @@ -2089,19 +1776,14 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Bows get a special "damage string" */ case TV_BOW: - /* Mega-Hack -- Extract the "base power" */ - power = (o_ptr->sval % 10); + s32b power = (o_ptr->sval % 10); /* Apply the "Extra Might" flag */ - if (f3 & (TR3_XTRA_MIGHT)) power += o_ptr->pval; + if (flags & TR_XTRA_MIGHT) power += o_ptr->pval; /* Append a special "damage" string */ - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_chr(t, 'x'); - t = object_desc_num(t, power); - t = object_desc_chr(t, p2); + t += fmt::format(" (x{:d})", power); /* All done */ break; @@ -2114,34 +1796,29 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Show the tohit/todam on request */ if (show_weapon) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_int(t, o_ptr->to_h); - t = object_desc_chr(t, ','); - t = object_desc_int(t, o_ptr->to_d); - t = object_desc_chr(t, p2); + t += fmt::format(" ({:+d},{:+d})", o_ptr->to_h, o_ptr->to_d); } /* Show the tohit if needed */ else if (o_ptr->to_h) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_int(t, o_ptr->to_h); - if (!(f3 & (TR3_HIDE_TYPE)) || o_ptr->art_name) - t = object_desc_str(t, " to accuracy"); - t = object_desc_chr(t, p2); + t += fmt::format(" ({:+d}", o_ptr->to_h); + if (!(flags & TR_HIDE_TYPE) || (!o_ptr->artifact_name.empty())) + { + t += " to accuracy"; + } + t += ')'; } /* Show the todam if needed */ else if (o_ptr->to_d) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_int(t, o_ptr->to_d); - if (!(f3 & (TR3_HIDE_TYPE)) || o_ptr->art_name) - t = object_desc_str(t, " to damage"); - t = object_desc_chr(t, p2); + t += fmt::format(" ({:+d}", o_ptr->to_d); + if (!(flags & TR_HIDE_TYPE) || (!o_ptr->artifact_name.empty())) + { + t += " to damage"; + } + t += ')'; } } @@ -2152,49 +1829,37 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) /* Show the armor class info */ if (show_armour) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, b1); - t = object_desc_num(t, o_ptr->ac); - t = object_desc_chr(t, ','); - t = object_desc_int(t, o_ptr->to_a); - t = object_desc_chr(t, b2); + t += fmt::format(" [{:d},{:+d}]", o_ptr->ac, o_ptr->to_a); } /* No base armor, but does increase armor */ else if (o_ptr->to_a) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, b1); - t = object_desc_int(t, o_ptr->to_a); - t = object_desc_chr(t, b2); + t += fmt::format(" [{:+d}]", o_ptr->to_a); } } /* Hack -- always show base armor */ else if (show_armour) { - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, b1); - t = object_desc_num(t, o_ptr->ac); - t = object_desc_chr(t, b2); + t += fmt::format(" [{:d}]", o_ptr->ac); } - if ((f1 & TR1_MANA) && (known) && (o_ptr->pval > 0)) + if ((flags & TR_MANA) && known && (o_ptr->pval > 0)) { - t = object_desc_chr(t, '('); - t = object_desc_num(t, 100 * o_ptr->pval / 5); - t = object_desc_str(t, "%)"); + t += fmt::format("({:d}%)", 100 * o_ptr->pval / 5); } - if ((known) && (f2 & TR2_LIFE) ) /* Can disp neg now -- Improv */ + if (known && (flags & TR_LIFE) ) /* Can disp neg now -- Improv */ { - t = object_desc_chr(t, '('); - t = object_desc_num(t, 100 * o_ptr->pval / 5); - t = object_desc_str(t, "%)"); + t += fmt::format("({:d}%)", 100 * o_ptr->pval / 5); } /* No more details wanted */ - if (mode < 2) goto copyback; + if (mode < 2) + { + return t; + } /* Hack -- Wands and Staffs have charges */ @@ -2202,13 +1867,8 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND))) { - /* Dump " (N charges)" */ - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - t = object_desc_num(t, o_ptr->pval); - t = object_desc_str(t, " charge"); - if (o_ptr->pval != 1) t = object_desc_chr(t, 's'); - t = object_desc_chr(t, p2); + auto plural = (o_ptr->pval != 1) ? "s" : ""; + t += fmt::format(" ({:d} charge{})", o_ptr->pval, plural); } /* @@ -2216,12 +1876,7 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) */ else if (known && (o_ptr->tval == TV_ROD_MAIN)) { - /* Display prettily. */ - t = object_desc_str(t, " ("); - t = object_desc_num(t, o_ptr->timeout); - t = object_desc_chr(t, '/'); - t = object_desc_num(t, o_ptr->pval2); - t = object_desc_chr(t, ')'); + t += fmt::format(" ({:d}/{:d})", o_ptr->timeout, o_ptr->pval2); } /* @@ -2229,201 +1884,166 @@ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) */ else if (known && (o_ptr->tval == TV_ROD)) { - /* Display prettily. */ - t = object_desc_str(t, " ("); - t = object_desc_num(t, o_ptr->pval); - t = object_desc_str(t, " Mana to cast"); - t = object_desc_chr(t, ')'); + t += fmt::format(" ({:d} Mana to cast)", o_ptr->pval); } /* Hack -- Process Lanterns/Torches */ - else if ((o_ptr->tval == TV_LITE) && (f4 & TR4_FUEL_LITE)) + else if ((o_ptr->tval == TV_LITE) && (flags & TR_FUEL_LITE)) { - /* Hack -- Turns of light for normal lites */ - t = object_desc_str(t, " (with "); - t = object_desc_num(t, o_ptr->timeout); - t = object_desc_str(t, " turns of light)"); + t += fmt::format(" (with {:d} turns of light)", o_ptr->timeout); } /* Dump "pval" flags for wearable items */ - if (known && ((f1 & (TR1_PVAL_MASK)) || (f5 & (TR5_PVAL_MASK)))) + if (known && (flags & TR_PVAL_MASK)) { /* Start the display */ - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, p1); - - /* Dump the "pval" itself */ - t = object_desc_int(t, o_ptr->pval); + t += fmt::format(" ({:+d}", o_ptr->pval); /* Do not display the "pval" flags */ - if (f3 & (TR3_HIDE_TYPE)) + if (flags & TR_HIDE_TYPE) { /* Nothing */ } /* Speed */ - else if (f1 & (TR1_SPEED)) + else if (flags & TR_SPEED) { - /* Dump " to speed" */ - t = object_desc_str(t, " to speed"); + t += " to speed"; } /* Attack speed */ - else if (f1 & (TR1_BLOWS)) + else if (flags & TR_BLOWS) { - /* Add " attack" */ - t = object_desc_str(t, " attack"); - - /* Add "attacks" */ - if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's'); + t += " attack"; + if (ABS(o_ptr->pval) != 1) + { + t += 's'; + } } /* Critical chance */ - else if (f5 & (TR5_CRIT)) + else if (flags & TR_CRIT) { - /* Add " attack" */ - t = object_desc_str(t, "% of critical hits"); + t += "% of critical hits"; } /* Stealth */ - else if (f1 & (TR1_STEALTH)) - { - /* Dump " to stealth" */ - t = object_desc_str(t, " to stealth"); - } - - /* Search */ - else if (f1 & (TR1_SEARCH)) + else if (flags & TR_STEALTH) { - /* Dump " to searching" */ - t = object_desc_str(t, " to searching"); + t += " to stealth"; } /* Infravision */ - else if (f1 & (TR1_INFRA)) + else if (flags & TR_INFRA) { - /* Dump " to infravision" */ - t = object_desc_str(t, " to infravision"); + t += " to infravision"; } /* Tunneling */ - else if (f1 & (TR1_TUNNEL)) + else if (flags & TR_TUNNEL) { /* Nothing */ } /* Finish the display */ - t = object_desc_chr(t, p2); + t += ')'; } /* Indicate "charging" artifacts XXX XXX XXX */ - if (known && (f3 & TR3_ACTIVATE) && o_ptr->timeout) + if (known && (flags & TR_ACTIVATE) && o_ptr->timeout) { - if(o_ptr->tval == TV_EGG) - /* Hack -- Dump " (stopped)" if relevant */ - t = object_desc_str(t, " (stopped)"); + if (o_ptr->tval == TV_EGG) + { + t += " (stopped)"; + } else - /* Hack -- Dump " (charging)" if relevant */ - t = object_desc_str(t, " (charging)"); - } - - /* Indicate "charging" Mage Staffs XXX XXX XXX */ - if (known && o_ptr->timeout && (is_ego_p(o_ptr, EGO_MSTAFF_SPELL))) - { - /* Hack -- Dump " (charging spell1)" if relevant */ - t = object_desc_str(t, " (charging spell1)"); - } - if (known && o_ptr->xtra2 && (is_ego_p(o_ptr, EGO_MSTAFF_SPELL))) - { - /* Hack -- Dump " (charging spell2)" if relevant */ - t = object_desc_str(t, " (charging spell2)"); + { + t += " (charging)"; + } } /* No more details wanted */ - if (mode < 3) goto copyback; - - - /* No inscription yet */ - tmp_val2[0] = '\0'; - - /* Sensed stuff */ - if (o_ptr->ident & (IDENT_SENSE)) + if (mode < 3) { - strcpy(tmp_val2, sense_desc[o_ptr->sense]); + return t; } - /* Hack - Note "cursed" if the item is 'known' and cursed */ - if (cursed_p(o_ptr) && (known) && (!tmp_val2[0])) - { - if (tmp_val2[0]) strcat(tmp_val2, ", "); - strcat(tmp_val2, "cursed"); - } - /* Use the standard inscription if available */ - if (o_ptr->note) + /* Inscribe */ { - char *u = tmp_val2; + std::vector<std::string> inscrip; - if (tmp_val2[0]) strcat(tmp_val2, ", "); - - strcat(tmp_val2, quark_str(o_ptr->note)); - - for (; *u && (*u != '#') && (*u != '%'); u++); + /* Sensed stuff */ + if ((o_ptr->ident & (IDENT_SENSE)) && sense_desc[o_ptr->sense] && sense_desc[o_ptr->sense][0] != '\0') + { + inscrip.push_back(sense_desc[o_ptr->sense]); + } - *u = '\0'; - } + /* Hack - Note "cursed" if the item is 'known' and cursed */ + if (cursed_p(o_ptr) && known && inscrip.empty()) + { + inscrip.push_back("cursed"); + } - /* Mega-Hack -- note empty wands/staffs */ - if (!known && (o_ptr->ident & (IDENT_EMPTY))) - { - if (tmp_val2[0]) strcat(tmp_val2, ", "); - strcat(tmp_val2, "empty"); - } + /* Use the standard inscription if available; + Chop at '#' or '%' if present. The suffix of the + '%' or '#' is handled elsewhere in this function. + */ + if (auto const pos = o_ptr->inscription.find_first_of("%#") != std::string::npos) + { + inscrip.push_back(o_ptr->inscription.substr(0, pos)); + } - /* Note "tried" if the object has been tested unsuccessfully */ - if (!aware && object_tried_p(o_ptr)) - { - if (tmp_val2[0]) strcat(tmp_val2, ", "); - strcpy(tmp_val2, "tried"); - } + /* Mega-Hack -- note empty wands/staffs */ + if (!known && (o_ptr->ident & (IDENT_EMPTY))) + { + inscrip.push_back("empty"); + } - /* Note the discount, if any */ - if ((o_ptr->discount) && (!tmp_val2[0])) - { - object_desc_num(tmp_val2, o_ptr->discount); - strcat(tmp_val2, "% off"); - } + /* Note "tried" if the object has been tested unsuccessfully */ + if (!aware && object_tried_p(o_ptr)) + { + inscrip.push_back("tried"); + } - /* Append the inscription, if any */ - if (tmp_val2[0]) - { - int n; + /* Note the discount, if any */ + if ((o_ptr->discount) && o_ptr->inscription.empty()) + { + inscrip.push_back(fmt::format("{:d}% off", o_ptr->discount)); + } - /* Hack -- How much so far */ - n = (t - tmp_val); + /* Append the user's inscription */ + if (!o_ptr->inscription.empty()) + { + inscrip.push_back(o_ptr->inscription); + } - /* Paranoia -- do not be stupid */ - if (n > 75) n = 75; + /* Append the inscription, if any */ + if (!inscrip.empty()) + { + auto inscrip_str = boost::algorithm::join(inscrip, ", "); - /* Hack -- shrink the inscription */ - tmp_val2[75 - n] = '\0'; + /* Make sure we don't exceed 75 characters */ + t.resize(std::min<std::size_t>(t.size(), 75)); - /* Append the inscription */ - t = object_desc_chr(t, ' '); - t = object_desc_chr(t, c1); - t = object_desc_str(t, tmp_val2); - t = object_desc_chr(t, c2); + /* Append the inscription */ + t += fmt::format(" {{{}}}", inscrip_str); + } } -copyback: - /* Here's where we dump the built string into buf. */ - tmp_val[79] = '\0'; - t = tmp_val; - while ((*(buf++) = *(t++))); /* copy the string over */ + + return t; } +void object_desc(char *buf, object_type const *o_ptr, int pref, int mode) +{ + auto s = object_desc_aux(o_ptr, pref, mode); + auto n = std::min<std::size_t>(s.size(), 79); + s.copy(buf, n); + buf[n] = '\0'; +} /* * Hack -- describe an item currently in a store's inventory @@ -2431,6 +2051,8 @@ copyback: */ void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode) { + auto &k_info = game->edit_data.k_info; + /* Save the "aware" flag */ bool_ hack_aware = k_info[o_ptr->k_idx].aware; @@ -2463,18 +2085,16 @@ void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode) * Determine the "Activation" (if any) for an artifact * Return a string, or NULL for "no activation" */ -cptr item_activation(object_type *o_ptr, byte num) +cptr item_activation(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - - /* Needed hacks */ - static char rspell[2][80]; + auto const &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Require activation ability */ - if (!(f3 & (TR3_ACTIVATE))) return (NULL); + if (!(flags & TR_ACTIVATE)) return (NULL); /* @@ -2484,29 +2104,6 @@ cptr item_activation(object_type *o_ptr, byte num) * for art_name */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - int gf, mod, mana; - - if (!num) - { - gf = o_ptr->pval & 0xFFFF; - mod = o_ptr->pval3 & 0xFFFF; - mana = o_ptr->pval2 & 0xFF; - } - else - { - gf = o_ptr->pval >> 16; - mod = o_ptr->pval3 >> 16; - mana = o_ptr->pval2 >> 8; - } - sprintf(rspell[num], "runespell(%s, %s, %d) every %d turns", - k_info[lookup_kind(TV_RUNE1, gf)].name, - k_info[lookup_kind(TV_RUNE2, mod)].name, - mana, mana * 5); - return rspell[num]; - } - if (o_ptr->tval == TV_EGG) { return "stop or resume the egg development"; @@ -2546,8 +2143,16 @@ static bool_ grab_tval_desc(int tval) return TRUE; } -#define CHECK_FIRST(txt, first) \ -if ((first)) { (first) = FALSE; text_out((txt)); } else text_out(", "); +static void check_first(bool_ *first) +{ + if (*first) { + *first = FALSE; + } + else + { + text_out(", "); + } +} /* * Display the damage done with a multiplier @@ -2559,7 +2164,7 @@ void output_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr agai dam = (o_ptr->dd + (o_ptr->dd * o_ptr->ds)) * 5 * mult; dam += (o_ptr->to_d + p_ptr->to_d + p_ptr->to_d_melee) * 10; dam *= p_ptr->num_blow; - CHECK_FIRST("", *first); + check_first(first); if (dam > 0) { if (dam % 10) @@ -2576,7 +2181,7 @@ void output_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr agai dam = (o_ptr->dd + (o_ptr->dd * o_ptr->ds)) * 5 * mult2; dam += (o_ptr->to_d + p_ptr->to_d + p_ptr->to_d_melee) * 10; dam *= p_ptr->num_blow; - CHECK_FIRST("", *first); + check_first(first); if (dam > 0) { if (dam % 10) @@ -2596,12 +2201,11 @@ void output_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr agai void display_weapon_damage(object_type *o_ptr) { object_type forge, *old_ptr = &forge; - u32b f1, f2, f3, f4, f5, esp; bool_ first = TRUE; bool_ full = o_ptr->ident & (IDENT_MENTAL); /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Ok now the hackish stuff, we replace the current weapon with this one */ object_copy(old_ptr, &p_ptr->inventory[INVEN_WIELD]); @@ -2612,23 +2216,23 @@ void display_weapon_damage(object_type *o_ptr) text_out_c(TERM_L_GREEN, format("%d ", p_ptr->num_blow)); text_out(format("blow%s and do an average damage per turn of ", (p_ptr->num_blow) ? "s" : "")); - if (full && (f1 & TR1_SLAY_ANIMAL)) output_dam(o_ptr, 2, 0, "animals", NULL, &first); - if (full && (f1 & TR1_SLAY_EVIL)) output_dam(o_ptr, 2, 0, "evil creatures", NULL, &first); - if (full && (f1 & TR1_SLAY_ORC)) output_dam(o_ptr, 3, 0, "orcs", NULL, &first); - if (full && (f1 & TR1_SLAY_TROLL)) output_dam(o_ptr, 3, 0, "trolls", NULL, &first); - if (full && (f1 & TR1_SLAY_GIANT)) output_dam(o_ptr, 3, 0, "giants", NULL, &first); - if (full && (f1 & TR1_KILL_DRAGON)) output_dam(o_ptr, 5, 0, "dragons", NULL, &first); - else if (full && (f1 & TR1_SLAY_DRAGON)) output_dam(o_ptr, 3, 0, "dragons", NULL, &first); - if (full && (f5 & TR5_KILL_UNDEAD)) output_dam(o_ptr, 5, 0, "undead", NULL, &first); - else if (full && (f1 & TR1_SLAY_UNDEAD)) output_dam(o_ptr, 3, 0, "undead", NULL, &first); - if (full && (f5 & TR5_KILL_DEMON)) output_dam(o_ptr, 5, 0, "demons", NULL, &first); - else if (full && (f1 & TR1_SLAY_DEMON)) output_dam(o_ptr, 3, 0, "demons", NULL, &first); - - if (full && (f1 & TR1_BRAND_FIRE)) output_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_COLD)) output_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_ELEC)) output_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_ACID)) output_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_POIS)) output_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first); + if (full && (flags & TR_SLAY_ANIMAL)) output_dam(o_ptr, 2, 0, "animals", NULL, &first); + if (full && (flags & TR_SLAY_EVIL)) output_dam(o_ptr, 2, 0, "evil creatures", NULL, &first); + if (full && (flags & TR_SLAY_ORC)) output_dam(o_ptr, 3, 0, "orcs", NULL, &first); + if (full && (flags & TR_SLAY_TROLL)) output_dam(o_ptr, 3, 0, "trolls", NULL, &first); + if (full && (flags & TR_SLAY_GIANT)) output_dam(o_ptr, 3, 0, "giants", NULL, &first); + if (full && (flags & TR_KILL_DRAGON)) output_dam(o_ptr, 5, 0, "dragons", NULL, &first); + else if (full && (flags & TR_SLAY_DRAGON)) output_dam(o_ptr, 3, 0, "dragons", NULL, &first); + if (full && (flags & TR_KILL_UNDEAD)) output_dam(o_ptr, 5, 0, "undead", NULL, &first); + else if (full && (flags & TR_SLAY_UNDEAD)) output_dam(o_ptr, 3, 0, "undead", NULL, &first); + if (full && (flags & TR_KILL_DEMON)) output_dam(o_ptr, 5, 0, "demons", NULL, &first); + else if (full && (flags & TR_SLAY_DEMON)) output_dam(o_ptr, 3, 0, "demons", NULL, &first); + + if (full && (flags & TR_BRAND_FIRE)) output_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first); + if (full && (flags & TR_BRAND_COLD)) output_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first); + if (full && (flags & TR_BRAND_ELEC)) output_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first); + if (full && (flags & TR_BRAND_ACID)) output_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first); + if (full && (flags & TR_BRAND_POIS)) output_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first); output_dam(o_ptr, 1, 0, (first) ? "all monsters" : "other monsters", NULL, &first); @@ -2656,7 +2260,7 @@ void output_ammo_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr dam *= tmul; if (!is_boomerang) dam += (p_ptr->to_d_ranged) * 10; dam *= mult; - CHECK_FIRST("", *first); + check_first(first); if (dam > 0) { if (dam % 10) @@ -2676,7 +2280,7 @@ void output_ammo_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr dam *= tmul; if (!is_boomerang) dam += (p_ptr->to_d_ranged) * 10; dam *= mult2; - CHECK_FIRST("", *first); + check_first(first); if (dam > 0) { if (dam % 10) @@ -2695,35 +2299,34 @@ void output_ammo_dam(object_type *o_ptr, int mult, int mult2, cptr against, cptr */ void display_ammo_damage(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; bool_ first = TRUE; int i; bool_ full = o_ptr->ident & (IDENT_MENTAL); /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); if (o_ptr->tval == TV_BOOMERANG) text_out("\nUsing it you would do an average damage per throw of "); else text_out("\nUsing it with your current shooter you would do an average damage per shot of "); - if (full && (f1 & TR1_SLAY_ANIMAL)) output_ammo_dam(o_ptr, 2, 0, "animals", NULL, &first); - if (full && (f1 & TR1_SLAY_EVIL)) output_ammo_dam(o_ptr, 2, 0, "evil creatures", NULL, &first); - if (full && (f1 & TR1_SLAY_ORC)) output_ammo_dam(o_ptr, 3, 0, "orcs", NULL, &first); - if (full && (f1 & TR1_SLAY_TROLL)) output_ammo_dam(o_ptr, 3, 0, "trolls", NULL, &first); - if (full && (f1 & TR1_SLAY_GIANT)) output_ammo_dam(o_ptr, 3, 0, "giants", NULL, &first); - if (full && (f1 & TR1_KILL_DRAGON)) output_ammo_dam(o_ptr, 5, 0, "dragons", NULL, &first); - else if (full && (f1 & TR1_SLAY_DRAGON)) output_ammo_dam(o_ptr, 3, 0, "dragons", NULL, &first); - if (full && (f5 & TR5_KILL_UNDEAD)) output_ammo_dam(o_ptr, 5, 0, "undeads", NULL, &first); - else if (full && (f1 & TR1_SLAY_UNDEAD)) output_ammo_dam(o_ptr, 3, 0, "undeads", NULL, &first); - if (full && (f5 & TR5_KILL_DEMON)) output_ammo_dam(o_ptr, 5, 0, "demons", NULL, &first); - else if (full && (f1 & TR1_SLAY_DEMON)) output_ammo_dam(o_ptr, 3, 0, "demons", NULL, &first); - - if (full && (f1 & TR1_BRAND_FIRE)) output_ammo_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_COLD)) output_ammo_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_ELEC)) output_ammo_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_ACID)) output_ammo_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first); - if (full && (f1 & TR1_BRAND_POIS)) output_ammo_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first); + if (full && (flags & TR_SLAY_ANIMAL)) output_ammo_dam(o_ptr, 2, 0, "animals", NULL, &first); + if (full && (flags & TR_SLAY_EVIL)) output_ammo_dam(o_ptr, 2, 0, "evil creatures", NULL, &first); + if (full && (flags & TR_SLAY_ORC)) output_ammo_dam(o_ptr, 3, 0, "orcs", NULL, &first); + if (full && (flags & TR_SLAY_TROLL)) output_ammo_dam(o_ptr, 3, 0, "trolls", NULL, &first); + if (full && (flags & TR_SLAY_GIANT)) output_ammo_dam(o_ptr, 3, 0, "giants", NULL, &first); + if (full && (flags & TR_KILL_DRAGON)) output_ammo_dam(o_ptr, 5, 0, "dragons", NULL, &first); + else if (full && (flags & TR_SLAY_DRAGON)) output_ammo_dam(o_ptr, 3, 0, "dragons", NULL, &first); + if (full && (flags & TR_KILL_UNDEAD)) output_ammo_dam(o_ptr, 5, 0, "undeads", NULL, &first); + else if (full && (flags & TR_SLAY_UNDEAD)) output_ammo_dam(o_ptr, 3, 0, "undeads", NULL, &first); + if (full && (flags & TR_KILL_DEMON)) output_ammo_dam(o_ptr, 5, 0, "demons", NULL, &first); + else if (full && (flags & TR_SLAY_DEMON)) output_ammo_dam(o_ptr, 3, 0, "demons", NULL, &first); + + if (full && (flags & TR_BRAND_FIRE)) output_ammo_dam(o_ptr, 3, 6, "non fire resistant creatures", "fire susceptible creatures", &first); + if (full && (flags & TR_BRAND_COLD)) output_ammo_dam(o_ptr, 3, 6, "non cold resistant creatures", "cold susceptible creatures", &first); + if (full && (flags & TR_BRAND_ELEC)) output_ammo_dam(o_ptr, 3, 6, "non lightning resistant creatures", "lightning susceptible creatures", &first); + if (full && (flags & TR_BRAND_ACID)) output_ammo_dam(o_ptr, 3, 6, "non acid resistant creatures", "acid susceptible creatures", &first); + if (full && (flags & TR_BRAND_POIS)) output_ammo_dam(o_ptr, 3, 6, "non poison resistant creatures", "poison susceptible creatures", &first); output_ammo_dam(o_ptr, 1, 0, (first) ? "all monsters" : "other monsters", NULL, &first); text_out(". "); @@ -2767,7 +2370,7 @@ static void describe_device(object_type *o_ptr) }); text_out("\nSpell level: "); - sprintf(buf, FMTs32b, get_level(o_ptr->pval2, 50, 0)); + sprintf(buf, FMTs32b, get_level(o_ptr->pval2, 50)); text_out_c(TERM_L_BLUE, buf); text_out("\nMinimum Magic Device level to increase spell level: "); @@ -2796,6 +2399,9 @@ static void describe_device(object_type *o_ptr) */ static cptr object_out_desc_where_found(s16b level, s16b dungeon) { + auto const &d_info = game->edit_data.d_info; + auto const &wf_info = game->edit_data.wf_info; + static char str[80]; if (dungeon == DUNGEON_WILDERNESS) @@ -2816,7 +2422,7 @@ static cptr object_out_desc_where_found(s16b level, s16b dungeon) } else { - sprintf(str, "on level %d of %s", level, d_info[dungeon].name); + sprintf(str, "on level %d of %s", level, d_info[dungeon].name.c_str()); } return str; @@ -2827,29 +2433,25 @@ static cptr object_out_desc_where_found(s16b level, s16b dungeon) */ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it) { - u32b f1, f2, f3, f4, f5, esp; - - const char *txt; + auto const &set_info = game->edit_data.set_info; + auto const &st_info = game->edit_data.st_info; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; cptr vp[64]; byte vc[64]; int vn; - bool_ first = TRUE; + object_flag_set flags; /* Extract the flags */ if ((!(o_ptr->ident & (IDENT_MENTAL))) && (!fff)) { - f1 = o_ptr->art_oflags1; - f2 = o_ptr->art_oflags2; - f3 = o_ptr->art_oflags3; - f4 = o_ptr->art_oflags4; - f5 = o_ptr->art_oflags5; - esp = o_ptr->art_oesp; + flags = o_ptr->art_oflags; } else { - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + flags = object_flags(o_ptr); } if (fff) @@ -2879,7 +2481,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait { if (o_ptr->k_idx && (!trim_down)) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; text_out_c(TERM_ORANGE, k_ptr->text); text_out("\n"); @@ -2887,41 +2489,38 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait if (o_ptr->name1 && (!trim_down)) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; text_out_c(TERM_YELLOW, a_ptr->text); text_out("\n"); if (a_ptr->set != -1) { - text_out_c(TERM_GREEN, set_info[a_ptr->set].desc); + text_out_c(TERM_GREEN, set_info[a_ptr->set].desc.c_str()); text_out("\n"); } } - if ((f4 & TR4_LEVELS) && (!trim_down)) + if ((flags & TR_LEVELS) && (!trim_down)) { - int j = 0; - - if (count_bits(o_ptr->pval3) == 0) text_out("It is sentient"); + if (o_ptr->pval3 == 0) text_out("It is sentient"); else if (count_bits(o_ptr->pval3) > 1) text_out("It is sentient and can have access to the realms of "); else text_out("It is sentient and can have access to the realm of "); - first = TRUE; - txt = ""; - for (j = 0; j < MAX_FLAG_GROUP; j++) + bool_ first = TRUE; + for (std::size_t j = 0; j < flags_groups().size(); j++) { if (BIT(j) & o_ptr->pval3) { - CHECK_FIRST(txt, first); - text_out_c(flags_groups[j].color, flags_groups[j].name); + check_first(&first); + text_out_c(flags_groups()[j].color, flags_groups()[j].name); } } text_out(". "); } - if (f4 & TR4_ULTIMATE) + if (flags & TR_ULTIMATE) { if ((wield_slot(o_ptr) == INVEN_WIELD) || (wield_slot(o_ptr) == INVEN_BOW)) @@ -2930,24 +2529,17 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out_c(TERM_VIOLET, "It is the ultimate armor. "); } - if (f4 & TR4_COULD2H) text_out("It can be wielded two-handed. "); - if (f4 & TR4_MUST2H) text_out("It must be wielded two-handed. "); + if (flags & TR_COULD2H) text_out("It can be wielded two-handed. "); + if (flags & TR_MUST2H) text_out("It must be wielded two-handed. "); /* Mega-Hack -- describe activation */ - if (f3 & (TR3_ACTIVATE)) + if (flags & TR_ACTIVATE) { text_out("It can be activated for "); - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - text_out(item_activation(o_ptr, 0)); - text_out(" and "); - text_out(item_activation(o_ptr, 1)); - } - else - text_out(item_activation(o_ptr, 0)); + text_out(item_activation(o_ptr)); /* Mega-hack -- get rid of useless line for e.g. randarts */ - if (f5 & (TR5_ACTIVATE_NO_WIELD)) + if (flags & TR_ACTIVATE_NO_WIELD) text_out(". "); else text_out(" if it is being worn. "); @@ -2960,23 +2552,25 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out(" if it is being worn. "); } - /* Hack -- describe lites */ - if ((o_ptr->tval == TV_LITE) || (f3 & TR3_LITE1) || (f4 & TR4_LITE2) || (f4 & TR4_LITE3)) + /* Describe light sources */ { int radius = 0; - if (f3 & TR3_LITE1) radius++; - if (f4 & TR4_LITE2) radius += 2; - if (f4 & TR4_LITE3) radius += 3; + if (flags & TR_LITE1) radius += 1; + if (flags & TR_LITE2) radius += 2; + if (flags & TR_LITE3) radius += 3; if (radius > 5) radius = 5; - if (f4 & TR4_FUEL_LITE) + if (radius > 0) { - text_out(format("It provides light (radius %d) when fueled. ", radius)); - } - else - { - text_out(format("It provides light (radius %d) forever. ", radius)); + if (flags & TR_FUEL_LITE) + { + text_out(format("It provides light (radius %d) when fueled. ", radius)); + } + else + { + text_out(format("It provides light (radius %d). ", radius)); + } } } @@ -2986,12 +2580,12 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out("It prevents the space-time continuum from being disrupted. "); } - if (f4 & TR4_ANTIMAGIC_50) + if (flags & TR_ANTIMAGIC_50) { text_out("It generates an antimagic field. "); } - if (f5 & TR5_SPELL_CONTAIN) + if (flags & TR_SPELL_CONTAIN) { if (o_ptr->pval2 == -1) text_out("It can be used to store a spell. "); @@ -3001,21 +2595,19 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait /* Pick up stat bonuses */ vn = 0; - if (f1 & (TR1_STR)) vp[vn++] = "strength"; - if (f1 & (TR1_INT)) vp[vn++] = "intelligence"; - if (f1 & (TR1_WIS)) vp[vn++] = "wisdom"; - if (f1 & (TR1_DEX)) vp[vn++] = "dexterity"; - if (f1 & (TR1_CON)) vp[vn++] = "constitution"; - if (f1 & (TR1_CHR)) vp[vn++] = "charisma"; - if ((o_ptr->tval != TV_TRAPKIT) && (f1 & (TR1_STEALTH))) vp[vn++] = "stealth"; - if (f1 & (TR1_SEARCH)) vp[vn++] = "searching"; - if (f1 & (TR1_INFRA)) vp[vn++] = "infravision"; - if (f1 & (TR1_TUNNEL)) vp[vn++] = "ability to tunnel"; - if (f1 & (TR1_SPEED)) vp[vn++] = "speed"; - if (f1 & (TR1_BLOWS)) vp[vn++] = "attack speed"; - if (f5 & (TR5_CRIT)) vp[vn++] = "ability to score critical hits"; - if (f5 & (TR5_LUCK)) vp[vn++] = "luck"; - if (f1 & (TR1_SPELL)) vp[vn++] = "spell power"; + if (flags & TR_STR) vp[vn++] = "strength"; + if (flags & TR_INT) vp[vn++] = "intelligence"; + if (flags & TR_WIS) vp[vn++] = "wisdom"; + if (flags & TR_DEX) vp[vn++] = "dexterity"; + if (flags & TR_CON) vp[vn++] = "constitution"; + if (flags & TR_CHR) vp[vn++] = "charisma"; + if (flags & TR_INFRA) vp[vn++] = "infravision"; + if (flags & TR_TUNNEL) vp[vn++] = "ability to tunnel"; + if (flags & TR_SPEED) vp[vn++] = "speed"; + if (flags & TR_BLOWS) vp[vn++] = "attack speed"; + if (flags & TR_CRIT) vp[vn++] = "ability to score critical hits"; + if (flags & TR_LUCK) vp[vn++] = "luck"; + if (flags & TR_SPELL) vp[vn++] = "spell power"; /* Describe */ if (vn) @@ -3051,8 +2643,8 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait vn = 0; - if (f1 & (TR1_MANA)) vp[vn++] = "mana capacity"; - if (f2 & (TR2_LIFE)) vp[vn++] = "hit points"; + if (flags & TR_MANA) vp[vn++] = "mana capacity"; + if (flags & TR_LIFE) vp[vn++] = "hit points"; /* Describe with percentuals */ if (vn) @@ -3084,28 +2676,23 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out(". "); } - if ((o_ptr->tval == TV_TRAPKIT) && (f1 & (TR1_STEALTH))) - { - text_out("It is well-hidden. "); - } - vn = 0; - if (f1 & (TR1_BRAND_ACID)) + if (flags & TR_BRAND_ACID) { vc[vn] = TERM_GREEN; vp[vn++] = "acid"; } - if (f1 & (TR1_BRAND_ELEC)) + if (flags & TR_BRAND_ELEC) { vc[vn] = TERM_L_BLUE; vp[vn++] = "electricity"; } - if (f1 & (TR1_BRAND_FIRE)) + if (flags & TR_BRAND_FIRE) { vc[vn] = TERM_RED; vp[vn++] = "fire"; } - if (f1 & (TR1_BRAND_COLD)) + if (flags & TR_BRAND_COLD) { vc[vn] = TERM_L_WHITE; vp[vn++] = "frost"; @@ -3133,296 +2720,261 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait } - if (f1 & (TR1_BRAND_POIS)) + if (flags & TR_BRAND_POIS) { text_out("It "); text_out_c(TERM_L_GREEN, "poisons your foes"); text_out(". "); } - if (f1 & (TR1_CHAOTIC)) + if (flags & TR_CHAOTIC) { text_out("It produces chaotic effects. "); } - if (f1 & (TR1_VAMPIRIC)) + if (flags & TR_VAMPIRIC) { text_out("It drains life from your foes. "); } - if (f1 & (TR1_IMPACT)) + if (flags & TR_IMPACT) { text_out("It can cause earthquakes. "); } - if (f1 & (TR1_VORPAL)) + if (flags & TR_VORPAL) { text_out("It is very sharp and can cut your foes. "); } - if (f5 & (TR5_WOUNDING)) + if (flags & TR_WOUNDING) { text_out("It is very sharp and can make your foes bleed. "); } - if (f1 & (TR1_KILL_DRAGON)) + if (flags & TR_KILL_DRAGON) { text_out("It is a great bane of dragons. "); } - else if (f1 & (TR1_SLAY_DRAGON)) + else if (flags & TR_SLAY_DRAGON) { text_out("It is especially deadly against dragons. "); } - if (f1 & (TR1_SLAY_ORC)) + + if (flags & TR_SLAY_ORC) { text_out("It is especially deadly against orcs. "); } - if (f1 & (TR1_SLAY_TROLL)) + + if (flags & TR_SLAY_TROLL) { text_out("It is especially deadly against trolls. "); } - if (f1 & (TR1_SLAY_GIANT)) + + if (flags & TR_SLAY_GIANT) { text_out("It is especially deadly against giants. "); } - if (f5 & (TR5_KILL_DEMON)) + + if (flags & TR_KILL_DEMON) { text_out("It is a great bane of demons. "); } - else if (f1 & (TR1_SLAY_DEMON)) + else if (flags & TR_SLAY_DEMON) { text_out("It strikes at demons with holy wrath. "); } - if (f5 & (TR5_KILL_UNDEAD)) + + if (flags & TR_KILL_UNDEAD) { text_out("It is a great bane of undead. "); } - else if (f1 & (TR1_SLAY_UNDEAD)) + else if (flags & TR_SLAY_UNDEAD) { text_out("It strikes at undead with holy wrath. "); } - if (f1 & (TR1_SLAY_EVIL)) + + if (flags & TR_SLAY_EVIL) { text_out("It fights against evil with holy fury. "); } - if (f1 & (TR1_SLAY_ANIMAL)) + + if (flags & TR_SLAY_ANIMAL) { text_out("It is especially deadly against natural creatures. "); } - if (f2 & (TR2_INVIS)) + if (flags & TR_INVIS) { text_out("It makes you invisible. "); } - if (o_ptr->tval != TV_TRAPKIT) + vn = 0; + if (flags & TR_SUST_STR) { - vn = 0; - if (f2 & (TR2_SUST_STR)) - { - vp[vn++] = "strength"; - } - if (f2 & (TR2_SUST_INT)) - { - vp[vn++] = "intelligence"; - } - if (f2 & (TR2_SUST_WIS)) - { - vp[vn++] = "wisdom"; - } - if (f2 & (TR2_SUST_DEX)) - { - vp[vn++] = "dexterity"; - } - if (f2 & (TR2_SUST_CON)) - { - vp[vn++] = "constitution"; - } - if (f2 & (TR2_SUST_CHR)) - { - vp[vn++] = "charisma"; - } - /* Describe */ - if (vn) - { - int i; - - /* Intro */ - text_out("It sustains "); - - /* List */ - for (i = 0; i < vn; i++) - { - /* Connectives */ - if (i == 0) text_out("your "); - else if (i < (vn - 1)) text_out(", "); - else text_out(" and "); + vp[vn++] = "strength"; + } + if (flags & TR_SUST_INT) + { + vp[vn++] = "intelligence"; + } + if (flags & TR_SUST_WIS) + { + vp[vn++] = "wisdom"; + } + if (flags & TR_SUST_DEX) + { + vp[vn++] = "dexterity"; + } + if (flags & TR_SUST_CON) + { + vp[vn++] = "constitution"; + } + if (flags & TR_SUST_CHR) + { + vp[vn++] = "charisma"; + } + /* Describe */ + if (vn) + { + int i; - /* Dump the stat */ - text_out(vp[i]); - } - text_out(". "); - } + /* Intro */ + text_out("It sustains "); - vn = 0; - if (f2 & (TR2_IM_ACID)) - { - vc[vn] = TERM_GREEN; - vp[vn++] = "acid"; - } - if (f2 & (TR2_IM_ELEC)) - { - vc[vn] = TERM_L_BLUE; - vp[vn++] = "electricity"; - } - if (f2 & (TR2_IM_FIRE)) - { - vc[vn] = TERM_RED; - vp[vn++] = "fire"; - } - if (f2 & (TR2_IM_COLD)) - { - vc[vn] = TERM_L_WHITE; - vp[vn++] = "cold"; - } - if (f4 & (TR4_IM_NETHER)) - { - vc[vn] = TERM_L_GREEN; - vp[vn++] = "nether"; - } - /* Describe */ - if (vn) + /* List */ + for (i = 0; i < vn; i++) { - int i; - - /* Intro */ - text_out("It provides immunity "); - - /* List */ - for (i = 0; i < vn; i++) - { - /* Connectives */ - if (i == 0) text_out("to "); - else if (i < (vn - 1)) text_out(", "); - else text_out(" and "); + /* Connectives */ + if (i == 0) text_out("your "); + else if (i < (vn - 1)) text_out(", "); + else text_out(" and "); - /* Dump the stat */ - text_out_c(vc[i], vp[i]); - } - text_out(". "); + /* Dump the stat */ + text_out(vp[i]); } + text_out(". "); } - else + + vn = 0; + if (flags & TR_IM_ACID) { - if (f2 & (TRAP2_AUTOMATIC_5)) - { - text_out("It can rearm itself. "); - } - if (f2 & (TRAP2_AUTOMATIC_99)) - { - text_out("It rearms itself. "); - } - if (f2 & (TRAP2_KILL_GHOST)) - { - text_out("It is effective against Ghosts. "); - } - if (f2 & (TRAP2_TELEPORT_TO)) - { - text_out("It can teleport monsters to you. "); - } - if (f2 & (TRAP2_ONLY_DRAGON)) - { - text_out("It can only be set off by dragons. "); - } - if (f2 & (TRAP2_ONLY_DEMON)) - { - text_out("It can only be set off by demons. "); - } - if (f2 & (TRAP2_ONLY_UNDEAD)) - { - text_out("It can only be set off by undead. "); - } - if (f2 & (TRAP2_ONLY_ANIMAL)) - { - text_out("It can only be set off by animals. "); - } - if (f2 & (TRAP2_ONLY_EVIL)) + vc[vn] = TERM_GREEN; + vp[vn++] = "acid"; + } + if (flags & TR_IM_ELEC) + { + vc[vn] = TERM_L_BLUE; + vp[vn++] = "electricity"; + } + if (flags & TR_IM_FIRE) + { + vc[vn] = TERM_RED; + vp[vn++] = "fire"; + } + if (flags & TR_IM_COLD) + { + vc[vn] = TERM_L_WHITE; + vp[vn++] = "cold"; + } + if (flags & TR_IM_NETHER) + { + vc[vn] = TERM_L_GREEN; + vp[vn++] = "nether"; + } + /* Describe */ + if (vn) + { + int i; + + /* Intro */ + text_out("It provides immunity "); + + /* List */ + for (i = 0; i < vn; i++) { - text_out("It can only be set off by evil creatures. "); + /* Connectives */ + if (i == 0) text_out("to "); + else if (i < (vn - 1)) text_out(", "); + else text_out(" and "); + + /* Dump the stat */ + text_out_c(vc[i], vp[i]); } + text_out(". "); } - if (f2 & (TR2_FREE_ACT)) + if (flags & TR_FREE_ACT) { text_out("It provides immunity to paralysis. "); } - if (f2 & (TR2_RES_FEAR)) + if (flags & TR_RES_FEAR) { text_out("It makes you completely fearless. "); } vn = 0; - if (f2 & (TR2_HOLD_LIFE)) + if (flags & TR_HOLD_LIFE) { vp[vn++] = "life draining"; } - if ((f2 & (TR2_RES_ACID)) && !(f2 & (TR2_IM_ACID))) + if ((flags & TR_RES_ACID) && !(flags & TR_IM_ACID)) { vp[vn++] = "acid"; } - if ((f2 & (TR2_RES_ELEC)) && !(f2 & (TR2_IM_ELEC))) + if ((flags & TR_RES_ELEC) && !(flags & TR_IM_ELEC)) { vp[vn++] = "electricity"; } - if ((f2 & (TR2_RES_FIRE)) && !(f2 & (TR2_IM_FIRE))) + if ((flags & TR_RES_FIRE) && !(flags & TR_IM_FIRE)) { vp[vn++] = "fire"; } - if ((f2 & (TR2_RES_COLD)) && !(f2 & (TR2_IM_COLD))) + if ((flags & TR_RES_COLD) && !(flags & TR_IM_COLD)) { vp[vn++] = "cold"; } - if (f2 & (TR2_RES_POIS)) + if (flags & TR_RES_POIS) { vp[vn++] = "poison"; } - if (f2 & (TR2_RES_LITE)) + if (flags & TR_RES_LITE) { vp[vn++] = "light"; } - if (f2 & (TR2_RES_DARK)) + if (flags & TR_RES_DARK) { vp[vn++] = "dark"; } - if (f2 & (TR2_RES_BLIND)) + if (flags & TR_RES_BLIND) { vp[vn++] = "blindness"; } - if (f2 & (TR2_RES_CONF)) + if (flags & TR_RES_CONF) { vp[vn++] = "confusion"; } - if (f2 & (TR2_RES_SOUND)) + if (flags & TR_RES_SOUND) { vp[vn++] = "sound"; } - if (f2 & (TR2_RES_SHARDS)) + if (flags & TR_RES_SHARDS) { vp[vn++] = "shards"; } - if ((f2 & (TR2_RES_NETHER)) && !(f4 & (TR4_IM_NETHER))) + if ((flags & TR_RES_NETHER) && !(flags & TR_IM_NETHER)) { vp[vn++] = "nether"; } - if (f2 & (TR2_RES_NEXUS)) + if (flags & TR_RES_NEXUS) { vp[vn++] = "nexus"; } - if (f2 & (TR2_RES_CHAOS)) + if (flags & TR_RES_CHAOS) { vp[vn++] = "chaos"; } - if (f2 & (TR2_RES_DISEN)) + if (flags & TR_RES_DISEN) { vp[vn++] = "disenchantment"; } @@ -3448,61 +3000,65 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out(". "); } - if (f2 & (TR2_SENS_FIRE)) + if (flags & TR_SENS_FIRE) { text_out("It renders you especially vulnerable to fire. "); } - if (f3 & (TR3_WRAITH)) + if (flags & TR_WRAITH) { text_out("It renders you incorporeal. "); } - if (f5 & (TR5_WATER_BREATH)) + if (flags & TR_WATER_BREATH) { text_out("It allows you to breathe underwater. "); } - if (f5 & (TR5_MAGIC_BREATH)) + if (flags & TR_MAGIC_BREATH) { text_out("It allows you to breathe without air. "); } - if (f3 & (TR3_FEATHER)) + if (flags & TR_FEATHER) { text_out("It allows you to levitate. "); } - if (f4 & (TR4_FLY)) + if (flags & TR_FLY) { text_out("It allows you to fly. "); } - if (f4 & (TR4_CLIMB)) + if (flags & TR_CLIMB) { text_out("It allows you to climb mountains. "); } - if (f5 & (TR5_IMMOVABLE)) + if (flags & TR_IMMOVABLE) { text_out("It renders you immovable. "); } - if (f3 & (TR3_SEE_INVIS)) + if (flags & TR_SEE_INVIS) { text_out("It allows you to see invisible monsters. "); } - if (esp) + + // ESP_* { - if (esp & ESP_ALL) text_out("It gives telepathic powers. "); + if (flags & ESP_ALL) + { + text_out("It gives telepathic powers. "); + } else { vn = 0; - if (esp & ESP_ORC) vp[vn++] = "orcs"; - if (esp & ESP_TROLL) vp[vn++] = "trolls"; - if (esp & ESP_DRAGON) vp[vn++] = "dragons"; - if (esp & ESP_SPIDER) vp[vn++] = "spiders"; - if (esp & ESP_GIANT) vp[vn++] = "giants"; - if (esp & ESP_DEMON) vp[vn++] = "demons"; - if (esp & ESP_UNDEAD) vp[vn++] = "undead"; - if (esp & ESP_EVIL) vp[vn++] = "evil beings"; - if (esp & ESP_ANIMAL) vp[vn++] = "animals"; - if (esp & ESP_THUNDERLORD) vp[vn++] = "thunderlords"; - if (esp & ESP_GOOD) vp[vn++] = "good beings"; - if (esp & ESP_NONLIVING) vp[vn++] = "non-living things"; - if (esp & ESP_UNIQUE) vp[vn++] = "unique beings"; + if (flags & ESP_ORC) vp[vn++] = "orcs"; + if (flags & ESP_TROLL) vp[vn++] = "trolls"; + if (flags & ESP_DRAGON) vp[vn++] = "dragons"; + if (flags & ESP_SPIDER) vp[vn++] = "spiders"; + if (flags & ESP_GIANT) vp[vn++] = "giants"; + if (flags & ESP_DEMON) vp[vn++] = "demons"; + if (flags & ESP_UNDEAD) vp[vn++] = "undead"; + if (flags & ESP_EVIL) vp[vn++] = "evil beings"; + if (flags & ESP_ANIMAL) vp[vn++] = "animals"; + if (flags & ESP_THUNDERLORD) vp[vn++] = "thunderlords"; + if (flags & ESP_GOOD) vp[vn++] = "good beings"; + if (flags & ESP_NONLIVING) vp[vn++] = "non-living things"; + if (flags & ESP_UNIQUE) vp[vn++] = "unique beings"; /* Describe */ if (vn) { @@ -3527,55 +3083,55 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait } } - if (f3 & (TR3_SLOW_DIGEST)) + if (flags & TR_SLOW_DIGEST) { text_out("It slows your metabolism. "); } - if (f3 & (TR3_REGEN)) + if (flags & TR_REGEN) { text_out("It speeds your regenerative powers. "); } - if (f2 & (TR2_REFLECT)) + if (flags & TR_REFLECT) { text_out("It reflects bolts and arrows. "); } - if (f3 & (TR3_SH_FIRE)) + if (flags & TR_SH_FIRE) { text_out("It produces a fiery sheath. "); } - if (f3 & (TR3_SH_ELEC)) + if (flags & TR_SH_ELEC) { text_out("It produces an electric sheath. "); } - if (f3 & (TR3_NO_MAGIC)) + if (flags & TR_NO_MAGIC) { text_out("It produces an anti-magic shell. "); } - if (f3 & (TR3_NO_TELE)) + if (flags & TR_NO_TELE) { text_out("It prevents teleportation. "); } - if (f3 & (TR3_XTRA_MIGHT)) + if (flags & TR_XTRA_MIGHT) { text_out("It fires missiles with extra might. "); } - if (f3 & (TR3_XTRA_SHOTS)) + if (flags & TR_XTRA_SHOTS) { text_out("It fires missiles excessively fast. "); } vn = 0; - if (f5 & (TR5_DRAIN_MANA)) + if (flags & TR_DRAIN_MANA) { vc[vn] = TERM_BLUE; vp[vn++] = "mana"; } - if (f5 & (TR5_DRAIN_HP)) + if (flags & TR_DRAIN_HP) { vc[vn] = TERM_RED; vp[vn++] = "life"; } - if (f3 & (TR3_DRAIN_EXP)) + if (flags & TR_DRAIN_EXP) { vc[vn] = TERM_L_DARK; vp[vn++] = "experience"; @@ -3602,38 +3158,38 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out(". "); } - if (f3 & (TR3_BLESSED)) + if (flags & TR_BLESSED) { text_out("It has been blessed by the gods. "); } - if (f4 & (TR4_AUTO_ID)) + if (flags & TR_AUTO_ID) { text_out("It identifies all items for you. "); } - if (f3 & (TR3_TELEPORT)) + if (flags & TR_TELEPORT) { text_out("It induces random teleportation. "); } - if (f3 & (TR3_AGGRAVATE)) + if (flags & TR_AGGRAVATE) { text_out("It aggravates nearby creatures. "); } - if (f4 & (TR4_NEVER_BLOW)) + if (flags & TR_NEVER_BLOW) { text_out("It can't attack. "); } - if (f4 & (TR4_BLACK_BREATH)) + if (flags & TR_BLACK_BREATH) { text_out("It fills you with the Black Breath. "); } if (cursed_p(o_ptr)) { - if (f3 & (TR3_PERMA_CURSE)) + if (flags & TR_PERMA_CURSE) { text_out("It is permanently cursed. "); } - else if (f3 & (TR3_HEAVY_CURSE)) + else if (flags & TR_HEAVY_CURSE) { text_out("It is heavily cursed. "); } @@ -3642,68 +3198,68 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait text_out("It is cursed. "); } } - if (f3 & (TR3_TY_CURSE)) + if (flags & TR_TY_CURSE) { text_out("It carries an ancient foul curse. "); } - if (f4 & (TR4_DG_CURSE)) + if (flags & TR_DG_CURSE) { text_out("It carries an ancient Morgothian curse. "); } - if (f4 & (TR4_CLONE)) + if (flags & TR_CLONE) { text_out("It can clone monsters. "); } - if (f4 & (TR4_CURSE_NO_DROP)) + if (flags & TR_CURSE_NO_DROP) { text_out("It cannot be dropped while cursed. "); } - if (f3 & (TR3_AUTO_CURSE)) + if (flags & TR_AUTO_CURSE) { text_out("It can re-curse itself. "); } - if (f4 & (TR4_CAPACITY)) + if (flags & TR_CAPACITY) { text_out("It can hold more mana. "); } - if (f4 & (TR4_CHEAPNESS)) + if (flags & TR_CHEAPNESS) { text_out("It can cast spells for a lesser mana cost. "); } - if (f4 & (TR4_FAST_CAST)) + if (flags & TR_FAST_CAST) { text_out("It can cast spells faster. "); } - if (f4 & (TR4_CHARGING)) + if (flags & TR_CHARGING) { text_out("It regenerates its mana faster. "); } - if (f5 & (TR5_RES_MORGUL)) + if (flags & TR_RES_MORGUL) { text_out("It can resist being shattered by morgul beings. "); } - if ((f3 & (TR3_IGNORE_ACID)) && (f3 & (TR3_IGNORE_FIRE)) && (f3 & (TR3_IGNORE_COLD)) && (f3 & (TR3_IGNORE_ELEC))) + if ((flags & TR_IGNORE_ACID) && (flags & TR_IGNORE_FIRE) && (flags & TR_IGNORE_COLD) && (flags & TR_IGNORE_ELEC)) { text_out("It cannot be harmed by acid, cold, lightning or fire. "); } else { - if (f3 & (TR3_IGNORE_ACID)) + if (flags & TR_IGNORE_ACID) { text_out("It cannot be harmed by acid. "); } - if (f3 & (TR3_IGNORE_ELEC)) + if (flags & TR_IGNORE_ELEC) { text_out("It cannot be harmed by electricity. "); } - if (f3 & (TR3_IGNORE_FIRE)) + if (flags & TR_IGNORE_FIRE) { text_out("It cannot be harmed by fire. "); } - if (f3 & (TR3_IGNORE_COLD)) + if (flags & TR_IGNORE_COLD) { text_out("It cannot be harmed by cold. "); } @@ -3767,7 +3323,7 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait /* Copying how others seem to do it. -- neil */ if (o_ptr->tval == TV_RING || o_ptr->tval == TV_AMULET || - !trim_down || (ego_item_p(o_ptr)) || (artifact_p(o_ptr))) + !trim_down || ego_item_p(o_ptr) || artifact_p(o_ptr)) { /* Where did we found it ? */ if (o_ptr->found == OBJ_FOUND_MONSTER) @@ -3803,12 +3359,12 @@ bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait else if (o_ptr->found == OBJ_FOUND_STORE) { text_out(format("\nYou bought it from the %s.", - st_info[o_ptr->found_aux1].name)); + st_info[o_ptr->found_aux1].name.c_str())); } else if (o_ptr->found == OBJ_FOUND_STOLEN) { text_out(format("\nYou stole it from the %s.", - st_info[o_ptr->found_aux1].name)); + st_info[o_ptr->found_aux1].name.c_str())); } else if (o_ptr->found == OBJ_FOUND_SELFMADE) { @@ -3943,24 +3499,6 @@ static int get_slot(int slot) */ s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal) { - /* Theme has restrictions for winged races. */ - if (game_module_idx == MODULE_THEME) - { - cptr race_name = rp_ptr->title; - - if (streq(race_name, "Dragon") || - streq(race_name, "Eagle")) - { - switch (o_ptr->tval) - { - case TV_CLOAK: - case TV_HARD_ARMOR: - case TV_DRAG_ARMOR: - return -1; - } - } - } - /* Slot for equipment */ switch (o_ptr->tval) { @@ -4365,15 +3903,15 @@ static bool item_tester_okay(object_type const *o_ptr, object_filter_t const &fi -static void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter); -static void show_inven_aux(bool_ mirror, bool_ everything, object_filter_t const &filter); +static void show_equip_aux(bool_ mirror, object_filter_t const &filter); +static void show_inven_aux(bool_ mirror, object_filter_t const &filter); /* * Choice window "shadow" of the "show_inven()" function */ -void display_inven(void) +void display_inven() { - show_inven_aux(TRUE, inventory_no_move, object_filter::True()); + show_inven_aux(TRUE, object_filter::True()); } @@ -4381,16 +3919,18 @@ void display_inven(void) /* * Choice window "shadow" of the "show_equip()" function */ -void display_equip(void) +void display_equip() { - show_equip_aux(TRUE, inventory_no_move, object_filter::True()); + show_equip_aux(TRUE, object_filter::True()); } /* Get the color of the letter idx */ -byte get_item_letter_color(object_type *o_ptr) +byte get_item_letter_color(object_type const *o_ptr) { + auto const &a_info = game->edit_data.a_info; + byte color = TERM_WHITE; /* Must have knowlegde */ @@ -4399,7 +3939,7 @@ byte get_item_letter_color(object_type *o_ptr) if (ego_item_p(o_ptr)) color = TERM_L_BLUE; if (artifact_p(o_ptr)) color = TERM_YELLOW; if (o_ptr->name1 && ( -1 != a_info[o_ptr->name1].set)) color = TERM_GREEN; - if (o_ptr->name1 && (a_info[o_ptr->name1].flags4 & TR4_ULTIMATE) && (o_ptr->ident & (IDENT_MENTAL))) color = TERM_VIOLET; + if (o_ptr->name1 && (a_info[o_ptr->name1].flags & TR_ULTIMATE) && (o_ptr->ident & (IDENT_MENTAL))) color = TERM_VIOLET; return (color); } @@ -4410,7 +3950,7 @@ byte get_item_letter_color(object_type *o_ptr) * * Hack -- do not display "trailing" empty slots */ -void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filter) +void show_inven_aux(bool_ mirror, const object_filter_t &filter) { int i, j, k, l, z = 0; int row, col, len, lim; @@ -4464,16 +4004,13 @@ void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filte /* Is this item acceptable? */ if (!item_tester_okay(o_ptr, filter)) { - if ( !everything ) - continue; - out_index[k] = -i - 1; - } - else - { - /* Save the object index */ - out_index[k] = i + 1; + /* Skip to next slot */ + continue; } + /* Save the object index */ + out_index[k] = i + 1; + /* Describe the object */ object_desc(o_name, o_ptr, TRUE, 3); @@ -4482,7 +4019,7 @@ void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filte /* Save the object color, and description */ out_color[k] = tval_to_attr[o_ptr->tval % 128]; - (void)strcpy(out_desc[k], o_name); + strcpy(out_desc[k], o_name); /* Find the predicted "line length" */ l = strlen(out_desc[k]) + 5; @@ -4572,7 +4109,7 @@ void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filte static void show_inven(object_filter_t const &filter) { - show_inven_aux(FALSE, FALSE, filter); + show_inven_aux(FALSE, filter); } void show_inven_full() @@ -4584,7 +4121,7 @@ void show_inven_full() static void show_equip(object_filter_t const &filter) { - show_equip_aux(FALSE, FALSE, filter); + show_equip_aux(FALSE, filter); } void show_equip_full() @@ -4597,7 +4134,7 @@ void show_equip_full() /* * Display the equipment. */ -void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter) +void show_equip_aux(bool_ mirror, object_filter_t const &filter) { int i, j, k, l; int row, col, len, lim, idx; @@ -4652,7 +4189,6 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte !o_ptr->k_idx && p_ptr->inventory[i - INVEN_ARM + INVEN_WIELD].k_idx) { - u32b f1, f2, f3, f4, f5, esp; object_type *q_ptr = &p_ptr->inventory[i - INVEN_ARM + INVEN_WIELD]; char q_name[80]; @@ -4660,9 +4196,9 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte object_desc(q_name, q_ptr, TRUE, 3); /* Get weapon flags */ - object_flags(q_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(q_ptr); - if (f4 & TR4_MUST2H) + if (flags & TR_MUST2H) { sprintf(o_name, "(two handed) %s", q_name); @@ -4676,7 +4212,7 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte /* Save the color */ out_color[k] = TERM_L_RED; - (void)strcpy(out_desc[k], o_name); + strcpy(out_desc[k], o_name); continue; } } @@ -4696,7 +4232,7 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte /* Save the color */ out_color[k] = TERM_L_BLUE; - (void)strcpy(out_desc[k], o_name); + strcpy(out_desc[k], o_name); } else { @@ -4707,22 +4243,21 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte /* Truncate the description */ o_name[lim] = 0; + /* Is this item acceptable? */ if (!item_tester_okay(o_ptr, filter)) { - if (!everything) continue; - out_index[k] = -1; - } - else - { - /* Save the index */ - out_index[k] = idx; + /* Skip to next slot */ + continue; } + + /* Save the index */ + out_index[k] = idx; out_rindex[k] = i; /* Save the color */ out_color[k] = tval_to_attr[o_ptr->tval % 128]; - (void)strcpy(out_desc[k], o_name); + strcpy(out_desc[k], o_name); } /* Extract the maximal length (see below) */ @@ -4784,7 +4319,7 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte /* Use labels */ { /* Mention the use */ - (void)sprintf(tmp_val, "%-14s: ", mention_use(out_rindex[j])); + sprintf(tmp_val, "%-14s: ", mention_use(out_rindex[j])); put_str(tmp_val, row + j, col + 5); /* Display the entry itself */ @@ -4827,12 +4362,12 @@ void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filte /* * Flip "inven" and "equip" in any sub-windows */ -void toggle_inven_equip(void) +void toggle_inven_equip() { int j; /* Scan windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Unused */ if (!angband_term[j]) continue; @@ -4883,7 +4418,7 @@ bool_ verify(cptr prompt, int item) object_desc(o_name, o_ptr, TRUE, 3); /* Prompt */ - (void)sprintf(out_val, "%s %s? ", prompt, o_name); + sprintf(out_val, "%s %s? ", prompt, o_name); /* Query */ return (get_check(out_val)); @@ -4897,18 +4432,17 @@ bool_ verify(cptr prompt, int item) */ static bool_ get_item_allow(int item) { - cptr s; - - object_type *o_ptr; - /* Get object */ - o_ptr = get_object(item); + auto o_ptr = get_object(item); /* No inscription */ - if (!o_ptr->note) return (TRUE); + if (o_ptr->inscription.empty()) + { + return TRUE; + } /* Find a '!' */ - s = strchr(quark_str(o_ptr->note), '!'); + auto s = strchr(o_ptr->inscription.c_str(), '!'); /* Process preventions */ while (s) @@ -4958,23 +4492,25 @@ static bool get_item_okay(int i, object_filter_t const &filter) */ static int get_tag(int *cp, char tag) { - int i; - cptr s; - - /* Check every object */ - for (i = 0; i < INVEN_TOTAL; ++i) + for (int i = 0; i < INVEN_TOTAL; ++i) { object_type *o_ptr = &p_ptr->inventory[i]; /* Skip non-objects */ - if (!o_ptr->k_idx) continue; + if (!o_ptr->k_idx) + { + continue; + } /* Skip empty inscriptions */ - if (!o_ptr->note) continue; + if (o_ptr->inscription.empty()) + { + continue; + } /* Find a '@' */ - s = strchr(quark_str(o_ptr->note), '@'); + auto s = strchr(o_ptr->inscription.c_str(), '@'); /* Process all tags */ while (s) @@ -5319,7 +4855,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter int ne = 0; /* Scan windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Unused */ if (!angband_term[j]) continue; @@ -6109,7 +5645,7 @@ static void absorb_gold(cave_type const *c_ptr) object_type *o_ptr = &o_list[this_o_idx]; /* Hack -- disturb */ - disturb(0); + disturb(); /* Pick up gold */ if (o_ptr->tval == TV_GOLD) @@ -6173,12 +5709,6 @@ void py_pickup_floor(int pickup) /* Get the tile */ auto c_ptr = &cave[p_ptr->py][p_ptr->px]; - /* Hack -- ignore monster traps */ - if (c_ptr->feat == FEAT_MON_TRAP) - { - return; - } - /* Try to grab ammo */ pickup_ammo(); @@ -6218,7 +5748,7 @@ void py_pickup_floor(int pickup) bool_ do_pickup = TRUE; /* Hack -- query every item */ - if (carry_query_flag || (!can_carry_heavy(&o_list[floor_o_idx]))) + if (options->carry_query_flag || !can_carry_heavy(&o_list[floor_o_idx])) { char o_name[80] = ""; object_desc(o_name, o_ptr, TRUE, 3); @@ -6292,13 +5822,13 @@ static void gain_flag_group(object_type *o_ptr) while (tries--) { - grp = rand_int(MAX_FLAG_GROUP); + grp = rand_int(flags_groups().size()); /* If we already got this group continue */ if (o_ptr->pval3 & BIT(grp)) continue; /* Not enough points ? */ - if (flags_groups[grp].price > o_ptr->pval2) continue; + if (flags_groups()[grp].price > o_ptr->pval2) continue; /* Ok, enough points and not already got it */ break; @@ -6307,7 +5837,7 @@ static void gain_flag_group(object_type *o_ptr) /* Ack, nothing found */ if (tries <= 1) return; - o_ptr->pval2 -= flags_groups[grp].price; + o_ptr->pval2 -= flags_groups()[grp].price; o_ptr->pval3 |= BIT(grp); /* Message */ @@ -6315,124 +5845,83 @@ static void gain_flag_group(object_type *o_ptr) char o_name[80]; object_desc(o_name, o_ptr, FALSE, 0); - msg_format("%s gains access to the %s realm.", o_name, flags_groups[grp].name); + msg_format("%s gains access to the %s realm.", o_name, flags_groups()[grp].name); } } -static u32b get_flag(object_type *o_ptr, int grp, int k) +static object_flag_set get_flag(object_type *o_ptr, int grp) { - u32b f = 0, flag_set = 0; int tries = 1000; - u32b f1, f2, f3, f4, f5, esp, flag_test; - - /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); /* get the corresponding flag set of the group */ - switch (k) - { - case 0: - flag_set = flags_groups[grp].flags1; - flag_test = f1; - break; - case 1: - flag_set = flags_groups[grp].flags2; - flag_test = f2; - break; - case 2: - flag_set = flags_groups[grp].flags3; - flag_test = f3; - break; - case 3: - flag_set = flags_groups[grp].flags4; - flag_test = f4; - break; - case 4: - flag_set = flags_groups[grp].esp; - flag_test = esp; - break; - default: - flag_set = flags_groups[grp].flags1; - flag_test = f1; - break; - } + auto const flag_set = flags_groups()[grp].flags; + auto const flag_test = object_flags(o_ptr); /* If no flags, no need to look */ - if (!count_bits(flag_set)) return 0; + if (flag_set.empty()) + { + return object_flag_set(); + } while (tries--) { - /* get a random flag */ - f = BIT(rand_int(32)); + // Choose a random flag + auto const f = object_flag_set::make_bit(rand_int(object_flag_set::nbits)); - /* is it part of the group */ - if (!(f & flag_set)) continue; + // Ignore if not part of the group + if (!(f & flag_set)) + { + continue; + } - /* Already got it */ - if (f & flag_test) continue; + // Ignore if already present + if (f & flag_test) + { + continue; + } - /* Ok one */ - break; + // Got a match! + return f; } - if (tries <= 1) return (0); - else return (f); + // Exhausted the number of tries + return object_flag_set(); } /* Add a flags from a flag group */ static void gain_flag_group_flag(object_type *o_ptr) { - int grp = 0, k = 0; - u32b f = 0; - int tries = 20000; - - if (!count_bits(o_ptr->pval3)) return; - - while (tries--) + // Try a "few" times to see if we can't find a flag. + for (int tries = 20000; tries > 0; tries--) { - /* Get a flag set */ - k = rand_int(5); + // Choose a random flag group + auto grp = rand_int(flags_groups().size()); - /* get a flag group */ - grp = rand_int(MAX_FLAG_GROUP); - - if (!(BIT(grp) & o_ptr->pval3)) continue; - - /* Return a flag from the group/set */ - f = get_flag(o_ptr, grp, k); - - if (!f) continue; + // If that group isn't available to the object, then choose a new one. + if (!(BIT(grp) & o_ptr->pval3)) + { + continue; + } - break; - } + // Get an as-yet unused flag from the group, if possible. + auto const f = get_flag(o_ptr, grp); - if (tries <= 1) return; + // If we couldn't find a flag, then we try again. + if (f.empty()) + { + continue; + } - switch (k) - { - case 0: - o_ptr->art_flags1 |= f; - break; - case 1: - o_ptr->art_flags2 |= f; - break; - case 2: - o_ptr->art_flags3 |= f; - break; - case 3: - o_ptr->art_flags4 |= f; - break; - case 4: - o_ptr->art_esp |= f; - break; - } + // Got a flag; mix it into the object. + o_ptr->art_flags |= f; - /* Message */ - { + // Describe what happened char o_name[80]; - object_desc(o_name, o_ptr, FALSE, 0); - msg_format("%s gains a new power from the %s realm.", o_name, flags_groups[grp].name); + msg_format("%s gains a new power from the %s realm.", o_name, flags_groups()[grp].name); + + // We're done. + return; } } @@ -6441,11 +5930,6 @@ static void gain_flag_group_flag(object_type *o_ptr) */ void object_gain_level(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - - /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - /* First it can gain some tohit and todam */ if ((o_ptr->tval == TV_AXE) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM) || (o_ptr->tval == TV_HAFTED) || (o_ptr->tval == TV_MSTAFF)) @@ -6468,16 +5952,31 @@ void object_gain_level(object_type *o_ptr) } else { - if (!o_ptr->pval3) gain_flag_group(o_ptr); + // Gain a group if none are available. + if (!o_ptr->pval3) + { + gain_flag_group(o_ptr); + } + // Gain a flag gain_flag_group_flag(o_ptr); - if (!o_ptr->pval) o_ptr->pval = 1; + // Increase/grant PVAL + if (!o_ptr->pval) + { + o_ptr->pval = 1; + } else { - while (magik(20 - (o_ptr->pval * 2))) o_ptr->pval++; + while (magik(20 - (o_ptr->pval * 2))) + { + o_ptr->pval++; + } - if (o_ptr->pval > 5) o_ptr->pval = 5; + if (o_ptr->pval > 5) + { + o_ptr->pval = 5; + } } } } @@ -6489,12 +5988,22 @@ void object_gain_level(object_type *o_ptr) */ bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent) { - set_type *s_ptr = &set_info[set_idx]; - int i; + auto &set_info = game->edit_data.set_info; + auto const &a_info = game->edit_data.a_info; if ( -1 == a_info[a_idx].set) return (FALSE); + + auto s_ptr = &set_info[set_idx]; + + int i; for (i = 0; i < s_ptr->num; i++) - if (a_idx == s_ptr->arts[i].a_idx) break; + { + if (a_idx == s_ptr->arts[i].a_idx) + { + break; + } + } + if (!s_ptr->arts[i].present) { s_ptr->num_use++; @@ -6505,21 +6014,31 @@ bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent) } else if ((s_ptr->num_use == s_ptr->num) && (!silent)) { - cmsg_format(TERM_GREEN, "%s item set completed.", s_ptr->name); + cmsg_format(TERM_GREEN, "%s item set completed.", s_ptr->name.c_str()); } return (TRUE); } + return (FALSE); } bool_ takeoff_set(s16b a_idx, s16b set_idx) { - set_type *s_ptr = &set_info[set_idx]; - int i; + auto &set_info = game->edit_data.set_info; + auto const &a_info = game->edit_data.a_info; if ( -1 == a_info[a_idx].set) return (FALSE); + + auto s_ptr = &set_info[set_idx]; + + int i; for (i = 0; i < s_ptr->num; i++) - if (a_idx == s_ptr->arts[i].a_idx) break; + { + if (a_idx == s_ptr->arts[i].a_idx) + { + break; + } + } if (s_ptr->arts[i].present) { @@ -6530,48 +6049,60 @@ bool_ takeoff_set(s16b a_idx, s16b set_idx) if (s_ptr->num_use == s_ptr->num - 1) { - cmsg_format(TERM_GREEN, "%s item set not complete anymore.", s_ptr->name); + cmsg_format(TERM_GREEN, "%s item set not complete anymore.", s_ptr->name.c_str()); } return (TRUE); } + return (FALSE); } -bool_ apply_set(s16b a_idx, s16b set_idx) +void apply_set(s16b a_idx, s16b set_idx) { - set_type *s_ptr = &set_info[set_idx]; - int i, j; + auto const &set_info = game->edit_data.set_info; + auto const &a_info = game->edit_data.a_info; - if ( -1 == a_info[a_idx].set) return (FALSE); + if ( -1 == a_info[a_idx].set) + { + return; + } + + auto s_ptr = &set_info[set_idx]; + + int i; for (i = 0; i < s_ptr->num; i++) - if (a_idx == s_ptr->arts[i].a_idx) break; + { + if (a_idx == s_ptr->arts[i].a_idx) + { + break; + } + } + if (s_ptr->arts[i].present) { - for (j = 0; j < s_ptr->num_use; j++) + for (int j = 0; j < s_ptr->num_use; j++) { - apply_flags(s_ptr->arts[i].flags1[j], - s_ptr->arts[i].flags2[j], - s_ptr->arts[i].flags3[j], - s_ptr->arts[i].flags4[j], - s_ptr->arts[i].flags5[j], - s_ptr->arts[i].esp[j], + apply_flags(s_ptr->arts[i].flags[j], s_ptr->arts[i].pval[j], 0, 0, 0, 0); } - return (TRUE); } - return (FALSE); } -static bool_ apply_flags_set(s16b a_idx, s16b set_idx, - u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp) +static void apply_flags_set(s16b a_idx, s16b set_idx, object_flag_set *f) { - set_type *s_ptr = &set_info[set_idx]; - int i, j; + auto const &set_info = game->edit_data.set_info; + auto const &a_info = game->edit_data.a_info; - if ( -1 == a_info[a_idx].set) return (FALSE); + if ( -1 == a_info[a_idx].set) + { + return; + } + auto s_ptr = &set_info[set_idx]; + + int i; for (i = 0; i < s_ptr->num; i++) { if (a_idx == s_ptr->arts[i].a_idx) break; @@ -6579,18 +6110,11 @@ static bool_ apply_flags_set(s16b a_idx, s16b set_idx, if (s_ptr->arts[i].present) { - for (j = 0; j < s_ptr->num_use; j++) + for (int j = 0; j < s_ptr->num_use; j++) { - (*f1) |= s_ptr->arts[i].flags1[j]; - (*f2) |= s_ptr->arts[i].flags2[j]; - (*f3) |= s_ptr->arts[i].flags3[j]; - (*f4) |= s_ptr->arts[i].flags4[j]; - (*f5) |= s_ptr->arts[i].flags5[j]; - (*esp) |= s_ptr->arts[i].esp[j]; + (*f) |= s_ptr->arts[i].flags[j]; } - return (TRUE); } - return (FALSE); } /* @@ -6601,6 +6125,9 @@ static bool_ apply_flags_set(s16b a_idx, s16b set_idx, byte object_attr(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + auto const &random_artifacts = game->random_artifacts; + if (o_ptr->tval == TV_RANDART) { return random_artifacts[o_ptr->sval].attr; @@ -6617,6 +6144,9 @@ byte object_attr(object_type const *o_ptr) byte object_attr_default(object_type *o_ptr) { + auto const &k_info = game->edit_data.k_info; + auto const &random_artifacts = game->random_artifacts; + if (o_ptr->tval == TV_RANDART) { return random_artifacts[o_ptr->sval].attr; @@ -6639,6 +6169,8 @@ byte object_attr_default(object_type *o_ptr) char object_char(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + if (k_info[o_ptr->k_idx].flavor) { return misc_to_char[k_info[o_ptr->k_idx].flavor]; @@ -6651,6 +6183,8 @@ char object_char(object_type const *o_ptr) char object_char_default(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + if (k_info[o_ptr->k_idx].flavor) { return misc_to_char[k_info[o_ptr->k_idx].flavor]; @@ -6666,11 +6200,13 @@ char object_char_default(object_type const *o_ptr) */ bool artifact_p(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + return (o_ptr->tval == TV_RANDART) || (o_ptr->name1 ? true : false) || - (o_ptr->art_name ? true : false) || - ((k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) ? true : false); + (!o_ptr->artifact_name.empty()) || + ((k_info[o_ptr->k_idx].flags & TR_NORM_ART) ? true : false); } /** diff --git a/src/object1.hpp b/src/object1.hpp index ec8f9367..8b9d6dc9 100644 --- a/src/object1.hpp +++ b/src/object1.hpp @@ -2,45 +2,48 @@ #include "h-basic.h" #include "object_filter.hpp" +#include "object_flag_set.hpp" #include <boost/optional.hpp> #include <functional> typedef std::function<boost::optional<int>(object_filter_t const &filter)> select_by_name_t; -extern byte get_item_letter_color(object_type *o_ptr); -extern void object_pickup(int this_o_idx); -extern bool_ apply_set(s16b a_idx, s16b set_idx); -extern bool_ takeoff_set(s16b a_idx, s16b set_idx); -extern bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent); -extern bool_ verify(cptr prompt, int item); -extern void flavor_init(void); -extern void reset_visuals(void); -extern int object_power(object_type *o_ptr); +byte get_item_letter_color(object_type const *o_ptr); +void object_pickup(int this_o_idx); +void apply_set(s16b a_idx, s16b set_idx); +bool_ takeoff_set(s16b a_idx, s16b set_idx); +bool_ wield_set(s16b a_idx, s16b set_idx, bool_ silent); +bool_ verify(cptr prompt, int item); +void flavor_init(); +void reset_visuals(); +int object_power(object_type *o_ptr); extern bool_ object_flags_no_set; -extern void object_flags(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp); -extern void object_flags_known(object_type const *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *esp); -extern void object_desc(char *buf, object_type *o_ptr, int pref, int mode); -extern void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode); -extern bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it); -extern char index_to_label(int i); -extern s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal); -extern s16b wield_slot(object_type const *o_ptr); -extern cptr describe_use(int i); -extern void display_inven(void); -extern void display_equip(void); -extern void show_inven_full(); -extern void show_equip_full(); -extern void toggle_inven_equip(void); -extern bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t()); -extern cptr item_activation(object_type *o_ptr,byte num); -extern void py_pickup_floor(int pickup); -extern void object_gain_level(object_type *o_ptr); -extern byte object_attr(object_type const *o_ptr); -extern byte object_attr_default(object_type *o_ptr); -extern char object_char(object_type const *o_ptr); -extern char object_char_default(object_type const *o_ptr); -extern bool artifact_p(object_type const *o_ptr); -extern bool ego_item_p(object_type const *o_ptr); -extern bool is_ego_p(object_type const *o_ptr, s16b ego); -extern bool cursed_p(object_type const *o_ptr); +object_flag_set object_flags(object_type const *o_ptr); +object_flag_set object_flags_known(object_type const *o_ptr); + +s32b calc_object_need_exp(object_type const *o_ptr); +void object_desc(char *buf, object_type const *o_ptr, int pref, int mode); +void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode); +bool_ object_out_desc(object_type *o_ptr, FILE *fff, bool_ trim_down, bool_ wait_for_it); +char index_to_label(int i); +s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal); +s16b wield_slot(object_type const *o_ptr); +cptr describe_use(int i); +void display_inven(); +void display_equip(); +void show_inven_full(); +void show_equip_full(); +void toggle_inven_equip(); +bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t()); +cptr item_activation(object_type *o_ptr); +void py_pickup_floor(int pickup); +void object_gain_level(object_type *o_ptr); +byte object_attr(object_type const *o_ptr); +byte object_attr_default(object_type *o_ptr); +char object_char(object_type const *o_ptr); +char object_char_default(object_type const *o_ptr); +bool artifact_p(object_type const *o_ptr); +bool ego_item_p(object_type const *o_ptr); +bool is_ego_p(object_type const *o_ptr, s16b ego); +bool cursed_p(object_type const *o_ptr); diff --git a/src/object2.cc b/src/object2.cc index 620037a3..2d6ea672 100644 --- a/src/object2.cc +++ b/src/object2.cc @@ -15,14 +15,20 @@ #include "spell_type.hpp" #include "device_allocation.hpp" #include "dungeon_info_type.hpp" +#include "ego_flag.hpp" #include "ego_item_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hooks.hpp" #include "mimic.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "object1.hpp" +#include "object_flag.hpp" +#include "object_flag_meta.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" @@ -34,7 +40,6 @@ #include "spells3.hpp" #include "spells5.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "variable.hpp" #include "wilderness_map.hpp" @@ -49,7 +54,7 @@ /* * Calculate the player's total inventory weight. */ -s32b calc_total_weight(void) +s32b calc_total_weight() { int i; s32b total; @@ -234,6 +239,8 @@ static void compact_objects_aux(int i1, int i2) */ void compact_objects(int size) { + auto const &k_info = game->edit_data.k_info; + int i, y, x, num; int cur_lev, cur_dis, chance; @@ -263,7 +270,7 @@ void compact_objects(int size) { object_type *o_ptr = &o_list[i]; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Skip dead objects */ if (!o_ptr->k_idx) continue; @@ -306,7 +313,7 @@ void compact_objects(int size) chance = chance - cur_lev / 2; /* Artifacts */ - if ( artifact_p(o_ptr) || o_ptr->art_name ) + if (artifact_p(o_ptr)) { /* Artifacts are "immune if the level is lower */ /* than 300 + artifact level */ @@ -314,7 +321,7 @@ void compact_objects(int size) continue; /* That's 400 + level for fixed artifacts */ - if ( (k_ptr->flags3 & TR3_NORM_ART) && cur_lev < 400 + k_ptr->level ) + if ( (k_ptr->flags & TR_NORM_ART) && cur_lev < 400 + k_ptr->level ) continue; /* Never protect if level is high enough; so we don't wipe a better artifact */ @@ -369,8 +376,11 @@ void compact_objects(int size) * clear those fields for grids/monsters containing objects, * and we clear it once for every such object. */ -void wipe_o_list(void) +void wipe_o_list() { + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + int i; /* Delete the existing objects */ @@ -382,7 +392,7 @@ void wipe_o_list(void) if (!o_ptr->k_idx) continue; /* Mega-Hack -- preserve artifacts */ - if (!character_dungeon || p_ptr->preserve) + if (!character_dungeon || options->preserve) { /* Hack -- Preserve unknown artifacts */ if (artifact_p(o_ptr) && !object_known_p(o_ptr)) @@ -390,9 +400,9 @@ void wipe_o_list(void) /* Mega-Hack -- Preserve the artifact */ if (o_ptr->tval == TV_RANDART) { - random_artifacts[o_ptr->sval].generated = FALSE; + game->random_artifacts[o_ptr->sval].generated = FALSE; } - else if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { k_info[o_ptr->k_idx].artifact = FALSE; } @@ -447,7 +457,7 @@ void wipe_o_list(void) * This routine should almost never fail, but in case it does, * we must be sure to handle "failure" of this routine. */ -s16b o_pop(void) +s16b o_pop() { int i; @@ -500,28 +510,25 @@ s16b o_pop(void) /* * Apply a "object restriction function" to the "object allocation table" */ -errr get_obj_num_prep(void) +errr get_obj_num_prep() { - int i; - - /* Get the entry */ - alloc_entry *table = alloc_kind_table; + auto &alloc = game->alloc; /* Scan the allocation table */ - for (i = 0; i < alloc_kind_size; i++) + for (auto &&entry: alloc.kind_table) { /* Accept objects which pass the restriction, if any */ - if (!get_obj_num_hook || (*get_obj_num_hook)(table[i].index)) + if (!get_obj_num_hook || (*get_obj_num_hook)(entry.index)) { /* Accept this object */ - table[i].prob2 = table[i].prob1; + entry.prob2 = entry.prob1; } /* Do not use this object */ else { /* Decline this object */ - table[i].prob2 = 0; + entry.prob2 = 0; } } @@ -548,11 +555,13 @@ errr get_obj_num_prep(void) */ s16b get_obj_num(int level) { - int i, j, p; + auto const &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; + + std::size_t i, j; + int p; int k_idx; long value, total; - object_kind *k_ptr; - alloc_entry *table = alloc_kind_table; /* Boost level */ @@ -571,51 +580,56 @@ s16b get_obj_num(int level) total = 0L; /* Process probabilities */ - for (i = 0; i < alloc_kind_size; i++) + for (i = 0; i < alloc.kind_table.size(); i++) { + auto &entry = alloc.kind_table[i]; + /* Objects are sorted by depth */ - if (table[i].level > level) break; + if (entry.level > level) break; /* Default */ - table[i].prob3 = 0; + entry.prob3 = 0; /* Access the index */ - k_idx = table[i].index; + k_idx = entry.index; /* Access the actual kind */ - k_ptr = &k_info[k_idx]; + auto k_ptr = &k_info[k_idx]; /* Hack -- prevent embedded chests */ if (opening_chest && (k_ptr->tval == TV_CHEST)) continue; /* Accept */ - table[i].prob3 = table[i].prob2; + entry.prob3 = entry.prob2; /* Total */ - total += table[i].prob3; + total += entry.prob3; } /* No legal objects */ if (total <= 0) return (0); - /* Pick an object */ value = rand_int(total); /* Find the object */ - for (i = 0; i < alloc_kind_size; i++) + for (i = 0; i < alloc.kind_table.size(); i++) { + auto &entry = alloc.kind_table[i]; + /* Found the entry */ - if (value < table[i].prob3) break; + if (value < entry.prob3) break; /* Decrement */ - value = value - table[i].prob3; + value = value - entry.prob3; } - /* Power boost */ p = rand_int(100); + /* Shorthand */ + auto &table = alloc.kind_table; + /* Try for a "better" object once (50%) or twice (10%) */ if (p < 60) { @@ -626,8 +640,9 @@ s16b get_obj_num(int level) value = rand_int(total); /* Find the monster */ - for (i = 0; i < alloc_kind_size; i++) + for (i = 0; i < table.size(); i++) { + /* Found the entry */ if (value < table[i].prob3) break; @@ -649,7 +664,7 @@ s16b get_obj_num(int level) value = rand_int(total); /* Find the object */ - for (i = 0; i < alloc_kind_size; i++) + for (i = 0; i < table.size(); i++) { /* Found the entry */ if (value < table[i].prob3) break; @@ -714,6 +729,8 @@ void object_known(object_type *o_ptr) */ bool object_known_p(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + return ((o_ptr->ident & (IDENT_KNOWN)) || (k_info[o_ptr->k_idx].easy_know && k_info[o_ptr->k_idx].aware)); } @@ -725,6 +742,8 @@ bool object_known_p(object_type const *o_ptr) */ void object_aware(object_type *o_ptr) { + auto &k_info = game->edit_data.k_info; + /* Fully aware of the effects */ k_info[o_ptr->k_idx].aware = TRUE; } @@ -734,6 +753,8 @@ void object_aware(object_type *o_ptr) */ bool object_aware_p(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + return k_info[o_ptr->k_idx].aware; } @@ -743,6 +764,8 @@ bool object_aware_p(object_type const *o_ptr) */ void object_tried(object_type *o_ptr) { + auto &k_info = game->edit_data.k_info; + /* Mark it as tried (even if "aware") */ k_info[o_ptr->k_idx].tried = TRUE; } @@ -753,6 +776,8 @@ void object_tried(object_type *o_ptr) */ bool object_tried_p(object_type const *o_ptr) { + auto const &k_info = game->edit_data.k_info; + return k_info[o_ptr->k_idx].tried; } @@ -763,7 +788,10 @@ bool object_tried_p(object_type const *o_ptr) */ static s32b object_value_base(object_type const *o_ptr) { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[o_ptr->k_idx]; /* Aware item -- use template cost */ if ((object_aware_p(o_ptr)) && (o_ptr->tval != TV_EGG)) return (k_ptr->cost); @@ -810,7 +838,7 @@ static s32b object_value_base(object_type const *o_ptr) /* Eggs */ case TV_EGG: { - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; /* Pay the monster level */ return (r_ptr->level * 100) + 100; @@ -825,139 +853,139 @@ static s32b object_value_base(object_type const *o_ptr) } /* Return the value of the flags the object has... */ -s32b flag_cost(object_type const * o_ptr, int plusses) +s32b flag_cost(object_type const *o_ptr, int plusses) { - s32b total = 0; - u32b f1, f2, f3, f4, f5, esp; + auto const flags = object_flags(o_ptr); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if (f5 & TR5_TEMPORARY) + if (flags & TR_TEMPORARY) { return 0; } - if (f4 & TR4_CURSE_NO_DROP) + + if (flags & TR_CURSE_NO_DROP) { return 0; } - if (f1 & TR1_STR) total += (1000 * plusses); - if (f1 & TR1_INT) total += (1000 * plusses); - if (f1 & TR1_WIS) total += (1000 * plusses); - if (f1 & TR1_DEX) total += (1000 * plusses); - if (f1 & TR1_CON) total += (1000 * plusses); - if (f1 & TR1_CHR) total += (250 * plusses); - if (f1 & TR1_CHAOTIC) total += 10000; - if (f1 & TR1_VAMPIRIC) total += 13000; - if (f1 & TR1_STEALTH) total += (250 * plusses); - if (f1 & TR1_SEARCH) total += (100 * plusses); - if (f1 & TR1_INFRA) total += (150 * plusses); - if (f1 & TR1_TUNNEL) total += (175 * plusses); - if ((f1 & TR1_SPEED) && (plusses > 0)) + + s32b total = 0; + + if (flags & TR_STR) total += (1000 * plusses); + if (flags & TR_INT) total += (1000 * plusses); + if (flags & TR_WIS) total += (1000 * plusses); + if (flags & TR_DEX) total += (1000 * plusses); + if (flags & TR_CON) total += (1000 * plusses); + if (flags & TR_CHR) total += (250 * plusses); + if (flags & TR_CHAOTIC) total += 10000; + if (flags & TR_VAMPIRIC) total += 13000; + if (flags & TR_STEALTH) total += (250 * plusses); + if (flags & TR_INFRA) total += (150 * plusses); + if (flags & TR_TUNNEL) total += (175 * plusses); + if ((flags & TR_SPEED) && (plusses > 0)) total += (10000 + (2500 * plusses)); - if ((f1 & TR1_BLOWS) && (plusses > 0)) + if ((flags & TR_BLOWS) && (plusses > 0)) total += (10000 + (2500 * plusses)); - if (f1 & TR1_MANA) total += (1000 * plusses); - if (f1 & TR1_SPELL) total += (2000 * plusses); - if (f1 & TR1_SLAY_ANIMAL) total += 3500; - if (f1 & TR1_SLAY_EVIL) total += 4500; - if (f1 & TR1_SLAY_UNDEAD) total += 3500; - if (f1 & TR1_SLAY_DEMON) total += 3500; - if (f1 & TR1_SLAY_ORC) total += 3000; - if (f1 & TR1_SLAY_TROLL) total += 3500; - if (f1 & TR1_SLAY_GIANT) total += 3500; - if (f1 & TR1_SLAY_DRAGON) total += 3500; - if (f5 & TR5_KILL_DEMON) total += 5500; - if (f5 & TR5_KILL_UNDEAD) total += 5500; - if (f1 & TR1_KILL_DRAGON) total += 5500; - if (f1 & TR1_VORPAL) total += 5000; - if (f1 & TR1_IMPACT) total += 5000; - if (f1 & TR1_BRAND_POIS) total += 7500; - if (f1 & TR1_BRAND_ACID) total += 7500; - if (f1 & TR1_BRAND_ELEC) total += 7500; - if (f1 & TR1_BRAND_FIRE) total += 5000; - if (f1 & TR1_BRAND_COLD) total += 5000; - if (f2 & TR2_SUST_STR) total += 850; - if (f2 & TR2_SUST_INT) total += 850; - if (f2 & TR2_SUST_WIS) total += 850; - if (f2 & TR2_SUST_DEX) total += 850; - if (f2 & TR2_SUST_CON) total += 850; - if (f2 & TR2_SUST_CHR) total += 250; - if (f2 & TR2_INVIS) total += 3000; - if (f2 & TR2_LIFE) total += (5000 * plusses); - if (f2 & TR2_IM_ACID) total += 10000; - if (f2 & TR2_IM_ELEC) total += 10000; - if (f2 & TR2_IM_FIRE) total += 10000; - if (f2 & TR2_IM_COLD) total += 10000; - if (f2 & TR2_SENS_FIRE) total -= 100; - if (f2 & TR2_REFLECT) total += 10000; - if (f2 & TR2_FREE_ACT) total += 4500; - if (f2 & TR2_HOLD_LIFE) total += 8500; - if (f2 & TR2_RES_ACID) total += 1250; - if (f2 & TR2_RES_ELEC) total += 1250; - if (f2 & TR2_RES_FIRE) total += 1250; - if (f2 & TR2_RES_COLD) total += 1250; - if (f2 & TR2_RES_POIS) total += 2500; - if (f2 & TR2_RES_FEAR) total += 2500; - if (f2 & TR2_RES_LITE) total += 1750; - if (f2 & TR2_RES_DARK) total += 1750; - if (f2 & TR2_RES_BLIND) total += 2000; - if (f2 & TR2_RES_CONF) total += 2000; - if (f2 & TR2_RES_SOUND) total += 2000; - if (f2 & TR2_RES_SHARDS) total += 2000; - if (f2 & TR2_RES_NETHER) total += 2000; - if (f2 & TR2_RES_NEXUS) total += 2000; - if (f2 & TR2_RES_CHAOS) total += 2000; - if (f2 & TR2_RES_DISEN) total += 10000; - if (f3 & TR3_SH_FIRE) total += 5000; - if (f3 & TR3_SH_ELEC) total += 5000; - if (f3 & TR3_DECAY) total += 0; - if (f3 & TR3_NO_TELE) total += 2500; - if (f3 & TR3_NO_MAGIC) total += 2500; - if (f3 & TR3_WRAITH) total += 250000; - if (f3 & TR3_TY_CURSE) total -= 15000; - if (f3 & TR3_EASY_KNOW) total += 0; - if (f3 & TR3_HIDE_TYPE) total += 0; - if (f3 & TR3_SHOW_MODS) total += 0; - if (f3 & TR3_INSTA_ART) total += 0; - if (f3 & TR3_LITE1) total += 750; - if (f4 & TR4_LITE2) total += 1250; - if (f4 & TR4_LITE3) total += 2750; - if (f3 & TR3_SEE_INVIS) total += 2000; - if (esp) total += (12500 * count_bits(esp)); - if (f3 & TR3_SLOW_DIGEST) total += 750; - if (f3 & TR3_REGEN) total += 2500; - if (f3 & TR3_XTRA_MIGHT) total += 2250; - if (f3 & TR3_XTRA_SHOTS) total += 10000; - if (f3 & TR3_IGNORE_ACID) total += 100; - if (f3 & TR3_IGNORE_ELEC) total += 100; - if (f3 & TR3_IGNORE_FIRE) total += 100; - if (f3 & TR3_IGNORE_COLD) total += 100; - if (f3 & TR3_ACTIVATE) total += 100; - if (f3 & TR3_DRAIN_EXP) total -= 12500; - if (f3 & TR3_TELEPORT) + if (flags & TR_MANA) total += (1000 * plusses); + if (flags & TR_SPELL) total += (2000 * plusses); + if (flags & TR_SLAY_ANIMAL) total += 3500; + if (flags & TR_SLAY_EVIL) total += 4500; + if (flags & TR_SLAY_UNDEAD) total += 3500; + if (flags & TR_SLAY_DEMON) total += 3500; + if (flags & TR_SLAY_ORC) total += 3000; + if (flags & TR_SLAY_TROLL) total += 3500; + if (flags & TR_SLAY_GIANT) total += 3500; + if (flags & TR_SLAY_DRAGON) total += 3500; + if (flags & TR_KILL_DEMON) total += 5500; + if (flags & TR_KILL_UNDEAD) total += 5500; + if (flags & TR_KILL_DRAGON) total += 5500; + if (flags & TR_VORPAL) total += 5000; + if (flags & TR_IMPACT) total += 5000; + if (flags & TR_BRAND_POIS) total += 7500; + if (flags & TR_BRAND_ACID) total += 7500; + if (flags & TR_BRAND_ELEC) total += 7500; + if (flags & TR_BRAND_FIRE) total += 5000; + if (flags & TR_BRAND_COLD) total += 5000; + if (flags & TR_SUST_STR) total += 850; + if (flags & TR_SUST_INT) total += 850; + if (flags & TR_SUST_WIS) total += 850; + if (flags & TR_SUST_DEX) total += 850; + if (flags & TR_SUST_CON) total += 850; + if (flags & TR_SUST_CHR) total += 250; + if (flags & TR_INVIS) total += 3000; + if (flags & TR_LIFE) total += (5000 * plusses); + if (flags & TR_IM_ACID) total += 10000; + if (flags & TR_IM_ELEC) total += 10000; + if (flags & TR_IM_FIRE) total += 10000; + if (flags & TR_IM_COLD) total += 10000; + if (flags & TR_SENS_FIRE) total -= 100; + if (flags & TR_REFLECT) total += 10000; + if (flags & TR_FREE_ACT) total += 4500; + if (flags & TR_HOLD_LIFE) total += 8500; + if (flags & TR_RES_ACID) total += 1250; + if (flags & TR_RES_ELEC) total += 1250; + if (flags & TR_RES_FIRE) total += 1250; + if (flags & TR_RES_COLD) total += 1250; + if (flags & TR_RES_POIS) total += 2500; + if (flags & TR_RES_FEAR) total += 2500; + if (flags & TR_RES_LITE) total += 1750; + if (flags & TR_RES_DARK) total += 1750; + if (flags & TR_RES_BLIND) total += 2000; + if (flags & TR_RES_CONF) total += 2000; + if (flags & TR_RES_SOUND) total += 2000; + if (flags & TR_RES_SHARDS) total += 2000; + if (flags & TR_RES_NETHER) total += 2000; + if (flags & TR_RES_NEXUS) total += 2000; + if (flags & TR_RES_CHAOS) total += 2000; + if (flags & TR_RES_DISEN) total += 10000; + if (flags & TR_SH_FIRE) total += 5000; + if (flags & TR_SH_ELEC) total += 5000; + if (flags & TR_DECAY) total += 0; + if (flags & TR_NO_TELE) total += 2500; + if (flags & TR_NO_MAGIC) total += 2500; + if (flags & TR_WRAITH) total += 250000; + if (flags & TR_TY_CURSE) total -= 15000; + if (flags & TR_EASY_KNOW) total += 0; + if (flags & TR_HIDE_TYPE) total += 0; + if (flags & TR_SHOW_MODS) total += 0; + if (flags & TR_INSTA_ART) total += 0; + if (flags & TR_LITE1) total += 750; + if (flags & TR_LITE2) total += 1250; + if (flags & TR_LITE3) total += 2750; + if (flags & TR_SEE_INVIS) total += 2000; + total += 12500 * ((flags & object_flags_esp()).count()); + if (flags & TR_SLOW_DIGEST) total += 750; + if (flags & TR_REGEN) total += 2500; + if (flags & TR_XTRA_MIGHT) total += 2250; + if (flags & TR_XTRA_SHOTS) total += 10000; + if (flags & TR_IGNORE_ACID) total += 100; + if (flags & TR_IGNORE_ELEC) total += 100; + if (flags & TR_IGNORE_FIRE) total += 100; + if (flags & TR_IGNORE_COLD) total += 100; + if (flags & TR_ACTIVATE) total += 100; + if (flags & TR_DRAIN_EXP) total -= 12500; + if (flags & TR_TELEPORT) { if (o_ptr->ident & IDENT_CURSED) total -= 7500; else total += 250; } - if (f3 & TR3_AGGRAVATE) total -= 10000; - if (f3 & TR3_BLESSED) total += 750; - if ((f3 & TR3_CURSED) && (o_ptr->ident & IDENT_CURSED)) total -= 5000; - if ((f3 & TR3_HEAVY_CURSE) && (o_ptr->ident & IDENT_CURSED)) total -= 12500; - if (f3 & TR3_PERMA_CURSE) total -= 15000; - if (f3 & TR3_FEATHER) total += 1250; - if (f4 & TR4_FLY) total += 10000; - if (f4 & TR4_NEVER_BLOW) total -= 15000; - if (f4 & TR4_PRECOGNITION) total += 250000; - if (f4 & TR4_BLACK_BREATH) total -= 12500; - if (f4 & TR4_DG_CURSE) total -= 25000; - if (f4 & TR4_CLONE) total -= 10000; - if (f4 & TR4_LEVELS) total += o_ptr->elevel * 2000; + if (flags & TR_AGGRAVATE) total -= 10000; + if (flags & TR_BLESSED) total += 750; + if ((flags & TR_CURSED) && (o_ptr->ident & IDENT_CURSED)) total -= 5000; + if ((flags & TR_HEAVY_CURSE) && (o_ptr->ident & IDENT_CURSED)) total -= 12500; + if (flags & TR_PERMA_CURSE) total -= 15000; + if (flags & TR_FEATHER) total += 1250; + if (flags & TR_FLY) total += 10000; + if (flags & TR_NEVER_BLOW) total -= 15000; + if (flags & TR_PRECOGNITION) total += 250000; + if (flags & TR_BLACK_BREATH) total -= 12500; + if (flags & TR_DG_CURSE) total -= 25000; + if (flags & TR_CLONE) total -= 10000; + if (flags & TR_LEVELS) total += o_ptr->elevel * 2000; /* Also, give some extra for activatable powers... */ - if ((o_ptr->art_name) && (o_ptr->art_flags3 & (TR3_ACTIVATE))) + if ((!o_ptr->artifact_name.empty()) && (o_ptr->art_flags & TR_ACTIVATE)) { int type = o_ptr->xtra2; @@ -1063,15 +1091,18 @@ s32b flag_cost(object_type const * o_ptr, int plusses) */ s32b object_value_real(object_type const *o_ptr) { - s32b value; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; - u32b f1, f2, f3, f4, f5, esp; + s32b value; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; if (o_ptr->tval == TV_RANDART) { - return random_artifacts[o_ptr->sval].cost; + return game->random_artifacts[o_ptr->sval].cost; } /* Hack -- "worthless" items */ @@ -1081,18 +1112,18 @@ s32b object_value_real(object_type const *o_ptr) value = k_ptr->cost; /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); - if (f5 & TR5_TEMPORARY) return (0L); + if (flags & TR_TEMPORARY) return (0L); - if (o_ptr->art_flags1 || o_ptr->art_flags2 || o_ptr->art_flags3) + if (o_ptr->art_flags) { value += flag_cost (o_ptr, o_ptr->pval); } /* Artifact */ else if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; /* Hack -- "worthless" artifacts */ if (!a_ptr->cost) return (0L); @@ -1104,7 +1135,7 @@ s32b object_value_real(object_type const *o_ptr) /* Ego-Item */ else if (o_ptr->name2) { - ego_item_type *e_ptr = &e_info[o_ptr->name2]; + auto e_ptr = &e_info[o_ptr->name2]; /* Hack -- "worthless" ego-items */ if (!e_ptr->cost) return (0L); @@ -1114,7 +1145,7 @@ s32b object_value_real(object_type const *o_ptr) if (o_ptr->name2b) { - ego_item_type *e_ptr = &e_info[o_ptr->name2b]; + auto e_ptr = &e_info[o_ptr->name2b]; /* Hack -- "worthless" ego-items */ if (!e_ptr->cost) return (0L); @@ -1125,7 +1156,7 @@ s32b object_value_real(object_type const *o_ptr) } /* Pay the spell */ - if (f5 & TR5_SPELL_CONTAIN) + if (flags & TR_SPELL_CONTAIN) { if (o_ptr->pval2 != -1) value += 5000 + 500 * spell_type_skill_level(spell_at(o_ptr->pval2)); @@ -1156,35 +1187,33 @@ s32b object_value_real(object_type const *o_ptr) case TV_AMULET: case TV_RING: case TV_MSTAFF: - case TV_TRAPKIT: case TV_INSTRUMENT: { /* No pval */ if (!o_ptr->pval) break; /* Give credit for stat bonuses */ - if (f1 & (TR1_STR)) value += (o_ptr->pval * 200L); - if (f1 & (TR1_INT)) value += (o_ptr->pval * 200L); - if (f1 & (TR1_WIS)) value += (o_ptr->pval * 200L); - if (f1 & (TR1_DEX)) value += (o_ptr->pval * 200L); - if (f1 & (TR1_CON)) value += (o_ptr->pval * 200L); - if (f1 & (TR1_CHR)) value += (o_ptr->pval * 200L); + if (flags & TR_STR) value += (o_ptr->pval * 200L); + if (flags & TR_INT) value += (o_ptr->pval * 200L); + if (flags & TR_WIS) value += (o_ptr->pval * 200L); + if (flags & TR_DEX) value += (o_ptr->pval * 200L); + if (flags & TR_CON) value += (o_ptr->pval * 200L); + if (flags & TR_CHR) value += (o_ptr->pval * 200L); - if (f5 & (TR5_CRIT)) value += (o_ptr->pval * 500L); + if (flags & TR_CRIT) value += (o_ptr->pval * 500L); /* Give credit for stealth and searching */ - if (f1 & (TR1_STEALTH)) value += (o_ptr->pval * 100L); - if (f1 & (TR1_SEARCH)) value += (o_ptr->pval * 100L); + if (flags & TR_STEALTH) value += (o_ptr->pval * 100L); /* Give credit for infra-vision and tunneling */ - if (f1 & (TR1_INFRA)) value += (o_ptr->pval * 50L); - if (f1 & (TR1_TUNNEL)) value += (o_ptr->pval * 50L); + if (flags & TR_INFRA) value += (o_ptr->pval * 50L); + if (flags & TR_TUNNEL) value += (o_ptr->pval * 50L); /* Give credit for extra attacks */ - if (f1 & (TR1_BLOWS)) value += (o_ptr->pval * 2000L); + if (flags & TR_BLOWS) value += (o_ptr->pval * 2000L); /* Give credit for speed bonus */ - if (f1 & (TR1_SPEED)) value += (o_ptr->pval * 30000L); + if (flags & TR_SPEED) value += (o_ptr->pval * 30000L); break; } @@ -1197,7 +1226,7 @@ s32b object_value_real(object_type const *o_ptr) /* Eggs */ case TV_EGG: { - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; /* Pay the monster level */ value += r_ptr->level * 100; @@ -1316,7 +1345,6 @@ s32b object_value_real(object_type const *o_ptr) case TV_DAEMON_BOOK: case TV_AXE: case TV_POLEARM: - case TV_TRAPKIT: { /* Hack -- negative hit/damage bonuses */ if (o_ptr->to_h + o_ptr->to_d < 0 && !value) return (0L); @@ -1434,17 +1462,15 @@ s32b object_value(object_type const *o_ptr) bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) { int total = o_ptr->number + j_ptr->number; - u32b f1, f2, f3, f4, f5, esp, f11, f12, f13, f14, esp1, f15; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - object_flags(j_ptr, &f11, &f12, &f13, &f14, &f15, &esp1); - + auto const o_flags = object_flags(o_ptr); + auto const j_flags = object_flags(j_ptr); /* Require identical object types */ if (o_ptr->k_idx != j_ptr->k_idx) return (0); - if ((f5 & TR5_SPELL_CONTAIN) || (f15 & TR5_SPELL_CONTAIN)) + if ((o_flags & TR_SPELL_CONTAIN) || (j_flags & TR_SPELL_CONTAIN)) return FALSE; /* Analyze the items */ @@ -1483,17 +1509,6 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) return FALSE; } - case TV_RUNE1: - { - return TRUE; - } - - case TV_RUNE2: - { - if ((o_ptr->sval == RUNE_STONE) || (j_ptr->sval == RUNE_STONE)) return FALSE; - else return TRUE; - } - case TV_INSTRUMENT: { return FALSE; @@ -1548,7 +1563,7 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) if (o_ptr->pval != j_ptr->pval) return (0); /* Do not combine recharged ones with non recharged ones. */ - if ((f4 & TR4_RECHARGED) != (f14 & TR4_RECHARGED)) return (0); + if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (0); /* Do not combine different spells */ if (o_ptr->pval2 != j_ptr->pval2) return (0); @@ -1583,7 +1598,7 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) if (o_ptr->name1 != j_ptr->name1) return (0); /* Do not combine recharged ones with non recharged ones. */ - if ((f4 & TR4_RECHARGED) != (f14 & TR4_RECHARGED)) return (0); + if ((o_flags & TR_RECHARGED) != (j_flags & TR_RECHARGED)) return (0); /* Do not combine different spells */ if (o_ptr->pval2 != j_ptr->pval2) return (0); @@ -1633,7 +1648,6 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR: - case TV_TRAPKIT: case TV_DAEMON_BOOK: { /* Fall through */ @@ -1723,16 +1737,19 @@ bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr) /* Hack -- Identical art_flags! */ - if ((o_ptr->art_flags1 != j_ptr->art_flags1) || - (o_ptr->art_flags2 != j_ptr->art_flags2) || - (o_ptr->art_flags3 != j_ptr->art_flags3)) + if (o_ptr->art_flags != j_ptr->art_flags) + { return (0); + } /* Hack -- Require identical "cursed" status */ if ((o_ptr->ident & (IDENT_CURSED)) != (j_ptr->ident & (IDENT_CURSED))) return (0); /* Hack -- require semi-matching "inscriptions" */ - if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)) return (0); + if ((!o_ptr->inscription.empty()) && (!j_ptr->inscription.empty()) && (o_ptr->inscription != j_ptr->inscription)) + { + return (0); + } /* Maximal "stacking" limit */ if (total >= MAX_STACK_SIZE) return (0); @@ -1768,7 +1785,10 @@ void object_absorb(object_type *o_ptr, object_type *j_ptr) if (j_ptr->ident & (IDENT_MENTAL)) o_ptr->ident |= (IDENT_MENTAL); /* Hack -- blend "inscriptions" */ - if (j_ptr->note) o_ptr->note = j_ptr->note; + if (!j_ptr->inscription.empty()) + { + o_ptr->inscription = j_ptr->inscription; + } /* Hack -- could average discounts XXX XXX XXX */ /* Hack -- save largest discount XXX XXX XXX */ @@ -1788,22 +1808,22 @@ void object_absorb(object_type *o_ptr, object_type *j_ptr) */ s16b lookup_kind(int tval, int sval) { - int k; + auto const &k_info = game->edit_data.k_info; - /* Look for it */ - for (k = 1; k < max_k_idx; k++) + for (std::size_t k = 1; k < k_info.size(); k++) { - object_kind *k_ptr = &k_info[k]; - - /* Found a match */ - if ((k_ptr->tval == tval) && (k_ptr->sval == sval)) return (k); + auto k_ptr = &k_info[k]; + if ((k_ptr->tval == tval) && (k_ptr->sval == sval)) + { + return k; + } } /* Oops */ if (wizard) msg_format("No object (%d,%d)", tval, sval); /* Oops */ - return (0); + return 0; } @@ -1813,8 +1833,7 @@ s16b lookup_kind(int tval, int sval) void object_wipe(object_type *o_ptr) { /* Wipe the structure */ - static_assert(std::is_pod<object_type>::value, "object_type must be POD type for memset to work"); - memset(o_ptr, 0, sizeof(object_type)); + *o_ptr = object_type(); } @@ -1829,11 +1848,24 @@ void object_copy(object_type *o_ptr, object_type *j_ptr) /* + * Initialize the experience of an object which is a + * "sentient" object. + */ +static void init_obj_exp(object_type *o_ptr, object_kind const *k_ptr) +{ + o_ptr->elevel = (k_ptr->level / 10) + 1; + o_ptr->exp = player_exp[o_ptr->elevel - 1]; +} + + +/* * Prepare an object based on an object kind. */ void object_prep(object_type *o_ptr, int k_idx) { - object_kind *k_ptr = &k_info[k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[k_idx]; /* Clear the record */ object_wipe(o_ptr); @@ -1866,13 +1898,15 @@ void object_prep(object_type *o_ptr, int k_idx) o_ptr->ds = k_ptr->ds; /* Hack -- cursed items are always "cursed" */ - if (k_ptr->flags3 & (TR3_CURSED)) o_ptr->ident |= (IDENT_CURSED); + if (k_ptr->flags & TR_CURSED) + { + o_ptr->ident |= (IDENT_CURSED); + } /* Hack give a basic exp/exp level to an object that needs it */ - if (k_ptr->flags4 & TR4_LEVELS) + if (k_ptr->flags & TR_LEVELS) { - o_ptr->elevel = (k_ptr->level / 10) + 1; - o_ptr->exp = player_exp[o_ptr->elevel - 1]; + init_obj_exp(o_ptr, k_ptr); o_ptr->pval2 = 1; /* Start with one point */ o_ptr->pval3 = 0; /* No flags groups */ } @@ -1968,24 +2002,21 @@ s16b m_bonus(int max, int level) */ static void finalize_randart(object_type* o_ptr, int lev) { - int r; - int i = 0; - int foo = lev + randnor(0, 5); - bool_ flag = TRUE; + auto &random_artifacts = game->random_artifacts; /* Paranoia */ - if (o_ptr->tval != TV_RANDART) return; - - if (foo < 1) foo = 1; - if (foo > 100) foo = 100; + if (o_ptr->tval != TV_RANDART) + { + return; + } - while (flag) + for (int i = 0; ; i++) { - r = rand_int(MAX_RANDARTS); + auto const r = rand_int(MAX_RANDARTS); if (!(random_artifacts[r].generated) || i > 2000) { - random_artifact* ra_ptr = &random_artifacts[r]; + auto ra_ptr = &random_artifacts[r]; o_ptr->sval = r; o_ptr->pval2 = ra_ptr->activation; @@ -1993,10 +2024,8 @@ static void finalize_randart(object_type* o_ptr, int lev) ra_ptr->level = lev; ra_ptr->generated = TRUE; - flag = FALSE; + return; } - - i++; } } @@ -2020,7 +2049,7 @@ static void object_mention(object_type *o_ptr) } /* Random Artifact */ - else if (o_ptr->art_name) + else if (!o_ptr->artifact_name.empty()) { msg_print("Random artifact"); } @@ -2040,86 +2069,106 @@ static void object_mention(object_type *o_ptr) } } - -void random_artifact_resistance(object_type * o_ptr) +static void random_artifact_power(object_type *o_ptr) { - bool_ give_resistance = FALSE, give_power = FALSE; - - switch (o_ptr->name1) - { - case ART_CELEBORN: - case ART_ARVEDUI: - case ART_CASPANION: - case ART_TRON: - case ART_ROHIRRIM: - case ART_CELEGORM: - case ART_ANARION: - case ART_THRANDUIL: - case ART_LUTHIEN: - case ART_THROR: - case ART_THORIN: - case ART_NIMTHANC: - case ART_DETHANC: - case ART_NARTHANC: - case ART_STING: - case ART_TURMIL: - case ART_THALKETTOTH: - { - /* Give a resistance */ - give_resistance = TRUE; + // Shorthand + auto flags = &o_ptr->art_flags; + + // Choose ability + auto try_choose = [&o_ptr, &flags](int choice) { + switch (choice) + { + case 0: + (*flags) |= (TR_FEATHER); + break; + case 1: + (*flags) |= (TR_LITE1); + break; + case 2: + (*flags) |= (TR_SEE_INVIS); + break; + case 3: + (*flags) |= (ESP_ALL); + break; + case 4: + (*flags) |= (TR_SLOW_DIGEST); + break; + case 5: + (*flags) |= (TR_REGEN); + break; + case 6: + (*flags) |= (TR_FREE_ACT); + break; + case 7: + (*flags) |= (TR_HOLD_LIFE); + break; } - break; - case ART_MAEDHROS: - case ART_GLAMDRING: - case ART_ORCRIST: - case ART_ANDURIL: - case ART_ZARCUTHRA: - case ART_GURTHANG: - case ART_HARADEKKET: - case ART_CUBRAGOL: - case ART_DAWN: - { - /* Give a resistance OR a power */ - if (randint(2) == 1) give_resistance = TRUE; - else give_power = TRUE; + }; + + // Save old values for comparison + auto const old_flags = *flags; + + // Choose an ability; make sure we choose one that isn't already chosen + for (int tries = 0; tries < 1000; tries++) + { + // Tentative choice + int choice = rand_int(8); + try_choose(choice); + + // If there's any difference, then we've chosen a non-overlapping power. + if (*flags != old_flags) + { + break; } - break; - case ART_NENYA: - case ART_VILYA: - case ART_BERUTHIEL: - case ART_FINGOLFIN: - case ART_THINGOL: - case ART_ULMO: - case ART_OLORIN: + } +} + +void random_artifact_resistance(object_type * o_ptr) +{ + auto const &a_info = game->edit_data.a_info; + + auto const art_flags = a_info[o_ptr->name1].flags; + + // Check flags of the 'protype' artifact + auto give_resistance = bool(art_flags & TR_RANDOM_RESIST); + auto give_power = bool(art_flags & TR_RANDOM_POWER); + if (art_flags & TR_RANDOM_RES_OR_POWER) + { + if (randint(2) == 1) { - /* Give a power */ - give_power = TRUE; + give_resistance = true; } - break; - case ART_POWER: - case ART_GONDOR: - case ART_AULE: + else { - /* Give both */ - give_power = TRUE; - give_resistance = TRUE; + give_power = true; } - break; } + // Grant a power? if (give_power) { - o_ptr->xtra1 = EGO_XTRA_ABILITY; - - /* Randomize the "xtra" power */ - if (o_ptr->xtra1) o_ptr->xtra2 = randint(256); + random_artifact_power(o_ptr); } artifact_bias = 0; if (give_resistance) { - random_resistance(o_ptr, FALSE, ((randint(22)) + 16)); + // Save the *combined* pre-existing flags on the object; + // including any power we may have granted above. + auto const flags_before = art_flags | o_ptr->art_flags; + + // We'll be a little generous here and make sure that the object + // gets a resistance that it doesn't actually already have. + for (int tries = 0; tries < 1000; tries++) + { + random_resistance(o_ptr, randint(22) + 16); + // Picked up new resistance? + if (flags_before != (art_flags | o_ptr->art_flags)) + { + break; + } + } } } @@ -2134,17 +2183,16 @@ void random_artifact_resistance(object_type * o_ptr) */ static bool_ make_artifact_special(object_type *o_ptr) { - int i; - int k_idx = 0; - u32b f1, f2, f3, f4, f5, esp; + auto const &k_info = game->edit_data.k_info; + auto const &a_info = game->edit_data.a_info; /* No artifacts in the town */ if (!dun_level) return (FALSE); /* Check the artifact list (just the "specials") */ - for (i = 0; i < max_a_idx; i++) + for (std::size_t i = 0; i < a_info.size(); i++) { - artifact_type *a_ptr = &a_info[i]; + auto a_ptr = &a_info[i]; /* Skip "empty" artifacts */ if (!a_ptr->name) continue; @@ -2153,10 +2201,10 @@ static bool_ make_artifact_special(object_type *o_ptr) if (a_ptr->cur_num) continue; /* Cannot generate non special ones */ - if (!(a_ptr->flags3 & TR3_INSTA_ART)) continue; + if (!(a_ptr->flags & TR_INSTA_ART)) continue; /* Cannot generate some artifacts because they can only exists in special dungeons/quests/... */ - if ((a_ptr->flags4 & TR4_SPECIAL_GENE) && (!a_allow_special[i])) continue; + if ((a_ptr->flags & TR_SPECIAL_GENE) && (!a_allow_special[i])) continue; /* XXX XXX Enforce minimum "depth" (loosely) */ if (a_ptr->level > dun_level) @@ -2172,7 +2220,7 @@ static bool_ make_artifact_special(object_type *o_ptr) if (rand_int(a_ptr->rarity - luck( -(a_ptr->rarity / 2), a_ptr->rarity / 2)) != 0) continue; /* Find the base object */ - k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); + int k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); /* XXX XXX Enforce minimum "object" level (loosely) */ if (k_info[k_idx].level > object_level) @@ -2191,13 +2239,12 @@ static bool_ make_artifact_special(object_type *o_ptr) o_ptr->name1 = i; /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack give a basic exp/exp level to an object that needs it */ - if (f4 & TR4_LEVELS) + if (flags & TR_LEVELS) { - o_ptr->elevel = (k_info[k_idx].level / 10) + 1; - o_ptr->exp = player_exp[o_ptr->elevel - 1]; + init_obj_exp(o_ptr, &k_info[k_idx]); } /* Success */ @@ -2218,9 +2265,8 @@ static bool_ make_artifact_special(object_type *o_ptr) */ static bool_ make_artifact(object_type *o_ptr) { - int i; - u32b f1, f2, f3, f4, f5, esp; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto const &a_info = game->edit_data.a_info; + auto const &k_info = game->edit_data.k_info; /* No artifacts in the town */ if (!dun_level) return (FALSE); @@ -2229,9 +2275,9 @@ static bool_ make_artifact(object_type *o_ptr) if (o_ptr->number != 1) return (FALSE); /* Check the artifact list (skip the "specials") */ - for (i = 0; i < max_a_idx; i++) + for (std::size_t i = 0; i < a_info.size(); i++) { - artifact_type *a_ptr = &a_info[i]; + auto a_ptr = &a_info[i]; /* Skip "empty" items */ if (!a_ptr->name) continue; @@ -2240,10 +2286,10 @@ static bool_ make_artifact(object_type *o_ptr) if (a_ptr->cur_num) continue; /* Cannot generate special ones */ - if (a_ptr->flags3 & TR3_INSTA_ART) continue; + if (a_ptr->flags & TR_INSTA_ART) continue; /* Cannot generate some artifacts because they can only exists in special dungeons/quests/... */ - if ((a_ptr->flags4 & TR4_SPECIAL_GENE) && (!a_allow_special[i])) continue; + if ((a_ptr->flags & TR_SPECIAL_GENE) && (!a_allow_special[i])) continue; /* Must have the correct fields */ if (a_ptr->tval != o_ptr->tval) continue; @@ -2269,13 +2315,12 @@ static bool_ make_artifact(object_type *o_ptr) random_artifact_resistance(o_ptr); /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack give a basic exp/exp level to an object that needs it */ - if (f4 & TR4_LEVELS) + if (flags & TR_LEVELS) { - o_ptr->elevel = (k_ptr->level / 10) + 1; - o_ptr->exp = player_exp[o_ptr->elevel - 1]; + init_obj_exp(o_ptr, &k_info[o_ptr->k_idx]); } /* Success */ @@ -2293,17 +2338,20 @@ static bool_ make_artifact(object_type *o_ptr) */ static bool_ make_ego_item(object_type *o_ptr, bool_ good) { + auto const &k_info = game->edit_data.k_info; + auto const &e_info = game->edit_data.e_info; + bool_ ret = FALSE; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; if (artifact_p(o_ptr) || o_ptr->name2) return (FALSE); std::vector<size_t> ok_ego; /* Grab the ok ego */ - for (size_t i = 0; i < max_e_idx; i++) + for (size_t i = 0; i < e_info.size(); i++) { - ego_item_type *e_ptr = &e_info[i]; + auto e_ptr = &e_info[i]; bool_ ok = FALSE; /* Skip "empty" items */ @@ -2330,19 +2378,9 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good) if ((!good) && e_ptr->cost) continue; /* Must posses the good flags */ - if (((k_ptr->flags1 & e_ptr->need_flags1) != e_ptr->need_flags1) || - ((k_ptr->flags2 & e_ptr->need_flags2) != e_ptr->need_flags2) || - ((k_ptr->flags3 & e_ptr->need_flags3) != e_ptr->need_flags3) || - ((k_ptr->flags4 & e_ptr->need_flags4) != e_ptr->need_flags4) || - ((k_ptr->flags5 & e_ptr->need_flags5) != e_ptr->need_flags5) || - ((k_ptr->esp & e_ptr->need_esp) != e_ptr->need_esp)) + if ((k_ptr->flags & e_ptr->need_flags) != e_ptr->need_flags) continue; - if ((k_ptr->flags1 & e_ptr->forbid_flags1) || - (k_ptr->flags2 & e_ptr->forbid_flags2) || - (k_ptr->flags3 & e_ptr->forbid_flags3) || - (k_ptr->flags4 & e_ptr->forbid_flags4) || - (k_ptr->flags5 & e_ptr->forbid_flags5) || - (k_ptr->esp & e_ptr->forbid_esp)) + if (k_ptr->flags & e_ptr->forbid_flags) continue; /* ok */ @@ -2353,7 +2391,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good) for (size_t i = 0; i < ok_ego.size() * 10; i++) { size_t j = ok_ego[rand_int(ok_ego.size())]; - ego_item_type *e_ptr = &e_info[j]; + auto e_ptr = &e_info[j]; /* XXX XXX Enforce minimum "depth" (loosely) */ if (e_ptr->level > dun_level) @@ -2392,7 +2430,7 @@ static bool_ make_ego_item(object_type *o_ptr, bool_ good) for (size_t i = 0; i < ok_ego.size() * 10; i++) { int j = ok_ego[rand_int(ok_ego.size())]; // Explicit int conversion to avoid warning - ego_item_type *e_ptr = &e_info[j]; + auto e_ptr = &e_info[j]; /* Cannot be a double ego of the same ego type */ if (j == o_ptr->name2) continue; @@ -2464,7 +2502,7 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power) if (power > 1) { /* Make ego item */ - if ((rand_int(RANDART_WEAPON) == 1) && (o_ptr->tval != TV_TRAPKIT)) create_artifact(o_ptr, FALSE, TRUE); + if (rand_int(RANDART_WEAPON) == 1) create_artifact(o_ptr, FALSE, TRUE); else make_ego_item(o_ptr, TRUE); } else if (power < -1) @@ -2511,45 +2549,9 @@ static void a_m_aux_1(object_type *o_ptr, int level, int power) /* Some special cases */ switch (o_ptr->tval) { - case TV_TRAPKIT: - { - /* Good */ - if (power > 0) o_ptr->to_a += randint(5); - - /* Very good */ - if (power > 1) o_ptr->to_a += randint(5); - - /* Bad */ - if (power < 0) o_ptr->to_a -= randint(5); - - /* Very bad */ - if (power < -1) o_ptr->to_a -= randint(5); - - break; - } case TV_MSTAFF: { - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - int gf[2], i; - - for (i = 0; i < 2; i++) - { - int k = 0; - - gf[i] = 0; - while (!k) - { - k = lookup_kind(TV_RUNE1, (gf[i] = rand_int(MAX_GF))); - } - } - - o_ptr->pval = gf[0] + (gf[1] << 16); - o_ptr->pval3 = rand_int(RUNE_MOD_MAX) + (rand_int(RUNE_MOD_MAX) << 16); - o_ptr->pval2 = randint(70) + (randint(70) << 8); - } - else - o_ptr->art_flags5 |= (TR5_SPELL_CONTAIN | TR5_WIELD_CAST); + o_ptr->art_flags |= (TR_SPELL_CONTAIN | TR_WIELD_CAST); break; } case TV_BOLT: @@ -2587,9 +2589,9 @@ static void dragon_resist(object_type * o_ptr) artifact_bias = 0; if (randint(4) == 1) - random_resistance(o_ptr, FALSE, ((randint(14)) + 4)); + random_resistance(o_ptr, randint(14) + 4); else - random_resistance(o_ptr, FALSE, ((randint(22)) + 16)); + random_resistance(o_ptr, randint(22) + 16); } while (randint(2) == 1); } @@ -2659,7 +2661,9 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power) case TV_CLOAK: { if (o_ptr->sval == SV_ELVEN_CLOAK) + { o_ptr->pval = randint(4); /* No cursed elven cloaks...? */ + } else if (o_ptr->sval == SV_MIMIC_CLOAK) { s32b mimic = find_random_mimic_shape(level, TRUE); @@ -2673,7 +2677,10 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power) rating += 30; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } break; } @@ -2685,7 +2692,10 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power) rating += 5; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } dragon_resist(o_ptr); } break; @@ -2698,7 +2708,10 @@ static void a_m_aux_2(object_type *o_ptr, int level, int power) rating += 5; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } dragon_resist(o_ptr); } break; @@ -2829,7 +2842,10 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) rating += 25; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } break; } @@ -2838,7 +2854,7 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) { do { - random_resistance(o_ptr, FALSE, ((randint(20)) + 18)); + random_resistance(o_ptr, randint(20) + 18); } while (randint(4) == 1); @@ -2848,25 +2864,6 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) } break; - /* Searching */ - case SV_RING_SEARCHING: - { - /* Bonus to searching */ - o_ptr->pval = 1 + m_bonus(5, level); - - /* Cursed */ - if (power < 0) - { - /* Cursed */ - o_ptr->ident |= (IDENT_CURSED); - - /* Reverse pval */ - o_ptr->pval = 0 - (o_ptr->pval); - } - - break; - } - /* Flames, Acid, Ice */ case SV_RING_FLAMES: case SV_RING_ACID: @@ -2997,7 +2994,10 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) o_ptr->pval = 1 + m_bonus(3, level); /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } break; } @@ -3009,7 +3009,10 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) o_ptr->to_d = 1 + m_bonus(5, level); /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } break; } @@ -3065,41 +3068,26 @@ static void a_m_aux_3(object_type *o_ptr, int level, int power) case SV_AMULET_RESISTANCE: { - if (randint(3) == 1) random_resistance(o_ptr, FALSE, ((randint(34)) + 4)); - if (randint(5) == 1) o_ptr->art_flags2 |= TR2_RES_POIS; + if (randint(3) == 1) random_resistance(o_ptr, randint(34) + 4); + if (randint(5) == 1) o_ptr->art_flags |= TR_RES_POIS; } break; - /* Amulet of searching */ - case SV_AMULET_SEARCHING: - { - o_ptr->pval = randint(5) + m_bonus(5, level); - - /* Cursed */ - if (power < 0) - { - /* Cursed */ - o_ptr->ident |= (IDENT_CURSED); - - /* Reverse bonuses */ - o_ptr->pval = 0 - (o_ptr->pval); - } - - break; - } - /* Amulet of the Magi -- never cursed */ case SV_AMULET_THE_MAGI: { o_ptr->pval = 1 + m_bonus(3, level); - if (randint(3) == 1) o_ptr->art_flags3 |= TR3_SLOW_DIGEST; + if (randint(3) == 1) o_ptr->art_flags |= TR_SLOW_DIGEST; /* Boost the rating */ rating += 25; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } break; } @@ -3174,9 +3162,11 @@ static int get_stick_max_level(byte tval, int level, int spl) */ static void a_m_aux_4(object_type *o_ptr, int level, int power) { - u32b f1, f2, f3, f4, f5, esp; + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + s32b bonus_lvl, max_lvl; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Very good */ if (power > 1) @@ -3223,12 +3213,15 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) case TV_LITE: { - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack -- random fuel */ - if (f4 & TR4_FUEL_LITE) + if (flags & TR_FUEL_LITE) { - if (k_info[o_ptr->k_idx].pval2 > 0) o_ptr->timeout = randint(k_info[o_ptr->k_idx].pval2); + if (k_info[o_ptr->k_idx].pval2 > 0) + { + o_ptr->timeout = randint(k_info[o_ptr->k_idx].pval2); + } } break; @@ -3237,14 +3230,18 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) case TV_CORPSE: { /* Hack -- choose a monster */ - monster_race* r_ptr; int r_idx = get_mon_num(dun_level); - r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; - if (!(r_ptr->flags1 & RF1_UNIQUE)) + if (!(r_ptr->flags & RF_UNIQUE)) + { o_ptr->pval2 = r_idx; + } else + { o_ptr->pval2 = 2; + } + o_ptr->pval3 = 0; break; } @@ -3252,25 +3249,28 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) case TV_EGG: { /* Hack -- choose a monster */ - monster_race* r_ptr; int r_idx, count = 0; bool_ OK = FALSE; while ((!OK) && (count < 1000)) { r_idx = get_mon_num(dun_level); - r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; - if (r_ptr->flags9 & RF9_HAS_EGG) + if (r_ptr->flags & RF_HAS_EGG) { o_ptr->pval2 = r_idx; OK = TRUE; } count++; } - if (count == 1000) o_ptr->pval2 = 940; /* Blue fire-lizard */ - r_ptr = &r_info[o_ptr->pval2]; + if (count == 1000) + { + o_ptr->pval2 = 940; /* Blue fire-lizard */ + } + + auto r_ptr = &r_info[o_ptr->pval2]; o_ptr->weight = (r_ptr->weight + rand_int(r_ptr->weight) / 100) + 1; o_ptr->pval = r_ptr->weight * 3 + rand_int(r_ptr->weight) + 1; break; @@ -3279,11 +3279,10 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) case TV_HYPNOS: { /* Hack -- choose a monster */ - monster_race* r_ptr; int r_idx = get_mon_num(dun_level); - r_ptr = &r_info[r_idx]; + auto r_ptr = &r_info[r_idx]; - if (!(r_ptr->flags1 & RF1_NEVER_MOVE)) + if (!(r_ptr->flags & RF_NEVER_MOVE)) o_ptr->pval = r_idx; else o_ptr->pval = 20; @@ -3364,9 +3363,6 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) /* Hack -- skip ruined chests */ if (k_info[o_ptr->k_idx].level <= 0) break; - /* Pick a trap */ - place_trap_object(o_ptr); - /* Hack - set pval2 to the number of objects in it */ if (o_ptr->pval) o_ptr->pval2 = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2; @@ -3378,7 +3374,10 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) /* Rating boost */ rating += 25; /* Mention the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } } break; case TV_POTION2: @@ -3426,153 +3425,137 @@ static void a_m_aux_4(object_type *o_ptr, int level, int power) } } -void trap_hack(object_type *o_ptr) -{ - if (o_ptr->tval != TV_TRAPKIT) return; - - switch (o_ptr->sval) - { - case SV_TRAPKIT_POTION: - case SV_TRAPKIT_SCROLL: - case SV_TRAPKIT_DEVICE: - o_ptr->to_h = 0; - o_ptr->to_d = 0; - default: - return; - } -} - /* Add a random glag to the ego item */ -void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows) +void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool_ *limit_blows) { - if (fego & ETR4_SUSTAIN) + if (fego & ETR_SUSTAIN) { /* Make a random sustain */ switch (randint(6)) { case 1: - o_ptr->art_flags2 |= TR2_SUST_STR; + o_ptr->art_flags |= TR_SUST_STR; break; case 2: - o_ptr->art_flags2 |= TR2_SUST_INT; + o_ptr->art_flags |= TR_SUST_INT; break; case 3: - o_ptr->art_flags2 |= TR2_SUST_WIS; + o_ptr->art_flags |= TR_SUST_WIS; break; case 4: - o_ptr->art_flags2 |= TR2_SUST_DEX; + o_ptr->art_flags |= TR_SUST_DEX; break; case 5: - o_ptr->art_flags2 |= TR2_SUST_CON; + o_ptr->art_flags |= TR_SUST_CON; break; case 6: - o_ptr->art_flags2 |= TR2_SUST_CHR; + o_ptr->art_flags |= TR_SUST_CHR; break; } } - if (fego & ETR4_OLD_RESIST) + if (fego & ETR_OLD_RESIST) { /* Make a random resist, equal probabilities */ switch (randint(11)) { case 1: - o_ptr->art_flags2 |= (TR2_RES_BLIND); + o_ptr->art_flags |= TR_RES_BLIND; break; case 2: - o_ptr->art_flags2 |= (TR2_RES_CONF); + o_ptr->art_flags |= TR_RES_CONF; break; case 3: - o_ptr->art_flags2 |= (TR2_RES_SOUND); + o_ptr->art_flags |= TR_RES_SOUND; break; case 4: - o_ptr->art_flags2 |= (TR2_RES_SHARDS); + o_ptr->art_flags |= TR_RES_SHARDS; break; case 5: - o_ptr->art_flags2 |= (TR2_RES_NETHER); + o_ptr->art_flags |= TR_RES_NETHER; break; case 6: - o_ptr->art_flags2 |= (TR2_RES_NEXUS); + o_ptr->art_flags |= TR_RES_NEXUS; break; case 7: - o_ptr->art_flags2 |= (TR2_RES_CHAOS); + o_ptr->art_flags |= TR_RES_CHAOS; break; case 8: - o_ptr->art_flags2 |= (TR2_RES_DISEN); + o_ptr->art_flags |= TR_RES_DISEN; break; case 9: - o_ptr->art_flags2 |= (TR2_RES_POIS); + o_ptr->art_flags |= TR_RES_POIS; break; case 10: - o_ptr->art_flags2 |= (TR2_RES_DARK); + o_ptr->art_flags |= TR_RES_DARK; break; case 11: - o_ptr->art_flags2 |= (TR2_RES_LITE); + o_ptr->art_flags |= TR_RES_LITE; break; } } - if (fego & ETR4_ABILITY) + if (fego & ETR_ABILITY) { /* Choose an ability */ switch (randint(8)) { case 1: - o_ptr->art_flags3 |= (TR3_FEATHER); + o_ptr->art_flags |= TR_FEATHER; break; case 2: - o_ptr->art_flags3 |= (TR3_LITE1); + o_ptr->art_flags |= TR_LITE1; break; case 3: - o_ptr->art_flags3 |= (TR3_SEE_INVIS); + o_ptr->art_flags |= TR_SEE_INVIS; break; case 4: - o_ptr->art_esp |= (ESP_ALL); + o_ptr->art_flags |= ESP_ALL; break; case 5: - o_ptr->art_flags3 |= (TR3_SLOW_DIGEST); + o_ptr->art_flags |= TR_SLOW_DIGEST; break; case 6: - o_ptr->art_flags3 |= (TR3_REGEN); + o_ptr->art_flags |= TR_REGEN; break; case 7: - o_ptr->art_flags2 |= (TR2_FREE_ACT); + o_ptr->art_flags |= TR_FREE_ACT; break; case 8: - o_ptr->art_flags2 |= (TR2_HOLD_LIFE); + o_ptr->art_flags |= TR_HOLD_LIFE; break; } } - if (fego & ETR4_R_ELEM) + if (fego & ETR_R_ELEM) { /* Make an acid/elec/fire/cold/poison resist */ - random_resistance(o_ptr, FALSE, randint(14) + 4); + random_resistance(o_ptr, randint(14) + 4); } - if (fego & ETR4_R_LOW) + if (fego & ETR_R_LOW) { /* Make an acid/elec/fire/cold resist */ - random_resistance(o_ptr, FALSE, randint(12) + 4); + random_resistance(o_ptr, randint(12) + 4); } - if (fego & ETR4_R_HIGH) + if (fego & ETR_R_HIGH) { /* Make a high resist */ - random_resistance(o_ptr, FALSE, randint(22) + 16); + random_resistance(o_ptr, randint(22) + 16); } - if (fego & ETR4_R_ANY) + if (fego & ETR_R_ANY) { /* Make any resist */ - random_resistance(o_ptr, FALSE, randint(34) + 4); + random_resistance(o_ptr, randint(34) + 4); } - if (fego & ETR4_R_DRAGON) + if (fego & ETR_R_DRAGON) { /* Make "dragon resist" */ dragon_resist(o_ptr); } - if (fego & ETR4_SLAY_WEAP) + if (fego & ETR_SLAY_WEAP) { /* Make a Weapon of Slaying */ @@ -3593,254 +3576,251 @@ void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows) } if (randint(5) == 1) { - o_ptr->art_flags1 |= TR1_BRAND_POIS; + o_ptr->art_flags |= TR_BRAND_POIS; } if (o_ptr->tval == TV_SWORD && (randint(3) == 1)) { - o_ptr->art_flags1 |= TR1_VORPAL; + o_ptr->art_flags |= TR_VORPAL; } } - if (fego & ETR4_DAM_DIE) + if (fego & ETR_DAM_DIE) { /* Increase damage dice */ o_ptr->dd++; } - if (fego & ETR4_DAM_SIZE) + if (fego & ETR_DAM_SIZE) { /* Increase damage dice size */ o_ptr->ds++; } - if (fego & ETR4_LIMIT_BLOWS) + if (fego & ETR_LIMIT_BLOWS) { /* Swap this flag */ *limit_blows = !(*limit_blows); } - if (fego & ETR4_PVAL_M1) + if (fego & ETR_PVAL_M1) { /* Increase pval */ o_ptr->pval++; } - if (fego & ETR4_PVAL_M2) + if (fego & ETR_PVAL_M2) { /* Increase pval */ o_ptr->pval += m_bonus(2, dun_level); } - if (fego & ETR4_PVAL_M3) + if (fego & ETR_PVAL_M3) { /* Increase pval */ o_ptr->pval += m_bonus(3, dun_level); } - if (fego & ETR4_PVAL_M5) + if (fego & ETR_PVAL_M5) { /* Increase pval */ o_ptr->pval += m_bonus(5, dun_level); } - if (fego & ETR4_AC_M1) + if (fego & ETR_AC_M1) { /* Increase ac */ o_ptr->to_a++; } - if (fego & ETR4_AC_M2) + if (fego & ETR_AC_M2) { /* Increase ac */ o_ptr->to_a += m_bonus(2, dun_level); } - if (fego & ETR4_AC_M3) + if (fego & ETR_AC_M3) { /* Increase ac */ o_ptr->to_a += m_bonus(3, dun_level); } - if (fego & ETR4_AC_M5) + if (fego & ETR_AC_M5) { /* Increase ac */ o_ptr->to_a += m_bonus(5, dun_level); } - if (fego & ETR4_TH_M1) + if (fego & ETR_TH_M1) { /* Increase to hit */ o_ptr->to_h++; } - if (fego & ETR4_TH_M2) + if (fego & ETR_TH_M2) { /* Increase to hit */ o_ptr->to_h += m_bonus(2, dun_level); } - if (fego & ETR4_TH_M3) + if (fego & ETR_TH_M3) { /* Increase to hit */ o_ptr->to_h += m_bonus(3, dun_level); } - if (fego & ETR4_TH_M5) + if (fego & ETR_TH_M5) { /* Increase to hit */ o_ptr->to_h += m_bonus(5, dun_level); } - if (fego & ETR4_TD_M1) + if (fego & ETR_TD_M1) { /* Increase to dam */ o_ptr->to_d++; } - if (fego & ETR4_TD_M2) + if (fego & ETR_TD_M2) { /* Increase to dam */ o_ptr->to_d += m_bonus(2, dun_level); } - if (fego & ETR4_TD_M3) + if (fego & ETR_TD_M3) { /* Increase to dam */ o_ptr->to_d += m_bonus(3, dun_level); } - if (fego & ETR4_TD_M5) + if (fego & ETR_TD_M5) { /* Increase to dam */ o_ptr->to_d += m_bonus(5, dun_level); } - if (fego & ETR4_R_P_ABILITY) + if (fego & ETR_R_P_ABILITY) { /* Add a random pval-affected ability */ /* This might cause boots with + to blows */ - switch (randint(6)) + switch (randint(5)) { case 1: - o_ptr->art_flags1 |= TR1_STEALTH; + o_ptr->art_flags |= TR_STEALTH; break; case 2: - o_ptr->art_flags1 |= TR1_SEARCH; + o_ptr->art_flags |= TR_INFRA; break; case 3: - o_ptr->art_flags1 |= TR1_INFRA; + o_ptr->art_flags |= TR_TUNNEL; break; case 4: - o_ptr->art_flags1 |= TR1_TUNNEL; + o_ptr->art_flags |= TR_SPEED; break; case 5: - o_ptr->art_flags1 |= TR1_SPEED; - break; - case 6: - o_ptr->art_flags1 |= TR1_BLOWS; + o_ptr->art_flags |= TR_BLOWS; break; } } - if (fego & ETR4_R_STAT) + if (fego & ETR_R_STAT) { /* Add a random stat */ switch (randint(6)) { case 1: - o_ptr->art_flags1 |= TR1_STR; + o_ptr->art_flags |= TR_STR; break; case 2: - o_ptr->art_flags1 |= TR1_INT; + o_ptr->art_flags |= TR_INT; break; case 3: - o_ptr->art_flags1 |= TR1_WIS; + o_ptr->art_flags |= TR_WIS; break; case 4: - o_ptr->art_flags1 |= TR1_DEX; + o_ptr->art_flags |= TR_DEX; break; case 5: - o_ptr->art_flags1 |= TR1_CON; + o_ptr->art_flags |= TR_CON; break; case 6: - o_ptr->art_flags1 |= TR1_CHR; + o_ptr->art_flags |= TR_CHR; break; } } - if (fego & ETR4_R_STAT_SUST) + if (fego & ETR_R_STAT_SUST) { /* Add a random stat and sustain it */ switch (randint(6)) { case 1: { - o_ptr->art_flags1 |= TR1_STR; - o_ptr->art_flags2 |= TR2_SUST_STR; + o_ptr->art_flags |= TR_STR; + o_ptr->art_flags |= TR_SUST_STR; break; } case 2: { - o_ptr->art_flags1 |= TR1_INT; - o_ptr->art_flags2 |= TR2_SUST_INT; + o_ptr->art_flags |= TR_INT; + o_ptr->art_flags |= TR_SUST_INT; break; } case 3: { - o_ptr->art_flags1 |= TR1_WIS; - o_ptr->art_flags2 |= TR2_SUST_WIS; + o_ptr->art_flags |= TR_WIS; + o_ptr->art_flags |= TR_SUST_WIS; break; } case 4: { - o_ptr->art_flags1 |= TR1_DEX; - o_ptr->art_flags2 |= TR2_SUST_DEX; + o_ptr->art_flags |= TR_DEX; + o_ptr->art_flags |= TR_SUST_DEX; break; } case 5: { - o_ptr->art_flags1 |= TR1_CON; - o_ptr->art_flags2 |= TR2_SUST_CON; + o_ptr->art_flags |= TR_CON; + o_ptr->art_flags |= TR_SUST_CON; break; } case 6: { - o_ptr->art_flags1 |= TR1_CHR; - o_ptr->art_flags2 |= TR2_SUST_CHR; + o_ptr->art_flags |= TR_CHR; + o_ptr->art_flags |= TR_SUST_CHR; break; } } } - if (fego & ETR4_R_IMMUNITY) + if (fego & ETR_R_IMMUNITY) { /* Give a random immunity */ switch (randint(4)) { case 1: { - o_ptr->art_flags2 |= TR2_IM_FIRE; - o_ptr->art_flags3 |= TR3_IGNORE_FIRE; + o_ptr->art_flags |= TR_IM_FIRE; + o_ptr->art_flags |= TR_IGNORE_FIRE; break; } case 2: { - o_ptr->art_flags2 |= TR2_IM_ACID; - o_ptr->art_flags3 |= TR3_IGNORE_ACID; + o_ptr->art_flags |= TR_IM_ACID; + o_ptr->art_flags |= TR_IGNORE_ACID; break; } case 3: { - o_ptr->art_flags2 |= TR2_IM_ELEC; - o_ptr->art_flags3 |= TR3_IGNORE_ELEC; + o_ptr->art_flags |= TR_IM_ELEC; + o_ptr->art_flags |= TR_IGNORE_ELEC; break; } case 4: { - o_ptr->art_flags2 |= TR2_IM_COLD; - o_ptr->art_flags3 |= TR3_IGNORE_COLD; + o_ptr->art_flags |= TR_IM_COLD; + o_ptr->art_flags |= TR_IGNORE_COLD; break; } } @@ -3880,30 +3860,29 @@ void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows) */ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power) { - int i, rolls, f1, f2, power; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto const &e_info = game->edit_data.e_info; + + int i, rolls; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Aply luck */ lev += luck( -7, 7); - /* Spell in it ? no ! */ - if (k_ptr->flags5 & TR5_SPELL_CONTAIN) + /* Spell in it? No! */ + if (k_ptr->flags & TR_SPELL_CONTAIN) o_ptr->pval2 = -1; /* Important to do before all else, be sure to have the basic obvious flags set */ - o_ptr->art_oflags1 = k_ptr->oflags1; - o_ptr->art_oflags2 = k_ptr->oflags2; - o_ptr->art_oflags3 = k_ptr->oflags3; - o_ptr->art_oflags4 = k_ptr->oflags4; - o_ptr->art_oflags5 = k_ptr->oflags5; - o_ptr->art_oesp = k_ptr->oesp; + o_ptr->art_oflags = k_ptr->oflags; /* No need to touch normal artifacts */ - if (k_ptr->flags3 & TR3_NORM_ART) + if (k_ptr->flags & TR_NORM_ART) { /* Ahah! we tried to trick us !! */ if (k_ptr->artifact || - ((k_ptr->flags4 & TR4_SPECIAL_GENE) && + ((k_ptr->flags & TR_SPECIAL_GENE) && (!k_allow_special[o_ptr->k_idx]))) { object_prep(o_ptr, lookup_kind(k_ptr->btval, k_ptr->bsval)); @@ -3933,7 +3912,10 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea k_ptr->artifact = TRUE; - if (cheat_peek || p_ptr->precognition) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } } return; @@ -3942,47 +3924,49 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea /* Maximum "level" for various things */ if (lev > MAX_DEPTH - 1) lev = MAX_DEPTH - 1; + /* Roll for power */ + int power = 0; + { + /* Base chance of being "good" */ + int f1 = lev + 10 + luck( -15, 15); - /* Base chance of being "good" */ - f1 = lev + 10 + luck( -15, 15); - - /* Maximal chance of being "good" */ - if (f1 > 75) f1 = 75; - - /* Base chance of being "great" */ - f2 = f1 / 2; + /* Maximal chance of being "good" */ + if (f1 > 75) f1 = 75; - /* Maximal chance of being "great" */ - if (f2 > 20) f2 = 20; + /* Base chance of being "great" */ + int f2 = f1 / 2; + /* Maximal chance of being "great" */ + if (f2 > 20) f2 = 20; - /* Assume normal */ - power = 0; + /* Assume normal */ + power = 0; - /* Roll for "good" */ - if (good || magik(f1)) - { - /* Assume "good" */ - power = 1; + /* Roll for "good" */ + if (good || magik(f1)) + { + /* Assume "good" */ + power = 1; - /* Roll for "great" */ - if (great || magik(f2)) power = 2; - } + /* Roll for "great" */ + if (great || magik(f2)) power = 2; + } - /* Roll for "cursed" */ - else if (magik(f1)) - { - /* Assume "cursed" */ - power = -1; + /* Roll for "cursed" */ + else if (magik(f1)) + { + /* Assume "cursed" */ + power = -1; - /* Roll for "broken" */ - if (magik(f2)) power = -2; - } + /* Roll for "broken" */ + if (magik(f2)) power = -2; + } - /* Override power with parameter? */ - if (auto power_override = force_power) - { - power = *power_override; + /* Override power with parameter? */ + if (auto power_override = force_power) + { + power = *power_override; + } } /* Assume no rolls */ @@ -4017,7 +4001,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea /* Hack -- analyze artifacts */ if (o_ptr->name1) { - artifact_type *a_ptr = &a_info[o_ptr->name1]; + auto a_ptr = &a_info[o_ptr->name1]; /* Hack -- Mark the artifact as "created" */ a_ptr->cur_num = 1; @@ -4034,7 +4018,7 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea o_ptr->number = 1; /* Hack -- extract the "cursed" flag */ - if (a_ptr->flags3 & (TR3_CURSED)) o_ptr->ident |= (IDENT_CURSED); + if (a_ptr->flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED); /* Mega-Hack -- increase the rating */ rating += 10; @@ -4046,17 +4030,19 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea good_item_flag = TRUE; /* Cheat -- peek at the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } - /* Spell in it ? no ! */ - if (a_ptr->flags5 & TR5_SPELL_CONTAIN) + /* Spell in it? No! */ + if (a_ptr->flags & TR_SPELL_CONTAIN) o_ptr->pval2 = -1; /* Give a basic exp/exp level to an artifact that needs it */ - if (a_ptr->flags4 & TR4_LEVELS) + if (a_ptr->flags & TR_LEVELS) { - o_ptr->elevel = (k_ptr->level / 10) + 1; - o_ptr->exp = player_exp[o_ptr->elevel - 1]; + init_obj_exp(o_ptr, k_ptr); } /* Done */ @@ -4082,7 +4068,6 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea case TV_SHOT: case TV_ARROW: case TV_BOLT: - case TV_TRAPKIT: { if (power) a_m_aux_1(o_ptr, lev, power); break; @@ -4131,22 +4116,23 @@ void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ grea } } - if (o_ptr->art_name) rating += 40; + if (!o_ptr->artifact_name.empty()) + { + rating += 40; + } /* Hack -- analyze ego-items */ else if (o_ptr->name2) { - ego_item_type *e_ptr; int j; bool_ limit_blows = FALSE; - u32b f1, f2, f3, f4, f5, esp; s16b e_idx; e_idx = o_ptr->name2; /* Ok now, THAT is truly ugly */ try_an_other_ego: - e_ptr = &e_info[e_idx]; + auto e_ptr = &e_info[e_idx]; /* Hack -- extra powers */ for (j = 0; j < FLAG_RARITY_MAX; j++) @@ -4154,35 +4140,23 @@ try_an_other_ego: /* Rarity check */ if (magik(e_ptr->rar[j])) { - o_ptr->art_flags1 |= e_ptr->flags1[j]; - o_ptr->art_flags2 |= e_ptr->flags2[j]; - o_ptr->art_flags3 |= e_ptr->flags3[j]; - o_ptr->art_flags4 |= e_ptr->flags4[j]; - o_ptr->art_flags5 |= e_ptr->flags5[j]; - o_ptr->art_esp |= e_ptr->esp[j]; - - o_ptr->art_oflags1 |= e_ptr->oflags1[j]; - o_ptr->art_oflags2 |= e_ptr->oflags2[j]; - o_ptr->art_oflags3 |= e_ptr->oflags3[j]; - o_ptr->art_oflags4 |= e_ptr->oflags4[j]; - o_ptr->art_oflags5 |= e_ptr->oflags5[j]; - o_ptr->art_oesp |= e_ptr->oesp[j]; - + o_ptr->art_flags |= e_ptr->flags[j]; + o_ptr->art_oflags |= e_ptr->oflags[j]; add_random_ego_flag(o_ptr, e_ptr->fego[j], &limit_blows); } } /* No insane number of blows */ - if (limit_blows && (o_ptr->art_flags1 & TR1_BLOWS)) + if (limit_blows && (o_ptr->art_flags & TR_BLOWS)) { if (o_ptr->pval > 2) o_ptr->pval = randint(2); } /* get flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack -- acquire "cursed" flag */ - if (f3 & TR3_CURSED) o_ptr->ident |= (IDENT_CURSED); + if (flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED); /* Hack -- obtain bonuses */ if (e_ptr->max_to_h > 0) o_ptr->to_h += randint(e_ptr->max_to_h); @@ -4205,53 +4179,41 @@ try_an_other_ego: goto try_an_other_ego; } - /* Spell in it ? no ! */ - if (f5 & TR5_SPELL_CONTAIN) + /* Spell in it ? No! */ + if (flags & TR_SPELL_CONTAIN) { - /* Mega hack, mage staves of spell cannot SPELL_CONTAIN */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - o_ptr->art_flags5 &= ~TR5_SPELL_CONTAIN; - } - else - o_ptr->pval2 = -1; + o_ptr->pval2 = -1; } /* Cheat -- describe the item */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(o_ptr); + } } /* Examine real objects */ if (o_ptr->k_idx) { - u32b f1, f2, f3, f4, f5, esp; - object_kind *k_ptr = &k_info[o_ptr->k_idx]; /* Hack -- acquire "cursed" flag */ - if (k_ptr->flags3 & (TR3_CURSED)) o_ptr->ident |= (IDENT_CURSED); + if (k_ptr->flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED); /* Extract some flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack give a basic exp/exp level to an object that needs it */ - if (f4 & TR4_LEVELS) + if (flags & TR_LEVELS) { - o_ptr->elevel = (k_ptr->level / 10) + 1; - o_ptr->exp = player_exp[o_ptr->elevel - 1]; + init_obj_exp(o_ptr, k_ptr); } - /* Spell in it ? no ! */ - if (f5 & TR5_SPELL_CONTAIN) + /* Spell in it ? No! */ + if (flags & TR_SPELL_CONTAIN) { - /* Mega hack, mage staves of spell cannot SPELL_CONTAIN */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - o_ptr->art_flags5 &= ~TR5_SPELL_CONTAIN; - } - else - o_ptr->pval2 = -1; + o_ptr->pval2 = -1; } /* Hacccccccckkkkk attack ! :) -- To prevent som ugly crashs */ @@ -4264,64 +4226,62 @@ try_an_other_ego: if (o_ptr->tval == TV_ROD_MAIN) { /* Set the max mana and the current mana */ - o_ptr->pval2 = (f4 & TR4_CAPACITY) ? o_ptr->sval * 2 : o_ptr->sval; + o_ptr->pval2 = (flags & TR_CAPACITY) ? o_ptr->sval * 2 : o_ptr->sval; o_ptr->timeout = o_ptr->pval2; } - - /* Remove some unnecessary stuff hack */ - if (o_ptr->tval == TV_TRAPKIT) trap_hack(o_ptr); } } /* The themed objects to use */ -static obj_theme match_theme; +static obj_theme *match_theme = nullptr; /* * XXX XXX XXX It relies on the fact that obj_theme is a four byte structure * for its efficient operation. A horrendous hack, I'd say. */ -void init_match_theme(obj_theme const &theme) +bool init_match_theme(obj_theme const &theme) { - /* Save the theme */ - match_theme = theme; + if (match_theme == nullptr) + { + match_theme = new obj_theme(theme); + return true; + } + else if (*match_theme != theme) + { + *match_theme = theme; + return true; + } + else + { + return false; + } } /* - * Ditto XXX XXX XXX + * Maga-Hack -- match certain types of object only. */ -static bool_ theme_changed(obj_theme theme) +static bool kind_is_theme(obj_theme const *theme, int k_idx) { - /* Any of the themes has been changed */ - if (theme.treasure != match_theme.treasure) return (TRUE); - if (theme.combat != match_theme.combat) return (TRUE); - if (theme.magic != match_theme.magic) return (TRUE); - if (theme.tools != match_theme.tools) return (TRUE); + auto const &k_info = game->edit_data.k_info; - /* No changes */ - return (FALSE); -} + assert(theme != nullptr); - -/* - * Maga-Hack -- match certain types of object only. - */ -static bool kind_is_theme(int k_idx) -{ - object_kind *k_ptr = &k_info[k_idx]; + auto k_ptr = &k_info[k_idx]; s32b prob = 0; - /* * Paranoia -- Prevent accidental "(Nothing)" * that are results of uninitialised theme structs. * * Caution: Junks go into the allocation table. */ - if (match_theme.treasure + match_theme.combat + - match_theme.magic + match_theme.tools == 0) return (TRUE); + if (theme->treasure + theme->combat + theme->magic + theme->tools == 0) + { + return TRUE; + } /* Pick probability to use */ @@ -4340,151 +4300,141 @@ static bool kind_is_theme(int k_idx) * larger than theme components, or we would see * unexpected, well, junks. */ - prob = 100 - (match_theme.treasure + match_theme.combat + - match_theme.magic + match_theme.tools); + prob = 100 - (theme->treasure + theme->combat + + theme->magic + theme->tools); break; } case TV_CHEST: - prob = match_theme.treasure; + prob = theme->treasure; break; case TV_CROWN: - prob = match_theme.treasure; + prob = theme->treasure; break; case TV_DRAG_ARMOR: - prob = match_theme.treasure; + prob = theme->treasure; break; case TV_AMULET: - prob = match_theme.treasure; + prob = theme->treasure; break; case TV_RING: - prob = match_theme.treasure; + prob = theme->treasure; break; case TV_SHOT: - prob = match_theme.combat; + prob = theme->combat; break; case TV_ARROW: - prob = match_theme.combat; + prob = theme->combat; break; case TV_BOLT: - prob = match_theme.combat; + prob = theme->combat; break; case TV_BOOMERANG: - prob = match_theme.combat; + prob = theme->combat; break; case TV_BOW: - prob = match_theme.combat; + prob = theme->combat; break; case TV_HAFTED: - // FIXME: These cases can be shortened drastically - prob = match_theme.combat; + prob = theme->combat; break; case TV_POLEARM: - prob = match_theme.combat; + prob = theme->combat; break; case TV_SWORD: - prob = match_theme.combat; + prob = theme->combat; break; case TV_AXE: - prob = match_theme.combat; + prob = theme->combat; break; case TV_GLOVES: - prob = match_theme.combat; + prob = theme->combat; break; case TV_HELM: - prob = match_theme.combat; + prob = theme->combat; break; case TV_SHIELD: - prob = match_theme.combat; + prob = theme->combat; break; case TV_SOFT_ARMOR: - prob = match_theme.combat; + prob = theme->combat; break; case TV_HARD_ARMOR: - prob = match_theme.combat; + prob = theme->combat; break; case TV_MSTAFF: - prob = match_theme.magic; + prob = theme->magic; break; case TV_STAFF: - prob = match_theme.magic; + prob = theme->magic; break; case TV_WAND: - prob = match_theme.magic; + prob = theme->magic; break; case TV_ROD: - prob = match_theme.magic; + prob = theme->magic; break; case TV_ROD_MAIN: - prob = match_theme.magic; + prob = theme->magic; break; case TV_SCROLL: - prob = match_theme.magic; + prob = theme->magic; break; case TV_PARCHMENT: - prob = match_theme.magic; + prob = theme->magic; break; case TV_POTION: - prob = match_theme.magic; + prob = theme->magic; break; case TV_POTION2: - prob = match_theme.magic; + prob = theme->magic; break; case TV_RANDART: - prob = match_theme.magic; - break; - case TV_RUNE1: - prob = match_theme.magic; - break; - case TV_RUNE2: - prob = match_theme.magic; + prob = theme->magic; break; case TV_BOOK: - prob = match_theme.magic; + prob = theme->magic; break; case TV_SYMBIOTIC_BOOK: - prob = match_theme.magic; + prob = theme->magic; break; case TV_MUSIC_BOOK: - prob = match_theme.magic; + prob = theme->magic; break; case TV_DRUID_BOOK: - prob = match_theme.magic; + prob = theme->magic; break; case TV_DAEMON_BOOK: - prob = match_theme.magic; + prob = theme->magic; break; case TV_LITE: - prob = match_theme.tools; + prob = theme->tools; break; case TV_CLOAK: - prob = match_theme.tools; + prob = theme->tools; break; case TV_BOOTS: - prob = match_theme.tools; + prob = theme->tools; break; case TV_SPIKE: - prob = match_theme.tools; + prob = theme->tools; break; case TV_DIGGING: - prob = match_theme.tools; + prob = theme->tools; break; case TV_FLASK: - prob = match_theme.tools; + prob = theme->tools; break; case TV_FOOD: - prob = match_theme.tools; + prob = theme->tools; break; case TV_TOOL: - prob = match_theme.tools; + prob = theme->tools; break; case TV_INSTRUMENT: - prob = match_theme.tools; - break; - case TV_TRAPKIT: - prob = match_theme.tools; + prob = theme->tools; break; } @@ -4500,18 +4450,20 @@ static bool kind_is_theme(int k_idx) */ bool_ kind_is_legal(int k_idx) { - object_kind *k_ptr = &k_info[k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[k_idx]; - if (!kind_is_theme(k_idx)) return FALSE; + if (!kind_is_theme(match_theme, k_idx)) return FALSE; - if (k_ptr->flags4 & TR4_SPECIAL_GENE) + if (k_ptr->flags & TR_SPECIAL_GENE) { if (k_allow_special[k_idx]) return TRUE; else return FALSE; } /* No 2 times the same normal artifact */ - if ((k_ptr->flags3 & TR3_NORM_ART) && (k_ptr->artifact)) + if ((k_ptr->flags & TR_NORM_ART) && (k_ptr->artifact)) { return FALSE; } @@ -4544,7 +4496,9 @@ bool_ kind_is_legal(int k_idx) */ static bool_ kind_is_good(int k_idx) { - object_kind *k_ptr = &k_info[k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[k_idx]; if (!kind_is_legal(k_idx)) return FALSE; @@ -4573,7 +4527,6 @@ static bool_ kind_is_good(int k_idx) case TV_HAFTED: case TV_POLEARM: case TV_DIGGING: - case TV_TRAPKIT: case TV_MSTAFF: case TV_BOOMERANG: { @@ -4599,7 +4552,6 @@ static bool_ kind_is_good(int k_idx) /* Expensive rod tips are good */ case TV_ROD: { - /* Probing is not good, but Recall is*/ if (k_ptr->cost >= 4500) return TRUE; return FALSE; } @@ -4641,23 +4593,21 @@ static bool_ kind_is_good(int k_idx) */ bool_ kind_is_artifactable(int k_idx) { - int i, j; - object_kind *k_ptr = &k_info[k_idx]; + auto const &ra_info = game->edit_data.ra_info; + auto const &k_info = game->edit_data.k_info; + auto k_ptr = &k_info[k_idx]; if (kind_is_good(k_idx)) { - /* We consider the item artifactable if there is at least one - * randart power in ra_info that could be added to this item. */ - for (i = 0; i < max_ra_idx; i++) + // Consider the item artifactable if there is at least one + // randart power which could be added to the item. + for (auto const &ra_ref: ra_info) { - randart_part_type *ra_ptr = &ra_info[i]; - - for (j = 0; j < 20; j++) + for (auto const &filter: ra_ref.kind_filter) { - if (ra_ptr->tval[j] != k_ptr->tval) continue; - if (ra_ptr->min_sval[j] > k_ptr->sval) continue; - if (ra_ptr->max_sval[j] < k_ptr->sval) continue; - /* Winner */ + if (filter.tval != k_ptr->tval) continue; + if (filter.min_sval > k_ptr->sval) continue; + if (filter.max_sval < k_ptr->sval) continue; return TRUE; } } @@ -4684,6 +4634,9 @@ bool_ kind_is_artifactable(int k_idx) */ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme) { + auto const &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; + int invprob, base; @@ -4697,16 +4650,11 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & /* Generate a special object, or a normal object */ if ((rand_int(invprob) != 0) || !make_artifact_special(j_ptr)) { - int k_idx; - - /* See if the theme has been changed XXX XXX XXX */ - if (theme_changed(theme)) + /* See if the theme has been changed */ + if (init_match_theme(theme)) { - /* Select items based on "theme" */ - init_match_theme(theme); - /* Invalidate the cached allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; } /* Good objects */ @@ -4720,7 +4668,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & } /* Normal objects -- only when the cache is invalidated */ - else if (!alloc_kind_table_valid) + else if (!alloc.kind_table_valid) { /* Activate normal restriction */ get_obj_num_hook = kind_is_legal; @@ -4729,11 +4677,11 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & get_obj_num_prep(); /* The table is synchronised */ - alloc_kind_table_valid = TRUE; + alloc.kind_table_valid = true; } /* Pick a random object */ - k_idx = get_obj_num(base); + int k_idx = get_obj_num(base); /* Good objects */ if (good) @@ -4745,7 +4693,7 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & get_obj_num_prep(); /* The table is synchronised */ - alloc_kind_table_valid = TRUE; + alloc.kind_table_valid = true; } /* Handle failure */ @@ -4781,7 +4729,10 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & rating += (k_info[j_ptr->k_idx].level - dun_level); /* Cheat -- peek at items */ - if ((cheat_peek) || (p_ptr->precognition)) object_mention(j_ptr); + if (options->cheat_peek || p_ptr->precognition) + { + object_mention(j_ptr); + } } /* Success */ @@ -4801,6 +4752,11 @@ bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const & */ void place_object(int y, int x, bool_ good, bool_ great, int where) { + auto const &d_info = game->edit_data.d_info; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &random_artifacts = game->random_artifacts; + s16b o_idx; cave_type *c_ptr; @@ -4883,7 +4839,7 @@ void place_object(int y, int x, bool_ good, bool_ great, int where) { a_info[q_ptr->name1].cur_num = 0; } - else if (k_info[q_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[q_ptr->k_idx].flags & TR_NORM_ART) { k_info[q_ptr->k_idx].artifact = 0; } @@ -4908,6 +4864,8 @@ void place_object(int y, int x, bool_ good, bool_ great, int where) */ bool_ make_gold(object_type *j_ptr) { + auto const &k_info = game->edit_data.k_info; + int i; s32b base; @@ -4938,8 +4896,10 @@ bool_ make_gold(object_type *j_ptr) j_ptr->pval = (base + (8L * randint(base)) + randint(8)); /* Multiply value by 5 if selling is disabled */ - if (no_selling) + if (options->no_selling) + { j_ptr->pval *= 5; + } /* Success */ return (TRUE); @@ -5029,6 +4989,11 @@ void place_gold(int y, int x) */ s16b drop_near(object_type *j_ptr, int chance, int y, int x) { + auto const &f_info = game->edit_data.f_info; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + auto &random_artifacts = game->random_artifacts; + int i, k, d, s; int bs, bn; @@ -5054,7 +5019,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) /* Handle normal "breakage" */ - if (!(j_ptr->art_name || artifact_p(j_ptr)) && (rand_int(100) < chance)) + if ((!artifact_p(j_ptr)) && (rand_int(100) < chance)) { /* Message */ msg_format("The %s disappear%s.", @@ -5106,10 +5071,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) c_ptr = &cave[ty][tx]; /* Require floor space (or shallow terrain) -KMW- */ - if (!(f_info[c_ptr->feat].flags1 & FF1_FLOOR)) continue; - - /* No traps */ - if (c_ptr->t_idx) continue; + if (!(f_info[c_ptr->feat].flags & FF_FLOOR)) continue; /* No objects */ k = 0; @@ -5159,7 +5121,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) /* Handle lack of space */ - if (!flag && !(artifact_p(j_ptr) || j_ptr->art_name)) + if (!flag && (!artifact_p(j_ptr))) { /* Message */ msg_format("The %s disappear%s.", @@ -5254,7 +5216,7 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) { a_info[j_ptr->name1].cur_num = 0; } - else if (k_info[j_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[j_ptr->k_idx].flags & TR_NORM_ART) { k_info[j_ptr->k_idx].artifact = 0; } @@ -5301,8 +5263,6 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) if (chance && (by == p_ptr->py) && (bx == p_ptr->px)) { msg_print("You feel something roll beneath your feet."); - /* Sound */ - sound(SOUND_DROP); } /* XXX XXX XXX */ @@ -5319,6 +5279,8 @@ s16b drop_near(object_type *j_ptr, int chance, int y, int x) */ void acquirement(int y1, int x1, int num, bool_ great, bool_ known) { + auto const &d_info = game->edit_data.d_info; + object_type *i_ptr; object_type object_type_body; @@ -5346,30 +5308,6 @@ void acquirement(int y1, int x1, int num, bool_ great, bool_ known) } - -/* - * Hack -- instantiate a trap - * - * XXX XXX XXX This routine should be redone to reflect trap "level". - * That is, it does not make sense to have spiked pits at 50 feet. - * Actually, it is not this routine, but the "trap instantiation" - * code, which should also check for "trap doors" on quest levels. - */ -void pick_trap(int y, int x) -{ - cave_type *c_ptr = &cave[y][x]; - - /* Paranoia */ - if ((c_ptr->t_idx == 0) || (c_ptr->info & CAVE_TRDT)) return; - - /* Activate the trap */ - c_ptr->info |= (CAVE_TRDT); - - /* Notice and redraw */ - note_spot(y, x); - lite_spot(y, x); -} - /* * Describe the charges on an item in the inventory. */ @@ -5458,6 +5396,8 @@ void inven_item_increase(int item, int num) */ bool_ inven_item_optimize(int item) { + auto const &a_info = game->edit_data.a_info; + object_type *o_ptr = &p_ptr->inventory[item]; /* Only optimize real items */ @@ -6039,7 +5979,7 @@ void inven_drop(int item, int amt, int dy, int dx, bool_ silent) * * Note special handling of the "overflow" slot */ -void combine_pack(void) +void combine_pack() { int i, j, k; object_type *o_ptr; @@ -6106,7 +6046,7 @@ void combine_pack(void) * * Note special handling of the "overflow" slot */ -void reorder_pack(void) +void reorder_pack() { int i, j, k; s32b o_value; @@ -6274,9 +6214,11 @@ s16b floor_carry(int y, int x, object_type *j_ptr) */ void pack_decay(int item) { + auto const &r_info = game->edit_data.r_info; + object_type *o_ptr = &p_ptr->inventory[item]; - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; object_type *i_ptr; object_type object_type_body; @@ -6325,7 +6267,7 @@ void pack_decay(int item) } /* Monster must have a skeleton for its corpse to become one */ - if ((i_ptr->sval == SV_CORPSE_CORPSE) && (r_ptr->flags3 & RF9_DROP_SKELETON)) + if ((i_ptr->sval == SV_CORPSE_CORPSE) && (r_ptr->flags & RF_DROP_SKELETON)) { /* Replace the corpse with a skeleton */ object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_SKELETON)); @@ -6359,9 +6301,11 @@ void pack_decay(int item) */ void floor_decay(int item) { + auto const &r_info = game->edit_data.r_info; + object_type *o_ptr = &o_list[item]; - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; object_type *i_ptr; object_type object_type_body; @@ -6420,7 +6364,7 @@ void floor_decay(int item) } /* Monster must have a skeleton for its corpse to become one */ - if ((i_ptr->sval == SV_CORPSE_CORPSE) && (r_ptr->flags3 & RF9_DROP_SKELETON)) + if ((i_ptr->sval == SV_CORPSE_CORPSE) && (r_ptr->flags & RF_DROP_SKELETON)) { /* Replace the corpse with a skeleton */ object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_SKELETON)); diff --git a/src/object2.hpp b/src/object2.hpp index 26d07b25..a91631aa 100644 --- a/src/object2.hpp +++ b/src/object2.hpp @@ -1,5 +1,6 @@ #pragma once +#include "ego_flag_set.hpp" #include "h-basic.h" #include "object_type_fwd.hpp" #include "obj_theme_fwd.hpp" @@ -9,61 +10,60 @@ typedef enum { OPTIMIZE, NO_OPTIMIZE } optimize_flag; typedef enum { DESCRIBE, NO_DESCRIBE } describe_flag; -extern void inc_stack_size(int item, int delta); -extern void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag desc); -extern object_type *get_object(int item); -extern s32b calc_total_weight(void); -extern void add_random_ego_flag(object_type *o_ptr, int fego, bool_ *limit_blows); -extern void init_match_theme(obj_theme const &theme); -extern bool_ kind_is_artifactable(int k_idx); -extern bool_ kind_is_legal(int k_idx); -extern void inven_item_charges(int item); -extern void inven_item_describe(int item); -extern void inven_item_increase(int item, int num); -extern bool_ inven_item_optimize(int item); -extern void floor_item_charges(int item); -extern void floor_item_describe(int item); -extern void floor_item_increase(int item, int num); -extern void floor_item_optimize(int item); -extern bool_ inven_carry_okay(object_type const *o_ptr); -extern s16b inven_carry(object_type *o_ptr, bool_ final); -extern s16b inven_takeoff(int item, int amt, bool_ force_drop); -extern void inven_drop(int item, int amt, int dy, int dx, bool_ silent); -extern void excise_object_idx(int o_idx); -extern void delete_object_idx(int o_idx); -extern void delete_object(int y, int x); -extern void compact_objects(int size); -extern void wipe_o_list(void); -extern s16b o_pop(void); -extern errr get_obj_num_prep(void); -extern s16b get_obj_num(int level); -extern void object_known(object_type *o_ptr); -extern bool object_known_p(object_type const *o_ptr); -extern void object_aware(object_type *o_ptr); -extern bool object_aware_p(object_type const *o_ptr); -extern void object_tried(object_type *o_ptr); -extern bool object_tried_p(object_type const *o_ptr); -extern s32b object_value(object_type const *o_ptr); -extern s32b object_value_real(object_type const *o_ptr); -extern bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr); -extern void object_absorb(object_type *o_ptr, object_type *j_ptr); -extern s16b lookup_kind(int tval, int sval); -extern void object_wipe(object_type *o_ptr); -extern void object_prep(object_type *o_ptr, int k_idx); -extern void object_copy(object_type *o_ptr, object_type *j_ptr); -extern void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power = boost::none); -extern bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme); -extern void place_object(int y, int x, bool_ good, bool_ great, int where); -extern bool_ make_gold(object_type *j_ptr); -extern void place_gold(int y, int x); -extern s16b drop_near(object_type *o_ptr, int chance, int y, int x); -extern void acquirement(int y1, int x1, int num, bool_ great, bool_ known); -extern void pick_trap(int y, int x); -extern void combine_pack(void); -extern void reorder_pack(void); -extern void random_artifact_resistance (object_type * o_ptr); -extern s16b floor_carry(int y, int x, object_type *j_ptr); -extern void pack_decay(int item); -extern void floor_decay(int item); -extern s16b m_bonus(int max, int level); -extern s32b flag_cost(object_type const *o_ptr, int plusses); +void inc_stack_size(int item, int delta); +void inc_stack_size_ex(int item, int delta, optimize_flag opt, describe_flag desc); +object_type *get_object(int item); +s32b calc_total_weight(); +void add_random_ego_flag(object_type *o_ptr, ego_flag_set const &fego, bool_ *limit_blows); +bool init_match_theme(obj_theme const &theme); +bool_ kind_is_artifactable(int k_idx); +bool_ kind_is_legal(int k_idx); +void inven_item_charges(int item); +void inven_item_describe(int item); +void inven_item_increase(int item, int num); +bool_ inven_item_optimize(int item); +void floor_item_charges(int item); +void floor_item_describe(int item); +void floor_item_increase(int item, int num); +void floor_item_optimize(int item); +bool_ inven_carry_okay(object_type const *o_ptr); +s16b inven_carry(object_type *o_ptr, bool_ final); +s16b inven_takeoff(int item, int amt, bool_ force_drop); +void inven_drop(int item, int amt, int dy, int dx, bool_ silent); +void excise_object_idx(int o_idx); +void delete_object_idx(int o_idx); +void delete_object(int y, int x); +void compact_objects(int size); +void wipe_o_list(); +s16b o_pop(); +errr get_obj_num_prep(); +s16b get_obj_num(int level); +void object_known(object_type *o_ptr); +bool object_known_p(object_type const *o_ptr); +void object_aware(object_type *o_ptr); +bool object_aware_p(object_type const *o_ptr); +void object_tried(object_type *o_ptr); +bool object_tried_p(object_type const *o_ptr); +s32b object_value(object_type const *o_ptr); +s32b object_value_real(object_type const *o_ptr); +bool_ object_similar(object_type const *o_ptr, object_type const *j_ptr); +void object_absorb(object_type *o_ptr, object_type *j_ptr); +s16b lookup_kind(int tval, int sval); +void object_wipe(object_type *o_ptr); +void object_prep(object_type *o_ptr, int k_idx); +void object_copy(object_type *o_ptr, object_type *j_ptr); +void apply_magic(object_type *o_ptr, int lev, bool_ okay, bool_ good, bool_ great, boost::optional<int> force_power = boost::none); +bool_ make_object(object_type *j_ptr, bool_ good, bool_ great, obj_theme const &theme); +void place_object(int y, int x, bool_ good, bool_ great, int where); +bool_ make_gold(object_type *j_ptr); +void place_gold(int y, int x); +s16b drop_near(object_type *o_ptr, int chance, int y, int x); +void acquirement(int y1, int x1, int num, bool_ great, bool_ known); +void combine_pack(); +void reorder_pack(); +void random_artifact_resistance(object_type * o_ptr); +s16b floor_carry(int y, int x, object_type *j_ptr); +void pack_decay(int item); +void floor_decay(int item); +s16b m_bonus(int max, int level); +s32b flag_cost(object_type const *o_ptr, int plusses); diff --git a/src/object_filter.cc b/src/object_filter.cc index 39961146..936eef7d 100644 --- a/src/object_filter.cc +++ b/src/object_filter.cc @@ -17,33 +17,10 @@ object_filter_t SVal(byte sval) { }; } -object_filter_t HasFlag3(u32b mask) { +object_filter_t HasFlags(object_flag_set const &mask) { return [=](object_type const *o_ptr) -> bool { - // Extract the flags - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - // Does the item have the flag? - return (f3 & mask); - }; -} - -object_filter_t HasFlag4(u32b mask) { - return [=](object_type const *o_ptr) -> bool { - // Extract the flags - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - // Does the item have the flag? - return (f4 & mask); - }; -} - -object_filter_t HasFlag5(u32b mask) { - return [=](object_type const *o_ptr) -> bool { - // Extract the flags - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - // Does the item have the flag? - return (f5 & mask); + auto const flags = object_flags(o_ptr); + return bool(flags & mask); }; } diff --git a/src/object_filter.hpp b/src/object_filter.hpp index 9a22090b..d18e13ee 100644 --- a/src/object_filter.hpp +++ b/src/object_filter.hpp @@ -1,6 +1,7 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" #include "object_type_fwd.hpp" #include <functional> @@ -21,19 +22,9 @@ object_filter_t TVal(byte tval); object_filter_t SVal(byte sval); /** - * Has given bit mask in flag3 value. + * Has given set of flags set. */ -object_filter_t HasFlag3(u32b mask); - -/** - * Has given bit mask in flag4 value. - */ -object_filter_t HasFlag4(u32b mask); - -/** - * Has given bit mask in flag5 value. - */ -object_filter_t HasFlag5(u32b mask); +object_filter_t HasFlags(object_flag_set const &); /** * Is the object an artifact? diff --git a/src/object_flag.hpp b/src/object_flag.hpp new file mode 100644 index 00000000..d5ec2fef --- /dev/null +++ b/src/object_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "object_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define TR(tier, index, name, e_name, c_name, c_page, c_col, c_row, c_type, c_prio, is_pval, is_esp) \ + DECLARE_FLAG(object_flag_set, name, tier, index) +#include "object_flag_list.hpp" +#undef TR diff --git a/src/object_flag_list.hpp b/src/object_flag_list.hpp new file mode 100644 index 00000000..a7aef7d4 --- /dev/null +++ b/src/object_flag_list.hpp @@ -0,0 +1,185 @@ +/** + * X-macro list of all the object flags. + * + * Parameters: + * + * - e_name: name of the flag in the edit files. + * - c_name: name of the flag on the character sheet + * (10 characters max). If nullptrptr the + * flag doesn't appear and the other c_* + * values are ignored. + * - c_page: page on the character sheet (0-3). + * - c_col: column number on the character sheet (0-1). + * - c_row: row number on the character sheet (0-15). + * - c_type: type of the character sheet; either + * NUMERIC, BINARY or TERNARY(n). + * - c_prio: priority if the flag overlaps another flag + * on the character sheet. 0 is lowes priority. + * - is_pval: true iff the flag _description_ depends on PVAL. + * - is_esp: true iff the flag affects ESP. + */ + +/* TR(<tier>, <index>, <name>, <e_name>, <c_name>, <c_page>, <c_col>, <c_row>, <c_type>, <c_prio>, <is_pval>, <is_esp>) */ + +TR(1, 0, TR_STR , STR , "Add Str" , 0, 0, 0, NUMERIC , 0, true , false) +TR(1, 1, TR_INT , INT , "Add Int" , 0, 0, 1, NUMERIC , 0, true , false) +TR(1, 2, TR_WIS , WIS , "Add Wis" , 0, 0, 2, NUMERIC , 0, true , false) +TR(1, 3, TR_DEX , DEX , "Add Dex" , 0, 0, 3, NUMERIC , 0, true , false) +TR(1, 4, TR_CON , CON , "Add Con" , 0, 0, 4, NUMERIC , 0, true , false) +TR(1, 5, TR_CHR , CHR , "Add Chr" , 0, 0, 5, NUMERIC , 0, true , false) +TR(1, 6, TR_MANA , MANA , "Mul Mana" , 0, 0, 6, BINARY , 0, false, false) +TR(1, 7, TR_SPELL , SPELL , "Mul SPower", 0, 0, 7, BINARY , 0, true , false) +TR(1, 8, TR_STEALTH , STEALTH , "Add Stea." , 0, 0, 8, NUMERIC , 0, true , false) +TR(1, 10, TR_INFRA , INFRA , "Add Infra" , 0, 0, 9, NUMERIC , 0, true , false) +TR(1, 11, TR_TUNNEL , TUNNEL , "Add Tun.." , 0, 0, 10, NUMERIC , 0, true , false) +TR(1, 12, TR_SPEED , SPEED , "Add Speed" , 0, 0, 11, NUMERIC , 0, true , false) +TR(1, 13, TR_BLOWS , BLOWS , "Add Blows" , 0, 0, 12, NUMERIC , 0, true , false) +TR(1, 14, TR_CHAOTIC , CHAOTIC , "Chaotic" , 0, 0, 13, BINARY , 0, false, false) +TR(1, 15, TR_VAMPIRIC , VAMPIRIC , "Vampiric" , 0, 0, 14, BINARY , 0, false, false) +TR(1, 16, TR_SLAY_ANIMAL , SLAY_ANIMAL , "Slay Anim.", 0, 1, 0, BINARY , 0, false, false) +TR(1, 17, TR_SLAY_EVIL , SLAY_EVIL , "Slay Evil" , 0, 1, 1, BINARY , 0, false, false) +TR(1, 18, TR_SLAY_UNDEAD , SLAY_UNDEAD , "Slay Und." , 0, 1, 2, BINARY , 0, false, false) +TR(1, 19, TR_SLAY_DEMON , SLAY_DEMON , "Slay Demon", 0, 1, 3, BINARY , 0, false, false) +TR(1, 20, TR_SLAY_ORC , SLAY_ORC , "Slay Orc" , 0, 1, 4, BINARY , 0, false, false) +TR(1, 21, TR_SLAY_TROLL , SLAY_TROLL , "Slay Troll", 0, 1, 5, BINARY , 0, false, false) +TR(1, 22, TR_SLAY_GIANT , SLAY_GIANT , "Slay Giant", 0, 1, 6, BINARY , 0, false, false) +TR(1, 23, TR_SLAY_DRAGON , SLAY_DRAGON , "Slay Drag.", 0, 1, 7, BINARY , 0, false, false) +TR(1, 24, TR_KILL_DRAGON , KILL_DRAGON , "Kill Drag.", 0, 1, 8, BINARY , 0, false, false) +TR(1, 25, TR_VORPAL , VORPAL , "Sharpness" , 0, 1, 9, BINARY , 0, false, false) +TR(1, 26, TR_IMPACT , IMPACT , "Impact" , 0, 1, 10, BINARY , 0, false, false) +TR(1, 27, TR_BRAND_POIS , BRAND_POIS , "Poison Brd", 0, 1, 11, BINARY , 0, false, false) +TR(1, 28, TR_BRAND_ACID , BRAND_ACID , "Acid Brand", 0, 1, 12, BINARY , 0, false, false) +TR(1, 29, TR_BRAND_ELEC , BRAND_ELEC , "Elec Brand", 0, 1, 13, BINARY , 0, false, false) +TR(1, 30, TR_BRAND_FIRE , BRAND_FIRE , "Fire Brand", 0, 1, 14, BINARY , 0, false, false) +TR(1, 31, TR_BRAND_COLD , BRAND_COLD , "Cold Brand", 0, 1, 15, BINARY , 0, false, false) + +TR(2, 0, TR_SUST_STR , SUST_STR , "Sust Str" , 1, 0, 0, BINARY , 0, false, false) +TR(2, 1, TR_SUST_INT , SUST_INT , "Sust Int" , 1, 0, 1, BINARY , 0, false, false) +TR(2, 2, TR_SUST_WIS , SUST_WIS , "Sust Wis" , 1, 0, 2, BINARY , 0, false, false) +TR(2, 3, TR_SUST_DEX , SUST_DEX , "Sust Dex" , 1, 0, 3, BINARY , 0, false, false) +TR(2, 4, TR_SUST_CON , SUST_CON , "Sust Con" , 1, 0, 4, BINARY , 0, false, false) +TR(2, 5, TR_SUST_CHR , SUST_CHR , "Sust Chr" , 1, 0, 5, BINARY , 0, false, false) +TR(2, 6, TR_INVIS , INVIS , "Invisible" , 1, 0, 6, BINARY , 0, false, false) +TR(2, 7, TR_LIFE , LIFE , "Mul life" , 1, 0, 7, BINARY , 0, false, false) +TR(2, 8, TR_IM_ACID , IM_ACID , "Imm Acid" , 1, 1, 0, TERNARY(2), 1, false, false) +TR(2, 9, TR_IM_ELEC , IM_ELEC , "Imm Elec" , 1, 1, 1, TERNARY(2), 1, false, false) +TR(2, 10, TR_IM_FIRE , IM_FIRE , "Imm Fire" , 1, 1, 2, TERNARY(2), 1, false, false) +TR(2, 11, TR_IM_COLD , IM_COLD , "Imm Cold" , 1, 1, 3, TERNARY(2), 1, false, false) +TR(2, 12, TR_SENS_FIRE , SENS_FIRE , "Sens Fire" , 1, 0, 12, BINARY , 0, false, false) +TR(2, 13, TR_REFLECT , REFLECT , "Reflect" , 1, 0, 13, BINARY , 0, false, false) +TR(2, 14, TR_FREE_ACT , FREE_ACT , "Free Act" , 1, 0, 14, BINARY , 0, false, false) +TR(2, 15, TR_HOLD_LIFE , HOLD_LIFE , "Hold Life" , 1, 0, 15, BINARY , 0, false, false) +TR(2, 16, TR_RES_ACID , RES_ACID , "Res Acid" , 1, 1, 0, TERNARY(1), 0, false, false) +TR(2, 17, TR_RES_ELEC , RES_ELEC , "Res Elec" , 1, 1, 1, TERNARY(1), 0, false, false) +TR(2, 18, TR_RES_FIRE , RES_FIRE , "Res Fire" , 1, 1, 2, TERNARY(1), 0, false, false) +TR(2, 19, TR_RES_COLD , RES_COLD , "Res Cold" , 1, 1, 3, TERNARY(1), 0, false, false) +TR(2, 20, TR_RES_POIS , RES_POIS , "Res Pois" , 1, 1, 4, BINARY , 0, false, false) +TR(2, 21, TR_RES_FEAR , RES_FEAR , "Res Fear" , 1, 1, 5, BINARY , 0, false, false) +TR(2, 22, TR_RES_LITE , RES_LITE , "Res Light" , 1, 1, 6, BINARY , 0, false, false) +TR(2, 23, TR_RES_DARK , RES_DARK , "Res Dark" , 1, 1, 7, BINARY , 0, false, false) +TR(2, 24, TR_RES_BLIND , RES_BLIND , "Res Blind" , 1, 1, 8, BINARY , 0, false, false) +TR(2, 25, TR_RES_CONF , RES_CONF , "Res Conf" , 1, 1, 9, BINARY , 0, false, false) +TR(2, 26, TR_RES_SOUND , RES_SOUND , "Res Sound" , 1, 1, 10, BINARY , 0, false, false) +TR(2, 27, TR_RES_SHARDS , RES_SHARDS , "Res Shard" , 1, 1, 11, BINARY , 0, false, false) +TR(2, 28, TR_RES_NETHER , RES_NETHER , "Res Neth" , 1, 1, 12, TERNARY(1), 0, false, false) +TR(2, 29, TR_RES_NEXUS , RES_NEXUS , "Res Nexus" , 1, 1, 13, BINARY , 0, false, false) +TR(2, 30, TR_RES_CHAOS , RES_CHAOS , "Res Chaos" , 1, 1, 14, BINARY , 0, false, false) +TR(2, 31, TR_RES_DISEN , RES_DISEN , "Res Disen" , 1, 1, 15, BINARY , 0, false, false) + +TR(3, 0, TR_SH_FIRE , SH_FIRE , "Aura Fire" , 2, 0, 0, BINARY , 0, false, false) +TR(3, 1, TR_SH_ELEC , SH_ELEC , "Aura Elec" , 2, 0, 1, BINARY , 0, false, false) +TR(3, 2, TR_AUTO_CURSE , AUTO_CURSE , "Auto Curse", 2, 0, 2, BINARY , 0, false, false) +TR(3, 3, TR_DECAY , DECAY , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 4, TR_NO_TELE , NO_TELE , "NoTeleport", 2, 0, 4, BINARY , 0, false, false) +TR(3, 5, TR_NO_MAGIC , NO_MAGIC , "AntiMagic" , 2, 0, 5, BINARY , 0, false, false) +TR(3, 6, TR_WRAITH , WRAITH , "WraithForm", 2, 0, 6, BINARY , 0, false, false) +TR(3, 7, TR_TY_CURSE , TY_CURSE , "EvilCurse" , 2, 0, 7, BINARY , 0, false, false) +TR(3, 8, TR_EASY_KNOW , EASY_KNOW , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 9, TR_HIDE_TYPE , HIDE_TYPE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 10, TR_SHOW_MODS , SHOW_MODS , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 11, TR_INSTA_ART , INSTA_ART , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 12, TR_FEATHER , FEATHER , "Levitate" , 2, 0, 12, BINARY , 0, false, false) +TR(3, 13, TR_LITE1 , LITE1 , "Lite" , 2, 0, 13, FIXED(1) , 0, false, false) +TR(3, 14, TR_SEE_INVIS , SEE_INVIS , "See Invis" , 2, 0, 14, BINARY , 0, false, false) +TR(3, 15, TR_NORM_ART , NORM_ART , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 16, TR_SLOW_DIGEST , SLOW_DIGEST , "Digestion" , 2, 1, 0, BINARY , 0, false, false) +TR(3, 17, TR_REGEN , REGEN , "Regen" , 2, 1, 1, BINARY , 0, false, false) +TR(3, 18, TR_XTRA_MIGHT , XTRA_MIGHT , "Xtra Might", 2, 1, 2, BINARY , 0, false, false) +TR(3, 19, TR_XTRA_SHOTS , XTRA_SHOTS , "Xtra Shots", 2, 1, 3, BINARY , 0, false, false) +TR(3, 20, TR_IGNORE_ACID , IGNORE_ACID , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 21, TR_IGNORE_ELEC , IGNORE_ELEC , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 22, TR_IGNORE_FIRE , IGNORE_FIRE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 23, TR_IGNORE_COLD , IGNORE_COLD , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(3, 24, TR_ACTIVATE , ACTIVATE , "Activate" , 2, 1, 8, BINARY , 0, false, false) +TR(3, 25, TR_DRAIN_EXP , DRAIN_EXP , "Drain Exp" , 2, 1, 9, BINARY , 0, false, false) +TR(3, 26, TR_TELEPORT , TELEPORT , "Teleport" , 2, 1, 10, BINARY , 0, false, false) +TR(3, 27, TR_AGGRAVATE , AGGRAVATE , "Aggravate" , 2, 1, 11, BINARY , 0, false, false) +TR(3, 28, TR_BLESSED , BLESSED , "Blessed" , 2, 1, 12, BINARY , 0, false, false) +TR(3, 29, TR_CURSED , CURSED , "Cursed" , 2, 1, 13, BINARY , 0, false, false) +TR(3, 30, TR_HEAVY_CURSE , HEAVY_CURSE , "Hvy Curse" , 2, 1, 14, BINARY , 0, false, false) +TR(3, 31, TR_PERMA_CURSE , PERMA_CURSE , "Prm Curse" , 2, 1, 15, BINARY , 0, false, false) + +TR(4, 0, TR_NEVER_BLOW , NEVER_BLOW , "No blows" , 3, 0, 0, BINARY , 0, false, false) +TR(4, 1, TR_PRECOGNITION , PRECOGNITION , "Precogn." , 3, 0, 1, BINARY , 0, false, false) +TR(4, 2, TR_BLACK_BREATH , BLACK_BREATH , "B.Breath" , 3, 0, 2, BINARY , 0, false, false) +TR(4, 3, TR_RECHARGE , RECHARGE , "Recharge" , 3, 0, 3, BINARY , 0, false, false) +TR(4, 4, TR_FLY , FLY , "Fly" , 3, 0, 4, BINARY , 0, false, false) +TR(4, 5, TR_DG_CURSE , DG_CURSE , "Mrg.Curse" , 3, 0, 5, BINARY , 0, false, false) +TR(4, 6, TR_COULD2H , COULD2H , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 7, TR_MUST2H , MUST2H , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 8, TR_LEVELS , LEVELS , "Sentient" , 3, 0, 8, BINARY , 0, false, false) +TR(4, 9, TR_CLONE , CLONE , "Clone" , 3, 0, 9, BINARY , 0, false, false) +TR(4, 10, TR_SPECIAL_GENE , SPECIAL_GENE , nullptr , 3, 0, 10, BINARY , 0, false, false) +TR(4, 11, TR_CLIMB , CLIMB , "Climb" , 3, 0, 11, BINARY , 0, false, false) +TR(4, 12, TR_FAST_CAST , FAST_CAST , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 13, TR_CAPACITY , CAPACITY , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 14, TR_CHARGING , CHARGING , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 15, TR_CHEAPNESS , CHEAPNESS , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 16, TR_FOUNTAIN , FOUNTAIN , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 17, TR_ANTIMAGIC_50 , ANTIMAGIC_50 , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 21, TR_EASY_USE , EASY_USE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 22, TR_IM_NETHER , IM_NETHER , "Imm Neth" , 1, 1, 12, TERNARY(2), 1, false, false) +TR(4, 23, TR_RECHARGED , RECHARGED , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 24, TR_ULTIMATE , ULTIMATE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 25, TR_AUTO_ID , AUTO_ID , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 26, TR_LITE2 , LITE2 , "Lite" , 2, 0, 13, FIXED(2) , 0, false, false) +TR(4, 27, TR_LITE3 , LITE3 , "Lite" , 2, 0, 13, FIXED(3) , 0, false, false) +TR(4, 28, TR_FUEL_LITE , FUEL_LITE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 30, TR_CURSE_NO_DROP , CURSE_NO_DROP , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(4, 31, TR_NO_RECHARGE , NO_RECHARGE , nullptr , -1, -1, -1, BINARY , 0, false, false) + +TR(5, 0, TR_TEMPORARY , TEMPORARY , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 1, TR_DRAIN_MANA , DRAIN_MANA , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 2, TR_DRAIN_HP , DRAIN_HP , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 3, TR_KILL_DEMON , KILL_DEMON , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 4, TR_KILL_UNDEAD , KILL_UNDEAD , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 5, TR_CRIT , CRIT , nullptr , -1, -1, -1, BINARY , 0, true , false) +TR(5, 6, TR_ATTR_MULTI , ATTR_MULTI , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 7, TR_WOUNDING , WOUNDING , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 8, TR_FULL_NAME , FULL_NAME , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 9, TR_LUCK , LUCK , nullptr , -1, -1, -1, BINARY , 0, true , false) +TR(5, 10, TR_IMMOVABLE , IMMOVABLE , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 11, TR_SPELL_CONTAIN , SPELL_CONTAIN , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 12, TR_RES_MORGUL , RES_MORGUL , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 13, TR_ACTIVATE_NO_WIELD , ACTIVATE_NO_WIELD , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 14, TR_MAGIC_BREATH , MAGIC_BREATH , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 15, TR_WATER_BREATH , WATER_BREATH , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 16, TR_WIELD_CAST , WIELD_CAST , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 17, TR_RANDOM_RESIST , RANDOM_RESIST , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 18, TR_RANDOM_POWER , RANDOM_POWER , nullptr , -1, -1, -1, BINARY , 0, false, false) +TR(5, 19, TR_RANDOM_RES_OR_POWER, RANDOM_RES_OR_POWER, nullptr , -1, -1, -1, BINARY , 0, false, false) + +TR(6, 0, ESP_ORC , ESP_ORC , "Orc.ESP" , 3, 1, 0, BINARY , 0, false, true ) +TR(6, 1, ESP_TROLL , ESP_TROLL , "Troll.ESP" , 3, 1, 1, BINARY , 0, false, true ) +TR(6, 2, ESP_DRAGON , ESP_DRAGON , "Dragon.ESP", 3, 1, 2, BINARY , 0, false, true ) +TR(6, 3, ESP_GIANT , ESP_GIANT , "Giant.ESP" , 3, 1, 3, BINARY , 0, false, true ) +TR(6, 4, ESP_DEMON , ESP_DEMON , "Demon.ESP" , 3, 1, 4, BINARY , 0, false, true ) +TR(6, 5, ESP_UNDEAD , ESP_UNDEAD , "Undead.ESP", 3, 1, 5, BINARY , 0, false, true ) +TR(6, 6, ESP_EVIL , ESP_EVIL , "Evil.ESP" , 3, 1, 6, BINARY , 0, false, true ) +TR(6, 7, ESP_ANIMAL , ESP_ANIMAL , "Animal.ESP", 3, 1, 7, BINARY , 0, false, true ) +TR(6, 8, ESP_THUNDERLORD , ESP_THUNDERLORD , "TLord.ESP" , 3, 1, 8, BINARY , 0, false, true ) +TR(6, 9, ESP_GOOD , ESP_GOOD , "Good.ESP" , 3, 1, 9, BINARY , 0, false, true ) +TR(6, 10, ESP_NONLIVING , ESP_NONLIVING , "Nlive.ESP" , 3, 1, 10, BINARY , 0, false, true ) +TR(6, 11, ESP_UNIQUE , ESP_UNIQUE , "Unique.ESP", 3, 1, 11, BINARY , 0, false, true ) +TR(6, 12, ESP_SPIDER , ESP_SPIDER , "Spider ESP", 3, 1, 12, BINARY , 0, false, true ) +TR(6, 31, ESP_ALL , ESP_ALL , "Full ESP" , 3, 1, 15, BINARY , 0, false, true ) diff --git a/src/object_flag_meta.cc b/src/object_flag_meta.cc new file mode 100644 index 00000000..89b91fea --- /dev/null +++ b/src/object_flag_meta.cc @@ -0,0 +1,59 @@ +#include "object_flag_meta.hpp" + +#include "object_flag.hpp" + +std::vector<object_flag_meta const *> const &object_flags_meta() +{ + static std::vector<object_flag_meta const *> instance; + + if (instance.empty()) + { +#define NUMERIC 'n' +#define BINARY 'b' +#define TERNARY(n) ((n == 1) ? '+' : ((n == 2) ? '*' : '?')) +#define FIXED(n) ((n == 1) ? '1' : ((n == 2) ? '2' : ((n == 3) ? '3' : '?'))) +#define TR(tier, index, name, e_name, c_name, c_page, c_col, c_row, c_type, c_prio, is_pval, is_esp) \ + instance.emplace_back(new object_flag_meta { \ + name, \ + #name, \ + #e_name, \ + c_name, \ + c_page, \ + c_col, \ + c_row, \ + c_type, \ + c_prio, \ + is_pval, \ + is_esp \ + }); +#include "object_flag_list.hpp" +#undef TR +#undef FIXED +#undef TERNARY +#undef BINARY +#undef NUMERIC + }; + + return instance; +} + +object_flag_set const &object_flags_esp() +{ + static object_flag_set instance; + static bool initialized = false; + + if (!initialized) + { + for (auto const object_flag_meta: object_flags_meta()) + { + if (object_flag_meta->is_esp) + { + instance |= object_flag_meta->flag_set; + } + } + + initialized = true; + } + + return instance; +} diff --git a/src/object_flag_meta.hpp b/src/object_flag_meta.hpp new file mode 100644 index 00000000..d488c0d5 --- /dev/null +++ b/src/object_flag_meta.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include "object_flag_set.hpp" + +#include <vector> + +struct object_flag_meta { + + /** + * Flag set representation of the object flag. + */ + const object_flag_set flag_set; + + /** + * Name of the object flag. + */ + const char *name; + + /** + * Edit file name of the object flag. + */ + const char *e_name; + + /** + * Character sheet name of the object flag. + */ + const char *c_name; + + /** + * Character sheet page. + */ + const int c_page; + + /** + * Character sheet column. + */ + const int c_column; + + /** + * Character sheet row. + */ + const int c_row; + + /** + * Character sheet type. + */ + char c_type; + + /** + * Priority wrt. other flags in the same position + * on the character sheet. + */ + int c_priority; + + /** + * Is this flag *described* using PVAL? + */ + bool is_pval; + + /** + * Is this a flag which affects ESP? + */ + bool is_esp; + +}; + +/** + * Get a vector of all the object flags. + */ +std::vector<object_flag_meta const *> const &object_flags_meta(); + +/** + * Get a flag representing all ESP flags. + */ +object_flag_set const &object_flags_esp(); diff --git a/src/object_flag_set.hpp b/src/object_flag_set.hpp new file mode 100644 index 00000000..a4e8f874 --- /dev/null +++ b/src/object_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t TR_MAX_TIERS = 6; + +typedef flag_set<TR_MAX_TIERS> object_flag_set; diff --git a/src/object_kind.hpp b/src/object_kind.hpp index 505f54d9..2f347f3f 100644 --- a/src/object_kind.hpp +++ b/src/object_kind.hpp @@ -1,6 +1,7 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" /** * Size of allocation table for objects @@ -14,70 +15,59 @@ constexpr int ALLOCATION_MAX = 8; */ struct object_kind { - const char *name; /* Name */ - char *text; /* Text */ + const char *name = nullptr; /* Name */ + char *text = nullptr; /* Text */ - byte tval; /* Object type */ - byte sval; /* Object sub type */ + byte tval = 0; /* Object type */ + byte sval = 0; /* Object sub type */ - s32b pval; /* Object extra info */ - s32b pval2; /* Object extra info */ + s32b pval = 0; /* Object extra info */ + s32b pval2 = 0; /* Object extra info */ - s16b to_h; /* Bonus to hit */ - s16b to_d; /* Bonus to damage */ - s16b to_a; /* Bonus to armor */ + s16b to_h = 0; /* Bonus to hit */ + s16b to_d = 0; /* Bonus to damage */ + s16b to_a = 0; /* Bonus to armor */ - s16b activate; /* Activation number */ + s16b activate = 0; /* Activation number */ - s16b ac; /* Base armor */ + s16b ac = 0; /* Base armor */ - byte dd, ds; /* Damage dice/sides */ + byte dd = 0; /* Damage dice */ + byte ds = 0; /* Damage sides */ - s32b weight; /* Weight */ + s32b weight = 0; /* Weight */ - s32b cost; /* Object "base cost" */ + s32b cost = 0; /* Object "base cost" */ - u32b flags1; /* Flags, set 1 */ - u32b flags2; /* Flags, set 2 */ - u32b flags3; /* Flags, set 3 */ - u32b flags4; /* Flags, set 4 */ - u32b flags5; /* Flags, set 5 */ + object_flag_set flags; - u32b oflags1; /* Obvious Flags, set 1 */ - u32b oflags2; /* Obvious Flags, set 2 */ - u32b oflags3; /* Obvious Flags, set 3 */ - u32b oflags4; /* Obvious Flags, set 4 */ - u32b oflags5; /* Obvious Flags, set 5 */ + object_flag_set oflags; - byte locale[ALLOCATION_MAX]; /* Allocation level(s) */ - byte chance[ALLOCATION_MAX]; /* Allocation chance(s) */ + byte locale[ALLOCATION_MAX] = { 0 }; /* Allocation level(s) */ + byte chance[ALLOCATION_MAX] = { 0 }; /* Allocation chance(s) */ - byte level; /* Level */ + byte level = 0; /* Level */ - byte d_attr; /* Default object attribute */ - char d_char; /* Default object character */ + byte d_attr = 0; /* Default object attribute */ + char d_char = 0; /* Default object character */ - byte x_attr; /* Desired object attribute */ - char x_char; /* Desired object character */ + byte x_attr = 0; /* Desired object attribute */ + char x_char = 0; /* Desired object character */ - byte flavor; /* Special object flavor (or zero) */ + byte flavor = 0; /* Special object flavor (or zero) */ - bool_ easy_know; /* This object is always known (if aware) */ + bool_ easy_know = 0; /* This object is always known (if aware) */ + bool_ aware = 0; /* The player is "aware" of the item's effects */ - bool_ aware; /* The player is "aware" of the item's effects */ + bool_ tried = 0; /* The player has "tried" one of the items */ - bool_ tried; /* The player has "tried" one of the items */ + byte btval = 0; /* Become Object type */ + byte bsval = 0; /* Become Object sub type */ + bool_ artifact = 0; /* Is it a normal artifact(already generated) */ - u32b esp; /* ESP flags */ - u32b oesp; /* Obvious ESP flags */ - - byte btval; /* Become Object type */ - byte bsval; /* Become Object sub type */ - bool_ artifact; /* Is it a normal artifact(already generated) */ - - s16b power; /* Power granted(if any) */ + s16b power = 0; /* Power granted(if any) */ }; diff --git a/src/object_kind_fwd.hpp b/src/object_kind_fwd.hpp deleted file mode 100644 index 6d26db9f..00000000 --- a/src/object_kind_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct object_kind; diff --git a/src/object_proto.hpp b/src/object_proto.hpp new file mode 100644 index 00000000..faa0b2e8 --- /dev/null +++ b/src/object_proto.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "h-basic.h" + +struct object_proto +{ + s16b tval = 0; + s16b sval = 0; + s16b pval = 0; + s16b dd = 0; + s16b ds = 0; +}; diff --git a/src/object_type.hpp b/src/object_type.hpp index d7f003e6..3a34d181 100644 --- a/src/object_type.hpp +++ b/src/object_type.hpp @@ -1,6 +1,9 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" + +#include <string> /** * Object information for a specific object. @@ -31,74 +34,63 @@ */ struct object_type { - s16b k_idx; /* Kind index (zero if "dead") */ + s16b k_idx = 0; /* Kind index (zero if "dead") */ - byte iy; /* Y-position on map, or zero */ - byte ix; /* X-position on map, or zero */ + byte iy = 0; /* Y-position on map, or zero */ + byte ix = 0; /* X-position on map, or zero */ - byte tval; /* Item type (from kind) */ - byte sval; /* Item sub-type (from kind) */ + byte tval = 0; /* Item type (from kind) */ + byte sval = 0; /* Item sub-type (from kind) */ - s32b pval; /* Item extra-parameter */ - s16b pval2; /* Item extra-parameter for some special - items*/ - s32b pval3; /* Item extra-parameter for some special - items*/ + s32b pval = 0; /* Item extra-parameter */ + s16b pval2 = 0; /* Item extra-parameter for some special items */ + s32b pval3 = 0; /* Item extra-parameter for some special items */ - byte discount; /* Discount (if any) */ + byte discount = 0; /* Discount (if any) */ - byte number; /* Number of items */ + byte number = 0; /* Number of items */ - s32b weight; /* Item weight */ + s32b weight = 0; /* Item weight */ - byte elevel; /* Item exp level */ - s32b exp; /* Item exp */ + byte elevel = 0; /* Item exp level */ + s32b exp = 0; /* Item exp */ - byte name1; /* Artifact type, if any */ - s16b name2; /* Ego-Item type, if any */ - s16b name2b; /* Second Ego-Item type, if any */ + byte name1 = 0; /* Artifact type, if any */ + s16b name2 = 0; /* Ego-Item type, if any */ + s16b name2b = 0; /* Second Ego-Item type, if any */ - byte xtra1; /* Extra info type */ - s16b xtra2; /* Extra info index */ + byte xtra1 = 0; /* Extra info type */ + s16b xtra2 = 0; /* Extra info index */ - s16b to_h; /* Plusses to hit */ - s16b to_d; /* Plusses to damage */ - s16b to_a; /* Plusses to AC */ + s16b to_h = 0; /* Plusses to hit */ + s16b to_d = 0; /* Plusses to damage */ + s16b to_a = 0; /* Plusses to AC */ - s16b ac; /* Normal AC */ + s16b ac = 0; /* Normal AC */ - byte dd, ds; /* Damage dice/sides */ + byte dd = 0; /* Damage dice/sides */ + byte ds = 0; /* Damage dice/sides */ - s16b timeout; /* Timeout Counter */ + s16b timeout = 0; /* Timeout Counter */ - byte ident; /* Special flags */ + byte ident = 0; /* Special flags */ - byte marked; /* Object is marked */ + byte marked = 0; /* Object is marked */ - u16b note; /* Inscription index */ - u16b art_name; /* Artifact name (random artifacts) */ + std::string inscription; /* Inscription index */ - u32b art_flags1; /* Flags, set 1 Alas, these were necessary */ - u32b art_flags2; /* Flags, set 2 for the random artifacts of*/ - u32b art_flags3; /* Flags, set 3 Zangband */ - u32b art_flags4; /* Flags, set 4 PernAngband */ - u32b art_flags5; /* Flags, set 5 PernAngband */ - u32b art_esp; /* Flags, set esp PernAngband */ + std::string artifact_name; /* Artifact name */ - u32b art_oflags1; /* Obvious Flags, set 1 */ - u32b art_oflags2; /* Obvious Flags, set 2 */ - u32b art_oflags3; /* Obvious Flags, set 3 */ - u32b art_oflags4; /* Obvious Flags, set 4 */ - u32b art_oflags5; /* Obvious Flags, set 5 */ - u32b art_oesp; /* Obvious Flags, set esp */ + object_flag_set art_flags; /* Flags */ + object_flag_set art_oflags; /* Obvious flags */ - s16b held_m_idx; /* Monster holding us (if any) */ + s16b held_m_idx = 0; /* Monster holding the object; if any */ - byte sense; /* Pseudo-id status */ + byte sense = 0; /* Pseudo-id status */ - byte found; /* How did we find it */ - s16b found_aux1; /* Stores info for found */ - s16b found_aux2; /* Stores info for found */ - s16b found_aux3; /* Stores info for found */ - s16b found_aux4; /* Stores info for found */ + byte found = 0; /* How did we find it */ + s16b found_aux1 = 0; /* Stores info for found */ + s16b found_aux2 = 0; /* Stores info for found */ + s16b found_aux3 = 0; /* Stores info for found */ + s16b found_aux4 = 0; /* Stores info for found */ }; diff --git a/src/option_type.hpp b/src/option_type.hpp index 58834b79..4d8a7a51 100644 --- a/src/option_type.hpp +++ b/src/option_type.hpp @@ -8,17 +8,11 @@ struct option_type { /** - * Address of actual option variable. NULL signals the - * end of the table. + * Address of actual option variable. */ bool_ *o_var; /** - * Default value. - */ - byte o_norm; - - /** * Option page number. */ byte o_page; diff --git a/src/options.cc b/src/options.cc index 5501ab52..ea2f3172 100644 --- a/src/options.cc +++ b/src/options.cc @@ -1,89 +1,10 @@ #include "options.hpp" -// -// Option Set 1 -- User Interface -// -bool_ rogue_like_commands; /* Rogue-like commands */ -bool_ quick_messages; /* Activate quick messages */ -bool_ carry_query_flag; /* Prompt before picking things up */ -bool_ use_old_target; /* Use old target by default */ -bool_ always_pickup; /* Pick things up by default */ -bool_ always_repeat; /* Repeat obvious commands */ -bool_ ring_bell; /* Ring the bell (on errors, etc) */ - -// -// Option Set 2 -- Disturbance -// -bool_ find_ignore_stairs; /* Run past stairs */ -bool_ find_ignore_doors; /* Run through open doors */ -bool_ find_cut; /* Run past known corners */ -bool_ find_examine; /* Run into potential corners */ -bool_ disturb_move; /* Disturb whenever any monster moves */ -bool_ disturb_near; /* Disturb whenever viewable monster moves */ -bool_ disturb_panel; /* Disturb whenever map panel changes */ -bool_ disturb_detect; /* Disturb whenever leaving trap-detected area */ -bool_ disturb_state; /* Disturn whenever player state changes */ -bool_ disturb_minor; /* Disturb whenever boring things happen */ -bool_ disturb_other; /* Disturb whenever various things happen */ -bool_ alert_hitpoint; /* Alert user to critical hitpoints */ -bool_ alert_failure; /* Alert user to various failures */ -bool_ last_words; /* Get last words upon dying */ -bool_ small_levels; /* Allow unusually small dungeon levels */ -bool_ empty_levels; /* Allow empty 'arena' levels */ -bool_ confirm_stairs; /* Prompt before staircases... */ -bool_ wear_confirm; /* Confirm before putting on known cursed items */ -bool_ disturb_pets; /* Pets moving nearby disturb us */ - -// -// Option Set 3 -- Game-Play -// -bool_ auto_scum; /* Auto-scum for good levels */ -bool_ view_perma_grids; /* Map remembers all perma-lit grids */ -bool_ view_torch_grids; /* Map remembers all torch-lit grids */ -bool_ dungeon_align; /* Generate dungeons with aligned rooms */ -bool_ dungeon_stair; /* Generate dungeons with connected stairs */ -bool_ flow_by_sound; /* Monsters track new player location */ -bool_ smart_learn; /* Monsters learn from their mistakes */ - -// -// Option Set 4 -- Efficiency -// -bool_ view_reduce_lite; /* Reduce lite-radius when running */ -bool_ avoid_abort; /* Avoid checking for user abort */ -bool_ avoid_shimmer; /* Avoid processing extra shimmering */ -bool_ avoid_other; /* Avoid processing special colors */ -bool_ flush_failure; /* Flush input on any failure */ -bool_ flush_disturb; /* Flush input on disturbance */ -bool_ flush_command; /* Flush input before every command */ -bool_ fresh_before; /* Flush output before normal commands */ -bool_ fresh_after; /* Flush output after normal commands */ -bool_ fresh_message; /* Flush output after all messages */ -bool_ hilite_player; /* Hilite the player with the cursor */ -bool_ view_yellow_lite; /* Use special colors for torch-lit grids */ -bool_ view_bright_lite; /* Use special colors for 'viewable' grids */ -bool_ view_granite_lite; /* Use special colors for wall grids (slow) */ -bool_ view_special_lite; /* Use special colors for floor grids (slow) */ -bool_ center_player; /* Center view on player */ - -// -// Option Set 5 - ToME options -// -bool_ linear_stats; -bool_ player_char_health; /* Display the player as a special symbol when in bad health ? */ -bool_ option_ingame_help; /* Ingame contextual help */ -bool_ auto_more; /* Auto more */ -bool_ inventory_no_move; /* In inventory option window, just erase the letters, - * rather that displaying the list without the invalid - * selections */ - -// -// Option Set 6 - Birth options -// -bool_ always_small_level; -bool_ autoroll; -bool_ fate_option; -bool_ ironman_rooms; -bool_ joke_monsters; -bool_ point_based; -bool_ preserve; -bool_ no_selling; +void options::reset_cheat_options() +{ + cheat_peek = FALSE; + cheat_hear = FALSE; + cheat_room = FALSE; + cheat_xtra = FALSE; + cheat_live = FALSE; +} diff --git a/src/options.hpp b/src/options.hpp index 45e19cf7..c1ac35a9 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -1,89 +1,215 @@ #pragma once #include "h-basic.h" +#include "option_type.hpp" -// -// Option Set 1 -- User Interface. -// -extern bool_ rogue_like_commands; -extern bool_ quick_messages; -extern bool_ carry_query_flag; -extern bool_ use_old_target; -extern bool_ always_pickup; -extern bool_ always_repeat; -extern bool_ ring_bell; - -// -// Option Set 2 -- Disturbance -// -extern bool_ find_ignore_stairs; -extern bool_ find_ignore_doors; -extern bool_ find_cut; -extern bool_ find_examine; -extern bool_ disturb_move; -extern bool_ disturb_near; -extern bool_ disturb_panel; -extern bool_ disturb_detect; -extern bool_ disturb_state; -extern bool_ disturb_minor; -extern bool_ disturb_other; -extern bool_ alert_hitpoint; -extern bool_ alert_failure; -extern bool_ last_words; -extern bool_ small_levels; -extern bool_ empty_levels; -extern bool_ confirm_stairs; -extern bool_ wear_confirm; -extern bool_ disturb_pets; - -// -// Option Set 3 -- Game-Play -// -extern bool_ auto_scum; -extern bool_ view_perma_grids; -extern bool_ view_torch_grids; -extern bool_ dungeon_align; -extern bool_ dungeon_stair; -extern bool_ flow_by_sound; -extern bool_ smart_learn; - -// -// Option Set 4 -- Efficiency -// -extern bool_ view_reduce_lite; -extern bool_ avoid_abort; -extern bool_ avoid_shimmer; -extern bool_ avoid_other; -extern bool_ flush_failure; -extern bool_ flush_disturb; -extern bool_ flush_command; -extern bool_ fresh_before; -extern bool_ fresh_after; -extern bool_ fresh_message; -extern bool_ hilite_player; -extern bool_ view_yellow_lite; -extern bool_ view_bright_lite; -extern bool_ view_granite_lite; -extern bool_ view_special_lite; -extern bool_ center_player; - -// -// Option Set 5 - ToME options -// -extern bool_ linear_stats; -extern bool_ player_char_health; -extern bool_ option_ingame_help; -extern bool_ auto_more; -extern bool_ inventory_no_move; - -// -// Option Set 6 - Birth options -// -extern bool_ always_small_level; -extern bool_ autoroll; -extern bool_ fate_option; -extern bool_ ironman_rooms; -extern bool_ joke_monsters; -extern bool_ point_based; -extern bool_ preserve; -extern bool_ no_selling; +#include <vector> + +/** + * Game options accessible via the '=' menu. + */ +struct options { + + // + // Option Set 1 -- User Interface + // + bool_ rogue_like_commands = FALSE; /* Rogue-like commands */ + bool_ quick_messages = TRUE; /* Activate quick messages */ + bool_ carry_query_flag = FALSE; /* Prompt before picking things up */ + bool_ use_old_target = FALSE; /* Use old target by default */ + bool_ always_pickup = FALSE; /* Pick things up by default */ + bool_ always_repeat = TRUE; /* Repeat obvious commands */ + bool_ ring_bell = FALSE; /* Ring the bell (on errors, etc) */ + + // + // Option Set 2 -- Disturbance + // + bool_ find_ignore_stairs = FALSE; /* Run past stairs */ + bool_ find_ignore_doors = TRUE; /* Run through open doors */ + bool_ find_cut = FALSE; /* Run past known corners */ + bool_ find_examine = TRUE; /* Run into potential corners */ + bool_ disturb_move = FALSE; /* Disturb whenever any monster moves */ + bool_ disturb_near = TRUE; /* Disturb whenever viewable monster moves */ + bool_ disturb_panel = TRUE; /* Disturb whenever map panel changes */ + bool_ disturb_state = TRUE; /* Disturn whenever player state changes */ + bool_ disturb_minor = TRUE; /* Disturb whenever boring things happen */ + bool_ disturb_other = FALSE; /* Disturb whenever various things happen */ + bool_ last_words = TRUE; /* Get last words upon dying */ + bool_ wear_confirm = TRUE; /* Confirm before putting on known cursed items */ + bool_ confirm_stairs = FALSE; /* Prompt before staircases... */ + bool_ disturb_pets = FALSE; /* Pets moving nearby disturb us */ + + // + // Option Set 3 -- Game-Play + // + bool_ auto_scum = TRUE; /* Auto-scum for good levels */ + bool_ view_perma_grids = TRUE; /* Map remembers all perma-lit grids */ + bool_ view_torch_grids = FALSE; /* Map remembers all torch-lit grids */ + bool_ dungeon_align = TRUE; /* Generate dungeons with aligned rooms */ + bool_ dungeon_stair = TRUE; /* Generate dungeons with connected stairs */ + bool_ flow_by_sound = FALSE; /* Monsters track new player location */ + bool_ smart_learn = FALSE; /* Monsters learn from their mistakes */ + bool_ small_levels = TRUE; /* Allow unusually small dungeon levels */ + bool_ empty_levels = TRUE; /* Allow empty 'arena' levels */ + + // + // Option Set 4 -- Efficiency + // + bool_ view_reduce_lite = FALSE; /* Reduce lite-radius when running */ + bool_ avoid_abort = FALSE; /* Avoid checking for user abort */ + bool_ avoid_shimmer = FALSE; /* Avoid processing extra shimmering */ + bool_ avoid_other = FALSE; /* Avoid processing special colors */ + bool_ flush_failure = TRUE; /* Flush input on any failure */ + bool_ flush_disturb = FALSE; /* Flush input on disturbance */ + bool_ flush_command = FALSE; /* Flush input before every command */ + bool_ fresh_before = TRUE; /* Flush output before normal commands */ + bool_ fresh_after = FALSE; /* Flush output after normal commands */ + bool_ fresh_message = FALSE; /* Flush output after all messages */ + bool_ hilite_player = FALSE; /* Hilite the player with the cursor */ + bool_ view_yellow_lite = FALSE; /* Use special colors for torch-lit grids */ + bool_ view_bright_lite = FALSE; /* Use special colors for 'viewable' grids */ + bool_ view_granite_lite = FALSE; /* Use special colors for wall grids (slow) */ + bool_ view_special_lite = FALSE; /* Use special colors for floor grids (slow) */ + bool_ center_player = FALSE; /* Center view on player */ + + // + // Option Set 5 - ToME options + // + bool_ ingame_help = TRUE; /* In-game contextual help? */ + bool_ auto_more = FALSE; /* Auto more */ + bool_ player_char_health = TRUE; /* Display the player as a special symbol when in bad health ? */ + bool_ linear_stats = TRUE; + + // + // Option Set 6 - Birth options + // + bool_ preserve = TRUE; /* Preserve artifacts */ + bool_ autoroll = TRUE; /* Specify 'minimal' stats to roll */ + bool_ point_based = FALSE; /* Generate character using a point system */ + bool_ ironman_rooms = FALSE; /* Always generate very unusual rooms */ + bool_ joke_monsters = FALSE; /* Allow 'joke' monsters */ + bool_ always_small_level = FALSE; /* Force small levels */ + bool_ fate_option = TRUE; /* Player can receive fates */ + bool_ no_selling = FALSE; /* Player cannot sell items */ + + // + // Other options + // + + bool_ cheat_peek = FALSE; /* Peek into object creation */ + bool_ cheat_hear = FALSE; /* Peek into monster creation */ + bool_ cheat_room = FALSE; /* Peek into dungeon creation */ + bool_ cheat_xtra = FALSE; /* Peek into something else */ + bool_ cheat_live = FALSE; /* Allow player to avoid death */ + + byte hitpoint_warn = 0; /* Hitpoint warning (0 to 9) */ + + byte delay_factor = 0; /* Delay factor (0 to 9) */ + + s16b autosave_freq = 100; /* Autosave frequency */ + bool_ autosave_t = FALSE; /* Timed autosave */ + bool_ autosave_l = FALSE; /* Autosave before entering new levels */ + + /** + * Option groups + */ + std::vector<option_type> standard_options = { + // User-Interface + { &rogue_like_commands, 1, 0, "rogue_like_commands", "Rogue-like commands" }, + { &quick_messages , 1, 1, "quick_messages" , "Activate quick messages" }, + { &carry_query_flag , 1, 3, "carry_query_flag" , "Prompt before picking things up" }, + { &use_old_target , 1, 4, "use_old_target" , "Use old target by default" }, + { &always_pickup , 1, 5, "always_pickup" , "Pick things up by default" }, + { &always_repeat , 1, 7, "always_repeat" , "Repeat obvious commands" }, + { &ring_bell , 1, 18, "ring_bell" , "Audible bell (on errors, etc)" }, + // Disturbance + { &find_ignore_stairs , 2, 0, "find_ignore_stairs" , "Run past stairs" }, + { &find_ignore_doors , 2, 1, "find_ignore_doors" , "Run through open doors" }, + { &find_cut , 2, 2, "find_cut" , "Run past known corners" }, + { &find_examine , 2, 3, "find_examine" , "Run into potential corners" }, + { &disturb_move , 2, 4, "disturb_move" , "Disturb whenever any monster moves" }, + { &disturb_near , 2, 5, "disturb_near" , "Disturb whenever viewable monster moves" }, + { &disturb_panel , 2, 6, "disturb_panel" , "Disturb whenever map panel changes" }, + { &disturb_state , 2, 7, "disturb_state" , "Disturb whenever player state changes" }, + { &disturb_minor , 2, 8, "disturb_minor" , "Disturb whenever boring things happen" }, + { &disturb_other , 2, 9, "disturb_other" , "Disturb whenever random things happen" }, + { &last_words , 2, 12, "last_words" , "Get last words when the character dies" }, + { &wear_confirm , 2, 15, "confirm_wear" , "Confirm to wear/wield known cursed items" }, + { &confirm_stairs , 2, 16, "confirm_stairs" , "Prompt before exiting a dungeon level" }, + { &disturb_pets , 2, 17, "disturb_pets" , "Disturb when visible pets move" }, + // Game-Play + { &auto_scum , 3, 1, "auto_scum" , "Auto-scum for good levels" }, + { &view_perma_grids , 3, 6, "view_perma_grids" , "Map remembers all perma-lit grids" }, + { &view_torch_grids , 3, 7, "view_torch_grids" , "Map remembers all torch-lit grids" }, + { &dungeon_align , 3, 8, "dungeon_align" , "Generate dungeons with aligned rooms" }, + { &dungeon_stair , 3, 9, "dungeon_stair" , "Generate dungeons with connected stairs" }, + { &flow_by_sound , 3, 10, "flow_by_sound" , "Monsters chase current location (v.slow)" }, + { &smart_learn , 3, 14, "smart_learn" , "Monsters learn from their mistakes" }, + { &small_levels , 3, 17, "small_levels" , "Allow unusually small dungeon levels" }, + { &empty_levels , 3, 18, "empty_levels" , "Allow empty 'arena' levels" }, + // Efficiency + { &view_reduce_lite , 4, 0, "view_reduce_lite" , "Reduce lite-radius when running" }, + { &avoid_abort , 4, 2, "avoid_abort" , "Avoid checking for user abort" }, + { &avoid_shimmer , 4, 17, "avoid_shimmer" , "Avoid extra shimmering (fast)" }, + { &avoid_other , 4, 3, "avoid_other" , "Avoid processing special colors (fast)" }, + { &flush_failure , 4, 4, "flush_failure" , "Flush input on various failures" }, + { &flush_disturb , 4, 5, "flush_disturb" , "Flush input whenever disturbed" }, + { &flush_command , 4, 6, "flush_command" , "Flush input before every command" }, + { &fresh_before , 4, 7, "fresh_before" , "Flush output before every command" }, + { &fresh_after , 4, 8, "fresh_after" , "Flush output after every command" }, + { &fresh_message , 4, 9, "fresh_message" , "Flush output after every message" }, + { &hilite_player , 4, 11, "hilite_player" , "Hilite the player with the cursor" }, + { &view_yellow_lite , 4, 12, "view_yellow_lite" , "Use special colors for torch-lit grids" }, + { &view_bright_lite , 4, 13, "view_bright_lite" , "Use special colors for 'viewable' grids" }, + { &view_granite_lite , 4, 14, "view_granite_lite" , "Use special colors for wall grids (slow)" }, + { &view_special_lite , 4, 15, "view_special_lite" , "Use special colors for floor grids (slow)" }, + { ¢er_player , 4, 16, "center_player" , "Center the view on the player (very slow)" }, + // ToME options + { &ingame_help , 5, 1, "ingame_help" , "Ingame contextual help" }, + { &auto_more , 5, 4, "auto_more" , "Automatically clear '-more-' prompts" }, + { &player_char_health , 5, 6, "player_char_health" , "Player char represent his/her health" }, + { &linear_stats , 5, 7, "linear_stats" , "Stats are represented in a linear way" }, + // Birth Options + { &preserve , 6, 2, "preserve" , "Preserve artifacts" }, + { &autoroll , 6, 3, "autoroll" , "Specify 'minimal' stats" }, + { &point_based , 6, 17, "point_based" , "Generate character using a point system" }, + { &ironman_rooms , 6, 6, "ironman_rooms" , "Always generate very unusual rooms" }, + { &joke_monsters , 6, 14, "joke_monsters" , "Allow use of some 'joke' monsters" }, + { &always_small_level , 6, 16, "always_small_level" , "Always make small levels" }, + { &fate_option , 6, 18, "fate_option" , "You can receive fates, good or bad" }, + { &no_selling , 6, 20, "no_selling" , "Items always sell for 0 gold" }, + }; + + /* + * Cheating options + */ + std::vector<option_type> cheat_options = { + { &cheat_peek, 0, 0, "cheat_peek", "Peek into object creation" }, + { &cheat_hear, 0, 1, "cheat_hear", "Peek into monster creation" }, + { &cheat_room, 0, 2, "cheat_room", "Peek into dungeon creation" }, + { &cheat_xtra, 0, 3, "cheat_xtra", "Peek into something else" }, + { &cheat_live, 0, 5, "cheat_live", "Allow player to avoid death" }, + }; + + /** + * Autosave boolean options + */ + std::vector<option_type> autosave_options { + { &autosave_l, 0, 6, "autosave_l", "Autosave when entering new levels" }, + { &autosave_t, 0, 7, "autosave_t", "Timed autosave" } + }; + + /* + * Reset cheat options + */ + void reset_cheat_options(); + + /** + * Convert delay_factor to milliseconds + */ + int delay_factor_ms() const + { + return delay_factor * delay_factor * delay_factor; + } + +}; diff --git a/src/owner_type.hpp b/src/owner_type.hpp index 703d3159..4c47dc48 100644 --- a/src/owner_type.hpp +++ b/src/owner_type.hpp @@ -1,5 +1,7 @@ #pragma once +#include <string> + #include "h-basic.h" /* @@ -10,30 +12,30 @@ struct owner_type /** * Name */ - const char *name; + std::string name; /** * Purse limit */ - s16b max_cost; + s16b max_cost = 0; /** * Inflation */ - s16b inflation; + s16b inflation = 0; /** * Liked/hated races. */ - u32b races[2][2]; + u32b races[2][2] { }; /** * Liked/hated classes */ - u32b classes[2][2]; + u32b classes[2][2] { }; /** * Costs for liked people */ - s16b costs[3]; + s16b costs[3] { }; }; diff --git a/src/owner_type_fwd.hpp b/src/owner_type_fwd.hpp deleted file mode 100644 index 20c25802..00000000 --- a/src/owner_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct owner_type; diff --git a/src/player_class.hpp b/src/player_class.hpp index d67d1d73..02d0fc11 100644 --- a/src/player_class.hpp +++ b/src/player_class.hpp @@ -2,104 +2,48 @@ #include "body.hpp" #include "h-basic.h" +#include "object_flag_set.hpp" +#include "object_proto.hpp" #include "player_defs.hpp" +#include "player_level_flag.hpp" +#include "player_race_flag_set.hpp" +#include "player_shared.hpp" #include "player_spec.hpp" - -/** - * Maximum number of specialties. - */ -constexpr int MAX_SPEC = 20; +#include "skill_modifiers.hpp" /** * Player descriptor and runtime data. */ struct player_class { - const char *title; /* Type of class */ - char *desc; /* Small desc of the class */ - const char *titles[PY_MAX_LEVEL / 5]; - /* Titles */ - - s16b c_adj[6]; /* Class stat modifier */ - - s16b c_dis; /* class disarming */ - s16b c_dev; /* class magic devices */ - s16b c_sav; /* class saving throws */ - s16b c_stl; /* class stealth */ - s16b c_srh; /* class searching ability */ - s16b c_fos; /* class searching frequency */ - s16b c_thn; /* class to hit (normal) */ - s16b c_thb; /* class to hit (bows) */ - - s16b x_dis; /* extra disarming */ - s16b x_dev; /* extra magic devices */ - s16b x_sav; /* extra saving throws */ - s16b x_stl; /* extra stealth */ - s16b x_srh; /* extra searching ability */ - s16b x_fos; /* extra searching frequency */ - s16b x_thn; /* extra to hit (normal) */ - s16b x_thb; /* extra to hit (bows) */ - - s16b c_mhp; /* Class hit-dice adjustment */ - s16b c_exp; /* Class experience factor */ - - s16b powers[4]; /* Powers of the class */ + std::string title; /* Type of class */ + std::string desc; /* Small desc of the class */ + const char *titles[PY_MAX_LEVEL / 5] { }; /* Titles */ - s16b spell_book; /* Tval of spell books (if any) */ - s16b spell_stat; /* Stat for spells (if any) */ - s16b spell_lev; /* The higher it is the higher the spells level are */ - s16b spell_fail; /* The higher it is the higher the spells failure are */ - s16b spell_mana; /* The higher it is the higher the spells mana are */ - s16b spell_first; /* Level of first spell */ - s16b spell_weight; /* Weight that hurts spells */ - byte max_spell_level; /* Maximun spell level */ - byte magic_max_spell; /* Maximun numbner of spells one can learn by natural means */ + int display_order_idx; /* Display order index; lowest first */ - u32b flags1; /* flags */ - u32b flags2; /* flags */ + player_shared ps; - s16b mana; - s16b blow_num; - s16b blow_wgt; - s16b blow_mul; - s16b extra_blows; + player_race_flag_set flags; - s32b sense_base; - s32b sense_pl; - s32b sense_plus; - byte sense_heavy; - byte sense_heavy_magic; + s16b mana = 0; + s16b blow_num = 0; + s16b blow_wgt = 0; + s16b blow_mul = 0; + s16b extra_blows = 0; - s16b obj_tval[5]; - s16b obj_sval[5]; - s16b obj_pval[5]; - s16b obj_dd[5]; - s16b obj_ds[5]; - s16b obj_num; + std::vector<object_proto> object_protos; - char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */ + char body_parts[BODY_MAX] { }; /* To help to decide what to use when body changing */ - u32b oflags1[PY_MAX_LEVEL + 1]; - u32b oflags2[PY_MAX_LEVEL + 1]; - u32b oflags3[PY_MAX_LEVEL + 1]; - u32b oflags4[PY_MAX_LEVEL + 1]; - u32b oflags5[PY_MAX_LEVEL + 1]; - u32b oesp[PY_MAX_LEVEL + 1]; - s16b opval[PY_MAX_LEVEL + 1]; + std::array<player_level_flag, PY_MAX_LEVEL+1> lflags; - char skill_basem[MAX_SKILLS]; - u32b skill_base[MAX_SKILLS]; - char skill_modm[MAX_SKILLS]; - s16b skill_mod[MAX_SKILLS]; + struct skill_modifiers skill_modifiers; - u32b gods; + u32b gods = 0; - player_spec spec[MAX_SPEC]; + std::vector<player_spec> spec; - struct - { - s16b ability; - s16b level; - } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */ + std::vector<player_race_ability_type> abilities; /* Abilities to be gained by level; ignores prereqs */ }; diff --git a/src/player_level_flag.hpp b/src/player_level_flag.hpp new file mode 100644 index 00000000..fe4c862c --- /dev/null +++ b/src/player_level_flag.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "h-basic.h" +#include "object_flag_set.hpp" +#include "player_defs.hpp" + +struct player_level_flag { + + object_flag_set oflags; + + s16b pval = 0; + +}; diff --git a/src/player_race.hpp b/src/player_race.hpp index edb304f2..e0b236db 100644 --- a/src/player_race.hpp +++ b/src/player_race.hpp @@ -2,82 +2,45 @@ #include "h-basic.h" #include "body.hpp" +#include "object_flag_set.hpp" +#include "object_proto.hpp" #include "player_defs.hpp" -#include "skills_defs.hpp" +#include "player_level_flag.hpp" +#include "player_race_ability_type.hpp" +#include "player_race_flag_set.hpp" +#include "player_shared.hpp" +#include "skill_modifiers.hpp" + +#include <array> +#include <string> +#include <vector> + /** * Player racial descriptior. */ struct player_race { - const char *title; /* Type of race */ - char *desc; - - s16b r_adj[6]; /* Racial stat bonuses */ - - char luck; /* Luck */ - - s16b r_dis; /* disarming */ - s16b r_dev; /* magic devices */ - s16b r_sav; /* saving throw */ - s16b r_stl; /* stealth */ - s16b r_srh; /* search ability */ - s16b r_fos; /* search frequency */ - s16b r_thn; /* combat (normal) */ - s16b r_thb; /* combat (shooting) */ - - byte r_mhp; /* Race hit-dice modifier */ - u16b r_exp; /* Race experience factor */ - - byte b_age; /* base age */ - byte m_age; /* mod age */ - - byte m_b_ht; /* base height (males) */ - byte m_m_ht; /* mod height (males) */ - byte m_b_wt; /* base weight (males) */ - byte m_m_wt; /* mod weight (males) */ - - byte f_b_ht; /* base height (females) */ - byte f_m_ht; /* mod height (females) */ - byte f_b_wt; /* base weight (females) */ - byte f_m_wt; /* mod weight (females) */ + std::string title; /* Type of race */ + std::string desc; - byte infra; /* Infra-vision range */ + char luck = '\0'; /* Luck */ - u32b choice[2]; /* Legal class choices */ + player_shared ps; - s16b powers[4]; /* Powers of the race */ + byte infra = 0; /* Infra-vision range */ - byte body_parts[BODY_MAX]; /* To help to decide what to use when body changing */ + u32b choice[2] { }; /* Legal class choices */ - s16b chart; /* Chart history */ + byte body_parts[BODY_MAX] { }; /* To help to decide what to use when body changing */ - u32b flags1; - u32b flags2; /* flags */ + player_race_flag_set flags; - u32b oflags1[PY_MAX_LEVEL + 1]; - u32b oflags2[PY_MAX_LEVEL + 1]; - u32b oflags3[PY_MAX_LEVEL + 1]; - u32b oflags4[PY_MAX_LEVEL + 1]; - u32b oflags5[PY_MAX_LEVEL + 1]; - u32b oesp[PY_MAX_LEVEL + 1]; - s16b opval[PY_MAX_LEVEL + 1]; + std::array<player_level_flag, PY_MAX_LEVEL+1> lflags; - char skill_basem[MAX_SKILLS]; - u32b skill_base[MAX_SKILLS]; - char skill_modm[MAX_SKILLS]; - s16b skill_mod[MAX_SKILLS]; + struct skill_modifiers skill_modifiers; - s16b obj_tval[5]; - s16b obj_sval[5]; - s16b obj_pval[5]; - s16b obj_dd[5]; - s16b obj_ds[5]; - s16b obj_num; + std::vector<object_proto> object_protos; - struct - { - s16b ability; - s16b level; - } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */ + std::vector<player_race_ability_type> abilities; /* Abilities to be gained by level; ignores prereqs */ }; diff --git a/src/player_race_ability_type.hpp b/src/player_race_ability_type.hpp new file mode 100644 index 00000000..5f520052 --- /dev/null +++ b/src/player_race_ability_type.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "h-basic.h" + +struct player_race_ability_type +{ + s16b ability = 0; + s16b level = 0; +}; diff --git a/src/player_race_flag.hpp b/src/player_race_flag.hpp new file mode 100644 index 00000000..1268c3c0 --- /dev/null +++ b/src/player_race_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "player_race_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define PR(tier, index, name) \ + DECLARE_FLAG(player_race_flag_set, BOOST_PP_CAT(PR_,name), tier, index) +#include "player_race_flag_list.hpp" +#undef PR diff --git a/src/player_race_flag_list.hpp b/src/player_race_flag_list.hpp new file mode 100644 index 00000000..5116ad87 --- /dev/null +++ b/src/player_race_flag_list.hpp @@ -0,0 +1,26 @@ +/** + * X-macro list of all the player race flags + */ + +/* PR(<tier>, <index>, <name>) */ + +PR(1, 0, EXPERIMENTAL) /* Experimental */ +PR(1, 1, RESIST_BLACK_BREATH) /* Resists black breath */ +PR(1, 2, NO_STUN) /* Cannot be stunned */ +PR(1, 3, XTRA_MIGHT_BOW) /* Xtra might with bows */ +PR(1, 4, XTRA_MIGHT_XBOW) /* Xtra might with x-bows */ +PR(1, 5, XTRA_MIGHT_SLING) /* Xtra might with slings */ +PR(1, 6, AC_LEVEL) /* AC increases with levels */ +PR(1, 7, HURT_LITE) /* Hurt by light */ +PR(1, 8, VAMPIRE) /* Vampire */ +PR(1, 9, UNDEAD) /* Undead */ +PR(1, 10, NO_CUT) /* No cuts */ +PR(1, 11, CORRUPT) /* Corrupted; automatically gains corruptions */ +PR(1, 12, NO_FOOD) /* Little gain from food */ +PR(1, 13, NO_GOD) /* Cannot worship any gods */ +PR(1, 14, ELF) /* Is an elf */ +PR(1, 15, SEMI_WRAITH) /* Allows walking through walls; taking damage */ +PR(1, 16, NO_SUBRACE_CHANGE) /* Impossible to change subrace */ +PR(1, 17, GOD_FRIEND) /* Better grace */ +PR(1, 18, EASE_STEAL) /* Gain XP by stealing */ +PR(1, 19, ASTRAL) /* Astral being from the halls of Mandos */ diff --git a/src/player_race_flag_set.hpp b/src/player_race_flag_set.hpp new file mode 100644 index 00000000..4dd8dd9f --- /dev/null +++ b/src/player_race_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t PR_MAX_TIERS = 1; + +typedef flag_set<PR_MAX_TIERS> player_race_flag_set; diff --git a/src/player_race_mod.hpp b/src/player_race_mod.hpp index 72f975ce..8eb984b7 100644 --- a/src/player_race_mod.hpp +++ b/src/player_race_mod.hpp @@ -2,86 +2,51 @@ #include "body.hpp" #include "h-basic.h" +#include "object_flag_set.hpp" +#include "object_proto.hpp" +#include "player_defs.hpp" +#include "player_level_flag.hpp" +#include "player_race_ability_type.hpp" +#include "player_race_flag_set.hpp" +#include "player_shared.hpp" +#include "skill_modifiers.hpp" #include "skills_defs.hpp" +#include <array> +#include <string> +#include <vector> + struct player_race_mod { - char *title; /* Type of race mod */ - char *desc; /* Desc */ - - bool_ place; /* TRUE = race race modifier, FALSE = Race modifier race */ - - s16b r_adj[6]; /* (+) Racial stat bonuses */ - - char luck; /* Luck */ - s16b mana; /* Mana % */ + std::string title; + std::string description; - s16b r_dis; /* (+) disarming */ - s16b r_dev; /* (+) magic devices */ - s16b r_sav; /* (+) saving throw */ - s16b r_stl; /* (+) stealth */ - s16b r_srh; /* (+) search ability */ - s16b r_fos; /* (+) search frequency */ - s16b r_thn; /* (+) combat (normal) */ - s16b r_thb; /* (+) combat (shooting) */ + bool_ place = FALSE; /* TRUE = race race modifier, FALSE = Race modifier race */ - char r_mhp; /* (+) Race mod hit-dice modifier */ - s16b r_exp; /* (+) Race mod experience factor */ + char luck = '\0'; /* Luck */ + s16b mana = 0; /* Mana % */ - char b_age; /* (+) base age */ - char m_age; /* (+) mod age */ + player_shared ps; - char m_b_ht; /* (+) base height (males) */ - char m_m_ht; /* (+) mod height (males) */ - char m_b_wt; /* (+) base weight (males) */ - char m_m_wt; /* (+) mod weight (males) */ + char infra = '\0'; /* (+) Infra-vision range */ - char f_b_ht; /* (+) base height (females) */ - char f_m_ht; /* (+) mod height (females) */ - char f_b_wt; /* (+) base weight (females) */ - char f_m_wt; /* (+) mod weight (females) */ + u32b choice[2] { }; /* Legal race choices */ - char infra; /* (+) Infra-vision range */ + u32b pclass[2] { }; /* Classes allowed */ + u32b mclass[2] { }; /* Classes restricted */ - u32b choice[2]; /* Legal race choices */ + char body_parts[BODY_MAX] { }; /* To help to decide what to use when body changing */ - u32b pclass[2]; /* Classes allowed */ - u32b mclass[2]; /* Classes restricted */ + player_race_flag_set flags; - s16b powers[4]; /* Powers of the subrace */ + std::array<player_level_flag, PY_MAX_LEVEL+1> lflags; - char body_parts[BODY_MAX]; /* To help to decide what to use when body changing */ + byte g_attr = 0; /* Overlay graphic attribute */ + char g_char = '\0'; /* Overlay graphic character */ - u32b flags1; - u32b flags2; /* flags */ + struct skill_modifiers skill_modifiers; - u32b oflags1[PY_MAX_LEVEL + 1]; - u32b oflags2[PY_MAX_LEVEL + 1]; - u32b oflags3[PY_MAX_LEVEL + 1]; - u32b oflags4[PY_MAX_LEVEL + 1]; - u32b oflags5[PY_MAX_LEVEL + 1]; - u32b oesp[PY_MAX_LEVEL + 1]; - s16b opval[PY_MAX_LEVEL + 1]; + std::vector<object_proto> object_protos; - byte g_attr; /* Overlay graphic attribute */ - char g_char; /* Overlay graphic character */ - - char skill_basem[MAX_SKILLS]; - u32b skill_base[MAX_SKILLS]; - char skill_modm[MAX_SKILLS]; - s16b skill_mod[MAX_SKILLS]; - - s16b obj_tval[5]; - s16b obj_sval[5]; - s16b obj_pval[5]; - s16b obj_dd[5]; - s16b obj_ds[5]; - s16b obj_num; - - struct - { - s16b ability; - s16b level; - } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */ + std::vector<player_race_ability_type> abilities; /* Abilities to be gained by level; ignores prereqs */ }; - diff --git a/src/player_sex.hpp b/src/player_sex.hpp deleted file mode 100644 index 5722f1a4..00000000 --- a/src/player_sex.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -/** - * Player sex descriptor. - */ -struct player_sex -{ - /** - * Type of sex. - */ - char const *title; - - /** - * Winner title. - */ - char const *winner; -}; diff --git a/src/player_sex_fwd.hpp b/src/player_sex_fwd.hpp deleted file mode 100644 index eabea488..00000000 --- a/src/player_sex_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct player_sex; diff --git a/src/player_shared.hpp b/src/player_shared.hpp new file mode 100644 index 00000000..1ae7b9a7 --- /dev/null +++ b/src/player_shared.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "h-basic.h" +#include "skills_defs.hpp" +#include <array> +#include <vector> + +struct player_shared +{ + std::array<s16b, 6> adj { }; /* Stat modifiers */ + + s16b mhp = 0; /* Hit-dice adjustment */ + s16b exp = 0; /* Experience factor */ + + std::vector<s16b> powers; /* Powers */ +}; diff --git a/src/player_spec.hpp b/src/player_spec.hpp index 28b32830..574425f6 100644 --- a/src/player_spec.hpp +++ b/src/player_spec.hpp @@ -1,38 +1,29 @@ #pragma once #include "h-basic.h" -#include "skills_defs.hpp" +#include "object_proto.hpp" +#include "player_race_ability_type.hpp" +#include "player_race_flag_set.hpp" +#include "skill_modifiers.hpp" + +#include <array> +#include <vector> /** * Player class descriptor. */ struct player_spec { - const char *title; /* Type of class spec */ - char *desc; /* Small desc of the class spec */ - - char skill_basem[MAX_SKILLS]; /* Mod for value */ - u32b skill_base[MAX_SKILLS]; /* value */ - char skill_modm[MAX_SKILLS]; /* mod for mod */ - s16b skill_mod[MAX_SKILLS]; /* mod */ + const char *title = nullptr; /* Type of class spec */ + char *desc = nullptr; /* Small desc of the class spec */ - u32b skill_ideal[MAX_SKILLS]; /* Ideal skill levels at level 50 */ + struct skill_modifiers skill_modifiers; - s16b obj_tval[5]; - s16b obj_sval[5]; - s16b obj_pval[5]; - s16b obj_dd[5]; - s16b obj_ds[5]; - s16b obj_num; + std::vector<object_proto> object_protos; - u32b gods; + u32b gods = 0; - u32b flags1; - u32b flags2; /* flags */ + player_race_flag_set flags; - struct - { - s16b ability; - s16b level; - } abilities[10]; /* Abilitiers to be gained by level(doesnt take prereqs in account) */ + std::vector<player_race_ability_type> abilities; /* Abilities to be gained by level; ignores prereqs */ }; diff --git a/src/player_type.cc b/src/player_type.cc new file mode 100644 index 00000000..0cc66de7 --- /dev/null +++ b/src/player_type.cc @@ -0,0 +1,28 @@ +#include "player_type.hpp" + +#include <algorithm> + +bool player_type::has_ability(u16b ability_idx) const +{ + return std::find( + abilities.begin(), + abilities.end(), + ability_idx) != abilities.end(); +} + +void player_type::gain_ability(u16b ability_idx) +{ + // Duplicates don't really matter, so let's just + // accept whatever value we get without checking + // anything. + abilities.push_back(ability_idx); +} + +void player_type::lose_ability(u16b ability_idx) +{ + abilities.erase( + std::remove( + abilities.begin(), + abilities.end(), + ability_idx)); +} diff --git a/src/player_type.hpp b/src/player_type.hpp index d9410dcb..9b7ac21d 100644 --- a/src/player_type.hpp +++ b/src/player_type.hpp @@ -1,11 +1,16 @@ #pragma once #include "corrupt.hpp" +#include "defines.h" #include "h-basic.h" #include "help_info.hpp" #include "inventory.hpp" #include "object_type.hpp" #include "powers.hpp" +#include "random_spell.hpp" +#include "spellbinder.hpp" + +#include <array> /* * Most of the "player" information goes here. @@ -24,400 +29,400 @@ struct player_type { - s32b lives; /* How many times we resurected */ - - s16b oldpy; /* Previous player location -KMW- */ - s16b oldpx; /* Previous player location -KMW- */ - - s16b py; /* Player location */ - s16b px; /* Player location */ - - byte psex; /* Sex index */ - byte prace; /* Race index */ - byte pracem; /* Race Mod index */ - byte pclass; /* Class index */ - byte pspec; /* Class spec index */ - byte mimic_form; /* Actualy transformation */ - s16b mimic_level; /* Level of the mimic effect */ - byte oops; /* Unused */ - - object_type inventory[INVEN_TOTAL]; /* Player inventory */ - - byte hitdie; /* Hit dice (sides) */ - u16b expfact; /* Experience factor */ - - byte preserve; /* Preserve artifacts */ - byte special; /* Special levels */ - byte allow_one_death; /* Blood of life */ - - s16b age; /* Characters age */ - s16b ht; /* Height */ - s16b wt; /* Weight */ - s16b sc; /* Social Class */ - - - s32b au; /* Current Gold */ - - s32b max_exp; /* Max experience */ - s32b exp; /* Cur experience */ - u16b exp_frac; /* Cur exp frac (times 2^16) */ - - s16b lev; /* Level */ - - s16b town_num; /* Current town number */ - s16b inside_quest; /* Inside quest level */ - - s32b wilderness_x; /* Coordinates in the wilderness */ - s32b wilderness_y; - bool_ wild_mode; /* TRUE = Small map, FLASE = Big map */ - bool_ old_wild_mode; /* TRUE = Small map, FLASE = Big map */ - - s16b mhp; /* Max hit pts */ - s16b chp; /* Cur hit pts */ - u16b chp_frac; /* Cur hit frac (times 2^16) */ - s16b hp_mod; /* A modificator(permanent) */ - - s16b msp; /* Max mana pts */ - s16b csp; /* Cur mana pts */ - u16b csp_frac; /* Cur mana frac (times 2^16) */ - - s16b msane; /* Max sanity */ - s16b csane; /* Cur sanity */ - u16b csane_frac; /* Cur sanity frac */ - - s32b grace; /* Your God's appreciation factor. */ - s32b grace_delay; /* Delay factor for granting piety. */ - byte pgod; /* Your God. */ - bool_ praying; /* Praying to your god. */ - s16b melkor_sacrifice; /* How much hp has been sacrified for damage */ - - s16b max_plv; /* Max Player Level */ - - s16b stat_max[6]; /* Current "maximal" stat values */ - s16b stat_cur[6]; /* Current "natural" stat values */ - - s16b luck_cur; /* Current "natural" luck value (range -30 <> 30) */ - s16b luck_max; /* Current "maximal base" luck value (range -30 <> 30) */ - s16b luck_base; /* Current "base" luck value (range -30 <> 30) */ - - s16b speed_factor; /* Timed -- Fast */ - s16b fast; /* Timed -- Fast */ - s16b lightspeed; /* Timed -- Light Speed */ - s16b slow; /* Timed -- Slow */ - s16b blind; /* Timed -- Blindness */ - s16b paralyzed; /* Timed -- Paralysis */ - s16b confused; /* Timed -- Confusion */ - s16b afraid; /* Timed -- Fear */ - s16b image; /* Timed -- Hallucination */ - s16b poisoned; /* Timed -- Poisoned */ - s16b cut; /* Timed -- Cut */ - s16b stun; /* Timed -- Stun */ - - s16b protevil; /* Timed -- Protection from Evil*/ - s16b protgood; /* Timed -- Protection from Good*/ - s16b protundead; /* Timed -- Protection from Undead*/ - s16b invuln; /* Timed -- Invulnerable */ - s16b hero; /* Timed -- Heroism */ - s16b shero; /* Timed -- Super Heroism */ - s16b shield; /* Timed -- Shield Spell */ - s16b shield_power; /* Timed -- Shield Spell Power */ - s16b shield_opt; /* Timed -- Shield Spell options */ - s16b shield_power_opt; /* Timed -- Shield Spell Power */ - s16b shield_power_opt2; /* Timed -- Shield Spell Power */ - s16b blessed; /* Timed -- Blessed */ - s16b tim_invis; /* Timed -- See Invisible */ - s16b tim_infra; /* Timed -- Infra Vision */ - - s16b oppose_acid; /* Timed -- oppose acid */ - s16b oppose_elec; /* Timed -- oppose lightning */ - s16b oppose_fire; /* Timed -- oppose heat */ - s16b oppose_cold; /* Timed -- oppose cold */ - s16b oppose_pois; /* Timed -- oppose poison */ - s16b oppose_ld; /* Timed -- oppose light & dark */ - s16b oppose_cc; /* Timed -- oppose chaos & confusion */ - s16b oppose_ss; /* Timed -- oppose sound & shards */ - s16b oppose_nex; /* Timed -- oppose nexus */ - - s16b tim_esp; /* Timed ESP */ - s16b tim_wraith; /* Timed wraithform */ - s16b tim_ffall; /* Timed Levitation */ - s16b tim_fly; /* Timed Levitation */ - s16b tim_poison; /* Timed poison hands */ - s16b tim_thunder; /* Timed thunderstorm */ - s16b tim_thunder_p1; /* Timed thunderstorm */ - s16b tim_thunder_p2; /* Timed thunderstorm */ - - s16b tim_project; /* Timed project upon melee blow */ - s16b tim_project_dam; - s16b tim_project_gf; - s16b tim_project_rad; - s16b tim_project_flag; - - s16b tim_roots; /* Timed roots */ - s16b tim_roots_ac; - s16b tim_roots_dam; - - s16b tim_invisible; /* Timed Invisibility */ - s16b tim_inv_pow; /* Power of timed invisibility */ - s16b tim_mimic; /* Timed Mimic */ - s16b tim_lite; /* Timed Lite */ - s16b tim_regen; /* Timed extra regen */ - s16b tim_regen_pow; /* Timed extra regen power */ - s16b holy; /* Holy Aura */ - s16b strike; /* True Strike(+25 hit) */ - s16b tim_reflect; /* Timed Reflection */ - s16b tim_deadly; /* Timed deadly blow */ - s16b prob_travel; /* Timed probability travel */ - s16b disrupt_shield;/* Timed disruption shield */ - s16b parasite; /* Timed parasite */ - s16b parasite_r_idx;/* Timed parasite monster */ - s16b absorb_soul; /* Timed soul absordtion */ - s16b tim_magic_breath; /* Magical breathing -- can breath anywhere */ - s16b tim_water_breath; /* Water breathing -- can breath underwater */ - s16b tim_precognition; /* Timed precognition */ - - s16b immov_cntr; /* Timed -- Last ``immovable'' command. */ - - s16b recall_dungeon; /* Recall in which dungeon */ - s16b word_recall; /* Word of recall counter */ - - s32b energy; /* Current energy */ - - s16b food; /* Current nutrition */ - - byte confusing; /* Glowing hands */ - byte searching; /* Currently searching */ - - bool_ old_cumber_armor; - bool_ old_cumber_glove; - bool_ old_heavy_wield; - bool_ old_heavy_shoot; - bool_ old_icky_wield; - - s16b old_lite; /* Old radius of lite (if any) */ - s16b old_view; /* Old radius of view (if any) */ - - s16b old_food_aux; /* Old value of food */ - - - bool_ cumber_armor; /* Mana draining armor */ - bool_ cumber_glove; /* Mana draining gloves */ - bool_ heavy_wield; /* Heavy weapon */ - bool_ heavy_shoot; /* Heavy shooter */ - bool_ icky_wield; /* Icky weapon */ - bool_ immovable; /* Immovable character */ - - s16b cur_lite; /* Radius of lite (if any) */ - - - u32b notice; /* Special Updates (bit flags) */ - u32b update; /* Pending Updates (bit flags) */ - u32b redraw; /* Normal Redraws (bit flags) */ - u32b window; /* Window Redraws (bit flags) */ - - s16b stat_use[6]; /* Current modified stats */ - s16b stat_top[6]; /* Maximal modified stats */ - - s16b stat_add[6]; /* Modifiers to stat values */ - s16b stat_ind[6]; /* Indexes into stat tables */ - s16b stat_cnt[6]; /* Counter for temporary drains */ - s16b stat_los[6]; /* Amount of temporary drains */ - - bool_ immune_acid; /* Immunity to acid */ - bool_ immune_elec; /* Immunity to lightning */ - bool_ immune_fire; /* Immunity to fire */ - bool_ immune_cold; /* Immunity to cold */ - bool_ immune_neth; /* Immunity to nether */ - - bool_ resist_acid; /* Resist acid */ - bool_ resist_elec; /* Resist lightning */ - bool_ resist_fire; /* Resist fire */ - bool_ resist_cold; /* Resist cold */ - bool_ resist_pois; /* Resist poison */ - - bool_ resist_conf; /* Resist confusion */ - bool_ resist_sound; /* Resist sound */ - bool_ resist_lite; /* Resist light */ - bool_ resist_dark; /* Resist darkness */ - bool_ resist_chaos; /* Resist chaos */ - bool_ resist_disen; /* Resist disenchant */ - bool_ resist_shard; /* Resist shards */ - bool_ resist_nexus; /* Resist nexus */ - bool_ resist_blind; /* Resist blindness */ - bool_ resist_neth; /* Resist nether */ - bool_ resist_fear; /* Resist fear */ - bool_ resist_continuum; /* Resist space-time continuum disruption */ - - bool_ sensible_fire; /* Fire does more damage on the player */ - bool_ sensible_lite; /* Lite does more damage on the player and blinds her/him */ - - bool_ reflect; /* Reflect 'bolt' attacks */ - bool_ sh_fire; /* Fiery 'immolation' effect */ - bool_ sh_elec; /* Electric 'immolation' effect */ - bool_ wraith_form; /* wraithform */ - - bool_ anti_magic; /* Anti-magic */ - bool_ anti_tele; /* Prevent teleportation */ - - bool_ sustain_str; /* Keep strength */ - bool_ sustain_int; /* Keep intelligence */ - bool_ sustain_wis; /* Keep wisdom */ - bool_ sustain_dex; /* Keep dexterity */ - bool_ sustain_con; /* Keep constitution */ - bool_ sustain_chr; /* Keep charisma */ - - bool_ aggravate; /* Aggravate monsters */ - bool_ teleport; /* Random teleporting */ - - bool_ exp_drain; /* Experience draining */ - byte drain_mana; /* mana draining */ - byte drain_life; /* hp draining */ - - bool_ magical_breath; /* Magical breathing -- can breath anywhere */ - bool_ water_breath; /* Water breathing -- can breath underwater */ - bool_ climb; /* Can climb mountains */ - bool_ fly; /* Can fly over some features */ - bool_ ffall; /* No damage falling */ - bool_ lite; /* Permanent light */ - bool_ free_act; /* Never paralyzed */ - bool_ see_inv; /* Can see invisible */ - bool_ regenerate; /* Regenerate hit pts */ - bool_ hold_life; /* Resist life draining */ - u32b telepathy; /* Telepathy */ - bool_ slow_digest; /* Slower digestion */ - bool_ bless_blade; /* Blessed blade */ - byte xtra_might; /* Extra might bow */ - bool_ impact; /* Earthquake blows */ - bool_ auto_id; /* Auto id items */ - - s16b invis; /* Invisibility */ - - s16b dis_to_h; /* Known bonus to hit */ - s16b dis_to_d; /* Known bonus to dam */ - s16b dis_to_a; /* Known bonus to ac */ - - s16b dis_ac; /* Known base ac */ - - s16b to_l; /* Bonus to life */ - s16b to_m; /* Bonus to mana */ - s16b to_s; /* Bonus to spell */ - s16b to_h; /* Bonus to hit */ - s16b to_d; /* Bonus to dam */ - s16b to_h_melee; /* Bonus to hit for melee */ - s16b to_d_melee; /* Bonus to dam for melee */ - s16b to_h_ranged; /* Bonus to hit for ranged */ - s16b to_d_ranged; /* Bonus to dam for ranged */ - s16b to_a; /* Bonus to ac */ - - s16b ac; /* Base ac */ - - byte antimagic; /* Power of the anti magic field */ - byte antimagic_dis; /* Radius of the anti magic field */ - - s16b see_infra; /* Infravision range */ - - s16b skill_dis; /* Skill: Disarming */ - s16b skill_dev; /* Skill: Magic Devices */ - s16b skill_sav; /* Skill: Saving throw */ - s16b skill_stl; /* Skill: Stealth factor */ - s16b skill_srh; /* Skill: Searching ability */ - s16b skill_fos; /* Skill: Searching frequency */ - s16b skill_thn; /* Skill: To hit (normal) */ - s16b skill_thb; /* Skill: To hit (shooting) */ - s16b skill_tht; /* Skill: To hit (throwing) */ - s16b skill_dig; /* Skill: Digging */ - - s16b num_blow; /* Number of blows */ - s16b num_fire; /* Number of shots */ - s16b xtra_crit; /* % of increased crits */ - - byte throw_mult; /* Multiplier for throw damage */ - - byte tval_ammo; /* Correct ammo tval */ - - s16b pspeed; /* Current speed */ - - u32b mimic_extra; /* Mimicry powers use that */ - u32b antimagic_extra; /* Antimagic powers */ - u32b music_extra; /* Music songs */ - u32b necro_extra; /* Necro powers */ - u32b necro_extra2; /* Necro powers */ - - s16b dodge_chance; /* Dodging chance */ - - u32b maintain_sum; /* Do we have partial summons */ + s32b lives = 0; /* How many times we resurected */ + + s16b oldpy = 0; /* Previous player location */ + s16b oldpx = 0; /* Previous player location */ + + s16b py = 0; /* Player location */ + s16b px = 0; /* Player location */ + + byte prace = 0; /* Race index */ + byte pracem = 0; /* Race Mod index */ + byte pclass = 0; /* Class index */ + byte pspec = 0; /* Class spec index */ + byte mimic_form = 0; /* Actualy transformation */ + s16b mimic_level = 0; /* Level of the mimic effect */ + + std::array<object_type, INVEN_TOTAL> inventory { }; /* Player inventory */ + + byte hitdie = 0; /* Hit dice (sides) */ + u16b expfact = 0; /* Experience factor */ + + byte allow_one_death = 0; /* Blood of life */ + + s32b au = 0; /* Current Gold */ + + s32b max_exp = 0; /* Max experience */ + s32b exp = 0; /* Cur experience */ + u16b exp_frac = 0; /* Cur exp frac (times 2^16) */ + + s16b lev = 0; /* Level */ + + s16b town_num = 0; /* Current town number */ + s16b inside_quest = 0; /* Inside quest level */ + + s32b wilderness_x = 0; /* Coordinates in the wilderness */ + s32b wilderness_y = 0; + bool_ wild_mode = FALSE; /* TRUE = Small map, FLASE = Big map */ + bool_ old_wild_mode = FALSE; /* TRUE = Small map, FLASE = Big map */ + + s16b mhp = 0; /* Max hit pts */ + s16b chp = 0; /* Cur hit pts */ + u16b chp_frac = 0; /* Cur hit frac (times 2^16) */ + s16b hp_mod = 0; /* A modificator (permanent) */ + + s16b msp = 0; /* Max mana pts */ + s16b csp = 0; /* Cur mana pts */ + u16b csp_frac = 0; /* Cur mana frac (times 2^16) */ + + s16b msane = 0; /* Max sanity */ + s16b csane = 0; /* Cur sanity */ + u16b csane_frac = 0; /* Cur sanity frac */ + + s32b grace = 0; /* Your God's appreciation factor. */ + s32b grace_delay = 0; /* Delay factor for granting piety. */ + byte pgod = 0; /* Your God. */ + bool_ praying = FALSE; /* Praying to your god. */ + s16b melkor_sacrifice = 0; /* How much hp has been sacrified for damage */ + + s16b max_plv = 0; /* Max Player Level */ + + s16b stat_max[6] = { 0 }; /* Current "maximal" stat values */ + s16b stat_cur[6] = { 0 }; /* Current "natural" stat values */ + + s16b luck_cur = 0; /* Current "natural" luck value (range -30 <> 30) */ + s16b luck_max = 0; /* Current "maximal base" luck value (range -30 <> 30) */ + s16b luck_base = 0; /* Current "base" luck value (range -30 <> 30) */ + + s16b speed_factor = 0; /* Timed -- Fast */ + s16b fast = 0; /* Timed -- Fast */ + s16b lightspeed = 0; /* Timed -- Light Speed */ + s16b slow = 0; /* Timed -- Slow */ + s16b blind = 0; /* Timed -- Blindness */ + s16b paralyzed = 0; /* Timed -- Paralysis */ + s16b confused = 0; /* Timed -- Confusion */ + s16b afraid = 0; /* Timed -- Fear */ + s16b image = 0; /* Timed -- Hallucination */ + s16b poisoned = 0; /* Timed -- Poisoned */ + s16b cut = 0; /* Timed -- Cut */ + s16b stun = 0; /* Timed -- Stun */ + + s16b protevil = 0; /* Timed -- Protection from Evil*/ + s16b invuln = 0; /* Timed -- Invulnerable */ + s16b hero = 0; /* Timed -- Heroism */ + s16b shero = 0; /* Timed -- Super Heroism */ + s16b shield = 0; /* Timed -- Shield Spell */ + s16b shield_power = 0; /* Timed -- Shield Spell Power */ + s16b shield_opt = 0; /* Timed -- Shield Spell options */ + s16b shield_power_opt = 0; /* Timed -- Shield Spell Power */ + s16b shield_power_opt2 = 0; /* Timed -- Shield Spell Power */ + s16b blessed = 0; /* Timed -- Blessed */ + s16b tim_invis = 0; /* Timed -- See Invisible */ + s16b tim_infra = 0; /* Timed -- Infra Vision */ + + s16b oppose_acid = 0; /* Timed -- oppose acid */ + s16b oppose_elec = 0; /* Timed -- oppose lightning */ + s16b oppose_fire = 0; /* Timed -- oppose heat */ + s16b oppose_cold = 0; /* Timed -- oppose cold */ + s16b oppose_pois = 0; /* Timed -- oppose poison */ + s16b oppose_cc = 0; /* Timed -- oppose chaos & confusion */ + + s16b tim_esp = 0; /* Timed ESP */ + s16b tim_wraith = 0; /* Timed wraithform */ + s16b tim_ffall = 0; /* Timed Levitation */ + s16b tim_fly = 0; /* Timed Levitation */ + s16b tim_poison = 0; /* Timed poison hands */ + s16b tim_thunder = 0; /* Timed thunderstorm */ + s16b tim_thunder_p1 = 0; /* Timed thunderstorm */ + s16b tim_thunder_p2 = 0; /* Timed thunderstorm */ + + s16b tim_project = 0; /* Timed project upon melee blow */ + s16b tim_project_dam = 0; + s16b tim_project_gf = 0; + s16b tim_project_rad = 0; + s16b tim_project_flag = 0; + + s16b tim_roots = 0; /* Timed roots */ + s16b tim_roots_ac = 0; + s16b tim_roots_dam = 0; + + s16b tim_invisible = 0; /* Timed Invisibility */ + s16b tim_inv_pow = 0; /* Power of timed invisibility */ + s16b tim_mimic = 0; /* Timed Mimic */ + s16b tim_lite = 0; /* Timed Lite */ + s16b tim_regen = 0; /* Timed extra regen */ + s16b tim_regen_pow = 0; /* Timed extra regen power */ + s16b holy = 0; /* Holy Aura */ + s16b strike = 0; /* True Strike(+25 hit) */ + s16b tim_reflect = 0; /* Timed Reflection */ + s16b tim_deadly = 0; /* Timed deadly blow */ + s16b prob_travel = 0; /* Timed probability travel */ + s16b disrupt_shield = 0; /* Timed disruption shield */ + s16b parasite = 0; /* Timed parasite */ + s16b parasite_r_idx = 0; /* Timed parasite monster */ + s16b absorb_soul = 0; /* Timed soul absordtion */ + s16b tim_magic_breath = 0; /* Magical breathing -- can breath anywhere */ + s16b tim_water_breath = 0; /* Water breathing -- can breath underwater */ + s16b tim_precognition = 0; /* Timed precognition */ + + s16b immov_cntr = 0; /* Timed -- Last ``immovable'' command. */ + + byte recall_dungeon = 0; /* Recall in which dungeon */ + s16b word_recall = 0; /* Word of recall counter */ + + s32b energy = 0; /* Current energy */ + + s16b food = 0; /* Current nutrition */ + + byte confusing = 0; /* Glowing hands */ + + bool_ old_cumber_armor = FALSE; + bool_ old_cumber_glove = FALSE; + bool_ old_heavy_wield = FALSE; + bool_ old_heavy_shoot = FALSE; + bool_ old_icky_wield = FALSE; + + s16b old_lite = 0; /* Old radius of lite (if any) */ + s16b old_view = 0; /* Old radius of view (if any) */ + + s16b old_food_aux = 0; /* Old value of food */ + + bool_ cumber_armor = FALSE; /* Mana draining armor */ + bool_ cumber_glove = FALSE; /* Mana draining gloves */ + bool_ heavy_wield = FALSE; /* Heavy weapon */ + bool_ heavy_shoot = FALSE; /* Heavy shooter */ + bool_ icky_wield = FALSE; /* Icky weapon */ + bool_ immovable = FALSE; /* Immovable character */ + + s16b cur_lite = 0; /* Radius of lite (if any) */ + + u32b notice = 0; /* Special Updates (bit flags) */ + u32b update = 0; /* Pending Updates (bit flags) */ + u32b redraw = 0; /* Normal Redraws (bit flags) */ + u32b window = 0; /* Window Redraws (bit flags) */ + + s16b stat_use[6] = { 0 }; /* Current modified stats */ + s16b stat_top[6] = { 0 }; /* Maximal modified stats */ + + s16b stat_add[6] = { 0 }; /* Modifiers to stat values */ + s16b stat_ind[6] = { 0 }; /* Indexes into stat tables */ + s16b stat_cnt[6] = { 0 }; /* Counter for temporary drains */ + s16b stat_los[6] = { 0 }; /* Amount of temporary drains */ + + bool_ immune_acid = FALSE; /* Immunity to acid */ + bool_ immune_elec = FALSE; /* Immunity to lightning */ + bool_ immune_fire = FALSE; /* Immunity to fire */ + bool_ immune_cold = FALSE; /* Immunity to cold */ + bool_ immune_neth = FALSE; /* Immunity to nether */ + + bool_ resist_acid = FALSE; /* Resist acid */ + bool_ resist_elec = FALSE; /* Resist lightning */ + bool_ resist_fire = FALSE; /* Resist fire */ + bool_ resist_cold = FALSE; /* Resist cold */ + bool_ resist_pois = FALSE; /* Resist poison */ + + bool_ resist_conf = FALSE; /* Resist confusion */ + bool_ resist_sound = FALSE; /* Resist sound */ + bool_ resist_lite = FALSE; /* Resist light */ + bool_ resist_dark = FALSE; /* Resist darkness */ + bool_ resist_chaos = FALSE; /* Resist chaos */ + bool_ resist_disen = FALSE; /* Resist disenchant */ + bool_ resist_shard = FALSE; /* Resist shards */ + bool_ resist_nexus = FALSE; /* Resist nexus */ + bool_ resist_blind = FALSE; /* Resist blindness */ + bool_ resist_neth = FALSE; /* Resist nether */ + bool_ resist_fear = FALSE; /* Resist fear */ + bool_ resist_continuum = FALSE; /* Resist space-time continuum disruption */ + + bool_ sensible_fire = FALSE; /* Fire does more damage on the player */ + bool_ sensible_lite = FALSE; /* Lite does more damage on the player and blinds her/him */ + + bool_ reflect = FALSE; /* Reflect 'bolt' attacks */ + bool_ sh_fire = FALSE; /* Fiery 'immolation' effect */ + bool_ sh_elec = FALSE; /* Electric 'immolation' effect */ + bool_ wraith_form = FALSE; /* wraithform */ + + bool_ anti_magic = FALSE; /* Anti-magic */ + bool_ anti_tele = FALSE; /* Prevent teleportation */ + + bool_ sustain_str = FALSE; /* Keep strength */ + bool_ sustain_int = FALSE; /* Keep intelligence */ + bool_ sustain_wis = FALSE; /* Keep wisdom */ + bool_ sustain_dex = FALSE; /* Keep dexterity */ + bool_ sustain_con = FALSE; /* Keep constitution */ + bool_ sustain_chr = FALSE; /* Keep charisma */ + + bool_ aggravate = FALSE; /* Aggravate monsters */ + bool_ teleport = FALSE; /* Random teleporting */ + + bool_ exp_drain = FALSE; /* Experience draining */ + byte drain_mana = FALSE; /* mana draining */ + byte drain_life = FALSE; /* hp draining */ + + bool_ magical_breath = FALSE; /* Magical breathing -- can breath anywhere */ + bool_ water_breath = FALSE; /* Water breathing -- can breath underwater */ + bool_ climb = FALSE; /* Can climb mountains */ + bool_ fly = FALSE; /* Can fly over some features */ + bool_ ffall = FALSE; /* No damage falling */ + bool_ lite = FALSE; /* Permanent light */ + bool_ free_act = FALSE; /* Never paralyzed */ + bool_ see_inv = FALSE; /* Can see invisible */ + bool_ regenerate = FALSE; /* Regenerate hit pts */ + bool_ hold_life = FALSE; /* Resist life draining */ + bool_ slow_digest = FALSE; /* Slower digestion */ + bool_ bless_blade = FALSE; /* Blessed blade */ + byte xtra_might = 0; /* Extra might bow */ + bool_ impact = FALSE; /* Earthquake blows */ + bool_ auto_id = FALSE; /* Auto id items */ + + s16b invis = 0; /* Invisibility */ + + s16b dis_to_h = 0; /* Known bonus to hit */ + s16b dis_to_d = 0; /* Known bonus to dam */ + s16b dis_to_a = 0; /* Known bonus to ac */ + + s16b dis_ac = 0; /* Known base ac */ + + s16b to_l = 0; /* Bonus to life */ + s16b to_m = 0; /* Bonus to mana */ + s16b to_s = 0; /* Bonus to spell */ + s16b to_h = 0; /* Bonus to hit */ + s16b to_d = 0; /* Bonus to dam */ + s16b to_h_melee = 0; /* Bonus to hit for melee */ + s16b to_d_melee = 0; /* Bonus to dam for melee */ + s16b to_h_ranged = 0; /* Bonus to hit for ranged */ + s16b to_d_ranged = 0; /* Bonus to dam for ranged */ + s16b to_a = 0; /* Bonus to ac */ + + s16b ac = 0; /* Base ac */ + + byte antimagic = 0; /* Power of the anti magic field */ + byte antimagic_dis = 0; /* Radius of the anti magic field */ + + s16b see_infra; /* Infravision range */ + + s16b skill_dev = 0; /* Skill: Magic Devices */ + s16b skill_sav = 0; /* Skill: Saving throw */ + s16b skill_stl = 0; /* Skill: Stealth factor */ + s16b skill_thn = 0; /* Skill: To hit (normal) */ + s16b skill_thb = 0; /* Skill: To hit (shooting) */ + s16b skill_tht = 0; /* Skill: To hit (throwing) */ + s16b skill_dig = 0; /* Skill: Digging */ + + s16b num_blow = 0; /* Number of blows */ + s16b num_fire = 0; /* Number of shots */ + s16b xtra_crit = 0; /* % of increased crits */ + + byte throw_mult = 0; /* Multiplier for throw damage */ + + byte tval_ammo = 0; /* Correct ammo tval */ + + s16b pspeed = 0; /* Current speed */ + + u32b mimic_extra = 0; /* Mimicry powers use that */ + u32b antimagic_extra = 0; /* Antimagic powers */ + u32b music_extra = 0; /* Music songs */ + u32b necro_extra = 0; /* Necro powers */ + u32b necro_extra2 = 0; /* Necro powers */ + + s16b dodge_chance = 0; /* Dodging chance */ + + u32b maintain_sum = 0; /* Do we have partial summons */ - byte spellbinder_num; /* Number of spells bound */ - u32b spellbinder[4]; /* Spell bounds */ - byte spellbinder_trigger; /* Spellbinder trigger condition */ + struct spellbinder spellbinder; - cptr mimic_name; - - char tactic; /* from 128-4 extremely coward to */ - /* 128+4 berserker */ - char movement; /* base movement way */ - - s16b companion_killed; /* Number of companion death */ + cptr mimic_name = nullptr; - bool_ no_mortal; /* Fated to never die by the hand of a mortal being */ - - bool_ black_breath; /* The Tolkien's Black Breath */ + char tactic = '\0'; /* from 128-4 "extremely coward" to, 128+4 "berserker" */ + char movement = '\0'; /* base movement way */ - bool_ precognition; /* Like the cheat mode */ + s16b companion_killed = 0; /* Number of companion death */ - /*** Extra flags -- used for lua and easying stuff ***/ - u32b xtra_f1; - u32b xtra_f2; - u32b xtra_f3; - u32b xtra_f4; - u32b xtra_f5; - u32b xtra_esp; + bool_ no_mortal = FALSE; /* Fated to never die by the hand of a mortal being */ + + bool_ black_breath = FALSE; /* The Tolkien's Black Breath */ + + bool_ precognition = FALSE; /* Like the cheat mode */ + + /*** Extra flags ***/ + object_flag_set xtra_flags; + + /** Computed flags based on all worn items, etc. */ + object_flag_set computed_flags; /* Corruptions */ - bool_ corruptions[CORRUPTIONS_MAX]; - bool_ corrupt_anti_teleport_stopped; + bool_ corruptions[CORRUPTIONS_MAX] = { FALSE }; + bool_ corrupt_anti_teleport_stopped = FALSE; /*** Pet commands ***/ - byte pet_follow_distance; /* Length of the imaginary "leash" for pets */ - byte pet_open_doors; /* flag - allow pets to open doors */ - byte pet_pickup_items; /* flag - allow pets to pickup items */ + byte pet_follow_distance = 0; /* Length of the imaginary "leash" for pets */ + byte pet_open_doors = 0; /* flag - allow pets to open doors */ + byte pet_pickup_items = 0; /* flag - allow pets to pickup items */ - s16b control; /* Controlled monster */ - byte control_dir; /* Controlled monster */ + s16b control = 0; /* Controlled monster */ + byte control_dir; /* Controlled monster */ /*** Body changing variables ***/ - u16b body_monster; /* In which body is the player */ - bool_ disembodied; /* Is the player in a body ? */ - byte body_parts[INVEN_TOTAL - INVEN_WIELD]; /* Which body parts does he have ? */ + u16b body_monster = 0; /* In which body is the player */ + bool_ disembodied = FALSE; /* Is the player in a body ? */ + std::array<byte, INVEN_TOTAL-INVEN_WIELD> body_parts = /* Which body parts does he have ? */ + { }; /* Astral */ - bool_ astral; /* We started at the bottom ? */ + bool_ astral = FALSE; /* We started at the bottom ? */ /* Powers */ - bool_ powers[POWER_MAX]; /* Actual powers */ - bool_ powers_mod[POWER_MAX]; /* Intrinsinc powers */ + bool_ powers[POWER_MAX] = { FALSE }; /* Actual powers */ + bool_ powers_mod[POWER_MAX] = { FALSE }; /* Intrinsinc powers */ + + /* Acquired abilities; indexes into ab_info[] */ + std::vector<u16b> abilities; + + /* Known inscriptions; true if known, false otherwise. */ + std::array<bool, MAX_INSCRIPTIONS> inscriptions; /* Skills */ - s16b skill_points; - s16b skill_last_level; /* Prevents gaining skills by losing level and regaining them */ - s16b melee_style; /* How are */ - s16b use_piercing_shots; /* for archery */ + s16b skill_points = 0; + s16b skill_last_level = 0; /* Prevents gaining skills by losing level and regaining them */ + s16b melee_style = 0; /* How are */ + s16b use_piercing_shots = 0; /* for archery */ /* Dripping Tread spell timer */ - s16b dripping_tread; + s16b dripping_tread = 0; /* Help */ help_info help; /* Inertia control */ - s32b inertia_controlled_spell; + s32b inertia_controlled_spell = 0; /* For automatic stat-gain */ - s16b last_rewarded_level; + s16b last_rewarded_level = 0; /*** Temporary fields ***/ - bool_ did_nothing; /* True if the last action wasnt a real action */ - bool_ leaving; /* True if player is leaving */ -}; + bool_ did_nothing = FALSE; /* True if the last action wasnt a real action */ + bool_ leaving = FALSE; /* True if player is leaving */ + + /** + * Random spells. + */ + std::vector<random_spell> random_spells; + + /** + * Does the player have the given ability? + */ + bool has_ability(u16b ability_idx) const; + /** + * Gain the given ability. + */ + void gain_ability(u16b ability_idx); + + /** + * Lose the given ability. + */ + void lose_ability(u16b ability_idx); + +}; diff --git a/src/point.hpp b/src/point.hpp new file mode 100644 index 00000000..c0c12f58 --- /dev/null +++ b/src/point.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include <cstdint> + +struct point { + +private: + std::uint8_t m_x; + std::uint8_t m_y; + +public: + point(std::uint8_t x, std::uint8_t y) + : m_x(x), m_y(y) { + } + + std::uint8_t x() const { + return m_x; + } + + std::uint8_t y() const { + return m_y; + } + +}; diff --git a/src/powers.cc b/src/powers.cc index a7db2968..f3ffe668 100644 --- a/src/powers.cc +++ b/src/powers.cc @@ -13,25 +13,27 @@ #include "cmd1.hpp" #include "cmd2.hpp" #include "cmd7.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hooks.hpp" #include "mimic.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_kind.hpp" #include "options.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "spells1.hpp" #include "spells2.hpp" #include "stats.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -119,7 +121,7 @@ static bool_ power_chance(power_type *x_ptr) return (TRUE); } - if (flush_failure) flush(); + flush_on_failure(); msg_print("You've failed to concentrate hard enough."); return (FALSE); @@ -127,6 +129,9 @@ static bool_ power_chance(power_type *x_ptr) static void power_activate(int power) { + auto const &f_info = game->edit_data.f_info; + auto const &k_info = game->edit_data.k_info; + s16b plev = p_ptr->lev; char ch = 0; int amber_power = 0; @@ -195,11 +200,6 @@ static void power_activate(int power) } } break; - case PWR_LAY_TRAP: - { - do_cmd_set_trap(); - } - break; case PWR_MAGIC_MAP: { msg_print("You sense the world around you."); @@ -235,17 +235,17 @@ static void power_activate(int power) case PWR_UNFEAR: { msg_print("You play tough."); - (void)set_afraid(0); + set_afraid(0); } break; case PWR_BERSERK: { msg_print("RAAAGH!"); - (void)set_afraid(0); + set_afraid(0); - (void)set_shero(p_ptr->shero + 10 + randint(plev)); - (void)hp_player(30); + set_shero(p_ptr->shero + 10 + randint(plev)); + hp_player(30); } break; @@ -260,7 +260,7 @@ static void power_activate(int power) { if (!get_aim_dir(&dir)) break; msg_print("You bash at a stone wall."); - (void)wall_to_mud(dir); + wall_to_mud(dir); } break; @@ -311,7 +311,7 @@ static void power_activate(int power) x_ptr_foo.diff = 7; if (power_chance(&x_ptr_foo)) { - (void)set_light_speed(p_ptr->lightspeed + 3); + set_light_speed(p_ptr->lightspeed + 3); } } break; @@ -328,9 +328,8 @@ static void power_activate(int power) case PWR_DETECT_TD: { msg_print("You examine your surroundings."); - (void)detect_traps(DEFAULT_RADIUS); - (void)detect_doors(DEFAULT_RADIUS); - (void)detect_stairs(DEFAULT_RADIUS); + detect_doors(DEFAULT_RADIUS); + detect_stairs(DEFAULT_RADIUS); } break; @@ -390,7 +389,7 @@ static void power_activate(int power) } if (amber_power == 2) { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels ..."); break; @@ -417,7 +416,7 @@ static void power_activate(int power) } if (amber_power == 3) { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No recall on special levels.."); break; @@ -511,7 +510,7 @@ static void power_activate(int power) { if (p_ptr->food < PY_FOOD_FULL) /* No heal if we are "full" */ - (void)hp_player(dummy); + hp_player(dummy); else msg_print("You were not hungry."); /* Gain nutritional sustenance: 150/hp drained */ @@ -520,7 +519,7 @@ static void power_activate(int power) /* But if we ARE Gorged, it won't cure us */ dummy = p_ptr->food + MIN(5000, 100 * dummy); if (p_ptr->food < PY_FOOD_MAX) /* Not gorged already */ - (void)set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy); + set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy); } else msg_print("Yechh. That tastes foul."); @@ -531,14 +530,14 @@ static void power_activate(int power) { msg_print("You emit an eldritch howl!"); if (!get_aim_dir(&dir)) break; - (void)fear_monster(dir, plev); + fear_monster(dir, plev); } break; case PWR_REST_LIFE: { msg_print("You attempt to restore your lost energies."); - (void)restore_level(); + restore_level(); } break; @@ -560,7 +559,7 @@ static void power_activate(int power) m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if ((r_ptr->flags1 & RF1_NEVER_MOVE) && (m_ptr->status == MSTATUS_PET) && (!(r_ptr->flags9 & RF9_SPECIAL_GENE))) + if ((r_ptr->flags & RF_NEVER_MOVE) && (m_ptr->status == MSTATUS_PET) && (!(r_ptr->flags & RF_SPECIAL_GENE))) { q_ptr = &forge; object_prep(q_ptr, lookup_kind(TV_HYPNOS, 1)); @@ -654,7 +653,7 @@ static void power_activate(int power) { msg_print("Your eyes look mesmerising..."); if (get_aim_dir(&dir)) - (void) charm_monster(dir, p_ptr->lev); + charm_monster(dir, p_ptr->lev); } break; @@ -690,13 +689,13 @@ static void power_activate(int power) case PWR_SMELL_MET: { - (void)detect_treasure(DEFAULT_RADIUS); + detect_treasure(DEFAULT_RADIUS); } break; case PWR_SMELL_MON: { - (void)detect_monsters_normal(DEFAULT_RADIUS); + detect_monsters_normal(DEFAULT_RADIUS); } break; @@ -720,7 +719,7 @@ static void power_activate(int power) msg_print("You bite into thin air!"); break; } - else if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT) || (c_ptr->feat == FEAT_MOUNTAIN)) + else if ((f_info[c_ptr->feat].flags & FF_PERMANENT) || (c_ptr->feat == FEAT_MOUNTAIN)) { msg_print("Ouch! This wall is harder than your teeth!"); break; @@ -740,25 +739,25 @@ static void power_activate(int power) if ((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_RUBBLE)) { - (void)set_food(p_ptr->food + 3000); + set_food(p_ptr->food + 3000); } else if ((c_ptr->feat >= FEAT_MAGMA) && (c_ptr->feat <= FEAT_QUARTZ_K)) { - (void)set_food(p_ptr->food + 5000); + set_food(p_ptr->food + 5000); } else if ((c_ptr->feat >= FEAT_SANDWALL) && (c_ptr->feat <= FEAT_SANDWALL_K)) { - (void)set_food(p_ptr->food + 500); + set_food(p_ptr->food + 500); } else { msg_print("This granite is very filling!"); - (void)set_food(p_ptr->food + 10000); + set_food(p_ptr->food + 10000); } } - (void)wall_to_mud(dir); + wall_to_mud(dir); oy = p_ptr->py; ox = p_ptr->px; @@ -780,20 +779,20 @@ static void power_activate(int power) case PWR_SWAP_POS: { if (!get_aim_dir(&dir)) return; - (void)teleport_swap(dir); + teleport_swap(dir); } break; case PWR_SHRIEK: { - (void)fire_ball(GF_SOUND, 0, 4 * p_ptr->lev, 8); - (void)aggravate_monsters(0); + fire_ball(GF_SOUND, 0, 4 * p_ptr->lev, 8); + aggravate_monsters(0); } break; case PWR_ILLUMINE: { - (void)lite_area(damroll(2, (p_ptr->lev / 2)), (p_ptr->lev / 10) + 1); + lite_area(damroll(2, (p_ptr->lev / 2)), (p_ptr->lev / 10) + 1); } break; @@ -821,7 +820,7 @@ static void power_activate(int power) case PWR_MIDAS_TCH: { - (void)alchemy(); + alchemy(); } break; @@ -842,27 +841,27 @@ static void power_activate(int power) if (rand_int(5) < num) { - (void)set_oppose_acid(p_ptr->oppose_acid + dur); + set_oppose_acid(p_ptr->oppose_acid + dur); num--; } if (rand_int(4) < num) { - (void)set_oppose_elec(p_ptr->oppose_elec + dur); + set_oppose_elec(p_ptr->oppose_elec + dur); num--; } if (rand_int(3) < num) { - (void)set_oppose_fire(p_ptr->oppose_fire + dur); + set_oppose_fire(p_ptr->oppose_fire + dur); num--; } if (rand_int(2) < num) { - (void)set_oppose_cold(p_ptr->oppose_cold + dur); + set_oppose_cold(p_ptr->oppose_cold + dur); num--; } if (num) { - (void)set_oppose_pois(p_ptr->oppose_pois + dur); + set_oppose_pois(p_ptr->oppose_pois + dur); num--; } } @@ -978,7 +977,7 @@ static void power_activate(int power) case PWR_RECALL: { - if (!(dungeon_flags2 & DF2_ASK_LEAVE) || ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? "))) + if (!(dungeon_flags & DF_ASK_LEAVE) || ((dungeon_flags & DF_ASK_LEAVE) && !get_check("Leave this unique level forever? "))) { recall_player(21, 15); } @@ -1000,7 +999,7 @@ static void power_activate(int power) monster_type *m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if (r_ptr->flags3 & RF3_EVIL) + if (r_ptr->flags & RF_EVIL) { /* Delete the monster, rather than killing it. */ delete_monster_idx(c_ptr->m_idx); diff --git a/src/powers.hpp b/src/powers.hpp index 35d317b0..aa24e7d0 100644 --- a/src/powers.hpp +++ b/src/powers.hpp @@ -1,6 +1,6 @@ #pragma once -extern void do_cmd_power(); +void do_cmd_power(); /* * Powers (mutation, activations, ...) @@ -64,7 +64,6 @@ extern void do_cmd_power(); #define PWR_UNHYPNO 53 #define PWR_INCARNATE 54 #define PWR_MAGIC_MAP 55 -#define PWR_LAY_TRAP 56 #define PWR_COMPANION 58 #define PWR_BEAR 59 #define PWR_DODGE 60 diff --git a/src/q_betwen.cc b/src/q_betwen.cc index 2bebe452..ca8243b4 100644 --- a/src/q_betwen.cc +++ b/src/q_betwen.cc @@ -1,6 +1,7 @@ #include "q_betwen.hpp" #include "cave.hpp" +#include "dungeon_flag.hpp" #include "cave_type.hpp" #include "hook_chardump_in.hpp" #include "hook_init_quest_in.hpp" @@ -18,7 +19,7 @@ #define cquest (quest[QUEST_BETWEEN]) -static bool_ quest_between_move_hook(void *, void *in_, void *) +static bool quest_between_move_hook(void *, void *in_, void *) { struct hook_move_in *in = static_cast<struct hook_move_in *>(in_); s32b y = in->y; @@ -27,7 +28,10 @@ static bool_ quest_between_move_hook(void *, void *in_, void *) c_ptr = &cave[y][x]; - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } /* The tower of Turgon */ if ((c_ptr->feat == FEAT_SHOP) && (c_ptr->special == 27)) @@ -37,19 +41,28 @@ static bool_ quest_between_move_hook(void *, void *in_, void *) cquest.status = QUEST_STATUS_COMPLETED; - return TRUE; + return true; } /* Only 1 ambush */ - if (cquest.data[0]) return (FALSE); + if (cquest.data[0]) + { + return false; + } if (!p_ptr->wild_mode) { - if (p_ptr->wilderness_y > 19) return (FALSE); + if (p_ptr->wilderness_y > 19) + { + return false; + } } else { - if (p_ptr->py > 19) return (FALSE); + if (p_ptr->py > 19) + { + return false; + } } /* Mark as entered */ @@ -63,16 +76,19 @@ static bool_ quest_between_move_hook(void *, void *in_, void *) cmsg_print(TERM_YELLOW, "Trone steps forth and speaks: 'The secret of the Void Jumpgates"); cmsg_print(TERM_YELLOW, "will not be used by any but the thunderlords!'"); - return FALSE; + return false; } -static bool_ quest_between_gen_hook(void *, void *, void *) +static bool quest_between_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_BETWEEN) return FALSE; + if (p_ptr->inside_quest != QUEST_BETWEEN) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -96,18 +112,18 @@ static bool_ quest_between_gen_hook(void *, void *, void *) /* Otherwise instadeath */ energy_use = 0; - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; - return TRUE; + return true; } -static bool_ quest_between_finish_hook(void *, void *in_, void *) +static bool quest_between_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; object_type forge, *q_ptr; - if (q_idx != QUEST_BETWEEN) return FALSE; + if (q_idx != QUEST_BETWEEN) return false; c_put_str(TERM_YELLOW, "Ah you finally arrived, I hope your travel wasn't too hard.", 8, 0); c_put_str(TERM_YELLOW, "As a reward you can freely use the Void Jumpgates for quick travel.", 9, 0); @@ -128,7 +144,7 @@ static bool_ quest_between_finish_hook(void *, void *in_, void *) object_known(q_ptr); q_ptr->discount = 100; q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NULL; @@ -136,14 +152,17 @@ static bool_ quest_between_finish_hook(void *, void *in_, void *) del_hook_new(HOOK_QUEST_FINISH, quest_between_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_between_death_hook(void *, void *, void *) +static bool quest_between_death_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_BETWEEN) return FALSE; + if (p_ptr->inside_quest != QUEST_BETWEEN) + { + return false; + } for (i = m_max - 1; i >= 1; i--) { @@ -162,14 +181,14 @@ static bool_ quest_between_death_hook(void *, void *, void *) cave_set_feat(p_ptr->py, p_ptr->px, FEAT_LESS); cave[p_ptr->py][p_ptr->px].special = 0; - return FALSE; + return false; } - return FALSE; + return false; } -static bool_ quest_between_dump_hook(void *, void *in_, void *) +static bool quest_between_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -179,10 +198,10 @@ static bool_ quest_between_dump_hook(void *, void *in_, void *) fprintf(f, "\n You established a permanent void jumpgates liaison between Minas Anor and Gondolin,"); fprintf(f, "\n thus allowing the last alliance to exist."); } - return (FALSE); + return false; } -static bool_ quest_between_forbid_hook(void *, void *in_, void *) +static bool quest_between_forbid_hook(void *, void *in_, void *) { hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_); s32b q_idx = in->q_idx; @@ -192,12 +211,12 @@ static bool_ quest_between_forbid_hook(void *, void *in_, void *) if (p_ptr->lev < 45) { c_put_str(TERM_WHITE, "I fear you are not ready for the next quest, come back later.", 8, 0); - return (TRUE); + return true; } - return (FALSE); + return false; } -bool_ quest_between_init_hook(int q) +void quest_between_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -208,5 +227,4 @@ bool_ quest_between_init_hook(int q) } add_hook_new(HOOK_CHAR_DUMP, quest_between_dump_hook, "between_dump", NULL); add_hook_new(HOOK_INIT_QUEST, quest_between_forbid_hook, "between_forbid", NULL); - return (FALSE); } diff --git a/src/q_betwen.hpp b/src/q_betwen.hpp index d2fc08f0..54042a24 100644 --- a/src/q_betwen.hpp +++ b/src/q_betwen.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_between_init_hook(int q_idx); +void quest_between_init_hook(); diff --git a/src/q_bounty.cc b/src/q_bounty.cc index bb84d48d..f0a431de 100644 --- a/src/q_bounty.cc +++ b/src/q_bounty.cc @@ -1,7 +1,10 @@ #include "q_bounty.hpp" +#include "game.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "object1.hpp" #include "object2.hpp" #include "object_type.hpp" @@ -11,38 +14,42 @@ #include "util.hpp" #include "variable.hpp" +#include <fmt/format.h> + #define cquest (quest[QUEST_BOUNTY]) #define bounty_quest_monster (cquest.data[0]) static bool_ lua_mon_hook_bounty(int r_idx) { - monster_race* r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; /* Reject uniques */ - if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE); + if (r_ptr->flags & RF_UNIQUE) return (FALSE); /* Reject those who cannot leave anything */ - if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) return (FALSE); + if (!(r_ptr->flags & RF_DROP_CORPSE)) return (FALSE); /* Accept only monsters that can be generated */ - if (r_ptr->flags9 & RF9_SPECIAL_GENE) return (FALSE); - if (r_ptr->flags9 & RF9_NEVER_GENE) return (FALSE); + if (r_ptr->flags & RF_SPECIAL_GENE) return (FALSE); + if (r_ptr->flags & RF_NEVER_GENE) return (FALSE); /* Reject pets */ - if (r_ptr->flags7 & RF7_PET) return (FALSE); + if (r_ptr->flags & RF_PET) return (FALSE); /* Reject friendly creatures */ - if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE); + if (r_ptr->flags & RF_FRIENDLY) return (FALSE); /* Accept only monsters that are not breeders */ - if (r_ptr->flags4 & RF4_MULTIPLY) return (FALSE); + if (r_ptr->spells & SF_MULTIPLY) return (FALSE); /* Forbid joke monsters */ - if (r_ptr->flags8 & RF8_JOKEANGBAND) return (FALSE); + if (r_ptr->flags & RF_JOKEANGBAND) return (FALSE); /* Accept only monsters that are not good */ - if (r_ptr->flags3 & RF3_GOOD) return (FALSE); + if (r_ptr->flags & RF_GOOD) return (FALSE); /* The rest are acceptable */ return (TRUE); @@ -74,9 +81,9 @@ static bool bounty_item_tester_hook(object_type const *o_ptr) return ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval2 == bounty_quest_monster)); } -bool_ quest_bounty_init_hook(int dummy) +void quest_bounty_init_hook() { - return FALSE; + // Initialized by building action } bool_ quest_bounty_drop_item() @@ -104,6 +111,8 @@ bool_ quest_bounty_drop_item() bool_ quest_bounty_get_item() { + auto &s_info = game->s_info; + if (cquest.status != QUEST_STATUS_TAKEN) { msg_print("You do not have any bounty quest yet."); @@ -132,16 +141,19 @@ bool_ quest_bounty_get_item() skill_type *lore = &s_info[SKILL_LORE]; skill_type *preservation = &s_info[SKILL_PRESERVATION]; - if (lore->mod == 0) { + if (lore->mod == 0) + { lore->mod = 900; - lore->dev = TRUE; + lore->dev = true; } + lore->value += lore->mod; - if (preservation->mod == 0) { + if (preservation->mod == 0) + { preservation->value = 800; preservation->mod = 800; - preservation->dev = TRUE; + preservation->dev = true; msg_print("I see you don't know the corpse preservation skill, I shall teach you it too."); } @@ -151,20 +163,18 @@ bool_ quest_bounty_get_item() return FALSE; } -bool_ quest_bounty_describe(FILE *fff) +std::string quest_bounty_describe() { char mdesc[512]; + fmt::MemoryWriter w; if (cquest.status == QUEST_STATUS_TAKEN) { monster_race_desc(mdesc, bounty_quest_monster, 0); - fprintf(fff, "#####yBounty quest!\n"); - fprintf(fff, "You must bring back %s corpse to the beastmaster.\n", mdesc); - fprintf(fff, "\n"); - - return TRUE; + w.write("#####yBounty quest!\n"); + w.write("You must bring back {} corpse to the beastmaster.", mdesc); } - return FALSE; + return w.str(); } diff --git a/src/q_bounty.hpp b/src/q_bounty.hpp index 234c036d..fe9742ef 100644 --- a/src/q_bounty.hpp +++ b/src/q_bounty.hpp @@ -2,7 +2,9 @@ #include "h-basic.h" -extern bool_ quest_bounty_init_hook(int q_idx); -extern bool_ quest_bounty_drop_item(); -extern bool_ quest_bounty_get_item(); -extern bool_ quest_bounty_describe(FILE *fff); +#include <string> + +void quest_bounty_init_hook(); +bool_ quest_bounty_drop_item(); +bool_ quest_bounty_get_item(); +std::string quest_bounty_describe(); diff --git a/src/q_dragons.cc b/src/q_dragons.cc index 6c6084d1..9f89089c 100644 --- a/src/q_dragons.cc +++ b/src/q_dragons.cc @@ -2,7 +2,10 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -16,8 +19,10 @@ #define cquest (quest[QUEST_DRAGONS]) -static bool_ quest_dragons_gen_hook(void *, void *, void *) +static bool quest_dragons_gen_hook(void *, void *, void *) { + auto const &f_info = game->edit_data.f_info; + int x, y, i; int xstart = 2; int ystart = 2; @@ -47,18 +52,17 @@ static bool_ quest_dragons_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("dragons.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; /* Place some columns */ for (i = 35; i > 0; ) { - int flags; y = rand_int(21) + 3; x = rand_int(31) + 3; /* Bar columns on even squares so the whole level is guaranteed to be accessible */ - flags = f_info[cave[y][x].feat].flags1; - if (!(flags % 2) && !(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(x % 2) && !(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { --i; cave_set_feat(y, x, FEAT_MOUNTAIN); @@ -68,11 +72,10 @@ static bool_ quest_dragons_gen_hook(void *, void *, void *) /* Place some random dragons */ for (i = 25; i > 0; ) { - int m_idx, flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { /* blue, white, red, black, bronze, gold, green, multi-hued */ int baby_dragons[8] = {163, 164, 167, 166, 218, 219, 165, 204}; @@ -94,7 +97,7 @@ static bool_ quest_dragons_gen_hook(void *, void *, void *) dragon = mature_dragons[color]; --i; - m_idx = place_monster_one(y, x, dragon, 0, magik(33), MSTATUS_ENEMY); + int m_idx = place_monster_one(y, x, dragon, 0, magik(33), MSTATUS_ENEMY); if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; } } @@ -104,7 +107,7 @@ static bool_ quest_dragons_gen_hook(void *, void *, void *) return TRUE; } -static bool_ quest_dragons_death_hook(void *, void *, void *) +static bool quest_dragons_death_hook(void *, void *, void *) { int i, mcnt = 0; @@ -117,9 +120,15 @@ static bool_ quest_dragons_death_hook(void *, void *, void *) monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ - if (!m_ptr->r_idx) continue; + if (!m_ptr->r_idx) + { + continue; + } - if (m_ptr->status <= MSTATUS_ENEMY) mcnt++; + if (m_ptr->status <= MSTATUS_ENEMY) + { + mcnt++; + } } /* Nobody left ? */ @@ -131,17 +140,21 @@ static bool_ quest_dragons_death_hook(void *, void *, void *) process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "Gondolin is safer now."); - return (FALSE); + return false; } - return FALSE; + + return false; } -static bool_ quest_dragons_finish_hook(void *, void *in_, void *) +static bool quest_dragons_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_DRAGONS) return FALSE; + if (q_idx != QUEST_DRAGONS) + { + return false; + } c_put_str(TERM_YELLOW, "Thank you for killing the dragons!", 8, 0); c_put_str(TERM_YELLOW, "You can use the cave as your house as a reward.", 9, 0); @@ -149,10 +162,10 @@ static bool_ quest_dragons_finish_hook(void *, void *in_, void *) /* Continue the plot */ *(quest[q_idx].plot) = QUEST_EOL; - return TRUE; + return true; } -bool_ quest_dragons_init_hook(int q_idx) +void quest_dragons_init_hook() { if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -160,5 +173,4 @@ bool_ quest_dragons_init_hook(int q_idx) add_hook_new(HOOK_QUEST_FINISH, quest_dragons_finish_hook, "dragons_finish", NULL); add_hook_new(HOOK_GEN_QUEST, quest_dragons_gen_hook, "dragons_geb", NULL); } - return (FALSE); } diff --git a/src/q_dragons.hpp b/src/q_dragons.hpp index f0aa50f2..cda41321 100644 --- a/src/q_dragons.hpp +++ b/src/q_dragons.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_dragons_init_hook(int q_idx); +void quest_dragons_init_hook(); diff --git a/src/q_eol.cc b/src/q_eol.cc index f27ce9df..815b3107 100644 --- a/src/q_eol.cc +++ b/src/q_eol.cc @@ -2,6 +2,7 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "game.hpp" #include "generate.hpp" #include "hook_stair_in.hpp" #include "hook_quest_finish_in.hpp" @@ -14,7 +15,6 @@ #include "object2.hpp" #include "player_type.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "variable.hpp" #include "z-rand.hpp" @@ -25,14 +25,17 @@ GENERATE_MONSTER_LOOKUP_FN(get_eol, "Eol, the Dark Elf") -static bool_ quest_eol_gen_hook(void *, void *, void *) +static bool quest_eol_gen_hook(void *, void *, void *) { int x, y; bool_ done = FALSE; int xsize = 50, ysize = 30, y0, x0; int m_idx = 0; - if (p_ptr->inside_quest != QUEST_EOL) return FALSE; + if (p_ptr->inside_quest != QUEST_EOL) + { + return false; + } x0 = 2 + (xsize / 2); y0 = 2 + (ysize / 2); @@ -95,11 +98,6 @@ static bool_ quest_eol_gen_hook(void *, void *, void *) if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; } - if (magik(18)) - { - place_trap(y, x); - } - /* Place player at one end */ p_ptr->py = y; p_ptr->px = x; @@ -107,16 +105,19 @@ static bool_ quest_eol_gen_hook(void *, void *, void *) cave_set_feat(p_ptr->py, p_ptr->px, FEAT_LESS); - return TRUE; + return true; } -static bool_ quest_eol_finish_hook(void *, void *in_, void *) +static bool quest_eol_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; object_type forge, *q_ptr; - if (q_idx != QUEST_EOL) return FALSE; + if (q_idx != QUEST_EOL) + { + return false; + } c_put_str(TERM_YELLOW, "A tragedy, but the deed needed to be done.", 8, 0); c_put_str(TERM_YELLOW, "Accept my thanks, and that reward.", 9, 0); @@ -130,24 +131,27 @@ static bool_ quest_eol_finish_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NIRNAETH; - quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot)); + quest[*(quest[q_idx].plot)].init(); del_hook_new(HOOK_QUEST_FINISH, quest_eol_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_eol_fail_hook(void *, void *in_, void *) +static bool quest_eol_fail_hook(void *, void *in_, void *) { struct hook_quest_fail_in *in = static_cast<struct hook_quest_fail_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_EOL) return FALSE; + if (q_idx != QUEST_EOL) + { + return false; + } c_put_str(TERM_YELLOW, "You fled ! I did not think you would flee...", 8, 0); @@ -157,16 +161,19 @@ static bool_ quest_eol_fail_hook(void *, void *in_, void *) del_hook_new(HOOK_QUEST_FAIL, quest_eol_fail_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_eol_death_hook(void *, void *in_, void *) +static bool quest_eol_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - if (p_ptr->inside_quest != QUEST_EOL) return FALSE; + if (p_ptr->inside_quest != QUEST_EOL) + { + return false; + } if (r_idx == get_eol()) { @@ -176,20 +183,28 @@ static bool_ quest_eol_death_hook(void *, void *in_, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_eol_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } - return FALSE; + return false; } -static bool_ quest_eol_stair_hook(void *, void *in_, void *) +static bool quest_eol_stair_hook(void *, void *in_, void *) { + auto const &r_info = game->edit_data.r_info; + struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_); - monster_race *r_ptr = &r_info[get_eol()]; + auto r_ptr = &r_info[get_eol()]; - if (p_ptr->inside_quest != QUEST_EOL) return FALSE; + if (p_ptr->inside_quest != QUEST_EOL) + { + return false; + } - if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return TRUE; + if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) + { + return true; + } if (r_ptr->max_num) { @@ -198,21 +213,24 @@ static bool_ quest_eol_stair_hook(void *, void *in_, void *) /* Flush input */ flush(); - if (!get_check("Really abandon the quest?")) return TRUE; + if (!get_check("Really abandon the quest?")) + { + return true; + } cmsg_print(TERM_YELLOW, "You flee away from Eol..."); cquest.status = QUEST_STATUS_FAILED; del_hook_new(HOOK_STAIR, quest_eol_stair_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } } - return FALSE; + return false; } -bool_ quest_eol_init_hook(int q) +void quest_eol_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -222,5 +240,4 @@ bool_ quest_eol_init_hook(int q) add_hook_new(HOOK_QUEST_FAIL, quest_eol_fail_hook, "eol_fail", NULL); add_hook_new(HOOK_QUEST_FINISH, quest_eol_finish_hook, "eol_finish", NULL); } - return (FALSE); } diff --git a/src/q_eol.hpp b/src/q_eol.hpp index ab7f1274..19af3583 100644 --- a/src/q_eol.hpp +++ b/src/q_eol.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_eol_init_hook(int q_idx); +void quest_eol_init_hook(); diff --git a/src/q_evil.cc b/src/q_evil.cc index 3bc953cd..4636356a 100644 --- a/src/q_evil.cc +++ b/src/q_evil.cc @@ -2,7 +2,10 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -16,17 +19,24 @@ #define cquest (quest[QUEST_EVIL]) -static bool_ quest_evil_gen_hook(void *, void *, void *) +static bool quest_evil_gen_hook(void *, void *, void *) { + auto const &f_info = game->edit_data.f_info; + int x, y, i; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_EVIL) return FALSE; + if (p_ptr->inside_quest != QUEST_EVIL) + { + return false; + } /* Just in case we didnt talk the the mayor */ if (cquest.status == QUEST_STATUS_UNTAKEN) + { cquest.status = QUEST_STATUS_TAKEN; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -47,18 +57,17 @@ static bool_ quest_evil_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("evil.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; /* Place some random balrogs */ for (i = 6; i > 0; ) { - int m_idx, flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { - m_idx = place_monster_one(y, x, 996, 0, FALSE, MSTATUS_ENEMY); + int m_idx = place_monster_one(y, x, 996, 0, FALSE, MSTATUS_ENEMY); if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; --i; } @@ -66,14 +75,17 @@ static bool_ quest_evil_gen_hook(void *, void *, void *) process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_evil_death_hook(void *, void *, void *) +static bool quest_evil_death_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_EVIL) return FALSE; + if (p_ptr->inside_quest != QUEST_EVIL) + { + return false; + } /* Process the monsters (backwards) */ for (i = m_max - 1; i >= 1; i--) @@ -99,17 +111,20 @@ static bool_ quest_evil_death_hook(void *, void *, void *) process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "Khazad-Dum is safer now."); - return (FALSE); + return false; } - return FALSE; + return false; } -static bool_ quest_evil_finish_hook(void *, void *in_, void *) +static bool quest_evil_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_EVIL) return FALSE; + if (q_idx != QUEST_EVIL) + { + return false; + } c_put_str(TERM_YELLOW, "Thank you for saving us!", 8, 0); c_put_str(TERM_YELLOW, "You can use the cave as your house as a reward.", 9, 0); @@ -117,10 +132,10 @@ static bool_ quest_evil_finish_hook(void *, void *in_, void *) /* End the plot */ *(quest[q_idx].plot) = QUEST_NULL; - return TRUE; + return true; } -bool_ quest_evil_init_hook(int q_idx) +void quest_evil_init_hook() { if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -128,5 +143,4 @@ bool_ quest_evil_init_hook(int q_idx) add_hook_new(HOOK_QUEST_FINISH, quest_evil_finish_hook, "evil_finish", NULL); add_hook_new(HOOK_GEN_QUEST, quest_evil_gen_hook, "evil_geb", NULL); } - return (FALSE); } diff --git a/src/q_evil.hpp b/src/q_evil.hpp index 06fb17e1..0079e56c 100644 --- a/src/q_evil.hpp +++ b/src/q_evil.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_evil_init_hook(int q_idx); +void quest_evil_init_hook(); diff --git a/src/q_fireprof.cc b/src/q_fireprof.cc index 021cf2fb..26bf75af 100644 --- a/src/q_fireprof.cc +++ b/src/q_fireprof.cc @@ -1,27 +1,27 @@ #include "q_fireprof.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "hook_get_in.hpp" #include "hooks.hpp" #include "lua_bind.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_type.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "variable.hpp" #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> #define cquest (quest[QUEST_FIREPROOF]) -#define print_hook(fmt,...) do { fprintf(hook_file, fmt, ##__VA_ARGS__); } while (0) - /* * Per-module "settings" */ @@ -29,16 +29,16 @@ typedef struct fireproof_settings fireproof_settings; struct fireproof_settings { byte tval; /* tval of object to use. */ + byte sval; /* sval of object to use. */ cptr tval_name; /* descriptive name of tval */ cptr tval_name_plural; /* descriptive name of tval (plural) */ - byte sval_max; /* max sval of object to use; sval will be 1<=X<=sval_max. */ s32b total_points; /* total number of points awarded */ }; static fireproof_settings const *fireproof_get_settings() { static fireproof_settings fireproof_settings = - { TV_RUNE2, "rune", "runes", 5, 24 }; + { TV_SCROLL, SV_SCROLL_FIRE, "scroll", "scrolls", 24 }; return &fireproof_settings; } @@ -61,22 +61,13 @@ static void set_item_points_remaining(s32b v) cquest.data[0] = settings->total_points - v; } -static void fireproof_set_sval(int sval_max) -{ - cquest.data[1] = sval_max; -} - -static int fireproof_get_sval() -{ - return cquest.data[1]; -} - static bool item_tester_hook_eligible(object_type const *o_ptr) { + fireproof_settings const *settings = fireproof_get_settings(); /* check it's the 'marked' item */ - return ((o_ptr->tval == fireproof_get_settings()->tval) && - (o_ptr->sval == fireproof_get_sval()) && - (o_ptr->pval2 == fireproof_get_sval())); + return ((o_ptr->tval == settings->tval) && + (o_ptr->sval == settings->sval) && + (o_ptr->pval2 == settings->sval)); } static object_filter_t const &item_tester_hook_proofable() @@ -90,7 +81,7 @@ static object_filter_t const &item_tester_hook_proofable() TVal(TV_STAFF)), // Must NOT already be fireproof Not( - HasFlag3(TR3_IGNORE_FIRE))); + HasFlags(TR_IGNORE_FIRE))); return instance; } @@ -368,7 +359,7 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate) } } -static bool_ fireproof_get_hook(void *, void *in_, void *) +static bool fireproof_get_hook(void *, void *in_, void *) { struct hook_get_in *in = static_cast<struct hook_get_in *>(in_); object_type *o_ptr = in->o_ptr; @@ -378,24 +369,24 @@ static bool_ fireproof_get_hook(void *, void *in_, void *) * generated via random object placement */ if ((p_ptr->inside_quest == QUEST_FIREPROOF) && (cquest.status != QUEST_STATUS_COMPLETED) && - (o_ptr->pval2 == fireproof_get_sval())) + (o_ptr->pval2 == fireproof_get_settings()->sval)) { /* ok mark the quest 'completed' */ cquest.status = QUEST_STATUS_COMPLETED; cmsg_print(TERM_YELLOW, "Fine! Looks like you've found it."); } - return FALSE; + return false; } -static bool_ fireproof_stair_hook(void *, void *, void *) +static bool fireproof_stair_hook(void *, void *, void *) { /* only ask this if player about to go up stairs of quest and * hasn't retrieved item */ if ((p_ptr->inside_quest != QUEST_FIREPROOF) || (cquest.status == QUEST_STATUS_COMPLETED)) { - return FALSE; + return false; } else { @@ -403,7 +394,7 @@ static bool_ fireproof_stair_hook(void *, void *, void *) if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) { - return FALSE; + return false; } /* flush all pending input */ @@ -417,17 +408,17 @@ static bool_ fireproof_stair_hook(void *, void *, void *) { /* fail the quest */ cquest.status = QUEST_STATUS_FAILED; - return FALSE; + return false; } else { /* if no, they stay in the quest */ - return TRUE; + return true; } } } -bool_ quest_fireproof_describe(FILE *hook_file) +std::string quest_fireproof_describe() { fireproof_settings const *settings = fireproof_get_settings(); int num_books, num_staff, num_scroll; @@ -437,53 +428,48 @@ bool_ quest_fireproof_describe(FILE *hook_file) num_staff = get_item_points_remaining() / FIREPROOF_STAFF_POINTS; num_scroll = get_item_points_remaining() / FIREPROOF_SCROLL_POINTS; + fmt::MemoryWriter w; + if (status == QUEST_STATUS_TAKEN) { /* Quest taken */ - print_hook("#####yAn Old Mages Quest!\n"); - print_hook("Retrieve the strange %s for the old mage " - "in Lothlorien.\n", settings->tval_name); - print_hook("\n"); + w.write("#####yAn Old Mages Quest!\n"); + w.write("Retrieve the strange {} for the old mage in Lothlorien.", settings->tval_name); } else if (status == QUEST_STATUS_COMPLETED) { /* essence retrieved, not taken to mage */ - print_hook("#####yAn Old Mages Quest!\n"); - print_hook("You have retrieved the %s for the old " - "mage in Lothlorien. Perhaps you \n", settings->tval_name); - print_hook("should see about a reward.\n"); - print_hook("\n"); + w.write("#####yAn Old Mages Quest!\n"); + w.write("You have retrieved the {} for the old mage in Lothlorien.\n", settings->tval_name); + w.write("Perhaps you should see about a reward."); } else if ((status == QUEST_STATUS_FINISHED) && (get_item_points_remaining() > 0)) { /* essence returned, not all books fireproofed */ - print_hook("#####yAn Old Mages Quest!\n"); - print_hook("You have retrieved the %s for the old " - "mage in Lothlorien. He will still \n", settings->tval_name); - print_hook("fireproof %d book(s) or %d staff/staves " - "or %d scroll(s) for you.\n", - num_books, num_staff, num_scroll); - print_hook("\n"); + w.write("#####yAn Old Mages Quest!\n"); + w.write("You have retrieved the {} for the old " + "mage in Lothlorien. He will still\n", settings->tval_name); + w.write("fireproof {} book(s) or {} staff/staves " + "or {} scroll(s) for you.", + num_books, num_staff, num_scroll); } - return TRUE; + return w.str(); } -static bool_ fireproof_gen_hook(void *, void *, void *) +static bool fireproof_gen_hook(void *, void *, void *) { fireproof_settings const *settings = fireproof_get_settings(); /* Only if player doing this quest */ if (p_ptr->inside_quest != QUEST_FIREPROOF) { - return FALSE; + return false; } /* Go ahead */ { - int traps, trap_y, trap_x; - /* load the map */ { int x0 = 2; @@ -492,75 +478,30 @@ static bool_ fireproof_gen_hook(void *, void *, void *) } /* no teleport */ - dungeon_flags2 = DF2_NO_TELEPORT; - - /* determine type of item */ - fireproof_set_sval(randint(settings->sval_max)); + dungeon_flags = DF_NO_TELEPORT; - /* create essence */ + /* create quest item */ { - int x, y; object_type forge; - - object_prep(&forge, lookup_kind(settings->tval, fireproof_get_sval())); + object_prep(&forge, lookup_kind(settings->tval, settings->sval)); /* mark item */ - forge.pval2 = fireproof_get_sval(); - forge.note = quark_add("quest"); + forge.pval2 = settings->sval; + forge.inscription = "quest"; /* roll for co-ordinates in top half of map */ - y = randint(3) + 2; - x = randint(45) + 2; + int const y = randint(3) + 2; + int const x = randint(45) + 2; /* drop it */ drop_near(&forge, -1, y, x); } - /* how many traps to generate */ - traps = rand_range(10, 30); - - /* generate the traps */ - while (traps > 0) - { - int tries = 0, trap_level = 0; - - /* make sure it's a safe place */ - while (tries == 0) - { - /* get grid coordinates */ - trap_y = randint(19) + 2; - trap_x = randint(45) + 2; - cave_type *c_ptr = &cave[trap_y][trap_x]; - - /* are the coordinates on a stair, or a wall? */ - if (((f_info[c_ptr->feat].flags1 & FF1_PERMANENT) != 0) || - ((f_info[c_ptr->feat].flags1 & FF1_FLOOR) == 0)) - { - /* try again */ - tries = 0; - } - else - { - /* not a stair, then stop this 'while' */ - tries = 1; - } - } - - /* randomise level of trap */ - trap_level = rand_range(20, 40); - - /* put the trap there */ - place_trap_leveled(trap_y, trap_x, trap_level); - - /* that's one less trap to place */ - traps = traps - 1; - } - - return TRUE; + return true; } } -bool_ quest_fireproof_init_hook(int q) +void quest_fireproof_init_hook() { /* Only need hooks if the quest is unfinished. */ if ((cquest.status >= QUEST_STATUS_UNTAKEN) && @@ -570,8 +511,4 @@ bool_ quest_fireproof_init_hook(int q) add_hook_new(HOOK_GET , fireproof_get_hook , "fireproof_get_hook", NULL); add_hook_new(HOOK_STAIR , fireproof_stair_hook, "fireproof_stair_hook", NULL); } - - return FALSE; } - -#undef print_hook diff --git a/src/q_fireprof.hpp b/src/q_fireprof.hpp index 53d368b0..361d45ad 100644 --- a/src/q_fireprof.hpp +++ b/src/q_fireprof.hpp @@ -2,6 +2,8 @@ #include "h-basic.h" -extern void quest_fireproof_building(bool_ *paid, bool_ *recreate); -extern bool_ quest_fireproof_init_hook(int q); -extern bool_ quest_fireproof_describe(FILE *fff); +#include <string> + +void quest_fireproof_building(bool_ *paid, bool_ *recreate); +void quest_fireproof_init_hook(); +std::string quest_fireproof_describe(); diff --git a/src/q_god.cc b/src/q_god.cc index 0a3b07e7..68296f36 100644 --- a/src/q_god.cc +++ b/src/q_god.cc @@ -1,16 +1,20 @@ #include "q_god.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_chardump_in.hpp" #include "hook_get_in.hpp" #include "hook_enter_dungeon_in.hpp" #include "hook_player_level_in.hpp" #include "hooks.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "object2.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "skill_type.hpp" #include "tables.hpp" #include "util.hpp" @@ -20,6 +24,7 @@ #include "z-rand.hpp" #include <assert.h> +#include <fmt/format.h> #define cquest (quest[QUEST_GOD]) #define cquest_quests_given (cquest.data[0]) @@ -41,13 +46,9 @@ * the return value will be one of the following: north, south, * east, west, north-east, south-east, south-west, north-west, * or "close" if it is within 2 tiles. - * - * The returned string is allocated with strdup(). */ -static char *compass(int y, int x, int y2, int x2) +static std::string compass(int y, int x, int y2, int x2) { - char compass_dir[64]; - // is it close to the north/south meridian? int y_diff = y2 - y; @@ -85,20 +86,25 @@ static char *compass(int y, int x, int y2, int x2) } // Maybe it is very close - if ((!x_axis) && (!y_axis)) { strcpy(compass_dir, "close"); } + if ((!x_axis) && (!y_axis)) { + return ""; // Handled specially by caller + } // Maybe it is (almost) due N/S - else if (!x_axis) { strcpy(compass_dir, y_axis); } + else if (!x_axis) { + return y_axis; + } // Maybe it is (almost) due E/W - else if (!y_axis) { strcpy(compass_dir, x_axis); } + else if (!y_axis) { + return x_axis; + } // or if it is neither - else { sprintf(compass_dir, "%s-%s", y_axis, x_axis); } - - /* Return a copy */ - return strdup(compass_dir); + else { + return fmt::format("{}-{}", y_axis, x_axis); + } } /* Returns a relative approximation of the 'distance' of y2, x2 from y, x. */ -static cptr approximate_distance(int y, int x, int y2, int x2) +static std::string approximate_distance(int y, int x, int y2, int x2) { // how far to away to the north/south? int y_diff = abs(y2 - y); @@ -222,107 +228,80 @@ static void get_home_coordinates(int *home1_y, int *home1_x, const char **home1, } } -/* Print using cmsg_print. */ -static void print_using_cmsg(cptr line, void *dummy) -{ - cmsg_print(TERM_YELLOW, line); -} - -/* Print using print_hook. */ -static void print_using_print_hook(cptr line, void *f_) -{ - FILE *f = (FILE *) f_; - fprintf(f, "%s\n", line); -} - -/* Show directions */ -static void print_directions(bool_ feel_it, void (*pfunc)(cptr, void *), void *pfdata) +static std::string make_directions(bool feel_it) { int home1_y, home1_x; int home2_y, home2_x; const char *home1 = NULL; const char *home2 = NULL; - char *home1_axis = NULL; - char *home2_axis = NULL; - cptr home1_distance = NULL; - cptr home2_distance = NULL; cptr feel_it_str = feel_it ? ", I can feel it.'" : "."; - char buf[256]; get_home_coordinates( &home1_y, &home1_x, &home1, &home2_y, &home2_x, &home2); - home1_axis = compass(home1_y, home1_x, cquest_dung_y, cquest_dung_x); - home2_axis = compass(home2_y, home2_x, cquest_dung_y, cquest_dung_x); - - home1_distance = approximate_distance(home1_y, home1_x, cquest_dung_y, cquest_dung_x); - home2_distance = approximate_distance(home2_y, home2_x, cquest_dung_y, cquest_dung_x); + auto home1_axis = compass(home1_y, home1_x, cquest_dung_y, cquest_dung_x); + auto home2_axis = compass(home2_y, home2_x, cquest_dung_y, cquest_dung_x); /* Build the message */ - if (!streq(home1_axis, "close")) + if (home1_axis.empty()) { - snprintf(buf, sizeof(buf), - "The temple lies %s to the %s of %s, ", - home1_distance, - home1_axis, - home1); - pfunc(buf, pfdata); + return fmt::format("The temple lies very close to {}, ", + home1); } else { - snprintf(buf, sizeof(buf), - "The temple lies very close to %s, ", - home1); - pfunc(buf, pfdata); + auto home1_distance = approximate_distance(home1_y, home1_x, cquest_dung_y, cquest_dung_x); + return fmt::format("The temple lies {} to the {} of {}, ", + home1_distance, + home1_axis, + home1); } - if (!streq(home2_axis, "close")) + if (home2_axis.empty()) { - snprintf(buf, sizeof(buf), - "and %s to the %s of %s%s", - home2_distance, - home2_axis, - home2, - feel_it_str); - pfunc(buf, pfdata); + return fmt::format("and very close to {}{}", + home2, + feel_it_str); } else { - snprintf(buf, sizeof(buf), - "and very close to %s%s", - home2, - feel_it_str); - pfunc(buf, pfdata); + auto home2_distance = approximate_distance(home2_y, home2_x, cquest_dung_y, cquest_dung_x); + return fmt::format("and {} to the {} of {}{}", + home2_distance, + home2_axis, + home2, + feel_it_str); } - - /* Free dyanmically allocated strings */ - free(home1_axis); - free(home2_axis); } -bool_ quest_god_describe(FILE *fff) +std::string quest_god_describe() { + fmt::MemoryWriter w; + if (cquest.status == QUEST_STATUS_TAKEN) { - fprintf(fff, "#####yGod quest " FMTs32b "!\n", cquest_quests_given); - fprintf(fff, "Thou art to find the lost temple of thy God and\n"); - fprintf(fff, "to retrieve the lost part of the relic for thy God! \n"); - print_directions(FALSE, print_using_print_hook, fff); - fprintf(fff, "\n"); + auto directions = make_directions(false); + w.write("#####yGod quest {}!\n", cquest_quests_given); + w.write("Thou art to find the lost temple of thy God and\n"); + w.write("to retrieve the lost part of the relic for thy God!\n"); + w.write("{}", directions.c_str()); } - return TRUE; + return w.str(); } static void quest_god_place_rand_dung() { + auto &wilderness = game->wilderness; + auto const &wf_info = game->edit_data.wf_info; + int x = -1, y = -1, tries; /* erase old dungeon */ if (cquest_quests_given > 0) { - wild_map[cquest_dung_y][cquest_dung_x].entrance = 0; + wilderness(cquest_dung_x, cquest_dung_y).entrance = 0; /* erase old recall level */ max_dlv[DUNGEON_GOD] = 0; @@ -332,19 +311,17 @@ static void quest_god_place_rand_dung() tries = 1000; while (tries > 0) { - wilderness_map *w_ptr = NULL; - wilderness_type_info *wf_ptr = NULL; tries = tries - 1; /* get grid coordinates, within a range which prevents * dungeon being generated at the very edge of the * wilderness (would crash the game). */ - x = rand_range(1, max_wild_x-2); - y = rand_range(1, max_wild_y-2); + x = rand_range(1, wilderness.width()-2); + y = rand_range(1, wilderness.height()-2); /* Is there a town/dungeon/potentially impassable feature there, ? */ - w_ptr = &wild_map[y][x]; - wf_ptr = &wf_info[w_ptr->feat]; + wilderness_map const *w_ptr = &wilderness(x, y); + wilderness_type_info const *wf_ptr = &wf_info[w_ptr->feat]; if ((w_ptr->entrance != 0) || (wf_ptr->entrance != 0) || @@ -375,7 +352,7 @@ static void quest_god_place_rand_dung() } /* create god dungeon in that place */ - wild_map[y][x].entrance = 1000 + DUNGEON_GOD; + wilderness(x, y).entrance = 1000 + DUNGEON_GOD; /* set quest variables */ cquest_dung_x = x; @@ -384,6 +361,8 @@ static void quest_god_place_rand_dung() static void quest_god_generate_relic() { + auto const &f_info = game->edit_data.f_info; + int tries = 1000, x = -1, y = -1; object_type relic; @@ -401,9 +380,8 @@ static void quest_god_generate_relic() c_ptr = &cave[y][x]; /* are the coordinates on a floor, not on a permanent feature (eg stairs), and not on a trap ? */ - if ((f_info[c_ptr->feat].flags1 & FF1_FLOOR) && - (!(f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) && - (c_ptr->t_idx == 0)) + if ((f_info[c_ptr->feat].flags & FF_FLOOR) && + (!(f_info[c_ptr->feat].flags & FF_PERMANENT))) { break; } @@ -413,7 +391,7 @@ static void quest_god_generate_relic() object_prep(&relic, lookup_kind(TV_JUNK, get_relic_num())); /* inscribe it to prevent automatizer 'accidents' */ - relic.note = quark_add("quest"); + relic.inscription = "quest"; /* If no safe co-ords were found, put it in the players backpack */ if (tries == 0) @@ -446,6 +424,8 @@ static void quest_god_generate_relic() static void quest_god_set_god_dungeon_attributes_eru() { + auto &d_info = game->edit_data.d_info; + /* The Eru temple is based on Meneltarma. */ /* W: Not too many monsters (they'll be tough though, with big @@ -478,30 +458,36 @@ static void quest_god_set_god_dungeon_attributes_eru() /* F: A large pillar, with stairs created at edges. (You can't * climb a rock through the middle, can you?) */ - d_info[DUNGEON_GOD].flags1 = - DF1_BIG | DF1_NO_DOORS | DF1_CIRCULAR_ROOMS | - DF1_EMPTY | DF1_TOWER | DF1_FLAT | DF1_ADJUST_LEVEL_2; - d_info[DUNGEON_GOD].flags2 = - DF2_ADJUST_LEVEL_1_2 | - DF2_NO_SHAFT | - DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_BIG | + DF_NO_DOORS | + DF_CIRCULAR_ROOMS | + DF_EMPTY | + DF_TOWER | + DF_FLAT | + DF_ADJUST_LEVEL_2 | + DF_ADJUST_LEVEL_1_2 | + DF_NO_SHAFT | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; d_info[DUNGEON_GOD].rules[0].percent = 50; /* M: We want evil or flying characters */ - d_info[DUNGEON_GOD].rules[0].mflags3 = RF3_EVIL; + d_info[DUNGEON_GOD].rules[0].mflags = RF_EVIL; d_info[DUNGEON_GOD].rules[1].mode = 3; d_info[DUNGEON_GOD].rules[1].percent = 50; /* M: We want evil or flying characters */ - d_info[DUNGEON_GOD].rules[1].mflags7 = RF7_CAN_FLY; + d_info[DUNGEON_GOD].rules[1].mflags = RF_CAN_FLY; } static void quest_god_set_god_dungeon_attributes_manwe() { + auto &d_info = game->edit_data.d_info; + /* Manwe's lost temple is high in the clouds */ /* W: Has average number of monsters. */ @@ -533,11 +519,13 @@ static void quest_god_set_god_dungeon_attributes_manwe() /* F: It's open, goes up like a tower, give it a few * interesting rooms, make the monsters hard(ish). */ - d_info[DUNGEON_GOD].flags1 = - DF1_NO_DOORS | DF1_TOWER | - DF1_CAVERN | DF1_ADJUST_LEVEL_2; - d_info[DUNGEON_GOD].flags2 = - DF2_NO_SHAFT | DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DOORS | + DF_TOWER | + DF_CAVERN | + DF_ADJUST_LEVEL_2 | + DF_NO_SHAFT | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; @@ -553,15 +541,17 @@ static void quest_god_set_god_dungeon_attributes_manwe() /* M: We want air(poison-type) or flying characters. Orcs * too. They would have ransacked his elf-loving temple :) */ - d_info[DUNGEON_GOD].rules[0].mflags2 = RF2_INVISIBLE; - d_info[DUNGEON_GOD].rules[1].mflags3 = RF3_ORC | RF3_IM_POIS; - d_info[DUNGEON_GOD].rules[2].mflags4 = RF4_BR_POIS | RF4_BR_GRAV; - d_info[DUNGEON_GOD].rules[3].mflags5 = RF5_BA_POIS; - d_info[DUNGEON_GOD].rules[4].mflags7 = RF7_CAN_FLY; + d_info[DUNGEON_GOD].rules[0].mflags = RF_INVISIBLE; + d_info[DUNGEON_GOD].rules[1].mflags = RF_ORC | RF_IM_POIS; + d_info[DUNGEON_GOD].rules[2].mspells = SF_BR_POIS | SF_BR_GRAV; + d_info[DUNGEON_GOD].rules[3].mspells = SF_BA_POIS; + d_info[DUNGEON_GOD].rules[4].mflags = RF_CAN_FLY; } static void quest_god_set_god_dungeon_attributes_tulkas() { + auto &d_info = game->edit_data.d_info; + /* Tulkas dungeon is quite normal, possibly a bit boring to be * honest. Maybe I should add something radical to it. 'The * house of Tulkas in the midmost of Valmar was a house of @@ -592,19 +582,23 @@ static void quest_god_set_god_dungeon_attributes_tulkas() d_info[DUNGEON_GOD].objs.tools = 15; /* F: fairly standard */ - d_info[DUNGEON_GOD].flags1 = DF1_NO_DESTROY | DF1_ADJUST_LEVEL_2; - d_info[DUNGEON_GOD].flags2 = DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DESTROY | + DF_ADJUST_LEVEL_2 | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; d_info[DUNGEON_GOD].rules[0].percent = 100; /* M: plenty demons please */ - d_info[DUNGEON_GOD].rules[0].mflags3 = RF3_DEMON | RF3_EVIL; + d_info[DUNGEON_GOD].rules[0].mflags = RF_DEMON | RF_EVIL; } static void quest_god_set_god_dungeon_attributes_melkor() { + auto &d_info = game->edit_data.d_info; + /* Melkors dungeon will be dark, fiery and stuff */ /* Many many monsters! (but prob ADJUST_LEVEL_1_2) */ @@ -637,8 +631,12 @@ static void quest_god_set_god_dungeon_attributes_melkor() d_info[DUNGEON_GOD].objs.tools = 25; /* F: Small, lava rivers, nasty monsters hehehehehe */ - d_info[DUNGEON_GOD].flags1 = DF1_SMALL | DF1_LAVA_RIVERS | DF1_ADJUST_LEVEL_1; - d_info[DUNGEON_GOD].flags2 = DF2_ADJUST_LEVEL_1_2 | DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_SMALL | + DF_LAVA_RIVERS | + DF_ADJUST_LEVEL_1 | + DF_ADJUST_LEVEL_1_2 | + DF_ADJUST_LEVEL_PLAYER; /* R: No restrictions on monsters here */ d_info[DUNGEON_GOD].rules[0].mode = 0; @@ -649,11 +647,13 @@ static void quest_god_set_god_dungeon_attributes_melkor() d_info[DUNGEON_GOD].rules[1].percent = 20; /* M: */ - d_info[DUNGEON_GOD].rules[1].mflags3 = RF3_GOOD; + d_info[DUNGEON_GOD].rules[1].mflags = RF_GOOD; } static void quest_god_set_god_dungeon_attributes_yavanna() { + auto &d_info = game->edit_data.d_info; + /* Yavannas dungeon will be very natural, tress and stuff. */ d_info[DUNGEON_GOD].min_m_alloc_level = 22; @@ -683,25 +683,30 @@ static void quest_god_set_god_dungeon_attributes_yavanna() d_info[DUNGEON_GOD].objs.tools = 40; /* F: Natural looking */ - d_info[DUNGEON_GOD].flags1 = - DF1_NO_DOORS | DF1_WATER_RIVERS | - DF1_NO_DESTROY | DF1_ADJUST_LEVEL_1 | - DF1_NO_RECALL; - d_info[DUNGEON_GOD].flags2 = - DF2_ADJUST_LEVEL_1_2 | DF2_NO_SHAFT | - DF2_NO_GENO | DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DOORS | + DF_WATER_RIVERS | + DF_NO_DESTROY | + DF_ADJUST_LEVEL_1 | + DF_NO_RECALL | + DF_ADJUST_LEVEL_1_2 | + DF_NO_SHAFT | + DF_NO_GENO | + DF_ADJUST_LEVEL_PLAYER; /* R: Demons, Undead, non-living */ d_info[DUNGEON_GOD].rules[0].mode = 3; d_info[DUNGEON_GOD].rules[0].percent = 100; /* M: */ - d_info[DUNGEON_GOD].rules[0].mflags3 = - RF3_DEMON | RF3_UNDEAD | RF3_NONLIVING; + d_info[DUNGEON_GOD].rules[0].mflags = + RF_DEMON | RF_UNDEAD | RF_NONLIVING; } static void quest_god_set_god_dungeon_attributes_aule() { + auto &d_info = game->edit_data.d_info; + d_info[DUNGEON_GOD].min_m_alloc_level = 24; d_info[DUNGEON_GOD].max_m_alloc_chance = 80; @@ -731,9 +736,11 @@ static void quest_god_set_god_dungeon_attributes_aule() /* F: Small, no destroyed levels, min monster level = dungeon * level */ - d_info[DUNGEON_GOD].flags1 = - DF1_SMALL | DF1_NO_DESTROY | - DF1_ADJUST_LEVEL_1 | DF1_NO_STREAMERS; + d_info[DUNGEON_GOD].flags = + DF_SMALL | + DF_NO_DESTROY | + DF_ADJUST_LEVEL_1 | + DF_NO_STREAMERS; /* R: No restrictions on monsters here */ d_info[DUNGEON_GOD].rules[0].mode = 0; @@ -742,6 +749,8 @@ static void quest_god_set_god_dungeon_attributes_aule() static void quest_god_set_god_dungeon_attributes_varda() { + auto &d_info = game->edit_data.d_info; + /* Varda lives with Manwe, so high in the clouds */ /* W: Has average number of monsters. */ @@ -771,11 +780,13 @@ static void quest_god_set_god_dungeon_attributes_varda() /* F: It's open, goes up like a tower, give it a few * interesting rooms, make the monsters hard(ish). */ - d_info[DUNGEON_GOD].flags1 = - DF1_NO_DOORS | DF1_TOWER | - DF1_CAVERN | DF1_ADJUST_LEVEL_1; - d_info[DUNGEON_GOD].flags2 = - DF2_NO_SHAFT | DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DOORS | + DF_TOWER | + DF_CAVERN | + DF_ADJUST_LEVEL_1 | + DF_NO_SHAFT | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; @@ -790,15 +801,17 @@ static void quest_god_set_god_dungeon_attributes_varda() d_info[DUNGEON_GOD].rules[4].percent = 20; /* M: We want air(poison-type) or flying characters. Orcs too. */ - d_info[DUNGEON_GOD].rules[0].mflags2 = RF2_INVISIBLE; - d_info[DUNGEON_GOD].rules[1].mflags3 = RF3_ORC | RF3_IM_POIS; - d_info[DUNGEON_GOD].rules[2].mflags4 = RF4_BR_POIS | RF4_BR_GRAV; - d_info[DUNGEON_GOD].rules[3].mflags5 = RF5_BA_POIS; - d_info[DUNGEON_GOD].rules[4].mflags7 = RF7_CAN_FLY; + d_info[DUNGEON_GOD].rules[0].mflags = RF_INVISIBLE; + d_info[DUNGEON_GOD].rules[1].mflags = RF_ORC | RF_IM_POIS; + d_info[DUNGEON_GOD].rules[2].mspells = SF_BR_POIS | SF_BR_GRAV; + d_info[DUNGEON_GOD].rules[3].mspells = SF_BA_POIS; + d_info[DUNGEON_GOD].rules[4].mflags = RF_CAN_FLY; } static void quest_god_set_god_dungeon_attributes_ulmo() { + auto &d_info = game->edit_data.d_info; + /* Ulmo dungeon is basically Tulkas, except with acquatic creatures. */ /* W: but with lots of monsters */ @@ -823,8 +836,10 @@ static void quest_god_set_god_dungeon_attributes_ulmo() d_info[DUNGEON_GOD].objs.tools = 5; /* F: fairly standard */ - d_info[DUNGEON_GOD].flags1 = DF1_NO_DESTROY | DF1_ADJUST_LEVEL_2; - d_info[DUNGEON_GOD].flags2 = DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DESTROY | + DF_ADJUST_LEVEL_2 | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; @@ -835,13 +850,15 @@ static void quest_god_set_god_dungeon_attributes_ulmo() d_info[DUNGEON_GOD].rules[2].percent = 30; /* M: Aquatic creatures only. */ - d_info[DUNGEON_GOD].rules[0].mflags3 = RF7_CAN_FLY; - d_info[DUNGEON_GOD].rules[1].mflags3 = RF7_AQUATIC; - d_info[DUNGEON_GOD].rules[2].mflags3 = RF3_RES_WATE; + d_info[DUNGEON_GOD].rules[0].mflags = RF_CAN_FLY; + d_info[DUNGEON_GOD].rules[1].mflags = RF_AQUATIC; + d_info[DUNGEON_GOD].rules[2].mflags = RF_RES_WATE; } static void quest_god_set_god_dungeon_attributes_mandos() { + auto &d_info = game->edit_data.d_info; + /* Mandos dungeon is basically Tulkas, except with undead. */ /* W: but with lots of monsters */ @@ -866,8 +883,10 @@ static void quest_god_set_god_dungeon_attributes_mandos() d_info[DUNGEON_GOD].objs.tools = 15; /* F: fairly standard */ - d_info[DUNGEON_GOD].flags1 = DF1_NO_DESTROY | DF1_ADJUST_LEVEL_2; - d_info[DUNGEON_GOD].flags2 = DF2_ADJUST_LEVEL_PLAYER; + d_info[DUNGEON_GOD].flags = + DF_NO_DESTROY | + DF_ADJUST_LEVEL_2 | + DF_ADJUST_LEVEL_PLAYER; /* R: */ d_info[DUNGEON_GOD].rules[0].mode = 3; @@ -879,16 +898,16 @@ static void quest_god_set_god_dungeon_attributes_mandos() d_info[DUNGEON_GOD].rules[0].r_char[2] = '\0'; d_info[DUNGEON_GOD].rules[0].r_char[3] = '\0'; d_info[DUNGEON_GOD].rules[0].r_char[4] = '\0'; - d_info[DUNGEON_GOD].rules[0].mflags3 = RF3_UNDEAD | RF3_EVIL; + d_info[DUNGEON_GOD].rules[0].mflags = RF_UNDEAD | RF_EVIL; } -static bool_ quest_god_level_end_gen_hook(void *, void *, void *) +static bool quest_god_level_end_gen_hook(void *, void *, void *) { /* Check for dungeon */ if ((dungeon_type != DUNGEON_GOD) || (cquest.status == QUEST_STATUS_UNTAKEN)) { - return FALSE; + return false; } /* if the relic has been created at this point, then it was @@ -936,17 +955,17 @@ static bool_ quest_god_level_end_gen_hook(void *, void *, void *) } } - return FALSE; + return false; } -static bool_ quest_god_player_level_hook(void *, void *in_, void *) +static bool quest_god_player_level_hook(void *, void *in_, void *) { struct hook_player_level_in *in = static_cast<struct hook_player_level_in *>(in_); s32b gained = in->gained_levels; if (gained <= 0) { - return FALSE; + return false; } /* check player is worshipping a god, not already on a god quest. */ @@ -965,7 +984,7 @@ static bool_ quest_god_player_level_hook(void *, void *in_, void *) { cquest_dun_minplev = p_ptr->lev; } - return FALSE; + return false; } else { @@ -978,6 +997,8 @@ static bool_ quest_god_player_level_hook(void *, void *in_, void *) quest_god_place_rand_dung(); /* God issues instructions */ + auto directions = make_directions(true); + cmsg_format(TERM_L_BLUE, "The voice of %s booms in your head:", deity_info[p_ptr->pgod].name); cmsg_print(TERM_YELLOW, "'I have a task for thee."); @@ -986,9 +1007,8 @@ static bool_ quest_god_player_level_hook(void *, void *in_, void *) cmsg_print(TERM_YELLOW, "Thou art to find my lost temple and retrieve a piece of the relic."); cmsg_print(TERM_YELLOW, "When thy task is done, thou art to lift it in the air and call upon my name."); cmsg_print(TERM_YELLOW, "I shall then come to reclaim what is mine!"); - - print_directions(TRUE, print_using_cmsg, NULL); - + cmsg_print(TERM_YELLOW, directions.c_str()); + /* Prepare depth of dungeon. If this was * generated in set_god_dungeon_attributes(), * then we'd have trouble if someone levelled @@ -997,11 +1017,13 @@ static bool_ quest_god_player_level_hook(void *, void *in_, void *) cquest_dun_maxdepth = cquest_dun_mindepth + 4; } - return FALSE; + return false; } -static bool_ quest_god_get_hook(void *, void *in_, void *) +static bool quest_god_get_hook(void *, void *in_, void *) { + auto &s_info = game->s_info; + hook_get_in *in = static_cast<hook_get_in *>(in_); s32b item = -in->o_idx; /* Note the negation */ @@ -1049,13 +1071,13 @@ static bool_ quest_god_get_hook(void *, void *in_, void *) /* Prevent further processing of 'take' action; we've destroyed the item. */ - return TRUE; + return true; } - return FALSE; + return false; } -static bool_ quest_god_char_dump_hook(void *, void *in_, void *) +static bool quest_god_char_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -1088,11 +1110,13 @@ static bool_ quest_god_char_dump_hook(void *, void *in_, void *) fprintf(f, "\n You found %s of the relic pieces%s.", relics_text, append_text); } - return FALSE; + return false; } static void set_god_dungeon_attributes() { + auto &d_info = game->edit_data.d_info; + /* dungeon properties altered according to which god player is worshipping, */ if (p_ptr->pgod == GOD_ERU) { @@ -1138,7 +1162,7 @@ static void set_god_dungeon_attributes() /* W: All dungeons are 5 levels deep, and created at 2/3 of * the player clvl when the quest is given */ { - dungeon_info_type *d_ptr = &d_info[DUNGEON_GOD]; + auto d_ptr = &d_info[DUNGEON_GOD]; d_ptr->mindepth = cquest_dun_mindepth; d_ptr->maxdepth = cquest_dun_maxdepth; d_ptr->min_plev = cquest_dun_minplev; @@ -1157,26 +1181,26 @@ static void quest_god_dungeon_setup(int d_idx) set_god_dungeon_attributes(); } -static bool_ quest_god_enter_dungeon_hook(void *, void *in_, void *) +static bool quest_god_enter_dungeon_hook(void *, void *in_, void *) { struct hook_enter_dungeon_in *in = static_cast<struct hook_enter_dungeon_in *>(in_); quest_god_dungeon_setup(in->d_idx); - return FALSE; + return false; } -static bool_ quest_god_gen_level_begin_hook(void *, void *, void *) +static bool quest_god_gen_level_begin_hook(void *, void *, void *) { quest_god_dungeon_setup(dungeon_type); - return FALSE; + return false; } -static bool_ quest_god_stair_hook(void *, void *, void *) +static bool quest_god_stair_hook(void *, void *, void *) { quest_god_dungeon_setup(dungeon_type); - return FALSE; + return false; } -static bool_ quest_god_birth_objects_hook(void *, void *, void *) +static bool quest_god_birth_objects_hook(void *, void *, void *) { cquest_quests_given = 0; cquest_relics_found = 0; @@ -1186,10 +1210,10 @@ static bool_ quest_god_birth_objects_hook(void *, void *, void *) cquest_relic_gen_tries = 0; cquest_relic_generated = FALSE; - return FALSE; + return false; } -bool_ quest_god_init_hook(int q) +void quest_god_init_hook() { /* Only need hooks if the quest is unfinished. */ if ((cquest.status >= QUEST_STATUS_UNTAKEN) && @@ -1207,6 +1231,4 @@ bool_ quest_god_init_hook(int q) /* Need this to re-initialize at birth; the quest data is * zeroed which isn't quite right. */ add_hook_new(HOOK_BIRTH_OBJECTS, quest_god_birth_objects_hook, "q_god_birth_objects", NULL); - - return FALSE; } diff --git a/src/q_god.hpp b/src/q_god.hpp index d9513bdb..839d4eaa 100644 --- a/src/q_god.hpp +++ b/src/q_god.hpp @@ -2,5 +2,7 @@ #include "h-basic.h" -bool_ quest_god_describe(FILE *); -bool_ quest_god_init_hook(int q); +#include <string> + +std::string quest_god_describe(); +void quest_god_init_hook(); diff --git a/src/q_haunted.cc b/src/q_haunted.cc index 57daa40e..f460ee80 100644 --- a/src/q_haunted.cc +++ b/src/q_haunted.cc @@ -2,14 +2,16 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" #include "init1.hpp" #include "monster2.hpp" #include "monster_type.hpp" #include "player_type.hpp" -#include "traps.hpp" #include "tables.hpp" #include "util.hpp" #include "variable.hpp" @@ -17,13 +19,18 @@ #define cquest (quest[QUEST_HAUNTED]) -static bool_ quest_haunted_gen_hook(void *, void *, void *) +static bool quest_haunted_gen_hook(void *, void *, void *) { + auto const &f_info = game->edit_data.f_info; + int x, y, i, m_idx; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_HAUNTED) return FALSE; + if (p_ptr->inside_quest != QUEST_HAUNTED) + { + return false; + } /* Just in case we didnt talk the the mayor */ if (cquest.status == QUEST_STATUS_UNTAKEN) @@ -48,16 +55,15 @@ static bool_ quest_haunted_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("haunted.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; /* Place some ghosts */ for (i = 12; i > 0; ) { - int flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { m_idx = place_monster_one(y, x, 477, 0, FALSE, MSTATUS_ENEMY); if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; @@ -68,11 +74,10 @@ static bool_ quest_haunted_gen_hook(void *, void *, void *) /* Place some random monsters to haunt us */ for (i = damroll(4, 4); i > 0; ) { - int flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { int monsters[22] = { 65, 100, 124, 125, 133, 231, 273, 327, 365, 416, 418, 507, 508, 533, 534, 553, 554, 555, 577, 607, 622, 665}; @@ -83,30 +88,19 @@ static bool_ quest_haunted_gen_hook(void *, void *, void *) } } - /* Place some random traps */ - for (i = 10 + damroll(4, 4); i > 0; ) - { - int flags; - y = rand_int(21) + 3; - x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) - { - --i; - place_trap(y, x); - } - } - process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_haunted_death_hook(void *, void *, void *) +static bool quest_haunted_death_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_HAUNTED) return FALSE; + if (p_ptr->inside_quest != QUEST_HAUNTED) + { + return false; + } /* Process the monsters (backwards) */ for (i = m_max - 1; i >= 1; i--) @@ -115,9 +109,15 @@ static bool_ quest_haunted_death_hook(void *, void *, void *) monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ - if (!m_ptr->r_idx) continue; + if (!m_ptr->r_idx) + { + continue; + } - if (m_ptr->status <= MSTATUS_ENEMY) mcnt++; + if (m_ptr->status <= MSTATUS_ENEMY) + { + mcnt++; + } } /* Nobody left ? */ @@ -130,17 +130,21 @@ static bool_ quest_haunted_death_hook(void *, void *, void *) process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "Minas Anor is safer now."); - return (FALSE); + return false; } - return FALSE; + + return false; } -static bool_ quest_haunted_finish_hook(void *, void *in_, void *) +static bool quest_haunted_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_HAUNTED) return FALSE; + if (q_idx != QUEST_HAUNTED) + { + return false; + } c_put_str(TERM_YELLOW, "Thank you for saving us!", 8, 0); c_put_str(TERM_YELLOW, "You can use the building as your house as a reward.", 9, 0); @@ -148,10 +152,10 @@ static bool_ quest_haunted_finish_hook(void *, void *in_, void *) /* Continue the plot */ *(quest[q_idx].plot) = QUEST_BETWEEN; - return TRUE; + return true; } -bool_ quest_haunted_init_hook(int q_idx) +void quest_haunted_init_hook() { if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -159,5 +163,4 @@ bool_ quest_haunted_init_hook(int q_idx) add_hook_new(HOOK_QUEST_FINISH, quest_haunted_finish_hook, "haunted_finish", NULL); add_hook_new(HOOK_GEN_QUEST, quest_haunted_gen_hook, "haunted_geb", NULL); } - return (FALSE); } diff --git a/src/q_haunted.hpp b/src/q_haunted.hpp index 4f51bce3..3965f0c3 100644 --- a/src/q_haunted.hpp +++ b/src/q_haunted.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_haunted_init_hook(int q_idx); +void quest_haunted_init_hook(); diff --git a/src/q_hobbit.cc b/src/q_hobbit.cc index 5a71711e..655755a3 100644 --- a/src/q_hobbit.cc +++ b/src/q_hobbit.cc @@ -1,6 +1,7 @@ #include "q_hobbit.hpp" #include "cave.hpp" +#include "game.hpp" #include "hook_chardump_in.hpp" #include "hook_chat_in.hpp" #include "hook_give_in.hpp" @@ -25,13 +26,16 @@ GENERATE_MONSTER_LOOKUP_FN(get_melinda_proudfoot, "Melinda Proudfoot") GENERATE_MONSTER_LOOKUP_FN(get_merton_proudfoot, "Merton Proudfoot, the lost hobbit") -static bool_ quest_hobbit_town_gen_hook(void *, void *in_, void *) +static bool quest_hobbit_town_gen_hook(void *, void *in_, void *) { struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_); int x = 1, y = 1, tries = 10000; bool_ small = in->small; - if ((turn < (cquest.data[1] + (DAY * 10L))) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) return (FALSE); + if ((turn < (cquest.data[1] + (DAY * 10L))) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) + { + return false; + } /* Find a good position */ while (tries) @@ -55,14 +59,17 @@ static bool_ quest_hobbit_town_gen_hook(void *, void *in_, void *) place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY); m_allow_special[r_idx] = FALSE; - return FALSE; + return false; } -static bool_ quest_hobbit_gen_hook(void *, void *, void *) +static bool quest_hobbit_gen_hook(void *, void *, void *) { int x = 1, y = 1, tries = 10000; - if ((cquest.status != QUEST_STATUS_TAKEN) || (dun_level != cquest.data[0]) || (dungeon_type != DUNGEON_MAZE)) return FALSE; + if ((cquest.status != QUEST_STATUS_TAKEN) || (dun_level != cquest.data[0]) || (dungeon_type != DUNGEON_MAZE)) + { + return false; + } /* Find a good position */ while (tries) @@ -84,10 +91,10 @@ static bool_ quest_hobbit_gen_hook(void *, void *, void *) place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_FRIEND); m_allow_special[r_idx] = FALSE; - return FALSE; + return false; } -static bool_ quest_hobbit_give_hook(void *, void *in_, void *) +static bool quest_hobbit_give_hook(void *, void *in_, void *) { struct hook_give_in *in = static_cast<struct hook_give_in *>(in_); object_type *o_ptr; @@ -98,9 +105,9 @@ static bool_ quest_hobbit_give_hook(void *, void *in_, void *) o_ptr = &p_ptr->inventory[item]; m_ptr = &m_list[m_idx]; - if (m_ptr->r_idx != get_merton_proudfoot()) return (FALSE); + if (m_ptr->r_idx != get_merton_proudfoot()) return false; - if ((o_ptr->tval != TV_SCROLL) || (o_ptr->sval != SV_SCROLL_WORD_OF_RECALL)) return (FALSE); + if ((o_ptr->tval != TV_SCROLL) || (o_ptr->sval != SV_SCROLL_WORD_OF_RECALL)) return false; msg_print("'Oh, thank you, noble one!'"); msg_print("Merton Proudfoot reads the scroll and is recalled to the safety of his home."); @@ -114,27 +121,27 @@ static bool_ quest_hobbit_give_hook(void *, void *in_, void *) del_hook_new(HOOK_GIVE, quest_hobbit_give_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_hobbit_speak_hook(void *, void *in_, void *) +static bool quest_hobbit_speak_hook(void *, void *in_, void *) { struct hook_mon_speak_in *in = static_cast<struct hook_mon_speak_in *>(in_); s32b m_idx = in->m_idx; if (m_list[m_idx].r_idx != get_melinda_proudfoot()) { - return (FALSE); + return false; } if (cquest.status < QUEST_STATUS_COMPLETED) { msg_format("%^s begs for your help.", in->m_name); } - return (TRUE); + return true; } -static bool_ quest_hobbit_chat_hook(void *, void *in_, void *) +static bool quest_hobbit_chat_hook(void *, void *in_, void *) { struct hook_chat_in *in = static_cast<struct hook_chat_in *>(in_); s32b m_idx = in->m_idx; @@ -142,7 +149,10 @@ static bool_ quest_hobbit_chat_hook(void *, void *in_, void *) m_ptr = &m_list[m_idx]; - if (m_ptr->r_idx != get_melinda_proudfoot()) return (FALSE); + if (m_ptr->r_idx != get_melinda_proudfoot()) + { + return false; + } if (cquest.status < QUEST_STATUS_COMPLETED) { @@ -151,7 +161,7 @@ static bool_ quest_hobbit_chat_hook(void *, void *in_, void *) msg_print("maze and never been seen again! Could you find him for me?"); cquest.status = QUEST_STATUS_TAKEN; - quest[QUEST_HOBBIT].init(QUEST_HOBBIT); + quest[QUEST_HOBBIT].init(); } else if (cquest.status == QUEST_STATUS_COMPLETED) { @@ -168,7 +178,7 @@ static bool_ quest_hobbit_chat_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); cquest.status = QUEST_STATUS_FINISHED; @@ -176,17 +186,17 @@ static bool_ quest_hobbit_chat_hook(void *, void *in_, void *) process_hooks_restart = TRUE; delete_monster_idx(m_idx); - return TRUE; + return true; } else { msg_print("Thanks again."); } - return TRUE; + return true; } -static bool_ quest_hobbit_dump_hook(void *, void *in_, void *) +static bool quest_hobbit_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -195,11 +205,13 @@ static bool_ quest_hobbit_dump_hook(void *, void *in_, void *) { fprintf(f, "\n You saved a young hobbit from an horrible fate."); } - return (FALSE); + return false; } -bool_ quest_hobbit_init_hook(int q_idx) +void quest_hobbit_init_hook() { + auto &messages = game->messages; + /* Get a level to place the hobbit */ if (!cquest.data[0]) { @@ -207,7 +219,7 @@ bool_ quest_hobbit_init_hook(int q_idx) cquest.data[1] = turn; if (wizard) { - message_add(format("Hobbit level %d", cquest.data[0]), TERM_BLUE); + messages.add(format("Hobbit level %d", cquest.data[0]), TERM_BLUE); } } @@ -226,5 +238,4 @@ bool_ quest_hobbit_init_hook(int q_idx) add_hook_new(HOOK_CHAT, quest_hobbit_chat_hook, "hobbit_chat", NULL); } add_hook_new(HOOK_CHAR_DUMP, quest_hobbit_dump_hook, "hobbit_dump", NULL); - return (FALSE); } diff --git a/src/q_hobbit.hpp b/src/q_hobbit.hpp index b1878748..c3482fd9 100644 --- a/src/q_hobbit.hpp +++ b/src/q_hobbit.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_hobbit_init_hook(int q_idx); +void quest_hobbit_init_hook(); diff --git a/src/q_invas.cc b/src/q_invas.cc index 64483d28..60ca0b65 100644 --- a/src/q_invas.cc +++ b/src/q_invas.cc @@ -19,13 +19,16 @@ #define cquest (quest[QUEST_INVASION]) -static bool_ quest_invasion_gen_hook(void *, void *, void *) +static bool quest_invasion_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; + if (p_ptr->inside_quest != QUEST_INVASION) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -47,6 +50,7 @@ static bool_ quest_invasion_gen_hook(void *, void *, void *) process_dungeon_file("maeglin.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); for (x = 3; x < xstart; x++) + { for (y = 3; y < ystart; y++) { if (cave[y][x].feat == FEAT_MARKER) @@ -58,18 +62,22 @@ static bool_ quest_invasion_gen_hook(void *, void *, void *) cave_set_feat(p_ptr->py, p_ptr->px, FEAT_LESS); } } + } - return TRUE; + return true; } -static bool_ quest_invasion_ai_hook(void *, void *in_, void *out_) +static bool quest_invasion_ai_hook(void *, void *in_, void *out_) { struct hook_monster_ai_in *in = static_cast<struct hook_monster_ai_in *>(in_); struct hook_monster_ai_out *out = static_cast<struct hook_monster_ai_out *>(out_); monster_type *m_ptr = in->m_ptr; s32b m_idx = in->m_idx; - if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; + if (p_ptr->inside_quest != QUEST_INVASION) + { + return false; + } /* Ugly but thats better than a call to test_monster_name which is SLOW */ if (m_ptr->r_idx == 825) @@ -82,26 +90,26 @@ static bool_ quest_invasion_ai_hook(void *, void *in_, void *out_) cmsg_print(TERM_YELLOW, "Maeglin found the way to Gondolin! All hope is lost now!"); cquest.status = QUEST_STATUS_FAILED; town_info[2].destroyed = TRUE; - return (FALSE); + return false; } /* Attack or flee ?*/ if (distance(m_ptr->fy, m_ptr->fx, p_ptr->py, p_ptr->px) <= 2) { - return (FALSE); + return false; } else { out->y = cquest.data[0]; out->x = cquest.data[1]; - return (TRUE); + return true; } } - return (FALSE); + return false; } -static bool_ quest_invasion_turn_hook(void *, void *, void *) +static bool quest_invasion_turn_hook(void *, void *, void *) { if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE); if (p_ptr->lev < 45) return (FALSE); @@ -120,14 +128,14 @@ static bool_ quest_invasion_turn_hook(void *, void *, void *) cquest.status = QUEST_STATUS_TAKEN; - quest_invasion_init_hook(QUEST_INVASION); + quest_invasion_init_hook(); del_hook_new(HOOK_END_TURN, quest_invasion_turn_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } -static bool_ quest_invasion_dump_hook(void *, void *in_, void *) +static bool quest_invasion_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -140,16 +148,19 @@ static bool_ quest_invasion_dump_hook(void *, void *in_, void *) { fprintf(f, "\n You saved Gondolin from destruction."); } - return (FALSE); + return false; } -static bool_ quest_invasion_death_hook(void *, void *in_, void *) +static bool quest_invasion_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - if (p_ptr->inside_quest != QUEST_INVASION) return FALSE; + if (p_ptr->inside_quest != QUEST_INVASION) + { + return false; + } if (r_idx == test_monster_name("Maeglin, the Traitor of Gondolin")) { @@ -159,13 +170,13 @@ static bool_ quest_invasion_death_hook(void *, void *in_, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_invasion_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } - return FALSE; + return false; } -static bool_ quest_invasion_stair_hook(void *, void *in_, void *) +static bool quest_invasion_stair_hook(void *, void *in_, void *) { struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_); @@ -201,13 +212,13 @@ static bool_ quest_invasion_stair_hook(void *, void *in_, void *) } del_hook_new(HOOK_STAIR, quest_invasion_stair_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } - return TRUE; + return true; } -bool_ quest_invasion_init_hook(int q_idx) +void quest_invasion_init_hook() { add_hook_new(HOOK_END_TURN, quest_invasion_turn_hook, "invasion_turn", NULL); add_hook_new(HOOK_CHAR_DUMP, quest_invasion_dump_hook, "invasion_dump", NULL); @@ -218,5 +229,4 @@ bool_ quest_invasion_init_hook(int q_idx) add_hook_new(HOOK_MONSTER_DEATH, quest_invasion_death_hook, "invasion_death", NULL); add_hook_new(HOOK_STAIR, quest_invasion_stair_hook, "invasion_stair", NULL); } - return (FALSE); } diff --git a/src/q_invas.hpp b/src/q_invas.hpp index 87b8fc77..dc2d8780 100644 --- a/src/q_invas.hpp +++ b/src/q_invas.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_invasion_init_hook(int q_idx); +void quest_invasion_init_hook(); diff --git a/src/q_library.cc b/src/q_library.cc index 52a67291..e267e2b7 100644 --- a/src/q_library.cc +++ b/src/q_library.cc @@ -1,13 +1,14 @@ #include "q_library.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "game.hpp" #include "hooks.hpp" #include "lua_bind.hpp" #include "monster2.hpp" #include "monster_type.hpp" #include "object2.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "spells3.hpp" #include "spells4.hpp" #include "tables.hpp" @@ -18,11 +19,10 @@ #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> #define cquest (quest[QUEST_LIBRARY]) -#define print_hook(fmt,...) do { fprintf(hook_file, fmt, ##__VA_ARGS__); } while (0) - #define MONSTER_LICH 518 #define MONSTER_MONASTIC_LICH 611 #define MONSTER_FLESH_GOLEM 256 @@ -59,7 +59,6 @@ void initialize_bookable_spells() push_spell(RECHARGE); push_spell(DISPERSEMAGIC); push_spell(BLINK); - push_spell(DISARM); push_spell(TELEPORT); push_spell(SENSEMONSTERS); push_spell(SENSEHIDDEN); @@ -313,19 +312,19 @@ static void library_quest_fill_book() screen_load(); } -static bool_ quest_library_gen_hook(void *, void *, void *) +static bool quest_library_gen_hook(void *, void *, void *) { /* Only if player doing this quest */ if (p_ptr->inside_quest != QUEST_LIBRARY) { - return FALSE; + return false; } { int y = 2; int x = 2; load_map("library.map", &y, &x); - dungeon_flags2 = DF2_NO_GENO; + dungeon_flags = DF_NO_GENO; } /* Generate monsters */ @@ -353,46 +352,41 @@ static bool_ quest_library_gen_hook(void *, void *, void *) library_quest_place_nrandom( 10, 10, 37, 67, MONSTER_MITHRIL_GOLEM, 1); - return TRUE; + return true; } -static bool_ quest_library_stair_hook(void *, void *, void *) +static bool quest_library_stair_hook(void *, void *, void *) { - bool_ ret; - /* only ask this if player about to go up stairs of quest and hasn't won yet */ if ((p_ptr->inside_quest != QUEST_LIBRARY) || (cquest.status == QUEST_STATUS_COMPLETED)) { - return FALSE; + return false; } if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) { - return FALSE; + return false; } /* flush all pending input */ flush(); /* confirm */ - ret = get_check("Really abandon the quest?"); - - /* if yes, then */ - if (ret == TRUE) + if (get_check("Really abandon the quest?")) { /* fail the quest */ cquest.status = QUEST_STATUS_FAILED; - return FALSE; + return false; } else { /* if no, they stay in the quest */ - return TRUE; + return true; } } -static bool_ quest_library_monster_death_hook(void *, void *, void *) +static bool quest_library_monster_death_hook(void *, void *, void *) { int i, count = -1; @@ -400,7 +394,7 @@ static bool_ quest_library_monster_death_hook(void *, void *, void *) if ((p_ptr->inside_quest != QUEST_LIBRARY) || (cquest.status == QUEST_STATUS_COMPLETED)) { - return FALSE; + return false; } /* Count all the enemies left alive */ @@ -422,7 +416,7 @@ static bool_ quest_library_monster_death_hook(void *, void *, void *) } /* Normal processing */ - return FALSE; + return false; } void quest_library_building(bool_ *paid, bool_ *recreate) @@ -457,7 +451,7 @@ void quest_library_building(bool_ *paid, bool_ *recreate) object_type forge; object_type *q_ptr = &forge; object_prep(q_ptr, lookup_kind(TV_BOOK, 61)); - q_ptr->art_name = quark_add(player_name); + q_ptr->artifact_name = game->player_name; q_ptr->found = OBJ_FOUND_REWARD; object_aware(q_ptr); object_known(q_ptr); @@ -482,28 +476,26 @@ void quest_library_building(bool_ *paid, bool_ *recreate) } } -bool_ quest_library_describe(FILE *hook_file) +std::string quest_library_describe() { + fmt::MemoryWriter w; + if (cquest.status == QUEST_STATUS_TAKEN) { - print_hook("#####yAn Old Mages Quest! (Danger Level: 35)\n"); - print_hook("Make the library safe for the old mage in Minas Anor.\n"); - print_hook("\n"); + w.write("#####yAn Old Mages Quest! (Danger Level: 35)\n"); + w.write("Make the library safe for the old mage in Minas Anor."); } else if (cquest.status == QUEST_STATUS_COMPLETED) { - /* Quest done, book not gotten yet */ - print_hook("#####yAn Old Mages Quest!\n"); - print_hook("You have made the library safe for the old mage in Minas Anor.\n"); - print_hook("Perhaps you should see about a reward.\n"); - print_hook("\n"); + w.write("#####yAn Old Mages Quest!\n"); + w.write("You have made the library safe for the old mage in Minas Anor.\n"); + w.write("Perhaps you should see about a reward."); } - /* Normal processing */ - return TRUE; + return w.str(); } -bool_ quest_library_init_hook(int q) +void quest_library_init_hook() { /* Only need hooks if the quest is unfinished. */ if ((cquest.status >= QUEST_STATUS_UNTAKEN) && @@ -519,8 +511,4 @@ bool_ quest_library_init_hook(int q) { quest_library_finalize_book(); } - - return FALSE; } - -#undef print_hook diff --git a/src/q_library.hpp b/src/q_library.hpp index 8150893e..266accc3 100644 --- a/src/q_library.hpp +++ b/src/q_library.hpp @@ -2,7 +2,9 @@ #include "h-basic.h" -bool_ quest_library_init_hook(int q); -bool_ quest_library_describe(FILE *fff); +#include <string> + +void quest_library_init_hook(); +std::string quest_library_describe(); void quest_library_building(bool_ *paid, bool_ *recreate); void initialize_bookable_spells(); diff --git a/src/q_main.cc b/src/q_main.cc index ed11b9dc..2d3473f1 100644 --- a/src/q_main.cc +++ b/src/q_main.cc @@ -1,10 +1,12 @@ #include "q_main.hpp" +#include "game.hpp" #include "hook_chardump_in.hpp" #include "hook_monster_death_in.hpp" #include "hook_new_monster_in.hpp" #include "hooks.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "player_type.hpp" #include "tables.hpp" @@ -27,8 +29,10 @@ static void quest_describe(int q_idx) } } -static bool_ quest_main_monsters_hook(void *, void *in_, void *) +static bool quest_main_monsters_hook(void *, void *in_, void *) { + auto const &r_info = game->edit_data.r_info; + struct hook_new_monster_in *in = static_cast<struct hook_new_monster_in *>(in_); s32b r_idx = in->r_idx; @@ -36,20 +40,28 @@ static bool_ quest_main_monsters_hook(void *, void *in_, void *) if (r_idx == get_sauron()) { /* No Sauron until Necromancer dies */ - if (r_info[get_necromancer()].max_num) return TRUE; + if (r_info[get_necromancer()].max_num) + { + return true; + } } /* Morgoth */ else if (r_idx == get_morgoth()) { /* No Morgoth until Sauron dies */ - if (r_info[get_sauron()].max_num) return TRUE; + if (r_info[get_sauron()].max_num) + { + return true; + } } - return FALSE; + return false; } -static bool_ quest_morgoth_hook(void *, void *, void *) +static bool quest_morgoth_hook(void *, void *, void *) { - monster_race *r_ptr = &r_info[get_morgoth()]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[get_morgoth()]; /* Need to kill him */ if (!r_ptr->max_num) @@ -92,12 +104,12 @@ static bool_ quest_morgoth_hook(void *, void *, void *) *(quest[QUEST_MORGOTH].plot) = QUEST_ULTRA_GOOD; else *(quest[QUEST_MORGOTH].plot) = QUEST_ULTRA_EVIL; - quest[*(quest[QUEST_MORGOTH].plot)].init(*(quest[QUEST_MORGOTH].plot)); + quest[*(quest[QUEST_MORGOTH].plot)].init(); } - return (FALSE); + return false; } -static bool_ quest_morgoth_dump_hook(void *, void *in_, void *) +static bool quest_morgoth_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -105,14 +117,18 @@ static bool_ quest_morgoth_dump_hook(void *, void *in_, void *) if (quest[QUEST_MORGOTH].status >= QUEST_STATUS_COMPLETED) { if (quest[QUEST_ONE].status == QUEST_STATUS_FINISHED) - fprintf(f, "\n You saved Arda and became a famed %s.", sp_ptr->winner); + { + fprintf(f, "\n You saved Arda and became a famed hero."); + } else + { fprintf(f, "\n You became a new force of darkness and enslaved all free people."); + } } - return (FALSE); + return false; } -bool_ quest_morgoth_init_hook(int q_idx) +void quest_morgoth_init_hook() { if ((quest[QUEST_MORGOTH].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_MORGOTH].status < QUEST_STATUS_FINISHED)) { @@ -120,12 +136,13 @@ bool_ quest_morgoth_init_hook(int q_idx) } add_hook_new(HOOK_CHAR_DUMP, quest_morgoth_dump_hook, "morgoth_dump", NULL); add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL); - return (FALSE); } -static bool_ quest_sauron_hook(void *, void *, void *) +static bool quest_sauron_hook(void *, void *, void *) { - monster_race *r_ptr = &r_info[get_sauron()]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[get_sauron()]; /* Need to kill him */ if (!r_ptr->max_num) @@ -139,23 +156,26 @@ static bool_ quest_sauron_hook(void *, void *, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_sauron_hook); add_hook_new(HOOK_MONSTER_DEATH, quest_morgoth_hook, "morgort_death", NULL); *(quest[QUEST_SAURON].plot) = QUEST_MORGOTH; - quest_morgoth_init_hook(QUEST_MORGOTH); + quest_morgoth_init_hook(); process_hooks_restart = TRUE; } - return (FALSE); + + return false; } -static bool_ quest_sauron_resurect_hook(void *, void *in_, void *) +static bool quest_sauron_resurrect_hook(void *, void *in_, void *) { + auto &r_info = game->edit_data.r_info; + struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; + auto r_ptr = &r_info[m_ptr->r_idx]; - if ((r_ptr->flags7 & RF7_NAZGUL) && r_info[get_sauron()].max_num) + if ((r_ptr->flags & RF_NAZGUL) && r_info[get_sauron()].max_num) { - msg_format("Somehow you feel %s is not totally destroyed...", (r_ptr->flags1 & RF1_FEMALE ? "she" : "he")); + msg_format("Somehow you feel %s is not totally destroyed...", (r_ptr->flags & RF_FEMALE ? "she" : "he")); r_ptr->max_num = 1; } else if ((m_ptr->r_idx == get_sauron()) && (quest[QUEST_ONE].status < QUEST_STATUS_FINISHED)) @@ -163,23 +183,24 @@ static bool_ quest_sauron_resurect_hook(void *, void *in_, void *) msg_print("Sauron will not be permanently defeated until the One Ring is either destroyed or used..."); r_ptr->max_num = 1; } - return FALSE; + return false; } -bool_ quest_sauron_init_hook(int q_idx) +void quest_sauron_init_hook() { if ((quest[QUEST_SAURON].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_SAURON].status < QUEST_STATUS_FINISHED)) { add_hook_new(HOOK_MONSTER_DEATH, quest_sauron_hook, "sauron_death", NULL); } add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL); - add_hook_new(HOOK_MONSTER_DEATH, quest_sauron_resurect_hook, "sauron_resurect_death", NULL); - return (FALSE); + add_hook_new(HOOK_MONSTER_DEATH, quest_sauron_resurrect_hook, "sauron_resurect_death", NULL); } -static bool_ quest_necro_hook(void *, void *, void *) +static bool quest_necro_hook(void *, void *, void *) { - monster_race *r_ptr = &r_info[get_necromancer()]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[get_necromancer()]; /* Need to kill him */ if (!r_ptr->max_num) @@ -191,20 +212,20 @@ static bool_ quest_necro_hook(void *, void *, void *) quest[QUEST_NECRO].status = QUEST_STATUS_FINISHED; *(quest[QUEST_NECRO].plot) = QUEST_ONE; - quest[*(quest[QUEST_NECRO].plot)].init(*(quest[QUEST_NECRO].plot)); + quest[*(quest[QUEST_NECRO].plot)].init(); del_hook_new(HOOK_MONSTER_DEATH, quest_necro_hook); process_hooks_restart = TRUE; } - return (FALSE); + + return false; } -bool_ quest_necro_init_hook(int q_idx) +void quest_necro_init_hook() { if ((quest[QUEST_NECRO].status >= QUEST_STATUS_TAKEN) && (quest[QUEST_NECRO].status < QUEST_STATUS_FINISHED)) { add_hook_new(HOOK_MONSTER_DEATH, quest_necro_hook, "necro_death", NULL); } add_hook_new(HOOK_NEW_MONSTER, quest_main_monsters_hook, "main_new_monster", NULL); - return (FALSE); } diff --git a/src/q_main.hpp b/src/q_main.hpp index a88530fc..be33897b 100644 --- a/src/q_main.hpp +++ b/src/q_main.hpp @@ -2,6 +2,6 @@ #include "h-basic.h" -bool_ quest_necro_init_hook(int q_idx); -bool_ quest_sauron_init_hook(int q_idx); -bool_ quest_morgoth_init_hook(int q_idx); +void quest_necro_init_hook(); +void quest_sauron_init_hook(); +void quest_morgoth_init_hook(); diff --git a/src/q_narsil.cc b/src/q_narsil.cc index a6c0eed3..8d3c2775 100644 --- a/src/q_narsil.cc +++ b/src/q_narsil.cc @@ -14,7 +14,7 @@ #define cquest (quest[QUEST_NARSIL]) -static bool_ quest_narsil_move_hook(void *, void *in_, void *) +static bool quest_narsil_move_hook(void *, void *in_, void *) { struct hook_move_in *in = static_cast<struct hook_move_in *>(in_); s32b y = in->y; @@ -23,10 +23,16 @@ static bool_ quest_narsil_move_hook(void *, void *in_, void *) int i; object_type *o_ptr; - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } /* The castle of Aragorn */ - if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 14)) return FALSE; + if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 14)) + { + return false; + } /* Look out for Narsil */ for (i = 0; i < INVEN_TOTAL; i++) @@ -38,7 +44,10 @@ static bool_ quest_narsil_move_hook(void *, void *in_, void *) if (o_ptr->name1 == ART_NARSIL) break; } - if (i == INVEN_TOTAL) return FALSE; + if (i == INVEN_TOTAL) + { + return false; + } cmsg_print(TERM_YELLOW, "I heard that the broken sword had been found!"); cmsg_print(TERM_YELLOW, "I thought it was only a rumor... until now."); @@ -65,10 +74,10 @@ static bool_ quest_narsil_move_hook(void *, void *in_, void *) del_hook_new(HOOK_MOVE, quest_narsil_move_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_narsil_dump_hook(void *, void *in_, void *) +static bool quest_narsil_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -77,10 +86,10 @@ static bool_ quest_narsil_dump_hook(void *, void *in_, void *) { fprintf(f, "\n The sword that was broken is now reforged."); } - return (FALSE); + return false; } -static bool_ quest_narsil_identify_hook(void *, void *in_, void *) +static bool quest_narsil_identify_hook(void *, void *in_, void *) { struct hook_identify_in *in = static_cast<struct hook_identify_in *>(in_); @@ -104,10 +113,10 @@ static bool_ quest_narsil_identify_hook(void *, void *in_, void *) } } - return (FALSE); + return false; } -bool_ quest_narsil_init_hook(int q_idx) +void quest_narsil_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -118,5 +127,4 @@ bool_ quest_narsil_init_hook(int q_idx) add_hook_new(HOOK_IDENTIFY, quest_narsil_identify_hook, "narsil_id", NULL); } add_hook_new(HOOK_CHAR_DUMP, quest_narsil_dump_hook, "narsil_dump", NULL); - return (FALSE); } diff --git a/src/q_narsil.hpp b/src/q_narsil.hpp index b83e63cf..da0fa85d 100644 --- a/src/q_narsil.hpp +++ b/src/q_narsil.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_narsil_init_hook(int q_idx); +void quest_narsil_init_hook(); diff --git a/src/q_nazgul.cc b/src/q_nazgul.cc index 15a6a843..99735eed 100644 --- a/src/q_nazgul.cc +++ b/src/q_nazgul.cc @@ -22,13 +22,16 @@ GENERATE_MONSTER_LOOKUP_FN(get_uvatha, "Uvatha the Horseman") -static bool_ quest_nazgul_gen_hook(void *, void *in_, void *) +static bool quest_nazgul_gen_hook(void *, void *in_, void *) { struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_); int m_idx, x = 1, y = 1, tries = 10000; bool_ small = in->small; - if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1)) return (FALSE); + if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1)) + { + return false; + } /* Find a good position */ while (tries) @@ -54,16 +57,19 @@ static bool_ quest_nazgul_gen_hook(void *, void *in_, void *) if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; - return FALSE; + return false; } -static bool_ quest_nazgul_finish_hook(void *, void *in_, void *) +static bool quest_nazgul_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; object_type forge, *q_ptr; - if (q_idx != QUEST_NAZGUL) return FALSE; + if (q_idx != QUEST_NAZGUL) + { + return false; + } c_put_str(TERM_YELLOW, "I believe he will not come back! Thank you.", 8, 0); c_put_str(TERM_YELLOW, "Some time ago a ranger gave me this.", 9, 0); @@ -76,7 +82,7 @@ static bool_ quest_nazgul_finish_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); /* End the plot */ *(quest[q_idx].plot) = QUEST_NULL; @@ -84,10 +90,10 @@ static bool_ quest_nazgul_finish_hook(void *, void *in_, void *) del_hook_new(HOOK_QUEST_FINISH, quest_nazgul_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_nazgul_dump_hook(void *, void *in_, void *) +static bool quest_nazgul_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -96,42 +102,53 @@ static bool_ quest_nazgul_dump_hook(void *, void *in_, void *) { fprintf(f, "\n You saved Bree from a dreadful Nazgul."); } - return (FALSE); + return false; } -static bool_ quest_nazgul_forbid_hook(void *, void *in_, void *) +static bool quest_nazgul_forbid_hook(void *, void *in_, void *) { struct hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_NAZGUL) return (FALSE); + if (q_idx != QUEST_NAZGUL) + { + return false; + } if (p_ptr->lev < 30) { c_put_str(TERM_WHITE, "I fear you are not ready for the next quest, come back later.", 8, 0); - return (TRUE); + return true; } - return (FALSE); + + return false; } -static bool_ quest_nazgul_death_hook(void *, void *in_, void *) +static bool quest_nazgul_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE); - if (r_idx != get_uvatha()) return (FALSE); + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } + + if (r_idx != get_uvatha()) + { + return false; + } cquest.status = QUEST_STATUS_COMPLETED; del_hook_new(HOOK_MONSTER_DEATH, quest_nazgul_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } -bool_ quest_nazgul_init_hook(int q_idx) +void quest_nazgul_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -141,5 +158,4 @@ bool_ quest_nazgul_init_hook(int q_idx) } add_hook_new(HOOK_CHAR_DUMP, quest_nazgul_dump_hook, "nazgul_dump", NULL); add_hook_new(HOOK_INIT_QUEST, quest_nazgul_forbid_hook, "nazgul_forbid", NULL); - return (FALSE); } diff --git a/src/q_nazgul.hpp b/src/q_nazgul.hpp index 32e3237c..ad35e5b3 100644 --- a/src/q_nazgul.hpp +++ b/src/q_nazgul.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_nazgul_init_hook(int q_idx); +void quest_nazgul_init_hook(); diff --git a/src/q_nirna.cc b/src/q_nirna.cc index a92ba6e4..822d8b6c 100644 --- a/src/q_nirna.cc +++ b/src/q_nirna.cc @@ -13,13 +13,16 @@ #define cquest (quest[QUEST_NIRNAETH]) -static bool_ quest_nirnaeth_gen_hook(void *, void *, void *) +static bool quest_nirnaeth_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE; + if (p_ptr->inside_quest != QUEST_NIRNAETH) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -44,20 +47,25 @@ static bool_ quest_nirnaeth_gen_hook(void *, void *, void *) cquest.data[0] = 0; cquest.data[1] = 0; for (x = 2; x < xstart; x++) + { for (y = 2; y < ystart; y++) { if (cave[y][x].m_idx) cquest.data[0]++; } + } - return TRUE; + return true; } -static bool_ quest_nirnaeth_finish_hook(void *, void *in_, void *) +static bool quest_nirnaeth_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_NIRNAETH) return FALSE; + if (q_idx != QUEST_NIRNAETH) + { + return false; + } /* Killed at least 2/3 of them ? better reward ! */ if (cquest.data[1] >= (2 * cquest.data[0] / 3)) @@ -86,33 +94,39 @@ static bool_ quest_nirnaeth_finish_hook(void *, void *in_, void *) del_hook_new(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_nirnaeth_death_hook(void *, void *, void *) +static bool quest_nirnaeth_death_hook(void *, void *, void *) { if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE; cquest.data[1]++; - return FALSE; + return false; } -static bool_ quest_nirnaeth_stair_hook(void *, void *, void *) +static bool quest_nirnaeth_stair_hook(void *, void *, void *) { - if (p_ptr->inside_quest != QUEST_NIRNAETH) return FALSE; + if (p_ptr->inside_quest != QUEST_NIRNAETH) + { + return false; + } - if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return (FALSE); + if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) + { + return false; + } cmsg_print(TERM_YELLOW, "You found a way out!"); cquest.status = QUEST_STATUS_COMPLETED; del_hook_new(HOOK_STAIR, quest_nirnaeth_stair_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } -bool_ quest_nirnaeth_init_hook(int q_idx) +void quest_nirnaeth_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -121,5 +135,4 @@ bool_ quest_nirnaeth_init_hook(int q_idx) add_hook_new(HOOK_STAIR, quest_nirnaeth_stair_hook, "nirnaeth_stair", NULL); add_hook_new(HOOK_QUEST_FINISH, quest_nirnaeth_finish_hook, "nirnaeth_finish", NULL); } - return (FALSE); } diff --git a/src/q_nirna.hpp b/src/q_nirna.hpp index 24a8759f..1aaeae54 100644 --- a/src/q_nirna.hpp +++ b/src/q_nirna.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_nirnaeth_init_hook(int q_idx); +void quest_nirnaeth_init_hook(); diff --git a/src/q_one.cc b/src/q_one.cc index 3741e009..8985b695 100644 --- a/src/q_one.cc +++ b/src/q_one.cc @@ -3,6 +3,7 @@ #include "artifact_type.hpp" #include "cave.hpp" #include "cave_type.hpp" +#include "game.hpp" #include "gods.hpp" #include "hook_calculate_hp_in.hpp" #include "hook_calculate_hp_out.hpp" @@ -26,7 +27,7 @@ #define cquest (quest[QUEST_ONE]) -static bool_ quest_one_move_hook(void *, void *in_, void *) +static bool quest_one_move_hook(void *, void *in_, void *) { struct hook_move_in *in = static_cast<struct hook_move_in *>(in_); s32b y = in->y; @@ -35,10 +36,16 @@ static bool_ quest_one_move_hook(void *, void *in_, void *) if (cquest.status == QUEST_STATUS_UNTAKEN) { - if (quest[QUEST_NECRO].status < QUEST_STATUS_FINISHED) return (FALSE); + if (quest[QUEST_NECRO].status < QUEST_STATUS_FINISHED) + { + return false; + } /* The mirror of Galadriel */ - if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 23)) return (FALSE); + if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 23)) + { + return false; + } cmsg_print(TERM_YELLOW, "You meet Galadriel; she seems worried."); cmsg_print(TERM_YELLOW, "'So it was Sauron that lurked in Dol Guldur...'"); @@ -82,24 +89,34 @@ static bool_ quest_one_move_hook(void *, void *in_, void *) /* Continue the plot */ cquest.status = QUEST_STATUS_TAKEN; - cquest.init(QUEST_ONE); + cquest.init(); - return TRUE; + return true; } - return FALSE; + return false; } -static bool_ quest_one_drop_hook(void *, void *in_, void *) +static bool quest_one_drop_hook(void *, void *in_, void *) { struct hook_drop_in *in = static_cast<struct hook_drop_in *>(in_); s32b o_idx = in->o_idx; object_type *o_ptr = &p_ptr->inventory[o_idx]; - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } + + if (o_ptr->name1 != ART_POWER) + { + return false; + } - if (o_ptr->name1 != ART_POWER) return FALSE; - if (cave[p_ptr->py][p_ptr->px].feat != FEAT_GREAT_FIRE) return FALSE; + if (cave[p_ptr->py][p_ptr->px].feat != FEAT_GREAT_FIRE) + { + return false; + } cmsg_print(TERM_YELLOW, "You throw the One Ring into the #RGreat Fire#y; it is rapidly consumed"); cmsg_print(TERM_YELLOW, "by the searing flames."); @@ -114,34 +131,46 @@ static bool_ quest_one_drop_hook(void *, void *in_, void *) cquest.status = QUEST_STATUS_FINISHED; *(quest[QUEST_ONE].plot) = QUEST_SAURON; quest[*(quest[QUEST_ONE].plot)].status = QUEST_STATUS_TAKEN; - quest[*(quest[QUEST_ONE].plot)].init(*(quest[QUEST_ONE].plot)); + quest[*(quest[QUEST_ONE].plot)].init(); - return TRUE; + return true; } -static bool_ quest_one_wield_hook(void *, void *in_, void *) +static bool quest_one_wield_hook(void *, void *in_, void *) { struct hook_wield_in *in = static_cast<struct hook_wield_in *>(in_); object_type *o_ptr = in->o_ptr; - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } - if (o_ptr->name1 != ART_POWER) return FALSE; + if (o_ptr->name1 != ART_POWER) + { + return false; + } - /* Flush input */ + // Make sure player is **really** warned flush(); + if (!get_check("You were warned not to wear it; are you sure?")) + { + return true; + } - if (!get_check("You were warned not to wear it; are you sure?")) return TRUE; - /* Flush input */ flush(); + if (!get_check("You were warned not to wear it; are you *REALLY* sure?")) + { + return true; + } - if (!get_check("You were warned not to wear it; are you *REALLY* sure?")) return TRUE; - - /* Flush input */ flush(); + if (!get_check("You were *WARNED* not to wear it; are you *R*E*A*L*L*Y* sure?")) + { + return true; + } - if (!get_check("You were *WARNED* not to wear it; are you *R*E*A*L*L*Y* sure?")) return TRUE; - + // Ok, that's enough warning cmsg_print(TERM_YELLOW, "As you put it on your finger you feel #Ddark powers #ysapping your soul."); cmsg_print(TERM_YELLOW, "The ring firmly binds to your finger!"); cmsg_print(TERM_YELLOW, "You feel you are drawn to the shadow world! Your material form weakens."); @@ -166,15 +195,15 @@ static bool_ quest_one_wield_hook(void *, void *in_, void *) cquest.status = QUEST_STATUS_FAILED_DONE; *(quest[QUEST_ONE].plot) = QUEST_SAURON; quest[*(quest[QUEST_ONE].plot)].status = QUEST_STATUS_TAKEN; - quest[*(quest[QUEST_ONE].plot)].init(*(quest[QUEST_ONE].plot)); + quest[*(quest[QUEST_ONE].plot)].init(); /* Ok lets reset the lives counter */ p_ptr->lives = 0; - return FALSE; + return false; } -static bool_ quest_one_hp_hook(void *, void *in_, void *out_) +static bool quest_one_hp_hook(void *, void *in_, void *out_) { struct hook_calculate_hp_in *in = static_cast<struct hook_calculate_hp_in *>(in_); struct hook_calculate_hp_out *out = static_cast<struct hook_calculate_hp_out *>(out_); @@ -184,15 +213,18 @@ static bool_ quest_one_hp_hook(void *, void *in_, void *out_) s32b mhp = in->mhp; for (int i = 0; i < p_ptr->lives + 1; i++) + { mhp = (mhp * 2) / 3; + } out->mhp = mhp; - return (TRUE); + return true; } - return (FALSE); + + return false; } -static bool_ quest_one_die_hook(void *, void *, void *) +static bool quest_one_die_hook(void *, void *, void *) { if (cquest.status == QUEST_STATUS_FAILED_DONE) { @@ -200,19 +232,19 @@ static bool_ quest_one_die_hook(void *, void *, void *) { cmsg_print(TERM_YELLOW, "You feel the power of the One Ring sustaining your life,"); cmsg_print(TERM_YELLOW, "but it drags you even more into the shadow world."); - return (TRUE); + return true; } else { cmsg_print(TERM_YELLOW, "The One Ring finally drags you totally to the shadow world."); cmsg_print(TERM_YELLOW, "Your mortal existence ends there."); - strcpy(died_from, "being drawn to the shadow world"); + game->died_from = "being drawn to the shadow world"; } } - return (FALSE); + return false; } -static bool_ quest_one_identify_hook(void *, void *in_, void *) +static bool quest_one_identify_hook(void *, void *in_, void *) { struct hook_identify_in *in = static_cast<struct hook_identify_in *>(in_); object_type *o_ptr = in->o_ptr; @@ -227,44 +259,52 @@ static bool_ quest_one_identify_hook(void *, void *in_, void *) } } - return (FALSE); + return false; } -static bool_ quest_one_death_hook(void *, void *in_, void *) +static bool quest_one_death_hook(void *, void *in_, void *) { + auto const &a_info = game->edit_data.a_info; + struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - bool_ ok = FALSE; + bool ok = false; - if (a_info[ART_POWER].cur_num) return FALSE; + if (a_info[ART_POWER].cur_num) + { + return false; + } /* Paranoia */ - if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE); + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } if (magik(30) && (r_idx == test_monster_name("Sauron, the Sorcerer"))) { - ok = TRUE; + ok = true; } else if (magik(10) && (r_idx == test_monster_name("Ar-Pharazon the Golden"))) { - ok = TRUE; + ok = true; } else if (magik(10) && (r_idx == test_monster_name("Shelob, Spider of Darkness"))) { - ok = TRUE; + ok = true; } else if (magik(10) && (r_idx == test_monster_name("The Watcher in the Water"))) { - ok = TRUE; + ok = true; } else if (magik(10) && (r_idx == test_monster_name("Glaurung, Father of the Dragons"))) { - ok = TRUE; + ok = true; } else if (magik(10) && (r_idx == test_monster_name("Feagwath, the Undead Sorcerer"))) { - ok = TRUE; + ok = true; } if (ok) @@ -287,7 +327,10 @@ static bool_ quest_one_death_hook(void *, void *in_, void *) for (i = 0; i < INVEN_PACK; i++) { /* Skip non-objects */ - if (!p_ptr->inventory[i].k_idx) break; + if (!p_ptr->inventory[i].k_idx) + { + break; + } } /* Arg, no space ! */ if (i == INVEN_PACK) @@ -307,10 +350,10 @@ static bool_ quest_one_death_hook(void *, void *in_, void *) inven_carry(q_ptr, FALSE); } - return (FALSE); + return false; } -static bool_ quest_one_dump_hook(void *, void *in_, void *) +static bool quest_one_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -323,16 +366,22 @@ static bool_ quest_one_dump_hook(void *, void *in_, void *) { fprintf(f, "\n You fell under the evil influence of the One Ring and decided to wear it."); } - return (FALSE); + return false; } -static bool_ quest_one_gen_hook(void *, void *, void *) +static bool quest_one_gen_hook(void *, void *, void *) { s32b x, y, tries = 10000; /* Paranoia */ - if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE); - if ((dungeon_type != DUNGEON_ANGBAND) || (dun_level != 99)) return (FALSE); + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } + if ((dungeon_type != DUNGEON_ANGBAND) || (dun_level != 99)) + { + return false; + } /* Find a good position */ while (tries) @@ -354,10 +403,10 @@ static bool_ quest_one_gen_hook(void *, void *, void *) if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; } - return (FALSE); + return false; } -bool_ quest_one_init_hook(int q_idx) +void quest_one_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -374,5 +423,4 @@ bool_ quest_one_init_hook(int q_idx) add_hook_new(HOOK_CHAR_DUMP, quest_one_dump_hook, "one_dump", NULL); add_hook_new(HOOK_CALC_HP, quest_one_hp_hook, "one_hp", NULL); add_hook_new(HOOK_DIE, quest_one_die_hook, "one_die", NULL); - return (FALSE); } diff --git a/src/q_one.hpp b/src/q_one.hpp index a85a5733..13389968 100644 --- a/src/q_one.hpp +++ b/src/q_one.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_one_init_hook(int q_idx); +void quest_one_init_hook(); diff --git a/src/q_poison.cc b/src/q_poison.cc index a5b274b0..e7f1c71b 100644 --- a/src/q_poison.cc +++ b/src/q_poison.cc @@ -2,6 +2,7 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "game.hpp" #include "hook_chardump_in.hpp" #include "hook_drop_in.hpp" #include "hook_init_quest_in.hpp" @@ -10,10 +11,11 @@ #include "messages.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "monster_type.hpp" #include "object2.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "tables.hpp" #include "util.hpp" #include "variable.hpp" @@ -31,9 +33,11 @@ static int wild_locs[4][2] = static bool_ create_molds_hook(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; - if (r_ptr->flags4 & RF4_MULTIPLY) return FALSE; + auto r_ptr = &r_info[r_idx]; + + if (r_ptr->spells & SF_MULTIPLY) return FALSE; if (r_ptr->d_char == 'm') return TRUE; else if (r_ptr->d_char == ',') return TRUE; @@ -41,15 +45,27 @@ static bool_ create_molds_hook(int r_idx) else return FALSE; } -static bool_ quest_poison_gen_hook(void *, void *, void *) +static bool quest_poison_gen_hook(void *, void *, void *) { int cy = 1, cx = 1, x, y, tries = 10000, r_idx; bool_ (*old_get_mon_num_hook)(int r_idx); - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; - if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE; - if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) return FALSE; - if (p_ptr->wild_mode) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } + if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) + { + return false; + } + if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) + { + return false; + } + if (p_ptr->wild_mode) + { + return false; + } /* Find a good position */ while (tries) @@ -59,7 +75,10 @@ static bool_ quest_poison_gen_hook(void *, void *, void *) cx = randint(cur_wid - 34) + 32; /* Is it a good spot ? */ - if (cave_empty_bold(cy, cx)) break; + if (cave_empty_bold(cy, cx)) + { + break; + } /* One less try */ tries--; @@ -78,15 +97,28 @@ static bool_ quest_poison_gen_hook(void *, void *, void *) /* Pick a monster, using the level calculation */ for (x = cx - 25; x <= cx + 25; x++) + { for (y = cy - 25; y <= cy + 25; y++) { - if (!in_bounds(y, x)) continue; + if (!in_bounds(y, x)) + { + continue; + } - if (distance(cy, cx, y, x) > 25) continue; + if (distance(cy, cx, y, x) > 25) + { + continue; + } - if (magik(80) && ((cave[y][x].feat == FEAT_DEEP_WATER) || (cave[y][x].feat == FEAT_SHAL_WATER))) cave_set_feat(y, x, FEAT_TAINTED_WATER); + if (magik(80) && ((cave[y][x].feat == FEAT_DEEP_WATER) || (cave[y][x].feat == FEAT_SHAL_WATER))) + { + cave_set_feat(y, x, FEAT_TAINTED_WATER); + } - if (distance(cy, cx, y, x) > 10) continue; + if (distance(cy, cx, y, x) > 10) + { + continue; + } if (magik(60)) { @@ -109,6 +141,7 @@ static bool_ quest_poison_gen_hook(void *, void *, void *) } } } + } /* Reset restriction */ get_mon_num_hook = old_get_mon_num_hook; @@ -116,16 +149,19 @@ static bool_ quest_poison_gen_hook(void *, void *, void *) /* Prepare allocation table */ get_mon_num_prep(); - return FALSE; + return false; } -static bool_ quest_poison_finish_hook(void *, void *in_, void *) +static bool quest_poison_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; object_type forge, *q_ptr; - if (q_idx != QUEST_POISON) return FALSE; + if (q_idx != QUEST_POISON) + { + return false; + } c_put_str(TERM_YELLOW, "The water is clean again! Thank you so much.", 8, 0); c_put_str(TERM_YELLOW, "The beautiful Mallorns are safe. Take this as a proof of our gratitude.", 9, 0); @@ -139,7 +175,7 @@ static bool_ quest_poison_finish_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NULL; @@ -147,10 +183,10 @@ static bool_ quest_poison_finish_hook(void *, void *in_, void *) del_hook_new(HOOK_QUEST_FINISH, quest_poison_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_poison_dump_hook(void *, void *in_, void *) +static bool quest_poison_dump_hook(void *, void *in_, void *) { hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -159,16 +195,19 @@ static bool_ quest_poison_dump_hook(void *, void *in_, void *) { fprintf(f, "\n You saved the beautiful Mallorns of Lothlorien."); } - return (FALSE); + return false; } -static bool_ quest_poison_quest_hook(void *, void *in_, void *) +static bool quest_poison_quest_hook(void *, void *in_, void *) { struct hook_init_quest_in *in = static_cast<struct hook_init_quest_in *>(in_); s32b q_idx = in->q_idx; object_type forge, *q_ptr; - if (q_idx != QUEST_POISON) return FALSE; + if (q_idx != QUEST_POISON) + { + return false; + } q_ptr = &forge; object_prep(q_ptr, lookup_kind(TV_POTION2, SV_POTION2_CURE_WATER)); @@ -176,29 +215,48 @@ static bool_ quest_poison_quest_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - q_ptr->note = quark_add("quest"); - (void)inven_carry(q_ptr, FALSE); + q_ptr->inscription = "quest"; + + inven_carry(q_ptr, FALSE); del_hook_new(HOOK_INIT_QUEST, quest_poison_quest_hook); process_hooks_restart = TRUE; - return FALSE; + return false; } -static bool_ quest_poison_drop_hook(void *, void *in_, void *) +static bool quest_poison_drop_hook(void *, void *in_, void *) { struct hook_drop_in *in = static_cast<struct hook_drop_in *>(in_); s32b mcnt = 0, i, x, y; s32b o_idx = in->o_idx; object_type *o_ptr = &p_ptr->inventory[o_idx]; - if (cquest.status != QUEST_STATUS_TAKEN) return FALSE; - if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE; - if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) return FALSE; - if (p_ptr->wild_mode) return FALSE; + if (cquest.status != QUEST_STATUS_TAKEN) + { + return false; + } + if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) + { + return false; + } + if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) + { + return false; + } + if (p_ptr->wild_mode) + { + return false; + } - if (o_ptr->tval != TV_POTION2) return FALSE; - if (o_ptr->sval != SV_POTION2_CURE_WATER) return FALSE; + if (o_ptr->tval != TV_POTION2) + { + return false; + } + if (o_ptr->sval != SV_POTION2_CURE_WATER) + { + return false; + } for (i = m_max - 1; i >= 1; i--) { @@ -206,20 +264,34 @@ static bool_ quest_poison_drop_hook(void *, void *in_, void *) monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ - if (!m_ptr->r_idx) continue; + if (!m_ptr->r_idx) + { + continue; + } - if (m_ptr->status <= MSTATUS_NEUTRAL) mcnt++; + if (m_ptr->status <= MSTATUS_NEUTRAL) + { + mcnt++; + } } if (mcnt < 10) { for (x = 1; x < cur_wid - 1; x++) + { for (y = 1; y < cur_hgt - 1; y++) { - if (!in_bounds(y, x)) continue; + if (!in_bounds(y, x)) + { + continue; + } - if (cave[y][x].feat == FEAT_TAINTED_WATER) cave_set_feat(y, x, FEAT_SHAL_WATER); + if (cave[y][x].feat == FEAT_TAINTED_WATER) + { + cave_set_feat(y, x, FEAT_SHAL_WATER); + } } + } cmsg_print(TERM_YELLOW, "Well done! The water seems to be clean now."); @@ -228,24 +300,29 @@ static bool_ quest_poison_drop_hook(void *, void *in_, void *) del_hook_new(HOOK_DROP, quest_poison_drop_hook); process_hooks_restart = TRUE; - return FALSE; + return false; } else { msg_print("There are too many monsters left to cure the water."); - return TRUE; + return true; } - return FALSE; + return false; } -bool_ quest_poison_init_hook(int q_idx) +void quest_poison_init_hook() { + auto &messages = game->messages; + /* Get a place to place the poison */ if (!cquest.data[1]) { cquest.data[1] = TRUE; cquest.data[0] = rand_int(4); - if (wizard) message_add(format("Wilderness poison %d, %d", wild_locs[cquest.data[0]][0], wild_locs[cquest.data[0]][1]), TERM_BLUE); + if (wizard) + { + messages.add(format("Wilderness poison %d, %d", wild_locs[cquest.data[0]][0], wild_locs[cquest.data[0]][1]), TERM_BLUE); + } } if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) @@ -259,5 +336,4 @@ bool_ quest_poison_init_hook(int q_idx) add_hook_new(HOOK_INIT_QUEST, quest_poison_quest_hook, "poison_iquest", NULL); } add_hook_new(HOOK_CHAR_DUMP, quest_poison_dump_hook, "poison_dump", NULL); - return (FALSE); } diff --git a/src/q_poison.hpp b/src/q_poison.hpp index f8d97ace..6c4e771b 100644 --- a/src/q_poison.hpp +++ b/src/q_poison.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_poison_init_hook(int q_idx); +void quest_poison_init_hook(); diff --git a/src/q_rand.cc b/src/q_rand.cc index 4ef79928..b643ca39 100644 --- a/src/q_rand.cc +++ b/src/q_rand.cc @@ -3,7 +3,9 @@ #include "artifact_type.hpp" #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" +#include "game.hpp" #include "generate.hpp" #include "hook_build_room1_in.hpp" #include "hook_chardump_in.hpp" @@ -14,10 +16,13 @@ #include "messages.hpp" #include "monster2.hpp" #include "monster3.hpp" -#include "monster_type.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" +#include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "player_type.hpp" @@ -28,6 +33,7 @@ #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> static int randquest_hero[] = { 20, 13, 15, 16, 9, 17, 18, 8, -1 }; @@ -49,6 +55,10 @@ GENERATE_MONSTER_LOOKUP_FN(get_adventurer, "Adventurer") void initialize_random_quests(int n) { + auto const &d_info = game->edit_data.d_info; + auto &r_info = game->edit_data.r_info; + auto &messages = game->messages; + int step, lvl, i, k; int old_type = dungeon_type; @@ -76,14 +86,12 @@ void initialize_random_quests(int n) random_quest *q_ptr = &random_quests[rl]; - int j; - /* Find the appropriate dungeon */ - for (j = 0; j < max_d_idx; j++) + for (std::size_t j = 0; j < d_info.size(); j++) { - dungeon_info_type *d_ptr = &d_info[j]; + auto d_ptr = &d_info[j]; - if (!(d_ptr->flags1 & DF1_PRINCIPAL)) continue; + if (!(d_ptr->flags & DF_PRINCIPAL)) continue; if ((d_ptr->mindepth <= rl) && (rl <= d_ptr->maxdepth)) { @@ -109,23 +117,23 @@ void initialize_random_quests(int n) 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; + if (r_ptr->flags & RF_SPECIAL_GENE) continue; + if (r_ptr->flags & RF_NEVER_GENE) continue; /* Accept only monsters that are not breeders */ - if (r_ptr->flags4 & RF4_MULTIPLY) continue; + if (r_ptr->spells & SF_MULTIPLY) continue; /* Forbid joke monsters */ - if (r_ptr->flags8 & RF8_JOKEANGBAND) continue; + if (r_ptr->flags & RF_JOKEANGBAND) continue; /* Accept only monsters that are not friends */ - if (r_ptr->flags7 & RF7_PET) continue; + if (r_ptr->flags & RF_PET) continue; /* Refuse nazguls */ - if (r_ptr->flags7 & RF7_NAZGUL) continue; + if (r_ptr->flags & RF_NAZGUL) continue; /* Accept only monsters that are not good */ - if (r_ptr->flags3 & RF3_GOOD) continue; + if (r_ptr->flags & RF_GOOD) continue; /* If module says a monster race is friendly, then skip */ if (modules[game_module_idx].race_status != NULL) @@ -148,11 +156,11 @@ void initialize_random_quests(int n) if (!ok) continue; /* No mutliple uniques */ - if ((r_ptr->flags1 & RF1_UNIQUE) && + if ((r_ptr->flags & RF_UNIQUE) && ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue; /* No single non uniques */ - if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue; + if ((!(r_ptr->flags & RF_UNIQUE)) && (q_ptr->type == 1)) continue; /* Level restriction */ min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl; @@ -166,23 +174,22 @@ void initialize_random_quests(int n) { if (wizard) { - message_add(format("Could not find quest monster on lvl %d", rl), TERM_RED); + messages.add(format("Could not find quest monster on lvl %d", rl), TERM_RED); } q_ptr->type = 0; } else { - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { r_ptr->max_num = -1; } - q_ptr->done = FALSE; + q_ptr->done = false; if (wizard) { - message_add(format("Quest for %d on lvl %d", - q_ptr->r_idx, rl), TERM_RED); + messages.add(format("Quest for %d on lvl %d", q_ptr->r_idx, rl), TERM_RED); } } @@ -211,7 +218,9 @@ bool_ is_randhero(int level) static void do_get_new_obj(int y, int x) { - obj_theme theme; + auto &k_info = game->edit_data.k_info; + auto &a_info = game->edit_data.a_info; + object_type *q_ptr[3], forge[3]; int res, i; @@ -225,14 +234,8 @@ static void do_get_new_obj(int y, int x) /* Wipe the object */ object_wipe(q_ptr[i]); - /* No themes */ - theme.treasure = 100; - theme.combat = 100; - theme.magic = 100; - theme.tools = 100; - /* Make a great object */ - make_object(q_ptr[i], TRUE, TRUE, theme); + make_object(q_ptr[i], TRUE, TRUE, obj_theme::no_theme()); q_ptr[i]->found = OBJ_FOUND_REWARD; char buf[100]; @@ -267,9 +270,9 @@ static void do_get_new_obj(int y, int x) /* Mega-Hack -- Preserve the artifact */ if (o_ptr->tval == TV_RANDART) { - random_artifacts[o_ptr->sval].generated = FALSE; + game->random_artifacts[o_ptr->sval].generated = FALSE; } - else if (k_info[o_ptr->k_idx].flags3 & TR3_NORM_ART) + else if (k_info[o_ptr->k_idx].flags & TR_NORM_ART) { k_info[o_ptr->k_idx].artifact = FALSE; } @@ -316,7 +319,7 @@ static void princess_death(s32b m_idx, s32b r_idx) do_get_new_obj(y, x); - random_quests[dun_level].done = TRUE; + random_quests[dun_level].done = true; break; } @@ -325,7 +328,7 @@ static void princess_death(s32b m_idx, s32b r_idx) static void hero_death(s32b m_idx, s32b r_idx) { - random_quests[dun_level].done = TRUE; + random_quests[dun_level].done = true; cmsg_print(TERM_YELLOW, "The adventurer steps out of the shadows and picks up his sword:"); cmsg_print(TERM_YELLOW, "'Ah! My sword! My trusty sword! Thanks."); @@ -401,49 +404,60 @@ static void hero_death(s32b m_idx, s32b r_idx) } } -static bool_ quest_random_death_hook(void *, void *in_, void *) +static bool quest_random_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; int r_idx = m_list[m_idx].r_idx; - if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE); - if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE); - if (!random_quests[dun_level].type) return (FALSE); - if (random_quests[dun_level].done) return (FALSE); - if (p_ptr->inside_quest) return (FALSE); - if (random_quests[dun_level].r_idx != r_idx) return (FALSE); - - if (!(m_list[m_idx].mflag & MFLAG_QUEST)) return (FALSE); + if ((!(dungeon_flags & DF_PRINCIPAL)) || + ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) || + (!random_quests[dun_level].type) || + (random_quests[dun_level].done) || + (p_ptr->inside_quest) || + (random_quests[dun_level].r_idx != r_idx) || + (!(m_list[m_idx].mflag & MFLAG_QUEST))) + { + return false; + } /* Killed enough ?*/ quest[QUEST_RANDOM].data[0]++; if (quest[QUEST_RANDOM].data[0] == random_quests[dun_level].type) { if (is_randhero(dun_level)) + { hero_death(m_idx, r_idx); + } else + { princess_death(m_idx, r_idx); + } } - return (FALSE); + return false; } -static bool_ quest_random_turn_hook(void *, void *, void *) +static bool quest_random_turn_hook(void *, void *, void *) { quest[QUEST_RANDOM].data[0] = 0; quest[QUEST_RANDOM].data[1] = 0; - return (FALSE); + return false; } -static bool_ quest_random_feeling_hook(void *, void *, void *) +static bool quest_random_feeling_hook(void *, void *, void *) { - if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE); - if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE); - if (!random_quests[dun_level].type) return (FALSE); - if (random_quests[dun_level].done) return (FALSE); - if (p_ptr->inside_quest) return (FALSE); - if (!dun_level) return (FALSE); + auto const &r_info = game->edit_data.r_info; + + if ((!(dungeon_flags & DF_PRINCIPAL)) || + ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) || + (!random_quests[dun_level].type) || + (random_quests[dun_level].done) || + (p_ptr->inside_quest) || + (!dun_level)) + { + return false; + } if (is_randhero(dun_level)) { @@ -451,22 +465,25 @@ static bool_ quest_random_feeling_hook(void *, void *, void *) cmsg_format(TERM_YELLOW, "'Oh, please help me! A horrible %s stole my sword! I'm nothing without it.'", r_info[random_quests[dun_level].r_idx].name); } else + { cmsg_format(TERM_YELLOW, "You hear someone shouting: 'Leave me alone, stupid %s'", r_info[random_quests[dun_level].r_idx].name); - return (FALSE); + } + return false; } -static bool_ quest_random_gen_hero_hook(void *, void *, void *) +static bool quest_random_gen_hero_hook(void *, void *, void *) { - int i; - - if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE); - if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE); - if (!random_quests[dun_level].type) return (FALSE); - if (random_quests[dun_level].done) return (FALSE); - if (p_ptr->inside_quest) return (FALSE); - if (!is_randhero(dun_level)) return (FALSE); + if ((!(dungeon_flags & DF_PRINCIPAL)) || + ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) || + (!random_quests[dun_level].type) || + (random_quests[dun_level].done) || + (p_ptr->inside_quest) || + (!is_randhero(dun_level))) + { + return false; + } - i = random_quests[dun_level].type; + int i = random_quests[dun_level].type; m_allow_special[random_quests[dun_level].r_idx] = TRUE; while (i) @@ -483,10 +500,10 @@ static bool_ quest_random_gen_hero_hook(void *, void *, void *) } m_allow_special[random_quests[dun_level].r_idx] = FALSE; - return (FALSE); + return false; } -static bool_ quest_random_gen_hook(void *, void *in_, void *) +static bool quest_random_gen_hook(void *, void *in_, void *) { struct hook_build_room1_in *in = static_cast<struct hook_build_room1_in *>(in_); s32b bx0 = in->x; @@ -497,19 +514,25 @@ static bool_ quest_random_gen_hook(void *, void *in_, void *) int y2, x2, yval, xval; int y1, x1, xsize, ysize; - if (!(dungeon_flags1 & DF1_PRINCIPAL)) return (FALSE); - if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return (FALSE); - if (!random_quests[dun_level].type) return (FALSE); - if (random_quests[dun_level].done) return (FALSE); - if (p_ptr->inside_quest) return (FALSE); - if (quest[QUEST_RANDOM].data[1]) return (FALSE); - if (is_randhero(dun_level)) return (FALSE); + if ((!(dungeon_flags & DF_PRINCIPAL)) || + ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) || + (!random_quests[dun_level].type) || + (random_quests[dun_level].done) || + (p_ptr->inside_quest) || + (quest[QUEST_RANDOM].data[1]) || + (is_randhero(dun_level))) + { + return false; + } /* Pick a room size */ get_map_size(format("qrand%d.map", random_quests[dun_level].type), &ysize, &xsize); /* Try to allocate space for room. If fails, exit */ - if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return FALSE; + if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) + { + return false; + } /* Get corner values */ y1 = yval - ysize / 2; @@ -541,24 +564,23 @@ static bool_ quest_random_gen_hook(void *, void *in_, void *) process_dungeon_file(format("qrand%d.map", random_quests[dun_level].type), &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); for (x = x1; x < xstart; x++) + { for (y = y1; y < ystart; y++) { cave[y][x].info |= CAVE_ICKY | CAVE_ROOM; if (cave[y][x].feat == FEAT_MARKER) { - monster_type *m_ptr; - int i; - m_allow_special[random_quests[dun_level].r_idx] = TRUE; - i = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, FALSE, MSTATUS_ENEMY); + int i = place_monster_one(y, x, random_quests[dun_level].r_idx, 0, FALSE, MSTATUS_ENEMY); m_allow_special[random_quests[dun_level].r_idx] = FALSE; if (i) { - m_ptr = &m_list[i]; + auto m_ptr = &m_list[i]; m_ptr->mflag |= MFLAG_QUEST; } } } + } /* Dont try another one for this generation */ quest[QUEST_RANDOM].data[1] = 1; @@ -566,10 +588,10 @@ static bool_ quest_random_gen_hook(void *, void *in_, void *) /* Boost level feeling a bit - a la pits */ rating += 10; - return (TRUE); + return true; } -static bool_ quest_random_dump_hook(void *, void *in_, void *) +static bool quest_random_dump_hook(void *, void *in_, void *) { static const char *number[] = { "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); @@ -612,37 +634,48 @@ static bool_ quest_random_dump_hook(void *, void *in_, void *) fprintf(f, "\n You haven't completed a single lost sword quest."); } - return (FALSE); + return false; } -bool_ quest_random_describe(FILE *fff) +std::string quest_random_describe() { - if (!(dungeon_flags1 & DF1_PRINCIPAL)) return FALSE; - if ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) return FALSE; - if (!random_quests[dun_level].type) return FALSE; - if (random_quests[dun_level].done) return FALSE; - if (p_ptr->inside_quest) return FALSE; - if (!dun_level) return FALSE; + auto const &r_info = game->edit_data.r_info; + + // Only emit description if we're actually on a + // random quest level. + if ((!(dungeon_flags & DF_PRINCIPAL)) || + ((dun_level < 1) || (dun_level >= MAX_RANDOM_QUEST)) || + (!random_quests[dun_level].type) || + (random_quests[dun_level].done) || + (p_ptr->inside_quest) || + (!dun_level)) + { + return ""; + } + + fmt::MemoryWriter w; if (!is_randhero(dun_level)) { - fprintf(fff, "#####yCaptured princess!\n"); - fprintf(fff, "A princess is being held prisoner and tortured here!\n"); - fprintf(fff, "Save her from the horrible %s.\n", r_info[random_quests[dun_level].r_idx].name); + w.write("#####yCaptured princess!\n"); + w.write("A princess is being held prisoner and tortured here!\n"); + w.write("Save her from the horrible {}.\n", r_info[random_quests[dun_level].r_idx].name); } else { - fprintf(fff, "#####yLost sword!\n"); - fprintf(fff, "An adventurer lost his sword to a bunch of %s!\n", r_info[random_quests[dun_level].r_idx].name); - fprintf(fff, "Kill them all to get it back.\n"); + w.write("#####yLost sword!\n"); + w.write("An adventurer lost his sword to a bunch of {}!\n", r_info[random_quests[dun_level].r_idx].name); + w.write("Kill them all to get it back.\n"); } - fprintf(fff, "Number: %d, Killed: %ld.\n", - random_quests[dun_level].type, (long int) quest[QUEST_RANDOM].data[0]); - fprintf(fff, "\n"); - return TRUE; + + w.write("Number: {}, Killed: {}.", + random_quests[dun_level].type, + quest[QUEST_RANDOM].data[0]); + + return w.str(); } -bool_ quest_random_init_hook(int q_idx) +void quest_random_init_hook() { add_hook_new(HOOK_MONSTER_DEATH, quest_random_death_hook, "rand_death", NULL); add_hook_new(HOOK_NEW_LEVEL, quest_random_turn_hook, "rand_new_lvl", NULL); @@ -651,5 +684,4 @@ bool_ quest_random_init_hook(int q_idx) add_hook_new(HOOK_BUILD_ROOM1, quest_random_gen_hook, "rand_gen", NULL); add_hook_new(HOOK_FEELING, quest_random_feeling_hook, "rand_feel", NULL); add_hook_new(HOOK_CHAR_DUMP, quest_random_dump_hook, "rand_dump", NULL); - return (FALSE); } diff --git a/src/q_rand.hpp b/src/q_rand.hpp index fe87289b..a992aa98 100644 --- a/src/q_rand.hpp +++ b/src/q_rand.hpp @@ -2,7 +2,9 @@ #include "h-basic.h" +#include <string> + void initialize_random_quests(int n); bool_ is_randhero(int level); -bool_ quest_random_init_hook(int q_idx); -bool_ quest_random_describe(FILE *fff); +void quest_random_init_hook(); +std::string quest_random_describe(); diff --git a/src/q_shroom.cc b/src/q_shroom.cc index 89b576d8..627f2b39 100644 --- a/src/q_shroom.cc +++ b/src/q_shroom.cc @@ -1,6 +1,7 @@ #include "q_shroom.hpp" #include "cave.hpp" +#include "game.hpp" #include "hook_chat_in.hpp" #include "hook_give_in.hpp" #include "hook_monster_death_in.hpp" @@ -22,15 +23,15 @@ #define cquest (quest[QUEST_SHROOM]) -static bool_ quest_shroom_speak_hook(void *, void *, void *); -static bool_ quest_shroom_chat_hook(void *, void *, void *); +static bool quest_shroom_speak_hook(void *, void *, void *); +static bool quest_shroom_chat_hook(void *, void *, void *); GENERATE_MONSTER_LOOKUP_FN(get_grip, "Grip, Farmer Maggot's dog") GENERATE_MONSTER_LOOKUP_FN(get_wolf, "Wolf, Farmer Maggot's dog") GENERATE_MONSTER_LOOKUP_FN(get_fang, "Fang, Farmer Maggot's dog") GENERATE_MONSTER_LOOKUP_FN(get_farmer_maggot, "Farmer Maggot") -static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *) +static bool quest_shroom_town_gen_hook(void *, void *in_, void *) { struct hook_wild_gen_in *in = static_cast<struct hook_wild_gen_in *>(in_); int m_idx, x = 1, y = 1, tries = 10000; @@ -41,8 +42,12 @@ static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *) { /* Create the field */ for (x = (cur_wid / 2) - 7; x <= (cur_wid / 2) + 7; x++) + { for (y = (cur_hgt / 2) - 5; y <= (cur_hgt / 2) + 5; y++) + { cave_set_feat(y, x, 181); + } + } /* Throw in some 'shrooms */ for (x = 0; x < (cquest.data[1] - cquest.data[0]); x++) @@ -82,7 +87,10 @@ static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *) } /* Generate maggot in town, in daylight */ - if ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) return (FALSE); + if ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) + { + return false; + } /* Find a good position */ while (tries) @@ -94,7 +102,10 @@ static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *) /* Is it a good spot ? */ /* Not in player los, and avoid shop grids */ if (!los(p_ptr->py, p_ptr->px, y, x) && cave_empty_bold(y, x) && - cave_plain_floor_bold(y, x)) break; + cave_plain_floor_bold(y, x)) + { + break; + } /* One less try */ tries--; @@ -105,16 +116,19 @@ static bool_ quest_shroom_town_gen_hook(void *, void *in_, void *) place_monster_one(y, x, get_farmer_maggot(), 0, FALSE, MSTATUS_ENEMY); m_allow_special[get_farmer_maggot()] = FALSE; - return FALSE; + return false; } -static bool_ quest_shroom_death_hook(void *, void *in_, void *) +static bool quest_shroom_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - if (cquest.status > QUEST_STATUS_COMPLETED) return FALSE; + if (cquest.status > QUEST_STATUS_COMPLETED) + { + return false; + } if ((r_idx == get_wolf()) || (r_idx == get_grip()) || @@ -123,11 +137,13 @@ static bool_ quest_shroom_death_hook(void *, void *in_, void *) msg_print("The dog yells a last time and drops dead on the grass."); } - return FALSE; + return false; } -static bool_ quest_shroom_give_hook(void *, void *in_, void *) +static bool quest_shroom_give_hook(void *, void *in_, void *) { + auto const &r_info = game->edit_data.r_info; + struct hook_give_in *in = static_cast<struct hook_give_in *>(in_); object_type *o_ptr; monster_type *m_ptr; @@ -138,7 +154,10 @@ static bool_ quest_shroom_give_hook(void *, void *in_, void *) o_ptr = &p_ptr->inventory[item]; m_ptr = &m_list[m_idx]; - if (m_ptr->r_idx != get_farmer_maggot()) return (FALSE); + if (m_ptr->r_idx != get_farmer_maggot()) + { + return false; + } /* If one is dead .. its bad */ if ((r_info[get_grip()].max_num == 0) || @@ -154,10 +173,13 @@ static bool_ quest_shroom_give_hook(void *, void *in_, void *) del_hook_new(HOOK_CHAT, quest_shroom_speak_hook); del_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } - if ((o_ptr->tval != TV_FOOD) || (o_ptr->pval2 != 1)) return (FALSE); + if ((o_ptr->tval != TV_FOOD) || (o_ptr->pval2 != 1)) + { + return false; + } /* Take a mushroom */ inc_stack_size_ex(item, -1, OPTIMIZE, NO_DESCRIBE); @@ -181,9 +203,13 @@ static bool_ quest_shroom_give_hook(void *, void *in_, void *) q_ptr->discount = 100; q_ptr->ident |= IDENT_STOREB; if (inven_carry_okay(q_ptr)) + { inven_carry(q_ptr, FALSE); + } else + { drop_near(q_ptr, 0, p_ptr->py, p_ptr->px); + } /* The sling of farmer maggot */ q_ptr = &forge; @@ -196,7 +222,7 @@ static bool_ quest_shroom_give_hook(void *, void *in_, void *) object_known(q_ptr); q_ptr->discount = 100; q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); delete_monster_idx(m_idx); @@ -206,13 +232,17 @@ static bool_ quest_shroom_give_hook(void *, void *in_, void *) process_hooks_restart = TRUE; } else + { msg_format("Oh thank you, but you still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]); + } - return TRUE; + return true; } static void check_dogs_alive(s32b m_idx) { + auto const &r_info = game->edit_data.r_info; + if ((r_info[get_grip()].max_num == 0) || (r_info[get_wolf()].max_num == 0) || (r_info[get_fang()].max_num == 0)) @@ -234,12 +264,15 @@ static void check_dogs_alive(s32b m_idx) } } -static bool_ quest_shroom_speak_hook(void *, void *in_, void *) +static bool quest_shroom_speak_hook(void *, void *in_, void *) { struct hook_mon_speak_in *in = static_cast<struct hook_mon_speak_in *>(in_); s32b m_idx = in->m_idx; - if (m_list[m_idx].r_idx != get_farmer_maggot()) return (FALSE); + if (m_list[m_idx].r_idx != get_farmer_maggot()) + { + return false; + } if (cquest.status == QUEST_STATUS_UNTAKEN) { @@ -250,16 +283,20 @@ static bool_ quest_shroom_speak_hook(void *, void *in_, void *) { check_dogs_alive(m_idx); } - return (TRUE); + + return true; } -static bool_ quest_shroom_chat_hook(void *, void *in_, void *) +static bool quest_shroom_chat_hook(void *, void *in_, void *) { struct hook_chat_in *in = static_cast<struct hook_chat_in *>(in_); s32b m_idx = in->m_idx; monster_type *m_ptr = &m_list[m_idx]; - if (m_ptr->r_idx != get_farmer_maggot()) return (FALSE); + if (m_ptr->r_idx != get_farmer_maggot()) + { + return false; + } if (cquest.status == QUEST_STATUS_UNTAKEN) { @@ -270,18 +307,20 @@ static bool_ quest_shroom_chat_hook(void *, void *in_, void *) msg_print("to the west of Bree? Please try to not harm my dogs. They are so lovely..."); cquest.status = QUEST_STATUS_TAKEN; - quest[QUEST_SHROOM].init(QUEST_SHROOM); + quest[QUEST_SHROOM].init(); } else { check_dogs_alive(m_idx); } - return TRUE; + return true; } -bool_ quest_shroom_init_hook(int q_idx) +void quest_shroom_init_hook() { + auto &messages = game->messages; + /* Get a number of 'shrooms */ if (!cquest.data[1]) { @@ -289,7 +328,7 @@ bool_ quest_shroom_init_hook(int q_idx) cquest.data[1] = rand_range(7, 14); if (wizard) { - message_add(format("Shrooms number %d", cquest.data[1]), TERM_BLUE); + messages.add(format("Shrooms number %d", cquest.data[1]), TERM_BLUE); } } @@ -307,5 +346,4 @@ bool_ quest_shroom_init_hook(int q_idx) add_hook_new(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen", NULL); add_hook_new(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat", NULL); } - return (FALSE); } diff --git a/src/q_shroom.hpp b/src/q_shroom.hpp index 6124775b..4478aee2 100644 --- a/src/q_shroom.hpp +++ b/src/q_shroom.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_shroom_init_hook(int q_idx); +void quest_shroom_init_hook(); diff --git a/src/q_spider.cc b/src/q_spider.cc index 07531b96..a5fa3486 100644 --- a/src/q_spider.cc +++ b/src/q_spider.cc @@ -16,13 +16,16 @@ #define cquest (quest[QUEST_SPIDER]) -static bool_ quest_spider_gen_hook(void *, void *, void *) +static bool quest_spider_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_SPIDER) return FALSE; + if (p_ptr->inside_quest != QUEST_SPIDER) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -43,14 +46,17 @@ static bool_ quest_spider_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("spiders.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); - return TRUE; + return true; } -static bool_ quest_spider_death_hook(void *, void *, void *) +static bool quest_spider_death_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_SPIDER) return FALSE; + if (p_ptr->inside_quest != QUEST_SPIDER) + { + return false; + } for (i = m_max - 1; i >= 1; i--) { @@ -58,9 +64,15 @@ static bool_ quest_spider_death_hook(void *, void *, void *) monster_type *m_ptr = &m_list[i]; /* Ignore "dead" monsters */ - if (!m_ptr->r_idx) continue; + if (!m_ptr->r_idx) + { + continue; + } - if (m_ptr->status <= MSTATUS_ENEMY) mcnt++; + if (m_ptr->status <= MSTATUS_ENEMY) + { + mcnt++; + } } if (mcnt <= 1) @@ -79,19 +91,22 @@ static bool_ quest_spider_death_hook(void *, void *, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_spider_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } - return (FALSE); + return false; } -static bool_ quest_spider_finish_hook(void *, void *in_, void *) +static bool quest_spider_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); object_type forge, *q_ptr; s32b q_idx = in->q_idx; - if (q_idx != QUEST_SPIDER) return FALSE; + if (q_idx != QUEST_SPIDER) + { + return false; + } c_put_str(TERM_YELLOW, "All of us praise your mighty deed in driving back the", 8, 0); c_put_str(TERM_YELLOW, "menace. Take this as a reward.", 9, 0); @@ -103,19 +118,19 @@ static bool_ quest_spider_finish_hook(void *, void *in_, void *) object_aware(q_ptr); object_known(q_ptr); q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); + inven_carry(q_ptr, FALSE); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_POISON; - quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot)); + quest[*(quest[q_idx].plot)].init(); del_hook_new(HOOK_QUEST_FINISH, quest_spider_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -bool_ quest_spider_init_hook(int q_idx) +void quest_spider_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -123,5 +138,4 @@ bool_ quest_spider_init_hook(int q_idx) add_hook_new(HOOK_GEN_QUEST, quest_spider_gen_hook, "spider_gen", NULL); add_hook_new(HOOK_QUEST_FINISH, quest_spider_finish_hook, "spider_finish", NULL); } - return (FALSE); } diff --git a/src/q_spider.hpp b/src/q_spider.hpp index e17cb523..bd16c06a 100644 --- a/src/q_spider.hpp +++ b/src/q_spider.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_spider_init_hook(int q_idx); +void quest_spider_init_hook(); diff --git a/src/q_thief.cc b/src/q_thief.cc index 0f6543cc..a4505d2a 100644 --- a/src/q_thief.cc +++ b/src/q_thief.cc @@ -2,6 +2,8 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "game.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -20,18 +22,23 @@ #define cquest (quest[QUEST_THIEVES]) -static bool_ quest_thieves_gen_hook(void *, void *, void *) +static bool quest_thieves_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; bool_ again = TRUE; - if (p_ptr->inside_quest != QUEST_THIEVES) return FALSE; + if (p_ptr->inside_quest != QUEST_THIEVES) + { + return false; + } /* Just in case we didnt talk the the mayor */ if (cquest.status == QUEST_STATUS_UNTAKEN) + { cquest.status = QUEST_STATUS_TAKEN; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -52,7 +59,7 @@ static bool_ quest_thieves_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("thieves.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; /* Rip the inventory from the player */ cmsg_print(TERM_YELLOW, "You feel a vicious blow on your head."); @@ -63,9 +70,15 @@ static bool_ quest_thieves_gen_hook(void *, void *, void *) { object_type *o_ptr = &p_ptr->inventory[x]; - if (!o_ptr->k_idx) continue; + if (!o_ptr->k_idx) + { + continue; + } - if ((x >= INVEN_WIELD) && cursed_p(o_ptr)) continue; + if ((x >= INVEN_WIELD) && cursed_p(o_ptr)) + { + continue; + } inven_drop(x, 99, 4, 24, TRUE); @@ -81,11 +94,14 @@ static bool_ quest_thieves_gen_hook(void *, void *, void *) return TRUE; } -static bool_ quest_thieves_hook(void *, void *, void *) +static bool quest_thieves_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_THIEVES) return FALSE; + if (p_ptr->inside_quest != QUEST_THIEVES) + { + return false; + } /* ALARM !!! */ if ((cave[17][22].feat == FEAT_OPEN) || @@ -130,17 +146,22 @@ static bool_ quest_thieves_hook(void *, void *, void *) process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "You stopped the thieves and saved Bree!"); - return (FALSE); + return false; } - return FALSE; + return false; } -static bool_ quest_thieves_finish_hook(void *, void *in_, void *) +static bool quest_thieves_finish_hook(void *, void *in_, void *) { + auto const &s_info = game->s_info; + struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_THIEVES) return FALSE; + if (q_idx != QUEST_THIEVES) + { + return false; + } c_put_str(TERM_YELLOW, "Thank you for killing the band of thieves!", 8, 0); c_put_str(TERM_YELLOW, "You can use the hideout as your house as a reward.", 9, 0); @@ -155,21 +176,28 @@ static bool_ quest_thieves_finish_hook(void *, void *in_, void *) else { if (s_info[SKILL_COMBAT].value > s_info[SKILL_MAGIC].value) + { *(quest[q_idx].plot) = QUEST_TROLL; + } else + { *(quest[q_idx].plot) = QUEST_WIGHT; + } } - quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot)); + quest[*(quest[q_idx].plot)].init(); del_hook_new(HOOK_QUEST_FINISH, quest_thieves_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_thieves_feeling_hook(void *, void *, void *) +static bool quest_thieves_feeling_hook(void *, void *, void *) { - if (p_ptr->inside_quest != QUEST_THIEVES) return FALSE; + if (p_ptr->inside_quest != QUEST_THIEVES) + { + return false; + } msg_print("You wake up in a prison cell."); msg_print("All your possessions have been stolen!"); @@ -177,10 +205,10 @@ static bool_ quest_thieves_feeling_hook(void *, void *, void *) del_hook_new(HOOK_FEELING, quest_thieves_feeling_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -bool_ quest_thieves_init_hook(int q_idx) +void quest_thieves_init_hook() { if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -189,5 +217,4 @@ bool_ quest_thieves_init_hook(int q_idx) add_hook_new(HOOK_GEN_QUEST, quest_thieves_gen_hook, "thieves_geb", NULL); add_hook_new(HOOK_FEELING, quest_thieves_feeling_hook, "thieves_feel", NULL); } - return (FALSE); } diff --git a/src/q_thief.hpp b/src/q_thief.hpp index 48e5dc8d..0e191db7 100644 --- a/src/q_thief.hpp +++ b/src/q_thief.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_thieves_init_hook(int q_idx); +void quest_thieves_init_hook(); diff --git a/src/q_thrain.cc b/src/q_thrain.cc index 05def27a..7b895695 100644 --- a/src/q_thrain.cc +++ b/src/q_thrain.cc @@ -3,6 +3,7 @@ #include "cave.hpp" #include "cave_type.hpp" #include "dungeon_info_type.hpp" +#include "game.hpp" #include "generate.hpp" #include "hook_build_room1_in.hpp" #include "hook_move_in.hpp" @@ -11,7 +12,6 @@ #include "init1.hpp" #include "lua_bind.hpp" #include "object_type.hpp" -#include "quark.hpp" #include "randart.hpp" #include "messages.hpp" #include "monster2.hpp" @@ -30,33 +30,52 @@ GENERATE_MONSTER_LOOKUP_FN(get_thrain, "Thrain, the King Under the Mountain") GENERATE_MONSTER_LOOKUP_FN(get_dwar, "Dwar, Dog Lord of Waw") GENERATE_MONSTER_LOOKUP_FN(get_hoarmurath, "Hoarmurath of Dir") -static bool_ quest_thrain_death_hook(void *, void *in_, void *) +static bool quest_thrain_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; int r, x, y; monster_type *m_ptr; - if ((cquest.status >= QUEST_STATUS_FINISHED) || (dun_level !=cquest.data[0]) || (dungeon_type != DUNGEON_DOL_GULDUR)) return (FALSE); + if ((cquest.status >= QUEST_STATUS_FINISHED) || (dun_level !=cquest.data[0]) || (dungeon_type != DUNGEON_DOL_GULDUR)) + { + return false; + } + m_ptr = &m_list[m_idx]; - if ((m_ptr->r_idx != get_dwar()) && (m_ptr->r_idx != get_hoarmurath())) return (FALSE); + if ((m_ptr->r_idx != get_dwar()) && (m_ptr->r_idx != get_hoarmurath())) + { + return false; + } cquest.data[2]++; - if (cquest.data[2] < 2) return (FALSE); + if (cquest.data[2] < 2) + { + return false; + } cmsg_print(TERM_YELLOW, "The magic hiding the room dissipates."); for (x = 0; x < cur_wid; x++) + { for (y = 0; y < cur_hgt; y++) { cave_type *c_ptr = &cave[y][x]; - if (c_ptr->mimic != 61) continue; - if (!(c_ptr->info & CAVE_FREE)) continue; + if (c_ptr->mimic != 61) + { + continue; + } + + if (!(c_ptr->info & CAVE_FREE)) + { + continue; + } c_ptr->mimic = 0; lite_spot(y, x); } + } cquest.status = QUEST_STATUS_FINISHED; cmsg_print(TERM_YELLOW, "Thrain speaks:"); @@ -72,7 +91,10 @@ static bool_ quest_thrain_death_hook(void *, void *in_, void *) monster_type *m_ptr = &m_list[r]; /* Ignore "dead" monsters */ - if (!m_ptr->r_idx) continue; + if (!m_ptr->r_idx) + { + continue; + } /* Is it the princess? */ if (m_ptr->r_idx == get_thrain()) @@ -80,18 +102,20 @@ static bool_ quest_thrain_death_hook(void *, void *in_, void *) int x = m_ptr->fx; int y = m_ptr->fy; int i, j; - object_type forge, *q_ptr; delete_monster_idx(r); /* Wipe the glass walls and create a stair */ for (i = x - 1; i <= x + 1; i++) + { for (j = y - 1; j <= y + 1; j++) { if (in_bounds(j, i)) cave_set_feat(j, i, FEAT_FLOOR); } + } /* Get local object */ + object_type forge, *q_ptr; q_ptr = &forge; /* Wipe the object */ @@ -100,7 +124,7 @@ static bool_ quest_thrain_death_hook(void *, void *in_, void *) q_ptr->number = 1; q_ptr->found = OBJ_FOUND_REWARD; create_artifact(q_ptr, FALSE, TRUE); - q_ptr->art_name = quark_add("of Thrain"); + q_ptr->artifact_name = "of Thrain"; /* Drop it in the dungeon */ drop_near(q_ptr, -1, y, x); @@ -112,10 +136,10 @@ static bool_ quest_thrain_death_hook(void *, void *in_, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_thrain_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } -static bool_ quest_thrain_gen_hook(void *, void *in_, void *) +static bool quest_thrain_gen_hook(void *, void *in_, void *) { struct hook_build_room1_in *in = static_cast<struct hook_build_room1_in *>(in_); s32b bx0 = in->x; @@ -126,16 +150,16 @@ static bool_ quest_thrain_gen_hook(void *, void *in_, void *) int y2, x2, yval, xval; int y1, x1, xsize, ysize; - if (dungeon_type != DUNGEON_DOL_GULDUR) return (FALSE); - if (cquest.data[0] != dun_level) return (FALSE); - if (cquest.data[1]) return (FALSE); - if ((cquest.status < QUEST_STATUS_TAKEN) || (cquest.status >= QUEST_STATUS_FINISHED)) return (FALSE); + if (dungeon_type != DUNGEON_DOL_GULDUR) return false; + if (cquest.data[0] != dun_level) return false; + if (cquest.data[1]) return false; + if ((cquest.status < QUEST_STATUS_TAKEN) || (cquest.status >= QUEST_STATUS_FINISHED)) return false; /* Pick a room size */ get_map_size("thrain.map", &ysize, &xsize); /* Try to allocate space for room. If fails, exit */ - if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return FALSE; + if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return false; /* Get corner values */ y1 = yval - ysize / 2; @@ -183,37 +207,38 @@ static bool_ quest_thrain_gen_hook(void *, void *in_, void *) /* Don't try another one for this generation */ cquest.data[1] = 1; - return (TRUE); + return true; } -static bool_ quest_thrain_feeling_hook(void *, void *, void *) +static bool quest_thrain_feeling_hook(void *, void *, void *) { - if (dungeon_type != DUNGEON_DOL_GULDUR) return (FALSE); - if (cquest.data[0] != dun_level) return (FALSE); - if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE); + if (dungeon_type != DUNGEON_DOL_GULDUR) return false; + if (cquest.data[0] != dun_level) return false; + if (cquest.status != QUEST_STATUS_UNTAKEN) return false; cmsg_format(TERM_YELLOW, "You hear someone shouting under the torture."); cquest.status = QUEST_STATUS_TAKEN; - cquest.init(QUEST_THRAIN); + cquest.init(); - return (FALSE); + return false; } -static bool_ quest_thrain_move_hook(void *, void *in_, void *) +static bool quest_thrain_move_hook(void *, void *in_, void *) { struct hook_move_in *in = static_cast<struct hook_move_in *>(in_); s32b y = in->y; s32b x = in->x; cave_type *c_ptr = &cave[y][x]; - if (dungeon_type != DUNGEON_DOL_GULDUR) return (FALSE); - if (cquest.data[0] != dun_level) return (FALSE); - if ((cquest.status < QUEST_STATUS_TAKEN) || (cquest.status >= QUEST_STATUS_FINISHED)) return (FALSE); - if (!(c_ptr->info & CAVE_FREE)) return (FALSE); - if (c_ptr->mimic != 61) return (FALSE); + if (dungeon_type != DUNGEON_DOL_GULDUR) return false; + if (cquest.data[0] != dun_level) return false; + if ((cquest.status < QUEST_STATUS_TAKEN) || (cquest.status >= QUEST_STATUS_FINISHED)) return false; + if (!(c_ptr->info & CAVE_FREE)) return false; + if (c_ptr->mimic != 61) return false; cmsg_print(TERM_YELLOW, "The magic hiding the room dissipates."); for (x = 0; x < cur_wid; x++) + { for (y = 0; y < cur_hgt; y++) { c_ptr = &cave[y][x]; @@ -224,25 +249,29 @@ static bool_ quest_thrain_move_hook(void *, void *in_, void *) c_ptr->mimic = 0; lite_spot(y, x); } + } - return (FALSE); + return false; } -static bool_ quest_thrain_turn_hook(void *, void *, void *) +static bool quest_thrain_turn_hook(void *, void *, void *) { cquest.data[1] = 0; cquest.data[2] = 0; - return (FALSE); + return false; } -bool_ quest_thrain_init_hook(int q) +void quest_thrain_init_hook() { + auto const &d_info = game->edit_data.d_info; + auto &messages = game->messages; + if (!cquest.data[0]) { cquest.data[0] = rand_range(d_info[DUNGEON_DOL_GULDUR].mindepth + 1, d_info[DUNGEON_DOL_GULDUR].maxdepth - 1); if (wizard) { - message_add(format("Thrain lvl %d", cquest.data[0]), TERM_BLUE); + messages.add(format("Thrain lvl %d", cquest.data[0]), TERM_BLUE); } } if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) @@ -257,5 +286,4 @@ bool_ quest_thrain_init_hook(int q) add_hook_new(HOOK_FEELING, quest_thrain_feeling_hook, "thrain_feel", NULL); add_hook_new(HOOK_MONSTER_DEATH, quest_thrain_death_hook, "thrain_death", NULL); } - return (FALSE); } diff --git a/src/q_thrain.hpp b/src/q_thrain.hpp index 830da016..aa42385d 100644 --- a/src/q_thrain.hpp +++ b/src/q_thrain.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -extern bool_ quest_thrain_init_hook(int q_idx); +void quest_thrain_init_hook(); diff --git a/src/q_troll.cc b/src/q_troll.cc index fce3ad49..54eb3406 100644 --- a/src/q_troll.cc +++ b/src/q_troll.cc @@ -3,6 +3,7 @@ #include "artifact_type.hpp" #include "cave.hpp" #include "cave_type.hpp" +#include "game.hpp" #include "hook_monster_death_in.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" @@ -25,13 +26,18 @@ GENERATE_MONSTER_LOOKUP_FN(get_tom, "Tom the Stone Troll") GENERATE_MONSTER_LOOKUP_FN(get_stone_troll, "Stone troll") GENERATE_MONSTER_LOOKUP_FN(get_forest_troll, "Forest troll") -static bool_ quest_troll_gen_hook(void *, void *, void *) +static bool quest_troll_gen_hook(void *, void *, void *) { + auto &a_info = game->edit_data.a_info; + int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_TROLL) return FALSE; + if (p_ptr->inside_quest != QUEST_TROLL) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -110,37 +116,43 @@ static bool_ quest_troll_gen_hook(void *, void *, void *) /* Reinitialize the ambush ... hehehe */ cquest.data[0] = FALSE; - return TRUE; + return true; } -static bool_ quest_troll_finish_hook(void *, void *in_, void *) +static bool quest_troll_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_TROLL) return FALSE; + if (q_idx != QUEST_TROLL) + { + return false; + } c_put_str(TERM_YELLOW, "I heard about your noble deeds.", 8, 0); c_put_str(TERM_YELLOW, "Keep what you found... may it serve you well.", 9, 0); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NAZGUL; - quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot)); + quest[*(quest[q_idx].plot)].init(); del_hook_new(HOOK_QUEST_FINISH, quest_troll_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_troll_death_hook(void *, void *in_, void *) +static bool quest_troll_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; int x, y, xstart = 2, ystart = 2; - if (p_ptr->inside_quest != QUEST_TROLL) return FALSE; + if (p_ptr->inside_quest != QUEST_TROLL) + { + return false; + } if (r_idx == get_tom()) { @@ -151,19 +163,23 @@ static bool_ quest_troll_death_hook(void *, void *in_, void *) cquest.status = QUEST_STATUS_COMPLETED; del_hook_new(HOOK_MONSTER_DEATH, quest_troll_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } init_flags = INIT_GET_SIZE; process_dungeon_file("trolls.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); - if (cquest.data[0]) return FALSE; + if (cquest.data[0]) + { + return false; + } cquest.data[0] = TRUE; msg_print("Oops, seems like an ambush..."); for (x = 3; x < xstart; x++) + { for (y = 3; y < ystart; y++) { cave_type *c_ptr = &cave[y][x]; @@ -178,11 +194,12 @@ static bool_ quest_troll_death_hook(void *, void *in_, void *) place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY); } } + } - return FALSE; + return false; } -bool_ quest_troll_init_hook(int q_idx) +void quest_troll_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -190,5 +207,4 @@ bool_ quest_troll_init_hook(int q_idx) add_hook_new(HOOK_GEN_QUEST, quest_troll_gen_hook, "troll_gen", NULL); add_hook_new(HOOK_QUEST_FINISH, quest_troll_finish_hook, "troll_finish", NULL); } - return (FALSE); } diff --git a/src/q_troll.hpp b/src/q_troll.hpp index 140fe0b2..08bba3dd 100644 --- a/src/q_troll.hpp +++ b/src/q_troll.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_troll_init_hook(int q_idx); +void quest_troll_init_hook(); diff --git a/src/q_ultrae.cc b/src/q_ultrae.cc index d42b9c6f..ff2a6a48 100644 --- a/src/q_ultrae.cc +++ b/src/q_ultrae.cc @@ -2,7 +2,7 @@ #define cquest (quest[QUEST_ULTRA_EVIL]) -bool_ quest_ultra_evil_init_hook(int q) +void quest_ultra_evil_init_hook() { - return (FALSE); + // Initialized by other hook. } diff --git a/src/q_ultrae.hpp b/src/q_ultrae.hpp index 5b08127b..77ec2e38 100644 --- a/src/q_ultrae.hpp +++ b/src/q_ultrae.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_ultra_evil_init_hook(int q_idx); +void quest_ultra_evil_init_hook(); diff --git a/src/q_ultrag.cc b/src/q_ultrag.cc index c7c0312b..e3da974f 100644 --- a/src/q_ultrag.cc +++ b/src/q_ultrag.cc @@ -10,6 +10,7 @@ #include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_type.hpp" #include "options.hpp" #include "player_type.hpp" @@ -19,7 +20,7 @@ #define cquest (quest[QUEST_ULTRA_GOOD]) -static bool_ quest_ultra_good_move_hook(void *, void *in_, void *) +static bool quest_ultra_good_move_hook(void *, void *in_, void *) { struct hook_move_in *in = static_cast<struct hook_move_in *>(in_); s32b y = in->y; @@ -28,14 +29,20 @@ static bool_ quest_ultra_good_move_hook(void *, void *in_, void *) if (cquest.status == QUEST_STATUS_UNTAKEN) { - bool_ old_quick_messages = quick_messages; - - if (quest[QUEST_MORGOTH].status < QUEST_STATUS_FINISHED) return (FALSE); + if (quest[QUEST_MORGOTH].status < QUEST_STATUS_FINISHED) + { + return false; + } /* The mirror of Galadriel */ - if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 23)) return (FALSE); + if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 23)) + { + return false; + } + + auto old_quick_messages = options->quick_messages; + options->quick_messages = FALSE; - quick_messages = FALSE; cmsg_print(TERM_L_BLUE, "You meet Galadriel."); cmsg_print(TERM_YELLOW, "'I still cannot believe this is all over.'"); cmsg_print(TERM_YELLOW, "'Morgoth's reign of terror is over at last!'"); @@ -79,37 +86,42 @@ static bool_ quest_ultra_good_move_hook(void *, void *in_, void *) /* Continue the plot */ cquest.status = QUEST_STATUS_TAKEN; - cquest.init(QUEST_ULTRA_GOOD); + cquest.init(); } - quick_messages = old_quick_messages; - return TRUE; + options->quick_messages = old_quick_messages; + + return true; } - return FALSE; + return false; } -static bool_ quest_ultra_good_stair_hook(void *, void *in_, void *) +static bool quest_ultra_good_stair_hook(void *, void *in_, void *) { struct hook_stair_in *in = static_cast<struct hook_stair_in *>(in_); stairs_direction dir = in->direction; if (dungeon_type != DUNGEON_VOID) - return FALSE; + { + return false; + } /* Cant leave */ if ((dir == STAIRS_UP) && (dun_level == 128)) { cmsg_print(TERM_YELLOW, "The portal to Arda is now closed."); - return TRUE; + return true; } + /* there is no coming back */ if ((dir == STAIRS_UP) && (dun_level == 150)) { cmsg_print(TERM_YELLOW, "The barrier seems to be impenetrable from this side."); cmsg_print(TERM_YELLOW, "You will have to move on."); - return TRUE; + return true; } + /* Cant enter without the flame imperishable */ if ((dir == STAIRS_DOWN) && (dun_level == 149)) { @@ -119,15 +131,16 @@ static bool_ quest_ultra_good_stair_hook(void *, void *in_, void *) /* Now look for an ULTIMATE artifact, that is, one imbued with the flame */ for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) { - u32b f1, f2, f3, f4, f5, esp; object_type *o_ptr = get_object(i); - if (!o_ptr->k_idx) continue; + if (!o_ptr->k_idx) + { + continue; + } - /* Examine the gloves */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); - if (f4 & TR4_ULTIMATE) + if (flags & TR_ULTIMATE) { ultimate = TRUE; break; @@ -148,19 +161,21 @@ static bool_ quest_ultra_good_stair_hook(void *, void *in_, void *) } } - return FALSE; + return false; } -static bool_ quest_ultra_good_recall_hook(void *, void *, void *) +static bool quest_ultra_good_recall_hook(void *, void *, void *) { if ((dungeon_type != DUNGEON_VOID) && (dungeon_type != DUNGEON_NETHER_REALM)) - return FALSE; + { + return false; + } cmsg_print(TERM_YELLOW, "You cannot recall. The portal to Arda is closed."); - return TRUE; + return true; } -static bool_ quest_ultra_good_death_hook(void *, void *in_, void *) +static bool quest_ultra_good_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; @@ -226,7 +241,10 @@ static bool_ quest_ultra_good_death_hook(void *, void *in_, void *) for (i = 0; i < INVEN_PACK; i++) { /* Skip non-objects */ - if (!p_ptr->inventory[i].k_idx) break; + if (!p_ptr->inventory[i].k_idx) + { + break; + } } /* Arg, no space ! */ if (i == INVEN_PACK) @@ -245,10 +263,11 @@ static bool_ quest_ultra_good_death_hook(void *, void *in_, void *) cmsg_format(TERM_VIOLET, "You feel the urge to pick up the Flame Imperishable."); inven_carry(q_ptr, FALSE); } - return (FALSE); + + return false; } -static bool_ quest_ultra_good_dump_hook(void *, void *in_, void *) +static bool quest_ultra_good_dump_hook(void *, void *in_, void *) { struct hook_chardump_in *in = static_cast<struct hook_chardump_in *>(in_); FILE *f = in->file; @@ -271,11 +290,12 @@ static bool_ quest_ultra_good_dump_hook(void *, void *in_, void *) } } } - return (FALSE); + + return false; } -bool_ quest_ultra_good_init_hook(int q) +void quest_ultra_good_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -288,5 +308,4 @@ bool_ quest_ultra_good_init_hook(int q) add_hook_new(HOOK_MOVE, quest_ultra_good_move_hook, "ultrag_move", NULL); } add_hook_new(HOOK_CHAR_DUMP, quest_ultra_good_dump_hook, "ultrag_dump", NULL); - return (FALSE); } diff --git a/src/q_ultrag.hpp b/src/q_ultrag.hpp index 0064b878..cef81fa5 100644 --- a/src/q_ultrag.hpp +++ b/src/q_ultrag.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_ultra_good_init_hook(int q_idx); +void quest_ultra_good_init_hook(); diff --git a/src/q_wight.cc b/src/q_wight.cc index f2cc630c..ced87277 100644 --- a/src/q_wight.cc +++ b/src/q_wight.cc @@ -9,8 +9,8 @@ #include "monster2.hpp" #include "monster_type.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "tables.hpp" #include "util.hpp" #include "variable.hpp" @@ -22,13 +22,16 @@ GENERATE_MONSTER_LOOKUP_FN(get_wight_king, "The Wight-King of the Barrow-downs") -static bool_ quest_wight_gen_hook(void *, void *, void *) +static bool quest_wight_gen_hook(void *, void *, void *) { int x, y; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_WIGHT) return FALSE; + if (p_ptr->inside_quest != QUEST_WIGHT) + { + return false; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -50,6 +53,7 @@ static bool_ quest_wight_gen_hook(void *, void *, void *) process_dungeon_file("wights.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE); for (x = 3; x < xstart; x++) + { for (y = 3; y < ystart; y++) { if (cave[y][x].feat == FEAT_MARKER) @@ -74,25 +78,31 @@ static bool_ quest_wight_gen_hook(void *, void *, void *) /* Name the rags */ - q_ptr->art_name = quark_add("of the Wight"); + q_ptr->artifact_name = "of the Wight"; + + q_ptr->art_flags |= + TR_INT | + TR_RES_BLIND | + TR_SENS_FIRE | + TR_RES_CONF | + TR_IGNORE_ACID | + TR_IGNORE_ELEC | + TR_IGNORE_FIRE | + TR_IGNORE_COLD | + TR_SEE_INVIS | + TR_CURSED | + TR_HEAVY_CURSE; - q_ptr->art_flags1 |= ( TR1_INT | TR1_SEARCH ); - q_ptr->art_flags2 |= ( TR2_RES_BLIND | TR2_SENS_FIRE | TR2_RES_CONF ); - q_ptr->art_flags3 |= ( TR3_IGNORE_ACID | TR3_IGNORE_ELEC | - TR3_IGNORE_FIRE | TR3_IGNORE_COLD | TR3_SEE_INVIS); - - /* For game balance... */ - q_ptr->art_flags3 |= (TR3_CURSED | TR3_HEAVY_CURSE); q_ptr->ident |= IDENT_CURSED; if (randint(2) == 1) { - q_ptr->art_flags1 |= (TR1_SPELL); + q_ptr->art_flags |= TR_SPELL; q_ptr->pval = 6; } else { - q_ptr->art_flags1 |= (TR1_MANA); + q_ptr->art_flags |= TR_MANA; q_ptr->pval = 2; } @@ -117,17 +127,21 @@ static bool_ quest_wight_gen_hook(void *, void *, void *) } } } + } - return TRUE; + return true; } -static bool_ quest_wight_death_hook(void *, void *in_, void *) +static bool quest_wight_death_hook(void *, void *in_, void *) { struct hook_monster_death_in *in = static_cast<struct hook_monster_death_in *>(in_); s32b m_idx = in->m_idx; s32b r_idx = m_list[m_idx].r_idx; - if (p_ptr->inside_quest != QUEST_WIGHT) return FALSE; + if (p_ptr->inside_quest != QUEST_WIGHT) + { + return false; + } if (r_idx == get_wight_king()) { @@ -141,33 +155,36 @@ static bool_ quest_wight_death_hook(void *, void *in_, void *) del_hook_new(HOOK_MONSTER_DEATH, quest_wight_death_hook); process_hooks_restart = TRUE; - return (FALSE); + return false; } - return (FALSE); + return false; } -static bool_ quest_wight_finish_hook(void *, void *in_, void *) +static bool quest_wight_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_WIGHT) return FALSE; + if (q_idx != QUEST_WIGHT) + { + return false; + } c_put_str(TERM_YELLOW, "I heard about your noble deeds.", 8, 0); c_put_str(TERM_YELLOW, "Keep what you found .. may it serve you well.", 9, 0); /* Continue the plot */ *(quest[q_idx].plot) = QUEST_NAZGUL; - quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot)); + quest[*(quest[q_idx].plot)].init(); del_hook_new(HOOK_QUEST_FINISH, quest_wight_finish_hook); process_hooks_restart = TRUE; - return TRUE; + return true; } -bool_ quest_wight_init_hook(int q_idx) +void quest_wight_init_hook() { if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -175,5 +192,4 @@ bool_ quest_wight_init_hook(int q_idx) add_hook_new(HOOK_GEN_QUEST, quest_wight_gen_hook, "wight_gen", NULL); add_hook_new(HOOK_QUEST_FINISH, quest_wight_finish_hook, "wight_finish", NULL); } - return (FALSE); } diff --git a/src/q_wight.hpp b/src/q_wight.hpp index 1252e4fa..16713332 100644 --- a/src/q_wight.hpp +++ b/src/q_wight.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_wight_init_hook(int q_idx); +void quest_wight_init_hook(); diff --git a/src/q_wolves.cc b/src/q_wolves.cc index c5863b59..0e811ce6 100644 --- a/src/q_wolves.cc +++ b/src/q_wolves.cc @@ -2,7 +2,10 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "dungeon_flag.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_quest_finish_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -17,17 +20,24 @@ #define cquest (quest[QUEST_WOLVES]) -static bool_ quest_wolves_gen_hook(void *, void *, void *) +static bool quest_wolves_gen_hook(void *, void *, void *) { + auto const &f_info = game->edit_data.f_info; + int x, y, i; int xstart = 2; int ystart = 2; - if (p_ptr->inside_quest != QUEST_WOLVES) return FALSE; + if (p_ptr->inside_quest != QUEST_WOLVES) + { + return false; + } /* Just in case we didnt talk the the mayor */ if (cquest.status == QUEST_STATUS_UNTAKEN) + { cquest.status = QUEST_STATUS_TAKEN; + } /* Start with perm walls */ for (y = 0; y < cur_hgt; y++) @@ -48,18 +58,17 @@ static bool_ quest_wolves_gen_hook(void *, void *, void *) init_flags = INIT_CREATE_DUNGEON; process_dungeon_file("wolves.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); - dungeon_flags2 |= DF2_NO_GENO; + dungeon_flags |= DF_NO_GENO; /* Place some random wolves */ for (i = damroll(4, 4); i > 0; ) { - int m_idx, flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { - m_idx = place_monster_one(y, x, 196, 0, magik(50), MSTATUS_ENEMY); + int m_idx = place_monster_one(y, x, 196, 0, magik(50), MSTATUS_ENEMY); if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; --i; } @@ -68,13 +77,12 @@ static bool_ quest_wolves_gen_hook(void *, void *, void *) /* Place some random wargs */ for (i = damroll(4, 4); i > 0; ) { - int m_idx, flags; y = rand_int(21) + 3; x = rand_int(31) + 3; - flags = f_info[cave[y][x].feat].flags1; - if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR)) + auto const flags = f_info[cave[y][x].feat].flags; + if (!(flags & FF_PERMANENT) && (flags & FF_FLOOR)) { - m_idx = place_monster_one(y, x, 257, 0, magik(50), MSTATUS_ENEMY); + int m_idx = place_monster_one(y, x, 257, 0, magik(50), MSTATUS_ENEMY); if (m_idx) m_list[m_idx].mflag |= MFLAG_QUEST; --i; } @@ -82,14 +90,17 @@ static bool_ quest_wolves_gen_hook(void *, void *, void *) process_hooks_restart = TRUE; - return TRUE; + return true; } -static bool_ quest_wolves_death_hook(void *, void *, void *) +static bool quest_wolves_death_hook(void *, void *, void *) { int i, mcnt = 0; - if (p_ptr->inside_quest != QUEST_WOLVES) return FALSE; + if (p_ptr->inside_quest != QUEST_WOLVES) + { + return false; + } /* Process the monsters (backwards) */ for (i = m_max - 1; i >= 1; i--) @@ -113,17 +124,20 @@ static bool_ quest_wolves_death_hook(void *, void *, void *) process_hooks_restart = TRUE; cmsg_print(TERM_YELLOW, "Lothlorien is safer now."); - return (FALSE); + return false; } - return FALSE; + return false; } -static bool_ quest_wolves_finish_hook(void *, void *in_, void *) +static bool quest_wolves_finish_hook(void *, void *in_, void *) { struct hook_quest_finish_in *in = static_cast<struct hook_quest_finish_in *>(in_); s32b q_idx = in->q_idx; - if (q_idx != QUEST_WOLVES) return FALSE; + if (q_idx != QUEST_WOLVES) + { + return false; + } c_put_str(TERM_YELLOW, "Thank you for killing the pack of wolves!", 8, 0); c_put_str(TERM_YELLOW, "You can use the hut as your house as a reward.", 9, 0); @@ -131,10 +145,10 @@ static bool_ quest_wolves_finish_hook(void *, void *in_, void *) /* Continue the plot */ *(quest[q_idx].plot) = QUEST_SPIDER; - return TRUE; + return true; } -bool_ quest_wolves_init_hook(int q_idx) +void quest_wolves_init_hook() { if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED)) { @@ -142,5 +156,4 @@ bool_ quest_wolves_init_hook(int q_idx) add_hook_new(HOOK_QUEST_FINISH, quest_wolves_finish_hook, "wolves_finish", NULL); add_hook_new(HOOK_GEN_QUEST, quest_wolves_gen_hook, "wolves_geb", NULL); } - return (FALSE); } diff --git a/src/q_wolves.hpp b/src/q_wolves.hpp index 59a83c56..c5596fc6 100644 --- a/src/q_wolves.hpp +++ b/src/q_wolves.hpp @@ -2,4 +2,4 @@ #include "h-basic.h" -bool_ quest_wolves_init_hook(int q_idx); +void quest_wolves_init_hook(); diff --git a/src/quark.cc b/src/quark.cc deleted file mode 100644 index 45072ded..00000000 --- a/src/quark.cc +++ /dev/null @@ -1,96 +0,0 @@ -#include "quark.hpp" - -#include "z-util.h" - -#include <cassert> - -/* - * The number of quarks - */ -static s16b quark__num = 0; - - -/* - * The pointers to the quarks [QUARK_MAX] - */ -static cptr *quark__str = NULL; - - -/* - * Initialize the quark subsystem - */ -void quark_init() -{ - quark__num = 0; - quark__str = new cptr[QUARK_MAX]; - - for (int i = 0; i < QUARK_MAX; i++) { - quark__str[i] = nullptr; - } -} - - -/* -* We use a global array for all inscriptions to reduce the memory -* spent maintaining inscriptions. Of course, it is still possible -* to run out of inscription memory, especially if too many different -* inscriptions are used, but hopefully this will be rare. -* -* We use dynamic string allocation because otherwise it is necessary -* to pre-guess the amount of quark activity. We limit the total -* number of quarks, but this is much easier to "expand" as needed. -* -* Any two items with the same inscription will have the same "quark" -* index, which should greatly reduce the need for inscription space. -* -* Note that "quark zero" is NULL and should not be "dereferenced". -*/ - -/* -* Add a new "quark" to the set of quarks. -*/ -s16b quark_add(cptr str) -{ - assert(str != nullptr); - - int i; - - /* Look for an existing quark */ - for (i = 1; i < quark__num; i++) - { - /* Check for equality */ - if (streq(quark__str[i], str)) return (i); - } - - /* Paranoia -- Require room */ - if (quark__num == QUARK_MAX) return (0); - - /* New maximal quark */ - quark__num = i + 1; - - /* Add a new quark */ - quark__str[i] = strdup(str); - - /* Return the index */ - return (i); -} - - -/* -* This function looks up a quark -*/ -cptr quark_str(s16b i) -{ - cptr q; - - /* Verify */ - if ((i < 0) || (i >= quark__num)) i = 0; - - /* Access the quark */ - q = quark__str[i]; - - /* Return the quark */ - return (q); -} - - diff --git a/src/quark.hpp b/src/quark.hpp deleted file mode 100644 index 0fce3932..00000000 --- a/src/quark.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "h-basic.h" - -/** - * Maximum number of quarks. - */ -constexpr int QUARK_MAX = 768; - -void quark_init(); -cptr quark_str(s16b num); -s16b quark_add(cptr str); diff --git a/src/quest.cc b/src/quest.cc index a1aee67f..181b46d2 100644 --- a/src/quest.cc +++ b/src/quest.cc @@ -6,12 +6,11 @@ void init_hooks_quests() { - for (std::size_t i = 0; i < MAX_Q_IDX; i++) + for (auto const &q: quest) { - if (quest[i].init != NULL) + if (q.init) { - quest[i].init(i); + q.init(); } } } - diff --git a/src/quest.hpp b/src/quest.hpp index 7ff3cd3c..1897bcfa 100644 --- a/src/quest.hpp +++ b/src/quest.hpp @@ -1,3 +1,3 @@ #pragma once -extern void init_hooks_quests(); +void init_hooks_quests(); diff --git a/src/quest_type.hpp b/src/quest_type.hpp index aa99f40a..ae97af35 100644 --- a/src/quest_type.hpp +++ b/src/quest_type.hpp @@ -2,6 +2,8 @@ #include "h-basic.h" +#include <string> + /** * Quest descriptor and runtime data. */ @@ -19,9 +21,9 @@ struct quest_type s16b *plot; /* Which plot does it belongs to? */ - bool_ (*init)(int q); /* Function that takes care of generating hardcoded quests */ + void (*init)(); /* Function that takes care of generating hardcoded quests */ - s32b data[9]; /* Various datas used by the quests */ + s32b data[9]; /* Various datas used by the quests */ - bool_ (*gen_desc)(FILE *fff); /* Function for generating description. */ + std::string (*gen_desc)(); /* Function for generating description. */ }; diff --git a/src/randart.cc b/src/randart.cc index 5135438a..a902d734 100644 --- a/src/randart.cc +++ b/src/randart.cc @@ -7,77 +7,76 @@ */ #include "randart.hpp" + +#include "game.hpp" #include "mimic.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_type.hpp" #include "options.hpp" #include "player_type.hpp" -#include "quark.hpp" -#include "randart_gen_type.hpp" -#include "randart_part_type.hpp" #include "spells2.hpp" #include "util.hpp" #include "variable.h" #include "variable.hpp" #include "z-rand.hpp" -#include <memory> -#include <vector> - /* Chance of using syllables to form the name instead of the "template" files */ -#define TABLE_NAME 45 #define A_CURSED 13 #define WEIRD_LUCK 12 -#define ACTIVATION_CHANCE 3 /* * Attempt to add a power to a randart */ -static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *max_times) +static bool_ grab_one_power(int *ra_idx, object_type const *o_ptr, std::vector<s16b> &max_times) { + auto const &ra_info = game->edit_data.ra_info; + + assert(max_times.size() >= ra_info.size()); + bool_ ret = FALSE; - u32b f1, f2, f3, f4, f5, esp; std::vector<size_t> ok_ra; /* Grab the ok randart */ - for (size_t i = 0; i < max_ra_idx; i++) + for (size_t i = 0; i < ra_info.size(); i++) { - randart_part_type *ra_ptr = &ra_info[i]; + auto ra_ptr = &ra_info[i]; bool_ ok = FALSE; /* Must have the correct fields */ - for (size_t j = 0; j < 20; j++) + for (auto const &filter: ra_ptr->kind_filter) { - if (ra_ptr->tval[j] == o_ptr->tval) + if ((filter.tval == o_ptr->tval) && + (filter.min_sval <= o_ptr->sval) && + (o_ptr->sval <= filter.max_sval)) { - if ((ra_ptr->min_sval[j] <= o_ptr->sval) && (ra_ptr->max_sval[j] >= o_ptr->sval)) ok = TRUE; + ok = TRUE; + break; } + } - if (ok) break; + if ((0 < ra_ptr->max_pval) && (ra_ptr->max_pval < o_ptr->pval)) + { + ok = FALSE; } - if ((0 < ra_ptr->max_pval) && (ra_ptr->max_pval < o_ptr->pval)) ok = FALSE; + if (!ok) { /* Doesnt count as a try*/ continue; } - /* Good should be good, bad should be bad */ - if (good && (ra_ptr->value <= 0)) continue; - if ((!good) && (ra_ptr->value > 0)) continue; + /* Skip bad powers */ + if (ra_ptr->value <= 0) continue; + /* Already chosen the maximum number of times? */ if (max_times[i] >= ra_ptr->max) continue; /* Must NOT have the antagonic flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f1 & ra_ptr->aflags1) continue; - if (f2 & ra_ptr->aflags2) continue; - if (f3 & ra_ptr->aflags3) continue; - if (f4 & ra_ptr->aflags4) continue; - if (f5 & ra_ptr->aflags5) continue; - if (esp & ra_ptr->aesp) continue; + auto const flags = object_flags(o_ptr); + if (flags & ra_ptr->aflags) continue; /* ok */ ok_ra.push_back(i); @@ -86,8 +85,8 @@ static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *m /* Now test them a few times */ for (size_t count = 0; count < ok_ra.size() * 10; count++) { - size_t i = ok_ra[rand_int(ok_ra.size())]; - randart_part_type *ra_ptr = &ra_info[i]; + size_t i = *uniform_element(ok_ra); + auto ra_ptr = &ra_info[i]; /* XXX XXX Enforce minimum player level (loosely) */ if (ra_ptr->level > p_ptr->lev) @@ -121,24 +120,6 @@ static bool_ grab_one_power(int *ra_idx, object_type *o_ptr, bool_ good, s16b *m return (ret); } -void give_activation_power (object_type * o_ptr) -{ - o_ptr->xtra2 = 0; - o_ptr->art_flags3 &= ~TR3_ACTIVATE; - o_ptr->timeout = 0; -} - - -int get_activation_power() -{ - object_type *o_ptr, forge; - - o_ptr = &forge; - - give_activation_power(o_ptr); - - return o_ptr->xtra2; -} #define MIN_NAME_LEN 5 #define MAX_NAME_LEN 9 @@ -193,7 +174,7 @@ void build_prob(cptr learn) * set. Relies on European vowels (a, e, i, o, u). The generated name should * be copied/used before calling this function again. */ -static char *make_word(void) +static char *make_word() { static char word_buf[90]; int r, totalfreq; @@ -264,11 +245,13 @@ void get_random_name(char * return_name) bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) { + auto const &ra_gen = game->edit_data.ra_gen; + auto const &ra_info = game->edit_data.ra_info; + char new_name[80]; - int powers = 0, i; + int powers = 0; s32b total_flags, total_power = 0; bool_ a_cursed = FALSE; - u32b f1, f2, f3, f4, f5, esp; s16b pval = 0; bool_ limit_blows = FALSE; @@ -276,52 +259,46 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) if ((!a_scroll) && (randint(A_CURSED) == 1)) a_cursed = TRUE; - i = 0; - while (ra_gen[i].chance) + for (auto const &g: ra_gen) { - powers += damroll(ra_gen[i].dd, ra_gen[i].ds) + ra_gen[i].plus; - i++; + powers += damroll(g.dd, g.ds) + g.plus; } if ((!a_cursed) && (randint(30) == 1)) powers *= 2; if (a_cursed) powers /= 2; - std::unique_ptr<s16b[]> max_times(new s16b[max_ra_idx]); - for (int i = 0; i < max_ra_idx; i++) { - max_times[i] = 0; - } + std::vector<s16b> max_times(ra_info.size(), 0); /* Main loop */ while (powers) { - int ra_idx; - randart_part_type *ra_ptr; - powers--; - if (!grab_one_power(&ra_idx, o_ptr, TRUE, max_times.get())) continue; + int ra_idx; + if (!grab_one_power(&ra_idx, o_ptr, max_times)) + { + continue; + } - ra_ptr = &ra_info[ra_idx]; + auto ra_ptr = &ra_info[ra_idx]; - if (wizard) msg_format("Adding randart power: %d", ra_idx); + if (wizard) + { + msg_format("Adding randart power: %d", ra_idx); + } total_power += ra_ptr->value; - o_ptr->art_flags1 |= ra_ptr->flags1; - o_ptr->art_flags2 |= ra_ptr->flags2; - o_ptr->art_flags3 |= ra_ptr->flags3; - o_ptr->art_flags4 |= ra_ptr->flags4; - o_ptr->art_flags5 |= ra_ptr->flags5; - o_ptr->art_esp |= ra_ptr->esp; + o_ptr->art_flags |= ra_ptr->flags; add_random_ego_flag(o_ptr, ra_ptr->fego, &limit_blows); /* get flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack -- acquire "cursed" flag */ - if (f3 & TR3_CURSED) o_ptr->ident |= (IDENT_CURSED); + if (flags & TR_CURSED) o_ptr->ident |= (IDENT_CURSED); /* Hack -- obtain bonuses */ if (ra_ptr->max_to_h > 0) o_ptr->to_h += randint(ra_ptr->max_to_h); @@ -339,23 +316,26 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) if (pval < 0) o_ptr->pval = randint( -pval); /* No insane number of blows */ - if (limit_blows && (o_ptr->art_flags1 & TR1_BLOWS)) + if (limit_blows && (o_ptr->art_flags & TR_BLOWS)) { if (o_ptr->pval > 2) o_ptr->pval = randint(2); } /* Just to be sure */ - o_ptr->art_flags3 |= ( TR3_IGNORE_ACID | TR3_IGNORE_ELEC | - TR3_IGNORE_FIRE | TR3_IGNORE_COLD); + o_ptr->art_flags |= + TR_IGNORE_ACID | + TR_IGNORE_ELEC | + TR_IGNORE_FIRE | + TR_IGNORE_COLD; total_flags = flag_cost(o_ptr, o_ptr->pval); - if (cheat_peek) msg_format("%ld", total_flags); + if (options->cheat_peek) + { + msg_format("%ld", total_flags); + } if (a_cursed) curse_artifact(o_ptr); - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (get_name) { if (a_scroll) @@ -378,7 +358,7 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) } else /* Default name = of 'player name' */ - sprintf(new_name, "of '%s'", player_name); + sprintf(new_name, "of '%s'", game->player_name.c_str()); } else { @@ -387,19 +367,22 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) } /* Save the inscription */ - o_ptr->art_name = quark_add(new_name); + o_ptr->artifact_name = new_name; o_ptr->name2 = o_ptr->name2b = 0; /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); + /* Extract the flags */ + auto const flags = object_flags(o_ptr); + /* HACKS for ToME */ if (o_ptr->tval == TV_CLOAK && o_ptr->sval == SV_MIMIC_CLOAK) { s32b mimic = find_random_mimic_shape(127, TRUE); o_ptr->pval2 = mimic; } - else if (f5 & TR5_SPELL_CONTAIN) + else if (flags & TR_SPELL_CONTAIN) { o_ptr->pval2 = -1; } @@ -408,7 +391,7 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name) } -bool_ artifact_scroll(void) +bool_ artifact_scroll() { bool_ okay = FALSE; @@ -466,7 +449,7 @@ bool_ artifact_scroll(void) if (!okay) { /* Flush */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("The enchantment failed."); diff --git a/src/randart.hpp b/src/randart.hpp index 31b70f08..6f91f36d 100644 --- a/src/randart.hpp +++ b/src/randart.hpp @@ -3,7 +3,6 @@ #include "h-basic.h" #include "object_type_fwd.hpp" -extern int get_activation_power(void); -extern void build_prob(cptr learn); -extern bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name); -extern bool_ artifact_scroll(void); +void build_prob(cptr learn); +bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name); +bool_ artifact_scroll(); diff --git a/src/randart_gen_type_fwd.hpp b/src/randart_gen_type_fwd.hpp deleted file mode 100644 index eba3e84e..00000000 --- a/src/randart_gen_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct randart_gen_type; diff --git a/src/randart_part_type.hpp b/src/randart_part_type.hpp index c2fa5386..5a4ca329 100644 --- a/src/randart_part_type.hpp +++ b/src/randart_part_type.hpp @@ -1,43 +1,44 @@ #pragma once +#include "ego_flag_set.hpp" #include "h-basic.h" +#include "object_flag_set.hpp" + +#include <vector> /** * Random artifact part descriptor. */ struct randart_part_type { - byte tval[20]; - byte min_sval[20]; - byte max_sval[20]; - - byte level; /* Minimum level */ - byte rarity; /* Object rarity */ - byte mrarity; /* Object rarity */ - - s16b max_to_h; /* Maximum to-hit bonus */ - s16b max_to_d; /* Maximum to-dam bonus */ - s16b max_to_a; /* Maximum to-ac bonus */ - - s32b max_pval; /* Maximum pval */ - - s32b value; /* power value */ - s16b max; /* Number of time it can appear on a single item */ - - u32b flags1; /* Ego-Item Flags, set 1 */ - u32b flags2; /* Ego-Item Flags, set 2 */ - u32b flags3; /* Ego-Item Flags, set 3 */ - u32b flags4; /* Ego-Item Flags, set 4 */ - u32b flags5; /* Ego-Item Flags, set 5 */ - u32b esp; /* ESP flags */ - u32b fego; /* ego flags */ - - u32b aflags1; /* Ego-Item Flags, set 1 */ - u32b aflags2; /* Ego-Item Flags, set 2 */ - u32b aflags3; /* Ego-Item Flags, set 3 */ - u32b aflags4; /* Ego-Item Flags, set 4 */ - u32b aflags5; /* Ego-Item Flags, set 5 */ - u32b aesp; /* ESP flags */ - - s16b power; /* Power granted(if any) */ +public: + struct kind_filter_t { + byte tval; + byte min_sval; + byte max_sval; + }; + + std::vector<kind_filter_t> kind_filter; + + byte level = 0; /* Minimum level */ + byte rarity = 0; /* Object rarity */ + byte mrarity = 0; /* Object rarity */ + + s16b max_to_h = 0; /* Maximum to-hit bonus */ + s16b max_to_d = 0; /* Maximum to-dam bonus */ + s16b max_to_a = 0; /* Maximum to-ac bonus */ + + s32b max_pval = 0; /* Maximum pval */ + + s32b value = 0; /* power value */ + s16b max = 0; /* Number of time it can appear on a single item */ + + object_flag_set flags; /* Ego item flags */ + + ego_flag_set fego; /* Ego flags */ + + object_flag_set aflags; /* Antagonistic ego item flags */ + + s16b power = -1; /* Power granted(if any) */ + }; diff --git a/src/randart_part_type_fwd.hpp b/src/randart_part_type_fwd.hpp deleted file mode 100644 index 979fd72c..00000000 --- a/src/randart_part_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct randart_part_type; diff --git a/src/random_artifact.hpp b/src/random_artifact.hpp index a3fc1c66..618f1102 100644 --- a/src/random_artifact.hpp +++ b/src/random_artifact.hpp @@ -2,13 +2,15 @@ #include "h-basic.h" +#include <string> + /** * Random artifact descriptor. */ struct random_artifact { - char name_full[80]; /* Full name for the artifact */ - char name_short[80]; /* Un-Id'd name */ + std::string name_full; /* Full name for the artifact */ + std::string name_short; /* Un-Id'd name */ byte level; /* Level of the artifact */ byte attr; /* Color that is used on the screen */ u32b cost; /* Object's value */ diff --git a/src/random_quest.hpp b/src/random_quest.hpp index 11ebe797..9e3c6e10 100644 --- a/src/random_quest.hpp +++ b/src/random_quest.hpp @@ -6,5 +6,5 @@ struct random_quest { byte type; /* Type/number of monsters to kill(0 = no quest) */ s16b r_idx; /* Monsters to crush */ - bool_ done; /* Done ? */ + bool done; /* Done? */ }; diff --git a/src/random_spell.hpp b/src/random_spell.hpp index 01b5ba5e..f02b9848 100644 --- a/src/random_spell.hpp +++ b/src/random_spell.hpp @@ -1,21 +1,20 @@ #pragma once #include "h-basic.h" +#include <string> /** * A structure to describe the random spells of the Power Mages */ struct random_spell { - char desc[30]; /* Desc of the spell */ - char name[30]; /* Name of the spell */ - s16b mana; /* Mana cost */ - s16b fail; /* Failure rate */ - u32b proj_flags; /* Project function flags */ - byte GF; /* Type of the projection */ - byte radius; - byte dam_sides; - byte dam_dice; - byte level; /* Level needed */ - bool_ untried; /* Is the spell was tried? */ + s16b mana = 0; /* Mana cost */ + s16b fail = 0; /* Failure rate */ + u32b proj_flags = 0; /* Project function flags */ + byte GF = 0; /* Type of the projection */ + byte radius = 0; + byte dam_sides = 0; + byte dam_dice = 0; + byte level = 0; /* Level needed */ + bool untried = true; /* Is the spell was tried? */ }; diff --git a/src/random_spell_fwd.hpp b/src/random_spell_fwd.hpp new file mode 100644 index 00000000..ee559c31 --- /dev/null +++ b/src/random_spell_fwd.hpp @@ -0,0 +1,3 @@ +#pragma once + +struct random_spell; diff --git a/src/rule_type.hpp b/src/rule_type.hpp index a8b35ffa..b88ce7bf 100644 --- a/src/rule_type.hpp +++ b/src/rule_type.hpp @@ -1,22 +1,17 @@ #pragma once #include "h-basic.h" +#include "monster_race_flag_set.hpp" +#include "monster_spell_flag_set.hpp" /* Define monster generation rules */ struct rule_type { - byte mode; /* Mode of combination of the monster flags */ - byte percent; /* Percent of monsters affected by the rule */ + byte mode = 0; /* Mode of combination of the monster flags */ + byte percent = 0; /* Percent of monsters affected by the rule */ - u32b mflags1; /* The monster flags that are allowed */ - u32b mflags2; - u32b mflags3; - u32b mflags4; - u32b mflags5; - u32b mflags6; - u32b mflags7; - u32b mflags8; - u32b mflags9; + monster_race_flag_set mflags; /* The monster flags that are allowed */ + monster_spell_flag_set mspells; /* Monster spells the are allowed */ - char r_char[5]; /* Monster race allowed */ + char r_char[5] = { 0 }; /* Monster race allowed */ }; diff --git a/src/rune_spell.hpp b/src/rune_spell.hpp deleted file mode 100644 index d04a8dc4..00000000 --- a/src/rune_spell.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "h-basic.h" - -/** - * Runecrafter prefered spells - */ -struct rune_spell -{ - char name[30]; /* name */ - - s16b type; /* Type of the spell(GF) */ - s16b rune2; /* Modifiers */ - s16b mana; /* Mana involved */ -}; diff --git a/src/rune_spell_fwd.hpp b/src/rune_spell_fwd.hpp deleted file mode 100644 index eb540a2a..00000000 --- a/src/rune_spell_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct rune_spell; diff --git a/src/script.cc b/src/script.cc deleted file mode 100644 index 84f7c3e4..00000000 --- a/src/script.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2001 Dark God - * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. - */ - -#include "script.h" - -#include "init2.hpp" -#include "q_library.hpp" -#include "spells4.hpp" -#include "spells5.hpp" -#include "spells6.hpp" - - -void init_lua_init() -{ - /* Initialize schooled spells */ - schools_init(); - school_spells_init(); - init_school_books(); - - /* Post-spell creation initialization */ - initialize_bookable_spells(); - - /* Finish up the corruptions */ - init_corruptions(); -} diff --git a/src/script.h b/src/script.h deleted file mode 100644 index 3d1a0840..00000000 --- a/src/script.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -// C linkage required for these functions since main-* code uses them. -#ifdef __cplusplus -extern "C" { -#endif - -extern void init_lua_init(void); - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/src/seed.cc b/src/seed.cc new file mode 100644 index 00000000..0550c769 --- /dev/null +++ b/src/seed.cc @@ -0,0 +1,53 @@ +#include "seed.hpp" + +#include <random> + +seed_t seed_t::system() +{ + seed_t seed; + // Use system's random device for seeding. + std::random_device random_device; + std::uniform_int_distribution<std::uint8_t> distribution; + // Extract the number of bytes we need. + for (std::size_t i = 0; i < n_bytes; i++) + { + seed.m_data[i] = distribution(random_device); + } + // Done + return seed; +} + +seed_t seed_t::from_bytes(std::uint8_t bytes[n_bytes]) +{ + seed_t seed; + // Copy + for (std::size_t i = 0; i < n_bytes; i++) + { + seed.m_data[i] = bytes[i]; + } + // Done + return seed; +} + +void seed_t::to_bytes(std::uint8_t bytes[n_bytes]) const +{ + // Copy + for (std::size_t i = 0; i < n_bytes; i++) + { + bytes[i] = m_data[i]; + } +} +void seed_t::to_uint32(std::uint32_t seed_seq_data[n_uint32]) const +{ + for (std::size_t i = 0; i < n_uint32; i++) + { + // Position in the byte-oriented data. + std::size_t p = 4 * i; + // Pack m_data[p + 0], ..., m_data[p + 3] into a single uint32_t + seed_seq_data[i] = 0; + seed_seq_data[i] |= (uint32_t(m_data[p + 0]) << (0 * 8)); + seed_seq_data[i] |= (uint32_t(m_data[p + 1]) << (1 * 8)); + seed_seq_data[i] |= (uint32_t(m_data[p + 2]) << (2 * 8)); + seed_seq_data[i] |= (uint32_t(m_data[p + 3]) << (3 * 8)); + } +} diff --git a/src/seed.hpp b/src/seed.hpp new file mode 100644 index 00000000..91ec7eba --- /dev/null +++ b/src/seed.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include <array> +#include <cstdint> + +class seed_t { + +public: + // Number of seed bytes. + static constexpr std::size_t n_bytes = 64; + + // Sanity check; we're relying on converting to uint32_t elsewhere, + // so let's just keep it as easy as possible. + static_assert(n_bytes % 4 == 0, "n_bytes must be multiple of 4"); + + // Number of uint32_t's required to store the seed. + static constexpr std::size_t n_uint32 = n_bytes / 4; + +private: + std::array<std::uint8_t, n_bytes> m_data; + + // Default constructor is private. Use the static + // factory functions instead. + seed_t() + { + // Factory functions do explicit initialization. + }; + +public: + + /** + * Create a seed from system entropy. + */ + static seed_t system(); + + /** + * Create a seed from the given bytes. + */ + static seed_t from_bytes(std::uint8_t bytes[n_bytes]); + + /** + * Convert seed to bytes. + */ + void to_bytes(std::uint8_t bytes[n_bytes]) const; + + /** + * Convert seed to uint32_t's suitable for seed_seq. + */ + void to_uint32(std::uint32_t seed_seq_data[n_uint32]) const; + +}; diff --git a/src/seed_fwd.hpp b/src/seed_fwd.hpp new file mode 100644 index 00000000..291a6063 --- /dev/null +++ b/src/seed_fwd.hpp @@ -0,0 +1,3 @@ +#pragma once + +class seed_t; diff --git a/src/set_component.hpp b/src/set_component.hpp new file mode 100644 index 00000000..18dc4d57 --- /dev/null +++ b/src/set_component.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "h-basic.h" +#include "object_flag_set.hpp" + +#include <array> +#include <cstdint> + +constexpr std::size_t SET_MAX_SIZE = 6; + +struct set_component { + bool_ present = FALSE; /* Is it being worn? */ + s16b a_idx = 0; /* What artifact? */ + std::array<s16b , SET_MAX_SIZE> pval; /* Pval for each combination */ + std::array<object_flag_set, SET_MAX_SIZE> flags; /* Flags */ +}; diff --git a/src/set_type.hpp b/src/set_type.hpp index 827c23ac..bf13c932 100644 --- a/src/set_type.hpp +++ b/src/set_type.hpp @@ -1,28 +1,20 @@ #pragma once -#include "h-basic.h" +#include <array> +#include <string> + +#include "set_component.hpp" /** * Item set descriptor and runtime information. */ struct set_type { - const char *name; /* Name */ - char *desc; /* Desc */ + std::string name; /* Name */ + std::string desc; /* Desc */ - byte num; /* Number of artifacts used */ - byte num_use; /* Number actually wore */ + byte num = 0; /* Number of artifacts used */ + byte num_use = 0; /* Number actually worn */ - struct /* the various items */ - { - bool_ present; /* Is it actually wore ? */ - s16b a_idx; /* What artifact ? */ - s16b pval[6]; /* Pval for each combination */ - u32b flags1[6]; /* Flags */ - u32b flags2[6]; /* Flags */ - u32b flags3[6]; /* Flags */ - u32b flags4[6]; /* Flags */ - u32b flags5[6]; /* Flags */ - u32b esp[6]; /* Flags */ - } arts[6]; + std::array<set_component, SET_MAX_SIZE> arts; }; diff --git a/src/set_type_fwd.hpp b/src/set_type_fwd.hpp deleted file mode 100644 index 3b311808..00000000 --- a/src/set_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct set_type; diff --git a/src/skill_descriptor.hpp b/src/skill_descriptor.hpp new file mode 100644 index 00000000..8d9de004 --- /dev/null +++ b/src/skill_descriptor.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "h-basic.h" +#include "skill_flag_set.hpp" +#include "skills_defs.hpp" + +#include <vector> +#include <tuple> + +/** + * Skill descriptor. + */ +struct skill_descriptor { + + std::string name; /* Name */ + std::string desc; /* Description */ + + std::string action_desc; /* Action Description */ + s16b action_mkey = 0; /* Action do to */ + + std::vector<std::size_t> excludes; /* List of skills that this skill excludes; + any skill points assigned completely nullify + the listed skills */ + + std::vector<std::tuple<std::size_t, int>> increases; + /* List of skills the this skill increases, + along with the modifier that gets applied. + The first tuple element is the skill index. */ + + s16b father = 0; /* Father in the skill tree */ + s16b order = 0; /* Order in the tree */ + + byte random_gain_chance = 100; /* Chance to gain from Lost Sword quest; if applicable */ + + skill_flag_set flags; /* Skill flags */ + +}; diff --git a/src/skill_flag.hpp b/src/skill_flag.hpp new file mode 100644 index 00000000..15c6de9c --- /dev/null +++ b/src/skill_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "skill_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define SKF(tier, index, name) \ + DECLARE_FLAG(skill_flag_set, BOOST_PP_CAT(SKF_,name), tier, index) +#include "skill_flag_list.hpp" +#undef SKF diff --git a/src/skill_flag_list.hpp b/src/skill_flag_list.hpp new file mode 100644 index 00000000..49cdc045 --- /dev/null +++ b/src/skill_flag_list.hpp @@ -0,0 +1,9 @@ +/** + * X-macro list of all the skill flags + */ + +/* SKF(<tier>, <index>, <name>) */ + +SKF(1, 0, HIDDEN ) /* Starts hidden */ +SKF(1, 1, AUTO_HIDE ) /* Tries to rehide at calc_bonus */ +SKF(1, 2, RANDOM_GAIN) /* Can be gained through Lost Sword quest */ diff --git a/src/skill_flag_set.hpp b/src/skill_flag_set.hpp new file mode 100644 index 00000000..a2768b70 --- /dev/null +++ b/src/skill_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t SKF_MAX_TIERS = 1; + +typedef flag_set<SKF_MAX_TIERS> skill_flag_set; diff --git a/src/skill_modifier.hpp b/src/skill_modifier.hpp new file mode 100644 index 00000000..e4bf4ce9 --- /dev/null +++ b/src/skill_modifier.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "h-basic.h" + +struct skill_modifier { + + char basem = '\0'; + u32b base = 0; + char modm = '\0'; + s16b mod = 0; + +}; diff --git a/src/skill_modifiers.hpp b/src/skill_modifiers.hpp new file mode 100644 index 00000000..5e90b000 --- /dev/null +++ b/src/skill_modifiers.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "h-basic.h" +#include "skills_defs.hpp" +#include "skill_modifier.hpp" + +#include <vector> + +struct skill_modifiers +{ + /** + * Skill modifiers indexed by skill. Note that this vector + * may be shorter than the s_descriptors vector. + */ + std::vector<skill_modifier> modifiers; + +}; diff --git a/src/skill_modifiers_fwd.hpp b/src/skill_modifiers_fwd.hpp new file mode 100644 index 00000000..18f692bd --- /dev/null +++ b/src/skill_modifiers_fwd.hpp @@ -0,0 +1,3 @@ +#pragma once + +struct skill_modifiers; diff --git a/src/skill_type.hpp b/src/skill_type.hpp index c6de1dc1..c26d8649 100644 --- a/src/skill_type.hpp +++ b/src/skill_type.hpp @@ -1,37 +1,32 @@ #pragma once #include "h-basic.h" +#include "skill_flag_set.hpp" #include "skills_defs.hpp" +#include "skill_descriptor.hpp" /** - * Skill descriptors and runtime data. + * Skill runtime data. */ struct skill_type { - const char *name; /* Name */ - char *desc; /* Description */ - - const char *action_desc; /* Action Description */ - - s16b action_mkey; /* Action do to */ - - s32b i_value; /* Actual value */ - s32b i_mod; /* Modifier(1 skill point = modifier skill) */ - - s32b value; /* Actual value */ - s32b mod; /* Modifier(1 skill point = modifier skill) */ - s16b rate; /* Modifier decreasing rate */ - - u32b uses; /* Number of times used */ - - s16b action[MAX_SKILLS]; /* List of actions against other skills */ - - s16b father; /* Father in the skill tree */ - bool_ dev; /* Is the branch developped ? */ - s16b order; /* Order in the tree */ - bool_ hidden; /* Innactive */ - - byte random_gain_chance; /* random gain chance, still needs the flag */ - - u32b flags1; /* Skill flags */ + /** + * Current value. + */ + s32b value = 0; + + /** + * Current modifier, i.e. how much value 1 skill point gives. + */ + s32b mod = 0; + + /** + * Is the branch developed? + */ + bool dev = false; + + /** + * Is the skill hidden? + */ + bool hidden = false; }; diff --git a/src/skill_type_fwd.hpp b/src/skill_type_fwd.hpp deleted file mode 100644 index 0a06dadb..00000000 --- a/src/skill_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct skill_type; diff --git a/src/skills.cc b/src/skills.cc index 3a14a6ce..af5e46c7 100644 --- a/src/skills.cc +++ b/src/skills.cc @@ -14,6 +14,7 @@ #include "cmd3.hpp" #include "cmd5.hpp" #include "cmd7.hpp" +#include "game.hpp" #include "gods.hpp" #include "help.hpp" #include "hooks.hpp" @@ -27,11 +28,11 @@ #include "player_race_mod.hpp" #include "player_spec.hpp" #include "player_type.hpp" +#include "skill_flag.hpp" #include "skill_type.hpp" #include "spells1.hpp" #include "spells4.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -43,6 +44,7 @@ #include <boost/algorithm/string/predicate.hpp> #include <cassert> #include <cmath> +#include <fmt/format.h> #include <memory> #include <vector> #include <tuple> @@ -55,6 +57,8 @@ using boost::algorithm::iequals; */ static void increase_skill(int i, s16b *invest) { + auto &s_info = game->s_info; + s32b max_skill_overage; /* No skill points to be allocated */ @@ -70,15 +74,11 @@ static void increase_skill(int i, s16b *invest) max_skill_overage = modules[game_module_idx].skills.max_skill_overage; if (((s_info[i].value + s_info[i].mod) / SKILL_STEP) >= (p_ptr->lev + max_skill_overage + 1)) { - int hgt, wid; - char buf[256]; - - sprintf(buf, - "Cannot raise a skill value above " FMTs32b " + player level.", - max_skill_overage); - - Term_get_size(&wid, &hgt); - msg_box(buf, hgt / 2, wid / 2); + msg_box_auto( + fmt::format( + "Cannot raise a skill value above {} + player level.", + max_skill_overage + )); return; } @@ -97,6 +97,8 @@ static void increase_skill(int i, s16b *invest) */ static void decrease_skill(int i, s16b *invest) { + auto &s_info = game->s_info; + /* Cannot decrease more */ if (!invest[i]) return; @@ -119,31 +121,33 @@ static void decrease_skill(int i, s16b *invest) * Given the name of a skill, returns skill index or -1 if no * such skill is found */ -s16b find_skill(cptr name) +s16b find_skill(cptr needle) { - u16b i; + auto const &s_descriptors = game->edit_data.s_descriptors; /* Scan skill list */ - for (i = 1; i < max_s_idx; i++) + for (std::size_t i = 1; i < s_descriptors.size(); i++) { - if (s_info[i].name && streq(s_info[i].name, name)) + auto const &name = s_descriptors[i].name; + if (!name.empty() && (name == needle)) { - return (i); + return i; } } /* No match found */ - return ( -1); + return -1; } -s16b find_skill_i(cptr name) + +s16b find_skill_i(cptr needle) { - u16b i; + auto const &s_descriptors = game->edit_data.s_descriptors; /* Scan skill list */ - for (i = 1; i < max_s_idx; i++) + for (std::size_t i = 1; i < s_descriptors.size(); i++) { - /* The name matches */ - if (s_info[i].name && iequals(s_info[i].name, name)) + auto const &name = s_descriptors[i].name; + if (!name.empty() && iequals(name, needle)) { return (i); } @@ -159,6 +163,8 @@ s16b find_skill_i(cptr name) */ s16b get_skill(int skill) { + auto const &s_info = game->s_info; + return (s_info[skill].value / SKILL_STEP); } @@ -169,7 +175,7 @@ s16b get_skill(int skill) */ s16b get_skill_scale(int skill, u32b scale) { - s32b temp; + auto const &s_info = game->s_info; /* * SKILL_STEP shouldn't matter here because the second parameter is @@ -181,32 +187,38 @@ s16b get_skill_scale(int skill, u32b scale) * formula given above, I verified this works the same by using a tiny * scheme program... -- pelpel */ - temp = scale * s_info[skill].value; + s32b temp = scale * s_info[skill].value; return (temp / SKILL_MAX); } -static int get_idx(int i) +static std::size_t get_idx(int i) { - for (int j = 1; j < max_s_idx; j++) + auto const &s_descriptors = game->edit_data.s_descriptors; + + for (std::size_t j = 1; j < s_descriptors.size(); j++) { - if (s_info[j].order == i) - return (j); + if (s_descriptors[j].order == i) + { + return j; + } } - return (0); + + return 0; } static bool_ is_known(int s_idx) { - int i; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; if (wizard) return TRUE; if (s_info[s_idx].value || s_info[s_idx].mod) return TRUE; - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { /* It is our child, if we don't know it we continue to search, if we know it it is enough*/ - if (s_info[i].father == s_idx) + if (s_descriptors[i].father == s_idx) { if (is_known(i)) return TRUE; @@ -217,38 +229,59 @@ static bool_ is_known(int s_idx) return FALSE; } -static void init_table_aux(int table[MAX_SKILLS][2], int *idx, int father, int lev, bool_ full) +namespace { // anonymous + +struct skill_entry { + std::size_t skill_idx; + int indent_level; +}; + +} + +static void init_table_aux(std::vector<skill_entry> *table, int father, int lev, bool_ full) { - for (int j = 1; j < max_s_idx; j++) + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; + + for (std::size_t j = 1; j < s_descriptors.size(); j++) { - int i = get_idx(j); - if (s_info[i].father != father) continue; + std::size_t i = get_idx(j); + + if (s_descriptors[i].father != father) continue; if (s_info[i].hidden) continue; if (!is_known(i)) continue; - table[*idx][0] = i; - table[*idx][1] = lev; - (*idx)++; - if (s_info[i].dev || full) init_table_aux(table, idx, i, lev + 1, full); + skill_entry entry; + entry.skill_idx = i; + entry.indent_level = lev; + table->emplace_back(entry); + + if (s_info[i].dev || full) + { + init_table_aux(table, i, lev + 1, full); + } } } -static void init_table(int table[MAX_SKILLS][2], int *max, bool_ full) +static void init_table(std::vector<skill_entry> *table, bool_ full) { - *max = 0; - init_table_aux(table, max, -1, 0, full); + table->clear(); + init_table_aux(table, -1, 0, full); } -static bool_ has_child(int sel) +static bool has_child(int sel) { - int i; + auto const &s_descriptors = game->edit_data.s_descriptors; - for (i = 1; i < max_s_idx; i++) + for (std::size_t i = 1; i < s_descriptors.size(); i++) { - if ((s_info[i].father == sel) && (is_known(i))) - return (TRUE); + if ((s_descriptors[i].father == sel) && is_known(i)) + { + return true; + } } - return (FALSE); + + return false; } @@ -257,42 +290,51 @@ static bool_ has_child(int sel) */ void dump_skills(FILE *fff) { - int i, j, max = 0; - int table[MAX_SKILLS][2]; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; + char buf[80]; - init_table(table, &max, TRUE); + std::vector<skill_entry> table; + table.reserve(s_descriptors.size()); + init_table(&table, TRUE); fprintf(fff, "\nSkills (points left: %d)", p_ptr->skill_points); - for (j = 0; j < max; j++) + for (auto const &entry: table) { - int z; - - i = table[j][0]; + std::size_t i = entry.skill_idx; + auto const &skill = s_info[i]; + auto const &skill_name = s_descriptors[i].name; - if ((s_info[i].value == 0) && (i != SKILL_MISC)) + if ((skill.value == 0) && (i != SKILL_MISC)) { - if (s_info[i].mod == 0) continue; + if (skill.mod == 0) + { + continue; + } } sprintf(buf, "\n"); - for (z = 0; z < table[j][1]; z++) strcat(buf, " "); + for (int z = 0; z < entry.indent_level; z++) + { + strcat(buf, " "); + } if (!has_child(i)) { - strcat(buf, format(" . %s", s_info[i].name)); + strcat(buf, format(" . %s", skill_name.c_str())); } else { - strcat(buf, format(" - %s", s_info[i].name)); + strcat(buf, format(" - %s", skill_name.c_str())); } fprintf(fff, "%-49s%s%06.3f [%05.3f]", - buf, s_info[i].value < 0 ? "-" : " ", - static_cast<double>(ABS(s_info[i].value)) / SKILL_STEP, - static_cast<double>(s_info[i].mod) / 1000); + buf, skill.value < 0 ? "-" : " ", + static_cast<double>(ABS(skill.value)) / SKILL_STEP, + static_cast<double>(skill.mod) / 1000); } fprintf(fff, "\n"); @@ -302,9 +344,12 @@ void dump_skills(FILE *fff) /* * Draw the skill tree */ -void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start) +static void print_skills(std::vector<skill_entry> const &table, int sel, int start) { - int i, j; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; + + int j; int wid, hgt; cptr keys; @@ -316,52 +361,73 @@ void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start) display_message(0, 1, strlen(keys), TERM_WHITE, keys); c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED, format("Skill points left: %d", p_ptr->skill_points), 2, 0); - print_desc_aux(s_info[table[sel][0]].desc, 3, 0); + print_desc_aux(s_descriptors[table[sel].skill_idx].desc.c_str(), 3, 0); for (j = start; j < start + (hgt - 7); j++) { byte color = TERM_WHITE; char deb = ' ', end = ' '; - if (j >= max) break; + if (j >= static_cast<int>(table.size())) + { + break; + } + + std::size_t i = table[j].skill_idx; + auto const &name = s_descriptors[i].name; + auto const &skill = s_info[i]; - i = table[j][0]; + if ((skill.value == 0) && (i != SKILL_MISC)) + { + if (skill.mod == 0) + { + color = TERM_L_DARK; + } + else + { + color = TERM_ORANGE; + } + } + else if (skill.value == SKILL_MAX) + { + color = TERM_L_BLUE; + } - if ((s_info[i].value == 0) && (i != SKILL_MISC)) + if (skill.hidden) { - if (s_info[i].mod == 0) color = TERM_L_DARK; - else color = TERM_ORANGE; + color = TERM_L_RED; } - else if (s_info[i].value == SKILL_MAX) color = TERM_L_BLUE; - if (s_info[i].hidden) color = TERM_L_RED; + if (j == sel) { color = TERM_L_GREEN; deb = '['; end = ']'; } + if (!has_child(i)) { - c_prt(color, format("%c.%c%s", deb, end, s_info[i].name), - j + 7 - start, table[j][1] * 4); + c_prt(color, format("%c.%c%s", deb, end, name.c_str()), + j + 7 - start, table[j].indent_level * 4); } - else if (s_info[i].dev) + else if (skill.dev) { - c_prt(color, format("%c-%c%s", deb, end, s_info[i].name), - j + 7 - start, table[j][1] * 4); + c_prt(color, format("%c-%c%s", deb, end, name.c_str()), + j + 7 - start, table[j].indent_level * 4); } else { - c_prt(color, format("%c+%c%s", deb, end, s_info[i].name), - j + 7 - start, table[j][1] * 4); + c_prt(color, format("%c+%c%s", deb, end, name.c_str()), + j + 7 - start, table[j].indent_level * 4); } + c_prt(color, format("%s%02ld.%03ld [%01d.%03d]", - s_info[i].value < 0 ? "-" : " ", - ABS(s_info[i].value) / SKILL_STEP, - ABS(s_info[i].value) % SKILL_STEP, - ABS(s_info[i].mod) / 1000, - ABS(s_info[i].mod) % 1000), + skill.value < 0 ? "-" : " ", + ABS(skill.value) / SKILL_STEP, + ABS(skill.value) % SKILL_STEP, + ABS(skill.mod) / 1000, + ABS(skill.mod) % 1000), j + 7 - start, 60); } } @@ -371,6 +437,8 @@ void print_skills(int table[MAX_SKILLS][2], int max, int sel, int start) */ void recalc_skills(bool_ init) { + auto const &s_info = game->s_info; + static int thaum_level = 0; /* TODO: This should be a hook in ToME's lua */ @@ -380,16 +448,19 @@ void recalc_skills(bool_ init) } else { + auto const &random_spells = p_ptr->random_spells; + int thaum_gain = 0; - /* Gain thaum spells */ - while (thaum_level < get_skill_scale(SKILL_THAUMATURGY, 100)) + /* Gain thaum spells while there's more to be gained */ + while ((thaum_level < get_skill_scale(SKILL_THAUMATURGY, 100)) && + (random_spells.size() < MAX_SPELLS)) { - if (spell_num == MAX_SPELLS) break; thaum_level++; generate_spell((thaum_level + 1) / 2); thaum_gain++; } + if (thaum_gain) { if (thaum_gain == 1) @@ -420,49 +491,64 @@ void recalc_skills(bool_ init) /* * Recalc the skill value */ -static void recalc_skills_theory(s16b *invest, s32b *base_val, s32b *base_mod, s32b *bonus) +static void recalc_skills_theory( + std::vector<s16b> &invest, + std::vector<s32b> const &base_val, + std::vector<s32b> const &base_mod, + std::vector<s32b> const &bonus) { - int i, j; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; /* First we assign the normal points */ - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { /* Calc the base */ s_info[i].value = base_val[i] + (base_mod[i] * invest[i]) + bonus[i]; /* It cannot exceed SKILL_MAX */ - if (s_info[i].value > SKILL_MAX) s_info[i].value = SKILL_MAX; + if (s_info[i].value > SKILL_MAX) + { + s_info[i].value = SKILL_MAX; + } } /* Then we modify related skills */ - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - for (j = 1; j < max_s_idx; j++) - { - /* Ignore self */ - if (j == i) continue; + auto const &s_descriptor = s_descriptors[i]; - /* Exclusive skills */ - if ((s_info[i].action[j] == SKILL_EXCLUSIVE) && invest[i]) + // Process all exlusions + if (invest[i]) + { + for (auto exclude_si: s_descriptor.excludes) { - /* Turn it off */ - p_ptr->skill_points += invest[j]; - invest[j] = 0; - s_info[j].value = 0; + // Give back skill points invested during this "session" + p_ptr->skill_points += invest[exclude_si]; + invest[exclude_si] = 0; + + // Turn it off + s_info[exclude_si].value = 0; } + } - /* Non-exclusive skills */ - else if (s_info[i].action[j]) - { - /* Increase / decrease with a % */ - s32b val = s_info[j].value + (invest[i] * s_info[j].mod * s_info[i].action[j] / 100); + // Add any bonuses + for (auto const &increase: s_descriptor.increases) + { + auto increase_si = std::get<0>(increase); + auto increase_pct = std::get<1>(increase); - /* It cannot exceed SKILL_MAX */ - if (val > SKILL_MAX) val = SKILL_MAX; + /* Increase/decrease by percentage */ + s32b val = s_info[increase_si].value + (invest[i] * s_info[increase_si].mod * increase_pct / 100); - /* Save the modified value */ - s_info[j].value = val; + /* It cannot exceed SKILL_MAX */ + if (val > SKILL_MAX) + { + val = SKILL_MAX; } + + /* Save the modified value */ + s_info[increase_si].value = val; } } } @@ -472,10 +558,11 @@ static void recalc_skills_theory(s16b *invest, s32b *base_val, s32b *base_mod, s */ void do_cmd_skill() { - int sel = 0, start = 0, max; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; + + int sel = 0, start = 0; char c; - int table[MAX_SKILLS][2]; - int i; int wid, hgt; s16b skill_points_save; @@ -484,41 +571,38 @@ void do_cmd_skill() /* Save the screen */ screen_save(); - /* Allocate arrays to save skill values */ - std::unique_ptr<s32b[]> skill_values_save(new s32b[MAX_SKILLS]); - std::unique_ptr<s32b[]> skill_mods_save(new s32b[MAX_SKILLS]); - std::unique_ptr<s16b[]> skill_rates_save(new s16b[MAX_SKILLS]); - std::unique_ptr<s16b[]> skill_invest(new s16b[MAX_SKILLS]); - std::unique_ptr<s32b[]> skill_bonus(new s32b[MAX_SKILLS]); + /* Allocate arrays to save skill values and track assigned points */ + std::vector<s32b> skill_values_save; skill_values_save.resize(s_descriptors.size(), 0); + std::vector<s32b> skill_mods_save; skill_mods_save.resize(s_descriptors.size(), 0); + std::vector<s16b> skill_invest; skill_invest.resize(s_descriptors.size(), 0); + std::vector<s32b> skill_bonus; skill_bonus.resize(s_descriptors.size(), 0); /* Save skill points */ skill_points_save = p_ptr->skill_points; /* Save skill values */ - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - skill_type *s_ptr = &s_info[i]; - + auto s_ptr = &s_info[i]; skill_values_save[i] = s_ptr->value; skill_mods_save[i] = s_ptr->mod; - skill_rates_save[i] = s_ptr->rate; - skill_invest[i] = 0; - skill_bonus[i] = 0; } /* Clear the screen */ Term_clear(); /* Initialise the skill list */ - init_table(table, &max, FALSE); + std::vector<skill_entry> table; + table.reserve(s_descriptors.size()); + init_table(&table, FALSE); while (TRUE) { Term_get_size(&wid, &hgt); /* Display list of skills */ - recalc_skills_theory(skill_invest.get(), skill_values_save.get(), skill_mods_save.get(), skill_bonus.get()); - print_skills(table, max, sel, start); + recalc_skills_theory(skill_invest, skill_values_save, skill_mods_save, skill_bonus); + print_skills(table, sel, start); /* Wait for user input */ c = inkey(); @@ -529,16 +613,21 @@ void do_cmd_skill() /* Expand / collapse list of skills */ else if (c == '\r') { - if (s_info[table[sel][0]].dev) s_info[table[sel][0]].dev = FALSE; - else s_info[table[sel][0]].dev = TRUE; - init_table(table, &max, FALSE); + // Toggle the selected skill + s_info[table[sel].skill_idx].dev = !s_info[table[sel].skill_idx].dev; + // Re-populate table + init_table(&table, FALSE); } /* Next page */ else if (c == 'n') { sel += (hgt - 7); - if (sel >= max) sel = max - 1; + + if (sel >= static_cast<int>(table.size())) + { + sel = table.size() - 1; + } } /* Previous page */ @@ -563,31 +652,31 @@ void do_cmd_skill() if (dir == 8) sel--; /* Miscellaneous skills cannot be increased/decreased as a group */ - if ((sel >= 0) && (sel < max) && table[sel][0] == SKILL_MISC) continue; + if ((sel >= 0) && (sel < static_cast<int>(table.size())) && table[sel].skill_idx == SKILL_MISC) continue; /* Increase the current skill */ - if (dir == 6) increase_skill(table[sel][0], skill_invest.get()); + if (dir == 6) increase_skill(table[sel].skill_idx, skill_invest.data()); /* Decrease the current skill */ - if (dir == 4) decrease_skill(table[sel][0], skill_invest.get()); + if (dir == 4) decrease_skill(table[sel].skill_idx, skill_invest.data()); /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ /* Increase the skill */ - if (wizard && (c == '+')) skill_bonus[table[sel][0]] += SKILL_STEP; + if (wizard && (c == '+')) skill_bonus[table[sel].skill_idx] += SKILL_STEP; /* Decrease the skill */ - if (wizard && (c == '-')) skill_bonus[table[sel][0]] -= SKILL_STEP; + if (wizard && (c == '-')) skill_bonus[table[sel].skill_idx] -= SKILL_STEP; /* Contextual help */ if (c == '?') { - help_skill(s_info[table[sel][0]].name); + help_skill(s_descriptors[table[sel].skill_idx].name); } /* Handle boundaries and scrolling */ - if (sel < 0) sel = max - 1; - if (sel >= max) sel = 0; + if (sel < 0) sel = table.size() - 1; + if (sel >= static_cast<int>(table.size())) sel = 0; if (sel < start) start = sel; if (sel >= start + (hgt - 7)) start = sel - (hgt - 7) + 1; } @@ -601,7 +690,7 @@ void do_cmd_skill() flush(); /* Ask we can commit the change */ - if (msg_box("Save and use these skill values? (y/n)", hgt / 2, wid / 2) != 'y') + if (msg_box_auto("Save and use these skill values? (y/n)") != 'y') { /* User declines -- restore the skill values before exiting */ @@ -609,13 +698,11 @@ void do_cmd_skill() p_ptr->skill_points = skill_points_save; /* Restore skill values */ - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - skill_type *s_ptr = &s_info[i]; - + auto s_ptr = &s_info[i]; s_ptr->value = skill_values_save[i]; s_ptr->mod = skill_mods_save[i]; - s_ptr->rate = skill_rates_save[i]; } } } @@ -665,9 +752,11 @@ cptr get_melee_name() s16b get_melee_skills() { - int i, j = 0; + auto const &s_info = game->s_info; - for (i = 0; i < MAX_MELEE; i++) + int j = 0; + + for (std::size_t i = 0; i < MAX_MELEE; i++) { if ((s_info[melee_skills[i]].value > 0) && (!s_info[melee_skills[i]].hidden)) { @@ -778,7 +867,7 @@ void select_default_melee() /* * Print a batch of skills. */ -static void print_skill_batch(const std::vector<std::tuple<cptr, int>> &p, int start) +static void print_skill_batch(const std::vector<std::tuple<std::string, int>> &p, int start) { char buff[80]; int j = 0; @@ -794,7 +883,7 @@ static void print_skill_batch(const std::vector<std::tuple<cptr, int>> &p, int s sprintf(buff, " %c - %d) %-30s", I2A(j), std::get<1>(p[i]), - std::get<0>(p[i])); + std::get<0>(p[i]).c_str()); prt(buff, 2 + j, 20); j++; @@ -805,11 +894,15 @@ static void print_skill_batch(const std::vector<std::tuple<cptr, int>> &p, int s static int do_cmd_activate_skill_aux() { + auto const &ab_info = game->edit_data.ab_info; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; + char which; int start = 0; int ret; - std::vector<std::tuple<cptr,int>> p; + std::vector<std::tuple<std::string,int>> p; /* More than 1 melee skill ? */ if (get_melee_skills() > 1) @@ -817,16 +910,16 @@ static int do_cmd_activate_skill_aux() p.push_back(std::make_tuple("Change melee mode", 0)); } - for (size_t i = 1; i < max_s_idx; i++) + for (size_t i = 1; i < s_descriptors.size(); i++) { - if (s_info[i].action_mkey && s_info[i].value && ((!s_info[i].hidden) || (i == SKILL_LEARN))) + if (s_descriptors[i].action_mkey && s_info[i].value && ((!s_info[i].hidden) || (i == SKILL_LEARN))) { bool_ next = FALSE; /* Already got it ? */ for (size_t j = 0; j < p.size(); j++) { - if (s_info[i].action_mkey == std::get<1>(p[j])) + if (s_descriptors[i].action_mkey == std::get<1>(p[j])) { next = TRUE; break; @@ -834,14 +927,14 @@ static int do_cmd_activate_skill_aux() } if (next) continue; - p.push_back(std::make_tuple(s_info[i].action_desc, - s_info[i].action_mkey)); + p.push_back(std::make_tuple(s_descriptors[i].action_desc, + s_descriptors[i].action_mkey)); } } - for (size_t i = 0; i < max_ab_idx; i++) + for (size_t i = 0; i < ab_info.size(); i++) { - if (ab_info[i].action_mkey && ab_info[i].acquired) + if (ab_info[i].action_mkey && p_ptr->has_ability(i)) { bool_ next = FALSE; @@ -912,8 +1005,10 @@ static int do_cmd_activate_skill_aux() size_t i = 0; for (; i < p.size(); i++) { - if (!strcmp(buf, std::get<0>(p[i]))) + if (std::get<0>(p[i]) == buf) + { break; + } } if (i < p.size()) @@ -949,6 +1044,10 @@ static int do_cmd_activate_skill_aux() /* Ask & execute a skill */ void do_cmd_activate_skill() { + auto const &ab_info = game->edit_data.ab_info; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &s_info = game->s_info; + int x_idx; bool_ push = TRUE; @@ -957,26 +1056,34 @@ void do_cmd_activate_skill() { push = FALSE; } - else if (!command_arg) x_idx = do_cmd_activate_skill_aux(); + else if (!command_arg) + { + x_idx = do_cmd_activate_skill_aux(); + } else { - int i, j; - x_idx = command_arg; /* Check validity */ - for (i = 1; i < max_s_idx; i++) + std::size_t i; + for (i = 1; i < s_descriptors.size(); i++) { - if (s_info[i].value && (s_info[i].action_mkey == x_idx)) + if (s_info[i].value && (s_descriptors[i].action_mkey == x_idx)) + { break; + } } - for (j = 0; j < max_ab_idx; j++) + + std::size_t j; + for (j = 0; j < ab_info.size(); j++) { - if (ab_info[j].acquired && (ab_info[j].action_mkey == x_idx)) + if (p_ptr->has_ability(j) && (ab_info[j].action_mkey == x_idx)) + { break; + } } - if ((j == max_ab_idx) && (i == max_s_idx)) + if ((j == ab_info.size()) && (i == s_descriptors.size())) { msg_print("Uh?"); return; @@ -1017,9 +1124,6 @@ void do_cmd_activate_skill() case MKEY_POWER_MAGE: do_cmd_powermage(); break; - case MKEY_RUNE: - do_cmd_runecrafter(); - break; case MKEY_FORGING: do_cmd_archer(); break; @@ -1035,9 +1139,6 @@ void do_cmd_activate_skill() case MKEY_SYMBIOTIC: do_cmd_symbiotic(); break; - case MKEY_TRAP: - do_cmd_set_trap(); - break; case MKEY_STEAL: do_cmd_steal(); break; @@ -1114,7 +1215,7 @@ void do_cmd_activate_skill() int dir, dy, dx, targetx, targety, max_blows, flags; o_ptr = get_object(INVEN_WIELD); - if (o_ptr->tval == TV_POLEARM) + if (o_ptr->tval != TV_POLEARM) { msg_print("You will need a long polearm for this!"); return; @@ -1179,76 +1280,47 @@ bool_ forbid_non_blessed() /* - * Gets the base value of a skill, given a race/class/... + * Augment skill value/modifier with the given skill_modifiers */ -void compute_skills(s32b *v, s32b *m, int i) +static void augment_skills(s32b *v, s32b *m, std::vector<skill_modifier> const &modifiers, std::size_t i) { - s32b value, mod; - - /***** general skills *****/ - - /* If the skill correspond to the magic school lets pump them a bit */ - value = gen_skill_base[i]; - mod = gen_skill_mod[i]; - - *v = modify_aux(*v, - value, gen_skill_basem[i]); - *m = modify_aux(*m, - mod, gen_skill_modm[i]); - - /***** race skills *****/ - - value = rp_ptr->skill_base[i]; - mod = rp_ptr->skill_mod[i]; - - *v = modify_aux(*v, - value, rp_ptr->skill_basem[i]); - *m = modify_aux(*m, - mod, rp_ptr->skill_modm[i]); - - /***** race mod skills *****/ - - value = rmp_ptr->skill_base[i]; - mod = rmp_ptr->skill_mod[i]; - - *v = modify_aux(*v, - value, rmp_ptr->skill_basem[i]); - *m = modify_aux(*m, - mod, rmp_ptr->skill_modm[i]); - - /***** class skills *****/ - - value = cp_ptr->skill_base[i]; - mod = cp_ptr->skill_mod[i]; - - *v = modify_aux(*v, - value, cp_ptr->skill_basem[i]); - *m = modify_aux(*m, - mod, cp_ptr->skill_modm[i]); + if (i < modifiers.size()) // Ignore if the skill has no modifiers. + { + auto const &s = modifiers[i]; + *v = modify_aux(*v, s.base, s.basem); + *m = modify_aux(*m, s.mod, s.modm); + } +} - /***** class spec skills *****/ - value = spp_ptr->skill_base[i]; - mod = spp_ptr->skill_mod[i]; +/* + * Gets the base value of a skill, given a race/class/... + */ +void compute_skills(s32b *v, s32b *m, std::size_t i) +{ + auto const &gen_skill = game->edit_data.gen_skill; - *v = modify_aux(*v, - value, spp_ptr->skill_basem[i]); - *m = modify_aux(*m, - mod, spp_ptr->skill_modm[i]); + augment_skills(v, m, gen_skill.modifiers, i); + augment_skills(v, m, rp_ptr->skill_modifiers.modifiers, i); + augment_skills(v, m, rmp_ptr->skill_modifiers.modifiers, i); + augment_skills(v, m, cp_ptr->skill_modifiers.modifiers, i); + augment_skills(v, m, spp_ptr->skill_modifiers.modifiers, i); } /* * Initialize a skill with given values */ -void init_skill(s32b value, s32b mod, int i) +void init_skill(s32b value, s32b mod, std::size_t i) { + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; + s_info[i].value = value; s_info[i].mod = mod; - - if (s_info[i].flags1 & SKF1_HIDDEN) - s_info[i].hidden = TRUE; - else - s_info[i].hidden = FALSE; + s_info[i].hidden = (s_descriptors[i].flags & SKF_HIDDEN) + ? true + : false + ; } /* @@ -1310,39 +1382,42 @@ static std::vector<size_t> wrs(const std::vector<s32b> &unscaled_weights) void do_get_new_skill() { - std::vector<std::string> items; - int skl[LOST_SWORD_NSKILLS]; - s32b val[LOST_SWORD_NSKILLS], mod[LOST_SWORD_NSKILLS]; - int available_skills[MAX_SKILLS]; - int max_a = 0, res, i; + auto const &s_descriptors = game->edit_data.s_descriptors; + auto &s_info = game->s_info; /* Check if some skills didn't influence other stuff */ recalc_skills(TRUE); /* Grab the ones we can gain */ - max_a = 0; - for (i = 0; i < max_s_idx; i++) + std::vector<size_t> available_skills; + available_skills.reserve(s_descriptors.size()); + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - if (s_info[i].flags1 & SKF1_RANDOM_GAIN) { - available_skills[max_a] = i; - max_a++; + if (s_descriptors[i].flags & SKF_RANDOM_GAIN) + { + available_skills.push_back(i); } } /* Perform the selection */ std::vector<s32b> weights; - for (i = 0; i < max_a; i++) { - weights.push_back(s_info[available_skills[i]].random_gain_chance); + for (std::size_t i = 0; i < available_skills.size(); i++) + { + weights.push_back(s_descriptors[available_skills[i]].random_gain_chance); } std::vector<size_t> indexes = wrs(weights); assert(indexes.size() >= LOST_SWORD_NSKILLS); /* Extract the information needed from the skills */ - for (i = 0; i < LOST_SWORD_NSKILLS; i++) + int skl[LOST_SWORD_NSKILLS]; + s32b val[LOST_SWORD_NSKILLS]; + s32b mod[LOST_SWORD_NSKILLS]; + std::vector<std::string> items; + for (std::size_t i = 0; i < LOST_SWORD_NSKILLS; i++) { s32b s_idx = available_skills[indexes[i]]; - skill_type *s_ptr = &s_info[s_idx]; + auto s_ptr = &s_info[s_idx]; if (s_ptr->mod) { @@ -1356,7 +1431,9 @@ void do_get_new_skill() val[i] = s_ptr->mod * 1; mod[i] = 100; if (mod[i] + s_ptr->mod > 500) + { mod[i] = 500 - s_ptr->mod; + } } else { @@ -1370,42 +1447,56 @@ void do_get_new_skill() val[i] = 1000; } - if (s_ptr->value + val[i] > SKILL_MAX) { + if (s_ptr->value + val[i] > SKILL_MAX) + { val[i] = SKILL_MAX - s_ptr->value; } skl[i] = s_idx; items.push_back(format("%-40s: +%02ld.%03ld value, +%01d.%03d modifier", - s_ptr->name, + s_descriptors[s_idx].name.c_str(), val[i] / SKILL_STEP, val[i] % SKILL_STEP, mod[i] / SKILL_STEP, mod[i] % SKILL_STEP)); } + // Ask for a skill while (TRUE) { char last = 'a' + (LOST_SWORD_NSKILLS-1); char buf[80]; - sprintf(buf, "Choose a skill to learn(a-%c to choose, ESC to cancel)?", last); - res = ask_menu(buf, items); + sprintf(buf, "Choose a skill to learn (a-%c to choose, ESC to cancel)?", last); + int res = ask_menu(buf, items); /* Ok ? lets learn ! */ if (res > -1) { - skill_type *s_ptr; + std::size_t chosen_skill = skl[res]; + bool_ oppose = FALSE; int oppose_skill = -1; - /* Check we don't oppose an existing skill */ - for (i = 0; i < max_s_idx; i++) + /* Check we don't oppose a skill the player already has */ + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - if ((s_info[i].action[skl[res]] == SKILL_EXCLUSIVE) && - (s_info[i].value != 0)) + auto const &s_descriptor = s_descriptors[i]; + + // Only bother if player has skill + if (s_info[i].value) { - oppose = TRUE; - oppose_skill = i; - break; + // Check if i'th skill opposes the chosen one. + auto found = std::find( + s_descriptor.excludes.begin(), + s_descriptor.excludes.end(), + chosen_skill); + + if (found != s_descriptor.excludes.end()) + { + oppose = TRUE; + oppose_skill = i; + break; + } } } @@ -1423,25 +1514,32 @@ void do_get_new_skill() /* Prepare prompt */ msg = format("This skill is mutually exclusive with " "at least %s, continue?", - s_info[oppose_skill].name); + s_descriptors[oppose_skill].name.c_str()); - /* The player rejected the choice */ - if (!get_check(msg)) continue; + /* The player rejected the choice; go back to prompt */ + if (!get_check(msg)) + { + continue; + } } - s_ptr = &s_info[skl[res]]; + auto const s_desc = &s_descriptors[chosen_skill]; + auto const s_ptr = &s_info[chosen_skill]; + s_ptr->value += val[res]; s_ptr->mod += mod[res]; + if (mod[res]) { msg_format("You can now learn the %s skill.", - s_ptr->name); + s_desc->name.c_str()); } else { msg_format("Your knowledge of the %s skill increases.", - s_ptr->name); + s_desc->name.c_str()); } + break; } } @@ -1461,12 +1559,13 @@ void do_get_new_skill() */ s16b find_ability(cptr name) { - u16b i; + auto const &ab_info = game->edit_data.ab_info; - /* Scan ability list */ - for (i = 0; i < max_ab_idx; i++) + for (std::size_t i = 0; i < ab_info.size(); i++) { - if (ab_info[i].name && streq(ab_info[i].name, name)) + auto const &ab_name = ab_info[i].name; + + if ((!ab_name.empty()) && (ab_name == name)) { return (i); } @@ -1476,51 +1575,40 @@ s16b find_ability(cptr name) return ( -1); } -/* - * Do the player have the ability - */ -bool_ has_ability(int ab) +/* Do we meet the requirements? */ +static bool can_learn_ability(int ab) { - return ab_info[ab].acquired; -} + auto const &ab_info = game->edit_data.ab_info; -/* Do we meet the requirements */ -static bool_ can_learn_ability(int ab) -{ - ability_type *ab_ptr = &ab_info[ab]; - int i; + auto ab_ptr = &ab_info[ab]; - if (ab_ptr->acquired) + if (p_ptr->has_ability(ab)) + { return FALSE; + } if (p_ptr->skill_points < ab_info[ab].cost) + { return FALSE; + } - for (i = 0; i < 10; i++) + for (auto const &need_skill: ab_ptr->need_skills) { - /* Must have skill level */ - if (ab_ptr->skills[i] > -1) - { - if (get_skill(ab_ptr->skills[i]) < ab_ptr->skill_levels[i]) - return FALSE; - } - - /* Must have ability */ - if (ab_ptr->need_abilities[i] > -1) + if (get_skill(need_skill.skill_idx) < need_skill.level) { - if (!ab_info[ab_ptr->need_abilities[i]].acquired) - return FALSE; + return FALSE; } + } - /* Must not have ability */ - if (ab_ptr->forbid_abilities[i] > -1) + for (auto const &need_ability: ab_ptr->need_abilities) + { + if (!p_ptr->has_ability(need_ability)) { - if (ab_info[ab_ptr->forbid_abilities[i]].acquired) - return FALSE; + return FALSE; } } - for (i = 0; i < 6; i++) + for (std::size_t i = 0; i < 6; i++) { /* Must have stat */ if (ab_ptr->stat[i] > -1) @@ -1536,12 +1624,11 @@ static bool_ can_learn_ability(int ab) /* Learn an ability */ static void gain_ability(int ab) { - int wid, hgt; - Term_get_size(&wid, &hgt); + auto const &ab_info = game->edit_data.ab_info; if (!can_learn_ability(ab)) { - msg_box("You cannot learn this ability.", hgt / 2, wid / 2); + msg_box_auto("You cannot learn this ability."); return; } @@ -1549,18 +1636,20 @@ static void gain_ability(int ab) flush(); /* Ask we can commit the change */ - if (msg_box("Learn this ability(this is permanent)? (y/n)", hgt / 2, wid / 2) != 'y') + if (msg_box_auto("Learn this ability (this is permanent)? (y/n)") != 'y') { return; } - ab_info[ab].acquired = TRUE; + p_ptr->gain_ability(ab); p_ptr->skill_points -= ab_info[ab].cost; } -static bool compare_abilities(const int ab_idx1, const int ab_idx2) +static bool compare_abilities(std::size_t ab_idx1, std::size_t ab_idx2) { - return strcmp(ab_info[ab_idx1].name, ab_info[ab_idx2].name) < 0; + auto const &ab_info = game->edit_data.ab_info; + + return ab_info[ab_idx1].name < ab_info[ab_idx2].name; } /* @@ -1568,13 +1657,13 @@ static bool compare_abilities(const int ab_idx1, const int ab_idx2) */ void dump_abilities(FILE *fff) { - int i; + auto const &ab_info = game->edit_data.ab_info; // Find all abilities that the player has. - std::vector<int> table; - for (i = 0; i < max_ab_idx; i++) + std::vector<std::size_t> table; + for (std::size_t i = 0; i < ab_info.size(); i++) { - if (ab_info[i].name && has_ability(i)) + if ((!ab_info[i].name.empty()) && p_ptr->has_ability(i)) { table.push_back(i); } @@ -1592,7 +1681,7 @@ void dump_abilities(FILE *fff) for (int i : table) { - fprintf(fff, "\n * %s", ab_info[i].name); + fprintf(fff, "\n * %s", ab_info[i].name.c_str()); } fprintf(fff, "\n"); @@ -1602,8 +1691,10 @@ void dump_abilities(FILE *fff) /* * Draw the abilities list */ -static void print_abilities(const std::vector<int> &table, int sel, int start) +static void print_abilities(const std::vector<std::size_t> &table, int sel, int start) { + auto const &ab_info = game->edit_data.ab_info; + int i, j; int wid, hgt; cptr keys; @@ -1617,7 +1708,7 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) c_prt((p_ptr->skill_points) ? TERM_L_BLUE : TERM_L_RED, format("Skill points left: %d", p_ptr->skill_points), 2, 0); - print_desc_aux(ab_info[table[sel]].desc, 3, 0); + print_desc_aux(ab_info[table[sel]].desc.c_str(), 3, 0); for (j = start; j < start + (hgt - 7); j++) { @@ -1632,12 +1723,18 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) i = table[j]; - if (ab_info[i].acquired) + if (p_ptr->has_ability(i)) + { color = TERM_L_BLUE; + } else if (can_learn_ability(i)) + { color = TERM_WHITE; + } else + { color = TERM_L_DARK; + } if (j == sel) @@ -1647,10 +1744,10 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) end = ']'; } - c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name), + c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name.c_str()), j + 7 - start, 0); - if (!ab_info[i].acquired) + if (!p_ptr->has_ability(i)) { c_prt(color, format("%d", ab_info[i].cost), j + 7 - start, 60); } @@ -1662,13 +1759,14 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) } /* - * Interreact with abilitiess + * Interreact with abilities */ void do_cmd_ability() { + auto const &ab_info = game->edit_data.ab_info; + int sel = 0, start = 0; char c; - int i; int wid, hgt; /* Save the screen */ @@ -1678,10 +1776,10 @@ void do_cmd_ability() Term_clear(); /* Initialise the abilities list */ - std::vector<int> table; - for (i = 0; i < max_ab_idx; i++) + std::vector<std::size_t> table; + for (std::size_t i = 0; i < ab_info.size(); i++) { - if (ab_info[i].name) + if (!ab_info[i].name.empty()) { table.push_back(i); } @@ -1742,10 +1840,16 @@ void do_cmd_ability() /* gain ability */ if (dir == 6) gain_ability(table[sel]); - /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ + /* Wizard mode allows any ability */ + if (wizard && (c == '+')) + { + p_ptr->gain_ability(table[sel]); + } - if (wizard && (c == '+')) ab_info[table[sel]].acquired = TRUE; - if (wizard && (c == '-')) ab_info[table[sel]].acquired = FALSE; + if (wizard && (c == '-')) + { + p_ptr->lose_ability(table[sel]); + } /* Contextual help */ if (c == '?') @@ -1789,41 +1893,26 @@ void do_cmd_ability() */ void apply_level_abilities(int level) { - int i; - - for (i = 0; i < 10; i++) + auto apply = [level](std::vector<player_race_ability_type> const &abilities) -> void { - if (cp_ptr->abilities[i].level == level) - { - if ((level > 1) && (!ab_info[cp_ptr->abilities[i].ability].acquired)) - { - cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[cp_ptr->abilities[i].ability].name); - } - ab_info[cp_ptr->abilities[i].ability].acquired = TRUE; - } - if (spp_ptr->abilities[i].level == level) - { - if ((level > 1) && (!ab_info[spp_ptr->abilities[i].ability].acquired)) - { - cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[spp_ptr->abilities[i].ability].name); - } - ab_info[spp_ptr->abilities[i].ability].acquired = TRUE; - } - if (rp_ptr->abilities[i].level == level) - { - if ((level > 1) && (!ab_info[rp_ptr->abilities[i].ability].acquired)) - { - cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[rp_ptr->abilities[i].ability].name); - } - ab_info[rp_ptr->abilities[i].ability].acquired = TRUE; - } - if (rmp_ptr->abilities[i].level == level) + auto const &ab_info = game->edit_data.ab_info; + + for (auto const &a: abilities) { - if ((level > 1) && (!ab_info[rmp_ptr->abilities[i].ability].acquired)) + if (a.level == level) { - cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[rmp_ptr->abilities[i].ability].name); + if ((level > 1) && (!p_ptr->has_ability(a.ability))) + { + cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[a.ability].name.c_str()); + } + + p_ptr->gain_ability(a.ability); } - ab_info[rmp_ptr->abilities[i].ability].acquired = TRUE; } - } + }; + + apply(cp_ptr->abilities); + apply(spp_ptr->abilities); + apply(rp_ptr->abilities); + apply(rmp_ptr->abilities); } diff --git a/src/skills.hpp b/src/skills.hpp index 6c1880a6..8b1437d9 100644 --- a/src/skills.hpp +++ b/src/skills.hpp @@ -2,26 +2,27 @@ #include "h-basic.h" +#include <cstddef> + /* Skill functions */ -extern void dump_skills(FILE *fff); -extern s16b find_skill(cptr name); -extern s16b find_skill_i(cptr name); -extern s16b get_skill(int skill); -extern s16b get_skill_scale(int skill, u32b scale); -extern void do_cmd_skill(void); -extern void do_cmd_activate_skill(void); -extern cptr get_melee_name(); -extern s16b get_melee_skills(void); -extern s16b get_melee_skill(void); -extern bool_ forbid_gloves(void); -extern bool_ forbid_non_blessed(void); -extern void compute_skills(s32b *v, s32b *m, int i); -extern void select_default_melee(void); -extern void do_get_new_skill(void); -extern void init_skill(s32b value, s32b mod, int i); -extern s16b find_ability(cptr name); -extern void dump_abilities(FILE *fff); -extern void do_cmd_ability(void); -extern bool_ has_ability(int ab); -extern void apply_level_abilities(int level); -extern void recalc_skills(bool_ init); +void dump_skills(FILE *fff); +s16b find_skill(cptr name); +s16b find_skill_i(cptr name); +s16b get_skill(int skill); +s16b get_skill_scale(int skill, u32b scale); +void do_cmd_skill(); +void do_cmd_activate_skill(); +cptr get_melee_name(); +s16b get_melee_skills(); +s16b get_melee_skill(); +bool_ forbid_gloves(); +bool_ forbid_non_blessed(); +void compute_skills(s32b *v, s32b *m, std::size_t i); +void select_default_melee(); +void do_get_new_skill(); +void init_skill(s32b value, s32b mod, std::size_t i); +s16b find_ability(cptr name); +void dump_abilities(FILE *fff); +void do_cmd_ability(); +void apply_level_abilities(int level); +void recalc_skills(bool_ init); diff --git a/src/skills_defs.hpp b/src/skills_defs.hpp index 1dbdee9f..9bf3c9ce 100644 --- a/src/skills_defs.hpp +++ b/src/skills_defs.hpp @@ -36,10 +36,9 @@ #define SKILL_NECROMANCY 31 #define SKILL_MIMICRY 32 #define SKILL_ANTIMAGIC 33 -#define SKILL_RUNECRAFT 34 -#define SKILL_SNEAK 35 +/* XXX */ #define SKILL_STEALTH 36 -#define SKILL_DISARMING 37 +/* XXX */ #define SKILL_STEALING 40 #define SKILL_SORCERY 41 #define SKILL_HAND 42 @@ -60,4 +59,3 @@ #define SKILL_STUN 57 #define SKILL_BOULDER 58 #define SKILL_GEOMANCY 59 -#define MAX_SKILLS 200 diff --git a/src/spellbinder.hpp b/src/spellbinder.hpp new file mode 100644 index 00000000..078d9eac --- /dev/null +++ b/src/spellbinder.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "h-basic.h" +#include <vector> + +/** + * Spellbinder state + */ +struct spellbinder { + + /** + * Bound spells. + */ + std::vector<u32b> spell_idxs; + + /** + * Trigger condition. + */ + byte trigger = 0; + +}; diff --git a/src/spells1.cc b/src/spells1.cc index 5d6722af..4df1a7c6 100644 --- a/src/spells1.cc +++ b/src/spells1.cc @@ -13,17 +13,23 @@ #include "cmd1.hpp" #include "cmd3.hpp" #include "cmd5.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "files.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "gods.hpp" #include "melee2.hpp" #include "monster2.hpp" #include "monster3.hpp" -#include "monster_type.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_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_type.hpp" @@ -35,8 +41,6 @@ #include "squeltch.hpp" #include "stats.hpp" #include "tables.hpp" -#include "traps.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.hpp" @@ -46,6 +50,7 @@ #include "z-rand.hpp" #include <chrono> +#include <fmt/format.h> #include <thread> using std::this_thread::sleep_for; @@ -86,12 +91,14 @@ using std::chrono::milliseconds; */ s16b poly_r_idx(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; int i, r; /* Hack -- Uniques never polymorph */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) return (r_idx); /* Pick a (possibly new) non-unique race */ @@ -107,7 +114,7 @@ s16b poly_r_idx(int r_idx) r_ptr = &r_info[r]; /* Ignore unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) continue; + if (r_ptr->flags & RF_UNIQUE) continue; /* Use that index */ r_idx = r; @@ -215,9 +222,6 @@ void teleport_player_directed(int rad, int dir) } - /* Sound */ - sound(SOUND_TELEPORT); - /* Move player */ teleport_player_to(y, x); @@ -230,7 +234,7 @@ void teleport_player_directed(int rad, int dir) if (c_ptr->feat == FEAT_SHOP) { /* Disturb */ - disturb(0); + disturb(); /* Hack -- enter store */ command_new = '_'; @@ -325,9 +329,6 @@ void teleport_away(int m_idx, int dis) if (tries > MAX_TRIES) return; } - /* Sound */ - sound(SOUND_TPOTHER); - /* Update the new location */ cave[ny][nx].m_idx = m_idx; last_teleportation_y = ny; @@ -351,7 +352,7 @@ void teleport_away(int m_idx, int dis) /* Update monster light */ auto const r_ptr = m_ptr->race(); - if (r_ptr->flags9 & RF9_HAS_LITE) + if (r_ptr->flags & RF_HAS_LITE) { p_ptr->update |= (PU_MON_LITE); } @@ -444,9 +445,6 @@ static void teleport_to_player(int m_idx) if (attempts < 1) return; - /* Sound */ - sound(SOUND_TPOTHER); - /* Update the new location */ cave[ny][nx].m_idx = m_idx; last_teleportation_y = ny; @@ -469,7 +467,7 @@ static void teleport_to_player(int m_idx) lite_spot(ny, nx); /* Update monster light */ - if (r_ptr->flags9 & RF9_HAS_LITE) p_ptr->update |= (PU_MON_LITE); + if (r_ptr->flags & RF_HAS_LITE) p_ptr->update |= (PU_MON_LITE); } @@ -508,7 +506,7 @@ void teleport_player(int dis) return; } - if ((dungeon_flags2 & DF2_NO_TELEPORT) && (!teleport_player_bypass)) + if ((dungeon_flags & DF_NO_TELEPORT) && (!teleport_player_bypass)) { msg_print("No teleport on special levels..."); return; @@ -566,9 +564,6 @@ void teleport_player(int dis) if (tries > MAX_TRIES) return; } - /* Sound */ - sound(SOUND_TELEPORT); - /* Save the old location */ oy = p_ptr->py; ox = p_ptr->px; @@ -598,7 +593,7 @@ void teleport_player(int dis) { auto const r_ptr = m_list[cave[oy + yy][ox + xx].m_idx].race(); - if ((r_ptr->flags6 & RF6_TPORT) && !(r_ptr->flags3 & RF3_RES_TELE)) + if ((r_ptr->spells & SF_TPORT) && !(r_ptr->flags & RF_RES_TELE)) /* * The latter limitation is to avoid * totally unkillable suckers... @@ -626,8 +621,6 @@ void teleport_player(int dis) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -749,9 +742,6 @@ void teleport_monster_to(int m_idx, int ny, int nx) } } - /* Sound */ - sound(SOUND_TPOTHER); - /* Save the old position */ oy = m_ptr->fy; ox = m_ptr->fx; @@ -797,7 +787,7 @@ void teleport_player_to(int ny, int nx) return; } - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); return; @@ -828,9 +818,6 @@ void teleport_player_to(int ny, int nx) } } - /* Sound */ - sound(SOUND_TELEPORT); - /* Save the old location */ oy = p_ptr->py; ox = p_ptr->px; @@ -856,9 +843,6 @@ void teleport_player_to(int ny, int nx) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -871,7 +855,7 @@ void teleport_player_to(int ny, int nx) /* * Teleport the player one level up or down (random when legal) */ -void teleport_player_level(void) +void teleport_player_level() { /* No effect in arena or quest */ if (p_ptr->inside_quest) @@ -879,14 +863,14 @@ void teleport_player_level(void) msg_print("There is no effect."); return; } - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); 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; } @@ -956,9 +940,6 @@ void teleport_player_level(void) /* Leaving */ p_ptr->leaving = TRUE; } - - /* Sound */ - sound(SOUND_TPLEVEL); } @@ -1219,16 +1200,18 @@ static u16b bolt_pict(int y, int x, int ny, int nx, int typ) */ void spellbinder_trigger() { - int i; + auto spellbinder = &p_ptr->spellbinder; cmsg_print(TERM_L_GREEN, "The spellbinder is triggered!"); - for (i = 0; i < p_ptr->spellbinder_num; i++) + + for (auto spell_idx: spellbinder->spell_idxs) { - msg_format("Triggering spell %s.", spell_type_name(spell_at(p_ptr->spellbinder[i]))); - lua_cast_school_spell(p_ptr->spellbinder[i], TRUE); + msg_format("Triggering spell %s.", spell_type_name(spell_at(spell_idx))); + lua_cast_school_spell(spell_idx, TRUE); } - p_ptr->spellbinder_num = 0; - p_ptr->spellbinder_trigger = 0; + + spellbinder->spell_idxs.clear(); + spellbinder->trigger = 0; } @@ -1251,14 +1234,14 @@ void take_hit(int damage, cptr hit_from) char death_message[80]; - int warning = (p_ptr->mhp * hitpoint_warn / 10); + int warning = (p_ptr->mhp * options->hitpoint_warn / 10); int percent; /* Paranoia */ if (death) return; /* Disturb */ - disturb(1); + disturb(); /* Apply "invulnerability" */ if (p_ptr->invuln && (damage < 9000)) @@ -1295,13 +1278,13 @@ void take_hit(int damage, cptr hit_from) /* Hurt the wielded monster if any */ if ((o_ptr->k_idx) && (magik(5 + get_skill(SKILL_SYMBIOTIC))) && (!carried_monster_hit)) { - cptr sym_name = symbiote_name(TRUE); + auto sym_name = symbiote_name(true); if (o_ptr->pval2 - damage <= 0) { cmsg_format(TERM_L_RED, "%s dies from protecting you, you feel very sad...", - sym_name); + sym_name.c_str()); inc_stack_size_ex(INVEN_CARRY, -1, OPTIMIZE, NO_DESCRIBE); damage -= o_ptr->pval2; o_ptr->pval2 = 0; @@ -1309,7 +1292,7 @@ void take_hit(int damage, cptr hit_from) } else { - msg_format("%s takes the damage instead of you.", sym_name); + msg_format("%s takes the damage instead of you.", sym_name.c_str()); o_ptr->pval2 -= damage; monster_take = TRUE; } @@ -1336,27 +1319,26 @@ void take_hit(int damage, cptr hit_from) if (p_ptr->chp < 0) { /* Necromancers get a special treatment */ - if (((!has_ability(AB_UNDEAD_FORM)) || ((p_ptr->necro_extra & CLASS_UNDEAD)))) + if (((!p_ptr->has_ability(AB_UNDEAD_FORM)) || ((p_ptr->necro_extra & CLASS_UNDEAD)))) { - /* Sound */ - sound(SOUND_DEATH); - /* Hack -- Note death */ - if (!last_words) + if (!options->last_words) { cmsg_print(TERM_RED, "You die."); msg_print(NULL); } else { - (void)get_rnd_line("death.txt", death_message); + get_rnd_line("death.txt", death_message); cmsg_print(TERM_RED, death_message); } /* Note cause of death */ - (void)strcpy(died_from, hit_from); - - if (p_ptr->image) strcat(died_from, "(?)"); + game->died_from = hit_from; + if (p_ptr->image) + { + game->died_from = "(?)"; + } /* Leaving */ p_ptr->leaving = TRUE; @@ -1405,9 +1387,10 @@ void take_hit(int damage, cptr hit_from) if (p_ptr->chp < warning) { /* Hack -- bell on first notice */ - if (alert_hitpoint && (old_chp > warning)) bell(); - - sound(SOUND_WARN); + if (old_chp > warning) + { + bell(); + } /* Message */ if (p_ptr->necro_extra & CLASS_UNDEAD) @@ -1421,23 +1404,28 @@ void take_hit(int damage, cptr hit_from) percent = p_ptr->chp * 100 / p_ptr->mhp; /* Check the spellbinder trigger */ - if (p_ptr->spellbinder_trigger == SPELLBINDER_HP75) - { - /* Trigger ?! */ - if (percent <= 75) - spellbinder_trigger(); - } - else if (p_ptr->spellbinder_trigger == SPELLBINDER_HP50) + switch (p_ptr->spellbinder.trigger) { - /* Trigger ?! */ - if (percent <= 50) - spellbinder_trigger(); - } - else if (p_ptr->spellbinder_trigger == SPELLBINDER_HP25) - { - /* Trigger ?! */ - if (percent <= 25) - spellbinder_trigger(); + case SPELLBINDER_HP75: + if (percent <= 75) + { + spellbinder_trigger(); + } + break; + + case SPELLBINDER_HP50: + if (percent <= 50) + { + spellbinder_trigger(); + } + break; + + case SPELLBINDER_HP25: + if (percent <= 25) + { + spellbinder_trigger(); + } + break; } /* Melkor acn summon to help you */ @@ -1472,8 +1460,10 @@ void take_hit(int damage, cptr hit_from) } } - if (player_char_health) + if (options->player_char_health) + { lite_spot(p_ptr->py, p_ptr->px); + } } @@ -1484,14 +1474,14 @@ void take_sanity_hit(int damage, cptr hit_from) char death_message[80]; - int warning = (p_ptr->msane * hitpoint_warn / 10); + int warning = (p_ptr->msane * options->hitpoint_warn / 10); /* Paranoia */ if (death) return; /* Disturb */ - disturb(1); + disturb(); /* Hurt the player */ @@ -1506,26 +1496,25 @@ void take_sanity_hit(int damage, cptr hit_from) /* Dead player */ if (p_ptr->csane < 0) { - /* Sound */ - sound(SOUND_DEATH); - /* Hack -- Note death */ cmsg_print(TERM_VIOLET, "You turn into an unthinking vegetable."); - if (!last_words) + if (!options->last_words) { cmsg_print(TERM_RED, "You die."); msg_print(NULL); } else { - (void)get_rnd_line("death.txt", death_message); + get_rnd_line("death.txt", death_message); cmsg_print(TERM_RED, death_message); } /* Note cause of death */ - (void)strcpy(died_from, hit_from); - - if (p_ptr->image) strcat(died_from, "(?)"); + game->died_from = hit_from; + if (p_ptr->image) + { + game->died_from = "(?)"; + } /* Leaving */ p_ptr->leaving = TRUE; @@ -1546,9 +1535,10 @@ void take_sanity_hit(int damage, cptr hit_from) if (p_ptr->csane < warning) { /* Hack -- bell on first notice */ - if (alert_hitpoint && (old_csane > warning)) bell(); - - sound(SOUND_WARN); + if (old_csane > warning) + { + bell(); + } /* Message */ cmsg_print(TERM_RED, "*** LOW SANITY WARNING! ***"); @@ -1727,12 +1717,10 @@ static bool_ hates_cold(object_type *o_ptr) */ static int set_acid_destroy(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - if (!hates_acid(o_ptr)) return (FALSE); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f3 & (TR3_IGNORE_ACID)) return (FALSE); + auto const f = object_flags(o_ptr); + if (f & TR_IGNORE_ACID) return (FALSE); return (TRUE); } @@ -1742,12 +1730,10 @@ static int set_acid_destroy(object_type *o_ptr) */ static int set_elec_destroy(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - if (!hates_elec(o_ptr)) return (FALSE); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f3 & (TR3_IGNORE_ELEC)) return (FALSE); + auto const f = object_flags(o_ptr); + if (f & TR_IGNORE_ELEC) return (FALSE); return (TRUE); } @@ -1757,12 +1743,10 @@ static int set_elec_destroy(object_type *o_ptr) */ static int set_fire_destroy(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - if (!hates_fire(o_ptr)) return (FALSE); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f3 & (TR3_IGNORE_FIRE)) return (FALSE); + auto const f = object_flags(o_ptr); + if (f & TR_IGNORE_FIRE) return (FALSE); return (TRUE); } @@ -1772,12 +1756,10 @@ static int set_fire_destroy(object_type *o_ptr) */ static int set_cold_destroy(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - if (!hates_cold(o_ptr)) return (FALSE); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f3 & (TR3_IGNORE_COLD)) return (FALSE); + auto const f = object_flags(o_ptr); + if (f & (TR_IGNORE_COLD)) return (FALSE); return (TRUE); } @@ -1797,6 +1779,8 @@ typedef int (*inven_func)(object_type *); */ static int inven_damage(inven_func typ, int perc) { + auto const &k_info = game->edit_data.k_info; + int i, j, k, amt; object_type *o_ptr; @@ -1816,7 +1800,7 @@ static int inven_damage(inven_func typ, int perc) if (!o_ptr->k_idx) continue; /* Hack -- for now, skip artifacts */ - if (artifact_p(o_ptr) || o_ptr->art_name) continue; + if (artifact_p(o_ptr)) continue; /* Give this item slot a shot at death */ if ((*typ)(o_ptr)) @@ -1843,8 +1827,8 @@ static int inven_damage(inven_func typ, int perc) /* Potions smash open */ if (k_info[o_ptr->k_idx].tval == TV_POTION) - { - (void)potion_smash_effect(0, p_ptr->py, p_ptr->px, o_ptr->sval); + { + potion_smash_effect(0, p_ptr->py, p_ptr->px, o_ptr->sval); } /* @@ -1881,12 +1865,10 @@ static int inven_damage(inven_func typ, int perc) * * If any armor is damaged (or resists), the player takes less damage. */ -static int minus_ac(void) +static int minus_ac() { object_type *o_ptr = NULL; - u32b f1, f2, f3, f4, f5, esp; - char o_name[80]; @@ -1924,10 +1906,10 @@ static int minus_ac(void) object_desc(o_name, o_ptr, FALSE, 0); /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Object resists */ - if (f3 & (TR3_IGNORE_ACID)) + if (flags & TR_IGNORE_ACID) { msg_format("Your %s is unaffected!", o_name); @@ -1967,7 +1949,7 @@ void acid_dam(int dam, cptr kb_str) if ((!(p_ptr->oppose_acid || p_ptr->resist_acid)) && randint(HURT_CHANCE) == 1) - (void) do_dec_stat(A_CHR, STAT_DEC_NORMAL); + do_dec_stat(A_CHR, STAT_DEC_NORMAL); /* If any armor gets hit, defend the player */ if (minus_ac()) dam = (dam + 1) / 2; @@ -1997,7 +1979,7 @@ void elec_dam(int dam, cptr kb_str) if ((!(p_ptr->oppose_elec || p_ptr->resist_elec)) && randint(HURT_CHANCE) == 1) - (void) do_dec_stat(A_DEX, STAT_DEC_NORMAL); + do_dec_stat(A_DEX, STAT_DEC_NORMAL); /* Take damage */ take_hit(dam, kb_str); @@ -2027,7 +2009,7 @@ void fire_dam(int dam, cptr kb_str) if ((!(p_ptr->oppose_fire || p_ptr->resist_fire)) && randint(HURT_CHANCE) == 1) - (void) do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_STR, STAT_DEC_NORMAL); /* Take damage */ @@ -2055,7 +2037,7 @@ void cold_dam(int dam, cptr kb_str) if ((!(p_ptr->oppose_cold || p_ptr->resist_cold)) && randint(HURT_CHANCE) == 1) - (void) do_dec_stat(A_STR, STAT_DEC_NORMAL); + do_dec_stat(A_STR, STAT_DEC_NORMAL); /* Take damage */ take_hit(dam, kb_str); @@ -2334,7 +2316,7 @@ bool_ apply_disenchant(int mode) /* Artifacts have 71% chance to resist */ - if ((artifact_p(o_ptr) || o_ptr->art_name) && (rand_int(100) < 71)) + if (artifact_p(o_ptr) && (rand_int(100) < 71)) { /* Message */ msg_format("Your %s (%c) resist%s disenchantment!", @@ -2374,7 +2356,7 @@ bool_ apply_disenchant(int mode) } -void corrupt_player(void) +void corrupt_player() { int max1, cur1, max2, cur2, ii, jj; @@ -2403,7 +2385,7 @@ static void apply_nexus(monster_type *m_ptr) { if (m_ptr == NULL) return; - if (!(dungeon_flags2 & DF2_NO_TELEPORT)) + if (!(dungeon_flags & DF_NO_TELEPORT)) { switch (randint(7)) { @@ -2924,6 +2906,7 @@ static int project_m_y; static bool_ project_f(int who, int r, int y, int x, int dam, int typ) { cave_type *c_ptr = &cave[y][x]; + auto const &f_info = game->edit_data.f_info; bool_ obvious = FALSE; @@ -2993,12 +2976,12 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) * the conditional... -- pelpel */ if (!cave_plain_floor_bold(y, x) || - (f_info[cave[y][x].feat].flags1 & FF1_PERMANENT)) break; + (f_info[cave[y][x].feat].flags & FF_PERMANENT)) break; /* Destination shouldn't be "interesting" either */ while (tries && (!cave_plain_floor_bold(y2, x2) || - (f_info[cave[y2][x2].feat].flags1 & FF1_PERMANENT))) + (f_info[cave[y2][x2].feat].flags & FF_PERMANENT))) { y2 = y1 = randint(cur_hgt) - 1; x2 = x1 = randint(cur_wid) - 1; @@ -3039,7 +3022,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) case GF_HELL_FIRE: { /* "Permanent" features will stay */ - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Trees *will* burn */ if (c_ptr->feat == FEAT_TREES) @@ -3078,7 +3061,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) } /* Floors can become ash or lava (chance == 25%) */ - else if (f_info[c_ptr->feat].flags1 & FF1_FLOOR) + else if (f_info[c_ptr->feat].flags & FF_FLOOR) { int k = rand_int(100); @@ -3125,7 +3108,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) int k; /* "Permanent" features will stay */ - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Needs more than 30 damage */ if (dam < 30) break; @@ -3194,7 +3177,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) case GF_NUKE: { /* "Permanent" features will stay */ - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; if ((c_ptr->feat == FEAT_TREES) || (c_ptr->feat == FEAT_SMALL_TREES)) @@ -3214,11 +3197,11 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) case GF_DISINTEGRATE: { /* "Permanent" features will stay */ - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; if (((c_ptr->feat == FEAT_TREES) || (c_ptr->feat == FEAT_SMALL_TREES) || - (f_info[c_ptr->feat].flags1 & FF1_FLOOR)) && + (f_info[c_ptr->feat].flags & FF_FLOOR)) && (rand_int(100) < 30)) { /* Flow change */ @@ -3239,71 +3222,12 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) break; } - /* Destroy Traps (and Locks) */ - case GF_KILL_TRAP: - { - /* Destroy normal traps and disarm monster traps */ - if ((c_ptr->t_idx != 0) || (c_ptr->feat == FEAT_MON_TRAP)) - { - /* Check line of sight */ - if (player_has_los_bold(y, x)) - { - msg_print("There is a bright flash of light!"); - obvious = TRUE; - } - - /* Forget the trap */ - c_ptr->info &= ~(CAVE_MARK | CAVE_TRDT); - - /* Destroy normal traps */ - c_ptr->t_idx = 0; - - /* Disarm monster traps */ - if (c_ptr->feat == FEAT_MON_TRAP) - { - c_ptr->special = c_ptr->special2 = 0; - - /* Remove the feature */ - if (!(f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) - place_floor_convert_glass(y, x); - } - - /* Hack -- Force redraw */ - note_spot(y, x); - lite_spot(y, x); - } - - /* Secret / Locked doors are found and unlocked */ - else if ((c_ptr->feat == FEAT_SECRET) || - ((c_ptr->feat >= FEAT_DOOR_HEAD + 0x01) && - (c_ptr->feat <= FEAT_DOOR_HEAD + 0x07))) - { - - /* Check line of sound */ - if (player_has_los_bold(y, x)) - { - msg_print("Click!"); - obvious = TRUE; - } - - /* Remove feature mimic */ - cave[y][x].mimic = 0; - - /* Unlock the door */ - cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); - } - - break; - } - - /* Destroy Doors (and traps) */ + /* Destroy Doors */ case GF_KILL_DOOR: { - /* Destroy all doors and traps, and disarm monster traps */ + /* Destroy all doors */ if ((c_ptr->feat == FEAT_OPEN) || (c_ptr->feat == FEAT_BROKEN) || - (c_ptr->t_idx != 0) || - (c_ptr->feat == FEAT_MON_TRAP) || ((c_ptr->feat >= FEAT_DOOR_HEAD) && (c_ptr->feat <= FEAT_DOOR_TAIL))) { @@ -3324,17 +3248,10 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) } /* Forget the door */ - c_ptr->info &= ~(CAVE_MARK | CAVE_TRDT); - - /* Remove normal traps */ - c_ptr->t_idx = 0; - - /* Disarm monster traps */ - if (c_ptr->feat == FEAT_MON_TRAP) - c_ptr->special = c_ptr->special2 = 0; + c_ptr->info &= ~(CAVE_MARK); /* Remove the feature */ - if (!(f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) + if (!(f_info[c_ptr->feat].flags & FF_PERMANENT)) place_floor_convert_glass(y, x); /* Hack -- Force redraw */ @@ -3375,7 +3292,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) if (cave_floor_bold(y, x)) break; /* "Permanent" features will stay */ - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Granite -- How about other wall types? */ if ((c_ptr->feat >= FEAT_WALL_EXTRA) && @@ -3503,7 +3420,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) /* Require a "naked" floor grid */ if (!cave_clean_bold(y, x)) break; - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Create a closed door */ cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); @@ -3517,25 +3434,12 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) break; } - /* Make traps */ - case GF_MAKE_TRAP: - { - /* Require a "naked" floor grid */ - if (!cave_clean_bold(y, x)) break; - - /* Place a trap */ - place_trap(y, x); - - break; - } - - case GF_MAKE_GLYPH: { /* Require a "naked" floor grid */ if (!cave_clean_bold(y, x)) break; - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; cave_set_feat(y, x, FEAT_GLYPH); @@ -3551,8 +3455,8 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) /* Require a "naked" floor grid */ if (!cave_clean_bold(y, x)) break; - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; - if (!(f_info[c_ptr->feat].flags1 & FF1_FLOOR)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; + if (!(f_info[c_ptr->feat].flags & FF_FLOOR)) break; /* Place a wall */ cave_set_feat(y, x, FEAT_WALL_EXTRA); @@ -3595,7 +3499,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) case GF_LAVA_FLOW: { - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Shallow Lava */ if (dam == 1) @@ -3709,7 +3613,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) /* Delete the monster (if any) */ delete_monster(y, x); - if ((f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) break; + if ((f_info[c_ptr->feat].flags & FF_PERMANENT)) break; /* Destroy "valid" grids */ if (cave_valid_bold(y, x)) @@ -3788,7 +3692,7 @@ static bool_ project_f(int who, int r, int y, int x, int dam, int typ) if (!p_ptr->resist_blind && !p_ptr->resist_lite) { /* Become blind */ - (void)set_blind(p_ptr->blind + 10 + randint(10)); + set_blind(p_ptr->blind + 10 + randint(10)); } } @@ -3832,12 +3736,13 @@ static int raise_ego[MAX_RAISE] = */ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { + auto const &r_info = game->edit_data.r_info; + auto const &k_info = game->edit_data.k_info; + cave_type *c_ptr = &cave[y][x]; bool_ obvious = FALSE; - u32b f1, f2, f3, f4, f5, esp; - char o_name[80]; int o_sval = 0; @@ -3870,13 +3775,13 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) object_type * o_ptr = &o_list[this_o_idx]; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Get the "plural"-ness */ if (o_ptr->number > 1) plural = TRUE; /* Check for artifact */ - if ((artifact_p(o_ptr) || o_ptr->art_name)) is_art = TRUE; + if (artifact_p(o_ptr)) is_art = TRUE; /* Analyze the type */ switch (typ) @@ -3886,10 +3791,11 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { if (o_ptr->tval == TV_CORPSE) { - monster_race *r_ptr = &r_info[o_ptr->pval2]; - s32b dama, radius = 7; + auto r_ptr = &r_info[o_ptr->pval2]; + s32b radius = 7; + s32b dama; - if (r_ptr->flags1 & RF1_FORCE_MAXHP) + if (r_ptr->flags & RF_FORCE_MAXHP) dama = maxroll(r_ptr->hdice, r_ptr->hside); else dama = damroll(r_ptr->hdice, r_ptr->hside); @@ -3914,7 +3820,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " melt!" : " melts!"); - if (f3 & (TR3_IGNORE_ACID)) ignore = TRUE; + if (flags & TR_IGNORE_ACID) ignore = TRUE; } break; } @@ -3926,7 +3832,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " are destroyed!" : " is destroyed!"); - if (f3 & (TR3_IGNORE_ELEC)) ignore = TRUE; + if (flags & TR_IGNORE_ELEC) ignore = TRUE; } break; } @@ -3938,7 +3844,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " burn up!" : " burns up!"); - if (f3 & (TR3_IGNORE_FIRE)) ignore = TRUE; + if (flags & TR_IGNORE_FIRE) ignore = TRUE; } break; } @@ -3950,7 +3856,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { note_kill = (plural ? " shatter!" : " shatters!"); do_kill = TRUE; - if (f3 & (TR3_IGNORE_COLD)) ignore = TRUE; + if (flags & TR_IGNORE_COLD) ignore = TRUE; } break; } @@ -3962,14 +3868,14 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " burn up!" : " burns up!"); - if (f3 & (TR3_IGNORE_FIRE)) ignore = TRUE; + if (flags & TR_IGNORE_FIRE) ignore = TRUE; } if (hates_elec(o_ptr)) { ignore = FALSE; do_kill = TRUE; note_kill = (plural ? " are destroyed!" : " is destroyed!"); - if (f3 & (TR3_IGNORE_ELEC)) ignore = TRUE; + if (flags & TR_IGNORE_ELEC) ignore = TRUE; } break; } @@ -3981,14 +3887,14 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " burn up!" : " burns up!"); - if (f3 & (TR3_IGNORE_FIRE)) ignore = TRUE; + if (flags & TR_IGNORE_FIRE) ignore = TRUE; } if (hates_cold(o_ptr)) { ignore = FALSE; do_kill = TRUE; note_kill = (plural ? " shatter!" : " shatters!"); - if (f3 & (TR3_IGNORE_COLD)) ignore = TRUE; + if (flags & TR_IGNORE_COLD) ignore = TRUE; } break; } @@ -4026,7 +3932,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) { do_kill = TRUE; note_kill = (plural ? " are destroyed!" : " is destroyed!"); - if (f2 & (TR2_RES_CHAOS)) ignore = TRUE; + if (flags & TR_RES_CHAOS) ignore = TRUE; break; } @@ -4043,7 +3949,6 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) } /* Unlock chests */ - case GF_KILL_TRAP: case GF_KILL_DOOR: { /* Chests are noticed only if trapped or locked */ @@ -4086,19 +3991,6 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) break; } - case GF_IDENTIFY: - { - object_aware(o_ptr); - object_known(o_ptr); - - /* Process the appropriate hooks */ - identify_hooks(0 - this_o_idx, o_ptr, IDENT_NORMAL); - - /* Squelch ! */ - squeltch_grid(); - - break; - } case GF_RAISE: { get_pos_player(7, &y, &x); @@ -4116,7 +4008,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) } case GF_RAISE_DEMON: { - monster_race *r_ptr = &r_info[o_ptr->pval2]; + auto r_ptr = &r_info[o_ptr->pval2]; cptr name; if (o_ptr->tval != TV_CORPSE) break; @@ -4188,7 +4080,7 @@ static bool_ project_o(int who, int r, int y, int x, int dam, int typ) /* Potions produce effects when 'shattered' */ if (is_potion) { - (void)potion_smash_effect(who, y, x, o_sval); + potion_smash_effect(who, y, x, o_sval); } @@ -4354,17 +4246,17 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) auto r_ptr = m_ptr->race(); /* Mega Gachk */ - if (r_ptr->flags2 & RF2_DEATH_ORB) + if (r_ptr->flags & RF_DEATH_ORB) { msg_format("%^s is immune to magic.", m_name); return seen; } /* Some monsters get "destroyed" */ - if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || - (r_ptr->flags3 & (RF3_NONLIVING)) || + if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || + (r_ptr->flags & RF_NONLIVING) || (strchr("Evg", r_ptr->d_char))) { /* Special note at death */ @@ -4392,51 +4284,50 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_JAM_DOOR: case GF_RAISE: case GF_RAISE_DEMON: - case GF_IDENTIFY: break; /* none of the above anger */ case GF_TRAP_DEMONSOUL: - if (r_ptr->flags3 & RF3_DEMON) + if (r_ptr->flags & RF_DEMON) get_angry = TRUE; break; case GF_KILL_WALL: - if (r_ptr->flags3 & (RF3_HURT_ROCK)) + if (r_ptr->flags & RF_HURT_ROCK) get_angry = TRUE; break; case GF_HOLY_FIRE: - if (!(r_ptr->flags3 & (RF3_GOOD))) + if (!(r_ptr->flags & RF_GOOD)) get_angry = TRUE; break; case GF_TURN_UNDEAD: case GF_DISP_UNDEAD: - if (r_ptr->flags3 & RF3_UNDEAD) + if (r_ptr->flags & RF_UNDEAD) get_angry = TRUE; break; case GF_TURN_EVIL: case GF_DISP_EVIL: - if (r_ptr->flags3 & RF3_EVIL) + if (r_ptr->flags & RF_EVIL) get_angry = TRUE; break; case GF_DISP_GOOD: - if (r_ptr->flags3 & RF3_GOOD) + if (r_ptr->flags & RF_GOOD) get_angry = TRUE; break; case GF_DISP_DEMON: - if (r_ptr->flags3 & RF3_DEMON) + if (r_ptr->flags & RF_DEMON) get_angry = TRUE; break; case GF_DISP_LIVING: case GF_UNBREATH: - if (!(r_ptr->flags3 & (RF3_UNDEAD)) && - !(r_ptr->flags3 & (RF3_NONLIVING))) + if (!(r_ptr->flags & RF_UNDEAD) && + !(r_ptr->flags & RF_NONLIVING)) get_angry = TRUE; break; case GF_PSI: case GF_PSI_DRAIN: - if (!(r_ptr->flags2 & (RF2_EMPTY_MIND))) + if (!(r_ptr->flags & RF_EMPTY_MIND)) get_angry = TRUE; break; case GF_DOMINATION: - if (!(r_ptr->flags3 & (RF3_NO_CONF))) + if (!(r_ptr->flags & RF_NO_CONF)) get_angry = TRUE; break; case GF_OLD_POLY: @@ -4446,7 +4337,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) break; case GF_LITE: case GF_LITE_WEAK: - if (r_ptr->flags3 & RF3_HURT_LITE) + if (r_ptr->flags & RF_HURT_LITE) get_angry = TRUE; break; case GF_INSTA_DEATH: @@ -4490,23 +4381,12 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) break; } - case GF_IDENTIFY: - { - if (seen) obvious = TRUE; - - /* Probe */ - do_probe(c_ptr->m_idx); - - dam = 0; - break; - } - /* Death -- instant death */ case GF_DEATH: { if (seen) obvious = TRUE; - if (r_ptr->r_flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { note = " resists."; dam = 0; @@ -4529,17 +4409,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_ACID: { if (seen) obvious = TRUE; - if (r_ptr->flags9 & (RF9_SUSCEP_ACID)) + if (r_ptr->flags & RF_SUSCEP_ACID) { note = " is hit hard."; dam *= 3; - if (seen) r_ptr->r_flags9 |= (RF9_SUSCEP_ACID); } - if (r_ptr->flags3 & (RF3_IM_ACID)) + if (r_ptr->flags & RF_IM_ACID) { note = " resists a lot."; dam /= 9; - if (seen) r_ptr->r_flags3 |= (RF3_IM_ACID); } break; } @@ -4548,17 +4426,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_ELEC: { if (seen) obvious = TRUE; - if (r_ptr->flags9 & (RF9_SUSCEP_ELEC)) + if (r_ptr->flags & RF_SUSCEP_ELEC) { note = " is hit hard."; dam *= 3; - if (seen) r_ptr->r_flags9 |= (RF9_SUSCEP_ELEC); } - if (r_ptr->flags3 & (RF3_IM_ELEC)) + if (r_ptr->flags & RF_IM_ELEC) { note = " resists a lot."; dam /= 9; - if (seen) r_ptr->r_flags3 |= (RF3_IM_ELEC); } break; } @@ -4567,17 +4443,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_FIRE: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_SUSCEP_FIRE)) + if (r_ptr->flags & RF_SUSCEP_FIRE) { note = " is hit hard."; dam *= 3; - if (seen) r_ptr->r_flags3 |= (RF3_SUSCEP_FIRE); } - if (r_ptr->flags3 & (RF3_IM_FIRE)) + if (r_ptr->flags & RF_IM_FIRE) { note = " resists a lot."; dam /= 9; - if (seen) r_ptr->r_flags3 |= (RF3_IM_FIRE); } break; } @@ -4586,17 +4460,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_COLD: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_SUSCEP_COLD)) + if (r_ptr->flags & RF_SUSCEP_COLD) { note = " is hit hard."; dam *= 3; - if (seen) r_ptr->r_flags3 |= (RF3_SUSCEP_COLD); } - if (r_ptr->flags3 & (RF3_IM_COLD)) + if (r_ptr->flags & RF_IM_COLD) { note = " resists a lot."; dam /= 9; - if (seen) r_ptr->r_flags3 |= (RF3_IM_COLD); } break; } @@ -4606,19 +4478,17 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; if (magik(25)) do_pois = (10 + randint(11) + r) / (r + 1); - if (r_ptr->flags9 & (RF9_SUSCEP_POIS)) + if (r_ptr->flags & RF_SUSCEP_POIS) { note = " is hit hard."; dam *= 3; do_pois *= 2; - if (seen) r_ptr->r_flags9 |= (RF9_SUSCEP_POIS); } - if (r_ptr->flags3 & (RF3_IM_POIS)) + if (r_ptr->flags & RF_IM_POIS) { note = " resists a lot."; dam /= 9; do_pois = 0; - if (seen) r_ptr->r_flags3 |= (RF3_IM_POIS); } break; } @@ -4629,7 +4499,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; if (magik(15)) do_pois = (10 + randint(11) + r) / (r + 1); - if ((r_ptr->flags3 & (RF3_NONLIVING)) || (r_ptr->flags3 & (RF3_UNDEAD))) + if ((r_ptr->flags & RF_NONLIVING) || (r_ptr->flags & RF_UNDEAD)) { note = " is immune."; dam = 0; @@ -4643,12 +4513,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_IM_POIS)) + if (r_ptr->flags & RF_IM_POIS) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) r_ptr->r_flags3 |= (RF3_IM_POIS); } else if (randint(3) == 1) do_poly = TRUE; break; @@ -4658,11 +4527,10 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_HELL_FIRE: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_EVIL)) + if (r_ptr->flags & RF_EVIL) { dam *= 2; note = " is hit hard."; - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); } break; } @@ -4671,17 +4539,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_HOLY_FIRE: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_GOOD)) + if (r_ptr->flags & RF_GOOD) { dam = 0; note = " is immune."; - if (seen) r_ptr->r_flags3 |= (RF3_GOOD); } - else if (r_ptr->flags3 & (RF3_EVIL)) + else if (r_ptr->flags & RF_EVIL) { dam *= 2; note = " is hit hard."; - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); } else { @@ -4703,13 +4569,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_PLASMA: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_RES_PLAS)) + if (r_ptr->flags & RF_RES_PLAS) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) - r_ptr->r_flags3 |= (RF3_RES_PLAS); } break; } @@ -4718,25 +4582,21 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_NETHER: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_UNDEAD)) + if (r_ptr->flags & RF_UNDEAD) { note = " is immune."; dam = 0; - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); } - else if (r_ptr->flags3 & (RF3_RES_NETH)) + else if (r_ptr->flags & RF_RES_NETH) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - - if (seen) r_ptr->r_flags3 |= (RF3_RES_NETH); } - else if (r_ptr->flags3 & (RF3_EVIL)) + else if (r_ptr->flags & RF_EVIL) { dam /= 2; note = " resists somewhat."; - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); } break; } @@ -4752,12 +4612,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) note = " is immune."; dam = 0; } - else if (r_ptr->flags3 & (RF3_RES_WATE)) + else if (r_ptr->flags & RF_RES_WATE) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) r_ptr->r_flags3 |= (RF3_RES_WATE); } break; } @@ -4773,12 +4632,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) note = " is immune."; dam = 0; } - else if (r_ptr->flags3 & (RF3_RES_WATE)) + else if (r_ptr->flags & RF_RES_WATE) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) r_ptr->r_flags3 |= (RF3_RES_WATE); } if (who == 0) @@ -4862,8 +4720,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; do_poly = TRUE; do_conf = (5 + randint(11) + r) / (r + 1); - if ((r_ptr->flags4 & (RF4_BR_CHAO)) || - ((r_ptr->flags3 & (RF3_DEMON)) && (randint(3) == 1))) + if ((r_ptr->spells & SF_BR_CHAO) || + ((r_ptr->flags & RF_DEMON) && (randint(3) == 1))) { note = " resists."; dam *= 3; @@ -4878,7 +4736,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; if (magik(33)) do_cut = (10 + randint(15) + r) / (r + 1); - if (r_ptr->flags4 & (RF4_BR_SHAR)) + if (r_ptr->spells & SF_BR_SHAR) { note = " resists."; dam *= 3; @@ -4894,7 +4752,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; if (magik(12)) do_cut = (10 + randint(15) + r) / (r + 1); - if (r_ptr->flags4 & (RF4_BR_SHAR)) + if (r_ptr->spells & SF_BR_SHAR) { note = " resists somewhat."; dam /= 2; @@ -4915,7 +4773,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) } else do_stun = (10 + randint(15) + r) / (r + 1); - if (r_ptr->flags4 & (RF4_BR_SOUN)) + if (r_ptr->spells & SF_BR_SOUN) { note = " resists."; dam *= 2; @@ -4929,13 +4787,13 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; do_conf = (10 + randint(15) + r) / (r + 1); - if (r_ptr->flags4 & (RF4_BR_CONF)) + if (r_ptr->spells & SF_BR_CONF) { note = " resists."; dam *= 2; dam /= (randint(6) + 6); } - else if (r_ptr->flags3 & (RF3_NO_CONF)) + else if (r_ptr->flags & RF_NO_CONF) { note = " resists somewhat."; dam /= 2; @@ -4947,12 +4805,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISENCHANT: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_RES_DISE)) + if (r_ptr->flags & RF_RES_DISE) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) r_ptr->r_flags3 |= (RF3_RES_DISE); } break; } @@ -4961,12 +4818,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_NEXUS: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_RES_NEXU)) + if (r_ptr->flags & RF_RES_NEXU) { note = " resists."; dam *= 3; dam /= (randint(6) + 6); - if (seen) r_ptr->r_flags3 |= (RF3_RES_NEXU); } break; } @@ -5059,7 +4915,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* --hack-- Only stun if a monster fired it */ else do_stun = (randint(15) + r) / (r + 1); - if (r_ptr->flags4 & (RF4_BR_WALL)) + if (r_ptr->spells & SF_BR_WALL) { note = " resists."; dam *= 3; @@ -5072,7 +4928,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_INERTIA: { if (seen) obvious = TRUE; - if (r_ptr->flags4 & (RF4_BR_INER)) + if (r_ptr->spells & SF_BR_INER) { note = " resists."; dam *= 3; @@ -5099,7 +4955,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_TIME: { if (seen) obvious = TRUE; - if (r_ptr->flags4 & (RF4_BR_TIME)) + if (r_ptr->spells & SF_BR_TIME) { note = " resists."; dam *= 3; @@ -5115,17 +4971,15 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_RES_TELE)) + if (r_ptr->flags & RF_RES_TELE) { - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " is unaffected!"; resist_tele = TRUE; } else if (m_ptr->level > randint(100)) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " resists!"; resist_tele = TRUE; } @@ -5134,7 +4988,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (!resist_tele) do_dist = 10; else do_dist = 0; - if (r_ptr->flags4 & (RF4_BR_GRAV)) + if (r_ptr->spells & SF_BR_GRAV) { note = " resists."; dam *= 3; @@ -5145,7 +4999,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { /* 1. slowness */ /* Powerful monsters can resist */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { obvious = FALSE; @@ -5161,7 +5015,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { /* Resist */ @@ -5186,15 +5040,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISINTEGRATE: { if (seen) obvious = TRUE; - if (r_ptr->flags3 & (RF3_HURT_ROCK)) + if (r_ptr->flags & RF_HURT_ROCK) { - if (seen) r_ptr->r_flags3 |= (RF3_HURT_ROCK); note = " loses some skin!"; note_dies = " evaporates!"; dam *= 2; } - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { if (rand_int(m_ptr->level + 10) > rand_int(p_ptr->lev)) { @@ -5207,7 +5060,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_FEAR: { - if (r_ptr->flags3 & (RF3_NO_FEAR)) + if (r_ptr->flags & RF_NO_FEAR) note = " is unaffected."; else set_afraid(p_ptr->afraid + (dam / 2) + randint(dam / 2)); @@ -5220,14 +5073,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_PSI: { if (seen) obvious = TRUE; - if (r_ptr->flags2 & RF2_EMPTY_MIND) + if (r_ptr->flags & RF_EMPTY_MIND) { dam = 0; note = " is immune!"; } - else if ((r_ptr->flags2 & RF2_STUPID) || - (r_ptr->flags2 & RF2_WEIRD_MIND) || - (r_ptr->flags3 & RF3_ANIMAL) || + else if ((r_ptr->flags & RF_STUPID) || + (r_ptr->flags & RF_WEIRD_MIND) || + (r_ptr->flags & RF_ANIMAL) || (m_ptr->level > randint(3 * dam))) { dam /= 3; @@ -5235,8 +5088,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Powerful demons & undead can turn a mindcrafter's * attacks back on them */ - if (((r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags3 & RF3_DEMON)) && + if (((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_DEMON)) && (m_ptr->level > p_ptr->lev / 2) && (randint(2) == 1)) { @@ -5265,7 +5118,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) break; case 3: { - if (r_ptr->flags3 & (RF3_NO_FEAR)) + if (r_ptr->flags & RF_NO_FEAR) note = " is unaffected."; else set_afraid(p_ptr->afraid + 3 + randint(dam)); @@ -5273,7 +5126,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) } default: if (!p_ptr->free_act) - (void)set_paralyzed(randint(dam)); + set_paralyzed(randint(dam)); break; } } @@ -5308,14 +5161,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_PSI_DRAIN: { if (seen) obvious = TRUE; - if (r_ptr->flags2 & RF2_EMPTY_MIND) + if (r_ptr->flags & RF_EMPTY_MIND) { dam = 0; note = " is immune!"; } - else if ((r_ptr->flags2 & RF2_STUPID) || - (r_ptr->flags2 & RF2_WEIRD_MIND) || - (r_ptr->flags3 & RF3_ANIMAL) || + else if ((r_ptr->flags & RF_STUPID) || + (r_ptr->flags & RF_WEIRD_MIND) || + (r_ptr->flags & RF_ANIMAL) || (m_ptr->level > randint(3 * dam))) { dam /= 3; @@ -5325,8 +5178,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) * Powerful demons & undead can turn a mindcrafter's * attacks back on them */ - if (((r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags3 & RF3_DEMON)) && + if (((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_DEMON)) && (m_ptr->level > p_ptr->lev / 2) && (randint(2) == 1)) { @@ -5372,7 +5225,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > 5 + randint(dam))) { /* Resist */ @@ -5396,16 +5249,10 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || - (r_ptr->flags3 & (RF3_NO_CONF)) || + if ((r_ptr->flags & RF_UNIQUE) || + (r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ do_conf = 0; @@ -5413,8 +5260,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) * Powerful demons & undead can turn a mindcrafter's * attacks back on them */ - if (((r_ptr->flags3 & RF3_UNDEAD) || - (r_ptr->flags3 & RF3_DEMON)) && + if (((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_DEMON)) && (m_ptr->level > p_ptr->lev / 2) && (randint(2) == 1)) { @@ -5439,7 +5286,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) break; default: { - if (r_ptr->flags3 & (RF3_NO_FEAR)) + if (r_ptr->flags & RF_NO_FEAR) note = " is unaffected."; else set_afraid(p_ptr->afraid + dam); @@ -5460,7 +5307,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { note = " is in your thrall!"; m_ptr->status = MSTATUS_PET; - if ((r_ptr->flags3 & RF3_ANIMAL) && (!(r_ptr->flags3 & RF3_EVIL))) + if ((r_ptr->flags & RF_ANIMAL) && (!(r_ptr->flags & RF_EVIL))) inc_piety(GOD_YAVANNA, m_ptr->level * 2); } else @@ -5492,19 +5339,17 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; do_stun = (randint(15) + 1) / (r + 1); if (magik(33)) do_cut = (10 + randint(15) + r) / (r + 1); - if (r_ptr->flags3 & (RF3_SUSCEP_COLD)) + if (r_ptr->flags & RF_SUSCEP_COLD) { note = " is hit hard."; dam *= 3; do_cut *= 2; - if (seen) r_ptr->r_flags3 |= (RF3_SUSCEP_COLD); } - if (r_ptr->flags3 & (RF3_IM_COLD)) + if (r_ptr->flags & RF_IM_COLD) { note = " resists a lot."; dam /= 9; do_cut = 0; - if (seen) r_ptr->r_flags3 |= (RF3_IM_COLD); } break; } @@ -5515,20 +5360,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { if (seen) obvious = TRUE; - if ((r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_NONLIVING)) || + if ((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_NONLIVING) || (strchr("Egv", r_ptr->d_char))) { - if (r_ptr->flags3 & (RF3_UNDEAD)) - { - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); - } - if (r_ptr->flags3 & (RF3_DEMON)) - { - if (seen) r_ptr->r_flags3 |= (RF3_DEMON); - } - note = " is unaffected!"; obvious = FALSE; dam = 0; @@ -5541,19 +5377,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DEATH_RAY: { if (seen) obvious = TRUE; - if ((r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags3 & (RF3_NONLIVING))) + if ((r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_NONLIVING)) { - if (r_ptr->flags3 & (RF3_UNDEAD)) - { - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); - } - note = " is immune."; obvious = FALSE; dam = 0; } - else if (((r_ptr->flags1 & (RF1_UNIQUE)) && + else if (((r_ptr->flags & RF_UNIQUE) && (randint(888) != 666)) || (((m_ptr->level + randint(20)) > randint((dam) + randint(10))) && randint(100) != 66 )) @@ -5577,7 +5408,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_poly = TRUE; /* Powerful monsters can resist */ - if ((r_ptr->flags1 & RF1_UNIQUE) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { @@ -5668,7 +5499,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Powerful monsters can resist */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { note = " is unaffected!"; @@ -5694,15 +5525,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags3 & (RF3_NO_SLEEP)) || + if ((r_ptr->flags & RF_NO_SLEEP) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_SLEEP)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_SLEEP); - } - /* No obvious effect */ note = " is unaffected!"; obvious = FALSE; @@ -5726,7 +5551,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { note = " is unaffected!"; @@ -5753,15 +5578,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Attempt a saving throw */ if ((m_ptr->mflag & MFLAG_QUEST) || - (r_ptr->flags3 & RF3_NO_CONF) || + (r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 5)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ /* No obvious effect */ note = " is unaffected!"; @@ -5777,7 +5596,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { note = " suddenly seems friendly!"; m_ptr->status = MSTATUS_FRIEND; - if ((r_ptr->flags3 & RF3_ANIMAL) && (!(r_ptr->flags3 & RF3_EVIL))) + if ((r_ptr->flags & RF_ANIMAL) && (!(r_ptr->flags & RF_EVIL))) inc_piety(GOD_YAVANNA, m_ptr->level * 2); } } @@ -5796,15 +5615,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Attempt a saving throw */ if ((m_ptr->mflag & MFLAG_QUEST) || - (r_ptr->flags3 & RF3_NO_CONF) || + (r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 5)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ /* No obvious effect */ note = " is unaffected!"; @@ -5822,7 +5635,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (can_create_companion()) m_ptr->status = MSTATUS_COMPANION; else m_ptr->status = MSTATUS_PET; - if ((r_ptr->flags3 & RF3_ANIMAL) && (!(r_ptr->flags3 & RF3_EVIL))) + if ((r_ptr->flags & RF_ANIMAL) && (!(r_ptr->flags & RF_EVIL))) inc_piety(GOD_YAVANNA, m_ptr->level * 2); } } @@ -5838,9 +5651,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & RF1_UNIQUE) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || - (!(r_ptr->flags3 & RF3_UNDEAD)) || + (!(r_ptr->flags & RF_UNDEAD)) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { /* Resist */ @@ -5869,9 +5682,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & RF1_UNIQUE) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || - (!(r_ptr->flags1 & RF1_NEVER_MOVE)) || + (!(r_ptr->flags & RF_NEVER_MOVE)) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { /* Resist */ @@ -5900,18 +5713,12 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || - (!(r_ptr->flags3 & (RF3_ANIMAL))) || - (r_ptr->flags3 & (RF3_NO_CONF)) || + (!(r_ptr->flags & RF_ANIMAL)) || + (r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ /* No obvious effect */ note = " is unaffected!"; @@ -5939,17 +5746,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || - (!(r_ptr->flags3 & (RF3_DEMON))) || + (!(r_ptr->flags & RF_DEMON)) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ /* No obvious effect */ note = " is unaffected!"; @@ -5979,15 +5780,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_conf = damroll(3, (dam / 2)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags3 & (RF3_NO_CONF)) || + if ((r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ do_conf = 0; @@ -6032,15 +5827,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_conf = damroll(3, (dam / 2)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags3 & (RF3_NO_CONF)) || + if ((r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ do_conf = 0; @@ -6078,7 +5867,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { /* Resist */ @@ -6090,7 +5879,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) } /* Non_living resists */ - if (r_ptr->flags3 & (RF3_NONLIVING)) + if (r_ptr->flags & RF_NONLIVING) { /* Resist */ do_stun = 0; @@ -6112,15 +5901,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_conf = damroll(3, (dam / 2)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags3 & (RF3_NO_CONF)) || + if ((r_ptr->flags & RF_NO_CONF) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { - /* Memorize a flag */ - if (r_ptr->flags3 & (RF3_NO_CONF)) - { - if (seen) r_ptr->r_flags3 |= (RF3_NO_CONF); - } - /* Resist */ do_conf = 0; @@ -6149,14 +5932,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_LITE_WEAK: { /* Hurt by light */ - if (r_ptr->flags3 & (RF3_HURT_LITE)) + if (r_ptr->flags & RF_HURT_LITE) { /* Obvious effect */ if (seen) obvious = TRUE; - /* Memorize the effects */ - if (seen) r_ptr->r_flags3 |= (RF3_HURT_LITE); - /* Special effect */ note = " cringes from the light!"; note_dies = " shrivels away in the light!"; @@ -6178,15 +5958,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_LITE: { if (seen) obvious = TRUE; - if (r_ptr->flags4 & (RF4_BR_LITE)) + if (r_ptr->spells & SF_BR_LITE) { note = " resists."; dam *= 2; dam /= (randint(6) + 6); } - else if (r_ptr->flags3 & (RF3_HURT_LITE)) + else if (r_ptr->flags & RF_HURT_LITE) { - if (seen) r_ptr->r_flags3 |= (RF3_HURT_LITE); note = " cringes from the light!"; note_dies = " shrivels away in the light!"; dam *= 2; @@ -6201,9 +5980,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Likes darkness... */ - if ((r_ptr->flags4 & (RF4_BR_DARK)) || - (r_ptr->flags3 & RF3_ORC) || - (r_ptr->flags3 & RF3_HURT_LITE)) + if ((r_ptr->spells & SF_BR_DARK) || + (r_ptr->flags & RF_ORC) || + (r_ptr->flags & RF_HURT_LITE)) { note = " resists."; dam *= 2; @@ -6217,14 +5996,11 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_KILL_WALL: { /* Hurt by rock remover */ - if (r_ptr->flags3 & (RF3_HURT_ROCK)) + if (r_ptr->flags & RF_HURT_ROCK) { /* Notice effect */ if (seen) obvious = TRUE; - /* Memorize the effects */ - if (seen) r_ptr->r_flags3 |= (RF3_HURT_ROCK); - /* Cute little message */ note = " loses some skin!"; note_dies = " dissolves!"; @@ -6245,23 +6021,21 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_AWAY_UNDEAD: { - if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */ + if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */ /* Only affect undead */ - if (r_ptr->flags3 & (RF3_UNDEAD)) + if (r_ptr->flags & RF_UNDEAD) { bool_ resists_tele = FALSE; - if (r_ptr->flags3 & (RF3_RES_TELE)) + if (r_ptr->flags & RF_RES_TELE) { - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " is unaffected!"; resists_tele = TRUE; } else if (m_ptr->level > randint(100)) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " resists!"; resists_tele = TRUE; } @@ -6270,7 +6044,6 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (!resists_tele) { if (seen) obvious = TRUE; - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); do_dist = dam; } } @@ -6291,23 +6064,21 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Teleport evil (Use "dam" as "power") */ case GF_AWAY_EVIL: { - if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */ + if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */ /* Only affect evil */ - if (r_ptr->flags3 & (RF3_EVIL)) + if (r_ptr->flags & RF_EVIL) { bool_ resists_tele = FALSE; - if (r_ptr->flags3 & (RF3_RES_TELE)) + if (r_ptr->flags & RF_RES_TELE) { - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " is unaffected!"; resists_tele = TRUE; } else if (m_ptr->level > randint(100)) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " resists!"; resists_tele = TRUE; } @@ -6316,7 +6087,6 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (!resists_tele) { if (seen) obvious = TRUE; - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); do_dist = dam; } } @@ -6339,18 +6109,16 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) { bool_ resists_tele = FALSE; - if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */ - if (r_ptr->flags3 & (RF3_RES_TELE)) + if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */ + if (r_ptr->flags & RF_RES_TELE) { - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " is unaffected!"; resists_tele = TRUE; } else if (m_ptr->level > randint(100)) { - if (seen) r_ptr->r_flags3 |= RF3_RES_TELE; note = " resists!"; resists_tele = TRUE; } @@ -6375,11 +6143,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_TURN_UNDEAD: { /* Only affect undead */ - if (r_ptr->flags3 & (RF3_UNDEAD)) + if (r_ptr->flags & RF_UNDEAD) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); - /* Obvious */ if (seen) obvious = TRUE; @@ -6413,11 +6178,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_TURN_EVIL: { /* Only affect evil */ - if (r_ptr->flags3 & (RF3_EVIL)) + if (r_ptr->flags & RF_EVIL) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); - /* Obvious */ if (seen) obvious = TRUE; @@ -6457,8 +6219,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_fear = damroll(3, (dam / 2)) + 1; /* Attempt a saving throw */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || - (r_ptr->flags3 & (RF3_NO_FEAR)) || + if ((r_ptr->flags & RF_UNIQUE) || + (r_ptr->flags & RF_NO_FEAR) || (m_ptr->level > randint((dam - 10) < 1 ? 1 : (dam - 10)) + 10)) { /* No obvious effect */ @@ -6477,11 +6239,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISP_UNDEAD: { /* Only affect undead */ - if (r_ptr->flags3 & (RF3_UNDEAD)) + if (r_ptr->flags & RF_UNDEAD) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_UNDEAD); - /* Obvious */ if (seen) obvious = TRUE; @@ -6508,11 +6267,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISP_EVIL: { /* Only affect evil */ - if (r_ptr->flags3 & (RF3_EVIL)) + if (r_ptr->flags & RF_EVIL) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_EVIL); - /* Obvious */ if (seen) obvious = TRUE; @@ -6538,11 +6294,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISP_GOOD: { /* Only affect good */ - if (r_ptr->flags3 & (RF3_GOOD)) + if (r_ptr->flags & RF_GOOD) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_GOOD); - /* Obvious */ if (seen) obvious = TRUE; @@ -6568,8 +6321,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISP_LIVING: { /* Only affect non-undead */ - if (!(r_ptr->flags3 & (RF3_UNDEAD)) && - !(r_ptr->flags3 & (RF3_NONLIVING))) + if (!(r_ptr->flags & RF_UNDEAD) && + !(r_ptr->flags & RF_NONLIVING)) { /* Obvious */ if (seen) obvious = TRUE; @@ -6596,11 +6349,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_DISP_DEMON: { /* Only affect demons */ - if (r_ptr->flags3 & (RF3_DEMON)) + if (r_ptr->flags & RF_DEMON) { - /* Learn about type */ - if (seen) r_ptr->r_flags3 |= (RF3_DEMON); - /* Obvious */ if (seen) obvious = TRUE; @@ -6666,9 +6416,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if (seen) obvious = TRUE; /* Check race */ - if ((r_ptr->flags1 & (RF1_UNIQUE)) || + if ((r_ptr->flags & RF_UNIQUE) || (m_ptr->mflag & MFLAG_QUEST) || - (!(r_ptr->flags3 & (RF3_DEMON)))) + (!(r_ptr->flags & RF_DEMON))) { /* No obvious effect */ note = " is unaffected!"; @@ -6685,7 +6435,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_CORPSE)); /* Unique corpses are unique */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { object_aware(i_ptr); i_ptr->name1 = 201; @@ -6712,7 +6462,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) case GF_INSTA_DEATH: { - if (magik(95) && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags3 & RF3_UNDEAD) && !(r_ptr->flags3 & RF3_NONLIVING)) { + if (magik(95) && !(r_ptr->flags & RF_UNIQUE) && !(r_ptr->flags & RF_UNDEAD) && !(r_ptr->flags & RF_NONLIVING)) { /* Kill outright, but reduce exp. */ m_ptr->level = m_ptr->level / 3; dam = 32535; /* Should be enough */ @@ -6737,7 +6487,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* "Unique" monsters cannot be polymorphed */ - if (r_ptr->flags1 & (RF1_UNIQUE)) do_poly = FALSE; + if (r_ptr->flags & RF_UNIQUE) do_poly = FALSE; /* * "Quest" monsters cannot be polymorphed @@ -6746,7 +6496,7 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) do_poly = FALSE; /* "Unique" monsters can only be "killed" by the player unless they are player's friends */ - if ((r_ptr->flags1 & RF1_UNIQUE) && (m_ptr->status <= MSTATUS_NEUTRAL_P)) + if ((r_ptr->flags & RF_UNIQUE) && (m_ptr->status <= MSTATUS_NEUTRAL_P)) { /* Uniques may only be killed by the player */ if (who && (who != -2) && (dam > m_ptr->hp)) dam = m_ptr->hp; @@ -6760,14 +6510,14 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) if ((who > 0) && (dam > m_ptr->hp)) dam = m_ptr->hp; } - if (do_pois && (!(r_ptr->flags3 & RF3_IM_POIS)) && (!(r_ptr->flags3 & RF4_BR_POIS)) && hurt_monster(m_ptr)) + if (do_pois && (r_ptr->flags & RF_IM_POIS).empty() && (r_ptr->spells & SF_BR_POIS).empty() && hurt_monster(m_ptr)) { if (m_ptr->poisoned) note = " is more poisoned."; else note = " is poisoned."; m_ptr->poisoned += do_pois; } - if (do_cut && (!(r_ptr->flags4 & RF4_BR_WALL)) && hurt_monster(m_ptr)) + if (do_cut && (!(r_ptr->spells & SF_BR_WALL)) && hurt_monster(m_ptr)) { if (m_ptr->bleeding) note = " bleeds more strongly."; else note = " starts bleeding."; @@ -6900,8 +6650,8 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Sound and Impact breathers never stun */ else if (do_stun && - !(r_ptr->flags4 & (RF4_BR_SOUN)) && - !(r_ptr->flags4 & (RF4_BR_WALL)) && hurt_monster(m_ptr)) + !(r_ptr->spells & SF_BR_SOUN) && + !(r_ptr->spells & SF_BR_WALL) && hurt_monster(m_ptr)) { /* Obvious */ if (seen) obvious = TRUE; @@ -6924,9 +6674,9 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Confusion and Chaos breathers (and sleepers) never confuse */ else if (do_conf && - !(r_ptr->flags3 & (RF3_NO_CONF)) && - !(r_ptr->flags4 & (RF4_BR_CONF)) && - !(r_ptr->flags4 & (RF4_BR_CHAO)) && hurt_monster(m_ptr)) + !(r_ptr->flags & RF_NO_CONF) && + !(r_ptr->spells & SF_BR_CONF) && + !(r_ptr->spells & SF_BR_CHAO) && hurt_monster(m_ptr)) { /* Obvious */ if (seen) obvious = TRUE; @@ -7006,9 +6756,6 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) /* Take note */ if ((fear || do_fear) && (m_ptr->ml)) { - /* Sound */ - sound(SOUND_FLEE); - /* Message */ msg_format("%^s flees in terror!", m_name); } @@ -7047,10 +6794,6 @@ bool_ project_m(int who, int r, int y, int x, int dam, int typ) } -/* Is the spell unsafe for the player ? */ -bool_ unsafe = FALSE; - - /* * Helper function for "project()" below. * @@ -7072,6 +6815,10 @@ bool_ unsafe = FALSE; */ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad) { + 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 k = 0, do_move = 0, a = 0, b = 0, x1 = 0, y1 = 0; /* Hack -- assume obvious */ @@ -7100,7 +6847,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad if ((x != p_ptr->px) || (y != p_ptr->py)) return (FALSE); /* Player cannot hurt himself */ - if ((!who) && (!unsafe)) return (FALSE); + if (!who) return (FALSE); /* Bolt attack from a monster */ if ((!a_rad) && get_skill(SKILL_DODGE) && (who > 0)) @@ -7141,7 +6888,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad project(0, 0, t_y, t_x, dam, typ, (PROJECT_STOP | PROJECT_KILL)); - disturb(1); + disturb(); return TRUE; } @@ -7156,9 +6903,6 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad /* If the player is blind, be more descriptive */ if (blind) fuzzy = TRUE; - /* If the player is hit by a trap, be more descritive */ - if (who == -2) fuzzy = TRUE; - /* Did ``God'' do it? */ if (who == -99) { @@ -7174,7 +6918,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad /* Did the dungeon do it? */ if (who == -100) { - sprintf(killer, "%s", d_info[dungeon_type].name); + sprintf(killer, "%s", d_info[dungeon_type].name.c_str()); } if (who == -101) { @@ -7193,12 +6937,6 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad monster_desc(killer, m_ptr, 0x88); } - if (who == -2) - { - sprintf(killer, "%s", - t_info[cave[p_ptr->py][p_ptr->px].t_idx].name); - } - /* Analyze the damage */ switch (typ) { @@ -7331,7 +7069,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad if (!p_ptr->resist_sound) { int k = (randint((dam > 40) ? 35 : (dam * 3 / 4 + 5))); - (void)set_stun(p_ptr->stun + k); + set_stun(p_ptr->stun + k); } if (!(p_ptr->resist_fire || @@ -7416,11 +7154,11 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + rand_int(20) + 10); + set_confused(p_ptr->confused + rand_int(20) + 10); } if (!p_ptr->resist_chaos) { - (void)set_image(p_ptr->image + randint(10)); + set_image(p_ptr->image + randint(10)); } if (!p_ptr->resist_neth && !p_ptr->resist_chaos) { @@ -7459,7 +7197,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } else { - (void)set_cut(p_ptr->cut + dam); + set_cut(p_ptr->cut + dam); } if ((!p_ptr->resist_shard) || (randint(13) == 1)) @@ -7483,7 +7221,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad else { int k = (randint((dam > 90) ? 35 : (dam / 3 + 5))); - (void)set_stun(p_ptr->stun + k); + set_stun(p_ptr->stun + k); } if ((!p_ptr->resist_sound) || (randint(13) == 1)) @@ -7506,7 +7244,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } if (!p_ptr->resist_conf) { - (void)set_confused(p_ptr->confused + randint(20) + 10); + set_confused(p_ptr->confused + randint(20) + 10); } take_hit(dam, killer); break; @@ -7523,7 +7261,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } else { - (void)apply_disenchant(0); + apply_disenchant(0); } take_hit(dam, killer); break; @@ -7552,7 +7290,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad if (fuzzy) msg_print("You are hit by kinetic force!"); if (!p_ptr->resist_sound) { - (void)set_stun(p_ptr->stun + randint(20)); + set_stun(p_ptr->stun + randint(20)); /* * If fired by player, try pushing monster. * First get vector from player to monster. @@ -7642,7 +7380,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad if (fuzzy) msg_print("There is an explosion!"); if (!p_ptr->resist_sound) { - (void)set_stun(p_ptr->stun + randint(20)); + set_stun(p_ptr->stun + randint(20)); } if (p_ptr->resist_shard) { @@ -7650,7 +7388,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } else { - (void)set_cut(p_ptr-> cut + ( dam / 2) ); + set_cut(p_ptr-> cut + ( dam / 2) ); } if ((!p_ptr->resist_shard) || (randint(12) == 1)) @@ -7666,7 +7404,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad case GF_INERTIA: { if (fuzzy) msg_print("You are hit by something slow!"); - (void)set_slow(p_ptr->slow + rand_int(4) + 4); + set_slow(p_ptr->slow + rand_int(4) + 4); take_hit(dam, killer); break; } @@ -7682,7 +7420,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } else if (!blind && !p_ptr->resist_blind) { - (void)set_blind(p_ptr->blind + randint(5) + 2); + set_blind(p_ptr->blind + randint(5) + 2); } if (p_ptr->sensible_lite) { @@ -7717,7 +7455,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad } else if (!blind && !p_ptr->resist_blind) { - (void)set_blind(p_ptr->blind + randint(5) + 2); + set_blind(p_ptr->blind + randint(5) + 2); } if (p_ptr->wraith_form) hp_player(dam); else take_hit(dam, killer); @@ -7812,33 +7550,29 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad /* Gravity -- stun plus slowness plus teleport */ case GF_GRAVITY: { - if (dungeon_flags2 & DF2_NO_TELEPORT) break; /* No teleport on special levels */ + if (dungeon_flags & DF_NO_TELEPORT) break; /* No teleport on special levels */ if (fuzzy) msg_print("You are hit by something heavy!"); msg_print("Gravity warps around you."); - if (!unsafe) - { - teleport_player(5); - if (!p_ptr->ffall) - (void)set_slow(p_ptr->slow + rand_int(4) + 4); - if (!(p_ptr->resist_sound || p_ptr->ffall)) - { - int k = (randint((dam > 90) ? 35 : (dam / 3 + 5))); - (void)set_stun(p_ptr->stun + k); - } - if (p_ptr->ffall) - { - dam = (dam * 2) / 3; - } - if ((!p_ptr->ffall) || (randint(13) == 1)) - { - inven_damage(set_cold_destroy, 2); - } + teleport_player(5); + if (!p_ptr->ffall) + set_slow(p_ptr->slow + rand_int(4) + 4); + if (!(p_ptr->resist_sound || p_ptr->ffall)) + { + int k = (randint((dam > 90) ? 35 : (dam / 3 + 5))); + set_stun(p_ptr->stun + k); + } + if (p_ptr->ffall) + { + dam = (dam * 2) / 3; + } - take_hit(dam, killer); + if ((!p_ptr->ffall) || (randint(13) == 1)) + { + inven_damage(set_cold_destroy, 2); } - else - teleport_player(dam); + + take_hit(dam, killer); break; } @@ -7853,7 +7587,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad case GF_OLD_HEAL: { if (fuzzy) msg_print("You are hit by something invigorating!"); - (void)hp_player(dam); + hp_player(dam); dam = 0; break; } @@ -7861,7 +7595,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad case GF_OLD_SPEED: { if (fuzzy) msg_print("You are hit by something!"); - (void)set_fast(p_ptr->fast + randint(5), 10); + set_fast(p_ptr->fast + randint(5), 10); dam = 0; break; } @@ -7869,7 +7603,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad case GF_OLD_SLOW: { if (fuzzy) msg_print("You are hit by something slow!"); - (void)set_slow(p_ptr->slow + rand_int(4) + 4); + set_slow(p_ptr->slow + rand_int(4) + 4); break; } @@ -7911,11 +7645,11 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad cold_dam(dam, killer); if (!p_ptr->resist_shard) { - (void)set_cut(p_ptr->cut + damroll(5, 8)); + set_cut(p_ptr->cut + damroll(5, 8)); } if (!p_ptr->resist_sound) { - (void)set_stun(p_ptr->stun + randint(15)); + set_stun(p_ptr->stun + randint(15)); } if ((!(p_ptr->resist_cold || p_ptr->oppose_cold)) || (randint(12) == 1)) @@ -7926,14 +7660,6 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad break; } - /* Knowledge */ - case GF_IDENTIFY: - { - if (fuzzy) msg_print("You are hit by pure knowledge!"); - self_knowledge(NULL); - break; - } - /* Psi -- ESP */ case GF_PSI: { @@ -8041,7 +7767,7 @@ static bool_ project_p(int who, int r, int y, int x, int dam, int typ, int a_rad /* Disturb */ - disturb(1); + disturb(); /* Return "Anything seen?" */ @@ -8204,7 +7930,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) int y_saver, x_saver; /* For reflecting monsters */ - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); /* Assume the player sees nothing */ bool_ notice = FALSE; @@ -8359,10 +8085,16 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) /* Visual effects */ print_rel(c, a, y, x); move_cursor_relative(y, x); - if (fresh_before) Term_fresh(); + if (options->fresh_before) + { + Term_fresh(); + } sleep_for(milliseconds(msec)); lite_spot(y, x); - if (fresh_before) Term_fresh(); + if (options->fresh_before) + { + Term_fresh(); + } /* Display "beam" grids */ if (flg & (PROJECT_BEAM)) @@ -8499,7 +8231,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) move_cursor_relative(y2, x2); /* Flush each "radius" seperately */ - if (fresh_before) Term_fresh(); + if (options->fresh_before) Term_fresh(); /* Delay (efficiently) */ if (visual || drawn) @@ -8529,7 +8261,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) move_cursor_relative(y2, x2); /* Flush the explosion */ - if (fresh_before) Term_fresh(); + if (options->fresh_before) Term_fresh(); } } @@ -8627,7 +8359,7 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) { auto ref_ptr = m_list[cave[y][x].m_idx].race(); - if ((ref_ptr->flags2 & (RF2_REFLECTING)) && (randint(10) != 1) + if ((ref_ptr->flags & RF_REFLECTING) && (randint(10) != 1) && (dist_hack > 1)) { int t_y, t_x; @@ -8653,7 +8385,6 @@ bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg) if (m_list[cave[y][x].m_idx].ml) { msg_print("The attack bounces!"); - ref_ptr->r_flags2 |= RF2_REFLECTING; } project(cave[y][x].m_idx, 0, t_y, t_x, dam, typ, flg); @@ -8780,7 +8511,6 @@ bool_ potion_smash_effect(int who, int y, int x, int o_sval) case SV_POTION_AUGMENTATION: case SV_POTION_ENLIGHTENMENT: case SV_POTION_STAR_ENLIGHTENMENT: - case SV_POTION_SELF_KNOWLEDGE: case SV_POTION_EXPERIENCE: case SV_POTION_RESISTANCE: case SV_POTION_INVULNERABILITY: @@ -8871,12 +8601,12 @@ bool_ potion_smash_effect(int who, int y, int x, int o_sval) ; } - (void) project(who, radius, y, x, dam, dt, + project(who, radius, y, x, dam, dt, (PROJECT_JUMP | PROJECT_ITEM | PROJECT_KILL)); // Silence warning. We may want to introuce an actual implementation // and I want to preserve the original "ident" values if we do so. - (void) ident; + ident; /* XXX those potions that explode need to become "known" */ return angry; @@ -9022,18 +8752,12 @@ static void describe_attack_fully(int type, char* r) case GF_KILL_DOOR: strcpy(r, "door destruction"); break; - case GF_KILL_TRAP: - strcpy(r, "trap destruction"); - break; case GF_STONE_WALL: strcpy(r, "wall creation"); break; case GF_MAKE_DOOR: strcpy(r, "door creation"); break; - case GF_MAKE_TRAP: - strcpy(r, "trap creation"); - break; case GF_DESTRUCTION: strcpy(r, "destruction"); break; @@ -9048,8 +8772,7 @@ static void describe_attack_fully(int type, char* r) * Give a randomly-generated spell a name. * Note that it only describes the first effect! */ - -static void name_spell(random_spell* s_ptr) +std::string name_spell(random_spell const *s_ptr) { char buff[30]; cptr buff2 = "???"; @@ -9080,141 +8803,114 @@ static void name_spell(random_spell* s_ptr) } describe_attack_fully(s_ptr->GF, buff); - strnfmt(s_ptr->name, 30, "%s - %s", buff2, buff); + return fmt::format("{:s} - {:s}", buff2, buff); } void generate_spell(int plev) { - random_spell* rspell; - int dice, sides, chance, mana, power; - bool_ destruc_gen = FALSE; - bool_ simple_gen = TRUE; - bool_ ball_desc = FALSE; - - if (spell_num == MAX_SPELLS) return; - - rspell = &random_spells[spell_num]; - - power = rand_int(5); - - dice = plev / 2; - sides = plev; - mana = plev; - - /* Make the spell more or less powerful. */ - dice += power; - sides += power; - mana += (plev * power) / 15; + auto &random_spells = p_ptr->random_spells; - /* Stay within reasonable bounds. */ - if (dice < 1) dice = 1; + assert(random_spells.size() < MAX_SPELLS); - if (sides < 5) sides = 5; + bool destruc_gen = false; + bool simple_gen = true; + bool ball_desc = false; - if (mana < 1) mana = 1; + // Calculate power, dice, etc. + int const power = rand_int(5); + int const dice = std::max(1, (plev / 2) + power); + int const sides = std::max(5, plev + power); + int const mana = std::max(1, plev + (plev * power) / 15); - rspell->level = plev; - rspell->mana = mana; - rspell->untried = TRUE; + // Create spell + random_spell rspell; + rspell.level = plev; + rspell.mana = mana; + rspell.untried = true; - /* Spells are always maximally destructive. */ - rspell->proj_flags = PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID; + // Spells are always maximally destructive + rspell.proj_flags = PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID; - chance = randint(100); + // Roll the dice as to the "type" of spell + int chance = randint(100); - /* Hack -- Always start with Magic Missile or derivative at lev. 1 */ + // We always start with Magic Missile or derivative at level 1 if (plev == 1 || chance < 25) { - rspell->proj_flags |= PROJECT_STOP; - /* Swap dice and sides for better damage */ - rspell->dam_dice = sides; - rspell->dam_sides = dice; - rspell->radius = 0; + // Swap dice and sides for better damage + rspell.proj_flags |= PROJECT_STOP; + rspell.dam_dice = sides; + rspell.dam_sides = dice; + rspell.radius = 0; } else if (chance < 50) { - rspell->proj_flags |= PROJECT_BEAM; - rspell->dam_dice = dice; - rspell->dam_sides = sides; - rspell->radius = 0; + rspell.proj_flags |= PROJECT_BEAM; + rspell.dam_dice = dice; + rspell.dam_sides = sides; + rspell.radius = 0; } else if (chance < 76) { - rspell->proj_flags |= PROJECT_STOP; - rspell->radius = dice / 3; - rspell->dam_dice = dice; - rspell->dam_sides = sides; - ball_desc = TRUE; + rspell.proj_flags |= PROJECT_STOP; + rspell.radius = dice / 3; + rspell.dam_dice = dice; + rspell.dam_sides = sides; + ball_desc = true; } else if (chance < 83) { - rspell->proj_flags |= PROJECT_BLAST; - rspell->radius = sides / 3; - rspell->dam_dice = dice; - rspell->dam_sides = sides; + rspell.proj_flags |= PROJECT_BLAST; + rspell.radius = sides / 3; + rspell.dam_dice = dice; + rspell.dam_sides = sides; - destruc_gen = TRUE; - simple_gen = FALSE; + destruc_gen = true; + simple_gen = false; } else if (chance < 90) { - rspell->proj_flags |= PROJECT_METEOR_SHOWER; - /* Area effect spells do way less damage "per shot" */ - rspell->dam_dice = dice / 5; - rspell->dam_sides = sides / 5; - rspell->radius = sides / 3; - if (rspell->radius < 4) rspell->radius = 4; + // Area effect spells do way less damage "per shot" + rspell.proj_flags |= PROJECT_METEOR_SHOWER; + rspell.dam_dice = dice / 5; + rspell.dam_sides = sides / 5; + rspell.radius = std::max(4, sides / 3); - destruc_gen = TRUE; + destruc_gen = true; } else { - rspell->proj_flags |= PROJECT_VIEWABLE; - /* View spells do less damage */ - rspell->dam_dice = dice; - rspell->dam_sides = sides / 2; + // View spells do less damage + rspell.proj_flags |= PROJECT_VIEWABLE; + rspell.dam_dice = dice; + rspell.dam_sides = sides / 2; } - /* Both a destructive and a simple spell requested -- - * pick one or the other. */ + // Both a destructive and a simple spell requested; pick one or the other if (destruc_gen && simple_gen) { if (magik(25)) { - simple_gen = FALSE; + simple_gen = false; } else { - destruc_gen = FALSE; + destruc_gen = false; } } - /* Pick a simple spell */ + // Choose the appropriate GF if (simple_gen) { - rspell->GF = attack_types[rand_int(25)]; - } - /* Pick a destructive spell */ - else - { - rspell->GF = destructive_attack_types[rand_int(10)]; - } - - /* Give the spell a name. */ - name_spell(rspell); - if (ball_desc) - { - /* 30 character limit on the string! */ - sprintf(rspell->desc, "Dam: %d, Rad: %d, Pow: %d", - sides, dice, power); + rspell.GF = attack_types[rand_int(25)]; } else { - sprintf(rspell->desc, "Damage: %dd%d, Power: %d", - dice, sides, power); + rspell.GF = destructive_attack_types[rand_int(10)]; } - spell_num++; + // Add + random_spells.emplace_back(rspell); } /* diff --git a/src/spells1.hpp b/src/spells1.hpp index 5512063f..ec8f2cc9 100644 --- a/src/spells1.hpp +++ b/src/spells1.hpp @@ -1,32 +1,35 @@ #pragma once +#include <string> + #include "h-basic.h" +#include "random_spell_fwd.hpp" -extern byte spell_color(int type); -extern s16b poly_r_idx(int r_idx); -extern void get_pos_player(int dis, int *ny, int *nx); +byte spell_color(int type); +s16b poly_r_idx(int r_idx); +void get_pos_player(int dis, int *ny, int *nx); extern bool_ teleport_player_bypass; -extern void teleport_player_directed(int rad, int dir); -extern void teleport_away(int m_idx, int dis); -extern void teleport_player(int dis); -extern void teleport_player_to(int ny, int nx); -extern void teleport_monster_to(int m_idx, int ny, int nx); -extern void teleport_player_level(void); -extern void recall_player(int d, int f); -extern void take_hit(int damage, cptr kb_str); -extern void take_sanity_hit(int damage, cptr hit_from); -extern void acid_dam(int dam, cptr kb_str); -extern void elec_dam(int dam, cptr kb_str); -extern void fire_dam(int dam, cptr kb_str); -extern void cold_dam(int dam, cptr kb_str); -extern bool_ dec_stat(int stat, int amount, int mode); -extern bool_ res_stat(int stat, bool_ full); -extern bool_ apply_disenchant(int mode); -extern bool_ project_m(int who, int r, int y, int x, int dam, int typ); -extern bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg); -extern bool_ potion_smash_effect(int who, int y, int x, int o_sval); -extern void do_poly_self(void); -extern void corrupt_player(void); -extern void generate_spell(int plev); -extern bool_ unsafe; -extern s16b do_poly_monster(int y, int x); +void teleport_player_directed(int rad, int dir); +void teleport_away(int m_idx, int dis); +void teleport_player(int dis); +void teleport_player_to(int ny, int nx); +void teleport_monster_to(int m_idx, int ny, int nx); +void teleport_player_level(); +void recall_player(int d, int f); +void take_hit(int damage, cptr kb_str); +void take_sanity_hit(int damage, cptr hit_from); +void acid_dam(int dam, cptr kb_str); +void elec_dam(int dam, cptr kb_str); +void fire_dam(int dam, cptr kb_str); +void cold_dam(int dam, cptr kb_str); +bool_ dec_stat(int stat, int amount, int mode); +bool_ res_stat(int stat, bool_ full); +bool_ apply_disenchant(int mode); +bool_ project_m(int who, int r, int y, int x, int dam, int typ); +bool_ project(int who, int rad, int y, int x, int dam, int typ, int flg); +bool_ potion_smash_effect(int who, int y, int x, int o_sval); +void do_poly_self(); +void corrupt_player(); +std::string name_spell(random_spell const *); +void generate_spell(int plev); +s16b do_poly_monster(int y, int x); diff --git a/src/spells2.cc b/src/spells2.cc index 08a643c9..c0d435ea 100644 --- a/src/spells2.cc +++ b/src/spells2.cc @@ -12,22 +12,29 @@ #include "cave_type.hpp" #include "cmd1.hpp" #include "cmd7.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hook_identify_in.hpp" #include "hooks.hpp" #include "melee2.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 "notes.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "object_type.hpp" #include "options.hpp" +#include "player_race_flag.hpp" #include "player_type.hpp" #include "skills.hpp" #include "spells1.hpp" @@ -72,8 +79,8 @@ void grow_things(s16b type, int rad) for (a = 0; a < rad * rad + 11; a++) { - i = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; - j = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; + i = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; + j = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; if (!in_bounds(p_ptr->py + j, p_ptr->px + i)) continue; if (distance(p_ptr->py, p_ptr->px, p_ptr->py + j, p_ptr->px + i) > rad) continue; @@ -90,17 +97,19 @@ void grow_things(s16b type, int rad) */ void grow_trees(int rad) { + auto const &f_info = game->edit_data.f_info; + int a, i, j; for (a = 0; a < rad * rad + 11; a++) { - i = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; - j = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; + i = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; + j = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; if (!in_bounds(p_ptr->py + j, p_ptr->px + i)) continue; if (distance(p_ptr->py, p_ptr->px, p_ptr->py + j, p_ptr->px + i) > rad) continue; - if (cave_clean_bold(p_ptr->py + j, p_ptr->px + i) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_SUPPORT_GROWTH)) + if (cave_clean_bold(p_ptr->py + j, p_ptr->px + i) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags & FF_SUPPORT_GROWTH)) { cave_set_feat(p_ptr->py + j, p_ptr->px + i, FEAT_TREES); } @@ -112,17 +121,19 @@ void grow_trees(int rad) */ void grow_grass(int rad) { + auto const &f_info = game->edit_data.f_info; + int a, i, j; for (a = 0; a < rad * rad + 11; a++) { - i = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; - j = (Rand_mod((rad * 2) + 1)-rad + Rand_mod((rad * 2) + 1)-rad) / 2; + i = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; + j = (rand_int((rad * 2) + 1)-rad + rand_int((rad * 2) + 1)-rad) / 2; if (!in_bounds(p_ptr->py + j, p_ptr->px + i)) continue; if (distance(p_ptr->py, p_ptr->px, p_ptr->py + j, p_ptr->px + i) > rad) continue; - if (cave_clean_bold(p_ptr->py + j, p_ptr->px + i) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_SUPPORT_GROWTH)) + if (cave_clean_bold(p_ptr->py + j, p_ptr->px + i) && (f_info[cave[p_ptr->py][p_ptr->px].feat].flags & FF_SUPPORT_GROWTH)) { cave_set_feat(p_ptr->py + j, p_ptr->px + i, FEAT_GRASS); } @@ -194,7 +205,7 @@ bool_ hp_player(int num) /* * Leave a "glyph of warding" which prevents monster movement */ -void warding_glyph(void) +void warding_glyph() { /* XXX XXX XXX */ if (!cave_clean_bold(p_ptr->py, p_ptr->px)) @@ -207,7 +218,7 @@ void warding_glyph(void) cave_set_feat(p_ptr->py, p_ptr->px, FEAT_GLYPH); } -void explosive_rune(void) +void explosive_rune() { /* XXX XXX XXX */ if (!cave_clean_bold(p_ptr->py, p_ptr->px)) @@ -465,7 +476,7 @@ void identify_hooks(int i, object_type *o_ptr, identify_mode mode) * Identify everything being carried. * Done by a potion of "self knowledge". */ -bool_ identify_pack(void) +bool_ identify_pack() { int i; @@ -507,7 +518,7 @@ static void make_item_fully_identified(object_type *o_ptr) * Identify everything being carried. * Done by a potion of "self knowledge". */ -void identify_pack_fully(void) +void identify_pack_fully() { int i; @@ -544,8 +555,6 @@ static int enchant_table[16] = static bool_ remove_curse_object(object_type *o_ptr, bool_ all) { - u32b f1, f2, f3, f4, f5, esp; - /* Skip non-objects */ if (!o_ptr->k_idx) return FALSE; @@ -553,13 +562,13 @@ static bool_ remove_curse_object(object_type *o_ptr, bool_ all) if (!cursed_p(o_ptr)) return FALSE; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Heavily Cursed Items need a special spell */ - if (!all && (f3 & (TR3_HEAVY_CURSE))) return FALSE; + if (!all && (flags & TR_HEAVY_CURSE)) return FALSE; /* Perma-Cursed Items can NEVER be uncursed */ - if (f3 & (TR3_PERMA_CURSE)) return FALSE; + if (flags & TR_PERMA_CURSE) return FALSE; /* Uncurse it */ o_ptr->ident &= ~(IDENT_CURSED); @@ -567,11 +576,9 @@ static bool_ remove_curse_object(object_type *o_ptr, bool_ all) /* Hack -- Assume felt */ o_ptr->ident |= (IDENT_SENSE); - if (o_ptr->art_flags3 & (TR3_CURSED)) - o_ptr->art_flags3 &= ~(TR3_CURSED); - - if (o_ptr->art_flags3 & (TR3_HEAVY_CURSE)) - o_ptr->art_flags3 &= ~(TR3_HEAVY_CURSE); + /* Strip curse flags */ + o_ptr->art_flags &= ~TR_CURSED; + o_ptr->art_flags &= ~TR_HEAVY_CURSE; /* Take note */ o_ptr->sense = SENSE_UNCURSED; @@ -634,7 +641,7 @@ static int remove_curse_aux(int all) /* * Remove most curses */ -bool_ remove_curse(void) +bool_ remove_curse() { return (remove_curse_aux(FALSE) ? TRUE : FALSE); } @@ -642,7 +649,7 @@ bool_ remove_curse(void) /* * Remove all curses */ -bool_ remove_all_curse(void) +bool_ remove_all_curse() { return (remove_curse_aux(TRUE) ? TRUE : FALSE); } @@ -652,7 +659,7 @@ bool_ remove_all_curse(void) /* * Restores any drained experience */ -bool_ restore_level(void) +bool_ restore_level() { /* Restore experience */ if (p_ptr->exp < p_ptr->max_exp) @@ -675,7 +682,7 @@ bool_ restore_level(void) } -bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a shop */ +bool_ alchemy() /* Turns an object into gold, gain some of its value in a shop */ { int item, amt = 1; int old_number; @@ -726,7 +733,7 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh } /* Artifacts cannot be destroyed */ - if (artifact_p(o_ptr) || o_ptr->art_name) + if (artifact_p(o_ptr)) { byte feel = SENSE_SPECIAL; @@ -782,1014 +789,6 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh - -/* - * self-knowledge... idea from nethack. Useful for determining powers and - * resistances of items. It saves the screen, clears it, then starts listing - * attributes, a screenful at a time. (There are a LOT of attributes to - * list. It will probably take 2 or 3 screens for a powerful character whose - * using several artifacts...) -CFT - * - * It is now a lot more efficient. -BEN- - * - * See also "identify_fully()". - * - * XXX XXX XXX Use the "show_file()" method, perhaps. - */ -void self_knowledge(FILE *fff) -{ - int i = 0, j, k; - - u32b f1 = 0L, f2 = 0L, f3 = 0L, f4 = 0L, f5 = 0L, esp = 0L; - - int iter; /* Iterator for a loop */ - - object_type *o_ptr; - - char Dummy[80]; - - cptr info[200]; - - strcpy (Dummy, ""); - - /* Acquire item flags from equipment */ - for (k = INVEN_WIELD; k < INVEN_TOTAL; k++) - { - u32b t1, t2, t3, t4, t5, esp; - - o_ptr = &p_ptr->inventory[k]; - - /* Skip non-objects */ - if (!o_ptr->k_idx) continue; - - /* Extract the flags */ - object_flags(o_ptr, &t1, &t2, &t3, &t4, &t5, &esp); - - /* Extract flags */ - f1 |= t1; - f2 |= t2; - f3 |= t3; - } - - if (death) - { - static char buf[250]; - - sprintf(buf, "You are dead, killed by %s %s.", - died_from, describe_player_location()); - info[i++] = buf; - } - - /* Racial powers... */ - if (p_ptr->body_monster != 0) - { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; - - if (r_ptr->flags1 & RF1_CHAR_CLEAR || - r_ptr->flags1 & RF1_ATTR_CLEAR) - info[i++] = "You are transparent."; - if ((r_ptr->flags1 & RF1_CHAR_MULTI) || - (r_ptr->flags2 & RF2_SHAPECHANGER)) - info[i++] = "Your form constantly changes."; - if (r_ptr->flags1 & RF1_ATTR_MULTI) - info[i++] = "Your color constantly changes."; - if (r_ptr->flags1 & RF1_NEVER_BLOW) - info[i++] = "You do not have a physical weapon."; - if (r_ptr->flags1 & RF1_NEVER_MOVE) - info[i++] = "You cannot move."; - if ((r_ptr->flags1 & RF1_RAND_25) && - (r_ptr->flags1 & RF1_RAND_50)) - info[i++] = "You move extremely erratically."; - else if (r_ptr->flags1 & RF1_RAND_50) - info[i++] = "You move somewhat erratically."; - else if (r_ptr->flags1 & RF1_RAND_25) - info[i++] = "You move a bit erratically."; - if (r_ptr->flags2 & RF2_STUPID) - info[i++] = "You are very stupid (INT -4)."; - if (r_ptr->flags2 & RF2_SMART) - info[i++] = "You are very smart (INT +4)."; - /* Not implemented */ - if (r_ptr->flags2 & RF2_CAN_SPEAK) - info[i++] = "You can speak."; - else - info[i++] = "You cannot speak."; - /* Not implemented */ - if (r_ptr->flags2 & RF2_COLD_BLOOD) - info[i++] = "You are cold blooded."; - /* Not implemented */ - if (r_ptr->flags2 & RF2_EMPTY_MIND) - info[i++] = "You have an empty mind."; - if (r_ptr->flags2 & RF2_WEIRD_MIND) - info[i++] = "You have a weird mind."; - if (r_ptr->flags4 & RF4_MULTIPLY) - info[i++] = "You can multiply."; - if (r_ptr->flags2 & RF2_POWERFUL) - info[i++] = "You have strong breath."; - /* Not implemented */ - if (r_ptr->flags2 & RF2_ELDRITCH_HORROR) - info[i++] = "You are an eldritch horror."; - if (r_ptr->flags2 & RF2_OPEN_DOOR) - info[i++] = "You can open doors."; - else - info[i++] = "You cannot open doors."; - if (r_ptr->flags2 & RF2_BASH_DOOR) - info[i++] = "You can bash doors."; - else - info[i++] = "You cannot bash doors."; - if (r_ptr->flags2 & RF2_PASS_WALL) - info[i++] = "You can pass walls."; - if (r_ptr->flags2 & RF2_KILL_WALL) - info[i++] = "You destroy walls."; - /* Not implemented */ - if (r_ptr->flags2 & RF2_MOVE_BODY) - info[i++] = "You can move monsters."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_ORC) - info[i++] = "You have orc blood in your veins."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_TROLL) - info[i++] = "You have troll blood in your veins."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_GIANT) - info[i++] = "You have giant blood in your veins."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_DRAGON) - info[i++] = "You have dragon blood in your veins."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_DEMON) - info[i++] = "You have demon blood in your veins."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_UNDEAD) - info[i++] = "You are an undead."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_ANIMAL) - info[i++] = "You are an animal."; - /* Not implemented */ - else if (r_ptr->flags3 & RF3_THUNDERLORD) - info[i++] = "You have thunderlord blood in your veins."; - if (r_ptr->flags3 & RF3_EVIL) - info[i++] = "You are inherently evil."; - else if (r_ptr->flags3 & RF3_GOOD) - info[i++] = "You are inherently good."; - if (r_ptr->flags3 & RF3_AURA_COLD) - info[i++] = "You are surrounded by a chilly aura."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_NONLIVING) - info[i++] = "You are not living."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_HURT_LITE) - info[i++] = "Your eyes are vulnerable to bright light."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_HURT_ROCK) - info[i++] = "You can be hurt by rock remover."; - if (r_ptr->flags3 & RF3_SUSCEP_FIRE) - info[i++] = "You are vulnerable to fire."; - if (r_ptr->flags3 & RF3_SUSCEP_COLD) - info[i++] = "You are vulnerable to cold."; - if (r_ptr->flags3 & RF3_RES_TELE) - info[i++] = "You are resistant to teleportation."; - if (r_ptr->flags3 & RF3_RES_NETH) - info[i++] = "You are resistant to nether."; - if (r_ptr->flags3 & RF3_RES_WATE) - info[i++] = "You are resistant to water."; - if (r_ptr->flags3 & RF3_RES_PLAS) - info[i++] = "You are resistant to plasma."; - if (r_ptr->flags3 & RF3_RES_WATE) - info[i++] = "You are resistant to nexus."; - if (r_ptr->flags3 & RF3_RES_DISE) - info[i++] = "You are resistant to disease."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_NO_SLEEP) - info[i++] = "You cannot be slept."; - /* Not implemented */ - if (r_ptr->flags3 & RF3_UNIQUE_4) - info[i++] = "You are a Nazgul."; - if (r_ptr->flags3 & RF3_NO_FEAR) - info[i++] = "You are immune to fear."; - if (r_ptr->flags3 & RF3_NO_STUN) - info[i++] = "You are immune to stun."; - if (r_ptr->flags3 & RF3_NO_CONF) - info[i++] = "You are immune to confusion."; - if (r_ptr->flags3 & RF3_NO_SLEEP) - info[i++] = "You are immune to sleep."; - - if (r_ptr->flags4 & RF4_SHRIEK) - info[i++] = "You can aggravate monsters."; - if (r_ptr->flags4 & RF4_ROCKET) - info[i++] = "You can fire a rocket."; - if (r_ptr->flags4 & RF4_ARROW_1) - info[i++] = "You can fire a light arrow."; - if (r_ptr->flags4 & RF4_ARROW_2) - info[i++] = "You can fire a heavy arrow."; - if (r_ptr->flags4 & RF4_ARROW_3) - info[i++] = "You can fire a light missile."; - if (r_ptr->flags4 & RF4_ARROW_4) - info[i++] = "You can fire a heavy missile."; - if (r_ptr->flags4 & RF4_BR_ACID) - info[i++] = "You can breathe acid."; - if (r_ptr->flags4 & RF4_BR_ELEC) - info[i++] = "You can breathe electricity."; - if (r_ptr->flags4 & RF4_BR_FIRE) - info[i++] = "You can breathe fire."; - if (r_ptr->flags4 & RF4_BR_COLD) - info[i++] = "You can breathe cold."; - if (r_ptr->flags4 & RF4_BR_POIS) - info[i++] = "You can breathe poison."; - if (r_ptr->flags4 & RF4_BR_NETH) - info[i++] = "You can breathe nether."; - if (r_ptr->flags4 & RF4_BR_LITE) - info[i++] = "You can breathe light."; - if (r_ptr->flags4 & RF4_BR_DARK) - info[i++] = "You can breathe darkness."; - if (r_ptr->flags4 & RF4_BR_CONF) - info[i++] = "You can breathe confusion."; - if (r_ptr->flags4 & RF4_BR_SOUN) - info[i++] = "You can breathe sound."; - if (r_ptr->flags4 & RF4_BR_CHAO) - info[i++] = "You can breathe chaos."; - if (r_ptr->flags4 & RF4_BR_DISE) - info[i++] = "You can breathe disenchantment."; - if (r_ptr->flags4 & RF4_BR_NEXU) - info[i++] = "You can breathe nexus."; - if (r_ptr->flags4 & RF4_BR_TIME) - info[i++] = "You can breathe time."; - if (r_ptr->flags4 & RF4_BR_INER) - info[i++] = "You can breathe inertia."; - if (r_ptr->flags4 & RF4_BR_GRAV) - info[i++] = "You can breathe gravity."; - if (r_ptr->flags4 & RF4_BR_SHAR) - info[i++] = "You can breathe shards."; - if (r_ptr->flags4 & RF4_BR_PLAS) - info[i++] = "You can breathe plasma."; - if (r_ptr->flags4 & RF4_BR_WALL) - info[i++] = "You can breathe force."; - if (r_ptr->flags4 & RF4_BR_MANA) - info[i++] = "You can breathe mana."; - if (r_ptr->flags4 & RF4_BR_NUKE) - info[i++] = "You can breathe nuke."; - if (r_ptr->flags4 & RF4_BR_DISI) - info[i++] = "You can breathe disintegration."; - if (r_ptr->flags5 & RF5_BA_ACID) - info[i++] = "You can cast a ball of acid."; - if (r_ptr->flags5 & RF5_BA_ELEC) - info[i++] = "You can cast a ball of electricity."; - if (r_ptr->flags5 & RF5_BA_FIRE) - info[i++] = "You can cast a ball of fire."; - if (r_ptr->flags5 & RF5_BA_COLD) - info[i++] = "You can cast a ball of cold."; - if (r_ptr->flags5 & RF5_BA_POIS) - info[i++] = "You can cast a ball of poison."; - if (r_ptr->flags5 & RF5_BA_NETH) - info[i++] = "You can cast a ball of nether."; - if (r_ptr->flags5 & RF5_BA_WATE) - info[i++] = "You can cast a ball of water."; - /* Not implemented */ - if (r_ptr->flags5 & RF5_DRAIN_MANA) - info[i++] = "You can drain mana."; - if (r_ptr->flags5 & RF5_MIND_BLAST) - info[i++] = "You can cause mind blasting."; - if (r_ptr->flags5 & RF5_BRAIN_SMASH) - info[i++] = "You can cause brain smashing."; - if (r_ptr->flags5 & RF5_CAUSE_1) - info[i++] = "You can cause light wounds."; - if (r_ptr->flags5 & RF5_CAUSE_2) - info[i++] = "You can cause serious wounds."; - if (r_ptr->flags5 & RF5_CAUSE_3) - info[i++] = "You can cause critical wounds."; - if (r_ptr->flags5 & RF5_CAUSE_4) - info[i++] = "You can cause mortal wounds."; - if (r_ptr->flags5 & RF5_BO_ACID) - info[i++] = "You can cast a bolt of acid."; - if (r_ptr->flags5 & RF5_BO_ELEC) - info[i++] = "You can cast a bolt of electricity."; - if (r_ptr->flags5 & RF5_BO_FIRE) - info[i++] = "You can cast a bolt of fire."; - if (r_ptr->flags5 & RF5_BO_COLD) - info[i++] = "You can cast a bolt of cold."; - if (r_ptr->flags5 & RF5_BO_POIS) - info[i++] = "You can cast a bolt of poison."; - if (r_ptr->flags5 & RF5_BO_NETH) - info[i++] = "You can cast a bolt of nether."; - if (r_ptr->flags5 & RF5_BO_WATE) - info[i++] = "You can cast a bolt of water."; - if (r_ptr->flags5 & RF5_BO_MANA) - info[i++] = "You can cast a bolt of mana."; - if (r_ptr->flags5 & RF5_BO_PLAS) - info[i++] = "You can cast a bolt of plasma."; - if (r_ptr->flags5 & RF5_BO_ICEE) - info[i++] = "You can cast a bolt of ice."; - if (r_ptr->flags5 & RF5_MISSILE) - info[i++] = "You can cast magic missile."; - if (r_ptr->flags5 & RF5_SCARE) - info[i++] = "You can terrify."; - if (r_ptr->flags5 & RF5_BLIND) - info[i++] = "You can blind."; - if (r_ptr->flags5 & RF5_CONF) - info[i++] = "You can use confusion."; - if (r_ptr->flags5 & RF5_SLOW) - info[i++] = "You can cast slow."; - if (r_ptr->flags5 & RF5_HOLD) - info[i++] = "You can touch to paralyze."; - if (r_ptr->flags6 & RF6_HASTE) - info[i++] = "You can haste yourself."; - if (r_ptr->flags6 & RF6_HAND_DOOM) - info[i++] = "You can invoke Hand of Doom."; - if (r_ptr->flags6 & RF6_HEAL) - info[i++] = "You can heal yourself."; - if (r_ptr->flags6 & RF6_BLINK) - info[i++] = "You can blink."; - if (r_ptr->flags6 & RF6_TPORT) - info[i++] = "You can teleport."; - if (r_ptr->flags6 & RF6_TELE_TO) - info[i++] = "You can go between places."; - if (r_ptr->flags6 & RF6_TELE_AWAY) - info[i++] = "You can teleport away."; - if (r_ptr->flags6 & RF6_TELE_LEVEL) - info[i++] = "You can teleport level."; - if (r_ptr->flags6 & RF6_DARKNESS) - info[i++] = "You can create darkness."; - if (r_ptr->flags6 & RF6_TRAPS) - info[i++] = "You can create traps."; - /* Not implemented */ - if (r_ptr->flags6 & RF6_FORGET) - info[i++] = "You can fade memories."; - if (r_ptr->flags6 & RF6_RAISE_DEAD) - info[i++] = "You can Raise the Dead."; - if (r_ptr->flags6 & RF6_S_BUG) - info[i++] = "You can magically summon a Software Bugs."; - if (r_ptr->flags6 & RF6_S_RNG) - info[i++] = "You can magically summon the RNG."; - if (r_ptr->flags6 & RF6_S_THUNDERLORD) - info[i++] = "You can magically summon some Thunderlords."; - if (r_ptr->flags6 & RF6_S_KIN) - info[i++] = "You can magically summon some Kins."; - if (r_ptr->flags6 & RF6_S_HI_DEMON) - info[i++] = "You can magically summon greater demons."; - if (r_ptr->flags6 & RF6_S_MONSTER) - info[i++] = "You can magically summon a monster."; - if (r_ptr->flags6 & RF6_S_MONSTERS) - info[i++] = "You can magically summon monsters."; - if (r_ptr->flags6 & RF6_S_ANT) - info[i++] = "You can magically summon ants."; - if (r_ptr->flags6 & RF6_S_SPIDER) - info[i++] = "You can magically summon spiders."; - if (r_ptr->flags6 & RF6_S_HOUND) - info[i++] = "You can magically summon hounds."; - if (r_ptr->flags6 & RF6_S_HYDRA) - info[i++] = "You can magically summon hydras."; - if (r_ptr->flags6 & RF6_S_ANGEL) - info[i++] = "You can magically summon an angel."; - if (r_ptr->flags6 & RF6_S_DEMON) - info[i++] = "You can magically summon a demon."; - if (r_ptr->flags6 & RF6_S_UNDEAD) - info[i++] = "You can magically summon an undead."; - if (r_ptr->flags6 & RF6_S_DRAGON) - info[i++] = "You can magically summon a dragon."; - if (r_ptr->flags6 & RF6_S_HI_UNDEAD) - info[i++] = "You can magically summon greater undead."; - if (r_ptr->flags6 & RF6_S_HI_DRAGON) - info[i++] = "You can magically summon greater dragons."; - if (r_ptr->flags6 & RF6_S_WRAITH) - info[i++] = "You can magically summon a wraith."; - /* Not implemented */ - if (r_ptr->flags6 & RF6_S_UNIQUE) - info[i++] = "You can magically summon an unique monster."; - /* Not implemented */ - if (r_ptr->flags7 & RF7_AQUATIC) - info[i++] = "You are aquatic."; - /* Not implemented */ - if (r_ptr->flags7 & RF7_CAN_SWIM) - info[i++] = "You can swim."; - /* Not implemented */ - if (r_ptr->flags7 & RF7_CAN_FLY) - info[i++] = "You can fly."; - if ((r_ptr->flags7 & RF7_MORTAL) == 0) - info[i++] = "You are immortal."; - /* Not implemented */ - if (r_ptr->flags7 & RF7_NAZGUL) - info[i++] = "You are a Nazgul."; - - if (r_ptr->flags7 & RF7_SPIDER) - info[i++] = "You are a spider."; - - if (r_ptr->flags8 & RF8_WILD_TOWN) - info[i++] = "You appear in towns."; - if (r_ptr->flags8 & RF8_WILD_SHORE) - info[i++] = "You appear on the shore."; - if (r_ptr->flags8 & RF8_WILD_OCEAN) - info[i++] = "You appear in the ocean."; - if (r_ptr->flags8 & RF8_WILD_WASTE) - info[i++] = "You appear in the waste."; - if (r_ptr->flags8 & RF8_WILD_WOOD) - info[i++] = "You appear in woods."; - if (r_ptr->flags8 & RF8_WILD_VOLCANO) - info[i++] = "You appear in volcanos."; - if (r_ptr->flags8 & RF8_WILD_MOUNTAIN) - info[i++] = "You appear in the mountains."; - if (r_ptr->flags8 & RF8_WILD_GRASS) - info[i++] = "You appear in grassy areas."; - - if (r_ptr->flags9 & RF9_SUSCEP_ACID) - info[i++] = "You are vulnerable to acid."; - if (r_ptr->flags9 & RF9_SUSCEP_ELEC) - info[i++] = "You are vulnerable to electricity."; - if (r_ptr->flags9 & RF9_SUSCEP_POIS) - info[i++] = "You are vulnerable to poison."; - if (r_ptr->flags9 & RF9_KILL_TREES) - info[i++] = "You can eat trees."; - if (r_ptr->flags9 & RF9_WYRM_PROTECT) - info[i++] = "You are protected by great wyrms of power."; - } - - /* List powers */ - for (iter = 0; iter < POWER_MAX; iter++) - { - if (p_ptr->powers[iter]) - { - info[i++] = powers_type[iter].desc_text; - } - } - - if (p_ptr->allow_one_death) - { - info[i++] = "The Blood of Life flows through your veins."; - } - if (p_ptr->blind) - { - info[i++] = "You cannot see."; - } - if (p_ptr->confused) - { - info[i++] = "You are confused."; - } - if (p_ptr->afraid) - { - info[i++] = "You are terrified."; - } - if (p_ptr->cut) - { - info[i++] = "You are bleeding."; - } - if (p_ptr->stun) - { - info[i++] = "You are stunned."; - } - if (p_ptr->poisoned) - { - info[i++] = "You are poisoned."; - } - if (p_ptr->image) - { - info[i++] = "You are hallucinating."; - } - if (p_ptr->aggravate) - { - info[i++] = "You aggravate monsters."; - } - if (p_ptr->teleport) - { - info[i++] = "Your position is very uncertain."; - } - if (p_ptr->blessed) - { - info[i++] = "You feel righteous."; - } - if (p_ptr->hero) - { - info[i++] = "You feel heroic."; - } - if (p_ptr->shero) - { - info[i++] = "You are in a battle rage."; - } - if (p_ptr->protevil) - { - info[i++] = "You are protected from evil."; - } - if (p_ptr->protgood) - { - info[i++] = "You are protected from good."; - } - if (p_ptr->shield) - { - info[i++] = "You are protected by a mystic shield."; - } - if (p_ptr->invuln) - { - info[i++] = "You are temporarily invulnerable."; - } - if (p_ptr->confusing) - { - info[i++] = "Your hands are glowing dull red."; - } - if (p_ptr->searching) - { - info[i++] = "You are looking around very carefully."; - } - if (p_ptr->word_recall) - { - info[i++] = "You will soon be recalled."; - } - if (p_ptr->see_infra) - { - info[i++] = "Your eyes are sensitive to infrared light."; - } - if (p_ptr->see_inv) - { - info[i++] = "You can see invisible creatures."; - } - if (p_ptr->magical_breath) - { - info[i++] = "You can breathe without air."; - } - else if (p_ptr->water_breath) - { - info[i++] = "You can breathe underwater."; - } - if (p_ptr->ffall) - { - info[i++] = "You levitate just over the ground."; - } - if (p_ptr->climb) - { - info[i++] = "You can climb high mountains."; - } - if (p_ptr->free_act) - { - info[i++] = "You have free action."; - } - if (p_ptr->regenerate) - { - info[i++] = "You regenerate quickly."; - } - if (p_ptr->slow_digest) - { - info[i++] = "Your appetite is small."; - } - if (p_ptr->telepathy) - { - if (p_ptr->telepathy & ESP_ALL) info[i++] = "You have ESP."; - else - { - if (p_ptr->telepathy & ESP_ORC) info[i++] = "You can sense the presence of orcs."; - if (p_ptr->telepathy & ESP_TROLL) info[i++] = "You can sense the presence of trolls."; - if (p_ptr->telepathy & ESP_DRAGON) info[i++] = "You can sense the presence of dragons."; - if (p_ptr->telepathy & ESP_SPIDER) info[i++] = "You can sense the presence of spiders."; - if (p_ptr->telepathy & ESP_GIANT) info[i++] = "You can sense the presence of giants."; - if (p_ptr->telepathy & ESP_DEMON) info[i++] = "You can sense the presence of demons."; - if (p_ptr->telepathy & ESP_UNDEAD) info[i++] = "You can sense presence of undead."; - if (p_ptr->telepathy & ESP_EVIL) info[i++] = "You can sense the presence of evil beings."; - if (p_ptr->telepathy & ESP_ANIMAL) info[i++] = "You can sense the presence of animals."; - if (p_ptr->telepathy & ESP_THUNDERLORD) info[i++] = "You can sense the presence of thunderlords."; - if (p_ptr->telepathy & ESP_GOOD) info[i++] = "You can sense the presence of good beings."; - if (p_ptr->telepathy & ESP_NONLIVING) info[i++] = "You can sense the presence of non-living things."; - if (p_ptr->telepathy & ESP_UNIQUE) info[i++] = "You can sense the presence of unique beings."; - } - } - if (!luck( -100, 100)) - { - info[i++] = "You have normal luck."; - } - else if (luck( -100, 100) < 0) - { - if (luck( -100, 100) < -90) - { - info[i++] = "You are incredibly unlucky."; - } - else if (luck( -100, 100) < -60) - { - info[i++] = "You are extremely unlucky."; - } - else if (luck( -100, 100) < -30) - { - info[i++] = "You are very unlucky."; - } - else - { - info[i++] = "You are unlucky."; - } - } - else if (luck( -100, 100) > 0) - { - if (luck( -100, 100) > 90) - { - info[i++] = "You are incredibly lucky."; - } - else if (luck( -100, 100) > 60) - { - info[i++] = "You are extremely lucky."; - } - else if (luck( -100, 100) > 30) - { - info[i++] = "You are very lucky."; - } - else - { - info[i++] = "You are lucky."; - } - } - if (p_ptr->auto_id) - { - info[i++] = "You know everything."; - } - if (p_ptr->hold_life) - { - info[i++] = "You have a firm hold on your life force."; - } - if (p_ptr->reflect) - { - info[i++] = "You reflect arrows and bolts."; - } - if (p_ptr->sh_fire) - { - info[i++] = "You are surrounded with a fiery aura."; - } - if (p_ptr->sh_elec) - { - info[i++] = "You are surrounded with electricity."; - } - if (p_ptr->antimagic) - { - info[i++] = "You are surrounded by an anti-magic field."; - } - if (p_ptr->anti_magic) - { - info[i++] = "You are surrounded by an anti-magic shell."; - } - if (p_ptr->wraith_form) - { - info[i++] = "You are incorporeal."; - } - if (p_ptr->anti_tele) - { - info[i++] = "You cannot teleport."; - } - if (p_ptr->lite) - { - info[i++] = "You are carrying a permanent light."; - } - - if (p_ptr->immune_acid) - { - info[i++] = "You are completely immune to acid."; - } - else if ((p_ptr->resist_acid) && (p_ptr->oppose_acid)) - { - info[i++] = "You resist acid exceptionally well."; - } - else if ((p_ptr->resist_acid) || (p_ptr->oppose_acid)) - { - info[i++] = "You are resistant to acid."; - } - - if (p_ptr->immune_elec) - { - info[i++] = "You are completely immune to lightning."; - } - else if ((p_ptr->resist_elec) && (p_ptr->oppose_elec)) - { - info[i++] = "You resist lightning exceptionally well."; - } - else if ((p_ptr->resist_elec) || (p_ptr->oppose_elec)) - { - info[i++] = "You are resistant to lightning."; - } - - if (p_ptr->immune_fire) - { - info[i++] = "You are completely immune to fire."; - } - else if ((p_ptr->resist_fire) && (p_ptr->oppose_fire)) - { - info[i++] = "You resist fire exceptionally well."; - } - else if ((p_ptr->resist_fire) || (p_ptr->oppose_fire)) - { - info[i++] = "You are resistant to fire."; - } - else if (p_ptr->sensible_fire) - { - info[i++] = "You are very vulnerable to fire."; - } - - if (p_ptr->immune_cold) - { - info[i++] = "You are completely immune to cold."; - } - else if ((p_ptr->resist_cold) && (p_ptr->oppose_cold)) - { - info[i++] = "You resist cold exceptionally well."; - } - else if ((p_ptr->resist_cold) || (p_ptr->oppose_cold)) - { - info[i++] = "You are resistant to cold."; - } - - if ((p_ptr->resist_pois) && (p_ptr->oppose_pois)) - { - info[i++] = "You resist poison exceptionally well."; - } - else if ((p_ptr->resist_pois) || (p_ptr->oppose_pois)) - { - info[i++] = "You are resistant to poison."; - } - - if (p_ptr->resist_lite) - { - info[i++] = "You are resistant to bright light."; - } - if (p_ptr->resist_dark) - { - info[i++] = "You are resistant to darkness."; - } - if (p_ptr->resist_conf) - { - info[i++] = "You are resistant to confusion."; - } - if (p_ptr->resist_sound) - { - info[i++] = "You are resistant to sonic attacks."; - } - if (p_ptr->resist_disen) - { - info[i++] = "You are resistant to disenchantment."; - } - if (p_ptr->resist_chaos) - { - info[i++] = "You are resistant to chaos."; - } - if (p_ptr->resist_shard) - { - info[i++] = "You are resistant to blasts of shards."; - } - if (p_ptr->resist_nexus) - { - info[i++] = "You are resistant to nexus attacks."; - } - if (p_ptr->immune_neth) - { - info[i++] = "You are immune to nether forces."; - } - else if (p_ptr->resist_neth) - { - info[i++] = "You are resistant to nether forces."; - } - if (p_ptr->resist_fear) - { - info[i++] = "You are completely fearless."; - } - if (p_ptr->resist_blind) - { - info[i++] = "Your eyes are resistant to blindness."; - } - if (p_ptr->resist_continuum) - { - info[i++] = "The space-time continuum cannot be disrupted near you."; - } - - if (p_ptr->sustain_str) - { - info[i++] = "Your strength is sustained."; - } - if (p_ptr->sustain_int) - { - info[i++] = "Your intelligence is sustained."; - } - if (p_ptr->sustain_wis) - { - info[i++] = "Your wisdom is sustained."; - } - if (p_ptr->sustain_con) - { - info[i++] = "Your constitution is sustained."; - } - if (p_ptr->sustain_dex) - { - info[i++] = "Your dexterity is sustained."; - } - if (p_ptr->sustain_chr) - { - info[i++] = "Your charisma is sustained."; - } - if (p_ptr->black_breath) - { - info[i++] = "You suffer from Black Breath."; - } - - if (f1 & (TR1_STR)) - { - info[i++] = "Your strength is affected by your equipment."; - } - if (f1 & (TR1_INT)) - { - info[i++] = "Your intelligence is affected by your equipment."; - } - if (f1 & (TR1_WIS)) - { - info[i++] = "Your wisdom is affected by your equipment."; - } - if (f1 & (TR1_DEX)) - { - info[i++] = "Your dexterity is affected by your equipment."; - } - if (f1 & (TR1_CON)) - { - info[i++] = "Your constitution is affected by your equipment."; - } - if (f1 & (TR1_CHR)) - { - info[i++] = "Your charisma is affected by your equipment."; - } - - if (f1 & (TR1_STEALTH)) - { - info[i++] = "Your stealth is affected by your equipment."; - } - if (f1 & (TR1_SEARCH)) - { - info[i++] = "Your searching ability is affected by your equipment."; - } - if (f1 & (TR1_INFRA)) - { - info[i++] = "Your infravision is affected by your equipment."; - } - if (f1 & (TR1_TUNNEL)) - { - info[i++] = "Your digging ability is affected by your equipment."; - } - if (f1 & (TR1_SPEED)) - { - info[i++] = "Your speed is affected by your equipment."; - } - if (f1 & (TR1_BLOWS)) - { - info[i++] = "Your attack speed is affected by your equipment."; - } - if (f5 & (TR5_CRIT)) - { - info[i++] = "Your ability to score critical hits is affected by your equipment."; - } - - - /* Access the current weapon */ - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - - /* Analyze the weapon */ - if (o_ptr->k_idx) - { - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Indicate Blessing */ - if (f3 & (TR3_BLESSED)) - { - info[i++] = "Your weapon has been blessed by the gods."; - } - - if (f1 & (TR1_CHAOTIC)) - { - info[i++] = "Your weapon is branded with the Sign of Chaos."; - } - - /* Hack */ - if (f1 & (TR1_IMPACT)) - { - info[i++] = "The impact of your weapon can cause earthquakes."; - } - - if (f1 & (TR1_VORPAL)) - { - info[i++] = "Your weapon is very sharp."; - } - - if (f1 & (TR1_VAMPIRIC)) - { - info[i++] = "Your weapon drains life from your foes."; - } - - /* Special "Attack Bonuses" */ - if (f1 & (TR1_BRAND_ACID)) - { - info[i++] = "Your weapon melts your foes."; - } - if (f1 & (TR1_BRAND_ELEC)) - { - info[i++] = "Your weapon shocks your foes."; - } - if (f1 & (TR1_BRAND_FIRE)) - { - info[i++] = "Your weapon burns your foes."; - } - if (f1 & (TR1_BRAND_COLD)) - { - info[i++] = "Your weapon freezes your foes."; - } - if (f1 & (TR1_BRAND_POIS)) - { - info[i++] = "Your weapon poisons your foes."; - } - - /* Special "slay" flags */ - if (f1 & (TR1_SLAY_ANIMAL)) - { - info[i++] = "Your weapon strikes at animals with extra force."; - } - if (f1 & (TR1_SLAY_EVIL)) - { - info[i++] = "Your weapon strikes at evil with extra force."; - } - if (f1 & (TR1_SLAY_UNDEAD)) - { - info[i++] = "Your weapon strikes at undead with holy wrath."; - } - if (f1 & (TR1_SLAY_DEMON)) - { - info[i++] = "Your weapon strikes at demons with holy wrath."; - } - if (f1 & (TR1_SLAY_ORC)) - { - info[i++] = "Your weapon is especially deadly against orcs."; - } - if (f1 & (TR1_SLAY_TROLL)) - { - info[i++] = "Your weapon is especially deadly against trolls."; - } - if (f1 & (TR1_SLAY_GIANT)) - { - info[i++] = "Your weapon is especially deadly against giants."; - } - if (f1 & (TR1_SLAY_DRAGON)) - { - info[i++] = "Your weapon is especially deadly against dragons."; - } - - /* Special "kill" flags */ - if (f1 & (TR1_KILL_DRAGON)) - { - info[i++] = "Your weapon is a great bane of dragons."; - } - /* Special "kill" flags */ - if (f5 & (TR5_KILL_DEMON)) - { - info[i++] = "Your weapon is a great bane of demons."; - } - /* Special "kill" flags */ - if (f5 & (TR5_KILL_UNDEAD)) - { - info[i++] = "Your weapon is a great bane of undeads."; - } - } - - /* Print on screen or in a file ? */ - if (fff == NULL) - { - /* Save the screen */ - character_icky = TRUE; - Term_save(); - - /* Erase the screen */ - for (k = 1; k < 24; k++) prt("", k, 13); - - /* Label the information */ - prt(" Your Attributes:", 1, 15); - - /* We will print on top of the map (column 13) */ - for (k = 2, j = 0; j < i; j++) - { - /* Show the info */ - prt(info[j], k++, 15); - - /* Every 20 entries (lines 2 to 21), start over */ - if ((k == 22) && (j + 1 < i)) - { - prt("-- more --", k, 15); - inkey(); - for (; k > 2; k--) prt("", k, 15); - } - } - - /* Pause */ - prt("[Press any key to continue]", k, 13); - inkey(); - - /* Restore the screen */ - Term_load(); - character_icky = FALSE; - } - else - { - /* Label the information */ - fprintf(fff, " Your Attributes:\n"); - - /* We will print on top of the map (column 13) */ - for (j = 0; j < i; j ++) - { - /* Show the info */ - fprintf(fff, "%s\n", info[j]); - } - } -} - - static int report_magics_aux(int dur) { if (dur <= 5) @@ -1835,7 +834,7 @@ static cptr report_magic_durations[] = }; -void report_magics(void) +void report_magics() { int i = 0, j, k; @@ -1890,11 +889,6 @@ void report_magics(void) info2[i] = report_magics_aux(p_ptr->protevil); info[i++] = "You are protected from evil"; } - if (p_ptr->protgood) - { - info2[i] = report_magics_aux(p_ptr->protgood); - info[i++] = "You are protected from good"; - } if (p_ptr->shield) { info2[i] = report_magics_aux(p_ptr->shield); @@ -1987,7 +981,7 @@ void report_magics(void) /* * Forget everything */ -bool_ lose_all_info(void) +bool_ lose_all_info() { int i; @@ -2032,76 +1026,6 @@ bool_ lose_all_info(void) } - - -/* - * Detect all traps on current panel - */ -bool_ detect_traps(int rad) -{ - int x, y; - bool_ detect = FALSE; - cave_type *c_ptr; - - - /* Scan the current panel */ - for (y = p_ptr->py - rad; y <= p_ptr->py + rad; y++) - { - for (x = p_ptr->px - rad; x <= p_ptr->px + rad; x++) - { - /* Reject locations outside of dungeon */ - if (!in_bounds(y, x)) continue; - - /* Reject those out of radius */ - if (distance(p_ptr->py, p_ptr->px, y, x) > rad) continue; - - /* Access the grid */ - c_ptr = &cave[y][x]; - - /* mark as detected */ - c_ptr->info |= CAVE_DETECT; - - /* Detect invisible traps */ - if (c_ptr->t_idx != 0) - { - /* Hack -- Remember detected traps */ - c_ptr->info |= (CAVE_MARK); - - /* Pick a trap */ - pick_trap(y, x); - - /* Obvious */ - detect = TRUE; - } - } - } - - /* Describe */ - if (detect) - { - msg_print("You sense the presence of traps!"); - } - - /* - * This reveals un-identified trap detection items, - * but so does leaving/entering trap-detected areas... - * There are a couple of possible solutions: - * (1) Immediately self-id such items (i.e. always returns TRUE) - * (2) add another parameter to function which tells if unaware - * item is used for trap detection, and if it is the case, - * do two-pass scanning, first scanning for traps if an unaware - * item is used and return FALSE there are none, - * followed by current implementation --pelpel - */ - p_ptr->redraw |= (PR_FRAME); - - /* Result -- see my comment above -- pelpel */ - /* return (detect); */ - return (TRUE); -} - - - /* * Detect all doors on current panel */ @@ -2293,7 +1217,7 @@ bool_ detect_treasure(int rad) * The "update function" is called exactly once if * the predicate succeeds. The */ -template<typename P, typename U> static bool detect_monsters_fn(int radius, P p, U u) { +template<typename P> static bool detect_monsters_fn(int radius, P p) { bool flag = false; /* Scan monsters */ for (int i = 1; i < m_max; i++) @@ -2319,19 +1243,6 @@ template<typename P, typename U> static bool detect_monsters_fn(int radius, P p, auto r_ptr = m_ptr->race(); if (p(r_ptr.get())) { - /* Update */ - u(r_ptr.get()); - - /* We're assuming the update function does - * *something*, so we'll need to update - * the recall window if we're currently looking - * at it. - */ - if (monster_race_idx == m_ptr->r_idx) - { - p_ptr->window |= (PW_MONSTER); - } - /* Repair visibility later */ repair_monsters = TRUE; @@ -2360,11 +1271,9 @@ static bool_ detect_monsters_string(cptr chars, int rad) auto predicate = [chars](monster_race *r_ptr) -> bool { return strchr(chars, r_ptr->d_char); }; - auto update = [](monster_race *) -> void { - }; /* Describe */ - if (detect_monsters_fn(rad, predicate, update)) + if (detect_monsters_fn(rad, predicate)) { /* Describe result */ msg_print("You sense the presence of monsters!"); @@ -2402,7 +1311,7 @@ template <typename P> bool detect_objects_fn(int radius, const char *object_mess monster_type *m_ptr = &m_list[o_ptr->held_m_idx]; auto const r_ptr = m_ptr->race(); - if (!(r_ptr->flags9 & RF9_MIMIC)) + if (!(r_ptr->flags & RF_MIMIC)) { continue; /* Skip mimics completely */ } @@ -2498,13 +1407,11 @@ bool detect_objects_normal(int rad) bool_ detect_monsters_normal(int rad) { auto predicate = [](monster_race *r_ptr) -> bool { - return (!(r_ptr->flags2 & (RF2_INVISIBLE))) || + return (!(r_ptr->flags & RF_INVISIBLE)) || p_ptr->see_inv || p_ptr->tim_invis; }; - auto update = [](monster_race *) -> void { - }; - if (detect_monsters_fn(rad, predicate, update)) + if (detect_monsters_fn(rad, predicate)) { /* Describe result */ msg_print("You sense the presence of monsters!"); @@ -2523,13 +1430,10 @@ bool_ detect_monsters_normal(int rad) bool_ detect_monsters_invis(int rad) { auto predicate = [](monster_race *r_ptr) -> bool { - return (r_ptr->flags2 & (RF2_INVISIBLE)); - }; - auto update = [](monster_race *r_ptr) -> void { - r_ptr->r_flags2 |= (RF2_INVISIBLE); + return bool(r_ptr->flags & RF_INVISIBLE); }; - if (detect_monsters_fn(rad, predicate, update)) + if (detect_monsters_fn(rad, predicate)) { /* Describe result */ msg_print("You sense the presence of invisible creatures!"); @@ -2544,44 +1448,17 @@ bool_ detect_monsters_invis(int rad) /* - * A "generic" detect monsters routine, tagged to flags3 + * Detect orcs */ -bool_ detect_monsters_xxx(u32b match_flag, int rad) +void detect_monsters_orcs(int rad) { - auto predicate = [match_flag](monster_race *r_ptr) -> bool { - return (r_ptr->flags3 & match_flag); - }; - auto update = [match_flag](monster_race *r_ptr) -> void { - r_ptr->r_flags3 |= (match_flag); + auto predicate = [](monster_race *r_ptr) -> bool { + return bool(r_ptr->flags & RF_ORC); }; - if (detect_monsters_fn(rad, predicate, update)) - { - cptr desc_monsters = "weird monsters"; - switch (match_flag) - { - case RF3_DEMON: - desc_monsters = "demons"; - break; - case RF3_UNDEAD: - desc_monsters = "the undead"; - break; - case RF3_GOOD: - desc_monsters = "good"; - break; - case RF3_ORC: - desc_monsters = "orcs"; - break; - } - - /* Describe result */ - msg_format("You sense the presence of %s!", desc_monsters); - msg_print(NULL); - return TRUE; - } - else + if (detect_monsters_fn(rad, predicate)) { - return FALSE; + msg_print("You sense the presence of orcs!"); } } @@ -2595,7 +1472,6 @@ bool_ detect_all(int rad) bool_ detect = FALSE; /* Detect everything */ - if (detect_traps(rad)) detect = TRUE; if (detect_doors(rad)) detect = TRUE; if (detect_stairs(rad)) detect = TRUE; if (detect_treasure(rad)) detect = TRUE; @@ -2613,7 +1489,7 @@ bool_ detect_all(int rad) /* * Create stairs at the player location */ -void stair_creation(void) +void stair_creation() { /* XXX XXX XXX */ if (!cave_valid_bold(p_ptr->py, p_ptr->px)) @@ -2622,13 +1498,13 @@ void stair_creation(void) return; } - if (dungeon_flags1 & DF1_FLAT) + if (dungeon_flags & DF_FLAT) { msg_print("No stair creation in non dungeons..."); return; } - if (dungeon_flags2 & DF2_SPECIAL) + if (dungeon_flags & DF_SPECIAL) { msg_print("No stair creation on special levels..."); return; @@ -2757,12 +1633,28 @@ bool_ enchant(object_type *o_ptr, int n, int eflag) { int i, chance, prob; bool_ res = FALSE; - bool_ a = (artifact_p(o_ptr) || o_ptr->art_name); - u32b f1, f2, f3, f4, f5, esp; - + auto const a = artifact_p(o_ptr); /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); + + /* Break curse if item is cursed the curse isn't permanent */ + auto maybe_break_curse = [o_ptr, &flags]() + { + if (cursed_p(o_ptr) && (!(flags & TR_PERMA_CURSE))) + { + msg_print("The curse is broken!"); + o_ptr->ident &= ~(IDENT_CURSED); + o_ptr->ident |= (IDENT_SENSE); + + if (o_ptr->art_flags & TR_CURSED) + o_ptr->art_flags &= ~TR_CURSED; + if (o_ptr->art_flags & TR_HEAVY_CURSE) + o_ptr->art_flags &= ~TR_HEAVY_CURSE; + + o_ptr->sense = SENSE_UNCURSED; + } + }; /* Large piles resist enchantment */ prob = o_ptr->number * 100; @@ -2793,21 +1685,10 @@ bool_ enchant(object_type *o_ptr, int n, int eflag) o_ptr->to_h++; res = TRUE; - /* only when you get it above -1 -CFT */ - if (cursed_p(o_ptr) && - (!(f3 & (TR3_PERMA_CURSE))) && - (o_ptr->to_h >= 0) && (rand_int(100) < 25)) + /* break curse? */ + if ((o_ptr->to_h >= 0) && (rand_int(100) < 25)) { - msg_print("The curse is broken!"); - o_ptr->ident &= ~(IDENT_CURSED); - o_ptr->ident |= (IDENT_SENSE); - - if (o_ptr->art_flags3 & (TR3_CURSED)) - o_ptr->art_flags3 &= ~(TR3_CURSED); - if (o_ptr->art_flags3 & (TR3_HEAVY_CURSE)) - o_ptr->art_flags3 &= ~(TR3_HEAVY_CURSE); - - o_ptr->sense = SENSE_UNCURSED; + maybe_break_curse(); } } } @@ -2824,21 +1705,10 @@ bool_ enchant(object_type *o_ptr, int n, int eflag) o_ptr->to_d++; res = TRUE; - /* only when you get it above -1 -CFT */ - if (cursed_p(o_ptr) && - (!(f3 & (TR3_PERMA_CURSE))) && - (o_ptr->to_d >= 0) && (rand_int(100) < 25)) + /* break curse? */ + if ((o_ptr->to_d >= 0) && (rand_int(100) < 25)) { - msg_print("The curse is broken!"); - o_ptr->ident &= ~(IDENT_CURSED); - o_ptr->ident |= (IDENT_SENSE); - - if (o_ptr->art_flags3 & (TR3_CURSED)) - o_ptr->art_flags3 &= ~(TR3_CURSED); - if (o_ptr->art_flags3 & (TR3_HEAVY_CURSE)) - o_ptr->art_flags3 &= ~(TR3_HEAVY_CURSE); - - o_ptr->sense = SENSE_UNCURSED; + maybe_break_curse(); } } } @@ -2856,21 +1726,10 @@ bool_ enchant(object_type *o_ptr, int n, int eflag) o_ptr->pval++; res = TRUE; - /* only when you get it above -1 -CFT */ - if (cursed_p(o_ptr) && - (!(f3 & (TR3_PERMA_CURSE))) && - (o_ptr->pval >= 0) && (rand_int(100) < 25)) + /* break curse? */ + if ((o_ptr->pval >= 0) && (rand_int(100) < 25)) { - msg_print("The curse is broken!"); - o_ptr->ident &= ~(IDENT_CURSED); - o_ptr->ident |= (IDENT_SENSE); - - if (o_ptr->art_flags3 & (TR3_CURSED)) - o_ptr->art_flags3 &= ~(TR3_CURSED); - if (o_ptr->art_flags3 & (TR3_HEAVY_CURSE)) - o_ptr->art_flags3 &= ~(TR3_HEAVY_CURSE); - - o_ptr->sense = SENSE_UNCURSED; + maybe_break_curse(); } } } @@ -2887,21 +1746,10 @@ bool_ enchant(object_type *o_ptr, int n, int eflag) o_ptr->to_a++; res = TRUE; - /* only when you get it above -1 -CFT */ - if (cursed_p(o_ptr) && - (!(f3 & (TR3_PERMA_CURSE))) && - (o_ptr->to_a >= 0) && (rand_int(100) < 25)) + /* break curse? */ + if ((o_ptr->to_a >= 0) && (rand_int(100) < 25)) { - msg_print("The curse is broken!"); - o_ptr->ident &= ~(IDENT_CURSED); - o_ptr->ident |= (IDENT_SENSE); - - if (o_ptr->art_flags3 & (TR3_CURSED)) - o_ptr->art_flags3 &= ~(TR3_CURSED); - if (o_ptr->art_flags3 & (TR3_HEAVY_CURSE)) - o_ptr->art_flags3 &= ~(TR3_HEAVY_CURSE); - - o_ptr->sense = SENSE_UNCURSED; + maybe_break_curse(); } } } @@ -2973,7 +1821,7 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval) if (!okay) { /* Flush */ - if (flush_failure) flush(); + flush_on_failure(); /* Message */ msg_print("The enchantment failed."); @@ -2989,141 +1837,141 @@ void curse_artifact(object_type * o_ptr) if (o_ptr->to_a) o_ptr->to_a = 0 - ((o_ptr->to_a) + randint(4)); if (o_ptr->to_h) o_ptr->to_h = 0 - ((o_ptr->to_h) + randint(4)); if (o_ptr->to_d) o_ptr->to_d = 0 - ((o_ptr->to_d) + randint(4)); - o_ptr->art_flags3 |= ( TR3_HEAVY_CURSE | TR3_CURSED ); - if (randint(3) == 1) o_ptr-> art_flags3 |= TR3_TY_CURSE; - if (randint(2) == 1) o_ptr-> art_flags3 |= TR3_AGGRAVATE; - if (randint(3) == 1) o_ptr-> art_flags3 |= TR3_DRAIN_EXP; - if (randint(3) == 1) o_ptr-> art_flags4 |= TR4_BLACK_BREATH; - if (randint(2) == 1) o_ptr-> art_flags3 |= TR3_TELEPORT; - else if (randint(3) == 1) o_ptr->art_flags3 |= TR3_NO_TELE; + o_ptr->art_flags |= TR_HEAVY_CURSE | TR_CURSED; + if (randint(3) == 1) o_ptr-> art_flags |= TR_TY_CURSE; + if (randint(2) == 1) o_ptr-> art_flags |= TR_AGGRAVATE; + if (randint(3) == 1) o_ptr-> art_flags |= TR_DRAIN_EXP; + if (randint(3) == 1) o_ptr-> art_flags |= TR_BLACK_BREATH; + if (randint(2) == 1) o_ptr-> art_flags |= TR_TELEPORT; + else if (randint(3) == 1) o_ptr->art_flags |= TR_NO_TELE; o_ptr->ident |= IDENT_CURSED; } -void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) +void random_resistance(object_type *o_ptr, int specific) { /* To avoid a number of possible bugs */ if (!specific) { if (artifact_bias == BIAS_ACID) { - if (!(o_ptr->art_flags2 & TR2_RES_ACID)) + if (!(o_ptr->art_flags & TR_RES_ACID)) { - o_ptr->art_flags2 |= TR2_RES_ACID; + o_ptr->art_flags |= TR_RES_ACID; if (rand_int(2) == 0) return; } - if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags2 & TR2_IM_ACID)) + if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags & TR_IM_ACID)) { - o_ptr->art_flags2 |= TR2_IM_ACID; + o_ptr->art_flags |= TR_IM_ACID; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_ELEC) { - if (!(o_ptr->art_flags2 & TR2_RES_ELEC)) + if (!(o_ptr->art_flags & TR_RES_ELEC)) { - o_ptr->art_flags2 |= TR2_RES_ELEC; + o_ptr->art_flags |= TR_RES_ELEC; if (rand_int(2) == 0) return; } if (o_ptr->tval >= TV_CLOAK && o_ptr->tval <= TV_HARD_ARMOR && - !(o_ptr->art_flags3 & TR3_SH_ELEC)) + !(o_ptr->art_flags & TR_SH_ELEC)) { - o_ptr->art_flags2 |= TR3_SH_ELEC; + o_ptr->art_flags |= TR_SH_ELEC; if (rand_int(2) == 0) return; } - if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags2 & TR2_IM_ELEC)) + if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags & TR_IM_ELEC)) { - o_ptr->art_flags2 |= TR2_IM_ELEC; + o_ptr->art_flags |= TR_IM_ELEC; if (rand_int(2) == 1) return; } } else if (artifact_bias == BIAS_FIRE) { - if (!(o_ptr->art_flags2 & TR2_RES_FIRE)) + if (!(o_ptr->art_flags & TR_RES_FIRE)) { - o_ptr->art_flags2 |= TR2_RES_FIRE; + o_ptr->art_flags |= TR_RES_FIRE; if (rand_int(2) == 0) return; } if (o_ptr->tval >= TV_CLOAK && o_ptr->tval <= TV_HARD_ARMOR && - !(o_ptr->art_flags3 & TR3_SH_FIRE)) + !(o_ptr->art_flags & TR_SH_FIRE)) { - o_ptr->art_flags2 |= TR3_SH_FIRE; + o_ptr->art_flags |= TR_SH_FIRE; if (rand_int(2) == 0) return; } - if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags2 & TR2_IM_FIRE)) + if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags & TR_IM_FIRE)) { - o_ptr->art_flags2 |= TR2_IM_FIRE; + o_ptr->art_flags |= TR_IM_FIRE; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_COLD) { - if (!(o_ptr->art_flags2 & TR2_RES_COLD)) + if (!(o_ptr->art_flags & TR_RES_COLD)) { - o_ptr->art_flags2 |= TR2_RES_COLD; + o_ptr->art_flags |= TR_RES_COLD; if (rand_int(2) == 0) return; } - if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags2 & TR2_IM_COLD)) + if (rand_int(BIAS_LUCK) == 0 && !(o_ptr->art_flags & TR_IM_COLD)) { - o_ptr->art_flags2 |= TR2_IM_COLD; + o_ptr->art_flags |= TR_IM_COLD; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_POIS) { - if (!(o_ptr->art_flags2 & TR2_RES_POIS)) + if (!(o_ptr->art_flags & TR_RES_POIS)) { - o_ptr->art_flags2 |= TR2_RES_POIS; + o_ptr->art_flags |= TR_RES_POIS; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_WARRIOR) { - if (rand_int(3) && (!(o_ptr->art_flags2 & TR2_RES_FEAR))) + if (rand_int(3) && (!(o_ptr->art_flags & TR_RES_FEAR))) { - o_ptr->art_flags2 |= TR2_RES_FEAR; + o_ptr->art_flags |= TR_RES_FEAR; if (rand_int(2) == 0) return; } - if ((rand_int(3) == 0) && (!(o_ptr->art_flags3 & TR3_NO_MAGIC))) + if ((rand_int(3) == 0) && (!(o_ptr->art_flags & TR_NO_MAGIC))) { - o_ptr->art_flags3 |= TR3_NO_MAGIC; + o_ptr->art_flags |= TR_NO_MAGIC; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_NECROMANTIC) { - if (!(o_ptr->art_flags2 & TR2_RES_NETHER)) + if (!(o_ptr->art_flags & TR_RES_NETHER)) { - o_ptr->art_flags2 |= TR2_RES_NETHER; + o_ptr->art_flags |= TR_RES_NETHER; if (rand_int(2) == 0) return; } - if (!(o_ptr->art_flags2 & TR2_RES_POIS)) + if (!(o_ptr->art_flags & TR_RES_POIS)) { - o_ptr->art_flags2 |= TR2_RES_POIS; + o_ptr->art_flags |= TR_RES_POIS; if (rand_int(2) == 0) return; } - if (!(o_ptr->art_flags2 & TR2_RES_DARK)) + if (!(o_ptr->art_flags & TR_RES_DARK)) { - o_ptr->art_flags2 |= TR2_RES_DARK; + o_ptr->art_flags |= TR_RES_DARK; if (rand_int(2) == 0) return; } } else if (artifact_bias == BIAS_CHAOS) { - if (!(o_ptr->art_flags2 & TR2_RES_CHAOS)) + if (!(o_ptr->art_flags & TR_RES_CHAOS)) { - o_ptr->art_flags2 |= TR2_RES_CHAOS; + o_ptr->art_flags |= TR_RES_CHAOS; if (rand_int(2) == 0) return; } - if (!(o_ptr->art_flags2 & TR2_RES_CONF)) + if (!(o_ptr->art_flags & TR_RES_CONF)) { - o_ptr->art_flags2 |= TR2_RES_CONF; + o_ptr->art_flags |= TR_RES_CONF; if (rand_int(2) == 0) return; } - if (!(o_ptr->art_flags2 & TR2_RES_DISEN)) + if (!(o_ptr->art_flags & TR_RES_DISEN)) { - o_ptr->art_flags2 |= TR2_RES_DISEN; + o_ptr->art_flags |= TR_RES_DISEN; if (rand_int(2) == 0) return; } } @@ -3133,10 +1981,10 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) { case 1 : if (randint(WEIRD_LUCK) != 1) - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); else { - o_ptr->art_flags2 |= TR2_IM_ACID; + o_ptr->art_flags |= TR_IM_ACID; /* if (is_scroll) msg_print("It looks totally incorruptible."); */ if (!(artifact_bias)) artifact_bias = BIAS_ACID; @@ -3144,10 +1992,10 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) break; case 2: if (randint(WEIRD_LUCK) != 1) - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); else { - o_ptr->art_flags2 |= TR2_IM_ELEC; + o_ptr->art_flags |= TR_IM_ELEC; /* if (is_scroll) msg_print("It looks completely grounded."); */ if (!(artifact_bias)) artifact_bias = BIAS_ELEC; @@ -3155,10 +2003,10 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) break; case 3: if (randint(WEIRD_LUCK) != 1) - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); else { - o_ptr->art_flags2 |= TR2_IM_COLD; + o_ptr->art_flags |= TR_IM_COLD; /* if (is_scroll) msg_print("It feels very warm."); */ if (!(artifact_bias)) artifact_bias = BIAS_COLD; @@ -3166,10 +2014,10 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) break; case 4: if (randint(WEIRD_LUCK) != 1) - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); else { - o_ptr->art_flags2 |= TR2_IM_FIRE; + o_ptr->art_flags |= TR_IM_FIRE; /* if (is_scroll) msg_print("It feels very cool."); */ if (!(artifact_bias)) artifact_bias = BIAS_FIRE; @@ -3178,7 +2026,7 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) case 5: case 6: case 13: - o_ptr->art_flags2 |= TR2_RES_ACID; + o_ptr->art_flags |= TR_RES_ACID; /* if (is_scroll) msg_print("It makes your stomach rumble."); */ if (!(artifact_bias)) artifact_bias = BIAS_ACID; @@ -3186,7 +2034,7 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) case 7: case 8: case 14: - o_ptr->art_flags2 |= TR2_RES_ELEC; + o_ptr->art_flags |= TR_RES_ELEC; /* if (is_scroll) msg_print("It makes you feel grounded."); */ if (!(artifact_bias)) artifact_bias = BIAS_ELEC; @@ -3194,7 +2042,7 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) case 9: case 10: case 15: - o_ptr->art_flags2 |= TR2_RES_FIRE; + o_ptr->art_flags |= TR_RES_FIRE; /* if (is_scroll) msg_print("It makes you feel cool!");*/ if (!(artifact_bias)) artifact_bias = BIAS_FIRE; @@ -3202,14 +2050,14 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) case 11: case 12: case 16: - o_ptr->art_flags2 |= TR2_RES_COLD; + o_ptr->art_flags |= TR_RES_COLD; /* if (is_scroll) msg_print("It makes you feel full of hot air!");*/ if (!(artifact_bias)) artifact_bias = BIAS_COLD; break; case 17: case 18: - o_ptr->art_flags2 |= TR2_RES_POIS; + o_ptr->art_flags |= TR_RES_POIS; /* if (is_scroll) msg_print("It makes breathing easier for you."); */ if (!(artifact_bias) && randint(4) != 1) artifact_bias = BIAS_POIS; @@ -3220,87 +2068,87 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific) break; case 19: case 20: - o_ptr->art_flags2 |= TR2_RES_FEAR; + o_ptr->art_flags |= TR_RES_FEAR; /* if (is_scroll) msg_print("It makes you feel brave!"); */ if (!(artifact_bias) && randint(3) == 1) artifact_bias = BIAS_WARRIOR; break; case 21: - o_ptr->art_flags2 |= TR2_RES_LITE; + o_ptr->art_flags |= TR_RES_LITE; /* if (is_scroll) msg_print("It makes everything look darker.");*/ break; case 22: - o_ptr->art_flags2 |= TR2_RES_DARK; + o_ptr->art_flags |= TR_RES_DARK; /* if (is_scroll) msg_print("It makes everything look brigher.");*/ break; case 23: case 24: - o_ptr->art_flags2 |= TR2_RES_BLIND; + o_ptr->art_flags |= TR_RES_BLIND; /* if (is_scroll) msg_print("It makes you feel you are wearing glasses.");*/ break; case 25: case 26: - o_ptr->art_flags2 |= TR2_RES_CONF; + o_ptr->art_flags |= TR_RES_CONF; /* if (is_scroll) msg_print("It makes you feel very determined.");*/ if (!(artifact_bias) && randint(6) == 1) artifact_bias = BIAS_CHAOS; break; case 27: case 28: - o_ptr->art_flags2 |= TR2_RES_SOUND; + o_ptr->art_flags |= TR_RES_SOUND; /* if (is_scroll) msg_print("It makes you feel deaf!");*/ break; case 29: case 30: - o_ptr->art_flags2 |= TR2_RES_SHARDS; + o_ptr->art_flags |= TR_RES_SHARDS; /* if (is_scroll) msg_print("It makes your skin feel thicker.");*/ break; case 31: case 32: - o_ptr->art_flags2 |= TR2_RES_NETHER; + o_ptr->art_flags |= TR_RES_NETHER; /* if (is_scroll) msg_print("It makes you feel like visiting a graveyard!");*/ if (!(artifact_bias) && randint(3) == 1) artifact_bias = BIAS_NECROMANTIC; break; case 33: case 34: - o_ptr->art_flags2 |= TR2_RES_NEXUS; + o_ptr->art_flags |= TR_RES_NEXUS; /* if (is_scroll) msg_print("It makes you feel normal.");*/ break; case 35: case 36: - o_ptr->art_flags2 |= TR2_RES_CHAOS; + o_ptr->art_flags |= TR_RES_CHAOS; /* if (is_scroll) msg_print("It makes you feel very firm.");*/ if (!(artifact_bias) && randint(2) == 1) artifact_bias = BIAS_CHAOS; break; case 37: case 38: - o_ptr->art_flags2 |= TR2_RES_DISEN; + o_ptr->art_flags |= TR_RES_DISEN; /* if (is_scroll) msg_print("It is surrounded by a static feeling.");*/ break; case 39: if (o_ptr->tval >= TV_CLOAK && o_ptr->tval <= TV_HARD_ARMOR) - o_ptr->art_flags3 |= TR3_SH_ELEC; + o_ptr->art_flags |= TR_SH_ELEC; else - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); if (!(artifact_bias)) artifact_bias = BIAS_ELEC; break; case 40: if (o_ptr->tval >= TV_CLOAK && o_ptr->tval <= TV_HARD_ARMOR) - o_ptr->art_flags3 |= TR3_SH_FIRE; + o_ptr->art_flags |= TR_SH_FIRE; else - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); if (!(artifact_bias)) artifact_bias = BIAS_FIRE; break; case 41: if (o_ptr->tval == TV_SHIELD || o_ptr->tval == TV_CLOAK || o_ptr->tval == TV_HELM || o_ptr->tval == TV_HARD_ARMOR) - o_ptr->art_flags2 |= TR2_REFLECT; + o_ptr->art_flags |= TR_REFLECT; else - random_resistance(o_ptr, is_scroll, specific); + random_resistance(o_ptr, specific); break; } } @@ -3315,7 +2163,7 @@ static void note_found_object(object_type *o_ptr) char note[150]; char item_name[80]; - if (artifact_p(o_ptr) || o_ptr->name1) + if (artifact_p(o_ptr)) { object_desc(item_name, o_ptr, FALSE, 0); @@ -3333,7 +2181,7 @@ static void note_found_object(object_type *o_ptr) * This routine does *not* automatically combine objects. * Returns TRUE if something was identified, else FALSE. */ -bool_ ident_spell(void) +bool_ ident_spell() { /* Get an item */ int item; @@ -3393,7 +2241,7 @@ bool_ ident_spell(void) /* * Identify all objects in the level */ -bool_ ident_all(void) +bool_ ident_all() { int i; @@ -3433,7 +2281,7 @@ static bool item_tester_hook_no_mental(object_type const *o_ptr) * Fully "identify" an object in the inventory -BEN- * This routine returns TRUE if an item was identified. */ -bool_ identify_fully(void) +bool_ identify_fully() { /* Get an item */ int item; @@ -3507,7 +2355,7 @@ object_filter_t const &item_tester_hook_recharge() static auto instance = And( // Must NOT have NO_RECHARGE flag. - Not(HasFlag4(TR4_NO_RECHARGE)), + Not(HasFlags(TR_NO_RECHARGE)), // ... and must be a device. Or( TVal(TV_STAFF), @@ -3539,6 +2387,8 @@ object_filter_t const &item_tester_hook_recharge() */ bool_ recharge(int power) { + auto const &k_info = game->edit_data.k_info; + int recharge_strength, recharge_amount; int lev; bool_ fail = FALSE; @@ -3561,8 +2411,7 @@ bool_ recharge(int power) object_type *o_ptr = get_object(item); /* Extract the flags */ - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Extract the object "level" */ lev = k_info[o_ptr->k_idx].level; @@ -3577,7 +2426,7 @@ bool_ recharge(int power) if (recharge_strength < 0) recharge_strength = 0; /* Back-fire */ - if ((rand_int(recharge_strength) == 0) && (!(f4 & TR4_RECHARGE))) + if ((rand_int(recharge_strength) == 0) && (!(flags & TR_RECHARGE))) { /* Activate the failure code. */ fail = TRUE; @@ -3614,8 +2463,8 @@ bool_ recharge(int power) /* Back-fire XXX XXX XXX */ - if (((rand_int(recharge_strength) == 0) && (!(f4 & TR4_RECHARGE))) || - (f4 & TR4_NO_RECHARGE)) + if (((rand_int(recharge_strength) == 0) && (!(flags & TR_RECHARGE))) || + (flags & TR_NO_RECHARGE)) { /* Activate the failure code. */ fail = TRUE; @@ -3648,7 +2497,7 @@ bool_ recharge(int power) /* Recharge the wand or staff. */ o_ptr->pval += recharge_amount; - if (!(f4 & TR4_RECHARGE)) + if (!(flags & TR_RECHARGE)) { /* Hack -- we no longer "know" the item */ o_ptr->ident &= ~(IDENT_KNOWN); @@ -3660,7 +2509,7 @@ bool_ recharge(int power) } /* Mark as recharged */ - o_ptr->art_flags4 |= TR4_RECHARGED; + o_ptr->art_flags |= TR_RECHARGED; /* Inflict the penalties for failing a recharge. */ if (fail) @@ -3687,7 +2536,7 @@ bool_ recharge(int power) /*** Determine Seriousness of Failure ***/ /* Mages recharge objects more safely. */ - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) { /* 10% chance to blow up one rod, otherwise draining. */ if (o_ptr->tval == TV_ROD_MAIN) @@ -4002,7 +2851,7 @@ bool_ genocide_aux(bool_ player_cast, char typ) { int i; bool_ result = FALSE; - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); int dam = 0; /* Delete the monsters of that "type" */ @@ -4015,7 +2864,7 @@ bool_ genocide_aux(bool_ player_cast, char typ) if (!m_ptr->r_idx) continue; /* Hack -- Skip Unique Monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) continue; + if (r_ptr->flags & RF_UNIQUE) continue; /* Hack -- Skip Quest Monsters */ if (m_ptr->mflag & MFLAG_QUEST) continue; @@ -4024,7 +2873,7 @@ bool_ genocide_aux(bool_ player_cast, char typ) if (r_ptr->d_char != typ) continue; /* Oups */ - if (r_ptr->flags2 & RF2_DEATH_ORB) + if (r_ptr->flags & RF_DEATH_ORB) { int wx, wy; int attempts = 500; @@ -4096,7 +2945,7 @@ bool_ genocide(bool_ player_cast) { char typ; - if (dungeon_flags2 & DF2_NO_GENO) return (FALSE); + if (dungeon_flags & DF_NO_GENO) return (FALSE); /* Hack -- when you are fated to die, you cant cheat :) */ if (dungeon_type == DUNGEON_DEATH) @@ -4119,13 +2968,11 @@ bool_ mass_genocide(bool_ player_cast) { int i; bool_ result = FALSE; - int msec = delay_factor * delay_factor * delay_factor; + auto const msec = options->delay_factor_ms(); int dam = 0; - if (dungeon_flags2 & DF2_NO_GENO) return (FALSE); - - /* Hack -- when you are fated to die, you cant cheat :) */ - if (dungeon_type == DUNGEON_DEATH) + /* Prevented? */ + if ((dungeon_flags & DF_NO_GENO) || (dungeon_type == DUNGEON_DEATH)) { msg_print("A mysterious force stops the genocide."); return FALSE; @@ -4141,7 +2988,7 @@ bool_ mass_genocide(bool_ player_cast) if (!m_ptr->r_idx) continue; /* Hack -- Skip unique monsters */ - if (r_ptr->flags1 & (RF1_UNIQUE)) continue; + if (r_ptr->flags & RF_UNIQUE) continue; /* Hack -- Skip Quest Monsters */ if (m_ptr->mflag & MFLAG_QUEST) continue; @@ -4150,7 +2997,7 @@ bool_ mass_genocide(bool_ player_cast) if (m_ptr->cdis > MAX_SIGHT) continue; /* Oups */ - if (r_ptr->flags2 & RF2_DEATH_ORB) + if (r_ptr->flags & RF_DEATH_ORB) { int wx, wy; int attempts = 500; @@ -4218,94 +3065,6 @@ bool_ mass_genocide(bool_ player_cast) return (result); } -/* Probe a monster */ -void do_probe(int m_idx) -{ - char m_name[80]; - monster_type *m_ptr = &m_list[m_idx]; - - /* Get "the monster" or "something" */ - monster_desc(m_name, m_ptr, 0x04); - - /* Describe the monster */ - if (!wizard && (m_ptr->status != MSTATUS_COMPANION)) msg_format("%^s has %d hit points.", m_name, m_ptr->hp); - else - { - int i; - char t_name[80]; - msg_format("%^s has %d(%d) hit points, %d ac, %d speed.", m_name, m_ptr->hp, m_ptr->maxhp, m_ptr->ac, m_ptr->mspeed - 110); - msg_format("%^s attacks with:", m_name); - - for (i = 0; i < 4; i++) - { - msg_format(" Blow %d: %dd%d", i, m_ptr->blow[i].d_dice, m_ptr->blow[i].d_side); - } - - if (m_ptr->target > 0) - monster_desc(t_name, &m_list[m_ptr->target], 0x04); - else if (!m_ptr->target) - sprintf(t_name, "you"); - else - sprintf(t_name, "nothing"); - msg_format("%^s target is %s.", m_name, t_name); - - { - std::ostringstream buf; - buf << " has " << m_ptr->exp - << " exp and needs " << monster_exp(m_ptr->level + 1) << "."; - msg_format("%^s%s", m_name, buf.str().c_str()); - } - } - - /* Learn all of the non-spell, non-treasure flags */ - lore_do_probe(m_idx); -} - -/* - * Probe nearby monsters - */ -bool_ probing(void) -{ - int i; - - bool_ probe = FALSE; - - - /* Probe all (nearby) monsters */ - for (i = 1; i < m_max; i++) - { - monster_type *m_ptr = &m_list[i]; - - /* Paranoia -- Skip dead monsters */ - if (!m_ptr->r_idx) continue; - - /* Require line of sight */ - if (!player_has_los_bold(m_ptr->fy, m_ptr->fx)) continue; - - /* Probe visible monsters */ - if (m_ptr->ml) - { - /* Start the message */ - if (!probe) msg_print("Probing..."); - - /* Actualy probe */ - do_probe(i); - - /* Probe worked */ - probe = TRUE; - } - } - - /* Done */ - if (probe) - { - msg_print("That's all."); - } - - /* Result */ - return (probe); -} - /* * The spell of destruction @@ -4324,7 +3083,7 @@ void destroy_area(int y1, int x1, int r) bool_ flag = FALSE; - if (dungeon_flags2 & DF2_NO_GENO) + if (dungeon_flags & DF_NO_GENO) { msg_print("Not on special levels!"); return; @@ -4427,7 +3186,7 @@ void destroy_area(int y1, int x1, int r) if (!p_ptr->resist_blind && !p_ptr->resist_lite) { /* Become blind */ - (void)set_blind(p_ptr->blind + 10 + randint(10)); + set_blind(p_ptr->blind + 10 + randint(10)); } } @@ -4602,14 +3361,14 @@ void earthquake(int cy, int cx, int r) { msg_print("You are bashed by rubble!"); damage = damroll(10, 4); - (void)set_stun(p_ptr->stun + randint(50)); + set_stun(p_ptr->stun + randint(50)); break; } case 3: { msg_print("You are crushed between the floor and ceiling!"); damage = damroll(10, 4); - (void)set_stun(p_ptr->stun + randint(50)); + set_stun(p_ptr->stun + randint(50)); break; } } @@ -4636,7 +3395,7 @@ void earthquake(int cy, int cx, int r) map[16 + p_ptr->py - cy][16 + p_ptr->px - cx] = FALSE; /* Semi-wraiths have to be hurt *some*, says DG */ - if (race_flags1_p(PR1_SEMI_WRAITH)) + if (race_flags_p(PR_SEMI_WRAITH)) damage /= 4; /* Take some damage */ @@ -4666,8 +3425,8 @@ void earthquake(int cy, int cx, int r) auto const r_ptr = m_ptr->race(); /* Most monsters cannot co-exist with rock */ - if (!(r_ptr->flags2 & (RF2_KILL_WALL)) && - !(r_ptr->flags2 & (RF2_PASS_WALL))) + if (!(r_ptr->flags & RF_KILL_WALL) && + !(r_ptr->flags & RF_PASS_WALL)) { char m_name[80]; @@ -4675,7 +3434,7 @@ void earthquake(int cy, int cx, int r) sn = 0; /* Monster can move to escape the wall */ - if (!(r_ptr->flags1 & (RF1_NEVER_MOVE))) + if (!(r_ptr->flags & RF_NEVER_MOVE)) { /* Look for safety */ for (i = 0; i < 8; i++) @@ -4866,7 +3625,7 @@ void earthquake(int cy, int cx, int r) * NORMAL monsters wake up 1/4 the time when illuminated * STUPID monsters wake up 1/10 the time when illuminated */ -static void cave_temp_room_lite(void) +static void cave_temp_room_lite() { int i; @@ -4917,10 +3676,10 @@ static void cave_temp_room_lite(void) update_mon(c_ptr->m_idx, FALSE); /* Stupid monsters rarely wake up */ - if (r_ptr->flags2 & (RF2_STUPID)) chance = 10; + if (r_ptr->flags & RF_STUPID) chance = 10; /* Smart monsters always wake up */ - if (r_ptr->flags2 & (RF2_SMART)) chance = 100; + if (r_ptr->flags & RF_SMART) chance = 100; /* Sometimes monsters wake up */ if (m_ptr->csleep && (rand_int(100) < chance)) @@ -4960,7 +3719,7 @@ static void cave_temp_room_lite(void) * * Also, process all affected monsters */ -static void cave_temp_room_unlite(void) +static void cave_temp_room_unlite() { int i; @@ -5128,7 +3887,7 @@ bool_ lite_area(int dam, int rad) } /* Hook into the "project()" function */ - (void)project(0, rad, p_ptr->py, p_ptr->px, dam, GF_LITE_WEAK, flg); + project(0, rad, p_ptr->py, p_ptr->px, dam, GF_LITE_WEAK, flg); /* Lite up the room */ lite_room(p_ptr->py, p_ptr->px); @@ -5153,7 +3912,7 @@ bool_ unlite_area(int dam, int rad) } /* Hook into the "project()" function */ - (void)project(0, rad, p_ptr->py, p_ptr->px, dam, GF_DARK_WEAK, flg); + project(0, rad, p_ptr->py, p_ptr->px, dam, GF_DARK_WEAK, flg); /* Lite up the room */ unlite_room(p_ptr->py, p_ptr->px); @@ -5277,14 +4036,12 @@ void teleport_swap(int dir) monster_type *m_ptr = &m_list[c_ptr->m_idx]; auto const r_ptr = m_ptr->race(); - if (r_ptr->flags3 & RF3_RES_TELE) + if (r_ptr->flags & RF_RES_TELE) { msg_print("Your teleportation is blocked!"); } else { - sound(SOUND_TELEPORT); - cave[p_ptr->py][p_ptr->px].m_idx = c_ptr->m_idx; /* Update the old location */ @@ -5338,9 +4095,6 @@ void teleport_swap(int dir) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -5366,8 +4120,6 @@ void swap_position(int lty, int ltx) if (!c_ptr->m_idx) { - sound(SOUND_TELEPORT); - /* Keep trace of the old location */ tx = p_ptr->px; ty = p_ptr->py; @@ -5391,9 +4143,6 @@ void swap_position(int lty, int ltx) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -5404,8 +4153,6 @@ void swap_position(int lty, int ltx) { m_ptr = &m_list[c_ptr->m_idx]; - sound(SOUND_TELEPORT); - cave[p_ptr->py][p_ptr->px].m_idx = c_ptr->m_idx; /* Update the old location */ @@ -5440,9 +4187,6 @@ void swap_position(int lty, int ltx) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -5548,14 +4292,6 @@ bool_ wizard_lock(int dir) return (project_hook(GF_JAM_DOOR, dir, 20 + randint(30), flg)); } - -bool_ disarm_trap(int dir) -{ - int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM; - return (project_hook(GF_KILL_TRAP, dir, 0, flg)); -} - - bool_ slow_monster(int dir) { int flg = PROJECT_STOP | PROJECT_KILL; @@ -5604,23 +4340,17 @@ bool_ teleport_monster(int dir) return (project_hook(GF_AWAY_ALL, dir, MAX_SIGHT * 5, flg)); } - -bool_ trap_creation(void) -{ - int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE; - return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_MAKE_TRAP, flg)); -} - - bool_ wall_stone(int y, int x) { + auto const &f_info = game->edit_data.f_info; + cave_type *c_ptr = &cave[y][x]; int flg = PROJECT_GRID | PROJECT_ITEM; - int featflags = f_info[c_ptr->feat].flags1; + auto const featflags = f_info[c_ptr->feat].flags; bool_ dummy = (project(0, 1, y, x, 0, GF_STONE_WALL, flg)); - if (!(featflags & FF1_PERMANENT) && !(featflags & FF1_WALL)) + if (!(featflags & FF_PERMANENT) && !(featflags & FF_WALL)) cave_set_feat(y, x, FEAT_FLOOR); /* Update stuff */ @@ -5639,26 +4369,20 @@ bool_ wall_stone(int y, int x) } -bool_ destroy_doors_touch(void) +bool_ destroy_doors_touch() { int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE; return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_KILL_DOOR, flg)); } -bool_ destroy_traps_touch(void) -{ - int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE; - return (project(0, 1, p_ptr->py, p_ptr->px, 0, GF_KILL_TRAP, flg)); -} - -bool_ sleep_monsters_touch(void) +bool_ sleep_monsters_touch() { int flg = PROJECT_KILL | PROJECT_HIDE; return (project(0, 1, p_ptr->py, p_ptr->px, p_ptr->lev, GF_OLD_SLEEP, flg)); } -void call_chaos(void) +void call_chaos() { int Chaos_type, dummy, dir; int plev = p_ptr->lev; @@ -5707,7 +4431,7 @@ void call_chaos(void) } -static void activate_hi_summon(void) +static void activate_hi_summon() { int i; @@ -5717,57 +4441,57 @@ static void activate_hi_summon(void) { case 1: case 2: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT); break; case 3: case 4: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER); break; case 5: case 6: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND); break; case 7: case 8: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA); break; case 9: case 10: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL); break; case 11: case 12: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD); break; case 13: case 14: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON); break; case 15: case 16: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON); break; case 17: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH); break; case 18: case 19: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE); break; case 20: case 21: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD); break; case 22: case 23: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON); + summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON); break; case 24: case 25: - (void) summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON); + summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON); break; default: - (void) summon_specific(p_ptr->py, p_ptr->px, (((dun_level * 3) / 2) + 5), 0); + summon_specific(p_ptr->py, p_ptr->px, (((dun_level * 3) / 2) + 5), 0); } } } @@ -5778,7 +4502,7 @@ static void activate_hi_summon(void) * rr9: Stop the nasty things when a Cyberdemon is summoned * or the player gets paralyzed. */ -void activate_ty_curse(void) +void activate_ty_curse() { int i = 0; bool_ stop_ty = FALSE; @@ -5800,7 +4524,7 @@ void activate_ty_curse(void) activate_hi_summon(); if (randint(6) != 1) break; case 7: case 8: case 9: case 18: - (void) summon_specific(p_ptr->py, p_ptr->px, dun_level, 0); + summon_specific(p_ptr->py, p_ptr->px, dun_level, 0); if (randint(6) != 1) break; case 10: case 11: case 12: msg_print("You feel your life draining away..."); @@ -5822,7 +4546,7 @@ case 13: case 14: case 15: case 19: case 20: } if (randint(6) != 1) break; case 21: case 22: case 23: - (void)do_dec_stat((randint(6)) - 1, STAT_DEC_NORMAL); + do_dec_stat((randint(6)) - 1, STAT_DEC_NORMAL); if (randint(6) != 1) break; case 24: msg_print("Huh? Who am I? What am I doing here?"); @@ -5843,7 +4567,7 @@ case 21: case 22: case 23: { do { - (void)do_dec_stat(i, STAT_DEC_NORMAL); + do_dec_stat(i, STAT_DEC_NORMAL); } while (randint(2) == 1); @@ -5857,7 +4581,7 @@ case 21: case 22: case 23: /* * Activate the ultra evil Dark God curse */ -void activate_dg_curse(void) +void activate_dg_curse() { int i = 0; bool_ stop_dg = FALSE; @@ -5924,7 +4648,7 @@ void activate_dg_curse(void) case 21: case 22: case 23: - (void)do_dec_stat((randint(6)) - 1, STAT_DEC_PERMANENT); + do_dec_stat((randint(6)) - 1, STAT_DEC_PERMANENT); if (randint(7) != 1) break; case 24: msg_print("Huh? Who am I? What am I doing here?"); @@ -5934,7 +4658,7 @@ case 27: case 28: case 29: if (p_ptr->inventory[INVEN_WIELD].k_idx) { msg_print("Your weapon now seems useless..."); - p_ptr->inventory[INVEN_WIELD].art_flags4 = TR4_NEVER_BLOW; + p_ptr->inventory[INVEN_WIELD].art_flags = TR_NEVER_BLOW; } break; case 25: @@ -5955,7 +4679,7 @@ case 27: case 28: case 29: { do { - (void)do_dec_stat(i, STAT_DEC_NORMAL); + do_dec_stat(i, STAT_DEC_NORMAL); } while (randint(2) == 1); @@ -5967,14 +4691,14 @@ case 27: case 28: case 29: } -void summon_cyber(void) +void summon_cyber() { int i; int max_cyber = (dun_level / 50) + randint(6); for (i = 0; i < max_cyber; i++) { - (void)summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON); + summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_HI_DEMON); } } @@ -5985,7 +4709,7 @@ static void summon_dragon_riders() for (i = 0; i < max_dr; i++) { - (void)summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_THUNDERLORD); + summon_specific(p_ptr->py, p_ptr->px, 100, SUMMON_THUNDERLORD); } } @@ -6073,7 +4797,7 @@ bool_ charm_animal(int dir, int plev) return (project_hook(GF_CONTROL_ANIMAL, dir, plev, flg)); } -void change_wild_mode(void) +void change_wild_mode() { if (p_ptr->immovable && !p_ptr->wild_mode) { @@ -6095,7 +4819,7 @@ void change_wild_mode(void) } -void alter_reality(void) +void alter_reality() { msg_print("The world changes!"); @@ -6150,13 +4874,20 @@ bool_ heal_insanity(int val) */ bool_ passwall(int dir, bool_ safe) { - int x = p_ptr->px, y = p_ptr->py, ox = p_ptr->px, oy = p_ptr->py, lx = p_ptr->px, ly = p_ptr->py; + auto const &f_info = game->edit_data.f_info; + + int x = p_ptr->px; + int y = p_ptr->py; + int ox = p_ptr->px; + int oy = p_ptr->py; + int lx = p_ptr->px; + int ly = p_ptr->py; cave_type *c_ptr; bool_ ok = FALSE; if (p_ptr->wild_mode) return FALSE; if (p_ptr->inside_quest) return FALSE; - if (dungeon_flags2 & DF2_NO_TELEPORT) return FALSE; + if (dungeon_flags & DF_NO_TELEPORT) return FALSE; /* Must go somewhere */ if (dir == 5) return FALSE; @@ -6168,7 +4899,7 @@ bool_ passwall(int dir, bool_ safe) c_ptr = &cave[y][x]; /* Perm walls stops the transfer */ - if ((!in_bounds(y, x)) && (f_info[c_ptr->feat].flags1 & FF1_PERMANENT)) + if ((!in_bounds(y, x)) && (f_info[c_ptr->feat].flags & FF_PERMANENT)) { /* get the last working position */ x -= ddx[dir]; @@ -6188,7 +4919,7 @@ bool_ passwall(int dir, bool_ safe) ly = y; /* Pass over walls */ - if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue; + if (f_info[c_ptr->feat].flags & FF_WALL) continue; /* So it must be ok */ ok = TRUE; @@ -6227,9 +4958,6 @@ bool_ passwall(int dir, bool_ safe) /* Update the monsters */ p_ptr->update |= (PU_DISTANCE); - /* Redraw trap detection status */ - p_ptr->redraw |= (PR_FRAME); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); @@ -6246,7 +4974,8 @@ static void print_dungeon_batch(std::vector<int> const &dungeon_idxs, int start, bool_ mode) { - char buf[80]; + auto const &d_info = game->edit_data.d_info; + int i, j; byte attr; @@ -6254,9 +4983,11 @@ static void print_dungeon_batch(std::vector<int> const &dungeon_idxs, for (i = 0, j = start; i < 20 && j < static_cast<int>(dungeon_idxs.size()); i++, j++) { - dungeon_info_type *d_ptr = &d_info[dungeon_idxs[j]]; + auto d_ptr = &d_info[dungeon_idxs[j]]; + + char buf[80]; + strnfmt(buf, 80, " %c) %-30s", I2A(i), d_ptr->name.c_str()); - strnfmt(buf, 80, " %c) %-30s", I2A(i), d_ptr->name); if (mode) { if (d_ptr->min_plev > p_ptr->lev) @@ -6277,13 +5008,11 @@ static void print_dungeon_batch(std::vector<int> const &dungeon_idxs, static int find_dungeon_by_name(char const *name) { + auto const &d_info = game->edit_data.d_info; + /* Find the index corresponding to the name */ - for (int i = 1; i < max_d_idx; i++) + for (std::size_t i = 1; i < d_info.size(); i++) { - /* Skip non-initialized entries. */ - if (d_info[i].name == nullptr) { - continue; - } if (iequals(name, d_info[i].name)) { return i; @@ -6295,6 +5024,8 @@ static int find_dungeon_by_name(char const *name) static int reset_recall_aux() { + auto const &d_info = game->edit_data.d_info; + char which; int start = 0; int ret; @@ -6302,10 +5033,10 @@ static int reset_recall_aux() // Dungeons available for recall std::vector<int> dungeons; - for (size_t i = 1; i < max_d_idx; i++) + for (size_t i = 1; i < d_info.size(); i++) { /* skip "blocked" dungeons */ - if (d_info[i].flags1 & DF1_NO_RECALL) continue; + if (d_info[i].flags & DF_NO_RECALL) continue; if (max_dlv[i]) { @@ -6360,7 +5091,8 @@ static int reset_recall_aux() else if (which == '@') { char buf[80]; - strcpy(buf, d_info[p_ptr->recall_dungeon].name); + strcpy(buf, d_info[p_ptr->recall_dungeon].name.c_str()); + if (!get_string("Which dungeon? ", buf, 79)) continue; /* Find the index corresponding to the name */ @@ -6372,7 +5104,7 @@ static int reset_recall_aux() msg_print(NULL); continue; } - else if (d_info[i].flags1 & DF1_NO_RECALL) + else if (d_info[i].flags & DF_NO_RECALL) { msg_print("This place blocks my magic!"); msg_print(NULL); @@ -6419,6 +5151,8 @@ static int reset_recall_aux() bool_ reset_recall(bool_ no_trepas_max_depth) { + auto const &d_info = game->edit_data.d_info; + int dun, depth, max; /* Choose dungeon */ @@ -6431,8 +5165,9 @@ bool_ reset_recall(bool_ no_trepas_max_depth) max = d_info[dun].maxdepth; else max = max_dlv[dun]; + depth = get_quantity(format("Which level in %s(%d-%d)? ", - d_info[dun].name, + d_info[dun].name.c_str(), d_info[dun].mindepth, max), max); @@ -6455,9 +5190,11 @@ bool_ reset_recall(bool_ no_trepas_max_depth) */ void create_between_gate(int dist, int y, int x) { + auto const &f_info = game->edit_data.f_info; + int ii, ij, plev = get_skill(SKILL_CONVEYANCE); - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("Not on special levels!"); return; @@ -6485,12 +5222,12 @@ void create_between_gate(int dist, int y, int x) ij = y; ii = x; } - if (!(f_info[cave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_PERMANENT)) + if (!(f_info[cave[p_ptr->py][p_ptr->px].feat].flags & FF_PERMANENT)) { cave_set_feat(p_ptr->py, p_ptr->px, FEAT_BETWEEN); cave[p_ptr->py][p_ptr->px].special = ii + (ij << 8); } - if (!(f_info[cave[ij][ii].feat].flags1 & FF1_PERMANENT)) + if (!(f_info[cave[ij][ii].feat].flags & FF_PERMANENT)) { cave_set_feat(ij, ii, FEAT_BETWEEN); cave[ij][ii].special = p_ptr->px + (p_ptr->py << 8); @@ -6558,6 +5295,8 @@ static int rotate_dir(int dir, int mov) void geomancy_random_wall(int y, int x) { + auto const &f_info = game->edit_data.f_info; + #define TABLE_SIZE 4 cave_type *c_ptr = &cave[y][x]; int feat = -1; @@ -6572,7 +5311,8 @@ void geomancy_random_wall(int y, int x) }; /* Do not destroy permanent things */ - if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) { + if (f_info[c_ptr->feat].flags & FF_PERMANENT) + { return; } @@ -6587,6 +5327,8 @@ void geomancy_random_wall(int y, int x) void geomancy_random_floor(int y, int x, bool_ kill_wall) { + auto const &f_info = game->edit_data.f_info; + #define TABLE_SIZE 9 cave_type *c_ptr = &cave[y][x]; int feat = -1; @@ -6606,10 +5348,10 @@ void geomancy_random_floor(int y, int x, bool_ kill_wall) }; /* Do not destroy permanent things */ - if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) { + if (f_info[c_ptr->feat].flags & FF_PERMANENT) { return; } - if (!(kill_wall || (f_info[c_ptr->feat].flags1 & FF1_FLOOR))) { + if (!(kill_wall || (f_info[c_ptr->feat].flags & FF_FLOOR))) { return; } diff --git a/src/spells2.hpp b/src/spells2.hpp index bffc4a2c..0eeb3f5b 100644 --- a/src/spells2.hpp +++ b/src/spells2.hpp @@ -2,114 +2,111 @@ #include "h-basic.h" #include "identify_mode.hpp" +#include "monster_race_flag_set.hpp" #include "object_filter.hpp" #include "object_type_fwd.hpp" -extern void curse_artifact(object_type * o_ptr); -extern void grow_things(s16b type, int rad); -extern void grow_grass(int rad); -extern void grow_trees(int rad); -extern bool_ hp_player(int num); -extern bool_ heal_insanity(int val); -extern void warding_glyph(void); -extern void explosive_rune(void); -extern bool_ do_dec_stat(int stat, int mode); -extern bool_ do_res_stat(int stat, bool_ full); -extern bool_ do_inc_stat(int stat); -extern void identify_hooks(int i, object_type *o_ptr, identify_mode type); -extern bool_ identify_pack(void); -extern void identify_pack_fully(void); -extern bool_ remove_curse(void); -extern bool_ remove_all_curse(void); -extern bool_ restore_level(void); -extern void self_knowledge(FILE *fff); -extern bool_ lose_all_info(void); -extern bool_ detect_traps(int rad); -extern bool_ detect_doors(int rad); -extern bool_ detect_stairs(int rad); -extern bool_ detect_treasure(int rad); -extern bool detect_objects_gold(int rad); -extern bool detect_objects_normal(int rad); -extern bool_ detect_monsters_normal(int rad); -extern bool_ detect_monsters_invis(int rad); -extern bool_ detect_monsters_xxx(u32b match_flag, int rad); -extern bool_ detect_all(int rad); -extern void stair_creation(void); -extern bool_ wall_stone(int y, int x); -extern bool_ enchant(object_type *o_ptr, int n, int eflag); -extern bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval); -extern bool_ ident_spell(void); -extern bool_ ident_all(void); -extern bool_ identify_fully(void); -extern bool_ recharge(int num); -extern void aggravate_monsters(int who); -extern bool_ genocide_aux(bool_ player_cast, char typ); -extern bool_ genocide(bool_ player_cast); -extern bool_ mass_genocide(bool_ player_cast); -extern void do_probe(int m_idx); -extern bool_ probing(void); -extern void change_wild_mode(void); -extern bool_ banish_evil(int dist); -extern bool_ dispel_evil(int dam); -extern bool_ dispel_good(int dam); -extern bool_ dispel_undead(int dam); -extern bool_ dispel_monsters(int dam); -extern void destroy_area(int y1, int x1, int r); -extern void earthquake(int cy, int cx, int r); -extern void lite_room(int y1, int x1); -extern void unlite_room(int y1, int x1); -extern bool_ lite_area(int dam, int rad); -extern bool_ unlite_area(int dam, int rad); -extern bool_ fire_cloud(int typ, int dir, int dam, int rad, int time); -extern bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff); -extern bool_ fire_wall(int typ, int dir, int dam, int time); -extern bool_ fire_ball(int typ, int dir, int dam, int rad); -extern bool_ fire_bolt(int typ, int dir, int dam); -extern bool_ fire_beam(int typ, int dir, int dam); -extern void call_chaos(void); -extern bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam); -extern bool_ lite_line(int dir); -extern bool_ drain_life(int dir, int dam); -extern bool_ wall_to_mud(int dir); -extern bool_ disarm_trap(int dir); -extern bool_ wizard_lock(int dir); -extern bool_ slow_monster(int dir); -extern bool_ sleep_monster(int dir); -extern bool_ confuse_monster(int dir, int plev); -extern bool_ fear_monster(int dir, int plev); -extern bool_ poly_monster(int dir); -extern bool_ teleport_monster(int dir); -extern bool_ trap_creation(void); -extern bool_ destroy_doors_touch(void); -extern bool_ destroy_traps_touch(void); -extern bool_ sleep_monsters_touch(void); -extern bool_ alchemy(void); -extern void activate_ty_curse(void); -extern void activate_dg_curse(void); -extern void summon_cyber(void); -extern bool_ confuse_monsters(int dam); -extern bool_ charm_monsters(int dam); -extern bool_ charm_animals(int dam); -extern bool_ stun_monsters(int dam); -extern bool_ banish_monsters(int dist); -extern bool_ turn_monsters(int dam); -extern bool_ charm_monster(int dir, int plev); -extern bool_ control_one_undead(int dir, int plev); -extern bool_ charm_animal(int dir, int plev); -extern bool_ mindblast_monsters(int dam); -extern void alter_reality(void); -extern void report_magics(void); -extern void teleport_swap(int dir); -extern void swap_position(int lty, int ltx); -extern object_filter_t const &item_tester_hook_recharge(); -extern bool_ project_hack(int typ, int dam); -extern void project_meteor(int radius, int typ, int dam, u32b flg); -extern object_filter_t const &item_tester_hook_artifactable(); -extern bool_ passwall(int dir, bool_ safe); -extern bool_ project_hook(int typ, int dir, int dam, int flg); -extern bool_ reset_recall(bool_ no_trepas_max_depth); -extern void geomancy_random_wall(int y, int x); -extern void geomancy_random_floor(int y, int x, bool_ kill_wall); -extern void geomancy_dig(int oy, int ox, int dir, int length); -extern void channel_the_elements(int y, int x, int level); -extern void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific); +void curse_artifact(object_type * o_ptr); +void grow_things(s16b type, int rad); +void grow_grass(int rad); +void grow_trees(int rad); +bool_ hp_player(int num); +bool_ heal_insanity(int val); +void warding_glyph(); +void explosive_rune(); +bool_ do_dec_stat(int stat, int mode); +bool_ do_res_stat(int stat, bool_ full); +bool_ do_inc_stat(int stat); +void identify_hooks(int i, object_type *o_ptr, identify_mode type); +bool_ identify_pack(); +void identify_pack_fully(); +bool_ remove_curse(); +bool_ remove_all_curse(); +bool_ restore_level(); +bool_ lose_all_info(); +bool_ detect_traps(int rad); +bool_ detect_doors(int rad); +bool_ detect_stairs(int rad); +bool_ detect_treasure(int rad); +bool detect_objects_gold(int rad); +bool detect_objects_normal(int rad); +bool_ detect_monsters_normal(int rad); +bool_ detect_monsters_invis(int rad); +void detect_monsters_orcs(int rad); +bool_ detect_all(int rad); +void stair_creation(); +bool_ wall_stone(int y, int x); +bool_ enchant(object_type *o_ptr, int n, int eflag); +bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval); +bool_ ident_spell(); +bool_ ident_all(); +bool_ identify_fully(); +bool_ recharge(int num); +void aggravate_monsters(int who); +bool_ genocide_aux(bool_ player_cast, char typ); +bool_ genocide(bool_ player_cast); +bool_ mass_genocide(bool_ player_cast); +void change_wild_mode(); +bool_ banish_evil(int dist); +bool_ dispel_evil(int dam); +bool_ dispel_good(int dam); +bool_ dispel_undead(int dam); +bool_ dispel_monsters(int dam); +void destroy_area(int y1, int x1, int r); +void earthquake(int cy, int cx, int r); +void lite_room(int y1, int x1); +void unlite_room(int y1, int x1); +bool_ lite_area(int dam, int rad); +bool_ unlite_area(int dam, int rad); +bool_ fire_cloud(int typ, int dir, int dam, int rad, int time); +bool_ fire_wave(int typ, int dir, int dam, int rad, int time, s32b eff); +bool_ fire_wall(int typ, int dir, int dam, int time); +bool_ fire_ball(int typ, int dir, int dam, int rad); +bool_ fire_bolt(int typ, int dir, int dam); +bool_ fire_beam(int typ, int dir, int dam); +void call_chaos(); +bool_ fire_bolt_or_beam(int prob, int typ, int dir, int dam); +bool_ lite_line(int dir); +bool_ drain_life(int dir, int dam); +bool_ wall_to_mud(int dir); +bool_ wizard_lock(int dir); +bool_ slow_monster(int dir); +bool_ sleep_monster(int dir); +bool_ confuse_monster(int dir, int plev); +bool_ fear_monster(int dir, int plev); +bool_ poly_monster(int dir); +bool_ teleport_monster(int dir); +bool_ trap_creation(); +bool_ destroy_doors_touch(); +bool_ destroy_traps_touch(); +bool_ sleep_monsters_touch(); +bool_ alchemy(); +void activate_ty_curse(); +void activate_dg_curse(); +void summon_cyber(); +bool_ confuse_monsters(int dam); +bool_ charm_monsters(int dam); +bool_ charm_animals(int dam); +bool_ stun_monsters(int dam); +bool_ banish_monsters(int dist); +bool_ turn_monsters(int dam); +bool_ charm_monster(int dir, int plev); +bool_ control_one_undead(int dir, int plev); +bool_ charm_animal(int dir, int plev); +bool_ mindblast_monsters(int dam); +void alter_reality(); +void report_magics(); +void teleport_swap(int dir); +void swap_position(int lty, int ltx); +object_filter_t const &item_tester_hook_recharge(); +bool_ project_hack(int typ, int dam); +void project_meteor(int radius, int typ, int dam, u32b flg); +object_filter_t const &item_tester_hook_artifactable(); +bool_ passwall(int dir, bool_ safe); +bool_ project_hook(int typ, int dir, int dam, int flg); +bool_ reset_recall(bool_ no_trepas_max_depth); +void geomancy_random_wall(int y, int x); +void geomancy_random_floor(int y, int x, bool_ kill_wall); +void geomancy_dig(int oy, int ox, int dir, int length); +void channel_the_elements(int y, int x, int level); +void random_resistance(object_type *o_ptr, int specific); diff --git a/src/spells3.cc b/src/spells3.cc index 35604f7d..58d42cab 100644 --- a/src/spells3.cc +++ b/src/spells3.cc @@ -3,12 +3,15 @@ #include "cave.hpp" #include "cave_type.hpp" #include "cmd5.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "lua_bind.hpp" #include "mimic.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" @@ -41,7 +44,6 @@ s32b THUNDERSTORM; s32b STERILIZE; s32b BLINK; -s32b DISARM; s32b TELEPORT; s32b TELEAWAY; s32b RECALL; @@ -192,11 +194,6 @@ s32b VARDA_CALL_ALMAREN; s32b VARDA_EVENSTAR; s32b VARDA_STARKINDLER; -static s32b get_level_s(int sp, int max) -{ - return get_level(sp, max, 1); -} - static void find_position(int y, int x, int *yy, int *xx) { int attempts = 500; @@ -403,19 +400,6 @@ const char *convey_blink_info() return buf; } -casting_result convey_disarm() -{ - casting_result result = NO_CAST; - - result = cplus(result, destroy_doors_touch()); - if (get_level_s(DISARM, 50) >= 10) - { - result = cplus(result, destroy_traps_touch()); - } - - return result; -} - casting_result convey_teleport() { p_ptr->energy -= (25 - get_level_s(TELEPORT, 50)); @@ -628,13 +612,13 @@ casting_result demonology_demon_madness() x2 = p_ptr->px - (x1 - p_ptr->px); result = cplus(result, - project(0, 1 + get_level(DEMON_MADNESS, 4, 0), + project(0, 1 + get_level(DEMON_MADNESS, 4), y1, x1, 20 + get_level_s(DEMON_MADNESS, 200), type, PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL)); result = cplus(result, - project(0, 1 + get_level(DEMON_MADNESS, 4, 0), + project(0, 1 + get_level(DEMON_MADNESS, 4), y2, x2, 20 + get_level_s(DEMON_MADNESS, 200), type, @@ -649,7 +633,7 @@ const char *demonology_demon_madness_info() sprintf(buf, "dam " FMTs32b " rad " FMTs32b, (20 + get_level_s(DEMON_MADNESS, 200)), - (1 + get_level(DEMON_MADNESS, 4, 0))); + (1 + get_level(DEMON_MADNESS, 4))); return buf; } @@ -721,7 +705,7 @@ casting_result demonology_unholy_word() } /* Oops he is angry now */ - if (magik(30 - get_level(UNHOLY_WORD, 25, 0))) + if (magik(30 - get_level(UNHOLY_WORD, 25))) { char buf[128]; monster_desc(buf, m_ptr, 0); @@ -741,7 +725,7 @@ casting_result demonology_unholy_word() msg_format("You consume %s.", buf); heal = (m_ptr->hp * 100) / m_ptr->maxhp; - heal = ((30 + get_level(UNHOLY_WORD, 50, 0)) * heal) / 100; + heal = ((30 + get_level(UNHOLY_WORD, 50)) * heal) / 100; hp_player(heal); @@ -761,13 +745,13 @@ const char *demonology_unholy_word_info() static char buf[128]; sprintf(buf, "heal mhp%% of " FMTs32b "%%", - (30 + get_level(UNHOLY_WORD, 50, 0))); + (30 + get_level(UNHOLY_WORD, 50))); return buf; } casting_result demonology_demon_cloak() { - return cast(set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15, 0))); + return cast(set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15))); } const char *demonology_demon_cloak_info() @@ -775,7 +759,7 @@ const char *demonology_demon_cloak_info() static char buf[128]; sprintf(buf, "dur " FMTs32b "+d5", - (5 + get_level(DEMON_CLOAK, 15, 0))); + (5 + get_level(DEMON_CLOAK, 15))); return buf; } @@ -844,10 +828,10 @@ casting_result demonology_discharge_minion() delete_monster_idx(c_ptr->m_idx); dam = m_ptr->hp; - dam = (dam * (20 + get_level(DISCHARGE_MINION, 60, 0))) / 100; - if (dam > 100 + get_level(DISCHARGE_MINION, 500, 0)) + dam = (dam * (20 + get_level(DISCHARGE_MINION, 60))) / 100; + if (dam > 100 + get_level(DISCHARGE_MINION, 500)) { - dam = 100 + get_level(DISCHARGE_MINION, 500, 0); + dam = 100 + get_level(DISCHARGE_MINION, 500); } /* We use project instead of fire_ball because we must tell it exactly where to land */ @@ -866,8 +850,8 @@ const char *demonology_discharge_minion_info() static char buf[128]; sprintf(buf, "dam " FMTs32b "%% max " FMTs32b, - (20 + get_level(DISCHARGE_MINION, 60, 0)), - (100 + get_level(DISCHARGE_MINION, 500, 0))); + (20 + get_level(DISCHARGE_MINION, 60)), + (100 + get_level(DISCHARGE_MINION, 500))); return buf; } @@ -893,31 +877,16 @@ const char *demonology_control_demon_info() casting_result divination_greater_identify() { - if (get_check("Cast on yourself?")) - { - self_knowledge(NULL); - } - else - { - identify_fully(); - } + identify_fully(); return CAST_OBVIOUS; } casting_result divination_identify() { - if (get_level_s(IDENTIFY, 50) >= 27) + if (get_level_s(IDENTIFY, 50) >= 17) { casting_result result = NO_CAST; result = cplus(result, identify_pack()); - result = cplus(result, fire_ball(GF_IDENTIFY, 0, 1, get_level_s(IDENTIFY, 3))); - return result; - } - else if (get_level_s(IDENTIFY, 50) >= 17) - { - casting_result result = NO_CAST; - result = cplus(result, identify_pack()); - result = cplus(result, fire_ball(GF_IDENTIFY, 0, 1, 0)); return result; } else if (ident_spell()) @@ -962,12 +931,7 @@ casting_result divination_vision() casting_result divination_sense_hidden() { casting_result result = NO_CAST; - - result = cplus(result, detect_traps(15 + get_level(SENSEHIDDEN, 40, 0))); - if (get_level_s(SENSEHIDDEN, 50) >= 15) - { - result = cplus(result, set_tim_invis(10 + randint(20) + get_level_s(SENSEHIDDEN, 40))); - } + result = cplus(result, set_tim_invis(10 + randint(20) + get_level_s(SENSEHIDDEN, 40))); return result; } @@ -996,8 +960,8 @@ const char *divination_sense_hidden_info() casting_result divination_reveal_ways() { casting_result result = NO_CAST; - result = cplus(result, detect_doors(10 + get_level(REVEALWAYS, 40, 0))); - result = cplus(result, detect_stairs(10 + get_level(REVEALWAYS, 40, 0))); + result = cplus(result, detect_doors(10 + get_level(REVEALWAYS, 40))); + result = cplus(result, detect_stairs(10 + get_level(REVEALWAYS, 40))); return result; } @@ -1014,7 +978,7 @@ casting_result divination_sense_monsters() { casting_result result = NO_CAST; - result = cplus(result, detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40, 0))); + result = cplus(result, detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40))); if (get_level_s(SENSEMONSTERS, 50) >= 30) { result = cplus(result, set_tim_esp(10 + randint(10) + get_level_s(SENSEMONSTERS, 20))); @@ -1250,7 +1214,7 @@ casting_result eru_know_the_music() casting_result eru_lay_of_protection() { - return cast(fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2, 0))); + return cast(fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2))); } const char *eru_lay_of_protection_info() @@ -1258,7 +1222,7 @@ const char *eru_lay_of_protection_info() static char buf[128]; sprintf(buf, "rad " FMTs32b, - (1 + get_level(ERU_PROT, 2, 0))); + (1 + get_level(ERU_PROT, 2))); return buf; } @@ -1471,7 +1435,7 @@ casting_result geomancy_call_the_elements() fire_ball(GF_ELEMENTAL_GROWTH, dir, 1, - 1 + get_level(CALL_THE_ELEMENTS, 5, 0)); + 1 + get_level(CALL_THE_ELEMENTS, 5)); return CAST_OBVIOUS; } @@ -1481,7 +1445,7 @@ const char *geomancy_call_the_elements_info() static char buf[128]; sprintf(buf, "rad " FMTs32b, - (1 + get_level(CALL_THE_ELEMENTS, 5, 0))); + (1 + get_level(CALL_THE_ELEMENTS, 5))); return buf; } @@ -2108,7 +2072,7 @@ casting_result manwe_call() if (m_idx > 0) { - monster_set_level(m_idx, 20 + get_level(MANWE_CALL, 70, 0)); + monster_set_level(m_idx, 20 + get_level(MANWE_CALL, 70)); return CAST_OBVIOUS; } @@ -2276,7 +2240,7 @@ casting_result melkor_mind_steal() auto const r_ptr = m_ptr->race(); if ((randint(m_ptr->level) < chance) && - ((r_ptr->flags1 & RF1_UNIQUE) == 0)) + ((r_ptr->flags & RF_UNIQUE).empty())) { p_ptr->control = target_who; m_ptr->mflag |= MFLAG_CONTROL; @@ -2327,7 +2291,9 @@ static int get_spellbinder_max() casting_result meta_spellbinder() { - if (p_ptr->spellbinder_num != 0) + auto spellbinder = &p_ptr->spellbinder; + + if (spellbinder->spell_idxs.size() > 0) { struct trigger { int idx; @@ -2340,13 +2306,12 @@ casting_result meta_spellbinder() { -1, NULL, }, }; int trigger_idx = -1; - int i; - assert(p_ptr->spellbinder_trigger >= 0); + assert(spellbinder->trigger >= 0); for (trigger_idx = 0; triggers[trigger_idx].idx >= 0; trigger_idx++) { - if (triggers[trigger_idx].idx == p_ptr->spellbinder_trigger) + if (triggers[trigger_idx].idx == spellbinder->trigger) { break; } @@ -2355,9 +2320,9 @@ casting_result meta_spellbinder() msg_print("The spellbinder is already active."); msg_format("It will trigger at %s.", triggers[trigger_idx].desc); msg_print("With the spells: "); - for (i = 0; i < p_ptr->spellbinder_num; i++) + for (auto spell_idx : spellbinder->spell_idxs) { - msg_print(spell_type_name(spell_at(p_ptr->spellbinder[i]))); + msg_print(spell_type_name(spell_at(spell_idx))); } /* Doesn't cost anything */ @@ -2366,7 +2331,6 @@ casting_result meta_spellbinder() else { char c; - int i; if (!get_com("Trigger at [a]75% hp [b]50% hp [c]25% hp?", &c)) { @@ -2376,30 +2340,32 @@ casting_result meta_spellbinder() switch (c) { case 'a': - p_ptr->spellbinder_trigger = SPELLBINDER_HP75; + spellbinder->trigger = SPELLBINDER_HP75; break; case 'b': - p_ptr->spellbinder_trigger = SPELLBINDER_HP50; + spellbinder->trigger = SPELLBINDER_HP50; break; case 'c': - p_ptr->spellbinder_trigger = SPELLBINDER_HP25; + spellbinder->trigger = SPELLBINDER_HP25; break; default: return NO_CAST; } - p_ptr->spellbinder_num = get_spellbinder_max(); - i = p_ptr->spellbinder_num; - while (i > 0) + std::size_t n = get_spellbinder_max(); + while (n > 0) { s32b s = get_school_spell("bind", 0); + if (s == -1) { - p_ptr->spellbinder_trigger = 0; - p_ptr->spellbinder_num = 0; + spellbinder->trigger = 0; + spellbinder->spell_idxs.clear(); return CAST_OBVIOUS; - } else { + } + else + { if (spell_type_skill_level(spell_at(s)) > 7 + get_level_s(SPELLBINDER, 35)) { msg_format("You are only allowed spells with a base level of " FMTs32b ".", (7 + get_level_s(SPELLBINDER, 35))); @@ -2407,8 +2373,8 @@ casting_result meta_spellbinder() } } - p_ptr->spellbinder[i] = s; - i = i - 1; + spellbinder->spell_idxs.push_back(s); + n--; } p_ptr->energy = p_ptr->energy - 3100; @@ -2481,7 +2447,7 @@ static void stop_inertia_controlled_spell() assert(TIMER_INERTIA_CONTROL != NULL); p_ptr->inertia_controlled_spell = -1; - TIMER_INERTIA_CONTROL->enabled = FALSE; + TIMER_INERTIA_CONTROL->disable(); p_ptr->update = p_ptr->update | PU_MANA; } @@ -2526,9 +2492,8 @@ casting_result meta_inertia_control() } p_ptr->inertia_controlled_spell = s; - TIMER_INERTIA_CONTROL->enabled = TRUE; - TIMER_INERTIA_CONTROL->delay = delay; - TIMER_INERTIA_CONTROL->countdown = delay; + TIMER_INERTIA_CONTROL->set_delay_and_reset(delay); + TIMER_INERTIA_CONTROL->enable(); p_ptr->update |= PU_MANA; msg_format("Inertia flow controlling spell %s.", spell_type_name(spell_at(s))); return CAST_OBVIOUS; @@ -2727,6 +2692,8 @@ const char *mind_stun_info() casting_result tempo_magelock() { + auto const &f_info = game->edit_data.f_info; + if (get_level_s(MAGELOCK, 50) >= 30) { int x,y; @@ -2742,8 +2709,8 @@ casting_result tempo_magelock() c_ptr = &cave[y][x]; - if ((!(f_info[c_ptr->feat].flags1 | FF1_FLOOR)) || - (f_info[c_ptr->feat].flags1 | FF1_PERMANENT) || + if ((!(f_info[c_ptr->feat].flags | FF_FLOOR)) || + (f_info[c_ptr->feat].flags | FF_PERMANENT) || (!los(p_ptr->py, p_ptr->px, y, x))) { msg_print("You cannot place it there."); @@ -2973,6 +2940,8 @@ static object_filter_t const &udun_object_is_drainable() casting_result udun_drain() { + auto const &k_info = game->edit_data.k_info; + /* Ask for an item */ int item; if (!get_item(&item, @@ -2992,7 +2961,7 @@ casting_result udun_drain() case TV_STAFF: case TV_WAND: { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; + auto k_ptr = &k_info[o_ptr->k_idx]; /* Generate mana */ increase_mana(o_ptr->pval * k_ptr->level * o_ptr->number); @@ -3123,7 +3092,7 @@ static int water_ice_storm_damage() static int water_ice_storm_radius() { - return 1 + get_level(ICESTORM, 3, 0); + return 1 + get_level(ICESTORM, 3); } static int water_ice_storm_duration() @@ -3206,7 +3175,7 @@ static int water_vapor_damage() static int water_vapor_radius() { - return 3 + get_level(VAPOR, 9, 0); + return 3 + get_level(VAPOR, 9); } static int water_vapor_duration() @@ -3925,10 +3894,6 @@ const char *music_hobbit_melodies_info() int music_clairaudience_lasting() { set_tim_esp(5); - if (get_level_s(MUSIC_MIND, 50) >= 10) - { - fire_ball(GF_IDENTIFY, 0, 1, 1 + get_level(MUSIC_MIND, 3, 0)); - } return get_mana(MUSIC_MIND); } @@ -3945,7 +3910,7 @@ const char *music_clairaudience_info() if (get_level_s(MUSIC_MIND, 50) >= 10) { sprintf(buf, "rad " FMTs32b, - 1 + get_level(MUSIC_MIND, 3, 0)); + 1 + get_level(MUSIC_MIND, 3)); return buf; } else @@ -3958,8 +3923,8 @@ casting_result music_blow_spell() { fire_ball(GF_SOUND, 0, - damroll(2 + get_level(MUSIC_BLOW, 10, 0), 4 + get_level(MUSIC_BLOW, 40, 0)), - 1 + get_level(MUSIC_BLOW, 12, 0)); + damroll(2 + get_level(MUSIC_BLOW, 10), 4 + get_level(MUSIC_BLOW, 40)), + 1 + get_level(MUSIC_BLOW, 12)); return CAST_OBVIOUS; } @@ -3968,9 +3933,9 @@ const char *music_blow_info() static char buf[128]; sprintf(buf, "dam " FMTs32b "d" FMTs32b " rad " FMTs32b, - 2 + get_level(MUSIC_BLOW, 10, 0), - 4 + get_level(MUSIC_BLOW, 40, 0), - 1 + get_level(MUSIC_BLOW, 12, 0)); + 2 + get_level(MUSIC_BLOW, 10), + 4 + get_level(MUSIC_BLOW, 40), + 1 + get_level(MUSIC_BLOW, 12)); return buf; } @@ -3978,8 +3943,8 @@ casting_result music_gush_of_wind_spell() { fire_ball(GF_AWAY_ALL, 0, - 10 + get_level(MUSIC_BLOW, 40, 0), - 1 + get_level(MUSIC_BLOW, 12, 0)); + 10 + get_level(MUSIC_BLOW, 40), + 1 + get_level(MUSIC_BLOW, 12)); return CAST_OBVIOUS; } @@ -3988,8 +3953,8 @@ const char *music_gush_of_wind_info() static char buf[128]; sprintf(buf, "dist " FMTs32b " rad " FMTs32b, - 10 + get_level(MUSIC_BLOW, 40, 0), - 1 + get_level(MUSIC_BLOW, 12, 0)); + 10 + get_level(MUSIC_BLOW, 40), + 1 + get_level(MUSIC_BLOW, 12)); return buf; } @@ -4192,7 +4157,7 @@ casting_result aule_child_spell() if (m_idx) { - monster_set_level(m_idx, 20 + get_level(AULE_CHILD, 70, 0)); + monster_set_level(m_idx, 20 + get_level(AULE_CHILD, 70)); return CAST_OBVIOUS; } else @@ -4295,7 +4260,7 @@ const char *mandos_tale_of_doom_info() int call_to_the_halls_mlev() { - return 20 + get_level(MANDOS_CALL_HALLS, 70, 0); + return 20 + get_level(MANDOS_CALL_HALLS, 70); } casting_result mandos_call_to_the_halls_spell() @@ -4408,7 +4373,7 @@ const char *ulmo_draught_of_ulmonan_info() static int call_of_the_ulumuri_mlev() { - return 30 + get_level(ULMO_CALL_ULUMURI, 70, 0); + return 30 + get_level(ULMO_CALL_ULUMURI, 70); } casting_result ulmo_call_of_the_ulumuri_spell() @@ -4558,7 +4523,6 @@ casting_result varda_evenstar_spell() if (get_level_s(VARDA_EVENSTAR, 50) >= 40) { identify_pack(); - self_knowledge(NULL); } return CAST_OBVIOUS; diff --git a/src/spells3.hpp b/src/spells3.hpp index 3380203a..12e6a78f 100644 --- a/src/spells3.hpp +++ b/src/spells3.hpp @@ -33,7 +33,6 @@ extern s32b PROBABILITY_TRAVEL; casting_result convey_blink(); const char *convey_blink_info(); -casting_result convey_disarm(); casting_result convey_teleport(); const char *convey_teleport_info(); casting_result convey_teleport_away(); diff --git a/src/spells4.cc b/src/spells4.cc index 62586758..97c3d523 100644 --- a/src/spells4.cc +++ b/src/spells4.cc @@ -210,7 +210,6 @@ void init_school_books() push_spell(TOME_TRANSLOCATION, RECALL); push_spell(TOME_TRANSLOCATION, TELEAWAY); push_spell(TOME_TRANSLOCATION, TELEPORT); - push_spell(TOME_TRANSLOCATION, DISARM); push_spell(TOME_TRANSLOCATION, BLINK); /* Create the book of the tree */ @@ -512,10 +511,7 @@ void lua_cast_school_spell(s32b s, bool_ no_cost) /* failures are dangerous; we'll flush the input buffer so it isn't missed. */ - if (flush_failure) - { - flush(); - } + flush_on_failure(); msg_print("You failed to get the spell off!"); } diff --git a/src/spells5.cc b/src/spells5.cc index f503c822..ba2e6d05 100644 --- a/src/spells5.cc +++ b/src/spells5.cc @@ -919,30 +919,6 @@ void school_spells_init() } { - spell_type *spell = spell_new(&DISARM, "Disarm"); - spell_type_describe(spell, "Destroys doors and traps"); - spell_type_describe(spell, "At level 10 it destroys doors and traps, then reveals and unlocks any secret"); - spell_type_describe(spell, "doors"); - spell_type_set_mana(spell, 2, 4); - spell_type_set_difficulty(spell, 3, 15); - spell_type_init_mage(spell, - RANDOM, - SCHOOL_CONVEYANCE, - no_info, - convey_disarm); - - spell_type_set_device_charges(spell, "10+d15"); - - { - device_allocation *device_allocation = device_allocation_new(TV_STAFF); - device_allocation->rarity = 4; - range_init(&device_allocation->base_level, 1, 10); - range_init(&device_allocation->max_level, 10, 50); - spell_type_add_device_allocation(spell, device_allocation); - } - } - - { spell_type *spell = spell_new(&TELEPORT, "Teleportation"); spell_type_describe(spell, "Teleports you around the level. The casting time decreases with level"); spell_type_set_mana(spell, 8, 14); @@ -1143,7 +1119,7 @@ void school_spells_init() spell_type_describe(spell, "Asks for an object and identifies it"); spell_type_describe(spell, "At level 17 it identifies all objects in the inventory"); spell_type_describe(spell, "At level 27 it identifies all objects in the inventory and in a"); - spell_type_describe(spell, "radius on the floor, as well as probing monsters in that radius"); + spell_type_describe(spell, "radius on the floor"); spell_type_set_mana(spell, 10, 50); spell_type_set_difficulty(spell, 8, 40); spell_type_init_mage(spell, @@ -2321,8 +2297,7 @@ void school_spells_init() { spell_type *spell = spell_new(&MUSIC_MIND, "Clairaudience(IV)"); spell_type_describe(spell, "Allows you to sense monster minds as long as you sing."); - spell_type_describe(spell, "At level 10 it identifies all objects in a radius on the floor,"); - spell_type_describe(spell, "as well as probing monsters in that radius."); + spell_type_describe(spell, "At level 10 it identifies all objects in a radius on the floor."); spell_type_describe(spell, "Consumes the amount of mana each turn."); spell_type_set_mana(spell, 15, 30); spell_type_set_difficulty(spell, 25, 75); diff --git a/src/spells6.cc b/src/spells6.cc index a4564ae3..555f252f 100644 --- a/src/spells6.cc +++ b/src/spells6.cc @@ -1,5 +1,6 @@ #include "spells6.hpp" +#include "game.hpp" #include "gods.hpp" #include "lua_bind.hpp" #include "object2.hpp" @@ -151,6 +152,8 @@ static bool_ geomancy_depends_satisfied() long get_provided_levels(school_type *school) { + auto const &s_info = game->s_info; + for (auto school_provider: school->providers->v) { if (school_provider.deity_idx == p_ptr->pgod) @@ -171,6 +174,8 @@ struct get_level_school_callback_data { static bool get_level_school_callback(struct get_level_school_callback_data *data, int school_idx) { + auto const &s_info = game->s_info; + school_type *school = school_at(school_idx); long r = 0, s = 0, p = 0, ok = 0; diff --git a/src/squelch/automatizer.cc b/src/squelch/automatizer.cc index c3c52b1b..b06367a8 100644 --- a/src/squelch/automatizer.cc +++ b/src/squelch/automatizer.cc @@ -12,20 +12,21 @@ namespace squelch { /** * Parse rules from JSON array */ -static std::vector< std::shared_ptr < Rule > > parse_rules(json_t *rules_j) +static std::vector< std::shared_ptr < Rule > > parse_rules(jsoncons::json const &rules_json) { std::vector< std::shared_ptr < Rule > > rules; - if (!json_is_array(rules_j)) + if (!rules_json.is_array()) { msg_format("Error 'rules' is not an array"); return rules; } - for (size_t i = 0; i < json_array_size(rules_j); i++) + auto rules_array = rules_json.array_value(); + + for (auto const &rule_value : rules_array) { - json_t *rule_j = json_array_get(rules_j, i); - auto rule = Rule::parse_rule(rule_j); + auto rule = Rule::parse_rule(rule_value); if (rule) { rules.push_back(rule); @@ -63,25 +64,25 @@ bool Automatizer::apply_rules(object_type *o_ptr, int item_idx) const return false; } -std::shared_ptr<json_t> Automatizer::to_json() const +jsoncons::json Automatizer::to_json() const { - auto rules_json = std::shared_ptr<json_t>(json_array(), &json_decref); + auto document = jsoncons::json::array(); for (auto rule : m_rules) { - json_array_append_new(rules_json.get(), rule->to_json()); + document.push_back(rule->to_json()); } - return rules_json; + return document; } -void Automatizer::load_json(json_t *json) +void Automatizer::load_json(jsoncons::json const &document) { // Go through all the found rules - auto rules = parse_rules(json); + auto rules = parse_rules(document); // Load rule - for (auto rule : rules) + for (auto rule: rules) { append_rule(rule); } @@ -204,13 +205,15 @@ void Automatizer::add_new_condition(std::function<std::shared_ptr<Condition> ()> factory); } -void Automatizer::get_rule_names(std::vector<const char *> *names) const +std::vector<std::string> Automatizer::get_rule_names() const { - names->resize(m_rules.size()); - for (size_t i = 0; i < m_rules.size(); i++) + std::vector<std::string> names; + names.reserve(m_rules.size()); + for (auto const &rule: m_rules) { - (*names)[i] = m_rules.at(i)->get_name(); + names.push_back(rule->get_name()); } + return names; } int Automatizer::rules_count() const diff --git a/src/squelch/condition.cc b/src/squelch/condition.cc index c3b8c3f5..cd7f879c 100644 --- a/src/squelch/condition.cc +++ b/src/squelch/condition.cc @@ -6,6 +6,7 @@ #include "tome/squelch/cursor.hpp" #include "tome/squelch/tree_printer.hpp" #include "../ability_type.hpp" +#include "../game.hpp" #include "../object1.hpp" #include "../object2.hpp" #include "../object_kind.hpp" @@ -16,7 +17,6 @@ #include "../player_type.hpp" #include "../skills.hpp" #include "../skill_type.hpp" -#include "../quark.hpp" #include "../util.hpp" #include "../variable.hpp" @@ -58,12 +58,15 @@ EnumStringMap<identification_state> &identification_state_mapping() return *m; } -json_t *Condition::to_json() const +jsoncons::json Condition::to_json() const { - json_t *j = json_object(); - json_object_set_new(j, "type", - json_string(match_mapping().stringify(match))); + // Start with an object with only 'type' property + jsoncons::json j; + j["type"] = match_mapping().stringify(match); + + // Add sub-class properties to_json(j); + // Return the completed JSON return j; } @@ -86,11 +89,11 @@ void Condition::display(TreePrinter *tree_printer, Cursor *cursor) const tree_printer->dedent(); } -std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json) +std::shared_ptr<Condition> Condition::parse_condition(jsoncons::json const &condition_json) { // Parsers for concrete types of conditions. static std::map< match_type, - std::function< std::shared_ptr< Condition > ( json_t * ) > > parsers { + std::function<std::shared_ptr<Condition>(jsoncons::json const &)>> parsers { { match_type::AND, &AndCondition::from_json }, { match_type::OR, &OrCondition::from_json }, { match_type::NOT, &NotCondition::from_json }, @@ -112,15 +115,13 @@ std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json) { match_type::SKILL, &SkillCondition::from_json }, { match_type::ABILITY, &AbilityCondition::from_json } }; - if ((condition_json == nullptr) || json_is_null(condition_json)) + if (condition_json.is_null()) { return nullptr; } - cptr type_s = nullptr; - if (json_unpack(condition_json, - "{s:s}", - "type", &type_s) < 0) + cptr type_s = condition_json.get("type").as<cptr>(); + if (!type_s) { msg_print("Missing/invalid 'type' in condition"); return nullptr; @@ -144,11 +145,11 @@ std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json) return nullptr; } -json_t *Condition::optional_to_json(std::shared_ptr<Condition> condition) +jsoncons::json Condition::optional_to_json(std::shared_ptr<Condition> condition) { return condition ? condition->to_json() - : json_null(); + : jsoncons::json::null_type(); } bool TvalCondition::is_match(object_type *o_ptr) const @@ -156,22 +157,23 @@ bool TvalCondition::is_match(object_type *o_ptr) const return (o_ptr->tval == m_tval); } -std::shared_ptr<Condition> TvalCondition::from_json(json_t *j) +std::shared_ptr<Condition> TvalCondition::from_json(jsoncons::json const &j) { - int tval; - - if (json_unpack(j, "{s:i}", "tval", &tval) < 0) + auto tval_j = j.get("tval"); + if (!tval_j.is_uinteger()) { msg_print("Missing/invalid 'tval' property"); return nullptr; } + int tval = tval_j.as_uint(); + return std::make_shared<TvalCondition>(tval); } -void TvalCondition::to_json(json_t *j) const +void TvalCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "tval", json_integer(m_tval)); + j["tval"] = m_tval; } void TvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const @@ -193,14 +195,16 @@ bool NameCondition::is_match(object_type *o_ptr) const return boost::algorithm::iequals(m_name, buf1); } -std::shared_ptr<Condition> NameCondition::from_json(json_t *j) +std::shared_ptr<Condition> NameCondition::from_json(jsoncons::json const &j) { - cptr s = nullptr; - if (json_unpack(j, "{s:s}", "name", &s) < 0) + cptr s = j.get("name").as<cptr>(); + + if (!s) { msg_print("Missing/invalid 'name' property"); return nullptr; } + return std::make_shared<NameCondition>(s); } @@ -214,9 +218,9 @@ void NameCondition::write_tree(TreePrinter *p, Cursor *cursor, uint8_t ecol, uin p->write(TERM_WHITE, "\n"); } -void NameCondition::to_json(json_t *j) const +void NameCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "name", json_string(m_name.c_str())); + j["name"] = m_name; } bool ContainCondition::is_match(object_type *o_ptr) const @@ -226,14 +230,16 @@ bool ContainCondition::is_match(object_type *o_ptr) const return boost::algorithm::icontains(buf1, m_contain); } -std::shared_ptr<Condition> ContainCondition::from_json(json_t *j) +std::shared_ptr<Condition> ContainCondition::from_json(jsoncons::json const &j) { - cptr s = nullptr; - if (json_unpack(j, "{s:s}", "contain", &s) < 0) + cptr s = j.get("contain").as<cptr>(); + + if (!s) { msg_print("Missing/invalid 'contain' property"); return nullptr; } + return std::make_shared<ContainCondition>(s); } @@ -247,9 +253,9 @@ void ContainCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_ p->write(TERM_WHITE, "\n"); } -void ContainCondition::to_json(json_t *j) const +void ContainCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "contain", json_string(m_contain.c_str())); + j["contain"] = m_contain; } bool SvalCondition::is_match(object_type *o_ptr) const @@ -259,19 +265,25 @@ bool SvalCondition::is_match(object_type *o_ptr) const (o_ptr->sval <= m_max)); } -std::shared_ptr<Condition> SvalCondition::from_json(json_t *j) +std::shared_ptr<Condition> SvalCondition::from_json(jsoncons::json const &j) { - int min, max; + auto min_j = j.get("min"); + if (!min_j.is_uinteger()) + { + msg_print("Missing/invalid 'min' property"); + return nullptr; + } - if (json_unpack(j, "{s:i,s:i}", - "min", &min, - "max", &max) < 0) + auto max_j = j.get("max"); + if (!max_j.is_uinteger()) { - msg_print("Missing/invalid 'min'/'max' properties"); + msg_print("Missing/invalid 'max' property"); return nullptr; } - return std::make_shared<SvalCondition>(min, max); + return std::make_shared<SvalCondition>( + min_j.as_uint(), + max_j.as_uint()); } void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const @@ -285,10 +297,10 @@ void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b p->write(TERM_WHITE, "\n"); } -void SvalCondition::to_json(json_t *j) const +void SvalCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "min", json_integer(m_min)); - json_object_set_new(j, "max", json_integer(m_max)); + j["min"] = m_min; + j["max"] = m_max; } void GroupingCondition::add_child(ConditionFactory const &factory) @@ -370,16 +382,15 @@ std::shared_ptr<Condition> GroupingCondition::next_child(Condition *current) return nullptr; } -std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(json_t *j) +std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(jsoncons::json const &j) { - json_t *conditions_j = json_object_get(j, "conditions"); + auto conditions_j = j.get("conditions"); - if ((conditions_j == nullptr) || - (json_is_null(conditions_j))) + if (conditions_j.is_null()) { return std::vector< std::shared_ptr<Condition> >(); } - else if (!json_is_array(conditions_j)) + else if (!conditions_j.is_array()) { msg_print("'conditions' property has invalid type"); return std::vector< std::shared_ptr<Condition> >(); @@ -387,11 +398,8 @@ std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(js else { std::vector< std::shared_ptr<Condition> > subconditions; - for (size_t i = 0; i < json_array_size(conditions_j); i++) + for (auto const &subcondition_j: conditions_j.array_value()) { - json_t *subcondition_j = - json_array_get(conditions_j, i); - std::shared_ptr<Condition> subcondition = parse_condition(subcondition_j); @@ -404,14 +412,16 @@ std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(js } } -void GroupingCondition::to_json(json_t *j) const +void GroupingCondition::to_json(jsoncons::json &j) const { - json_t *ja = json_array(); + // Put all the sub-conditions into an array + jsoncons::json::array ja; for (auto condition_p : m_conditions) { - json_array_append_new(ja, optional_to_json(condition_p)); + ja.push_back(optional_to_json(condition_p)); } - json_object_set_new(j, "conditions", ja); + // Add to JSON object + j["conditions"] = ja; } bool AndCondition::is_match(object_type *o_ptr) const @@ -426,7 +436,7 @@ bool AndCondition::is_match(object_type *o_ptr) const return true; } -std::shared_ptr<Condition> AndCondition::from_json(json_t *j) +std::shared_ptr<Condition> AndCondition::from_json(jsoncons::json const &j) { auto condition = std::make_shared<AndCondition>(); for (auto subcondition : parse_conditions(j)) @@ -459,7 +469,7 @@ bool OrCondition::is_match(object_type *o_ptr) const return false; } -std::shared_ptr<Condition> OrCondition::from_json(json_t *j) +std::shared_ptr<Condition> OrCondition::from_json(jsoncons::json const &j) { std::shared_ptr<OrCondition> condition = std::make_shared<OrCondition>(); @@ -488,10 +498,11 @@ bool StatusCondition::is_match(object_type *o_ptr) const return m_status == object_status(o_ptr); } -std::shared_ptr<Condition> StatusCondition::from_json(json_t *j) +std::shared_ptr<Condition> StatusCondition::from_json(jsoncons::json const &j) { - cptr s; - if (json_unpack(j, "{s:s}", "status", &s) < 0) + cptr s = j.get("status").as<cptr>(); + + if (!s) { msg_print("Missing/invalid 'status' property"); return nullptr; @@ -518,9 +529,9 @@ void StatusCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void StatusCondition::to_json(json_t *j) const +void StatusCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "status", json_string(status_mapping().stringify(m_status))); + j["status"] = status_mapping().stringify(m_status); } bool RaceCondition::is_match(object_type *o_ptr) const @@ -528,11 +539,11 @@ bool RaceCondition::is_match(object_type *o_ptr) const return boost::algorithm::iequals(m_race, rp_ptr->title); } -std::shared_ptr<Condition> RaceCondition::from_json(json_t *j) +std::shared_ptr<Condition> RaceCondition::from_json(jsoncons::json const &j) { - cptr s; + cptr s = j.get("race").as<cptr>(); - if (json_unpack(j, "{s:s}", "race", &s) < 0) + if (!s) { msg_print("Missing/invalid 'race' property"); return nullptr; @@ -552,9 +563,9 @@ void RaceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b p->write(TERM_WHITE, "\n"); } -void RaceCondition::to_json(json_t *j) const +void RaceCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "race", json_string(m_race.c_str())); + j["race"] = m_race; } bool SubraceCondition::is_match(object_type *o_ptr) const @@ -562,11 +573,11 @@ bool SubraceCondition::is_match(object_type *o_ptr) const return boost::algorithm::iequals(m_subrace, rmp_ptr->title); } -std::shared_ptr<Condition> SubraceCondition::from_json(json_t *j) +std::shared_ptr<Condition> SubraceCondition::from_json(jsoncons::json const &j) { - cptr s; + cptr s = j.get("subrace").as<cptr>(); - if (json_unpack(j, "{s:s}", "subrace", &s) < 0) + if (!s) { msg_print("Missing/invalid 'subrace' property"); return nullptr; @@ -586,9 +597,9 @@ void SubraceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_ p->write(TERM_WHITE, "\n"); } -void SubraceCondition::to_json(json_t *j) const +void SubraceCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "subrace", json_string(m_subrace.c_str())); + j["subrace"] = m_subrace; } bool ClassCondition::is_match(object_type *o_ptr) const @@ -596,11 +607,11 @@ bool ClassCondition::is_match(object_type *o_ptr) const return boost::algorithm::iequals(m_class, spp_ptr->title); } -std::shared_ptr<Condition> ClassCondition::from_json(json_t *j) +std::shared_ptr<Condition> ClassCondition::from_json(jsoncons::json const &j) { - cptr s; + cptr s = j.get("class").as<cptr>(); - if (json_unpack(j, "{s:s}", "class", &s) < 0) + if (!s) { msg_print("Missing/invalid 'class' property"); return nullptr; @@ -620,30 +631,28 @@ void ClassCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void ClassCondition::to_json(json_t *j) const +void ClassCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "class", json_string(m_class.c_str())); + j["class"] = m_class; } bool InscriptionCondition::is_match(object_type *o_ptr) const { - if (o_ptr->note == 0) - { - return false; - } return boost::algorithm::icontains( - quark_str(o_ptr->note), + o_ptr->inscription, m_inscription); } -std::shared_ptr<Condition> InscriptionCondition::from_json(json_t *j) +std::shared_ptr<Condition> InscriptionCondition::from_json(jsoncons::json const &j) { - cptr s = nullptr; - if (json_unpack(j, "{s:s}", "inscription", &s) < 0) + cptr s = j.get("inscription").as<cptr>(); + + if (!s) { msg_print("Missing/invalid 'inscription' property"); return nullptr; } + return std::make_shared<InscriptionCondition>(s); } @@ -658,9 +667,9 @@ void InscriptionCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, ui p->write(TERM_WHITE, "\n"); } -void InscriptionCondition::to_json(json_t *j) const +void InscriptionCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "inscription", json_string(m_inscription.c_str())); + j["inscription"] = m_inscription; } bool DiscountCondition::is_match(object_type *o_ptr) const @@ -670,17 +679,23 @@ bool DiscountCondition::is_match(object_type *o_ptr) const (o_ptr->discount <= m_max)); } -std::shared_ptr<Condition> DiscountCondition::from_json(json_t *j) +std::shared_ptr<Condition> DiscountCondition::from_json(jsoncons::json const &j) { - int min, max; + auto min_j = j.get("min"); + if (!min_j.is_integer()) + { + msg_print("Missing/invalid 'min' property"); + return nullptr; + } + int min = min_j.as_int(); - if (json_unpack(j, "{s:i,s:i}", - "min", &min, - "max", &max) < 0) + auto max_j = j.get("max"); + if (!max_j.is_integer()) { - msg_print("Missing/invalid 'min'/'max' properties"); + msg_print("Missing/invalid 'max' property"); return nullptr; } + int max = max_j.as_int(); return std::make_shared<DiscountCondition>(min, max); } @@ -696,10 +711,10 @@ void DiscountCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8 p->write(TERM_WHITE, "\n"); } -void DiscountCondition::to_json(json_t *j) const +void DiscountCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "min", json_integer(m_min)); - json_object_set_new(j, "max", json_integer(m_max)); + j["min"] = m_min; + j["max"] = m_max; } bool LevelCondition::is_match(object_type *) const @@ -708,16 +723,23 @@ bool LevelCondition::is_match(object_type *) const (p_ptr->lev <= m_max)); } -std::shared_ptr<Condition> LevelCondition::from_json(json_t *j) +std::shared_ptr<Condition> LevelCondition::from_json(jsoncons::json const &j) { - int min, max; - if (json_unpack(j, "{s:i,s:i}", - "min", &min, - "max", &max) < 0) + auto min_j = j.get("min"); + if (!min_j.is_integer()) { - msg_print("Missing/invalid 'min'/'max' properties"); + msg_print("Missing/invalid 'min' property"); return nullptr; } + int min = min_j.as_int(); + + auto max_j = j.get("max"); + if (!max_j.is_integer()) + { + msg_print("Missing/invalid 'max' property"); + return nullptr; + } + int max = max_j.as_int(); return std::make_shared<LevelCondition>(min, max); } @@ -734,10 +756,10 @@ void LevelCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void LevelCondition::to_json(json_t *j) const +void LevelCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "min", json_integer(m_min)); - json_object_set_new(j, "max", json_integer(m_max)); + j["min"] = m_min; + j["max"] = m_max; } bool SkillCondition::is_match(object_type *) const @@ -747,16 +769,28 @@ bool SkillCondition::is_match(object_type *) const (sk <= m_max)); } -std::shared_ptr<Condition> SkillCondition::from_json(json_t *j) +std::shared_ptr<Condition> SkillCondition::from_json(jsoncons::json const &j) { - cptr s; - int min, max; - if (json_unpack(j, "{s:i,s:i,s:s}", - "min", &min, - "max", &max, - "name", &s) < 0) + auto min_j = j.get("min"); + if (!min_j.is_integer()) + { + msg_print("Missing/invalid 'min' property"); + return nullptr; + } + int min = min_j.as_int(); + + auto max_j = j.get("max"); + if (!max_j.is_integer()) { - msg_print("Missing/invalid 'min'/'max'/'name' properties"); + msg_print("Missing/invalid 'max' property"); + return nullptr; + } + int max = max_j.as_int(); + + auto s = j.get("name").as<cptr>(); + if (!s) + { + msg_print("Missing/invalid 'name' property"); return nullptr; } @@ -772,8 +806,10 @@ std::shared_ptr<Condition> SkillCondition::from_json(json_t *j) void SkillCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const { + auto const &s_descriptors = game->edit_data.s_descriptors; + p->write(ecol, "Your skill in "); - p->write(bcol, s_info[m_skill_idx].name); + p->write(bcol, s_descriptors[m_skill_idx].name); p->write(ecol, " is from "); p->write(TERM_WHITE, format("%d", (int) m_min)); p->write(ecol, " to "); @@ -781,14 +817,13 @@ void SkillCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void SkillCondition::to_json(json_t *j) const +void SkillCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "name", - json_string(s_info[m_skill_idx].name)); - json_object_set_new(j, "min", - json_integer(m_min)); - json_object_set_new(j, "max", - json_integer(m_max)); + auto const &s_descriptors = game->edit_data.s_descriptors; + + j["name"] = s_descriptors[m_skill_idx].name; + j["min"] = m_min; + j["max"] = m_max; } bool StateCondition::is_match(object_type *o_ptr) const @@ -805,10 +840,11 @@ bool StateCondition::is_match(object_type *o_ptr) const return false; } -std::shared_ptr<Condition> StateCondition::from_json(json_t *j) +std::shared_ptr<Condition> StateCondition::from_json(jsoncons::json const &j) { - cptr s; - if (json_unpack(j, "{s:s}", "state", &s) < 0) + cptr s = j.get("state").as<cptr>(); + + if (!s) { msg_print("Missing/invalid 'state' property"); return nullptr; @@ -835,34 +871,28 @@ void StateCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void StateCondition::to_json(json_t *j) const +void StateCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "state", - json_string(identification_state_mapping(). - stringify(m_state))); + j["state"] = identification_state_mapping().stringify(m_state); } bool SymbolCondition::is_match(object_type *o_ptr) const { - object_kind *k_ptr = &k_info[o_ptr->k_idx]; - return k_ptr->d_char == m_symbol; + auto const &k_info = game->edit_data.k_info; + + return k_info[o_ptr->k_idx].d_char == m_symbol; } -std::shared_ptr<Condition> SymbolCondition::from_json(json_t *j) +std::shared_ptr<Condition> SymbolCondition::from_json(jsoncons::json const &j) { - cptr s_ = nullptr; - if (json_unpack(j, "{s:s}", "symbol", &s_) < 0) - { - msg_print("Missing/invalid 'symbol' property"); - return nullptr; - } + auto s = j.get("symbol").as<std::string>(); - std::string s(s_); if (s.empty()) { - msg_print("Invalid 'symbol' property: Too short"); + msg_print("Missing/invalid 'symbol' property"); return nullptr; } + if (s.size() > 1) { msg_print("Invalid 'symbol' property: Too long"); @@ -883,21 +913,21 @@ void SymbolCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t p->write(TERM_WHITE, "\n"); } -void SymbolCondition::to_json(json_t *j) const +void SymbolCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "symbol", - json_string(format("%c", m_symbol))); + j["symbol"] = format("%c", m_symbol); } bool AbilityCondition::is_match(object_type *) const { - return has_ability(m_ability_idx); + return p_ptr->has_ability(m_ability_idx); } -std::shared_ptr<Condition> AbilityCondition::from_json(json_t *j) +std::shared_ptr<Condition> AbilityCondition::from_json(jsoncons::json const &j) { - cptr a; - if (json_unpack(j, "{s:s}", "ability", &a) < 0) + cptr a = j.get("ability").as<cptr>(); + + if (!a) { msg_print("Missing/invalid 'ability' property"); return nullptr; @@ -915,18 +945,19 @@ std::shared_ptr<Condition> AbilityCondition::from_json(json_t *j) void AbilityCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const { - cptr ability_s = ab_info[m_ability_idx].name; + auto const &ab_info = game->edit_data.ab_info; p->write(ecol, "You have the "); - p->write(bcol, ability_s); + p->write(bcol, ab_info[m_ability_idx].name); p->write(ecol, " ability"); p->write(TERM_WHITE, "\n"); } -void AbilityCondition::to_json(json_t *j) const +void AbilityCondition::to_json(jsoncons::json &j) const { - cptr ability_s = ab_info[m_ability_idx].name; - json_object_set_new(j, "ability", json_string(ability_s)); + auto const &ab_info = game->edit_data.ab_info; + + j["ability"] = ab_info[m_ability_idx].name; } void SingleSubconditionCondition::add_child(std::function< std::shared_ptr<Condition> () > const &factory) @@ -951,23 +982,20 @@ std::shared_ptr<Condition> SingleSubconditionCondition::first_child() return m_subcondition; } -void SingleSubconditionCondition::to_json(json_t *j) const +void SingleSubconditionCondition::to_json(jsoncons::json &j) const { - json_object_set_new(j, "condition", - optional_to_json(m_subcondition)); + j["condition"] = optional_to_json(m_subcondition); } -std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(json_t *in_json) +std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(jsoncons::json const &in_json) { - json_t *condition_j = - json_object_get(in_json, "condition"); + auto condition_j = in_json.get("condition"); - if ((condition_j == nullptr) || - (json_is_null(condition_j))) + if (condition_j.is_null()) { return nullptr; } - else if (!json_is_object(condition_j)) + else if (!condition_j.is_object()) { msg_format("Invalid 'condition' property"); return nullptr; @@ -988,7 +1016,7 @@ bool NotCondition::is_match(object_type *o_ptr) const return !m_subcondition->is_match(o_ptr); } -std::shared_ptr<Condition> NotCondition::from_json(json_t *j) +std::shared_ptr<Condition> NotCondition::from_json(jsoncons::json const &j) { return std::make_shared<NotCondition>(parse_single_subcondition(j)); } @@ -1021,7 +1049,7 @@ bool InventoryCondition::is_match(object_type *) const return false; } -std::shared_ptr<Condition> InventoryCondition::from_json(json_t *j) +std::shared_ptr<Condition> InventoryCondition::from_json(jsoncons::json const &j) { return std::make_shared<InventoryCondition>( parse_single_subcondition(j)); @@ -1057,7 +1085,7 @@ bool EquipmentCondition::is_match(object_type *) const return false; } -std::shared_ptr<Condition> EquipmentCondition::from_json(json_t *j) +std::shared_ptr<Condition> EquipmentCondition::from_json(jsoncons::json const &j) { return std::make_shared<EquipmentCondition>( parse_single_subcondition(j)); diff --git a/src/squelch/condition_metadata.cc b/src/squelch/condition_metadata.cc index 62a90e58..f6d4370c 100644 --- a/src/squelch/condition_metadata.cc +++ b/src/squelch/condition_metadata.cc @@ -14,8 +14,8 @@ namespace squelch { static std::shared_ptr<Condition> create_condition_name() { - cptr s = lua_input_box("Object name to match?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Object name to match?", 79); + if (s.empty()) { return nullptr; } @@ -25,8 +25,8 @@ static std::shared_ptr<Condition> create_condition_name() static std::shared_ptr<Condition> create_condition_contain() { - cptr s = lua_input_box("Word to find in object name?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Word to find in object name?", 79); + if (s.empty()) { return nullptr; } @@ -36,8 +36,8 @@ static std::shared_ptr<Condition> create_condition_contain() static std::shared_ptr<Condition> create_condition_inscribed() { - cptr s = lua_input_box("Word to find in object inscription?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Word to find in object inscription?", 79); + if (s.empty() == 0) { return nullptr; } @@ -50,16 +50,16 @@ static std::shared_ptr<Condition> create_condition_discount() int min, max; { - cptr s = lua_input_box("Min discount?", 79); - if (sscanf(s, "%d", &min) < 1) + auto s = input_box_auto("Min discount?", 79); + if (sscanf(s.c_str(), "%d", &min) < 1) { return nullptr; } } { - cptr s = lua_input_box("Max discount?", 79); - if (sscanf(s, "%d", &max) < 1) + auto s = input_box_auto("Max discount?", 79); + if (sscanf(s.c_str(), "%d", &max) < 1) { return nullptr; } @@ -70,22 +70,20 @@ static std::shared_ptr<Condition> create_condition_discount() static std::shared_ptr<Condition> create_condition_symbol() { - char c; - cptr s = lua_input_box("Symbol to match?", 1); - if (sscanf(s, "%c", &c) < 1) + auto s = input_box_auto("Symbol to match?", 1); + if (s.empty()) { return nullptr; } - return std::make_shared<SymbolCondition>(c); + return std::make_shared<SymbolCondition>(s[0]); } static std::shared_ptr<Condition> create_condition_status() { status_type status; - char c; - c = lua_msg_box("[t]errible, [v]ery bad, [b]ad, " + auto c = msg_box_auto("[t]errible, [v]ery bad, [b]ad, " "[a]verage, [G]ood, [V]ery good, [S]pecial?"); switch (c) @@ -105,7 +103,7 @@ static std::shared_ptr<Condition> create_condition_status() static std::shared_ptr<Condition> create_condition_state() { - char c = lua_msg_box("[i]dentified, [n]on identified?"); + char c = msg_box_auto("[i]dentified, [n]on identified?"); identification_state s; switch (c) @@ -125,9 +123,9 @@ static bool in_byte_range(int x) static std::shared_ptr<Condition> create_condition_tval() { - cptr s = lua_input_box("Tval to match?", 79); + auto s = input_box_auto("Tval to match?", 79); int tval; - if (sscanf(s, "%d", &tval) < 1) + if (sscanf(s.c_str(), "%d", &tval) < 1) { return nullptr; } @@ -145,8 +143,8 @@ static std::shared_ptr<Condition> create_condition_sval() int sval_min, sval_max; { - cptr s = lua_input_box("Min sval?", 79); - if ((sscanf(s, "%d", &sval_min) < 1) || + auto s = input_box_auto("Min sval?", 79); + if ((sscanf(s.c_str(), "%d", &sval_min) < 1) || (!in_byte_range(sval_min))) { return nullptr; @@ -154,8 +152,8 @@ static std::shared_ptr<Condition> create_condition_sval() } { - cptr s = lua_input_box("Max sval?", 79); - if ((sscanf(s, "%d", &sval_max) < 1) || + auto s = input_box_auto("Max sval?", 79); + if ((sscanf(s.c_str(), "%d", &sval_max) < 1) || (!in_byte_range(sval_max))) { return nullptr; @@ -167,8 +165,8 @@ static std::shared_ptr<Condition> create_condition_sval() static std::shared_ptr<Condition> create_condition_race() { - cptr s = lua_input_box("Player race to match?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Player race to match?", 79); + if (s.empty()) { return nullptr; } @@ -178,8 +176,8 @@ static std::shared_ptr<Condition> create_condition_race() static std::shared_ptr<Condition> create_condition_subrace() { - cptr s = lua_input_box("Player subrace to match?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Player subrace to match?", 79); + if (s.empty()) { return nullptr; } @@ -189,8 +187,8 @@ static std::shared_ptr<Condition> create_condition_subrace() static std::shared_ptr<Condition> create_condition_class() { - cptr s = lua_input_box("Player class to match?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Player class to match?", 79); + if (s.empty()) { return nullptr; } @@ -203,16 +201,16 @@ static std::shared_ptr<Condition> create_condition_level() int min, max; { - cptr s = lua_input_box("Min player level?", 79); - if (sscanf(s, "%d", &min) < 1) + auto s = input_box_auto("Min player level?", 79); + if (sscanf(s.c_str(), "%d", &min) < 1) { return nullptr; } } { - cptr s = lua_input_box("Max player level?", 79); - if (sscanf(s, "%d", &max) < 1) + auto s = input_box_auto("Max player level?", 79); + if (sscanf(s.c_str(), "%d", &max) < 1) { return nullptr; } @@ -226,16 +224,16 @@ static std::shared_ptr<Condition> create_condition_skill() int min, max; { - cptr s = lua_input_box("Min skill level?", 79); - if (sscanf(s, "%d", &min) < 1) + auto s = input_box_auto("Min skill level?", 79); + if (sscanf(s.c_str(), "%d", &min) < 1) { return nullptr; } } { - cptr s = lua_input_box("Max skill level?", 79); - if (sscanf(s, "%d", &max) < 1) + auto s = input_box_auto("Max skill level?", 79); + if (sscanf(s.c_str(), "%d", &max) < 1) { return nullptr; } @@ -243,13 +241,13 @@ static std::shared_ptr<Condition> create_condition_skill() s16b skill_idx; { - cptr s = lua_input_box("Skill name?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Skill name?", 79); + if (s.empty() == 0) { return nullptr; } - skill_idx = find_skill_i(s); + skill_idx = find_skill_i(s.c_str()); if (skill_idx < 0) { return nullptr; @@ -261,13 +259,13 @@ static std::shared_ptr<Condition> create_condition_skill() static std::shared_ptr<Condition> create_condition_ability() { - cptr s = lua_input_box("Ability name?", 79); - if (strlen(s) == 0) + auto s = input_box_auto("Ability name?", 79); + if (s.empty() == 0) { return nullptr; } - s16b ai = find_ability(s); + s16b ai = find_ability(s.c_str()); if (ai < 0) { return nullptr; @@ -394,7 +392,7 @@ std::shared_ptr<Condition> new_condition_interactive() match_type::INVENTORY, match_type::EQUIPMENT }; - static std::vector<const char *> condition_type_names; + static std::vector<std::string> condition_type_names; // Fill in types names? if (condition_type_names.empty()) @@ -414,7 +412,7 @@ std::shared_ptr<Condition> new_condition_interactive() Term_clear(); Term_get_size(&wid, &hgt); - display_list(0, 0, hgt - 1, 15, "Rule types", condition_type_names.data(), condition_types.size(), begin, sel, TERM_L_GREEN); + display_list(0, 0, hgt - 1, 15, "Rule types", condition_type_names, begin, sel, TERM_L_GREEN); display_desc(condition_types[sel]); diff --git a/src/squelch/rule.cc b/src/squelch/rule.cc index 1c17d2fd..e35b3ce1 100644 --- a/src/squelch/rule.cc +++ b/src/squelch/rule.cc @@ -8,8 +8,8 @@ #include "../modules.hpp" #include "../object1.hpp" #include "../object2.hpp" +#include "../object_flag.hpp" #include "../object_type.hpp" -#include "../quark.hpp" #include "../tables.hpp" #include "../util.hpp" #include "../variable.hpp" @@ -25,15 +25,14 @@ EnumStringMap<action_type> &action_mapping() return *m; } -void Rule::set_name(const char *new_name) +void Rule::set_name(std::string const &new_name) { - assert(new_name != nullptr); m_name = new_name; } -const char *Rule::get_name() const +std::string Rule::get_name() const { - return m_name.c_str(); + return m_name; } std::shared_ptr<Condition> Rule::get_condition() const @@ -41,22 +40,16 @@ std::shared_ptr<Condition> Rule::get_condition() const return m_condition; } -json_t *Rule::to_json() const +jsoncons::json Rule::to_json() const { - json_t *rule_json = json_object(); - json_object_set_new(rule_json, - "name", - json_string(m_name.c_str())); - json_object_set_new(rule_json, - "action", - json_string(action_mapping().stringify(m_action))); - json_object_set_new(rule_json, - "module", - json_string(modules[m_module_idx].meta.name)); - json_object_set_new(rule_json, - "condition", - Condition::optional_to_json(m_condition)); - return rule_json; + jsoncons::json j; + + j["name"] = jsoncons::json::string_type(m_name); + j["action"] = action_mapping().stringify(m_action); + j["module"] = modules[m_module_idx].meta.name; + j["condition"] = Condition::optional_to_json(m_condition); + + return j; } void Rule::add_new_condition(Cursor *cursor, @@ -138,23 +131,19 @@ bool Rule::apply_rule(object_type *o_ptr, int item_idx) const return false; } -std::shared_ptr<Rule> Rule::parse_rule(json_t *rule_json) +std::shared_ptr<Rule> Rule::parse_rule(jsoncons::json const &rule_json) { - if (!json_is_object(rule_json)) + if (!rule_json.is_object()) { msg_print("Rule is not an object"); return nullptr; } // Retrieve the attributes - char *rule_name_s = nullptr; - char *rule_action_s = nullptr; - char *rule_module_s = nullptr; - if (json_unpack(rule_json, - "{s:s,s:s,s:s}", - "name", &rule_name_s, - "action", &rule_action_s, - "module", &rule_module_s) < 0) + char const *rule_name_s = rule_json.get("name").as<char const *>(); + char const *rule_action_s = rule_json.get("action").as<char const *>(); + char const *rule_module_s = rule_json.get("module").as<char const *>(); + if ((!rule_name_s) || (!rule_action_s) || (!rule_module_s)) { msg_print("Rule missing required field(s)"); return nullptr; @@ -178,28 +167,29 @@ std::shared_ptr<Rule> Rule::parse_rule(json_t *rule_json) // Parse condition std::shared_ptr<Condition> condition = - Condition::parse_condition(json_object_get(rule_json, "condition")); + Condition::parse_condition(rule_json.get("condition")); // Parse rule switch (action) { case action_type::AUTO_INSCRIBE: { - json_t *rule_inscription_j = json_object_get(rule_json, "inscription"); + auto rule_inscription_j = rule_json.get("inscription"); - if (rule_inscription_j == nullptr) + if (rule_inscription_j.is_null()) { msg_print("Inscription rule missing 'inscription' attribute"); return nullptr; } - if (!json_is_string(rule_inscription_j)) + + if (!rule_inscription_j.is_string()) { msg_print("Inscription rule 'inscription' attribute wrong type"); return nullptr; } - std::string inscription = - json_string_value(rule_inscription_j); + std::string inscription = rule_inscription_j.as<std::string>(); + return std::make_shared<InscribeRule>( rule_name_s, module_idx, condition, inscription); } @@ -237,7 +227,7 @@ bool DestroyRule::do_apply_rule(object_type *o_ptr, int item_idx) const } // Never destroy inscribed items - if (o_ptr->note) + if (!o_ptr->inscription.empty()) { return false; } @@ -250,10 +240,8 @@ bool DestroyRule::do_apply_rule(object_type *o_ptr, int item_idx) const // Cannot destroy CURSE_NO_DROP objects. { - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if ((f4 & TR4_CURSE_NO_DROP) != 0) + auto const f = object_flags(o_ptr); + if (f & TR_CURSE_NO_DROP) { return false; } @@ -292,14 +280,10 @@ bool PickUpRule::do_apply_rule(object_type *o_ptr, int item_idx) const return true; } -json_t *InscribeRule::to_json() const +jsoncons::json InscribeRule::to_json() const { - json_t *j = Rule::to_json(); - - json_object_set_new(j, - "inscription", - json_string(m_inscription.c_str())); - + jsoncons::json j; + j["inscription"] = m_inscription; return j; } @@ -318,14 +302,14 @@ void InscribeRule::do_write_tree(TreePrinter *p) const bool InscribeRule::do_apply_rule(object_type *o_ptr, int) const { // Already inscribed? - if (o_ptr->note != 0) + if (!o_ptr->inscription.empty()) { return false; } // Inscribe msg_format("<Auto-Inscribe {%s}>", m_inscription.c_str()); - o_ptr->note = quark_add(m_inscription.c_str()); + o_ptr->inscription = m_inscription; return true; } diff --git a/src/squelch/tree_printer.cc b/src/squelch/tree_printer.cc index 2be098dc..0dbceec9 100644 --- a/src/squelch/tree_printer.cc +++ b/src/squelch/tree_printer.cc @@ -86,4 +86,9 @@ void TreePrinter::write(uint8_t color, cptr line) } } +void TreePrinter::write(uint8_t color, std::string const &line) +{ + write(color, line.c_str()); +} + } // namespace diff --git a/src/squeltch.cc b/src/squeltch.cc index bab1e5c0..1db8ff74 100644 --- a/src/squeltch.cc +++ b/src/squeltch.cc @@ -11,6 +11,7 @@ #include "cave_type.hpp" #include "files.hpp" +#include "game.hpp" #include "loadsave.hpp" #include "lua_bind.hpp" #include "object1.hpp" @@ -30,11 +31,11 @@ #include "variable.h" #include "variable.hpp" -#include <jansson.h> #include <algorithm> -#include <memory> #include <deque> +#include <fmt/format.h> #include <list> +#include <memory> #include <string> #include <vector> @@ -57,8 +58,10 @@ using squelch::StatusCondition; static squelch::Automatizer *automatizer = nullptr; -void squeltch_grid(void) +void squeltch_grid() { + auto const &k_info = game->edit_data.k_info; + if (!automatizer_enabled) { return; @@ -84,7 +87,7 @@ void squeltch_grid(void) } } -void squeltch_inventory(void) +void squeltch_inventory() { if (!automatizer_enabled) { @@ -118,18 +121,14 @@ void squeltch_inventory(void) static int create_new_rule() { - char name[20] = { '\0' }; - int wid = 0, hgt = 0; - - Term_get_size(&wid, &hgt); + std::string name = "No name"; - sprintf(name, "%s", "No name"); - if (!input_box("Name?", hgt / 2, wid / 2, name, sizeof(name))) + if (!input_box_auto("Name?", &name, 20)) { return -1; } - char typ = lua_msg_box("[D]estroy, [P]ickup, [I]nscribe?"); + char typ = msg_box_auto("[D]estroy, [P]ickup, [I]nscribe?"); std::shared_ptr<Rule> rule; switch (typ) @@ -147,15 +146,13 @@ static int create_new_rule() case 'i': case 'I': { - cptr i = lua_input_box("Inscription?", 79); - if ((i == nullptr) || (strlen(i) == 0)) + auto s = input_box_auto("Inscription?", 79); + if (s.empty()) { return -1; } - rule = std::make_shared<InscribeRule>( - name, game_module_idx, nullptr, std::string(i)); - + rule = std::make_shared<InscribeRule>(name, game_module_idx, nullptr, s); break; } @@ -168,28 +165,41 @@ static int create_new_rule() static void automatizer_save_rules() { - char name[30] = { '\0' }; char buf[1025]; char ch; int hgt, wid; Term_get_size(&wid, &hgt); - sprintf(name, "%s.atm", player_name); + std::string name = fmt::format("{}.atm", game->player_name); - if (!input_box("Save name?", hgt / 2, wid / 2, name, sizeof(name))) + if (!input_box_auto("Save name?", &name, 30)) { return; } + // Function for showing a message + auto show_message = [hgt, wid](std::string text) { + auto n = std::max<std::size_t>(text.size(), 28); + while (text.size() < n) + { + text += ' '; + } + c_put_str(TERM_WHITE, text.c_str(), hgt/2, wid/2 - 14); + }; + + // Function for showing an error message + auto error = [show_message]() { + show_message("Saving rules FAILED!"); + inkey(); + }; + // Build the filename - path_build(buf, 1024, ANGBAND_DIR_USER, name); + path_build(buf, 1024, ANGBAND_DIR_USER, name.c_str()); - if (file_exist(buf)) + if (boost::filesystem::exists(buf)) { - c_put_str(TERM_WHITE, "File exists, continue?[y/n]", - hgt / 2, - wid / 2 - 14); + show_message("File exists, continue? [y/n]"); ch = inkey(); if ((ch != 'Y') && (ch != 'y')) { @@ -197,44 +207,42 @@ static void automatizer_save_rules() } } - // Write to file - { - auto rules_json = automatizer->to_json(); + // Pretty-printing options + jsoncons::output_format format; + format.indent(2); - int status = json_dump_file(rules_json.get(), buf, - JSON_INDENT(2) | - JSON_SORT_KEYS); - if (status == 0) - { - c_put_str(TERM_WHITE, "Saved rules in file ", - hgt / 2, - wid / 2 - 14); - } - else - { - c_put_str(TERM_WHITE, "Saving rules failed! ", - hgt / 2, - wid / 2 - 14); - } + // Convert to a JSON document + auto rules_document = automatizer->to_json(); - // Wait for keypress - inkey(); + // Open output stream + std::ofstream of(buf, std::ios_base::out | std::ios_base::binary); + if (of.fail()) + { + error(); + return; + } + + // Write JSON to output + of << jsoncons::pretty_print(rules_document, format); + if (of.fail()) + { + error(); + return; } + + // Success + show_message("Saved rules in file"); + inkey(); } static void rename_rule(Rule *rule) { - char name[16]; - int wid, hgt; - assert(rule != nullptr); - Term_get_size(&wid, &hgt); - - sprintf(name, "%s", rule->get_name()); - if (input_box("New name?", hgt / 2, wid / 2, name, sizeof(name))) + std::string name = rule->get_name(); + if (input_box_auto("New name?", &name, 16)) { - rule->set_name(name); + rule->set_name(name.c_str()); } } @@ -242,18 +250,15 @@ static void rename_rule(Rule *rule) #define ACTIVE_RULE 1 void do_cmd_automatizer() { - int wid = 0, hgt = 0; int active = ACTIVE_LIST; cptr keys; cptr keys2; cptr keys3; std::vector<cptr> rule_names; - Term_get_size(&wid, &hgt); - if (!automatizer_enabled) { - if (msg_box("Automatizer is currently disabled, enable it? (y/n)", hgt / 2, wid / 2) == 'y') + if (msg_box_auto("Automatizer is currently disabled, enable it? (y/n)") == 'y') { automatizer_enabled = TRUE; } @@ -268,11 +273,13 @@ void do_cmd_automatizer() while (1) { Term_clear(); + + int wid, hgt; Term_get_size(&wid, &hgt); - automatizer->get_rule_names(&rule_names); + auto rule_names = automatizer->get_rule_names(); - display_list(0, 0, hgt - 1, 15, "Rules", rule_names.data(), automatizer->rules_count(), automatizer->rules_begin(), automatizer->selected_rule(), (active == ACTIVE_LIST) ? TERM_L_GREEN : TERM_GREEN); + display_list(0, 0, hgt - 1, 15, "Rules", rule_names, automatizer->rules_begin(), automatizer->selected_rule(), (active == ACTIVE_LIST) ? TERM_L_GREEN : TERM_GREEN); draw_box(0, 15, hgt - 4, wid - 1 - 15); if (active == ACTIVE_RULE) @@ -301,7 +308,7 @@ void do_cmd_automatizer() if (c == '?') { screen_save(); - show_file("automat.txt", "Automatizer help", 0, 0); + show_file("automat.txt", "Automatizer help"); screen_load(); } else if (c == '8') @@ -375,7 +382,7 @@ void do_cmd_automatizer() if (c == '?') { screen_save(); - show_file("automat.txt", "Automatizer help", 0, 0); + show_file("automat.txt", "Automatizer help"); screen_load(); } else if (c == '8') @@ -574,20 +581,21 @@ bool automatizer_load(boost::filesystem::path const &path) return false; // Not fatal; just skip } - // Parse file - json_error_t error; - std::shared_ptr<json_t> rules_json( - json_load_file(path.c_str(), 0, &error), - &json_decref); - if (rules_json == nullptr) + // Parse into memory + jsoncons::json rules_json; + try + { + rules_json = jsoncons::json::parse_file(path.string()); + } + catch (jsoncons::json_exception const &exc) { msg_format("Error parsing automatizer rules from '%s'.", path.c_str()); - msg_format("Line %d, Column %d", error.line, error.column); - msg_print(nullptr); + msg_print(exc.what()); return false; } - // Load rules - automatizer->load_json(rules_json.get()); + // We didn't return directly via an exception, so let's extract + // the rules. + automatizer->load_json(rules_json); return true; } diff --git a/src/squeltch.hpp b/src/squeltch.hpp index 65ddfb51..c4525e7d 100644 --- a/src/squeltch.hpp +++ b/src/squeltch.hpp @@ -4,10 +4,10 @@ #include "object_type_fwd.hpp" #include <boost/filesystem.hpp> -extern void squeltch_inventory(void); -extern void squeltch_grid(void); -extern void do_cmd_automatizer(void); -extern void automatizer_add_rule(object_type *o_ptr); +void squeltch_inventory(); +void squeltch_grid(); +void do_cmd_automatizer(); +void automatizer_add_rule(object_type *o_ptr); extern bool_ automatizer_create; -extern void automatizer_init(); -extern bool automatizer_load(boost::filesystem::path const &path); +void automatizer_init(); +bool automatizer_load(boost::filesystem::path const &path); diff --git a/src/status.cc b/src/status.cc deleted file mode 100644 index 0a3977c7..00000000 --- a/src/status.cc +++ /dev/null @@ -1,783 +0,0 @@ -/* File status.c */ - -/* Purpose: Status information */ - -/* Written by Pat Gunn <qc@apk.net> for ToME - * This file is released into the public domain - */ - -/* Throughout this file, I make use of 2-d arrays called flag_arr. - * I fill them out with esp as the 0th element because then the second - * index is equal to the f-number that they are in the attributes, and - * that makes it more intuitive to use. I do need to fill them out in an - * odd order, but that's all abstracted nicely away. The 6th element is used - * to mark if the rest of the array is filled, that is, if there's an object - * there. - */ - -#include "files.hpp" -#include "monster2.hpp" -#include "monster_type.hpp" -#include "object1.hpp" -#include "player_type.hpp" -#include "stats.hpp" -#include "util.hpp" -#include "util.h" -#include "variable.h" -#include "variable.hpp" -#include "xtra1.hpp" - -static void row_trival(const char*, s16b, u32b, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static void row_bival(const char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static void row_npval(const char*, s16b, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static void statline(const char*, int, u32b, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static void row_hd_bon(int, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static void row_count(const char*, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, s16b, u32b, int, int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); -static int row_x_start = 0; - -static void status_count(s32b val1, int v1, s32b val2, int v2, s32b val3, int v3, s32b val4, int v4, byte ypos, byte xpos); -static void status_trival(s32b, s32b, byte, byte); -static void status_bival(s32b, byte, byte); -static void status_numeric(s32b, byte, byte); -static void status_curses(void); -static void status_companion(void); -static void status_sight(void); -static void status_attr(void); -static void status_combat(void); -static void status_move(void); -static void status_item(void); -static void az_line(int, u32b[INVEN_TOTAL - INVEN_WIELD + 2][7]); - -#define STATNM_LENGTH 11 -#define SL_LENGTH 11 - -#define INVEN_PLAYER (INVEN_TOTAL - INVEN_WIELD + 1) - -static void status_attr(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 0; - char c; - - clear_from(0); - c_put_str(TERM_L_BLUE, "Statistics", yo++, 1); - yo += 2; - az_line(SL_LENGTH, flag_arr); - statline("Str", A_STR, TR1_STR, yo++, flag_arr); - statline("Int", A_INT, TR1_INT, yo++, flag_arr); - statline("Wis", A_INT, TR1_WIS, yo++, flag_arr); - statline("Con", A_CON, TR1_CON, yo++, flag_arr); - statline("Dex", A_DEX, TR1_DEX, yo++, flag_arr); - statline("Chr", A_CHR, TR1_CHR, yo++, flag_arr); - row_npval("Luck", 5, TR5_LUCK, yo++, flag_arr); - yo++; - row_npval("Life", 2, TR2_LIFE, yo++, flag_arr); - row_npval("Mana", 1, TR1_MANA, yo++, flag_arr); - - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - c = inkey(); - if (c == ESCAPE) break; - } -} - -void status_move(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - clear_from(0); - c_put_str(TERM_L_BLUE, "Movement", 0, 1); - az_line(STATNM_LENGTH, flag_arr); - - row_trival("Fly/Lev", 4, TR4_FLY, 3, TR3_FEATHER, yo++, flag_arr); - row_bival("Climb", 4, TR4_CLIMB, yo++, flag_arr); - row_npval("Dig", 1, TR1_TUNNEL, yo++, flag_arr); - row_npval("Speed", 1, TR1_SPEED, yo++, flag_arr); - row_bival("Wraith", 3, TR3_WRAITH, yo++, flag_arr); - yo++; - row_npval("Stealth", 1, TR1_STEALTH, yo++, flag_arr); - row_bival("Telep", 3, TR3_TELEPORT, yo++, flag_arr); - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - c = inkey(); - switch (c) - { - case ESCAPE: - { - loop_exit = TRUE; - } - } - if (loop_exit) - { - break; - } - } -} - -static void status_sight(void) -/* Tell player about ESP, infravision, auto-id, see invis, and similar */ -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - clear_from(0); - c_put_str(TERM_L_BLUE, "Sight", 0, 1); - az_line(STATNM_LENGTH, flag_arr); - - row_bival("SeeInvis", 3, TR3_SEE_INVIS, yo++, flag_arr); - row_npval("Invis", 2, TR2_INVIS, yo++, flag_arr); - row_npval("Infra", 1, TR1_INFRA, yo++, flag_arr); - row_npval("Search", 1, TR1_SEARCH, yo++, flag_arr); - row_bival("AutoID", 4, TR4_AUTO_ID, yo++, flag_arr); - row_count("Light", 3, TR3_LITE1, 1, 4, TR4_LITE2, 2, 4, TR4_LITE3, 3, 0, 0, 0, yo++, flag_arr); - row_bival("Full ESP", 0, ESP_ALL, yo++, flag_arr); - row_bival("Orc ESP", 0, ESP_ORC, yo++, flag_arr); - row_bival("Trol ESP", 0, ESP_TROLL, yo++, flag_arr); - row_bival("Drag ESP", 0, ESP_DRAGON, yo++, flag_arr); - row_bival("GiantESP", 0, ESP_GIANT, yo++, flag_arr); - row_bival("DemonESP", 0, ESP_DEMON, yo++, flag_arr); - row_bival("Undd ESP", 0, ESP_UNDEAD, yo++, flag_arr); - row_bival("Evil ESP", 0, ESP_EVIL, yo++, flag_arr); - row_bival("Anim ESP", 0, ESP_ANIMAL, yo++, flag_arr); - row_bival("Drid ESP", 0, ESP_THUNDERLORD, yo++, flag_arr); - row_bival("Good ESP", 0, ESP_GOOD, yo++, flag_arr); - row_bival("SpidrESP", 0, ESP_SPIDER, yo++, flag_arr); - row_bival("NonlvESP", 0, ESP_NONLIVING, yo++, flag_arr); - row_bival("Uniq ESP", 0, ESP_UNIQUE, yo++, flag_arr); - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - c = inkey(); - switch (c) - { - case ESCAPE: - { - loop_exit = TRUE; - } - } - if (loop_exit) - { - break; - } - } -} - -static void status_item(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - clear_from(0); - c_put_str(TERM_L_BLUE, "Misc", 0, 1); - - row_x_start = 40; - az_line(STATNM_LENGTH + row_x_start, flag_arr); - row_bival("Blessed", 3, TR3_BLESSED, yo++, flag_arr); - row_bival("Activate", 3, TR3_ACTIVATE, yo++, flag_arr); - row_bival("EasyKnow", 3, TR3_EASY_KNOW, yo++, flag_arr); - row_bival("HideType", 3, TR3_HIDE_TYPE, yo++, flag_arr); - yo++; - row_bival("SafeAcid", 3, TR3_IGNORE_ACID, yo++, flag_arr); - row_bival("SafeElec", 3, TR3_IGNORE_ELEC, yo++, flag_arr); - row_bival("SafeFire", 3, TR3_IGNORE_FIRE, yo++, flag_arr); - row_bival("SafeCold", 3, TR3_IGNORE_COLD, yo++, flag_arr); - row_bival("ResMorgul", 5, TR5_RES_MORGUL, yo++, flag_arr); - - yo = 3; - row_x_start = 0; - az_line(STATNM_LENGTH, flag_arr); - row_bival("Sh.fire", 3, TR3_SH_FIRE, yo++, flag_arr); - row_bival("Sh.elec", 3, TR3_SH_ELEC, yo++, flag_arr); - row_bival("Regen", 3, TR3_REGEN, yo++, flag_arr); - row_bival("SlowDigest", 3, TR3_SLOW_DIGEST, yo++, flag_arr); - row_bival("Precog", 4, TR4_PRECOGNITION, yo++, flag_arr); - row_bival("Auto.Id", 4, TR4_AUTO_ID, yo++, flag_arr); - row_bival("Spell.In", 5, TR5_SPELL_CONTAIN, yo++, flag_arr); - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - c = inkey(); - switch (c) - { - case ESCAPE: - loop_exit = TRUE; - } - if (loop_exit) - { - break; - } - } -} - -static void status_combat(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - clear_from(0); - c_put_str(TERM_L_BLUE, "Combat", 0, 1); - az_line(STATNM_LENGTH, flag_arr); - - row_npval("Spell", 1, TR1_SPELL, yo++, flag_arr); - row_npval("Blows", 1, TR1_BLOWS, yo++, flag_arr); - row_npval("Crits", 5, TR5_CRIT, yo++, flag_arr); - row_npval("Ammo_Mgt", 3, TR3_XTRA_MIGHT, yo++, flag_arr); - row_npval("Ammo_Sht", 3, TR3_XTRA_SHOTS, yo++, flag_arr); - row_bival("Vorpal", 1, TR1_VORPAL, yo++, flag_arr); - row_bival("Quake", 1, TR1_IMPACT, yo++, flag_arr); - row_bival("Chaotic", 1, TR1_CHAOTIC, yo++, flag_arr); - row_bival("Vampiric", 1, TR1_VAMPIRIC, yo++, flag_arr); - row_bival("Poison", 1, TR1_BRAND_POIS, yo++, flag_arr); - row_bival("Acidic", 1, TR1_BRAND_ACID, yo++, flag_arr); - row_bival("Shocks", 1, TR1_BRAND_ELEC, yo++, flag_arr); - row_bival("Burns", 1, TR1_BRAND_FIRE, yo++, flag_arr); - row_bival("Chills", 1, TR1_BRAND_COLD, yo++, flag_arr); - row_bival("Wound", 5, TR5_WOUNDING, yo++, flag_arr); - - row_x_start = 40; - yo = 3; - az_line(row_x_start + STATNM_LENGTH, flag_arr); - row_bival("No.Blow", 4, TR4_NEVER_BLOW, yo++, flag_arr); - row_trival("S/K Undd", 1, TR1_SLAY_UNDEAD, 5, TR5_KILL_UNDEAD, yo++, flag_arr); - row_trival("S/K Dmn", 1, TR1_SLAY_DEMON, 5, TR5_KILL_DEMON, yo++, flag_arr); - row_trival("S/K Drag", 1, TR1_SLAY_DRAGON, 1, TR1_KILL_DRAGON, yo++, flag_arr); - row_bival("Sl.Orc", 1, TR1_SLAY_ORC, yo++, flag_arr); - row_bival("Sl.Troll", 1, TR1_SLAY_TROLL, yo++, flag_arr); - row_bival("Sl.Giant", 1, TR1_SLAY_GIANT, yo++, flag_arr); - row_bival("Sl.Evil", 1, TR1_SLAY_EVIL, yo++, flag_arr); - row_bival("Sl.Animal", 1, TR1_SLAY_ANIMAL, yo++, flag_arr); - row_hd_bon(0, yo++, flag_arr); - row_hd_bon(1, yo++, flag_arr); - row_x_start = 0; - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - c = inkey(); - switch (c) - { - case ESCAPE: - loop_exit = TRUE; - } - if (loop_exit) - { - break; - } - } -} - -static void status_curses(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - - clear_from(0); - c_put_str(TERM_L_BLUE, "Curses", 0, 1); - az_line(STATNM_LENGTH, flag_arr); - - row_trival("Hvy/Nrm", 3, TR3_HEAVY_CURSE, 3, TR3_CURSED, yo++, flag_arr); - row_bival("Perma", 3, TR3_PERMA_CURSE, yo++, flag_arr); - row_trival("DG/Ty", 4, TR4_DG_CURSE, 3, TR3_TY_CURSE, yo++, flag_arr); - row_trival("Prm/Auto", 3, TR3_PERMA_CURSE, 3, TR3_AUTO_CURSE, yo++, flag_arr); - row_bival("NoDrop", 4, TR4_CURSE_NO_DROP, yo++, flag_arr); - yo++; - row_bival("B.Breath", 4, TR4_BLACK_BREATH, yo++, flag_arr); - row_bival("Dr.Exp", 3, TR3_DRAIN_EXP, yo++, flag_arr); - row_bival("Dr.Mana", 5, TR5_DRAIN_MANA, yo++, flag_arr); - row_bival("Dr.HP", 5, TR5_DRAIN_HP, yo++, flag_arr); - row_bival("No Hit", 4, TR4_NEVER_BLOW, yo++, flag_arr); - row_bival("NoTelep", 3, TR3_NO_TELE, yo++, flag_arr); - row_bival("NoMagic", 3, TR3_NO_MAGIC, yo++, flag_arr); - row_bival("Aggrav", 3, TR3_AGGRAVATE, yo++, flag_arr); - row_bival("Clone", 4, TR4_CLONE, yo++, flag_arr); - row_bival("Temp", 5, TR5_TEMPORARY, yo++, flag_arr); - yo++; - row_bival("Antimagic", 4, TR4_ANTIMAGIC_50, yo++, flag_arr); - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - - c = inkey(); - switch (c) - { - case ESCAPE: - { - loop_exit = TRUE; - } - } - if (loop_exit == TRUE) - { - break; - } - } -} - -static void status_res(void) -{ - u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]; - int yo = 3; - - clear_from(0); - c_put_str(TERM_L_BLUE, "Resistances", 0, 1); - az_line(STATNM_LENGTH, flag_arr); - - row_trival("Fire", 2, TR2_IM_FIRE, 2, TR2_RES_FIRE, yo++, flag_arr); - row_trival("Cold", 2, TR2_IM_COLD, 2, TR2_RES_COLD, yo++, flag_arr); - row_trival("Acid", 2, TR2_IM_ACID, 2, TR2_RES_ACID, yo++, flag_arr); - row_trival("Lightning", 2, TR2_IM_ELEC, 2, TR2_RES_ELEC, yo++, flag_arr); - row_bival("Poison", 2, TR2_RES_POIS, yo++, flag_arr); - row_bival("Lite", 2, TR2_RES_LITE, yo++, flag_arr); - row_bival("Dark", 2, TR2_RES_DARK, yo++, flag_arr); - row_bival("Sound", 2, TR2_RES_SOUND, yo++, flag_arr); - row_bival("Shards", 2, TR2_RES_SHARDS, yo++, flag_arr); - row_trival("Nether", 4, TR4_IM_NETHER, 2, TR2_RES_NETHER, yo++, flag_arr); - row_bival("Nexus", 2, TR2_RES_NEXUS, yo++, flag_arr); - row_bival("Chaos", 2, TR2_RES_CHAOS, yo++, flag_arr); - row_bival("Disen.", 2, TR2_RES_DISEN, yo++, flag_arr); - row_bival("Confusion", 2, TR2_RES_CONF, yo++, flag_arr); - row_bival("Blindness", 2, TR2_RES_BLIND, yo++, flag_arr); - row_bival("Fear", 2, TR2_RES_FEAR, yo++, flag_arr); - row_bival("Free Act", 2, TR2_FREE_ACT, yo++, flag_arr); - row_bival("Reflect", 2, TR2_REFLECT, yo++, flag_arr); - row_bival("Hold Life", 2, TR2_HOLD_LIFE, yo++, flag_arr); - - c_put_str(TERM_WHITE, "Press ESC to continue", 23, 0); - Term_fresh(); - while (1) - { - bool_ loop_exit = FALSE; - char c; - - c = inkey(); - switch (c) - { - case ESCAPE: - { - loop_exit = TRUE; - } - } - if (loop_exit == TRUE) - { - break; - } - } -} - -void status_main() -{ - int do_quit = 0; - char c; - - character_icky = TRUE; - Term_save(); - while (1) - { - clear_from(0); - c_put_str(TERM_WHITE, format("%s Character Status screen", game_module), 0, 10); - c_put_str(TERM_WHITE, "1) Statistics", 2, 5); - c_put_str(TERM_WHITE, "2) Movement", 3, 5); - c_put_str(TERM_WHITE, "3) Combat", 4, 5); - c_put_str(TERM_WHITE, "4) Resistances", 5, 5); - c_put_str(TERM_WHITE, "5) Misc", 6, 5); - c_put_str(TERM_WHITE, "6) Curses", 7, 5); - c_put_str(TERM_WHITE, "7) Sight", 8, 5); - c_put_str(TERM_WHITE, "8) Companions", 9, 5); - c_put_str(TERM_RED, "Press 'q' to Quit", 23, 5); - c = inkey(); - switch (c) - { - case '1': - status_attr(); - break; - case '2': - status_move(); - break; - case '3': - status_combat(); - break; - case '4': - status_res(); - break; - case '5': - status_item(); - break; - case '6': - status_curses(); - break; - case '7': - status_sight(); - break; - case '8': - status_companion(); - break; - case 'q': - case ESCAPE: - do_quit = 1; /* Schedule leaving the outer loop */ - break; - } - Term_fresh(); - if (do_quit) break; - } - Term_load(); - character_icky = FALSE; - p_ptr->redraw |= (PR_WIPE | PR_FRAME | PR_MAP); - handle_stuff(); -} - -static void az_line(int xo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -{ - int index = xo; /* Leave room for description */ - int i; - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) - { - if (p_ptr->inventory[i].k_idx) /* Wearing anything here? */ - { - char cstrng[2]; - cstrng[0] = (i - INVEN_WIELD) + 'a'; /* Assumes ASCII */ - cstrng[1] = '\0'; /* terminate it */ - c_put_str(TERM_WHITE, cstrng, 2, index++); /* Assumes ASCII */ - - /* DGDGDGDG */ - /* object_flags_known(&inventory[i],*/ - object_flags(&p_ptr->inventory[i], /* Help me debug */ - &flag_arr[i - INVEN_WIELD][1], /* f1 */ - &flag_arr[i - INVEN_WIELD][2], /* f2 */ - &flag_arr[i - INVEN_WIELD][3], /* f3 */ - &flag_arr[i - INVEN_WIELD][4], /* f4 */ - &flag_arr[i - INVEN_WIELD][5], /* f5 */ - &flag_arr[i - INVEN_WIELD][0]); /* esp */ - flag_arr[i - INVEN_WIELD][6] = 1; /* And mark it to display */ - } - else flag_arr[i - INVEN_WIELD][6] = 0; /* Otherwise don't display it */ - } - c_put_str(TERM_WHITE, "@", 2, index++); - player_flags( - &flag_arr[INVEN_PLAYER][1], /* f1 */ - &flag_arr[INVEN_PLAYER][2], /* f2 */ - &flag_arr[INVEN_PLAYER][3], /* f3 */ - &flag_arr[INVEN_PLAYER][4], /* f4 */ - &flag_arr[INVEN_PLAYER][5], /* f5 */ - &flag_arr[INVEN_PLAYER][0] /* esp */ - ); - flag_arr[INVEN_PLAYER][6] = 1; -} - -static void status_trival(s32b val1, s32b val2, byte ypos, byte xpos) -{ - if (val1 != 0) - c_put_str(TERM_L_BLUE, "*", ypos, xpos); - else if (val2 != 0) - c_put_str(TERM_L_BLUE, "+", ypos, xpos); - else - c_put_str(TERM_WHITE, ".", ypos, xpos); -} - -static void status_bival(s32b val, byte ypos, byte xpos) -{ - if (val != 0) - c_put_str(TERM_L_BLUE, "+", ypos, xpos); - else - c_put_str(TERM_WHITE, ".", ypos, xpos); -} - -static void status_numeric(s32b val, byte ypos, byte xpos) -{ - u32b magnitude = ABS(val); - int color = TERM_WHITE; /* default */ - char strnum[2]; - - if (val<0) { - color = TERM_RED; - }; - if (val>0) { - color = TERM_GREEN; - }; - - if (magnitude == 0) { - sprintf(strnum, "."); - } if (magnitude > 9) { - sprintf(strnum, "*"); - } else { - sprintf(strnum, "%lu", (unsigned long int) magnitude); - } - - c_put_str(color, strnum, ypos, xpos); -} - -static void status_count(s32b val1, int v1, s32b val2, int v2, s32b val3, int v3, s32b val4, int v4, byte ypos, byte xpos) -{ - int v = 0; - - if (val1 != 0) v += v1; - if (val2 != 0) v += v2; - if (val3 != 0) v += v3; - if (val4 != 0) v += v4; - - status_numeric(v, ypos, xpos); -} - -static void row_count(const char* statname, s16b row1, u32b flag1, int v1, s16b row2, u32b flag2, int v2, s16b row3, u32b flag3, int v3, s16b row4, u32b flag4, int v4, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -{ - int i; - int x = row_x_start; - - c_put_str(TERM_L_GREEN, statname, yo, row_x_start); - - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - if (flag_arr[i][6] == 1) - { - status_count((flag_arr[i][row1] & flag1), v1, (flag_arr[i][row2] & flag2), v2, (flag_arr[i][row3] & flag3), v3, (flag_arr[i][row4] & flag4), v4, yo, x + STATNM_LENGTH); - x++; - } - } -} - -static void row_trival(const char* statname, s16b row, u32b flag, s16b row2, u32b flag2, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -{ - int i; - int x = row_x_start; - c_put_str(TERM_L_GREEN, statname, yo, row_x_start); - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - if (flag_arr[i][6] == 1) - { - status_trival( - (flag_arr[i][row] & flag), - (flag_arr[i][row2] & flag2), - yo, x + STATNM_LENGTH); - x++; - } - } -} - -static void row_bival(const char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -{ - int i; - int x = row_x_start; - c_put_str(TERM_L_GREEN, statname, yo, row_x_start); - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - if (flag_arr[i][6] == 1) - { - status_bival((flag_arr[i][row] & flag), yo, x + STATNM_LENGTH); - x++; - } - } -} - -static void row_npval(const char* statname, s16b row, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -/* Displays nicely a pval-based status row */ -{ - int i; - int x = row_x_start; - c_put_str(TERM_L_GREEN, statname, yo, row_x_start); - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - if (flag_arr[i][6] == 1) - { - if (i == INVEN_PLAYER) - /* Special case, player_flags */ - /* Players lack a pval, no way to calc value */ - { - if (flag_arr[i][row] & flag) - c_put_str(TERM_YELLOW, "*", yo, x + STATNM_LENGTH); - else c_put_str(TERM_WHITE, ".", yo, x + STATNM_LENGTH); - x++; - continue; - } - if (flag_arr[i][row] & flag) - status_numeric(p_ptr->inventory[i + INVEN_WIELD].pval, yo, x + STATNM_LENGTH); - else - c_put_str(TERM_WHITE, ".", yo, x + STATNM_LENGTH); - x++; - } - } -} - -static void statline(const char* statname, int statidx, u32b flag, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -/* Displays a status row for a primary stat */ -{ - int i; - int x = row_x_start; - char statstr[8]; - byte stat_color = TERM_L_RED; - - cnv_stat(p_ptr->stat_use[statidx], statstr); - - c_put_str(TERM_L_GREEN, statstr, yo, 4 + row_x_start); - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - byte color = TERM_L_RED; - - if (flag_arr[i][6] == 1) - { - switch (statidx) - { - case A_STR: - if (flag_arr[i][2] & TR2_SUST_STR) - color = TERM_L_BLUE; - break; - case A_INT: - if (flag_arr[i][2] & TR2_SUST_INT) - color = TERM_L_BLUE; - break; - case A_WIS: - if (flag_arr[i][2] & TR2_SUST_WIS) - color = TERM_L_BLUE; - break; - case A_DEX: - if (flag_arr[i][2] & TR2_SUST_DEX) - color = TERM_L_BLUE; - break; - case A_CON: - if (flag_arr[i][2] & TR2_SUST_CON) - color = TERM_L_BLUE; - break; - case A_CHR: - if (flag_arr[i][2] & TR2_SUST_CHR) - color = TERM_L_BLUE; - break; - } - - if (i == INVEN_PLAYER ) /* Player flags */ - { - if (flag_arr[i][1] & flag) - c_put_str((color == TERM_L_RED) ? TERM_YELLOW : color, "*", yo, x + SL_LENGTH); - else c_put_str((color == TERM_L_RED) ? TERM_WHITE : color, ".", yo, x + SL_LENGTH); - x++; - continue; - } - if (flag_arr[i][1] & flag) - status_numeric(p_ptr->inventory[i + INVEN_WIELD].pval, yo, x + SL_LENGTH); - else - c_put_str((color == TERM_L_RED) ? TERM_WHITE : color, ".", yo, x + SL_LENGTH); - - if (color != TERM_L_RED) - stat_color = color; - - x++; - } - } - - c_put_str(stat_color, statname, yo, row_x_start); -} - -static void row_hd_bon(int which, int yo, u32b flag_arr[INVEN_TOTAL - INVEN_WIELD + 2][7]) -/* To-hit/dmg modifiers, selected by 1st argument */ -{ - int i; - int x = row_x_start; - if ((which != 0) && (which != 1)) return; - c_put_str(TERM_L_GREEN, ((which == 0) ? "To-Hit" : "To-Dmg"), yo, row_x_start); - for (i = 0; i < (INVEN_TOTAL - INVEN_WIELD + 2); i++) - { - if (flag_arr[i][6] == 1) - { - if (i == INVEN_PLAYER) /* Player? */ - { - c_put_str(TERM_WHITE, ".", yo, x + STATNM_LENGTH); - x++; - continue; - } - if ( (which == 0) && (p_ptr->inventory[INVEN_WIELD + i].to_h != 0)) - { - status_numeric(p_ptr->inventory[INVEN_WIELD + i].to_h, yo, x + STATNM_LENGTH); - x++; - continue; - } - if ( (which == 1) && (p_ptr->inventory[INVEN_WIELD + i].to_d != 0)) - { - status_numeric(p_ptr->inventory[INVEN_WIELD + i].to_d, yo, x + STATNM_LENGTH); - x++; - continue; - } - c_put_str(TERM_WHITE, ".", yo, x + STATNM_LENGTH); - x++; - } - } -} - -static void status_companion(void) -{ - int i; - - FILE *fff; - - char file_name[1024]; - - Term_clear(); - - /* Temporary file */ - if (path_temp(file_name, 1024)) return; - - /* Open a new file */ - fff = my_fopen(file_name, "w"); - - /* Calculate companions */ - /* Process the monsters (backwards) */ - for (i = m_max - 1; i >= 1; i--) - { - /* Access the monster */ - monster_type *m_ptr = &m_list[i]; - - if (m_ptr->status == MSTATUS_COMPANION) - { - char m_name[80]; - int b, y = 0; - - /* Extract monster name */ - monster_desc(m_name, m_ptr, 0x80); - - fprintf(fff, "#####BCompanion: %s\n", m_name); - - fprintf(fff, " Lev/Exp : [[[[[G%d / %ld]\n", m_ptr->level, (long int) m_ptr->exp); - if (m_ptr->level < MONSTER_LEVEL_MAX) fprintf(fff, " Next lvl: [[[[[G%ld]\n", (long int) monster_exp(m_ptr->level + 1)); - else fprintf(fff, " Next lvl: [[[[[G****]\n"); - - fprintf(fff, " HP : [[[[[G%ld / %ld]\n", (long int) m_ptr->hp, (long int) m_ptr->maxhp); - fprintf(fff, " AC : [[[[[G%d]\n", m_ptr->ac); - fprintf(fff, " Speed : [[[[[G%d]\n", m_ptr->mspeed - 110); - - for (b = 0; b < 4; b++) - { - if (!m_ptr->blow[b].d_dice) continue; - if (!m_ptr->blow[b].d_side) continue; - - fprintf(fff, " Blow %1d : [[[[[G%dd%d]\n", y + 1, m_ptr->blow[b].d_dice, m_ptr->blow[b].d_side); - y++; - } - - fprintf(fff, "\n"); - } - } - - /* Close the file */ - my_fclose(fff); - - /* Display the file contents */ - show_file(file_name, "Companion List", 0, 0); - - /* Remove the file */ - fd_kill(file_name); -} diff --git a/src/status.hpp b/src/status.hpp deleted file mode 100644 index 74624446..00000000 --- a/src/status.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void status_main(); diff --git a/src/store.cc b/src/store.cc index 0fbe2e9b..a11a3ea8 100644 --- a/src/store.cc +++ b/src/store.cc @@ -15,20 +15,22 @@ #include "cmd4.hpp" #include "cmd5.hpp" #include "files.hpp" +#include "game.hpp" #include "hooks.hpp" #include "obj_theme.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_kind.hpp" #include "options.hpp" #include "owner_type.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "spell_type.hpp" #include "skills.hpp" #include "spells5.hpp" #include "stats.hpp" #include "store_action_type.hpp" +#include "store_flag.hpp" #include "store_type.hpp" #include "store_info_type.hpp" #include "tables.hpp" @@ -41,6 +43,7 @@ #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> #define STORE_GENERAL_STORE "General Store" #define STORE_ARMOURY "Armoury" @@ -52,7 +55,6 @@ #define STORE_BOOKS "Book Store" #define STORE_PETS "Pet Shop" #define STORE_HUNTING_SUPPLIES "Hunting Supply Store" -#define STORE_RUNIC_MAGIC "Runic Magic Shop" #define STORE_CONSTRUCTION_SUPPLIES "Construction Supply Store" #define STORE_MUSIC "Music Store" @@ -94,7 +96,7 @@ static cptr comment_4b[MAX_COMMENT_4B] = /* * Successful haggle. */ -static void say_comment_1(void) +static void say_comment_1() { char rumour[80]; @@ -112,7 +114,7 @@ static void say_comment_1(void) /* * Kick 'da bum out. -RAK- */ -static void say_comment_4(void) +static void say_comment_4() { msg_print(comment_4a[rand_int(MAX_COMMENT_4A)]); msg_print(comment_4b[rand_int(MAX_COMMENT_4B)]); @@ -176,9 +178,6 @@ static void purchase_analyze(s32b price, s32b value, s32b guess) { /* Comment */ msg_print(comment_7a[rand_int(MAX_COMMENT_7A)]); - - /* Sound */ - sound(SOUND_STORE1); } /* Item was cheaper than we thought, and we paid more than necessary */ @@ -186,9 +185,6 @@ static void purchase_analyze(s32b price, s32b value, s32b guess) { /* Comment */ msg_print(comment_7b[rand_int(MAX_COMMENT_7B)]); - - /* Sound */ - sound(SOUND_STORE2); } /* Item was a good bargain, and we got away with it */ @@ -196,9 +192,6 @@ static void purchase_analyze(s32b price, s32b value, s32b guess) { /* Comment */ msg_print(comment_7c[rand_int(MAX_COMMENT_7C)]); - - /* Sound */ - sound(SOUND_STORE3); } /* Item was a great bargain, and we got away with it */ @@ -206,9 +199,6 @@ static void purchase_analyze(s32b price, s32b value, s32b guess) { /* Comment */ msg_print(comment_7d[rand_int(MAX_COMMENT_7D)]); - - /* Sound */ - sound(SOUND_STORE4); } } @@ -234,7 +224,7 @@ static store_type *st_ptr = NULL; /* * We store the current "owner type" here so everyone can access it */ -static owner_type *ot_ptr = NULL; +static owner_type const *ot_ptr = NULL; @@ -259,6 +249,8 @@ static owner_type *ot_ptr = NULL; */ static s32b price_item(object_type *o_ptr, int greed, bool_ flip) { + auto const &st_info = game->edit_data.st_info; + int factor; int adjust; s32b price; @@ -307,10 +299,10 @@ static s32b price_item(object_type *o_ptr, int greed, bool_ flip) if (adjust > 100) adjust = 100; /* Mega-Hack -- Black market sucks */ - if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) price = price / 2; + if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM) price = price / 2; /* No selling means you get no money */ - if (no_selling) price = 0; + if (options->no_selling) price = 0; } /* Shop is selling */ @@ -323,7 +315,7 @@ static s32b price_item(object_type *o_ptr, int greed, bool_ flip) if (adjust < 100) adjust = 100; /* Mega-Hack -- Black market sucks */ - if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) price = price * 2; + if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM) price = price * 2; /* Never give items away for free */ if (price <= 0L) price = 1L; @@ -462,9 +454,9 @@ static void mass_produce(object_type *o_ptr) } - if (o_ptr->art_name) + if (!o_ptr->artifact_name.empty()) { - if (cheat_peek && discount) + if (options->cheat_peek && discount) { msg_print("No discount on random artifacts."); } @@ -490,7 +482,7 @@ static void mass_produce(object_type *o_ptr) * * See "object_similar()" for the same function for the "player" */ -static bool_ store_object_similar(object_type *o_ptr, object_type *j_ptr) +static bool_ store_object_similar(object_type const *o_ptr, object_type *j_ptr) { /* Hack -- Identical items cannot be stacked */ if (o_ptr == j_ptr) return (0); @@ -520,12 +512,11 @@ static bool_ store_object_similar(object_type *o_ptr, object_type *j_ptr) if (o_ptr->name2b != j_ptr->name2b) return (0); /* Random artifacts don't stack !*/ - if (o_ptr->art_name || j_ptr->art_name) return (0); + if (!o_ptr->artifact_name.empty()) return 0; + if (!j_ptr->artifact_name.empty()) return 0; /* Hack -- Identical art_flags! */ - if ((o_ptr->art_flags1 != j_ptr->art_flags1) || - (o_ptr->art_flags2 != j_ptr->art_flags2) || - (o_ptr->art_flags3 != j_ptr->art_flags3)) + if (o_ptr->art_flags != j_ptr->art_flags) return (0); /* Hack -- Never stack "powerful" items */ @@ -583,24 +574,25 @@ static void store_object_absorb(object_type *o_ptr, object_type *j_ptr) */ static bool_ store_check_num(object_type *o_ptr) { - int i; - object_type *j_ptr; + auto const &st_info = game->edit_data.st_info; /* Free space is always usable */ - if (st_ptr->stock_num < st_ptr->stock_size) return TRUE; + if (st_ptr->stock.size() < st_ptr->stock_size) + { + return TRUE; + } /* The "home" acts like the player */ - if ((cur_store_num == 7) || - (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM)) + if ((cur_store_num == 7) || (st_info[st_ptr->st_idx].flags & STF_MUSEUM)) { /* Check all the items */ - for (i = 0; i < st_ptr->stock_num; i++) + for (auto const &o_ref: st_ptr->stock) { - /* Get the existing item */ - j_ptr = &st_ptr->stock[i]; - /* Can the new object be combined with the old one? */ - if (object_similar(j_ptr, o_ptr)) return (TRUE); + if (object_similar(&o_ref, o_ptr)) + { + return TRUE; + } } } @@ -608,27 +600,25 @@ static bool_ store_check_num(object_type *o_ptr) else { /* Check all the items */ - for (i = 0; i < st_ptr->stock_num; i++) + for (auto const &o_ref: st_ptr->stock) { - /* Get the existing item */ - j_ptr = &st_ptr->stock[i]; - /* Can the new object be combined with the old one? */ - if (store_object_similar(j_ptr, o_ptr)) return (TRUE); + if (store_object_similar(&o_ref, o_ptr)) + { + return TRUE; + } } } /* But there was no room at the inn... */ - return (FALSE); + return FALSE; } -static bool_ is_blessed(object_type const *o_ptr) +static bool is_blessed(object_type const *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - object_flags_known(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if (f3 & TR3_BLESSED) return (TRUE); - else return (FALSE); + auto flags = object_flags_known(o_ptr); + return bool(flags & TR_BLESSED); } @@ -640,7 +630,9 @@ static bool_ is_blessed(object_type const *o_ptr) */ static bool store_will_buy(object_type const *o_ptr) { - cptr store_name = st_info[st_ptr->st_idx].name; + auto const &st_info = game->edit_data.st_info; + + auto const &store_name = st_info[st_ptr->st_idx].name; /* Hack -- The Home is simple */ if (cur_store_num == 7) @@ -648,7 +640,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } - if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) + if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) { return true; } @@ -660,7 +652,7 @@ static bool store_will_buy(object_type const *o_ptr) } /* What do stores buy? */ - if (streq(store_name, STORE_GENERAL_STORE)) + if ((store_name == STORE_GENERAL_STORE)) { switch (o_ptr->tval) { @@ -678,7 +670,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_ARMOURY)) + else if ((store_name == STORE_ARMOURY)) { switch (o_ptr->tval) { @@ -694,7 +686,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_WEAPONSMITH)) + else if ((store_name == STORE_WEAPONSMITH)) { switch (o_ptr->tval) { @@ -712,7 +704,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_TEMPLE)) + else if ((store_name == STORE_TEMPLE)) { switch (o_ptr->tval) { @@ -751,7 +743,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_ALCHEMY)) + else if ((store_name == STORE_ALCHEMY)) { switch (o_ptr->tval) { @@ -762,7 +754,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_MAGIC)) + else if ((store_name == STORE_MAGIC)) { switch (o_ptr->tval) { @@ -793,11 +785,11 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_BLACK_MARKET)) + else if ((store_name == STORE_BLACK_MARKET)) { return true; } - else if (streq(store_name, STORE_BOOKS)) + else if ((store_name == STORE_BOOKS)) { switch (o_ptr->tval) { @@ -809,15 +801,14 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_PETS)) + else if ((store_name == STORE_PETS)) { return (o_ptr->tval == TV_EGG); } - else if (streq(store_name, STORE_HUNTING_SUPPLIES)) + else if ((store_name == STORE_HUNTING_SUPPLIES)) { switch (o_ptr->tval) { - case TV_TRAPKIT: case TV_BOOMERANG: case TV_SHOT: case TV_BOLT: @@ -827,16 +818,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_RUNIC_MAGIC)) - { - switch (o_ptr->tval) - { - case TV_RUNE1: - case TV_RUNE2: - return true; - } - } - else if (streq(store_name, STORE_CONSTRUCTION_SUPPLIES)) + else if ((store_name == STORE_CONSTRUCTION_SUPPLIES)) { switch (o_ptr->tval) { @@ -845,7 +827,7 @@ static bool store_will_buy(object_type const *o_ptr) return true; } } - else if (streq(store_name, STORE_MUSIC)) + else if ((store_name == STORE_MUSIC)) { return (o_ptr->tval == TV_INSTRUMENT); } @@ -868,17 +850,13 @@ static bool store_will_buy(object_type const *o_ptr) */ static int home_carry(object_type *o_ptr) { - int slot; - s32b value, j_value; - int i; - object_type *j_ptr; - + std::size_t slot; /* Check each existing item (try to combine) */ - for (slot = 0; slot < st_ptr->stock_num; slot++) + for (slot = 0; slot < st_ptr->stock.size(); slot++) { /* Get the existing item */ - j_ptr = &st_ptr->stock[slot]; + auto j_ptr = &st_ptr->stock[slot]; /* The home acts just like the player */ if (object_similar(j_ptr, o_ptr)) @@ -887,22 +865,24 @@ static int home_carry(object_type *o_ptr) object_absorb(j_ptr, o_ptr); /* All done */ - return (slot); + return slot; } } /* No space? */ - if (st_ptr->stock_num >= st_ptr->stock_size) return ( -1); - + if (st_ptr->stock.size() >= st_ptr->stock_size) + { + return -1; + } /* Determine the "value" of the item */ - value = object_value(o_ptr); + auto const value = object_value(o_ptr); /* Check existing slots to see if we must "slide" */ - for (slot = 0; slot < st_ptr->stock_num; slot++) + for (slot = 0; slot < st_ptr->stock.size(); slot++) { /* Get that item */ - j_ptr = &st_ptr->stock[slot]; + auto j_ptr = &st_ptr->stock[slot]; /* Objects sort by decreasing type */ if (o_ptr->tval > j_ptr->tval) break; @@ -932,25 +912,16 @@ static int home_carry(object_type *o_ptr) } /* Objects sort by decreasing value */ - j_value = object_value(j_ptr); + auto const j_value = object_value(j_ptr); if (value > j_value) break; if (value < j_value) continue; } - /* Slide the others up */ - for (i = st_ptr->stock_num; i > slot; i--) - { - st_ptr->stock[i] = st_ptr->stock[i - 1]; - } - - /* More stuff now */ - st_ptr->stock_num++; - - /* Insert the new item */ - st_ptr->stock[slot] = *o_ptr; + /* Insert */ + st_ptr->stock.insert(st_ptr->stock.begin() + slot, *o_ptr); /* Return the location */ - return (slot); + return slot; } @@ -968,28 +939,28 @@ static int home_carry(object_type *o_ptr) */ static int store_carry(object_type *o_ptr) { - int i, slot; - s32b value, j_value; - object_type *j_ptr; - + std::size_t slot; /* Evaluate the object */ - value = object_value(o_ptr); + auto const value = object_value(o_ptr); /* Cursed/Worthless items "disappear" when sold */ - if (value <= 0) return ( -1); + if (value <= 0) + { + return -1; + } /* All store items are fully *identified* */ o_ptr->ident |= IDENT_MENTAL; /* Erase the inscription */ - o_ptr->note = 0; + o_ptr->inscription.clear(); /* Check each existing item (try to combine) */ - for (slot = 0; slot < st_ptr->stock_num; slot++) + for (slot = 0; slot < st_ptr->stock.size(); slot++) { /* Get the existing item */ - j_ptr = &st_ptr->stock[slot]; + auto j_ptr = &st_ptr->stock[slot]; /* Can the existing items be incremented? */ if (store_object_similar(j_ptr, o_ptr)) @@ -998,19 +969,22 @@ static int store_carry(object_type *o_ptr) store_object_absorb(j_ptr, o_ptr); /* All done */ - return (slot); + return slot; } } /* No space? */ - if (st_ptr->stock_num >= st_ptr->stock_size) return ( -1); + if (st_ptr->stock.size() >= st_ptr->stock_size) + { + return -1; + } /* Check existing slots to see if we must "slide" */ - for (slot = 0; slot < st_ptr->stock_num; slot++) + for (slot = 0; slot < st_ptr->stock.size(); slot++) { /* Get that item */ - j_ptr = &st_ptr->stock[slot]; + auto j_ptr = &st_ptr->stock[slot]; /* Objects sort by decreasing type */ if (o_ptr->tval > j_ptr->tval) break; @@ -1032,27 +1006,18 @@ static int store_carry(object_type *o_ptr) } /* Evaluate that slot */ - j_value = object_value(j_ptr); + auto const j_value = object_value(j_ptr); /* Objects sort by decreasing value */ if (value > j_value) break; if (value < j_value) continue; } - /* Slide the others up */ - for (i = st_ptr->stock_num; i > slot; i--) - { - st_ptr->stock[i] = st_ptr->stock[i - 1]; - } - - /* More stuff now */ - st_ptr->stock_num++; - /* Insert the new item */ - st_ptr->stock[slot] = *o_ptr; + st_ptr->stock.insert(st_ptr->stock.begin() + slot, *o_ptr); /* Return the location */ - return (slot); + return slot; } @@ -1062,14 +1027,11 @@ static int store_carry(object_type *o_ptr) */ static void store_item_increase(int item, int num) { - int cnt; - object_type *o_ptr; - /* Get the item */ - o_ptr = &st_ptr->stock[item]; + auto o_ptr = &st_ptr->stock[item]; /* Verify the number */ - cnt = o_ptr->number + num; + int cnt = o_ptr->number + num; if (cnt > 255) cnt = 255; else if (cnt < 0) cnt = 0; num = cnt - o_ptr->number; @@ -1084,11 +1046,8 @@ static void store_item_increase(int item, int num) */ static void store_item_optimize(int item) { - int j; - object_type *o_ptr; - /* Get the item */ - o_ptr = &st_ptr->stock[item]; + auto const o_ptr = &st_ptr->stock[item]; /* Must exist */ if (!o_ptr->k_idx) return; @@ -1096,17 +1055,11 @@ static void store_item_optimize(int item) /* Must have no items */ if (o_ptr->number) return; - /* One less item */ - st_ptr->stock_num--; + /* Wipe the item */ + object_wipe(&st_ptr->stock[item]); - /* Slide everyone */ - for (j = item; j < st_ptr->stock_num; j++) - { - st_ptr->stock[j] = st_ptr->stock[j + 1]; - } - - /* Nuke the final slot */ - object_wipe(&st_ptr->stock[j]); + /* Erase the item */ + st_ptr->stock.erase(st_ptr->stock.begin() + item); } @@ -1117,7 +1070,7 @@ static void store_item_optimize(int item) */ static bool_ black_market_crap(object_type *o_ptr) { - int i, j; + auto const &st_info = game->edit_data.st_info; /* Ego items are never crap */ if (o_ptr->name2) return (FALSE); @@ -1128,18 +1081,16 @@ static bool_ black_market_crap(object_type *o_ptr) if (o_ptr->to_d > 0) return (FALSE); /* Check all stores */ - for (i = 0; i < max_st_idx; i++) + for (std::size_t i = 0; i < st_info.size(); i++) { if (i == STORE_HOME) continue; - if (st_info[i].flags1 & SF1_MUSEUM) continue; + if (st_info[i].flags & STF_MUSEUM) continue; /* Check every item in the store */ - for (j = 0; j < town_info[p_ptr->town_num].store[i].stock_num; j++) + for (auto const &stock_obj: town_info[p_ptr->town_num].store[i].stock) { - object_type *j_ptr = &town_info[p_ptr->town_num].store[i].stock[j]; - /* Duplicate item "type", assume crappy */ - if (o_ptr->k_idx == j_ptr->k_idx) return (TRUE); + if (o_ptr->k_idx == stock_obj.k_idx) return (TRUE); } } @@ -1152,15 +1103,13 @@ static bool_ black_market_crap(object_type *o_ptr) * Attempt to delete (some of) a random item from the store * Hack -- we attempt to "maintain" piles of items when possible. */ -static void store_delete(void) +static void store_delete() { - int what, num; - /* Pick a random slot */ - what = rand_int(st_ptr->stock_num); + int const what = rand_int(st_ptr->stock.size()); /* Determine how many items are here */ - num = st_ptr->stock[what].number; + int num = st_ptr->stock[what].number; /* Hack -- sometimes, only destroy half the items */ if (rand_int(100) < 50) num = (num + 1) / 2; @@ -1182,19 +1131,22 @@ static void store_delete(void) /* Analyze store flags and return a level */ int return_level() { - store_info_type *sti_ptr = &st_info[st_ptr->st_idx]; + auto const &st_info = game->edit_data.st_info; + + auto sti_ptr = &st_info[st_ptr->st_idx]; + int level; - if (sti_ptr->flags1 & SF1_RANDOM) level = 0; + if (sti_ptr->flags & STF_RANDOM) level = 0; else level = rand_range(1, STORE_OBJ_LEVEL); - if (sti_ptr->flags1 & SF1_DEPEND_LEVEL) level += dun_level; + if (sti_ptr->flags & STF_DEPEND_LEVEL) level += dun_level; - if (sti_ptr->flags1 & SF1_SHALLOW_LEVEL) level += 5 + rand_int(5); - if (sti_ptr->flags1 & SF1_MEDIUM_LEVEL) level += 25 + rand_int(25); - if (sti_ptr->flags1 & SF1_DEEP_LEVEL) level += 45 + rand_int(45); + if (sti_ptr->flags & STF_SHALLOW_LEVEL) level += 5 + rand_int(5); + if (sti_ptr->flags & STF_MEDIUM_LEVEL) level += 25 + rand_int(25); + if (sti_ptr->flags & STF_DEEP_LEVEL) level += 45 + rand_int(45); - if (sti_ptr->flags1 & SF1_ALL_ITEM) level += p_ptr->lev; + if (sti_ptr->flags & STF_ALL_ITEM) level += p_ptr->lev; return (level); } @@ -1207,12 +1159,14 @@ static int store_tval = 0, store_level = 0; */ static bool_ kind_is_storeok(int k_idx) { - object_kind *k_ptr = &k_info[k_idx]; + auto const &k_info = game->edit_data.k_info; + + auto k_ptr = &k_info[k_idx]; - if (k_info[k_idx].flags3 & TR3_NORM_ART) + if (k_info[k_idx].flags & TR_NORM_ART) return ( FALSE ); - if (k_info[k_idx].flags3 & TR3_INSTA_ART) + if (k_info[k_idx].flags & TR_INSTA_ART) return ( FALSE ); if (!kind_is_legal(k_idx)) return FALSE; @@ -1233,9 +1187,13 @@ static bool_ kind_is_storeok(int k_idx) * * Should we check for "permission" to have the given item? */ -static void store_create(void) +static void store_create() { - int i = 0, tries, level = 0, chance, item; + auto const &st_info = game->edit_data.st_info; + auto const &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; + + int i = 0, tries, level = 0; object_type forge; object_type *q_ptr = NULL; @@ -1243,7 +1201,10 @@ static void store_create(void) /* Paranoia -- no room left */ - if (st_ptr->stock_num >= st_ptr->stock_size) return; + if (st_ptr->stock.size() >= st_ptr->stock_size) + { + return; + } /* Hack -- consider up to four items */ @@ -1252,7 +1213,7 @@ static void store_create(void) obj_all_done = FALSE; /* Magic Shop */ - if (streq(st_info[st_ptr->st_idx].name, STORE_MAGIC) && + if ((st_info[st_ptr->st_idx].name == STORE_MAGIC) && magik(20)) { s16b spell; @@ -1268,7 +1229,7 @@ static void store_create(void) } /* Temple */ - else if (streq(st_info[st_ptr->st_idx].name, STORE_TEMPLE) && + else if ((st_info[st_ptr->st_idx].name == STORE_TEMPLE) && magik(20)) { s16b spell; @@ -1284,16 +1245,10 @@ static void store_create(void) } /* Black Market */ - else if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) + else if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM) { - obj_theme theme; - /* No themes */ - theme.treasure = 100; - theme.combat = 100; - theme.magic = 100; - theme.tools = 100; - init_match_theme(theme); + init_match_theme(obj_theme::no_theme()); /* * Even in Black Markets, illegal objects can be @@ -1311,7 +1266,7 @@ static void store_create(void) i = get_obj_num(level); /* Invalidate the cached allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; /* Handle failure */ if (!i) continue; @@ -1322,12 +1277,12 @@ static void store_create(void) else { /* Hack -- Pick an item to sell */ - item = rand_int(st_info[st_ptr->st_idx].table_num); - i = st_info[st_ptr->st_idx].table[item][0]; - chance = st_info[st_ptr->st_idx].table[item][1]; + auto const &item = st_info[st_ptr->st_idx].items[rand_int(st_info[st_ptr->st_idx].items.size())]; + i = item.kind; + auto chance = item.chance; /* Don't allow k_info artifacts */ - if ((i <= 10000) && (k_info[i].flags3 & TR3_NORM_ART)) + if ((i <= 10000) && (k_info[i].flags & TR_NORM_ART)) continue; /* Does it passes the rarity check ? */ @@ -1339,22 +1294,22 @@ static void store_create(void) /* Hack -- i > 10000 means it's a tval and all svals are allowed */ if (i > 10000) { - obj_theme theme; - /* No themes */ - theme.treasure = 100; - theme.combat = 100; - theme.magic = 100; - theme.tools = 100; - init_match_theme(theme); + init_match_theme(obj_theme::no_theme()); /* Activate restriction */ get_obj_num_hook = kind_is_storeok; store_tval = i - 10000; /* Do we forbid too shallow items ? */ - if (st_info[st_ptr->st_idx].flags1 & SF1_FORCE_LEVEL) store_level = level; - else store_level = 0; + if (st_info[st_ptr->st_idx].flags & STF_FORCE_LEVEL) + { + store_level = level; + } + else + { + store_level = 0; + } /* Prepare allocation table */ get_obj_num_prep(); @@ -1363,7 +1318,7 @@ static void store_create(void) i = get_obj_num(level); /* Invalidate the cached allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; } if (!i) continue; @@ -1373,11 +1328,11 @@ static void store_create(void) if (!obj_all_done) { /* Don't allow k_info artifacts */ - if (k_info[i].flags3 & TR3_NORM_ART) + if (k_info[i].flags & TR_NORM_ART) continue; /* Don't allow artifacts */ - if (k_info[i].flags3 & TR3_INSTA_ART) + if (k_info[i].flags & TR_INSTA_ART) continue; /* Get local object */ @@ -1392,11 +1347,11 @@ static void store_create(void) /* Hack -- Charge lite's */ if (q_ptr->tval == TV_LITE) { - u32b f1, f2, f3, f4, f5, esp; - - object_flags(q_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if (f4 & TR4_FUEL_LITE) q_ptr->timeout = k_info[q_ptr->k_idx].pval2; + auto const flags = object_flags(q_ptr); + if (flags & TR_FUEL_LITE) + { + q_ptr->timeout = k_info[q_ptr->k_idx].pval2; + } } } @@ -1411,7 +1366,7 @@ static void store_create(void) if (q_ptr->tval == TV_CHEST) continue; /* Prune the black market */ - if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) + if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM) { /* Hack -- No "crappy" items */ if (black_market_crap(q_ptr)) continue; @@ -1438,7 +1393,7 @@ static void store_create(void) } /* Attempt to carry the (known) item */ - (void)store_carry(q_ptr); + store_carry(q_ptr); /* Definitely done */ break; @@ -1452,28 +1407,21 @@ static void store_create(void) */ static void display_entry(int pos) { - int i, cur_col; - object_type *o_ptr; - s32b x; - - char o_name[80]; - char out_val[160]; - - - int maxwid = 75; + auto const &st_info = game->edit_data.st_info; /* Get the item */ - o_ptr = &st_ptr->stock[pos]; + auto o_ptr = &st_ptr->stock[pos]; /* Get the "offset" */ - i = (pos % 12); + auto const i = (pos % 12); /* Label it, clear the line --(-- */ + char out_val[160]; strnfmt(out_val, 160, "%c) ", I2A(i)); c_prt(get_item_letter_color(o_ptr), out_val, i + 6, 0); - cur_col = 3; + int cur_col = 3; { byte a = object_attr(o_ptr); char c = object_char(o_ptr); @@ -1486,14 +1434,15 @@ static void display_entry(int pos) /* Describe an item in the home */ if ((cur_store_num == 7) || - (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM)) + (st_info[st_ptr->st_idx].flags & STF_MUSEUM)) { - maxwid = 75; + int maxwid = 75; /* Leave room for weights */ maxwid -= 10; /* Describe the object */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 3); o_name[maxwid] = '\0'; c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col); @@ -1513,12 +1462,13 @@ static void display_entry(int pos) byte color = TERM_WHITE; /* Must leave room for the "price" */ - maxwid = 65; + int maxwid = 65; /* Leave room for weights */ maxwid -= 7; /* Describe the object (fully) */ + char o_name[80]; object_desc_store(o_name, o_ptr, TRUE, 3); o_name[maxwid] = '\0'; c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col); @@ -1532,7 +1482,7 @@ static void display_entry(int pos) } /* Extract the "minimum" price */ - x = price_item(o_ptr, ot_ptr->inflation, FALSE); + auto const x = price_item(o_ptr, ot_ptr->inflation, FALSE); /* Can we buy one ? */ if (x > p_ptr->au) color = TERM_L_DARK; @@ -1548,28 +1498,31 @@ static void display_entry(int pos) * Displays a store's inventory -RAK- * All prices are listed as "per individual object". -BEN- */ -static void display_inventory(void) +static void display_inventory() { - int i, k; + int k; /* Display the next 12 items */ for (k = 0; k < 12; k++) { /* Do not display "dead" items */ - if (store_top + k >= st_ptr->stock_num) break; + if (store_top + k >= static_cast<int>(st_ptr->stock.size())) + { + break; + } /* Display that line */ display_entry(store_top + k); } /* Erase the extra lines and the "more" prompt */ - for (i = k; i < 13; i++) prt("", i + 6, 0); + for (int i = k; i < 13; i++) prt("", i + 6, 0); /* Assume "no current page" */ put_str(" ", 5, 20); /* Visual reminder of "more items" */ - if (st_ptr->stock_num > 12) + if (st_ptr->stock.size() > 12) { /* Show "more" reminder (after the last item) */ prt("-more-", k + 6, 3); @@ -1583,7 +1536,7 @@ static void display_inventory(void) /* * Displays players gold -RAK- */ -void store_prt_gold(void) +void store_prt_gold() { char out_val[64]; @@ -1597,8 +1550,10 @@ void store_prt_gold(void) /* * Displays store (after clearing screen) -RAK- */ -void display_store(void) +void display_store() { + auto const &st_info = game->edit_data.st_info; + char buf[80]; @@ -1617,11 +1572,10 @@ void display_store(void) put_str("Weight", 5, 70); } - else if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) + else if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) { /* Show the name of the store */ - strnfmt(buf, 80, "%s", st_info[cur_store_num].name); - prt(buf, 3, 30); + prt(st_info[cur_store_num].name, 3, 30); /* Label the item descriptions */ put_str("Item Description", 5, 3); @@ -1634,14 +1588,11 @@ void display_store(void) else { /* Put the owner name and race */ - strnfmt(buf, 80, "%s", ot_ptr->name); + strnfmt(buf, 80, "%s", ot_ptr->name.c_str()); put_str(buf, 3, 10); /* Show the max price in the store (above prices) */ - strnfmt(buf, 80, "%s (" FMTs16b ")", - st_info[cur_store_num].name, - ot_ptr->max_cost); - prt(buf, 3, 50); + prt(fmt::format("{:s} ({:d})", st_info[cur_store_num].name, ot_ptr->max_cost), 3, 50); /* Label the item descriptions */ put_str("Item Description", 5, 3); @@ -1761,7 +1712,7 @@ static bool_ prompt_yesno(cptr prompt) } /* Any other key must be in the allowed set to break the loop. */ - if ((strchr(allowed, key) != NULL) || quick_messages) { + if ((strchr(allowed, key) != NULL) || options->quick_messages) { /* Check for presence in the 'yes' set */ ret = (strchr(yes, key) != NULL); break; @@ -1879,43 +1830,55 @@ static bool_ sell_haggle(object_type *o_ptr, s32b *price) /* * Will the owner retire? */ -static bool_ retire_owner_p(void) +static bool retire_owner_p() { - store_info_type *sti_ptr = &st_info[town_info[p_ptr->town_num].store[cur_store_num].st_idx]; + auto const &st_info = game->edit_data.st_info; - if ((sti_ptr->owners[0] == sti_ptr->owners[1]) && - (sti_ptr->owners[0] == sti_ptr->owners[2]) && - (sti_ptr->owners[0] == sti_ptr->owners[3])) + auto sti_ptr = &st_info[town_info[p_ptr->town_num].store[cur_store_num].st_idx]; + + if (sti_ptr->owners.size() > 1) { - /* there is no other owner */ - return FALSE; + return false; // No other possible owner } if (rand_int(STORE_SHUFFLE) != 0) { - return FALSE; + return false; } - return TRUE; + return true; } /* - * Stole an item from a store -DG- + * Adjust store_top to account for a removed item */ -void store_stole(void) +static void adjust_store_top_item_removed() { - int i, amt; - int item, item_new; - - object_type forge; - object_type *j_ptr; + /* Nothing left? */ + if (st_ptr->stock.empty() == 0) + { + store_top = 0; + } - object_type *o_ptr; + /* Already at the top beginning? */ + else if (store_top == 0) + { + /* Nothing to do */ + } - char o_name[80]; + /* Nothing left on current screen? */ + else if (store_top >= static_cast<int>(st_ptr->stock.size())) + { + store_top -= 12; + } +} - char out_val[160]; +/* + * Stole an item from a store -DG- + */ +void store_stole() +{ if (cur_store_num == 7) { msg_print("You can't steal from your home!"); @@ -1923,7 +1886,7 @@ void store_stole(void) } /* Empty? */ - if (st_ptr->stock_num <= 0) + if (st_ptr->stock.empty()) { msg_print("There is no item to steal."); return; @@ -1931,30 +1894,31 @@ void store_stole(void) /* Find the number of objects on this and following pages */ - i = (st_ptr->stock_num - store_top); + int i = (st_ptr->stock.size() - store_top); /* And then restrict it to the current page */ if (i > 12) i = 12; /* Prompt */ + char out_val[160]; strnfmt(out_val, 160, "Which item do you want to steal? "); /* Get the item number to be bought */ + int item; if (!get_stock(&item, out_val, 0, i - 1)) return; /* Get the actual index */ item = item + store_top; /* Get the actual item */ - o_ptr = &st_ptr->stock[item]; + object_type *o_ptr = &st_ptr->stock[item]; /* Assume the player wants just one of them */ - amt = 1; - - /* Get local object */ - j_ptr = &forge; + int amt = 1; /* Get a copy of the object */ + object_type forge; + object_type *j_ptr = &forge; object_copy(j_ptr, o_ptr); /* Modify quantity */ @@ -2018,16 +1982,17 @@ void store_stole(void) } /* Describe the transaction */ + char o_name[80]; object_desc(o_name, j_ptr, TRUE, 3); /* Message */ msg_format("You steal %s.", o_name); /* Erase the inscription */ - j_ptr->note = 0; + j_ptr->inscription.clear(); /* Give it to the player */ - item_new = inven_carry(j_ptr, FALSE); + int const item_new = inven_carry(j_ptr, FALSE); /* Describe the final result */ object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3); @@ -2040,14 +2005,14 @@ void store_stole(void) handle_stuff(); /* Note how many slots the store used to have */ - i = st_ptr->stock_num; + auto prev_stock_size = st_ptr->stock.size(); /* Remove the bought items from the store */ store_item_increase(item, -amt); store_item_optimize(item); /* Store is empty */ - if (st_ptr->stock_num == 0) + if (st_ptr->stock.empty()) { /* Shuffle */ if (retire_owner_p()) @@ -2067,7 +2032,7 @@ void store_stole(void) } /* New inventory */ - for (i = 0; i < 10; i++) + for (int k = 0; k < 10; k++) { /* Maintain the store */ store_maint(p_ptr->town_num, cur_store_num); @@ -2081,10 +2046,9 @@ void store_stole(void) } /* The item is gone */ - else if (st_ptr->stock_num != i) + else if (st_ptr->stock.size() != prev_stock_size) { - /* Pick the correct screen */ - if (store_top >= st_ptr->stock_num) store_top -= 12; + adjust_store_top_item_removed(); /* Redraw everything */ display_inventory(); @@ -2113,31 +2077,19 @@ void store_stole(void) /* * Buy an item from a store -RAK- */ -void store_purchase(void) +void store_purchase() { - int i, amt = 1, choice; - int item, item_new; - - s32b price, best; - - object_type forge; - object_type *j_ptr; - - object_type *o_ptr; - - char o_name[80]; - - char out_val[160]; + auto const &st_info = game->edit_data.st_info; /* Museum? */ - if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) + if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) { msg_print("You cannot take items from the museum!"); return; } /* Empty? */ - if (st_ptr->stock_num <= 0) + if (st_ptr->stock.empty()) { if (cur_store_num == 7) msg_print("Your home is empty."); else msg_print("I am currently out of stock."); @@ -2146,12 +2098,13 @@ void store_purchase(void) /* Find the number of objects on this and following pages */ - i = (st_ptr->stock_num - store_top); + int i = (st_ptr->stock.size() - store_top); /* And then restrict it to the current page */ if (i > 12) i = 12; /* Prompt */ + char out_val[160]; if (cur_store_num == 7) { strnfmt(out_val, 160, "Which item do you want to take? "); @@ -2162,18 +2115,18 @@ void store_purchase(void) } /* Get the item number to be bought */ + int item; if (!get_stock(&item, out_val, 0, i - 1)) return; /* Get the actual index */ item = item + store_top; /* Get the actual item */ - o_ptr = &st_ptr->stock[item]; - - /* Get local object */ - j_ptr = &forge; + auto o_ptr = &st_ptr->stock[item]; /* Get a copy of one object to determine the price */ + object_type forge; + auto j_ptr = &forge; object_copy(j_ptr, o_ptr); /* Modify quantity */ @@ -2193,9 +2146,10 @@ void store_purchase(void) } /* Determine the "best" price (per item) */ - best = price_item(j_ptr, ot_ptr->inflation, FALSE); + auto const best = price_item(j_ptr, ot_ptr->inflation, FALSE); /* Find out how many the player wants */ + int amt = 1; if (o_ptr->number > 1) { s32b q; @@ -2231,10 +2185,8 @@ void store_purchase(void) if (amt <= 0) return; } - /* Get local object */ - j_ptr = &forge; - /* Get desired object */ + j_ptr = &forge; object_copy(j_ptr, o_ptr); /* Modify quantity */ @@ -2259,14 +2211,15 @@ void store_purchase(void) if (cur_store_num != 7) { /* Haggle for a final price */ - choice = purchase_haggle(j_ptr, &price); + s32b price; + auto const choice = purchase_haggle(j_ptr, &price); /* Hack -- Got kicked out */ if (st_ptr->store_open >= turn) return; /* Player wants it */ - if (choice == 0) + if (!choice) { /* Player can afford it */ if (p_ptr->au >= price) @@ -2274,9 +2227,6 @@ void store_purchase(void) /* Say "okay" */ say_comment_1(); - /* Make a sound */ - sound(SOUND_BUY); - /* Spend the money */ p_ptr->au -= price; @@ -2291,13 +2241,14 @@ void store_purchase(void) j_ptr->found_aux1 = st_ptr->st_idx; /* Describe the transaction */ + char o_name[80]; object_desc(o_name, j_ptr, TRUE, 3); /* Message */ msg_format("You bought %s for " FMTs32b " gold.", o_name, price); /* Erase the inscription */ - j_ptr->note = 0; + j_ptr->inscription.clear(); /* Hack -- If a rod or wand, allocate total maximum * timeouts or charges between those picked up and @@ -2310,7 +2261,7 @@ void store_purchase(void) } /* Give it to the player */ - item_new = inven_carry(j_ptr, FALSE); + int const item_new = inven_carry(j_ptr, FALSE); /* Describe the final result */ object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3); @@ -2323,14 +2274,14 @@ void store_purchase(void) handle_stuff(); /* Note how many slots the store used to have */ - i = st_ptr->stock_num; + auto prev_stock_size = st_ptr->stock.size(); /* Remove the bought items from the store */ store_item_increase(item, -amt); store_item_optimize(item); /* Store is empty */ - if (st_ptr->stock_num == 0) + if (st_ptr->stock.empty()) { /* Shuffle */ if (retire_owner_p()) @@ -2350,7 +2301,7 @@ void store_purchase(void) } /* New inventory */ - for (i = 0; i < 10; i++) + for (int k = 0; k < 10; k++) { /* Maintain the store */ store_maint(p_ptr->town_num, cur_store_num); @@ -2361,10 +2312,9 @@ void store_purchase(void) } /* The item is gone */ - else if (st_ptr->stock_num != i) + else if (st_ptr->stock.size() != prev_stock_size) { - /* Pick the correct screen */ - if (store_top >= st_ptr->stock_num) store_top -= 12; + adjust_store_top_item_removed(); } /* Redraw everything */ @@ -2394,9 +2344,10 @@ void store_purchase(void) } /* Give it to the player */ - item_new = inven_carry(j_ptr, FALSE); + int const item_new = inven_carry(j_ptr, FALSE); /* Describe just the result */ + char o_name[80]; object_desc(o_name, &p_ptr->inventory[item_new], TRUE, 3); /* Message */ @@ -2406,14 +2357,14 @@ void store_purchase(void) handle_stuff(); /* Take note if we take the last one */ - i = st_ptr->stock_num; + std::size_t prev_stock_size = st_ptr->stock.size(); /* Remove the items from the home */ store_item_increase(item, -amt); store_item_optimize(item); /* Hack -- Item is still here */ - if (i == st_ptr->stock_num) + if (prev_stock_size == st_ptr->stock.size()) { /* Redraw the item */ display_entry(item); @@ -2422,11 +2373,7 @@ void store_purchase(void) /* The item is gone */ else { - /* Nothing left */ - if (st_ptr->stock_num == 0) store_top = 0; - - /* Nothing left on that screen */ - else if (store_top >= st_ptr->stock_num) store_top -= 12; + adjust_store_top_item_removed(); /* Redraw everything */ display_inventory(); @@ -2441,8 +2388,10 @@ void store_purchase(void) /* * Sell an item to the store (or home) */ -void store_sell(void) +void store_sell() { + auto const &st_info = game->edit_data.st_info; + int choice; int item, item_pos; int amt; @@ -2452,13 +2401,9 @@ void store_sell(void) object_type forge; object_type *q_ptr; - object_type *o_ptr; - char o_name[80]; - u32b f1, f2, f3, f4, f5, esp; - - bool_ museum = (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) ? TRUE : FALSE; + bool museum = bool(st_info[st_ptr->st_idx].flags & STF_MUSEUM); /* Prepare prompt */ cptr q, s; @@ -2485,9 +2430,9 @@ void store_sell(void) } /* Get the item */ - o_ptr = get_object(item); + auto o_ptr = get_object(item); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Hack -- Cannot remove cursed items */ if (cursed_p(o_ptr)) @@ -2502,7 +2447,7 @@ void store_sell(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."); @@ -2550,7 +2495,7 @@ void store_sell(void) /* Remove any inscription for stores */ if ((cur_store_num != 7) && !museum) { - q_ptr->note = 0; + q_ptr->inscription.clear(); } /* Is there room in the store (or the home?) */ @@ -2578,9 +2523,6 @@ void store_sell(void) /* Say "okay" */ say_comment_1(); - /* Make a sound */ - sound(SOUND_SELL); - /* Get some money */ p_ptr->au += price; @@ -2747,45 +2689,38 @@ void store_sell(void) /* * Examine an item in a store -JDL- */ -void store_examine(void) +void store_examine() { - int i; - int item; - - object_type *o_ptr; - - char o_name[80]; - - char out_val[160]; - + auto const &st_info = game->edit_data.st_info; /* Empty? */ - if (st_ptr->stock_num <= 0) + if (st_ptr->stock.empty()) { if (cur_store_num == 7) msg_print("Your home is empty."); - else if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) msg_print("The museum is empty."); + else if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) msg_print("The museum is empty."); else msg_print("I am currently out of stock."); return; } /* Find the number of objects on this and following pages */ - i = (st_ptr->stock_num - store_top); + int i = (st_ptr->stock.size() - store_top); /* And then restrict it to the current page */ - if (i > 12) i = 12; - - /* Prompt */ - strnfmt(out_val, 160, "Which item do you want to examine? "); + if (i > 12) + { + i = 12; + } /* Get the item number to be examined */ - if (!get_stock(&item, out_val, 0, i - 1)) return; + int item; + if (!get_stock(&item, "Which item do you want to examine? ", 0, i - 1)) return; /* Get the actual index */ item = item + store_top; /* Get the actual item */ - o_ptr = &st_ptr->stock[item]; + auto o_ptr = &st_ptr->stock[item]; /* Debug hack */ if (wizard) @@ -2802,6 +2737,7 @@ void store_examine(void) } /* Description */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 3); /* Describe */ @@ -2834,6 +2770,34 @@ static bool_ leave_store = FALSE; /* + * Find building action for command. Returns nullptr if no matching + * action is found. + */ +static store_action_type const *find_store_action(s16b command_cmd) +{ + auto const &st_info = game->edit_data.st_info; + auto const &ba_info = game->edit_data.ba_info; + + for (std::size_t i = 0; i < st_info[st_ptr->st_idx].actions.size(); i++) + { + auto ba_ptr = &ba_info[st_info[st_ptr->st_idx].actions[i]]; + + if (ba_ptr->letter && (ba_ptr->letter == command_cmd)) + { + return ba_ptr; + } + + if (ba_ptr->letter_aux && (ba_ptr->letter_aux == command_cmd)) + { + return ba_ptr; + } + } + + return nullptr; +} + + +/* * Process a command in a store * * Note that we must allow the use of a few "special" commands @@ -2841,41 +2805,18 @@ static bool_ leave_store = FALSE; * must disable some commands which are allowed in the dungeon * but not in the stores, to prevent chaos. */ -static bool_ store_process_command(void) +static bool_ store_process_command() { - bool_ validcmd = FALSE; - int i; - store_action_type *ba_ptr; bool_ recreate = FALSE; /* Handle repeating the last command */ repeat_check(); - for (i = 0; i < 6; i++) - { - ba_ptr = &ba_info[st_info[st_ptr->st_idx].actions[i]]; + auto ba_ptr = find_store_action(command_cmd); - if (ba_ptr->letter) - { - if (ba_ptr->letter == command_cmd) - { - validcmd = TRUE; - break; - } - } - if (ba_ptr->letter_aux) - { - if (ba_ptr->letter_aux == command_cmd) - { - validcmd = TRUE; - break; - } - } - } - - if (validcmd) + if (ba_ptr) { - recreate = bldg_process_command(st_ptr, i); + recreate = bldg_process_command(st_ptr, ba_ptr); } else { @@ -2892,14 +2833,17 @@ static bool_ store_process_command(void) /* Browse */ case ' ': { - if (st_ptr->stock_num <= 12) + if (st_ptr->stock.size() <= 12) { msg_print("Entire inventory is shown."); } else { store_top += 12; - if (store_top >= st_ptr->stock_num) store_top = 0; + if (store_top >= static_cast<int>(st_ptr->stock.size())) + { + store_top = 0; + } display_inventory(); } break; @@ -2908,7 +2852,7 @@ static bool_ store_process_command(void) /* Browse backwards */ case '-': { - if (st_ptr->stock_num <= 12) + if (st_ptr->stock.size() <= 12) { msg_print("Entire inventory is shown."); } @@ -2917,7 +2861,7 @@ static bool_ store_process_command(void) store_top -= 12; if (store_top < 0) { - store_top = ((st_ptr->stock_num - 1) / 12) * 12; + store_top = ((st_ptr->stock.size() - 1) / 12) * 12; } display_inventory(); } @@ -3169,8 +3113,12 @@ static bool_ store_process_command(void) * into other commands, normally, we convert "p" (pray) and "m" * (cast magic) into "g" (get), and "s" (search) into "d" (drop). */ -void do_cmd_store(void) +void do_cmd_store() { + auto const &ow_info = game->edit_data.ow_info; + auto const &ba_info = game->edit_data.ba_info; + auto const &st_info = game->edit_data.st_info; + int which; int maintain_num; int tmp_chr; @@ -3252,13 +3200,11 @@ void do_cmd_store(void) display_store(); /* Mega-Hack -- Ignore keymaps on store action letters */ - for (i = 0; i < 6; i++) + for (std::size_t i = 0; i < st_info[st_ptr->st_idx].actions.size(); i++) { - store_action_type *ba_ptr = - &ba_info[st_info[st_ptr->st_idx].actions[i]]; + auto ba_ptr = &ba_info[st_info[st_ptr->st_idx].actions[i]]; request_command_ignore_keymaps[2*i] = ba_ptr->letter; request_command_ignore_keymaps[2*i+1] = ba_ptr->letter_aux; - } /* Do not leave */ @@ -3282,7 +3228,7 @@ void do_cmd_store(void) prt(") Exit.", 22, 4); /* Browse if necessary */ - if (st_ptr->stock_num > 12) + if (st_ptr->stock.size() > 12) { c_prt(TERM_YELLOW, " SPACE", 23, 0); prt(") Next page", 23, 6); @@ -3439,14 +3385,14 @@ void do_cmd_store(void) */ void store_shuffle(int which) { - int i, j; - + auto const &ow_info = game->edit_data.ow_info; + auto const &st_info = game->edit_data.st_info; /* Ignore home */ if (which == STORE_HOME) return; /* Ignoer Museum */ - if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) return; + if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) return; /* Save the store index */ @@ -3456,9 +3402,9 @@ void store_shuffle(int which) st_ptr = &town_info[p_ptr->town_num].store[cur_store_num]; /* Pick a new owner */ - for (j = st_ptr->owner; j == st_ptr->owner; ) + for (auto j = st_ptr->owner; j == st_ptr->owner; ) { - st_ptr->owner = st_info[st_ptr->st_idx].owners[rand_int(4)]; + st_ptr->owner = *uniform_element(st_info[st_ptr->st_idx].owners); } /* Activate the new owner */ @@ -3470,19 +3416,16 @@ void store_shuffle(int which) /* Hack -- discount all the items */ - for (i = 0; i < st_ptr->stock_num; i++) + for (auto &o_ref: st_ptr->stock) { - object_type *o_ptr; - - /* Get the item */ - o_ptr = &st_ptr->stock[i]; + auto o_ptr = &o_ref; /* Hack -- Sell all old items for "half price" */ - if (!(o_ptr->art_name)) + if (o_ptr->artifact_name.empty()) o_ptr->discount = 50; /* Mega-Hack -- Note that the item is "on sale" */ - o_ptr->note = quark_add("on sale"); + o_ptr->inscription = "on sale"; } } @@ -3492,9 +3435,10 @@ void store_shuffle(int which) */ void store_maint(int town_num, int store_num) { - int j, tries = 100; + auto const &ow_info = game->edit_data.ow_info; + auto const &st_info = game->edit_data.st_info; - int old_rating = rating; + int const old_rating = rating; cur_store_num = store_num; @@ -3505,16 +3449,16 @@ void store_maint(int town_num, int store_num) st_ptr = &town_info[town_num].store[store_num]; /* Ignoer Museum */ - if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) return; + if (st_info[st_ptr->st_idx].flags & STF_MUSEUM) return; /* Activate the owner */ ot_ptr = &ow_info[st_ptr->owner]; /* Mega-Hack -- prune the black market */ - if (st_info[st_ptr->st_idx].flags1 & SF1_ALL_ITEM) + if (st_info[st_ptr->st_idx].flags & STF_ALL_ITEM) { /* Destroy crappy black market items */ - for (j = st_ptr->stock_num - 1; j >= 0; j--) + for (int j = st_ptr->stock.size() - 1; j >= 0; j--) { object_type *o_ptr = &st_ptr->stock[j]; @@ -3530,7 +3474,7 @@ void store_maint(int town_num, int store_num) /* Choose the number of slots to keep */ - j = st_ptr->stock_num; + int j = st_ptr->stock.size(); /* Sell a few items */ j = j - randint(STORE_TURNOVER); @@ -3545,11 +3489,13 @@ void store_maint(int town_num, int store_num) if (j < 0) j = 0; /* Destroy objects until only "j" slots are left */ - while (st_ptr->stock_num > j) store_delete(); - + while (j < static_cast<int>(st_ptr->stock.size())) + { + store_delete(); + } /* Choose the number of slots to fill */ - j = st_ptr->stock_num; + j = st_ptr->stock.size(); /* Buy some more items */ j = j + randint(STORE_TURNOVER); @@ -3561,13 +3507,15 @@ void store_maint(int town_num, int store_num) if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP; /* Hack -- prevent "overflow" */ - if (j >= st_ptr->stock_size) j = st_ptr->stock_size - 1; + if (j >= st_ptr->stock_size) + { + j = st_ptr->stock_size - 1; + } /* Acquire some new items */ - while ((st_ptr->stock_num < j) && tries) + for (int tries = 0; (tries < 100) && (static_cast<int>(st_ptr->stock.size()) < j); tries++) { store_create(); - tries--; } /* Hack -- Restore the rating */ @@ -3580,38 +3528,34 @@ void store_maint(int town_num, int store_num) */ void store_init(int town_num, int store_num) { - int k; + auto const &ow_info = game->edit_data.ow_info; + auto const &st_info = game->edit_data.st_info; cur_store_num = store_num; - /* Activate that store */ + // Activate store st_ptr = &town_info[town_num].store[store_num]; + // Pick an owner. We use 0 for st_info[] which haven't been + // initialized, i.e. where there's no entry in st_info.txt. + st_ptr->owner = st_info[st_ptr->st_idx].owners.empty() + ? 0 + : *uniform_element(st_info[st_ptr->st_idx].owners) + ; - /* Pick an owner */ - st_ptr->owner = st_info[st_ptr->st_idx].owners[rand_int(4)]; - - /* Activate the new owner */ + // Activate the new owner ot_ptr = &ow_info[st_ptr->owner]; - - /* Initialize the store */ + // Initialize the store st_ptr->store_open = 0; - /* Nothing in stock */ - st_ptr->stock_num = 0; + // Nothing in stock + st_ptr->stock.reserve(st_ptr->stock_size); + st_ptr->stock.clear(); - /* - * MEGA-HACK - Last visit to store is - * BEFORE player birth to enable store restocking - */ + // MEGA-HACK - Last visit to store is BEFORE player + // birth to enable store restocking. st_ptr->last_visit = -100L * STORE_TURNS; - - /* Clear any old items */ - for (k = 0; k < st_ptr->stock_size; k++) - { - object_wipe(&st_ptr->stock[k]); - } } @@ -3625,12 +3569,15 @@ void store_init(int town_num, int store_num) * into other commands, normally, we convert "p" (pray) and "m" * (cast magic) into "g" (get), and "s" (search) into "d" (drop). */ -void do_cmd_home_trump(void) +void do_cmd_home_trump() { + auto const &ow_info = game->edit_data.ow_info; + auto const &ba_info = game->edit_data.ba_info; + auto const &st_info = game->edit_data.st_info; + int which; int maintain_num; int tmp_chr; - int i; int town_num; /* Extract the store code */ @@ -3655,8 +3602,10 @@ void do_cmd_home_trump(void) if (maintain_num) { /* Maintain the store */ - for (i = 0; i < maintain_num; i++) + for (int i = 0; i < maintain_num; i++) + { store_maint(town_num, which); + } /* Save the visit */ town_info[town_num].store[which].last_visit = turn; @@ -3698,10 +3647,10 @@ void do_cmd_home_trump(void) display_store(); /* Mega-Hack -- Ignore keymaps on store action letters */ - for (i = 0; i < 6; i++) + auto const &st_actions = st_info[st_ptr->st_idx].actions; + for (std::size_t i = 0; (i < (MAX_IGNORE_KEYMAPS/2)) && (i < st_actions.size()); i++) { - store_action_type *ba_ptr = - &ba_info[st_info[st_ptr->st_idx].actions[i]]; + auto ba_ptr = &ba_info[st_actions[i]]; request_command_ignore_keymaps[2*i] = ba_ptr->letter; request_command_ignore_keymaps[2*i+1] = ba_ptr->letter_aux; } @@ -3726,7 +3675,7 @@ void do_cmd_home_trump(void) prt(" ESC) Exit from Building.", 22, 0); /* Browse if necessary */ - if (st_ptr->stock_num > 12) + if (st_ptr->stock.size() > 12) { prt(" SPACE) Next page of stock", 23, 0); } diff --git a/src/store.hpp b/src/store.hpp index f67d94eb..0f189167 100644 --- a/src/store.hpp +++ b/src/store.hpp @@ -1,12 +1,12 @@ #pragma once -extern void do_cmd_store(); -extern void store_shuffle(int which); -extern void store_maint(int town_num, int store_num); -extern void store_init(int town_num, int store_num); -extern void do_cmd_home_trump(); -extern void store_sell(); -extern void store_purchase(); -extern void store_examine(); -extern void store_stole(); -extern void store_prt_gold(); +void do_cmd_store(); +void store_shuffle(int which); +void store_maint(int town_num, int store_num); +void store_init(int town_num, int store_num); +void do_cmd_home_trump(); +void store_sell(); +void store_purchase(); +void store_examine(); +void store_stole(); +void store_prt_gold(); diff --git a/src/store_action_type.hpp b/src/store_action_type.hpp index 048e13a0..ee479375 100644 --- a/src/store_action_type.hpp +++ b/src/store_action_type.hpp @@ -7,11 +7,11 @@ */ struct store_action_type { - const char *name; /* Name */ + std::string name; /* Name */ - s16b costs[3]; /* Costs for liked people */ - char letter; /* Action letter */ - char letter_aux; /* Action letter */ - s16b action; /* Action code */ - s16b action_restr; /* Action restriction */ + std::array<s16b, 3> costs { }; /* Costs for liked people */ + char letter = '\0'; /* Action letter */ + char letter_aux = '\0'; /* Action letter */ + s16b action = 0; /* Action code */ + s16b action_restr = 0; /* Action restriction */ }; diff --git a/src/store_flag.hpp b/src/store_flag.hpp new file mode 100644 index 00000000..6844bd84 --- /dev/null +++ b/src/store_flag.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "store_flag_set.hpp" +#include <boost/preprocessor/cat.hpp> + +// +// Define flag set for each flag. +// +#define STF(tier, index, name) \ + DECLARE_FLAG(store_flag_set, BOOST_PP_CAT(STF_,name), tier, index) +#include "store_flag_list.hpp" +#undef STF diff --git a/src/store_flag_list.hpp b/src/store_flag_list.hpp new file mode 100644 index 00000000..f8e4b177 --- /dev/null +++ b/src/store_flag_list.hpp @@ -0,0 +1,17 @@ +/** + * X-macro list of all the store flags + */ + +/* STF(<tier>, <index>, <name>) */ + +STF(1, 0, DEPEND_LEVEL ) +STF(1, 1, SHALLOW_LEVEL) +STF(1, 2, MEDIUM_LEVEL ) +STF(1, 3, DEEP_LEVEL ) +STF(1, 4, RARE ) +STF(1, 5, VERY_RARE ) +STF(1, 6, COMMON ) +STF(1, 7, ALL_ITEM ) +STF(1, 8, RANDOM ) +STF(1, 9, FORCE_LEVEL ) +STF(1, 10, MUSEUM ) diff --git a/src/store_flag_set.hpp b/src/store_flag_set.hpp new file mode 100644 index 00000000..0529baed --- /dev/null +++ b/src/store_flag_set.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "flag_set.hpp" + +constexpr std::size_t STF_MAX_TIERS = 1; + +typedef flag_set<STF_MAX_TIERS> store_flag_set; diff --git a/src/store_info_type.hpp b/src/store_info_type.hpp index 030afe91..78aa071e 100644 --- a/src/store_info_type.hpp +++ b/src/store_info_type.hpp @@ -1,32 +1,31 @@ #pragma once #include "h-basic.h" +#include "store_flag_set.hpp" +#include "store_item.hpp" -/** - * Number of items to choose stock from - */ -constexpr int STORE_CHOICES = 56; +#include <vector> /** * Store descriptor. */ struct store_info_type { - const char *name; /* Name */ + std::string name; /* Name */ + + std::vector<store_item> items; /* Table -- Legal item kinds */ - s16b table[STORE_CHOICES][2]; /* Table -- Legal item kinds */ - byte table_num; /* Number of items */ - s16b max_obj; /* Number of items this store can hold */ + s16b max_obj = 0; /* Number of items this store can hold */ - u16b owners[4]; /* List of owners(refers to ow_info) */ + std::vector<u16b> owners; /* List of owners; refers to ow_info */ - u16b actions[6]; /* Actions(refers to ba_info) */ + std::vector<u16b> actions; /* Actions; refers to ba_info */ - byte d_attr; /* Default building attribute */ - char d_char; /* Default building character */ + byte d_attr = 0; /* Default building attribute */ + char d_char = '\0'; /* Default building character */ - byte x_attr; /* Desired building attribute */ - char x_char; /* Desired building character */ + byte x_attr = 0; /* Desired building attribute */ + char x_char = '\0'; /* Desired building character */ - u32b flags1; /* Flags */ + store_flag_set flags; /* Flags */ }; diff --git a/src/store_info_type_fwd.hpp b/src/store_info_type_fwd.hpp deleted file mode 100644 index a0dace90..00000000 --- a/src/store_info_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct store_info_type; diff --git a/src/store_item.hpp b/src/store_item.hpp new file mode 100644 index 00000000..62d3f2a9 --- /dev/null +++ b/src/store_item.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "h-basic.h" + +struct store_item +{ + /** + * Legal item kinds; if > 10000, designates (TVAL - 10000) and any SVAL. + * Otherwise designates an entry in k_info.txt. + */ + s16b kind = 0; + + /** + * Percentage chance of generation if the entry is chosen. + */ + s16b chance = 0; + +}; diff --git a/src/store_type.hpp b/src/store_type.hpp index e3f917ac..5fb4ac7f 100644 --- a/src/store_type.hpp +++ b/src/store_type.hpp @@ -1,7 +1,9 @@ #pragma once #include "h-basic.h" -#include "object_type.hpp" +#include "object_type_fwd.hpp" + +#include <vector> /** * A store, with an owner, various state flags, a current stock @@ -9,35 +11,30 @@ */ struct store_type { - u16b st_idx; + u16b st_idx = 0; /** * Owner index */ - u16b owner; + u16b owner = 0; /** * Closed until this turn. */ - s32b store_open; + s32b store_open = 0; /** * Last visited on this turn. */ - s32b last_visit; - - /** - * Stock: Number of entries. - */ - byte stock_num; + s32b last_visit = 0; /** * Stock: Total size of array */ - s16b stock_size; + u16b stock_size = 0; /** * Stock: Actual stock items */ - object_type *stock; + std::vector<object_type> stock; }; diff --git a/src/tables.cc b/src/tables.cc index 09e6c18c..1caa4bcf 100644 --- a/src/tables.cc +++ b/src/tables.cc @@ -10,6 +10,9 @@ #include "tables.h" #include "modules.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" +#include "object_flag.hpp" #include "options.hpp" #include "q_library.hpp" #include "q_fireprof.hpp" @@ -311,98 +314,6 @@ byte adj_wis_sav[] = /* - * Stat Table (DEX) -- disarming - */ -byte adj_dex_dis[] = -{ - 0 /* 3 */, - 0 /* 4 */, - 0 /* 5 */, - 0 /* 6 */, - 0 /* 7 */, - 0 /* 8 */, - 0 /* 9 */, - 0 /* 10 */, - 0 /* 11 */, - 0 /* 12 */, - 1 /* 13 */, - 1 /* 14 */, - 1 /* 15 */, - 2 /* 16 */, - 2 /* 17 */, - 4 /* 18/00-18/09 */, - 4 /* 18/10-18/19 */, - 4 /* 18/20-18/29 */, - 4 /* 18/30-18/39 */, - 5 /* 18/40-18/49 */, - 5 /* 18/50-18/59 */, - 5 /* 18/60-18/69 */, - 6 /* 18/70-18/79 */, - 6 /* 18/80-18/89 */, - 7 /* 18/90-18/99 */, - 8 /* 18/100-18/109 */, - 8 /* 18/110-18/119 */, - 8 /* 18/120-18/129 */, - 8 /* 18/130-18/139 */, - 8 /* 18/140-18/149 */, - 9 /* 18/150-18/159 */, - 9 /* 18/160-18/169 */, - 9 /* 18/170-18/179 */, - 9 /* 18/180-18/189 */, - 9 /* 18/190-18/199 */, - 10 /* 18/200-18/209 */, - 10 /* 18/210-18/219 */, - 10 /* 18/220+ */ -}; - - -/* - * Stat Table (INT) -- disarming - */ -byte adj_int_dis[] = -{ - 0 /* 3 */, - 0 /* 4 */, - 0 /* 5 */, - 0 /* 6 */, - 0 /* 7 */, - 1 /* 8 */, - 1 /* 9 */, - 1 /* 10 */, - 1 /* 11 */, - 1 /* 12 */, - 1 /* 13 */, - 1 /* 14 */, - 2 /* 15 */, - 2 /* 16 */, - 2 /* 17 */, - 3 /* 18/00-18/09 */, - 3 /* 18/10-18/19 */, - 3 /* 18/20-18/29 */, - 4 /* 18/30-18/39 */, - 4 /* 18/40-18/49 */, - 5 /* 18/50-18/59 */, - 6 /* 18/60-18/69 */, - 7 /* 18/70-18/79 */, - 8 /* 18/80-18/89 */, - 9 /* 18/90-18/99 */, - 10 /* 18/100-18/109 */, - 10 /* 18/110-18/119 */, - 11 /* 18/120-18/129 */, - 12 /* 18/130-18/139 */, - 13 /* 18/140-18/149 */, - 14 /* 18/150-18/159 */, - 15 /* 18/160-18/169 */, - 16 /* 18/170-18/179 */, - 17 /* 18/180-18/189 */, - 18 /* 18/190-18/199 */, - 19 /* 18/200-18/209 */, - 19 /* 18/210-18/219 */, - 20 /* 18/220+ */ -}; - - -/* * Stat Table (DEX) -- bonus to ac (plus 128) */ byte adj_dex_ta[] = @@ -1144,29 +1055,6 @@ s32b player_exp[PY_MAX_LEVEL] = /* - * Player Sexes - * - * Title, - * Winner - */ -player_sex sex_info[MAX_SEXES] = -{ - { - "Female", - "Queen" - }, - -{ -"Male", -"King" -}, -{ -"Neuter", -"Ruler" -} -}; - -/* * Hack -- the "basic" color names (see "TERM_xxx") */ cptr color_names[16] = @@ -1258,230 +1146,6 @@ cptr window_flag_desc[32] = }; -/* - * Available Options - * - * Option Screen Sets: - * - * Set 1: User Interface - * Set 2: Disturbance - * Set 3: Inventory - * Set 4: Game Play - * Set 5: ToME - * Set 6: Birth - * - * Note that bits 28-31 of set 0 are currently unused. - */ -option_type option_info[] = -{ - /*** User-Interface ***/ - - { &rogue_like_commands, FALSE, 1, 0, - "rogue_like_commands", "Rogue-like commands" }, - - { &quick_messages, TRUE, 1, 1, - "quick_messages", "Activate quick messages" }, - - { &carry_query_flag, FALSE, 1, 3, - "carry_query_flag", "Prompt before picking things up" }, - - { &use_old_target, FALSE, 1, 4, - "use_old_target", "Use old target by default" }, - - { &always_pickup, FALSE, 1, 5, - "always_pickup", "Pick things up by default" }, - - { &always_repeat, TRUE, 1, 7, - "always_repeat", "Repeat obvious commands" }, - - { &ring_bell, FALSE, 1, 18, - "ring_bell", "Audible bell (on errors, etc)" }, - /* Changed to default to FALSE -- it's so extremely annoying!!! -TY */ - - /*** Disturbance ***/ - - { &find_ignore_stairs, FALSE, 2, 0, - "find_ignore_stairs", "Run past stairs" }, - - { &find_ignore_doors, TRUE, 2, 1, - "find_ignore_doors", "Run through open doors" }, - - { &find_cut, FALSE, 2, 2, - "find_cut", "Run past known corners" }, - - { &find_examine, TRUE, 2, 3, - "find_examine", "Run into potential corners" }, - - { &disturb_move, FALSE, 2, 4, - "disturb_move", "Disturb whenever any monster moves" }, - - { &disturb_near, TRUE, 2, 5, - "disturb_near", "Disturb whenever viewable monster moves" }, - - { &disturb_panel, TRUE, 2, 6, - "disturb_panel", "Disturb whenever map panel changes" }, - - { &disturb_detect, TRUE, 2, 21, - "disturb_detect", "Disturb whenever leaving trap-detected area" }, - - { &disturb_state, TRUE, 2, 7, - "disturb_state", "Disturb whenever player state changes" }, - - { &disturb_minor, TRUE, 2, 8, - "disturb_minor", "Disturb whenever boring things happen" }, - - { &disturb_other, FALSE, 2, 9, - "disturb_other", "Disturb whenever random things happen" }, - - { &alert_hitpoint, FALSE, 2, 10, - "alert_hitpoint", "Alert user to critical hitpoints" }, - - { &alert_failure, FALSE, 2, 11, - "alert_failure", "Alert user to various failures" }, - - { &last_words, TRUE, 2, 12, - "last_words", "Get last words when the character dies" }, - - { &wear_confirm, TRUE, 2, 15, - "confirm_wear", "Confirm to wear/wield known cursed items" }, - - { &confirm_stairs, FALSE, 2, 16, - "confirm_stairs", "Prompt before exiting a dungeon level" }, - - { &disturb_pets, FALSE, 2, 17, - "disturb_pets", "Disturb when visible pets move" }, - - /*** Game-Play ***/ - - { &auto_scum, TRUE, 3, 1, - "auto_scum", "Auto-scum for good levels" }, - - { &view_perma_grids, TRUE, 3, 6, - "view_perma_grids", "Map remembers all perma-lit grids" }, - - { &view_torch_grids, FALSE, 3, 7, - "view_torch_grids", "Map remembers all torch-lit grids" }, - - { &dungeon_align, TRUE, 3, 8, - "dungeon_align", "Generate dungeons with aligned rooms" }, - - { &dungeon_stair, TRUE, 3, 9, - "dungeon_stair", "Generate dungeons with connected stairs" }, - - { &flow_by_sound, FALSE, 3, 10, - "flow_by_sound", "Monsters chase current location (v.slow)" }, - - { &smart_learn, FALSE, 3, 14, - "smart_learn", "Monsters learn from their mistakes" }, - - { &small_levels, TRUE, 3, 17, - "small_levels", "Allow unusually small dungeon levels" }, - - { &empty_levels, TRUE, 3, 18, - "empty_levels", "Allow empty 'arena' levels" }, - - /*** Efficiency ***/ - - { &view_reduce_lite, FALSE, 4, 0, - "view_reduce_lite", "Reduce lite-radius when running" }, - - { &avoid_abort, FALSE, 4, 2, - "avoid_abort", "Avoid checking for user abort" }, - - { &avoid_shimmer, FALSE, 4, 17, - "avoid_shimmer", "Avoid extra shimmering (fast)" }, - - { &avoid_other, FALSE, 4, 3, - "avoid_other", "Avoid processing special colors (fast)" }, - - { &flush_failure, TRUE, 4, 4, - "flush_failure", "Flush input on various failures" }, - - { &flush_disturb, FALSE, 4, 5, - "flush_disturb", "Flush input whenever disturbed" }, - - { &flush_command, FALSE, 4, 6, - "flush_command", "Flush input before every command" }, - - { &fresh_before, TRUE, 4, 7, - "fresh_before", "Flush output before every command" }, - - { &fresh_after, FALSE, 4, 8, - "fresh_after", "Flush output after every command" }, - - { &fresh_message, FALSE, 4, 9, - "fresh_message", "Flush output after every message" }, - - { &hilite_player, FALSE, 4, 11, - "hilite_player", "Hilite the player with the cursor" }, - - { &view_yellow_lite, FALSE, 4, 12, - "view_yellow_lite", "Use special colors for torch-lit grids" }, - - { &view_bright_lite, FALSE, 4, 13, - "view_bright_lite", "Use special colors for 'viewable' grids" }, - - { &view_granite_lite, FALSE, 4, 14, - "view_granite_lite", "Use special colors for wall grids (slow)" }, - - { &view_special_lite, FALSE, 4, 15, - "view_special_lite", "Use special colors for floor grids (slow)" }, - - { ¢er_player, FALSE, 4, 16, - "center_player", "Center the view on the player (very slow)" }, - - /*** ToME options ***/ - - { &option_ingame_help, TRUE, 5, 1, - "ingame_help", "Ingame contextual help" }, - - { &auto_more, FALSE, 5, 4, - "auto_more", "Automatically clear '-more-' prompts" }, - - { &player_char_health, TRUE, 5, 6, - "player_char_health", "Player char represent his/her health" }, - - { &linear_stats, TRUE, 5, 7, - "linear_stats", "Stats are represented in a linear way" }, - - { &inventory_no_move, FALSE, 5, 8, - "inventory_no_move", "In option windows, just omit the select char" }, - - - /*** Birth Options ***/ - - { &preserve, TRUE, 6, 2, - "preserve", "Preserve artifacts" }, - - { &autoroll, TRUE, 6, 3, - "autoroll", "Specify 'minimal' stats" }, - - { &point_based, FALSE, 6, 17, - "point_based", "Generate character using a point system" }, - - { &ironman_rooms, FALSE, 6, 6, - "ironman_rooms", "Always generate very unusual rooms" }, - - { &joke_monsters, FALSE, 6, 14, - "joke_monsters", "Allow use of some 'joke' monsters" }, - - { &always_small_level, FALSE, 6, 16, - "always_small_level", "Always make small levels" }, - - { &fate_option, TRUE, 6, 18, - "fate_option", "You can receive fates, good or bad" }, - - { &no_selling, FALSE, 6, 20, - "no_selling", "Items always sell for 0 gold" }, - - /*** End of Table ***/ - - { NULL, 0, 0, 0, - NULL, NULL } -}; - - - /* Names used for random artifact name generation */ cptr artifact_names_list = "adanedhel\n" @@ -2505,16 +2169,16 @@ deity_type deity_info[MAX_GODS] = /* as far as I know. */ tactic_info_type tactic_info[9] = { - /* hit dam ac stl dis sav */ - { -10, -10, + 15, + 3, + 15, + 14, "coward"}, /* 4-4 */ - { -8, -8, + 10, + 2, + 9, + 9, "meek"}, /* 4-3 */ - { -4, -4, + 5, + 1, + 5, + 5, "wary"}, /* 4-2 */ - { -2, -2, + 2, + 1, + 2, + 2, "careful"}, /* 4-1 */ - { 0, 0, 0, 0, 0, 0, "normal"}, /* 4+0 */ - { 2, 2, -2, -1, -2, -3, "confident"}, /* 4+1 */ - { 4, 4, -5, -2, -5, -7, "aggressive"}, /* 4+2 */ - { 6, 6, -10, -3, -11, -12, "furious"}, /* 4+3 */ - { 8, 12, -25, -5, -18, -18, "berserker"} /* 4+4 */ + /* hit dam ac stl sav */ + { -10, -10, +15, +3, +14, "coward" }, + { -8, -8, +10, +2, +9, "meek" }, + { -4, -4, +5, +1, +5, "wary" }, + { -2, -2, +2, +1, +2, "careful" }, + { 0, 0, 0, 0, 0, "normal" }, + { 2, 2, -2, -1, -3, "confident" }, + { 4, 4, -5, -2, -7, "aggressive" }, + { 6, 6, -10, -3, -12, "furious" }, + { 8, 12, -25, -5, -18, "berserker" } }; /* @@ -2597,52 +2261,44 @@ move_info_type move_info[9] = */ inscription_info_type inscription_info[MAX_INSCRIPTIONS] = { - { /* Nothing */ + { /* Padding; 0 index is used to signify "no inscription" */ "", 0, - TRUE, 0, }, { /* Light up the room(Adunaic) */ "ure nimir", /* sun shine */ INSCRIP_EXEC_ENGRAVE | INSCRIP_EXEC_WALK | INSCRIP_EXEC_MONST_WALK, - FALSE, 30, }, { /* Darkness in room(Adunaic) */ "lomi gimli", /* night stars */ INSCRIP_EXEC_ENGRAVE | INSCRIP_EXEC_WALK | INSCRIP_EXEC_MONST_WALK, - FALSE, 10, }, { /* Storm(Adunaic) */ "dulgi bawiba", /* black winds */ INSCRIP_EXEC_ENGRAVE | INSCRIP_EXEC_WALK | INSCRIP_EXEC_MONST_WALK, - FALSE, 40, }, { /* Protection(Sindarin) */ "pedo mellon a minno", /* say friend and enter */ INSCRIP_EXEC_MONST_WALK, - FALSE, 8, }, { /* Dwarves summoning(Khuzdul) */ "Baruk Khazad! Khazad aimenu!", /* Axes of the Dwarves, the Dwarves are upon you! */ INSCRIP_EXEC_ENGRAVE, - FALSE, 100, }, { /* Open Chasm(Nandorin) */ "dunna hrassa", /* black precipice */ INSCRIP_EXEC_MONST_WALK, - FALSE, 50, }, { /* Blast of Black Fire(Orcish) */ "burz ghash ronk", /* black fire pool */ INSCRIP_EXEC_ENGRAVE | INSCRIP_EXEC_WALK | INSCRIP_EXEC_MONST_WALK, - FALSE, 60, }, }; @@ -2676,128 +2332,103 @@ cptr sense_desc[] = * Flags 4, * ESP, */ -flags_group flags_groups[MAX_FLAG_GROUP] = +std::vector<flags_group> const &flags_groups() { - { - "Fire", - TERM_L_RED, - 1, - TR1_SLAY_UNDEAD | TR1_BRAND_FIRE, - TR2_RES_FIRE, - TR3_SH_FIRE | TR3_LITE1 | TR3_IGNORE_FIRE, - 0, - 0, - }, - { - "Cold", - TERM_WHITE, - 1, - TR1_SLAY_DRAGON | TR1_SLAY_DEMON | TR1_BRAND_COLD, - TR2_RES_COLD | TR2_INVIS, - TR3_SLOW_DIGEST | TR3_IGNORE_COLD, - 0, - 0, - }, - { - "Acid", - TERM_GREEN, - 3, - TR1_SLAY_ANIMAL | TR1_IMPACT | TR1_TUNNEL | TR1_BRAND_ACID, - TR2_RES_ACID, - TR3_IGNORE_ACID, - 0, - 0, - }, - { - "Lightning", - TERM_L_BLUE, - 1, - TR1_SLAY_EVIL | TR1_BRAND_ELEC, - TR2_RES_ELEC, - TR3_IGNORE_ELEC | TR3_SH_ELEC | TR3_TELEPORT, - 0, - 0, - }, - { - "Poison", - TERM_L_GREEN, - 2, - TR1_CHR | TR1_VAMPIRIC | TR1_SLAY_ANIMAL | TR1_BRAND_POIS, - TR2_SUST_CHR | TR2_RES_POIS, - TR3_DRAIN_EXP, - 0, - ESP_TROLL | ESP_GIANT, - }, - { - "Air", - TERM_BLUE, - 5, - TR1_WIS | TR1_STEALTH | TR1_INFRA | TR1_SPEED, - TR2_RES_LITE | TR2_RES_DARK | TR2_RES_BLIND | TR2_SUST_WIS, - TR3_FEATHER | TR3_SEE_INVIS | TR3_BLESSED, - 0, - ESP_GOOD, - }, - { - "Earth", - TERM_L_UMBER, - 5, - TR1_STR | TR1_CON | TR1_TUNNEL | TR1_BLOWS | TR1_SLAY_TROLL | TR1_SLAY_GIANT | TR1_IMPACT, - TR2_SUST_STR | TR2_SUST_CON | TR2_FREE_ACT | TR2_RES_FEAR | TR2_RES_SHARDS, - TR3_REGEN, - 0, - ESP_TROLL | ESP_GIANT, - }, - { - "Mind", - TERM_YELLOW, - 7, - TR1_INT | TR1_SEARCH, - TR2_SUST_INT | TR2_RES_CONF | TR2_RES_FEAR, - 0, - 0, - ESP_ORC | ESP_TROLL | ESP_GIANT | ESP_ANIMAL | ESP_UNIQUE | ESP_SPIDER | ESP_DEMON, - }, - { - "Shield", - TERM_RED, - 7, - TR1_DEX, - TR2_SUST_DEX | TR2_INVIS | TR2_REFLECT | TR2_HOLD_LIFE | TR2_RES_SOUND | TR2_RES_NEXUS, - TR3_REGEN, - 0, - 0, - }, - { - "Chaos", - TERM_VIOLET, - 7, - TR1_CHAOTIC | TR1_IMPACT, - TR2_RES_CHAOS | TR2_RES_DISEN, - TR3_REGEN, - 0, - ESP_ALL, - }, - { - "Magic", - TERM_L_BLUE, - 10, - TR1_MANA | TR1_SPELL, - TR2_RES_CHAOS | TR2_RES_DISEN, - TR3_WRAITH, - TR4_PRECOGNITION | TR4_FLY | TR4_CLONE, - 0, - }, - { - "Antimagic", - TERM_L_DARK, - 10, - TR1_VAMPIRIC | TR1_CHAOTIC | TR1_BLOWS | TR1_SPEED, - TR2_LIFE | TR2_REFLECT | TR2_FREE_ACT | TR2_HOLD_LIFE, - TR3_NO_MAGIC | TR3_NO_TELE | TR3_SEE_INVIS, - TR4_ANTIMAGIC_50, - 0, - }, + static auto *instance = new std::vector<flags_group> { + flags_group { + "Fire", + TERM_L_RED, + 1, + TR_SLAY_UNDEAD | TR_BRAND_FIRE | TR_RES_FIRE | + TR_SH_FIRE | TR_LITE1 | TR_IGNORE_FIRE, + }, + flags_group { + "Cold", + TERM_WHITE, + 1, + TR_SLAY_DRAGON | TR_SLAY_DEMON | TR_BRAND_COLD | TR_RES_COLD | + TR_INVIS | TR_SLOW_DIGEST | TR_IGNORE_COLD, + }, + flags_group { + "Acid", + TERM_GREEN, + 3, + TR_SLAY_ANIMAL | TR_IMPACT | TR_TUNNEL | + TR_BRAND_ACID | TR_RES_ACID | TR_IGNORE_ACID, + }, + flags_group { + "Lightning", + TERM_L_BLUE, + 1, + TR_SLAY_EVIL | TR_BRAND_ELEC | TR_RES_ELEC | + TR_IGNORE_ELEC | TR_SH_ELEC | TR_TELEPORT, + }, + flags_group { + "Poison", + TERM_L_GREEN, + 2, + TR_CHR | TR_VAMPIRIC | TR_SLAY_ANIMAL | TR_BRAND_POIS | + TR_SUST_CHR | TR_RES_POIS | TR_DRAIN_EXP | + ESP_TROLL | ESP_GIANT, + }, + flags_group { + "Air", + TERM_BLUE, + 5, + TR_WIS | TR_STEALTH | TR_INFRA | TR_SPEED | + TR_RES_LITE | TR_RES_DARK | TR_RES_BLIND | TR_SUST_WIS | + TR_FEATHER | TR_SEE_INVIS | TR_BLESSED | + ESP_GOOD, + }, + flags_group { + "Earth", + TERM_L_UMBER, + 5, + TR_STR | TR_CON | TR_TUNNEL | TR_BLOWS | TR_SLAY_TROLL | + TR_SLAY_GIANT | TR_IMPACT | TR_SUST_STR | TR_SUST_CON | + TR_FREE_ACT | TR_RES_FEAR | TR_RES_SHARDS | TR_REGEN | + ESP_TROLL | ESP_GIANT, + }, + flags_group { + "Mind", + TERM_YELLOW, + 7, + TR_INT | TR_SUST_INT | TR_RES_CONF | TR_RES_FEAR | + ESP_ORC | ESP_TROLL | ESP_GIANT | ESP_ANIMAL | ESP_UNIQUE | ESP_SPIDER | ESP_DEMON, + }, + flags_group { + "Shield", + TERM_RED, + 7, + TR_DEX | TR_SUST_DEX | TR_INVIS | TR_REFLECT | + TR_HOLD_LIFE | TR_RES_SOUND | TR_RES_NEXUS | + TR_REGEN, + }, + flags_group { + "Chaos", + TERM_VIOLET, + 7, + TR_CHAOTIC | TR_IMPACT | TR_RES_CHAOS | TR_RES_DISEN | TR_REGEN | + ESP_ALL, + }, + flags_group { + "Magic", + TERM_L_BLUE, + 10, + TR_MANA | TR_SPELL | TR_RES_CHAOS | TR_RES_DISEN | TR_WRAITH | + TR_PRECOGNITION | TR_FLY | TR_CLONE, + }, + flags_group { + "Antimagic", + TERM_L_DARK, + 10, + TR_VAMPIRIC | TR_CHAOTIC | TR_BLOWS | TR_SPEED | TR_LIFE | + TR_REFLECT | TR_FREE_ACT | TR_HOLD_LIFE | TR_NO_MAGIC | + TR_NO_TELE | TR_SEE_INVIS | TR_ANTIMAGIC_50, + } + }; + + return *instance; }; /* Powers */ @@ -3954,107 +3585,148 @@ quest_type quest[MAX_Q_IDX] = /* List of powers for Symbiants/Powers */ -monster_power monster_powers[96] = - { - { RF4_SHRIEK, "Aggravate Monster", 1, FALSE }, - { RF4_MULTIPLY, "Multiply", 10, FALSE }, - { RF4_S_ANIMAL, "Summon Animal", 30, FALSE }, - { RF4_ROCKET, "Fire a Rocket", 40, TRUE }, - { RF4_ARROW_1, "Light Arrow", 1, FALSE }, - { RF4_ARROW_2, "Minor Arrow", 3, FALSE }, - { RF4_ARROW_3, "Major Arrow", 7, TRUE }, - { RF4_ARROW_4, "Great Arrow", 9, TRUE }, - { RF4_BR_ACID, "Breathe Acid", 10, FALSE }, - { RF4_BR_ELEC, "Breathe Lightning", 10, FALSE }, - { RF4_BR_FIRE, "Breathe Fire", 10, FALSE }, - { RF4_BR_COLD, "Breathe Cold", 10, FALSE }, - { RF4_BR_POIS, "Breathe Poison", 15, TRUE }, - { RF4_BR_NETH, "Breathe Nether", 30, TRUE }, - { RF4_BR_LITE, "Breathe Light", 20, TRUE }, - { RF4_BR_DARK, "Breathe Dark", 20, TRUE }, - { RF4_BR_CONF, "Breathe Confusion", 15, TRUE }, - { RF4_BR_SOUN, "Breathe Sound", 30, TRUE }, - { RF4_BR_CHAO, "Breathe Chaos", 30, TRUE }, - { RF4_BR_DISE, "Breathe Disenchantment", 30, TRUE }, - { RF4_BR_NEXU, "Breathe Nexus", 30, TRUE }, - { RF4_BR_TIME, "Breathe Time", 30, TRUE }, - { RF4_BR_INER, "Breathe Inertia", 30, TRUE }, - { RF4_BR_GRAV, "Breathe Gravity", 30, TRUE }, - { RF4_BR_SHAR, "Breathe Shards", 30, TRUE }, - { RF4_BR_PLAS, "Breathe Plasma", 30, TRUE }, - { RF4_BR_WALL, "Breathe Force", 30, TRUE }, - { RF4_BR_MANA, "Breathe Mana", 40, TRUE }, - { RF4_BA_NUKE, "Nuke Ball", 30, TRUE }, - { RF4_BR_NUKE, "Breathe Nuke", 40, TRUE }, - { RF4_BA_CHAO, "Chaos Ball", 30, TRUE }, - { RF4_BR_DISI, "Breathe Disintegration", 40, TRUE }, +monster_power monster_powers[] = + { + { SF_SHRIEK_IDX, "Aggravate Monster", 1, FALSE }, + { SF_MULTIPLY_IDX, "Multiply", 10, FALSE }, + { SF_S_ANIMAL_IDX, "Summon Animal", 30, FALSE }, + { SF_ROCKET_IDX, "Fire a Rocket", 40, TRUE }, + { SF_ARROW_1_IDX, "Light Arrow", 1, FALSE }, + { SF_ARROW_2_IDX, "Minor Arrow", 3, FALSE }, + { SF_ARROW_3_IDX, "Major Arrow", 7, TRUE }, + { SF_ARROW_4_IDX, "Great Arrow", 9, TRUE }, + { SF_BR_ACID_IDX, "Breathe Acid", 10, FALSE }, + { SF_BR_ELEC_IDX, "Breathe Lightning", 10, FALSE }, + { SF_BR_FIRE_IDX, "Breathe Fire", 10, FALSE }, + { SF_BR_COLD_IDX, "Breathe Cold", 10, FALSE }, + { SF_BR_POIS_IDX, "Breathe Poison", 15, TRUE }, + { SF_BR_NETH_IDX, "Breathe Nether", 30, TRUE }, + { SF_BR_LITE_IDX, "Breathe Light", 20, TRUE }, + { SF_BR_DARK_IDX, "Breathe Dark", 20, TRUE }, + { SF_BR_CONF_IDX, "Breathe Confusion", 15, TRUE }, + { SF_BR_SOUN_IDX, "Breathe Sound", 30, TRUE }, + { SF_BR_CHAO_IDX, "Breathe Chaos", 30, TRUE }, + { SF_BR_DISE_IDX, "Breathe Disenchantment", 30, TRUE }, + { SF_BR_NEXU_IDX, "Breathe Nexus", 30, TRUE }, + { SF_BR_TIME_IDX, "Breathe Time", 30, TRUE }, + { SF_BR_INER_IDX, "Breathe Inertia", 30, TRUE }, + { SF_BR_GRAV_IDX, "Breathe Gravity", 30, TRUE }, + { SF_BR_SHAR_IDX, "Breathe Shards", 30, TRUE }, + { SF_BR_PLAS_IDX, "Breathe Plasma", 30, TRUE }, + { SF_BR_WALL_IDX, "Breathe Force", 30, TRUE }, + { SF_BR_MANA_IDX, "Breathe Mana", 40, TRUE }, + { SF_BA_NUKE_IDX, "Nuke Ball", 30, TRUE }, + { SF_BR_NUKE_IDX, "Breathe Nuke", 40, TRUE }, + { SF_BA_CHAO_IDX, "Chaos Ball", 30, TRUE }, + { SF_BR_DISI_IDX, "Breathe Disintegration", 40, TRUE }, + { SF_BA_ACID_IDX, "Acid Ball", 8, FALSE }, + { SF_BA_ELEC_IDX, "Lightning Ball", 8, FALSE }, + { SF_BA_FIRE_IDX, "Fire Ball", 8, FALSE }, + { SF_BA_COLD_IDX, "Cold Ball", 8, FALSE }, + { SF_BA_POIS_IDX, "Poison Ball", 20, TRUE }, + { SF_BA_NETH_IDX, "Nether Ball", 20, TRUE }, + { SF_BA_WATE_IDX, "Water Ball", 20, TRUE }, + { SF_BA_MANA_IDX, "Mana Ball", 50, TRUE }, + { SF_BA_DARK_IDX, "Darkness Ball", 20, TRUE }, + { SF_CAUSE_1_IDX, "Cause Light Wounds", 20, FALSE }, + { SF_CAUSE_2_IDX, "Cause Medium Wounds", 30, FALSE }, + { SF_CAUSE_3_IDX, "Cause Critical Wounds", 35, TRUE }, + { SF_CAUSE_4_IDX, "Cause Mortal Wounds", 45, TRUE }, + { SF_BO_ACID_IDX, "Acid Bolt", 5, FALSE }, + { SF_BO_ELEC_IDX, "Lightning Bolt", 5, FALSE }, + { SF_BO_FIRE_IDX, "Fire Bolt", 5, FALSE }, + { SF_BO_COLD_IDX, "Cold Bolt", 5, FALSE }, + { SF_BO_POIS_IDX, "Poison Bolt", 10, TRUE }, + { SF_BO_NETH_IDX, "Nether Bolt", 15, TRUE }, + { SF_BO_WATE_IDX, "Water Bolt", 20, TRUE }, + { SF_BO_MANA_IDX, "Mana Bolt", 25, TRUE }, + { SF_BO_PLAS_IDX, "Plasma Bolt", 20, TRUE }, + { SF_BO_ICEE_IDX, "Ice Bolt", 20, TRUE }, + { SF_MISSILE_IDX, "Magic Missile", 1, FALSE }, + { SF_SCARE_IDX, "Scare", 4, FALSE }, + { SF_BLIND_IDX, "Blindness", 6, FALSE }, + { SF_CONF_IDX, "Confusion", 7, FALSE }, + { SF_SLOW_IDX, "Slowness", 10, FALSE }, + { SF_HOLD_IDX, "Paralyse", 10, FALSE }, + { SF_HASTE_IDX, "Haste Self", 50, FALSE }, + { SF_HAND_DOOM_IDX, "Hand of Doom", 30, TRUE }, + { SF_HEAL_IDX, "Healing", 60, FALSE }, + { SF_S_ANIMALS_IDX, "Summon Animals", 60, TRUE }, + { SF_BLINK_IDX, "Phase Door", 2, FALSE }, + { SF_TPORT_IDX, "Teleport", 10, FALSE }, + { SF_TELE_TO_IDX, "Teleport To", 20, TRUE }, + { SF_TELE_AWAY_IDX, "Teleport Away", 20, FALSE }, + { SF_TELE_LEVEL_IDX, "Teleport Level", 20, TRUE }, + { SF_DARKNESS_IDX, "Darkness", 3, FALSE }, + { SF_RAISE_DEAD_IDX, "Raise the Dead", 400, TRUE }, + { SF_S_THUNDERLORD_IDX, "Summon Thunderlords", 90, TRUE }, + { SF_S_KIN_IDX, "Summon Kin", 80, FALSE }, + { SF_S_HI_DEMON_IDX, "Summon Greater Demons", 90, TRUE }, + { SF_S_MONSTER_IDX, "Summon Monster", 50, FALSE }, + { SF_S_MONSTERS_IDX, "Summon Monsters", 60, TRUE }, + { SF_S_ANT_IDX, "Summon Ants", 30, FALSE }, + { SF_S_SPIDER_IDX, "Summon Spider", 30, FALSE }, + { SF_S_HOUND_IDX, "Summon Hound", 50, TRUE }, + { SF_S_HYDRA_IDX, "Summon Hydra", 40, TRUE }, + { SF_S_ANGEL_IDX, "Summon Angel", 60, TRUE }, + { SF_S_DEMON_IDX, "Summon Demon", 60, TRUE }, + { SF_S_UNDEAD_IDX, "Summon Undead", 70, TRUE }, + { SF_S_DRAGON_IDX, "Summon Dragon", 70, TRUE }, + { SF_S_HI_UNDEAD_IDX, "Summon High Undead", 90, TRUE }, + { SF_S_HI_DRAGON_IDX, "Summon High Dragon", 90, TRUE }, + { SF_S_WRAITH_IDX, "Summon Wraith", 90, TRUE }, + }; - { RF5_BA_ACID, "Acid Ball", 8, FALSE }, - { RF5_BA_ELEC, "Lightning Ball", 8, FALSE }, - { RF5_BA_FIRE, "Fire Ball", 8, FALSE }, - { RF5_BA_COLD, "Cold Ball", 8, FALSE }, - { RF5_BA_POIS, "Poison Ball", 20, TRUE }, - { RF5_BA_NETH, "Nether Ball", 20, TRUE }, - { RF5_BA_WATE, "Water Ball", 20, TRUE }, - { RF5_BA_MANA, "Mana Ball", 50, TRUE }, - { RF5_BA_DARK, "Darkness Ball", 20, TRUE }, - { 0, "(none)", 0, FALSE }, - { 0, "(none)", 0, FALSE }, - { 0, "(none)", 0, FALSE }, - { RF5_CAUSE_1, "Cause Light Wounds", 20, FALSE }, - { RF5_CAUSE_2, "Cause Medium Wounds", 30, FALSE }, - { RF5_CAUSE_3, "Cause Critical Wounds", 35, TRUE }, - { RF5_CAUSE_4, "Cause Mortal Wounds", 45, TRUE }, - { RF5_BO_ACID, "Acid Bolt", 5, FALSE }, - { RF5_BO_ELEC, "Lightning Bolt", 5, FALSE }, - { RF5_BO_FIRE, "Fire Bolt", 5, FALSE }, - { RF5_BO_COLD, "Cold Bolt", 5, FALSE }, - { RF5_BO_POIS, "Poison Bolt", 10, TRUE }, - { RF5_BO_NETH, "Nether Bolt", 15, TRUE }, - { RF5_BO_WATE, "Water Bolt", 20, TRUE }, - { RF5_BO_MANA, "Mana Bolt", 25, TRUE }, - { RF5_BO_PLAS, "Plasma Bolt", 20, TRUE }, - { RF5_BO_ICEE, "Ice Bolt", 20, TRUE }, - { RF5_MISSILE, "Magic Missile", 1, FALSE }, - { RF5_SCARE, "Scare", 4, FALSE }, - { RF5_BLIND, "Blindness", 6, FALSE }, - { RF5_CONF, "Confusion", 7, FALSE }, - { RF5_SLOW, "Slowness", 10, FALSE }, - { RF5_HOLD, "Paralyse", 10, FALSE }, - { RF6_HASTE, "Haste Self", 50, FALSE }, - { RF6_HAND_DOOM, "Hand of Doom", 30, TRUE }, - { RF6_HEAL, "Healing", 60, FALSE }, - { RF6_S_ANIMALS, "Summon Animals", 60, TRUE }, - { RF6_BLINK, "Phase Door", 2, FALSE }, - { RF6_TPORT, "Teleport", 10, FALSE }, - { RF6_TELE_TO, "Teleport To", 20, TRUE }, - { RF6_TELE_AWAY, "Teleport Away", 20, FALSE }, - { RF6_TELE_LEVEL, "Teleport Level", 20, TRUE }, - { RF6_DARKNESS, "Darkness", 3, FALSE }, - { RF6_TRAPS, "Create Traps", 10, TRUE }, - { 0, "(none)", 0, FALSE }, - { RF6_RAISE_DEAD, "Raise the Dead", 400, TRUE }, - { 0, "(none)", 0, FALSE }, - { 0, "(none)", 0, FALSE }, - { RF6_S_THUNDERLORD, "Summon Thunderlords", 90, TRUE }, - { RF6_S_KIN, "Summon Kin", 80, FALSE }, - { RF6_S_HI_DEMON, "Summon Greater Demons", 90, TRUE }, - { RF6_S_MONSTER, "Summon Monster", 50, FALSE }, - { RF6_S_MONSTERS, "Summon Monsters", 60, TRUE }, - { RF6_S_ANT, "Summon Ants", 30, FALSE }, - { RF6_S_SPIDER, "Summon Spider", 30, FALSE }, - { RF6_S_HOUND, "Summon Hound", 50, TRUE }, - { RF6_S_HYDRA, "Summon Hydra", 40, TRUE }, - { RF6_S_ANGEL, "Summon Angel", 60, TRUE }, - { RF6_S_DEMON, "Summon Demon", 60, TRUE }, - { RF6_S_UNDEAD, "Summon Undead", 70, TRUE }, - { RF6_S_DRAGON, "Summon Dragon", 70, TRUE }, - { RF6_S_HI_UNDEAD, "Summon High Undead", 90, TRUE }, - { RF6_S_HI_DRAGON, "Summon High Dragon", 90, TRUE }, - { RF6_S_WRAITH, "Summon Wraith", 90, TRUE }, - { 0, "(none)", 0, FALSE }, - }; +/* + * A list of tvals and their textual names + */ +tval_desc tvals[] = +{ + { TV_SWORD, "Sword" }, + { TV_POLEARM, "Polearm" }, + { TV_HAFTED, "Hafted Weapon" }, + { TV_AXE, "Axe" }, + { TV_BOW, "Bow" }, + { TV_BOOMERANG, "Boomerang" }, + { TV_ARROW, "Arrows" }, + { TV_BOLT, "Bolts" }, + { TV_SHOT, "Shots" }, + { TV_SHIELD, "Shield" }, + { TV_CROWN, "Crown" }, + { TV_HELM, "Helm" }, + { TV_GLOVES, "Gloves" }, + { TV_BOOTS, "Boots" }, + { TV_CLOAK, "Cloak" }, + { TV_DRAG_ARMOR, "Dragon Scale Mail" }, + { TV_HARD_ARMOR, "Hard Armor" }, + { TV_SOFT_ARMOR, "Soft Armor" }, + { TV_RING, "Ring" }, + { TV_AMULET, "Amulet" }, + { TV_LITE, "Lite" }, + { TV_POTION, "Potion" }, + { TV_POTION2, "Potion" }, + { TV_SCROLL, "Scroll" }, + { TV_WAND, "Wand" }, + { TV_STAFF, "Staff" }, + { TV_ROD_MAIN, "Rod" }, + { TV_ROD, "Rod Tip" }, + { TV_BOOK, "Schools Spellbook", }, + { TV_SYMBIOTIC_BOOK, "Symbiotic Spellbook", }, + { TV_DRUID_BOOK, "Elemental Stone" }, + { TV_MUSIC_BOOK, "Music Book" }, + { TV_DAEMON_BOOK, "Daemon Book" }, + { TV_SPIKE, "Spikes" }, + { TV_DIGGING, "Digger" }, + { TV_CHEST, "Chest" }, + { TV_FOOD, "Food" }, + { TV_FLASK, "Flask" }, + { TV_MSTAFF, "Mage Staff" }, + { TV_PARCHMENT, "Parchment" }, + { TV_INSTRUMENT, "Musical Instrument" }, + { TV_JUNK, "Junk" }, + { 0, NULL } +}; /* Tval descriptions */ tval_desc tval_descs[] = @@ -4156,11 +3828,6 @@ tval_desc tval_descs[] = "arcane magics." }, { - TV_TRAPKIT, - "Trapping kits are used with the trapping ability to set " - "deadly monster traps." - }, - { TV_STAFF, "Staves are objects imbued with mystical powers." }, @@ -4217,14 +3884,6 @@ tval_desc tval_descs[] = "they can be activated for great or strange effects..." }, { - TV_RUNE1, - "Runes are used with the Runecraft skill to create brand new spells." - }, - { - TV_RUNE2, - "Runes are used with the Runecraft skill to create brand new spells." - }, - { TV_JUNK, "Junk is usually worthless, though experienced archers can " "create ammo with them." @@ -4390,10 +4049,8 @@ gf_name_type gf_names[] = { GF_GRAVITY, "gravity" }, { GF_KILL_WALL, "wall destruction" }, { GF_KILL_DOOR, "door destruction" }, - { GF_KILL_TRAP, "trap destruction" }, { GF_MAKE_WALL, "wall creation" }, { GF_MAKE_DOOR, "door creation" }, - { GF_MAKE_TRAP, "trap creation" }, { GF_OLD_CLONE, "clone" }, { GF_OLD_POLY, "polymorph" }, { GF_OLD_HEAL, "healing" }, @@ -4432,7 +4089,6 @@ gf_name_type gf_names[] = { GF_JAM_DOOR, "door jamming" }, { GF_DOMINATION, "domination" }, { GF_DISP_GOOD, "dispel good" }, - { GF_IDENTIFY, "identification" }, { GF_RAISE, "raise dead" }, { GF_STAR_IDENTIFY, "*identification*" }, { GF_DESTRUCTION, "destruction" }, @@ -4470,8 +4126,6 @@ module_type modules[MAX_MODULES] = }, /* Randarts: */ { 30, 20, 20 }, - /* Max player level: */ - 50, /* Skills: */ { 6, 4, }, /* Intro function */ @@ -4492,8 +4146,6 @@ module_type modules[MAX_MODULES] = }, /* Randarts: */ { 30, 30, 30 }, - /* Max player level: */ - 50, /* Skill overage: */ { 6, 5, }, /* Intro function */ diff --git a/src/tables.hpp b/src/tables.hpp index 4a3e33d6..613dbddb 100644 --- a/src/tables.hpp +++ b/src/tables.hpp @@ -15,13 +15,14 @@ #include "move_info_type.hpp" #include "option_type.hpp" #include "player_defs.hpp" -#include "player_sex.hpp" #include "power_type.hpp" #include "powers.hpp" #include "quest_type.hpp" #include "tactic_info_type.hpp" #include "tval_desc.hpp" +#include <vector> + extern s16b ddd[9]; extern s16b ddx[10]; extern s16b ddy[10]; @@ -32,8 +33,6 @@ extern byte adj_mag_fail[]; extern byte adj_mag_stat[]; extern byte adj_chr_gold[]; extern byte adj_wis_sav[]; -extern byte adj_dex_dis[]; -extern byte adj_int_dis[]; extern byte adj_dex_ta[]; extern byte adj_str_td[]; extern byte adj_dex_th[]; @@ -49,12 +48,10 @@ extern byte adj_con_mhp[]; extern byte blows_table[12][12]; extern byte extract_energy[300]; extern s32b player_exp[PY_MAX_LEVEL]; -extern player_sex sex_info[MAX_SEXES]; extern cptr color_names[16]; extern cptr stat_names[6]; extern cptr stat_names_reduced[6]; extern cptr window_flag_desc[32]; -extern option_type option_info[]; extern martial_arts bear_blows[MAX_BEAR]; extern martial_arts ma_blows[MAX_MA]; extern magic_power mindcraft_powers[MAX_MINDCRAFT_POWERS]; @@ -66,10 +63,11 @@ extern tactic_info_type tactic_info[9]; extern activation activation_info[MAX_T_ACT]; extern inscription_info_type inscription_info[MAX_INSCRIPTIONS]; extern cptr sense_desc[]; -extern flags_group flags_groups[MAX_FLAG_GROUP]; +std::vector<flags_group> const &flags_groups(); extern power_type powers_type[POWER_MAX]; extern cptr artifact_names_list; -extern monster_power monster_powers[96]; +extern monster_power monster_powers[MONSTER_POWERS_MAX]; +extern tval_desc tvals[]; extern tval_desc tval_descs[]; extern between_exit between_exits[MAX_BETWEEN_EXITS]; extern int month_day[9]; diff --git a/src/tactic_info_type.hpp b/src/tactic_info_type.hpp index da94767d..4cb330f4 100644 --- a/src/tactic_info_type.hpp +++ b/src/tactic_info_type.hpp @@ -11,7 +11,6 @@ struct tactic_info_type s16b to_dam; s16b to_ac; s16b to_stealth; - s16b to_disarm; s16b to_saving; cptr name; }; diff --git a/src/timer_type.hpp b/src/timer_type.hpp index 0ce6b095..d682b3bd 100644 --- a/src/timer_type.hpp +++ b/src/timer_type.hpp @@ -2,17 +2,80 @@ #include "h-basic.h" +#include <functional> + /* * Timer descriptor and runtime data. */ struct timer_type { - timer_type *next; /* The next timer in the list */ +private: + std::function<void ()> m_callback; + +public: + // + // XXX Currently need public access for loading and saving. + // + bool m_enabled; + s32b m_delay = 0; + s32b m_countdown = 0; + +public: + /** + * Create a new timer + */ + timer_type(std::function<void()> callback, s32b delay) + : m_callback(callback) + , m_enabled(false) + , m_delay(delay) + , m_countdown(delay) + { + } + + timer_type(timer_type const &other) = delete; + timer_type &operator =(timer_type const &other) = delete; + + /** + * Enable the timer. + */ + void enable() + { + m_enabled = true; + } + + /** + * Disable the timer. + */ + void disable() + { + m_enabled = false; + } + + /** + * Change delay and reset. + */ + void set_delay_and_reset(s32b delay) + { + m_delay = delay; + m_countdown = delay; + } - bool_ enabled; /* Is it currently counting? */ + /** + * Count down. + */ + void count_down() + { + if (!m_enabled) + { + return; + } - s32b delay; /* Delay between activations */ - s32b countdown; /* The current number of turns passed, when it reaches delay it fires */ + m_countdown--; + if (m_countdown <= 0) + { + m_countdown = m_delay; + m_callback(); + } + } - void (*callback)(); /* The C function to call upon firing */ }; diff --git a/src/town_type.hpp b/src/town_type.hpp index f8458c60..0b903138 100644 --- a/src/town_type.hpp +++ b/src/town_type.hpp @@ -1,21 +1,25 @@ #pragma once #include "h-basic.h" +#include "seed.hpp" #include "store_type_fwd.hpp" +#include <vector> + /** * Town descriptor. */ struct town_type { - cptr name; - u32b seed; /* Seed for RNG */ - store_type *store; /* The stores [max_st_idx] */ - byte numstores; + cptr name = nullptr; + + seed_t seed = seed_t::system(); /* Seed for RNG */ + + std::vector<store_type> store; /* The stores [max_st_idx] */ + + byte flags = 0; /* Town flags */ - byte flags; /* Town flags */ - /* Left this for the sake of compatibility */ - bool_ stocked; /* Is the town actualy stocked ? */ + bool_ stocked = FALSE; /* Is the town actualy stocked ? */ - bool_ destroyed; /* Is the town destroyed? */ + bool_ destroyed = FALSE; /* Is the town destroyed? */ }; diff --git a/src/trap_type.hpp b/src/trap_type.hpp deleted file mode 100644 index d82c925b..00000000 --- a/src/trap_type.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "h-basic.h" - -/** - * Trap descriptor. - */ -struct trap_type -{ - s16b probability; /* probability of existence */ - s16b another; /* does this trap easily combine */ - s16b p1valinc; /* how much does this trap attribute to p1val */ - byte difficulty; /* how difficult to disarm */ - byte minlevel; /* what is the minimum level on which the traps should be */ - byte color; /* what is the color on screen */ - u32b flags; /* where can these traps go - and perhaps other flags */ - bool_ ident; /* do we know the name */ - s16b known; /* how well is this trap known */ - const char *name; /* normal name like weakness */ - s16b dd, ds; /* base damage */ - char *text; /* longer description once you've met this trap */ - byte g_attr; /* Overlay graphic attribute */ - char g_char; /* Overlay graphic character */ -}; diff --git a/src/trap_type_fwd.hpp b/src/trap_type_fwd.hpp deleted file mode 100644 index 480edfef..00000000 --- a/src/trap_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct trap_type; diff --git a/src/traps.cc b/src/traps.cc deleted file mode 100644 index 99428cf9..00000000 --- a/src/traps.cc +++ /dev/null @@ -1,3174 +0,0 @@ -/* the below copyright probably still applies, but it is heavily changed - * copied, adapted & re-engineered by JK. - * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke - * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. - */ - -#include "traps.hpp" - -#include "artifact_type.hpp" -#include "cave.hpp" -#include "cave_type.hpp" -#include "cmd1.hpp" -#include "cmd2.hpp" -#include "dungeon_info_type.hpp" -#include "feature_type.hpp" -#include "files.hpp" -#include "gods.hpp" -#include "monster2.hpp" -#include "monster_race.hpp" -#include "monster_type.hpp" -#include "object1.hpp" -#include "object2.hpp" -#include "object_kind.hpp" -#include "player_race.hpp" -#include "player_race_mod.hpp" -#include "player_spec.hpp" -#include "player_type.hpp" -#include "spells1.hpp" -#include "spells2.hpp" -#include "stats.hpp" -#include "tables.hpp" -#include "trap_type.hpp" -#include "util.hpp" -#include "variable.hpp" -#include "xtra1.hpp" -#include "xtra2.hpp" -#include "z-rand.hpp" - -bool_ do_player_trap_call_out(void) -{ - s16b i, sn, cx, cy; - s16b h_index = 0; - s16b h_level = 0; - monster_type *m_ptr; - char m_name[80]; - bool_ ident = FALSE; - - for (i = 1; i < m_max; i++) - { - m_ptr = &m_list[i]; - - /* Paranoia -- Skip dead monsters */ - if (!m_ptr->r_idx) continue; - - if (m_ptr->level >= h_level) - { - h_level = m_ptr->level; - h_index = i; - } - } - - /* if the level is empty of monsters, h_index will be 0 */ - if (!h_index) return (FALSE); - - m_ptr = &m_list[h_index]; - - sn = 0; - for (i = 0; i < 8; i++) - { - cx = p_ptr->px + ddx[i]; - cy = p_ptr->py + ddy[i]; - - /* Skip non-empty grids */ - if (!cave_valid_bold(cy, cx)) continue; - if (cave[cy][cx].feat == FEAT_GLYPH) continue; - if ((cx == p_ptr->px) && (cy == p_ptr->py)) continue; - sn++; - - /* Randomize choice */ - if (rand_int(sn) > 0) continue; - cave[cy][cx].m_idx = h_index; - cave[m_ptr->fy][m_ptr->fx].m_idx = 0; - m_ptr->fx = cx; - m_ptr->fy = cy; - - /* we do not change the sublevel! */ - ident = TRUE; - update_mon(h_index, TRUE); - monster_desc(m_name, m_ptr, 0x08); - msg_format("You hear a rapid-shifting wail, and %s appears!", m_name); - break; - } - - return (ident); -} - -static bool_ do_trap_teleport_away(object_type *i_ptr, s16b y, s16b x) -{ - bool_ ident = FALSE; - char o_name[80]; - - s16b o_idx = 0; - object_type *o_ptr; - cave_type *c_ptr; - - s16b x1; - s16b y1; - - if (i_ptr == NULL) return (FALSE); - - if (i_ptr->name1 == ART_POWER) return (FALSE); - - while (o_idx == 0) - { - x1 = rand_int(cur_wid); - y1 = rand_int(cur_hgt); - - /* Obtain grid */ - c_ptr = &cave[y1][x1]; - - /* Require floor space (or shallow terrain) -KMW- */ - if (!(f_info[c_ptr->feat].flags1 & FF1_FLOOR)) continue; - - o_idx = drop_near(i_ptr, 0, y1, x1); - } - - o_ptr = &o_list[o_idx]; - - x1 = o_ptr->ix; - y1 = o_ptr->iy; - - if (!p_ptr->blind) - { - note_spot(y, x); - lite_spot(y, x); - ident = TRUE; - object_desc(o_name, i_ptr, FALSE, 0); - if (player_has_los_bold(y1, x1)) - { - lite_spot(y1, x1); - msg_format("The %s suddenly stands elsewhere.", o_name); - - } - else - { - msg_format("You suddenly don't see the %s any more!", o_name); - } - } - else - { - msg_print("You hear something move."); - } - return (ident); -} - -/* - * this handles a trap that places walls around the player - */ -static bool_ player_handle_trap_of_walls(void) -{ - bool_ ident; - - s16b dx, dy, cx, cy; - s16b sx = 0, sy = 0, sn, i; - cave_type *cv_ptr; - bool_ map[5][5] = - { - {FALSE, FALSE, FALSE, FALSE, FALSE}, - {FALSE, FALSE, FALSE, FALSE, FALSE}, - {FALSE, FALSE, FALSE, FALSE, FALSE}, - {FALSE, FALSE, FALSE, FALSE, FALSE}, - {FALSE, FALSE, FALSE, FALSE, FALSE} - }; - - for (dy = -2; dy <= 2; dy++) - for (dx = -2; dx <= 2; dx++) - { - /* Extract the location */ - cx = p_ptr->px + dx; - cy = p_ptr->py + dy; - - if (!in_bounds(cy, cx)) continue; - - cv_ptr = &cave[cy][cx]; - - if (cv_ptr->m_idx) continue; - - /* Lose room and vault */ - cv_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY); - /* Lose light and knowledge */ - cv_ptr->info &= ~(CAVE_GLOW | CAVE_MARK); - - /* Skip the center */ - if (!dx && !dy) continue; - - /* test for dungeon level */ - if (randint(100) > 10 + max_dlv[dungeon_type]) continue; - - /* Damage this grid */ - map[2 + dx][2 + dy] = TRUE; - } - - for (dy = -2; dy <= 2; dy++) - for (dx = -2; dx <= 2; dx++) - { - /* Extract the location */ - cx = p_ptr->px + dx; - cy = p_ptr->py + dy; - - /* Skip unaffected grids */ - if (!map[2 + dx][2 + dy]) continue; - - cv_ptr = &cave[cy][cx]; - - if (cv_ptr->m_idx) - { - monster_type *m_ptr = &m_list[cv_ptr->m_idx]; - auto const r_ptr = m_ptr->race(); - - /* Most monsters cannot co-exist with rock */ - if ((!(r_ptr->flags2 & RF2_KILL_WALL)) && - (!(r_ptr->flags2 & RF2_PASS_WALL))) - { - char m_name[80]; - - /* Assume not safe */ - sn = 0; - - /* Monster can move to escape the wall */ - if (!(r_ptr->flags1 & RF1_NEVER_MOVE)) - { - /* Look for safety */ - for (i = 0; i < 8; i++) - { - /* Access the grid */ - cy = p_ptr->py + ddy[i]; - cx = p_ptr->px + ddx[i]; - - /* Skip non-empty grids */ - if (!cave_clean_bold(cy, cx)) continue; - - /* Hack -- no safety on glyph of warding */ - if (cave[cy][cx].feat == FEAT_GLYPH) continue; - - /* Important -- Skip "quake" grids */ - if (map[2 + (cx - p_ptr->px)][2 + (cy - p_ptr->py)]) continue; - - /* Count "safe" grids */ - sn++; - - /* Randomize choice */ - if (rand_int(sn) > 0) continue; - - /* Save the safe grid */ - sx = cx; - sy = cy; - - ident = TRUE; - - break; /* discontinue for loop - safe grid found */ - } - } - - /* Describe the monster */ - monster_desc(m_name, m_ptr, 0); - - /* Scream in pain */ - msg_format("%^s wails out in pain!", m_name); - - /* Monster is certainly awake */ - m_ptr->csleep = 0; - - /* Apply damage directly */ - m_ptr->hp -= (sn ? damroll(4, 8) : 200); - - /* Delete (not kill) "dead" monsters */ - if (m_ptr->hp < 0) - { - /* Message */ - msg_format("%^s is entombed in the rock!", m_name); - - /* Delete the monster */ - delete_monster_idx(cave[cy][cx].m_idx); - - /* No longer safe */ - sn = 0; - } - - /* Hack -- Escape from the rock */ - if (sn) - { - s16b m_idx = cave[cy][cx].m_idx; - - /* Update the new location */ - cave[sy][sx].m_idx = m_idx; - - /* Update the old location */ - cave[cy][cx].m_idx = 0; - - /* Move the monster */ - m_ptr->fy = sy; - m_ptr->fx = sx; - - /* do not change fz */ - /* don't make rock on that square! */ - if ((sx >= (p_ptr->px - 2)) && (sx <= (p_ptr->px + 2)) && - (sy >= (p_ptr->py - 2)) && (sy <= (p_ptr->py + 2))) - { - map[2 + (sx - p_ptr->px)][2 + (sy - p_ptr->py)] = FALSE; - } - - /* Update the monster (new location) */ - update_mon(m_idx, TRUE); - - /* Redraw the old grid */ - lite_spot(cy, cx); - - /* Redraw the new grid */ - lite_spot(sy, sx); - } /* if sn */ - } /* if monster can co-exist with rock */ - } /* if monster on square */ - } - - /* Examine the quaked region */ - for (dy = -2; dy <= 2; dy++) - for (dx = -2; dx <= 2; dx++) - { - /* Extract the location */ - cx = p_ptr->px + dx; - cy = p_ptr->py + dy; - - /* Skip unaffected grids */ - if (!map[2 + dx][2 + dy]) continue; - - /* Access the cave grid */ - cv_ptr = &cave[cy][cx]; - - /* Paranoia -- never affect player */ - if (!dy && !dx) continue; - - /* Destroy location (if valid) */ - if ((cx < cur_wid) && (cy < cur_hgt) && cave_valid_bold(cy, cx)) - { - bool_ floor = (f_info[cave[cy][cx].feat].flags1 & FF1_FLOOR); - - /* Delete any object that is still there */ - delete_object(cy, cx); - - if (floor) - { - cave_set_feat(cy, cx, FEAT_WALL_OUTER); - } - else - { - /* Clear previous contents, add floor */ - cave_set_feat(cy, cx, FEAT_FLOOR); - } - } - } - - /* Mega-Hack -- Forget the view and lite */ - p_ptr->update |= PU_UN_VIEW; - - /* Update stuff */ - p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MON_LITE); - - /* Update the monsters */ - p_ptr->update |= (PU_DISTANCE); - - /* Update the health bar */ - p_ptr->redraw |= (PR_FRAME); - - /* Redraw map */ - p_ptr->redraw |= (PR_MAP); - - /* Window stuff */ - p_ptr->window |= (PW_OVERHEAD); - handle_stuff(); - - msg_print("Suddenly the cave shifts around you. The air is getting stale!"); - - ident = TRUE; - - return (ident); -} - - -/* - * this function handles arrow & dagger traps, in various types. - * num = number of missiles - * tval, sval = kind of missiles - * dd,ds = damage roll for missiles - * poison_dam = additional poison damage - * name = name given if you should die from it... - * - * return value = ident (always TRUE) - */ -static bool_ player_handle_missile_trap(s16b num, s16b tval, s16b sval, s16b dd, s16b ds, - s16b pdam, cptr name) -{ - object_type *o_ptr, forge; - s16b i, k_idx = lookup_kind(tval, sval); - char i_name[80]; - - o_ptr = &forge; - object_prep(o_ptr, k_idx); - o_ptr->number = num; - apply_magic(o_ptr, max_dlv[dungeon_type], FALSE, FALSE, FALSE); - object_desc(i_name, o_ptr, TRUE, 0); - - msg_format("Suddenly %s hit%s you!", i_name, - ((num == 1) ? "" : "s")); - - for (i = 0; i < num; i++) - { - take_hit(damroll(dd, ds), name); - - redraw_stuff(); - - if (pdam > 0) - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - (void)set_poisoned(p_ptr->poisoned + pdam); - } - } - } - - drop_near(o_ptr, -1, p_ptr->py, p_ptr->px); - - return TRUE; -} - -/* - * this function handles a "breath" type trap - acid bolt, lightning balls etc. - */ -static bool_ player_handle_breath_trap(s16b rad, s16b type, u16b trap) -{ - trap_type *t_ptr = &t_info[trap]; - bool_ ident; - s16b my_dd, my_ds, dam; - - my_dd = t_ptr->dd; - my_ds = t_ptr->ds; - - /* these traps gets nastier as levels progress */ - if (max_dlv[dungeon_type] > (2 * t_ptr->minlevel)) - { - my_dd += (max_dlv[dungeon_type] / 15); - my_ds += (max_dlv[dungeon_type] / 15); - } - dam = damroll(my_dd, my_ds); - - ident = project( -2, rad, p_ptr->py, p_ptr->px, dam, type, PROJECT_KILL | PROJECT_JUMP); - - return (ident); -} - -/* - * This function damages the player by a trap - */ -static void trap_hit(s16b trap) -{ - trap_type *t_ptr = &t_info[trap]; - s16b dam = damroll(t_ptr->dd, t_ptr->ds); - take_hit(dam, t_ptr->name); -} - -/* - * this function activates one trap type, and returns - * a bool_ indicating if this trap is now identified - */ -bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item) -{ - bool_ ident = FALSE; - s16b trap; - - s16b k, l; - - trap = cave[y][x].t_idx; - - if (i_ptr != NULL) - { - trap = i_ptr->pval; - } - - switch (trap) - { - /* stat traps */ - case TRAP_OF_WEAKNESS_I: - ident = do_dec_stat(A_STR, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_WEAKNESS_II: - ident = do_dec_stat(A_STR, STAT_DEC_NORMAL); - break; - case TRAP_OF_WEAKNESS_III: - ident = do_dec_stat(A_STR, STAT_DEC_PERMANENT); - break; - case TRAP_OF_INTELLIGENCE_I: - ident = do_dec_stat(A_INT, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_INTELLIGENCE_II: - ident = do_dec_stat(A_INT, STAT_DEC_NORMAL); - break; - case TRAP_OF_INTELLIGENCE_III: - ident = do_dec_stat(A_INT, STAT_DEC_PERMANENT); - break; - case TRAP_OF_WISDOM_I: - ident = do_dec_stat(A_WIS, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_WISDOM_II: - ident = do_dec_stat(A_WIS, STAT_DEC_NORMAL); - break; - case TRAP_OF_WISDOM_III: - ident = do_dec_stat(A_WIS, STAT_DEC_PERMANENT); - break; - case TRAP_OF_FUMBLING_I: - ident = do_dec_stat(A_DEX, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_FUMBLING_II: - ident = do_dec_stat(A_DEX, STAT_DEC_NORMAL); - break; - case TRAP_OF_FUMBLING_III: - ident = do_dec_stat(A_DEX, STAT_DEC_PERMANENT); - break; - case TRAP_OF_WASTING_I: - ident = do_dec_stat(A_CON, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_WASTING_II: - ident = do_dec_stat(A_CON, STAT_DEC_NORMAL); - break; - case TRAP_OF_WASTING_III: - ident = do_dec_stat(A_CON, STAT_DEC_PERMANENT); - break; - case TRAP_OF_BEAUTY_I: - ident = do_dec_stat(A_CHR, STAT_DEC_TEMPORARY); - break; - case TRAP_OF_BEAUTY_II: - ident = do_dec_stat(A_CHR, STAT_DEC_NORMAL); - break; - case TRAP_OF_BEAUTY_III: - ident = do_dec_stat(A_CHR, STAT_DEC_PERMANENT); - break; - - /* Trap of Curse Weapon */ - case TRAP_OF_CURSE_WEAPON: - { - ident = curse_weapon(); - break; - } - - /* Trap of Curse Armor */ - case TRAP_OF_CURSE_ARMOR: - { - ident = curse_armor(); - break; - } - - /* Earthquake Trap */ - case TRAP_OF_EARTHQUAKE: - { - msg_print("As you touch the trap, the ground starts to shake."); - earthquake(y, x, 10); - ident = TRUE; - break; - } - - /* Poison Needle Trap */ - case TRAP_OF_POISON_NEEDLE: - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - msg_print("You prick yourself on a poisoned needle."); - (void)set_poisoned(p_ptr->poisoned + rand_int(15) + 10); - ident = TRUE; - } - else - { - msg_print("You prick yourself on a needle."); - } - break; - } - - /* Summon Monster Trap */ - case TRAP_OF_SUMMON_MONSTER: - { - msg_print("A spell hangs in the air."); - for (k = 0; k < randint(3); k++) - { - ident |= summon_specific(y, x, max_dlv[dungeon_type], 0); - } - break; - } - - /* Summon Undead Trap */ - case TRAP_OF_SUMMON_UNDEAD: - { - msg_print("A mighty spell hangs in the air."); - for (k = 0; k < randint(3); k++) - { - ident |= summon_specific(y, x, max_dlv[dungeon_type], - SUMMON_UNDEAD); - } - break; - } - - /* Summon Greater Undead Trap */ - case TRAP_OF_SUMMON_GREATER_UNDEAD: - { - msg_print("An old and evil spell hangs in the air."); - for (k = 0; k < randint(3); k++) - { - ident |= summon_specific(y, x, max_dlv[dungeon_type], - SUMMON_HI_UNDEAD); - } - break; - } - - /* Teleport Trap */ - case TRAP_OF_TELEPORT: - { - msg_print("The world whirls around you."); - teleport_player(RATIO * 67); - ident = TRUE; - break; - } - - /* Paralyzing Trap */ - case TRAP_OF_PARALYZING: - { - if (!p_ptr->free_act) - { - msg_print("You touch a poisoned part and can't move."); - (void)set_paralyzed(rand_int(10) + 10); - ident = TRUE; - } - else - { - msg_print("You prick yourself on a needle."); - } - break; - } - - /* Explosive Device */ - case TRAP_OF_EXPLOSIVE_DEVICE: - { - msg_print("A hidden explosive device explodes in your face."); - take_hit(damroll(5, 8), "an explosion"); - ident = TRUE; - break; - } - - /* Teleport Away Trap */ - case TRAP_OF_TELEPORT_AWAY: - { - /* teleport away all items */ - while (!cave[y][x].o_idxs.empty()) - { - auto item = cave[y][x].o_idxs.front(); - - object_type *o_ptr = &o_list[item]; - - int amt = o_ptr->number; - - ident = do_trap_teleport_away(o_ptr, y, x); - - floor_item_increase(item, -amt); - floor_item_optimize(item); - } - break; - } - - /* Lose Memory Trap */ - case TRAP_OF_LOSE_MEMORY: - { - lose_exp(p_ptr->exp / 4); - - ident |= dec_stat(A_WIS, rand_int(20) + 10, STAT_DEC_NORMAL); - ident |= dec_stat(A_INT, rand_int(20) + 10, STAT_DEC_NORMAL); - - if (!p_ptr->resist_conf) - { - ident |= set_confused(p_ptr->confused + rand_int(100) + 50); - } - - if (ident) - { - msg_print("You suddenly don't remember what you were doing."); - } - else - { - msg_print("You feel an alien force probing your mind."); - } - break; - } - /* Bitter Regret Trap */ - case TRAP_OF_BITTER_REGRET: - { - msg_print("An age-old and hideous-sounding spell reverberates off the walls."); - - ident |= dec_stat(A_DEX, 25, TRUE); - ident |= dec_stat(A_WIS, 25, TRUE); - ident |= dec_stat(A_CON, 25, TRUE); - ident |= dec_stat(A_STR, 25, TRUE); - ident |= dec_stat(A_CHR, 25, TRUE); - ident |= dec_stat(A_INT, 25, TRUE); - break; - } - - /* Bowel Cramps Trap */ - case TRAP_OF_BOWEL_CRAMPS: - { - msg_print("A wretched-smelling gas cloud upsets your stomach."); - - (void)set_food(PY_FOOD_STARVE - 1); - (void)set_poisoned(0); - - if (!p_ptr->free_act) - { - (void)set_paralyzed(rand_int(dun_level) + 6); - } - ident = TRUE; - break; - } - - /* Blindness/Confusion Trap */ - case TRAP_OF_BLINDNESS_CONFUSION: - { - msg_print("A powerful magic protected this."); - - if (!p_ptr->resist_blind) - { - ident |= set_blind(p_ptr->blind + rand_int(100) + 100); - } - if (!p_ptr->resist_conf) - { - ident |= set_confused(p_ptr->confused + rand_int(20) + 15); - } - break; - } - - /* Aggravation Trap */ - case TRAP_OF_AGGRAVATION: - { - msg_print("You hear a hollow noise echoing through the dungeons."); - aggravate_monsters(1); - break; - } - - /* Multiplication Trap */ - case TRAP_OF_MULTIPLICATION: - { - msg_print("You hear a loud click."); - for (k = -1; k <= 1; k++) - for (l = -1; l <= 1; l++) - { - if ((in_bounds(p_ptr->py + l, p_ptr->px + k)) && - (!cave[p_ptr->py + l][p_ptr->px + k].t_idx)) - { - place_trap(p_ptr->py + l, p_ptr->px + k); - } - } - ident = TRUE; - break; - } - - /* Steal Item Trap */ - case TRAP_OF_STEAL_ITEM: - { - /* - * please note that magical stealing is not so - * easily circumvented - */ - if (!p_ptr->paralyzed && - (rand_int(160) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] + - p_ptr->lev))) - { - /* Saving throw message */ - msg_print("Your backpack seems to vibrate strangely!"); - break; - } - - /* Find an item */ - for (k = 0; k < rand_int(10); k++) - { - char i_name[80]; - object_type *j_ptr, *q_ptr, forge; - - /* Pick an item */ - s16b i = rand_int(INVEN_PACK); - - /* Obtain the item */ - j_ptr = &p_ptr->inventory[i]; - - /* Accept real items */ - if (!j_ptr->k_idx) continue; - - /* Don't steal artifacts -CFT */ - if (artifact_p(j_ptr)) continue; - - /* Get a description */ - object_desc(i_name, j_ptr, FALSE, 3); - - /* Message */ - msg_format("%sour %s (%c) was stolen!", - ((j_ptr->number > 1) ? "One of y" : "Y"), - i_name, index_to_label(i)); - - /* Create the item */ - q_ptr = &forge; - object_copy(q_ptr, j_ptr); - q_ptr->number = 1; - - /* Drop it somewhere */ - do_trap_teleport_away(q_ptr, y, x); - - inc_stack_size_ex(i, -1, OPTIMIZE, NO_DESCRIBE); - - ident = TRUE; - } - break; - } - - /* Summon Fast Quylthulgs Trap */ - case TRAP_OF_SUMMON_FAST_QUYLTHULGS: - { - for (k = 0; k < randint(3); k++) - { - ident |= summon_specific(y, x, max_dlv[dungeon_type], SUMMON_QUYLTHULG); - } - - if (ident) - { - msg_print("You suddenly have company."); - (void)set_slow(p_ptr->slow + randint(25) + 15); - } - break; - } - - /* Trap of Sinking */ - case TRAP_OF_SINKING: - { - msg_print("You fell through a trap door!"); - - if (p_ptr->ffall) - { - if (dungeon_flags1 & DF1_TOWER) - { - msg_print("You float gently down to the previous level."); - } - else - { - msg_print("You float gently down to the next level."); - } - } - else - { - take_hit(damroll(2, 8), "a trap door"); - } - - /* Still alive and autosave enabled */ - if (p_ptr->chp >= 0) - { - autosave_checkpoint(); - } - - if (dungeon_flags1 & DF1_TOWER) dun_level--; - else dun_level++; - - /* Leaving */ - p_ptr->leaving = TRUE; - break; - } - - /* Trap of Mana Drain */ - case TRAP_OF_MANA_DRAIN: - { - if (p_ptr->csp > 0) - { - p_ptr->csp = 0; - p_ptr->csp_frac = 0; - p_ptr->redraw |= (PR_FRAME); - msg_print("You sense a great loss."); - ident = TRUE; - } - else if (p_ptr->msp == 0) - { - /* no sense saying this unless you never have mana */ - msg_format("Suddenly you feel glad you're a mere %s", - spp_ptr->title); - } - else - { - msg_print("Your head feels dizzy for a moment."); - } - break; - } - /* Trap of Missing Money */ - case TRAP_OF_MISSING_MONEY: - { - s32b gold = (p_ptr->au / 10) + randint(25); - - if (gold < 2) gold = 2; - if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000); - if (gold > p_ptr->au) gold = p_ptr->au; - - p_ptr->au -= gold; - if (gold <= 0) - { - msg_print("You feel something touching you."); - } - else if (p_ptr->au) - { - msg_print("Your purse feels lighter."); - msg_format("%ld coins were stolen!", (long)gold); - ident = TRUE; - } - else - { - msg_print("Your purse feels empty."); - msg_print("All of your coins were stolen!"); - ident = TRUE; - } - p_ptr->redraw |= (PR_FRAME); - break; - } - - /* Trap of No Return */ - case TRAP_OF_NO_RETURN: - { - object_type *j_ptr; - s16b j; - - for (j = 0; j < INVEN_WIELD; j++) - { - if (!p_ptr->inventory[j].k_idx) continue; - - j_ptr = &p_ptr->inventory[j]; - - if ((j_ptr->tval == TV_SCROLL) && - (j_ptr->sval == SV_SCROLL_WORD_OF_RECALL)) - { - inc_stack_size_ex(j, -j_ptr->number, OPTIMIZE, NO_DESCRIBE); - - combine_pack(); - reorder_pack(); - - if (!ident) - { - msg_print("A small fire works its way through your backpack. " - "Some scrolls are burnt."); - } - else - { - msg_print("The fire hasn't finished."); - } - ident = TRUE; - } - else if ((j_ptr->tval == TV_ROD_MAIN) && - (j_ptr->pval == SV_ROD_RECALL)) - { - j_ptr->timeout = 0; /* a long time */ - if (!ident) msg_print("You feel the air stabilise around you."); - ident = TRUE; - } - } - if ((!ident) && (p_ptr->word_recall)) - { - msg_print("You feel like staying around."); - p_ptr->word_recall = 0; - ident = TRUE; - } - break; - } - - /* Trap of Silent Switching */ - case TRAP_OF_SILENT_SWITCHING: - { - s16b i, j, slot1, slot2; - object_type *j_ptr, *k_ptr; - u32b f1, f2, f3, f4, f5, esp; - - for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) - { - j_ptr = &p_ptr->inventory[i]; - - if (!j_ptr->k_idx) continue; - - /* Do not allow this trap to touch the One Ring */ - object_flags(j_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if(f3 & TR3_PERMA_CURSE) continue; - - slot1 = wield_slot(j_ptr); - - for (j = 0; j < INVEN_WIELD; j++) - { - k_ptr = &p_ptr->inventory[j]; - - if (!k_ptr->k_idx) continue; - - /* Do not allow this trap to touch the One Ring */ - object_flags(k_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if(f3 & TR3_PERMA_CURSE) continue; - - /* this is a crude hack, but it prevent wielding 6 torches... */ - if (k_ptr->number > 1) continue; - - slot2 = wield_slot(k_ptr); - - /* a chance of 4 in 5 of switching something, then 2 in 5 to do it again */ - if ((slot1 == slot2) && - (rand_int(100) < (80 - (ident * 40)))) - { - object_type tmp_obj; - - if (p_ptr->inventory[j].name1) - wield_set(p_ptr->inventory[j].name1, a_info[p_ptr->inventory[j].name1].set, FALSE); - if (p_ptr->inventory[i].name1) - takeoff_set(p_ptr->inventory[i].name1, a_info[p_ptr->inventory[i].name1].set); - - tmp_obj = p_ptr->inventory[j]; - p_ptr->inventory[j] = p_ptr->inventory[i]; - p_ptr->inventory[i] = tmp_obj; - ident = TRUE; - } - } - } - - if (ident) - { - p_ptr->update |= (PU_BONUS); - p_ptr->update |= (PU_TORCH); - p_ptr->update |= (PU_MANA); - msg_print("You somehow feel like another person."); - } - else - { - msg_print("You feel a lack of useful items."); - } - break; - } - - /* Trap of Walls */ - case TRAP_OF_WALLS: - { - ident = player_handle_trap_of_walls(); - break; - } - - /* Trap of Calling Out */ - case TRAP_OF_CALLING_OUT: - { - ident = do_player_trap_call_out(); - - if (!ident) - { - /* Increase "afraid" */ - if (p_ptr->resist_fear) - { - msg_print("You feel as if you had a nightmare!"); - } - else if (rand_int(100) < p_ptr->skill_sav) - { - msg_print("You remember having a nightmare!"); - } - else - { - if (set_afraid(p_ptr->afraid + 3 + randint(40))) - { - msg_print("You have a vision of a powerful enemy."); - } - } - } - break; - } - - /* Trap of Sliding */ - case TRAP_OF_SLIDING: - break; - - /* Trap of Charges Drain */ - case TRAP_OF_CHARGES_DRAIN: - { - /* Find an item */ - for (k = 0; k < 10; k++) - { - s16b i = rand_int(INVEN_PACK); - - object_type *j_ptr = &p_ptr->inventory[i]; - - /* Drain charged wands/staffs - Hack -- don't let artifacts get drained */ - if (((j_ptr->tval == TV_STAFF) || - (j_ptr->tval == TV_WAND)) && - (j_ptr->pval) && - !artifact_p(j_ptr)) - { - ident = TRUE; - j_ptr->pval = j_ptr->pval / (randint(4) + 1); - - /* 60% chance of only 1 */ - if (randint(10) > 3) break; - } - } - - if (ident) - { - /* Window stuff */ - p_ptr->window |= PW_INVEN; - /* Combine / Reorder the pack */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - msg_print("Your backpack seems to be turned upside down."); - } - else - { - msg_print("You hear a wail of great disappointment."); - } - break; - } - - /* Trap of Stair Movement */ - case TRAP_OF_STAIR_MOVEMENT: - { - s16b cx, cy, i, j; - s16b cnt = 0; - s16b cnt_seen = 0; - s16b tmps, tmpx; - s16b tmpspecial, tmpspecial2; - u32b tmpf; - bool_ seen = FALSE; - s16b index_x[20], index_y[20]; /* 20 stairs per level is enough? */ - cave_type *cv_ptr; - - if (max_dlv[dungeon_type] == 99) - { - /* no sense in relocating that stair! */ - msg_print("You have a feeling that this trap could be dangerous."); - break; - } - - for (cx = 0; cx < cur_wid; cx++) - for (cy = 0; cy < cur_hgt; cy++) - { - cv_ptr = &cave[cy][cx]; - - if ((cv_ptr->feat != FEAT_LESS) && - (cv_ptr->feat != FEAT_MORE) && - (cv_ptr->feat != FEAT_SHAFT_UP) && - (cv_ptr->feat != FEAT_SHAFT_DOWN)) continue; - - index_x[cnt] = cx; - index_y[cnt] = cy; - cnt++; - } - - if (cnt == 0) - { - if (wizard) msg_print("Executing moving stairs trap on level with no stairs!"); - break; - } - - for (i = 0; i < cnt; i++) - { - seen = FALSE; - - for (j = 0; j < 10; j++) /* try 10 times to relocate */ - { - cave_type *cv_ptr = &cave[index_y[i]][index_x[i]]; - cave_type *cv_ptr2; - - cx = rand_int(cur_wid); - cy = rand_int(cur_hgt); - - if ((cx == index_x[i]) || (cy == index_y[i])) continue; - - cv_ptr2 = &cave[cy][cx]; - - if (!cave_valid_bold(cy, cx) || (!cv_ptr2->o_idxs.empty())) continue; - - /* don't put anything in vaults */ - if (cv_ptr2->info & CAVE_ICKY) continue; - - tmpx = cv_ptr2->mimic; - tmps = cv_ptr2->info; - tmpf = cv_ptr2->feat; - tmpspecial = cv_ptr2->special; - tmpspecial2 = cv_ptr2->special2; - cave[cy][cx].mimic = cv_ptr->mimic; - cave[cy][cx].info = cv_ptr->info; - cave[cy][cx].special = cv_ptr->special; - cave[cy][cx].special2 = cv_ptr->special2; - cave_set_feat(cy, cx, cv_ptr->feat); - cv_ptr->mimic = tmpx; - cv_ptr->info = tmps; - cv_ptr->special = tmpspecial; - cv_ptr->special2 = tmpspecial2; - cave_set_feat(index_y[i], index_x[i], tmpf); - - /* if we are placing walls in rooms, make them rubble instead */ - if ((cv_ptr->info & CAVE_ROOM) && - (cv_ptr->feat >= FEAT_WALL_EXTRA) && - (cv_ptr->feat <= FEAT_PERM_SOLID)) - { - cave_set_feat(index_y[i], index_x[i], FEAT_RUBBLE); - } - - if (player_has_los_bold(cy, cx)) - { - note_spot(cy, cx); - lite_spot(cy, cx); - seen = TRUE; - } - else - { - cv_ptr2->info &= ~CAVE_MARK; - } - - if (player_has_los_bold(index_y[i], index_x[i])) - { - note_spot(index_y[i], index_x[i]); - lite_spot(index_y[i], index_x[i]); - seen = TRUE; - } - else - { - cv_ptr->info &= ~CAVE_MARK; - } - break; - } - - if (seen) cnt_seen++; - } - - ident = (cnt_seen > 0); - - if ((ident) && (cnt_seen > 1)) - { - msg_print("You see some stairs move."); - } - else if (ident) - { - msg_print("You see a stair move."); - } - else - { - msg_print("You hear distant scraping noises."); - } - p_ptr->redraw |= PR_MAP; - break; - } - - /* Trap of New Trap */ - case TRAP_OF_NEW: - { - /* if we're on a floor or on a door, place a new trap */ - if ((item == -1) || (item == -2)) - { - place_trap(y, x); - if (player_has_los_bold(y, x)) - { - note_spot(y, x); - lite_spot(y, x); - } - } - else - { - /* re-trap the chest */ - place_trap(y, x); - } - msg_print("You hear a noise, and then its echo."); - ident = FALSE; - break; - } - - /* Trap of Acquirement */ - case TRAP_OF_ACQUIREMENT: - { - /* Get a nice thing */ - msg_print("You notice something falling off the trap."); - acquirement(y, x, 1, TRUE, FALSE); - - /* If we're on a floor or on a door, place a new trap */ - if ((item == -1) || (item == -2)) - { - place_trap(y, x); - if (player_has_los_bold(y, x)) - { - note_spot(y, x); - lite_spot(y, x); - } - } - else - { - /* Re-trap the chest */ - place_trap(y, x); - } - msg_print("You hear a noise, and then its echo."); - - /* Never known */ - ident = FALSE; - } - break; - - /* Trap of Scatter Items */ - case TRAP_OF_SCATTER_ITEMS: - { - s16b i, j; - bool_ message = FALSE; - - for (i = 0; i < INVEN_PACK; i++) - { - - if (!p_ptr->inventory[i].k_idx) continue; - - if (rand_int(10) < 3) continue; - - for (j = 0; j < 10; j++) - { - object_type tmp_obj, *j_ptr = &tmp_obj; - s16b cx = x + 15 - rand_int(30); - s16b cy = y + 15 - rand_int(30); - - if (!in_bounds(cy, cx)) continue; - - if (!cave_floor_bold(cy, cx)) continue; - - object_copy(j_ptr, &p_ptr->inventory[i]); - - inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE); - - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - (void)floor_carry(cy, cx, j_ptr); - - if (!message) - { - msg_print("You feel light-footed."); - message = TRUE; - } - - if (player_has_los_bold(cy, cx)) - { - char i_name[80]; - - object_desc(i_name, &tmp_obj, TRUE, 3); - note_spot(cy, cx); - lite_spot(cy, cx); - ident = TRUE; - msg_format("Suddenly %s appear%s!", i_name, - (j_ptr->number > 1) ? "" : "s"); - } - break; - } - } - ident = message; - break; - } - - /* Trap of Decay */ - case TRAP_OF_DECAY: - break; - - /* Trap of Wasting Wands */ - case TRAP_OF_WASTING_WANDS: - { - s16b i; - object_type *j_ptr; - - for (i = 0; i < INVEN_PACK; i++) - { - if (!p_ptr->inventory[i].k_idx) continue; - - j_ptr = &p_ptr->inventory[i]; - - if ((j_ptr->tval == TV_WAND) && (rand_int(5) == 1)) - { - if (object_known_p(j_ptr)) ident = TRUE; - - /* Create a Wand of Nothing */ - object_prep(j_ptr, lookup_kind(TV_WAND, SV_WAND_NOTHING)); - apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0)); - j_ptr->ident &= ~IDENT_KNOWN; - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - } - else if ((j_ptr->tval == TV_STAFF) && (rand_int(5) == 1)) - { - if (object_known_p(j_ptr)) ident = TRUE; - - /* Create a Staff of Nothing */ - object_prep(j_ptr, lookup_kind(TV_STAFF, SV_STAFF_NOTHING)); - apply_magic(j_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0)); - j_ptr->ident &= ~IDENT_KNOWN; - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - } - } - if (ident) - { - msg_print("You have lost trust in your backpack!"); - } - else - { - msg_print("You hear an echoing cry of rage."); - } - break; - } - - /* Trap of Filling */ - case TRAP_OF_FILLING: - { - s16b nx, ny; - - for (nx = x - 8; nx <= x + 8; nx++) - for (ny = y - 8; ny <= y + 8; ny++) - { - if (!in_bounds (ny, nx)) continue; - - if (rand_int(distance(ny, nx, y, x)) > 3) - { - place_trap(ny, nx); - } - } - - msg_print("The floor vibrates in a strange way."); - ident = FALSE; - break; - } - - case TRAP_OF_DRAIN_SPEED: - { - object_type *j_ptr; - s16b j, chance = 75; - u32b f1, f2, f3, f4, f5, esp; - - for (j = 0; j < INVEN_TOTAL; j++) - { - /* don't bother the overflow slot */ - if (j == INVEN_PACK) continue; - - if (!p_ptr->inventory[j].k_idx) continue; - - j_ptr = &p_ptr->inventory[j]; - object_flags(j_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* is it a non-artifact speed item? */ - if ((!j_ptr->name1) && (f1 & TR1_SPEED)) - { - if (randint(100) < chance) - { - j_ptr->pval = j_ptr->pval / 2; - if (j_ptr->pval == 0) - { - j_ptr->pval--; - } - chance /= 2; - ident = TRUE; - } - inven_item_optimize(j); - } - } - if (!ident) - { - msg_print("You feel some things in your pack vibrating."); - } - else - { - combine_pack(); - reorder_pack(); - msg_print("You suddenly feel you have time for self-reflection."); - - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - /* Recalculate mana */ - p_ptr->update |= (PU_MANA); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - } - break; - } - - /* - * single missile traps - */ - case TRAP_OF_ARROW_I: - ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_NORMAL, 4, 8, 0, "Arrow Trap"); - break; - case TRAP_OF_ARROW_II: - ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_NORMAL, 5, 8, 0, "Bolt Trap"); - break; - case TRAP_OF_ARROW_III: - ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_HEAVY, 6, 8, 0, "Seeker Arrow Trap"); - break; - case TRAP_OF_ARROW_IV: - ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_HEAVY, 8, 10, 0, "Seeker Bolt Trap"); - break; - case TRAP_OF_POISON_ARROW_I: - ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_NORMAL, 4, 8, 10 + randint(20), "Poison Arrow Trap"); - break; - case TRAP_OF_POISON_ARROW_II: - ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_NORMAL, 5, 8, 15 + randint(30), "Poison Bolt Trap"); - break; - case TRAP_OF_POISON_ARROW_III: - ident = player_handle_missile_trap(1, TV_ARROW, SV_AMMO_HEAVY, 6, 8, 30 + randint(50), "Poison Seeker Arrow Trap"); - break; - case TRAP_OF_POISON_ARROW_IV: - ident = player_handle_missile_trap(1, TV_BOLT, SV_AMMO_HEAVY, 8, 10, 40 + randint(70), "Poison Seeker Bolt Trap"); - break; - case TRAP_OF_DAGGER_I: - ident = player_handle_missile_trap(1, TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 0, "Dagger Trap"); - break; - case TRAP_OF_DAGGER_II: - ident = player_handle_missile_trap(1, TV_SWORD, SV_DAGGER, 3, 8, 0, "Dagger Trap"); - break; - case TRAP_OF_POISON_DAGGER_I: - ident = player_handle_missile_trap(1, TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 15 + randint(20), "Poison Dagger Trap"); - break; - case TRAP_OF_POISON_DAGGER_II: - ident = player_handle_missile_trap(1, TV_SWORD, SV_DAGGER, 3, 8, 20 + randint(30), "Poison Dagger Trap"); - break; - - /* - * multiple missile traps - * numbers range from 2 (level 0 to 14) to 10 (level 120 and up) - */ - case TRAP_OF_ARROWS_I: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_NORMAL, 4, 8, 0, "Arrow Trap"); - break; - case TRAP_OF_ARROWS_II: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_NORMAL, 5, 8, 0, "Bolt Trap"); - break; - case TRAP_OF_ARROWS_III: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_HEAVY, 6, 8, 0, "Seeker Arrow Trap"); - break; - case TRAP_OF_ARROWS_IV: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_HEAVY, 8, 10, 0, "Seeker Bolt Trap"); - break; - case TRAP_OF_POISON_ARROWS_I: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_NORMAL, 4, 8, 10 + randint(20), "Poison Arrow Trap"); - break; - case TRAP_OF_POISON_ARROWS_II: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_NORMAL, 5, 8, 15 + randint(30), "Poison Bolt Trap"); - break; - case TRAP_OF_POISON_ARROWS_III: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_ARROW, SV_AMMO_HEAVY, 6, 8, 30 + randint(50), "Poison Seeker Arrow Trap"); - break; - case TRAP_OF_POISON_ARROWS_IV: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_BOLT, SV_AMMO_HEAVY, 8, 10, 40 + randint(70), "Poison Seeker Bolt Trap"); - break; - case TRAP_OF_DAGGERS_I: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 0, "Dagger Trap"); - break; - case TRAP_OF_DAGGERS_II: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_DAGGER, 3, 8, 0, "Dagger Trap"); - break; - case TRAP_OF_POISON_DAGGERS_I: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_BROKEN_DAGGER, 2, 8, 15 + randint(20), "Poison Dagger Trap"); - break; - case TRAP_OF_POISON_DAGGERS_II: - ident = player_handle_missile_trap(2 + (max_dlv[dungeon_type] / 15), TV_SWORD, SV_DAGGER, 3, 8, 20 + randint(30), "Poison Dagger Trap"); - break; - - case TRAP_OF_DROP_ITEMS: - { - s16b i; - bool_ message = FALSE; - - for (i = 0; i < INVEN_PACK; i++) - { - object_type tmp_obj; - - if (!p_ptr->inventory[i].k_idx) continue; - if (randint(100) < 80) continue; - if (p_ptr->inventory[i].name1 == ART_POWER) continue; - - tmp_obj = p_ptr->inventory[i]; - - /* drop carefully */ - drop_near(&tmp_obj, 0, y, x); - - inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE); - - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - if (!message) - { - msg_print("You are startled by a sudden sound."); - message = TRUE; - } - ident = TRUE; - } - if (!ident) - { - msg_print("You hear a sudden, strange sound."); - } - break; - } - - case TRAP_OF_DROP_ALL_ITEMS: - { - s16b i; - bool_ message = FALSE; - - for (i = 0; i < INVEN_PACK; i++) - { - object_type tmp_obj; - - if (!p_ptr->inventory[i].k_idx) continue; - if (randint(100) < 10) continue; - if (p_ptr->inventory[i].name1 == ART_POWER) continue; - - tmp_obj = p_ptr->inventory[i]; - - /* drop carefully */ - drop_near(&tmp_obj, 0, y, x); - - inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE); - - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - if (!message) - { - msg_print("You are greatly startled by a sudden sound."); - message = TRUE; - } - ident = TRUE; - } - if (!ident) - { - msg_print("You hear a sudden, strange sound."); - } - break; - } - - case TRAP_OF_DROP_EVERYTHING: - { - s16b i; - bool_ message = FALSE; - - for (i = 0; i < INVEN_TOTAL; i++) - { - object_type tmp_obj; - if (!p_ptr->inventory[i].k_idx) continue; - if (randint(100) < 30) continue; - if (p_ptr->inventory[i].name1 == ART_POWER) continue; - - tmp_obj = p_ptr->inventory[i]; - /* drop carefully */ - - drop_near(&tmp_obj, 0, y, x); - - inc_stack_size_ex(i, -999, OPTIMIZE, NO_DESCRIBE); - - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - if (!message) - { - msg_print("You are completely startled by a sudden sound."); - message = TRUE; - } - ident = TRUE; - } - if (!ident) - { - msg_print("You hear a sudden, strange sound."); - } - break; - } - - /* Bolt Trap */ - case TRAP_G_ELEC_BOLT: - ident = player_handle_breath_trap(1, GF_ELEC, TRAP_G_ELEC_BOLT); - break; - case TRAP_G_POIS_BOLT: - ident = player_handle_breath_trap(1, GF_POIS, TRAP_G_POIS_BOLT); - break; - case TRAP_G_ACID_BOLT: - ident = player_handle_breath_trap(1, GF_ACID, TRAP_G_ACID_BOLT); - break; - case TRAP_G_COLD_BOLT: - ident = player_handle_breath_trap(1, GF_COLD, TRAP_G_COLD_BOLT); - break; - case TRAP_G_FIRE_BOLT: - ident = player_handle_breath_trap(1, GF_FIRE, TRAP_G_FIRE_BOLT); - break; - case TRAP_OF_ELEC_BOLT: - ident = player_handle_breath_trap(1, GF_ELEC, TRAP_OF_ELEC_BOLT); - break; - case TRAP_OF_POIS_BOLT: - ident = player_handle_breath_trap(1, GF_POIS, TRAP_OF_POIS_BOLT); - break; - case TRAP_OF_ACID_BOLT: - ident = player_handle_breath_trap(1, GF_ACID, TRAP_OF_ACID_BOLT); - break; - case TRAP_OF_COLD_BOLT: - ident = player_handle_breath_trap(1, GF_COLD, TRAP_OF_COLD_BOLT); - break; - case TRAP_OF_FIRE_BOLT: - ident = player_handle_breath_trap(1, GF_FIRE, TRAP_OF_FIRE_BOLT); - break; - case TRAP_OF_PLASMA_BOLT: - ident = player_handle_breath_trap(1, GF_PLASMA, TRAP_OF_PLASMA_BOLT); - break; - case TRAP_OF_WATER_BOLT: - ident = player_handle_breath_trap(1, GF_WATER, TRAP_OF_WATER_BOLT); - break; - case TRAP_OF_LITE_BOLT: - ident = player_handle_breath_trap(1, GF_LITE, TRAP_OF_LITE_BOLT); - break; - case TRAP_OF_DARK_BOLT: - ident = player_handle_breath_trap(1, GF_DARK, TRAP_OF_DARK_BOLT); - break; - case TRAP_OF_SHARDS_BOLT: - ident = player_handle_breath_trap(1, GF_SHARDS, TRAP_OF_SHARDS_BOLT); - break; - case TRAP_OF_SOUND_BOLT: - ident = player_handle_breath_trap(1, GF_SOUND, TRAP_OF_SOUND_BOLT); - break; - case TRAP_OF_CONFUSION_BOLT: - ident = player_handle_breath_trap(1, GF_CONFUSION, TRAP_OF_CONFUSION_BOLT); - break; - case TRAP_OF_FORCE_BOLT: - ident = player_handle_breath_trap(1, GF_FORCE, TRAP_OF_FORCE_BOLT); - break; - case TRAP_OF_INERTIA_BOLT: - ident = player_handle_breath_trap(1, GF_INERTIA, TRAP_OF_INERTIA_BOLT); - break; - case TRAP_OF_MANA_BOLT: - ident = player_handle_breath_trap(1, GF_MANA, TRAP_OF_MANA_BOLT); - break; - case TRAP_OF_ICE_BOLT: - ident = player_handle_breath_trap(1, GF_ICE, TRAP_OF_ICE_BOLT); - break; - case TRAP_OF_CHAOS_BOLT: - ident = player_handle_breath_trap(1, GF_CHAOS, TRAP_OF_CHAOS_BOLT); - break; - case TRAP_OF_NETHER_BOLT: - ident = player_handle_breath_trap(1, GF_NETHER, TRAP_OF_NETHER_BOLT); - break; - case TRAP_OF_DISENCHANT_BOLT: - ident = player_handle_breath_trap(1, GF_DISENCHANT, TRAP_OF_DISENCHANT_BOLT); - break; - case TRAP_OF_NEXUS_BOLT: - ident = player_handle_breath_trap(1, GF_NEXUS, TRAP_OF_NEXUS_BOLT); - break; - case TRAP_OF_TIME_BOLT: - ident = player_handle_breath_trap(1, GF_TIME, TRAP_OF_TIME_BOLT); - break; - case TRAP_OF_GRAVITY_BOLT: - ident = player_handle_breath_trap(1, GF_GRAVITY, TRAP_OF_GRAVITY_BOLT); - break; - - /* Ball Trap */ - case TRAP_OF_ELEC_BALL: - ident = player_handle_breath_trap(3, GF_ELEC, TRAP_OF_ELEC_BALL); - break; - case TRAP_OF_POIS_BALL: - ident = player_handle_breath_trap(3, GF_POIS, TRAP_OF_POIS_BALL); - break; - case TRAP_OF_ACID_BALL: - ident = player_handle_breath_trap(3, GF_ACID, TRAP_OF_ACID_BALL); - break; - case TRAP_OF_COLD_BALL: - ident = player_handle_breath_trap(3, GF_COLD, TRAP_OF_COLD_BALL); - break; - case TRAP_OF_FIRE_BALL: - ident = player_handle_breath_trap(3, GF_FIRE, TRAP_OF_FIRE_BALL); - break; - case TRAP_OF_PLASMA_BALL: - ident = player_handle_breath_trap(3, GF_PLASMA, TRAP_OF_PLASMA_BALL); - break; - case TRAP_OF_WATER_BALL: - ident = player_handle_breath_trap(3, GF_WATER, TRAP_OF_WATER_BALL); - break; - case TRAP_OF_LITE_BALL: - ident = player_handle_breath_trap(3, GF_LITE, TRAP_OF_LITE_BALL); - break; - case TRAP_OF_DARK_BALL: - ident = player_handle_breath_trap(3, GF_DARK, TRAP_OF_DARK_BALL); - break; - case TRAP_OF_SHARDS_BALL: - ident = player_handle_breath_trap(3, GF_SHARDS, TRAP_OF_SHARDS_BALL); - break; - case TRAP_OF_SOUND_BALL: - ident = player_handle_breath_trap(3, GF_SOUND, TRAP_OF_SOUND_BALL); - break; - case TRAP_OF_CONFUSION_BALL: - ident = player_handle_breath_trap(3, GF_CONFUSION, TRAP_OF_CONFUSION_BALL); - break; - case TRAP_OF_FORCE_BALL: - ident = player_handle_breath_trap(3, GF_FORCE, TRAP_OF_FORCE_BALL); - break; - case TRAP_OF_INERTIA_BALL: - ident = player_handle_breath_trap(3, GF_INERTIA, TRAP_OF_INERTIA_BALL); - break; - case TRAP_OF_MANA_BALL: - ident = player_handle_breath_trap(3, GF_MANA, TRAP_OF_MANA_BALL); - break; - case TRAP_OF_ICE_BALL: - ident = player_handle_breath_trap(3, GF_ICE, TRAP_OF_ICE_BALL); - break; - case TRAP_OF_CHAOS_BALL: - ident = player_handle_breath_trap(3, GF_CHAOS, TRAP_OF_CHAOS_BALL); - break; - case TRAP_OF_NETHER_BALL: - ident = player_handle_breath_trap(3, GF_NETHER, TRAP_OF_NETHER_BALL); - break; - case TRAP_OF_DISENCHANT_BALL: - ident = player_handle_breath_trap(3, GF_DISENCHANT, TRAP_OF_DISENCHANT_BALL); - break; - case TRAP_OF_NEXUS_BALL: - ident = player_handle_breath_trap(3, GF_NEXUS, TRAP_OF_NEXUS_BALL); - break; - case TRAP_OF_TIME_BALL: - ident = player_handle_breath_trap(3, GF_TIME, TRAP_OF_TIME_BALL); - break; - case TRAP_OF_GRAVITY_BALL: - ident = player_handle_breath_trap(3, GF_GRAVITY, TRAP_OF_GRAVITY_BALL); - break; - - /* -SC- */ - case TRAP_OF_FEMINITY: - { - msg_print("Gas sprouts out... you feel yourself transmute."); - p_ptr->psex = SEX_FEMALE; - sp_ptr = &sex_info[p_ptr->psex]; - ident = TRUE; - trap_hit(trap); - break; - } - - case TRAP_OF_MASCULINITY: - { - msg_print("Gas sprouts out... you feel yourself transmute."); - p_ptr->psex = SEX_MALE; - sp_ptr = &sex_info[p_ptr->psex]; - ident = TRUE; - trap_hit(trap); - break; - } - - case TRAP_OF_NEUTRALITY: - { - msg_print("Gas sprouts out... you feel yourself transmute."); - p_ptr->psex = SEX_NEUTER; - sp_ptr = &sex_info[p_ptr->psex]; - ident = TRUE; - trap_hit(trap); - break; - } - - case TRAP_OF_AGING: - { - msg_print("Colors are scintillating around you. " - "You see your past running before your eyes."); - p_ptr->age += randint((rp_ptr->b_age + rmp_ptr->b_age) / 2); - ident = TRUE; - trap_hit(trap); - break; - } - - case TRAP_OF_GROWING: - { - s16b tmp; - - msg_print("Heavy fumes sprout out... you feel yourself transmute."); - if (p_ptr->psex == SEX_FEMALE) tmp = rp_ptr->f_b_ht + rmp_ptr->f_b_ht; - else tmp = rp_ptr->m_b_ht + rmp_ptr->m_b_ht; - - p_ptr->ht += randint(tmp / 4); - ident = TRUE; - trap_hit(trap); - break; - } - - case TRAP_OF_SHRINKING: - { - s16b tmp; - - msg_print("Heavy fumes sprout out... you feel yourself transmute."); - if (p_ptr->psex == SEX_FEMALE) tmp = rp_ptr->f_b_ht + rmp_ptr->f_b_ht; - else tmp = rp_ptr->m_b_ht + rmp_ptr->m_b_ht; - - p_ptr->ht -= randint(tmp / 4); - if (p_ptr->ht <= tmp / 4) p_ptr->ht = tmp / 4; - ident = TRUE; - trap_hit(trap); - break; - } - - /* Trap of Divine Anger */ - case TRAP_OF_DIVINE_ANGER: - { - if (p_ptr->pgod == 0) - { - msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title); - } - else - { - cptr name; - - name = deity_info[p_ptr->pgod].name; - msg_format("You feel you have angered %s.", name); - inc_piety(p_ptr->pgod, -3000); - } - break; - } - - /* Trap of Divine Wrath */ - case TRAP_OF_DIVINE_WRATH: - { - if (p_ptr->pgod == 0) - { - msg_format("Suddenly you feel glad you're a mere %s", spp_ptr->title); - } - else - { - cptr name; - - name = deity_info[p_ptr->pgod].name; - - msg_format("%s quakes in rage: ``Thou art supremely insolent, mortal!!''", name); - inc_piety(p_ptr->pgod, -500 * p_ptr->lev); - } - break; - } - - /* Trap of hallucination */ - case TRAP_OF_HALLUCINATION: - { - msg_print("Scintillating colors hypnotise you for a moment."); - - set_image(80); - } - break; - - /* Bolt Trap */ - case TRAP_OF_ROCKET: - ident = player_handle_breath_trap(1, GF_ROCKET, trap); - break; - case TRAP_OF_NUKE_BOLT: - ident = player_handle_breath_trap(1, GF_NUKE, trap); - break; - case TRAP_OF_HOLY_FIRE: - ident = player_handle_breath_trap(1, GF_HOLY_FIRE, trap); - break; - case TRAP_OF_HELL_FIRE: - ident = player_handle_breath_trap(1, GF_HELL_FIRE, trap); - break; - case TRAP_OF_PSI_BOLT: - ident = player_handle_breath_trap(1, GF_PSI, trap); - break; - case TRAP_OF_PSI_DRAIN: - ident = player_handle_breath_trap(1, GF_PSI_DRAIN, trap); - break; - - /* Ball Trap */ - case TRAP_OF_NUKE_BALL: - ident = player_handle_breath_trap(3, GF_NUKE, TRAP_OF_NUKE_BALL); - break; - case TRAP_OF_PSI_BALL: - ident = player_handle_breath_trap(3, GF_PSI, TRAP_OF_NUKE_BALL); - break; - - default: - { - msg_print(format("Executing unknown trap %d", trap)); - } - } - return ident; -} - -void player_activate_door_trap(s16b y, s16b x) -{ - cave_type *c_ptr; - bool_ ident = FALSE; - - c_ptr = &cave[y][x]; - - /* Return if trap or door not found */ - if ((c_ptr->t_idx == 0) || - !(f_info[c_ptr->feat].flags1 & FF1_DOOR)) return; - - /* Disturb */ - disturb(0); - - /* Message */ - msg_print("You found a trap!"); - - /* Pick a trap */ - pick_trap(y, x); - - /* Hit the trap */ - ident = player_activate_trap_type(y, x, NULL, -1); - if (ident) - { - t_info[c_ptr->t_idx].ident = TRUE; - msg_format("You identified that trap as %s.", - t_info[c_ptr->t_idx].name); - } -} - - -/* - * Places a random trap at the given location. - * - * The location must be a valid, empty, clean, floor grid. - */ -void place_trap(int y, int x) -{ - s16b trap; - trap_type *t_ptr; - int cnt; - u32b flags; - cave_type *c_ptr = &cave[y][x]; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; - - /* No traps in town or on first level */ - if (dun_level <= 1) return; - - /* - * Avoid open doors -- because DOOR flag is added to make much more - * important processing faster - */ - if (c_ptr->feat == FEAT_OPEN) return; - if (c_ptr->feat == FEAT_BROKEN) return; - - /* Traps only appears on empty floor */ - if (!cave_floor_grid(c_ptr) && - !(f_info[c_ptr->feat].flags1 & (FF1_DOOR))) return; - - /* Set flags */ - if (f_info[c_ptr->feat].flags1 & FF1_DOOR) flags = FTRAP_DOOR; - else flags = FTRAP_FLOOR; - - /* Try 100 times */ - cnt = 100; - while (cnt--) - { - trap = randint(max_t_idx - 1); - t_ptr = &t_info[trap]; - - /* No traps below their minlevel */ - if (t_ptr->minlevel > dun_level) continue; - - /* is this a correct trap now? */ - if (!(t_ptr->flags & flags)) continue; - - /* - * Hack -- No trap door at the bottom of dungeon or in flat - * (non dungeon) places or on quest levels - */ - if ((trap == TRAP_OF_SINKING) && - ((d_ptr->maxdepth == dun_level) || - (dungeon_flags1 & DF1_FLAT) || (is_quest(dun_level))) ) - { - continue; - } - - /* How probable is this trap */ - if (rand_int(100) < t_ptr->probability) - { - c_ptr->t_idx = trap; - break; - } - } - - return; -} - - -/* - * Place a leveled trap at given position - */ -void place_trap_leveled(int y, int x, int lev) -{ - int prev_dun_level = dun_level; - dun_level = lev; - place_trap(y,x); - dun_level = prev_dun_level; -} - -/* - * Places a random trap on the given chest. - * - * The object must be a valid chest. - */ -void place_trap_object(object_type *o_ptr) -{ - s16b trap; - trap_type *t_ptr; - int cnt; - - /* No traps in town or on first level */ - if (dun_level <= 1) - { - /* empty chest were already looted, therefore known */ - o_ptr->ident |= IDENT_KNOWN; - return; - } - - /* Try 100 times */ - cnt = 100; - while (cnt--) - { - trap = randint(max_t_idx - 1); - t_ptr = &t_info[trap]; - - /* no traps below their minlevel */ - if (t_ptr->minlevel > dun_level) continue; - - /* Is this a correct trap now? */ - if (!(t_ptr->flags & FTRAP_CHEST)) continue; - - /* How probable is this trap */ - if (rand_int(100) < t_ptr->probability) - { - o_ptr->pval = trap; - break; - } - } - - return; -} - -/* Dangerous trap placing function */ -void wiz_place_trap(int y, int x, int idx) -{ - cave_type *c_ptr = &cave[y][x]; - - /* Dangerous enough as it is... */ - if (!cave_floor_grid(c_ptr) && (!(f_info[c_ptr->feat].flags1 & FF1_DOOR))) return; - - c_ptr->t_idx = idx; -} - -/* - * Here begin monster traps code - */ - -/* - * Hook to determine if an object is a device - */ -static bool item_tester_hook_device(object_type const *o_ptr) -{ - return (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) || - (o_ptr->tval == TV_STAFF) || - (o_ptr->tval == TV_WAND)); -} - -/* - * The trap setting code for rogues -MWK- - * - * Also, it will fail or give weird results if the tvals are resorted! - */ -void do_cmd_set_trap(void) -{ - int item_kit, item_load, i; - int num; - - object_type *o_ptr, *j_ptr, *i_ptr; - - cptr q, s, c; - - object_type object_type_body; - - u32b f1, f2, f3, f4, f5, esp; - - /* Check some conditions */ - if (p_ptr->blind) - { - msg_print("You can't see anything."); - return; - } - if (no_lite()) - { - msg_print("You don't dare to set a trap in the darkness."); - return; - } - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - /* Only set traps on clean floor grids */ - if (!cave_clean_bold(p_ptr->py, p_ptr->px)) - { - msg_print("You cannot set a trap on this."); - return; - } - - /* Get an item */ - q = "Use which trapping kit? "; - s = "You have no trapping kits."; - if (!get_item(&item_kit, - q, s, - USE_INVEN, - object_filter::TVal(TV_TRAPKIT))) - { - return; - } - - o_ptr = &p_ptr->inventory[item_kit]; - - /* Trap kits need a second object */ - object_filter_t object_filter = object_filter::Or( - object_filter::And( - object_filter::SVal(SV_TRAPKIT_BOW), - object_filter::TVal(TV_ARROW)), - object_filter::And( - object_filter::SVal(SV_TRAPKIT_XBOW), - object_filter::TVal(TV_BOLT)), - object_filter::And( - object_filter::SVal(SV_TRAPKIT_SLING), - object_filter::TVal(TV_SHOT)), - object_filter::And( - object_filter::SVal(SV_TRAPKIT_POTION), - object_filter::Or( - object_filter::TVal(TV_POTION), - object_filter::TVal(TV_POTION2))), - object_filter::And( - object_filter::SVal(SV_TRAPKIT_SCROLL), - object_filter::TVal(TV_SCROLL)), - object_filter::And( - object_filter::SVal(SV_TRAPKIT_DEVICE), - &item_tester_hook_device)); - - /* Get the second item */ - q = "Load with what? "; - s = "You have nothing to load that trap with."; - if (!get_item(&item_load, q, s, USE_INVEN, object_filter)) return; - - /* Get the second object */ - j_ptr = &p_ptr->inventory[item_load]; - - /* Assume a single object */ - num = 1; - - /* In some cases, take multiple objects to load */ - if (o_ptr->sval != SV_TRAPKIT_DEVICE) - { - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if ((f3 & TR3_XTRA_SHOTS) && (o_ptr->pval > 0)) num += o_ptr->pval; - - if (f2 & (TRAP2_AUTOMATIC_5 | TRAP2_AUTOMATIC_99)) num = 99; - - if (num > j_ptr->number) num = j_ptr->number; - - c = format("How many (1-%d)? ", num); - - /* Ask for number of items to use */ - num = get_quantity(c, num); - } - - /* Canceled */ - if (!num) return; - - /* Take a turn */ - energy_use = 100; - - /* Get local object */ - i_ptr = &object_type_body; - - /* Obtain local object for trap content */ - object_copy(i_ptr, j_ptr); - - /* Set number */ - i_ptr->number = num; - - /* Drop it here */ - cave[p_ptr->py][p_ptr->px].special = floor_carry(p_ptr->py, p_ptr->px, i_ptr); - - /* Obtain local object for trap trigger kit */ - object_copy(i_ptr, o_ptr); - - /* Set number */ - i_ptr->number = 1; - - /* Drop it here */ - cave[p_ptr->py][p_ptr->px].special2 = floor_carry(p_ptr->py, p_ptr->px, i_ptr); - - /* Modify, Describe, Optimize */ - inc_stack_size_ex(item_kit, -1, NO_OPTIMIZE, DESCRIBE); - inc_stack_size_ex(item_load, -num, NO_OPTIMIZE, DESCRIBE); - - for (i = 0; i < INVEN_WIELD; i++) - { - if (inven_item_optimize(i)) break; - } - for (i = 0; i < INVEN_WIELD; i++) - { - inven_item_optimize(i); - } - - /* Actually set the trap */ - cave_set_feat(p_ptr->py, p_ptr->px, FEAT_MON_TRAP); -} - -/* - * Monster hitting a rod trap -MWK- - * - * Return TRUE if the monster died - */ -bool_ mon_hit_trap_aux_rod(int m_idx, object_type *o_ptr) -{ - int dam = 0, typ = 0; - int rad = 0; - monster_type *m_ptr = &m_list[m_idx]; - int y = m_ptr->fy; - int x = m_ptr->fx; - - /* Depend on rod type */ - switch (o_ptr->pval) - { - case SV_ROD_DETECT_TRAP: - m_ptr->smart |= SM_NOTE_TRAP; - break; - case SV_ROD_DETECTION: - m_ptr->smart |= SM_NOTE_TRAP; - break; - case SV_ROD_ILLUMINATION: - typ = GF_LITE_WEAK; - dam = damroll(2, 15); - rad = 3; - lite_room(y, x); - break; - case SV_ROD_CURING: - typ = GF_OLD_HEAL; - dam = damroll(3, 4); /* and heal conf? */ - break; - case SV_ROD_HEALING: - typ = GF_OLD_HEAL; - dam = 300; - break; - case SV_ROD_SPEED: - typ = GF_OLD_SPEED; - dam = 50; - break; - case SV_ROD_TELEPORT_AWAY: - typ = GF_AWAY_ALL; - dam = MAX_SIGHT * 5; - break; - case SV_ROD_DISARMING: - break; - case SV_ROD_LITE: - typ = GF_LITE_WEAK; - dam = damroll(6, 8); - break; - case SV_ROD_SLEEP_MONSTER: - typ = GF_OLD_SLEEP; - dam = 50; - break; - case SV_ROD_SLOW_MONSTER: - typ = GF_OLD_SLOW; - dam = 50; - break; - case SV_ROD_DRAIN_LIFE: - typ = GF_OLD_DRAIN; - dam = 75; - break; - case SV_ROD_POLYMORPH: - typ = GF_OLD_POLY; - dam = 50; - break; - case SV_ROD_ACID_BOLT: - typ = GF_ACID; - dam = damroll(6, 8); - break; - case SV_ROD_ELEC_BOLT: - typ = GF_ELEC; - dam = damroll(3, 8); - break; - case SV_ROD_FIRE_BOLT: - typ = GF_FIRE; - dam = damroll(8, 8); - break; - case SV_ROD_COLD_BOLT: - typ = GF_COLD; - dam = damroll(5, 8); - break; - case SV_ROD_ACID_BALL: - typ = GF_ACID; - dam = 60; - rad = 2; - break; - case SV_ROD_ELEC_BALL: - typ = GF_ELEC; - dam = 32; - rad = 2; - break; - case SV_ROD_FIRE_BALL: - typ = GF_FIRE; - dam = 72; - rad = 2; - break; - case SV_ROD_COLD_BALL: - typ = GF_COLD; - dam = 48; - rad = 2; - break; - default: - return (FALSE); - } - - /* Actually hit the monster */ - if (typ) (void) project( -2, rad, y, x, dam, typ, PROJECT_KILL | PROJECT_ITEM | PROJECT_JUMP); - return (cave[y][x].m_idx == 0 ? TRUE : FALSE); -} - -/* - * Monster hitting a staff trap -MWK- - * - * Return TRUE if the monster died - */ -bool_ mon_hit_trap_aux_staff(int m_idx, object_type *o_ptr) -{ - return (FALSE); -} - -/* - * Monster hitting a scroll trap -MWK- - * - * Return TRUE if the monster died - */ -bool_ mon_hit_trap_aux_scroll(int m_idx, int sval) -{ - monster_type *m_ptr = &m_list[m_idx]; - int dam = 0, typ = 0; - int rad = 0; - int y = m_ptr->fy; - int x = m_ptr->fx; - int k; - - /* Depend on scroll type */ - switch (sval) - { - case SV_SCROLL_CURSE_ARMOR: - case SV_SCROLL_CURSE_WEAPON: - case SV_SCROLL_TRAP_CREATION: /* these don't work :-( */ - case SV_SCROLL_WORD_OF_RECALL: /* should these? */ - case SV_SCROLL_IDENTIFY: - case SV_SCROLL_STAR_IDENTIFY: - case SV_SCROLL_MAPPING: - case SV_SCROLL_DETECT_GOLD: - case SV_SCROLL_DETECT_ITEM: - case SV_SCROLL_REMOVE_CURSE: - case SV_SCROLL_STAR_REMOVE_CURSE: - case SV_SCROLL_ENCHANT_ARMOR: - case SV_SCROLL_ENCHANT_WEAPON_TO_HIT: - case SV_SCROLL_ENCHANT_WEAPON_TO_DAM: - case SV_SCROLL_STAR_ENCHANT_ARMOR: - case SV_SCROLL_STAR_ENCHANT_WEAPON: - case SV_SCROLL_RECHARGING: - case SV_SCROLL_DETECT_DOOR: - case SV_SCROLL_DETECT_INVIS: - case SV_SCROLL_SATISFY_HUNGER: - case SV_SCROLL_RUNE_OF_PROTECTION: - case SV_SCROLL_TRAP_DOOR_DESTRUCTION: - case SV_SCROLL_PROTECTION_FROM_EVIL: - return (FALSE); - case SV_SCROLL_DARKNESS: - unlite_room(y, x); - typ = GF_DARK_WEAK; - dam = 10; - rad = 3; - break; - case SV_SCROLL_AGGRAVATE_MONSTER: - aggravate_monsters(m_idx); - return (FALSE); - case SV_SCROLL_SUMMON_MONSTER: - for (k = 0; k < randint(3) ; k++) summon_specific(y, x, dun_level, 0); - return (FALSE); - case SV_SCROLL_SUMMON_UNDEAD: - for (k = 0; k < randint(3) ; k++) summon_specific(y, x, dun_level, SUMMON_UNDEAD); - return (FALSE); - case SV_SCROLL_PHASE_DOOR: - typ = GF_AWAY_ALL; - dam = 10; - break; - case SV_SCROLL_TELEPORT: - typ = GF_AWAY_ALL; - dam = 100; - break; - case SV_SCROLL_TELEPORT_LEVEL: - delete_monster(y, x); - return (TRUE); - case SV_SCROLL_LIGHT: - lite_room(y, x); - typ = GF_LITE_WEAK; - dam = damroll(2, 8); - rad = 2; - break; - case SV_SCROLL_DETECT_TRAP: - m_ptr->smart |= SM_NOTE_TRAP; - return (FALSE); - case SV_SCROLL_BLESSING: - typ = GF_HOLY_FIRE; - dam = damroll(1, 4); - break; - case SV_SCROLL_HOLY_CHANT: - typ = GF_HOLY_FIRE; - dam = damroll(2, 4); - break; - case SV_SCROLL_HOLY_PRAYER: - typ = GF_HOLY_FIRE; - dam = damroll(4, 4); - break; - case SV_SCROLL_MONSTER_CONFUSION: - typ = GF_OLD_CONF; - dam = damroll(5, 10); - break; - case SV_SCROLL_STAR_DESTRUCTION: - destroy_area(y, x, 15); - return (FALSE); - case SV_SCROLL_DISPEL_UNDEAD: - typ = GF_DISP_UNDEAD; - rad = 5; - dam = 60; - break; - case SV_SCROLL_GENOCIDE: - { - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - genocide_aux(FALSE, r_ptr->d_char); - /* although there's no point in a multiple genocide trap... */ - return (!(r_ptr->flags1 & RF1_UNIQUE)); - } - case SV_SCROLL_MASS_GENOCIDE: - for (k = 0; k < 8; k++) - delete_monster(y + ddy[k], x + ddx[k]); - delete_monster(y, x); - return (TRUE); - case SV_SCROLL_ACQUIREMENT: - acquirement(y, x, 1, TRUE, FALSE); - return (FALSE); - case SV_SCROLL_STAR_ACQUIREMENT: - acquirement(y, x, randint(2) + 1, TRUE, FALSE); - return (FALSE); - default: - return (FALSE); - } - - /* Actually hit the monster */ - (void) project( -2, rad, y, x, dam, typ, PROJECT_KILL | PROJECT_ITEM | PROJECT_JUMP); - return (cave[y][x].m_idx == 0 ? TRUE : FALSE); -} - -/* - * Monster hitting a wand trap -MWK- - * - * Return TRUE if the monster died - */ -bool_ mon_hit_trap_aux_wand(int m_idx, object_type *o_ptr) -{ - return (FALSE); -} - -/* - * Monster hitting a potions trap -MWK- - * - * Return TRUE if the monster died - */ -bool_ mon_hit_trap_aux_potion(int m_idx, object_type *o_ptr) -{ - monster_type *m_ptr = &m_list[m_idx]; - int dam = 0, typ = 0; - int y = m_ptr->fy; - int x = m_ptr->fx; - int sval = o_ptr->sval; - - /* Depend on potion type */ - if (o_ptr->tval == TV_POTION) - { - switch (sval) - { - /* Nothing happens */ - case SV_POTION_WATER: - case SV_POTION_APPLE_JUICE: - case SV_POTION_SLIME_MOLD: - case SV_POTION_SALT_WATER: - case SV_POTION_DEC_STR: - case SV_POTION_DEC_INT: - case SV_POTION_DEC_WIS: - case SV_POTION_DEC_DEX: - case SV_POTION_DEC_CON: - case SV_POTION_DEC_CHR: - case SV_POTION_INFRAVISION: - case SV_POTION_DETECT_INVIS: - case SV_POTION_SLOW_POISON: - case SV_POTION_CURE_POISON: - case SV_POTION_RESIST_HEAT: - case SV_POTION_RESIST_COLD: - case SV_POTION_RESTORE_MANA: - case SV_POTION_RESTORE_EXP: - case SV_POTION_RES_STR: - case SV_POTION_RES_INT: - case SV_POTION_RES_WIS: - case SV_POTION_RES_DEX: - case SV_POTION_RES_CON: - case SV_POTION_RES_CHR: - case SV_POTION_INC_STR: - case SV_POTION_INC_INT: - case SV_POTION_INC_WIS: - case SV_POTION_INC_DEX: - case SV_POTION_INC_CON: - case SV_POTION_INC_CHR: - case SV_POTION_AUGMENTATION: - case SV_POTION_RUINATION: /* ??? */ - case SV_POTION_ENLIGHTENMENT: - case SV_POTION_STAR_ENLIGHTENMENT: - case SV_POTION_SELF_KNOWLEDGE: - return (FALSE); - - case SV_POTION_EXPERIENCE: - if (m_ptr->level < MONSTER_LEVEL_MAX) - { - m_ptr->exp = monster_exp(m_ptr->level + 1); - monster_check_experience(m_idx, FALSE); - } - return (FALSE); - case SV_POTION_SLOWNESS: - typ = GF_OLD_SLOW; - dam = damroll(4, 6); - break; - case SV_POTION_POISON: - typ = GF_POIS; - dam = damroll(8, 6); - break; - case SV_POTION_CONFUSION: - typ = GF_CONFUSION; - dam = damroll(4, 6); - break; - case SV_POTION_BLINDNESS: - typ = GF_DARK; - dam = 10; - break; - case SV_POTION_SLEEP: - typ = GF_OLD_SLEEP; - dam = damroll (4, 6); - break; - case SV_POTION_LOSE_MEMORIES: - typ = GF_OLD_CONF; - dam = damroll(10, 10); - break; - case SV_POTION_DETONATIONS: - typ = GF_DISINTEGRATE; - dam = damroll(20, 20); - break; - case SV_POTION_DEATH: - typ = GF_NETHER; - dam = damroll(100, 20); - break; - case SV_POTION_BOLDNESS: - m_ptr->monfear = 0; - return (FALSE); - case SV_POTION_SPEED: - typ = GF_OLD_SPEED; - dam = damroll(5, 10); - break; - case SV_POTION_HEROISM: - case SV_POTION_BESERK_STRENGTH: - m_ptr->monfear = 0; - typ = GF_OLD_HEAL; - dam = damroll(2, 10); - break; - case SV_POTION_CURE_LIGHT: - typ = GF_OLD_HEAL; - dam = damroll(3, 4); - break; - case SV_POTION_CURE_SERIOUS: - typ = GF_OLD_HEAL; - dam = damroll(4, 6); - break; - case SV_POTION_CURE_CRITICAL: - typ = GF_OLD_HEAL; - dam = damroll(6, 8); - break; - case SV_POTION_HEALING: - typ = GF_OLD_HEAL; - dam = 300; - break; - case SV_POTION_STAR_HEALING: - typ = GF_OLD_HEAL; - dam = 1000; - break; - case SV_POTION_LIFE: - { - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - if (r_ptr->flags3 & RF3_UNDEAD) - { - typ = GF_HOLY_FIRE; - dam = damroll(20, 20); - } - else - { - typ = GF_OLD_HEAL; - dam = 5000; - } - break; - } - default: - return (FALSE); - - } - } - else - {} - - /* Actually hit the monster */ - (void) project_m( -2, 0, y, x, dam, typ); - return (cave[y][x].m_idx == 0 ? TRUE : FALSE); -} - -/* - * Monster hitting a monster trap -MWK- - * Returns True if the monster died, false otherwise - */ -bool_ mon_hit_trap(int m_idx) -{ - monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - - u32b f1, f2, f3, f4, f5, esp; - - object_type object_type_body; - - int mx = m_ptr->fx; - int my = m_ptr->fy; - - int difficulty; - int smartness; - - char m_name[80]; - - bool_ notice = FALSE; - bool_ disarm = FALSE; - bool_ remove = FALSE; - bool_ dead = FALSE; - bool_ fear = FALSE; - s32b special = 0; - - int dam, chance, shots; - int mul = 0; - int breakage = -1; - - int cost = 0; - - /* Get the trap objects */ - auto kit_o_idx = cave[my][mx].special2; - auto kit_o_ptr = &o_list[kit_o_idx]; - auto load_o_ptr = &o_list[cave[my][mx].special]; - auto j_ptr = &object_type_body; - - /* Get trap properties */ - object_flags(kit_o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Can set off check */ - /* Ghosts only set off Ghost traps */ - if ((r_ptr->flags2 & RF2_PASS_WALL) && !(f2 & TRAP2_KILL_GHOST)) return (FALSE); - - /* Some traps are specialized to some creatures */ - if (f2 & TRAP2_ONLY_MASK) - { - bool_ affect = FALSE; - if ((f2 & TRAP2_ONLY_DRAGON) && (r_ptr->flags3 & RF3_DRAGON)) affect = TRUE; - if ((f2 & TRAP2_ONLY_DEMON) && (r_ptr->flags3 & RF3_DEMON)) affect = TRUE; - if ((f2 & TRAP2_ONLY_UNDEAD) && (r_ptr->flags3 & RF3_UNDEAD)) affect = TRUE; - if ((f2 & TRAP2_ONLY_EVIL) && (r_ptr->flags3 & RF3_EVIL)) affect = TRUE; - if ((f2 & TRAP2_ONLY_ANIMAL) && (r_ptr->flags3 & RF3_ANIMAL)) affect = TRUE; - - /* Don't set it off if forbidden */ - if (!affect) return (FALSE); - } - - /* Get detection difficulty */ - difficulty = 25; - - /* Some traps are well-hidden */ - if (f1 & TR1_STEALTH) - { - difficulty += 10 * (kit_o_ptr->pval); - } - - /* Get monster smartness for trap detection */ - /* Higher level monsters are smarter */ - smartness = r_ptr->level; - - /* Smart monsters are better at detecting traps */ - if (r_ptr->flags2 & RF2_SMART) smartness += 10; - - /* Some monsters have already noticed one of out traps */ - if (m_ptr->smart & SM_NOTE_TRAP) smartness += 20; - - /* Stupid monsters are no good at detecting traps */ - if (r_ptr->flags2 & (RF2_STUPID | RF2_EMPTY_MIND)) smartness = -150; - - /* Check if the monster notices the trap */ - if (randint(300) > (difficulty - smartness + 150)) notice = TRUE; - - /* Disarm check */ - if (notice) - { - /* The next traps will be easier to spot! */ - m_ptr->smart |= SM_NOTE_TRAP; - - /* Get trap disarming difficulty */ - difficulty = (kit_o_ptr->ac + kit_o_ptr->to_a); - - /* Get monster disarming ability */ - /* Higher level monsters are better */ - smartness = r_ptr->level / 5; - - /* Smart monsters are better at disarming */ - if (r_ptr->flags2 & RF2_SMART) smartness *= 2; - - /* Stupid monsters never disarm traps */ - if (r_ptr->flags2 & RF2_STUPID) smartness = -150; - - /* Nonsmart animals never disarm traps */ - if ((r_ptr->flags3 & RF3_ANIMAL) && !(r_ptr->flags2 & RF2_SMART)) smartness = -150; - - /* Check if the monster disarms the trap */ - if (randint(120) > (difficulty - smartness + 80)) disarm = TRUE; - } - - /* If disarmed, remove the trap and print a message */ - if (disarm) - { - remove = TRUE; - - if (m_ptr->ml) - { - /* Get the name */ - monster_desc(m_name, m_ptr, 0); - - /* Print a message */ - msg_format("%^s disarms a trap!", m_name); - } - } - - /* Otherwise, activate the trap! */ - else - { - /* Message for visible monster */ - if (m_ptr->ml) - { - /* Get the name */ - monster_desc(m_name, m_ptr, 0); - - /* Print a message */ - msg_format("%^s sets off a trap!", m_name); - } - else - { - /* No message if monster isn't visible ? */ - } - - /* Next time be more careful */ - if (randint(100) < 80) m_ptr->smart |= SM_NOTE_TRAP; - - /* Actually activate the trap */ - switch (kit_o_ptr->sval) - { - case SV_TRAPKIT_BOW: - case SV_TRAPKIT_XBOW: - case SV_TRAPKIT_SLING: - { - /* Get number of shots */ - shots = 1; - if (f3 & TR3_XTRA_SHOTS) shots += kit_o_ptr->pval; - if (shots <= 0) shots = 1; - if (shots > load_o_ptr->number) shots = load_o_ptr->number; - - while (shots-- && !dead) - { - /* Total base damage */ - dam = damroll(load_o_ptr->dd, load_o_ptr->ds) + load_o_ptr->to_d + kit_o_ptr->to_d; - - /* Total hit probability */ - chance = (kit_o_ptr->to_h + load_o_ptr->to_h + 20) * BTH_PLUS_ADJ; - - /* Damage multiplier */ - if (kit_o_ptr->sval == SV_TRAPKIT_BOW) mul = 3; - if (kit_o_ptr->sval == SV_TRAPKIT_XBOW) mul = 4; - if (kit_o_ptr->sval == SV_TRAPKIT_SLING) mul = 2; - if (f3 & TR3_XTRA_MIGHT) mul += kit_o_ptr->pval; - if (mul < 0) mul = 0; - - /* Multiply damage */ - dam *= mul; - - /* Check if we hit the monster */ - if (test_hit_fire(chance, r_ptr->ac, TRUE)) - { - /* Assume a default death */ - cptr note_dies = " dies."; - - /* Some monsters get "destroyed" */ - if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || - (strchr("Evg", r_ptr->d_char))) - { - /* Special note at death */ - note_dies = " is destroyed."; - } - - /* Message if visible */ - if (m_ptr->ml) - { - /* describe the monster (again, just in case :-) */ - monster_desc(m_name, m_ptr, 0); - - /* Print a message */ - msg_format("%^s is hit by a missile.", m_name); - } - - /* Apply slays, brand, critical hits */ - dam = tot_dam_aux(load_o_ptr, dam, m_ptr, &special); - dam = critical_shot(load_o_ptr->weight, load_o_ptr->to_h, dam, SKILL_ARCHERY); - - /* No negative damage */ - if (dam < 0) dam = 0; - - /* Hit the monster, check for death */ - if (mon_take_hit(m_idx, dam, &fear, note_dies)) - { - /* Dead monster */ - dead = TRUE; - } - - /* No death */ - else - { - /* Message */ - message_pain(m_idx, dam); - - if (special) attack_special(m_ptr, special, dam); - - /* Take note */ - if (fear && m_ptr->ml) - { - /* Message */ - msg_format("%^s flees in terror!", m_name); - } - } - - } - - /* Exploding ammo */ - if (load_o_ptr->pval2 != 0) - { - int rad = 0; - int dam = (damroll(load_o_ptr->dd, load_o_ptr->ds) + load_o_ptr->to_d)*2; - int flag = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | - PROJECT_JUMP; - - switch (load_o_ptr->sval) - { - case SV_AMMO_LIGHT: - rad = 2; - dam /= 2; - break; - case SV_AMMO_NORMAL: - rad = 3; - break; - case SV_AMMO_HEAVY: - rad = 4; - dam *= 2; - break; - } - - project(0, rad, my, mx, dam, load_o_ptr->pval2, flag); - - breakage = 100; - } - else - { - breakage = breakage_chance(load_o_ptr); - } - - /* Copy and decrease ammo */ - object_copy(j_ptr, load_o_ptr); - - j_ptr->number = 1; - - load_o_ptr->number--; - - if (load_o_ptr->number <= 0) - { - remove = TRUE; - delete_object_idx(kit_o_idx); - } - - /* Drop (or break) near that location */ - drop_near(j_ptr, breakage, my, mx); - - } - - break; - } - - case SV_TRAPKIT_POTION: - { - /* Get number of shots */ - shots = 1; - if (f3 & TR3_XTRA_SHOTS) shots += kit_o_ptr->pval; - if (shots <= 0) shots = 1; - if (shots > load_o_ptr->number) shots = load_o_ptr->number; - - while (shots-- && !dead) - { - - /* Message if visible */ - if (m_ptr->ml) - { - /* describe the monster (again, just in case :-) */ - monster_desc(m_name, m_ptr, 0); - - /* Print a message */ - msg_format("%^s is hit by fumes.", m_name); - } - - /* Get the potion effect */ - dead = mon_hit_trap_aux_potion(m_idx, load_o_ptr); - - /* Copy and decrease ammo */ - object_copy(j_ptr, load_o_ptr); - - j_ptr->number = 1; - - load_o_ptr->number--; - - if (load_o_ptr->number <= 0) - { - remove = TRUE; - delete_object_idx(kit_o_idx); - } - } - - break; - } - - case SV_TRAPKIT_SCROLL: - { - /* Get number of shots */ - shots = 1; - if (f3 & TR3_XTRA_SHOTS) shots += kit_o_ptr->pval; - if (shots <= 0) shots = 1; - if (shots > load_o_ptr->number) shots = load_o_ptr->number; - - while (shots-- && !dead) - { - - /* Message if visible */ - if (m_ptr->ml) - { - /* describe the monster (again, just in case :-) */ - monster_desc(m_name, m_ptr, 0); - - /* Print a message */ - msg_format("%^s activates a spell!", m_name); - } - - /* Get the potion effect */ - dead = mon_hit_trap_aux_scroll(m_idx, load_o_ptr->sval); - - /* Copy and decrease ammo */ - object_copy(j_ptr, load_o_ptr); - - j_ptr->number = 1; - - load_o_ptr->number--; - - if (load_o_ptr->number <= 0) - { - remove = TRUE; - delete_object_idx(kit_o_idx); - } - } - - break; - } - - case SV_TRAPKIT_DEVICE: - { - if (load_o_ptr->tval == TV_ROD_MAIN) - { - /* Extract mana cost of the rod tip */ - u32b tf1, tf2, tf3, tf4, tf5, tesp; - object_kind *tip_o_ptr = &k_info[lookup_kind(TV_ROD, load_o_ptr->pval)]; - object_flags(load_o_ptr, &tf1, &tf2, &tf3, &tf4, &tf5, &tesp); - cost = (tf4 & TR4_CHEAPNESS) ? tip_o_ptr->pval / 2 : tip_o_ptr->pval; - if (cost <= 0) cost = 1; - } - - /* Get number of shots */ - shots = 1; - if (f3 & TR3_XTRA_SHOTS) shots += kit_o_ptr->pval; - if (shots <= 0) shots = 1; - - if (load_o_ptr->tval == TV_ROD_MAIN) - { - if (shots > load_o_ptr->timeout / cost) shots = load_o_ptr->timeout / cost; - } - else - { - if (shots > load_o_ptr->pval) shots = load_o_ptr->pval; - } - - while (shots-- && !dead) - { - /* Get the effect effect */ - switch (load_o_ptr->tval) - { - case TV_ROD_MAIN: - dead = mon_hit_trap_aux_rod(m_idx, load_o_ptr); - break; - case TV_WAND: - dead = mon_hit_trap_aux_wand(m_idx, load_o_ptr); - break; - case TV_STAFF: - dead = mon_hit_trap_aux_staff(m_idx, load_o_ptr); - break; - } - - if (load_o_ptr->tval == TV_ROD_MAIN) - { - /* decrease stored mana (timeout) for rods */ - load_o_ptr->timeout -= cost; - } - else - { - /* decrease charges for wands and staves */ - load_o_ptr->pval--; - } - } - - break; - } - - default: - msg_print("oops! nonexistant trap!"); - - } - - /* Non-automatic traps are removed */ - if (!(f2 & (TRAP2_AUTOMATIC_5 | TRAP2_AUTOMATIC_99))) - { - remove = TRUE; - } - else if (f2 & TRAP2_AUTOMATIC_5) remove = (randint(5) == 1); - - } - - /* Special trap effect -- teleport to */ - if ((f2 & TRAP2_TELEPORT_TO) && (!disarm) && (!dead)) - { - teleport_monster_to(m_idx, p_ptr->py, p_ptr->px); - } - - /* Remove the trap if inactive now */ - if (remove) place_floor_convert_glass(my, mx); - - /* did it die? */ - return (dead); -} - diff --git a/src/traps.hpp b/src/traps.hpp deleted file mode 100644 index 3df1e430..00000000 --- a/src/traps.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "h-basic.h" -#include "object_type_fwd.hpp" - -extern bool_ player_activate_trap_type(s16b y, s16b x, object_type *i_ptr, s16b item); -extern void player_activate_door_trap(s16b y, s16b x); -extern void place_trap(int y, int x); -extern void place_trap_leveled(int y, int x, int lev); -extern void place_trap_object(object_type *o_ptr); -extern void wiz_place_trap(int y, int x, int idx); -extern void do_cmd_set_trap(void); -extern bool_ mon_hit_trap(int); diff --git a/src/util.cc b/src/util.cc index 08af0658..7d795828 100644 --- a/src/util.cc +++ b/src/util.cc @@ -8,6 +8,7 @@ #include "cli_comm.hpp" #include "cmd3.hpp" #include "cmd4.hpp" +#include "game.hpp" #include "init1.hpp" #include "messages.hpp" #include "monster_ego.hpp" @@ -17,7 +18,6 @@ #include "player_race.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" -#include "quark.hpp" #include "tables.h" #include "tables.hpp" #include "timer_type.hpp" @@ -27,6 +27,7 @@ #include <boost/algorithm/string/predicate.hpp> #include <chrono> +#include <sstream> #include <thread> using boost::algorithm::iequals; @@ -36,23 +37,23 @@ using std::chrono::milliseconds; /* * Find a default user name from the system. */ -void user_name(char *buf, int id) +std::string user_name() { #ifdef SET_UID + /* Get the user id (?) */ + int player_uid = getuid(); + struct passwd *pw; /* Look up the user name */ - if ((pw = getpwuid(id))) + if ((pw = getpwuid(player_uid))) { - (void)strcpy(buf, pw->pw_name); - buf[16] = '\0'; - - return; + return pw->pw_name; } #endif /* SET_UID */ - /* Oops. Hack -- default to "PLAYER" */ - strcpy(buf, "PLAYER"); + /* Default to "PLAYER" if we don't have platform support */ + return "PLAYER"; } @@ -70,8 +71,6 @@ void user_name(char *buf, int id) * to assume that all filenames are "Unix" filenames, and explicitly "extract" * such filenames if needed (by "path_parse()", or perhaps "path_canon()"). * -* Note that "path_temp" should probably return a "canonical" filename. -* * Note that "my_fopen()" and "my_open()" and "my_make()" and "my_kill()" * and "my_move()" and "my_copy()" should all take "canonical" filenames. * @@ -126,7 +125,7 @@ errr path_parse(char *buf, int max, cptr file) if (!u) return (1); - (void)strcpy(buf, u); + strcpy(buf, u); #else /* Look up password data for user */ pw = getpwuid(getuid()); @@ -135,11 +134,11 @@ errr path_parse(char *buf, int max, cptr file) if (!pw) return (1); /* Make use of the info */ - (void)strcpy(buf, pw->pw_dir); + strcpy(buf, pw->pw_dir); #endif /* Append the rest of the filename, if any */ - if (s) (void)strcat(buf, s); + if (s) strcat(buf, s); /* Success */ return (0); @@ -169,42 +168,6 @@ errr path_parse(char *buf, int max, cptr file) /* -* Hack -- acquire a "temporary" file name if possible -* -* This filename is always in "system-specific" form. -*/ -errr path_temp(char *buf, int max) -{ -#ifdef WINDOWS - static u32b tmp_counter; - static char valid_characters[] = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - char rand_ext[4]; - - rand_ext[0] = valid_characters[rand_int(sizeof (valid_characters))]; - rand_ext[1] = valid_characters[rand_int(sizeof (valid_characters))]; - rand_ext[2] = valid_characters[rand_int(sizeof (valid_characters))]; - rand_ext[3] = '\0'; - strnfmt(buf, max, "%s/t_%ud.%s", ANGBAND_DIR_XTRA, tmp_counter, rand_ext); - tmp_counter++; -#else - cptr s; - - /* Temp file */ - s = tmpnam(NULL); - - /* Oops */ - if (!s) return ( -1); - - /* Format to length */ - strnfmt(buf, max, "%s", s); -#endif - /* Success */ - return (0); -} - - -/* * Create a new path by appending a file (or directory) to a path * * This requires no special processing on simple machines, except @@ -381,7 +344,7 @@ errr fd_kill(cptr file) if (path_parse(buf, 1024, file)) return ( -1); /* Remove */ - (void)remove(buf); + remove(buf); /* XXX XXX XXX */ return (0); @@ -403,7 +366,7 @@ errr fd_move(cptr file, cptr what) if (path_parse(aux, 1024, what)) return ( -1); /* Rename */ - (void)rename(buf, aux); + rename(buf, aux); /* XXX XXX XXX */ return (0); @@ -551,7 +514,7 @@ errr fd_close(int fd) if (fd < 0) return ( -1); /* Close */ - (void)close(fd); + close(fd); /* XXX XXX XXX */ return (0); @@ -1250,7 +1213,7 @@ static bool_ parse_under = FALSE; * This is not only more efficient, but also necessary to make sure * that various "inkey()" codes are not "lost" along the way. */ -void flush(void) +void flush() { /* Do it later */ flush_later = TRUE; @@ -1258,15 +1221,27 @@ void flush(void) /* + * Flush input if the 'flush_failure' option is set. + */ +void flush_on_failure() +{ + if (options->flush_failure) + { + flush(); + } +} + + +/* * Flush the screen, make a noise */ -void bell(void) +void bell() { /* Mega-Hack -- Flush the output */ Term_fresh(); /* Make a bell noise (if allowed) */ - if (ring_bell) + if (options->ring_bell) { Term_bell(); } @@ -1276,16 +1251,6 @@ void bell(void) } -/* -* Hack -- Make a (relevant?) sound -*/ -void sound(int val) -{ - /* Ignore; sound not currently supported. */ - return; -} - - /* * Helper function called only from "inkey()" @@ -1304,7 +1269,7 @@ void sound(int val) * macro trigger, 500 milliseconds must pass before the key sequence is * known not to be that macro trigger. XXX XXX XXX */ -static char inkey_aux(void) +static char inkey_aux() { int k = 0, n, p = 0, w = 0; @@ -1316,7 +1281,7 @@ static char inkey_aux(void) /* Wait for a keypress */ - (void)(Term_inkey(&ch, TRUE, TRUE)); + (Term_inkey(&ch, TRUE, TRUE)); /* End "macro action" */ @@ -1393,7 +1358,7 @@ static char inkey_aux(void) } /* Wait for (and remove) a pending key */ - (void)Term_inkey(&ch, TRUE, TRUE); + Term_inkey(&ch, TRUE, TRUE); /* Return the key */ return (ch); @@ -1538,13 +1503,13 @@ static char inkey_real(bool_ inkey_scan) /* Access cursor state */ - (void)Term_get_cursor(&v); + Term_get_cursor(&v); /* Show the cursor if waiting, except sometimes in "command" mode */ - if (!inkey_scan && (!inkey_flag || hilite_player || character_icky)) + if (!inkey_scan && (!inkey_flag || options->hilite_player || character_icky)) { /* Show the cursor */ - (void)Term_set_cursor(1); + Term_set_cursor(1); } @@ -1633,7 +1598,7 @@ static char inkey_real(bool_ inkey_scan) /* Handle "control-right-bracket" */ - if ((ch == 29) || ((!rogue_like_commands) && (ch == KTRL('D')))) + if ((ch == 29) || ((!options->rogue_like_commands) && (ch == KTRL('D')))) { /* Strip this key */ ch = 0; @@ -1704,7 +1669,7 @@ static char inkey_real(bool_ inkey_scan) return (ch); } -char inkey(void) { +char inkey() { return inkey_real(FALSE); } @@ -1726,7 +1691,7 @@ static void msg_flush(int x) while (1) { int cmd = inkey(); - if (quick_messages) break; + if (options->quick_messages) break; if ((cmd == ESCAPE) || (cmd == ' ')) break; if ((cmd == '\n') || (cmd == '\r')) break; bell(); @@ -1793,15 +1758,15 @@ void display_message(int x, int y, int split, byte color, cptr t) */ void cmsg_print(byte color, cptr msg) { - static int p = 0; + auto &messages = game->messages; - int n; - int wid; + static int p = 0; char *t; char buf[1024]; + int wid; Term_get_size(&wid, nullptr); int lim = wid - 8; @@ -1809,7 +1774,7 @@ void cmsg_print(byte color, cptr msg) if (!msg_flag) p = 0; /* Message Length */ - n = (msg ? strlen(msg) : 0); + int n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ if (p && (!msg || ((p + n) > lim))) @@ -1833,10 +1798,13 @@ void cmsg_print(byte color, cptr msg) /* Memorize the message */ - if (character_generated) message_add(msg, color); + if (character_generated) + { + messages.add(msg, color); + } /* Handle "auto_more" */ - if (auto_more) + if (options->auto_more) { /* Window stuff */ p_ptr->window |= (PW_MESSAGE); @@ -1902,11 +1870,11 @@ void cmsg_print(byte color, cptr msg) /* Display the tail of the message */ display_message(p, 0, n, color, t); - /* Memorize the tail */ - /* if (character_generated) message_add(t); */ - /* Window stuff */ - p_ptr->window |= (PW_MESSAGE); + if (p_ptr) + { + p_ptr->window |= (PW_MESSAGE); + } /* Remember the message */ msg_flag = TRUE; @@ -1915,7 +1883,12 @@ void cmsg_print(byte color, cptr msg) p += n + 1; /* Optional refresh */ - if (fresh_message) Term_fresh(); + if (options->fresh_message) Term_fresh(); +} + +void cmsg_print(byte color, std::string const &msg) +{ + cmsg_print(color, msg.c_str()); } /* Hack -- for compatibility and easy sake */ @@ -1936,7 +1909,7 @@ static int screen_depth = 0; * * This function must match exactly one call to "screen_load()". */ -void screen_save(void) +void screen_save() { /* Hack -- Flush messages */ msg_print(NULL); @@ -1954,7 +1927,7 @@ void screen_save(void) * * This function must match exactly one call to "screen_save()". */ -void screen_load(void) +void screen_load() { /* Hack -- Flush messages */ msg_print(NULL); @@ -1980,7 +1953,7 @@ void msg_format(cptr fmt, ...) va_start(vp, fmt); /* Format the args, save the length */ - (void)vstrnfmt(buf, 1024, fmt, vp); + vstrnfmt(buf, 1024, fmt, vp); /* End the Varargs Stuff */ va_end(vp); @@ -1999,7 +1972,7 @@ void cmsg_format(byte color, cptr fmt, ...) va_start(vp, fmt); /* Format the args, save the length */ - (void)vstrnfmt(buf, 1024, fmt, vp); + vstrnfmt(buf, 1024, fmt, vp); /* End the Varargs Stuff */ va_end(vp); @@ -2008,29 +1981,25 @@ void cmsg_format(byte color, cptr fmt, ...) cmsg_print(color, buf); } - - -/* -* Display a string on the screen using an attribute. -* -* At the given location, using the given attribute, if allowed, -* add the given string. Do not clear the line. -*/ void c_put_str(byte attr, cptr str, int row, int col) { - /* Position cursor, Dump the attr/text */ Term_putstr(col, row, -1, attr, str); } -/* -* As above, but in "white" -*/ +void c_put_str(byte attr, std::string const &str, int row, int col) +{ + Term_putstr(col, row, -1, attr, str.c_str()); +} + void put_str(cptr str, int row, int col) { - /* Spawn */ Term_putstr(col, row, -1, TERM_WHITE, str); } +void put_str(std::string const &str, int row, int col) +{ + Term_putstr(col, row, -1, TERM_WHITE, str.c_str()); +} /* @@ -2046,16 +2015,20 @@ void c_prt(byte attr, cptr str, int row, int col) Term_addstr( -1, attr, str); } -/* -* As above, but in "white" -*/ +void c_prt(byte attr, std::string const &s, int row, int col) +{ + c_prt(attr, s.c_str(), row, col); +} + void prt(cptr str, int row, int col) { - /* Spawn */ c_prt(TERM_WHITE, str, row, col); } - +void prt(std::string const &s, int row, int col) +{ + prt(s.c_str(), row, col); +} /* * Print some (colored) text to the screen at the current cursor position, @@ -2083,10 +2056,10 @@ void text_out_to_screen(byte a, cptr str) /* Obtain the size */ - (void)Term_get_size(&wid, &h); + Term_get_size(&wid, &h); /* Obtain the cursor */ - (void)Term_locate(&x, &y); + Term_locate(&x, &y); /* Wrapping boundary */ wrap = wid; @@ -2193,7 +2166,7 @@ void text_out_to_file(byte a, cptr str) cptr s = str; /* Unused parameter */ - (void)a; + a; /* Process the string */ while (*s) @@ -2381,6 +2354,23 @@ static int complete_command(char *buf, int clen, int mlen) } +bool askfor_aux(std::string *buf, std::size_t max_len) +{ + // Buffer + char cstr[1024]; + // Sanity + assert(max_len < sizeof(cstr)); + // Copy into temporary buffer + cstr[buf->size()] = '\0'; + buf->copy(cstr, std::string::npos); + // Delegate + bool result = askfor_aux(cstr, max_len); + // Copy back + (*buf) = cstr; + // Done + return result; +} + /* * Get some input at the cursor location. * Assume the buffer is initialized to a default string. @@ -2574,7 +2564,7 @@ bool_ get_check(cptr prompt) while (TRUE) { i = inkey(); - if (quick_messages) break; + if (options->quick_messages) break; if (i == ESCAPE) break; if (strchr("YyNn", i)) break; bell(); @@ -2728,7 +2718,6 @@ static char request_command_buffer[256]; * request_command(). This MUST have at least twice as many characters as * there are building actions in the actions[] array in store_info_type. */ -#define MAX_IGNORE_KEYMAPS 12 char request_command_ignore_keymaps[MAX_IGNORE_KEYMAPS]; /* @@ -2925,7 +2914,7 @@ void request_command(int shopping) if (cmd == '\\') { /* Get a real command */ - (void)get_com("Command: ", &cmd_char); + get_com("Command: ", &cmd_char); cmd = cmd_char; @@ -2983,7 +2972,7 @@ void request_command(int shopping) } /* Hack -- Auto-repeat certain commands */ - if (always_repeat && (command_arg <= 0)) + if (options->always_repeat && (command_arg <= 0)) { /* Hack -- auto repeat certain commands */ if (strchr("TBDoc+", command_cmd)) @@ -2996,18 +2985,19 @@ void request_command(int shopping) /* Hack -- Scan equipment */ for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) { - cptr s; - object_type *o_ptr = &p_ptr->inventory[i]; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* No inscription */ - if (!o_ptr->note) continue; + if (o_ptr->inscription.empty()) + { + continue; + } /* Obtain the inscription */ - s = quark_str(o_ptr->note); + auto s = o_ptr->inscription.c_str(); /* Find a '^' */ s = strchr(s, '^'); @@ -3152,7 +3142,7 @@ bool_ repeat_pull(int *what) return (TRUE); } -void repeat_check(void) +void repeat_check() { int what; @@ -3196,7 +3186,7 @@ void repeat_check(void) * * Allow numbers of any size and save the last keypress. */ -u32b get_number(u32b def, u32b max, int y, int x, char *cmd) +static u32b get_number(u32b def, u32b max, int y, int x, char *cmd) { u32b res = def; @@ -3293,7 +3283,10 @@ void get_count(int number, int max) command_arg = number; /* Hack -- Optional flush */ - if (flush_command) flush(); + if (options->flush_command) + { + flush(); + } /* Clear top line */ prt("", 0, 0); @@ -3336,28 +3329,33 @@ void strlower(char *buf) */ int test_monster_name(cptr name) { - int i; + auto const &r_info = game->edit_data.r_info; - /* Scan the monsters */ - for (i = 1; i < max_r_idx; i++) + for (std::size_t i = 0; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; - if (r_ptr->name && iequals(name, r_ptr->name)) return (i); + auto r_ptr = &r_info[i]; + if (r_ptr->name && iequals(name, r_ptr->name)) + { + return (i); + } } return (0); } -int test_mego_name(cptr name) +int test_mego_name(cptr needle) { - int i; + const auto &re_info = game->edit_data.re_info; /* Scan the monsters */ - for (i = 1; i < max_re_idx; i++) + for (std::size_t i = 0; i < re_info.size(); i++) { - monster_ego *re_ptr = &re_info[i]; - if (re_ptr->name && iequals(name, re_ptr->name)) return (i); + auto name = re_info[i].name; + if (name && iequals(name, needle)) + { + return i; + } } - return (0); + return 0; } /* @@ -3366,18 +3364,20 @@ int test_mego_name(cptr name) * returned. Case doesn't matter. -DG- */ -int test_item_name(cptr name) +int test_item_name(cptr needle) { - int i; + auto const &k_info = game->edit_data.k_info; - /* Scan the items */ - for (i = 1; i < max_k_idx; i++) + for (std::size_t i = 0; i < k_info.size(); i++) { - object_kind *k_ptr = &k_info[i]; - /* If name matches, give us the number */ - if (k_ptr->name && iequals(name, k_ptr->name)) return (i); + auto const &name = k_info[i].name; + if (name && iequals(needle, name)) + { + return i; + } } - return (0); + + return 0; } /* @@ -3402,41 +3402,53 @@ s32b bst(s32b what, s32b t) } } -cptr get_day(int day) +std::string get_day(s32b day_no) { - static char buf[20]; - cptr p = "th"; - - if ((day / 10) == 1) ; - else if ((day % 10) == 1) p = "st"; - else if ((day % 10) == 2) p = "nd"; - else if ((day % 10) == 3) p = "rd"; - - sprintf(buf, "%d%s", day, p); - return (buf); + // Convert the number + std::string day(std::to_string(day_no)); + // Suffix + if ((day_no / 10) == 1) + { + return day + "th"; + } + else if ((day_no % 10) == 1) + { + return day + "st"; + } + else if ((day_no % 10) == 2) + { + return day + "nd"; + } + else if ((day_no % 10) == 3) + { + return day + "rd"; + } + else + { + return day + "th"; + } } -cptr get_player_race_name(int pr, int ps) +std::string get_player_race_name(int pr, int ps) { - static char buf[50]; + auto const &race_info = game->edit_data.race_info; + auto const &race_mod_info = game->edit_data.race_mod_info; if (ps) { if (race_mod_info[ps].place) { - sprintf(buf, "%s %s", race_info[pr].title, race_mod_info[ps].title); + return std::string(race_info[pr].title) + " " + race_mod_info[ps].title; } else { - sprintf(buf, "%s %s", race_mod_info[ps].title, race_info[pr].title); + return std::string(race_mod_info[ps].title) + " " + race_info[pr].title; } } else { - sprintf(buf, "%s", race_info[pr].title); + return std::string(race_info[pr].title); } - - return (buf); } /* @@ -3446,7 +3458,7 @@ int ask_menu(cptr ask, const std::vector<std::string> &items) { int ret = -1, i, start = 0; char c; - int size = items.size(); // Convert to int to avoid warnings + int size = static_cast<int>(items.size()); // Convert to int to avoid warnings /* Enter "icky" mode */ character_icky = TRUE; @@ -3524,10 +3536,6 @@ bool_ prefix(cptr s, cptr t) /* Paranoia */ if (!s || !t) { - if (alert_failure) - { - message_add("prefix() called with null argument!", TERM_RED); - } return FALSE; } @@ -3573,56 +3581,59 @@ void draw_box(int y, int x, int h, int w) /* * Displays a scrollable boxed list with a selected item */ -void display_list(int y, int x, int h, int w, cptr title, cptr *list, int max, int begin, int sel, byte sel_color) +void display_list(int y, int x, int h, int w, cptr title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color) { - int i; - draw_box(y, x, h, w); c_put_str(TERM_L_BLUE, title, y, x + ((w - strlen(title)) / 2)); - for (i = 0; i < h - 1; i++) + for (int i = 0; i < h - 1; i++) { byte color = TERM_WHITE; - if (i + begin >= max) break; + if (i + begin >= list.size()) + { + break; + } if (i + begin == sel) color = sel_color; - c_put_str(color, list[i + begin], y + 1 + i, x + 1); + c_put_str(color, list[i + begin].c_str(), y + 1 + i, x + 1); } } -/* - * Creates an input box - */ -bool_ input_box(cptr text, int y, int x, char *buf, int max) +bool input_box_auto(std::string const &prompt, std::string *buf, std::size_t max) { - int smax = strlen(text); + int wid, hgt; + Term_get_size(&wid, &hgt); + + auto const y = hgt / 2; + auto const x = wid / 2; - if (max > smax) smax = max; - smax++; + auto const smax = std::max(prompt.size(), max) + 1; draw_box(y - 1, x - (smax / 2), 3, smax); - c_put_str(TERM_WHITE, text, y, x - (strlen(text) / 2)); + c_put_str(TERM_WHITE, prompt.c_str(), y, x - (prompt.size() / 2)); Term_gotoxy(x - (smax / 2) + 1, y + 1); return askfor_aux(buf, max); } -/* - * Creates a msg bbox and ask a question - */ -char msg_box(cptr text, int y, int x) +std::string input_box_auto(std::string const &title, std::size_t max) { - if (x == -1) - { - int wid = 0, hgt = 0; - Term_get_size(&wid, &hgt); - x = wid / 2; - y = hgt / 2; - } + std::string buf; + input_box_auto(title, &buf, max); + return buf; +} + +char msg_box_auto(std::string const &text) +{ + int wid, hgt; + Term_get_size(&wid, &hgt); + + auto const y = hgt / 2; + auto const x = wid / 2; - draw_box(y - 1, x - ((strlen(text) + 1) / 2), 2, strlen(text) + 1); - c_put_str(TERM_WHITE, text, y, x - ((strlen(text) + 1) / 2) + 1); + draw_box(y - 1, x - ((text.size() + 1) / 2), 2, text.size() + 1); + c_put_str(TERM_WHITE, text.c_str(), y, x - ((text.size() + 1) / 2) + 1); return inkey(); } @@ -3631,25 +3642,16 @@ char msg_box(cptr text, int y, int x) */ timer_type *new_timer(void (*callback)(), s32b delay) { - timer_type *t_ptr = new timer_type(); - - static_assert(std::is_pod<timer_type>::value, "Cannot memset a non-POD type"); - memset(t_ptr, 0, sizeof(timer_type)); - - t_ptr->next = gl_timers; - gl_timers = t_ptr; - - t_ptr->callback = callback; - t_ptr->delay = delay; - t_ptr->countdown = delay; - t_ptr->enabled = FALSE; + auto &timers = game->timers; + timer_type *t_ptr = new timer_type(callback, delay); + timers.push_back(t_ptr); return t_ptr; } int get_keymap_mode() { - if (rogue_like_commands) + if (options->rogue_like_commands) { return KEYMAP_MODE_ROGUE; } @@ -7,15 +7,12 @@ extern "C" { #endif -extern errr path_parse(char *buf, int max, cptr file); -extern errr path_build(char *buf, int max, cptr path, cptr file); -extern void bell(void); -extern errr macro_add(cptr pat, cptr act); -extern sint macro_find_exact(cptr pat); -extern char inkey(void); -extern void prt(cptr str, int row, int col); -extern void pause_line(int row); -extern void user_name(char *buf, int id); +errr path_build(char *buf, int max, cptr path, cptr file); +void bell(); +errr macro_add(cptr pat, cptr act); +sint macro_find_exact(cptr pat); +char inkey(); +void prt(cptr str, int row, int col); #ifdef __cplusplus } // extern "C" diff --git a/src/util.hpp b/src/util.hpp index bb8a64f4..1f5c3aed 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -6,69 +6,81 @@ #include <vector> #include <string> -extern bool_ input_box(cptr text, int y, int x, char *buf, int max); -extern void draw_box(int y, int x, int h, int w); -extern void display_list(int y, int x, int h, int w, cptr title, cptr *list, int max, int begin, int sel, byte sel_color); -extern cptr get_player_race_name(int pr, int ps); -extern cptr get_day(int day); -extern s32b bst(s32b what, s32b t); -extern errr path_temp(char *buf, int max); -extern FILE *my_fopen(cptr file, cptr mode); -extern errr my_fgets(FILE *fff, char *buf, huge n); -extern errr my_fclose(FILE *fff); -extern errr fd_kill(cptr file); -extern errr fd_move(cptr file, cptr what); -extern int fd_make(cptr file, int mode); -extern int fd_open(cptr file, int flags); -extern errr fd_seek(int fd, huge n); -extern errr fd_read(int fd, char *buf, huge n); -extern errr fd_write(int fd, cptr buf, huge n); -extern errr fd_close(int fd); -extern void flush(void); -extern void sound(int num); -extern void move_cursor(int row, int col); -extern void text_to_ascii(char *buf, cptr str); -extern void ascii_to_text(char *buf, cptr str); -extern char inkey_scan(void); -extern void display_message(int x, int y, int split, byte color, cptr t); -extern void cmsg_print(byte color, cptr msg); -extern void msg_print(cptr msg); -extern void cmsg_format(byte color, cptr fmt, ...); -extern void msg_format(cptr fmt, ...); -extern void screen_save(void); -extern void screen_load(void); -extern void c_put_str(byte attr, cptr str, int row, int col); -extern void put_str(cptr str, int row, int col); -extern void c_prt(byte attr, cptr str, int row, int col); -extern void text_out_to_screen(byte a, cptr str); -extern void text_out_to_file(byte a, cptr str); -extern void text_out(cptr str); -extern void text_out_c(byte a, cptr str); -extern void clear_from(int row); -extern int ask_menu(cptr ask, const std::vector<std::string> &items); -extern bool_ askfor_aux(char *buf, int len); -extern bool_ askfor_aux_with_completion(char *buf, int len); -extern bool_ get_string(cptr prompt, char *buf, int len); -extern bool_ get_check(cptr prompt); -extern bool_ get_com(cptr prompt, char *command); -extern s32b get_quantity(cptr prompt, s32b max); -extern char request_command_ignore_keymaps[]; +#define MAX_IGNORE_KEYMAPS 12 + +bool input_box(std::string const &text, int y, int x, std::string *buf, std::size_t max); +std::string input_box_auto(std::string const &title, std::size_t max); +bool input_box_auto(std::string const &prompt, std::string *buf, std::size_t max); +void draw_box(int y, int x, int h, int w); +void display_list(int y, int x, int h, int w, cptr title, std::vector<std::string> const &list, std::size_t begin, std::size_t sel, byte sel_color); +std::string get_player_race_name(int pr, int ps); +std::string get_day(s32b day); +s32b bst(s32b what, s32b t); +FILE *my_fopen(cptr file, cptr mode); +errr my_fgets(FILE *fff, char *buf, huge n); +errr my_fclose(FILE *fff); +errr fd_kill(cptr file); +errr fd_move(cptr file, cptr what); +int fd_make(cptr file, int mode); +int fd_open(cptr file, int flags); +errr fd_seek(int fd, huge n); +errr fd_read(int fd, char *buf, huge n); +errr fd_write(int fd, cptr buf, huge n); +errr fd_close(int fd); +void flush(); +void flush_on_failure(); +void move_cursor(int row, int col); +void text_to_ascii(char *buf, cptr str); +void ascii_to_text(char *buf, cptr str); +char inkey_scan(); +void display_message(int x, int y, int split, byte color, cptr t); +void cmsg_print(byte color, cptr msg); +void cmsg_print(byte color, std::string const &msg); +void msg_print(cptr msg); +void cmsg_format(byte color, cptr fmt, ...); +void msg_format(cptr fmt, ...); +void screen_save(); +void screen_load(); +void c_put_str(byte attr, cptr str, int row, int col); +void c_put_str(byte attr, std::string const &str, int row, int col); +void put_str(cptr str, int row, int col); +void put_str(std::string const &s, int row, int col); +void c_prt(byte attr, cptr str, int row, int col); +void c_prt(byte attr, std::string const &s, int row, int col); +void prt(std::string const &s, int row, int col); +void text_out_to_screen(byte a, cptr str); +void text_out_to_file(byte a, cptr str); +void text_out(cptr str); +void text_out_c(byte a, cptr str); +void clear_from(int row); +int ask_menu(cptr ask, const std::vector<std::string> &items); +bool askfor_aux(std::string *buf, std::size_t max_len); +bool_ askfor_aux(char *buf, int len); +bool_ askfor_aux_with_completion(char *buf, int len); +bool_ get_string(cptr prompt, char *buf, int len); +bool_ get_check(cptr prompt); +bool_ get_com(cptr prompt, char *command); +s32b get_quantity(cptr prompt, s32b max); +extern char request_command_ignore_keymaps[MAX_IGNORE_KEYMAPS]; extern bool_ request_command_inven_mode; -extern void request_command(int shopping); -extern bool_ is_a_vowel(int ch); -extern int get_keymap_dir(char ch); -extern byte count_bits(u32b array); -extern void strlower(char *buf); -extern int test_monster_name(cptr name); -extern int test_mego_name(cptr name); -extern int test_item_name(cptr name); -extern char msg_box(cptr text, int y, int x); -extern timer_type *new_timer(void (*callback)(), s32b delay); -extern int get_keymap_mode(); -extern void repeat_push(int what); -extern bool_ repeat_pull(int *what); -extern void repeat_check(void); -extern void get_count(int number, int max); -extern bool in_bounds(int y, int x); -extern bool in_bounds2(int y, int x); -extern bool panel_contains(int y, int x); +void request_command(int shopping); +bool_ is_a_vowel(int ch); +int get_keymap_dir(char ch); +byte count_bits(u32b array); +void strlower(char *buf); +int test_monster_name(cptr name); +int test_mego_name(cptr name); +int test_item_name(cptr name); +char msg_box_auto(std::string const &title); +timer_type *new_timer(void (*callback)(), s32b delay); +int get_keymap_mode(); +void repeat_push(int what); +bool_ repeat_pull(int *what); +void repeat_check(); +void get_count(int number, int max); +bool in_bounds(int y, int x); +bool in_bounds2(int y, int x); +bool panel_contains(int y, int x); +errr path_parse(char *buf, int max, cptr file); +void pause_line(int row); +std::string user_name(); diff --git a/src/variable.cc b/src/variable.cc index f0d18111..ae40676f 100644 --- a/src/variable.cc +++ b/src/variable.cc @@ -11,7 +11,7 @@ #include "cli_comm_fwd.hpp" #include "player_type.hpp" -#include "randart_gen_type.hpp" +#include "skill_modifiers.hpp" #include "util.hpp" @@ -23,27 +23,6 @@ char *macro_trigger_name[MAX_MACRO_TRIG]; char *macro_trigger_keycode[2][MAX_MACRO_TRIG]; /* - * Executable version - */ -byte version_major; -byte version_minor; -byte version_patch; - -/* - * Savefile version - */ -byte sf_major; /* Savefile's "version_major" */ -byte sf_minor; /* Savefile's "version_minor" */ -byte sf_patch; /* Savefile's "version_patch" */ - -/* - * Savefile information - */ -u32b sf_when; /* Time when savefile created */ -u16b sf_lives; /* Number of past "lives" with this file */ -u16b sf_saves; /* Number of "saves" during this life */ - -/* * Run-time aruments */ bool_ arg_wizard; /* Command arg -- Request wizard mode */ @@ -61,7 +40,11 @@ bool_ character_loaded; /* The character was loaded from a savefile */ bool_ character_icky; /* The game is in an icky full screen mode */ bool_ character_xtra; /* The game is in an icky startup mode */ -u32b seed_flavor; /* Hack -- consistent object colors */ +seed_t &seed_flavor() +{ + static seed_t *instance = new seed_t(seed_t::system()); + return *instance; +} s16b command_cmd; /* Current "Angband Command" */ @@ -162,32 +145,9 @@ int text_out_indent = 0; /* - * Software options (set via the '=' command). See "tables.c" + * Options */ - - - - -/* Cheating options */ - -bool_ cheat_peek; /* Peek into object creation */ -bool_ cheat_hear; /* Peek into monster creation */ -bool_ cheat_room; /* Peek into dungeon creation */ -bool_ cheat_xtra; /* Peek into something else */ -bool_ cheat_know; /* Know complete monster info */ -bool_ cheat_live; /* Allow player to avoid death */ - - -/* Special options */ - -byte hitpoint_warn; /* Hitpoint warning (0 to 9) */ - -byte delay_factor; /* Delay factor (0 to 9) */ - -bool_ autosave_l; /* Autosave before entering new levels */ -bool_ autosave_t; /* Timed autosave */ -s16b autosave_freq; /* Autosave frequency */ - +struct options *options = nullptr; /* * Dungeon variables @@ -242,26 +202,6 @@ object_type *tracked_object; /* - * Current player's character name - */ -char player_name[32]; - -/* - * Stripped version of "player_name" - */ -char player_base[32]; - -/* - * What killed the player - */ -char died_from[80]; - -/* - * Hack -- Textual "history" for the Player - */ -char history[4][60]; - -/* * Buffer to hold the current savefile name */ char savefile[1024]; @@ -316,17 +256,10 @@ char *macro__buf; /* - * The array of normal options - */ -u32b option_flag[8]; -u32b option_mask[8]; - - -/* * The array of window options */ -u32b window_flag[8]; -u32b window_mask[8]; +u32b window_flag[ANGBAND_TERM_MAX]; +u32b window_mask[ANGBAND_TERM_MAX]; /* @@ -408,34 +341,6 @@ u16b max_real_towns; town_type *town_info; /* - * The size of "alloc_kind_table" (at most max_k_idx * ALLOCATIONS_MAX) - */ -s16b alloc_kind_size; - -/* - * The entries in the "kind allocator table" - */ -alloc_entry *alloc_kind_table; - -/* - * The flag to tell if alloc_kind_table contains valid entries - * for normal (i.e. kind_is_legal) object allocation - */ -bool_ alloc_kind_table_valid = FALSE; - - -/* - * The size of "alloc_race_table" (at most max_r_idx) - */ -s16b alloc_race_size; - -/* - * The entries in the "race allocator table" - */ -alloc_entry *alloc_race_table; - - -/* * Specify attr/char pairs for visual special effects * Be sure to use "index & 0x7F" to avoid illegal access */ @@ -469,124 +374,17 @@ player_type *p_ptr = nullptr; * Pointer to the player tables * (sex, race, race mod, class, magic) */ -player_sex *sp_ptr; -player_race *rp_ptr; -player_race_mod *rmp_ptr; -player_class *cp_ptr; -player_spec *spp_ptr; - - -/* - * Calculated base hp values for player at each level, - * store them so that drain life + restore life does not - * affect hit points. Also prevents shameless use of backup - * savefiles for hitpoint acquirement. - */ -s16b player_hp[PY_MAX_LEVEL]; - -/* - * The vault generation arrays - */ -vault_type *v_info; - -/* - * The terrain feature arrays - */ -feature_type *f_info; - -/* - * The object kind arrays - */ -object_kind *k_info; - -/* - * The artifact arrays - */ -artifact_type *a_info; - -/* - * The item set arrays - */ -set_type *set_info; - -/* - * The ego-item arrays - */ -ego_item_type *e_info; - -/* - * The randart arrays - */ -randart_part_type *ra_info; -randart_gen_type ra_gen[30]; - -/* jk */ -/* the trap-arrays */ -trap_type *t_info; - -/* - * The monster race arrays - */ -monster_race *r_info; - -/* - * The monster ego race arrays - */ -monster_ego *re_info; - -/* - * The dungeon types arrays - */ -dungeon_info_type *d_info; - -/* - * Player abilities arrays - */ -ability_type *ab_info; - -/* - * Player skills arrays - */ -skill_type *s_info; - -/* - * Player race arrays - */ -player_race *race_info; - -/* - * Player mod race arrays - */ -player_race_mod *race_mod_info; - -/* - * Player class arrays - */ -player_class *class_info; -meta_class_type *meta_class_info; +player_race const *rp_ptr; +player_race_mod const *rmp_ptr; +player_class const *cp_ptr; +player_spec const *spp_ptr; /* * The wilderness features arrays */ -wilderness_type_info *wf_info; int wildc2i[256]; /* - * The store/building types arrays - */ -store_info_type *st_info; - -/* - * The building actions types arrays - */ -store_action_type *ba_info; - -/* - * The owner types arrays - */ -owner_type *ow_info; - -/* * Default texts for feature information. */ cptr DEFAULT_FEAT_TEXT = "a wall blocking your way"; @@ -703,102 +501,6 @@ s32b get_level_max_stick = -1; s32b get_level_use_stick = -1; /* - * Maximum size of the wilderness map - */ -u16b max_wild_x; -u16b max_wild_y; - -/* - * Wilderness map - */ -wilderness_map **wild_map; - - -/* - * Maximum number of skills in s_info.txt - */ -u16b old_max_s_idx = 0; -u16b max_s_idx; - -/* - * Maximum number of abilities in ab_info.txt - */ -u16b max_ab_idx; - -/* - * Maximum number of monsters in r_info.txt - */ -u16b max_r_idx; - -/* - * Maximum number of ego monsters in re_info.txt - */ -u16b max_re_idx; - -/* - * Maximum number of items in k_info.txt - */ -u16b max_k_idx; - -/* - * Maximum number of vaults in v_info.txt - */ -u16b max_v_idx; - -/* - * Maximum number of terrain features in f_info.txt - */ -u16b max_f_idx; - -/* - * Maximum number of artifacts in a_info.txt - */ -u16b max_a_idx; - -/* - * Maximum number of ego-items in e_info.txt - */ -u16b max_e_idx; - -/* - * Maximum number of randarts in ra_info.txt - */ -u16b max_ra_idx; - -/* - * Maximum number of dungeon types in d_info.txt - */ -u16b max_d_idx; - -/* - * Maximum number of stores types in st_info.txt - */ -u16b max_st_idx; - -/* - * Item sets - */ -u16b max_set_idx = 1; - -/* - * Maximum number of players info in p_info.txt - */ -u16b max_rp_idx; -u16b max_rmp_idx; -u16b max_c_idx; -u16b max_mc_idx; - -/* - * Maximum number of actions types in ba_info.txt - */ -u16b max_ba_idx; - -/* - * Maximum number of owner types in ow_info.txt - */ -u16b max_ow_idx; - -/* * Maximum number of objects in the level */ u16b max_o_idx; @@ -809,16 +511,6 @@ u16b max_o_idx; u16b max_m_idx; /* - * Maximum number of traps in tr_info.txt - */ -u16b max_t_idx; - -/* - * Maximum number of wilderness features in wf_info.txt - */ -u16b max_wf_idx; - -/* * Flags for initialization */ int init_flags; @@ -838,25 +530,11 @@ bool_ carried_monster_hit = FALSE; /* * Random artifacts. */ -random_artifact random_artifacts[MAX_RANDARTS]; -/* These three used to be constants but now are set by modules */ s32b RANDART_WEAPON; s32b RANDART_ARMOR; s32b RANDART_JEWEL; /* - * Random spells. - */ -random_spell random_spells[MAX_SPELLS]; -s16b spell_num; - -/* - * Runecrafter's selfmade spells. - */ -rune_spell rune_spells[MAX_RUNES]; -s16b rune_num; - -/* * Fate. */ fate fates[MAX_FATES]; @@ -879,10 +557,7 @@ s16b *max_dlv; s16b doppleganger; /* To allow wilderness encounters */ -bool_ generate_encounter; - -/* Special levels */ -bool_ special_lvls; +bool_ generate_encounter = FALSE; /* * Such an ugly hack ... @@ -902,27 +577,9 @@ s16b plots[MAX_PLOTS]; random_quest random_quests[MAX_RANDOM_QUEST]; /* - * Special levels - */ -bool_ *special_lvl[MAX_DUNGEON_DEPTH]; -bool_ generate_special_feeling = FALSE; - -/* * Dungeon flags */ -u32b dungeon_flags1; -u32b dungeon_flags2; - -/* - * The last character displayed - */ -birther previous_char; - -/* - * Race histories - */ -hist_type *bg; -int max_bg_idx; +DECLARE_FLAG_ZERO_IMPL(dungeon_flag_set, dungeon_flags); /* * The spell list of schools @@ -938,25 +595,12 @@ s32b project_time_effect = 0; effect_type effects[MAX_EFFECTS]; /* - * General skills set - */ -char gen_skill_basem[MAX_SKILLS]; -u32b gen_skill_base[MAX_SKILLS]; -char gen_skill_modm[MAX_SKILLS]; -s16b gen_skill_mod[MAX_SKILLS]; - -/* * Table of "cli" macros. */ cli_comm *cli_info; int cli_total = 0; /* - * max_bact, only used so that lua scripts can add new bacts without worrying about the numbers - */ -int max_bact = 127; - -/* * Automatizer enabled status */ bool_ automatizer_enabled = FALSE; @@ -980,19 +624,12 @@ s32b VERSION_PATCH; /* * Some module info */ -s32b max_plev = 50; s32b DUNGEON_BASE = 4; s32b DUNGEON_DEATH = 28; s32b DUNGEON_ASTRAL = 8; s32b DUNGEON_ASTRAL_WILD_X = 45; s32b DUNGEON_ASTRAL_WILD_Y = 19; -/* - * Timers - */ -timer_type *gl_timers = NULL; - - /** * Get the version string. */ @@ -1010,56 +647,3 @@ const char *get_version_string() } return version_str; } - -/* - * A list of tvals and their textual names - */ -tval_desc tvals[] = -{ - { TV_SWORD, "Sword" }, - { TV_POLEARM, "Polearm" }, - { TV_HAFTED, "Hafted Weapon" }, - { TV_AXE, "Axe" }, - { TV_BOW, "Bow" }, - { TV_BOOMERANG, "Boomerang" }, - { TV_ARROW, "Arrows" }, - { TV_BOLT, "Bolts" }, - { TV_SHOT, "Shots" }, - { TV_SHIELD, "Shield" }, - { TV_CROWN, "Crown" }, - { TV_HELM, "Helm" }, - { TV_GLOVES, "Gloves" }, - { TV_BOOTS, "Boots" }, - { TV_CLOAK, "Cloak" }, - { TV_DRAG_ARMOR, "Dragon Scale Mail" }, - { TV_HARD_ARMOR, "Hard Armor" }, - { TV_SOFT_ARMOR, "Soft Armor" }, - { TV_RING, "Ring" }, - { TV_AMULET, "Amulet" }, - { TV_LITE, "Lite" }, - { TV_POTION, "Potion" }, - { TV_POTION2, "Potion" }, - { TV_SCROLL, "Scroll" }, - { TV_WAND, "Wand" }, - { TV_STAFF, "Staff" }, - { TV_ROD_MAIN, "Rod" }, - { TV_ROD, "Rod Tip" }, - { TV_BOOK, "Schools Spellbook", }, - { TV_SYMBIOTIC_BOOK, "Symbiotic Spellbook", }, - { TV_DRUID_BOOK, "Elemental Stone" }, - { TV_MUSIC_BOOK, "Music Book" }, - { TV_DAEMON_BOOK, "Daemon Book" }, - { TV_SPIKE, "Spikes" }, - { TV_DIGGING, "Digger" }, - { TV_CHEST, "Chest" }, - { TV_FOOD, "Food" }, - { TV_FLASK, "Flask" }, - { TV_MSTAFF, "Mage Staff" }, - { TV_PARCHMENT, "Parchment" }, - { TV_INSTRUMENT, "Musical Instrument" }, - { TV_RUNE1, "Rune 1" }, - { TV_RUNE2, "Rune 2" }, - { TV_JUNK, "Junk" }, - { TV_TRAPKIT, "Trapping Kit" }, - { 0, NULL } -}; diff --git a/src/variable.h b/src/variable.h index 7621149a..6d6e5775 100644 --- a/src/variable.h +++ b/src/variable.h @@ -7,10 +7,7 @@ extern "C" { #endif extern cptr ANGBAND_SYS; -extern char *ANGBAND_DIR_MODULES; extern char *ANGBAND_DIR_SAVE; -extern char *ANGBAND_DIR_CORE; -extern char *ANGBAND_DIR_DNGN; extern char *ANGBAND_DIR_DATA; extern char *ANGBAND_DIR_EDIT; extern char *ANGBAND_DIR_FILE; @@ -23,15 +20,10 @@ extern char *ANGBAND_DIR_XTRA; extern term *angband_term[ANGBAND_TERM_MAX]; extern char angband_term_name[ANGBAND_TERM_MAX][80]; extern byte angband_color_table[256][4]; -extern bool_ arg_wizard; -extern bool_ arg_force_original; -extern bool_ arg_force_roguelike; extern bool_ character_generated; extern bool_ character_icky; extern bool_ inkey_flag; extern bool_ msg_flag; -extern char player_name[32]; -extern char player_base[32]; extern char savefile[1024]; #ifdef __cplusplus diff --git a/src/variable.hpp b/src/variable.hpp index ab52f5b6..73d63be7 100644 --- a/src/variable.hpp +++ b/src/variable.hpp @@ -1,51 +1,29 @@ #pragma once #include "angband.h" -#include "ability_type_fwd.hpp" #include "alloc_entry_fwd.hpp" -#include "artifact_type_fwd.hpp" #include "birther.hpp" #include "cave_type_fwd.hpp" #include "deity_type.hpp" -#include "dungeon_info_type_fwd.hpp" +#include "dungeon_flag_set.hpp" #include "effect_type.hpp" -#include "ego_item_type_fwd.hpp" #include "fate.hpp" -#include "feature_type_fwd.hpp" -#include "hist_type_fwd.hpp" -#include "meta_class_type_fwd.hpp" -#include "monster_ego_fwd.hpp" -#include "monster_race_fwd.hpp" #include "monster_type_fwd.hpp" -#include "object_kind_fwd.hpp" #include "object_type_fwd.hpp" -#include "owner_type_fwd.hpp" +#include "options.hpp" #include "player_class_fwd.hpp" #include "player_defs.hpp" #include "player_race_fwd.hpp" #include "player_race_mod_fwd.hpp" -#include "player_sex_fwd.hpp" #include "player_spec_fwd.hpp" #include "player_type_fwd.hpp" -#include "randart_gen_type_fwd.hpp" -#include "randart_part_type_fwd.hpp" -#include "random_artifact.hpp" #include "random_quest.hpp" -#include "random_spell.hpp" -#include "rune_spell.hpp" #include "school_type.hpp" -#include "set_type_fwd.hpp" -#include "skill_type_fwd.hpp" +#include "skill_modifiers_fwd.hpp" #include "skills_defs.hpp" -#include "store_action_type_fwd.hpp" -#include "store_info_type_fwd.hpp" #include "timer_type_fwd.hpp" #include "town_type_fwd.hpp" -#include "trap_type_fwd.hpp" -#include "tval_desc.hpp" -#include "vault_type_fwd.hpp" -#include "wilderness_map_fwd.hpp" -#include "wilderness_type_info_fwd.hpp" +#include "seed.hpp" extern int max_macrotrigger; extern char *macro_template; @@ -53,19 +31,10 @@ extern char *macro_modifier_chr; extern char *macro_modifier_name[MAX_MACRO_MOD]; extern char *macro_trigger_name[MAX_MACRO_TRIG]; extern char *macro_trigger_keycode[2][MAX_MACRO_TRIG]; -extern byte version_major; -extern byte version_minor; -extern byte version_patch; -extern byte sf_major; -extern byte sf_minor; -extern byte sf_patch; -extern u32b sf_when; -extern u16b sf_lives; -extern u16b sf_saves; extern bool_ character_dungeon; extern bool_ character_loaded; extern bool_ character_xtra; -extern u32b seed_flavor; +seed_t &seed_flavor(); extern s16b command_cmd; extern s16b command_arg; extern s16b command_rep; @@ -117,17 +86,6 @@ extern int artifact_bias; extern FILE *text_out_file; extern void (*text_out_hook)(byte a, cptr str); extern int text_out_indent; -extern bool_ cheat_peek; -extern bool_ cheat_hear; -extern bool_ cheat_room; -extern bool_ cheat_xtra; -extern bool_ cheat_know; -extern bool_ cheat_live; -extern byte hitpoint_warn; -extern byte delay_factor; -extern s16b autosave_freq; -extern bool_ autosave_t; -extern bool_ autosave_l; extern s16b feeling; extern s16b rating; extern bool_ good_item_flag; @@ -146,8 +104,6 @@ extern s16b health_who; extern s16b monster_race_idx; extern s16b monster_ego_idx; extern object_type *tracked_object; -extern char died_from[80]; -extern char history[4][60]; extern s16b lite_n; extern s16b lite_y[LITE_MAX]; extern s16b lite_x[LITE_MAX]; @@ -162,8 +118,6 @@ extern char **macro__pat; extern char **macro__act; extern bool_ *macro__cmd; extern char *macro__buf; -extern u32b option_flag[8]; -extern u32b option_mask[8]; extern u32b window_flag[ANGBAND_TERM_MAX]; extern u32b window_mask[ANGBAND_TERM_MAX]; extern cave_type **cave; @@ -173,120 +127,53 @@ extern monster_type *km_list; extern u16b max_real_towns; extern u16b max_towns; extern town_type *town_info; -extern s16b alloc_kind_size; -extern alloc_entry *alloc_kind_table; -extern bool_ alloc_kind_table_valid; -extern s16b alloc_race_size; -extern alloc_entry *alloc_race_table; extern byte misc_to_attr[256]; extern char misc_to_char[256]; extern byte tval_to_attr[128]; extern char tval_to_char[128]; extern char *keymap_act[KEYMAP_MODES][256]; extern player_type *p_ptr; -extern player_sex *sp_ptr; -extern player_race *rp_ptr; -extern player_race_mod *rmp_ptr; -extern player_class *cp_ptr; -extern player_spec *spp_ptr; -extern s16b player_hp[PY_MAX_LEVEL]; -extern ability_type *ab_info; -extern skill_type *s_info; -extern vault_type *v_info; -extern feature_type *f_info; -extern object_kind *k_info; -extern artifact_type *a_info; -extern ego_item_type *e_info; -extern randart_part_type *ra_info; -extern randart_gen_type ra_gen[30]; -extern monster_race *r_info; -extern monster_ego *re_info; -extern dungeon_info_type *d_info; -extern player_class *class_info; -extern meta_class_type *meta_class_info; -extern player_race *race_info; -extern player_race_mod *race_mod_info; -extern trap_type *t_info; -extern wilderness_type_info *wf_info; +extern player_race const *rp_ptr; +extern player_race_mod const *rmp_ptr; +extern player_class const *cp_ptr; +extern player_spec const *spp_ptr; extern int wildc2i[256]; -extern store_info_type *st_info; -extern store_action_type *ba_info; -extern owner_type *ow_info; -extern set_type *set_info; extern cptr DEFAULT_FEAT_TEXT; extern cptr DEFAULT_FEAT_TUNNEL; extern cptr DEFAULT_FEAT_BLOCK; extern char *ANGBAND_DIR; +extern char *ANGBAND_DIR_MODULES; +extern char *ANGBAND_DIR_CORE; +extern char *ANGBAND_DIR_DNGN; extern bool_ (*get_mon_num_hook)(int r_idx); extern bool_ (*get_mon_num2_hook)(int r_idx); extern bool_ (*get_obj_num_hook)(int k_idx); -extern u16b max_wild_x; -extern u16b max_wild_y; -extern wilderness_map **wild_map; -extern u16b old_max_s_idx; -extern u16b max_ab_idx; -extern u16b max_s_idx; -extern u16b max_r_idx; -extern u16b max_re_idx; -extern u16b max_k_idx; -extern u16b max_v_idx; -extern u16b max_f_idx; -extern u16b max_a_idx; -extern u16b max_e_idx; -extern u16b max_ra_idx; -extern u16b max_d_idx; extern u16b max_o_idx; extern u16b max_m_idx; -extern u16b max_t_idx; -extern u16b max_rp_idx; -extern u16b max_c_idx; -extern u16b max_mc_idx; -extern u16b max_rmp_idx; -extern u16b max_st_idx; -extern u16b max_ba_idx; -extern u16b max_ow_idx; -extern u16b max_wf_idx; -extern u16b max_set_idx; extern int init_flags; extern bool_ ambush_flag; extern bool_ fate_flag; extern s16b no_breeds; extern bool_ carried_monster_hit; -extern random_artifact random_artifacts[MAX_RANDARTS]; extern s32b RANDART_WEAPON; extern s32b RANDART_ARMOR; extern s32b RANDART_JEWEL; -extern random_spell random_spells[MAX_SPELLS]; -extern s16b spell_num; -extern rune_spell rune_spells[MAX_RUNES]; -extern s16b rune_num; extern fate fates[MAX_FATES]; extern byte dungeon_type; extern s16b *max_dlv; extern s16b doppleganger; extern bool_ generate_encounter; -extern bool_ special_lvls; extern bool_ *m_allow_special; extern bool_ *k_allow_special; extern bool_ *a_allow_special; extern s16b plots[MAX_PLOTS]; extern random_quest random_quests[MAX_RANDOM_QUEST]; -extern bool_ *special_lvl[MAX_DUNGEON_DEPTH]; -extern bool_ generate_special_feeling; -extern u32b dungeon_flags1; -extern u32b dungeon_flags2; -extern birther previous_char; -extern int max_bg_idx; +DECLARE_FLAG_ZERO_INTF(dungeon_flag_set, dungeon_flags); extern s16b schools_count; extern school_type schools[SCHOOLS_MAX]; extern int project_time; extern s32b project_time_effect; extern effect_type effects[MAX_EFFECTS]; -extern char gen_skill_basem[MAX_SKILLS]; -extern u32b gen_skill_base[MAX_SKILLS]; -extern char gen_skill_modm[MAX_SKILLS]; -extern s16b gen_skill_mod[MAX_SKILLS]; -extern int max_bact; extern bool_ automatizer_enabled; extern s16b last_teleportation_y; extern s16b last_teleportation_x; @@ -295,14 +182,14 @@ extern s32b game_module_idx; extern s32b VERSION_MAJOR; extern s32b VERSION_MINOR; extern s32b VERSION_PATCH; -extern s32b max_plev; extern s32b DUNGEON_BASE; extern s32b DUNGEON_DEATH; extern s32b DUNGEON_ASTRAL; extern s32b DUNGEON_ASTRAL_WILD_X; extern s32b DUNGEON_ASTRAL_WILD_Y; extern deity_type deity_info[MAX_GODS]; -extern timer_type *gl_timers; -extern const char *get_version_string(); -extern tval_desc tvals[]; -extern hist_type *bg; +const char *get_version_string(); +extern bool_ arg_wizard; +extern bool_ arg_force_original; +extern bool_ arg_force_roguelike; +extern struct options *options; diff --git a/src/vault_type.hpp b/src/vault_type.hpp index 650599cb..9d407d8f 100644 --- a/src/vault_type.hpp +++ b/src/vault_type.hpp @@ -1,24 +1,25 @@ #pragma once #include "h-basic.h" +#include <string> /** * Vault descriptors. */ struct vault_type { - char *data; /* Vault data */ + std::string data; /* Vault data */ - byte typ; /* Vault type */ + byte typ = 0; /* Vault type */ - byte rat; /* Vault rating */ + byte rat = 0; /* Vault rating */ - byte hgt; /* Vault height */ - byte wid; /* Vault width */ + byte hgt = 0; /* Vault height */ + byte wid = 0; /* Vault width */ - s16b lvl; /* level of special (if any) */ - byte dun_type; /* Dungeon type where the level will show up */ + s16b lvl = 0; /* level of special (if any) */ + byte dun_type = 0; /* Dungeon type where the level will show up */ - s16b mon[10]; /* special monster */ - int item[3]; /* number of item (usually artifact) */ + s16b mon[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* special monster */ + int item[3] = { 0, 0, 0 }; /* number of item (usually artifact) */ }; diff --git a/src/vault_type_fwd.hpp b/src/vault_type_fwd.hpp deleted file mode 100644 index 25ffd8cc..00000000 --- a/src/vault_type_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct vault_type; diff --git a/src/wild.cc b/src/wild.cc index 7724176f..3d86c0b7 100644 --- a/src/wild.cc +++ b/src/wild.cc @@ -10,7 +10,9 @@ #include "cave.hpp" #include "cave_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" +#include "game.hpp" #include "hook_wild_gen_in.hpp" #include "hooks.hpp" #include "init1.hpp" @@ -20,6 +22,7 @@ #include "options.hpp" #include "player_type.hpp" #include "store_info_type.hpp" +#include "store_flag.hpp" #include "tables.hpp" #include "town_type.hpp" #include "util.hpp" @@ -28,6 +31,7 @@ #include "wilderness_type_info.hpp" #include "z-rand.hpp" +#include <algorithm> #include <memory> @@ -152,13 +156,19 @@ static void plasma_recursive(int x1, int y1, int x2, int y2, */ static int generate_area(int y, int x, bool_ border, bool_ corner) { + auto const &wilderness = game->wilderness; + auto const &wf_info = game->edit_data.wf_info; + int road, entrance; int x1, y1; int hack_floor = 0; /* Number of the town (if any) */ - p_ptr->town_num = wf_info[wild_map[y][x].feat].entrance; - if (!p_ptr->town_num) p_ptr->town_num = wild_map[y][x].entrance; + p_ptr->town_num = wf_info[wilderness(x, y).feat].entrance; + if (!p_ptr->town_num) + { + p_ptr->town_num = wilderness(x, y).entrance; + } { int roughness = 1; /* The roughness of the level. */ @@ -170,25 +180,23 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) if (!p_ptr->oldpy) p_ptr->oldpy = MAX_HGT / 2; /* Initialize the terrain array */ - ym = ((y - 1) < 0) ? 0 : (y - 1); - xm = ((x - 1) < 0) ? 0 : (x - 1); - yp = ((y + 1) >= max_wild_y) ? (max_wild_y - 1) : (y + 1); - xp = ((x + 1) >= max_wild_x) ? (max_wild_x - 1) : (x + 1); - terrain[0][0] = wild_map[ym][xm].feat; - terrain[0][1] = wild_map[ym][x].feat; - terrain[0][2] = wild_map[ym][xp].feat; - terrain[1][0] = wild_map[y][xm].feat; - terrain[1][1] = wild_map[y][x].feat; - terrain[1][2] = wild_map[y][xp].feat; - terrain[2][0] = wild_map[yp][xm].feat; - terrain[2][1] = wild_map[yp][x].feat; - terrain[2][2] = wild_map[yp][xp].feat; - - /* Hack -- Use the "simple" RNG */ - Rand_quick = TRUE; + ym = std::max<int>(y - 1, 0); + xm = std::max<int>(x - 1, 0); + yp = std::min<int>(y + 1, static_cast<int>(wilderness.height()) - 1); + xp = std::min<int>(x + 1, static_cast<int>(wilderness.width()) - 1); + + terrain[0][0] = wilderness(xm, ym).feat; + terrain[0][1] = wilderness(x , ym).feat; + terrain[0][2] = wilderness(xp, ym).feat; + terrain[1][0] = wilderness(xm, y ).feat; + terrain[1][1] = wilderness(x , y ).feat; + terrain[1][2] = wilderness(xp, y ).feat; + terrain[2][0] = wilderness(xm, yp).feat; + terrain[2][1] = wilderness(x , yp).feat; + terrain[2][2] = wilderness(xp, yp).feat; /* Hack -- Induce consistant town layout */ - Rand_value = wild_map[y][x].seed; + set_quick_rng(wilderness(x, y).seed); /* Create level background */ for (y1 = 0; y1 < MAX_HGT; y1++) @@ -215,9 +223,6 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) plasma_recursive(1, 1, MAX_WID - 2, MAX_HGT - 2, MAX_WILD_TERRAIN - 1, roughness); } - /* Use the complex RNG */ - Rand_quick = FALSE; - for (y1 = 1; y1 < MAX_HGT - 1; y1++) { for (x1 = 1; x1 < MAX_WID - 1; x1++) @@ -227,6 +232,8 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) } } + /* Change back to "complex" RNG */ + set_complex_rng(); } /* Should we create a town ? */ @@ -252,7 +259,7 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) * Place roads in the wilderness * ToDo: make the road a bit more interresting */ - road = wf_info[wild_map[y][x].feat].road; + road = wf_info[wilderness(x, y).feat].road; if (road & ROAD_NORTH) { @@ -295,14 +302,11 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) } } - /* Hack -- Use the "simple" RNG */ - Rand_quick = TRUE; - /* Hack -- Induce consistant town layout */ - Rand_value = wild_map[y][x].seed; + set_quick_rng(wilderness(x, y).seed); - entrance = wf_info[wild_map[y][x].feat].entrance; - if (!entrance) entrance = wild_map[y][x].entrance; + entrance = wf_info[wilderness(x, y).feat].entrance; + if (!entrance) entrance = wilderness(x, y).entrance; /* Create the dungeon if requested on the map */ if (entrance >= 1000) @@ -318,7 +322,7 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) } /* Use the complex RNG */ - Rand_quick = FALSE; + set_complex_rng(); /* MEGA HACK -- set at least one floor grid */ for (y1 = 1; y1 < cur_hgt - 1; y1++) @@ -337,11 +341,10 @@ static int generate_area(int y, int x, bool_ border, bool_ corner) hack_floor = 1; } - /* Set the monster generation level to the wilderness level */ - monster_level = wf_info[wild_map[y][x].feat].level; - - /* Set the object generation level to the wilderness level */ - object_level = wf_info[wild_map[y][x].feat].level; + /* Set the monster/object generation level to the wilderness level */ + auto const &wf = wf_info[wilderness(x, y).feat]; + monster_level = wf.level; + object_level = wf.level; return hack_floor; } @@ -373,6 +376,8 @@ namespace { */ void wilderness_gen() { + auto const &f_info = game->edit_data.f_info; + int i, y, x, hack_floor; bool_ daytime; int xstart = 0; @@ -514,15 +519,18 @@ void wilderness_gen() if (daytime) { /* Assume lit */ - c_ptr->info |= (CAVE_GLOW); + c_ptr->info |= CAVE_GLOW; /* Hack -- Memorize lit grids if allowed */ - if (view_perma_grids) c_ptr->info |= (CAVE_MARK); + if (options->view_perma_grids) + { + c_ptr->info |= CAVE_MARK; + } } else { /* Darken "boring" features */ - if (!(f_info[c_ptr->feat].flags1 & FF1_REMEMBER)) + if (!(f_info[c_ptr->feat].flags & FF_REMEMBER)) { /* Forget the grid */ c_ptr->info &= ~(CAVE_GLOW | CAVE_MARK); @@ -546,7 +554,7 @@ void wilderness_gen() for (i = 0; i < lim; i++) { /* Make a resident */ - (void)alloc_monster((generate_encounter == TRUE) ? 0 : 3, (generate_encounter == TRUE) ? FALSE : TRUE); + alloc_monster((generate_encounter == TRUE) ? 0 : 3, (generate_encounter == TRUE) ? FALSE : TRUE); } if (generate_encounter) ambush_flag = TRUE; @@ -572,14 +580,16 @@ void wilderness_gen() */ void wilderness_gen_small() { - int i, j, entrance; + auto const &wilderness = game->wilderness; + auto const &wf_info = game->edit_data.wf_info; + int xstart = 0; int ystart = 0; /* To prevent stupid things */ - for (i = 0; i < MAX_WID; i++) + for (int i = 0; i < MAX_WID; i++) { - for (j = 0; j < MAX_HGT; j++) + for (int j = 0; j < MAX_HGT; j++) { cave_set_feat(j, i, FEAT_EKKAIA); } @@ -589,31 +599,35 @@ void wilderness_gen_small() process_dungeon_file("w_info.txt", &ystart, &xstart, cur_hgt, cur_wid, TRUE, FALSE); /* Fill the map */ - for (i = 0; i < max_wild_x; i++) + for (std::size_t x = 0; x < wilderness.width(); x++) { - for (j = 0; j < max_wild_y; j++) + for (std::size_t y = 0; y < wilderness.height(); y++) { - entrance = wf_info[wild_map[j][i].feat].entrance; - if (!entrance) entrance = wild_map[j][i].entrance; + auto const &wm = wilderness(x, y); + + int entrance = wf_info[wm.feat].entrance; + if (!entrance) entrance = wm.entrance; - if (wild_map[j][i].entrance) + if (wm.entrance) { - cave_set_feat(j, i, FEAT_MORE); + cave_set_feat(y, x, FEAT_MORE); } else { - cave_set_feat(j, i, wf_info[wild_map[j][i].feat].feat); + cave_set_feat(y, x, wf_info[wm.feat].feat); } - if ((cave[j][i].feat == FEAT_MORE) && (entrance >= 1000)) + auto &cv = cave[y][x]; + + if ((cv.feat == FEAT_MORE) && (entrance >= 1000)) { - cave[j][i].special = entrance - 1000; + cv.special = entrance - 1000; } /* Show it if we know it */ - if (wild_map[j][i].known) + if (wm.known) { - cave[j][i].info |= (CAVE_GLOW | CAVE_MARK); + cv.info |= (CAVE_GLOW | CAVE_MARK); } } } @@ -623,7 +637,7 @@ void wilderness_gen_small() p_ptr->py = p_ptr->wilderness_y; /* Set rewarded quests to finished */ - for (i = 0; i < MAX_Q_IDX; i++) + for (int i = 0; i < MAX_Q_IDX; i++) { if (quest[i].status == QUEST_STATUS_REWARDED) { @@ -638,26 +652,30 @@ void wilderness_gen_small() /* Show a small radius of wilderness around the player */ void reveal_wilderness_around_player(int y, int x, int h, int w) { - int i, j; + auto &wilderness = game->wilderness; /* Circle or square ? */ if (h == 0) { - for (i = x - w; i < x + w; i++) + for (int i = x - w; i < x + w; i++) { - for (j = y - w; j < y + w; j++) + for (int j = y - w; j < y + w; j++) { /* Bound checking */ if (!in_bounds(j, i)) continue; /* Severe bound checking */ - if ((i < 0) || (i >= max_wild_x) || (j < 0) || (j >= max_wild_y)) continue; + if ((i < 0) || (static_cast<size_t>(i) >= wilderness.width()) || + (j < 0) || (static_cast<size_t>(j) >= wilderness.height())) + { + continue; + } /* We want a radius, not a "squarus" :) */ if (distance(y, x, j, i) >= w) continue; /* New we know here */ - wild_map[j][i].known = TRUE; + wilderness(i, j).known = TRUE; /* Only if we are in overview */ if (p_ptr->wild_mode) @@ -672,15 +690,15 @@ void reveal_wilderness_around_player(int y, int x, int h, int w) } else { - for (i = x; i < x + w; i++) + for (int i = x; i < x + w; i++) { - for (j = y; j < y + h; j++) + for (int j = y; j < y + h; j++) { /* Bound checking */ if (!in_bounds(j, i)) continue; /* New we know here */ - wild_map[j][i].known = TRUE; + wilderness(i, j).known = TRUE; /* Only if we are in overview */ if (p_ptr->wild_mode) @@ -876,38 +894,58 @@ static void build_store_hidden(int n, int yy, int xx) } /* Return a list of stores */ -static int get_shops(int *rooms) +static std::vector<std::size_t> get_shops() { - int i, n, num = 0; + auto const &st_info = game->edit_data.st_info; - for (n = 0; n < max_st_idx; n++) - { - rooms[n] = 0; - } + std::vector<std::size_t> rooms; - for (n = 0; n < max_st_idx; n++) + for (std::size_t n = 0; n < st_info.size(); n++) { int chance = 50; - if (st_info[n].flags1 & SF1_COMMON) chance += 30; - if (st_info[n].flags1 & SF1_RARE) chance -= 20; - if (st_info[n].flags1 & SF1_VERY_RARE) chance -= 30; + if (st_info[n].flags & STF_COMMON) + { + chance += 30; + } - if (!magik(chance)) continue; + if (st_info[n].flags & STF_RARE) + { + chance -= 20; + } - for (i = 0; i < num; ++i) + if (st_info[n].flags & STF_VERY_RARE) + { + chance -= 30; + } + + if (!magik(chance)) + { + continue; + } + + for (std::size_t i = 0; i < rooms.size(); ++i) + { if (rooms[i] == n) + { continue; + } + } - if (st_info[n].flags1 & SF1_RANDOM) rooms[num++] = n; + if (st_info[n].flags & STF_RANDOM) + { + rooms.push_back(n); + } } - return num; + return rooms; } /* Generate town borders */ static void set_border(int y, int x) { + auto const &f_info = game->edit_data.f_info; + cave_type *c_ptr; /* Paranoia */ @@ -915,7 +953,7 @@ static void set_border(int y, int x) /* Was a floor */ if (cave_floor_bold(y, x) || - (f_info[cave[y][x].feat].flags1 & FF1_DOOR)) + (f_info[cave[y][x].feat].flags & FF_DOOR)) { cave_set_feat(y, x, FEAT_DOOR_HEAD); } @@ -937,7 +975,7 @@ static void set_border(int y, int x) } -static void town_borders(int t_idx, int qy, int qx) +static void town_borders(int qy, int qx) { int y, x; @@ -968,10 +1006,11 @@ static void town_borders(int t_idx, int qy, int qx) static bool_ create_townpeople_hook(int r_idx) { - monster_race *r_ptr = &r_info[r_idx]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[r_idx]; - if (r_ptr->d_char == 't') return TRUE; - else return FALSE; + return (r_ptr->d_char == 't'); } @@ -982,9 +1021,9 @@ static bool_ create_townpeople_hook(int r_idx) * layout, including the size and shape of the buildings, the * locations of the doorways, and the location of the stairs. */ -static void town_gen_hack(int t_idx, int qy, int qx) +static void town_gen_hack(int qy, int qx) { - int y, x, floor, num = 0; + int y, x, floor; bool_ (*old_get_mon_num_hook)(int r_idx); /* Do we use dungeon floor or normal one */ @@ -1003,8 +1042,7 @@ static void town_gen_hack(int t_idx, int qy, int qx) } /* Prepare an Array of "remaining stores", and count them */ - std::unique_ptr<int[]> rooms(new int[max_st_idx]); - num = get_shops(rooms.get()); + auto rooms = get_shops(); /* Place two rows of stores */ for (y = 0; y < 2; y++) @@ -1012,16 +1050,20 @@ static void town_gen_hack(int t_idx, int qy, int qx) /* Place four stores per row */ for (x = 0; x < 4; x++) { - if(--num > -1) + if (!rooms.empty()) { + /* Extract store */ + auto room = rooms.back(); + rooms.pop_back(); + /* Build that store at the proper location */ - build_store(qy, qx, rooms[num], y, x); + build_store(qy, qx, room, y, x); } } } /* Generates the town's borders */ - if (magik(TOWN_NORMAL_FLOOR)) town_borders(t_idx, qy, qx); + if (magik(TOWN_NORMAL_FLOOR)) town_borders(qy, qx); /* Some inhabitants(leveled .. hehe :) */ @@ -1070,9 +1112,9 @@ static void town_gen_hack(int t_idx, int qy, int qx) get_mon_num_prep(); } -static void town_gen_circle(int t_idx, int qy, int qx) +static void town_gen_circle(int qy, int qx) { - int y, x, cy, cx, rad, floor, num = 0; + int y, x, cy, cx, rad, floor; bool_ (*old_get_mon_num_hook)(int r_idx); /* Do we use dungeon floor or normal one */ @@ -1135,9 +1177,8 @@ static void town_gen_circle(int t_idx, int qy, int qx) } } - /* Prepare an Array of "remaining stores", and count them */ - std::unique_ptr<int[]> rooms(new int[max_st_idx]); - num = get_shops(rooms.get()); + /* Get "remaining stores" */ + auto rooms = get_shops(); /* Place two rows of stores */ for (y = 0; y < 2; y++) @@ -1145,10 +1186,14 @@ static void town_gen_circle(int t_idx, int qy, int qx) /* Place four stores per row */ for (x = 0; x < 4; x++) { - if(--num > -1) + if (!rooms.empty()) { + /* Extract store */ + auto room = rooms.back(); + rooms.pop_back(); + /* Build that store at the proper location */ - build_store_circle(qy, qx, rooms[num], y, x); + build_store_circle(qy, qx, room, y, x); } } } @@ -1199,33 +1244,40 @@ static void town_gen_circle(int t_idx, int qy, int qx) } -static void town_gen_hidden(int t_idx, int qy, int qx) +static void town_gen_hidden() { - int y, x, n, num = 0, i; - - /* Prepare an Array of "remaining stores", and count them */ - std::unique_ptr<int[]> rooms(new int[max_st_idx]); - num = get_shops(rooms.get()); + /* Get "remaining stores" */ + auto rooms = get_shops(); /* Get a number of stores to place */ - n = rand_int(num / 2) + (num / 2); + std::size_t n = rand_int(rooms.size() / 2) + (rooms.size() / 2); /* Place k stores */ - for (i = 0; i < n; i++) + for (std::size_t i = 0; i < n; i++) { /* Find a good spot */ + int x; + int y; while (TRUE) { y = rand_range(1, cur_hgt - 2); x = rand_range(1, cur_wid - 2); - if (cave_empty_bold(y, x)) break; + if (cave_empty_bold(y, x)) + { + break; + } } - if(--num > -1) + /* Any stores left? */ + if (!rooms.empty()) { + /* Extract store */ + auto room = rooms.back(); + rooms.pop_back(); + /* Build that store at the proper location */ - build_store_hidden(rooms[num], y, x); + build_store_hidden(room, y, x); } } } @@ -1250,22 +1302,20 @@ static void town_gen_hidden(int t_idx, int qy, int qx) */ void town_gen(int t_idx) { - int qy, qx; - /* Level too small to contain a town */ if (cur_hgt < SCREEN_HGT) return; if (cur_wid < SCREEN_WID) return; - /* Center fo the level */ - qy = (cur_hgt - SCREEN_HGT) / 2; - qx = (cur_wid - SCREEN_WID) / 2; + /* Center of the level */ + int qy = (cur_hgt - SCREEN_HGT) / 2; + int qx = (cur_wid - SCREEN_WID) / 2; /* Build stuff */ switch (rand_int(3)) { case 0: { - town_gen_hack(t_idx, qy, qx); + town_gen_hack(qy, qx); if (wizard) { msg_format("Town level(normal) (%d, seed %d)", @@ -1276,7 +1326,7 @@ void town_gen(int t_idx) case 1: { - town_gen_circle(t_idx, qy, qx); + town_gen_circle(qy, qx); if (wizard) { msg_format("Town level(circle)(%d, seed %d)", @@ -1287,7 +1337,7 @@ void town_gen(int t_idx) case 2: { - town_gen_hidden(t_idx, qy, qx); + town_gen_hidden(); if (wizard) { msg_format("Town level(hidden)(%d, seed %d)", diff --git a/src/wild.hpp b/src/wild.hpp index 4cd9f0e7..d6a40e8d 100644 --- a/src/wild.hpp +++ b/src/wild.hpp @@ -1,6 +1,6 @@ #pragma once -extern void wilderness_gen(); -extern void wilderness_gen_small(void); -extern void reveal_wilderness_around_player(int y, int x, int h, int w); -extern void town_gen(int t_idx); +void wilderness_gen(); +void wilderness_gen_small(); +void reveal_wilderness_around_player(int y, int x, int h, int w); +void town_gen(int t_idx); diff --git a/src/wilderness_map.hpp b/src/wilderness_map.hpp index 41e873bd..3db36101 100644 --- a/src/wilderness_map.hpp +++ b/src/wilderness_map.hpp @@ -1,15 +1,15 @@ #pragma once #include "h-basic.h" +#include "seed.hpp" /** * A structure describing a wilderness map */ struct wilderness_map { - int feat; /* Wilderness feature */ - u32b seed; /* Seed for the RNG */ - u16b entrance; /* Entrance for dungeons */ - - bool_ known; /* Is it seen by the player ? */ + int feat = 0; /* Wilderness feature */ + seed_t seed = seed_t::system(); /* Seed for the RNG when building tile */ + u16b entrance = 0; /* Entrance for dungeons */ + bool_ known = FALSE; /* Is it seen by the player ? */ }; diff --git a/src/wilderness_type_info.hpp b/src/wilderness_type_info.hpp index bc23c03e..fa834e09 100644 --- a/src/wilderness_type_info.hpp +++ b/src/wilderness_type_info.hpp @@ -9,17 +9,16 @@ */ struct wilderness_type_info { - const char *name; /* Name */ - const char *text; /* Text */ + const char *name = nullptr; /* Name */ + const char *text = nullptr; /* Text */ - u16b entrance; /* Which town is there(<1000 i's a town, >=1000 it a dungeon) */ - s32b wild_x; /* Map coordinates (backed out while parsing map) */ - s32b wild_y; - byte road; /* Flags of road */ - int level; /* Difficulty level */ - u32b flags1; /* Some flags */ - byte feat; /* The feature of f_info.txt that is used to allow passing, ... and to get a char/color/graph */ - byte terrain_idx; /* Terrain index(defined in defines.h) */ + u16b entrance = 0; /* Which town is there(<1000 i's a town, >=1000 it a dungeon) */ + s32b wild_x = 0; /* Map coordinates (backed out while parsing map) */ + s32b wild_y = 0; + byte road = 0; /* Flags of road */ + int level = 0; /* Difficulty level */ + byte feat = 0; /* The feature of f_info.txt that is used to allow passing, ... and to get a char/color/graph */ + byte terrain_idx = 0; /* Terrain index(defined in defines.h) */ - byte terrain[MAX_WILD_TERRAIN];/* Feature types for the plasma generator */ + byte terrain[MAX_WILD_TERRAIN] = { 0 }; /* Feature types for the plasma generator */ }; diff --git a/src/wilderness_type_info_fwd.hpp b/src/wilderness_type_info_fwd.hpp deleted file mode 100644 index a206c9e3..00000000 --- a/src/wilderness_type_info_fwd.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -struct wilderness_type_info; diff --git a/src/wizard1.cc b/src/wizard1.cc deleted file mode 100644 index 616a46cd..00000000 --- a/src/wizard1.cc +++ /dev/null @@ -1,2499 +0,0 @@ -#include "wizard1.hpp" - -#include "artifact_type.hpp" -#include "cmd7.hpp" -#include "ego_item_type.hpp" -#include "monster_race.hpp" -#include "object1.hpp" -#include "object2.hpp" -#include "object_kind.hpp" -#include "object_type.hpp" -#include "skill_type.hpp" -#include "tables.hpp" -#include "util.hpp" -#include "util.h" -#include "variable.h" -#include "variable.hpp" - -#include <vector> - -/* - * The spoiler file being created - */ -static FILE *fff = NULL; - - -/* - * Write out `n' of the character `c' to the spoiler file - */ -static void spoiler_out_n_chars(int n, char c) -{ - while (--n >= 0) fputc(c, fff); -} - - -/* - * Write out `n' blank lines to the spoiler file - */ -static void spoiler_blanklines(int n) -{ - spoiler_out_n_chars(n, '\n'); -} - - -/* - * Write a line to the spoiler file and then "underline" it with hyphens - */ -static void spoiler_underline(cptr str) -{ - fprintf(fff, "%s\n", str); - spoiler_out_n_chars(strlen(str), '-'); - fprintf(fff, "\n"); -} - - -/* - * Buffer text to the given file. (-SHAWN-) - * This is basically c_roff() from mon-desc.c with a few changes. - */ -static void spoil_out(cptr str) -{ - cptr r; - - /* Line buffer */ - static char roff_buf[256]; - - /* Current pointer into line roff_buf */ - static char *roff_p = roff_buf; - - /* Last space saved into roff_buf */ - static char *roff_s = NULL; - - /* Special handling for "new sequence" */ - if (!str) - { - if (roff_p != roff_buf) roff_p--; - while (*roff_p == ' ' && roff_p != roff_buf) roff_p--; - if (roff_p == roff_buf) fprintf(fff, "\n"); - else - { - *(roff_p + 1) = '\0'; - fprintf(fff, "%s\n\n", roff_buf); - } - roff_p = roff_buf; - roff_s = NULL; - roff_buf[0] = '\0'; - return; - } - - /* Scan the given string, character at a time */ - for (; *str; str++) - { - char ch = *str; - int wrap = (ch == '\n'); - - if (!isprint(ch)) ch = ' '; - if (roff_p >= roff_buf + 75) wrap = 1; - if ((ch == ' ') && (roff_p + 2 >= roff_buf + 75)) wrap = 1; - - /* Handle line-wrap */ - if (wrap) - { - *roff_p = '\0'; - r = roff_p; - if (roff_s && (ch != ' ')) - { - *roff_s = '\0'; - r = roff_s + 1; - } - fprintf(fff, "%s\n", roff_buf); - roff_s = NULL; - roff_p = roff_buf; - while (*r) *roff_p++ = *r++; - } - - /* Save the char */ - if ((roff_p > roff_buf) || (ch != ' ')) - { - if (ch == ' ') roff_s = roff_p; - *roff_p++ = ch; - } - } -} - - -/* - * Extract a textual representation of an attribute - */ -static cptr attr_to_text(byte a) -{ - switch (a) - { - case TERM_DARK: - return ("xxx"); - case TERM_WHITE: - return ("White"); - case TERM_SLATE: - return ("Slate"); - case TERM_ORANGE: - return ("Orange"); - case TERM_RED: - return ("Red"); - case TERM_GREEN: - return ("Green"); - case TERM_BLUE: - return ("Blue"); - case TERM_UMBER: - return ("Umber"); - case TERM_L_DARK: - return ("L.Dark"); - case TERM_L_WHITE: - return ("L.Slate"); - case TERM_VIOLET: - return ("Violet"); - case TERM_YELLOW: - return ("Yellow"); - case TERM_L_RED: - return ("L.Red"); - case TERM_L_GREEN: - return ("L.Green"); - case TERM_L_BLUE: - return ("L.Blue"); - case TERM_L_UMBER: - return ("L.Umber"); - } - - /* Oops */ - return ("Icky"); -} - - - -/* - * A tval grouper - */ -typedef struct -{ - byte tval; - cptr name; -} -grouper; - - - -/* - * Item Spoilers by: benh@phial.com (Ben Harrison) - */ - - -/* - * The basic items categorized by type - */ -static grouper group_item[] = -{ - { TV_SWORD, "Melee Weapons" }, - { TV_POLEARM, NULL }, - { TV_HAFTED, NULL }, - { TV_AXE, NULL }, - { TV_MSTAFF, NULL }, - - { TV_BOW, "Bows and Slings" }, - - { TV_SHOT, "Ammo" }, - { TV_ARROW, NULL }, - { TV_BOLT, NULL }, - - { TV_BOOMERANG, "Boomerangs" }, - - { TV_INSTRUMENT, "Instruments" }, - - { TV_SOFT_ARMOR, "Armour (Body)" }, - { TV_HARD_ARMOR, NULL }, - { TV_DRAG_ARMOR, NULL }, - - { TV_SHIELD, "Armour (Misc)" }, - { TV_HELM, NULL }, - { TV_CROWN, NULL }, - { TV_GLOVES, NULL }, - { TV_BOOTS, NULL }, - - { TV_CLOAK, "Cloaks" }, - { TV_AMULET, "Amulets" }, - { TV_RING, "Rings" }, - - { TV_SCROLL, "Scrolls" }, - { TV_POTION, "Potions" }, - { TV_POTION2, NULL }, - - { TV_FOOD, "Food" }, - - { TV_ROD_MAIN, "Rods" }, - { TV_ROD, "Rod Tips" }, - { TV_WAND, "Wands" }, - { TV_STAFF, "Staves" }, - - { TV_BOOK, "Books (Magic, Gods, Music)" }, - { TV_DAEMON_BOOK, "Demonic Equipment" }, - - { TV_RUNE1, "Runes" }, - { TV_RUNE2, NULL }, - - { TV_PARCHMENT, "Parchments" }, - - { TV_DIGGING, "Tools" }, - { TV_TOOL, NULL }, - - { TV_TRAPKIT, "Trapping Kits" }, - - { TV_CHEST, "Chests" }, - - { TV_SPIKE, "Various" }, - { TV_LITE, NULL }, - { TV_FLASK, NULL }, - { TV_BOTTLE, NULL }, - { TV_JUNK, NULL }, - - { TV_SKELETON, "Corpses and Eggs" }, - { TV_CORPSE, NULL }, - { TV_EGG, NULL }, - - { 0, "" } -}; - - -/* - * Describe the kind - */ -static void kind_info(char *buf, char *dam, char *wgt, int *lev, s32b *val, int k) -{ - object_type forge; - object_type *q_ptr; - - object_kind *k_ptr; - - - /* Get local object */ - q_ptr = &forge; - - /* Prepare a fake item */ - object_prep(q_ptr, k); - - /* Obtain the "kind" info */ - k_ptr = &k_info[q_ptr->k_idx]; - - /* It is known */ - q_ptr->ident |= (IDENT_KNOWN); - - /* Cancel bonuses */ - q_ptr->to_a = 0; - q_ptr->to_h = 0; - q_ptr->to_d = 0; - - if ((k_ptr->tval == TV_WAND) || (k_ptr->tval == TV_STAFF)) - { - apply_magic(q_ptr, 0, FALSE, FALSE, FALSE, boost::make_optional(0)); - } - - /* Level */ - (*lev) = k_ptr->level; - - /* Value */ - (*val) = object_value(q_ptr); - - - /* Hack */ - if (!buf || !dam || !wgt) return; - - - /* Description (too brief) */ - object_desc_store(buf, q_ptr, FALSE, 0); - - - /* Misc info */ - strcpy(dam, ""); - - /* Damage */ - switch (q_ptr->tval) - { - /* Bows */ - case TV_BOW: - { - break; - } - - /* Ammo */ - case TV_SHOT: - case TV_BOLT: - case TV_ARROW: - - /* Boomerangs */ - case TV_BOOMERANG: - - /* Weapons */ - case TV_HAFTED: - case TV_POLEARM: - case TV_SWORD: - case TV_AXE: - case TV_MSTAFF: - - /* Tools */ - case TV_DIGGING: - { - sprintf(dam, "%dd%d", q_ptr->dd, q_ptr->ds); - break; - } - - /* Armour */ - case TV_BOOTS: - case TV_GLOVES: - case TV_CLOAK: - case TV_CROWN: - case TV_HELM: - case TV_SHIELD: - case TV_SOFT_ARMOR: - case TV_HARD_ARMOR: - case TV_DRAG_ARMOR: - { - sprintf(dam, "%d", q_ptr->ac); - break; - } - } - - - /* Weight */ - sprintf(wgt, "%3ld.%ld", (long int) (q_ptr->weight / 10), (long int) (q_ptr->weight % 10)); -} - - -/* - * Create a spoiler file for items - */ -static void spoil_obj_desc(cptr fname) -{ - int i, k, s, t, n = 0; - - u16b who[200]; - - char buf[1024]; - - char wgt[80]; - char dam[80]; - - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname); - - /* Open the file */ - fff = my_fopen(buf, "w"); - - /* Oops */ - if (!fff) - { - msg_print("Cannot create spoiler file."); - return; - } - - - /* Header */ - sprintf(buf, "Basic Items Spoilers for %s", get_version_string()); - spoiler_underline(buf); - spoiler_blanklines(2); - - /* More Header */ - fprintf(fff, "%-45s %8s%7s%5s%9s\n", - "Description", "Dam/AC", "Wgt", "Lev", "Cost"); - fprintf(fff, "%-45s %8s%7s%5s%9s\n", - "----------------------------------------", - "------", "---", "---", "----"); - - /* List the groups */ - for (i = 0; TRUE; i++) - { - /* Write out the group title */ - if (group_item[i].name) - { - /* Hack -- bubble-sort by cost and then level */ - for (s = 0; s < n - 1; s++) - { - for (t = 0; t < n - 1; t++) - { - int i1 = t; - int i2 = t + 1; - - int e1; - int e2; - - s32b t1; - s32b t2; - - kind_info(NULL, NULL, NULL, &e1, &t1, who[i1]); - kind_info(NULL, NULL, NULL, &e2, &t2, who[i2]); - - if ((t1 > t2) || ((t1 == t2) && (e1 > e2))) - { - int tmp = who[i1]; - who[i1] = who[i2]; - who[i2] = tmp; - } - } - } - - /* Spoil each item */ - for (s = 0; s < n; s++) - { - int e; - s32b v; - - /* Describe the kind */ - kind_info(buf, dam, wgt, &e, &v, who[s]); - - /* Dump it */ - fprintf(fff, " %-45s%8s%7s%5d%9ld\n", - buf, dam, wgt, e, (long)(v)); - } - - /* Start a new set */ - n = 0; - - /* Notice the end */ - if (!group_item[i].tval) break; - - /* Start a new set */ - fprintf(fff, "\n\n%s\n\n", group_item[i].name); - } - - /* Acquire legal item types */ - for (k = 1; k < max_k_idx; k++) - { - object_kind *k_ptr = &k_info[k]; - - /* Skip wrong tval's */ - if (k_ptr->tval != group_item[i].tval) continue; - - /* Hack -- Skip artifacts */ - if (k_ptr->flags3 & (TR3_INSTA_ART | TR3_NORM_ART)) continue; - - /* Hack -- Skip Ring of Powers */ - if (k == 785) continue; - - /* Save the index */ - who[n++] = k; - } - } - - - /* Check for errors */ - if (ferror(fff) || my_fclose(fff)) - { - msg_print("Cannot close spoiler file."); - return; - } - - /* Message */ - msg_print("Successfully created a spoiler file."); -} - - - -/* - * Artifact Spoilers by: randy@PICARD.tamu.edu (Randy Hutson) - */ - - -/* - * Returns a "+" string if a number is non-negative and an empty - * string if negative - */ -#define POSITIZE(v) (((v) >= 0) ? "+" : "") - -/* - * These are used to format the artifact spoiler file. INDENT1 is used - * to indent all but the first line of an artifact spoiler. INDENT2 is - * used when a line "wraps". (Bladeturner's resistances cause this.) - */ -#define INDENT1 " " -#define INDENT2 " " - -/* - * MAX_LINE_LEN specifies when a line should wrap. - */ -#define MAX_LINE_LEN 75 - -/* - * Given an array, determine how many elements are in the array - */ -#define N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0])) - -/* - * The artifacts categorized by type - */ -static grouper group_artifact[] = -{ - { TV_SWORD, "Edged Weapons" }, - { TV_POLEARM, "Polearms" }, - { TV_HAFTED, "Hafted Weapons" }, - { TV_AXE, "Axes" }, - - { TV_MSTAFF, "Mage Staffs" }, - - { TV_BOW, "Bows" }, - - { TV_SHOT, "Ammo" }, - { TV_ARROW, NULL }, - { TV_BOLT, NULL }, - - { TV_BOOMERANG, "Boomerangs" }, - - { TV_INSTRUMENT, "Instruments" }, - - { TV_SOFT_ARMOR, "Body Armor" }, - { TV_HARD_ARMOR, NULL }, - { TV_DRAG_ARMOR, NULL }, - - { TV_CLOAK, "Cloaks" }, - { TV_SHIELD, "Shields" }, - { TV_HELM, "Helms/Crowns" }, - { TV_CROWN, NULL }, - { TV_GLOVES, "Gloves" }, - { TV_BOOTS, "Boots" }, - - { TV_DAEMON_BOOK, "Demonic Equipment" }, - - { TV_LITE, "Light Sources" }, - { TV_AMULET, "Amulets" }, - { TV_RING, "Rings" }, - - { TV_TOOL, "Tools" }, - { TV_DIGGING, NULL }, - { TV_TRAPKIT, "Trapping Kits" }, - - { 0, NULL } -}; - - - -/* - * Pair together a constant flag with a textual description. - * - * Used by both "init.c" and "wiz-spo.c". - * - * Note that it sometimes more efficient to actually make an array - * of textual names, where entry 'N' is assumed to be paired with - * the flag whose value is "1L << N", but that requires hard-coding. - */ - -typedef struct flag_desc flag_desc; - -struct flag_desc -{ - const u32b flag; - const char *const desc; -}; - - - -/* - * These are used for "+3 to STR, DEX", etc. These are separate from - * the other pval affected traits to simplify the case where an object - * affects all stats. In this case, "All stats" is used instead of - * listing each stat individually. - */ - -static flag_desc stat_flags_desc[] = -{ - { TR1_STR, "STR" }, - { TR1_INT, "INT" }, - { TR1_WIS, "WIS" }, - { TR1_DEX, "DEX" }, - { TR1_CON, "CON" }, - { TR1_CHR, "CHR" } -}; - -/* - * Besides stats, these are the other player traits - * which may be affected by an object's pval - */ - -static flag_desc pval_flags1_desc[] = -{ - { TR1_STEALTH, "Stealth" }, - { TR1_SEARCH, "Searching" }, - { TR1_INFRA, "Infravision" }, - { TR1_TUNNEL, "Tunnelling" }, - { TR1_BLOWS, "Attacks" }, - { TR1_SPEED, "Speed" } -}; - -/* - * Slaying preferences for weapons - */ - -static flag_desc slay_flags_desc[] = -{ - { TR1_SLAY_ANIMAL, "Animal" }, - { TR1_SLAY_EVIL, "Evil" }, - { TR1_SLAY_UNDEAD, "Undead" }, - { TR1_SLAY_DEMON, "Demon" }, - { TR1_SLAY_ORC, "Orc" }, - { TR1_SLAY_TROLL, "Troll" }, - { TR1_SLAY_GIANT, "Giant" }, - { TR1_SLAY_DRAGON, "Dragon" }, - { TR1_KILL_DRAGON, "Xdragon" } -}; - -/* - * Elemental brands for weapons - * - * Clearly, TR1_IMPACT is a bit out of place here. To simplify - * coding, it has been included here along with the elemental - * brands. It does seem to fit in with the brands and slaying - * more than the miscellaneous section. - */ -static flag_desc brand_flags_desc[] = -{ - { TR1_BRAND_ACID, "Acid Brand" }, - { TR1_BRAND_ELEC, "Lightning Brand" }, - { TR1_BRAND_FIRE, "Flame Tongue" }, - { TR1_BRAND_COLD, "Frost Brand" }, - { TR1_BRAND_POIS, "Poisoned" }, - - { TR1_CHAOTIC, "Mark of Chaos" }, - { TR1_VAMPIRIC, "Vampiric" }, - { TR1_IMPACT, "Earthquake impact on hit" }, - { TR1_VORPAL, "Very sharp" }, -}; - - -/* - * The 15 resistables - */ -static const flag_desc resist_flags_desc[] = -{ - { TR2_RES_ACID, "Acid" }, - { TR2_RES_ELEC, "Lightning" }, - { TR2_RES_FIRE, "Fire" }, - { TR2_RES_COLD, "Cold" }, - { TR2_RES_POIS, "Poison" }, - { TR2_RES_FEAR, "Fear"}, - { TR2_RES_LITE, "Light" }, - { TR2_RES_DARK, "Dark" }, - { TR2_RES_BLIND, "Blindness" }, - { TR2_RES_CONF, "Confusion" }, - { TR2_RES_SOUND, "Sound" }, - { TR2_RES_SHARDS, "Shards" }, - { TR2_RES_NETHER, "Nether" }, - { TR2_RES_NEXUS, "Nexus" }, - { TR2_RES_CHAOS, "Chaos" }, - { TR2_RES_DISEN, "Disenchantment" }, -}; - -/* - * Elemental immunities (along with poison) - */ - -static const flag_desc immune_flags_desc[] = -{ - { TR2_IM_ACID, "Acid" }, - { TR2_IM_ELEC, "Lightning" }, - { TR2_IM_FIRE, "Fire" }, - { TR2_IM_COLD, "Cold" }, -}; - -/* - * Sustain stats - these are given their "own" line in the - * spoiler file, mainly for simplicity - */ -static const flag_desc sustain_flags_desc[] = -{ - { TR2_SUST_STR, "STR" }, - { TR2_SUST_INT, "INT" }, - { TR2_SUST_WIS, "WIS" }, - { TR2_SUST_DEX, "DEX" }, - { TR2_SUST_CON, "CON" }, - { TR2_SUST_CHR, "CHR" }, -}; - -/* - * Miscellaneous magic given by an object's "flags2" field - */ - -static const flag_desc misc_flags2_desc[] = -{ - { TR2_REFLECT, "Reflection" }, - { TR2_FREE_ACT, "Free Action" }, - { TR2_HOLD_LIFE, "Hold Life" }, -}; - -/* - * Miscellaneous magic given by an object's "flags3" field - * - * Note that cursed artifacts and objects with permanent light - * are handled "directly" -- see analyze_misc_magic() - */ - -static const flag_desc misc_flags3_desc[] = -{ - { TR3_SH_FIRE, "Fiery Aura" }, - { TR3_SH_ELEC, "Electric Aura" }, - { TR3_NO_TELE, "Prevent Teleportation" }, - { TR3_NO_MAGIC, "Anti-Magic" }, - { TR3_WRAITH, "Wraith Form" }, - { TR3_FEATHER, "Levitation" }, - { TR3_SEE_INVIS, "See Invisible" }, - { TR3_SLOW_DIGEST, "Slow Digestion" }, - { TR3_REGEN, "Regeneration" }, - { TR3_XTRA_SHOTS, "+1 Extra Shot" }, /* always +1? */ - { TR3_DRAIN_EXP, "Drains Experience" }, - { TR3_AGGRAVATE, "Aggravates" }, - { TR3_BLESSED, "Blessed Blade" }, -}; - - -/* - * A special type used just for dealing with pvals - */ -typedef struct -{ - /* - * This will contain a string such as "+2", "-10", etc. - */ - char pval_desc[12]; - - /* - * A list of various player traits affected by an object's pval such - * as stats, speed, stealth, etc. "Extra attacks" is NOT included in - * this list since it will probably be desirable to format its - * description differently. - * - * Note that room need only be reserved for the number of stats - 1 - * since the description "All stats" is used if an object affects all - * all stats. Also, room must be reserved for a sentinel NULL pointer. - * - * This will be a list such as ["STR", "DEX", "Stealth", NULL] etc. - * - * This list includes extra attacks, for simplicity. - */ - cptr pval_affects[N_ELEMENTS(stat_flags_desc) - 1 + - N_ELEMENTS(pval_flags1_desc) + 1]; - -} -pval_info_type; - - -/* - * An "object analysis structure" - * - * It will be filled with descriptive strings detailing an object's - * various magical powers. The "ignore X" traits are not noted since - * all artifacts ignore "normal" destruction. - */ - -typedef struct -{ - /* "The Longsword Dragonsmiter (6d4) (+20, +25)" */ - char description[160]; - - /* Description of what is affected by an object's pval */ - pval_info_type pval_info; - - /* A list of an object's slaying preferences */ - cptr slays[N_ELEMENTS(slay_flags_desc) + 1]; - - /* A list if an object's elemental brands */ - cptr brands[N_ELEMENTS(brand_flags_desc) + 1]; - - /* A list of immunities granted by an object */ - cptr immunities[N_ELEMENTS(immune_flags_desc) + 1]; - - /* A list of resistances granted by an object */ - cptr resistances[N_ELEMENTS(resist_flags_desc) + 1]; - - /* A list of stats sustained by an object */ - cptr sustains[N_ELEMENTS(sustain_flags_desc) - 1 + 1]; - - /* A list of various magical qualities an object may have */ - cptr misc_magic[N_ELEMENTS(misc_flags2_desc) + N_ELEMENTS(misc_flags3_desc) - + 1 /* Permanent Light */ - + 1 /* type of curse */ - + 1]; /* sentinel NULL */ - - /* A string describing an artifact's activation */ - cptr activation; - - /* "Level 20, Rarity 30, 3.0 lbs, 20000 Gold" */ - char misc_desc[80]; -} -obj_desc_list; - - - - - - -/* - * This function does most of the actual "analysis". Given a set of bit flags - * (which will be from one of the flags fields from the object in question), - * a "flag description structure", a "description list", and the number of - * elements in the "flag description structure", this function sets the - * "description list" members to the appropriate descriptions contained in - * the "flag description structure". - * - * The possibly updated description pointer is returned. - */ -static cptr *spoiler_flag_aux(const u32b art_flags, const flag_desc *flag_ptr, - cptr *desc_ptr, const int n_elmnts) -{ - int i; - - for (i = 0; i < n_elmnts; ++i) - { - if (art_flags & flag_ptr[i].flag) - { - *desc_ptr++ = flag_ptr[i].desc; - } - } - - return desc_ptr; -} - - -/* - * Acquire a "basic" description "The Cloak of Death [1,+10]" - */ -static void analyze_general (object_type *o_ptr, char *desc_ptr) -{ - /* Get a "useful" description of the object */ - object_desc_store(desc_ptr, o_ptr, TRUE, 1); -} - - -/* - * List "player traits" altered by an artifact's pval. These include stats, - * speed, infravision, tunnelling, stealth, searching, and extra attacks. - */ -static void analyze_pval (object_type *o_ptr, pval_info_type *p_ptr) -{ - const u32b all_stats = (TR1_STR | TR1_INT | TR1_WIS | - TR1_DEX | TR1_CON | TR1_CHR); - - u32b f1, f2, f3, f4, f5, esp; - - cptr *affects_list; - - /* If pval == 0, there is nothing to do. */ - if (!o_ptr->pval) - { - /* An "empty" pval description indicates that pval == 0 */ - p_ptr->pval_desc[0] = '\0'; - return; - } - - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - affects_list = p_ptr->pval_affects; - - /* Create the "+N" string */ - sprintf(p_ptr->pval_desc, "%s%ld", POSITIZE(o_ptr->pval), (long int) o_ptr->pval); - - /* First, check to see if the pval affects all stats */ - if ((f1 & all_stats) == all_stats) - { - *affects_list++ = "All stats"; - } - - /* Are any stats affected? */ - else if (f1 & all_stats) - { - affects_list = spoiler_flag_aux(f1, stat_flags_desc, - affects_list, - N_ELEMENTS(stat_flags_desc)); - } - - /* And now the "rest" */ - affects_list = spoiler_flag_aux(f1, pval_flags1_desc, - affects_list, - N_ELEMENTS(pval_flags1_desc)); - - /* Terminate the description list */ - *affects_list = NULL; -} - - -/* Note the slaying specialties of a weapon */ -static void analyze_slay (object_type *o_ptr, cptr *slay_list) -{ - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - slay_list = spoiler_flag_aux(f1, slay_flags_desc, slay_list, - N_ELEMENTS(slay_flags_desc)); - - /* Terminate the description list */ - *slay_list = NULL; -} - -/* Note an object's elemental brands */ -static void analyze_brand (object_type *o_ptr, cptr *brand_list) -{ - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - brand_list = spoiler_flag_aux(f1, brand_flags_desc, brand_list, - N_ELEMENTS(brand_flags_desc)); - - /* Terminate the description list */ - *brand_list = NULL; -} - - -/* Note the resistances granted by an object */ -static void analyze_resist (object_type *o_ptr, cptr *resist_list) -{ - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - resist_list = spoiler_flag_aux(f2, resist_flags_desc, - resist_list, N_ELEMENTS(resist_flags_desc)); - - /* Terminate the description list */ - *resist_list = NULL; -} - - -/* Note the immunities granted by an object */ -static void analyze_immune (object_type *o_ptr, cptr *immune_list) -{ - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - immune_list = spoiler_flag_aux(f2, immune_flags_desc, - immune_list, N_ELEMENTS(immune_flags_desc)); - - /* Terminate the description list */ - *immune_list = NULL; -} - -/* Note which stats an object sustains */ - -static void analyze_sustains (object_type *o_ptr, cptr *sustain_list) -{ - const u32b all_sustains = (TR2_SUST_STR | TR2_SUST_INT | TR2_SUST_WIS | - TR2_SUST_DEX | TR2_SUST_CON | TR2_SUST_CHR); - - u32b f1, f2, f3, f4, f5, esp; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Simplify things if an item sustains all stats */ - if ((f2 & all_sustains) == all_sustains) - { - *sustain_list++ = "All stats"; - } - - /* Should we bother? */ - else if ((f2 & all_sustains)) - { - sustain_list = spoiler_flag_aux(f2, sustain_flags_desc, - sustain_list, - N_ELEMENTS(sustain_flags_desc)); - } - - /* Terminate the description list */ - *sustain_list = NULL; -} - - -/* - * Note miscellaneous powers bestowed by an artifact such as see invisible, - * free action, permanent light, etc. - */ -static void analyze_misc_magic (object_type *o_ptr, cptr *misc_list) -{ - u32b f1, f2, f3, f4, f5, esp; - int radius = 0; - - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - misc_list = spoiler_flag_aux(f2, misc_flags2_desc, misc_list, - N_ELEMENTS(misc_flags2_desc)); - - misc_list = spoiler_flag_aux(f3, misc_flags3_desc, misc_list, - N_ELEMENTS(misc_flags3_desc)); - - /* - * Glowing artifacts -- small radius light. - */ - - if (f3 & TR3_LITE1) radius++; - if (f4 & TR4_LITE2) radius += 2; - if (f4 & TR4_LITE3) radius += 3; - - if (f4 & TR4_FUEL_LITE) - { - *misc_list++ = format("It provides light (radius %d) forever.", radius); - } - else - { - *misc_list++ = format("It provides light (radius %d) when fueled.", radius); - } - - /* - * Handle cursed objects here to avoid redundancies such as noting - * that a permanently cursed object is heavily cursed as well as - * being "lightly cursed". - */ - - if (cursed_p(o_ptr)) - { - if (f3 & (TR3_TY_CURSE)) - { - *misc_list++ = "Ancient Curse"; - } - if (f3 & (TR3_PERMA_CURSE)) - { - *misc_list++ = "Permanently Cursed"; - } - else if (f3 & (TR3_HEAVY_CURSE)) - { - *misc_list++ = "Heavily Cursed"; - } - else - { - *misc_list++ = "Cursed"; - } - } - - /* Terminate the description list */ - *misc_list = NULL; -} - - - - -/* - * Determine the minimum depth an artifact can appear, its rarity, its weight, - * and its value in gold pieces - */ -static void analyze_misc (object_type *o_ptr, char *misc_desc) -{ - artifact_type *a_ptr = &a_info[o_ptr->name1]; - - sprintf(misc_desc, "Level %u, Rarity %u, %d.%d lbs, %ld Gold", - a_ptr->level, a_ptr->rarity, - a_ptr->weight / 10, a_ptr->weight % 10, (long int) a_ptr->cost); -} - - -/* - * Fill in an object description structure for a given object - */ -static void object_analyze(object_type *o_ptr, obj_desc_list *desc_ptr) -{ - analyze_general(o_ptr, desc_ptr->description); - - analyze_pval(o_ptr, &desc_ptr->pval_info); - - analyze_brand(o_ptr, desc_ptr->brands); - - analyze_slay(o_ptr, desc_ptr->slays); - - analyze_immune(o_ptr, desc_ptr->immunities); - - analyze_resist(o_ptr, desc_ptr->resistances); - - analyze_sustains(o_ptr, desc_ptr->sustains); - - analyze_misc_magic(o_ptr, desc_ptr->misc_magic); - - analyze_misc(o_ptr, desc_ptr->misc_desc); - - desc_ptr->activation = item_activation(o_ptr, 0); -} - - -static void print_header(void) -{ - char buf[80]; - - sprintf(buf, "Artifact Spoilers for %s", get_version_string()); - spoiler_underline(buf); -} - -/* - * This is somewhat ugly. - * - * Given a header ("Resist", e.g.), a list ("Fire", "Cold", Acid", e.g.), - * and a separator character (',', e.g.), write the list to the spoiler file - * in a "nice" format, such as: - * - * Resist Fire, Cold, Acid - * - * That was a simple example, but when the list is long, a line wrap - * should occur, and this should induce a new level of indention if - * a list is being spread across lines. So for example, Bladeturner's - * list of resistances should look something like this - * - * Resist Acid, Lightning, Fire, Cold, Poison, Light, Dark, Blindness, - * Confusion, Sound, Shards, Nether, Nexus, Chaos, Disenchantment - * - * However, the code distinguishes between a single list of many items vs. - * many lists. (The separator is used to make this determination.) A single - * list of many items will not cause line wrapping (since there is no - * apparent reason to do so). So the lists of Ulmo's miscellaneous traits - * might look like this: - * - * Free Action; Hold Life; See Invisible; Slow Digestion; Regeneration - * Blessed Blade - * - * So comparing the two, "Regeneration" has no trailing separator and - * "Blessed Blade" was not indented. (Also, Ulmo's lists have no headers, - * but that's not relevant to line wrapping and indention.) - */ - -/* ITEM_SEP separates items within a list */ -#define ITEM_SEP ',' - - -/* LIST_SEP separates lists */ -#define LIST_SEP ';' - - -/* Create a spoiler file entry for an artifact */ - -static void spoiler_print_art(obj_desc_list *art_ptr, int name1, int set, object_type *o_ptr) -{ - /* Don't indent the first line */ - fprintf(fff, "%s\n ", art_ptr->description); - text_out_indent = 4; - object_out_desc(o_ptr, fff, FALSE, TRUE); - text_out_indent = 0; - - /* End with the miscellaneous facts */ - fprintf(fff, "%s%s\n\n", INDENT1, art_ptr->misc_desc); -} - - -/* - * Hack -- Create a "forged" artifact - */ -static bool_ make_fake_artifact(object_type *o_ptr, int name1) -{ - int i; - int cur; - - artifact_type *a_ptr = &a_info[name1]; - - - /* Ignore "empty" artifacts */ - if (!a_ptr->name) return FALSE; - - /* Acquire the "kind" index */ - i = lookup_kind(a_ptr->tval, a_ptr->sval); - - /* Oops */ - if (!i) return (FALSE); - - /* Create the artifact */ - object_prep(o_ptr, i); - - /* Save the name */ - o_ptr->name1 = name1; - - /* Keep the One Ring untouched by apply_magic */ - if (name1 != ART_POWER) - { - cur = a_ptr->cur_num; - apply_magic(o_ptr, -1, TRUE, TRUE, TRUE); - a_ptr->cur_num = cur; - } - else - { - o_ptr->pval = a_ptr->pval; - } - - /* Success */ - return (TRUE); -} - - -/* - * Create a spoiler file for artifacts - */ -static void spoil_artifact(cptr fname) -{ - int i, j; - - object_type forge; - object_type *q_ptr; - - obj_desc_list artifact; - - char buf[1024]; - - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname); - - /* Open the file */ - fff = my_fopen(buf, "w"); - - /* Oops */ - if (!fff) - { - msg_print("Cannot create spoiler file."); - return; - } - - /* Dump the header */ - print_header(); - - /* List the artifacts by tval */ - for (i = 0; group_artifact[i].tval; i++) - { - /* Write out the group title */ - if (group_artifact[i].name) - { - spoiler_blanklines(2); - spoiler_underline(group_artifact[i].name); - spoiler_blanklines(1); - } - - /* Now search through all of the artifacts */ - for (j = 1; j < max_a_idx; ++j) - { - artifact_type *a_ptr = &a_info[j]; - - /* We only want objects in the current group */ - if (a_ptr->tval != group_artifact[i].tval) continue; - - /* Get local object */ - q_ptr = &forge; - - /* Wipe the object */ - object_wipe(q_ptr); - - /* Attempt to "forge" the artifact */ - if (!make_fake_artifact(q_ptr, j)) continue; - - /* Aware and Known */ - object_known(q_ptr); - - /* Mark the item as fully known */ - q_ptr->ident |= (IDENT_MENTAL); - - /* Analyze the artifact */ - object_analyze(q_ptr, &artifact); - - /* Write out the artifact description to the spoiler file */ - spoiler_print_art(&artifact, j, a_ptr->set, q_ptr); - } - } - - /* Check for errors */ - if (ferror(fff) || my_fclose(fff)) - { - msg_print("Cannot close spoiler file."); - return; - } - - /* Message */ - msg_print("Successfully created a spoiler file."); -} - - - - - -/* - * Create a spoiler file for monsters -BEN- - */ -static void spoil_mon_desc(cptr fname) -{ - char buf[1024]; - - char nam[80]; - char lev[80]; - char rar[80]; - char spd[80]; - char ac[80]; - char hp[80]; - char exp[80]; - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname); - - /* Open the file */ - fff = my_fopen(buf, "w"); - - /* Oops */ - if (!fff) - { - msg_print("Cannot create spoiler file."); - return; - } - - /* Allocate the "who" array */ - std::vector<s16b> who; - - /* Dump the header */ - sprintf(buf, "Monster Spoilers for %s", get_version_string()); - spoiler_underline(buf); - spoiler_blanklines(2); - - /* Dump the header */ - fprintf(fff, "%-40.40s%4s%4s%6s%8s%4s %11.11s\n", - "Name", "Lev", "Rar", "Spd", "Hp", "Ac", "Visual Info"); - fprintf(fff, "%-40.40s%4s%4s%6s%8s%4s %11.11s\n", - "----", "---", "---", "---", "--", "--", "-----------"); - - - /* Scan the monsters */ - for (size_t i = 1; i < max_r_idx; i++) - { - monster_race *r_ptr = &r_info[i]; - - /* Use that monster */ - if (r_ptr->name) { - who.push_back(i); - } - } - - - /* Scan again */ - for (auto const who_i : who) - { - monster_race *r_ptr = &r_info[who_i]; - - /* Get the "name" */ - if (r_ptr->flags1 & (RF1_UNIQUE)) - { - sprintf(nam, "[U] %s", r_ptr->name); - } - else - { - sprintf(nam, "The %s", r_ptr->name); - } - - - /* Level */ - sprintf(lev, "%d", r_ptr->level); - - /* Rarity */ - sprintf(rar, "%d", r_ptr->rarity); - - /* Speed */ - if (r_ptr->speed >= 110) - { - sprintf(spd, "+%d", (r_ptr->speed - 110)); - } - else - { - sprintf(spd, "-%d", (110 - r_ptr->speed)); - } - - /* Armor Class */ - sprintf(ac, "%d", r_ptr->ac); - - /* Hitpoints */ - if ((r_ptr->flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1)) - { - sprintf(hp, "%d", r_ptr->hdice * r_ptr->hside); - } - else - { - sprintf(hp, "%dd%d", r_ptr->hdice, r_ptr->hside); - } - - - /* Experience */ - sprintf(exp, "%ld", (long)(r_ptr->mexp)); - - /* Hack -- use visual instead */ - sprintf(exp, "%s '%c'", attr_to_text(r_ptr->d_attr), r_ptr->d_char); - - /* Dump the info */ - fprintf(fff, "%-40.40s%4s%4s%6s%8s%4s %11.11s\n", - nam, lev, rar, spd, hp, ac, exp); - } - - /* End it */ - fprintf(fff, "\n"); - - /* Check for errors */ - if (ferror(fff) || my_fclose(fff)) - { - msg_print("Cannot close spoiler file."); - return; - } - - /* Worked */ - msg_print("Successfully created a spoiler file."); -} - - - - -/* - * Monster spoilers by: smchorse@ringer.cs.utsa.edu (Shawn McHorse) - * - * Primarily based on code already in mon-desc.c, mostly by -BEN- - */ - -/* - * Pronoun arrays - */ -static cptr wd_che[3] = { "It", "He", "She" }; -static cptr wd_lhe[3] = { "it", "he", "she" }; - - - -/* - * Create a spoiler file for monsters (-SHAWN-) - */ -static void spoil_mon_info(cptr fname) -{ - char buf[1024]; - int msex, vn, i, j, k, n; - bool_ breath, magic, sin; - cptr p, q; - cptr vp[64]; - u32b flags1, flags2, flags3, flags4, flags5, flags6, flags9; - - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname); - - /* Open the file */ - fff = my_fopen(buf, "w"); - - /* Oops */ - if (!fff) - { - msg_print("Cannot create spoiler file."); - return; - } - - - /* Dump the header */ - sprintf(buf, "Monster Spoilers for %s", get_version_string()); - spoiler_underline(buf); - spoiler_blanklines(2); - - /* - * List all monsters in order. - */ - for (n = 1; n < max_r_idx; n++) - { - monster_race *r_ptr = &r_info[n]; - - /* Extract the flags */ - flags1 = r_ptr->flags1; - flags2 = r_ptr->flags2; - flags3 = r_ptr->flags3; - flags4 = r_ptr->flags4; - flags5 = r_ptr->flags5; - flags6 = r_ptr->flags6; - flags9 = r_ptr->flags9; - breath = FALSE; - magic = FALSE; - - /* Extract a gender (if applicable) */ - if (flags1 & (RF1_FEMALE)) msex = 2; - else if (flags1 & (RF1_MALE)) msex = 1; - else msex = 0; - - - /* Prefix */ - if (flags1 & (RF1_UNIQUE)) - { - spoil_out("[U] "); - } - else - { - spoil_out("The "); - } - - /* Name */ - sprintf(buf, "%s (", r_ptr->name); /* ---)--- */ - spoil_out(buf); - - /* Color */ - spoil_out(attr_to_text(r_ptr->d_attr)); - - /* Symbol --(-- */ - sprintf(buf, " '%c')\n", r_ptr->d_char); - spoil_out(buf); - - - /* Indent */ - sprintf(buf, "=== "); - spoil_out(buf); - - /* Number */ - sprintf(buf, "Num:%d ", n); - spoil_out(buf); - - /* Level */ - sprintf(buf, "Lev:%d ", r_ptr->level); - spoil_out(buf); - - /* Rarity */ - sprintf(buf, "Rar:%d ", r_ptr->rarity); - spoil_out(buf); - - /* Speed */ - if (r_ptr->speed >= 110) - { - sprintf(buf, "Spd:+%d ", (r_ptr->speed - 110)); - } - else - { - sprintf(buf, "Spd:-%d ", (110 - r_ptr->speed)); - } - spoil_out(buf); - - /* Hitpoints */ - if ((flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1)) - { - sprintf(buf, "Hp:%d ", r_ptr->hdice * r_ptr->hside); - } - else - { - sprintf(buf, "Hp:%dd%d ", r_ptr->hdice, r_ptr->hside); - } - spoil_out(buf); - - /* Armor Class */ - sprintf(buf, "Ac:%d ", r_ptr->ac); - spoil_out(buf); - - /* Experience */ - sprintf(buf, "Exp:%ld\n", (long)(r_ptr->mexp)); - spoil_out(buf); - - - /* Describe */ - spoil_out(r_ptr->text); - spoil_out(" "); - - - spoil_out("This"); - - if (flags2 & (RF2_ELDRITCH_HORROR)) spoil_out (" sanity-blasting"); - if (flags3 & (RF3_ANIMAL)) spoil_out(" natural"); - if (flags3 & (RF3_EVIL)) spoil_out(" evil"); - if (flags3 & (RF3_GOOD)) spoil_out(" good"); - if (flags3 & (RF3_UNDEAD)) spoil_out(" undead"); - - if (flags3 & (RF3_DRAGON)) spoil_out(" dragon"); - else if (flags3 & (RF3_DEMON)) spoil_out(" demon"); - else if (flags3 & (RF3_GIANT)) spoil_out(" giant"); - else if (flags3 & (RF3_TROLL)) spoil_out(" troll"); - else if (flags3 & (RF3_ORC)) spoil_out(" orc"); - else if (flags3 & (RF3_THUNDERLORD)) spoil_out (" Thunderlord"); - else spoil_out(" creature"); - - spoil_out(" moves"); - - if ((flags1 & (RF1_RAND_50)) && (flags1 & (RF1_RAND_25))) - { - spoil_out(" extremely erratically"); - } - else if (flags1 & (RF1_RAND_50)) - { - spoil_out(" somewhat erratically"); - } - else if (flags1 & (RF1_RAND_25)) - { - spoil_out(" a bit erratically"); - } - else - { - spoil_out(" normally"); - } - - if (flags1 & (RF1_NEVER_MOVE)) - { - spoil_out(", but does not deign to chase intruders"); - } - - spoil_out(". "); - - if (!r_ptr->level || (flags1 & (RF1_FORCE_DEPTH))) - { - sprintf(buf, "%s is never found out of depth. ", wd_che[msex]); - spoil_out(buf); - } - - if (flags1 & (RF1_FORCE_SLEEP)) - { - sprintf(buf, "%s is always created sluggish. ", wd_che[msex]); - spoil_out(buf); - } - - if (flags2 & (RF2_AURA_FIRE)) - { - sprintf(buf, "%s is surrounded by flames. ", wd_che[msex]); - spoil_out(buf); - } - - if (flags2 & (RF2_AURA_ELEC)) - { - sprintf(buf, "%s is surrounded by electricity. ", wd_che[msex]); - spoil_out(buf); - } - - if (flags2 & (RF2_REFLECTING)) - { - sprintf(buf, "%s reflects bolt spells. ", wd_che[msex]); - spoil_out(buf); - } - - if (flags1 & (RF1_ESCORT)) - { - sprintf(buf, "%s usually appears with ", wd_che[msex]); - spoil_out(buf); - if (flags1 & (RF1_ESCORTS)) spoil_out("escorts. "); - else spoil_out("an escort. "); - } - - if ((flags1 & (RF1_FRIEND)) || (flags1 & (RF1_FRIENDS))) - { - sprintf(buf, "%s usually appears in groups. ", wd_che[msex]); - spoil_out(buf); - } - - /* Collect innate attacks */ - vn = 0; - if (flags4 & (RF4_SHRIEK)) vp[vn++] = "shriek for help"; - if (flags4 & (RF4_ROCKET)) vp[vn++] = "shoot a rocket"; - if (flags4 & (RF4_ARROW_1)) vp[vn++] = "fire arrows"; - if (flags4 & (RF4_ARROW_2)) vp[vn++] = "fire arrows"; - if (flags4 & (RF4_ARROW_3)) vp[vn++] = "fire missiles"; - if (flags4 & (RF4_ARROW_4)) vp[vn++] = "fire missiles"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" may "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" or "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - /* Collect breaths */ - vn = 0; - if (flags4 & (RF4_BR_ACID)) vp[vn++] = "acid"; - if (flags4 & (RF4_BR_ELEC)) vp[vn++] = "lightning"; - if (flags4 & (RF4_BR_FIRE)) vp[vn++] = "fire"; - if (flags4 & (RF4_BR_COLD)) vp[vn++] = "frost"; - if (flags4 & (RF4_BR_POIS)) vp[vn++] = "poison"; - if (flags4 & (RF4_BR_NETH)) vp[vn++] = "nether"; - if (flags4 & (RF4_BR_LITE)) vp[vn++] = "light"; - if (flags4 & (RF4_BR_DARK)) vp[vn++] = "darkness"; - if (flags4 & (RF4_BR_CONF)) vp[vn++] = "confusion"; - if (flags4 & (RF4_BR_SOUN)) vp[vn++] = "sound"; - if (flags4 & (RF4_BR_CHAO)) vp[vn++] = "chaos"; - if (flags4 & (RF4_BR_DISE)) vp[vn++] = "disenchantment"; - if (flags4 & (RF4_BR_NEXU)) vp[vn++] = "nexus"; - if (flags4 & (RF4_BR_TIME)) vp[vn++] = "time"; - if (flags4 & (RF4_BR_INER)) vp[vn++] = "inertia"; - if (flags4 & (RF4_BR_GRAV)) vp[vn++] = "gravity"; - if (flags4 & (RF4_BR_SHAR)) vp[vn++] = "shards"; - if (flags4 & (RF4_BR_PLAS)) vp[vn++] = "plasma"; - if (flags4 & (RF4_BR_WALL)) vp[vn++] = "force"; - if (flags4 & (RF4_BR_MANA)) vp[vn++] = "mana"; - if (flags4 & (RF4_BR_NUKE)) vp[vn++] = "toxic waste"; - if (flags4 & (RF4_BR_DISI)) vp[vn++] = "disintegration"; - - if (vn) - { - breath = TRUE; - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" may breathe "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" or "); - spoil_out(vp[i]); - } - if (flags2 & (RF2_POWERFUL)) spoil_out(" powerfully"); - } - - /* Collect spells */ - vn = 0; - if (flags5 & (RF5_BA_ACID)) vp[vn++] = "produce acid balls"; - if (flags5 & (RF5_BA_ELEC)) vp[vn++] = "produce lightning balls"; - if (flags5 & (RF5_BA_FIRE)) vp[vn++] = "produce fire balls"; - if (flags5 & (RF5_BA_COLD)) vp[vn++] = "produce frost balls"; - if (flags5 & (RF5_BA_POIS)) vp[vn++] = "produce poison balls"; - if (flags5 & (RF5_BA_NETH)) vp[vn++] = "produce nether balls"; - if (flags5 & (RF5_BA_WATE)) vp[vn++] = "produce water balls"; - if (flags4 & (RF4_BA_NUKE)) vp[vn++] = "produce balls of radiation"; - if (flags5 & (RF5_BA_MANA)) vp[vn++] = "produce mana storms"; - if (flags5 & (RF5_BA_DARK)) vp[vn++] = "produce darkness storms"; - if (flags4 & (RF4_BA_CHAO)) vp[vn++] = "invoke raw Chaos"; - if (flags6 & (RF6_HAND_DOOM)) vp[vn++] = "invoke the Hand of Doom"; - if (flags5 & (RF5_DRAIN_MANA)) vp[vn++] = "drain mana"; - if (flags5 & (RF5_MIND_BLAST)) vp[vn++] = "cause mind blasting"; - if (flags5 & (RF5_BRAIN_SMASH)) vp[vn++] = "cause brain smashing"; - if (flags5 & (RF5_CAUSE_1)) vp[vn++] = "cause light wounds and cursing"; - if (flags5 & (RF5_CAUSE_2)) vp[vn++] = "cause serious wounds and cursing"; - if (flags5 & (RF5_CAUSE_3)) vp[vn++] = "cause critical wounds and cursing"; - if (flags5 & (RF5_CAUSE_4)) vp[vn++] = "cause mortal wounds"; - if (flags5 & (RF5_BO_ACID)) vp[vn++] = "produce acid bolts"; - if (flags5 & (RF5_BO_ELEC)) vp[vn++] = "produce lightning bolts"; - if (flags5 & (RF5_BO_FIRE)) vp[vn++] = "produce fire bolts"; - if (flags5 & (RF5_BO_COLD)) vp[vn++] = "produce frost bolts"; - if (flags5 & (RF5_BO_POIS)) vp[vn++] = "produce poison bolts"; - if (flags5 & (RF5_BO_NETH)) vp[vn++] = "produce nether bolts"; - if (flags5 & (RF5_BO_WATE)) vp[vn++] = "produce water bolts"; - if (flags5 & (RF5_BO_MANA)) vp[vn++] = "produce mana bolts"; - if (flags5 & (RF5_BO_PLAS)) vp[vn++] = "produce plasma bolts"; - if (flags5 & (RF5_BO_ICEE)) vp[vn++] = "produce ice bolts"; - if (flags5 & (RF5_MISSILE)) vp[vn++] = "produce magic missiles"; - if (flags5 & (RF5_SCARE)) vp[vn++] = "terrify"; - if (flags5 & (RF5_BLIND)) vp[vn++] = "blind"; - if (flags5 & (RF5_CONF)) vp[vn++] = "confuse"; - if (flags5 & (RF5_SLOW)) vp[vn++] = "slow"; - if (flags5 & (RF5_HOLD)) vp[vn++] = "paralyse"; - if (flags6 & (RF6_HASTE)) vp[vn++] = "haste-self"; - if (flags6 & (RF6_HEAL)) vp[vn++] = "heal-self"; - if (flags6 & (RF6_BLINK)) vp[vn++] = "blink-self"; - if (flags6 & (RF6_TPORT)) vp[vn++] = "teleport-self"; - if (flags6 & (RF6_S_BUG)) vp[vn++] = "summon software bugs"; - if (flags6 & (RF6_S_RNG)) vp[vn++] = "summon RNGs"; - if (flags6 & (RF6_TELE_TO)) vp[vn++] = "teleport to"; - if (flags6 & (RF6_TELE_AWAY)) vp[vn++] = "teleport away"; - if (flags6 & (RF6_TELE_LEVEL)) vp[vn++] = "teleport level"; - if (flags6 & (RF6_DARKNESS)) vp[vn++] = "create darkness"; - if (flags6 & (RF6_TRAPS)) vp[vn++] = "create traps"; - if (flags6 & (RF6_FORGET)) vp[vn++] = "cause amnesia"; - if (flags6 & (RF6_RAISE_DEAD)) vp[vn++] = "raise dead"; - if (flags6 & (RF6_S_THUNDERLORD)) vp[vn++] = "summon a thunderlord"; - if (flags6 & (RF6_S_MONSTER)) vp[vn++] = "summon a monster"; - if (flags6 & (RF6_S_MONSTERS)) vp[vn++] = "summon monsters"; - if (flags6 & (RF6_S_KIN)) vp[vn++] = "summon aid"; - if (flags6 & (RF6_S_ANT)) vp[vn++] = "summon ants"; - if (flags6 & (RF6_S_SPIDER)) vp[vn++] = "summon spiders"; - if (flags6 & (RF6_S_HOUND)) vp[vn++] = "summon hounds"; - if (flags6 & (RF6_S_HYDRA)) vp[vn++] = "summon hydras"; - if (flags6 & (RF6_S_ANGEL)) vp[vn++] = "summon an angel"; - if (flags6 & (RF6_S_DEMON)) vp[vn++] = "summon a demon"; - if (flags6 & (RF6_S_UNDEAD)) vp[vn++] = "summon an undead"; - if (flags6 & (RF6_S_DRAGON)) vp[vn++] = "summon a dragon"; - if (flags4 & (RF4_S_ANIMAL)) vp[vn++] = "summon animal"; - if (flags6 & (RF6_S_ANIMALS)) vp[vn++] = "summon animals"; - if (flags6 & (RF6_S_HI_UNDEAD)) vp[vn++] = "summon greater undead"; - if (flags6 & (RF6_S_HI_DRAGON)) vp[vn++] = "summon ancient dragons"; - if (flags6 & (RF6_S_HI_DEMON)) vp[vn++] = "summon greater demons"; - if (flags6 & (RF6_S_WRAITH)) vp[vn++] = "summon Ringwraith"; - if (flags6 & (RF6_S_UNIQUE)) vp[vn++] = "summon unique monsters"; - - if (vn) - { - magic = TRUE; - if (breath) - { - spoil_out(", and is also"); - } - else - { - spoil_out(wd_che[msex]); - spoil_out(" is"); - } - - spoil_out(" magical, casting spells"); - if (flags2 & (RF2_SMART)) spoil_out(" intelligently"); - - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" which "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" or "); - spoil_out(vp[i]); - } - } - - if (breath || magic) - { - int times = r_ptr->freq_inate + r_ptr->freq_spell; - sprintf(buf, "; 1 time in %d. ", - 200 / ((times) ? times : 1)); - spoil_out(buf); - } - - /* Collect special abilities. */ - vn = 0; - if (flags2 & (RF2_OPEN_DOOR)) vp[vn++] = "open doors"; - if (flags2 & (RF2_BASH_DOOR)) vp[vn++] = "bash down doors"; - if (flags2 & (RF2_PASS_WALL)) vp[vn++] = "pass through walls"; - if (flags2 & (RF2_KILL_WALL)) vp[vn++] = "bore through walls"; - if (flags2 & (RF2_MOVE_BODY)) vp[vn++] = "push past weaker monsters"; - if (flags2 & (RF2_KILL_BODY)) vp[vn++] = "destroy weaker monsters"; - if (flags2 & (RF2_TAKE_ITEM)) vp[vn++] = "pick up objects"; - if (flags2 & (RF2_KILL_ITEM)) vp[vn++] = "destroy objects"; - if (flags9 & (RF9_HAS_LITE)) vp[vn++] = "illuminate the dungeon"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" can "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" and "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - if (flags2 & (RF2_INVISIBLE)) - { - spoil_out(wd_che[msex]); - spoil_out(" is invisible. "); - } - if (flags2 & (RF2_COLD_BLOOD)) - { - spoil_out(wd_che[msex]); - spoil_out(" is cold blooded. "); - } - if (flags2 & (RF2_EMPTY_MIND)) - { - spoil_out(wd_che[msex]); - spoil_out(" is not detected by telepathy. "); - } - if (flags2 & (RF2_WEIRD_MIND)) - { - spoil_out(wd_che[msex]); - spoil_out(" is rarely detected by telepathy. "); - } - if (flags4 & (RF4_MULTIPLY)) - { - spoil_out(wd_che[msex]); - spoil_out(" breeds explosively. "); - } - if (flags2 & (RF2_REGENERATE)) - { - spoil_out(wd_che[msex]); - spoil_out(" regenerates quickly. "); - } - - /* Collect susceptibilities */ - vn = 0; - if (flags3 & (RF3_HURT_ROCK)) vp[vn++] = "rock remover"; - if (flags3 & (RF3_HURT_LITE)) vp[vn++] = "bright light"; - if (flags3 & (RF3_SUSCEP_FIRE)) vp[vn++] = "fire"; - if (flags3 & (RF3_SUSCEP_COLD)) vp[vn++] = "cold"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" is hurt by "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" and "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - /* Collect immunities */ - vn = 0; - if (flags3 & (RF3_IM_ACID)) vp[vn++] = "acid"; - if (flags3 & (RF3_IM_ELEC)) vp[vn++] = "lightning"; - if (flags3 & (RF3_IM_FIRE)) vp[vn++] = "fire"; - if (flags3 & (RF3_IM_COLD)) vp[vn++] = "cold"; - if (flags3 & (RF3_IM_POIS)) vp[vn++] = "poison"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" resists "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" and "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - /* Collect resistances */ - vn = 0; - if (flags3 & (RF3_RES_NETH)) vp[vn++] = "nether"; - if (flags3 & (RF3_RES_WATE)) vp[vn++] = "water"; - if (flags3 & (RF3_RES_PLAS)) vp[vn++] = "plasma"; - if (flags3 & (RF3_RES_NEXU)) vp[vn++] = "nexus"; - if (flags3 & (RF3_RES_DISE)) vp[vn++] = "disenchantment"; - if (flags3 & (RF3_RES_TELE)) vp[vn++] = "teleportation"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" resists "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" and "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - /* Collect non-effects */ - vn = 0; - if (flags3 & (RF3_NO_STUN)) vp[vn++] = "stunned"; - if (flags3 & (RF3_NO_FEAR)) vp[vn++] = "frightened"; - if (flags3 & (RF3_NO_CONF)) vp[vn++] = "confused"; - if (flags3 & (RF3_NO_SLEEP)) vp[vn++] = "slept"; - - if (vn) - { - spoil_out(wd_che[msex]); - for (i = 0; i < vn; i++) - { - if (!i) spoil_out(" cannot be "); - else if (i < vn - 1) spoil_out(", "); - else spoil_out(" or "); - spoil_out(vp[i]); - } - spoil_out(". "); - } - - spoil_out(wd_che[msex]); - if (r_ptr->sleep > 200) spoil_out(" prefers to ignore"); - else if (r_ptr->sleep > 95) spoil_out(" pays very little attention to"); - else if (r_ptr->sleep > 75) spoil_out(" pays little attention to"); - else if (r_ptr->sleep > 45) spoil_out(" tends to overlook"); - else if (r_ptr->sleep > 25) spoil_out(" takes quite a while to see"); - else if (r_ptr->sleep > 10) spoil_out(" takes a while to see"); - else if (r_ptr->sleep > 5) spoil_out(" is fairly observant of"); - else if (r_ptr->sleep > 3) spoil_out(" is observant of"); - else if (r_ptr->sleep > 1) spoil_out(" is very observant of"); - else if (r_ptr->sleep > 0) spoil_out(" is vigilant for"); - else spoil_out(" is ever vigilant for"); - - sprintf(buf, " intruders, which %s may notice from %d feet. ", - wd_lhe[msex], 10 * r_ptr->aaf); - spoil_out(buf); - - i = 0; - if (flags1 & (RF1_DROP_60)) i += 1; - if (flags1 & (RF1_DROP_90)) i += 2; - if (flags1 & (RF1_DROP_1D2)) i += 2; - if (flags1 & (RF1_DROP_2D2)) i += 4; - if (flags1 & (RF1_DROP_3D2)) i += 6; - if (flags1 & (RF1_DROP_4D2)) i += 8; - - /* Drops gold and/or items */ - if (i) - { - sin = FALSE; - spoil_out(wd_che[msex]); - spoil_out(" will carry"); - - if (i == 1) - { - spoil_out(" a"); - sin = TRUE; - } - else if (i == 2) - { - spoil_out(" one or two"); - } - else - { - sprintf(buf, " up to %u", i); - spoil_out(buf); - } - - if (flags1 & (RF1_DROP_GREAT)) - { - if (sin) spoil_out("n"); - spoil_out(" exceptional object"); - } - else if (flags1 & (RF1_DROP_GOOD)) - { - spoil_out(" good object"); - } - else if (flags1 & (RF1_DROP_USEFUL)) - { - spoil_out(" useful object"); - } - else if (flags1 & (RF1_ONLY_ITEM)) - { - spoil_out(" object"); - } - else if (flags1 & (RF1_ONLY_GOLD)) - { - spoil_out(" treasure"); - } - else - { - if (sin) spoil_out("n"); - spoil_out(" object"); - if (i > 1) spoil_out("s"); - spoil_out(" or treasure"); - } - if (i > 1) spoil_out("s"); - - if (flags1 & (RF1_DROP_CHOSEN)) - { - spoil_out(", in addition to chosen objects"); - } - - spoil_out(". "); - } - - /* Count the actual attacks */ - for (i = 0, j = 0; j < 4; j++) - { - if (r_ptr->blow[j].method) i++; - } - - /* Examine the actual attacks */ - for (k = 0, j = 0; j < 4; j++) - { - if (!r_ptr->blow[j].method) continue; - - /* No method yet */ - p = "???"; - - /* Acquire the method */ - switch (r_ptr->blow[j].method) - { - case RBM_HIT: - p = "hit"; - break; - case RBM_TOUCH: - p = "touch"; - break; - case RBM_PUNCH: - p = "punch"; - break; - case RBM_KICK: - p = "kick"; - break; - case RBM_CLAW: - p = "claw"; - break; - case RBM_BITE: - p = "bite"; - break; - case RBM_STING: - p = "sting"; - break; - case RBM_XXX1: - break; - case RBM_BUTT: - p = "butt"; - break; - case RBM_CRUSH: - p = "crush"; - break; - case RBM_ENGULF: - p = "engulf"; - break; - case RBM_CHARGE: - p = "charge"; - break; - case RBM_CRAWL: - p = "crawl on you"; - break; - case RBM_DROOL: - p = "drool on you"; - break; - case RBM_SPIT: - p = "spit"; - break; - case RBM_EXPLODE: - p = "explode"; - break; - case RBM_GAZE: - p = "gaze"; - break; - case RBM_WAIL: - p = "wail"; - break; - case RBM_SPORE: - p = "release spores"; - break; - case RBM_XXX4: - break; - case RBM_BEG: - p = "beg"; - break; - case RBM_INSULT: - p = "insult"; - break; - case RBM_MOAN: - p = "moan"; - break; - case RBM_SHOW: - p = "sing"; - break; - } - - - /* Default effect */ - q = "???"; - - /* Acquire the effect */ - switch (r_ptr->blow[j].effect) - { - case RBE_HURT: - q = "attack"; - break; - case RBE_POISON: - q = "poison"; - break; - case RBE_UN_BONUS: - q = "disenchant"; - break; - case RBE_UN_POWER: - q = "drain charges"; - break; - case RBE_EAT_GOLD: - q = "steal gold"; - break; - case RBE_EAT_ITEM: - q = "steal items"; - break; - case RBE_EAT_FOOD: - q = "eat your food"; - break; - case RBE_EAT_LITE: - q = "absorb light"; - break; - case RBE_ACID: - q = "shoot acid"; - break; - case RBE_ELEC: - q = "electrocute"; - break; - case RBE_FIRE: - q = "burn"; - break; - case RBE_COLD: - q = "freeze"; - break; - case RBE_BLIND: - q = "blind"; - break; - case RBE_CONFUSE: - q = "confuse"; - break; - case RBE_TERRIFY: - q = "terrify"; - break; - case RBE_PARALYZE: - q = "paralyze"; - break; - case RBE_LOSE_STR: - q = "reduce strength"; - break; - case RBE_LOSE_INT: - q = "reduce intelligence"; - break; - case RBE_LOSE_WIS: - q = "reduce wisdom"; - break; - case RBE_LOSE_DEX: - q = "reduce dexterity"; - break; - case RBE_LOSE_CON: - q = "reduce constitution"; - break; - case RBE_LOSE_CHR: - q = "reduce charisma"; - break; - case RBE_LOSE_ALL: - q = "reduce all stats"; - break; - case RBE_SHATTER: - q = "shatter"; - break; - case RBE_EXP_10: - q = "lower experience (by 10d6+)"; - break; - case RBE_EXP_20: - q = "lower experience (by 20d6+)"; - break; - case RBE_EXP_40: - q = "lower experience (by 40d6+)"; - break; - case RBE_EXP_80: - q = "lower experience (by 80d6+)"; - break; - case RBE_DISEASE: - q = "disease"; - break; - case RBE_TIME: - q = "time"; - break; - case RBE_SANITY: - q = "make insane"; - break; - case RBE_HALLU: - q = "cause hallucinations"; - break; - case RBE_PARASITE: - q = "parasite"; - break; - } - - - if (!k) - { - spoil_out(wd_che[msex]); - spoil_out(" can "); - } - else if (k < i - 1) - { - spoil_out(", "); - } - else - { - spoil_out(", and "); - } - - /* Describe the method */ - spoil_out(p); - - /* Describe the effect, if any */ - if (r_ptr->blow[j].effect) - { - spoil_out(" to "); - spoil_out(q); - if (r_ptr->blow[j].d_dice && r_ptr->blow[j].d_side) - { - spoil_out(" with damage"); - if (r_ptr->blow[j].d_side == 1) - sprintf(buf, " %d", r_ptr->blow[j].d_dice); - else - sprintf(buf, " %dd%d", - r_ptr->blow[j].d_dice, r_ptr->blow[j].d_side); - spoil_out(buf); - } - } - - k++; - } - - if (k) - { - spoil_out(". "); - } - else if (flags1 & (RF1_NEVER_BLOW)) - { - sprintf(buf, "%s has no physical attacks. ", wd_che[msex]); - spoil_out(buf); - } - - spoil_out(NULL); - } - - /* Check for errors */ - if (ferror(fff) || my_fclose(fff)) - { - msg_print("Cannot close spoiler file."); - return; - } - - msg_print("Successfully created a spoiler file."); -} - -/* - * Print a bookless spell list - */ -void print_magic_powers( magic_power *powers, int max_powers, void(*power_info)(char *p, int power), int skill_num ) -{ - int i, save_skill; - - char buf[80]; - - magic_power spell; - - /* Use a maximal skill */ - save_skill = s_info[skill_num].value; - s_info[skill_num].value = SKILL_MAX; - - /* Dump the header line */ - spoiler_blanklines(2); - sprintf(buf, "%s", s_info[skill_num].name); - spoiler_underline(buf); - spoiler_blanklines(1); - - fprintf(fff, " Name Lvl Mana Fail Info\n"); - - /* Dump the spells */ - for (i = 0; i < max_powers; i++) - { - /* Access the spell */ - spell = powers[i]; - - /* Get the additional info */ - power_info(buf, i); - - /* Dump the spell */ - spoil_out(format("%c) %-30s%2d %4d %3d%%%s\n", - I2A(i), spell.name, - spell.min_lev, spell.mana_cost, spell.fail, buf)); - spoil_out(format("%s\n", spell.desc)); - } - - /* Restore skill */ - s_info[skill_num].value = save_skill; -} - - -/* - * Create a spoiler file for spells - */ - -static void spoil_spells(cptr fname) -{ - char buf[1024]; - - /* Build the filename */ - path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname); - - fff = my_fopen(buf, "w"); - - /* Oops */ - if (!fff) - { - msg_print("Cannot create spoiler file."); - return; - } - - /* Dump the header */ - sprintf(buf, "Spell Spoiler (Skill Level 50) for %s", get_version_string()); - spoiler_underline(buf); - - /* Dump the bookless magic powers in alphabetical order */ - - /* Mimicry */ - print_magic_powers(mimic_powers, MAX_MIMIC_POWERS, mimic_info, SKILL_MIMICRY); - - /* Mindcraft */ - print_magic_powers(mindcraft_powers, MAX_MINDCRAFT_POWERS, mindcraft_info, SKILL_MINDCRAFT); - - /* Necromancy */ - print_magic_powers(necro_powers, MAX_NECRO_POWERS, necro_info, SKILL_NECROMANCY); - - /* Symbiosis */ - print_magic_powers(symbiotic_powers, MAX_SYMBIOTIC_POWERS, symbiotic_info, SKILL_SYMBIOTIC); - - /* Check for errors */ - if (ferror(fff) || my_fclose(fff)) - { - msg_print("Cannot close spoiler file."); - return; - } - - /* Message */ - msg_print("Successfully created a spoiler file."); -} - - -/* - * Create Spoiler files -BEN- - */ -void do_cmd_spoilers() -{ - int i; - - - /* Enter "icky" mode */ - character_icky = TRUE; - - /* Save the screen */ - Term_save(); - - /* Interact */ - while (1) - { - /* Clear screen */ - Term_clear(); - - /* Info */ - prt("Create a spoiler file.", 2, 0); - - /* Prompt for a file */ - prt("(1) Brief Object Info (obj-desc.spo)", 5, 5); - prt("(2) Full Artifact Info (artifact.spo)", 6, 5); - prt("(3) Brief Monster Info (mon-desc.spo)", 7, 5); - prt("(4) Full Monster Info (mon-info.spo)", 8, 5); - prt("(5) Spell Info (spell.spo)", 10, 5); - - /* Prompt */ - prt("Command: ", 12, 0); - - /* Get a choice */ - i = inkey(); - - /* Escape */ - if (i == ESCAPE) - { - break; - } - - /* Option (1) */ - else if (i == '1') - { - spoil_obj_desc("obj-desc.spo"); - } - - /* Option (2) */ - else if (i == '2') - { - spoil_artifact("artifact.spo"); - } - - /* Option (3) */ - else if (i == '3') - { - spoil_mon_desc("mon-desc.spo"); - } - - /* Option (4) */ - else if (i == '4') - { - spoil_mon_info("mon-info.spo"); - } - - /* Option (5) */ - else if (i == '5') - { - spoil_spells("spell.spo"); - } - - /* Oops */ - else - { - bell(); - } - - /* Flush messages */ - msg_print(NULL); - } - - - /* Restore the screen */ - Term_load(); - - /* Leave "icky" mode */ - character_icky = FALSE; -} diff --git a/src/wizard1.hpp b/src/wizard1.hpp deleted file mode 100644 index 0429aa70..00000000 --- a/src/wizard1.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void do_cmd_spoilers(); diff --git a/src/wizard2.cc b/src/wizard2.cc index 837d778b..890c6fbe 100644 --- a/src/wizard2.cc +++ b/src/wizard2.cc @@ -9,34 +9,35 @@ #include "wizard2.hpp" #include "artifact_type.hpp" +#include "birth.hpp" #include "cave.hpp" #include "cave_type.hpp" #include "cmd4.hpp" #include "corrupt.hpp" #include "dungeon_info_type.hpp" #include "files.hpp" +#include "game.hpp" #include "hooks.hpp" #include "monster2.hpp" #include "monster_race.hpp" #include "monster_type.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" +#include "object_flag_meta.hpp" #include "object_kind.hpp" #include "player_type.hpp" #include "randart.hpp" -#include "status.hpp" #include "spells1.hpp" #include "spells2.hpp" #include "stats.hpp" #include "tables.hpp" -#include "traps.hpp" #include "util.hpp" #include "util.h" #include "variable.h" #include "variable.hpp" #include "wilderness_map.hpp" #include "wilderness_type_info.hpp" -#include "wizard1.hpp" #include "xtra1.hpp" #include "xtra2.hpp" #include "z-rand.hpp" @@ -80,7 +81,7 @@ static void wiz_align_monster(int status) */ static void teleport_player_town(int town) { - int x = 0, y = 0; + auto const &wf_info = game->edit_data.wf_info; autosave_checkpoint(); @@ -88,52 +89,43 @@ static void teleport_player_town(int town) dun_level = 0; p_ptr->town_num = town; - for (x = 0; x < max_wild_x; x++) - for (y = 0; y < max_wild_y; y++) - if (p_ptr->town_num == wf_info[wild_map[y][x].feat].entrance) goto finteletown; -finteletown: - p_ptr->wilderness_y = y; - p_ptr->wilderness_x = x; + auto const &wilderness = game->wilderness; + for (std::size_t y = 0; y < wilderness.height(); y++) + { + for (std::size_t x = 0; x < wilderness.width(); x++) + { + if (p_ptr->town_num == wf_info[wilderness(x, y).feat].entrance) + { + p_ptr->wilderness_y = y; + p_ptr->wilderness_x = x; - leaving_quest = p_ptr->inside_quest; - p_ptr->inside_quest = 0; + leaving_quest = p_ptr->inside_quest; + p_ptr->inside_quest = 0; - /* Leaving */ - p_ptr->leaving = TRUE; + /* Leaving */ + p_ptr->leaving = TRUE; + + // Done + return; + } + } + } } /* * Hack -- Rerate Hitpoints */ -void do_cmd_rerate(void) +void do_cmd_rerate() { - int min_value, max_value, i, percent; + auto &player_hp = game->player_hp; - min_value = (PY_MAX_LEVEL * 3 * (p_ptr->hitdie - 1)) / 8; - min_value += PY_MAX_LEVEL; + // Force HP re-roll + roll_player_hp(); - max_value = (PY_MAX_LEVEL * 5 * (p_ptr->hitdie - 1)) / 8; - max_value += PY_MAX_LEVEL; - - player_hp[0] = p_ptr->hitdie; - - /* Rerate */ - while (1) - { - /* Collect values */ - for (i = 1; i < PY_MAX_LEVEL; i++) - { - player_hp[i] = randint(p_ptr->hitdie); - player_hp[i] += player_hp[i - 1]; - } - - /* Legal values */ - if ((player_hp[PY_MAX_LEVEL - 1] >= min_value) && - (player_hp[PY_MAX_LEVEL - 1] <= max_value)) break; - } - - percent = (int)(((long)player_hp[PY_MAX_LEVEL - 1] * 200L) / + // Calculate life rating + int percent = static_cast<int>( + (static_cast<long>(player_hp[PY_MAX_LEVEL - 1]) * 200L) / (p_ptr->hitdie + ((PY_MAX_LEVEL - 1) * p_ptr->hitdie))); /* Update and redraw hitpoints */ @@ -157,20 +149,24 @@ void do_cmd_rerate(void) */ static void wiz_create_named_art() { + auto const &a_info = game->edit_data.a_info; + object_type forge; object_type *q_ptr; int i, a_idx; - cptr p = "Number of the artifact :"; + cptr p = "Number of the artifact: "; char out_val[80] = ""; - artifact_type *a_ptr; if (!get_string(p, out_val, 4)) return; a_idx = atoi(out_val); /* Return if out-of-bounds */ - if ((a_idx <= 0) || (a_idx >= max_a_idx)) return; + if ((a_idx <= 0) || (a_idx >= static_cast<int>(a_info.size()))) + { + return; + } - a_ptr = &a_info[a_idx]; + auto a_ptr = &a_info[a_idx]; /* Get local object */ q_ptr = &forge; @@ -195,6 +191,9 @@ static void wiz_create_named_art() apply_magic(q_ptr, -1, TRUE, TRUE, TRUE); + /* Apply any random resistances/powers */ + random_artifact_resistance(q_ptr); + /* Identify it fully */ object_aware(q_ptr); object_known(q_ptr); @@ -221,40 +220,14 @@ static void do_cmd_summon_horde() if (cave_naked_bold(wy, wx)) break; } - (void)alloc_horde(wy, wx); -} - - -/* - * Output a long int in binary format. - */ -static void prt_binary(u32b flags, int row, int col) -{ - int i; - u32b bitmask; - - /* Scan the flags */ - for (i = bitmask = 1; i <= 32; i++, bitmask *= 2) - { - /* Dump set bits */ - if (flags & bitmask) - { - Term_putch(col++, row, TERM_BLUE, '*'); - } - - /* Dump unset bits */ - else - { - Term_putch(col++, row, TERM_WHITE, '-'); - } - } + alloc_horde(wy, wx); } /* * Hack -- Teleport to the target */ -static void do_cmd_wiz_bamf(void) +static void do_cmd_wiz_bamf() { /* Must have a target */ if (!target_who) return; @@ -267,7 +240,7 @@ static void do_cmd_wiz_bamf(void) /* * Aux function for "do_cmd_wiz_change()". -RAK- */ -static void do_cmd_wiz_change_aux(void) +static void do_cmd_wiz_change_aux() { int i; int tmp_int; @@ -370,7 +343,7 @@ static void do_cmd_wiz_change_aux(void) /* * Change various "permanent" player variables. */ -static void do_cmd_wiz_change(void) +static void do_cmd_wiz_change() { /* Interact */ do_cmd_wiz_change_aux(); @@ -443,12 +416,13 @@ static void do_cmd_wiz_change(void) */ static void wiz_display_item(object_type *o_ptr) { + auto const &k_info = game->edit_data.k_info; + int i, j = 13; - u32b f1, f2, f3, f4, f5, esp; char buf[256]; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Clear the screen */ for (i = 1; i <= 23; i++) prt("", i, j - 2); @@ -475,32 +449,27 @@ static void wiz_display_item(object_type *o_ptr) prt(format("ident = %04x timeout = %-d", o_ptr->ident, o_ptr->timeout), 8, j); - prt("+------------FLAGS1------------+", 10, j); - prt("AFFECT........SLAY........BRAND.", 11, j); - prt(" cvae xsqpaefc", 12, j); - prt("siwdcc ssidsahanvudotgddhuoclio", 13, j); - prt("tnieoh trnipttmiinmrrnrrraiierl", 14, j); - prt("rtsxna..lcfgdkcpmldncltggpksdced", 15, j); - prt_binary(f1, 16, j); - - prt("+------------FLAGS2------------+", 17, j); - prt("SUST....IMMUN.RESIST............", 18, j); - prt(" aefcprpsaefcpfldbc sn ", 19, j); - prt("siwdcc cliooeatcliooeialoshtncd", 20, j); - prt("tnieoh ierlifraierliatrnnnrhehi", 21, j); - prt("rtsxna..dcedslatdcedsrekdfddrxss", 22, j); - prt_binary(f2, 23, j); - - prt("+------------FLAGS3------------+", 10, j + 32); - prt("fe ehsi st iiiiadta hp", 11, j + 32); - prt("il n taihnf ee ggggcregb vr", 12, j + 32); - prt("re nowysdose eld nnnntalrl ym", 13, j + 32); - prt("ec omrcyewta ieirmsrrrriieaeccc", 14, j + 32); - prt("aa taauktmatlnpgeihaefcvnpvsuuu", 15, j + 32); - prt("uu egirnyoahivaeggoclioaeoasrrr", 16, j + 32); - prt("rr litsopdretitsehtierltxrtesss", 17, j + 32); - prt("aa echewestreshtntsdcedeptedeee", 18, j + 32); - prt_binary(f3, 19, j + 32); + /* Print all the flags which are set */ + prt("Flags:", 10, j); + + int const row0 = 11; + int row = row0; + int col = 0; + for (auto const &object_flag_meta: object_flags_meta()) + { + // Is the flag set? + if (object_flag_meta->flag_set & flags) + { + // Advance to next row/column + row += 1; + if (row >= 23) { + row = row0 + 1; + col += 1; + } + // Display + prt(object_flag_meta->name, row, j + 1 + 20 * col); + } + } } @@ -508,12 +477,8 @@ static void wiz_display_item(object_type *o_ptr) /* * Strip an "object name" into a buffer */ -static void strip_name(char *buf, int k_idx) +static void strip_name(char *buf, const object_kind *k_ptr) { - char *t; - - object_kind *k_ptr = &k_info[k_idx]; - cptr str = k_ptr->name; @@ -521,6 +486,7 @@ static void strip_name(char *buf, int k_idx) while ((*str == ' ') || (*str == '&')) str++; /* Copy useful chars */ + char *t; for (t = buf; *str; str++) { if (*str != '~') *t++ = *str; @@ -568,16 +534,16 @@ static void wci_string(cptr string, int num) * * List up to 50 choices in three columns */ -static int wiz_create_itemtype(void) +static int wiz_create_itemtype() { - int i, num, max_num; + auto const &k_info = game->edit_data.k_info; + + int num, max_num; int tval; cptr tval_desc2; char ch; - int choice[60]; - char buf[160]; @@ -616,29 +582,32 @@ static int wiz_create_itemtype(void) Term_clear(); /* We have to search the whole itemlist. */ - for (num = 0, i = 1; (num < 60) && (i < max_k_idx); i++) + std::vector<std::size_t> choice; + choice.reserve(60); + std::size_t i; + for (i = 1; (choice.size() < 60) && (i < k_info.size()); i++) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_info[i]; /* Analyze matching items */ if (k_ptr->tval == tval) { /* Hack -- Skip instant artifacts */ - if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; + if (k_ptr->flags & TR_INSTA_ART) continue; - /* Acquire the "name" of object "i" */ - strip_name(buf, i); + /* Acquire the "name" of object */ + strip_name(buf, k_ptr); /* Print it */ - wci_string(buf, num); + wci_string(buf, choice.size()); /* Remember the object index */ - choice[num++] = i; + choice.push_back(i); } } /* Me need to know the maximal possible remembered object_index */ - max_num = num; + max_num = choice.size(); /* Choose! */ if (!get_com(format("What Kind of %s? ", tval_desc2), &ch)) return (0); @@ -664,10 +633,9 @@ static void wiz_tweak_item(object_type *o_ptr) { cptr p; char tmp_val[80]; - u32b f1, f2, f3, f4, f5, esp; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); p = "Enter new 'pval' setting: "; @@ -729,7 +697,7 @@ static void wiz_tweak_item(object_type *o_ptr) if (!get_string(p, tmp_val, 9)) return; wiz_display_item(o_ptr); o_ptr->exp = atoi(tmp_val); - if (f4 & TR4_LEVELS) check_experience_obj(o_ptr); + if (flags & TR_LEVELS) check_experience_obj(o_ptr); p = "Enter new 'timeout' setting: "; sprintf(tmp_val, "%d", o_ptr->timeout); @@ -753,7 +721,7 @@ static void wiz_reroll_item(object_type *o_ptr) /* Hack -- leave artifacts alone */ - if (artifact_p(o_ptr) || o_ptr->art_name) return; + if (artifact_p(o_ptr)) return; /* Get local object */ @@ -856,6 +824,9 @@ static void wiz_reroll_item(object_type *o_ptr) */ static void wiz_statistics(object_type *o_ptr) { + auto &a_info = game->edit_data.a_info; + auto &random_artifacts = game->random_artifacts; + long i, matches, better, worse, other; char ch; @@ -866,16 +837,8 @@ static void wiz_statistics(object_type *o_ptr) object_type forge; object_type *q_ptr; - obj_theme theme; - cptr q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld"; - /* We can have everything */ - theme.treasure = OBJ_GENE_TREASURE; - theme.combat = OBJ_GENE_COMBAT; - theme.magic = OBJ_GENE_MAGIC; - theme.tools = OBJ_GENE_TOOL; - /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ if (artifact_p(o_ptr)) { @@ -963,7 +926,7 @@ static void wiz_statistics(object_type *o_ptr) object_wipe(q_ptr); /* Create an object */ - make_object(q_ptr, good, great, theme); + make_object(q_ptr, good, great, obj_theme::defaults()); /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ @@ -1074,7 +1037,7 @@ static void wiz_quantity_item(object_type *o_ptr) * - Change properties (via wiz_tweak_item) * - Change the number of items (via wiz_quantity_item) */ -static void do_cmd_wiz_play(void) +static void do_cmd_wiz_play() { /* Get an item */ int item; @@ -1205,7 +1168,7 @@ static void do_cmd_wiz_play(void) * Hack -- this routine always makes a "dungeon object", and applies * magic to it, and attempts to decline cursed items. */ -static void wiz_create_item(void) +static void wiz_create_item() { object_type forge; object_type *q_ptr; @@ -1251,25 +1214,28 @@ static void wiz_create_item(void) /* * As above, but takes the k_idx as a parameter instead of using menus. */ -static void wiz_create_item_2(void) +static void wiz_create_item_2() { - object_type forge; - object_type *q_ptr; - int a_idx; + auto const &k_info = game->edit_data.k_info; + cptr p = "Number of the object :"; char out_val[80] = ""; if (!get_string(p, out_val, 4)) return; - a_idx = atoi(out_val); + int k_idx = atoi(out_val); /* Return if failed or out-of-bounds */ - if ((a_idx <= 0) || (a_idx >= max_k_idx)) return; + if ((k_idx <= 0) || (k_idx >= static_cast<int>(k_info.size()))) + { + return; + } /* Get local object */ - q_ptr = &forge; + object_type forge; + auto q_ptr = &forge; /* Create the item */ - object_prep(q_ptr, a_idx); + object_prep(q_ptr, k_idx); /* Apply magic (no messages, no artifacts) */ apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE); @@ -1285,23 +1251,23 @@ static void wiz_create_item_2(void) /* * Cure everything instantly */ -void do_cmd_wiz_cure_all(void) +void do_cmd_wiz_cure_all() { object_type *o_ptr; /* Remove curses */ - (void)remove_all_curse(); + remove_all_curse(); /* Restore stats */ - (void)res_stat(A_STR, TRUE); - (void)res_stat(A_INT, TRUE); - (void)res_stat(A_WIS, TRUE); - (void)res_stat(A_CON, TRUE); - (void)res_stat(A_DEX, TRUE); - (void)res_stat(A_CHR, TRUE); + res_stat(A_STR, TRUE); + res_stat(A_INT, TRUE); + res_stat(A_WIS, TRUE); + res_stat(A_CON, TRUE); + res_stat(A_DEX, TRUE); + res_stat(A_CHR, TRUE); /* Restore the level */ - (void)restore_level(); + restore_level(); /* Heal the player */ p_ptr->chp = p_ptr->mhp; @@ -1324,19 +1290,19 @@ void do_cmd_wiz_cure_all(void) p_ptr->csp_frac = 0; /* Cure stuff */ - (void)set_blind(0); - (void)set_confused(0); - (void)set_poisoned(0); - (void)set_afraid(0); - (void)set_paralyzed(0); - (void)set_image(0); - (void)set_stun(0); - (void)set_cut(0); - (void)set_slow(0); + set_blind(0); + set_confused(0); + set_poisoned(0); + set_afraid(0); + set_paralyzed(0); + set_image(0); + set_stun(0); + set_cut(0); + set_slow(0); p_ptr->black_breath = FALSE; /* No longer hungry */ - (void)set_food(PY_FOOD_MAX - 1); + set_food(PY_FOOD_MAX - 1); /* Redraw everything */ do_cmd_redraw(); @@ -1346,8 +1312,10 @@ void do_cmd_wiz_cure_all(void) /* * Go to any level */ -static void do_cmd_wiz_jump(void) +static void do_cmd_wiz_jump() { + auto const &d_info = game->edit_data.d_info; + /* Ask for level */ if (command_arg <= 0) { @@ -1395,23 +1363,21 @@ static void do_cmd_wiz_jump(void) /* * Become aware of a lot of objects */ -static void do_cmd_wiz_learn(void) +static void do_cmd_wiz_learn() { - int i; - - object_type forge; - object_type *q_ptr; + auto const &k_info = game->edit_data.k_info; /* Scan every object */ - for (i = 1; i < max_k_idx; i++) + for (std::size_t i = 0; i < k_info.size(); i++) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_info[i]; /* Induce awareness */ if (k_ptr->level <= command_arg) { /* Get local object */ - q_ptr = &forge; + object_type forge; + auto q_ptr = &forge; /* Prepare object */ object_prep(q_ptr, i); @@ -1432,7 +1398,7 @@ static void do_cmd_wiz_summon(int num) for (i = 0; i < num; i++) { - (void)summon_specific(p_ptr->py, p_ptr->px, dun_level, 0); + summon_specific(p_ptr->py, p_ptr->px, dun_level, 0); } } @@ -1442,15 +1408,17 @@ static void do_cmd_wiz_summon(int num) * * XXX XXX XXX This function is rather dangerous */ -static void do_cmd_wiz_named(int r_idx, bool_ slp) +static void do_cmd_wiz_named(std::size_t r_idx, bool_ slp) { + auto const &r_info = game->edit_data.r_info; + int i, x, y; /* Paranoia */ /* if (!r_idx) return; */ /* Prevent illegal monsters */ - if (r_idx >= max_r_idx) return; + if (r_idx >= r_info.size()) return; /* Try 10 times */ for (i = 0; i < 10; i++) @@ -1482,15 +1450,17 @@ static void do_cmd_wiz_named(int r_idx, bool_ slp) * * XXX XXX XXX This function is rather dangerous */ -void do_cmd_wiz_named_friendly(int r_idx, bool_ slp) +void do_cmd_wiz_named_friendly(std::size_t r_idx, bool_ slp) { + auto const &r_info = game->edit_data.r_info; + int i, x, y; /* Paranoia */ /* if (!r_idx) return; */ /* Prevent illegal monsters */ - if (r_idx >= max_r_idx) return; + if (r_idx >= r_info.size()) return; /* Try 10 times */ for (i = 0; i < 10; i++) @@ -1521,7 +1491,7 @@ void do_cmd_wiz_named_friendly(int r_idx, bool_ slp) /* * Hack -- Delete all nearby monsters */ -static void do_cmd_wiz_zap(void) +static void do_cmd_wiz_zap() { int i; @@ -1543,6 +1513,8 @@ static void do_cmd_wiz_body(s16b bidx) /* Might create problems with equipment slots. For safety, be nude when calling this function */ { + auto const &r_info = game->edit_data.r_info; + p_ptr->body_monster = bidx; p_ptr->disembodied = FALSE; p_ptr->chp = maxroll( (&r_info[bidx])->hdice, (&r_info[bidx])->hside); @@ -1556,6 +1528,8 @@ static void do_cmd_wiz_body(s16b bidx) */ void do_cmd_debug() { + auto const &d_info = game->edit_data.d_info; + int x, y; char cmd; @@ -1574,15 +1548,6 @@ void do_cmd_debug() break; - /* Hack -- Generate Spoilers */ - case '"': - do_cmd_spoilers(); - break; - - case 'A': - status_main(); - break; - /* Hack -- Help */ case '?': do_cmd_help(); @@ -1625,11 +1590,11 @@ void do_cmd_debug() /* Change of Dungeon type */ case 'D': - if ((command_arg >= 0) && (command_arg < max_d_idx)) + if ((command_arg >= 0) && (std::size_t(command_arg) < d_info.size())) { dungeon_type = command_arg; dun_level = d_info[dungeon_type].mindepth; - msg_format("You go into %s", d_info[dungeon_type].text); + msg_format("You go into %s", d_info[dungeon_type].text.c_str()); /* Leaving */ p_ptr->leaving = TRUE; @@ -1666,7 +1631,7 @@ void do_cmd_debug() /* Identify */ case 'i': - (void)ident_spell(); + ident_spell(); break; /* Go up or down in the dungeon */ @@ -1674,11 +1639,6 @@ void do_cmd_debug() do_cmd_wiz_jump(); break; - /* Self-Knowledge */ - case 'k': - self_knowledge(NULL); - break; - /* Learn about objects */ case 'l': do_cmd_wiz_learn(); @@ -1694,11 +1654,6 @@ void do_cmd_debug() gain_random_corruption(); break; - /* Create a trap */ - case 'R': - wiz_place_trap(p_ptr->py, p_ptr->px, command_arg); - break; - /* Summon _friendly_ named monster */ case 'N': do_cmd_wiz_named_friendly(command_arg, TRUE); @@ -1727,7 +1682,7 @@ void do_cmd_debug() { quest[command_arg].status = QUEST_STATUS_TAKEN; *(quest[command_arg].plot) = command_arg; - quest[command_arg].init(command_arg); + quest[command_arg].init(); break; } break; @@ -1842,7 +1797,6 @@ void do_cmd_debug() /* Change the feature of the map */ case 'F': - msg_format("Trap: %d", cave[p_ptr->py][p_ptr->px].t_idx); msg_format("Old feature: %d", cave[p_ptr->py][p_ptr->px].feat); msg_format("Special: %d", cave[p_ptr->py][p_ptr->px].special); cave_set_feat(p_ptr->py, p_ptr->px, command_arg); diff --git a/src/wizard2.hpp b/src/wizard2.hpp index cec515c8..9bad7f92 100644 --- a/src/wizard2.hpp +++ b/src/wizard2.hpp @@ -2,7 +2,9 @@ #include "h-basic.h" -extern void do_cmd_rerate(void); -extern void do_cmd_wiz_cure_all(void); -extern void do_cmd_wiz_named_friendly(int r_idx, bool_ slp); -extern void do_cmd_debug(); +#include <cstddef> + +void do_cmd_rerate(); +void do_cmd_wiz_cure_all(); +void do_cmd_wiz_named_friendly(std::size_t r_idx, bool_ slp); +void do_cmd_debug(); diff --git a/src/xtra1.cc b/src/xtra1.cc index fd4a11fd..ae797aa8 100644 --- a/src/xtra1.cc +++ b/src/xtra1.cc @@ -13,8 +13,10 @@ #include "cave_type.hpp" #include "corrupt.hpp" #include "cmd7.hpp" +#include "dungeon_flag.hpp" #include "dungeon_info_type.hpp" #include "files.hpp" +#include "game.hpp" #include "gods.hpp" #include "hook_calculate_hp_in.hpp" #include "hook_calculate_hp_out.hpp" @@ -25,15 +27,20 @@ #include "monster1.hpp" #include "monster2.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_flag_meta.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 "skill_flag.hpp" #include "skill_type.hpp" #include "skills.hpp" #include "spells3.hpp" @@ -50,13 +57,14 @@ #include "z-rand.hpp" #include <cassert> +#include <fmt/format.h> /* * Converts stat num into a six-char (right justified) string */ void cnv_stat(int val, char *out_val) { - if (!linear_stats) + if (!options->linear_stats) { /* Above 18 */ if (val > 18) @@ -181,7 +189,7 @@ static void prt_field(cptr info, int row, int col) /* * Prints players max/cur piety */ -static void prt_piety(void) +static void prt_piety() { char tmp[32]; @@ -200,7 +208,7 @@ static void prt_piety(void) /* * Prints the player's current sanity. */ -static void prt_sane(void) +static void prt_sane() { char tmp[32]; byte color; @@ -223,7 +231,7 @@ static void prt_sane(void) { color = TERM_L_GREEN; } - else if (perc > (10 * hitpoint_warn)) + else if (perc > (10 * options->hitpoint_warn)) { color = TERM_YELLOW; } @@ -286,7 +294,7 @@ static void prt_stat(int stat) /* * Prints "title", including "wizard" or "winner" as needed. */ -static void prt_title(void) +static void prt_title() { cptr p = ""; @@ -328,7 +336,7 @@ static void prt_title(void) /* * Prints level */ -static void prt_level(void) +static void prt_level() { char tmp[32]; @@ -350,17 +358,17 @@ static void prt_level(void) /* * Display the experience */ -static void prt_exp(void) +static void prt_exp() { char out_val[32]; - if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev)) + if (p_ptr->lev >= PY_MAX_LEVEL) { - (void)sprintf(out_val, "********"); + sprintf(out_val, "********"); } else { - (void)sprintf(out_val, "%8ld", (long)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp); + sprintf(out_val, "%8ld", (long)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp); } if (p_ptr->exp >= p_ptr->max_exp) @@ -379,7 +387,7 @@ static void prt_exp(void) /* * Prints current gold */ -static void prt_gold(void) +static void prt_gold() { char tmp[32]; @@ -393,7 +401,7 @@ static void prt_gold(void) /* * Prints current AC */ -static void prt_ac(void) +static void prt_ac() { char tmp[32]; @@ -406,13 +414,16 @@ static void prt_ac(void) /* * Prints Cur/Max hit points */ -static void prt_hp(void) +static void prt_hp() { char tmp[32]; byte color; - if (player_char_health) lite_spot(p_ptr->py, p_ptr->px); + if (options->player_char_health) + { + lite_spot(p_ptr->py, p_ptr->px); + } if (p_ptr->necro_extra & CLASS_UNDEAD) { @@ -424,7 +435,7 @@ static void prt_hp(void) { color = TERM_L_BLUE; } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) + else if (p_ptr->chp > (p_ptr->mhp * options->hitpoint_warn) / 10) { color = TERM_VIOLET; } @@ -444,7 +455,7 @@ static void prt_hp(void) { color = TERM_L_GREEN; } - else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10) + else if (p_ptr->chp > (p_ptr->mhp * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -459,7 +470,7 @@ static void prt_hp(void) /* * Prints Cur/Max monster hit points */ -static void prt_mh(void) +static void prt_mh() { char tmp[32]; @@ -483,7 +494,7 @@ static void prt_mh(void) { color = TERM_L_GREEN; } - else if (o_ptr->pval2 > (o_ptr->pval3 * hitpoint_warn) / 10) + else if (o_ptr->pval2 > (o_ptr->pval3 * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -498,7 +509,7 @@ static void prt_mh(void) /* * Prints players max/cur spell points */ -static void prt_sp(void) +static void prt_sp() { char tmp[32]; byte color; @@ -511,7 +522,7 @@ static void prt_sp(void) { color = TERM_L_GREEN; } - else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10) + else if (p_ptr->csp > (p_ptr->msp * options->hitpoint_warn) / 10) { color = TERM_YELLOW; } @@ -528,8 +539,11 @@ static void prt_sp(void) */ static void prt_depth(int row, int col) { + auto const &d_info = game->edit_data.d_info; + auto const &wf_info = game->edit_data.wf_info; + char depths[32]; - dungeon_info_type *d_ptr = &d_info[dungeon_type]; + auto d_ptr = &d_info[dungeon_type]; if (p_ptr->wild_mode) { @@ -539,7 +553,7 @@ static void prt_depth(int row, int col) { /* Empty */ } - else if (dungeon_flags2 & DF2_SPECIAL) + else if (dungeon_flags & DF_SPECIAL) { strcpy(depths, "Special"); } @@ -549,9 +563,11 @@ static void prt_depth(int row, int col) } else if (!dun_level) { - if (wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name) + auto const &wilderness = game->wilderness; + auto const &wf = wf_info[wilderness(p_ptr->wilderness_x, p_ptr->wilderness_y).feat]; + if (wf.name) { - strcpy(depths, wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name); + strcpy(depths, wf.name); } else { @@ -560,9 +576,9 @@ static void prt_depth(int row, int col) } else { - if (dungeon_flags1 & DF1_TOWER) + if (dungeon_flags & DF_TOWER) { - (void)strnfmt(depths, 32, "%c%c%c -%d", + strnfmt(depths, 32, "%c%c%c -%d", d_ptr->short_name[0], d_ptr->short_name[1], d_ptr->short_name[2], @@ -570,7 +586,7 @@ static void prt_depth(int row, int col) } else { - (void)strnfmt(depths, 32, "%c%c%c %d", + strnfmt(depths, 32, "%c%c%c %d", d_ptr->short_name[0], d_ptr->short_name[1], d_ptr->short_name[2], @@ -677,20 +693,14 @@ static void prt_state(int row, int col) { if (command_rep > 999) { - (void)sprintf(text, "Rep. %3d00", command_rep / 100); + sprintf(text, "Rep. %3d00", command_rep / 100); } else { - (void)sprintf(text, "Repeat %3d", command_rep); + sprintf(text, "Repeat %3d", command_rep); } } - /* Searching */ - else if (p_ptr->searching) - { - strcpy(text, "Searching "); - } - /* Nothing interesting */ else { @@ -712,9 +722,6 @@ static void prt_speed(int row, int col) byte attr = TERM_WHITE; char buf[32] = ""; - /* Hack -- Visually "undo" the Search Mode Slowdown */ - if (p_ptr->searching) i += 10; - /* Fast */ if (i > 110) { @@ -738,7 +745,7 @@ static void prt_speed(int row, int col) /* * Prints status line */ -static void prt_status_line(void) +static void prt_status_line() { int wid, hgt; Term_get_size(&wid, &hgt); @@ -815,17 +822,6 @@ static void prt_status_line(void) put_str(" ", row, col); } - /* Dtrap */ - col = 32; - if (cave[p_ptr->py][p_ptr->px].info & CAVE_DETECT) - { - c_put_str(TERM_L_GREEN, "DTrap", row, col); - } - else - { - put_str(" ", row, col); - } - /* State */ col = 38; prt_state(row, col); @@ -852,7 +848,7 @@ static void prt_status_line(void) -static void prt_cut(void) +static void prt_cut() { int c = p_ptr->cut; int hgt; @@ -896,7 +892,7 @@ static void prt_cut(void) -static void prt_stun(void) +static void prt_stun() { int s = p_ptr->stun; int hgt; @@ -938,7 +934,7 @@ static void prt_stun(void) * Auto-track current target monster when bored. Note that the * health-bar stops tracking any monster that "disappears". */ -static void health_redraw(void) +static void health_redraw() { int hgt; Term_get_size(nullptr, &hgt); @@ -1032,12 +1028,12 @@ static void health_redraw(void) /* * Display basic info (mostly left of map) */ -static void prt_frame(void) +static void prt_frame() { int i; /* Race and Class */ - prt_field(rp_ptr->title, ROW_RACE, COL_RACE); + prt_field(rp_ptr->title.c_str(), ROW_RACE, COL_RACE); prt_field(spp_ptr->title, ROW_CLASS, COL_CLASS); /* Title */ @@ -1083,15 +1079,16 @@ static void prt_frame(void) } -/* - * Hack -- display inventory in sub-windows +/** + * Fix up each terminal based on whether a window flag + * is set. */ -static void fix_inven(void) -{ - int j; +namespace { // anonymous - /* Scan windows */ - for (j = 0; j < 8; j++) +template <typename F> +static void fixup_display(u32b mask, F callback) +{ + for (int j = 0; j < ANGBAND_TERM_MAX; j++) { term *old = Term; @@ -1099,13 +1096,13 @@ static void fix_inven(void) if (!angband_term[j]) continue; /* No relevant flags */ - if (!(window_flag[j] & (PW_INVEN))) continue; + if (!(window_flag[j] & mask)) continue; /* Activate */ Term_activate(angband_term[j]); - /* Display inventory */ - display_inven(); + /* Apply fixup callback */ + callback(); /* Fresh */ Term_fresh(); @@ -1115,70 +1112,33 @@ static void fix_inven(void) } } +} // namespace anonymous /* - * Hack -- display equipment in sub-windows + * Hack -- display inventory in sub-windows */ -static void fix_equip(void) +static void fix_inven() { - int j; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_EQUIP))) continue; - - /* Activate */ - Term_activate(angband_term[j]); - - /* Display equipment */ - display_equip(); - - /* Fresh */ - Term_fresh(); + fixup_display(PW_INVEN, display_inven); +} - /* Restore */ - Term_activate(old); - } +/* + * Hack -- display equipment in sub-windows + */ +static void fix_equip() +{ + fixup_display(PW_EQUIP, display_equip); } /* * Hack -- display character in sub-windows */ -static void fix_player(void) +static void fix_player() { - int j; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_PLAYER))) continue; - - /* Activate */ - Term_activate(angband_term[j]); - - /* Display player */ + fixup_display(PW_PLAYER, [] { display_player(0); - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + }); } @@ -1188,48 +1148,32 @@ static void fix_player(void) * * XXX XXX XXX Adjust for width and split messages */ -void fix_message(void) +void fix_message() { - int j, i; - int w, h; - int x, y; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_MESSAGE))) continue; - - /* Activate */ - Term_activate(angband_term[j]); + auto const &messages = game->messages; + fixup_display(PW_MESSAGE, [&messages] { /* Get size */ + int w, h; Term_get_size(&w, &h); /* Dump messages */ - for (i = 0; i < h; i++) + for (int i = 0; i < h; i++) { + auto message = messages.at(i); + auto text_with_count = message.text_with_count(); + /* Dump the message on the appropriate line */ - display_message(0, (h - 1) - i, strlen(message_str((s16b)i)), message_color((s16b)i), message_str((s16b)i)); + display_message(0, (h - 1) - i, text_with_count.size(), message.color, text_with_count.c_str()); /* Cursor */ + int x, y; Term_locate(&x, &y); /* Clear to end of line */ Term_erase(x, y, 255); } - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + }); } @@ -1238,132 +1182,60 @@ void fix_message(void) * * Note that the "player" symbol does NOT appear on the map. */ -static void fix_overhead(void) +static void fix_overhead() { - int j; - - int cy, cx; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_OVERHEAD))) continue; - - /* Activate */ - Term_activate(angband_term[j]); - - /* Redraw map */ + fixup_display(PW_OVERHEAD, [] { + int cy, cx; display_map(&cy, &cx); - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + }); } /* * Hack -- display monster recall in sub-windows */ -static void fix_monster(void) +static void fix_monster() { - int j; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_MONSTER))) continue; - - /* Activate */ - Term_activate(angband_term[j]); - + fixup_display(PW_MONSTER, [] { /* Display monster race info */ if (monster_race_idx) { display_roff(monster_race_idx, monster_ego_idx); } - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + }); } /* * Hack -- display object recall in sub-windows */ -static void fix_object(void) +static void fix_object() { - int j; - - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_OBJECT))) continue; - - /* Activate */ - Term_activate(angband_term[j]); - + fixup_display(PW_OBJECT, [] { /* Clear */ Term_clear(); /* Display object info */ - if (tracked_object) - if (!object_out_desc(tracked_object, NULL, FALSE, FALSE)) text_out("You see nothing special."); - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + if (tracked_object && + !object_out_desc(tracked_object, NULL, FALSE, FALSE)) + { + text_out("You see nothing special."); + } + }); } /* Show the monster list in a window */ -static void fix_m_list(void) +static void fix_m_list() { - int i, j; + auto const &r_info = game->edit_data.r_info; - /* Scan windows */ - for (j = 0; j < 8; j++) - { - term *old = Term; - - int c = 0; - - /* No window */ - if (!angband_term[j]) continue; - - /* No relevant flags */ - if (!(window_flag[j] & (PW_M_LIST))) continue; - - /* Activate */ - Term_activate(angband_term[j]); + // Mirror of the r_info array, index by index. We use a + // statically allocated value to avoid frequent allocations. + static auto r_total_visible = + std::vector<u16b>(r_info.size(), 0); + fixup_display(PW_M_LIST, [&r_info] { /* Clear */ Term_clear(); @@ -1371,35 +1243,28 @@ static void fix_m_list(void) if (p_ptr->image) { c_prt(TERM_WHITE, "You can not see clearly", 0, 0); - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - return; } /* reset visible count */ - for (i = 1; i < max_r_idx; i++) + for (std::size_t i = 1; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; - - r_ptr->total_visible = 0; + r_total_visible[i] = 0; } /* Count up the number visible in each race */ - for (i = 1; i < m_max; i++) + int c = 0; + for (std::size_t i = 1; i < static_cast<u16b>(m_max); i++) { - monster_type *m_ptr = &m_list[i]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; + auto const m_ptr = &m_list[i]; + auto const r_ptr = &r_info[m_ptr->r_idx]; + auto total_visible = &r_total_visible[m_ptr->r_idx]; /* Skip dead monsters */ if (m_ptr->hp < 0) continue; /* Skip unseen monsters */ - if (r_ptr->flags9 & RF9_MIMIC) + if (r_ptr->flags & RF_MIMIC) { /* Acquire object */ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; @@ -1413,7 +1278,7 @@ static void fix_m_list(void) } /* Increase for this race */ - r_ptr->total_visible++; + (*total_visible)++; /* Increase total Count */ c++; @@ -1424,34 +1289,38 @@ static void fix_m_list(void) { int w, h, num = 0; - (void)Term_get_size(&w, &h); + Term_get_size(&w, &h); c_prt(TERM_WHITE, format("You can see %d monster%s", c, (c > 1 ? "s:" : ":")), 0, 0); - for (i = 1; i < max_r_idx; i++) + for (std::size_t i = 1; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; + auto const r_ptr = &r_info[i]; + auto const total_visible = r_total_visible[i]; /* Default Colour */ byte attr = TERM_SLATE; /* Only visible monsters */ - if (!r_ptr->total_visible) continue; + if (!total_visible) + { + continue; + } /* Uniques */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { attr = TERM_L_BLUE; } - /* Have we ever killed one? */ - if (r_ptr->r_tkills) + /* Have we killed one? */ + if (r_ptr->r_pkills) { if (r_ptr->level > dun_level) { attr = TERM_VIOLET; - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { attr = TERM_RED; } @@ -1459,18 +1328,17 @@ static void fix_m_list(void) } else { - if (!(r_ptr->flags1 & RF1_UNIQUE)) attr = TERM_GREEN; + if (!(r_ptr->flags & RF_UNIQUE)) attr = TERM_GREEN; } - /* Dump the monster name */ - if (r_ptr->total_visible == 1) + if (total_visible == 1) { c_prt(attr, r_ptr->name, (num % (h - 1)) + 1, (num / (h - 1) * 26)); } else { - c_prt(attr, format("%s (x%d)", r_ptr->name, r_ptr->total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26); + c_prt(attr, format("%s (x%d)", r_ptr->name, total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26); } num++; @@ -1482,13 +1350,7 @@ static void fix_m_list(void) { c_prt(TERM_WHITE, "You see no monsters.", 0, 0); } - - /* Fresh */ - Term_fresh(); - - /* Restore */ - Term_activate(old); - } + }); } @@ -1518,8 +1380,17 @@ static void calc_powers_corruption() /* Ugly hack */ bool_ calc_powers_silent = FALSE; +/* Add in powers */ +static void add_powers(std::vector<s16b> const &powers) +{ + for (auto const &p: powers) + { + p_ptr->powers[p] = TRUE; + } +} + /* Calc the player powers */ -static void calc_powers(void) +static void calc_powers() { int i, p = 0; bool_ old_powers[POWER_MAX]; @@ -1548,32 +1419,23 @@ static void calc_powers(void) if (!o_ptr->k_idx) continue; p = object_power(o_ptr); - if (p != -1) p_ptr->powers[p] = TRUE; + if (p != -1) + { + p_ptr->powers[p] = TRUE; + } } if ((!p_ptr->tim_mimic) && (!p_ptr->body_monster)) { - /* Add in racial and subracial powers */ - for (i = 0; i < 4; i++) - { - p = rp_ptr->powers[i]; - if (p != -1) p_ptr->powers[p] = TRUE; - - p = rmp_ptr->powers[i]; - if (p != -1) p_ptr->powers[p] = TRUE; - } + add_powers(rp_ptr->ps.powers); + add_powers(rmp_ptr->ps.powers); } else if (p_ptr->mimic_form) { calc_mimic_power(); } - /* Add in class powers */ - for (i = 0; i < 4; i++) - { - p = cp_ptr->powers[i]; - if (p != -1) p_ptr->powers[p] = TRUE; - } + add_powers(cp_ptr->ps.powers); if (p_ptr->disembodied) { @@ -1641,12 +1503,11 @@ static void calc_sanity() * * This function induces status messages. */ -static void calc_mana(void) +static void calc_mana() { - int msp, levels, cur_wgt, max_wgt; - u32b f1, f2, f3, f4, f5, esp; + auto const &r_info = game->edit_data.r_info; - object_type *o_ptr; + int msp, levels, cur_wgt, max_wgt; levels = p_ptr->lev; @@ -1666,7 +1527,8 @@ static void calc_mana(void) /* Possessors mana is different */ if (p_ptr->body_monster && (!p_ptr->disembodied)) { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; + int f = 100 / (r_ptr->freq_spell ? r_ptr->freq_spell : 1); msp = 21 - f; @@ -1697,16 +1559,16 @@ static void calc_mana(void) p_ptr->cumber_glove = FALSE; /* Get the gloves */ - o_ptr = &p_ptr->inventory[INVEN_HANDS]; + object_type *o_ptr = &p_ptr->inventory[INVEN_HANDS]; /* Examine the gloves */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Normal gloves hurt mage-type spells */ if (o_ptr->k_idx && - !(f2 & (TR2_FREE_ACT)) && - !((f1 & (TR1_DEX)) && (o_ptr->pval > 0)) && - !(f5 & TR5_SPELL_CONTAIN)) + !(flags & TR_FREE_ACT) && + !((flags & TR_DEX) && (o_ptr->pval > 0)) && + !(flags & TR_SPELL_CONTAIN)) { /* Encumbered */ p_ptr->cumber_glove = TRUE; @@ -1821,17 +1683,16 @@ static void calc_mana(void) * Calculate the players (maximal) hit points * Adjust current hitpoints if necessary */ -void calc_hitpoints(void) +void calc_hitpoints() { - int bonus, mhp; + auto const &player_hp = game->player_hp; + auto const &r_info = game->edit_data.r_info; /* Un-inflate "half-hitpoint bonus per level" value */ - bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128); + int const bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128); /* Calculate hitpoints */ - assert(p_ptr->lev - 1 >= 0); - assert(p_ptr->lev - 1 < PY_MAX_LEVEL); - mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2); + int mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2); /* Always have at least one hitpoint per level */ if (mhp < p_ptr->lev + 1) mhp = p_ptr->lev + 1; @@ -1865,7 +1726,7 @@ void calc_hitpoints(void) if (p_ptr->body_monster) { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto r_ptr = &r_info[p_ptr->body_monster]; u32b rhp = maxroll(r_ptr->hdice, r_ptr->hside); /* Adjust the hp with the possession skill */ @@ -1946,11 +1807,10 @@ static void calc_torch_gods() * SWD: Experimental modification: multiple light sources have additive effect. * */ -static void calc_torch(void) +static void calc_torch() { int i; object_type *o_ptr; - u32b f1, f2, f3, f4, f5, esp; /* Assume no light */ p_ptr->cur_lite = 0; @@ -1964,14 +1824,14 @@ static void calc_torch(void) if (!o_ptr->k_idx) continue; /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* does this item glow? */ - if (((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0)) || (!(f4 & TR4_FUEL_LITE))) + if (((flags & TR_FUEL_LITE) && (o_ptr->timeout > 0)) || (!(flags & TR_FUEL_LITE))) { - if (f3 & TR3_LITE1) p_ptr->cur_lite++; - if (f4 & TR4_LITE2) p_ptr->cur_lite += 2; - if (f4 & TR4_LITE3) p_ptr->cur_lite += 3; + if (flags & TR_LITE1) p_ptr->cur_lite++; + if (flags & TR_LITE2) p_ptr->cur_lite += 2; + if (flags & TR_LITE3) p_ptr->cur_lite += 3; } } @@ -2005,7 +1865,7 @@ static void calc_torch(void) /* Reduce lite when running if requested */ - if (running && view_reduce_lite) + if (running && options->view_reduce_lite) { /* Reduce the lite radius if needed */ if (p_ptr->cur_lite > 1) p_ptr->cur_lite = 1; @@ -2030,7 +1890,7 @@ static void calc_torch(void) /* * Computes current weight limit. */ -int weight_limit(void) +int weight_limit() { int i; @@ -2043,23 +1903,22 @@ int weight_limit(void) void calc_wield_monster() { - object_type *o_ptr; - monster_race *r_ptr; + auto const &r_info = game->edit_data.r_info; /* Get the carried monster */ - o_ptr = &p_ptr->inventory[INVEN_CARRY]; + auto o_ptr = &p_ptr->inventory[INVEN_CARRY]; if (o_ptr->k_idx) { - r_ptr = &r_info[o_ptr->pval]; + auto r_ptr = &r_info[o_ptr->pval]; - if (r_ptr->flags2 & RF2_INVISIBLE) + if (r_ptr->flags & RF_INVISIBLE) p_ptr->invis += 20; - if (r_ptr->flags2 & RF2_REFLECTING) + if (r_ptr->flags & RF_REFLECTING) p_ptr->reflect = TRUE; - if (r_ptr->flags7 & RF7_CAN_FLY) + if (r_ptr->flags & RF_CAN_FLY) p_ptr->ffall = TRUE; - if (r_ptr->flags7 & RF7_AQUATIC) + if (r_ptr->flags & RF_AQUATIC) p_ptr->water_breath = TRUE; } } @@ -2072,7 +1931,9 @@ void calc_wield_monster() */ void calc_body() { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[p_ptr->body_monster]; int i, b_weapon, b_legs, b_arms; byte *body_parts, bp[BODY_MAX]; @@ -2191,10 +2052,15 @@ void calc_body() /* Should be called by every calc_bonus call */ void calc_body_bonus() { - monster_race *r_ptr = &r_info[p_ptr->body_monster]; + auto const &r_info = game->edit_data.r_info; + + auto r_ptr = &r_info[p_ptr->body_monster]; /* If in the player body nothing have to be done */ - if (!p_ptr->body_monster) return; + if (!p_ptr->body_monster) + { + return; + } if (p_ptr->disembodied) { @@ -2205,29 +2071,29 @@ void calc_body_bonus() p_ptr->ac += r_ptr->ac; p_ptr->pspeed = r_ptr->speed; - if (r_ptr->flags1 & RF1_NEVER_MOVE) p_ptr->immovable = TRUE; - if (r_ptr->flags2 & RF2_STUPID) p_ptr->stat_add[A_INT] -= 1; - if (r_ptr->flags2 & RF2_SMART) p_ptr->stat_add[A_INT] += 1; - if (r_ptr->flags2 & RF2_REFLECTING) p_ptr->reflect = TRUE; - if (r_ptr->flags2 & RF2_INVISIBLE) p_ptr->invis += 20; - if (r_ptr->flags2 & RF2_REGENERATE) p_ptr->regenerate = TRUE; - if (r_ptr->flags2 & RF2_AURA_FIRE) p_ptr->sh_fire = TRUE; - if (r_ptr->flags2 & RF2_AURA_ELEC) p_ptr->sh_elec = TRUE; - if (r_ptr->flags2 & RF2_PASS_WALL) p_ptr->wraith_form = TRUE; - if (r_ptr->flags3 & RF3_SUSCEP_FIRE) p_ptr->sensible_fire = TRUE; - if (r_ptr->flags3 & RF3_IM_ACID) p_ptr->resist_acid = TRUE; - if (r_ptr->flags3 & RF3_IM_ELEC) p_ptr->resist_elec = TRUE; - if (r_ptr->flags3 & RF3_IM_FIRE) p_ptr->resist_fire = TRUE; - if (r_ptr->flags3 & RF3_IM_POIS) p_ptr->resist_pois = TRUE; - if (r_ptr->flags3 & RF3_IM_COLD) p_ptr->resist_cold = TRUE; - if (r_ptr->flags3 & RF3_RES_NETH) p_ptr->resist_neth = TRUE; - if (r_ptr->flags3 & RF3_RES_NEXU) p_ptr->resist_nexus = TRUE; - if (r_ptr->flags3 & RF3_RES_DISE) p_ptr->resist_disen = TRUE; - if (r_ptr->flags3 & RF3_NO_FEAR) p_ptr->resist_fear = TRUE; - if (r_ptr->flags3 & RF3_NO_SLEEP) p_ptr->free_act = TRUE; - if (r_ptr->flags3 & RF3_NO_CONF) p_ptr->resist_conf = TRUE; - if (r_ptr->flags7 & RF7_CAN_FLY) p_ptr->ffall = TRUE; - if (r_ptr->flags7 & RF7_AQUATIC) p_ptr->water_breath = TRUE; + if (r_ptr->flags & RF_NEVER_MOVE) p_ptr->immovable = TRUE; + if (r_ptr->flags & RF_STUPID) p_ptr->stat_add[A_INT] -= 1; + if (r_ptr->flags & RF_SMART) p_ptr->stat_add[A_INT] += 1; + if (r_ptr->flags & RF_REFLECTING) p_ptr->reflect = TRUE; + if (r_ptr->flags & RF_INVISIBLE) p_ptr->invis += 20; + if (r_ptr->flags & RF_REGENERATE) p_ptr->regenerate = TRUE; + if (r_ptr->flags & RF_AURA_FIRE) p_ptr->sh_fire = TRUE; + if (r_ptr->flags & RF_AURA_ELEC) p_ptr->sh_elec = TRUE; + if (r_ptr->flags & RF_PASS_WALL) p_ptr->wraith_form = TRUE; + if (r_ptr->flags & RF_SUSCEP_FIRE) p_ptr->sensible_fire = TRUE; + if (r_ptr->flags & RF_IM_ACID) p_ptr->resist_acid = TRUE; + if (r_ptr->flags & RF_IM_ELEC) p_ptr->resist_elec = TRUE; + if (r_ptr->flags & RF_IM_FIRE) p_ptr->resist_fire = TRUE; + if (r_ptr->flags & RF_IM_POIS) p_ptr->resist_pois = TRUE; + if (r_ptr->flags & RF_IM_COLD) p_ptr->resist_cold = TRUE; + if (r_ptr->flags & RF_RES_NETH) p_ptr->resist_neth = TRUE; + if (r_ptr->flags & RF_RES_NEXU) p_ptr->resist_nexus = TRUE; + if (r_ptr->flags & RF_RES_DISE) p_ptr->resist_disen = TRUE; + if (r_ptr->flags & RF_NO_FEAR) p_ptr->resist_fear = TRUE; + if (r_ptr->flags & RF_NO_SLEEP) p_ptr->free_act = TRUE; + if (r_ptr->flags & RF_NO_CONF) p_ptr->resist_conf = TRUE; + if (r_ptr->flags & RF_CAN_FLY) p_ptr->ffall = TRUE; + if (r_ptr->flags & RF_AQUATIC) p_ptr->water_breath = TRUE; } @@ -2235,8 +2101,8 @@ void calc_body_bonus() static int get_extra_blows_ability() { /* Count bonus abilities */ int num = 0; - if (has_ability(AB_MAX_BLOW1)) num++; - if (has_ability(AB_MAX_BLOW2)) num++; + if (p_ptr->has_ability(AB_MAX_BLOW1)) num++; + if (p_ptr->has_ability(AB_MAX_BLOW2)) num++; return num; } @@ -2491,15 +2357,17 @@ static void calc_schools() /* Apply corruptions */ static void calc_corruptions() { + auto &s_info = game->s_info; + if (player_has_corruption(CORRUPT_BALROG_AURA)) { - p_ptr->xtra_f3 |= TR3_SH_FIRE; - p_ptr->xtra_f3 |= TR3_LITE1; + p_ptr->xtra_flags |= TR_SH_FIRE; + p_ptr->xtra_flags |= TR_LITE1; } if (player_has_corruption(CORRUPT_BALROG_WINGS)) { - p_ptr->xtra_f4 |= TR4_FLY; + p_ptr->xtra_flags |= TR_FLY; p_ptr->stat_add[A_CHR] -= 4; p_ptr->stat_add[A_DEX] -= 2; } @@ -2525,7 +2393,7 @@ static void calc_corruptions() p_ptr->pspeed = p_ptr->pspeed - (p_ptr->lev / 7); if (p_ptr->lev >= 40) { - p_ptr->xtra_f2 |= TR2_IM_FIRE; + p_ptr->xtra_flags |= TR_IM_FIRE; } } @@ -2537,12 +2405,12 @@ static void calc_corruptions() { s_info[SKILL_DAEMON].mod = 1500; } - s_info[SKILL_DAEMON].hidden = FALSE; + s_info[SKILL_DAEMON].hidden = false; } if (player_has_corruption(CORRUPT_RANDOM_TELEPORT)) { - p_ptr->xtra_f3 |= TR3_TELEPORT; + p_ptr->xtra_flags |= TR_TELEPORT; } if (player_has_corruption(CORRUPT_ANTI_TELEPORT)) @@ -2555,136 +2423,131 @@ static void calc_corruptions() if (player_has_corruption(CORRUPT_TROLL_BLOOD)) { - p_ptr->xtra_f3 |= (TR3_REGEN | TR3_AGGRAVATE); - p_ptr->xtra_esp |= ESP_TROLL; + p_ptr->xtra_flags |= (TR_REGEN | TR_AGGRAVATE | ESP_TROLL); } } /* Apply flags */ static int extra_blows; static int extra_shots; -void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a) +void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a) { s16b antimagic_mod; + // Mix into computed flags + p_ptr->computed_flags |= f; + /* Affect stats */ - if (f1 & (TR1_STR)) p_ptr->stat_add[A_STR] += pval; - if (f1 & (TR1_INT)) p_ptr->stat_add[A_INT] += pval; - if (f1 & (TR1_WIS)) p_ptr->stat_add[A_WIS] += pval; - if (f1 & (TR1_DEX)) p_ptr->stat_add[A_DEX] += pval; - if (f1 & (TR1_CON)) p_ptr->stat_add[A_CON] += pval; - if (f1 & (TR1_CHR)) p_ptr->stat_add[A_CHR] += pval; - if (f5 & (TR5_LUCK)) p_ptr->luck_cur += pval; + if (f & TR_STR) p_ptr->stat_add[A_STR] += pval; + if (f & TR_INT) p_ptr->stat_add[A_INT] += pval; + if (f & TR_WIS) p_ptr->stat_add[A_WIS] += pval; + if (f & TR_DEX) p_ptr->stat_add[A_DEX] += pval; + if (f & TR_CON) p_ptr->stat_add[A_CON] += pval; + if (f & TR_CHR) p_ptr->stat_add[A_CHR] += pval; + if (f & TR_LUCK) p_ptr->luck_cur += pval; /* Affect spell power */ - if (f1 & (TR1_SPELL)) p_ptr->to_s += pval; + if (f & TR_SPELL) p_ptr->to_s += pval; /* Affect mana capacity */ - if (f1 & (TR1_MANA)) p_ptr->to_m += pval; + if (f & TR_MANA) p_ptr->to_m += pval; /* Affect life capacity */ - if (f2 & (TR2_LIFE)) p_ptr->to_l += pval; + if (f & TR_LIFE) p_ptr->to_l += pval; /* Affect stealth */ - if (f1 & (TR1_STEALTH)) p_ptr->skill_stl += pval; - - /* Affect searching ability (factor of five) */ - if (f1 & (TR1_SEARCH)) p_ptr->skill_srh += (pval * 5); - - /* Affect searching frequency (factor of five) */ - if (f1 & (TR1_SEARCH)) p_ptr->skill_fos += (pval * 5); + if (f & TR_STEALTH) p_ptr->skill_stl += pval; /* Affect infravision */ - if (f1 & (TR1_INFRA)) p_ptr->see_infra += pval; + if (f & TR_INFRA) p_ptr->see_infra += pval; /* Affect digging (factor of 20) */ - if (f1 & (TR1_TUNNEL)) p_ptr->skill_dig += (pval * 20); + if (f & TR_TUNNEL) p_ptr->skill_dig += (pval * 20); /* Affect speed */ - if (f1 & (TR1_SPEED)) p_ptr->pspeed += pval; + if (f & TR_SPEED) p_ptr->pspeed += pval; /* Affect blows */ - if (f1 & (TR1_BLOWS)) extra_blows += pval; - if (f5 & (TR5_CRIT)) p_ptr->xtra_crit += pval; + if (f & TR_BLOWS) extra_blows += pval; + if (f & TR_CRIT) p_ptr->xtra_crit += pval; /* Hack -- Sensible fire */ - if (f2 & (TR2_SENS_FIRE)) p_ptr->sensible_fire = TRUE; + if (f & TR_SENS_FIRE) p_ptr->sensible_fire = TRUE; /* Hack -- cause earthquakes */ - if (f1 & (TR1_IMPACT)) p_ptr->impact = TRUE; + if (f & TR_IMPACT) p_ptr->impact = TRUE; /* Affect invisibility */ - if (f2 & (TR2_INVIS)) p_ptr->invis += (pval * 10); + if (f & TR_INVIS) p_ptr->invis += (pval * 10); /* Boost shots */ - if (f3 & (TR3_XTRA_SHOTS)) extra_shots++; + if (f & TR_XTRA_SHOTS) extra_shots++; /* Various flags */ - if (f3 & (TR3_AGGRAVATE)) p_ptr->aggravate = TRUE; - if (f3 & (TR3_TELEPORT)) p_ptr->teleport = TRUE; - if (f5 & (TR5_DRAIN_MANA)) p_ptr->drain_mana++; - if (f5 & (TR5_DRAIN_HP)) p_ptr->drain_life++; - if (f3 & (TR3_DRAIN_EXP)) p_ptr->exp_drain = TRUE; - if (f3 & (TR3_BLESSED)) p_ptr->bless_blade = TRUE; - if (f3 & (TR3_XTRA_MIGHT)) p_ptr->xtra_might += pval; - if (f3 & (TR3_SLOW_DIGEST)) p_ptr->slow_digest = TRUE; - if (f3 & (TR3_REGEN)) p_ptr->regenerate = TRUE; - if (esp) p_ptr->telepathy |= esp; - if ((tval != TV_LITE) && (f3 & (TR3_LITE1))) p_ptr->lite = TRUE; - if ((tval != TV_LITE) && (f4 & (TR4_LITE2))) p_ptr->lite = TRUE; - if ((tval != TV_LITE) && (f4 & (TR4_LITE3))) p_ptr->lite = TRUE; - if (f3 & (TR3_SEE_INVIS)) p_ptr->see_inv = TRUE; - if (f2 & (TR2_FREE_ACT)) p_ptr->free_act = TRUE; - if (f2 & (TR2_HOLD_LIFE)) p_ptr->hold_life = TRUE; - if (f3 & (TR3_WRAITH)) p_ptr->wraith_form = TRUE; - if (f3 & (TR3_FEATHER)) p_ptr->ffall = TRUE; - if (f4 & (TR4_FLY)) p_ptr->fly = TRUE; - if (f4 & (TR4_CLIMB)) p_ptr->climb = TRUE; + if (f & TR_AGGRAVATE) p_ptr->aggravate = TRUE; + if (f & TR_TELEPORT) p_ptr->teleport = TRUE; + if (f & TR_DRAIN_MANA) p_ptr->drain_mana++; + if (f & TR_DRAIN_HP) p_ptr->drain_life++; + if (f & TR_DRAIN_EXP) p_ptr->exp_drain = TRUE; + if (f & TR_BLESSED) p_ptr->bless_blade = TRUE; + if (f & TR_XTRA_MIGHT) p_ptr->xtra_might += pval; + if (f & TR_SLOW_DIGEST) p_ptr->slow_digest = TRUE; + if (f & TR_REGEN) p_ptr->regenerate = TRUE; + if ((tval != TV_LITE) && (f & TR_LITE1)) p_ptr->lite = TRUE; + if ((tval != TV_LITE) && (f & TR_LITE2)) p_ptr->lite = TRUE; + if ((tval != TV_LITE) && (f & TR_LITE3)) p_ptr->lite = TRUE; + if (f & TR_SEE_INVIS) p_ptr->see_inv = TRUE; + if (f & TR_FREE_ACT) p_ptr->free_act = TRUE; + if (f & TR_HOLD_LIFE) p_ptr->hold_life = TRUE; + if (f & TR_WRAITH) p_ptr->wraith_form = TRUE; + if (f & TR_FEATHER) p_ptr->ffall = TRUE; + if (f & TR_FLY) p_ptr->fly = TRUE; + if (f & TR_CLIMB) p_ptr->climb = TRUE; /* Immunity flags */ - if (f2 & (TR2_IM_FIRE)) p_ptr->immune_fire = TRUE; - if (f2 & (TR2_IM_ACID)) p_ptr->immune_acid = TRUE; - if (f2 & (TR2_IM_COLD)) p_ptr->immune_cold = TRUE; - if (f2 & (TR2_IM_ELEC)) p_ptr->immune_elec = TRUE; + if (f & TR_IM_FIRE) p_ptr->immune_fire = TRUE; + if (f & TR_IM_ACID) p_ptr->immune_acid = TRUE; + if (f & TR_IM_COLD) p_ptr->immune_cold = TRUE; + if (f & TR_IM_ELEC) p_ptr->immune_elec = TRUE; /* Resistance flags */ - if (f2 & (TR2_RES_ACID)) p_ptr->resist_acid = TRUE; - if (f2 & (TR2_RES_ELEC)) p_ptr->resist_elec = TRUE; - if (f2 & (TR2_RES_FIRE)) p_ptr->resist_fire = TRUE; - if (f2 & (TR2_RES_COLD)) p_ptr->resist_cold = TRUE; - if (f2 & (TR2_RES_POIS)) p_ptr->resist_pois = TRUE; - if (f2 & (TR2_RES_FEAR)) p_ptr->resist_fear = TRUE; - if (f2 & (TR2_RES_CONF)) p_ptr->resist_conf = TRUE; - if (f2 & (TR2_RES_SOUND)) p_ptr->resist_sound = TRUE; - if (f2 & (TR2_RES_LITE)) p_ptr->resist_lite = TRUE; - if (f2 & (TR2_RES_DARK)) p_ptr->resist_dark = TRUE; - if (f2 & (TR2_RES_CHAOS)) p_ptr->resist_chaos = TRUE; - if (f2 & (TR2_RES_DISEN)) p_ptr->resist_disen = TRUE; - if (f2 & (TR2_RES_SHARDS)) p_ptr->resist_shard = TRUE; - if (f2 & (TR2_RES_NEXUS)) p_ptr->resist_nexus = TRUE; - if (f2 & (TR2_RES_BLIND)) p_ptr->resist_blind = TRUE; - if (f2 & (TR2_RES_NETHER)) p_ptr->resist_neth = TRUE; - if (f4 & (TR4_IM_NETHER)) p_ptr->immune_neth = TRUE; - - if (f2 & (TR2_REFLECT)) p_ptr->reflect = TRUE; - if (f3 & (TR3_SH_FIRE)) p_ptr->sh_fire = TRUE; - if (f3 & (TR3_SH_ELEC)) p_ptr->sh_elec = TRUE; - if (f3 & (TR3_NO_MAGIC)) p_ptr->anti_magic = TRUE; - if (f3 & (TR3_NO_TELE)) p_ptr->anti_tele = TRUE; + if (f & TR_RES_ACID) p_ptr->resist_acid = TRUE; + if (f & TR_RES_ELEC) p_ptr->resist_elec = TRUE; + if (f & TR_RES_FIRE) p_ptr->resist_fire = TRUE; + if (f & TR_RES_COLD) p_ptr->resist_cold = TRUE; + if (f & TR_RES_POIS) p_ptr->resist_pois = TRUE; + if (f & TR_RES_FEAR) p_ptr->resist_fear = TRUE; + if (f & TR_RES_CONF) p_ptr->resist_conf = TRUE; + if (f & TR_RES_SOUND) p_ptr->resist_sound = TRUE; + if (f & TR_RES_LITE) p_ptr->resist_lite = TRUE; + if (f & TR_RES_DARK) p_ptr->resist_dark = TRUE; + if (f & TR_RES_CHAOS) p_ptr->resist_chaos = TRUE; + if (f & TR_RES_DISEN) p_ptr->resist_disen = TRUE; + if (f & TR_RES_SHARDS) p_ptr->resist_shard = TRUE; + if (f & TR_RES_NEXUS) p_ptr->resist_nexus = TRUE; + if (f & TR_RES_BLIND) p_ptr->resist_blind = TRUE; + if (f & TR_RES_NETHER) p_ptr->resist_neth = TRUE; + if (f & TR_IM_NETHER) p_ptr->immune_neth = TRUE; + + if (f & TR_REFLECT) p_ptr->reflect = TRUE; + if (f & TR_SH_FIRE) p_ptr->sh_fire = TRUE; + if (f & TR_SH_ELEC) p_ptr->sh_elec = TRUE; + if (f & TR_NO_MAGIC) p_ptr->anti_magic = TRUE; + if (f & TR_NO_TELE) p_ptr->anti_tele = TRUE; /* Sustain flags */ - if (f2 & (TR2_SUST_STR)) p_ptr->sustain_str = TRUE; - if (f2 & (TR2_SUST_INT)) p_ptr->sustain_int = TRUE; - if (f2 & (TR2_SUST_WIS)) p_ptr->sustain_wis = TRUE; - if (f2 & (TR2_SUST_DEX)) p_ptr->sustain_dex = TRUE; - if (f2 & (TR2_SUST_CON)) p_ptr->sustain_con = TRUE; - if (f2 & (TR2_SUST_CHR)) p_ptr->sustain_chr = TRUE; + if (f & TR_SUST_STR) p_ptr->sustain_str = TRUE; + if (f & TR_SUST_INT) p_ptr->sustain_int = TRUE; + if (f & TR_SUST_WIS) p_ptr->sustain_wis = TRUE; + if (f & TR_SUST_DEX) p_ptr->sustain_dex = TRUE; + if (f & TR_SUST_CON) p_ptr->sustain_con = TRUE; + if (f & TR_SUST_CHR) p_ptr->sustain_chr = TRUE; - if (f4 & (TR4_PRECOGNITION)) p_ptr->precognition = TRUE; + if (f & TR_PRECOGNITION) p_ptr->precognition = TRUE; antimagic_mod = to_h + to_d + to_a; - if (f4 & (TR4_ANTIMAGIC_50)) + if (f & TR_ANTIMAGIC_50) { s32b tmp; @@ -2695,7 +2558,7 @@ void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pva if (tmp > 0) p_ptr->antimagic_dis += tmp; } - if (f4 & (TR4_AUTO_ID)) + if (f & TR_AUTO_ID) { p_ptr->auto_id = TRUE; } @@ -2705,13 +2568,17 @@ void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pva * "black_breath". This flag can also be set by a unlucky blow from * an undead. -LM- */ - if (f4 & (TR4_BLACK_BREATH)) p_ptr->black_breath = TRUE; + if (f & TR_BLACK_BREATH) p_ptr->black_breath = TRUE; - if (f5 & (TR5_IMMOVABLE)) p_ptr->immovable = TRUE; + if (f & TR_IMMOVABLE) p_ptr->immovable = TRUE; /* Breaths */ - if (f5 & (TR5_WATER_BREATH)) p_ptr->water_breath = TRUE; - if (f5 & (TR5_MAGIC_BREATH)) + if (f & TR_WATER_BREATH) + { + p_ptr->water_breath = TRUE; + } + + if (f & TR_MAGIC_BREATH) { p_ptr->magical_breath = TRUE; p_ptr->water_breath = TRUE; @@ -2719,11 +2586,23 @@ void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pva } +/** + * Apply player level flags + */ +template <class LF> +static void apply_lflags(LF const &lflags) +{ + for (int i = 1; i <= p_ptr->lev; i++) + { + apply_flags(lflags[i].oflags, lflags[i].pval, 0, 0, 0, 0); + } +} + /** * Are barehand fighter's hands empty? */ -static bool_ monk_empty_hands(void) +static bool_ monk_empty_hands() { int i; object_type *o_ptr; @@ -2768,23 +2647,28 @@ static bool_ monk_empty_hands(void) */ void calc_bonuses(bool_ silent) { + auto const &s_descriptors = game->edit_data.s_descriptors; + auto const &r_info = game->edit_data.r_info; + auto &s_info = game->s_info; + auto const &a_info = game->edit_data.a_info; + static bool_ monk_notify_aux = FALSE; int i, j, hold; int old_speed; - u32b old_telepathy; int old_see_inv; int old_dis_ac; int old_dis_to_a; object_type *o_ptr; - u32b f1, f2, f3, f4, f5, esp; bool_ monk_armour_aux; + /* Save the old computed_flags */ + auto old_computed_flags = p_ptr->computed_flags; + /* Save the old speed */ old_speed = p_ptr->pspeed; /* Save the old vision stuff */ - old_telepathy = p_ptr->telepathy; old_see_inv = p_ptr->see_inv; /* Save the old armor class */ @@ -2852,7 +2736,7 @@ void calc_bonuses(bool_ silent) p_ptr->climb = FALSE; p_ptr->ffall = FALSE; p_ptr->hold_life = FALSE; - p_ptr->telepathy = 0; + p_ptr->computed_flags = object_flag_set(); p_ptr->lite = FALSE; p_ptr->sustain_str = FALSE; p_ptr->sustain_int = FALSE; @@ -2906,10 +2790,6 @@ void calc_bonuses(bool_ silent) /* Base infravision (purely racial) */ p_ptr->see_infra = rp_ptr->infra + rmp_ptr->infra; - - /* Base skill -- disarming */ - p_ptr->skill_dis = 0; - /* Base skill -- magic devices */ p_ptr->skill_dev = 0; @@ -2919,12 +2799,6 @@ void calc_bonuses(bool_ silent) /* Base skill -- stealth */ p_ptr->skill_stl = 0; - /* Base skill -- searching ability */ - p_ptr->skill_srh = 0; - - /* Base skill -- searching frequency */ - p_ptr->skill_fos = 0; - /* Base skill -- combat (normal) */ p_ptr->skill_thn = 0; @@ -2939,18 +2813,15 @@ void calc_bonuses(bool_ silent) p_ptr->skill_dig = 0; /* Xtra player flags */ - p_ptr->xtra_f1 = 0; - p_ptr->xtra_f2 = 0; - p_ptr->xtra_f3 = 0; - p_ptr->xtra_f4 = 0; - p_ptr->xtra_f5 = 0; - p_ptr->xtra_esp = 0; + p_ptr->xtra_flags = object_flag_set(); /* Hide the skills that should auto hide */ - for (i = 0; i < max_s_idx; i++) + for (std::size_t i = 0; i < s_descriptors.size(); i++) { - if (s_info[i].flags1 & SKF1_AUTO_HIDE) - s_info[i].hidden = TRUE; + if (s_descriptors[i].flags & SKF_AUTO_HIDE) + { + s_info[i].hidden = true; + } } /* Base Luck */ @@ -2975,10 +2846,8 @@ void calc_bonuses(bool_ silent) /* The powers gived by the wielded monster */ calc_wield_monster(); - for (i = 1; i <= p_ptr->lev; i++) - { - apply_flags(cp_ptr->oflags1[i], cp_ptr->oflags2[i], cp_ptr->oflags3[i], cp_ptr->oflags4[i], cp_ptr->oflags5[i], cp_ptr->oesp[i], cp_ptr->opval[i], 0, 0, 0, 0); - } + /* Apply all the level-dependent class flags */ + apply_lflags(cp_ptr->lflags); if (p_ptr->melee_style == SKILL_HAND) { @@ -3006,7 +2875,10 @@ void calc_bonuses(bool_ silent) if (get_skill(SKILL_DAEMON) > 20) p_ptr->resist_conf = TRUE; if (get_skill(SKILL_DAEMON) > 30) p_ptr->resist_fear = TRUE; - if ( get_skill(SKILL_MINDCRAFT) >= 40 ) p_ptr->telepathy = ESP_ALL; + if ( get_skill(SKILL_MINDCRAFT) >= 40 ) + { + p_ptr->computed_flags |= ESP_ALL; + } if (p_ptr->astral) { @@ -3016,26 +2888,23 @@ void calc_bonuses(bool_ silent) /***** Races ****/ if ((!p_ptr->mimic_form) && (!p_ptr->body_monster)) { - int i; + /* Apply level-dependent flags from race/sub-race */ + apply_lflags(rp_ptr->lflags); + apply_lflags(rmp_ptr->lflags); - for (i = 1; i <= p_ptr->lev; i++) - { - apply_flags(rp_ptr->oflags1[i], rp_ptr->oflags2[i], rp_ptr->oflags3[i], rp_ptr->oflags4[i], rp_ptr->oflags5[i], rp_ptr->oesp[i], rp_ptr->opval[i], 0, 0, 0, 0); - apply_flags(rmp_ptr->oflags1[i], rmp_ptr->oflags2[i], rmp_ptr->oflags3[i], rmp_ptr->oflags4[i], rmp_ptr->oflags5[i], rmp_ptr->oesp[i], rmp_ptr->opval[i], 0, 0, 0, 0); - } - - if (race_flags1_p(PR1_HURT_LITE)) + /* Is the player's race hurt by light? */ + if (race_flags_p(PR_HURT_LITE)) p_ptr->sensible_lite = TRUE; } /* The extra flags */ - apply_flags(p_ptr->xtra_f1, p_ptr->xtra_f2, p_ptr->xtra_f3, p_ptr->xtra_f4, p_ptr->xtra_f5, p_ptr->xtra_esp, 0, 0, 0, 0, 0); + apply_flags(p_ptr->xtra_flags, 0, 0, 0, 0, 0); /* Apply the racial modifiers */ for (i = 0; i < 6; i++) { /* Modify the stats for "race" */ - p_ptr->stat_add[i] += (rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]); + p_ptr->stat_add[i] += (rp_ptr->ps.adj[i] + rmp_ptr->ps.adj[i] + cp_ptr->ps.adj[i]); } @@ -3049,7 +2918,7 @@ void calc_bonuses(bool_ silent) /* Extract the item flags */ object_flags_no_set = TRUE; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto flags = object_flags(o_ptr); object_flags_no_set = FALSE; /* MEGA ugly hack -- set spacetime distortion resistance */ @@ -3061,10 +2930,10 @@ void calc_bonuses(bool_ silent) /* Hack - don't give the Black Breath when merely inspecting a weapon */ if (silent) { - f4 &= ~TR4_BLACK_BREATH; + flags &= ~TR_BLACK_BREATH; } - apply_flags(f1, f2, f3, f4, f5, esp, o_ptr->pval, o_ptr->tval, o_ptr->to_h, o_ptr->to_d, o_ptr->to_a); + apply_flags(flags, o_ptr->pval, o_ptr->tval, o_ptr->to_h, o_ptr->to_d, o_ptr->to_a); if (o_ptr->name1) { @@ -3142,7 +3011,7 @@ void calc_bonuses(bool_ silent) /* Hack -- aura of fire also provides light */ if (p_ptr->sh_fire) p_ptr->lite = TRUE; - if (race_flags1_p(PR1_AC_LEVEL)) + if (race_flags_p(PR_AC_LEVEL)) { p_ptr->to_a += 20 + (p_ptr->lev / 5); p_ptr->dis_to_a += 20 + (p_ptr->lev / 5); @@ -3247,12 +3116,9 @@ void calc_bonuses(bool_ silent) p_ptr->to_a += tactic_info[(byte)p_ptr->tactic].to_ac; p_ptr->skill_stl += tactic_info[(byte)p_ptr->tactic].to_stealth; - p_ptr->skill_dis += tactic_info[(byte)p_ptr->tactic].to_disarm; p_ptr->skill_sav += tactic_info[(byte)p_ptr->tactic].to_saving; p_ptr->pspeed += move_info[(byte)p_ptr->movement].to_speed; - p_ptr->skill_srh += move_info[(byte)p_ptr->movement].to_search; - p_ptr->skill_fos += move_info[(byte)p_ptr->movement].to_percep; p_ptr->skill_stl += move_info[(byte)p_ptr->movement].to_stealth; /* Apply temporary "stun" */ @@ -3282,7 +3148,7 @@ void calc_bonuses(bool_ silent) /* Temporary precognition */ if (p_ptr->tim_precognition > 0) { - apply_flags(0, 0, 0, TR4_PRECOGNITION, 0, 0, 0, 0, 0, 0, 0); + apply_flags(TR_PRECOGNITION, 0, 0, 0, 0, 0); } /* Breath */ @@ -3391,13 +3257,6 @@ void calc_bonuses(bool_ silent) p_ptr->fly = TRUE; } - /* Oppose Light & Dark */ - if (p_ptr->oppose_ld) - { - p_ptr->resist_lite = TRUE; - p_ptr->resist_dark = TRUE; - } - /* Oppose Chaos & Confusion */ if (p_ptr->oppose_cc) { @@ -3405,19 +3264,6 @@ void calc_bonuses(bool_ silent) p_ptr->resist_conf = TRUE; } - /* Oppose Sound & Shards */ - if (p_ptr->oppose_ss) - { - p_ptr->resist_sound = TRUE; - p_ptr->resist_shard = TRUE; - } - - /* Oppose Nexus */ - if (p_ptr->oppose_nex) - { - p_ptr->resist_nexus = TRUE; - } - /* Temporary "fast" */ if (p_ptr->fast) { @@ -3438,7 +3284,7 @@ void calc_bonuses(bool_ silent) if (p_ptr->tim_esp) { - p_ptr->telepathy |= ESP_ALL; + p_ptr->computed_flags |= ESP_ALL; } /* Temporary see invisible */ @@ -3479,9 +3325,12 @@ void calc_bonuses(bool_ silent) /* Hack -- Telepathy Change */ - if (p_ptr->telepathy != old_telepathy) { - p_ptr->update |= (PU_MONSTERS); + auto const &esp_mask = object_flags_esp(); + if ((p_ptr->computed_flags & esp_mask) != (old_computed_flags & esp_mask)) + { + p_ptr->update |= (PU_MONSTERS); + } } /* Hack -- See Invis Change */ @@ -3503,9 +3352,6 @@ void calc_bonuses(bool_ silent) /* Bloating slows the player down (a little) */ if (p_ptr->food >= PY_FOOD_MAX) p_ptr->pspeed -= 10; - /* Searching slows the player down */ - if (p_ptr->searching) p_ptr->pspeed -= 10; - /* Display the speed (if needed) */ if (p_ptr->pspeed != old_speed) p_ptr->redraw |= (PR_FRAME); @@ -3610,13 +3456,13 @@ void calc_bonuses(bool_ silent) if (p_ptr->num_fire < 1) p_ptr->num_fire = 1; } - if (race_flags1_p(PR1_XTRA_MIGHT_BOW) && p_ptr->tval_ammo == TV_ARROW) + if (race_flags_p(PR_XTRA_MIGHT_BOW) && p_ptr->tval_ammo == TV_ARROW) p_ptr->xtra_might += 1; - if (race_flags1_p(PR1_XTRA_MIGHT_SLING) && p_ptr->tval_ammo == TV_SHOT) + if (race_flags_p(PR_XTRA_MIGHT_SLING) && p_ptr->tval_ammo == TV_SHOT) p_ptr->xtra_might += 1; - if (race_flags1_p(PR1_XTRA_MIGHT_XBOW) && p_ptr->tval_ammo == TV_BOLT) + if (race_flags_p(PR_XTRA_MIGHT_XBOW) && p_ptr->tval_ammo == TV_BOLT) p_ptr->xtra_might += 1; /* Examine the "current tool" */ @@ -3823,10 +3669,8 @@ void calc_bonuses(bool_ silent) /* 2handed weapon and shield = less damage */ if (p_ptr->inventory[INVEN_WIELD + i].k_idx && p_ptr->inventory[INVEN_ARM + i].k_idx) { - /* Extract the item flags */ - object_flags(&p_ptr->inventory[INVEN_WIELD + i], &f1, &f2, &f3, &f4, &f5, &esp); - - if (f4 & TR4_COULD2H) + auto const flags = object_flags(&p_ptr->inventory[INVEN_WIELD + i]); + if (flags & TR_COULD2H) { int tmp; @@ -3900,22 +3744,12 @@ void calc_bonuses(bool_ silent) /* Affect Skill -- stealth (bonus one) */ p_ptr->skill_stl += 1; - /* Affect Skill -- disarming (DEX and INT) */ - p_ptr->skill_dis += adj_dex_dis[p_ptr->stat_ind[A_DEX]]; - p_ptr->skill_dis += adj_int_dis[p_ptr->stat_ind[A_INT]]; - - /* Affect Skill -- magic devices (INT) */ - p_ptr->skill_dev += get_skill_scale(SKILL_DEVICE, 20); - /* Affect Skill -- saving throw (WIS) */ p_ptr->skill_sav += adj_wis_sav[p_ptr->stat_ind[A_WIS]]; /* Affect Skill -- digging (STR) */ p_ptr->skill_dig += adj_str_dig[p_ptr->stat_ind[A_STR]]; - /* Affect Skill -- disarming (skill) */ - p_ptr->skill_dis += (get_skill_scale(SKILL_DISARMING, 75)); - /* Affect Skill -- magic devices (skill) */ p_ptr->skill_dev += (get_skill_scale(SKILL_DEVICE, 150)); @@ -3925,12 +3759,6 @@ void calc_bonuses(bool_ silent) /* Affect Skill -- stealth (skill) */ p_ptr->skill_stl += (get_skill_scale(SKILL_STEALTH, 25)); - /* Affect Skill -- search ability (Sneakiness skill) */ - p_ptr->skill_srh += (get_skill_scale(SKILL_SNEAK, 35)); - - /* Affect Skill -- search frequency (Sneakiness skill) */ - p_ptr->skill_fos += (get_skill_scale(SKILL_SNEAK, 25)); - /* Affect Skill -- combat (Combat skill + mastery) */ p_ptr->skill_thn += (50 * (((7 * get_skill(p_ptr->melee_style)) + (3 * get_skill(SKILL_COMBAT))) / 10) / 10); @@ -4065,7 +3893,7 @@ void calc_bonuses(bool_ silent) /* * Handle "p_ptr->notice" */ -void notice_stuff(void) +void notice_stuff() { /* Notice stuff */ if (!p_ptr->notice) return; @@ -4090,7 +3918,7 @@ void notice_stuff(void) /* * Handle "p_ptr->update" */ -void update_stuff(void) +void update_stuff() { /* Update stuff */ if (!p_ptr->update) return; @@ -4197,7 +4025,7 @@ void update_stuff(void) /* * Handle "p_ptr->redraw" */ -void redraw_stuff(void) +void redraw_stuff() { /* Redraw stuff */ if (!p_ptr->redraw) return; @@ -4238,7 +4066,7 @@ void redraw_stuff(void) /* * Handle "p_ptr->window" */ -void window_stuff(void) +void window_stuff() { int j; @@ -4249,7 +4077,7 @@ void window_stuff(void) if (!p_ptr->window) return; /* Scan windows */ - for (j = 0; j < 8; j++) + for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Save usable flags */ if (angband_term[j]) mask |= window_flag[j]; @@ -4323,7 +4151,7 @@ void window_stuff(void) /* * Handle "p_ptr->update" and "p_ptr->redraw" and "p_ptr->window" */ -void handle_stuff(void) +void handle_stuff() { /* Update stuff */ if (p_ptr->update) update_stuff(); @@ -4336,7 +4164,7 @@ void handle_stuff(void) } -bool_ monk_heavy_armor(void) +bool_ monk_heavy_armor() { u16b monk_arm_wgt = 0; @@ -4355,15 +4183,17 @@ bool_ monk_heavy_armor(void) static int get_artifact_idx(int level) { + auto const &a_info = game->edit_data.a_info; + int count = 0, i; while (count < 1000) { - artifact_type *a_ptr; count++; - i = randint(max_a_idx - 1); - a_ptr = &a_info[i]; + i = rand_int(a_info.size()); + + auto a_ptr = &a_info[i]; if (!a_ptr->tval) continue; /* It is found/lost */ @@ -4373,7 +4203,7 @@ static int get_artifact_idx(int level) if (a_ptr->level > level) continue; /* Avoid granting SPECIAL_GENE artifacts */ - if (a_ptr->flags4 & TR4_SPECIAL_GENE) continue; + if (a_ptr->flags & TR_SPECIAL_GENE) continue; return i; } @@ -4386,6 +4216,9 @@ static int get_artifact_idx(int level) /* Chose a fate */ void gain_fate(byte fate) { + auto const &k_info = game->edit_data.k_info; + auto &alloc = game->alloc; + int i; int level; @@ -4456,7 +4289,6 @@ void gain_fate(byte fate) { while (TRUE) { - object_kind *k_ptr; obj_theme theme; /* No themes */ @@ -4475,11 +4307,11 @@ void gain_fate(byte fate) fates[i].o_idx = get_obj_num(max_dlv[dungeon_type] + randint(10)); /* Invalidate the cached allocation table */ - alloc_kind_table_valid = FALSE; + alloc.kind_table_valid = false; - k_ptr = &k_info[fates[i].o_idx]; + auto k_ptr = &k_info[fates[i].o_idx]; - if (!(k_ptr->flags3 & TR3_INSTA_ART) && !(k_ptr->flags3 & TR3_NORM_ART)) break; + if (!(k_ptr->flags & TR_INSTA_ART) && !(k_ptr->flags & TR_NORM_ART)) break; } level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20); fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level; @@ -4529,18 +4361,21 @@ void gain_fate(byte fate) } } -void fate_desc(char *desc, int fate) +std::string fate_desc(int fate) { - char buf[120]; + auto const &a_info = game->edit_data.a_info; + + fmt::MemoryWriter w; if (fates[fate].serious) { - strcpy(desc, "You are fated to "); + w.write("You are fated to "); } else { - strcpy(desc, "You may "); + w.write("You may "); } + switch (fates[fate].fate) { case FATE_FIND_O: @@ -4552,15 +4387,14 @@ void fate_desc(char *desc, int fate) object_prep(o_ptr, fates[fate].o_idx); object_desc_store(o_name, o_ptr, 1, 0); - sprintf(buf, "find %s on level %d.", o_name, fates[fate].level); - strcat(desc, buf); + w.write("find {} on level {}.", o_name, fates[fate].level); break; } case FATE_FIND_A: { object_type *q_ptr, forge; char o_name[80]; - artifact_type *a_ptr = &a_info[fates[fate].a_idx]; + auto a_ptr = &a_info[fates[fate].a_idx]; int I_kind; /* Failed artefact allocation XXX XXX XXX */ @@ -4598,61 +4432,62 @@ void fate_desc(char *desc, int fate) q_ptr->weight = a_ptr->weight; /* Hack -- acquire "cursed" flag */ - if (a_ptr->flags3 & (TR3_CURSED)) q_ptr->ident |= (IDENT_CURSED); + if (a_ptr->flags & (TR_CURSED)) q_ptr->ident |= (IDENT_CURSED); random_artifact_resistance(q_ptr); object_desc_store(o_name, q_ptr, 1, 0); } - sprintf(buf, "find %s on level %d.", o_name, fates[fate].level); - strcat(desc, buf); + w.write("find {} on level {}.", o_name, fates[fate].level); break; } case FATE_FIND_R: { char m_name[80]; - monster_race_desc(m_name, fates[fate].r_idx, 0); - sprintf(buf, "meet %s on level %d.", m_name, fates[fate].level); - strcat(desc, buf); + + w.write("meet {} on level {}.", m_name, fates[fate].level); break; } case FATE_DIE: { - sprintf(buf, "die on level %d.", fates[fate].level); - strcat(desc, buf); + w.write("die on level {}.", fates[fate].level); break; } case FATE_NO_DIE_MORTAL: { - strcat(desc, "never to die by the hand of a mortal being."); + w.write("never to die by the hand of a mortal being."); break; } } + + return w.str(); } -void dump_fates(FILE *outfile) +std::string dump_fates() { - int i; - char buf[120]; bool_ pending = FALSE; - if (!outfile) return; + fmt::MemoryWriter w; - for (i = 0; i < MAX_FATES; i++) + for (int i = 0; i < MAX_FATES; i++) { if ((fates[i].fate) && (fates[i].know)) { - fate_desc(buf, i); - fprintf(outfile, "%s\n", buf); + w.write("{}\n", fate_desc(i)); } - if ((fates[i].fate) && !(fates[i].know)) pending = TRUE; + + // Pending gets set if there's at least one fate we don't know + pending |= ((fates[i].fate) && !(fates[i].know)); } + if (pending) { - fprintf(outfile, "You do not know all of your fate.\n"); + w.write("You do not know all of your fate.\n"); } + + return w.str(); } /* @@ -4673,12 +4508,7 @@ int luck(int min, int max) return (luck + min); } -bool race_flags1_p(u32b flags1_mask) -{ - return (rp_ptr->flags1 | rmp_ptr->flags1 | cp_ptr->flags1 | spp_ptr->flags1) & flags1_mask; -} - -bool race_flags2_p(u32b flags2_mask) +bool race_flags_p(player_race_flag_set const &flags_mask) { - return (rp_ptr->flags2 | rmp_ptr->flags2 | cp_ptr->flags2 | spp_ptr->flags2) & flags2_mask; + return bool((rp_ptr->flags | rmp_ptr->flags | cp_ptr->flags | spp_ptr->flags) & flags_mask); } diff --git a/src/xtra1.hpp b/src/xtra1.hpp index df2592ac..4fde1619 100644 --- a/src/xtra1.hpp +++ b/src/xtra1.hpp @@ -1,24 +1,27 @@ #pragma once #include "h-basic.h" +#include "object_flag_set.hpp" +#include "player_race_flag_set.hpp" -extern void fix_message(void); -extern void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a); -extern int luck(int min, int max); -extern int weight_limit(void); +#include <string> + +void fix_message(); +void apply_flags(object_flag_set const &f, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a); +int luck(int min, int max); +int weight_limit(); extern bool_ calc_powers_silent; -extern void cnv_stat(int i, char *out_val); -extern s16b modify_stat_value(int value, int amount); -extern void calc_hitpoints(void); -extern void notice_stuff(void); -extern void update_stuff(void); -extern void redraw_stuff(void); -extern void window_stuff(void); -extern void handle_stuff(void); -extern bool_ monk_heavy_armor(void); -extern void calc_bonuses(bool_ silent); -extern void gain_fate(byte fate); -extern void fate_desc(char *desc, int fate); -extern void dump_fates(FILE *OutFile); -extern bool race_flags1_p(u32b flags1_mask); -extern bool race_flags2_p(u32b flags2_mask); +void cnv_stat(int i, char *out_val); +s16b modify_stat_value(int value, int amount); +void calc_hitpoints(); +void notice_stuff(); +void update_stuff(); +void redraw_stuff(); +void window_stuff(); +void handle_stuff(); +bool_ monk_heavy_armor(); +void calc_bonuses(bool_ silent); +void gain_fate(byte fate); +std::string fate_desc(int fate); +std::string dump_fates(); +bool race_flags_p(player_race_flag_set const &flags_mask); diff --git a/src/xtra2.cc b/src/xtra2.cc index 096f8966..d8b87f51 100644 --- a/src/xtra2.cc +++ b/src/xtra2.cc @@ -14,8 +14,10 @@ #include "corrupt.hpp" #include "dungeon_info_type.hpp" #include "ego_item_type.hpp" +#include "feature_flag.hpp" #include "feature_type.hpp" #include "files.hpp" +#include "game.hpp" #include "gods.hpp" #include "hook_player_level_in.hpp" #include "hook_monster_death_in.hpp" @@ -27,17 +29,20 @@ #include "monster3.hpp" #include "monster_ego.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" #include "monster_type.hpp" #include "notes.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.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 "quark.hpp" +#include "point.hpp" #include "randart.hpp" #include "skill_type.hpp" #include "skills.hpp" @@ -46,7 +51,6 @@ #include "stats.hpp" #include "store_info_type.hpp" #include "tables.hpp" -#include "trap_type.hpp" #include "util.hpp" #include "util.h" #include "variable.h" @@ -57,14 +61,16 @@ #include "xtra1.hpp" #include "z-rand.hpp" -#include <type_traits> +#include <boost/algorithm/string/predicate.hpp> #include <cassert> +#include <fmt/format.h> +#include <type_traits> + -#include <boost/algorithm/string/predicate.hpp> using boost::algorithm::iequals; -static void corrupt_corrupted(void); +static void corrupt_corrupted(); /* * Set "p_ptr->parasite" and "p_ptr->parasite_r_idx" @@ -129,7 +135,7 @@ bool_ set_parasite(int v, int r) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -182,8 +188,7 @@ static bool_ set_simple_field( return (FALSE); /* Disturb */ - if (disturb_state) - disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -398,17 +403,6 @@ bool_ set_strike(int v) } /* - * Set "p_ptr->oppose_ld" - */ -bool_ set_oppose_ld(int v) -{ - return set_simple_field( - &p_ptr->oppose_ld, v, - TERM_WHITE, "You feel protected against light's fluctuation.", - TERM_WHITE, "You are no longer protected against light's fluctuation."); -} - -/* * Set "p_ptr->oppose_cc" */ bool_ set_oppose_cc(int v) @@ -420,33 +414,13 @@ bool_ set_oppose_cc(int v) } /* - * Set "p_ptr->oppose_ss" - */ -bool_ set_oppose_ss(int v) -{ - return set_simple_field( - &p_ptr->oppose_ss, v, - TERM_WHITE, "You feel protected against the ravages of sound and shards.", - TERM_WHITE, "You are no longer protected against the ravages of sound and shards."); -} - -/* - * Set "p_ptr->oppose_nex" - */ -bool_ set_oppose_nex(int v) -{ - return set_simple_field( - &p_ptr->oppose_nex, v, - TERM_WHITE, "You feel protected against the strange forces of nexus.", - TERM_WHITE, "You are no longer protected against the strange forces of nexus."); -} - -/* * Set "p_ptr->tim_mimic", and "p_ptr->mimic_form", * notice observable changes */ bool_ set_mimic(int v, int p, int level) { + auto &s_info = game->s_info; + bool_ notice = FALSE; /* Hack -- Force good values */ @@ -473,7 +447,7 @@ bool_ set_mimic(int v, int p, int level) notice = TRUE; if (p == resolve_mimic_name("Bear")) { - s_info[SKILL_BEAR].hidden = TRUE; + s_info[SKILL_BEAR].hidden = true; select_default_melee(); } p = 0; @@ -488,7 +462,7 @@ bool_ set_mimic(int v, int p, int level) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Redraw title */ p_ptr->redraw |= (PR_FRAME); @@ -785,7 +759,7 @@ bool_ set_fast(int v, int p) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -963,45 +937,6 @@ bool_ set_protevil(int v) } /* - * Set "p_ptr->protgood", notice observable changes - */ -bool_ set_protgood(int v) -{ - bool_ notice = set_simple_field( - &p_ptr->protgood, v, - TERM_WHITE, "You feel safe from good!", - TERM_WHITE, "You no longer feel safe from good."); - - if (notice) - { - /* Handle stuff */ - handle_stuff(); - } - - /* Result */ - return notice; -} - -/* - * Set "p_ptr->protundead", notice observable changes - */ -bool_ set_protundead(int v) -{ - bool_ notice = set_simple_field( - &p_ptr->protundead, v, - TERM_WHITE, "You feel safe from undead!", - TERM_WHITE, "You no longer feel safe from undead."); - - if (notice) { - /* Handle stuff */ - handle_stuff(); - } - - /* Result */ - return notice; -} - -/* * Set "p_ptr->set_shadow", notice observable changes */ bool_ set_shadow(int v) @@ -1127,7 +1062,7 @@ bool_ set_tim_thunder(int v, int p1, int p2) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -1334,7 +1269,7 @@ bool_ set_tim_regen(int v, int p) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Handle stuff */ handle_stuff(); @@ -1358,7 +1293,7 @@ bool_ set_stun(int v) /* Hack -- Force good values */ v = (v > 10000) ? 10000 : (v < 0) ? 0 : v; - if (race_flags1_p(PR1_NO_STUN)) v = 0; + if (race_flags_p(PR_NO_STUN)) v = 0; /* Knocked out */ if (p_ptr->stun > 100) @@ -1438,25 +1373,25 @@ bool_ set_stun(int v) { if (!p_ptr->sustain_int) { - (void) do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); } if (!p_ptr->sustain_wis) { - (void) do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); } } else if (randint(2) == 1) { if (!p_ptr->sustain_int) { - (void) do_dec_stat(A_INT, STAT_DEC_NORMAL); + do_dec_stat(A_INT, STAT_DEC_NORMAL); } } else { if (!p_ptr->sustain_wis) { - (void) do_dec_stat(A_WIS, STAT_DEC_NORMAL); + do_dec_stat(A_WIS, STAT_DEC_NORMAL); } } } @@ -1474,7 +1409,7 @@ bool_ set_stun(int v) /* None */ case 0: msg_print("You are no longer stunned."); - if (disturb_state) disturb(0); + disturb_on_state(); break; } @@ -1489,7 +1424,7 @@ bool_ set_stun(int v) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -1519,7 +1454,7 @@ bool_ set_cut(int v) /* Hack -- Force good values */ v = (v > 10000) ? 10000 : (v < 0) ? 0 : v; - if (race_flags1_p(PR1_NO_CUT)) v = 0; + if (race_flags_p(PR_NO_CUT)) v = 0; /* Mortal wound */ if (p_ptr->cut > 1000) @@ -1682,7 +1617,7 @@ bool_ set_cut(int v) /* None */ case 0: msg_print("You are no longer bleeding."); - if (disturb_state) disturb(0); + disturb_on_state(); break; } @@ -1697,7 +1632,7 @@ bool_ set_cut(int v) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -1911,7 +1846,7 @@ bool_ set_food(int v) if (!notice) return (FALSE); /* Disturb */ - if (disturb_state) disturb(0); + disturb_on_state(); /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); @@ -1930,7 +1865,7 @@ bool_ set_food(int v) /* * Advance experience levels and print experience */ -void check_experience(void) +void check_experience() { int gained = 0; bool_ level_corruption = FALSE; @@ -1982,8 +1917,8 @@ void check_experience(void) /* Gain levels while possible */ - while ((p_ptr->lev < PY_MAX_LEVEL) && (p_ptr->lev < max_plev) && - (p_ptr->exp >= (player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L))) + while ((p_ptr->lev < PY_MAX_LEVEL) && + (p_ptr->exp >= (player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L))) { /* Gain a level */ p_ptr->lev++; @@ -1994,16 +1929,13 @@ void check_experience(void) if (p_ptr->lev > p_ptr->max_plv) { p_ptr->max_plv = p_ptr->lev; - if ((race_flags1_p(PR1_CORRUPT)) && + if ((race_flags_p(PR_CORRUPT)) && (randint(3) == 1)) { level_corruption = TRUE; } } - /* Sound */ - sound(SOUND_LEVEL); - /* Message */ cmsg_format(TERM_L_GREEN, "Welcome to level %d.", p_ptr->lev); @@ -2067,7 +1999,7 @@ void check_experience_obj(object_type *o_ptr) /* Gain levels while possible */ while ((o_ptr->elevel < PY_MAX_LEVEL) && - (o_ptr->exp >= (player_exp[o_ptr->elevel - 1] * 5 / 2))) + (o_ptr->exp >= calc_object_need_exp(o_ptr))) { char buf[100]; @@ -2089,7 +2021,7 @@ void check_experience_obj(object_type *o_ptr) */ void gain_exp(s32b amount) { - if ((p_ptr->max_exp > 0) && (race_flags1_p(PR1_CORRUPT))) + if ((p_ptr->max_exp > 0) && (race_flags_p(PR_CORRUPT))) { if ((randint(p_ptr->max_exp) < amount) || (randint(12000000) < amount)) { @@ -2181,13 +2113,13 @@ void place_corpse(monster_type *m_ptr) auto const r_ptr = m_ptr->race(); /* It has a physical form */ - if (r_ptr->flags9 & RF9_DROP_CORPSE) + if (r_ptr->flags & RF_DROP_CORPSE) { /* Wipe the object */ object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_CORPSE)); /* Unique corpses are unique */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { object_aware(i_ptr); i_ptr->name1 = 201; @@ -2217,13 +2149,13 @@ void place_corpse(monster_type *m_ptr) } /* The creature is an animated skeleton. */ - if (!(r_ptr->flags9 & RF9_DROP_CORPSE) && (r_ptr->flags9 & RF9_DROP_SKELETON)) + if (!(r_ptr->flags & RF_DROP_CORPSE) && (r_ptr->flags & RF_DROP_SKELETON)) { /* Wipe the object */ object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_SKELETON)); /* Unique corpses are unique */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { object_aware(i_ptr); i_ptr->name1 = 201; @@ -2469,15 +2401,14 @@ static void monster_death_gods(int m_idx, monster_type *m_ptr) */ void monster_death(int m_idx) { - int dump_item = 0; - int dump_gold = 0; + auto const &d_info = game->edit_data.d_info; + auto const &f_info = game->edit_data.f_info; + auto &a_info = game->edit_data.a_info; monster_type *m_ptr = &m_list[m_idx]; auto const r_ptr = m_ptr->race(); - bool_ visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE))); - bool_ create_stairs = FALSE; int force_coin = get_coin_type(r_ptr); @@ -2524,7 +2455,7 @@ void monster_death(int m_idx) } /* If the doppleganger die, the variable must be set accordingly */ - if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = 0; + if (r_ptr->flags & RF_DOPPLEGANGER) doppleganger = 0; /* Need copy of object list since we're going to mutate it */ auto const object_idxs(m_ptr->hold_o_idxs); @@ -2547,9 +2478,6 @@ void monster_death(int m_idx) /* Delete the object */ delete_object_idx(this_o_idx); - if (q_ptr->tval == TV_GOLD) dump_gold++; - else dump_item++; - /* Drop it */ drop_near(q_ptr, -1, y, x); } @@ -2571,31 +2499,41 @@ void monster_death(int m_idx) /* Mega-Hack -- Name the sword */ - q_ptr->art_name = quark_add("'Stormbringer'"); + q_ptr->artifact_name = "'Stormbringer'"; q_ptr->to_h = 16; q_ptr->to_d = 16; q_ptr->ds = 6; q_ptr->dd = 6; q_ptr->pval = 2; - q_ptr->art_flags1 |= ( TR1_VAMPIRIC | TR1_STR | TR1_CON | TR1_BLOWS ); - q_ptr->art_flags2 |= ( TR2_FREE_ACT | TR2_HOLD_LIFE | - TR2_RES_NEXUS | TR2_RES_CHAOS | TR2_RES_NETHER | - TR2_RES_CONF ); /* No longer resist_disen */ - q_ptr->art_flags3 |= ( TR3_IGNORE_ACID | TR3_IGNORE_ELEC | - TR3_IGNORE_FIRE | TR3_IGNORE_COLD); - /* Just to be sure */ - - q_ptr->art_flags3 |= TR3_NO_TELE; /* How's that for a downside? */ + q_ptr->art_flags |= + TR_VAMPIRIC | + TR_STR | + TR_CON | + TR_BLOWS | + TR_FREE_ACT | + TR_HOLD_LIFE | + TR_RES_NEXUS | + TR_RES_CHAOS | + TR_RES_NETHER | + TR_RES_CONF | + TR_IGNORE_ACID | + TR_IGNORE_ELEC | + TR_IGNORE_FIRE | + TR_IGNORE_COLD | + TR_NO_TELE | + TR_CURSED | + TR_HEAVY_CURSE; - /* For game balance... */ - q_ptr->art_flags3 |= (TR3_CURSED | TR3_HEAVY_CURSE); q_ptr->ident |= IDENT_CURSED; - if (randint(2) == 1) - q_ptr->art_flags3 |= (TR3_DRAIN_EXP); + { + q_ptr->art_flags |= TR_DRAIN_EXP; + } else - q_ptr->art_flags3 |= (TR3_AGGRAVATE); + { + q_ptr->art_flags |= TR_AGGRAVATE; + } q_ptr->found = OBJ_FOUND_MONSTER; q_ptr->found_aux1 = m_ptr->r_idx; @@ -2650,7 +2588,7 @@ void monster_death(int m_idx) else if (strstr(r_ptr->name, "Unmaker")) { int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL; - (void)project(m_idx, 6, y, x, 100, GF_CHAOS, flg); + project(m_idx, 6, y, x, 100, GF_CHAOS, flg); } /* Pink horrors are replaced with 2 Blue horrors */ else if (strstr(r_ptr->name, "ink horror")) @@ -2678,7 +2616,7 @@ void monster_death(int m_idx) } /* Mega-Hack -- drop "winner" treasures */ - else if (r_ptr->flags1 & (RF1_DROP_CHOSEN)) + else if (r_ptr->flags & RF_DROP_CHOSEN) { if (strstr(r_ptr->name, "Morgoth, Lord of Darkness")) { @@ -2740,7 +2678,7 @@ void monster_death(int m_idx) /* Drop it in the dungeon */ drop_near(q_ptr, -1, y, x); } - else if (r_ptr->flags7 & RF7_NAZGUL) + else if (r_ptr->flags & RF_NAZGUL) { /* Get local object */ q_ptr = &forge; @@ -2757,7 +2695,7 @@ void monster_death(int m_idx) create_artifact(q_ptr, TRUE, FALSE); /* Save the inscription */ - q_ptr->art_name = quark_add(format("of %s", r_ptr->name)); + q_ptr->artifact_name = fmt::format("of {}", r_ptr->name); q_ptr->found = OBJ_FOUND_MONSTER; q_ptr->found_aux1 = m_ptr->r_idx; @@ -2770,46 +2708,14 @@ void monster_death(int m_idx) } else { - byte a_idx = 0; - int chance = 0; - int I_kind = 0; - - if (strstr(r_ptr->name, "Marda, rider of the Gold Laronth")) - { - a_idx = ART_MARDA; - chance = 50; - } - else if (strstr(r_ptr->name, "Saruman of Many Colours")) - { - a_idx = ART_PALANTIR; - chance = 30; - } - else if (strstr(r_ptr->name, "Hagen, son of Alberich")) - { - a_idx = ART_NIMLOTH; - chance = 66; - } - else if (strstr(r_ptr->name, "Durin's Bane")) - { - a_idx = ART_CALRIS; - chance = 60; - } - else if (strstr(r_ptr->name, "Gothmog, the High Captain of Balrogs")) - { - a_idx = ART_GOTHMOG; - chance = 50; - } - else if (strstr(r_ptr->name, "Eol, the Dark Elf")) - { - a_idx = ART_ANGUIREL; - chance = 50; - } + byte a_idx = r_ptr->artifact_idx; + int chance = r_ptr->artifact_chance; if ((a_idx > 0) && ((randint(99) < chance) || (wizard))) { if (a_info[a_idx].cur_num == 0) { - artifact_type *a_ptr = &a_info[a_idx]; + auto a_ptr = &a_info[a_idx]; /* Get local object */ q_ptr = &forge; @@ -2818,7 +2724,7 @@ void monster_death(int m_idx) object_wipe(q_ptr); /* Acquire the "kind" index */ - I_kind = lookup_kind(a_ptr->tval, a_ptr->sval); + int I_kind = lookup_kind(a_ptr->tval, a_ptr->sval); /* Create the artifact */ object_prep(q_ptr, I_kind); @@ -2837,7 +2743,7 @@ void monster_death(int m_idx) q_ptr->weight = a_ptr->weight; /* Hack -- acquire "cursed" flag */ - if (a_ptr->flags3 & (TR3_CURSED)) q_ptr->ident |= (IDENT_CURSED); + if (a_ptr->flags & TR_CURSED) q_ptr->ident |= (IDENT_CURSED); random_artifact_resistance(q_ptr); @@ -2857,7 +2763,7 @@ void monster_death(int m_idx) } /* Hack - the protected monsters must be advanged */ - else if (r_ptr->flags9 & RF9_WYRM_PROTECT) + else if (r_ptr->flags & RF_WYRM_PROTECT) { int xx = x, yy = y; int attempts = 100; @@ -2995,13 +2901,6 @@ void monster_death(int m_idx) if ((!force_coin) && (magik(10 + get_skill_scale(SKILL_PRESERVATION, 75))) && (!(m_ptr->mflag & MFLAG_NO_DROP))) place_corpse(m_ptr); - /* Take note of any dropped treasure */ - if (visible && (dump_item || dump_gold)) - { - /* Take notes on treasure */ - lore_treasure(m_idx, dump_item, dump_gold); - } - /* Create a magical staircase */ if (create_stairs && (dun_level < d_info[dungeon_type].maxdepth)) { @@ -3009,7 +2908,7 @@ void monster_death(int m_idx) { for (int j = -1; j <= 1; j++) { - if (!(f_info[cave[y + j][x + i].feat].flags1 & FF1_PERMANENT)) + if (!(f_info[cave[y + j][x + i].feat].flags & FF_PERMANENT)) { cave_set_feat(y + j, x + i, d_info[dungeon_type].floor1); } @@ -3082,7 +2981,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) if (health_who == m_idx) p_ptr->redraw |= (PR_FRAME); /* Some mosnters are immune to death */ - if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE; + if (r_ptr->flags & RF_NO_DEATH) return FALSE; /* Wake it up */ m_ptr->csleep = 0; @@ -3106,7 +3005,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) /* Extract monster name */ monster_desc(m_name, m_ptr, 0); - if ((r_ptr->flags7 & RF7_DG_CURSE) && (randint(2) == 1)) + if ((r_ptr->flags & RF_DG_CURSE) && (randint(2) == 1)) { int curses = 2 + randint(5); @@ -3120,7 +3019,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) while (--curses); } - if (r_ptr->flags2 & (RF2_CAN_SPEAK)) + if (r_ptr->flags & RF_CAN_SPEAK) { char line_got[80]; /* Dump a message */ @@ -3129,10 +3028,6 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) msg_format("%^s says: %s", m_name, line_got); } - - /* Make a sound */ - sound(SOUND_KILL); - /* Death by Missile/Spell attack */ if (note) { @@ -3146,10 +3041,10 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* Death by Physical attack -- non-living monster */ - else if ((r_ptr->flags3 & (RF3_DEMON)) || - (r_ptr->flags3 & (RF3_UNDEAD)) || - (r_ptr->flags2 & (RF2_STUPID)) || - (r_ptr->flags3 & (RF3_NONLIVING)) || + else if ((r_ptr->flags & RF_DEMON) || + (r_ptr->flags & RF_UNDEAD) || + (r_ptr->flags & RF_STUPID) || + (r_ptr->flags & RF_NONLIVING) || (strchr("Evg", r_ptr->d_char))) { cmsg_format(TERM_L_RED, "You have destroyed %s.", m_name); @@ -3190,15 +3085,12 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) if (!note) { - object_type *o_ptr; - u32b f1, f2, f3, f4, f5, esp; - /* Access the weapon */ - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD]; + auto const flags = object_flags(o_ptr); /* Can the weapon gain levels ? */ - if ((o_ptr->k_idx) && (f4 & TR4_LEVELS)) + if ((o_ptr->k_idx) && (flags & TR_LEVELS)) { /* Give some experience for the kill */ const int new_exp = ((long)r_ptr->mexp * m_ptr->level) / (div * 2); @@ -3210,7 +3102,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* When the player kills a Unique, it stays dead */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { r_ptr->max_num = 0; } @@ -3219,7 +3111,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) monster_death(m_idx); /* Eru doesn't appreciate good monster death */ - if (r_ptr->flags3 & RF3_GOOD) + if (r_ptr->flags & RF_GOOD) { inc_piety(GOD_ERU, -7 * m_ptr->level); inc_piety(GOD_MANWE, -10 * m_ptr->level); @@ -3231,7 +3123,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* Manwe appreciate evil monster death */ - if (r_ptr->flags3 & RF3_EVIL) + if (r_ptr->flags & RF_EVIL) { int inc = std::max(1, m_ptr->level / 2); @@ -3247,7 +3139,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) if (praying_to(GOD_TULKAS)) { inc_piety(GOD_TULKAS, inc / 2); - if (r_ptr->flags3 & RF3_DEMON) + if (r_ptr->flags & RF_DEMON) { inc_piety(GOD_TULKAS, inc); } @@ -3255,7 +3147,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* Yavanna likes when corruption is destroyed */ - if ((r_ptr->flags3 & RF3_NONLIVING) || (r_ptr->flags3 & RF3_DEMON) || (r_ptr->flags3 & RF3_UNDEAD)) + if ((r_ptr->flags & RF_NONLIVING) || (r_ptr->flags & RF_DEMON) || (r_ptr->flags & RF_UNDEAD)) { int inc = std::max(1, m_ptr->level / 2); inc_piety(GOD_YAVANNA, inc); @@ -3268,12 +3160,12 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) inc_piety(GOD_YAVANNA, -inc); /* Killing animals in her name is a VERY bad idea */ - if (r_ptr->flags3 & RF3_ANIMAL) + if (r_ptr->flags & RF_ANIMAL) inc_piety(GOD_YAVANNA, -(inc * 3)); } /* SHould we absorb its soul? */ - if (p_ptr->absorb_soul && (!(r_ptr->flags3 & RF3_UNDEAD)) && (!(r_ptr->flags3 & RF3_NONLIVING))) + if (p_ptr->absorb_soul && (!(r_ptr->flags & RF_UNDEAD)) && (!(r_ptr->flags & RF_NONLIVING))) { msg_print("You absorb the life of the dying soul."); hp_player(1 + (m_ptr->level / 2) + get_skill_scale(SKILL_NECROMANCY, 40)); @@ -3283,7 +3175,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) * XXX XXX XXX Mega-Hack -- Remove random quest rendered * impossible */ - if (r_ptr->flags1 & (RF1_UNIQUE)) + if (r_ptr->flags & RF_UNIQUE) { int i; @@ -3311,7 +3203,7 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* Make note of unique kills */ - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { char note[80]; @@ -3322,14 +3214,11 @@ bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note) } /* Recall even invisible uniques or winners */ - if (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE))) + if (m_ptr->ml || (r_ptr->flags & RF_UNIQUE)) { /* Count kills this life */ if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++; - /* Count kills in all lives */ - if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++; - /* Hack -- Auto-recall */ monster_race_track(m_ptr->r_idx, m_ptr->ego); } @@ -3366,7 +3255,7 @@ void get_screen_size(int *wid_p, int *hgt_p) * Calculates current boundaries * Called below. */ -static void panel_bounds(void) +static void panel_bounds() { int wid, hgt; @@ -3449,7 +3338,7 @@ bool_ change_panel(int dy, int dx) * * The map is reprinted if necessary, and "TRUE" is returned. */ -void verify_panel(void) +void verify_panel() { int y = p_ptr->py; int x = p_ptr->px; @@ -3488,7 +3377,7 @@ void verify_panel(void) if (max_pcol_min < 0) max_pcol_min = 0; /* An option: center on player */ - if (center_player) + if (options->center_player) { /* Center vertically */ prow_min = y - panel_hgt; @@ -3562,7 +3451,10 @@ void verify_panel(void) panel_col_min = pcol_min; /* Hack -- optional disturb on "panel change" */ - if (disturb_panel && !center_player) disturb(0); + if (options->disturb_panel && !options->center_player) + { + disturb(); + } /* Recalculate the boundaries */ panel_bounds(); @@ -3581,7 +3473,7 @@ void verify_panel(void) /* * Map resizing whenever the main term changes size */ -void resize_map(void) +void resize_map() { /* Only if the dungeon exists */ if (!character_dungeon) return; @@ -3630,7 +3522,7 @@ void resize_map(void) /* * Redraw a term when it is resized */ -void resize_window(void) +void resize_window() { /* Only if the dungeon exists */ if (!character_dungeon) return; @@ -3669,9 +3561,9 @@ static cptr look_mon_desc(int m_idx) /* Determine if the monster is "living" (vs "undead") */ monster_type *m_ptr = &m_list[m_idx]; auto const r_ptr = m_ptr->race(); - if (r_ptr->flags3 & (RF3_UNDEAD)) living = FALSE; - if (r_ptr->flags3 & (RF3_DEMON)) living = FALSE; - if (r_ptr->flags3 & (RF3_NONLIVING)) living = FALSE; + if (r_ptr->flags & RF_UNDEAD) living = FALSE; + if (r_ptr->flags & RF_DEMON) living = FALSE; + if (r_ptr->flags & RF_NONLIVING) living = FALSE; if (strchr("Egv", r_ptr->d_char)) living = FALSE; @@ -3706,81 +3598,6 @@ static cptr look_mon_desc(int m_idx) -/* - * Current "comp" function for ang_sort() - */ -static bool_ (*ang_sort_comp)(vptr u, vptr v, int a, int b) = nullptr; - -/* - * Current "swap" function for ang_sort() - */ -static void (*ang_sort_swap)(vptr u, vptr v, int a, int b) = nullptr; - - - -/* - * Angband sorting algorithm -- quick sort in place - * - * Note that the details of the data we are sorting is hidden, - * and we rely on the "ang_sort_comp()" and "ang_sort_swap()" - * function hooks to interact with the data, which is given as - * two pointers, and which may have any user-defined form. - */ -static void ang_sort_aux(vptr u, vptr v, int p, int q) -{ - int z, a, b; - - /* Done sort */ - if (p >= q) return; - - /* Pivot */ - z = p; - - /* Begin */ - a = p; - b = q; - - /* Partition */ - while (TRUE) - { - /* Slide i2 */ - while (!(*ang_sort_comp)(u, v, b, z)) b--; - - /* Slide i1 */ - while (!(*ang_sort_comp)(u, v, z, a)) a++; - - /* Done partition */ - if (a >= b) break; - - /* Swap */ - (*ang_sort_swap)(u, v, a, b); - - /* Advance */ - a++, b--; - } - - /* Recurse left side */ - ang_sort_aux(u, v, p, b); - - /* Recurse right side */ - ang_sort_aux(u, v, b + 1, q); -} - - -/* - * Angband sorting algorithm -- quick sort in place - * - * Note that the details of the data we are sorting is hidden, - * and we rely on the "ang_sort_comp()" and "ang_sort_swap()" - * function hooks to interact with the data, which is given as - * two pointers, and which may have any user-defined form. - */ -static void ang_sort(vptr u, vptr v, int n) -{ - /* Sort the array */ - ang_sort_aux(u, v, 0, n - 1); -} - /*** Targetting Code ***/ @@ -3802,6 +3619,8 @@ static void ang_sort(vptr u, vptr v, int n) */ static bool target_able(int m_idx) { + auto const &r_info = game->edit_data.r_info; + monster_type *m_ptr = &m_list[m_idx]; /* Monster must be alive */ @@ -3820,7 +3639,7 @@ static bool target_able(int m_idx) if (is_friend(m_ptr) > 0) return (FALSE); /* Honor flag */ - if (r_info[m_ptr->r_idx].flags7 & RF7_NO_TARGET) return (FALSE); + if (r_info[m_ptr->r_idx].flags & RF_NO_TARGET) return (FALSE); /* XXX XXX XXX Hack -- Never target trappers */ /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */ @@ -3837,7 +3656,7 @@ static bool target_able(int m_idx) * * We return TRUE if the target is "okay" and FALSE otherwise. */ -bool_ target_okay(void) +bool_ target_okay() { /* Accept stationary targets */ if (target_who < 0) return (TRUE); @@ -3866,108 +3685,37 @@ bool_ target_okay(void) /* - * Sorting hook -- comp function -- by "distance to player" - * - * We use "u" and "v" to point to arrays of "x" and "y" positions, - * and sort the arrays by double-distance to the player. - */ -static bool_ ang_sort_comp_distance(vptr u, vptr v, int a, int b) -{ - byte *x = (byte*)(u); - byte *y = (byte*)(v); - - int da, db, kx, ky; - - /* Absolute distance components */ - kx = x[a]; - kx -= p_ptr->px; - kx = ABS(kx); - ky = y[a]; - ky -= p_ptr->py; - ky = ABS(ky); - - /* Approximate Double Distance to the first point */ - da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx)); - - /* Absolute distance components */ - kx = x[b]; - kx -= p_ptr->px; - kx = ABS(kx); - ky = y[b]; - ky -= p_ptr->py; - ky = ABS(ky); - - /* Approximate Double Distance to the first point */ - db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx)); - - /* Compare the distances */ - return (da <= db); -} - - -/* - * Sorting hook -- swap function -- by "distance to player" - * - * We use "u" and "v" to point to arrays of "x" and "y" positions, - * and sort the arrays by distance to the player. - */ -static void ang_sort_swap_distance(vptr u, vptr v, int a, int b) -{ - byte *x = (byte*)(u); - byte *y = (byte*)(v); - - byte temp; - - /* Swap "x" */ - temp = x[a]; - x[a] = x[b]; - x[b] = temp; - - /* Swap "y" */ - temp = y[a]; - y[a] = y[b]; - y[b] = temp; -} - - - -/* * Hack -- help "select" a location (see below) */ -static s16b target_pick(int y1, int x1, int dy, int dx) +static s16b target_pick(point p, int dy, int dx, std::vector<point> const &points) { - int i, v; - - int x2, y2, x3, y3, x4, y4; - int b_i = -1, b_v = 9999; - /* Scan the locations */ - for (i = 0; i < temp_n; i++) + for (std::size_t i = 0; i < points.size(); i++) { /* Point 2 */ - x2 = temp_x[i]; - y2 = temp_y[i]; + int x2 = points[i].x(); + int y2 = points[i].y(); /* Directed distance */ - x3 = (x2 - x1); - y3 = (y2 - y1); + int x3 = (x2 - p.x()); + int y3 = (y2 - p.y()); /* Verify quadrant */ if (dx && (x3 * dx <= 0)) continue; if (dy && (y3 * dy <= 0)) continue; /* Absolute distance */ - x4 = ABS(x3); - y4 = ABS(y3); + int x4 = ABS(x3); + int y4 = ABS(y3); /* Verify quadrant */ if (dy && !dx && (x4 > y4)) continue; if (dx && !dy && (y4 > x4)) continue; /* Approximate Double Distance */ - v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4)); + int v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4)); /* XXX XXX XXX Penalize location */ @@ -3989,6 +3737,9 @@ static s16b target_pick(int y1, int x1, int dy, int dx) */ static bool_ target_set_accept(int y, int x) { + auto const &r_info = game->edit_data.r_info; + auto const &f_info = game->edit_data.f_info; + /* Player grid is always interesting */ if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE); @@ -4001,7 +3752,7 @@ static bool_ target_set_accept(int y, int x) cave_type *c_ptr = &cave[y][x]; /* Visible monsters */ - if (c_ptr->m_idx && c_ptr->m_idx < max_r_idx) + if (c_ptr->m_idx && c_ptr->m_idx < static_cast<int>(r_info.size())) { monster_type *m_ptr = &m_list[c_ptr->m_idx]; @@ -4025,9 +3776,6 @@ static bool_ target_set_accept(int y, int x) /* Interesting memorized features */ if (c_ptr->info & (CAVE_MARK)) { - /* Traps are interesting */ - if (c_ptr->info & (CAVE_TRDT)) return (TRUE); - /* Hack -- Doors are boring */ if (c_ptr->feat == FEAT_OPEN) return (FALSE); if (c_ptr->feat == FEAT_BROKEN) return (FALSE); @@ -4035,7 +3783,7 @@ static bool_ target_set_accept(int y, int x) (c_ptr->feat <= FEAT_DOOR_TAIL)) return (FALSE); /* Accept 'naturally' interesting features */ - if (f_info[c_ptr->feat].flags1 & FF1_NOTICE) return (TRUE); + if (f_info[c_ptr->feat].flags & FF_NOTICE) return (TRUE); } /* Nope */ @@ -4048,39 +3796,42 @@ static bool_ target_set_accept(int y, int x) * * Return the number of target_able monsters in the set. */ -static void target_set_prepare(int mode) +static std::vector<point> target_set_prepare(int mode) { - int y, x; + std::vector<point> points; - /* Reset "temp" array */ - temp_n = 0; - - /* Scan the current panel */ - for (y = panel_row_min; y <= panel_row_max; y++) + // Scan the current panel + for (int y = panel_row_min; y <= panel_row_max; y++) { - for (x = panel_col_min; x <= panel_col_max; x++) + for (int x = panel_col_min; x <= panel_col_max; x++) { cave_type *c_ptr = &cave[y][x]; - /* Require "interesting" contents */ + // Require "interesting" contents if (!target_set_accept(y, x)) continue; - /* Require target_able monsters for "TARGET_KILL" */ + // Require target_able monsters for "TARGET_KILL" if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue; - /* Save the location */ - temp_x[temp_n] = x; - temp_y[temp_n] = y; - temp_n++; + // Save the location + points.push_back(point(x,y)); } } - /* Set the sort hooks */ - ang_sort_comp = ang_sort_comp_distance; - ang_sort_swap = ang_sort_swap_distance; + // Sort the points by distance to player; we'll + // use a stable sort to avoid equidistant targets + // "swapping" priorities. + std::stable_sort( + std::begin(points), + std::end(points), + [](point i, point j) -> bool { + auto di = distance(p_ptr->py, p_ptr->px, i.y(), i.x()); + auto dj = distance(p_ptr->py, p_ptr->px, j.y(), j.x()); + return di < dj; + } + ); - /* Sort the positions */ - ang_sort(temp_x, temp_y, temp_n); + return points; } @@ -4142,6 +3893,12 @@ bool_ target_object(int y, int x, int mode, cptr info, bool_ *boring, */ static int target_set_aux(int y, int x, int mode, cptr info) { + auto const &d_info = game->edit_data.d_info; + auto const &st_info = game->edit_data.st_info; + auto const &wf_info = game->edit_data.wf_info; + auto const &f_info = game->edit_data.f_info; + auto const &k_info = game->edit_data.k_info; + cave_type *c_ptr = &cave[y][x]; cptr s1, s2, s3; @@ -4206,7 +3963,7 @@ static int target_set_aux(int y, int x, int mode, cptr info) auto const r_ptr = m_ptr->race(); /* Mimics special treatment -- looks like an object */ - if ((r_ptr->flags9 & RF9_MIMIC) && (m_ptr->csleep)) + if ((r_ptr->flags & RF_MIMIC) && (m_ptr->csleep)) { /* Acquire object */ object_type *o_ptr = &o_list[m_ptr->mimic_o_idx()]; @@ -4254,7 +4011,7 @@ static int target_set_aux(int y, int x, int mode, cptr info) Term_save(); /* Recall on screen */ - screen_roff(m_ptr->r_idx, m_ptr->ego, 0); + screen_roff(m_ptr->r_idx, m_ptr->ego); /* Hack -- Complete the prompt (again) */ Term_addstr( -1, TERM_WHITE, format(" [r,%s]", info)); @@ -4329,8 +4086,8 @@ static int target_set_aux(int y, int x, int mode, cptr info) s1 = "It is "; /* Hack -- take account of gender */ - if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is "; - else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is "; + if (r_ptr->flags & RF_FEMALE) s1 = "She is "; + else if (r_ptr->flags & RF_MALE) s1 = "He is "; /* Use a preposition */ s2 = "carrying "; @@ -4404,34 +4161,6 @@ static int target_set_aux(int y, int x, int mode, cptr info) } } - /* Actual traps */ - if ((c_ptr->info & (CAVE_TRDT)) && c_ptr->t_idx) - { - cptr name = "a trap", s4; - - /* Name trap */ - if (t_info[c_ptr->t_idx].ident) - { - s4 = format("(%s)", t_info[c_ptr->t_idx].name); - } - else - { - s4 = "an unknown trap"; - } - - /* Display a message */ - sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, s4); - prt(out_val, 0, 0); - move_cursor_relative(y, x); - query = inkey(); - - /* Stop on everything but "return" */ - if ((query != '\r') && (query != '\n')) break; - - /* Repeat forever */ - continue; - } - /* Feature (apply "mimic") */ if (c_ptr->mimic) { @@ -4452,7 +4181,7 @@ static int target_set_aux(int y, int x, int mode, cptr info) /* Terrain feature if needed */ if (boring || (feat >= FEAT_GLYPH)) { - cptr name; + std::string name; /* Hack -- special handling for building doors */ if (feat == FEAT_SHOP) @@ -4494,10 +4223,11 @@ static int target_set_aux(int y, int x, int mode, cptr info) if (p_ptr->wild_mode && (feat == FEAT_TOWN)) { + auto const &wilderness = game->wilderness; + auto const &wf = wf_info[wilderness(x, y).feat]; + s3 = ""; - name = format("%s(%s)", - wf_info[wild_map[y][x].feat].name, - wf_info[wild_map[y][x].feat].text); + name = fmt::format("{}({})", wf.name, wf.text); } if ((feat == FEAT_FOUNTAIN) && (c_ptr->info & CAVE_IDNT)) @@ -4521,12 +4251,12 @@ static int target_set_aux(int y, int x, int mode, cptr info) /* Display a message */ if (!wizard) { - sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info); + sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name.c_str(), info); } else { sprintf(out_val, "%s%s%s%s [%s] (%d:%d:%d)", - s1, s2, s3, name, info, + s1, s2, s3, name.c_str(), info, c_ptr->feat, c_ptr->mimic, c_ptr->special); } prt(out_val, 0, 0); @@ -4603,8 +4333,6 @@ bool_ target_set(int mode) char info[80]; - cave_type *c_ptr; - int screen_wid, screen_hgt; int panel_wid, panel_hgt; @@ -4624,7 +4352,7 @@ bool_ target_set(int mode) /* Prepare the "temp" array */ - target_set_prepare(mode); + std::vector<point> points = target_set_prepare(mode); /* Start near the player */ m = 0; @@ -4633,13 +4361,13 @@ bool_ target_set(int mode) while (!done) { /* Interesting grids */ - if (flag && temp_n) + if (flag && points.size()) { - y = temp_y[m]; - x = temp_x[m]; + y = points[m].y(); + x = points[m].x(); /* Access */ - c_ptr = &cave[y][x]; + cave_type *c_ptr = &cave[y][x]; /* Allow target */ if (target_able(c_ptr->m_idx)) @@ -4696,7 +4424,7 @@ bool_ target_set(int mode) case '*': case '+': { - if (++m == temp_n) + if (++m == points.size()) { m = 0; } @@ -4707,7 +4435,7 @@ bool_ target_set(int mode) { if (m-- == 0) { - m = temp_n - 1; + m = points.size() - 1; } break; } @@ -4763,7 +4491,7 @@ bool_ target_set(int mode) if (d) { /* Find a new monster */ - i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]); + i = target_pick(points[m], ddy[d], ddx[d], points); /* Scroll to find interesting grid */ if (i < 0) @@ -4777,14 +4505,13 @@ bool_ target_set(int mode) /* Note panel change */ if (change_panel(dy, dx)) { - int ty = temp_y[m]; - int tx = temp_x[m]; + auto const t = points[m]; /* Recalculate interesting grids */ target_set_prepare(mode); /* Find a new monster */ - i = target_pick(ty, tx, dy, dx); + i = target_pick(t, dy, dx, points); /* Restore panel if needed */ if (i < 0) @@ -4806,9 +4533,6 @@ bool_ target_set(int mode) /* Arbitrary grids */ else { - /* Access */ - c_ptr = &cave[y][x]; - /* Default prompt */ strcpy(info, "q,t,p,m,+,-,'dir'"); @@ -4936,9 +4660,6 @@ bool_ target_set(int mode) } } - /* Forget */ - temp_n = 0; - /* Clear the top line */ prt("", 0, 0); @@ -5003,7 +4724,10 @@ bool_ get_aim_dir(int *dp) dir = command_dir; /* Hack -- auto-target if requested */ - if (use_old_target && target_okay()) dir = 5; + if (options->use_old_target && target_okay()) + { + dir = 5; + } /* Ask until satisfied */ while (!dir) @@ -5250,19 +4974,22 @@ void set_grace(s32b v) static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge, const char *what) { - int i, j, jb, save_aware; + auto &k_info = game->edit_data.k_info; + auto const &e_info = game->edit_data.e_info; + + int save_aware; char buf[200]; /* try all objects, this *IS* a very ugly and slow method :( */ - for (i = 0; i < max_k_idx; i++) + for (std::size_t i = 0; i < k_info.size(); i++) { - object_kind *k_ptr = &k_info[i]; + auto k_ptr = &k_info[i]; o_ptr = forge; if (!k_ptr->name) continue; - if (k_ptr->flags3 & TR3_NORM_ART) continue; - if (k_ptr->flags3 & TR3_INSTA_ART) continue; + if (k_ptr->flags & TR_NORM_ART) continue; + if (k_ptr->flags & TR_INSTA_ART) continue; if (k_ptr->tval == TV_GOLD) continue; object_prep(o_ptr, i); @@ -5282,9 +5009,9 @@ static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge (o_ptr->tval == TV_ROD_MAIN && strstr(name, "rod of"))) { /* try all ego */ - for (j = max_e_idx - 1; j >= 0; j--) + for (std::size_t j = 0; j < e_info.size(); j++) { - ego_item_type *e_ptr = &e_info[j]; + auto e_ptr = &e_info[j]; bool_ ok = FALSE; if (j && !e_ptr->name) continue; @@ -5310,9 +5037,9 @@ static bool_ test_object_wish(char *name, object_type *o_ptr, object_type *forge } /* try all ego */ - for (jb = max_e_idx - 1; jb >= 0; jb--) + for (std::size_t jb = 0; jb < e_info.size(); jb++) { - ego_item_type *eb_ptr = &e_info[jb]; + auto eb_ptr = &e_info[jb]; bool_ ok = FALSE; if (jb && !eb_ptr->name) continue; @@ -5403,13 +5130,17 @@ static void clean_wish_name(char *buf, char *name) /* * Allow the player to make a wish */ -void make_wish(void) +void make_wish() { - char buf[200], name[200], *mname; - int i, j, mstatus = MSTATUS_ENEMY; + auto const &re_info = game->edit_data.re_info; + auto const &r_info = game->edit_data.r_info; + + char name[200], *mname; + int mstatus = MSTATUS_ENEMY; object_type forge, *o_ptr = &forge; /* Make an empty string */ + char buf[200]; buf[0] = 0; /* Ask for the wish */ @@ -5461,16 +5192,20 @@ void make_wish(void) else mstatus = MSTATUS_PET; mname = name + 10; } - else mname = name; - for (i = 1; i < max_r_idx; i++) + else + { + mname = name; + } + + for (std::size_t i = 1; i < r_info.size(); i++) { - monster_race *r_ptr = &r_info[i]; + auto r_ptr = &r_info[i]; if (!r_ptr->name) continue; - if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue; - if (r_ptr->flags9 & RF9_NEVER_GENE) continue; - if (r_ptr->flags1 & RF1_UNIQUE) continue; + if (r_ptr->flags & RF_SPECIAL_GENE) continue; + if (r_ptr->flags & RF_NEVER_GENE) continue; + if (r_ptr->flags & RF_UNIQUE) continue; sprintf(buf, "%s", r_ptr->name); strlower(buf); @@ -5478,9 +5213,9 @@ void make_wish(void) if (strstr(mname, buf)) { /* try all ego */ - for (j = max_re_idx - 1; j >= 0; j--) + for (std::size_t j = 0; j < re_info.size(); j++) { - monster_ego *re_ptr = &re_info[j]; + auto re_ptr = &re_info[j]; if (j && !re_ptr->name) continue; @@ -5501,6 +5236,7 @@ void make_wish(void) { sprintf(buf, "%s", r_ptr->name); } + strlower(buf); if (iequals(mname, buf)) @@ -5516,7 +5252,9 @@ void make_wish(void) /* Create the monster */ if (place_monster_one(wy, wx, i, j, FALSE, mstatus)) + { msg_print("Your wish becomes truth!"); + } /* Don't search any more */ return; @@ -5531,7 +5269,7 @@ void make_wish(void) * Corrupted have a 1/3 chance of losing a mutation each time this is called, * assuming they have any in the first place */ -static void corrupt_corrupted(void) +static void corrupt_corrupted() { if (magik(45)) { @@ -5549,66 +5287,37 @@ static void corrupt_corrupted(void) /* * Change to an other subrace */ -void switch_subrace(int racem, bool_ copy_old) +void switch_subrace(std::size_t racem, bool_ copy_old) { - if ((racem < 0) && (racem >= max_rmp_idx)) return; + auto &race_mod_info = game->edit_data.race_mod_info; + + assert(racem < race_mod_info.size()); /* If we switch to the saved subrace, we copy over the old subrace data */ if (copy_old && (racem == SUBRACE_SAVE)) { - // This code is very reliant on the race_mod_info - // elements being simple PODs, in particular the - // text pointers being *unmanaged* owned pointers. - static_assert(std::is_pod<player_race_mod>::value, - "This code needs reworking"); - // Keep references to owned pointers. - auto old_title = race_mod_info[SUBRACE_SAVE].title; - auto old_desc = race_mod_info[SUBRACE_SAVE].desc; + // Keep old description + auto old_desc = race_mod_info[SUBRACE_SAVE].description; // Copy everything race_mod_info[SUBRACE_SAVE] = race_mod_info[p_ptr->pracem]; - // "Undo" copy of title and description (since they're *owned* pointers) - race_mod_info[SUBRACE_SAVE].title = old_title; - race_mod_info[SUBRACE_SAVE].desc = old_desc; - // Replace subrace title with the title currently held by player. - set_subrace_title(&race_mod_info[SUBRACE_SAVE], race_mod_info[p_ptr->pracem].title); + // Reinstate description + race_mod_info[SUBRACE_SAVE].description = old_desc; } p_ptr->pracem = racem; rmp_ptr = &race_mod_info[p_ptr->pracem]; } -void set_subrace_title(player_race_mod *rmp_ptr, cptr name) -{ - // Free old title. - free(rmp_ptr->title); - // Allocate copy of new title. - rmp_ptr->title = strdup(name); - if (!rmp_ptr->title) { - abort(); - } -} - -void set_subrace_description(player_race_mod *rmp_ptr, cptr desc) -{ - // Free old description - free(rmp_ptr->desc); - // Allocate copy of new description. - rmp_ptr->desc = strdup(desc); - if (!rmp_ptr->desc) { - abort(); - } -} - /* * Rebirth, recalc hp & exp/level */ void do_rebirth() { /* Experience factor */ - p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp; + p_ptr->expfact = rp_ptr->ps.exp + rmp_ptr->ps.exp + cp_ptr->ps.exp; /* Hitdice */ - p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp; + p_ptr->hitdie = rp_ptr->ps.mhp + rmp_ptr->ps.mhp + cp_ptr->ps.mhp; /* Recalc HP */ do_cmd_rerate(); diff --git a/src/xtra2.hpp b/src/xtra2.hpp index 10d752a2..9edcec1e 100644 --- a/src/xtra2.hpp +++ b/src/xtra2.hpp @@ -7,90 +7,83 @@ #include <memory> -extern void do_rebirth(void); -extern void set_subrace_title(player_race_mod *rmp_ptr, cptr name); -extern void set_subrace_description(player_race_mod *rmp_ptr, cptr desc); -extern void switch_subrace(int racem, bool_ copy_old); -extern void drop_from_wild(void); -extern bool_ set_roots(int v, s16b ac, s16b dam); -extern bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag); -extern bool_ set_parasite(int v, int r); -extern bool_ set_disrupt_shield(int v); -extern bool_ set_prob_travel(int v); -extern bool_ set_absorb_soul(int v); -extern bool_ set_tim_breath(int v, bool_ magical); -extern bool_ set_tim_precognition(int v); -extern bool_ set_tim_deadly(int v); -extern bool_ set_tim_reflect(int v); -extern bool_ set_tim_thunder(int v, int p1, int p2); -extern bool_ set_strike(int v); -extern bool_ set_tim_regen(int v, int p); -extern bool_ set_tim_ffall(int v); -extern bool_ set_tim_fly(int v); -extern bool_ set_poison(int v); -extern bool_ set_holy(int v); -extern void set_grace(s32b v); -extern bool_ set_mimic(int v, int p, int level); -extern bool_ set_no_breeders(int v); -extern bool_ set_invis(int v,int p); -extern bool_ set_lite(int v); -extern bool_ set_blind(int v); -extern bool_ set_confused(int v); -extern bool_ set_poisoned(int v); -extern bool_ set_afraid(int v); -extern bool_ set_paralyzed(int v); -extern void dec_paralyzed(); -extern bool_ set_image(int v); -extern bool_ set_fast(int v, int p); -extern bool_ set_light_speed(int v); -extern bool_ set_slow(int v); -extern bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2); -extern bool_ set_blessed(int v); -extern bool_ set_hero(int v); -extern bool_ set_shero(int v); -extern bool_ set_protevil(int v); -extern bool_ set_protgood(int v); -extern bool_ set_protundead(int v); -extern bool_ set_invuln(int v); -extern bool_ set_tim_invis(int v); -extern bool_ set_tim_infra(int v); -extern bool_ set_mental_barrier(int v); -extern bool_ set_oppose_acid(int v); -extern bool_ set_oppose_elec(int v); -extern bool_ set_oppose_fire(int v); -extern bool_ set_oppose_cold(int v); -extern bool_ set_oppose_pois(int v); -extern bool_ set_oppose_ld(int v); -extern bool_ set_oppose_cc(int v); -extern bool_ set_oppose_ss(int v); -extern bool_ set_oppose_nex(int v); -extern bool_ set_stun(int v); -extern bool_ set_cut(int v); -extern bool_ set_food(int v); -extern void check_experience(void); -extern void check_experience_obj(object_type *o_ptr); -extern void gain_exp(s32b amount); -extern void lose_exp(s32b amount); -extern int get_coin_type(std::shared_ptr<monster_race const> r_ptr); -extern void monster_death(int m_idx); -extern bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note); -extern bool_ change_panel(int dy, int dx); -extern void verify_panel(void); -extern bool_ target_okay(void); -extern bool_ target_set(int mode); -extern bool_ get_aim_dir(int *dp); -extern bool_ get_rep_dir(int *dp); -extern bool_ set_shadow(int v); -extern bool_ set_tim_esp(int v); -extern bool_ tgp_pt(int *x, int * y); -extern bool_ tgt_pt (int *x, int *y); -extern void do_poly_self(void); -extern bool_ curse_weapon(void); -extern bool_ curse_armor(void); -extern void make_wish(void); -extern void create_between_gate(int dist, int y, int x); +void do_rebirth(); +void switch_subrace(std::size_t racem, bool_ copy_old); +void drop_from_wild(); +bool_ set_roots(int v, s16b ac, s16b dam); +bool_ set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag); +bool_ set_parasite(int v, int r); +bool_ set_disrupt_shield(int v); +bool_ set_prob_travel(int v); +bool_ set_absorb_soul(int v); +bool_ set_tim_breath(int v, bool_ magical); +bool_ set_tim_precognition(int v); +bool_ set_tim_deadly(int v); +bool_ set_tim_reflect(int v); +bool_ set_tim_thunder(int v, int p1, int p2); +bool_ set_strike(int v); +bool_ set_tim_regen(int v, int p); +bool_ set_tim_ffall(int v); +bool_ set_tim_fly(int v); +bool_ set_poison(int v); +bool_ set_holy(int v); +void set_grace(s32b v); +bool_ set_mimic(int v, int p, int level); +bool_ set_no_breeders(int v); +bool_ set_invis(int v,int p); +bool_ set_lite(int v); +bool_ set_blind(int v); +bool_ set_confused(int v); +bool_ set_poisoned(int v); +bool_ set_afraid(int v); +bool_ set_paralyzed(int v); +void dec_paralyzed(); +bool_ set_image(int v); +bool_ set_fast(int v, int p); +bool_ set_light_speed(int v); +bool_ set_slow(int v); +bool_ set_shield(int v, int p, s16b o, s16b d1, s16b d2); +bool_ set_blessed(int v); +bool_ set_hero(int v); +bool_ set_shero(int v); +bool_ set_protevil(int v); +bool_ set_invuln(int v); +bool_ set_tim_invis(int v); +bool_ set_tim_infra(int v); +bool_ set_mental_barrier(int v); +bool_ set_oppose_acid(int v); +bool_ set_oppose_elec(int v); +bool_ set_oppose_fire(int v); +bool_ set_oppose_cold(int v); +bool_ set_oppose_pois(int v); +bool_ set_oppose_cc(int v); +bool_ set_stun(int v); +bool_ set_cut(int v); +bool_ set_food(int v); +void check_experience(); +void check_experience_obj(object_type *o_ptr); +void gain_exp(s32b amount); +void lose_exp(s32b amount); +int get_coin_type(std::shared_ptr<monster_race const> r_ptr); +void monster_death(int m_idx); +bool_ mon_take_hit(int m_idx, int dam, bool_ *fear, cptr note); +bool_ change_panel(int dy, int dx); +void verify_panel(); +bool_ target_okay(); +bool_ target_set(int mode); +bool_ get_aim_dir(int *dp); +bool_ get_rep_dir(int *dp); +bool_ set_shadow(int v); +bool_ set_tim_esp(int v); +bool_ tgp_pt(int *x, int * y); +bool_ tgt_pt (int *x, int *y); +void do_poly_self(); +bool_ curse_weapon(); +bool_ curse_armor(); +void make_wish(); +void create_between_gate(int dist, int y, int x); extern "C" { - extern void resize_map(void); - extern void resize_window(void); + void resize_map(); + void resize_window(); } diff --git a/src/z-form.h b/src/z-form.h index ac49c658..f67d1484 100644 --- a/src/z-form.h +++ b/src/z-form.h @@ -21,16 +21,16 @@ extern "C" { /**** Available Functions ****/ /* Format arguments into given bounded-length buffer */ -extern uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp); +uint vstrnfmt(char *buf, uint max, cptr fmt, va_list vp); /* Simple interface to "vstrnfmt()" */ -extern uint strnfmt(char *buf, uint max, cptr fmt, ...); +uint strnfmt(char *buf, uint max, cptr fmt, ...); /* Simple interface to "vformat()" */ -extern char *format(cptr fmt, ...); +char *format(cptr fmt, ...); /* Vararg interface to "quit()", using "format()" */ -extern void quit_fmt(cptr fmt, ...); +void quit_fmt(cptr fmt, ...); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/z-rand.cc b/src/z-rand.cc index c06b7893..a35eb08b 100644 --- a/src/z-rand.cc +++ b/src/z-rand.cc @@ -4,329 +4,186 @@ #include "z-rand.hpp" - - - -/* - * Angband 2.7.9 introduced a new (optimized) random number generator, - * based loosely on the old "random.c" from Berkeley but with some major - * optimizations and algorithm changes. See below for more details. - * - * Code by myself (benh@phial.com) and Randy (randy@stat.tamu.edu). - * - * This code provides (1) a "decent" RNG, based on the "BSD-degree-63-RNG" - * used in Angband 2.7.8, but rather optimized, and (2) a "simple" RNG, - * based on the simple "LCRNG" currently used in Angband, but "corrected" - * to give slightly better values. Both of these are available in two - * flavors, first, the simple "mod" flavor, which is fast, but slightly - * biased at high values, and second, the simple "div" flavor, which is - * less fast (and potentially non-terminating) but which is not biased - * and is much less subject to low-bit-non-randomness problems. - * - * You can select your favorite flavor by proper definition of the - * "rand_int()" macro in the "defines.h" file. - * - * Note that, in Angband 2.8.0, the "state" table will be saved in the - * savefile, so a special "initialization" phase will be necessary. - * - * Note the use of the "simple" RNG, first you activate it via - * "Rand_quick = TRUE" and "Rand_value = seed" and then it is used - * automatically used instead of the "complex" RNG, and when you are - * done, you de-activate it via "Rand_quick = FALSE" or choose a new - * seed via "Rand_value = seed". +#include <assert.h> +#include <cstdint> +#include <limits> +#include <random> +#include <sstream> +#include <type_traits> + +#include "pcg_random.hpp" +#include "seed.hpp" + +/** + * Choice of RNG; we use the "statistically most powerful" (per the + * documentation) RNG. The "insecure" bit just means that the RNG + * is definitely known to *not* be cryptographically secure. */ +using rng_t = pcg64_once_insecure; - -/* - * Random Number Generator -- Linear Congruent RNG - */ -#define LCRNG(X) ((X) * 1103515245 + 12345) - - - -/* - * Use the "simple" LCRNG +/** + * Reseed the given RNG. */ -bool_ Rand_quick = TRUE; - +static void reseed_rng(rng_t *rng, seed_t const &seed) +{ + assert(rng != nullptr); + // Create a seed_seq from the seed data. + std::uint32_t data[seed_t::n_uint32]; + std::seed_seq seed_seq( + std::begin(data), + std::end(data) + ); + // Seed the RNG. + rng->seed(seed_seq); +} -/* - * Current "value" of the "simple" RNG +/** + * Allocate a new RNG and initialize with the given seed. */ -u32b Rand_value; - +static rng_t *new_seeded_rng(seed_t const &seed) +{ + rng_t *rng = new rng_t; + reseed_rng(rng, seed); + return rng; +} -/* - * Current "index" for the "complex" RNG +/** + * The "quick" RNG is used for fixed-seed applications. */ -u16b Rand_place; +static rng_t *quick_rng() +{ + // Note that the "quick_rng" will always be seeded explicitly + // whenever it's used, so we don't need to do any seeding here. + static rng_t *instance = new rng_t(); + return instance; +} -/* - * Current "state" table for the "complex" RNG +/** + * The "complex" RNG is used when we really want non-deterministic + * random numbers. */ -u32b Rand_state[RAND_DEG]; +static rng_t *complex_rng() +{ + static rng_t *instance = new_seeded_rng(seed_t::system()); + return instance; +} +/** + * Current RNG. + */ +static rng_t *current_rng = nullptr; -/* - * Initialize the "complex" RNG using a new seed +/** + * Get the current RNG. */ -void Rand_state_init(u32b seed) +static rng_t *get_current_rng() { - int i, j; + // Do we need to initialize? + if (current_rng == nullptr) + { + // We start with the complex RNG. + current_rng = complex_rng(); + } - /* Seed the table */ - Rand_state[0] = seed; + return current_rng; +} - /* Propagate the seed */ - for (i = 1; i < RAND_DEG; i++) Rand_state[i] = LCRNG(Rand_state[i - 1]); +void set_quick_rng(seed_t const &seed) +{ + reseed_rng(quick_rng(), seed); + current_rng = quick_rng(); +} - /* Cycle the table ten times per degree */ - for (i = 0; i < RAND_DEG * 10; i++) - { - /* Acquire the next index */ - j = Rand_place + 1; - if (j == RAND_DEG) j = 0; +void set_complex_rng() +{ + current_rng = complex_rng(); +} - /* Update the table, extract an entry */ - Rand_state[j] += Rand_state[Rand_place]; +std::string get_complex_rng_state() +{ + std::stringstream s; + s << *complex_rng(); + return s.str(); +} - /* Advance the index */ - Rand_place = j; - } +void set_complex_rng_state(std::string const &state) +{ + std::stringstream s(state); + s >> *complex_rng(); } + /* - * Extract a "random" number from 0 to m-1, via "modulus" - * - * Note that "m" should probably be less than 500000, or the - * results may be rather biased towards low values. + * Stochastic rounding */ -s32b Rand_mod(s32b m) +static double round_stochastic(double x) { - int j; - u32b r; - - /* Hack -- simple case */ - if (m <= 1) return (0); + double n; + double f = std::modf(x, &n); - /* Use the "simple" RNG */ - if (Rand_quick) + // Round up? + if (f > 0.5) { - /* Cycle the generator */ - r = (Rand_value = LCRNG(Rand_value)); - - /* Mutate a 28-bit "random" number */ - r = (r >> 4) % m; + return n + 1; } - /* Use the "complex" RNG */ - else + // Round down? + if (f < 0.5) { - /* Acquire the next index */ - j = Rand_place + 1; - if (j == RAND_DEG) j = 0; - - /* Update the table, extract an entry */ - r = (Rand_state[j] += Rand_state[Rand_place]); - - /* Advance the index */ - Rand_place = j; - - /* Extract a "random" number */ - r = (r >> 4) % m; + return n - 1; } - /* Use the value */ - return (r); -} - - -/* - * Extract a "random" number from 0 to m-1, via "division" - * - * This method selects "random" 28-bit numbers, and then uses - * division to drop those numbers into "m" different partitions, - * plus a small non-partition to reduce bias, taking as the final - * value the first "good" partition that a number falls into. - * - * This method has no bias, and is much less affected by patterns - * in the "low" bits of the underlying RNG's. - */ -static s32b Rand_div(s32b m) -{ - u32b r, n; - - /* Hack -- simple case */ - if (m <= 1) return (0); - - /* Partition size */ - n = (0x10000000 / m); - - /* Use a simple RNG */ - if (Rand_quick) + // Tie breaker is random; hence 'stochastic'. + std::uniform_int_distribution<int> distribution(0, 1); + if (distribution(*get_current_rng()) == 0) { - /* Wait for it */ - while (1) - { - /* Cycle the generator */ - r = (Rand_value = LCRNG(Rand_value)); - - /* Mutate a 28-bit "random" number */ - r = ((r >> 4) & 0x0FFFFFFF) / n; - - /* Done */ - if (r < (u32b)m) break; - } + return n - 1; } - - /* Use a complex RNG */ else { - /* Wait for it */ - while (1) - { - int j; - - /* Acquire the next index */ - j = Rand_place + 1; - if (j == RAND_DEG) j = 0; - - /* Update the table, extract an entry */ - r = (Rand_state[j] += Rand_state[Rand_place]); - - /* Hack -- extract a 28-bit "random" number */ - r = ((r >> 4) & 0x0FFFFFFF) / n; - - /* Advance the index */ - Rand_place = j; - - /* Done */ - if (r < (u32b)m) break; - } + return n + 1; } - - /* Use the value */ - return (r); } - - -/* - * The number of entries in the "randnor_table" - */ -#define RANDNOR_NUM 256 - -/* - * The standard deviation of the "randnor_table" - */ -#define RANDNOR_STD 64 - -/* - * The normal distribution table for the "randnor()" function (below) - */ -static s16b randnor_table[RANDNOR_NUM] = -{ - 206, 613, 1022, 1430, 1838, 2245, 2652, 3058, - 3463, 3867, 4271, 4673, 5075, 5475, 5874, 6271, - 6667, 7061, 7454, 7845, 8234, 8621, 9006, 9389, - 9770, 10148, 10524, 10898, 11269, 11638, 12004, 12367, - 12727, 13085, 13440, 13792, 14140, 14486, 14828, 15168, - 15504, 15836, 16166, 16492, 16814, 17133, 17449, 17761, - 18069, 18374, 18675, 18972, 19266, 19556, 19842, 20124, - 20403, 20678, 20949, 21216, 21479, 21738, 21994, 22245, - - 22493, 22737, 22977, 23213, 23446, 23674, 23899, 24120, - 24336, 24550, 24759, 24965, 25166, 25365, 25559, 25750, - 25937, 26120, 26300, 26476, 26649, 26818, 26983, 27146, - 27304, 27460, 27612, 27760, 27906, 28048, 28187, 28323, - 28455, 28585, 28711, 28835, 28955, 29073, 29188, 29299, - 29409, 29515, 29619, 29720, 29818, 29914, 30007, 30098, - 30186, 30272, 30356, 30437, 30516, 30593, 30668, 30740, - 30810, 30879, 30945, 31010, 31072, 31133, 31192, 31249, - - 31304, 31358, 31410, 31460, 31509, 31556, 31601, 31646, - 31688, 31730, 31770, 31808, 31846, 31882, 31917, 31950, - 31983, 32014, 32044, 32074, 32102, 32129, 32155, 32180, - 32205, 32228, 32251, 32273, 32294, 32314, 32333, 32352, - 32370, 32387, 32404, 32420, 32435, 32450, 32464, 32477, - 32490, 32503, 32515, 32526, 32537, 32548, 32558, 32568, - 32577, 32586, 32595, 32603, 32611, 32618, 32625, 32632, - 32639, 32645, 32651, 32657, 32662, 32667, 32672, 32677, - - 32682, 32686, 32690, 32694, 32698, 32702, 32705, 32708, - 32711, 32714, 32717, 32720, 32722, 32725, 32727, 32729, - 32731, 32733, 32735, 32737, 32739, 32740, 32742, 32743, - 32745, 32746, 32747, 32748, 32749, 32750, 32751, 32752, - 32753, 32754, 32755, 32756, 32757, 32757, 32758, 32758, - 32759, 32760, 32760, 32761, 32761, 32761, 32762, 32762, - 32763, 32763, 32763, 32764, 32764, 32764, 32764, 32765, - 32765, 32765, 32765, 32766, 32766, 32766, 32766, 32767, -}; - - - /* * Generate a random integer number of NORMAL distribution - * - * The table above is used to generate a psuedo-normal distribution, - * in a manner which is much faster than calling a transcendental - * function to calculate a true normal distribution. - * - * Basically, entry 64*N in the table above represents the number of - * times out of 32767 that a random variable with normal distribution - * will fall within N standard deviations of the mean. That is, about - * 68 percent of the time for N=1 and 95 percent of the time for N=2. - * - * The table above contains a "faked" final entry which allows us to - * pretend that all values in a normal distribution are strictly less - * than four standard deviations away from the mean. This results in - * "conservative" distribution of approximately 1/32768 values. - * - * Note that the binary search takes up to 16 quick iterations. */ s16b randnor(int mean, int stand) { - s16b tmp; - s16b offset; - - s16b low = 0; - s16b high = RANDNOR_NUM; + // Get our own return type; we need it for limits and casting. + using retval_t = std::result_of<decltype(&randnor)(int, int)>::type; - /* Paranoia */ - if (stand < 1) return (mean); - - /* Roll for probability */ - tmp = (s16b)rand_int(32768); - - /* Binary Search */ - while (low < high) + // Degenerate case + if (stand < 1) { - int mid = (low + high) >> 1; - - /* Move right if forced */ - if (randnor_table[mid] < tmp) - { - low = mid + 1; - } - - /* Move left otherwise */ - else - { - high = mid; - } + return 0; } - /* Convert the index into an offset */ - offset = (long)stand * (long)low / RANDNOR_STD; - - /* One half should be negative */ - if (rand_int(100) < 50) return (mean - offset); - - /* One half should be positive */ - return (mean + offset); + // Sample from normal distribution + std::normal_distribution<double> distribution(mean, stand); + double x = distribution(*get_current_rng()); + + // Stochastic rounding to avoid rounding bias + double rounded_x = round_stochastic(x); + + // Enforce limits of retval_t. Given that we're talking about a normal + // distribution, we're usually very unlikely to actually hit these (given + // reasonable values for 'mean' and 'stand' parameters), but in (very) rare + // cases it's needed to avoid undefined behavior due to the conversion + // we're going to do. This does introduce some (very minor) bias, but + // it's really unavoidable since retval_t cannot represent all possible + // values. We also assuming that a double can accurately represent all + // values in the range of retval_t. + double clipped_x = std::min( + static_cast<double>(std::numeric_limits<retval_t>::max()), + std::max(static_cast<double>(std::numeric_limits<retval_t>::min()), + rounded_x)); + + // Done: We just need to convert to retval_t. + return static_cast<retval_t>(clipped_x); } @@ -351,26 +208,47 @@ s32b maxroll(s16b num, s16b sides) return (num * sides); } -bool magik(int p) { +bool magik(s32b p) { return rand_int(100) < p; } s32b rand_int(s32b m) { - return Rand_div(m); + /* Degenerate case */ + if (m < 1) + { + return 0; + } + /* Normal case */ + std::uniform_int_distribution<s32b> distribution(0, m - 1); + return distribution(*get_current_rng()); } s32b randint(s32b m) { - return rand_int(m) + 1; + /* Degenerate case */ + if (m < 2) + { + return 1; + } + /* Normal case */ + std::uniform_int_distribution<s32b> distribution(1, m); + return distribution(*get_current_rng()); } s32b rand_range(s32b a, s32b b) { - return a + rand_int(1 + b - a); + /* Degenerate case */ + if (b < a) + { + return a; + } + /* Normal case */ + std::uniform_int_distribution<s32b> distribution(a, b); + return distribution(*get_current_rng()); } s32b rand_spread(s32b a, s32b d) { - return a + rand_int(1 + d + d) - d; + return rand_range(a-d, a+d); } diff --git a/src/z-rand.hpp b/src/z-rand.hpp index f2e3ce5c..b04523c3 100644 --- a/src/z-rand.hpp +++ b/src/z-rand.hpp @@ -1,8 +1,9 @@ #pragma once #include "h-basic.h" +#include "seed_fwd.hpp" - +#include <string> /**** Available constants ****/ @@ -19,17 +20,34 @@ /**** Available Variables ****/ -extern bool_ Rand_quick; -extern u32b Rand_value; -extern u16b Rand_place; -extern u32b Rand_state[RAND_DEG]; +/** + * Change to "quick" RNG, using the given seed. + */ +void set_quick_rng(seed_t const &seed); + + +/** + * Change to "complex" RNG which uses the "non-deterministic" seed. + */ +void set_complex_rng(); + + +/** + * Get a copy of the state of the "complex" RNG. + */ +std::string get_complex_rng_state(); + +/** + * Set the state of the "complex" RNG. The given array must have + * been previously obtained via the get_complex_rng_state() function. + */ +void set_complex_rng_state(std::string const &state); /**** Available Functions ****/ -void Rand_state_init(u32b seed); -s32b Rand_mod(s32b m); +void Rand_state_init(); s16b randnor(int mean, int stand); s32b damroll(s16b num, s16b sides); s32b maxroll(s16b num, s16b sides); @@ -40,7 +58,7 @@ s32b maxroll(s16b num, s16b sides); bool magik(s32b p); /* - * Generates a random long integer X where O<=X<M. + * Generates a random long integer X where 0<=X<M. * The integer X falls along a uniform distribution. * For example, if M is 100, you get "percentile dice" */ @@ -65,3 +83,23 @@ s32b rand_range(s32b a, s32b b); * Note: rand_spread(A,D) == rand_range(A-D,A+D) */ s32b rand_spread(s32b a, s32b d); + +/** + * Choose a random element in from the given container. + * The container, C, must fulfill the Container concept + * whose iterators fulfill the RandomIterator concept. + **/ +template <class C> typename C::const_iterator uniform_element(C const &c) +{ + return c.cbegin() + rand_int(c.size()); +} + +/** + * Choose a random element in from the given container. + * The container, C, must fulfill the Container concept + * whose iterators fulfill the RandomIterator concept. + **/ +template <class C> typename C::iterator uniform_element(C &c) +{ + return c.begin() + rand_int(c.size()); +} diff --git a/src/z-term.h b/src/z-term.h index 01795629..92f09577 100644 --- a/src/z-term.h +++ b/src/z-term.h @@ -150,7 +150,7 @@ struct term errr (*text_hook)(int x, int y, int n, byte a, cptr s); - void (*resize_hook)(void); + void (*resize_hook)(); }; @@ -220,46 +220,46 @@ extern term *Term; /**** Available Functions ****/ -extern errr Term_xtra(int n, int v); - -extern void Term_queue_char(int x, int y, byte a, char c); -extern void Term_queue_chars(int x, int y, int n, byte a, cptr s); - -extern errr Term_fresh(void); -extern errr Term_set_cursor(int v); -extern errr Term_gotoxy(int x, int y); -extern errr Term_draw(int x, int y, byte a, char c); -extern errr Term_addch(byte a, char c); -extern errr Term_addstr(int n, byte a, cptr s); -extern errr Term_putch(int x, int y, byte a, char c); -extern errr Term_putstr(int x, int y, int n, byte a, cptr s); -extern errr Term_erase(int x, int y, int n); -extern errr Term_clear(void); -extern errr Term_redraw(void); -extern errr Term_redraw_section(int x1, int y1, int x2, int y2); -extern void Term_bell(); - -extern errr Term_get_cursor(int *v); -extern errr Term_get_size(int *w, int *h); -extern errr Term_locate(int *x, int *y); -extern errr Term_what(int x, int y, byte *a, char *c); - -extern errr Term_flush(void); -extern errr Term_keypress(int k); -extern errr Term_key_push(int k); -extern errr Term_inkey(char *ch, bool_ wait, bool_ take); - -extern errr Term_save(void); -extern term_win* Term_save_to(void); -extern errr Term_load(void); -extern errr Term_load_from(term_win *save); - -extern errr Term_resize(int w, int h); - -extern errr Term_activate(term *t); - -extern errr term_nuke(term *t); -extern errr term_init(term *t, int w, int h, int k); +errr Term_xtra(int n, int v); + +void Term_queue_char(int x, int y, byte a, char c); +void Term_queue_chars(int x, int y, int n, byte a, cptr s); + +errr Term_fresh(); +errr Term_set_cursor(int v); +errr Term_gotoxy(int x, int y); +errr Term_draw(int x, int y, byte a, char c); +errr Term_addch(byte a, char c); +errr Term_addstr(int n, byte a, cptr s); +errr Term_putch(int x, int y, byte a, char c); +errr Term_putstr(int x, int y, int n, byte a, cptr s); +errr Term_erase(int x, int y, int n); +errr Term_clear(); +errr Term_redraw(); +errr Term_redraw_section(int x1, int y1, int x2, int y2); +void Term_bell(); + +errr Term_get_cursor(int *v); +errr Term_get_size(int *w, int *h); +errr Term_locate(int *x, int *y); +errr Term_what(int x, int y, byte *a, char *c); + +errr Term_flush(); +errr Term_keypress(int k); +errr Term_key_push(int k); +errr Term_inkey(char *ch, bool_ wait, bool_ take); + +errr Term_save(); +term_win* Term_save_to(); +errr Term_load(); +errr Term_load_from(term_win *save); + +errr Term_resize(int w, int h); + +errr Term_activate(term *t); + +errr term_nuke(term *t); +errr term_init(term *t, int w, int h, int k); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/z-util.h b/src/z-util.h index 914a64e7..d2fa79dc 100644 --- a/src/z-util.h +++ b/src/z-util.h @@ -21,19 +21,19 @@ extern void (*quit_aux)(cptr); /* Test equality, prefix, suffix */ -extern bool_ streq(cptr s, cptr t); -extern bool_ prefix(cptr s, cptr t); -extern bool_ suffix(cptr s, cptr t); +bool_ streq(cptr s, cptr t); +bool_ prefix(cptr s, cptr t); +bool_ suffix(cptr s, cptr t); /* Capitalize the first letter of string. Ignores whitespace at the start of string. */ -extern void capitalize(char *s); +void capitalize(char *s); /* Print an error message */ -extern void plog(cptr str); +void plog(cptr str); /* Exit, with optional message */ -extern void quit(cptr str); +void quit(cptr str); #ifdef __cplusplus |