summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2009-08-18 13:46:12 +0000
committerennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2009-08-18 13:46:12 +0000
commit1f0b02a561dc32e9d8781e7503cc6258bad2cd02 (patch)
treea0ad43341b4dea0356f0a80d9204bafc3dbeda1b /crawl-ref
parentcec34e68c2361ea28ceca489acd73e41d6a473c7 (diff)
downloadcrawl-ref-1f0b02a561dc32e9d8781e7503cc6258bad2cd02.tar.gz
crawl-ref-1f0b02a561dc32e9d8781e7503cc6258bad2cd02.zip
Reimplementing playing with dolls ('-' command). Keys are mostly the same as the 0.4 version and are documented.
Dolls are no longer limited in what features they can force, so your character can always look like a flaming centaur with wings if that's how you want to present yourself. This shouldn't cause any major breakage with save games or dolls.txt files, although expect some weirdness. Sorry. Also, fixed a bug where barding wasn't appearing on nagas or centaurs. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10568 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/changelog.txt1
-rw-r--r--crawl-ref/docs/tiles_help.txt16
-rw-r--r--crawl-ref/settings/dolls.txt24
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/cmd-keys.h30
-rw-r--r--crawl-ref/source/enum.h25
-rw-r--r--crawl-ref/source/files.cc2
-rw-r--r--crawl-ref/source/macro.cc5
-rw-r--r--crawl-ref/source/menu.cc17
-rw-r--r--crawl-ref/source/rltiles/dc-player.txt6
-rw-r--r--crawl-ref/source/tilepick.cc75
-rw-r--r--crawl-ref/source/tilereg.cc722
-rw-r--r--crawl-ref/source/tilereg.h57
-rw-r--r--crawl-ref/source/tiles.h13
-rw-r--r--crawl-ref/source/tilesdl.cc42
-rw-r--r--crawl-ref/source/tilesdl.h10
16 files changed, 731 insertions, 316 deletions
diff --git a/crawl-ref/docs/changelog.txt b/crawl-ref/docs/changelog.txt
index cdca868ef2..75af7c3a91 100644
--- a/crawl-ref/docs/changelog.txt
+++ b/crawl-ref/docs/changelog.txt
@@ -18,6 +18,7 @@ Stone Soup 0.6
* Add some tiles "animations" whenever the screen is redrawn.
* Unrandarts and randarts now share the same, cleaner coding structure.
* More vaults.
+* Tiles: re-added doll editing screen ('-' command).
Stone Soup 0.5.1 (20090728)
---------------------------
diff --git a/crawl-ref/docs/tiles_help.txt b/crawl-ref/docs/tiles_help.txt
index 3886ed0cb1..930ac6b90c 100644
--- a/crawl-ref/docs/tiles_help.txt
+++ b/crawl-ref/docs/tiles_help.txt
@@ -151,3 +151,19 @@ left mouseclick on line Select item, inventory menus only.
left mouseclick Scroll to next page.
right mouseclick Escape (quit menu).
+
+DOLL EDITING
+
+Shift + left/right keys Switch current doll.
+Ctrl + R Randomize current doll.
+left/right keys Change current part.
+m Change current doll usage mode.
+up/down keys Change current part category.
+Ctrl + C Copy current doll.
+Ctrl + V Paste current doll.
+t Remove current equipped part.
+T Remove all equipped parts
+* Toggle "show equipment".
+Ctrl + E Set all to show "show equipment".
+Ctrl + D Set current doll to job defaults.
+Escape Quit doll editing screen.
diff --git a/crawl-ref/settings/dolls.txt b/crawl-ref/settings/dolls.txt
index 1ccde89896..7bcc2265d0 100644
--- a/crawl-ref/settings/dolls.txt
+++ b/crawl-ref/settings/dolls.txt
@@ -1,16 +1,12 @@
MODE=EQUIP
NUM=00
-#Legend:
-#***:equipment/123:index/000:none
-#Shadow/Gender/Cloak/Boots/Legs/Body/Gloves/Weapon/Shield/Hair/Beard/Helmet
-#--:Sex:Clk:Bts:Leg:Bdy:Glv:Wpn:Shd:Hai:Brd:Hlm
-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
+***:***:***:011:034:092:***:023:034:017:000:063:***:***:***:***
+***:***:***:009:002:040:016:077:***:023:009:040:***:***:***:***
+***:020:***:014:017:046:020:048:***:010:000:041:***:***:***:***
+***:***:001:018:000:017:***:190:066:000:009:043:***:***:006:***
+***:***:005:003:016:137:***:117:005:000:000:***:***:***:***:***
+***:***:001:021:000:033:***:136:058:007:000:012:***:***:***:***
+***:***:003:014:000:005:***:194:041:017:000:028:***:***:***:***
+***:***:***:017:027:068:***:197:050:011:000:068:***:***:***:***
+***:018:008:022:033:091:007:055:027:008:000:054:***:***:***:***
+***:***:007:***:026:015:020:170:057:011:000:032:001:***:***:***
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 80d1f5d0a2..f43a5130f4 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1350,7 +1350,7 @@ void process_command( command_type cmd )
{
#ifdef USE_TILE
case CMD_EDIT_PLAYER_TILE:
- TilePlayerEdit();
+ tiles.draw_doll_edit();
break;
#endif
diff --git a/crawl-ref/source/cmd-keys.h b/crawl-ref/source/cmd-keys.h
index 82cb9e4a17..234f369ff3 100644
--- a/crawl-ref/source/cmd-keys.h
+++ b/crawl-ref/source/cmd-keys.h
@@ -307,4 +307,34 @@
{'T', CMD_MAP_WIZARD_TELEPORT},
#endif
+#ifdef USE_TILE
+{CONTROL('R'), CMD_DOLL_RANDOMIZE},
+{'H', CMD_DOLL_SELECT_PREV_DOLL},
+{'L', CMD_DOLL_SELECT_NEXT_DOLL},
+{CK_SHIFT_LEFT, CMD_DOLL_SELECT_PREV_DOLL},
+{CK_SHIFT_RIGHT, CMD_DOLL_SELECT_NEXT_DOLL},
+{'k', CMD_DOLL_SELECT_PREV_PART},
+{'j', CMD_DOLL_SELECT_NEXT_PART},
+{'h', CMD_DOLL_CHANGE_PART_PREV},
+{'l', CMD_DOLL_CHANGE_PART_NEXT},
+{CK_UP, CMD_DOLL_SELECT_PREV_PART},
+{CK_DOWN, CMD_DOLL_SELECT_NEXT_PART},
+{CK_LEFT, CMD_DOLL_CHANGE_PART_PREV},
+{CK_RIGHT, CMD_DOLL_CHANGE_PART_NEXT},
+{1008, CMD_DOLL_SELECT_PREV_PART},
+{1002, CMD_DOLL_SELECT_NEXT_PART},
+{1004, CMD_DOLL_CHANGE_PART_PREV},
+{1006, CMD_DOLL_CHANGE_PART_NEXT},
+{CONTROL('C'), CMD_DOLL_COPY},
+{CONTROL('V'), CMD_DOLL_PASTE},
+{'t', CMD_DOLL_TAKE_OFF},
+{CONTROL('T'), CMD_DOLL_TAKE_OFF_ALL},
+{'*', CMD_DOLL_TOGGLE_EQUIP},
+{CONTROL('E'), CMD_DOLL_TOGGLE_EQUIP_ALL},
+{CONTROL('D'), CMD_DOLL_CLASS_DEFAULT},
+{'m', CMD_DOLL_CHANGE_MODE},
+{ESCAPE, CMD_DOLL_QUIT},
+{'q', CMD_DOLL_QUIT},
+#endif
+
{'\0', CMD_NO_CMD}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 534d78c36a..dc22a50d6e 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -680,6 +680,28 @@ enum command_type
CMD_TARGET_HELP,
CMD_MAX_TARGET = CMD_TARGET_HELP,
+#ifdef USE_TILE
+ // Tile doll editing screen
+ CMD_DOLL_RANDOMIZE,
+ CMD_MIN_DOLL = CMD_DOLL_RANDOMIZE,
+ CMD_DOLL_SELECT_NEXT_DOLL,
+ CMD_DOLL_SELECT_PREV_DOLL,
+ CMD_DOLL_SELECT_NEXT_PART,
+ CMD_DOLL_SELECT_PREV_PART,
+ CMD_DOLL_CHANGE_PART_NEXT,
+ CMD_DOLL_CHANGE_PART_PREV,
+ CMD_DOLL_COPY,
+ CMD_DOLL_PASTE,
+ CMD_DOLL_TAKE_OFF,
+ CMD_DOLL_TAKE_OFF_ALL,
+ CMD_DOLL_TOGGLE_EQUIP,
+ CMD_DOLL_TOGGLE_EQUIP_ALL,
+ CMD_DOLL_CLASS_DEFAULT,
+ CMD_DOLL_CHANGE_MODE,
+ CMD_DOLL_QUIT,
+ CMD_MAX_DOLL = CMD_DOLL_QUIT,
+#endif
+
// Disable/enable -more- prompts.
CMD_DISABLE_MORE,
CMD_MIN_SYNTHETIC = CMD_DISABLE_MORE,
@@ -1489,6 +1511,9 @@ enum KeymapContext
KMC_TARGETING, // Only during 'x' and other targeting modes
KMC_CONFIRM, // When being asked y/n/q questions
KMC_MENU, // For menus
+#ifdef USE_TILE
+ KMC_DOLL, // For the tiles doll menu editing screen
+#endif
KMC_CONTEXT_COUNT, // Must always be the last real context
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 67bf806c93..0e56c969ca 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -624,7 +624,7 @@ static void _fill_player_doll(player_save_info &p, const std::string &dollfile)
memset(fbuf, 0, sizeof(fbuf));
if (fscanf(fdoll, "%s", fbuf) != EOF)
{
- tilep_scan_parts(fbuf, equip_doll.parts);
+ tilep_scan_parts(fbuf, equip_doll);
tilep_race_default(p.species,
get_gender_from_tile(equip_doll.parts),
p.experience_level,
diff --git a/crawl-ref/source/macro.cc b/crawl-ref/source/macro.cc
index 44f4c8b7a3..d6b998cc83 100644
--- a/crawl-ref/source/macro.cc
+++ b/crawl-ref/source/macro.cc
@@ -1133,6 +1133,11 @@ KeymapContext context_for_command(command_type cmd)
if (cmd >= CMD_MIN_TARGET && cmd <= CMD_MAX_TARGET)
return KMC_TARGETING;
+#ifdef USE_TILE
+ if (cmd >= CMD_MIN_DOLL && cmd <= CMD_MAX_DOLL)
+ return KMC_DOLL;
+#endif
+
return KMC_NONE;
}
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index 8dfe5bc842..693bda8be6 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -880,6 +880,23 @@ bool PlayerMenuEntry::get_tiles(std::vector<tile_def>& tileset) const
p_order[7] = TILEP_PART_LEG;
}
+ // Special case bardings from being cut off.
+ bool is_naga = (equip_doll.parts[TILEP_PART_BASE] == TILEP_BASE_NAGA
+ || equip_doll.parts[TILEP_PART_BASE] == TILEP_BASE_NAGA + 1);
+ if (equip_doll.parts[TILEP_PART_BOOTS] >= TILEP_BOOTS_NAGA_BARDING
+ && equip_doll.parts[TILEP_PART_BOOTS] <= TILEP_BOOTS_NAGA_BARDING_RED)
+ {
+ flags[TILEP_PART_BOOTS] = is_naga ? TILEP_FLAG_NORMAL : TILEP_FLAG_HIDE;
+ }
+
+ bool is_cent = (equip_doll.parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR
+ || equip_doll.parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR + 1);
+ if (equip_doll.parts[TILEP_PART_BOOTS] >= TILEP_BOOTS_CENTAUR_BARDING
+ && equip_doll.parts[TILEP_PART_BOOTS] <= TILEP_BOOTS_CENTAUR_BARDING_RED)
+ {
+ flags[TILEP_PART_BOOTS] = is_cent ? TILEP_FLAG_NORMAL : TILEP_FLAG_HIDE;
+ }
+
for (int i = 0; i < TILEP_PART_MAX; ++i)
{
const int p = p_order[i];
diff --git a/crawl-ref/source/rltiles/dc-player.txt b/crawl-ref/source/rltiles/dc-player.txt
index e6366c51df..0075f22f41 100644
--- a/crawl-ref/source/rltiles/dc-player.txt
+++ b/crawl-ref/source/rltiles/dc-player.txt
@@ -5,6 +5,10 @@
%include dc-demon.txt
%include dc-mon.txt
+effect/net_trap TRAP_NET
+dc-misc/error ERROR
+dc-misc/cursor CURSOR
+
%rim 1
###BASE
@@ -866,5 +870,3 @@ drchead_red RED
drchead_white WHITE
%end
-effect/net_trap TRAP_NET
-dc-misc/error ERROR
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 8b822bab64..2bbb7014ec 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -30,6 +30,7 @@ REVISION("$Rev$");
#include "tiles.h"
#include "tilemcache.h"
#include "tiledef-dngn.h"
+#include "tiledef-player.h"
#include "tiledef-unrand.h"
#include "transfor.h"
#include "traps.h"
@@ -2826,8 +2827,12 @@ static int _draconian_colour(int race, int level)
int get_gender_from_tile(int parts[])
{
- return ((parts[TILEP_PART_BASE]
- - tile_player_part_start[TILEP_PART_BASE]) % 2);
+ int gender = ((parts[TILEP_PART_BASE]
+ - tile_player_part_start[TILEP_PART_BASE]) % 2);
+
+ if (gender == TILEP_GENDER_MALE || gender == TILEP_GENDER_FEMALE)
+ return gender;
+ return TILEP_GENDER_FEMALE;
}
int tilep_species_to_base_tile(int sp, int level)
@@ -2901,10 +2906,11 @@ void tilep_race_default(int sp, int gender, int level, int *parts)
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;
+ int wing = 0;
+ int head = 0;
if (gender == TILEP_GENDER_MALE)
hair = TILEP_HAIR_SHORT_BLACK;
@@ -2961,12 +2967,12 @@ void tilep_race_default(int sp, int gender, int level, int *parts)
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;
+ head = st + colour_offset;
if (player_mutation_level(MUT_BIG_WINGS))
{
st = tile_player_part_start[TILEP_PART_DRCWING];
- parts[TILEP_PART_DRCWING] = st + colour_offset;
+ wing = st + colour_offset;
}
break;
}
@@ -3007,12 +3013,18 @@ void tilep_race_default(int sp, int gender, int level, int *parts)
}
parts[TILEP_PART_BASE] = result;
+
// Don't overwrite doll parts defined elsewhere.
- if (hair == 0 || parts[TILEP_PART_HAIR] == TILEP_SHOW_EQUIP)
+ if (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;
+ if (parts[TILEP_PART_BEARD] == TILEP_SHOW_EQUIP)
+ parts[TILEP_PART_BEARD] = beard;
+ if (parts[TILEP_PART_SHADOW] == TILEP_SHOW_EQUIP)
+ parts[TILEP_PART_SHADOW] = TILEP_SHADOW_SHADOW;
+ if (parts[TILEP_PART_DRCHEAD] == TILEP_SHOW_EQUIP)
+ parts[TILEP_PART_DRCHEAD] = head;
+ if (parts[TILEP_PART_DRCWING] == TILEP_SHOW_EQUIP)
+ parts[TILEP_PART_DRCWING] = wing;
}
void tilep_job_default(int job, int gender, int *parts)
@@ -3290,7 +3302,10 @@ int tilep_str_to_part(char *str)
return atoi(str);
}
-const int parts_saved[] ={
+// This order is to preserve dolls.txt integrity over multiple versions.
+// Newer entries should be added to the end before the -1 terminator.
+const int parts_saved[TILEP_PART_MAX + 1] =
+{
TILEP_PART_SHADOW,
TILEP_PART_BASE,
TILEP_PART_CLOAK,
@@ -3305,13 +3320,15 @@ const int parts_saved[] ={
TILEP_PART_HELM,
TILEP_PART_HALO,
TILEP_PART_ENCH,
+ TILEP_PART_DRCWING,
+ TILEP_PART_DRCHEAD,
-1
};
/*
* scan input line from dolls.txt
*/
-void tilep_scan_parts(char *fbuf, int *parts)
+void tilep_scan_parts(char *fbuf, dolls_data &doll)
{
char ibuf[8];
@@ -3332,21 +3349,19 @@ void tilep_scan_parts(char *fbuf, int *parts)
gcount++;
int idx = tilep_str_to_part(ibuf);
- if (p == TILEP_PART_BASE)
- parts[p] = tilep_species_to_base_tile() + idx % 2;
- else if (idx == 0)
- parts[p] = 0;
+ if (idx == 0)
+ doll.parts[p] = 0;
else if (idx == TILEP_SHOW_EQUIP)
- continue;
+ doll.parts[p] = TILEP_SHOW_EQUIP;
else if (idx > tile_player_part_count[p])
- parts[p] = tile_player_part_start[p];
+ doll.parts[p] = tile_player_part_start[p];
else
{
int idx2 = tile_player_part_start[p] + idx - 1;
if (idx2 < TILE_MAIN_MAX || idx2 >= TILEP_PLAYER_MAX)
- parts[p] = TILEP_SHOW_EQUIP;
+ doll.parts[p] = TILEP_SHOW_EQUIP;
else
- parts[p] = idx2;
+ doll.parts[p] = idx2;
}
}
}
@@ -3354,28 +3369,20 @@ void tilep_scan_parts(char *fbuf, int *parts)
/*
* format-print parts
*/
-void tilep_print_parts(char *fbuf, int *parts, bool check_halo)
+void tilep_print_parts(char *fbuf, const dolls_data &doll)
{
char *ptr = fbuf;
for (unsigned i = 0; parts_saved[i] != -1; ++i)
{
- if (!check_halo && parts_saved[i] == TILEP_PART_HALO)
- break;
-
int p = parts_saved[i];
- if (p == TILEP_PART_BASE) // 0: female 1: male
- sprintf(ptr, "%03d", get_gender_from_tile(parts));
- else
+ int idx = doll.parts[p];
+ if (idx != 0 && idx != TILEP_SHOW_EQUIP)
{
- 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);
+ idx = doll.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 = ':';
diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc
index 7ca7a2efbc..7e559d1b79 100644
--- a/crawl-ref/source/tilereg.cc
+++ b/crawl-ref/source/tilereg.cc
@@ -301,21 +301,49 @@ void DungeonRegion::pack_background(unsigned int bg, int x, int y)
}
}
-#define NUM_MAX_DOLLS 10
static dolls_data player_doll;
static int gender = -1;
-enum tile_doll_mode
+// Saves player doll definitions into dolls.txt.
+// Returns true if successful, else false.
+static bool _save_doll_data(int mode, int num, const dolls_data* dolls)
{
- 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
-};
+ // 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]);
+ fprintf(fp, "%s\n", fbuf);
+ }
+ fclose(fp);
+
+ return (true);
+ }
+ else
+ {
+ mprf(MSGCH_ERROR, "Could not write into file '%s'.", dollsTxt);
+ return (false);
+ }
+}
// 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)
+ tile_doll_mode *mode, int *cur)
{
char fbuf[1024];
FILE *fp = NULL;
@@ -337,7 +365,7 @@ static bool _load_doll_data(const char *fn, dolls_data *dolls, int max,
if (fscanf(fp, "%s", fbuf) != EOF)
{
if (strcmp(fbuf, "MODE=DEFAULT") == 0)
- *mode = (int) TILEP_MODE_DEFAULT;
+ *mode = TILEP_MODE_DEFAULT;
else if (strcmp(fbuf, "MODE=EQUIP") == 0)
*mode = TILEP_MODE_EQUIP; // Nothing else to be done.
}
@@ -377,7 +405,7 @@ static bool _load_doll_data(const char *fn, dolls_data *dolls, int max,
if (*cur == count++)
{
- tilep_scan_parts(fbuf, dolls[0].parts);
+ tilep_scan_parts(fbuf, dolls[0]);
gender = get_gender_from_tile(dolls[0].parts);
break;
}
@@ -395,7 +423,7 @@ static bool _load_doll_data(const char *fn, dolls_data *dolls, int max,
if (fbuf[0] == '#') // Skip comment lines.
continue;
- tilep_scan_parts(fbuf, dolls[count++].parts);
+ tilep_scan_parts(fbuf, dolls[count++]);
}
}
@@ -406,25 +434,33 @@ static bool _load_doll_data(const char *fn, dolls_data *dolls, int max,
void init_player_doll()
{
- dolls_data default_doll[1];
+ dolls_data dolls[NUM_MAX_DOLLS];
- for (unsigned int i = 0; i < TILEP_PART_MAX; ++i)
- default_doll[0].parts[i] = TILEP_SHOW_EQUIP;
+ for (int i = 0; i < NUM_MAX_DOLLS; i++)
+ for (int j = 0; j < TILEP_PART_MAX; j++)
+ dolls[i].parts[j] = TILEP_SHOW_EQUIP;
- default_doll[0].parts[TILEP_PART_BASE]
- = tilep_species_to_base_tile(you.species, you.experience_level);
+ tile_doll_mode mode = TILEP_MODE_LOADING;
+ int cur = 0;
+ _load_doll_data("dolls.txt", dolls, NUM_MAX_DOLLS, &mode, &cur);
- int mode = TILEP_MODE_LOADING;
- int cur = 0;
- _load_doll_data("dolls.txt", default_doll, 1, &mode, &cur);
+ if (mode == TILEP_MODE_LOADING)
+ {
+ player_doll = dolls[cur];
+ return;
+ }
if (gender == -1)
gender = coinflip();
- tilep_race_default(you.species, gender, you.experience_level,
- default_doll[0].parts);
+ for (int i = 0; i < TILEP_PART_MAX; i++)
+ player_doll.parts[i] = TILEP_SHOW_EQUIP;
+ tilep_race_default(you.species, gender, you.experience_level, player_doll.parts);
+
+ if (mode == TILEP_MODE_EQUIP)
+ return;
- player_doll = default_doll[0];
+ tilep_job_default(you.char_class, gender, player_doll.parts);
}
static int _get_random_doll_part(int p)
@@ -466,6 +502,15 @@ static void _create_random_doll(dolls_data &rdoll)
static void _fill_doll_equipment(dolls_data &result)
{
+ // Base tile.
+ if (result.parts[TILEP_PART_BASE] == TILEP_SHOW_EQUIP)
+ {
+ if (gender == -1)
+ gender = get_gender_from_tile(player_doll.parts);
+ tilep_race_default(you.species, gender, you.experience_level,
+ result.parts);
+ }
+
// Main hand.
if (result.parts[TILEP_PART_HAND1] == TILEP_SHOW_EQUIP)
{
@@ -556,14 +601,25 @@ static void _fill_doll_equipment(dolls_data &result)
else
result.parts[TILEP_PART_ARM] = 0;
}
+ // Halo.
+ if (result.parts[TILEP_PART_HALO] == TILEP_SHOW_EQUIP)
+ {
+ const bool halo = inside_halo(you.pos());
+ result.parts[TILEP_PART_HALO] = halo ? TILEP_HALO_TSO : 0;
+ }
+ // Enchantments.
+ if (result.parts[TILEP_PART_ENCH] == TILEP_SHOW_EQUIP)
+ {
+ result.parts[TILEP_PART_ENCH] =
+ (you.duration[DUR_LIQUID_FLAMES] ? TILEP_ENCH_STICKY_FLAME : 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;
+ for (int i = 0; i < TILEP_PART_MAX; i++)
+ {
+ if (result.parts[i] == TILEP_SHOW_EQUIP)
+ result.parts[i] = 0;
+ }
}
// Writes equipment information into per-character doll file.
@@ -572,217 +628,25 @@ void save_doll_file(FILE *dollf)
ASSERT(dollf);
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);
// Write into file.
char fbuf[80];
- tilep_print_parts(fbuf, result.parts, true);
+ tilep_print_parts(fbuf, result);
fprintf(dollf, "%s\n", fbuf);
if (you.attribute[ATTR_HELD] > 0)
fprintf(dollf, "net\n");
}
-// 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;
-
- 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);
-
- // Print some explanatory comments. May contain no spaces!
- fprintf(fp, "#Legend:\n");
- fprintf(fp, "#***:equipment/123:index/000:none\n");
- fprintf(fp, "#Shadow/Gender/Cloak/Boots/Legs/Body/Gloves/Weapon/Shield/Hair/Beard/Helmet\n");
- fprintf(fp, "#--:Sex:Clk:Bts:Leg:Bdy:Glv:Wpn:Shd:Hai:Brd:Hlm\n");
-
- 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);
}
-void DungeonRegion::pack_doll(const dolls_data &doll, int x, int y)
+void pack_doll_buf(TileBuffer& buf, const dolls_data &doll, int x, int y)
{
int p_order[TILEP_PART_MAX] =
{
@@ -814,9 +678,27 @@ void DungeonRegion::pack_doll(const dolls_data &doll, int x, int y)
p_order[7] = TILEP_PART_LEG;
}
+ // Special case bardings from being cut off.
+ bool is_naga = (doll.parts[TILEP_PART_BASE] == TILEP_BASE_NAGA
+ || doll.parts[TILEP_PART_BASE] == TILEP_BASE_NAGA + 1);
+ if (doll.parts[TILEP_PART_BOOTS] >= TILEP_BOOTS_NAGA_BARDING
+ && doll.parts[TILEP_PART_BOOTS] <= TILEP_BOOTS_NAGA_BARDING_RED)
+ {
+ flags[TILEP_PART_BOOTS] = is_naga ? TILEP_FLAG_NORMAL : TILEP_FLAG_HIDE;
+ }
+
+ bool is_cent = (doll.parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR
+ || doll.parts[TILEP_PART_BASE] == TILEP_BASE_CENTAUR + 1);
+ if (doll.parts[TILEP_PART_BOOTS] >= TILEP_BOOTS_CENTAUR_BARDING
+ && doll.parts[TILEP_PART_BOOTS] <= TILEP_BOOTS_CENTAUR_BARDING_RED)
+ {
+ flags[TILEP_PART_BOOTS] = is_cent ? TILEP_FLAG_NORMAL : TILEP_FLAG_HIDE;
+ }
+
for (int i = 0; i < TILEP_PART_MAX; i++)
{
int p = p_order[i];
+
if (!doll.parts[p] || flags[p] == TILEP_FLAG_HIDE)
continue;
@@ -828,10 +710,16 @@ void DungeonRegion::pack_doll(const dolls_data &doll, int x, int y)
ymax = 18;
}
- m_buf_doll.add(doll.parts[p], x, y, 0, 0, true, ymax);
+ buf.add(doll.parts[p], x, y, 0, 0, true, ymax);
}
}
+void DungeonRegion::pack_doll(const dolls_data &doll, int x, int y)
+{
+ pack_doll_buf(m_buf_doll, doll, x, y);
+}
+
+
void DungeonRegion::pack_mcache(mcache_entry *entry, int x, int y)
{
ASSERT(entry);
@@ -2838,16 +2726,6 @@ void MessageRegion::set_overlay(bool is_overlay)
m_overlay = is_overlay;
}
-struct box_vert
-{
- float x;
- float y;
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
-};
-
void MessageRegion::render()
{
#ifdef DEBUG_TILES_REDRAW
@@ -3351,6 +3229,386 @@ void TitleRegion::render()
m_buf.draw();
}
+void TitleRegion::run()
+{
+ mouse_control mc(MOUSE_MODE_MORE);
+ getch();
+}
+
+DollEditRegion::DollEditRegion(ImageManager *im, FTFont *font) :
+ m_font_buf(font)
+{
+ sx = sy = 0;
+ dx = dy = 32;
+ mx = my = 1;
+
+ m_font = font;
+
+ m_doll_idx = 0;
+ m_cat_idx = TILEP_PART_BASE;
+ m_copy_valid = false;
+
+ m_tile_buf.set_tex(&im->m_textures[TEX_PLAYER]);
+ m_cur_buf.set_tex(&im->m_textures[TEX_PLAYER]);
+}
+
+void DollEditRegion::clear()
+{
+ m_shape_buf.clear();
+ m_tile_buf.clear();
+ m_cur_buf.clear();
+ m_font_buf.clear();
+}
+
+static int _get_next_part(int cat, int part, int inc)
+{
+ // Can't increment or decrement on show equip.
+ if (part == TILEP_SHOW_EQUIP)
+ {
+ return part;
+ }
+
+ // Increment max_part by 1 to include the special value of "none".
+ int max_part = tile_player_part_count[cat] + 1;
+ int offset = tile_player_part_start[cat];
+
+ ASSERT(inc > -max_part);
+
+ // Translate the "none" value into something we can do modulo math with.
+ if (part == 0)
+ {
+ part = offset;
+ inc--;
+ }
+
+ // Valid part numbers are in the range [offset, offset + max_part - 1].
+ int ret = (part + max_part + inc - offset) % (max_part);
+
+ if (ret == max_part - 1)
+ {
+ // "none" value.
+ return 0;
+ }
+ else
+ {
+ // Otherwise, valid part number.
+ return ret + offset;
+ }
+}
+
+void DollEditRegion::render()
+{
+#ifdef DEBUG_TILES_REDRAW
+ cprintf("rendering DollEditRegion\n");
+#endif
+ VColour grey(128, 128, 128, 255);
+
+ m_cur_buf.clear();
+ m_tile_buf.clear();
+ m_shape_buf.clear();
+ m_font_buf.clear();
+
+ // Max items to show at once.
+ const int max_show = 9;
+
+ // Layout options (units are in 32x32 squares)
+ const int left_gutter = 2;
+ const int item_line = 2;
+ const int edit_doll_line = 5;
+ const int doll_line = 8;
+ const int info_offset =
+ left_gutter + std::max(max_show, (int)NUM_MAX_DOLLS) + 1;
+
+ const int center_x = left_gutter + max_show / 2;
+
+ // Pack current doll separately so it can be drawn repeatedly.
+ {
+ dolls_data temp = m_dolls[m_doll_idx];
+ _fill_doll_equipment(temp);
+ pack_doll_buf(m_cur_buf, temp, 0, 0);
+ }
+
+ // Draw set of dolls.
+ for (int i = 0; i < NUM_MAX_DOLLS; i++)
+ {
+ int x = left_gutter + i;
+ int y = doll_line;
+
+ if (m_doll_idx == i)
+ m_tile_buf.add(TILEP_CURSOR, x, y);
+
+ dolls_data temp = m_dolls[i];
+ _fill_doll_equipment(temp);
+ pack_doll_buf(m_tile_buf, temp, x, y);
+
+ m_shape_buf.add(x, y, x + 1, y + 1, grey);
+ }
+
+ // Draw current category of parts.
+ int max_part = tile_player_part_count[m_cat_idx];
+ int show = std::min(max_show, max_part);
+ int half_show = show / 2;
+ for (int i = -half_show; i <= show - half_show; i++)
+ {
+ int x = center_x + i;
+ int y = item_line;
+
+ if (i == 0)
+ m_tile_buf.add(TILEP_CURSOR, x, y);
+
+ int part = _get_next_part(m_cat_idx, m_part_idx, i);
+ ASSERT(part != TILEP_SHOW_EQUIP);
+ if (part)
+ m_tile_buf.add(part, x, y);
+
+ m_shape_buf.add(x, y, x + 1, y + 1, grey);
+ }
+
+ m_shape_buf.add(left_gutter, edit_doll_line, left_gutter + 2, edit_doll_line + 2, grey);
+ m_shape_buf.add(left_gutter + 3, edit_doll_line, left_gutter + 4, edit_doll_line + 1, grey);
+
+ set_transform();
+ m_shape_buf.draw();
+ m_tile_buf.draw();
+
+ glLoadIdentity();
+ glTranslatef(32 * left_gutter, 32 * edit_doll_line, 0);
+ glScalef(64, 64, 1);
+ m_cur_buf.draw();
+
+ glLoadIdentity();
+ glTranslatef(32 * (left_gutter + 3), 32 * edit_doll_line, 0);
+ glScalef(32, 32, 1);
+ m_cur_buf.draw();
+
+ // Add text.
+ const char *part_name = "(none)";
+ if (m_part_idx == TILEP_SHOW_EQUIP)
+ part_name = "(show equip)";
+ else if (m_part_idx)
+ part_name = tile_player_name(m_part_idx);
+
+ glLoadIdentity();
+ glTranslatef(0, 0, 0);
+ glScalef(1, 1, 1);
+
+ std::string item_str = part_name;
+ float item_name_x = left_gutter * 32.0f;
+ float item_name_y = (item_line + 1) * 32.0f;
+ m_font_buf.add(item_str, VColour::white, item_name_x, item_name_y);
+
+ std::string doll_name;
+ doll_name = make_stringf("Doll %d / %d", m_doll_idx + 1, NUM_MAX_DOLLS);
+ float doll_name_x = left_gutter * 32.0f;
+ float doll_name_y = (doll_line + 1) * 32.0f;
+ m_font_buf.add(doll_name, VColour::white, doll_name_x, doll_name_y);
+
+ const char *mode_name[TILEP_MODE_MAX] =
+ {
+ "Current Equipment",
+ "Custom Doll",
+ "Job Defaults"
+ };
+ doll_name = make_stringf("Doll Mode: %s", mode_name[m_mode]);
+ doll_name_y += m_font->char_height() * 2.0f;
+ m_font_buf.add(doll_name, VColour::white, doll_name_x, doll_name_y);
+
+ // Add current doll information:
+
+ std::string info_str;
+ float info_x = info_offset * 32.0f;
+ float info_y = 0.0f;
+
+ // FIXME - this should be generated in rltiles
+ const char *cat_name[TILEP_PART_MAX] =
+ {
+ "Species",
+ "Shadow",
+ "Halo",
+ "Ench",
+ "Cloak",
+ "Boots",
+ "Legs",
+ "Body",
+ "Arm",
+ "LHand",
+ "RHand",
+ "Hair",
+ "Beard",
+ "Helm",
+ "DrcWing",
+ "DrcHead"
+ };
+
+ for (int i = 0 ; i < TILEP_PART_MAX; i++)
+ {
+ int part = m_dolls[m_doll_idx].parts[i];
+ int disp = part;
+ if (disp)
+ disp = disp - tile_player_part_start[i] + 1;
+ int maxp = tile_player_part_count[i];
+
+ const char *sel = (m_cat_idx == i) ? "->" : " ";
+
+ if (part == TILEP_SHOW_EQUIP)
+ info_str = make_stringf("%2s%9s: (show equip)", sel, cat_name[i]);
+ else if (!part)
+ info_str = make_stringf("%2s%9s: (none)", sel, cat_name[i]);
+ else
+ info_str = make_stringf("%2s%9s: %3d/%3d", sel, cat_name[i], disp, maxp);
+ m_font_buf.add(info_str, VColour::white, info_x, info_y);
+ info_y += m_font->char_height();
+ }
+
+ m_font_buf.draw();
+}
+
+int DollEditRegion::handle_mouse(MouseEvent &event)
+{
+ return 0;
+}
+
+void DollEditRegion::run()
+{
+ // Initialize equipment setting.
+ dolls_data equip_doll;
+ for (unsigned int i = 0; i < TILEP_PART_MAX; ++i)
+ equip_doll.parts[i] = TILEP_SHOW_EQUIP;
+
+ // Initialize job default.
+ m_job_default = equip_doll;
+ tilep_race_default(you.species, gender,
+ you.experience_level, m_job_default.parts);
+ tilep_job_default(you.char_class, gender, m_job_default.parts);
+
+ // Read predefined dolls from file.
+ for (unsigned int i = 0; i < NUM_MAX_DOLLS; ++i)
+ m_dolls[i] = equip_doll;
+
+ m_mode = TILEP_MODE_LOADING;
+ m_doll_idx = -1;
+
+ if (!_load_doll_data("dolls.txt", m_dolls, NUM_MAX_DOLLS, &m_mode, &m_doll_idx))
+ {
+ m_doll_idx = 0;
+ }
+
+ bool update_part_idx = true;
+
+ command_type cmd;
+ do
+ {
+ if (update_part_idx)
+ {
+ m_part_idx = m_dolls[m_doll_idx].parts[m_cat_idx];
+ if (m_part_idx == TILEP_SHOW_EQUIP)
+ m_part_idx = 0;
+ update_part_idx = false;
+ }
+
+ int key = getchm(KMC_DOLL);
+ cmd = key_to_command(key, KMC_DOLL);
+
+ switch (cmd)
+ {
+ case CMD_DOLL_RANDOMIZE:
+ _create_random_doll(m_dolls[m_doll_idx]);
+ break;
+ case CMD_DOLL_SELECT_NEXT_DOLL:
+ m_doll_idx = (m_doll_idx + 1) % NUM_MAX_DOLLS;
+ update_part_idx = true;
+ break;
+ case CMD_DOLL_SELECT_PREV_DOLL:
+ m_doll_idx = (m_doll_idx + NUM_MAX_DOLLS - 1) % NUM_MAX_DOLLS;
+ update_part_idx = true;
+ break;
+ case CMD_DOLL_SELECT_NEXT_PART:
+ m_cat_idx = (m_cat_idx + 1) % TILEP_PART_MAX;
+ update_part_idx = true;
+ break;
+ case CMD_DOLL_SELECT_PREV_PART:
+ m_cat_idx = (m_cat_idx + TILEP_PART_MAX - 1) % TILEP_PART_MAX;
+ update_part_idx = true;
+ break;
+ case CMD_DOLL_CHANGE_PART_NEXT:
+ m_part_idx = _get_next_part(m_cat_idx, m_part_idx, 1);
+ if (m_dolls[m_doll_idx].parts[m_cat_idx] != TILEP_SHOW_EQUIP)
+ m_dolls[m_doll_idx].parts[m_cat_idx] = m_part_idx;
+ break;
+ case CMD_DOLL_CHANGE_PART_PREV:
+ m_part_idx = _get_next_part(m_cat_idx, m_part_idx, -1);
+ if (m_dolls[m_doll_idx].parts[m_cat_idx] != TILEP_SHOW_EQUIP)
+ m_dolls[m_doll_idx].parts[m_cat_idx] = m_part_idx;
+ break;
+ case CMD_DOLL_COPY:
+ m_doll_copy = m_dolls[m_doll_idx];
+ m_copy_valid = true;
+ break;
+ case CMD_DOLL_PASTE:
+ if (m_copy_valid)
+ m_dolls[m_doll_idx] = m_doll_copy;
+ break;
+ case CMD_DOLL_TAKE_OFF:
+ m_part_idx = 0;
+ m_dolls[m_doll_idx].parts[m_cat_idx] = 0;
+ break;
+ case CMD_DOLL_TAKE_OFF_ALL:
+ for (int i = 0; i < TILEP_PART_MAX; i++)
+ {
+ switch (i)
+ {
+ case TILEP_PART_BASE:
+ case TILEP_PART_SHADOW:
+ case TILEP_PART_HALO:
+ case TILEP_PART_ENCH:
+ case TILEP_PART_DRCWING:
+ case TILEP_PART_DRCHEAD:
+ break;
+ default:
+ m_dolls[m_doll_idx].parts[i] = 0;
+ };
+ }
+ break;
+ case CMD_DOLL_TOGGLE_EQUIP:
+ if (m_dolls[m_doll_idx].parts[m_cat_idx] == TILEP_SHOW_EQUIP)
+ m_dolls[m_doll_idx].parts[m_cat_idx] = m_part_idx;
+ else
+ m_dolls[m_doll_idx].parts[m_cat_idx] = TILEP_SHOW_EQUIP;
+ break;
+ case CMD_DOLL_TOGGLE_EQUIP_ALL:
+ for (int i = 0; i < TILEP_PART_MAX; i++)
+ {
+ m_dolls[m_doll_idx].parts[i] = TILEP_SHOW_EQUIP;
+ }
+ break;
+ case CMD_DOLL_CLASS_DEFAULT:
+ m_dolls[m_doll_idx] = m_job_default;
+ break;
+ case CMD_DOLL_CHANGE_MODE:
+ m_mode = (tile_doll_mode)(((int)m_mode + 1) % TILEP_MODE_MAX);
+ default:
+ break;
+ }
+ }
+ while (cmd != CMD_DOLL_QUIT);
+
+ _save_doll_data(m_mode, m_doll_idx, &m_dolls[0]);
+
+ // Update player with the current doll.
+ switch (m_mode)
+ {
+ case TILEP_MODE_LOADING:
+ player_doll = m_dolls[m_doll_idx];
+ break;
+ case TILEP_MODE_DEFAULT:
+ player_doll = m_job_default;
+ break;
+ default:
+ case TILEP_MODE_EQUIP:
+ player_doll = equip_doll;
+ }
+}
+
ImageManager::ImageManager()
{
}
diff --git a/crawl-ref/source/tilereg.h b/crawl-ref/source/tilereg.h
index f6f687b84c..3ea855a493 100644
--- a/crawl-ref/source/tilereg.h
+++ b/crawl-ref/source/tilereg.h
@@ -424,13 +424,21 @@ protected:
bool m_far_view;
};
-class TitleRegion : public Region
+// An abstract tiles-only region that takes control over all input.
+class ControlRegion : public Region
+{
+public:
+ virtual void run() = 0;
+};
+
+class TitleRegion : public ControlRegion
{
public:
TitleRegion(int width, int height);
virtual void render();
virtual void clear() {};
+ virtual void run();
virtual int handle_mouse(MouseEvent &event) { return 0; }
@@ -440,5 +448,52 @@ protected:
GenericTexture m_img;
VertBuffer<PTVert> m_buf;
};
+
+enum tile_doll_mode
+{
+ 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
+ TILEP_MODE_MAX
+};
+
+class DollEditRegion : public ControlRegion
+{
+public:
+ DollEditRegion(ImageManager *im, FTFont *font);
+
+ virtual void render();
+ virtual void clear();
+ virtual void run();
+
+ virtual int handle_mouse(MouseEvent &event);
+protected:
+ virtual void on_resize() {}
+
+ // Currently edited doll index.
+ int m_doll_idx;
+ // Currently edited category of parts.
+ int m_cat_idx;
+ // Current part in current category.
+ int m_part_idx;
+
+ // Set of loaded dolls.
+ dolls_data m_dolls[NUM_MAX_DOLLS];
+
+ dolls_data m_player;
+ dolls_data m_job_default;
+ dolls_data m_doll_copy;
+ bool m_copy_valid;
+
+ tile_doll_mode m_mode;
+
+ FTFont *m_font;
+
+ ShapeBuffer m_shape_buf;
+ FontBuffer m_font_buf;
+ TileBuffer m_tile_buf;
+ TileBuffer m_cur_buf;
+};
+
#endif
#endif
diff --git a/crawl-ref/source/tiles.h b/crawl-ref/source/tiles.h
index 4898ea16d2..e2a9eedd63 100644
--- a/crawl-ref/source/tiles.h
+++ b/crawl-ref/source/tiles.h
@@ -60,8 +60,8 @@ void tilep_calc_flags(const int parts[], int flag[]);
void tilep_part_to_str(int number, char *buf);
int tilep_str_to_part(char *str);
-void tilep_scan_parts(char *fbuf, int *parts);
-void tilep_print_parts(char *fbuf, int *parts, bool check_halo = false);
+void tilep_scan_parts(char *fbuf, dolls_data &doll);
+void tilep_print_parts(char *fbuf, const dolls_data &doll);
int tilep_equ_weapon(const item_def &item);
int tilep_equ_shield(const item_def &item);
@@ -121,15 +121,12 @@ int TileDrawCursor(int x, int y, int flag);
void TileNewLevel(bool first_time);
// edit player tile
-void TilePlayerEdit();
void init_player_doll();
void save_doll_file(FILE *dollf);
int item_unid_type(const item_def &item);
int tile_known_weapon_brand(const item_def item);
-void TileDrawTitle();
-
int get_clean_map_idx(int tile_idx);
// Flags for drawing routines
@@ -212,5 +209,11 @@ enum
TILE_Y = 32
};
+// Don't change this without also modifying the data save/load routines.
+enum
+{
+ NUM_MAX_DOLLS = 10
+};
+
#endif
#endif
diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc
index 3383a13c9a..f49bc3e48a 100644
--- a/crawl-ref/source/tilesdl.cc
+++ b/crawl-ref/source/tilesdl.cc
@@ -158,12 +158,6 @@ void TilesFramework::shutdown()
m_region_crt = NULL;
m_region_menu = NULL;
- if (m_region_title)
- {
- delete m_region_title;
- m_region_title = NULL;
- }
-
for (unsigned int i = 0; i < LAYER_MAX; i++)
m_layers[i].m_regions.clear();
@@ -180,14 +174,27 @@ void TilesFramework::shutdown()
void TilesFramework::draw_title()
{
- m_active_layer = LAYER_TITLE;
+ TitleRegion* reg = new TitleRegion(m_windowsz.x, m_windowsz.y);
+ use_control_region(reg);
+ delete reg;
+}
+
+void TilesFramework::draw_doll_edit()
+{
+ DollEditRegion* reg = new DollEditRegion(&m_image, m_fonts[m_msg_font].font);
+ use_control_region(reg);
+ delete reg;
+}
+
+void TilesFramework::use_control_region(ControlRegion *reg)
+{
+ m_layers[LAYER_TILE_CONTROL].m_regions.push_back(reg);
+ m_active_layer = LAYER_TILE_CONTROL;
set_need_redraw();
- mouse_control mc(MOUSE_MODE_MORE);
- getch();
+ reg->run();
- delete m_region_title;
- m_region_title = NULL;
+ m_layers[LAYER_TILE_CONTROL].m_regions.clear();
}
void TilesFramework::calculate_default_options()
@@ -313,7 +320,7 @@ bool TilesFramework::initialise()
int crt_font = load_font(Options.tile_font_crt_file.c_str(),
Options.tile_font_crt_size, true, true);
- int msg_font = load_font(Options.tile_font_msg_file.c_str(),
+ m_msg_font = load_font(Options.tile_font_msg_file.c_str(),
Options.tile_font_msg_size, true, false);
int stat_font = load_font(Options.tile_font_stat_file.c_str(),
Options.tile_font_stat_size, true, false);
@@ -322,7 +329,7 @@ bool TilesFramework::initialise()
int lbl_font = load_font(Options.tile_font_lbl_file.c_str(),
Options.tile_font_lbl_size, true, true);
- if (crt_font == -1 || msg_font == -1 || stat_font == -1
+ if (crt_font == -1 || m_msg_font == -1 || stat_font == -1
|| m_tip_font == -1 || lbl_font == -1)
{
return (false);
@@ -334,7 +341,7 @@ bool TilesFramework::initialise()
m_region_inv = new InventoryRegion(&m_image, m_fonts[lbl_font].font,
TILE_X, TILE_Y);
- m_region_msg = new MessageRegion(m_fonts[msg_font].font);
+ m_region_msg = new MessageRegion(m_fonts[m_msg_font].font);
m_region_stat = new StatRegion(m_fonts[stat_font].font);
m_region_crt = new CRTRegion(m_fonts[crt_font].font);
m_region_menu = new MenuRegion(&m_image, m_fonts[crt_font].font);
@@ -348,13 +355,6 @@ bool TilesFramework::initialise()
m_layers[LAYER_CRT].m_regions.push_back(m_region_crt);
m_layers[LAYER_CRT].m_regions.push_back(m_region_menu);
- // Only initialize title region if we'll actually want to draw it.
- if (Options.tile_title_screen)
- {
- m_region_title = new TitleRegion(m_windowsz.x, m_windowsz.y);
- m_layers[LAYER_TITLE].m_regions.push_back(m_region_title);
- }
-
cgotoxy(1, 1, GOTO_CRT);
GLStateManager::init();
diff --git a/crawl-ref/source/tilesdl.h b/crawl-ref/source/tilesdl.h
index b1ab6866e2..1913ebbf8b 100644
--- a/crawl-ref/source/tilesdl.h
+++ b/crawl-ref/source/tilesdl.h
@@ -126,14 +126,16 @@ public:
void clear_overlays();
void draw_title();
+ void draw_doll_edit();
MenuRegion *get_menu() { return m_region_menu; }
protected:
-
int load_font(const char *font_file, int font_size,
bool default_on_fail, bool outline);
int handle_mouse(MouseEvent &event);
+ void use_control_region(ControlRegion *region);
+
// screen pixel dimensions
coord_def m_windowsz;
// screen pixels per view cell
@@ -147,7 +149,7 @@ protected:
{
LAYER_NORMAL,
LAYER_CRT,
- LAYER_TITLE,
+ LAYER_TILE_CONTROL,
LAYER_MAX
};
@@ -171,9 +173,6 @@ protected:
CRTRegion *m_region_crt;
MenuRegion *m_region_menu;
- // Title layer
- TitleRegion *m_region_title;
-
struct font_info
{
std::string name;
@@ -182,6 +181,7 @@ protected:
FTFont *font;
};
std::vector<font_info> m_fonts;
+ int m_msg_font;
int m_tip_font;
void do_layout();