From 9b909453a2e070df3ac33277d0a7f07deb6e9132 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Fri, 27 Jul 2007 17:26:00 +0000 Subject: Reworked Bazaars as a special case of portal vaults. The level-type is now called portal vault. The dungeon builder bases its behaviour on the level_type_name, which must be set as the "dst" property on the portal leading to the bazaar/portal vault. Added WELCOME: directive to .des files to allow maps to specify a welcome message when the player enters the level (only relevant to encompass maps). Readjusted kenku flight speed. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1941 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/dat/bazaar.des | 46 +++++++++++++------- crawl-ref/source/dat/clua/lm_1way.lua | 18 ++++---- crawl-ref/source/dat/clua/lm_pdesc.lua | 38 +++++++++++++++++ crawl-ref/source/dat/clua/lm_timed.lua | 50 ++++++++++++++-------- crawl-ref/source/dat/clua/luamark.lua | 9 ++-- crawl-ref/source/debug.cc | 4 +- crawl-ref/source/direct.cc | 65 +++++++++++++++++----------- crawl-ref/source/direct.h | 4 +- crawl-ref/source/dungeon.cc | 33 ++++++++++++--- crawl-ref/source/dungeon.h | 1 + crawl-ref/source/enum.h | 6 +-- crawl-ref/source/externs.h | 1 + crawl-ref/source/files.cc | 11 +++-- crawl-ref/source/hiscores.cc | 2 +- crawl-ref/source/luadgn.cc | 42 ++++++++++++++++--- crawl-ref/source/mapdef.cc | 7 ++-- crawl-ref/source/mapdef.h | 2 + crawl-ref/source/mapmark.cc | 77 ++++++++++++++++++++++++++++------ crawl-ref/source/mapmark.h | 20 ++++++--- crawl-ref/source/menu.cc | 4 +- crawl-ref/source/misc.cc | 31 +++++++------- crawl-ref/source/ouch.cc | 2 +- crawl-ref/source/player.cc | 8 ++-- crawl-ref/source/stash.cc | 2 +- crawl-ref/source/tags.cc | 2 + crawl-ref/source/travel.cc | 8 ++-- crawl-ref/source/util/levcomp.lpp | 1 + crawl-ref/source/util/levcomp.ypp | 12 +++++- crawl-ref/source/view.cc | 8 ++-- 29 files changed, 362 insertions(+), 152 deletions(-) create mode 100644 crawl-ref/source/dat/clua/lm_pdesc.lua diff --git a/crawl-ref/source/dat/bazaar.des b/crawl-ref/source/dat/bazaar.des index cc1cb17d0b..65bd852aa1 100644 --- a/crawl-ref/source/dat/bazaar.des +++ b/crawl-ref/source/dat/bazaar.des @@ -8,17 +8,26 @@ # Utility functions lua {{ - function check_expire_marker(e) - e.messager = - bell_clock_msg { initmsg="You hear coins being counted." } - if not crawl.one_chance_in(3) then - e.marker( [[ O = lua: timed_marker { - low=1000, high=1500, msg=messager } - ]] ) - else - e.marker("O = lua: one_way_stair()") - end - end + +function bazaar_portal() + local messager = bell_clock_msg { initmsg="You hear coins being counted." } + if not crawl.one_chance_in(3) then + local pdesc = 'flickering gateway to a bazaar' + return timed_marker { + low=1000, high=1500, msg=messager, + disappear='The gate to the bazaar disappears!', + props = { desc=pdesc, dst='bazaar' } + } + else + return one_way_stair { desc = 'gateway to a bazaar', + dst = 'bazaar' } + end +end + +function bazaar_message(e) + e.welcome("You enter an inter-dimensional bazaar!") +end + }} default-depth: D:10-27 @@ -29,7 +38,7 @@ default-depth: D:10-27 NAME: bzr_entry_dummy TAGS: bzr_entry transparent ORIENT: float -: check_expire_marker(_G) +MARKER: O = lua:bazaar_portal() MAP O ENDMAP @@ -40,7 +49,7 @@ NAME: bzr_entry_001 TAGS: bzr_entry no_pool_fixup ORIENT: float SHUFFLE: wwl -: check_expire_marker(_G) +MARKER: O = lua:bazaar_portal() MAP www w.w.w @@ -55,7 +64,7 @@ NAME: bzr_entry_002 TAGS: bzr_entry ORIENT: float SUBST: $=$. -: check_expire_marker(_G) +MARKER: O = lua:bazaar_portal() MAP xx.xx x$$$x @@ -72,7 +81,7 @@ ORIENT: float MONS: human, orc, goblin, kobold SUBST: . = .:210 1 SHUFFLE: 1234 -: check_expire_marker(_G) +MARKER: O = lua:bazaar_portal() MAP ..... ....... @@ -91,13 +100,15 @@ ENDMAP # Every encompass bazaar level must have at least one downstair, which will be # replaced with an exit from the bazaar. It's a good idea to also provide an # upstair, which will be converted into a stone arch (and on which the player -# will be placed when entering the bazaar). +# will be placed when entering the bazaar). If there's no upstair, the player +# will arrive on a random square. NAME: bazaar_general_marketplace TAGS: bazaar ORIENT: encompass KFEAT: A = any shop CHANCE: 30 +: bazaar_message(_G) MAP xxxxxxxxx xxxx>xxxx @@ -120,6 +131,7 @@ KFEAT: B = antique weapon shop / weapon shop KFEAT: C = antique armour shop / armour shop ITEM: any weapon / w:2 good_item any weapon ITEM: any armour / w:2 good_item any armour +: bazaar_message(_G) MAP xxxxxxxxx xxxx>xxxx @@ -141,6 +153,7 @@ KFEAT: B = jewellery shop ITEM: any jewelry / good_item any jewelry ITEM: any book / good_item any book, any staff SUBST: w:w.l, x:b, c:., v=bl, d=.d, e=.e, f=.f +: bazaar_message(_G) MAP xxxxxxxxxxxxx xxxxxxxwwwxxx @@ -156,6 +169,7 @@ TAGS: bazaar ORIENT: encompass KFEAT: A = wand shop ITEM: any wand +: bazaar_message(_G) MAP xxxxxxxxxxx xx...>...xx diff --git a/crawl-ref/source/dat/clua/lm_1way.lua b/crawl-ref/source/dat/clua/lm_1way.lua index 6ce1e6d722..e6e56beced 100644 --- a/crawl-ref/source/dat/clua/lm_1way.lua +++ b/crawl-ref/source/dat/clua/lm_1way.lua @@ -3,12 +3,12 @@ -- One-way stair marker. ------------------------------------------------------------------------------ -OneWayStair = { } +OneWayStair = PortalDescriptor:new() OneWayStair.__index = OneWayStair -function OneWayStair.new() - local ows = { } - setmetatable(ows, OneWayStair) +function OneWayStair:new(props) + local ows = PortalDescriptor.new(self, props) + setmetatable(ows, self) return ows end @@ -26,10 +26,12 @@ function OneWayStair:event(marker, ev) end end -function OneWayStair.read(marker, th) - return OneWayStair.new() +function OneWayStair:read(marker, th) + PortalDescriptor.read(self, marker, th) + setmetatable(self, OneWayStair) + return self end -function one_way_stair() - return OneWayStair.new() +function one_way_stair(pars) + return OneWayStair:new(pars) end diff --git a/crawl-ref/source/dat/clua/lm_pdesc.lua b/crawl-ref/source/dat/clua/lm_pdesc.lua new file mode 100644 index 0000000000..5b02247fa2 --- /dev/null +++ b/crawl-ref/source/dat/clua/lm_pdesc.lua @@ -0,0 +1,38 @@ +------------------------------------------------------------------------------ +-- lm_desc.lua: +-- Portal descriptor markers. +------------------------------------------------------------------------------ + +PortalDescriptor = { } +PortalDescriptor.__index = PortalDescriptor + +function PortalDescriptor:new(properties) + local pd = { } + setmetatable(pd, self) + pd.props = properties + return pd +end + +function PortalDescriptor:write(marker, th) + file.marshall(th, self.desc or '') + lmark.marshall_table(th, self.props) +end + +function PortalDescriptor:read(marker, th) + self.desc = file.unmarshall_string(th) + self.props = lmark.unmarshall_table(th) + setmetatable(self, PortalDescriptor) + return self +end + +function PortalDescriptor:feature_description(marker) + return self.props.desc +end + +function PortalDescriptor:property(marker, pname) + return self.props and self.props[pname] or '' +end + +function portal_desc(desc, props) + return PortalDescriptor:new(desc, props) +end diff --git a/crawl-ref/source/dat/clua/lm_timed.lua b/crawl-ref/source/dat/clua/lm_timed.lua index 8b9f1aaf26..769db38ac5 100644 --- a/crawl-ref/source/dat/clua/lm_timed.lua +++ b/crawl-ref/source/dat/clua/lm_timed.lua @@ -5,16 +5,17 @@ dofile('clua/lm_tmsg.lua') -TimedMarker = { } +TimedMarker = PortalDescriptor:new() TimedMarker.__index = TimedMarker -function TimedMarker._new() +function TimedMarker:_new() local marker = { } - setmetatable(marker, TimedMarker) + setmetatable(marker, self) + self.__index = self return marker end -function TimedMarker.new(pars) +function TimedMarker:new(pars) pars = pars or { } if not pars.msg then error("No messaging object provided (msg = nil)") @@ -28,11 +29,16 @@ function TimedMarker.new(pars) error("Bad feature name: " .. feat) end - local tmarker = TimedMarker._new() - tmarker.dur = dur * 10 - tmarker.fnum = fnum - tmarker.feat = feat - tmarker.msg = pars.msg + local tmarker = self:_new() + tmarker.dur = dur * 10 + tmarker.fnum = fnum + tmarker.feat = feat + tmarker.msg = pars.msg + tmarker.disappear = pars.disappear + + if pars.props then + tmarker.props = pars.props + end return tmarker end @@ -48,8 +54,8 @@ function TimedMarker:timeout(marker, verbose, affect_player) local x, y = marker:pos() if verbose then if you.see_grid(marker:pos()) then - crawl.mpr(dgn.feature_desc(dgn.grid(x, y), "The") .. - " disappears!") + crawl.mpr( self.disappear or + dgn.feature_desc_at(x, y, "The") .. " disappears!") else crawl.mpr("The walls and floor vibrate strangely for a moment.") end @@ -87,19 +93,27 @@ function TimedMarker:describe(marker) return self.feat .. "/" .. tostring(self.dur) end -function TimedMarker.read(marker, th) - local marker = TimedMarker._new() - marker.dur = file.unmarshall_number(th) - marker.fnum = file.unmarshall_number(th) - marker.feat = file.unmarshall_string(th) - marker.msg = file.unmarshall_fn(th)(th) - return marker +function TimedMarker:read(marker, th) + PortalDescriptor.read(self, marker, th) + self.dur = file.unmarshall_number(th) + self.fnum = file.unmarshall_number(th) + self.feat = file.unmarshall_string(th) + self.disappear = file.unmarshall_meta(th) + self.msg = file.unmarshall_fn(th)(th) + setmetatable(self, TimedMarker) + return self end function TimedMarker:write(marker, th) + PortalDescriptor.write(self, marker, th) file.marshall(th, self.dur) file.marshall(th, self.fnum) file.marshall(th, self.feat) + file.marshall_meta(th, self.disappear) file.marshall(th, self.msg.read) self.msg:write(th) end + +function timed_marker(pars) + return TimedMarker:new(pars) +end diff --git a/crawl-ref/source/dat/clua/luamark.lua b/crawl-ref/source/dat/clua/luamark.lua index d2d12ce34e..58eeda6c68 100644 --- a/crawl-ref/source/dat/clua/luamark.lua +++ b/crawl-ref/source/dat/clua/luamark.lua @@ -3,8 +3,9 @@ -- Lua map marker handling. ------------------------------------------------------------------------------ -dofile('clua/lm_timed.lua') +dofile('clua/lm_pdesc.lua') dofile('clua/lm_1way.lua') +dofile('clua/lm_timed.lua') function dlua_marker_function(table, name) return table[name] @@ -17,11 +18,7 @@ function dlua_marker_method(table, name, marker, ...) end function dlua_marker_read(fn, marker, th) - return fn(marker, th) -end - -function timed_marker(pars) - return TimedMarker.new(pars) + return fn({ }, marker, th) end lmark = { } diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 4e3c27ffe2..2b8dc05f17 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -2273,7 +2273,7 @@ static void mg_build_levels(int niters) you.level_type = LEVEL_PANDEMONIUM; if (!mg_do_build_level(niters)) return; - you.level_type = LEVEL_BAZAAR; + you.level_type = LEVEL_PORTAL_VAULT; if (!mg_do_build_level(niters)) return; } @@ -2337,7 +2337,7 @@ static void write_mapgen_stats() check_mapless(level_id(LEVEL_ABYSS), mapless); check_mapless(level_id(LEVEL_PANDEMONIUM), mapless); check_mapless(level_id(LEVEL_LABYRINTH), mapless); - check_mapless(level_id(LEVEL_BAZAAR), mapless); + check_mapless(level_id(LEVEL_PORTAL_VAULT), mapless); if (!mapless.empty()) { diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index 675e214549..c08a7fa406 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -1200,17 +1200,14 @@ void describe_floor() mpr("Beware, for starvation awaits!"); } -std::string feature_description(dungeon_feature_type grid, - trap_type trap, - bool temporary, - description_level_type dtype, - bool add_stop) +static std::string feature_do_grammar(description_level_type dtype, + bool add_stop, + bool force_article, + std::string desc) { - std::string desc = - raw_feature_description(grid, trap, temporary); if (add_stop) desc += "."; - if (dtype == DESC_PLAIN || (!grid_is_trap(grid) && isupper(desc[0]))) + if (dtype == DESC_PLAIN || (!force_article && isupper(desc[0]))) { if (isupper(desc[0])) { @@ -1238,12 +1235,20 @@ std::string feature_description(dungeon_feature_type grid, return article_a(desc, true); default: return (desc); - } + } +} + +std::string feature_description(dungeon_feature_type grid, + trap_type trap, + description_level_type dtype, + bool add_stop) +{ + std::string desc = raw_feature_description(grid, trap); + return feature_do_grammar(dtype, add_stop, grid_is_trap(grid), desc); } std::string raw_feature_description(dungeon_feature_type grid, - trap_type trap, - bool temporary) + trap_type trap) { if (grid_is_trap(grid) && trap != NUM_TRAPS) { @@ -1341,17 +1346,7 @@ std::string raw_feature_description(dungeon_feature_type grid, case DNGN_ENTER_SHOP: return ("shop"); case DNGN_ENTER_LABYRINTH: - if (temporary) - return ("slowly fading labyrinth entrance"); - else - return ("labyrinth entrance"); - case DNGN_ENTER_BAZAAR: - if (temporary) - return ("gently fading gateway to a bazaar"); - else - return ("gateway to a bazaar"); - case DNGN_EXIT_BAZAAR: - return ("exit from the bazaar"); + return ("labyrinth entrance"); case DNGN_ENTER_DIS: return ("gateway to the Iron City of Dis"); case DNGN_ENTER_GEHENNA: @@ -1400,6 +1395,8 @@ std::string raw_feature_description(dungeon_feature_type grid, return ("staircase to the Swamp"); case DNGN_ENTER_SHOALS: return ("staircase to the Shoals"); + case DNGN_EXIT_PORTAL_VAULT: + return ("gate leading back to the Dungeon"); case DNGN_RETURN_FROM_ORCISH_MINES: case DNGN_RETURN_FROM_HIVE: case DNGN_RETURN_FROM_LAIR: @@ -1464,6 +1461,18 @@ std::string raw_feature_description(dungeon_feature_type grid, } } +static std::string marker_feature_description(const coord_def &p) +{ + std::vector markers = env_get_markers(p); + for (int i = 0, size = markers.size(); i < size; ++i) + { + const std::string desc = markers[i]->feature_description(); + if (!desc.empty()) + return (desc); + } + return (""); +} + std::string feature_description(int mx, int my, description_level_type dtype, bool add_stop) { @@ -1473,12 +1482,18 @@ std::string feature_description(int mx, int my, description_level_type dtype, case DNGN_TRAP_MECHANICAL: case DNGN_TRAP_MAGICAL: case DNGN_TRAP_III: - return (feature_description(grid, trap_type_at_xy(mx, my), false, + return (feature_description(grid, trap_type_at_xy(mx, my), dtype, add_stop)); case DNGN_ENTER_SHOP: return (shop_name(mx, my, add_stop)); + + case DNGN_ENTER_PORTAL_VAULT: + return (feature_do_grammar( + dtype, add_stop, false, + marker_feature_description(coord_def(mx, my)))); + default: - return (feature_description(grid, NUM_TRAPS, false, dtype, add_stop)); + return (feature_description(grid, NUM_TRAPS, dtype, add_stop)); } } @@ -1714,7 +1729,7 @@ static void describe_cell(int mx, int my) std::string marker; if (map_marker *mark = env_find_marker(coord_def(mx, my), MAT_ANY)) { - std::string desc = mark->describe(); + std::string desc = mark->debug_describe(); if (desc.empty()) desc = "?"; marker = " (" + desc + ")"; diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h index f8ac7beafd..4ffd1b5109 100644 --- a/crawl-ref/source/direct.h +++ b/crawl-ref/source/direct.h @@ -60,11 +60,9 @@ std::string feature_description(int mx, int my, description_level_type dtype = DESC_CAP_A, bool add_stop = true); std::string raw_feature_description(dungeon_feature_type grid, - trap_type tr = NUM_TRAPS, - bool temporary = false); + trap_type tr = NUM_TRAPS); std::string feature_description(dungeon_feature_type grid, trap_type trap = NUM_TRAPS, - bool temporary = false, description_level_type dtype = DESC_CAP_A, bool add_stop = true); diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 5a0f9e20b4..1738b6483f 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -219,9 +219,10 @@ typedef std::list coord_list; // A mask of vaults and vault-specific flags. map_mask dgn_map_mask; +std::vector level_vaults; + static dgn_region_list vault_zones; static int vault_chance = 9; -static std::vector level_vaults; static int minivault_chance = 3; static bool dgn_level_vetoed = false; static bool use_random_maps = true; @@ -277,6 +278,17 @@ bool builder(int level_number, int level_type) return (false); } +void level_welcome_messages() +{ + for (int i = 0, size = level_vaults.size(); i < size; ++i) + { + const std::vector &msgs = + level_vaults[i].map.welcome_messages; + for (int j = 0, msize = msgs.size(); j < msize; ++j) + mpr(msgs[j].c_str()); + } +} + static void dgn_register_vault(const map_def &map) { if (map.has_tag("uniq")) @@ -711,7 +723,8 @@ static void build_dungeon_level(int level_number, int level_type) build_layout_skeleton(level_number, level_type, sr); - if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_BAZAAR + if (you.level_type == LEVEL_LABYRINTH + || you.level_type == LEVEL_PORTAL_VAULT || dgn_level_vetoed) return; @@ -1255,9 +1268,16 @@ static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2, // -1 if we should immediately quit, and 0 otherwise. static builder_rc_type builder_by_type(int level_number, char level_type) { - if (level_type == LEVEL_BAZAAR) + if (level_type == LEVEL_PORTAL_VAULT) { - bazaar_level(level_number); + if (you.level_type_name == "bazaar") + bazaar_level(level_number); + else + { + // Need to find encompass vault with tag matching + // level_type_name. + ASSERT(false); + } return (BUILD_QUIT); } @@ -1340,7 +1360,7 @@ static void fixup_bazaar_stairs() if (grid_is_stone_stair(feat) || grid_is_rock_stair(feat)) { if (grid_stair_direction(feat) == CMD_GO_DOWNSTAIRS) - grd[x][y] = DNGN_EXIT_BAZAAR; + grd[x][y] = DNGN_EXIT_PORTAL_VAULT; else grd[x][y] = DNGN_STONE_ARCH; } @@ -4431,7 +4451,8 @@ static void place_shops(int level_number, int nshops) if (allow_bazaars && level_number > 9 && level_number < 27 && one_chance_in(30 - level_number)) { - place_specific_stair(DNGN_ENTER_BAZAAR, "bzr_entry", + place_specific_stair(DNGN_ENTER_PORTAL_VAULT, + "bzr_entry", level_number, true); allow_bazaars = false; } diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index cd637213f2..530226554d 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -112,6 +112,7 @@ struct dgn_region }; bool builder(int level_number, int level_type); +void level_welcome_messages(); void define_zombie(int mid, int ztype, int cs, int power); bool is_wall(int feature); bool place_specific_trap(int spec_x, int spec_y, trap_type spec_type); diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 50e180a307..b910b82f95 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1102,8 +1102,8 @@ enum dungeon_feature_type DNGN_RETURN_RESERVED_4, // 146 // Portals to various places unknown. - DNGN_ENTER_BAZAAR = 160, - DNGN_EXIT_BAZAAR, + DNGN_ENTER_PORTAL_VAULT = 160, + DNGN_EXIT_PORTAL_VAULT, DNGN_ALTAR_ZIN = 180, // 180 DNGN_ALTAR_SHINING_ONE, @@ -1763,7 +1763,7 @@ enum level_area_type // you.level_type LEVEL_LABYRINTH, LEVEL_ABYSS, LEVEL_PANDEMONIUM, - LEVEL_BAZAAR, + LEVEL_PORTAL_VAULT, NUM_LEVEL_AREA_TYPES }; diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index ade4bf5014..41b7b240c4 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -736,6 +736,7 @@ public: KillMaster kills; level_area_type level_type; + std::string level_type_name; branch_type where_are_you; diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index e7e6762ec2..437ea5b389 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -554,8 +554,8 @@ static std::string get_level_suffix(int level, branch_type where, return ("abs"); case LEVEL_PANDEMONIUM: return ("pan"); - case LEVEL_BAZAAR: - return ("bzr"); + case LEVEL_PORTAL_VAULT: + return ("ptl"); } } @@ -704,11 +704,11 @@ static void place_player_on_stair(branch_type old_branch, int stair_taken) // when entering a hell or pandemonium stair_taken = DNGN_STONE_STAIRS_UP_I; } - else if (stair_taken == DNGN_ENTER_BAZAAR) + else if (stair_taken == DNGN_ENTER_PORTAL_VAULT) { stair_taken = DNGN_STONE_ARCH; } - else if (stair_taken == DNGN_EXIT_BAZAAR) + else if (stair_taken == DNGN_EXIT_PORTAL_VAULT) { stair_taken = DNGN_STONE_STAIRS_DOWN_I; } @@ -935,6 +935,9 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, // Things to update for player entering level if (load_mode == LOAD_ENTER_LEVEL) { + if (just_created_level) + level_welcome_messages(); + // Activate markers that want activating, but only when // entering a new level in an existing game. If we're starting // a new game, or reloading an existing game, diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc index 6ec9701606..1c44997a62 100644 --- a/crawl-ref/source/hiscores.cc +++ b/crawl-ref/source/hiscores.cc @@ -588,7 +588,7 @@ static const char *short_branch_name(int branch) static const char *level_type_names[] = { - "D", "Lab", "Abyss", "Pan", "Bzr" + "D", "Lab", "Abyss", "Pan", "Port" }; const char *level_area_type_name(int level_type) diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index 041b0460ad..eea7ac1121 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -702,6 +702,13 @@ static int dgn_name(lua_State *ls) PLUARET(string, map->name.c_str()); } +static int dgn_welcome(lua_State *ls) +{ + MAP(ls, 1, map); + map->welcome_messages.push_back(luaL_checkstring(ls, 2)); + return (0); +} + static int dgn_grid(lua_State *ls) { const int x = luaL_checkint(ls, 1), y = luaL_checkint(ls, 2); @@ -841,9 +848,9 @@ const char *dngn_feature_names[] = "return_from_elven_halls", "return_from_tomb", "return_from_swamp", "return_from_shoals", "return_reserved_2", "return_reserved_3", "return_reserved_4", "", "", "", "", "", "", - "", "", "", "", "", "", "", "enter_bazaar", "exit_bazaar", "", "", + "", "", "", "", "", "", "", "enter_portal_vault", "exit_portal_vault", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "altar_zin", "altar_shining_one", "altar_kikubaaqudgha", + "", "", "altar_zin", "altar_shining_one", "altar_kikubaaqudgha", "altar_yredelemnul", "altar_xom", "altar_vehumet", "altar_okawaru", "altar_makhleb", "altar_sif_muna", "altar_trog", "altar_nemelex_xobeh", "altar_elyvilon", "altar_lugonu", @@ -851,7 +858,7 @@ const char *dngn_feature_names[] = "dry_fountain_i", "sparkling_fountain", "dry_fountain_ii", "dry_fountain_iii", "dry_fountain_iv", "dry_fountain_v", "dry_fountain_vi", "dry_fountain_vii", "dry_fountain_viii", - "permadry_fountain" + "permadry_fountain" }; dungeon_feature_type dungeon_feature_by_name(const std::string &name) @@ -987,7 +994,21 @@ static int dgn_feature_desc(lua_State *ls) description_type_by_name(lua_tostring(ls, 2)); const bool need_stop = lua_isboolean(ls, 3)? lua_toboolean(ls, 3) : false; const std::string s = - feature_description(feat, NUM_TRAPS, false, dtype, need_stop); + feature_description(feat, NUM_TRAPS, dtype, need_stop); + lua_pushstring(ls, s.c_str()); + return (1); +} + +static int dgn_feature_desc_at(lua_State *ls) +{ + const description_level_type dtype = + lua_isnumber(ls, 3)? + static_cast(luaL_checkint(ls, 3)) : + description_type_by_name(lua_tostring(ls, 3)); + const bool need_stop = lua_isboolean(ls, 4)? lua_toboolean(ls, 4) : false; + const std::string s = + feature_description(luaL_checkint(ls, 1), luaL_checkint(ls, 2), + dtype, need_stop); lua_pushstring(ls, s.c_str()); return (1); } @@ -1016,6 +1037,7 @@ static const struct luaL_reg dgn_lib[] = { "tags", dgn_tags }, { "tags_remove", dgn_tags_remove }, { "chance", dgn_weight }, + { "welcome", dgn_welcome }, { "weight", dgn_weight }, { "orient", dgn_orient }, { "shuffle", dgn_shuffle }, @@ -1046,6 +1068,7 @@ static const struct luaL_reg dgn_lib[] = { "remove_listener", dgn_remove_listener }, { "remove_marker", dgn_remove_marker }, { "feature_desc", dgn_feature_desc }, + { "feature_desc_at", dgn_feature_desc_at }, { NULL, NULL } }; @@ -1112,7 +1135,8 @@ enum lua_persist_type LPT_NONE, LPT_NUMBER, LPT_STRING, - LPT_FUNCTION + LPT_FUNCTION, + LPT_NIL }; static int file_marshall_meta(lua_State *ls) @@ -1129,10 +1153,13 @@ static int file_marshall_meta(lua_State *ls) ptype = LPT_STRING; else if (lua_isfunction(ls, 2)) ptype = LPT_FUNCTION; + else if (lua_isnil(ls, 2)) + ptype = LPT_NIL; else luaL_error(ls, "Can marshall only numbers, strings and functions."); marshallByte(th, ptype); - file_marshall(ls); + if (ptype != LPT_NIL) + file_marshall(ls); return (0); } @@ -1149,6 +1176,9 @@ static int file_unmarshall_meta(lua_State *ls) return file_unmarshall_string(ls); case LPT_FUNCTION: return file_unmarshall_fn(ls); + case LPT_NIL: + lua_pushnil(ls); + return (1); default: luaL_error(ls, "Unexpected type signature."); } diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 6e5e5c7c8d..e5049c71cf 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -1023,9 +1023,9 @@ dlua_set_map::~dlua_set_map() map_def::map_def() : name(), tags(), place(), depths(), orient(), chance(), - map(), mons(), items(), keyspecs(), prelude("dlprelude"), - main("dlmain"), validate("dlvalidate"), veto("dlveto"), - index_only(false), cache_offset(0L) + welcome_messages(), map(), mons(), items(), keyspecs(), + prelude("dlprelude"), main("dlmain"), validate("dlvalidate"), + veto("dlveto"), index_only(false), cache_offset(0L) { init(); } @@ -1049,6 +1049,7 @@ void map_def::reinit() { items.clear(); keyspecs.clear(); + welcome_messages.clear(); // Base chance; this is not a percentage. chance = 10; diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index d1a0316aad..bfeb112566 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -498,6 +498,8 @@ public: map_section_type orient; int chance; + std::vector welcome_messages; + map_lines map; mons_list mons; item_list items; diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 4867225072..2f2dc84a6b 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -58,6 +58,16 @@ void map_marker::read(tagHeader &inf) unmarshallCoord(inf, pos); } +std::string map_marker::feature_description() const +{ + return (""); +} + +std::string map_marker::property(const std::string &pname) const +{ + return (""); +} + map_marker *map_marker::read_marker(tagHeader &inf) { const map_marker_type type = @@ -129,7 +139,7 @@ map_marker *map_feature_marker::parse( return new map_feature_marker(coord_def(0, 0), ft); } -std::string map_feature_marker::describe() const +std::string map_feature_marker::debug_describe() const { return make_stringf("feature (%s)", dungeon_feature_name(feat)); } @@ -270,12 +280,15 @@ void map_lua_marker::push_fn_args(const char *fn) const dlua_push_userdata(dlua, this, MAPMARK_METATABLE); } -bool map_lua_marker::callfn(const char *fn, bool warn_err) const +bool map_lua_marker::callfn(const char *fn, bool warn_err, int args) const { - const int top = lua_gettop(dlua); - push_fn_args(fn); - const bool res = - dlua.callfn("dlua_marker_method", lua_gettop(dlua) - top, 1); + if (args == -1) + { + const int top = lua_gettop(dlua); + push_fn_args(fn); + args = lua_gettop(dlua) - top; + } + const bool res = dlua.callfn("dlua_marker_method", args, 1); if (!res && warn_err) mprf(MSGCH_WARN, "mlua error: %s", dlua.error.c_str()); return (res); @@ -297,16 +310,40 @@ void map_lua_marker::notify_dgn_event(const dgn_event &e) dlua.error.c_str()); } -std::string map_lua_marker::describe() const +std::string map_lua_marker::call_str_fn(const char *fn) const { lua_stack_cleaner cln(dlua); - if (!callfn("describe")) - return make_stringf("error: %s", dlua.error.c_str()); + if (!callfn(fn)) + return make_stringf("error (%s): %s", fn, dlua.error.c_str()); - std::string desc; + std::string result; if (lua_isstring(dlua, -1)) - desc = lua_tostring(dlua, -1); - return desc; + result = lua_tostring(dlua, -1); + return (result); +} + +std::string map_lua_marker::debug_describe() const +{ + return (call_str_fn("describe")); +} + +std::string map_lua_marker::feature_description() const +{ + return (call_str_fn("feature_description")); +} + +std::string map_lua_marker::property(const std::string &pname) const +{ + lua_stack_cleaner cln(dlua); + push_fn_args("property"); + lua_pushstring(dlua, pname.c_str()); + if (!callfn("property", false, 4)) + return make_stringf("error (prop:%s): %s", + pname.c_str(), dlua.error.c_str()); + std::string result; + if (lua_isstring(dlua, -1)) + result = lua_tostring(dlua, -1); + return (result); } map_marker *map_lua_marker::parse( @@ -315,7 +352,7 @@ map_marker *map_lua_marker::parse( if (s.find("lua:") != 0) return (NULL); std::string raw = s; - strip_tag(raw, "lua:"); + strip_tag(raw, "lua:", true); map_lua_marker *mark = new map_lua_marker(raw, ctx); if (!mark->initialised) { @@ -394,6 +431,20 @@ std::vector env_get_markers(const coord_def &c) return (rmarkers); } +std::string env_property_at(const coord_def &c, map_marker_type type, + const std::string &key) +{ + std::pair + els = env.markers.equal_range(c); + for (dgn_marker_map::const_iterator i = els.first; i != els.second; ++i) + { + const std::string prop = i->second->property(key); + if (!prop.empty()) + return (prop); + } + return (""); +} + void env_clear_markers() { for (dgn_marker_map::iterator i = env.markers.begin(); diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h index eacddcf266..dc18f77946 100644 --- a/crawl-ref/source/mapmark.h +++ b/crawl-ref/source/mapmark.h @@ -14,6 +14,7 @@ enum map_marker_type { MAT_FEATURE, // Stock marker. MAT_LUA_MARKER, + MAT_FEATURE_NAME, NUM_MAP_MARKER_TYPES, MAT_ANY }; @@ -29,8 +30,10 @@ public: virtual void activate(); virtual void write(tagHeader &) const; virtual void read(tagHeader &); - virtual std::string describe() const = 0; - + virtual std::string debug_describe() const = 0; + virtual std::string feature_description() const; + virtual std::string property(const std::string &pname) const; + static map_marker *read_marker(tagHeader&); static map_marker *parse_marker(const std::string &text, const std::string &ctx = "") @@ -57,7 +60,7 @@ public: map_feature_marker(const map_feature_marker &other); void write(tagHeader &) const; void read(tagHeader &); - std::string describe() const; + std::string debug_describe() const; static map_marker *read(tagHeader &, map_marker_type); static map_marker *parse(const std::string &s, const std::string &) throw (std::string); @@ -78,8 +81,10 @@ public: void write(tagHeader &) const; void read(tagHeader &); - std::string describe() const; - + std::string debug_describe() const; + std::string feature_description() const; + std::string property(const std::string &pname) const; + void notify_dgn_event(const dgn_event &e); static map_marker *read(tagHeader &, map_marker_type); @@ -91,7 +96,8 @@ private: void check_register_table(); bool get_table() const; void push_fn_args(const char *fn) const; - bool callfn(const char *fn, bool warn_err = false) const; + bool callfn(const char *fn, bool warn_err = false, int args = -1) const; + std::string call_str_fn(const char *fn) const; }; void env_activate_markers(); @@ -101,5 +107,7 @@ void env_remove_markers_at(const coord_def &c, map_marker_type); map_marker *env_find_marker(const coord_def &c, map_marker_type); std::vector env_get_markers(const coord_def &c); void env_clear_markers(); +std::string env_property_at(const coord_def &c, map_marker_type, + const std::string &key); #endif diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc index 1af550ccfe..d5c39d31db 100644 --- a/crawl-ref/source/menu.cc +++ b/crawl-ref/source/menu.cc @@ -760,14 +760,14 @@ std::vector slider_menu::show() fix_entry(); do_menu(); - if (selected >= 0 && selected <= (int) items.size()) + if (selected >= 0 && selected < (int) items.size()) sel.push_back(items[selected]); return (sel); } const MenuEntry *slider_menu::selected_entry() const { - if (selected >= 0 && selected <= (int) items.size()) + if (selected >= 0 && selected < (int) items.size()) return (items[selected]); return (NULL); diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index f94624ff39..328f46617d 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -198,7 +198,7 @@ bool grid_sealable_portal(dungeon_feature_type grid) case DNGN_ENTER_ABYSS: case DNGN_ENTER_PANDEMONIUM: case DNGN_ENTER_LABYRINTH: - case DNGN_ENTER_BAZAAR: + case DNGN_ENTER_PORTAL_VAULT: return (true); default: return (false); @@ -233,10 +233,10 @@ command_type grid_stair_direction(dungeon_feature_type grid) case DNGN_RETURN_RESERVED_4: case DNGN_ENTER_SHOP: case DNGN_EXIT_HELL: - case DNGN_EXIT_BAZAAR: + case DNGN_EXIT_PORTAL_VAULT: return (CMD_GO_UPSTAIRS); - case DNGN_ENTER_BAZAAR: + case DNGN_ENTER_PORTAL_VAULT: case DNGN_ENTER_HELL: case DNGN_ENTER_LABYRINTH: case DNGN_STONE_STAIRS_DOWN_I: @@ -380,7 +380,7 @@ const char *grid_item_destruction_message( dungeon_feature_type grid ) // Returns true if exits from this type of level involve going upstairs. bool level_type_exits_up(level_area_type type) { - return (type == LEVEL_LABYRINTH || type == LEVEL_BAZAAR); + return (type == LEVEL_LABYRINTH || type == LEVEL_PORTAL_VAULT); } bool level_type_exits_down(level_area_type type) @@ -788,8 +788,15 @@ static void climb_message(dungeon_feature_type stair, bool going_up) static void leaving_level_now() { + // Note the name ahead of time because the events may cause + // markers to be discarded. + const std::string newtype = + env_property_at(you.pos(), MAT_ANY, "dst"); + dungeon_events.fire_position_event(DET_PLAYER_CLIMBS, you.pos()); dungeon_events.fire_event(DET_LEAVING_LEVEL); + + you.level_type_name = newtype; } void up_stairs(void) @@ -1167,9 +1174,9 @@ void down_stairs( int old_level, dungeon_feature_type force_stair ) { you.level_type = LEVEL_PANDEMONIUM; } - else if (stair_find == DNGN_ENTER_BAZAAR) + else if (stair_find == DNGN_ENTER_PORTAL_VAULT) { - you.level_type = LEVEL_BAZAAR; + you.level_type = LEVEL_PORTAL_VAULT; } // When going downstairs into a special level, delete any previous @@ -1238,10 +1245,6 @@ void down_stairs( int old_level, dungeon_feature_type force_stair ) } break; - case LEVEL_BAZAAR: - mpr("You enter an inter-dimensional bazaar!"); - break; - default: climb_message(stair_find, false); break; @@ -1379,8 +1382,8 @@ std::string level_description_string() if (you.level_type == LEVEL_LABYRINTH) return "- a Labyrinth"; - if (you.level_type == LEVEL_BAZAAR) - return "- a Bazaar"; + if (you.level_type == LEVEL_PORTAL_VAULT) + return "- a Portal Chamber"; // level_type == LEVEL_DUNGEON char buf[200]; @@ -2250,8 +2253,8 @@ std::string place_name( unsigned short place, bool long_name, return ( long_name ? "Pandemonium" : "Pan" ); case LEVEL_LABYRINTH: return ( long_name ? "a Labyrinth" : "Lab" ); - case LEVEL_BAZAAR: - return ( long_name ? "a Bazaar" : "Bzr" ); + case LEVEL_PORTAL_VAULT: + return ( long_name ? "a Portal Chamber" : "Port" ); default: return ( long_name ? "Buggy Badlands" : "Bug" ); } diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 88355d3166..01ef978f6d 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -922,7 +922,7 @@ void end_game( struct scorefile_entry &se ) unlink( make_filename( you.your_name, 0, BRANCH_MAIN_DUNGEON, LEVEL_LABYRINTH, false ).c_str() ); unlink( make_filename( you.your_name, 0, BRANCH_MAIN_DUNGEON, - LEVEL_BAZAAR, false ).c_str() ); + LEVEL_PORTAL_VAULT, false ).c_str() ); // create base file name std::string basename = get_savedir_filename( you.your_name, "", "" ); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 00c3e24076..5120e2f876 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -5356,15 +5356,13 @@ flight_type player::flies() const bool player::light_flight() const { - return (flies() == FL_FLY && travelling_light()); + // Only Kenku get perks for flying light. + return (species == SP_KENKU && flies() == FL_FLY && travelling_light()); } bool player::travelling_light() const { - const item_def *armour = you.slot_item(EQ_BODY_ARMOUR); - if (armour && !is_light_armour(*armour)) - return (false); - return (you.burden < carrying_capacity(BS_UNENCUMBERED) * 60 / 100); + return (you.burden < carrying_capacity(BS_UNENCUMBERED) * 70 / 100); } int player::mons_species() const diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc index b93a231f6d..c5146a6d6e 100644 --- a/crawl-ref/source/stash.cc +++ b/crawl-ref/source/stash.cc @@ -44,7 +44,7 @@ void stash_init_new_level() { // If there's an existing stash level for Pan, blow it away. stashes.remove_level( level_id(LEVEL_PANDEMONIUM) ); - stashes.remove_level( level_id(LEVEL_BAZAAR) ); + stashes.remove_level( level_id(LEVEL_PORTAL_VAULT) ); } std::string userdef_annotate_item(const char *s, const item_def *item, diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index cc0e1648d9..8972af6cc0 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -726,6 +726,7 @@ static void tag_construct_you(struct tagHeader &th) marshallByte(th,you.special_wield); marshallByte(th,you.berserk_penalty); marshallByte(th,you.level_type); + marshallString(th, you.level_type_name); marshallByte(th,you.synch_time); marshallByte(th,you.disease); marshallByte(th,you.species); @@ -1032,6 +1033,7 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) you.special_wield = unmarshallByte(th); you.berserk_penalty = unmarshallByte(th); you.level_type = static_cast( unmarshallByte(th) ); + you.level_type_name = unmarshallString(th); you.synch_time = unmarshallByte(th); you.disease = unmarshallByte(th); you.species = static_cast(unmarshallByte(th)); diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 8db09aa571..71c674355f 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -569,8 +569,8 @@ void initialise_travel() traversable_terrain[DNGN_RETURN_FROM_TOMB] = traversable_terrain[DNGN_RETURN_FROM_SWAMP] = traversable_terrain[DNGN_RETURN_FROM_SHOALS] = - traversable_terrain[DNGN_ENTER_BAZAAR] = - traversable_terrain[DNGN_EXIT_BAZAAR] = + traversable_terrain[DNGN_ENTER_PORTAL_VAULT] = + traversable_terrain[DNGN_EXIT_PORTAL_VAULT] = traversable_terrain[DNGN_ALTAR_ZIN] = traversable_terrain[DNGN_ALTAR_SHINING_ONE] = traversable_terrain[DNGN_ALTAR_KIKUBAAQUDGHA] = @@ -2735,8 +2735,8 @@ level_id level_id::parse_level_id(const std::string &s) throw (std::string) return (level_id(LEVEL_PANDEMONIUM)); else if (branch == "Lab") return (level_id(LEVEL_LABYRINTH)); - else if (branch == "Bzr") - return (level_id(LEVEL_BAZAAR)); + else if (branch == "Port") + return (level_id(LEVEL_PORTAL_VAULT)); const branch_type br = str_to_branch(branch); if (br == NUM_BRANCHES) diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp index e234f90b2d..f831de576a 100644 --- a/crawl-ref/source/util/levcomp.lpp +++ b/crawl-ref/source/util/levcomp.lpp @@ -188,6 +188,7 @@ default-depth: { BEGIN(ARGUMENT); return DEFAULT_DEPTH; } DEPTH: { BEGIN(ARGUMENT); return DEPTH; } ORIENT: { BEGIN(ARGUMENT); return ORIENT; } PLACE: { BEGIN(ARGUMENT); return PLACE; } +WELCOME: { BEGIN(ARGUMENT); return WELCOME; } CHANCE: return CHANCE; WEIGHT: return CHANCE; FLAGS: { BEGIN(KEYWORDS); return TAGS; } diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp index 10b74dcc04..26f736cd23 100644 --- a/crawl-ref/source/util/levcomp.ypp +++ b/crawl-ref/source/util/levcomp.ypp @@ -54,7 +54,7 @@ level_range set_range(const char *s, int start, int end) %token DEFAULT_DEPTH SHUFFLE SUBST TAGS KFEAT KITEM KMONS %token NAME DEPTH ORIENT PLACE CHANCE MONS ITEM MARKER -%token PRELUDE MAIN VALIDATE VETO NSUBST +%token PRELUDE MAIN VALIDATE VETO NSUBST WELCOME %token COMMA INTEGER CHARACTER @@ -152,6 +152,7 @@ metaline : place | depth | chance | orientation + | welcome | mons | items | marker @@ -413,6 +414,15 @@ orientation : ORIENT {} } ; +welcome : WELCOME STRING + { + lc_map.main.add( + yylineno, + make_stringf("welcome(\"%s\")", + quote_lua_string($2).c_str())); + } + ; + map_def : map_lines ; diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 67e9274d22..0024465eb2 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -2238,8 +2238,8 @@ bool is_feature(int feature, int x, int y) { case DNGN_ENTER_HELL: case DNGN_ENTER_LABYRINTH: - case DNGN_ENTER_BAZAAR: - case DNGN_EXIT_BAZAAR: + case DNGN_ENTER_PORTAL_VAULT: + case DNGN_EXIT_PORTAL_VAULT: case DNGN_ENTER_SHOP: case DNGN_ENTER_DIS: case DNGN_ENTER_GEHENNA: @@ -3400,8 +3400,8 @@ void init_feature_table( void ) Feature[i].seen_colour = CYAN; break; - case DNGN_ENTER_BAZAAR: - case DNGN_EXIT_BAZAAR: + case DNGN_ENTER_PORTAL_VAULT: + case DNGN_EXIT_PORTAL_VAULT: Feature[i].symbol = Options.char_table[ DCHAR_ARCH ]; Feature[i].colour = EC_SHIMMER_BLUE; Feature[i].notable = true; -- cgit v1.2.3-54-g00ecf