code into Lua utility functions which can be reused by things other than bazaars). Related changes:
Portal vault entrances now work if they have destinations ("dst" property) besides "bazaar" (though it still causes an assert if no matchng maps for the destination can be found).
The floor and rock colour for a level are generated once and then stored in the save file, rather than being constantly regenerated (which means that bazaar floor colours are now truly random, rather than being tied to the depth of the bazaar entrance).
The floor and rock colour for a portal vault (or for any level containing any vault) can be set with ROCKCOL and FLOORCOL (which currently only accepts a single colour, unlike COLOUR); there are also Lua functions for querying and setting the colours.
Each portal vault level_type_name can have an associated Lua callback which is called when level generation is complete; it can be used for things like stair fixup.
I also moved the Halls of Zot rock/floor colour special casing to the dat/zot.des file, since it was easy once ROCKCOL and FLOORCOL had been implemented.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2314 c06c8d41-db1a-0410-9941-cceddc491573
TLA5UN6LZPXGKERI27EFY4HKIIU3VU5Y7ZU54WXL6ANBUV2VOTMQC
EJ4GIPFSSQCQASUMRF4CR2WPUQOTEHFRGLOYEZ7BH6YEMIR6DN4QC
AUXVWXWIFSTWFA6VZXN2FMG7FQEKRZVV6MD32VQQ7J2RKCXHAVGAC
JT672SIJK4BOIUAGL2WQ6NR2NF4PSWP3BT6Q4HMNRF25UN6JQ2MAC
ZANSES4OX4GVTHFIVORYRZFZOUIPV2CL2ABUVWFZB7TMKOPKQFSQC
ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
WKTZHLOJ65WSK6FR5MF7RWGSMZ22T2D6LHB66FV3IPGXIBLYHHNAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
JM6GKZ6VMX6FNVOZIDXIV22HGX7YESMIFZFE6EEQVCMFJIEA3FNAC
UZ6N6HOUPGVSPC5NQROEEDWMEGJA5XUWUY2AKH5QG65AZ25PVXDAC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
TLO257LZSB6ZO36STDUEWJBO2LETXFKTFGXELA6Y4BZBVAEIIINAC
W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
UBQTNLYGD3SNWMUNGWUPX7EXEGQXOXCFCPWIVWBFE7ID7DJLPFWAC
E7DV36ZR6TOGBD75BHGARCMIQQS6MSV7V3A7M7V4LOFHEC5NF6CQC
ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
OY7KHQPESOUHPBXRZ2JSNUKPAC7DCDY73TAUHCSJG5V6TPAHBVYQC
XAFFD52IHN6FWFR2TT5F2KCUS7HAVCBI5CWTFMKPQG77GGTGAHLAC
2YSMM7QMFZOPD5NXAD2OAMDJEY5LOZO4NCYBC7UCQVANKINJRNBAC
C22455VGUQOSUX2OORA32LROFQ7NNYDMD2ZDTTUZSAQLXK4AD6QAC
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
3XZOL3FFQZITUJIGDD6B6V6ZYMBN524JKNN6ZPJAXEC7RY433I3QC
V2SIR47DZF52SZOVRUTQKTSJ4H7LKOFK654JGGHFZQWR64CLNAUQC
BNP25NWD5OXPQEPLM3YJRJCRE24DH55RZKFCZPUX5NLWGOSBIYGAC
L4RYVF46EQKMVOEADGRG4WMPVTQ6NNFGYMU4SHAH6XJIKWVHT77QC
2WRXQTGYDBLV46WRNVIUKGNA5QS563XZNNW3N2L6PVOCHIP2YGHQC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
H3552BCIAVBLKAYKE4DHFLBLFW5RGRMYBMRRYHYEB5IPIJRUVU5QC
CI5VTLSMB2L5W5ZVKDZEJFUARGSZP2FUSTRFV3MG6U44TDDUYH5AC
OUEUG67YNHCAEAR5TYOBG3RMJYXG6WI52OAH5SL5OHZPNFHT7R7AC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
R6XS2HO5QX2FJUGL5UQQRNETKCMYWTUFPHPPS5SYWK3OQA4UDUQQC
return (0);
}
static int dgn_floor_colour(lua_State *ls)
{
MAP(ls, 1, map);
const char *s = luaL_checkstring(ls, 2);
int colour = str_to_colour(s);
if (colour < 0 || colour == BLACK)
{
std::string error;
if (colour == BLACK)
{
error = "Can't set floor to black.";
}
else {
error = "No such colour as '";
error += s;
error += "'";
}
luaL_argerror(ls, 2, error.c_str());
return (0);
}
map->floor_colour = (unsigned char) colour;
return (0);
}
static int dgn_rock_colour(lua_State *ls)
{
MAP(ls, 1, map);
const char *s = luaL_checkstring(ls, 2);
int colour = str_to_colour(s);
if (colour < 0 || colour == BLACK)
{
std::string error;
if (colour == BLACK)
{
error = "Can't set rock to black.";
}
else {
error = "No such colour as '";
error += s;
error += "'";
}
luaL_argerror(ls, 2, error.c_str());
return (0);
}
map->rock_colour = (unsigned char) colour;
return (0);
}
static int dgn_get_floor_colour(lua_State *ls)
{
PLUARET(string, colour_to_str(env.floor_colour));
}
static int dgn_get_rock_colour(lua_State *ls)
{
PLUARET(string, colour_to_str(env.rock_colour));
}
static int dgn_change_floor_colour(lua_State *ls)
{
const char *s = luaL_checkstring(ls, 1);
int colour = str_to_colour(s);
if (colour < 0 || colour == BLACK)
{
std::string error;
if (colour == BLACK)
{
error = "Can't set floor to black.";
}
else {
error = "No such colour as '";
error += s;
error += "'";
}
luaL_argerror(ls, 1, error.c_str());
return (0);
}
env.floor_colour = (unsigned char) colour;
viewwindow(true, false);
return (0);
}
static int dgn_change_rock_colour(lua_State *ls)
{
const char *s = luaL_checkstring(ls, 1);
int colour = str_to_colour(s);
if (colour < 0 || colour == BLACK)
{
std::string error;
if (colour == BLACK)
{
error = "Can't set rock to black.";
}
else {
error = "No such colour as '";
error += s;
error += "'";
}
luaL_argerror(ls, 1, error.c_str());
return (0);
}
env.rock_colour = (unsigned char) colour;
viewwindow(true, false);
}
static int lua_dgn_set_lt_callback(lua_State *ls)
{
const char *level_type = luaL_checkstring(ls, 1);
if (level_type == NULL || strlen(level_type) == 0)
return (0);
const char *callback_name = luaL_checkstring(ls, 2);
if (callback_name == NULL || strlen(callback_name) == 0)
return (0);
dgn_set_lt_callback(level_type, callback_name);
return (0);
}
static int dgn_fixup_stairs(lua_State *ls)
{
const dungeon_feature_type up_feat =
dungeon_feature_by_name(luaL_checkstring(ls, 1));
const dungeon_feature_type down_feat =
dungeon_feature_by_name(luaL_checkstring(ls, 2));
if (up_feat == DNGN_UNSEEN && down_feat == DNGN_UNSEEN)
return(0);
for (int y = 0; y < GYM; ++y)
{
for (int x = 0; x < GXM; ++x)
{
const dungeon_feature_type feat = grd[x][y];
if (grid_is_stone_stair(feat) || grid_is_rock_stair(feat))
{
dungeon_feature_type new_feat = DNGN_UNSEEN;
if (grid_stair_direction(feat) == CMD_GO_DOWNSTAIRS)
new_feat = down_feat;
else
new_feat = up_feat;
if (new_feat != DNGN_UNSEEN)
{
grd[x][y] = new_feat;
env.markers.add(
new map_feature_marker(
coord_def(x, y),
new_feat));
}
}
}
}
return (0);
}
static int dgn_floor_halo(lua_State *ls)
{
std::string error = "";
const char* s1 = luaL_checkstring(ls, 1);
const dungeon_feature_type target = dungeon_feature_by_name(s1);
if (target == DNGN_UNSEEN)
{
error += "No such dungeon feature as '";
error += s1;
error += "'. ";
}
const char* s2 = luaL_checkstring(ls, 2);
unsigned char colour = str_to_colour(s2);
if (colour == -1)
{
error += "No such colour as '";
error += s2;
error += "'.";
}
else if (colour == BLACK)
{
error += "Can't set floor colour to black.";
}
if (error != "")
{
luaL_argerror(ls, 2, error.c_str());
return(0);
}
for (int y = 0; y < GYM; ++y)
{
for (int x = 0; x < GXM; ++x)
{
const dungeon_feature_type feat = grd[x][y];
if (feat == target)
{
for (int i=-1; i<=1; i++)
for (int j=-1; j<=1; j++)
{
if (!map_bounds(x+i, y+j))
continue;
const dungeon_feature_type feat2 = grd[x+i][y+j];
if (feat2 == DNGN_FLOOR
|| feat2 == DNGN_UNDISCOVERED_TRAP)
{
env.grid_colours[x+i][y+j] = colour;
}
}
}
}
}
return (0);
{ "get_floor_colour", dgn_get_floor_colour},
{ "get_rock_colour", dgn_get_rock_colour},
{ "change_floor_colour", dgn_change_floor_colour},
{ "change_rock_colour", dgn_change_rock_colour},
{ "set_lt_callback", lua_dgn_set_lt_callback},
{ "fixup_stairs", dgn_fixup_stairs},
{ "floor_halo", dgn_floor_halo},
}
int bazaar_floor_colour(int curr_level)
{
const char floorcolours_bzr[] =
{ BLUE, RED, LIGHTBLUE, MAGENTA, GREEN };
// set colour according to current level
// randomization would reset between save/reload and after showing map
return (floorcolours_bzr[curr_level % 5]);
env.floor_colour = LIGHTGREY;
env.rock_colour = BROWN;
}
else if (you.level_type == LEVEL_PORTAL_VAULT
&& you.level_type_name == "bazaar")
{
// bazaars get gold walls
env.rock_colour = YELLOW;
// bazaar floor is colourful
env.floor_colour = bazaar_floor_colour(you.your_level + 1);
}
else
{
// Zot is multicoloured
if ( you.where_are_you == BRANCH_HALL_OF_ZOT )
{
const char floorcolours_zot[] = { LIGHTGREY, LIGHTGREY, BLUE,
LIGHTBLUE, MAGENTA };
const char rockcolours_zot[] = { LIGHTGREY, BLUE, LIGHTBLUE,
MAGENTA, LIGHTMAGENTA };
if (old_floor_colour != BLACK)
env.floor_colour = old_floor_colour;
if (old_rock_colour != BLACK)
env.rock_colour = old_rock_colour;
const int curr_subdungeon_level = player_branch_depth();
if ( curr_subdungeon_level > 5 || curr_subdungeon_level < 1 )
mpr("Odd colouring!");
else
{
env.floor_colour = floorcolours_zot[curr_subdungeon_level-1];
env.rock_colour = rockcolours_zot[curr_subdungeon_level-1];
}
}
}
if (env.floor_colour == BLACK)
env.floor_colour = LIGHTGREY;
if (env.rock_colour == BLACK)
env.rock_colour = BROWN;
for (int y = 0; y < GYM; ++y)
{
for (int x = 0; x < GXM; ++x)
{
const dungeon_feature_type feat = grd[x][y];
if (grid_is_stone_stair(feat) || grid_is_rock_stair(feat))
{
if (grid_stair_direction(feat) == CMD_GO_DOWNSTAIRS)
grd[x][y] = DNGN_EXIT_PORTAL_VAULT;
else
{
grd[x][y] = DNGN_STONE_ARCH;
env.markers.add(
new map_feature_marker(
coord_def(x, y),
DNGN_STONE_ARCH));
}
}
// colour floor squares around shops
if (feat == DNGN_ENTER_SHOP)
{
for (int i=-1; i<=1; i++)
for (int j=-1; j<=1; j++)
{
if (grd[x+i][y+j] == DNGN_FLOOR)
grd[x+i][y+j] = DNGN_FLOOR_SPECIAL;
}
}
}
}
}
std::string trimmed_name = trimmed_string(you.level_type_name);
ASSERT(trimmed_name.c_str() != "");
const char* level_name = trimmed_name.c_str();
ensure_vault_placed( build_vaults(level_number, vault) );
link_items();
fixup_bazaar_stairs();
return;
plan_main(level_number, 0);
place_minivaults(level_name, 1, 1, true);
if (level_vaults.empty())
{
mprf(MSGCH_WARN, "No maps or tags named '%s'.",
level_name);
ASSERT(false);
end(-1);
}
// No vaults placed yet? Place some shops of our own.
if (level_vaults.empty())
place_shops(level_number, random_range(5, MAX_SHOPS));
// TODO: Let portal vault map have arbitrary properties which can
// be passed onto the callback.
callback_map::const_iterator
i = level_type_post_callbacks.find(you.level_type_name);
MAP
.
ENDMAP
###
NAME: hall_of_Zot_3
PLACE: Zot:3
TAGS: transparent
ORIENT: float
FLOORCOL: blue
ROCKCOL: lightblue
MAP
.
ENDMAP
###
NAME: hall_of_Zot_4
PLACE: Zot:4
TAGS: transparent
ORIENT: float
FLOORCOL: lightblue
ROCKCOL: magenta
MAP
.
ENDMAP
function random_bazaar_colour()
local colours = {"blue", "red", "lightblue", "magenta", "green"}
crawl.mpr("#colours = " .. #colours)
local ret = colours[crawl.random2(#colours) + 1]
crawl.mpr("ret = " .. ret)
return ret
end
function fixup_bazaar()
dgn.fixup_stairs("stone_arch", "exit_portal_vault")
dgn.floor_halo("enter_shop", "yellow")
if (dgn.get_floor_colour() == "black") then
dgn.change_floor_colour(random_bazaar_colour())
end
if (dgn.get_rock_colour() == "black") then
dgn.change_rock_colour("yellow")
end
end
dgn.set_lt_callback("bazaar", "fixup_bazaar")
grd[you.x_pos][you.y_pos] = DNGN_ENTER_PORTAL_VAULT;
map_wiz_props_marker
*marker = new map_wiz_props_marker(you.pos());
marker->set_property("dst", dst);
marker->set_property("desc", "wizard portal, dest = " + dst);
env.markers.add(marker);
mprf("No map named '%s' or tagged '%s'.",
dst.c_str(), dst.c_str());
return;