diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-06-20 21:06:39 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-06-20 21:06:39 +0000 |
commit | 3884a47fb05f613b0cb617f09326b24b9a518576 (patch) | |
tree | 1865464950f23aaa2d41870ca61c55433eeeb65b | |
parent | 3ad6e28a57ab9cdbe139e6de12fb8a25c19d86cb (diff) | |
download | crawl-ref-3884a47fb05f613b0cb617f09326b24b9a518576.tar.gz crawl-ref-3884a47fb05f613b0cb617f09326b24b9a518576.zip |
* Add player doll selection prompt ('-') into 0.5 branch.
* Handle Artificers in the job default setting.
* Update change log.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.5@10009 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/docs/changes.stone_soup | 10 | ||||
-rw-r--r-- | crawl-ref/settings/dolls.txt | 12 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 12 | ||||
-rw-r--r-- | crawl-ref/source/cio.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/cmd-keys.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/cmd-name.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 54 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 15 | ||||
-rw-r--r-- | crawl-ref/source/macro.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 29 | ||||
-rw-r--r-- | crawl-ref/source/tilepick.cc | 282 | ||||
-rw-r--r-- | crawl-ref/source/tilereg.cc | 385 | ||||
-rw-r--r-- | crawl-ref/source/tilereg.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/tiles.h | 80 | ||||
-rw-r--r-- | crawl-ref/source/tilesdl.cc | 7 |
17 files changed, 678 insertions, 254 deletions
diff --git a/crawl-ref/docs/changes.stone_soup b/crawl-ref/docs/changes.stone_soup index 42efa6900d..9986f75c3e 100644 --- a/crawl-ref/docs/changes.stone_soup +++ b/crawl-ref/docs/changes.stone_soup @@ -1,3 +1,13 @@ +Stone Soup 0.5.1 (2009????) +--------------------------- + +* Fix crashes related to giant spores. +* Fix erroneous "blocked line of fire" warnings. +* Fix missing items in Tiles inventory. +* Tiles: Allow selection of player dolls. +* Add missing tiles options to the options guide (docs/, '?&' command). +* Speed-up for the Tiles version. + Stone Soup 0.5.0 (20090612) --------------------------- diff --git a/crawl-ref/settings/dolls.txt b/crawl-ref/settings/dolls.txt new file mode 100644 index 0000000000..ea5a8f9e0e --- /dev/null +++ b/crawl-ref/settings/dolls.txt @@ -0,0 +1,12 @@ +MODE=EQUIP +NUM=00 +001:001:***:011:034:092:***:023:034:017:000:063 +001:001:***:009:002:040:016:077:***:023:009:040 +001:000:***:014:017:046:020:048:***:010:000:041 +001:001:001:018:000:017:***:190:066:000:009:043 +001:001:005:003:016:137:***:117:005:000:000:*** +001:000:001:021:000:033:***:136:058:007:000:012 +001:001:003:014:000:005:***:194:041:017:000:028 +001:000:***:017:027:068:***:197:050:011:000:068 +001:000:008:011:033:091:007:055:027:008:000:054 +001:001:007:***:026:015:020:170:057:011:000:032 diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 18798dee26..02ba4c55d7 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -788,6 +788,9 @@ static bool _cmd_is_repeatable(command_type cmd, bool is_again = false) case CMD_INSCRIBE_ITEM: case CMD_MAKE_NOTE: case CMD_CYCLE_QUIVER_FORWARD: +#ifdef USE_TILE + case CMD_EDIT_PLAYER_TILE: +#endif mpr("You can't repeat that command."); return (false); @@ -1325,9 +1328,14 @@ static void _print_friendly_pickup_setting(bool was_changed) void process_command( command_type cmd ) { apply_berserk_penalty = true; - switch (cmd) { +#ifdef USE_TILE + case CMD_EDIT_PLAYER_TILE: + TilePlayerEdit(); + break; +#endif + case CMD_OPEN_DOOR_UP_RIGHT: _open_door( 1, -1); break; case CMD_OPEN_DOOR_UP: _open_door( 0, -1); break; case CMD_OPEN_DOOR_UP_LEFT: _open_door(-1, -1); break; @@ -3461,6 +3469,8 @@ static bool _initialise(void) if (Options.tile_menu_icons && Options.show_inventory_weights) Options.show_inventory_weights = false; + init_player_doll(); + tiles.resize(); #endif diff --git a/crawl-ref/source/cio.cc b/crawl-ref/source/cio.cc index 166bdb6382..d5c87f7e0a 100644 --- a/crawl-ref/source/cio.cc +++ b/crawl-ref/source/cio.cc @@ -95,9 +95,9 @@ int unmangle_direction_keys(int keyin, KeymapContext keymap, case '8': return 'k'; case '9': return 'u'; -#ifndef USE_TILE + #ifndef USE_TILE default: return unixcurses_get_vi_key(keyin); -#endif + #endif #else case '1': return 'B'; diff --git a/crawl-ref/source/cmd-keys.h b/crawl-ref/source/cmd-keys.h index f45e2383fd..82cb9e4a17 100644 --- a/crawl-ref/source/cmd-keys.h +++ b/crawl-ref/source/cmd-keys.h @@ -1,3 +1,6 @@ +#ifdef USE_TILE +{'-', CMD_EDIT_PLAYER_TILE}, +#endif {'b', CMD_MOVE_DOWN_LEFT}, {'h', CMD_MOVE_LEFT}, {'j', CMD_MOVE_DOWN}, diff --git a/crawl-ref/source/cmd-name.h b/crawl-ref/source/cmd-name.h index 5aa7954b3a..a262f1cb85 100644 --- a/crawl-ref/source/cmd-name.h +++ b/crawl-ref/source/cmd-name.h @@ -104,6 +104,9 @@ {CMD_MOUSE_MOVE, "CMD_MOUSE_MOVE"}, {CMD_MOUSE_CLICK, "CMD_MOUSE_CLICK"}, {CMD_ANNOTATE_LEVEL, "CMD_ANNOTATE_LEVEL"}, +#ifdef USE_TILE +{CMD_EDIT_PLAYER_TILE, "CMD_EDIT_PLAYER_TILE"}, +#endif {CMD_PREV_CMD_AGAIN, "CMD_PREV_CMD_AGAIN"}, {CMD_REPEAT_CMD, "CMD_REPEAT_CMD"}, {CMD_MAP_CLEAR_MAP, "CMD_MAP_CLEAR_MAP"}, @@ -201,7 +204,5 @@ {CMD_TARGET_MOUSE_MOVE, "CMD_TARGET_MOUSE_MOVE"}, {CMD_TARGET_MOUSE_SELECT, "CMD_TARGET_MOUSE_SELECT"}, {CMD_TARGET_HELP, "CMD_TARGET_HELP"}, -#ifdef USE_TILE -#endif {CMD_NO_CMD, NULL} diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 7aff78807c..b0096b7bb2 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -660,14 +660,14 @@ void list_weapons(void) mpr(wstring.c_str(), MSGCH_EQUIPMENT, colour); // Print out the swap slots. - for (int i = 0; i <= 1; i++) + for (int i = 0; i <= 1; ++i) { // We'll avoid repeating the current weapon for these slots, // in order to keep things clean. if (weapon_id == i) continue; - if ( i == 0 ) + if (i == 0) wstring = "Primary : "; else wstring = "Secondary : "; @@ -724,8 +724,8 @@ void list_weapons(void) if (colour == MSGCOL_BLACK) colour = menu_colour(wstring, "", "equip"); - mpr( wstring.c_str(), MSGCH_EQUIPMENT, colour ); -} // end list_weapons() + mpr(wstring.c_str(), MSGCH_EQUIPMENT, colour); +} static bool _cmdhelp_textfilter(const std::string &tag) { @@ -2161,7 +2161,12 @@ static void _add_formatted_keyhelp(column_composer &cols) "<w>:</w> : add note (use <w>?:</w> to read notes)\n" "<w>~</w> : add macro (also <w>Ctrl-D</w>)\n" "<w>=</w> : reassign inventory/spell letters\n" +// No online play for tiles, so this replacement is reasonable. (jpeg) +#ifdef USE_TILE + "<w>-</w> : select player doll" +#else "<w>_</w> : read messages (online play only)" +#endif " \n", true, true, _cmdhelp_textfilter); diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 860769e014..7e99f1921c 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -362,6 +362,9 @@ void wizard_change_species( void ) break; } +#ifdef USE_TILE + init_player_doll(); +#endif redraw_screen(); } #endif @@ -5952,18 +5955,24 @@ void debug_miscast( int target_index ) MiscastEffect *miscast; if (spell != SPELL_NO_SPELL) + { miscast = new MiscastEffect(target, target_index, spell, pow, fail, "", nothing); + } else { if (level != -1) + { miscast = new MiscastEffect(target, target_index, school, level, "wizard testing miscast", nothing); + } else + { miscast = new MiscastEffect(target, target_index, school, pow, fail, "wizard testing miscast", nothing); + } } // Merely creating the miscast object causes one miscast effect to // happen. @@ -6366,8 +6375,10 @@ static void _debug_marker_scan() map_marker_type type = marker->get_type(); if (type < MAT_FEATURE || type >= NUM_MAP_MARKER_TYPES) + { mprf(MSGCH_ERROR, "Makrer #%d at (%d, %d) has invalid type %d", i, marker->pos.x, marker->pos.y, (int) type); + } if (!in_bounds(marker->pos)) { diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 15a174c59a..b30fce1734 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -261,12 +261,10 @@ static const char *target_mode_help_text(int mode) } } -static void draw_ray_glyph(const coord_def &pos, int colour, - int glych, int mcol, bool in_range) +#ifndef USE_TILE +static void _draw_ray_glyph(const coord_def &pos, int colour, + int glych, int mcol, bool in_range) { -#ifdef USE_TILE - tile_place_ray(pos, in_range); -#else if (const monsters *mons = monster_at(pos)) { if (mons->alive() && player_monster_visible(mons)) @@ -279,8 +277,8 @@ static void draw_ray_glyph(const coord_def &pos, int colour, cgotoxy(vp.x, vp.y, GOTO_DNGN); textcolor( real_colour(colour) ); putch(glych); -#endif } +#endif // Unseen monsters in shallow water show a "strange disturbance". // (Unless flying!) @@ -1649,8 +1647,8 @@ void direction(dist& moves, targeting_type restricts, if (old_target != moves.target) { have_moved = true; - show_beam = show_beam && find_ray(you.pos(), moves.target, - true, ray, 0, true); + show_beam = show_beam && find_ray(you.pos(), moves.target, + true, ray, 0, true); } if (force_redraw) @@ -1673,13 +1671,17 @@ void direction(dist& moves, targeting_type restricts, #ifdef USE_TILE // Tiles always need a beam redraw if show_beam is true (and valid...) - bool _draw_beam = find_ray(you.pos(), moves.target, true, ray, 0, true) - && show_beam && !_blocked_ray(moves.target); - if (need_beam_redraw || _draw_beam) + if (!need_beam_redraw) { -#else + need_beam_redraw = show_beam + && find_ray(you.pos(), moves.target, true, ray, + 0, true) + && !_blocked_ray(moves.target); + } +#endif if (need_beam_redraw) { +#ifndef USE_TILE viewwindow(true, false); #endif if (show_beam @@ -1700,25 +1702,27 @@ void direction(dist& moves, targeting_type restricts, const bool in_range = (range < 0) || grid_distance(raycopy.pos(), you.pos()) <= range; +#ifdef USE_TILE + tile_place_ray(raycopy.pos(), in_range); +#else const int bcol = in_range ? MAGENTA : DARKGREY; - - draw_ray_glyph(raycopy.pos(), bcol, '*', - bcol | COLFLAG_REVERSE, in_range); + _draw_ray_glyph(raycopy.pos(), bcol, '*', + bcol | COLFLAG_REVERSE, in_range); +#endif } raycopy.advance_through(moves.target); } textcolor(LIGHTGREY); #ifdef USE_TILE - const bool in_range = (range < 0) - || grid_distance(raycopy.pos(), you.pos()) <= range; - draw_ray_glyph(moves.target, MAGENTA, '*', - MAGENTA | COLFLAG_REVERSE, in_range); + const bool in_range + = (range < 0 + || grid_distance(raycopy.pos(), you.pos()) <= range); + tile_place_ray(moves.target, in_range); +#endif } +#ifdef USE_TILE viewwindow(true, false); -#else - } #endif - } skip_iter = false; // Only skip one iteration at most. } @@ -1862,7 +1866,7 @@ void full_describe_square(const coord_def &c) static void _extend_move_to_edge(dist &moves) { - if ( moves.delta.origin() ) + if (moves.delta.origin()) return; // Now the tricky bit - extend the target x,y out to map edge. @@ -3496,8 +3500,8 @@ int targeting_behaviour::get_key() if (!crawl_state.is_replaying_keys()) flush_input_buffer(FLUSH_BEFORE_COMMAND); - return unmangle_direction_keys( getchm(KMC_TARGETING), KMC_TARGETING, - false, false); + return unmangle_direction_keys(getchm(KMC_TARGETING), KMC_TARGETING, + false, false); } command_type targeting_behaviour::get_command(int key) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index da71bb4991..0e5ab40ae0 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -537,6 +537,12 @@ enum command_type CMD_ANNOTATE_LEVEL, +#ifdef USE_TILE + CMD_EDIT_PLAYER_TILE, + CMD_MIN_TILE = CMD_EDIT_PLAYER_TILE, + CMD_MAX_TILE = CMD_MIN_TILE, +#endif + // Repeat previous command CMD_PREV_CMD_AGAIN, @@ -659,11 +665,6 @@ enum command_type CMD_TARGET_HELP, CMD_MAX_TARGET = CMD_TARGET_HELP, -#ifdef USE_TILE - CMD_MIN_TILE, - CMD_MAX_TILE = CMD_MIN_TILE - 1, -#endif - // Disable/enable -more- prompts. CMD_DISABLE_MORE, CMD_MIN_SYNTHETIC = CMD_DISABLE_MORE, @@ -1460,10 +1461,6 @@ enum KeymapContext KMC_CONFIRM, // When being asked y/n/q questions KMC_MENU, // For menus -#ifdef USE_TILE - KMC_TILE, // For context_for_command() -#endif - KMC_CONTEXT_COUNT, // Must always be the last real context KMC_NONE diff --git a/crawl-ref/source/macro.cc b/crawl-ref/source/macro.cc index fe200e45a4..61070cf855 100644 --- a/crawl-ref/source/macro.cc +++ b/crawl-ref/source/macro.cc @@ -63,10 +63,6 @@ static macromap *all_maps[] = &Keymaps[KMC_TARGETING], &Keymaps[KMC_CONFIRM], -#ifdef USE_TILE - &Keymaps[KMC_TILE], -#endif - &Macros, }; @@ -1134,11 +1130,6 @@ int command_to_key(command_type cmd) KeymapContext context_for_command(command_type cmd) { -#ifdef USE_TILE - if (cmd >= CMD_MIN_TILE && cmd <= CMD_MAX_TILE) - return KMC_TILE; -#endif - if (cmd > CMD_NO_CMD && cmd <= CMD_MAX_NORMAL) return KMC_DEFAULT; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 2145370f10..8152b5d9f2 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -3088,10 +3088,6 @@ void level_change(bool skip_attribute_increase) break; case SP_MOUNTAIN_DWARF: - // lowered because of HD raise -- bwr - // if (you.experience_level < 14) - // hp_adjust++; - if (!(you.experience_level % 2)) hp_adjust++; @@ -3202,10 +3198,6 @@ void level_change(bool skip_attribute_increase) break; case SP_NAGA: - // lower because of HD raise -- bwr - // if (you.experience_level < 14) - // hp_adjust++; - hp_adjust++; if (!(you.experience_level % 4)) @@ -3249,6 +3241,9 @@ void level_change(bool skip_attribute_increase) case SP_BASE_DRACONIAN: if (you.experience_level == 7) { +#ifdef USE_TILE + init_player_doll(); +#endif switch (you.species) { case SP_RED_DRACONIAN: @@ -3267,19 +3262,24 @@ void level_change(bool skip_attribute_increase) break; case SP_YELLOW_DRACONIAN: - mpr("Your scales start taking on a golden yellow colour.", MSGCH_INTRINSIC_GAIN); + mpr("Your scales start taking on a golden yellow colour.", + MSGCH_INTRINSIC_GAIN); break; case SP_BLACK_DRACONIAN: - mpr("Your scales start turning black.", MSGCH_INTRINSIC_GAIN); + mpr("Your scales start turning black.", + MSGCH_INTRINSIC_GAIN); break; case SP_PURPLE_DRACONIAN: - mpr("Your scales start taking on a rich purple colour.", MSGCH_INTRINSIC_GAIN); + mpr("Your scales start taking on a rich purple colour.", + MSGCH_INTRINSIC_GAIN); break; case SP_MOTTLED_DRACONIAN: - mpr("Your scales start taking on a weird mottled pattern.", MSGCH_INTRINSIC_GAIN); + mpr("Your scales start taking on a weird mottled pattern.", + MSGCH_INTRINSIC_GAIN); break; case SP_PALE_DRACONIAN: - mpr("Your scales start fading to a pale grey colour.", MSGCH_INTRINSIC_GAIN); + mpr("Your scales start fading to a pale grey colour.", + MSGCH_INTRINSIC_GAIN); break; case SP_BASE_DRACONIAN: mpr(""); @@ -3326,6 +3326,9 @@ void level_change(bool skip_attribute_increase) case SP_GREY_DRACONIAN: if (you.experience_level == 7) { +#ifdef USE_TILE + init_player_doll(); +#endif mpr("Your scales start turning grey.", MSGCH_INTRINSIC_GAIN); more(); diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 1a79526ac8..5fde337f23 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -2716,9 +2716,7 @@ static inline void _finalize_tile(unsigned int *tile, void tilep_calc_flags(const int parts[], int flag[]) { - int i; - - for (i = 0; i < TILEP_PART_MAX; i++) + for (unsigned i = 0; i < TILEP_PART_MAX; i++) flag[i] = TILEP_FLAG_NORMAL; if (parts[TILEP_PART_HELM] - 1 >= TILEP_HELM_HELM_OFS) @@ -2733,21 +2731,24 @@ void tilep_calc_flags(const int parts[], int flag[]) flag[TILEP_PART_BOOTS] = flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_NAGA; } - - if (parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR - || parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR + 1) + else if (parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR + || parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR + 1) { flag[TILEP_PART_BOOTS] = flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_CENTAUR; } - - if (parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER - || parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER + 1) + else if (parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER + || parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER + 1) { flag[TILEP_PART_BOOTS] = TILEP_FLAG_HIDE; flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_SHADOW] = TILEP_FLAG_HIDE; } + else if (parts[TILEP_PART_BASE] >= TILEP_BASE_DRACONIAN + && parts[TILEP_PART_BASE] <= TILEP_BASE_DRACONIAN_WHITE + 1) + { + flag[TILEP_PART_HAIR] = flag[TILEP_PART_HELM] = TILEP_FLAG_HIDE; + } } /* @@ -2789,35 +2790,106 @@ static int _draconian_colour(int race, int level) return 0; } -void tilep_race_default(int race, int gender, int level, int *parts) +int get_gender_from_tile(int parts[]) +{ + return ((parts[TILEP_PART_BASE] + - tile_player_part_start[TILEP_PART_BASE]) % 2); +} + +int tilep_species_to_base_tile(int sp, int level) +{ + switch (sp) + { + case SP_HUMAN: + return TILEP_BASE_HUMAN; + case SP_ELF: + case SP_HIGH_ELF: + case SP_SLUDGE_ELF: + return TILEP_BASE_ELF; + case SP_DEEP_ELF: + return TILEP_BASE_DEEP_ELF; + case SP_MOUNTAIN_DWARF: + return TILEP_BASE_DWARF; + case SP_HALFLING: + return TILEP_BASE_HALFLING; + case SP_HILL_ORC: + return TILEP_BASE_ORC; + case SP_KOBOLD: + return TILEP_BASE_KOBOLD; + case SP_MUMMY: + return TILEP_BASE_MUMMY; + case SP_NAGA: + return TILEP_BASE_NAGA; + case SP_OGRE: + return TILEP_BASE_OGRE; + case SP_TROLL: + return TILEP_BASE_TROLL; + case SP_BASE_DRACONIAN: + case SP_RED_DRACONIAN: + case SP_WHITE_DRACONIAN: + case SP_GREEN_DRACONIAN: + case SP_YELLOW_DRACONIAN: + case SP_GREY_DRACONIAN: + case SP_BLACK_DRACONIAN: + case SP_PURPLE_DRACONIAN: + case SP_MOTTLED_DRACONIAN: + case SP_PALE_DRACONIAN: + { + const int colour_offset = _draconian_colour(sp, level); + return (TILEP_BASE_DRACONIAN + colour_offset * 2); + } + case SP_CENTAUR: + return TILEP_BASE_CENTAUR; + case SP_DEMIGOD: + return TILEP_BASE_DEMIGOD; + case SP_SPRIGGAN: + return TILEP_BASE_SPRIGGAN; + case SP_MINOTAUR: + return TILEP_BASE_MINOTAUR; + case SP_DEMONSPAWN: + return TILEP_BASE_DEMONSPAWN; + case SP_GHOUL: + return TILEP_BASE_GHOUL; + case SP_KENKU: + return TILEP_BASE_KENKU; + case SP_MERFOLK: + return TILEP_BASE_MERFOLK; + case SP_VAMPIRE: + return TILEP_BASE_VAMPIRE; + case SP_DEEP_DWARF: + return TILEP_BASE_DEEP_DWARF; + default: + return TILEP_BASE_HUMAN; + } +} + +void tilep_race_default(int sp, int gender, int level, int *parts) { - int result; - int hair; - int beard = 0; + if (gender == -1) + gender = get_gender_from_tile(parts); + + ASSERT(gender == TILEP_GENDER_MALE || gender == TILEP_GENDER_FEMALE); + int result = tilep_species_to_base_tile(sp, level) + gender; + int hair = 0; + int beard = 0; if (gender == TILEP_GENDER_MALE) hair = TILEP_HAIR_SHORT_BLACK; else hair = TILEP_HAIR_LONG_BLACK; - switch (race) + switch (sp) { - case SP_HUMAN: - result = TILEP_BASE_HUMAN; - break; case SP_ELF: case SP_HIGH_ELF: case SP_SLUDGE_ELF: - result = TILEP_BASE_ELF; - hair = TILEP_HAIR_ELF_YELLOW; + hair = TILEP_HAIR_ELF_YELLOW; break; case SP_DEEP_ELF: - result = TILEP_BASE_DEEP_ELF; - hair = TILEP_HAIR_ELF_WHITE; + hair = TILEP_HAIR_ELF_WHITE; break; case SP_HILL_DWARF: case SP_MOUNTAIN_DWARF: - result = TILEP_BASE_DWARF; if (gender == TILEP_GENDER_MALE) { hair = TILEP_HAIR_SHORT_RED; @@ -2829,32 +2901,18 @@ void tilep_race_default(int race, int gender, int level, int *parts) beard = TILEP_BEARD_SHORT_RED; } break; - case SP_HALFLING: - result = TILEP_BASE_HALFLING; - break; case SP_HILL_ORC: - result = TILEP_BASE_ORC; - hair = 0; + hair = 0; break; case SP_KOBOLD: - result = TILEP_BASE_KOBOLD; - hair = 0; + hair = 0; break; case SP_MUMMY: - result = TILEP_BASE_MUMMY; - hair = 0; - break; - case SP_NAGA: - result = TILEP_BASE_NAGA; - break; - case SP_OGRE: - result = TILEP_BASE_OGRE; + hair = 0; break; case SP_TROLL: - result = TILEP_BASE_TROLL; - hair = 0; + hair = 0; break; - case SP_BASE_DRACONIAN: case SP_RED_DRACONIAN: case SP_WHITE_DRACONIAN: @@ -2865,53 +2923,40 @@ void tilep_race_default(int race, int gender, int level, int *parts) case SP_PURPLE_DRACONIAN: case SP_MOTTLED_DRACONIAN: case SP_PALE_DRACONIAN: - hair = 0; + { + const int colour_offset = _draconian_colour(sp, level); + result = TILEP_BASE_DRACONIAN + colour_offset * 2; + hair = 0; + int st = tile_player_part_start[TILEP_PART_DRCHEAD]; + parts[TILEP_PART_DRCHEAD] = st + colour_offset; + if (player_mutation_level(MUT_BIG_WINGS)) { - int st = tile_player_part_start[TILEP_PART_DRCWING]; - parts[TILEP_PART_DRCWING] = st + _draconian_colour(race, level); + st = tile_player_part_start[TILEP_PART_DRCWING]; + parts[TILEP_PART_DRCWING] = st + colour_offset; } - - result = TILEP_BASE_DRACONIAN + _draconian_colour(race, level) * 2; - break; - - case SP_CENTAUR: - result = TILEP_BASE_CENTAUR; - break; - case SP_DEMIGOD: - result = TILEP_BASE_DEMIGOD; - break; - case SP_SPRIGGAN: - result = TILEP_BASE_SPRIGGAN; break; + } case SP_MINOTAUR: - result = TILEP_BASE_MINOTAUR; - hair = 0; + hair = 0; break; case SP_DEMONSPAWN: - result = TILEP_BASE_DEMONSPAWN; - hair = 0; + hair = 0; break; case SP_GHOUL: - result = TILEP_BASE_GHOUL; - hair = 0; - break; - case SP_KENKU: - result = TILEP_BASE_KENKU; + hair = 0; break; case SP_MERFOLK: result = player_in_water() ? TILEP_BASE_MERFOLK_WATER : TILEP_BASE_MERFOLK; break; case SP_VAMPIRE: - result = TILEP_BASE_VAMPIRE; if (gender == TILEP_GENDER_MALE) hair = TILEP_HAIR_ARAGORN; else hair = TILEP_HAIR_ARWEN; break; case SP_DEEP_DWARF: - result = TILEP_BASE_DEEP_DWARF; if (gender == TILEP_GENDER_MALE) { hair = TILEP_HAIR_SHORT_WHITE; @@ -2924,36 +2969,34 @@ void tilep_race_default(int race, int gender, int level, int *parts) } break; default: - result = TILEP_BASE_HUMAN; + // nothing to do break; } - if (gender == TILEP_GENDER_MALE) - result++; parts[TILEP_PART_BASE] = result; - parts[TILEP_PART_HAIR] = hair; - parts[TILEP_PART_BEARD] = beard; + // Don't overwrite doll parts defined elsewhere. + if (hair == 0 || parts[TILEP_PART_HAIR] == TILEP_SHOW_EQUIP) + parts[TILEP_PART_HAIR] = hair; + if (beard == 0 || parts[TILEP_PART_BEARD] == TILEP_SHOW_EQUIP) + parts[TILEP_PART_BEARD] = beard; parts[TILEP_PART_SHADOW] = TILEP_SHADOW_SHADOW; } void tilep_job_default(int job, int gender, int *parts) { - parts[TILEP_PART_CLOAK] = 0; - parts[TILEP_PART_BOOTS] = 0; - parts[TILEP_PART_LEG] = 0; - parts[TILEP_PART_BODY] = 0; - parts[TILEP_PART_ARM] = 0; - parts[TILEP_PART_HAND1] = 0; - parts[TILEP_PART_HAND2] = 0; - parts[TILEP_PART_HELM] = 0; + parts[TILEP_PART_CLOAK] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_BOOTS] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_LEG] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_BODY] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_ARM] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; + parts[TILEP_PART_HELM] = TILEP_SHOW_EQUIP; switch (job) { case JOB_FIGHTER: - parts[TILEP_PART_BODY] = TILEP_SHOW_EQUIP; parts[TILEP_PART_LEG] = TILEP_LEG_METAL_SILVER; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; break; case JOB_CRUSADER: @@ -2963,8 +3006,6 @@ void tilep_job_default(int job, int gender, int *parts) parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_GRAY; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_BLUE; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; break; case JOB_PALADIN: @@ -2974,8 +3015,6 @@ void tilep_job_default(int job, int gender, int *parts) parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_GRAY; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_BLUE; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; break; case JOB_DEATH_KNIGHT: @@ -2984,7 +3023,6 @@ void tilep_job_default(int job, int gender, int *parts) parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_OFS; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_BLACK; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_YELLOW; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_BLACK; break; @@ -2993,22 +3031,17 @@ void tilep_job_default(int job, int gender, int *parts) parts[TILEP_PART_LEG] = TILEP_LEG_METAL_GRAY; parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_PLUME; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; break; case JOB_BERSERKER: parts[TILEP_PART_BODY] = TILEP_BODY_ANIMAL_SKIN; parts[TILEP_PART_LEG] = TILEP_LEG_BELT_REDBROWN; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; break; case JOB_REAVER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BLACK_GOLD; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BROWN; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_RED_DIM; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; @@ -3055,7 +3088,6 @@ void tilep_job_default(int job, int gender, int *parts) case JOB_PRIEST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_WHITE; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WHITE; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; @@ -3158,7 +3190,6 @@ void tilep_job_default(int job, int gender, int *parts) break; case JOB_GLADIATOR: - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; parts[TILEP_PART_HAND2] = TILEP_HAND2_SHIELD_ROUND2; if (gender == TILEP_GENDER_MALE) @@ -3177,17 +3208,19 @@ void tilep_job_default(int job, int gender, int *parts) case JOB_MONK: parts[TILEP_PART_BODY] = TILEP_BODY_MONK_BLACK; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; break; case JOB_WANDERER: parts[TILEP_PART_BODY] = TILEP_BODY_SHIRT_HAWAII; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_SHORT_BROWN; - parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; - parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN3; break; + + case JOB_ARTIFICER: + parts[TILEP_PART_HAND1] = TILEP_HAND1_SCEPTRE; + parts[TILEP_PART_BODY] = TILEP_BODY_LEATHER_ARMOUR3; + parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BLACK; + break; } } @@ -3206,7 +3239,7 @@ void tilep_part_to_str(int number, char *buf) //normal 2 digits buf[0] = '0' + (number/100) % 10; buf[1] = '0' + (number/ 10) % 10; - buf[2] = '0' + number % 10; + buf[2] = '0' + number % 10; } buf[3] ='\0'; } @@ -3220,7 +3253,7 @@ int tilep_str_to_part(char *str) if (str[0] == '*') return TILEP_SHOW_EQUIP; - //normal 2 digits + //normal 3 digits return atoi(str); } @@ -3251,7 +3284,6 @@ void tilep_scan_parts(char *fbuf, int *parts) int ccount = 0; for (int i = 0; parts_saved[i] != -1; i++) { - int idx; ccount = 0; int p = parts_saved[i]; @@ -3264,23 +3296,23 @@ void tilep_scan_parts(char *fbuf, int *parts) ibuf[ccount] = '\0'; gcount++; - idx = tilep_str_to_part(ibuf); + int idx = tilep_str_to_part(ibuf); if (p == TILEP_PART_BASE) - { - int p0 = (parts[p]-1) & (0xfe); - if (((1-idx) & 1) == 1) - p0++; - parts[p] = p0 + 1; - } - else if (idx == TILEP_SHOW_EQUIP) - parts[p] = TILEP_SHOW_EQUIP; - else if (idx < 0) + parts[p] = tilep_species_to_base_tile() + idx % 2; + else if (idx == 0) parts[p] = 0; - // TODO enne - is this right? did the old count end at idx not just subtotal? + else if (idx == TILEP_SHOW_EQUIP) + continue; else if (idx > tile_player_part_count[p]) - parts[p] = tile_player_part_count[p]; + parts[p] = tile_player_part_start[p]; else - parts[p] = idx; + { + int idx2 = tile_player_part_start[p] + idx - 1; + if (idx2 < TILE_MAIN_MAX || idx2 >= TILEP_PLAYER_MAX) + parts[p] = TILEP_SHOW_EQUIP; + else + parts[p] = idx2; + } } } @@ -3289,21 +3321,25 @@ void tilep_scan_parts(char *fbuf, int *parts) */ void tilep_print_parts(char *fbuf, int *parts) { - int i; char *ptr = fbuf; - for (i = 0; parts_saved[i] != -1; i++) + for (unsigned i = 0; parts_saved[i] != -1; ++i) { int p = parts_saved[i]; - if (p == TILEP_PART_BASE) // 0:female 1:male - { - sprintf(ptr, "%03d", parts[p]%2); - ptr += 3; - } + if (p == TILEP_PART_BASE) // 0: female 1: male + sprintf(ptr, "%03d", get_gender_from_tile(parts)); else { - tilep_part_to_str(parts[p], ptr); - ptr += 3; + int idx = parts[p]; + if (idx != 0 && idx != TILEP_SHOW_EQUIP) + { + idx = parts[p] - tile_player_part_start[p] + 1; + if (idx < 0 || idx > tile_player_part_count[p]) + idx = 0; + } + tilep_part_to_str(idx, ptr); } + ptr += 3; + *ptr = ':'; ptr++; } diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 84a471fd8f..ce6177465f 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -13,11 +13,13 @@ REVISION("$Rev$"); #include "cio.h" #include "debug.h" #include "describe.h" +#include "files.h" #include "food.h" #include "itemname.h" #include "it_use2.h" #include "item_use.h" #include "items.h" +#include "macro.h" #include "message.h" #include "misc.h" #include "menu.h" @@ -291,34 +293,174 @@ void DungeonRegion::pack_background(unsigned int bg, int x, int y) m_buf_dngn.add(TILE_RAY_OUT_OF_RANGE, x, y); } -void DungeonRegion::pack_player(int x, int y) +#define NUM_MAX_DOLLS 10 +static dolls_data player_doll; +static int gender = -1; + +enum tile_doll_mode { - dolls_data default_doll; - dolls_data player_doll; - dolls_data result; + TILEP_MODE_EQUIP = 0, // draw doll based on equipment + TILEP_MODE_LOADING = 1, // draw doll based on dolls.txt definitions + TILEP_MODE_DEFAULT = 2 // draw doll based on job specific definitions +}; - for (int i = 0; i < TILEP_PART_MAX; i++) - default_doll.parts[i] = TILEP_SHOW_EQUIP; +// Loads player doll definitions from (by default) dolls.txt. +// Returns true if file found, else false. +static bool _load_doll_data(const char *fn, dolls_data *dolls, int max, + int *mode, int *cur) +{ + char fbuf[1024]; + FILE *fp = NULL; + + std::string dollsTxtString = datafile_path(fn, false, true); + const char *dollsTxt = (dollsTxtString.c_str()[0] == 0) ? + "dolls.txt" : dollsTxtString.c_str(); + + if ( (fp = fopen(dollsTxt, "r")) == NULL ) + { + // File doesn't exist. By default, use equipment settings. + *mode = TILEP_MODE_EQUIP; + return (false); + } + else + { + memset(fbuf, 0, sizeof(fbuf)); + // Read mode from file. + if (fscanf(fp, "%s", fbuf) != EOF) + { + if (strcmp(fbuf, "MODE=DEFAULT") == 0) + *mode = (int) TILEP_MODE_DEFAULT; + else if (strcmp(fbuf, "MODE=EQUIP") == 0) + *mode = TILEP_MODE_EQUIP; // Nothing else to be done. + } + // Read current doll from file. + if (fscanf(fp, "%s", fbuf) != EOF) + { + if (strncmp(fbuf, "NUM=", 4) == 0) + { + sscanf(fbuf, "NUM=%d", cur); + if (*cur < 0 || *cur >= NUM_MAX_DOLLS) + *cur = 0; + } + } + + if (max == 1) + { + // Load only one doll, either the one defined by NUM or + // use the default/equipment setting. + if (*mode != TILEP_MODE_LOADING) + { + if (gender == -1) + gender = coinflip(); + + if (*mode == TILEP_MODE_DEFAULT) + tilep_job_default(you.char_class, gender, dolls[0].parts); + + // If we don't need to load a doll, return now. + fclose(fp); + return (true); + } + + int count = 0; + while (fscanf(fp, "%s", fbuf) != EOF) + { + if (*cur == count++) + { + tilep_scan_parts(fbuf, dolls[0].parts); + gender = get_gender_from_tile(dolls[0].parts); + break; + } + } + if (*cur >= count) + { + mprf(MSGCH_WARN, "Doll %d could not be found in '%s'.", + *cur, dollsTxt); + } + } + else // Load up to max dolls from file. + { + for (int count = 0; count < max && fscanf(fp, "%s", fbuf) != EOF; + ++count) + { + tilep_scan_parts(fbuf, dolls[count].parts); + } + } + + fclose(fp); + return (true); + } +} + +void init_player_doll() +{ + dolls_data default_doll[1]; + + for (unsigned int i = 0; i < TILEP_PART_MAX; ++i) + default_doll[0].parts[i] = TILEP_SHOW_EQUIP; - int gender = you.your_name[0] % 2; + default_doll[0].parts[TILEP_PART_BASE] + = tilep_species_to_base_tile(you.species, you.experience_level); + mprf("gender 1: %d", gender); + int mode = TILEP_MODE_LOADING; + int cur = 0; + _load_doll_data("dolls.txt", default_doll, 1, &mode, &cur); + mprf("gender 2: %d", gender); + + if (gender == -1) + gender = coinflip(); + + mprf("gender 3: %d", gender); tilep_race_default(you.species, gender, you.experience_level, - default_doll.parts); + default_doll[0].parts); - result = default_doll; + mprf("gender 4: %d", gender); + player_doll = default_doll[0]; +} - result.parts[TILEP_PART_BASE] = default_doll.parts[TILEP_PART_BASE]; - result.parts[TILEP_PART_DRCHEAD] = default_doll.parts[TILEP_PART_DRCHEAD]; - result.parts[TILEP_PART_DRCWING] = default_doll.parts[TILEP_PART_DRCWING]; +static int _get_random_doll_part(int p) +{ + ASSERT(p >= 0 && p <= TILEP_PART_MAX); + return (tile_player_part_start[p] + + random2(tile_player_part_count[p])); +} - const bool halo = inside_halo(you.pos()); - result.parts[TILEP_PART_HALO] = halo ? TILEP_HALO_TSO : 0; - result.parts[TILEP_PART_ENCH] = - (you.duration[DUR_LIQUID_FLAMES] ? TILEP_ENCH_STICKY_FLAME : 0); +static void _fill_doll_part(dolls_data &doll, int p) +{ + ASSERT(p >= 0 && p <= TILEP_PART_MAX); + doll.parts[p] = _get_random_doll_part(p); +} + +static void _create_random_doll(dolls_data &rdoll) +{ + // All dolls roll for these. + _fill_doll_part(rdoll, TILEP_PART_BODY); + _fill_doll_part(rdoll, TILEP_PART_HAND1); + _fill_doll_part(rdoll, TILEP_PART_LEG); + _fill_doll_part(rdoll, TILEP_PART_BOOTS); + _fill_doll_part(rdoll, TILEP_PART_HAIR); + + // The following only are rolled with 50% chance. + if (coinflip()) + _fill_doll_part(rdoll, TILEP_PART_CLOAK); + if (coinflip()) + _fill_doll_part(rdoll, TILEP_PART_ARM); + if (coinflip()) + _fill_doll_part(rdoll, TILEP_PART_HAND2); + if (coinflip()) + _fill_doll_part(rdoll, TILEP_PART_HELM); + // Only male dolls get a chance at a beard. + if (rdoll.parts[TILEP_PART_BASE] % 2 == 1 && one_chance_in(4)) + _fill_doll_part(rdoll, TILEP_PART_BEARD); +} + +void _fill_doll_equipment(dolls_data &result) +{ + // Main hand. if (result.parts[TILEP_PART_HAND1] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_WEAPON]; + const int item = you.equip[EQ_WEAPON]; if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) result.parts[TILEP_PART_HAND1] = TILEP_HAND1_BLADEHAND; else if (item == -1) @@ -326,9 +468,10 @@ void DungeonRegion::pack_player(int x, int y) else result.parts[TILEP_PART_HAND1] = tilep_equ_weapon(you.inv[item]); } + // Off hand. if (result.parts[TILEP_PART_HAND2] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_SHIELD]; + const int item = you.equip[EQ_SHIELD]; if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) result.parts[TILEP_PART_HAND2] = TILEP_HAND2_BLADEHAND; else if (item == -1) @@ -336,25 +479,28 @@ void DungeonRegion::pack_player(int x, int y) else result.parts[TILEP_PART_HAND2] = tilep_equ_shield(you.inv[item]); } + // Body armour. if (result.parts[TILEP_PART_BODY] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_BODY_ARMOUR]; + const int item = you.equip[EQ_BODY_ARMOUR]; if (item == -1) result.parts[TILEP_PART_BODY] = 0; else result.parts[TILEP_PART_BODY] = tilep_equ_armour(you.inv[item]); } + // Cloak. if (result.parts[TILEP_PART_CLOAK] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_CLOAK]; + const int item = you.equip[EQ_CLOAK]; if (item == -1) result.parts[TILEP_PART_CLOAK] = 0; else result.parts[TILEP_PART_CLOAK] = tilep_equ_cloak(you.inv[item]); } + // Helmet. if (result.parts[TILEP_PART_HELM] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_HELMET]; + const int item = you.equip[EQ_HELMET]; if (item != -1) { result.parts[TILEP_PART_HELM] = tilep_equ_helm(you.inv[item]); @@ -379,10 +525,10 @@ void DungeonRegion::pack_player(int x, int y) result.parts[TILEP_PART_HELM] = 0; } } - + // Boots. if (result.parts[TILEP_PART_BOOTS] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_BOOTS]; + const int item = you.equip[EQ_BOOTS]; if (item != -1) result.parts[TILEP_PART_BOOTS] = tilep_equ_boots(you.inv[item]); else if (player_mutation_level(MUT_HOOVES)) @@ -390,10 +536,10 @@ void DungeonRegion::pack_player(int x, int y) else result.parts[TILEP_PART_BOOTS] = 0; } - + // Gloves. if (result.parts[TILEP_PART_ARM] == TILEP_SHOW_EQUIP) { - int item = you.equip[EQ_GLOVES]; + const int item = you.equip[EQ_GLOVES]; if (item != -1) result.parts[TILEP_PART_ARM] = tilep_equ_gloves(you.inv[item]); else if (you.has_claws(false) >= 3) @@ -402,13 +548,200 @@ void DungeonRegion::pack_player(int x, int y) result.parts[TILEP_PART_ARM] = 0; } + // Various other slots. if (result.parts[TILEP_PART_LEG] == TILEP_SHOW_EQUIP) result.parts[TILEP_PART_LEG] = 0; if (result.parts[TILEP_PART_DRCWING] == TILEP_SHOW_EQUIP) result.parts[TILEP_PART_DRCWING] = 0; if (result.parts[TILEP_PART_DRCHEAD] == TILEP_SHOW_EQUIP) result.parts[TILEP_PART_DRCHEAD] = 0; +} + +// Allow player to choose between up to 10 premade dolls, or replace them +// with the job default, using current equipment, or a random doll. +// If the player makes any changes while browsing the selections, i.e. +// overwrites a slot or changes the mode, these changes are saved back +// into dolls.txt. +// TODO: Change to proper menu. +void TilePlayerEdit() +{ + // Initialize equipment setting. + dolls_data equip_doll; + for (unsigned int i = 0; i < TILEP_PART_MAX; ++i) + equip_doll.parts[i] = TILEP_SHOW_EQUIP; + + mprf("gender: %d", gender); + tilep_race_default(you.species, gender, + you.experience_level, equip_doll.parts); + + // Initialize job default. + dolls_data default_doll = equip_doll; + tilep_job_default(you.char_class, gender, default_doll.parts); + + // Read predefined dolls from file. + dolls_data dolls[NUM_MAX_DOLLS]; + for (unsigned int i = 0; i < NUM_MAX_DOLLS; ++i) + dolls[i] = equip_doll; + + int old_mode = TILEP_MODE_LOADING; + int old_num = -1; + const bool found_file = _load_doll_data("dolls.txt", dolls, NUM_MAX_DOLLS, + &old_mode, &old_num); + int mode = old_mode; + int num = old_num; + + bool display_num = (found_file && mode == TILEP_MODE_LOADING); + bool dolls_changed = false; + bool did_random = false; + + while (true) + { + // Offer a list of choices. + std::vector<std::string> prompt; + prompt.push_back("Pick (d)efault doll for job, use (e)quipment settings"); + prompt.push_back("roll a (r)andom doll"); + if (found_file) + prompt.push_back("load doll (0-9) from file"); + if (did_random || mode != TILEP_MODE_LOADING) + prompt.push_back("(s)ave current doll"); + + std::string current = ""; + bool need_braces = false; + if (did_random || mode != TILEP_MODE_LOADING) + { + current = (did_random ? "random" : + mode == TILEP_MODE_EQUIP ? "equipment" : + mode == TILEP_MODE_DEFAULT ? "default" : "buggy"); + + need_braces = true; + } + + if (display_num) + { + snprintf(info, INFO_SIZE, "doll %d", num); + if (need_braces) + current += " ["; + current += info; + if (need_braces) + current += "]"; + } + + mprf(MSGCH_PROMPT, "%s? (Current: %s)", + comma_separated_line(prompt.begin(), + prompt.end(), ", or ", ", ").c_str(), + current.c_str()); + + char ch = (char) getchm(KMC_DEFAULT); + ch = tolower(ch); + + bool finish = false; + did_random = false; + if (ch == 'd') + { + player_doll = default_doll; + mode = TILEP_MODE_DEFAULT; + } + else if (ch == 'e') + { + player_doll = equip_doll; + mode = TILEP_MODE_EQUIP; + } + else if (ch == 'r') + { + dolls_data random_doll = equip_doll; + _create_random_doll(random_doll); + player_doll = random_doll; + did_random = true; + } + else if (ch == 's') + { + mpr("Save current doll to what slot? (0-9)", MSGCH_PROMPT); + const char ch2 = (char) getchm(KMC_DEFAULT); + if (ch2 >= '0' && ch2 <= '9') + { + const int slot = ch2 - '0'; + ASSERT(slot >= 0 && slot <= 9); + + // Translate TILEP_SHOW_EQUIP according to equipment. + _fill_doll_equipment(player_doll); + dolls[slot] = player_doll; + num = slot; + did_random = false; + dolls_changed = true; + display_num = true; + mprf("Doll saved to slot %d.", slot); + } + else + mpr("Doll not saved."); + more(); + } + else if (ch >= '0' && ch <= '9') + { + // HACK until I can find the proper function. + num = ch - '0'; + ASSERT(num >= 0 && num <= 9); + ASSERT(num < NUM_MAX_DOLLS); + + player_doll = dolls[num]; + mode = TILEP_MODE_LOADING; + display_num = true; + } + else // All other input exits the loop. + finish = true; + + gender = get_gender_from_tile(player_doll.parts); + + mesclr(); + + if (finish) + { + // No changes, nothing to be saved. + if (!dolls_changed && mode == old_mode && num == old_num) + break; + + // Save mode, num, and all dolls into dolls.txt. + std::string dollsTxtString = datafile_path("dolls.txt", false, true); + const char *dollsTxt = (dollsTxtString.c_str()[0] == 0) ? + "dolls.txt" : dollsTxtString.c_str(); + + FILE *fp = NULL; + if ( (fp = fopen(dollsTxt, "w+")) != NULL ) + { + fprintf(fp, "MODE=%s\n", + (mode == TILEP_MODE_EQUIP) ? "EQUIP" : + (mode == TILEP_MODE_LOADING) ? "LOADING" + : "DEFAULT"); + + fprintf(fp, "NUM=%02d\n", num == -1 ? 0 : num); + + char fbuf[80]; + for (unsigned int i = 0; i < NUM_MAX_DOLLS; ++i) + { + tilep_print_parts(fbuf, dolls[i].parts); + fprintf(fp, "%s\n", fbuf); + } + fclose(fp); + } + else + mprf(MSGCH_ERROR, "Could not write into file '%s'.", dollsTxt); + + break; + } + + viewwindow(true, false); + } +} + +void DungeonRegion::pack_player(int x, int y) +{ + dolls_data result = player_doll; + + const bool halo = inside_halo(you.pos()); + result.parts[TILEP_PART_HALO] = halo ? TILEP_HALO_TSO : 0; + result.parts[TILEP_PART_ENCH] = + (you.duration[DUR_LIQUID_FLAMES] ? TILEP_ENCH_STICKY_FLAME : 0); + _fill_doll_equipment(result); pack_doll(result, x, y); } @@ -447,7 +780,7 @@ void DungeonRegion::pack_doll(const dolls_data &doll, int x, int y) for (int i = 0; i < TILEP_PART_MAX; i++) { int p = p_order[i]; - if (!doll.parts[p]) + if (!doll.parts[p] || flags[p] == TILEP_FLAG_HIDE) continue; int ymax = TILE_Y; diff --git a/crawl-ref/source/tilereg.h b/crawl-ref/source/tilereg.h index 17bd2d56b3..231c5c3efb 100644 --- a/crawl-ref/source/tilereg.h +++ b/crawl-ref/source/tilereg.h @@ -439,6 +439,5 @@ protected: GenericTexture m_img; VertBuffer<PTVert> m_buf; }; - #endif #endif diff --git a/crawl-ref/source/tiles.h b/crawl-ref/source/tiles.h index 7e84bbc775..f678e3aa50 100644 --- a/crawl-ref/source/tiles.h +++ b/crawl-ref/source/tiles.h @@ -20,7 +20,7 @@ enum tag_version { TILETAG_PRE_MCACHE = 71, - TILETAG_CURRENT = 72 + TILETAG_CURRENT = 72 }; struct dolls_data @@ -57,7 +57,10 @@ int tileidx_monster_base(const monsters *mon, bool detected = false); int tileidx_monster(const monsters *mon, bool detected = false); // Player tile related -void tilep_race_default(int race, int gender, int level, int *parts); +int get_gender_from_tile(int parts[]); +int tilep_species_to_base_tile(int sp = you.species, + int level = you.experience_level); +void tilep_race_default(int sp, int gender, int level, int *parts); void tilep_job_default(int job, int gender, int *parts); void tilep_calc_flags(const int parts[], int flag[]); @@ -126,6 +129,7 @@ void TileNewLevel(bool first_time); // edit player tile void TilePlayerEdit(); +void init_player_doll(); int item_unid_type(const item_def &item); int tile_known_weapon_brand(const item_def item); @@ -138,45 +142,45 @@ int get_clean_map_idx(int tile_idx); enum tile_flags { // Foreground flags - TILE_FLAG_S_UNDER = 0x00000800, - TILE_FLAG_FLYING = 0x00001000, - TILE_FLAG_PET = 0x00002000, - TILE_FLAG_NEUTRAL = 0x00004000, - TILE_FLAG_STAB = 0x00008000, - TILE_FLAG_MAY_STAB = 0x0000C000, - TILE_FLAG_NET = 0x00010000, - TILE_FLAG_POISON = 0x00020000, - TILE_FLAG_FLAME = 0x00040000, - TILE_FLAG_ANIM_WEP = 0x00080000, + TILE_FLAG_S_UNDER = 0x00000800, + TILE_FLAG_FLYING = 0x00001000, + TILE_FLAG_PET = 0x00002000, + TILE_FLAG_NEUTRAL = 0x00004000, + TILE_FLAG_STAB = 0x00008000, + TILE_FLAG_MAY_STAB = 0x0000C000, + TILE_FLAG_NET = 0x00010000, + TILE_FLAG_POISON = 0x00020000, + TILE_FLAG_FLAME = 0x00040000, + TILE_FLAG_ANIM_WEP = 0x00080000, // MDAM has 5 possibilities, so uses 3 bits. - TILE_FLAG_MDAM_MASK = 0x03800000, - TILE_FLAG_MDAM_LIGHT= 0x00800000, - TILE_FLAG_MDAM_MOD = 0x01000000, - TILE_FLAG_MDAM_HEAVY= 0x01800000, - TILE_FLAG_MDAM_SEV = 0x02000000, - TILE_FLAG_MDAM_ADEAD= 0x02800000, + TILE_FLAG_MDAM_MASK = 0x03800000, + TILE_FLAG_MDAM_LIGHT = 0x00800000, + TILE_FLAG_MDAM_MOD = 0x01000000, + TILE_FLAG_MDAM_HEAVY = 0x01800000, + TILE_FLAG_MDAM_SEV = 0x02000000, + TILE_FLAG_MDAM_ADEAD = 0x02800000, // Background flags - TILE_FLAG_RAY = 0x00000800, - TILE_FLAG_MM_UNSEEN = 0x00001000, - TILE_FLAG_UNSEEN = 0x00002000, - TILE_FLAG_CURSOR1 = 0x00004000, - TILE_FLAG_CURSOR2 = 0x00008000, - TILE_FLAG_CURSOR3 = 0x0000C000, - TILE_FLAG_CURSOR = 0x0000C000, - TILE_FLAG_BLOOD = 0x00010000, - TILE_FLAG_HALO = 0x00020000, - TILE_FLAG_NEW_STAIR = 0x00040000, - TILE_FLAG_TRAV_EXCL = 0x00080000, - TILE_FLAG_EXCL_CTR = 0x00100000, - TILE_FLAG_SANCTUARY = 0x00200000, - TILE_FLAG_TUT_CURSOR= 0x00400000, - TILE_FLAG_RAY_OOR = 0x00800000, - TILE_FLAG_OOR = 0x01000000, + TILE_FLAG_RAY = 0x00000800, + TILE_FLAG_MM_UNSEEN = 0x00001000, + TILE_FLAG_UNSEEN = 0x00002000, + TILE_FLAG_CURSOR1 = 0x00004000, + TILE_FLAG_CURSOR2 = 0x00008000, + TILE_FLAG_CURSOR3 = 0x0000C000, + TILE_FLAG_CURSOR = 0x0000C000, + TILE_FLAG_BLOOD = 0x00010000, + TILE_FLAG_HALO = 0x00020000, + TILE_FLAG_NEW_STAIR = 0x00040000, + TILE_FLAG_TRAV_EXCL = 0x00080000, + TILE_FLAG_EXCL_CTR = 0x00100000, + TILE_FLAG_SANCTUARY = 0x00200000, + TILE_FLAG_TUT_CURSOR = 0x00400000, + TILE_FLAG_RAY_OOR = 0x00800000, + TILE_FLAG_OOR = 0x01000000, // General - TILE_FLAG_MASK = 0x000007FF + TILE_FLAG_MASK = 0x000007FF }; enum @@ -193,9 +197,9 @@ enum enum { - TILEP_GENDER_MALE = 0, - TILEP_GENDER_FEMALE = 1, - TILEP_SHOW_EQUIP = 0x1000 + TILEP_GENDER_FEMALE = 0, + TILEP_GENDER_MALE = 1, + TILEP_SHOW_EQUIP = 0x1000 }; enum tile_player_flag_cut diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc index 22d6f4d1e8..54b9749dc2 100644 --- a/crawl-ref/source/tilesdl.cc +++ b/crawl-ref/source/tilesdl.cc @@ -743,7 +743,12 @@ int TilesFramework::getch_ck() int key = 0; - const unsigned int ticks_per_redraw = 100; + // When moving the mouse via cursor when targeting update more often. + // For beams, the beam drawing already handles this, and when not targeting + // the normal drawing routines handle it. + const unsigned int ticks_per_redraw + = (mouse_control::current_mode() == MOUSE_MODE_TARGET ? 50 : 100); + unsigned int last_redraw_tick = 0; unsigned int res = Options.tile_tooltip_ms; |