Apply the new ground_level method.
[crawl.git] / crawl-ref / source / l_dgnit.cc
blobeadc8fc7e15aecd860b845367679cad2d9faf646
1 /*
2 * File: l_dgnit.cc
3 * Summary: Item-related functions in lua library "dgn".
4 */
6 #include "AppHdr.h"
8 #include "cluautil.h"
9 #include "l_libs.h"
11 #include "coord.h"
12 #include "dungeon.h"
13 #include "env.h"
14 #include "items.h"
15 #include "libutil.h"
16 #include "mapdef.h"
17 #include "stash.h"
19 #define ITEMLIST_METATABLE "crawldgn.item_list"
21 static item_list _lua_get_ilist(lua_State *ls, int ndx)
23 if (lua_isstring(ls, ndx))
25 const char *spec = lua_tostring(ls, ndx);
27 item_list ilist;
28 const std::string err = ilist.add_item(spec);
29 if (!err.empty())
30 luaL_error(ls, err.c_str());
32 return (ilist);
34 else
36 item_list **ilist =
37 clua_get_userdata<item_list*>(ls, ITEMLIST_METATABLE, ndx);
38 if (ilist)
39 return (**ilist);
41 luaL_argerror(ls, ndx, "Expected item list object or string");
42 return item_list();
46 void register_itemlist(lua_State *ls)
48 clua_register_metatable(ls, ITEMLIST_METATABLE, NULL,
49 lua_object_gc<item_list>);
52 static int dgn_item_from_index(lua_State *ls)
54 const int index = luaL_checkint(ls, 1);
56 item_def *item = &mitm[index];
58 if (item->defined())
59 clua_push_item(ls, item);
60 else
61 lua_pushnil(ls);
63 return (1);
66 static int dgn_items_at(lua_State *ls)
68 COORDS(c, 1, 2);
69 lua_push_floor_items(ls, env.igrid(c));
70 return (1);
73 static int _dgn_item_spec(lua_State *ls)
75 const item_list ilist = _lua_get_ilist(ls, 1);
76 dlua_push_object_type<item_list>(ls, ITEMLIST_METATABLE, ilist);
77 return (1);
80 static int dgn_create_item(lua_State *ls)
82 COORDS(c, 1, 2);
84 item_list ilist = _lua_get_ilist(ls, 3);
85 const int level =
86 lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.absdepth0;
88 dgn_place_multiple_items(ilist, c, level);
89 link_items();
90 return (0);
93 static int dgn_item_property_remove(lua_State *ls)
95 if (item_def *item = clua_get_item(ls, 1))
97 item->props.erase(luaL_checkstring(ls, 2));
99 return (0);
102 static int dgn_item_property_set(lua_State *ls)
104 if (item_def *item = clua_get_item(ls, 1))
106 const std::string key = luaL_checkstring(ls, 2);
107 const std::string type = luaL_checkstring(ls, 3);
108 if (type.empty() || type.length() > 1)
109 luaL_error(ls, "Expected type: [BbSifsC], got: '%s'",
110 type.c_str());
112 switch (type[0])
114 case 'B':
115 item->props[key].get_bool() = lua_toboolean(ls, 4);
116 break;
117 case 'b':
118 item->props[key].get_byte() = luaL_checkint(ls, 4);
119 break;
120 case 'S':
121 item->props[key].get_short() = luaL_checkint(ls, 4);
122 break;
123 case 'i':
124 item->props[key].get_int() = luaL_checkint(ls, 4);
125 break;
126 case 'f':
127 item->props[key].get_float() = luaL_checknumber(ls, 4);
128 break;
129 case 's':
130 item->props[key].get_string() = luaL_checkstring(ls, 4);
131 break;
132 case 'C':
133 item->props[key].get_coord() = coord_def(luaL_checkint(ls, 4),
134 luaL_checkint(ls, 5));
135 break;
136 default:
137 luaL_error(ls, "Unknown type: '%s'", type.c_str());
138 break;
141 return (0);
144 static int dgn_item_property(lua_State *ls)
146 if (item_def *item = clua_get_item(ls, 1))
148 const std::string key = luaL_checkstring(ls, 2);
149 const std::string type = luaL_checkstring(ls, 3);
150 if (type.empty() || type.length() > 1)
151 luaL_error(ls, "Expected type: [BbSifsC], got: '%s'",
152 type.c_str());
154 if (!item->props.exists(key))
156 lua_pushnil(ls);
157 return (1);
160 switch (type[0])
162 case 'B':
163 lua_pushboolean(ls, item->props[key].get_byte());
164 break;
165 case 'b':
166 lua_pushnumber(ls, item->props[key].get_byte());
167 break;
168 case 'S':
169 lua_pushnumber(ls, item->props[key].get_short());
170 break;
171 case 'i':
172 lua_pushnumber(ls, item->props[key].get_int());
173 break;
174 case 'f':
175 lua_pushnumber(ls, item->props[key].get_float());
176 break;
177 case 's':
178 lua_pushstring(ls, item->props[key].get_string().c_str());
179 break;
180 case 'C':
182 const coord_def p(item->props[key].get_coord());
183 lua_pushnumber(ls, p.x);
184 lua_pushnumber(ls, p.y);
185 return (2);
187 default:
188 luaL_error(ls, "Unknown type: '%s'", type.c_str());
189 break;
192 return (1);
195 // Returns two arrays: one of floor items, one of shop items.
196 static int dgn_stash_items(lua_State *ls)
198 unsigned min_value = lua_isnumber(ls, 1) ? luaL_checkint(ls, 1) : 0;
199 bool skip_stackable = lua_isboolean(ls, 2) ? lua_toboolean(ls, 2)
200 : false;
201 std::vector<const item_def*> floor_items;
202 std::vector<const item_def*> shop_items;
204 for (ST_ItemIterator stii; stii; ++stii)
206 if (skip_stackable && is_stackable_item(*stii))
207 continue;
208 if (min_value > 0)
210 if (stii.shop())
212 if (stii.price() < min_value)
213 continue;
215 else if (item_value(*stii, true) < min_value)
216 continue;
218 if (stii.shop())
219 shop_items.push_back(&(*stii));
220 else
221 floor_items.push_back(&(*stii));
224 lua_newtable(ls);
225 int index = 0;
227 for (unsigned int i = 0; i < floor_items.size(); i++)
229 clua_push_item(ls, const_cast<item_def*>(floor_items[i]));
230 lua_rawseti(ls, -2, ++index);
233 lua_newtable(ls);
234 index = 0;
236 for (unsigned int i = 0; i < shop_items.size(); i++)
238 clua_push_item(ls, const_cast<item_def*>(shop_items[i]));
239 lua_rawseti(ls, -2, ++index);
242 return (2);
245 const struct luaL_reg dgn_item_dlib[] =
247 { "item_from_index", dgn_item_from_index },
248 { "items_at", dgn_items_at },
249 { "create_item", dgn_create_item },
250 { "item_property_remove", dgn_item_property_remove },
251 { "item_property_set", dgn_item_property_set },
252 { "item_property", dgn_item_property },
253 { "item_spec", _dgn_item_spec },
254 { "stash_items", dgn_stash_items },
256 { NULL, NULL }