summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-25 15:33:36 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-11-25 15:33:36 +0000
commit0afe4c455bf5a0358cf7f6688b413389a5080fcc (patch)
tree9580836186a5f1612b2a98279255ee7af45c1063
parentad382c58bd22273fdcb13759bf35e1c89d573e97 (diff)
downloadcrawl-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.cc68
-rw-r--r--crawl-ref/source/clua.h6
-rw-r--r--crawl-ref/source/dat/clua/lm_toll.lua61
-rw-r--r--crawl-ref/source/dat/clua/ziggurat.lua9
-rw-r--r--crawl-ref/source/dgnevent.cc26
-rw-r--r--crawl-ref/source/dgnevent.h15
-rw-r--r--crawl-ref/source/luadgn.cc5
-rw-r--r--crawl-ref/source/mapmark.cc15
-rw-r--r--crawl-ref/source/mapmark.h2
-rw-r--r--crawl-ref/source/misc.cc10
-rw-r--r--crawl-ref/source/stuff.cc7
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);