summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-20 21:06:39 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-06-20 21:06:39 +0000
commit3884a47fb05f613b0cb617f09326b24b9a518576 (patch)
tree1865464950f23aaa2d41870ca61c55433eeeb65b
parent3ad6e28a57ab9cdbe139e6de12fb8a25c19d86cb (diff)
downloadcrawl-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_soup10
-rw-r--r--crawl-ref/settings/dolls.txt12
-rw-r--r--crawl-ref/source/acr.cc12
-rw-r--r--crawl-ref/source/cio.cc4
-rw-r--r--crawl-ref/source/cmd-keys.h3
-rw-r--r--crawl-ref/source/cmd-name.h5
-rw-r--r--crawl-ref/source/command.cc13
-rw-r--r--crawl-ref/source/debug.cc11
-rw-r--r--crawl-ref/source/directn.cc54
-rw-r--r--crawl-ref/source/enum.h15
-rw-r--r--crawl-ref/source/macro.cc9
-rw-r--r--crawl-ref/source/player.cc29
-rw-r--r--crawl-ref/source/tilepick.cc282
-rw-r--r--crawl-ref/source/tilereg.cc385
-rw-r--r--crawl-ref/source/tilereg.h1
-rw-r--r--crawl-ref/source/tiles.h80
-rw-r--r--crawl-ref/source/tilesdl.cc7
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;