diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-25 15:33:36 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-25 15:33:36 +0000 |
commit | 0afe4c455bf5a0358cf7f6688b413389a5080fcc (patch) | |
tree | 9580836186a5f1612b2a98279255ee7af45c1063 | |
parent | ad382c58bd22273fdcb13759bf35e1c89d573e97 (diff) | |
download | crawl-ref-0afe4c455bf5a0358cf7f6688b413389a5080fcc.tar.gz crawl-ref-0afe4c455bf5a0358cf7f6688b413389a5080fcc.zip |
Ziggurat portals charge gold for entry.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7610 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/clua.cc | 68 | ||||
-rw-r--r-- | crawl-ref/source/clua.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/dat/clua/lm_toll.lua | 61 | ||||
-rw-r--r-- | crawl-ref/source/dat/clua/ziggurat.lua | 9 | ||||
-rw-r--r-- | crawl-ref/source/dgnevent.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/dgnevent.h | 15 | ||||
-rw-r--r-- | crawl-ref/source/luadgn.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/stuff.cc | 7 |
11 files changed, 207 insertions, 17 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index ae30763ab3..5d4cdb5e36 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -816,6 +816,18 @@ LUARET1(you_see_grid_no_trans, boolean, LUARET1(you_can_smell, boolean, player_can_smell()) LUARET1(you_has_claws, number, you.has_claws(false)) +static int _you_gold(lua_State *ls) +{ + if (lua_gettop(ls) >= 1) + { + ASSERT_DLUA; + const int new_gold = luaL_checkint(ls, 1); + you.gold = std::max(new_gold, 0); + you.redraw_gold = true; + } + PLUARET(number, you.gold); +} + void lua_push_floor_items(lua_State *ls); static int you_floor_items(lua_State *ls) { @@ -871,6 +883,7 @@ static const struct luaL_reg you_lib[] = { "race" , you_race }, { "class" , you_class }, { "god" , you_god }, + { "gold" , _you_gold }, { "good_god" , you_good_god }, { "evil_god" , you_evil_god }, { "hp" , you_hp }, @@ -1824,6 +1837,48 @@ LUARET1(crawl_getch, number, getch()) LUARET1(crawl_kbhit, number, kbhit()) LUAWRAP(crawl_flush_input, flush_input_buffer(FLUSH_LUA)) +static char _lua_char(lua_State *ls, int ndx, char defval = 0) +{ + return (lua_isnone(ls, ndx) || !lua_isstring(ls, ndx)? defval + : lua_tostring(ls, ndx)[0]); +} + +static int crawl_yesno(lua_State *ls) +{ + const char *prompt = luaL_checkstring(ls, 1); + const bool safe = lua_toboolean(ls, 2); + const int safeanswer = _lua_char(ls, 3); + const bool clear_after = + lua_isnone(ls, 4) ? true : lua_toboolean(ls, 4); + const bool interrupt_delays = + lua_isnone(ls, 5) ? true : lua_toboolean(ls, 5); + const bool noprompt = + lua_isnone(ls, 6) ? false : lua_toboolean(ls, 6); + + cursor_control con(true); + lua_pushboolean(ls, yesno(prompt, safe, safeanswer, clear_after, + interrupt_delays, noprompt)); + return (1); +} + +static int crawl_yesnoquit(lua_State *ls) +{ + const char *prompt = luaL_checkstring(ls, 1); + const bool safe = lua_toboolean(ls, 2); + const int safeanswer = _lua_char(ls, 3); + const bool allow_all = + lua_isnone(ls, 4) ? false : lua_toboolean(ls, 4); + const bool clear_after = + lua_isnone(ls, 5) ? true : lua_toboolean(ls, 5); + + // Skipping the other params until somebody needs them. + + cursor_control con(true); + lua_pushnumber(ls, yesnoquit(prompt, safe, safeanswer, allow_all, + clear_after)); + return (1); +} + static void crawl_sendkeys_proc(lua_State *ls, int argi) { if (lua_isstring(ls, argi)) @@ -2107,6 +2162,10 @@ LUARET1(crawl_random_range, number, random_range( luaL_checkint(ls, 1), luaL_checkint(ls, 2), lua_isnumber(ls, 3)? luaL_checkint(ls, 3) : 1 )) LUARET1(crawl_coinflip, boolean, coinflip()) +LUARET1(crawl_roll_dice, number, + lua_gettop(ls) == 1 + ? roll_dice( 1, luaL_checkint(ls, 1) ) + : roll_dice( luaL_checkint(ls, 1), luaL_checkint(ls, 2) )) static int crawl_random_element(lua_State *ls) { @@ -2202,12 +2261,15 @@ static const struct luaL_reg crawl_lib[] = { "one_chance_in", crawl_one_chance_in }, { "random2avg" , crawl_random2avg }, { "coinflip", crawl_coinflip }, + { "roll_dice", crawl_roll_dice }, { "random_range", crawl_random_range }, { "random_element", crawl_random_element }, { "redraw_screen", crawl_redraw_screen }, { "input_line", crawl_input_line }, { "c_input_line", crawl_c_input_line}, { "getch", crawl_getch }, + { "yesno", crawl_yesno }, + { "yesnoquit", crawl_yesnoquit }, { "kbhit", crawl_kbhit }, { "flush_input", crawl_flush_input }, { "sendkeys", crawl_sendkeys }, @@ -2411,12 +2473,6 @@ struct MonsterWrap return (1); \ } -#define ASSERT_DLUA \ - do { \ - if (CLua::get_vm(ls).managed_vm) \ - luaL_error(ls, "Operation forbidden in end-user script"); \ - } while (false) - MDEF(name) { PLUARET(string, mons_type_name(mons->type, DESC_PLAIN).c_str()); diff --git a/crawl-ref/source/clua.h b/crawl-ref/source/clua.h index e1499675a8..136e332b19 100644 --- a/crawl-ref/source/clua.h +++ b/crawl-ref/source/clua.h @@ -259,6 +259,12 @@ void lua_set_exclusive_item(const item_def *item = NULL); return (2); \ } +#define ASSERT_DLUA \ + do { \ + if (CLua::get_vm(ls).managed_vm) \ + luaL_error(ls, "Operation forbidden in end-user script"); \ + } while (false) + template <class T> inline static T *util_get_userdata(lua_State *ls, int ndx) { diff --git a/crawl-ref/source/dat/clua/lm_toll.lua b/crawl-ref/source/dat/clua/lm_toll.lua new file mode 100644 index 0000000000..3e111e6dba --- /dev/null +++ b/crawl-ref/source/dat/clua/lm_toll.lua @@ -0,0 +1,61 @@ +------------------------------------------------------------------------------ +-- lm_toll.lua: +-- One-way toll-stair marker. +------------------------------------------------------------------------------ + +require("clua/lm_1way.lua") + +TollStair = util.subclass(OneWayStair) + +function TollStair:new(props) + local toll = self.super.new(self, props) + if not props.amount or props.amount < 1 then + error("Bad toll amount: " .. props.amount) + end + return toll +end + +function TollStair:activate(marker) + self.super.activate(self, marker) + + dgn.register_listener(dgn.dgn_event_type("v_leave_level"), + marker, marker:pos()) +end + +function TollStair:event(marker, ev) + if self.super.event(self, marker, ev) then + return true + end + + if ev:type() == dgn.dgn_event_type('v_leave_level') then + -- Have we enough gold? + local gold = you.gold() + local needed = self.props.amount + + if gold < needed then + crawl.mpr("This portal charges " .. needed .. " gold for entry; " .. + "you have only " .. gold .. " gold.") + return false + end + + -- Ok, ask if the player wants to spend the $$$. + if not crawl.yesno("This portal charges " .. needed .. + " gold for entry. Pay?", true, "n") then + return false + end + + -- Gold gold gold! Forget that gold! + you.gold(you.gold() - needed) + return true + end +end + +function TollStair:read(marker, th) + TollStair.super.read(self, marker, th) + setmetatable(self, TollStair) + return self +end + +function toll_stair(pars) + return TollStair:new(pars) +end
\ No newline at end of file diff --git a/crawl-ref/source/dat/clua/ziggurat.lua b/crawl-ref/source/dat/clua/ziggurat.lua index 9b00eab380..366f6274c1 100644 --- a/crawl-ref/source/dat/clua/ziggurat.lua +++ b/crawl-ref/source/dat/clua/ziggurat.lua @@ -10,6 +10,8 @@ -- upvalues cannot (yet) be saved. ------------------------------------------------------------------------------ +require("clua/lm_toll.lua") + function zig() if not dgn.persist.ziggurat or not dgn.persist.ziggurat.depth then dgn.persist.ziggurat = { } @@ -71,8 +73,13 @@ end -- Common setup for ziggurat entry vaults. function ziggurat_portal(e) + local d = crawl.roll_dice + local entry_fee = + 10 * math.floor(100 + d(3,200) / 3 + d(10) * d(10) * d(10)) + local function stair() - return one_way_stair { + return toll_stair { + amount = entry_fee, desc = "gateway to a ziggurat", dst = "ziggurat", dstname = "Ziggurat:1", diff --git a/crawl-ref/source/dgnevent.cc b/crawl-ref/source/dgnevent.cc index d6848a8039..e6092d7de2 100644 --- a/crawl-ref/source/dgnevent.cc +++ b/crawl-ref/source/dgnevent.cc @@ -40,6 +40,31 @@ bool dgn_event_dispatcher::has_listeners_at(const coord_def &pos) const return (grid_triggers[pos.x][pos.y].get()); } +bool dgn_event_dispatcher::fire_vetoable_position_event( + dgn_event_type et, const coord_def &pos) +{ + const dgn_event event(et, pos); + return fire_vetoable_position_event(event, pos); +} + +bool dgn_event_dispatcher::fire_vetoable_position_event( + const dgn_event &et, const coord_def &pos) +{ + dgn_square_alarm *alarm = grid_triggers[pos.x][pos.y].get(); + if (alarm && (alarm->eventmask & et.type)) + { + dgn_square_alarm alcopy(*alarm); + for (std::list<dgn_event_listener*>::iterator + i = alcopy.listeners.begin(); + i != alcopy.listeners.end(); ++i) + { + if (!(*i)->notify_dgn_event(et)) + return (false); + } + } + return (true); +} + void dgn_event_dispatcher::fire_position_event( dgn_event_type event, const coord_def &pos) { @@ -61,7 +86,6 @@ void dgn_event_dispatcher::fire_position_event( (*i)->notify_dgn_event(et); } } - } void dgn_event_dispatcher::fire_event(const dgn_event &e) diff --git a/crawl-ref/source/dgnevent.h b/crawl-ref/source/dgnevent.h index fdafe892aa..75a0174c06 100644 --- a/crawl-ref/source/dgnevent.h +++ b/crawl-ref/source/dgnevent.h @@ -29,7 +29,10 @@ enum dgn_event_type DET_MONSTER_DIED = 0x0100, DET_ITEM_PICKUP = 0x0200, DET_ITEM_MOVED = 0x0400, - DET_FEAT_CHANGE = 0x0800 + DET_FEAT_CHANGE = 0x0800, + + // Vetoable events, usually fired before the corresponding (real) event. + DETV_LEAVE_LEVEL = 0x1000 }; class dgn_event @@ -55,7 +58,8 @@ class dgn_event_listener { public: virtual ~dgn_event_listener(); - virtual void notify_dgn_event(const dgn_event &e) = 0; + // For vetoable events, return false to veto. + virtual bool notify_dgn_event(const dgn_event &e) = 0; }; // Alarm goes off when something enters this square. @@ -97,6 +101,13 @@ public: bool has_listeners_at(const coord_def &pos) const; void move_listeners(const coord_def &from, const coord_def &to); + // Returns false if the event is vetoed. + bool fire_vetoable_position_event(const dgn_event &e, + const coord_def &pos); + + bool fire_vetoable_position_event(dgn_event_type et, + const coord_def &pos); + void fire_position_event(dgn_event_type et, const coord_def &pos); void fire_position_event(const dgn_event &e, const coord_def &pos); void fire_event(dgn_event_type et); diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc index f760a90e0d..797e367f8c 100644 --- a/crawl-ref/source/luadgn.cc +++ b/crawl-ref/source/luadgn.cc @@ -1271,7 +1271,10 @@ static const char *dgn_event_type_names[] = { "none", "turn", "mons_move", "player_move", "leave_level", "entering_level", "entered_level", "player_los", "player_climb", - "monster_dies", "item_pickup", "item_moved", "feat_change" + "monster_dies", "item_pickup", "item_moved", "feat_change", + + // vetoable events + "v_leave_level" }; static dgn_event_type dgn_event_type_by_name(const std::string &name) diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 269b973cbf..6e4e2f0907 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -337,16 +337,27 @@ void map_lua_marker::activate(bool verbose) callfn("activate", true, 4); } -void map_lua_marker::notify_dgn_event(const dgn_event &e) +bool map_lua_marker::notify_dgn_event(const dgn_event &e) { lua_stack_cleaner clean(dlua); push_fn_args("event"); clua_push_dgn_event(dlua, &e); - if (!dlua.callfn("dlua_marker_method", 4, 0)) + if (!dlua.callfn("dlua_marker_method", 4, 1)) { mprf(MSGCH_ERROR, "notify_dgn_event: Lua error: %s", dlua.error.c_str()); + + // Lua error prevents veto if the event is vetoable. + return (true); } + + bool accepted = true; + + // We accept only a real boolean false as a veto. + if (lua_isboolean(dlua, -1)) + accepted = lua_toboolean(dlua, -1); + + return (accepted); } std::string map_lua_marker::call_str_fn(const char *fn) const diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h index eb7eb22ba4..5b9862bffe 100644 --- a/crawl-ref/source/mapmark.h +++ b/crawl-ref/source/mapmark.h @@ -112,7 +112,7 @@ public: std::string feature_description() const; std::string property(const std::string &pname) const; - void notify_dgn_event(const dgn_event &e); + bool notify_dgn_event(const dgn_event &e); static map_marker *read(reader &, map_marker_type); static map_marker *parse(const std::string &s, const std::string &) diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index d7d8fb9c1b..e70d5fa9e3 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -1676,6 +1676,11 @@ void up_stairs(dungeon_feature_type force_stair, return; } + // Bail if any markers veto the move. + if (!dungeon_events.fire_vetoable_position_event(DETV_LEAVE_LEVEL, + you.pos())) + return; + // Checks are done, the character is committed to moving between levels. leaving_level_now(); @@ -2056,6 +2061,11 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, } } + // Bail if any markers veto the move. + if (!dungeon_events.fire_vetoable_position_event(DETV_LEAVE_LEVEL, + you.pos())) + return; + const level_id destination_override(_stair_destination_override()); // All checks are done, the player is on the move now. diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 6dc6abc4d3..42a3ede04c 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -1139,9 +1139,10 @@ int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all, if (!crawl_state.is_repeating_cmd()) interrupt_activity( AI_FORCE_INTERRUPT ); - std::string prompt = make_stringf("%s%s ", str ? str : "Buggy prompt?", - _list_allowed_keys(alt_yes, alt_yes2, - safe, allow_all).c_str()); + std::string prompt = + make_stringf("%s%s ", str ? str : "Buggy prompt?", + _list_allowed_keys(alt_yes, alt_yes2, + safe, allow_all).c_str()); while (true) { mpr(prompt.c_str(), MSGCH_PROMPT); |