+static void setfloatfield(lua_State *L, int table,
+ const char *fieldname, float value)
+{
+ lua_pushnumber(L, value);
+ if(table < 0)
+ table -= 1;
+ lua_setfield(L, table, fieldname);
+}
+
+static void warn_if_field_exists(lua_State *L, int table,
+ const char *fieldname, const std::string &message)
+{
+ lua_getfield(L, table, fieldname);
+ if(!lua_isnil(L, -1)){
+ infostream<<script_get_backtrace(L)<<std::endl;
+ infostream<<"WARNING: field \""<<fieldname<<"\": "
+ <<message<<std::endl;
+ }
+ lua_pop(L, 1);
+}
+
+/*
+ Inventory stuff
+*/
+
+static void inventory_set_list_from_lua(Inventory *inv, const char *name,
+ lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
+{
+ if(tableindex < 0)
+ tableindex = lua_gettop(L) + 1 + tableindex;
+ // If nil, delete list
+ if(lua_isnil(L, tableindex)){
+ inv->deleteList(name);
+ return;
+ }
+ // Otherwise set list
+ std::list<std::string> items;
+ luaL_checktype(L, tableindex, LUA_TTABLE);
+ int table = tableindex;
+ lua_pushnil(L);
+ while(lua_next(L, table) != 0){
+ // key at index -2 and value at index -1
+ luaL_checktype(L, -1, LUA_TSTRING);
+ std::string itemstring = luaL_checkstring(L, -1);
+ items.push_back(itemstring);
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ int listsize = (forcesize != -1) ? forcesize : items.size();
+ InventoryList *invlist = inv->addList(name, listsize);
+ int index = 0;
+ for(std::list<std::string>::const_iterator
+ i = items.begin(); i != items.end(); i++){
+ if(forcesize != -1 && index == forcesize)
+ break;
+ const std::string &itemstring = *i;
+ InventoryItem *newitem = NULL;
+ if(itemstring != "")
+ newitem = InventoryItem::deSerialize(itemstring,
+ gamedef);
+ InventoryItem *olditem = invlist->changeItem(index, newitem);
+ delete olditem;
+ index++;
+ }
+ while(forcesize != -1 && index < forcesize){
+ InventoryItem *olditem = invlist->changeItem(index, NULL);
+ delete olditem;
+ index++;
+ }
+}
+
+static void inventory_get_list_to_lua(Inventory *inv, const char *name,
+ lua_State *L)
+{
+ InventoryList *invlist = inv->getList(name);
+ if(invlist == NULL){
+ lua_pushnil(L);
+ return;
+ }
+ // Get the table insert function
+ lua_getglobal(L, "table");
+ lua_getfield(L, -1, "insert");
+ int table_insert = lua_gettop(L);
+ // Create and fill table
+ lua_newtable(L);
+ int table = lua_gettop(L);
+ for(u32 i=0; i<invlist->getSize(); i++){
+ InventoryItem *item = invlist->getItem(i);
+ lua_pushvalue(L, table_insert);
+ lua_pushvalue(L, table);
+ if(item == NULL){
+ lua_pushstring(L, "");
+ } else {
+ lua_pushstring(L, item->getItemString().c_str());
+ }
+ if(lua_pcall(L, 2, 0, 0))
+ script_error(L, "error: %s", lua_tostring(L, -1));
+ }
+}
+
+/*
+ ToolDiggingProperties
+*/
+
+static ToolDiggingProperties read_tool_digging_properties(
+ lua_State *L, int table)
+{
+ ToolDiggingProperties prop;
+ getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
+ getfloatfield(L, table, "basetime", prop.basetime);
+ getfloatfield(L, table, "dt_weight", prop.dt_weight);
+ getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
+ getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
+ getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
+ getfloatfield(L, table, "basedurability", prop.basedurability);
+ getfloatfield(L, table, "dd_weight", prop.dd_weight);
+ getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
+ getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
+ getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
+ return prop;
+}
+
+static void set_tool_digging_properties(lua_State *L, int table,
+ const ToolDiggingProperties &prop)
+{
+ setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
+ setfloatfield(L, table, "basetime", prop.basetime);
+ setfloatfield(L, table, "dt_weight", prop.dt_weight);
+ setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
+ setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
+ setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
+ setfloatfield(L, table, "basedurability", prop.basedurability);
+ setfloatfield(L, table, "dd_weight", prop.dd_weight);
+ setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
+ setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
+ setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
+}
+
+static void push_tool_digging_properties(lua_State *L,
+ const ToolDiggingProperties &prop)
+{
+ lua_newtable(L);
+ set_tool_digging_properties(L, -1, prop);
+}
+
+/*
+ ToolDefinition
+*/
+
+static ToolDefinition read_tool_definition(lua_State *L, int table)
+{
+ ToolDefinition def;
+ getstringfield(L, table, "image", def.imagename);
+ def.properties = read_tool_digging_properties(L, table);
+ return def;
+}
+
+static void push_tool_definition(lua_State *L, const ToolDefinition &def)
+{
+ lua_newtable(L);
+ lua_pushstring(L, def.imagename.c_str());
+ lua_setfield(L, -2, "image");
+ set_tool_digging_properties(L, -1, def.properties);
+}
+
+/*
+ EnumString definitions
+*/
+