From bdbdeab0053d9ebbaffea17effeba777b710d390 Mon Sep 17 00:00:00 2001 From: sapier Date: Sat, 23 Feb 2013 18:06:57 +0000 Subject: split scriptapi.cpp Remerge some files in order to reduce number of additional files Make necessary changes for split, rename files, reorganize some bits --- src/scriptapi.cpp | 7717 ++++++----------------------------------------------- 1 file changed, 823 insertions(+), 6894 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 7aa148fd6..ef8a1454a 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -27,89 +27,27 @@ extern "C" { #include } -#include "log.h" -#include "server.h" -#include "porting.h" -#include "filesys.h" -#include "serverobject.h" -#include "script.h" -#include "object_properties.h" -#include "content_sao.h" // For LuaEntitySAO and PlayerSAO -#include "itemdef.h" -#include "nodedef.h" -#include "biome.h" -#include "craftdef.h" -#include "main.h" // For g_settings #include "settings.h" // For accessing g_settings -#include "nodemetadata.h" -#include "mapblock.h" // For getNodeBlockPos -#include "content_nodemeta.h" -#include "tool.h" -#include "daynightratio.h" -#include "noise.h" // PseudoRandom for LuaPseudoRandom -#include "util/pointedthing.h" +#include "main.h" // For g_settings +#include "biome.h" +#include "script.h" #include "rollback.h" -#include "treegen.h" - -static void stackDump(lua_State *L, std::ostream &o) -{ - int i; - int top = lua_gettop(L); - for (i = 1; i <= top; i++) { /* repeat for each level */ - int t = lua_type(L, i); - switch (t) { - - case LUA_TSTRING: /* strings */ - o<<"\""<= 30){ - dstream<<"Stack is over 30:"< &result) { - std::string result = default_; - getstringfield(L, table, fieldname, result); - return result; + result.clear(); + lua_pushnil(L); + if(index < 0) + index -= 1; + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + std::string key = luaL_checkstring(L, -2); + bool value = lua_toboolean(L, -1); + if(value) + result.insert(key); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } } -static int getintfield_default(lua_State *L, int table, - const char *fieldname, int default_) +static void get_auth_handler(lua_State *L) { - int result = default_; - getintfield(L, table, fieldname, result); - return result; + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_auth_handler"); + if(lua_isnil(L, -1)){ + lua_pop(L, 1); + lua_getfield(L, -1, "builtin_auth_handler"); + } + if(lua_type(L, -1) != LUA_TTABLE) + throw LuaError(L, "Authentication handler table not valid"); } -static float getfloatfield_default(lua_State *L, int table, - const char *fieldname, float default_) +bool scriptapi_get_auth(lua_State *L, const std::string &playername, + std::string *dst_password, std::set *dst_privs) { - float result = default_; - getfloatfield(L, table, fieldname, result); - return result; -} + realitycheck(L); + assert(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); -static bool getboolfield_default(lua_State *L, int table, - const char *fieldname, bool default_) -{ - bool result = default_; - getboolfield(L, table, fieldname, result); - return result; -} + get_auth_handler(L); + lua_getfield(L, -1, "get_auth"); + if(lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError(L, "Authentication handler missing get_auth"); + lua_pushstring(L, playername.c_str()); + if(lua_pcall(L, 1, 1, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); -struct EnumString -{ - int num; - const char *str; -}; + // nil = login not allowed + if(lua_isnil(L, -1)) + return false; + luaL_checktype(L, -1, LUA_TTABLE); -static bool string_to_enum(const EnumString *spec, int &result, - const std::string &str) -{ - const EnumString *esp = spec; - while(esp->str){ - if(str == std::string(esp->str)){ - result = esp->num; - return true; - } - esp++; - } - return false; -} + std::string password; + bool found = getstringfield(L, -1, "password", password); + if(!found) + throw LuaError(L, "Authentication handler didn't return password"); + if(dst_password) + *dst_password = password; -/*static bool enum_to_string(const EnumString *spec, std::string &result, - int num) -{ - const EnumString *esp = spec; - while(esp){ - if(num == esp->num){ - result = esp->str; - return true; - } - esp++; - } - return false; -}*/ + lua_getfield(L, -1, "privileges"); + if(!lua_istable(L, -1)) + throw LuaError(L, + "Authentication handler didn't return privilege table"); + if(dst_privs) + read_privileges(L, -1, *dst_privs); + lua_pop(L, 1); -static int getenumfield(lua_State *L, int table, - const char *fieldname, const EnumString *spec, int default_) -{ - int result = default_; - string_to_enum(spec, result, - getstringfield_default(L, table, fieldname, "")); - return result; + return true; } -static void setintfield(lua_State *L, int table, - const char *fieldname, int value) +void scriptapi_create_auth(lua_State *L, const std::string &playername, + const std::string &password) { - lua_pushinteger(L, value); - if(table < 0) - table -= 1; - lua_setfield(L, table, fieldname); -} + realitycheck(L); + assert(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); -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); + get_auth_handler(L); + lua_getfield(L, -1, "create_auth"); + if(lua_type(L, -1) != LUA_TFUNCTION) + throw LuaError(L, "Authentication handler missing create_auth"); + lua_pushstring(L, playername.c_str()); + lua_pushstring(L, password.c_str()); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); } -static void setboolfield(lua_State *L, int table, - const char *fieldname, bool value) +bool scriptapi_set_password(lua_State *L, const std::string &playername, + const std::string &password) { - lua_pushboolean(L, value); - if(table < 0) - table -= 1; - lua_setfield(L, table, fieldname); -} + realitycheck(L); + assert(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); -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< &result) { - {TAT_NONE, "none"}, - {TAT_VERTICAL_FRAMES, "vertical_frames"}, - {0, NULL}, -}; + if (!lua_istable(L,index)) + return; + result.clear(); + lua_pushnil(L); + if(index < 0) + index -= 1; + while(lua_next(L, index) != 0){ + // key at index -2 and value at index -1 + std::string name = luaL_checkstring(L, -2); + int rating = luaL_checkinteger(L, -1); + result[name] = rating; + // removes value, keeps key for next iteration + lua_pop(L, 1); + } +} struct EnumString es_BiomeTerrainType[] = { @@ -447,5969 +241,303 @@ struct EnumString es_BiomeTerrainType[] = {0, NULL}, }; +/*****************************************************************************/ +/* Parameters */ +/*****************************************************************************/ /* - C struct <-> Lua table converter functions + DigParams */ -static void push_v3f(lua_State *L, v3f p) +static void set_dig_params(lua_State *L, int table, + const DigParams ¶ms) { - lua_newtable(L); - lua_pushnumber(L, p.X); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, p.Y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, p.Z); - lua_setfield(L, -2, "z"); + setboolfield(L, table, "diggable", params.diggable); + setfloatfield(L, table, "time", params.time); + setintfield(L, table, "wear", params.wear); } -static v2s16 read_v2s16(lua_State *L, int index) +static void push_dig_params(lua_State *L, + const DigParams ¶ms) { - v2s16 p; - luaL_checktype(L, index, LUA_TTABLE); - lua_getfield(L, index, "x"); - p.X = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - p.Y = lua_tonumber(L, -1); - lua_pop(L, 1); - return p; + lua_newtable(L); + set_dig_params(L, -1, params); } -static v2f read_v2f(lua_State *L, int index) +/* + HitParams +*/ + +static void set_hit_params(lua_State *L, int table, + const HitParams ¶ms) { - v2f p; - luaL_checktype(L, index, LUA_TTABLE); - lua_getfield(L, index, "x"); - p.X = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - p.Y = lua_tonumber(L, -1); - lua_pop(L, 1); - return p; + setintfield(L, table, "hp", params.hp); + setintfield(L, table, "wear", params.wear); } -static v3f read_v3f(lua_State *L, int index) -{ - v3f pos; - luaL_checktype(L, index, LUA_TTABLE); - lua_getfield(L, index, "x"); - pos.X = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - pos.Y = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - pos.Z = lua_tonumber(L, -1); - lua_pop(L, 1); - return pos; -} - -static v3f check_v3f(lua_State *L, int index) -{ - v3f pos; - luaL_checktype(L, index, LUA_TTABLE); - lua_getfield(L, index, "x"); - pos.X = luaL_checknumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - pos.Y = luaL_checknumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - pos.Z = luaL_checknumber(L, -1); - lua_pop(L, 1); - return pos; -} - -static void pushFloatPos(lua_State *L, v3f p) -{ - p /= BS; - push_v3f(L, p); -} - -static v3f checkFloatPos(lua_State *L, int index) -{ - return check_v3f(L, index) * BS; -} - -static void push_v3s16(lua_State *L, v3s16 p) -{ - lua_newtable(L); - lua_pushnumber(L, p.X); - lua_setfield(L, -2, "x"); - lua_pushnumber(L, p.Y); - lua_setfield(L, -2, "y"); - lua_pushnumber(L, p.Z); - lua_setfield(L, -2, "z"); -} - -static v3s16 read_v3s16(lua_State *L, int index) -{ - // Correct rounding at <0 - v3f pf = read_v3f(L, index); - return floatToInt(pf, 1.0); -} - -static v3s16 check_v3s16(lua_State *L, int index) -{ - // Correct rounding at <0 - v3f pf = check_v3f(L, index); - return floatToInt(pf, 1.0); -} - -static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef) +static void push_hit_params(lua_State *L, + const HitParams ¶ms) { lua_newtable(L); - lua_pushstring(L, ndef->get(n).name.c_str()); - lua_setfield(L, -2, "name"); - lua_pushnumber(L, n.getParam1()); - lua_setfield(L, -2, "param1"); - lua_pushnumber(L, n.getParam2()); - lua_setfield(L, -2, "param2"); -} - -static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef) -{ - lua_getfield(L, index, "name"); - const char *name = luaL_checkstring(L, -1); - lua_pop(L, 1); - u8 param1; - lua_getfield(L, index, "param1"); - if(lua_isnil(L, -1)) - param1 = 0; - else - param1 = lua_tonumber(L, -1); - lua_pop(L, 1); - u8 param2; - lua_getfield(L, index, "param2"); - if(lua_isnil(L, -1)) - param2 = 0; - else - param2 = lua_tonumber(L, -1); - lua_pop(L, 1); - return MapNode(ndef, name, param1, param2); -} - -static video::SColor readARGB8(lua_State *L, int index) -{ - video::SColor color; - luaL_checktype(L, index, LUA_TTABLE); - lua_getfield(L, index, "a"); - if(lua_isnumber(L, -1)) - color.setAlpha(lua_tonumber(L, -1)); - lua_pop(L, 1); - lua_getfield(L, index, "r"); - color.setRed(lua_tonumber(L, -1)); - lua_pop(L, 1); - lua_getfield(L, index, "g"); - color.setGreen(lua_tonumber(L, -1)); - lua_pop(L, 1); - lua_getfield(L, index, "b"); - color.setBlue(lua_tonumber(L, -1)); - lua_pop(L, 1); - return color; + set_hit_params(L, -1, params); } -static aabb3f read_aabb3f(lua_State *L, int index, f32 scale) -{ - aabb3f box; - if(lua_istable(L, index)){ - lua_rawgeti(L, index, 1); - box.MinEdge.X = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - lua_rawgeti(L, index, 2); - box.MinEdge.Y = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - lua_rawgeti(L, index, 3); - box.MinEdge.Z = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - lua_rawgeti(L, index, 4); - box.MaxEdge.X = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - lua_rawgeti(L, index, 5); - box.MaxEdge.Y = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - lua_rawgeti(L, index, 6); - box.MaxEdge.Z = lua_tonumber(L, -1) * scale; - lua_pop(L, 1); - } - return box; -} +/* + ServerSoundParams +*/ -static std::vector read_aabb3f_vector(lua_State *L, int index, f32 scale) +static void read_server_sound_params(lua_State *L, int index, + ServerSoundParams ¶ms) { - std::vector boxes; + if(index < 0) + index = lua_gettop(L) + 1 + index; + // Clear + params = ServerSoundParams(); if(lua_istable(L, index)){ - int n = lua_objlen(L, index); - // Check if it's a single box or a list of boxes - bool possibly_single_box = (n == 6); - for(int i = 1; i <= n && possibly_single_box; i++){ - lua_rawgeti(L, index, i); - if(!lua_isnumber(L, -1)) - possibly_single_box = false; - lua_pop(L, 1); + getfloatfield(L, index, "gain", params.gain); + getstringfield(L, index, "to_player", params.to_player); + lua_getfield(L, index, "pos"); + if(!lua_isnil(L, -1)){ + v3f p = read_v3f(L, -1)*BS; + params.pos = p; + params.type = ServerSoundParams::SSP_POSITIONAL; } - if(possibly_single_box){ - // Read a single box - boxes.push_back(read_aabb3f(L, index, scale)); - } else { - // Read a list of boxes - for(int i = 1; i <= n; i++){ - lua_rawgeti(L, index, i); - boxes.push_back(read_aabb3f(L, -1, scale)); - lua_pop(L, 1); + lua_pop(L, 1); + lua_getfield(L, index, "object"); + if(!lua_isnil(L, -1)){ + ObjectRef *ref = ObjectRef::checkobject(L, -1); + ServerActiveObject *sao = ObjectRef::getobject(ref); + if(sao){ + params.object = sao->getId(); + params.type = ServerSoundParams::SSP_OBJECT; } } - } - return boxes; -} - -static NodeBox read_nodebox(lua_State *L, int index) -{ - NodeBox nodebox; - if(lua_istable(L, -1)){ - nodebox.type = (NodeBoxType)getenumfield(L, index, "type", - es_NodeBoxType, NODEBOX_REGULAR); - - lua_getfield(L, index, "fixed"); - if(lua_istable(L, -1)) - nodebox.fixed = read_aabb3f_vector(L, -1, BS); - lua_pop(L, 1); - - lua_getfield(L, index, "wall_top"); - if(lua_istable(L, -1)) - nodebox.wall_top = read_aabb3f(L, -1, BS); - lua_pop(L, 1); - - lua_getfield(L, index, "wall_bottom"); - if(lua_istable(L, -1)) - nodebox.wall_bottom = read_aabb3f(L, -1, BS); - lua_pop(L, 1); - - lua_getfield(L, index, "wall_side"); - if(lua_istable(L, -1)) - nodebox.wall_side = read_aabb3f(L, -1, BS); lua_pop(L, 1); + params.max_hear_distance = BS*getfloatfield_default(L, index, + "max_hear_distance", params.max_hear_distance/BS); + getboolfield(L, index, "loop", params.loop); } - return nodebox; } -/* - NoiseParams -*/ -static NoiseParams *read_noiseparams(lua_State *L, int index) -{ - if (index < 0) - index = lua_gettop(L) + 1 + index; - - if (!lua_istable(L, index)) - return NULL; - - NoiseParams *np = new NoiseParams; - - np->offset = getfloatfield_default(L, index, "offset", 0.0); - np->scale = getfloatfield_default(L, index, "scale", 0.0); - lua_getfield(L, index, "spread"); - np->spread = read_v3f(L, -1); - np->seed = getintfield_default(L, index, "seed", 0); - np->octaves = getintfield_default(L, index, "octaves", 0); - np->persist = getfloatfield_default(L, index, "persist", 0.0); - - return np; -} +/*****************************************************************************/ +/* callbacks */ +/*****************************************************************************/ -/* - Groups -*/ -static void read_groups(lua_State *L, int index, - std::map &result) +// Push the list of callbacks (a lua table). +// Then push nargs arguments. +// Then call this function, which +// - runs the callbacks +// - removes the table and arguments from the lua stack +// - pushes the return value, computed depending on mode +void scriptapi_run_callbacks(lua_State *L, int nargs, + RunCallbacksMode mode) { - if (!lua_istable(L,index)) - return; - result.clear(); + // Insert the return value into the lua stack, below the table + assert(lua_gettop(L) >= nargs + 1); lua_pushnil(L); - if(index < 0) - index -= 1; - while(lua_next(L, index) != 0){ - // key at index -2 and value at index -1 - std::string name = luaL_checkstring(L, -2); - int rating = luaL_checkinteger(L, -1); - result[name] = rating; - // removes value, keeps key for next iteration - lua_pop(L, 1); - } -} + lua_insert(L, -(nargs + 1) - 1); + // Stack now looks like this: + // ... ... -/* - Privileges -*/ -static void read_privileges(lua_State *L, int index, - std::set &result) -{ - result.clear(); + int rv = lua_gettop(L) - nargs - 1; + int table = rv + 1; + int arg = table + 1; + + luaL_checktype(L, table, LUA_TTABLE); + + // Foreach lua_pushnil(L); - if(index < 0) - index -= 1; - while(lua_next(L, index) != 0){ + bool first_loop = true; + while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 - std::string key = luaL_checkstring(L, -2); - bool value = lua_toboolean(L, -1); - if(value) - result.insert(key); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } -} - -/* - ToolCapabilities -*/ + luaL_checktype(L, -1, LUA_TFUNCTION); + // Call function + for(int i = 0; i < nargs; i++) + lua_pushvalue(L, arg+i); + if(lua_pcall(L, nargs, 1, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); -static ToolCapabilities read_tool_capabilities( - lua_State *L, int table) -{ - ToolCapabilities toolcap; - getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); - getintfield(L, table, "max_drop_level", toolcap.max_drop_level); - lua_getfield(L, table, "groupcaps"); - if(lua_istable(L, -1)){ - int table_groupcaps = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table_groupcaps) != 0){ - // key at index -2 and value at index -1 - std::string groupname = luaL_checkstring(L, -2); - if(lua_istable(L, -1)){ - int table_groupcap = lua_gettop(L); - // This will be created - ToolGroupCap groupcap; - // Read simple parameters - getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); - getintfield(L, table_groupcap, "uses", groupcap.uses); - // DEPRECATED: maxwear - float maxwear = 0; - if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){ - if(maxwear != 0) - groupcap.uses = 1.0/maxwear; - else - groupcap.uses = 0; - infostream<::const_iterator - i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){ - // Create groupcap table - lua_newtable(L); - const std::string &name = i->first; - const ToolGroupCap &groupcap = i->second; - // Create subtable "times" - lua_newtable(L); - for(std::map::const_iterator - i = groupcap.times.begin(); i != groupcap.times.end(); i++){ - int rating = i->first; - float time = i->second; - lua_pushinteger(L, rating); - lua_pushnumber(L, time); - lua_settable(L, -3); + // Remove stuff from stack, leaving only the return value + lua_settop(L, rv); + + // Fix return value in case no callbacks were called + if(first_loop){ + if(mode == RUN_CALLBACKS_MODE_AND || + mode == RUN_CALLBACKS_MODE_AND_SC){ + lua_pop(L, 1); + lua_pushboolean(L, true); + } + else if(mode == RUN_CALLBACKS_MODE_OR || + mode == RUN_CALLBACKS_MODE_OR_SC){ + lua_pop(L, 1); + lua_pushboolean(L, false); } - // Set subtable "times" - lua_setfield(L, -2, "times"); - // Set simple parameters - setintfield(L, -1, "maxlevel", groupcap.maxlevel); - setintfield(L, -1, "uses", groupcap.uses); - // Insert groupcap table into groupcaps table - lua_setfield(L, -2, name.c_str()); } - // Set groupcaps table - lua_setfield(L, -2, "groupcaps"); } -static void push_tool_capabilities(lua_State *L, - const ToolCapabilities &prop) -{ - lua_newtable(L); - set_tool_capabilities(L, -1, prop); -} - -/* - DigParams -*/ - -static void set_dig_params(lua_State *L, int table, - const DigParams ¶ms) +bool scriptapi_on_chat_message(lua_State *L, const std::string &name, + const std::string &message) { - setboolfield(L, table, "diggable", params.diggable); - setfloatfield(L, table, "time", params.time); - setintfield(L, table, "wear", params.wear); -} - -static void push_dig_params(lua_State *L, - const DigParams ¶ms) -{ - lua_newtable(L); - set_dig_params(L, -1, params); -} - -/* - HitParams -*/ - -static void set_hit_params(lua_State *L, int table, - const HitParams ¶ms) -{ - setintfield(L, table, "hp", params.hp); - setintfield(L, table, "wear", params.wear); -} - -static void push_hit_params(lua_State *L, - const HitParams ¶ms) -{ - lua_newtable(L); - set_hit_params(L, -1, params); -} - -/* - PointedThing -*/ - -static void push_pointed_thing(lua_State *L, const PointedThing& pointed) -{ - lua_newtable(L); - if(pointed.type == POINTEDTHING_NODE) - { - lua_pushstring(L, "node"); - lua_setfield(L, -2, "type"); - push_v3s16(L, pointed.node_undersurface); - lua_setfield(L, -2, "under"); - push_v3s16(L, pointed.node_abovesurface); - lua_setfield(L, -2, "above"); - } - else if(pointed.type == POINTEDTHING_OBJECT) - { - lua_pushstring(L, "object"); - lua_setfield(L, -2, "type"); - objectref_get(L, pointed.object_id); - lua_setfield(L, -2, "ref"); - } - else - { - lua_pushstring(L, "nothing"); - lua_setfield(L, -2, "type"); - } -} - -/* - SimpleSoundSpec -*/ - -static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - if(lua_isnil(L, index)){ - } else if(lua_istable(L, index)){ - getstringfield(L, index, "name", spec.name); - getfloatfield(L, index, "gain", spec.gain); - } else if(lua_isstring(L, index)){ - spec.name = lua_tostring(L, index); - } -} - -/* - ObjectProperties -*/ - -static void read_object_properties(lua_State *L, int index, - ObjectProperties *prop) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - if(!lua_istable(L, index)) - return; - - prop->hp_max = getintfield_default(L, -1, "hp_max", 10); - - getboolfield(L, -1, "physical", prop->physical); - - getfloatfield(L, -1, "weight", prop->weight); - - lua_getfield(L, -1, "collisionbox"); - if(lua_istable(L, -1)) - prop->collisionbox = read_aabb3f(L, -1, 1.0); - lua_pop(L, 1); - - getstringfield(L, -1, "visual", prop->visual); - - getstringfield(L, -1, "mesh", prop->mesh); - - lua_getfield(L, -1, "visual_size"); - if(lua_istable(L, -1)) - prop->visual_size = read_v2f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, -1, "textures"); - if(lua_istable(L, -1)){ - prop->textures.clear(); - int table = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - if(lua_isstring(L, -1)) - prop->textures.push_back(lua_tostring(L, -1)); - else - prop->textures.push_back(""); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } - lua_pop(L, 1); - - lua_getfield(L, -1, "colors"); - if(lua_istable(L, -1)){ - prop->colors.clear(); - int table = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - if(lua_isstring(L, -1)) - prop->colors.push_back(readARGB8(L, -1)); - else - prop->colors.push_back(video::SColor(255, 255, 255, 255)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } - lua_pop(L, 1); - - lua_getfield(L, -1, "spritediv"); - if(lua_istable(L, -1)) - prop->spritediv = read_v2s16(L, -1); - lua_pop(L, 1); - - lua_getfield(L, -1, "initial_sprite_basepos"); - if(lua_istable(L, -1)) - prop->initial_sprite_basepos = read_v2s16(L, -1); - lua_pop(L, 1); - - getboolfield(L, -1, "is_visible", prop->is_visible); - getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound); - getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate); -} - -/* - ItemDefinition -*/ - -static ItemDefinition read_item_definition(lua_State *L, int index, - ItemDefinition default_def = ItemDefinition()) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - // Read the item definition - ItemDefinition def = default_def; - - def.type = (ItemType)getenumfield(L, index, "type", - es_ItemType, ITEM_NONE); - getstringfield(L, index, "name", def.name); - getstringfield(L, index, "description", def.description); - getstringfield(L, index, "inventory_image", def.inventory_image); - getstringfield(L, index, "wield_image", def.wield_image); - - lua_getfield(L, index, "wield_scale"); - if(lua_istable(L, -1)){ - def.wield_scale = check_v3f(L, -1); - } - lua_pop(L, 1); - - def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max); - if(def.stack_max == 0) - def.stack_max = 1; - - lua_getfield(L, index, "on_use"); - def.usable = lua_isfunction(L, -1); - lua_pop(L, 1); - - getboolfield(L, index, "liquids_pointable", def.liquids_pointable); - - warn_if_field_exists(L, index, "tool_digging_properties", - "deprecated: use tool_capabilities"); - - lua_getfield(L, index, "tool_capabilities"); - if(lua_istable(L, -1)){ - def.tool_capabilities = new ToolCapabilities( - read_tool_capabilities(L, -1)); - } - - // If name is "" (hand), ensure there are ToolCapabilities - // because it will be looked up there whenever any other item has - // no ToolCapabilities - if(def.name == "" && def.tool_capabilities == NULL){ - def.tool_capabilities = new ToolCapabilities(); - } - - lua_getfield(L, index, "groups"); - read_groups(L, -1, def.groups); - lua_pop(L, 1); - - // Client shall immediately place this node when player places the item. - // Server will update the precise end result a moment later. - // "" = no prediction - getstringfield(L, index, "node_placement_prediction", - def.node_placement_prediction); - - return def; -} - -/* - TileDef -*/ - -static TileDef read_tiledef(lua_State *L, int index) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - TileDef tiledef; - - // key at index -2 and value at index - if(lua_isstring(L, index)){ - // "default_lava.png" - tiledef.name = lua_tostring(L, index); - } - else if(lua_istable(L, index)) - { - // {name="default_lava.png", animation={}} - tiledef.name = ""; - getstringfield(L, index, "name", tiledef.name); - getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat. - tiledef.backface_culling = getboolfield_default( - L, index, "backface_culling", true); - // animation = {} - lua_getfield(L, index, "animation"); - if(lua_istable(L, -1)){ - // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (TileAnimationType) - getenumfield(L, -1, "type", es_TileAnimationType, - TAT_NONE); - tiledef.animation.aspect_w = - getintfield_default(L, -1, "aspect_w", 16); - tiledef.animation.aspect_h = - getintfield_default(L, -1, "aspect_h", 16); - tiledef.animation.length = - getfloatfield_default(L, -1, "length", 1.0); - } - lua_pop(L, 1); - } - - return tiledef; -} - -/* - ContentFeatures -*/ - -static ContentFeatures read_content_features(lua_State *L, int index) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - ContentFeatures f; - - /* Cache existence of some callbacks */ - lua_getfield(L, index, "on_construct"); - if(!lua_isnil(L, -1)) f.has_on_construct = true; - lua_pop(L, 1); - lua_getfield(L, index, "on_destruct"); - if(!lua_isnil(L, -1)) f.has_on_destruct = true; - lua_pop(L, 1); - lua_getfield(L, index, "after_destruct"); - if(!lua_isnil(L, -1)) f.has_after_destruct = true; - lua_pop(L, 1); - - lua_getfield(L, index, "on_rightclick"); - f.rightclickable = lua_isfunction(L, -1); - lua_pop(L, 1); - - /* Name */ - getstringfield(L, index, "name", f.name); - - /* Groups */ - lua_getfield(L, index, "groups"); - read_groups(L, -1, f.groups); - lua_pop(L, 1); - - /* Visual definition */ - - f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType, - NDT_NORMAL); - getfloatfield(L, index, "visual_scale", f.visual_scale); - - // tiles = {} - lua_getfield(L, index, "tiles"); - // If nil, try the deprecated name "tile_images" instead - if(lua_isnil(L, -1)){ - lua_pop(L, 1); - warn_if_field_exists(L, index, "tile_images", - "Deprecated; new name is \"tiles\"."); - lua_getfield(L, index, "tile_images"); - } - if(lua_istable(L, -1)){ - int table = lua_gettop(L); - lua_pushnil(L); - int i = 0; - while(lua_next(L, table) != 0){ - // Read tiledef from value - f.tiledef[i] = read_tiledef(L, -1); - // removes value, keeps key for next iteration - lua_pop(L, 1); - i++; - if(i==6){ - lua_pop(L, 1); - break; - } - } - // Copy last value to all remaining textures - if(i >= 1){ - TileDef lasttile = f.tiledef[i-1]; - while(i < 6){ - f.tiledef[i] = lasttile; - i++; - } - } - } - lua_pop(L, 1); - - // special_tiles = {} - lua_getfield(L, index, "special_tiles"); - // If nil, try the deprecated name "special_materials" instead - if(lua_isnil(L, -1)){ - lua_pop(L, 1); - warn_if_field_exists(L, index, "special_materials", - "Deprecated; new name is \"special_tiles\"."); - lua_getfield(L, index, "special_materials"); - } - if(lua_istable(L, -1)){ - int table = lua_gettop(L); - lua_pushnil(L); - int i = 0; - while(lua_next(L, table) != 0){ - // Read tiledef from value - f.tiledef_special[i] = read_tiledef(L, -1); - // removes value, keeps key for next iteration - lua_pop(L, 1); - i++; - if(i==6){ - lua_pop(L, 1); - break; - } - } - } - lua_pop(L, 1); - - f.alpha = getintfield_default(L, index, "alpha", 255); - - /* Other stuff */ - - lua_getfield(L, index, "post_effect_color"); - if(!lua_isnil(L, -1)) - f.post_effect_color = readARGB8(L, -1); - lua_pop(L, 1); - - f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", - es_ContentParamType, CPT_NONE); - f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", - es_ContentParamType2, CPT2_NONE); - - // Warn about some deprecated fields - warn_if_field_exists(L, index, "wall_mounted", - "deprecated: use paramtype2 = 'wallmounted'"); - warn_if_field_exists(L, index, "light_propagates", - "deprecated: determined from paramtype"); - warn_if_field_exists(L, index, "dug_item", - "deprecated: use 'drop' field"); - warn_if_field_exists(L, index, "extra_dug_item", - "deprecated: use 'drop' field"); - warn_if_field_exists(L, index, "extra_dug_item_rarity", - "deprecated: use 'drop' field"); - warn_if_field_exists(L, index, "metadata_name", - "deprecated: use on_add and metadata callbacks"); - - // True for all ground-like things like stone and mud, false for eg. trees - getboolfield(L, index, "is_ground_content", f.is_ground_content); - f.light_propagates = (f.param_type == CPT_LIGHT); - getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); - // This is used for collision detection. - // Also for general solidness queries. - getboolfield(L, index, "walkable", f.walkable); - // Player can point to these - getboolfield(L, index, "pointable", f.pointable); - // Player can dig these - getboolfield(L, index, "diggable", f.diggable); - // Player can climb these - getboolfield(L, index, "climbable", f.climbable); - // Player can build on these - getboolfield(L, index, "buildable_to", f.buildable_to); - // Whether the node is non-liquid, source liquid or flowing liquid - f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", - es_LiquidType, LIQUID_NONE); - // If the content is liquid, this is the flowing version of the liquid. - getstringfield(L, index, "liquid_alternative_flowing", - f.liquid_alternative_flowing); - // If the content is liquid, this is the source version of the liquid. - getstringfield(L, index, "liquid_alternative_source", - f.liquid_alternative_source); - // Viscosity for fluid flow, ranging from 1 to 7, with - // 1 giving almost instantaneous propagation and 7 being - // the slowest possible - f.liquid_viscosity = getintfield_default(L, index, - "liquid_viscosity", f.liquid_viscosity); - getboolfield(L, index, "liquid_renewable", f.liquid_renewable); - // Amount of light the node emits - f.light_source = getintfield_default(L, index, - "light_source", f.light_source); - f.damage_per_second = getintfield_default(L, index, - "damage_per_second", f.damage_per_second); - - lua_getfield(L, index, "node_box"); - if(lua_istable(L, -1)) - f.node_box = read_nodebox(L, -1); - lua_pop(L, 1); - - lua_getfield(L, index, "selection_box"); - if(lua_istable(L, -1)) - f.selection_box = read_nodebox(L, -1); - lua_pop(L, 1); - - // Set to true if paramtype used to be 'facedir_simple' - getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); - // Set to true if wall_mounted used to be set to true - getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); - - // Sound table - lua_getfield(L, index, "sounds"); - if(lua_istable(L, -1)){ - lua_getfield(L, -1, "footstep"); - read_soundspec(L, -1, f.sound_footstep); - lua_pop(L, 1); - lua_getfield(L, -1, "dig"); - read_soundspec(L, -1, f.sound_dig); - lua_pop(L, 1); - lua_getfield(L, -1, "dug"); - read_soundspec(L, -1, f.sound_dug); - lua_pop(L, 1); - } - lua_pop(L, 1); - - return f; -} - -/* - Inventory stuff -*/ - -static ItemStack read_item(lua_State *L, int index); -static std::vector read_items(lua_State *L, int index); -// creates a table of ItemStacks -static void push_items(lua_State *L, const std::vector &items); - -static void inventory_set_list_from_lua(Inventory *inv, const char *name, - lua_State *L, int tableindex, 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::vector items = read_items(L, tableindex); - int listsize = (forcesize != -1) ? forcesize : items.size(); - InventoryList *invlist = inv->addList(name, listsize); - int index = 0; - for(std::vector::const_iterator - i = items.begin(); i != items.end(); i++){ - if(forcesize != -1 && index == forcesize) - break; - invlist->changeItem(index, *i); - index++; - } - while(forcesize != -1 && index < forcesize){ - invlist->deleteItem(index); - 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; - } - std::vector items; - for(u32 i=0; igetSize(); i++) - items.push_back(invlist->getItem(i)); - push_items(L, items); -} - -/* - Helpful macros for userdata classes -*/ - -#define method(class, name) {#name, class::l_##name} - -/* - LuaItemStack -*/ - -class LuaItemStack -{ -private: - ItemStack m_stack; - - static const char className[]; - static const luaL_reg methods[]; - - // Exported functions - - // garbage collector - static int gc_object(lua_State *L) - { - LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - // is_empty(self) -> true/false - static int l_is_empty(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushboolean(L, item.empty()); - return 1; - } - - // get_name(self) -> string - static int l_get_name(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushstring(L, item.name.c_str()); - return 1; - } - - // get_count(self) -> number - static int l_get_count(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushinteger(L, item.count); - return 1; - } - - // get_wear(self) -> number - static int l_get_wear(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushinteger(L, item.wear); - return 1; - } - - // get_metadata(self) -> string - static int l_get_metadata(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); - return 1; - } - - // clear(self) -> true - static int l_clear(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - o->m_stack.clear(); - lua_pushboolean(L, true); - return 1; - } - - // replace(self, itemstack or itemstring or table or nil) -> true - static int l_replace(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - o->m_stack = read_item(L, 2); - lua_pushboolean(L, true); - return 1; - } - - // to_string(self) -> string - static int l_to_string(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - std::string itemstring = o->m_stack.getItemString(); - lua_pushstring(L, itemstring.c_str()); - return 1; - } - - // to_table(self) -> table or nil - static int l_to_table(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - const ItemStack &item = o->m_stack; - if(item.empty()) - { - lua_pushnil(L); - } - else - { - lua_newtable(L); - lua_pushstring(L, item.name.c_str()); - lua_setfield(L, -2, "name"); - lua_pushinteger(L, item.count); - lua_setfield(L, -2, "count"); - lua_pushinteger(L, item.wear); - lua_setfield(L, -2, "wear"); - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); - lua_setfield(L, -2, "metadata"); - } - return 1; - } - - // get_stack_max(self) -> number - static int l_get_stack_max(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushinteger(L, item.getStackMax(get_server(L)->idef())); - return 1; - } - - // get_free_space(self) -> number - static int l_get_free_space(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - lua_pushinteger(L, item.freeSpace(get_server(L)->idef())); - return 1; - } - - // is_known(self) -> true/false - // Checks if the item is defined. - static int l_is_known(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - bool is_known = item.isKnown(get_server(L)->idef()); - lua_pushboolean(L, is_known); - return 1; - } - - // get_definition(self) -> table - // Returns the item definition table from minetest.registered_items, - // or a fallback one (name="unknown") - static int l_get_definition(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - - // Get minetest.registered_items[name] - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_items"); - luaL_checktype(L, -1, LUA_TTABLE); - lua_getfield(L, -1, item.name.c_str()); - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_getfield(L, -1, "unknown"); - } - return 1; - } - - // get_tool_capabilities(self) -> table - // Returns the effective tool digging properties. - // Returns those of the hand ("") if this item has none associated. - static int l_get_tool_capabilities(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - const ToolCapabilities &prop = - item.getToolCapabilities(get_server(L)->idef()); - push_tool_capabilities(L, prop); - return 1; - } - - // add_wear(self, amount) -> true/false - // The range for "amount" is [0,65535]. Wear is only added if the item - // is a tool. Adding wear might destroy the item. - // Returns true if the item is (or was) a tool. - static int l_add_wear(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - int amount = lua_tointeger(L, 2); - bool result = item.addWear(amount, get_server(L)->idef()); - lua_pushboolean(L, result); - return 1; - } - - // add_item(self, itemstack or itemstring or table or nil) -> itemstack - // Returns leftover item stack - static int l_add_item(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - ItemStack newitem = read_item(L, 2); - ItemStack leftover = item.addItem(newitem, get_server(L)->idef()); - create(L, leftover); - return 1; - } - - // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack - // First return value is true iff the new item fits fully into the stack - // Second return value is the would-be-left-over item stack - static int l_item_fits(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - ItemStack newitem = read_item(L, 2); - ItemStack restitem; - bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef()); - lua_pushboolean(L, fits); // first return value - create(L, restitem); // second return value - return 2; - } - - // take_item(self, takecount=1) -> itemstack - static int l_take_item(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - u32 takecount = 1; - if(!lua_isnone(L, 2)) - takecount = luaL_checkinteger(L, 2); - ItemStack taken = item.takeItem(takecount); - create(L, taken); - return 1; - } - - // peek_item(self, peekcount=1) -> itemstack - static int l_peek_item(lua_State *L) - { - LuaItemStack *o = checkobject(L, 1); - ItemStack &item = o->m_stack; - u32 peekcount = 1; - if(!lua_isnone(L, 2)) - peekcount = lua_tointeger(L, 2); - ItemStack peekaboo = item.peekItem(peekcount); - create(L, peekaboo); - return 1; - } - -public: - LuaItemStack(const ItemStack &item): - m_stack(item) - { - } - - ~LuaItemStack() - { - } - - const ItemStack& getItem() const - { - return m_stack; - } - ItemStack& getItem() - { - return m_stack; - } - - // LuaItemStack(itemstack or itemstring or table or nil) - // Creates an LuaItemStack and leaves it on top of stack - static int create_object(lua_State *L) - { - ItemStack item = read_item(L, 1); - LuaItemStack *o = new LuaItemStack(item); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - return 1; - } - // Not callable from Lua - static int create(lua_State *L, const ItemStack &item) - { - LuaItemStack *o = new LuaItemStack(item); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - return 1; - } - - static LuaItemStack* checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(LuaItemStack**)ud; // unbox pointer - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil)) - lua_register(L, className, create_object); - } -}; -const char LuaItemStack::className[] = "ItemStack"; -const luaL_reg LuaItemStack::methods[] = { - method(LuaItemStack, is_empty), - method(LuaItemStack, get_name), - method(LuaItemStack, get_count), - method(LuaItemStack, get_wear), - method(LuaItemStack, get_metadata), - method(LuaItemStack, clear), - method(LuaItemStack, replace), - method(LuaItemStack, to_string), - method(LuaItemStack, to_table), - method(LuaItemStack, get_stack_max), - method(LuaItemStack, get_free_space), - method(LuaItemStack, is_known), - method(LuaItemStack, get_definition), - method(LuaItemStack, get_tool_capabilities), - method(LuaItemStack, add_wear), - method(LuaItemStack, add_item), - method(LuaItemStack, item_fits), - method(LuaItemStack, take_item), - method(LuaItemStack, peek_item), - {0,0} -}; - -static ItemStack read_item(lua_State *L, int index) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - if(lua_isnil(L, index)) - { - return ItemStack(); - } - else if(lua_isuserdata(L, index)) - { - // Convert from LuaItemStack - LuaItemStack *o = LuaItemStack::checkobject(L, index); - return o->getItem(); - } - else if(lua_isstring(L, index)) - { - // Convert from itemstring - std::string itemstring = lua_tostring(L, index); - IItemDefManager *idef = get_server(L)->idef(); - try - { - ItemStack item; - item.deSerialize(itemstring, idef); - return item; - } - catch(SerializationError &e) - { - infostream<<"WARNING: unable to create item from itemstring" - <<": "<idef(); - std::string name = getstringfield_default(L, index, "name", ""); - int count = getintfield_default(L, index, "count", 1); - int wear = getintfield_default(L, index, "wear", 0); - std::string metadata = getstringfield_default(L, index, "metadata", ""); - return ItemStack(name, count, wear, metadata, idef); - } - else - { - throw LuaError(L, "Expecting itemstack, itemstring, table or nil"); - } -} - -static std::vector read_items(lua_State *L, int index) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - std::vector items; - luaL_checktype(L, index, LUA_TTABLE); - lua_pushnil(L); - while(lua_next(L, index) != 0){ - // key at index -2 and value at index -1 - items.push_back(read_item(L, -1)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - return items; -} - -// creates a table of ItemStacks -static void push_items(lua_State *L, const std::vector &items) -{ - // 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; igetInventory(ref->m_loc); - } - - static InventoryList* getlist(lua_State *L, InvRef *ref, - const char *listname) - { - Inventory *inv = getinv(L, ref); - if(!inv) - return NULL; - return inv->getList(listname); - } - - static void reportInventoryChange(lua_State *L, InvRef *ref) - { - // Inform other things that the inventory has changed - get_server(L)->setInventoryModified(ref->m_loc); - } - - // Exported functions - - // garbage collector - static int gc_object(lua_State *L) { - InvRef *o = *(InvRef **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - // is_empty(self, listname) -> true/false - static int l_is_empty(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - InventoryList *list = getlist(L, ref, listname); - if(list && list->getUsedSlots() > 0){ - lua_pushboolean(L, false); - } else { - lua_pushboolean(L, true); - } - return 1; - } - - // get_size(self, listname) - static int l_get_size(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - InventoryList *list = getlist(L, ref, listname); - if(list){ - lua_pushinteger(L, list->getSize()); - } else { - lua_pushinteger(L, 0); - } - return 1; - } - - // get_width(self, listname) - static int l_get_width(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - InventoryList *list = getlist(L, ref, listname); - if(list){ - lua_pushinteger(L, list->getWidth()); - } else { - lua_pushinteger(L, 0); - } - return 1; - } - - // set_size(self, listname, size) - static int l_set_size(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - int newsize = luaL_checknumber(L, 3); - Inventory *inv = getinv(L, ref); - if(newsize == 0){ - inv->deleteList(listname); - reportInventoryChange(L, ref); - return 0; - } - InventoryList *list = inv->getList(listname); - if(list){ - list->setSize(newsize); - } else { - list = inv->addList(listname, newsize); - } - reportInventoryChange(L, ref); - return 0; - } - - // set_width(self, listname, size) - static int l_set_width(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - int newwidth = luaL_checknumber(L, 3); - Inventory *inv = getinv(L, ref); - InventoryList *list = inv->getList(listname); - if(list){ - list->setWidth(newwidth); - } else { - return 0; - } - reportInventoryChange(L, ref); - return 0; - } - - // get_stack(self, listname, i) -> itemstack - static int l_get_stack(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - int i = luaL_checknumber(L, 3) - 1; - InventoryList *list = getlist(L, ref, listname); - ItemStack item; - if(list != NULL && i >= 0 && i < (int) list->getSize()) - item = list->getItem(i); - LuaItemStack::create(L, item); - return 1; - } - - // set_stack(self, listname, i, stack) -> true/false - static int l_set_stack(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - int i = luaL_checknumber(L, 3) - 1; - ItemStack newitem = read_item(L, 4); - InventoryList *list = getlist(L, ref, listname); - if(list != NULL && i >= 0 && i < (int) list->getSize()){ - list->changeItem(i, newitem); - reportInventoryChange(L, ref); - lua_pushboolean(L, true); - } else { - lua_pushboolean(L, false); - } - return 1; - } - - // get_list(self, listname) -> list or nil - static int l_get_list(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - Inventory *inv = getinv(L, ref); - inventory_get_list_to_lua(inv, listname, L); - return 1; - } - - // set_list(self, listname, list) - static int l_set_list(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - Inventory *inv = getinv(L, ref); - InventoryList *list = inv->getList(listname); - if(list) - inventory_set_list_from_lua(inv, listname, L, 3, - list->getSize()); - else - inventory_set_list_from_lua(inv, listname, L, 3); - reportInventoryChange(L, ref); - return 0; - } - - // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack - // Returns the leftover stack - static int l_add_item(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3); - InventoryList *list = getlist(L, ref, listname); - if(list){ - ItemStack leftover = list->addItem(item); - if(leftover.count != item.count) - reportInventoryChange(L, ref); - LuaItemStack::create(L, leftover); - } else { - LuaItemStack::create(L, item); - } - return 1; - } - - // room_for_item(self, listname, itemstack or itemstring or table or nil) -> true/false - // Returns true if the item completely fits into the list - static int l_room_for_item(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3); - InventoryList *list = getlist(L, ref, listname); - if(list){ - lua_pushboolean(L, list->roomForItem(item)); - } else { - lua_pushboolean(L, false); - } - return 1; - } - - // contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false - // Returns true if the list contains the given count of the given item name - static int l_contains_item(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3); - InventoryList *list = getlist(L, ref, listname); - if(list){ - lua_pushboolean(L, list->containsItem(item)); - } else { - lua_pushboolean(L, false); - } - return 1; - } - - // remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack - // Returns the items that were actually removed - static int l_remove_item(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3); - InventoryList *list = getlist(L, ref, listname); - if(list){ - ItemStack removed = list->removeItem(item); - if(!removed.empty()) - reportInventoryChange(L, ref); - LuaItemStack::create(L, removed); - } else { - LuaItemStack::create(L, ItemStack()); - } - return 1; - } - - // get_location() -> location (like minetest.get_inventory(location)) - static int l_get_location(lua_State *L) - { - InvRef *ref = checkobject(L, 1); - const InventoryLocation &loc = ref->m_loc; - switch(loc.type){ - case InventoryLocation::PLAYER: - lua_newtable(L); - lua_pushstring(L, "player"); - lua_setfield(L, -2, "type"); - lua_pushstring(L, loc.name.c_str()); - lua_setfield(L, -2, "name"); - return 1; - case InventoryLocation::NODEMETA: - lua_newtable(L); - lua_pushstring(L, "nodemeta"); - lua_setfield(L, -2, "type"); - push_v3s16(L, loc.p); - lua_setfield(L, -2, "name"); - return 1; - case InventoryLocation::DETACHED: - lua_newtable(L); - lua_pushstring(L, "detached"); - lua_setfield(L, -2, "type"); - lua_pushstring(L, loc.name.c_str()); - lua_setfield(L, -2, "name"); - return 1; - case InventoryLocation::UNDEFINED: - case InventoryLocation::CURRENT_PLAYER: - break; - } - lua_newtable(L); - lua_pushstring(L, "undefined"); - lua_setfield(L, -2, "type"); - return 1; - } - -public: - InvRef(const InventoryLocation &loc): - m_loc(loc) - { - } - - ~InvRef() - { - } - - // Creates an InvRef and leaves it on top of stack - // Not callable from Lua; all references are created on the C side. - static void create(lua_State *L, const InventoryLocation &loc) - { - InvRef *o = new InvRef(loc); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - } - static void createPlayer(lua_State *L, Player *player) - { - InventoryLocation loc; - loc.setPlayer(player->getName()); - create(L, loc); - } - static void createNodeMeta(lua_State *L, v3s16 p) - { - InventoryLocation loc; - loc.setNodeMeta(p); - create(L, loc); - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Cannot be created from Lua - //lua_register(L, className, create_object); - } -}; -const char InvRef::className[] = "InvRef"; -const luaL_reg InvRef::methods[] = { - method(InvRef, is_empty), - method(InvRef, get_size), - method(InvRef, set_size), - method(InvRef, get_width), - method(InvRef, set_width), - method(InvRef, get_stack), - method(InvRef, set_stack), - method(InvRef, get_list), - method(InvRef, set_list), - method(InvRef, add_item), - method(InvRef, room_for_item), - method(InvRef, contains_item), - method(InvRef, remove_item), - method(InvRef, get_location), - {0,0} -}; - -/* - NodeMetaRef -*/ - -class NodeMetaRef -{ -private: - v3s16 m_p; - ServerEnvironment *m_env; - - static const char className[]; - static const luaL_reg methods[]; - - static NodeMetaRef *checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(NodeMetaRef**)ud; // unbox pointer - } - - static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create) - { - NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p); - if(meta == NULL && auto_create) - { - meta = new NodeMetadata(ref->m_env->getGameDef()); - ref->m_env->getMap().setNodeMetadata(ref->m_p, meta); - } - return meta; - } - - static void reportMetadataChange(NodeMetaRef *ref) - { - // NOTE: This same code is in rollback_interface.cpp - // Inform other things that the metadata has changed - v3s16 blockpos = getNodeBlockPos(ref->m_p); - MapEditEvent event; - event.type = MEET_BLOCK_NODE_METADATA_CHANGED; - event.p = blockpos; - ref->m_env->getMap().dispatchEvent(&event); - // Set the block to be saved - MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos); - if(block) - block->raiseModified(MOD_STATE_WRITE_NEEDED, - "NodeMetaRef::reportMetadataChange"); - } - - // Exported functions - - // garbage collector - static int gc_object(lua_State *L) { - NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - // get_string(self, name) - static int l_get_string(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - - NodeMetadata *meta = getmeta(ref, false); - if(meta == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushlstring(L, str.c_str(), str.size()); - return 1; - } - - // set_string(self, name, var) - static int l_set_string(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - size_t len = 0; - const char *s = lua_tolstring(L, 3, &len); - std::string str(s, len); - - NodeMetadata *meta = getmeta(ref, !str.empty()); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; - } - - // get_int(self, name) - static int l_get_int(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = getmeta(ref, false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stoi(str)); - return 1; - } - - // set_int(self, name, var) - static int l_set_int(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - int a = lua_tointeger(L, 3); - std::string str = itos(a); - - NodeMetadata *meta = getmeta(ref, true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; - } - - // get_float(self, name) - static int l_get_float(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = getmeta(ref, false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stof(str)); - return 1; - } - - // set_float(self, name, var) - static int l_set_float(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - float a = lua_tonumber(L, 3); - std::string str = ftos(a); - - NodeMetadata *meta = getmeta(ref, true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; - } - - // get_inventory(self) - static int l_get_inventory(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - getmeta(ref, true); // try to ensure the metadata exists - InvRef::createNodeMeta(L, ref->m_p); - return 1; - } - - // to_table(self) - static int l_to_table(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - - NodeMetadata *meta = getmeta(ref, true); - if(meta == NULL){ - lua_pushnil(L); - return 1; - } - lua_newtable(L); - // fields - lua_newtable(L); - { - std::map fields = meta->getStrings(); - for(std::map::const_iterator - i = fields.begin(); i != fields.end(); i++){ - const std::string &name = i->first; - const std::string &value = i->second; - lua_pushlstring(L, name.c_str(), name.size()); - lua_pushlstring(L, value.c_str(), value.size()); - lua_settable(L, -3); - } - } - lua_setfield(L, -2, "fields"); - // inventory - lua_newtable(L); - Inventory *inv = meta->getInventory(); - if(inv){ - std::vector lists = inv->getLists(); - for(std::vector::const_iterator - i = lists.begin(); i != lists.end(); i++){ - inventory_get_list_to_lua(inv, (*i)->getName().c_str(), L); - lua_setfield(L, -2, (*i)->getName().c_str()); - } - } - lua_setfield(L, -2, "inventory"); - return 1; - } - - // from_table(self, table) - static int l_from_table(lua_State *L) - { - NodeMetaRef *ref = checkobject(L, 1); - int base = 2; - - if(lua_isnil(L, base)){ - // No metadata - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - lua_pushboolean(L, true); - return 1; - } - - // Has metadata; clear old one first - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - // Create new metadata - NodeMetadata *meta = getmeta(ref, true); - // Set fields - lua_getfield(L, base, "fields"); - int fieldstable = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, fieldstable) != 0){ - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - size_t cl; - const char *cs = lua_tolstring(L, -1, &cl); - std::string value(cs, cl); - meta->setString(name, value); - lua_pop(L, 1); // removes value, keeps key for next iteration - } - // Set inventory - Inventory *inv = meta->getInventory(); - lua_getfield(L, base, "inventory"); - int inventorytable = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, inventorytable) != 0){ - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - inventory_set_list_from_lua(inv, name.c_str(), L, -1); - lua_pop(L, 1); // removes value, keeps key for next iteration - } - reportMetadataChange(ref); - lua_pushboolean(L, true); - return 1; - } - -public: - NodeMetaRef(v3s16 p, ServerEnvironment *env): - m_p(p), - m_env(env) - { - } - - ~NodeMetaRef() - { - } - - // Creates an NodeMetaRef and leaves it on top of stack - // Not callable from Lua; all references are created on the C side. - static void create(lua_State *L, v3s16 p, ServerEnvironment *env) - { - NodeMetaRef *o = new NodeMetaRef(p, env); - //infostream<<"NodeMetaRef::create: o="<m_object; - return co; - } -private: - static LuaEntitySAO* getluaobject(ObjectRef *ref) - { - ServerActiveObject *obj = getobject(ref); - if(obj == NULL) - return NULL; - if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY) - return NULL; - return (LuaEntitySAO*)obj; - } - - static PlayerSAO* getplayersao(ObjectRef *ref) - { - ServerActiveObject *obj = getobject(ref); - if(obj == NULL) - return NULL; - if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER) - return NULL; - return (PlayerSAO*)obj; - } - - static Player* getplayer(ObjectRef *ref) - { - PlayerSAO *playersao = getplayersao(ref); - if(playersao == NULL) - return NULL; - return playersao->getPlayer(); - } - - // Exported functions - - // garbage collector - static int gc_object(lua_State *L) { - ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1)); - //infostream<<"ObjectRef::gc_object: o="<setPos(pos); - return 0; - } - - // moveto(self, pos, continuous=false) - static int l_moveto(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - //LuaEntitySAO *co = getluaobject(ref); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // pos - v3f pos = checkFloatPos(L, 2); - // continuous - bool continuous = lua_toboolean(L, 3); - // Do it - co->moveTo(pos, continuous); - return 0; - } - - // punch(self, puncher, time_from_last_punch, tool_capabilities, dir) - static int l_punch(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ObjectRef *puncher_ref = checkobject(L, 2); - ServerActiveObject *co = getobject(ref); - ServerActiveObject *puncher = getobject(puncher_ref); - if(co == NULL) return 0; - if(puncher == NULL) return 0; - v3f dir; - if(lua_type(L, 5) != LUA_TTABLE) - dir = co->getBasePosition() - puncher->getBasePosition(); - else - dir = read_v3f(L, 5); - float time_from_last_punch = 1000000; - if(lua_isnumber(L, 3)) - time_from_last_punch = lua_tonumber(L, 3); - ToolCapabilities toolcap = read_tool_capabilities(L, 4); - dir.normalize(); - // Do it - co->punch(dir, &toolcap, puncher, time_from_last_punch); - return 0; - } - - // right_click(self, clicker); clicker = an another ObjectRef - static int l_right_click(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ObjectRef *ref2 = checkobject(L, 2); - ServerActiveObject *co = getobject(ref); - ServerActiveObject *co2 = getobject(ref2); - if(co == NULL) return 0; - if(co2 == NULL) return 0; - // Do it - co->rightClick(co2); - return 0; - } - - // set_hp(self, hp) - // hp = number of hitpoints (2 * number of hearts) - // returns: nil - static int l_set_hp(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - luaL_checknumber(L, 2); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - int hp = lua_tonumber(L, 2); - /*infostream<<"ObjectRef::l_set_hp(): id="<getId() - <<" hp="<setHP(hp); - // Return - return 0; - } - - // get_hp(self) - // returns: number of hitpoints (2 * number of hearts) - // 0 if not applicable to this type of object - static int l_get_hp(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL){ - // Default hp is 1 - lua_pushnumber(L, 1); - return 1; - } - int hp = co->getHP(); - /*infostream<<"ObjectRef::l_get_hp(): id="<getId() - <<" hp="<getInventoryLocation(); - if(get_server(L)->getInventory(loc) != NULL) - InvRef::create(L, loc); - else - lua_pushnil(L); // An object may have no inventory (nil) - return 1; - } - - // get_wield_list(self) - static int l_get_wield_list(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - lua_pushstring(L, co->getWieldList().c_str()); - return 1; - } - - // get_wield_index(self) - static int l_get_wield_index(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - lua_pushinteger(L, co->getWieldIndex() + 1); - return 1; - } - - // get_wielded_item(self) - static int l_get_wielded_item(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL){ - // Empty ItemStack - LuaItemStack::create(L, ItemStack()); - return 1; - } - // Do it - LuaItemStack::create(L, co->getWieldedItem()); - return 1; - } - - // set_wielded_item(self, itemstack or itemstring or table or nil) - static int l_set_wielded_item(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - ItemStack item = read_item(L, 2); - bool success = co->setWieldedItem(item); - lua_pushboolean(L, success); - return 1; - } - - // set_armor_groups(self, groups) - static int l_set_armor_groups(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - ItemGroupList groups; - read_groups(L, 2, groups); - co->setArmorGroups(groups); - return 0; - } - - // set_animation(self, frame_range, frame_speed, frame_blend) - static int l_set_animation(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - v2f frames = v2f(1, 1); - if(!lua_isnil(L, 2)) - frames = read_v2f(L, 2); - float frame_speed = 15; - if(!lua_isnil(L, 3)) - frame_speed = lua_tonumber(L, 3); - float frame_blend = 0; - if(!lua_isnil(L, 4)) - frame_blend = lua_tonumber(L, 4); - co->setAnimation(frames, frame_speed, frame_blend); - return 0; - } - - // set_bone_position(self, std::string bone, v3f position, v3f rotation) - static int l_set_bone_position(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - std::string bone = ""; - if(!lua_isnil(L, 2)) - bone = lua_tostring(L, 2); - v3f position = v3f(0, 0, 0); - if(!lua_isnil(L, 3)) - position = read_v3f(L, 3); - v3f rotation = v3f(0, 0, 0); - if(!lua_isnil(L, 4)) - rotation = read_v3f(L, 4); - co->setBonePosition(bone, position, rotation); - return 0; - } - - // set_attach(self, parent, bone, position, rotation) - static int l_set_attach(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ObjectRef *parent_ref = checkobject(L, 2); - ServerActiveObject *co = getobject(ref); - ServerActiveObject *parent = getobject(parent_ref); - if(co == NULL) return 0; - if(parent == NULL) return 0; - // Do it - std::string bone = ""; - if(!lua_isnil(L, 3)) - bone = lua_tostring(L, 3); - v3f position = v3f(0, 0, 0); - if(!lua_isnil(L, 4)) - position = read_v3f(L, 4); - v3f rotation = v3f(0, 0, 0); - if(!lua_isnil(L, 5)) - rotation = read_v3f(L, 5); - co->setAttachment(parent->getId(), bone, position, rotation); - return 0; - } - - // set_detach(self) - static int l_set_detach(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - // Do it - co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0)); - return 0; - } - - // set_properties(self, properties) - static int l_set_properties(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - ServerActiveObject *co = getobject(ref); - if(co == NULL) return 0; - ObjectProperties *prop = co->accessObjectProperties(); - if(!prop) - return 0; - read_object_properties(L, 2, prop); - co->notifyObjectPropertiesModified(); - return 0; - } - - /* LuaEntitySAO-only */ - - // setvelocity(self, {x=num, y=num, z=num}) - static int l_setvelocity(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - v3f pos = checkFloatPos(L, 2); - // Do it - co->setVelocity(pos); - return 0; - } - - // getvelocity(self) - static int l_getvelocity(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - v3f v = co->getVelocity(); - pushFloatPos(L, v); - return 1; - } - - // setacceleration(self, {x=num, y=num, z=num}) - static int l_setacceleration(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // pos - v3f pos = checkFloatPos(L, 2); - // Do it - co->setAcceleration(pos); - return 0; - } - - // getacceleration(self) - static int l_getacceleration(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - v3f v = co->getAcceleration(); - pushFloatPos(L, v); - return 1; - } - - // setyaw(self, radians) - static int l_setyaw(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - float yaw = luaL_checknumber(L, 2) * core::RADTODEG; - // Do it - co->setYaw(yaw); - return 0; - } - - // getyaw(self) - static int l_getyaw(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - float yaw = co->getYaw() * core::DEGTORAD; - lua_pushnumber(L, yaw); - return 1; - } - - // settexturemod(self, mod) - static int l_settexturemod(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - std::string mod = luaL_checkstring(L, 2); - co->setTextureMod(mod); - return 0; - } - - // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2, - // select_horiz_by_yawpitch=false) - static int l_setsprite(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - v2s16 p(0,0); - if(!lua_isnil(L, 2)) - p = read_v2s16(L, 2); - int num_frames = 1; - if(!lua_isnil(L, 3)) - num_frames = lua_tonumber(L, 3); - float framelength = 0.2; - if(!lua_isnil(L, 4)) - framelength = lua_tonumber(L, 4); - bool select_horiz_by_yawpitch = false; - if(!lua_isnil(L, 5)) - select_horiz_by_yawpitch = lua_toboolean(L, 5); - co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch); - return 0; - } - - // DEPRECATED - // get_entity_name(self) - static int l_get_entity_name(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - std::string name = co->getName(); - lua_pushstring(L, name.c_str()); - return 1; - } - - // get_luaentity(self) - static int l_get_luaentity(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - LuaEntitySAO *co = getluaobject(ref); - if(co == NULL) return 0; - // Do it - luaentity_get(L, co->getId()); - return 1; - } - - /* Player-only */ - - // is_player(self) - static int l_is_player(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - lua_pushboolean(L, (player != NULL)); - return 1; - } - - // get_player_name(self) - static int l_get_player_name(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - // Do it - lua_pushstring(L, player->getName()); - return 1; - } - - // get_look_dir(self) - static int l_get_look_dir(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL) return 0; - // Do it - float pitch = player->getRadPitch(); - float yaw = player->getRadYaw(); - v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw)); - push_v3f(L, v); - return 1; - } - - // get_look_pitch(self) - static int l_get_look_pitch(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL) return 0; - // Do it - lua_pushnumber(L, player->getRadPitch()); - return 1; - } - - // get_look_yaw(self) - static int l_get_look_yaw(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL) return 0; - // Do it - lua_pushnumber(L, player->getRadYaw()); - return 1; - } - - // set_inventory_formspec(self, formspec) - static int l_set_inventory_formspec(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL) return 0; - std::string formspec = luaL_checkstring(L, 2); - - player->inventory_formspec = formspec; - get_server(L)->reportInventoryFormspecModified(player->getName()); - lua_pushboolean(L, true); - return 1; - } - - // get_inventory_formspec(self) -> formspec - static int l_get_inventory_formspec(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL) return 0; - - std::string formspec = player->inventory_formspec; - lua_pushlstring(L, formspec.c_str(), formspec.size()); - return 1; - } - - // get_player_control(self) - static int l_get_player_control(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - // Do it - PlayerControl control = player->getPlayerControl(); - lua_newtable(L); - lua_pushboolean(L, control.up); - lua_setfield(L, -2, "up"); - lua_pushboolean(L, control.down); - lua_setfield(L, -2, "down"); - lua_pushboolean(L, control.left); - lua_setfield(L, -2, "left"); - lua_pushboolean(L, control.right); - lua_setfield(L, -2, "right"); - lua_pushboolean(L, control.jump); - lua_setfield(L, -2, "jump"); - lua_pushboolean(L, control.aux1); - lua_setfield(L, -2, "aux1"); - lua_pushboolean(L, control.sneak); - lua_setfield(L, -2, "sneak"); - lua_pushboolean(L, control.LMB); - lua_setfield(L, -2, "LMB"); - lua_pushboolean(L, control.RMB); - lua_setfield(L, -2, "RMB"); - return 1; - } - - // get_player_control_bits(self) - static int l_get_player_control_bits(lua_State *L) - { - ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); - if(player == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - // Do it - lua_pushnumber(L, player->keyPressed); - return 1; - } - -public: - ObjectRef(ServerActiveObject *object): - m_object(object) - { - //infostream<<"ObjectRef created for id="<getId()<getId() == 0){ - ObjectRef::create(L, cobj); - } else { - objectref_get(L, cobj->getId()); - } -} - -class LuaPerlinNoise -{ -private: - int seed; - int octaves; - float persistence; - float scale; - static const char className[]; - static const luaL_reg methods[]; - - // Exported functions - - // garbage collector - static int gc_object(lua_State *L) - { - LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - static int l_get2d(lua_State *L) - { - LuaPerlinNoise *o = checkobject(L, 1); - v2f pos2d = read_v2f(L,2); - lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence); - lua_pushnumber(L, val); - return 1; - } - static int l_get3d(lua_State *L) - { - LuaPerlinNoise *o = checkobject(L, 1); - v3f pos3d = read_v3f(L,2); - lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence); - lua_pushnumber(L, val); - return 1; - } - -public: - LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence, - float a_scale): - seed(a_seed), - octaves(a_octaves), - persistence(a_persistence), - scale(a_scale) - { - } - - ~LuaPerlinNoise() - { - } - - // LuaPerlinNoise(seed, octaves, persistence, scale) - // Creates an LuaPerlinNoise and leaves it on top of stack - static int create_object(lua_State *L) - { - int seed = luaL_checkint(L, 1); - int octaves = luaL_checkint(L, 2); - float persistence = luaL_checknumber(L, 3); - float scale = luaL_checknumber(L, 4); - LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - return 1; - } - - static LuaPerlinNoise* checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(LuaPerlinNoise**)ud; // unbox pointer - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Can be created from Lua (PerlinNoise(seed, octaves, persistence) - lua_register(L, className, create_object); - } -}; -const char LuaPerlinNoise::className[] = "PerlinNoise"; -const luaL_reg LuaPerlinNoise::methods[] = { - method(LuaPerlinNoise, get2d), - method(LuaPerlinNoise, get3d), - {0,0} -}; - -/* - PerlinNoiseMap - */ -class LuaPerlinNoiseMap -{ -private: - Noise *noise; - static const char className[]; - static const luaL_reg methods[]; - - static int gc_object(lua_State *L) - { - LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - static int l_get2dMap(lua_State *L) - { - int i = 0; - - LuaPerlinNoiseMap *o = checkobject(L, 1); - v2f p = read_v2f(L, 2); - - Noise *n = o->noise; - n->perlinMap2D(p.X, p.Y); - - lua_newtable(L); - for (int y = 0; y != n->sy; y++) { - lua_newtable(L); - for (int x = 0; x != n->sx; x++) { - float noiseval = n->np->offset + n->np->scale * n->result[i++]; - lua_pushnumber(L, noiseval); - lua_rawseti(L, -2, x + 1); - } - lua_rawseti(L, -2, y + 1); - } - return 1; - } - - static int l_get3dMap(lua_State *L) - { - int i = 0; - - LuaPerlinNoiseMap *o = checkobject(L, 1); - v3f p = read_v3f(L, 2); - - Noise *n = o->noise; - n->perlinMap3D(p.X, p.Y, p.Z); - - lua_newtable(L); - for (int z = 0; z != n->sz; z++) { - lua_newtable(L); - for (int y = 0; y != n->sy; y++) { - lua_newtable(L); - for (int x = 0; x != n->sx; x++) { - lua_pushnumber(L, n->np->offset + n->np->scale * n->result[i++]); - lua_rawseti(L, -2, x + 1); - } - lua_rawseti(L, -2, y + 1); - } - lua_rawseti(L, -2, z + 1); - } - return 1; - } - -public: - LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) { - noise = new Noise(np, seed, size.X, size.Y, size.Z); - } - - ~LuaPerlinNoiseMap() - { - delete noise->np; - delete noise; - } - - // LuaPerlinNoiseMap(np, size) - // Creates an LuaPerlinNoiseMap and leaves it on top of stack - static int create_object(lua_State *L) - { - NoiseParams *np = read_noiseparams(L, 1); - if (!np) - return 0; - v3s16 size = read_v3s16(L, 2); - - LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - return 1; - } - - static LuaPerlinNoiseMap *checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - - void *ud = luaL_checkudata(L, narg, className); - if (!ud) - luaL_typerror(L, narg, className); - - return *(LuaPerlinNoiseMap **)ud; // unbox pointer - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Can be created from Lua (PerlinNoiseMap(np, size) - lua_register(L, className, create_object); - } -}; -const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap"; -const luaL_reg LuaPerlinNoiseMap::methods[] = { - method(LuaPerlinNoiseMap, get2dMap), - method(LuaPerlinNoiseMap, get3dMap), - {0,0} -}; - -/* - NodeTimerRef -*/ - -class NodeTimerRef -{ -private: - v3s16 m_p; - ServerEnvironment *m_env; - - static const char className[]; - static const luaL_reg methods[]; - - static int gc_object(lua_State *L) { - NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - static NodeTimerRef *checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(NodeTimerRef**)ud; // unbox pointer - } - - static int l_set(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - f32 t = luaL_checknumber(L,2); - f32 e = luaL_checknumber(L,3); - env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e)); - return 0; - } - - static int l_start(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - f32 t = luaL_checknumber(L,2); - env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0)); - return 0; - } - - static int l_stop(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - env->getMap().removeNodeTimer(o->m_p); - return 0; - } - - static int l_is_started(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - - NodeTimer t = env->getMap().getNodeTimer(o->m_p); - lua_pushboolean(L,(t.timeout != 0)); - return 1; - } - - static int l_get_timeout(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - - NodeTimer t = env->getMap().getNodeTimer(o->m_p); - lua_pushnumber(L,t.timeout); - return 1; - } - - static int l_get_elapsed(lua_State *L) - { - NodeTimerRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - - NodeTimer t = env->getMap().getNodeTimer(o->m_p); - lua_pushnumber(L,t.elapsed); - return 1; - } - -public: - NodeTimerRef(v3s16 p, ServerEnvironment *env): - m_p(p), - m_env(env) - { - } - - ~NodeTimerRef() - { - } - - // Creates an NodeTimerRef and leaves it on top of stack - // Not callable from Lua; all references are created on the C side. - static void create(lua_State *L, v3s16 p, ServerEnvironment *env) - { - NodeTimerRef *o = new NodeTimerRef(p, env); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - } - - static void set_null(lua_State *L) - { - NodeTimerRef *o = checkobject(L, -1); - o->m_env = NULL; - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Cannot be created from Lua - //lua_register(L, className, create_object); - } -}; -const char NodeTimerRef::className[] = "NodeTimerRef"; -const luaL_reg NodeTimerRef::methods[] = { - method(NodeTimerRef, start), - method(NodeTimerRef, set), - method(NodeTimerRef, stop), - method(NodeTimerRef, is_started), - method(NodeTimerRef, get_timeout), - method(NodeTimerRef, get_elapsed), - {0,0} -}; - -/* - EnvRef -*/ - -class EnvRef -{ -private: - ServerEnvironment *m_env; - - static const char className[]; - static const luaL_reg methods[]; - - static int gc_object(lua_State *L) { - EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1)); - delete o; - return 0; - } - - static EnvRef *checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(EnvRef**)ud; // unbox pointer - } - - // Exported functions - - // EnvRef:set_node(pos, node) - // pos = {x=num, y=num, z=num} - static int l_set_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - INodeDefManager *ndef = env->getGameDef()->ndef(); - // parameters - v3s16 pos = read_v3s16(L, 2); - MapNode n = readnode(L, 3, ndef); - // Do it - bool succeeded = env->setNode(pos, n); - lua_pushboolean(L, succeeded); - return 1; - } - - static int l_add_node(lua_State *L) - { - return l_set_node(L); - } - - // EnvRef:remove_node(pos) - // pos = {x=num, y=num, z=num} - static int l_remove_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - INodeDefManager *ndef = env->getGameDef()->ndef(); - // parameters - v3s16 pos = read_v3s16(L, 2); - // Do it - bool succeeded = env->removeNode(pos); - lua_pushboolean(L, succeeded); - return 1; - } - - // EnvRef:get_node(pos) - // pos = {x=num, y=num, z=num} - static int l_get_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // pos - v3s16 pos = read_v3s16(L, 2); - // Do it - MapNode n = env->getMap().getNodeNoEx(pos); - // Return node - pushnode(L, n, env->getGameDef()->ndef()); - return 1; - } - - // EnvRef:get_node_or_nil(pos) - // pos = {x=num, y=num, z=num} - static int l_get_node_or_nil(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // pos - v3s16 pos = read_v3s16(L, 2); - // Do it - try{ - MapNode n = env->getMap().getNode(pos); - // Return node - pushnode(L, n, env->getGameDef()->ndef()); - return 1; - } catch(InvalidPositionException &e) - { - lua_pushnil(L); - return 1; - } - } - - // EnvRef:get_node_light(pos, timeofday) - // pos = {x=num, y=num, z=num} - // timeofday: nil = current time, 0 = night, 0.5 = day - static int l_get_node_light(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // Do it - v3s16 pos = read_v3s16(L, 2); - u32 time_of_day = env->getTimeOfDay(); - if(lua_isnumber(L, 3)) - time_of_day = 24000.0 * lua_tonumber(L, 3); - time_of_day %= 24000; - u32 dnr = time_to_daynight_ratio(time_of_day, true); - MapNode n = env->getMap().getNodeNoEx(pos); - try{ - MapNode n = env->getMap().getNode(pos); - INodeDefManager *ndef = env->getGameDef()->ndef(); - lua_pushinteger(L, n.getLightBlend(dnr, ndef)); - return 1; - } catch(InvalidPositionException &e) - { - lua_pushnil(L); - return 1; - } - } - - // EnvRef:place_node(pos, node) - // pos = {x=num, y=num, z=num} - static int l_place_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - v3s16 pos = read_v3s16(L, 2); - MapNode n = readnode(L, 3, env->getGameDef()->ndef()); - - // Don't attempt to load non-loaded area as of now - MapNode n_old = env->getMap().getNodeNoEx(pos); - if(n_old.getContent() == CONTENT_IGNORE){ - lua_pushboolean(L, false); - return 1; - } - // Create item to place - INodeDefManager *ndef = get_server(L)->ndef(); - IItemDefManager *idef = get_server(L)->idef(); - ItemStack item(ndef->get(n).name, 1, 0, "", idef); - // Make pointed position - PointedThing pointed; - pointed.type = POINTEDTHING_NODE; - pointed.node_abovesurface = pos; - pointed.node_undersurface = pos + v3s16(0,-1,0); - // Place it with a NULL placer (appears in Lua as a non-functional - // ObjectRef) - bool success = scriptapi_item_on_place(L, item, NULL, pointed); - lua_pushboolean(L, success); - return 1; - } - - // EnvRef:dig_node(pos) - // pos = {x=num, y=num, z=num} - static int l_dig_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - v3s16 pos = read_v3s16(L, 2); - - // Don't attempt to load non-loaded area as of now - MapNode n = env->getMap().getNodeNoEx(pos); - if(n.getContent() == CONTENT_IGNORE){ - lua_pushboolean(L, false); - return 1; - } - // Dig it out with a NULL digger (appears in Lua as a - // non-functional ObjectRef) - bool success = scriptapi_node_on_dig(L, pos, n, NULL); - lua_pushboolean(L, success); - return 1; - } - - // EnvRef:punch_node(pos) - // pos = {x=num, y=num, z=num} - static int l_punch_node(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - v3s16 pos = read_v3s16(L, 2); - - // Don't attempt to load non-loaded area as of now - MapNode n = env->getMap().getNodeNoEx(pos); - if(n.getContent() == CONTENT_IGNORE){ - lua_pushboolean(L, false); - return 1; - } - // Punch it with a NULL puncher (appears in Lua as a non-functional - // ObjectRef) - bool success = scriptapi_node_on_punch(L, pos, n, NULL); - lua_pushboolean(L, success); - return 1; - } - - // EnvRef:get_meta(pos) - static int l_get_meta(lua_State *L) - { - //infostream<<"EnvRef::l_get_meta()"<m_env; - if(env == NULL) return 0; - // Do it - v3s16 p = read_v3s16(L, 2); - NodeMetaRef::create(L, p, env); - return 1; - } - - // EnvRef:get_node_timer(pos) - static int l_get_node_timer(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // Do it - v3s16 p = read_v3s16(L, 2); - NodeTimerRef::create(L, p, env); - return 1; - } - - // EnvRef:add_entity(pos, entityname) -> ObjectRef or nil - // pos = {x=num, y=num, z=num} - static int l_add_entity(lua_State *L) - { - //infostream<<"EnvRef::l_add_entity()"<m_env; - if(env == NULL) return 0; - // pos - v3f pos = checkFloatPos(L, 2); - // content - const char *name = luaL_checkstring(L, 3); - // Do it - ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, ""); - int objectid = env->addActiveObject(obj); - // If failed to add, return nothing (reads as nil) - if(objectid == 0) - return 0; - // Return ObjectRef - objectref_get_or_create(L, obj); - return 1; - } - - // EnvRef:add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil - // pos = {x=num, y=num, z=num} - static int l_add_item(lua_State *L) - { - //infostream<<"EnvRef::l_add_item()"<m_env; - if(env == NULL) return 0; - // pos - v3f pos = checkFloatPos(L, 2); - // item - ItemStack item = read_item(L, 3); - if(item.empty() || !item.isKnown(get_server(L)->idef())) - return 0; - // Use minetest.spawn_item to spawn a __builtin:item - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "spawn_item"); - if(lua_isnil(L, -1)) - return 0; - lua_pushvalue(L, 2); - lua_pushstring(L, item.getItemString().c_str()); - if(lua_pcall(L, 2, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - return 1; - /*lua_pushvalue(L, 1); - lua_pushstring(L, "__builtin:item"); - lua_pushstring(L, item.getItemString().c_str()); - return l_add_entity(L);*/ - /*// Do it - ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString()); - int objectid = env->addActiveObject(obj); - // If failed to add, return nothing (reads as nil) - if(objectid == 0) - return 0; - // Return ObjectRef - objectref_get_or_create(L, obj); - return 1;*/ - } - - // EnvRef:add_rat(pos) - // pos = {x=num, y=num, z=num} - static int l_add_rat(lua_State *L) - { - infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed." - <<" Doing nothing."<m_env; - if(env == NULL) return 0; - // Do it - const char *name = luaL_checkstring(L, 2); - Player *player = env->getPlayer(name); - if(player == NULL){ - lua_pushnil(L); - return 1; - } - PlayerSAO *sao = player->getPlayerSAO(); - if(sao == NULL){ - lua_pushnil(L); - return 1; - } - // Put player on stack - objectref_get_or_create(L, sao); - return 1; - } - - // EnvRef:get_objects_inside_radius(pos, radius) - static int l_get_objects_inside_radius(lua_State *L) - { - // Get the table insert function - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int table_insert = lua_gettop(L); - // Get environemnt - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // Do it - v3f pos = checkFloatPos(L, 2); - float radius = luaL_checknumber(L, 3) * BS; - std::set ids = env->getObjectsInsideRadius(pos, radius); - lua_newtable(L); - int table = lua_gettop(L); - for(std::set::const_iterator - i = ids.begin(); i != ids.end(); i++){ - ServerActiveObject *obj = env->getActiveObject(*i); - // Insert object reference into table - lua_pushvalue(L, table_insert); - lua_pushvalue(L, table); - objectref_get_or_create(L, obj); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - } - return 1; - } - - // EnvRef:set_timeofday(val) - // val = 0...1 - static int l_set_timeofday(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // Do it - float timeofday_f = luaL_checknumber(L, 2); - assert(timeofday_f >= 0.0 && timeofday_f <= 1.0); - int timeofday_mh = (int)(timeofday_f * 24000.0); - // This should be set directly in the environment but currently - // such changes aren't immediately sent to the clients, so call - // the server instead. - //env->setTimeOfDay(timeofday_mh); - get_server(L)->setTimeOfDay(timeofday_mh); - return 0; - } - - // EnvRef:get_timeofday() -> 0...1 - static int l_get_timeofday(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - // Do it - int timeofday_mh = env->getTimeOfDay(); - float timeofday_f = (float)timeofday_mh / 24000.0; - lua_pushnumber(L, timeofday_f); - return 1; - } - - - // EnvRef:find_node_near(pos, radius, nodenames) -> pos or nil - // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" - static int l_find_node_near(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - INodeDefManager *ndef = get_server(L)->ndef(); - v3s16 pos = read_v3s16(L, 2); - int radius = luaL_checkinteger(L, 3); - std::set filter; - if(lua_istable(L, 4)){ - int table = 4; - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TSTRING); - ndef->getIds(lua_tostring(L, -1), filter); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } else if(lua_isstring(L, 4)){ - ndef->getIds(lua_tostring(L, 4), filter); - } - - for(int d=1; d<=radius; d++){ - core::list list; - getFacePositions(list, d); - for(core::list::Iterator i = list.begin(); - i != list.end(); i++){ - v3s16 p = pos + (*i); - content_t c = env->getMap().getNodeNoEx(p).getContent(); - if(filter.count(c) != 0){ - push_v3s16(L, p); - return 1; - } - } - } - return 0; - } - - // EnvRef:find_nodes_in_area(minp, maxp, nodenames) -> list of positions - // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" - static int l_find_nodes_in_area(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - INodeDefManager *ndef = get_server(L)->ndef(); - v3s16 minp = read_v3s16(L, 2); - v3s16 maxp = read_v3s16(L, 3); - std::set filter; - if(lua_istable(L, 4)){ - int table = 4; - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TSTRING); - ndef->getIds(lua_tostring(L, -1), filter); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } else if(lua_isstring(L, 4)){ - ndef->getIds(lua_tostring(L, 4), filter); - } - - // Get the table insert function - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int table_insert = lua_gettop(L); - - lua_newtable(L); - int table = lua_gettop(L); - for(s16 x=minp.X; x<=maxp.X; x++) - for(s16 y=minp.Y; y<=maxp.Y; y++) - for(s16 z=minp.Z; z<=maxp.Z; z++) - { - v3s16 p(x,y,z); - content_t c = env->getMap().getNodeNoEx(p).getContent(); - if(filter.count(c) != 0){ - lua_pushvalue(L, table_insert); - lua_pushvalue(L, table); - push_v3s16(L, p); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - } - } - return 1; - } - - // EnvRef:get_perlin(seeddiff, octaves, persistence, scale) - // returns world-specific PerlinNoise - static int l_get_perlin(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - - int seeddiff = luaL_checkint(L, 2); - int octaves = luaL_checkint(L, 3); - float persistence = luaL_checknumber(L, 4); - float scale = luaL_checknumber(L, 5); - - LuaPerlinNoise *n = new LuaPerlinNoise(seeddiff + int(env->getServerMap().getSeed()), octaves, persistence, scale); - *(void **)(lua_newuserdata(L, sizeof(void *))) = n; - luaL_getmetatable(L, "PerlinNoise"); - lua_setmetatable(L, -2); - return 1; - } - - // EnvRef:get_perlin_map(noiseparams, size) - // returns world-specific PerlinNoiseMap - static int l_get_perlin_map(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if (env == NULL) - return 0; - - NoiseParams *np = read_noiseparams(L, 2); - if (!np) - return 0; - v3s16 size = read_v3s16(L, 3); - - int seed = (int)(env->getServerMap().getSeed()); - LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(np, seed, size); - *(void **)(lua_newuserdata(L, sizeof(void *))) = n; - luaL_getmetatable(L, "PerlinNoiseMap"); - lua_setmetatable(L, -2); - return 1; - } - - // EnvRef:clear_objects() - // clear all objects in the environment - static int l_clear_objects(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - o->m_env->clearAllObjects(); - return 0; - } - - static int l_spawn_tree(lua_State *L) - { - EnvRef *o = checkobject(L, 1); - ServerEnvironment *env = o->m_env; - if(env == NULL) return 0; - v3s16 p0 = read_v3s16(L, 2); - - treegen::TreeDef tree_def; - std::string trunk,leaves,fruit; - INodeDefManager *ndef = env->getGameDef()->ndef(); - - if(lua_istable(L, 3)) - { - getstringfield(L, 3, "axiom", tree_def.initial_axiom); - getstringfield(L, 3, "rules_a", tree_def.rules_a); - getstringfield(L, 3, "rules_b", tree_def.rules_b); - getstringfield(L, 3, "rules_c", tree_def.rules_c); - getstringfield(L, 3, "rules_d", tree_def.rules_d); - getstringfield(L, 3, "trunk", trunk); - tree_def.trunknode=ndef->getId(trunk); - getstringfield(L, 3, "leaves", leaves); - tree_def.leavesnode=ndef->getId(leaves); - tree_def.leaves2_chance=0; - getstringfield(L, 3, "leaves2", leaves); - if (leaves !="") - { - tree_def.leaves2node=ndef->getId(leaves); - getintfield(L, 3, "leaves2_chance", tree_def.leaves2_chance); - } - getintfield(L, 3, "angle", tree_def.angle); - getintfield(L, 3, "iterations", tree_def.iterations); - getintfield(L, 3, "random_level", tree_def.iterations_random_level); - getstringfield(L, 3, "trunk_type", tree_def.trunk_type); - getboolfield(L, 3, "thin_branches", tree_def.thin_branches); - tree_def.fruit_chance=0; - getstringfield(L, 3, "fruit", fruit); - if (fruit != "") - { - tree_def.fruitnode=ndef->getId(fruit); - getintfield(L, 3, "fruit_chance",tree_def.fruit_chance); - } - getintfield(L, 3, "seed", tree_def.seed); - } - else - return 0; - treegen::spawn_ltree (env, p0, ndef, tree_def); - return 1; - } - -public: - EnvRef(ServerEnvironment *env): - m_env(env) - { - //infostream<<"EnvRef created"< get next value - static int l_next(lua_State *L) - { - LuaPseudoRandom *o = checkobject(L, 1); - int min = 0; - int max = 32767; - lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist - if(!lua_isnil(L, 2)) - min = luaL_checkinteger(L, 2); - if(!lua_isnil(L, 3)) - max = luaL_checkinteger(L, 3); - if(max < min){ - errorstream<<"PseudoRandom.next(): max="< 32767/5) - throw LuaError(L, "PseudoRandom.next() max-min is not 32767 and is > 32768/5. This is disallowed due to the bad random distribution the implementation would otherwise make."); - PseudoRandom &pseudo = o->m_pseudo; - int val = pseudo.next(); - val = (val % (max-min+1)) + min; - lua_pushinteger(L, val); - return 1; - } - -public: - LuaPseudoRandom(int seed): - m_pseudo(seed) - { - } - - ~LuaPseudoRandom() - { - } - - const PseudoRandom& getItem() const - { - return m_pseudo; - } - PseudoRandom& getItem() - { - return m_pseudo; - } - - // LuaPseudoRandom(seed) - // Creates an LuaPseudoRandom and leaves it on top of stack - static int create_object(lua_State *L) - { - int seed = luaL_checknumber(L, 1); - LuaPseudoRandom *o = new LuaPseudoRandom(seed); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - return 1; - } - - static LuaPseudoRandom* checkobject(lua_State *L, int narg) - { - luaL_checktype(L, narg, LUA_TUSERDATA); - void *ud = luaL_checkudata(L, narg, className); - if(!ud) luaL_typerror(L, narg, className); - return *(LuaPseudoRandom**)ud; // unbox pointer - } - - static void Register(lua_State *L) - { - lua_newtable(L); - int methodtable = lua_gettop(L); - luaL_newmetatable(L, className); - int metatable = lua_gettop(L); - - lua_pushliteral(L, "__metatable"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methodtable); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_object); - lua_settable(L, metatable); - - lua_pop(L, 1); // drop metatable - - luaL_openlib(L, 0, methods, 0); // fill methodtable - lua_pop(L, 1); // drop methodtable - - // Can be created from Lua (LuaPseudoRandom(seed)) - lua_register(L, className, create_object); - } -}; -const char LuaPseudoRandom::className[] = "PseudoRandom"; -const luaL_reg LuaPseudoRandom::methods[] = { - method(LuaPseudoRandom, next), - {0,0} -}; - - - -/* - LuaABM -*/ - -class LuaABM : public ActiveBlockModifier -{ -private: - lua_State *m_lua; - int m_id; - - std::set m_trigger_contents; - std::set m_required_neighbors; - float m_trigger_interval; - u32 m_trigger_chance; -public: - LuaABM(lua_State *L, int id, - const std::set &trigger_contents, - const std::set &required_neighbors, - float trigger_interval, u32 trigger_chance): - m_lua(L), - m_id(id), - m_trigger_contents(trigger_contents), - m_required_neighbors(required_neighbors), - m_trigger_interval(trigger_interval), - m_trigger_chance(trigger_chance) - { - } - virtual std::set getTriggerContents() - { - return m_trigger_contents; - } - virtual std::set getRequiredNeighbors() - { - return m_required_neighbors; - } - virtual float getTriggerInterval() - { - return m_trigger_interval; - } - virtual u32 getTriggerChance() - { - return m_trigger_chance; - } - virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, - u32 active_object_count, u32 active_object_count_wider) - { - lua_State *L = m_lua; - - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_abms - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_abms"); - luaL_checktype(L, -1, LUA_TTABLE); - int registered_abms = lua_gettop(L); - - // Get minetest.registered_abms[m_id] - lua_pushnumber(L, m_id); - lua_gettable(L, registered_abms); - if(lua_isnil(L, -1)) - assert(0); - - // Call action - luaL_checktype(L, -1, LUA_TTABLE); - lua_getfield(L, -1, "action"); - luaL_checktype(L, -1, LUA_TFUNCTION); - push_v3s16(L, p); - pushnode(L, n, env->getGameDef()->ndef()); - lua_pushnumber(L, active_object_count); - lua_pushnumber(L, active_object_count_wider); - if(lua_pcall(L, 4, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - } -}; - -/* - ServerSoundParams -*/ - -static void read_server_sound_params(lua_State *L, int index, - ServerSoundParams ¶ms) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - // Clear - params = ServerSoundParams(); - if(lua_istable(L, index)){ - getfloatfield(L, index, "gain", params.gain); - getstringfield(L, index, "to_player", params.to_player); - lua_getfield(L, index, "pos"); - if(!lua_isnil(L, -1)){ - v3f p = read_v3f(L, -1)*BS; - params.pos = p; - params.type = ServerSoundParams::SSP_POSITIONAL; - } - lua_pop(L, 1); - lua_getfield(L, index, "object"); - if(!lua_isnil(L, -1)){ - ObjectRef *ref = ObjectRef::checkobject(L, -1); - ServerActiveObject *sao = ObjectRef::getobject(ref); - if(sao){ - params.object = sao->getId(); - params.type = ServerSoundParams::SSP_OBJECT; - } - } - lua_pop(L, 1); - params.max_hear_distance = BS*getfloatfield_default(L, index, - "max_hear_distance", params.max_hear_distance/BS); - getboolfield(L, index, "loop", params.loop); - } -} - -/* - Global functions -*/ - -// debug(text) -// Writes a line to dstream -static int l_debug(lua_State *L) -{ - std::string text = lua_tostring(L, 1); - dstream << text << std::endl; - return 0; -} - -// log([level,] text) -// Writes a line to the logger. -// The one-argument version logs to infostream. -// The two-argument version accept a log level: error, action, info, or verbose. -static int l_log(lua_State *L) -{ - std::string text; - LogMessageLevel level = LMT_INFO; - if(lua_isnone(L, 2)) - { - text = lua_tostring(L, 1); - } - else - { - std::string levelname = luaL_checkstring(L, 1); - text = luaL_checkstring(L, 2); - if(levelname == "error") - level = LMT_ERROR; - else if(levelname == "action") - level = LMT_ACTION; - else if(levelname == "verbose") - level = LMT_VERBOSE; - } - log_printline(level, text); - return 0; -} - -// request_shutdown() -static int l_request_shutdown(lua_State *L) -{ - get_server(L)->requestShutdown(); - return 0; -} - -// get_server_status() -static int l_get_server_status(lua_State *L) -{ - lua_pushstring(L, wide_to_narrow(get_server(L)->getStatusString()).c_str()); - return 1; -} - -// register_biome_groups({frequencies}) -static int l_register_biome_groups(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TTABLE); - int index = 1; - if (!lua_istable(L, index)) - throw LuaError(L, "register_biome_groups: parameter is not a table"); - - BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); - if (!bmgr) { - verbosestream << "register_biome_groups: BiomeDefManager not active" << std::endl; - return 0; - } - - lua_pushnil(L); - for (int i = 1; lua_next(L, index) != 0; i++) { - bmgr->addBiomeGroup(lua_tonumber(L, -1)); - lua_pop(L, 1); - } - lua_pop(L, 1); - - return 0; -} - -// register_biome({lots of stuff}) -static int l_register_biome(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TTABLE); - int index = 1, groupid; - std::string nodename; - - IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager(); - BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); - if (!bmgr) { - verbosestream << "register_biome: BiomeDefManager not active" << std::endl; - return 0; - } - - groupid = getintfield_default(L, index, "group_id", 0); - - enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index, - "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL); - Biome *b = bmgr->createBiome(terrain); - - b->name = getstringfield_default(L, index, "name", ""); - - if (getstringfield(L, index, "node_top", nodename)) - b->n_top = MapNode(ndef->getId(nodename)); - else - b->n_top = MapNode(CONTENT_IGNORE); - - if (getstringfield(L, index, "node_filler", nodename)) - b->n_filler = MapNode(ndef->getId(nodename)); - else - b->n_filler = b->n_top; - - b->ntopnodes = getintfield_default(L, index, "num_top_nodes", 0); - - b->height_min = getintfield_default(L, index, "height_min", 0); - b->height_max = getintfield_default(L, index, "height_max", 0); - b->heat_min = getfloatfield_default(L, index, "heat_min", 0.); - b->heat_max = getfloatfield_default(L, index, "heat_max", 0.); - b->humidity_min = getfloatfield_default(L, index, "humidity_min", 0.); - b->humidity_max = getfloatfield_default(L, index, "humidity_max", 0.); - - b->np = new NoiseParams; // should read an entire NoiseParams later on... - getfloatfield(L, index, "scale", b->np->scale); - getfloatfield(L, index, "offset", b->np->offset); - - b->groupid = (s8)groupid; - b->flags = 0; //reserved - - bmgr->addBiome(b); - - verbosestream << "register_biome: " << b->name << std::endl; - return 0; -} - -// register_item_raw({lots of stuff}) -static int l_register_item_raw(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TTABLE); - int table = 1; - - // Get the writable item and node definition managers from the server - IWritableItemDefManager *idef = - get_server(L)->getWritableItemDefManager(); - IWritableNodeDefManager *ndef = - get_server(L)->getWritableNodeDefManager(); - - // Check if name is defined - std::string name; - lua_getfield(L, table, "name"); - if(lua_isstring(L, -1)){ - name = lua_tostring(L, -1); - verbosestream<<"register_item_raw: "<registerItem(def); - - // Read the node definition (content features) and register it - if(def.type == ITEM_NODE) - { - ContentFeatures f = read_content_features(L, table); - ndef->set(f.name, f); - } - - return 0; /* number of results */ -} - -// register_alias_raw(name, convert_to_name) -static int l_register_alias_raw(lua_State *L) -{ - std::string name = luaL_checkstring(L, 1); - std::string convert_to = luaL_checkstring(L, 2); - - // Get the writable item definition manager from the server - IWritableItemDefManager *idef = - get_server(L)->getWritableItemDefManager(); - - idef->registerAlias(name, convert_to); - - return 0; /* number of results */ -} - -// helper for register_craft -static bool read_craft_recipe_shaped(lua_State *L, int index, - int &width, std::vector &recipe) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - if(!lua_istable(L, index)) - return false; - - lua_pushnil(L); - int rowcount = 0; - while(lua_next(L, index) != 0){ - int colcount = 0; - // key at index -2 and value at index -1 - if(!lua_istable(L, -1)) - return false; - int table2 = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table2) != 0){ - // key at index -2 and value at index -1 - if(!lua_isstring(L, -1)) - return false; - recipe.push_back(lua_tostring(L, -1)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - colcount++; - } - if(rowcount == 0){ - width = colcount; - } else { - if(colcount != width) - return false; - } - // removes value, keeps key for next iteration - lua_pop(L, 1); - rowcount++; - } - return width != 0; -} - -// helper for register_craft -static bool read_craft_recipe_shapeless(lua_State *L, int index, - std::vector &recipe) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - if(!lua_istable(L, index)) - return false; - - lua_pushnil(L); - while(lua_next(L, index) != 0){ - // key at index -2 and value at index -1 - if(!lua_isstring(L, -1)) - return false; - recipe.push_back(lua_tostring(L, -1)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - return true; -} - -// helper for register_craft -static bool read_craft_replacements(lua_State *L, int index, - CraftReplacements &replacements) -{ - if(index < 0) - index = lua_gettop(L) + 1 + index; - - if(!lua_istable(L, index)) - return false; - - lua_pushnil(L); - while(lua_next(L, index) != 0){ - // key at index -2 and value at index -1 - if(!lua_istable(L, -1)) - return false; - lua_rawgeti(L, -1, 1); - if(!lua_isstring(L, -1)) - return false; - std::string replace_from = lua_tostring(L, -1); - lua_pop(L, 1); - lua_rawgeti(L, -1, 2); - if(!lua_isstring(L, -1)) - return false; - std::string replace_to = lua_tostring(L, -1); - lua_pop(L, 1); - replacements.pairs.push_back( - std::make_pair(replace_from, replace_to)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - return true; -} -// register_craft({output=item, recipe={{item00,item10},{item01,item11}}) -static int l_register_craft(lua_State *L) -{ - //infostream<<"register_craft"<getWritableCraftDefManager(); - - std::string type = getstringfield_default(L, table, "type", "shaped"); - - /* - CraftDefinitionShaped - */ - if(type == "shaped"){ - std::string output = getstringfield_default(L, table, "output", ""); - if(output == "") - throw LuaError(L, "Crafting definition is missing an output"); - - int width = 0; - std::vector recipe; - lua_getfield(L, table, "recipe"); - if(lua_isnil(L, -1)) - throw LuaError(L, "Crafting definition is missing a recipe" - " (output=\"" + output + "\")"); - if(!read_craft_recipe_shaped(L, -1, width, recipe)) - throw LuaError(L, "Invalid crafting recipe" - " (output=\"" + output + "\")"); - - CraftReplacements replacements; - lua_getfield(L, table, "replacements"); - if(!lua_isnil(L, -1)) - { - if(!read_craft_replacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" - " (output=\"" + output + "\")"); - } - - CraftDefinition *def = new CraftDefinitionShaped( - output, width, recipe, replacements); - craftdef->registerCraft(def); - } - /* - CraftDefinitionShapeless - */ - else if(type == "shapeless"){ - std::string output = getstringfield_default(L, table, "output", ""); - if(output == "") - throw LuaError(L, "Crafting definition (shapeless)" - " is missing an output"); - - std::vector recipe; - lua_getfield(L, table, "recipe"); - if(lua_isnil(L, -1)) - throw LuaError(L, "Crafting definition (shapeless)" - " is missing a recipe" - " (output=\"" + output + "\")"); - if(!read_craft_recipe_shapeless(L, -1, recipe)) - throw LuaError(L, "Invalid crafting recipe" - " (output=\"" + output + "\")"); - - CraftReplacements replacements; - lua_getfield(L, table, "replacements"); - if(!lua_isnil(L, -1)) - { - if(!read_craft_replacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" - " (output=\"" + output + "\")"); - } - - CraftDefinition *def = new CraftDefinitionShapeless( - output, recipe, replacements); - craftdef->registerCraft(def); - } - /* - CraftDefinitionToolRepair - */ - else if(type == "toolrepair"){ - float additional_wear = getfloatfield_default(L, table, - "additional_wear", 0.0); - - CraftDefinition *def = new CraftDefinitionToolRepair( - additional_wear); - craftdef->registerCraft(def); - } - /* - CraftDefinitionCooking - */ - else if(type == "cooking"){ - std::string output = getstringfield_default(L, table, "output", ""); - if(output == "") - throw LuaError(L, "Crafting definition (cooking)" - " is missing an output"); - - std::string recipe = getstringfield_default(L, table, "recipe", ""); - if(recipe == "") - throw LuaError(L, "Crafting definition (cooking)" - " is missing a recipe" - " (output=\"" + output + "\")"); - - float cooktime = getfloatfield_default(L, table, "cooktime", 3.0); - - CraftReplacements replacements; - lua_getfield(L, table, "replacements"); - if(!lua_isnil(L, -1)) - { - if(!read_craft_replacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" - " (cooking output=\"" + output + "\")"); - } - - CraftDefinition *def = new CraftDefinitionCooking( - output, recipe, cooktime, replacements); - craftdef->registerCraft(def); - } - /* - CraftDefinitionFuel - */ - else if(type == "fuel"){ - std::string recipe = getstringfield_default(L, table, "recipe", ""); - if(recipe == "") - throw LuaError(L, "Crafting definition (fuel)" - " is missing a recipe"); - - float burntime = getfloatfield_default(L, table, "burntime", 1.0); - - CraftReplacements replacements; - lua_getfield(L, table, "replacements"); - if(!lua_isnil(L, -1)) - { - if(!read_craft_replacements(L, -1, replacements)) - throw LuaError(L, "Invalid replacements" - " (fuel recipe=\"" + recipe + "\")"); - } - - CraftDefinition *def = new CraftDefinitionFuel( - recipe, burntime, replacements); - craftdef->registerCraft(def); - } - else - { - throw LuaError(L, "Unknown crafting definition type: \"" + type + "\""); - } - - lua_pop(L, 1); - return 0; /* number of results */ -} - -// setting_set(name, value) -static int l_setting_set(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - const char *value = luaL_checkstring(L, 2); - g_settings->set(name, value); - return 0; -} - -// setting_get(name) -static int l_setting_get(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - try{ - std::string value = g_settings->get(name); - lua_pushstring(L, value.c_str()); - } catch(SettingNotFoundException &e){ - lua_pushnil(L); - } - return 1; -} - -// setting_getbool(name) -static int l_setting_getbool(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - try{ - bool value = g_settings->getBool(name); - lua_pushboolean(L, value); - } catch(SettingNotFoundException &e){ - lua_pushnil(L); - } - return 1; -} - -// setting_save() -static int l_setting_save(lua_State *L) -{ - get_server(L)->saveConfig(); - return 0; -} - -// chat_send_all(text) -static int l_chat_send_all(lua_State *L) -{ - const char *text = luaL_checkstring(L, 1); - // Get server from registry - Server *server = get_server(L); - // Send - server->notifyPlayers(narrow_to_wide(text)); - return 0; -} - -// chat_send_player(name, text) -static int l_chat_send_player(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - const char *text = luaL_checkstring(L, 2); - // Get server from registry - Server *server = get_server(L); - // Send - server->notifyPlayer(name, narrow_to_wide(text)); - return 0; -} - -// get_player_privs(name, text) -static int l_get_player_privs(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - // Get server from registry - Server *server = get_server(L); - // Do it - lua_newtable(L); - int table = lua_gettop(L); - std::set privs_s = server->getPlayerEffectivePrivs(name); - for(std::set::const_iterator - i = privs_s.begin(); i != privs_s.end(); i++){ - lua_pushboolean(L, true); - lua_setfield(L, table, i->c_str()); - } - lua_pushvalue(L, table); - return 1; -} - -// get_ban_list() -static int l_get_ban_list(lua_State *L) -{ - lua_pushstring(L, get_server(L)->getBanDescription("").c_str()); - return 1; -} - -// get_ban_description() -static int l_get_ban_description(lua_State *L) -{ - const char * ip_or_name = luaL_checkstring(L, 1); - lua_pushstring(L, get_server(L)->getBanDescription(std::string(ip_or_name)).c_str()); - return 1; -} - -// ban_player() -static int l_ban_player(lua_State *L) -{ - const char * name = luaL_checkstring(L, 1); - Player *player = get_env(L)->getPlayer(name); - if(player == NULL) - { - lua_pushboolean(L, false); // no such player - return 1; - } - try - { - Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id); - std::string ip_str = addr.serializeString(); - get_server(L)->setIpBanned(ip_str, name); - } - catch(con::PeerNotFoundException) // unlikely - { - dstream << __FUNCTION_NAME << ": peer was not found" << std::endl; - lua_pushboolean(L, false); // error - return 1; - } - lua_pushboolean(L, true); - return 1; -} - -// unban_player_or_ip() -static int l_unban_player_of_ip(lua_State *L) -{ - const char * ip_or_name = luaL_checkstring(L, 1); - get_server(L)->unsetIpBanned(ip_or_name); - lua_pushboolean(L, true); - return 1; -} - -// get_inventory(location) -static int l_get_inventory(lua_State *L) -{ - InventoryLocation loc; - - std::string type = checkstringfield(L, 1, "type"); - if(type == "player"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setPlayer(name); - } else if(type == "node"){ - lua_getfield(L, 1, "pos"); - v3s16 pos = check_v3s16(L, -1); - loc.setNodeMeta(pos); - } else if(type == "detached"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setDetached(name); - } - - if(get_server(L)->getInventory(loc) != NULL) - InvRef::create(L, loc); - else - lua_pushnil(L); - return 1; -} - -// create_detached_inventory_raw(name) -static int l_create_detached_inventory_raw(lua_State *L) -{ - const char *name = luaL_checkstring(L, 1); - if(get_server(L)->createDetachedInventory(name) != NULL){ - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - }else{ - lua_pushnil(L); - } - return 1; -} - -// show_formspec(playername,formname,formspec) -static int l_show_formspec(lua_State *L) -{ - const char *playername = luaL_checkstring(L, 1); - const char *formname = luaL_checkstring(L, 2); - const char *formspec = luaL_checkstring(L, 3); - - if(get_server(L)->showFormspec(playername,formspec,formname)) - { - lua_pushboolean(L, true); - }else{ - lua_pushboolean(L, false); - } - return 1; -} - -// get_dig_params(groups, tool_capabilities[, time_from_last_punch]) -static int l_get_dig_params(lua_State *L) -{ - std::map groups; - read_groups(L, 1, groups); - ToolCapabilities tp = read_tool_capabilities(L, 2); - if(lua_isnoneornil(L, 3)) - push_dig_params(L, getDigParams(groups, &tp)); - else - push_dig_params(L, getDigParams(groups, &tp, - luaL_checknumber(L, 3))); - return 1; -} - -// get_hit_params(groups, tool_capabilities[, time_from_last_punch]) -static int l_get_hit_params(lua_State *L) -{ - std::map groups; - read_groups(L, 1, groups); - ToolCapabilities tp = read_tool_capabilities(L, 2); - if(lua_isnoneornil(L, 3)) - push_hit_params(L, getHitParams(groups, &tp)); - else - push_hit_params(L, getHitParams(groups, &tp, - luaL_checknumber(L, 3))); - return 1; -} - -// get_current_modname() -static int l_get_current_modname(lua_State *L) -{ - lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname"); - return 1; -} - -// get_modpath(modname) -static int l_get_modpath(lua_State *L) -{ - std::string modname = luaL_checkstring(L, 1); - // Do it - if(modname == "__builtin"){ - std::string path = get_server(L)->getBuiltinLuaPath(); - lua_pushstring(L, path.c_str()); - return 1; - } - const ModSpec *mod = get_server(L)->getModSpec(modname); - if(!mod){ - lua_pushnil(L); - return 1; - } - lua_pushstring(L, mod->path.c_str()); - return 1; -} - -// get_modnames() -// the returned list is sorted alphabetically for you -static int l_get_modnames(lua_State *L) -{ - // Get a list of mods - core::list mods_unsorted, mods_sorted; - get_server(L)->getModNames(mods_unsorted); - - // Take unsorted items from mods_unsorted and sort them into - // mods_sorted; not great performance but the number of mods on a - // server will likely be small. - for(core::list::Iterator i = mods_unsorted.begin(); - i != mods_unsorted.end(); i++) - { - bool added = false; - for(core::list::Iterator x = mods_sorted.begin(); - x != mods_unsorted.end(); x++) - { - // I doubt anybody using Minetest will be using - // anything not ASCII based :) - if((*i).compare(*x) <= 0) - { - mods_sorted.insert_before(x, *i); - added = true; - break; - } - } - if(!added) - mods_sorted.push_back(*i); - } - - // Get the table insertion function from Lua. - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int insertion_func = lua_gettop(L); - - // Package them up for Lua - lua_newtable(L); - int new_table = lua_gettop(L); - core::list::Iterator i = mods_sorted.begin(); - while(i != mods_sorted.end()) - { - lua_pushvalue(L, insertion_func); - lua_pushvalue(L, new_table); - lua_pushstring(L, (*i).c_str()); - if(lua_pcall(L, 2, 0, 0) != 0) - { - script_error(L, "error: %s", lua_tostring(L, -1)); - } - i++; - } - return 1; -} - -// get_worldpath() -static int l_get_worldpath(lua_State *L) -{ - std::string worldpath = get_server(L)->getWorldPath(); - lua_pushstring(L, worldpath.c_str()); - return 1; -} - -// sound_play(spec, parameters) -static int l_sound_play(lua_State *L) -{ - SimpleSoundSpec spec; - read_soundspec(L, 1, spec); - ServerSoundParams params; - read_server_sound_params(L, 2, params); - s32 handle = get_server(L)->playSound(spec, params); - lua_pushinteger(L, handle); - return 1; -} - -// sound_stop(handle) -static int l_sound_stop(lua_State *L) -{ - int handle = luaL_checkinteger(L, 1); - get_server(L)->stopSound(handle); - return 0; -} - -// is_singleplayer() -static int l_is_singleplayer(lua_State *L) -{ - lua_pushboolean(L, get_server(L)->isSingleplayer()); - return 1; -} - -// get_password_hash(name, raw_password) -static int l_get_password_hash(lua_State *L) -{ - std::string name = luaL_checkstring(L, 1); - std::string raw_password = luaL_checkstring(L, 2); - std::string hash = translatePassword(name, - narrow_to_wide(raw_password)); - lua_pushstring(L, hash.c_str()); - return 1; -} - -// notify_authentication_modified(name) -static int l_notify_authentication_modified(lua_State *L) -{ - std::string name = ""; - if(lua_isstring(L, 1)) - name = lua_tostring(L, 1); - get_server(L)->reportPrivsModified(name); - return 0; -} - -// get_craft_result(input) -static int l_get_craft_result(lua_State *L) -{ - int input_i = 1; - std::string method_s = getstringfield_default(L, input_i, "method", "normal"); - enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method", - es_CraftMethod, CRAFT_METHOD_NORMAL); - int width = 1; - lua_getfield(L, input_i, "width"); - if(lua_isnumber(L, -1)) - width = luaL_checkinteger(L, -1); - lua_pop(L, 1); - lua_getfield(L, input_i, "items"); - std::vector items = read_items(L, -1); - lua_pop(L, 1); // items - - IGameDef *gdef = get_server(L); - ICraftDefManager *cdef = gdef->cdef(); - CraftInput input(method, width, items); - CraftOutput output; - bool got = cdef->getCraftResult(input, output, true, gdef); - lua_newtable(L); // output table - if(got){ - ItemStack item; - item.deSerialize(output.item, gdef->idef()); - LuaItemStack::create(L, item); - lua_setfield(L, -2, "item"); - setintfield(L, -1, "time", output.time); - } else { - LuaItemStack::create(L, ItemStack()); - lua_setfield(L, -2, "item"); - setintfield(L, -1, "time", 0); - } - lua_newtable(L); // decremented input table - lua_pushstring(L, method_s.c_str()); - lua_setfield(L, -2, "method"); - lua_pushinteger(L, width); - lua_setfield(L, -2, "width"); - push_items(L, input.items); - lua_setfield(L, -2, "items"); - return 2; -} - -// get_craft_recipe(result item) -static int l_get_craft_recipe(lua_State *L) -{ - int k = 0; - char tmp[20]; - int input_i = 1; - std::string o_item = luaL_checkstring(L,input_i); - - IGameDef *gdef = get_server(L); - ICraftDefManager *cdef = gdef->cdef(); - CraftInput input; - CraftOutput output(o_item,0); - bool got = cdef->getCraftRecipe(input, output, gdef); - lua_newtable(L); // output table - if(got){ - lua_newtable(L); - for(std::vector::const_iterator - i = input.items.begin(); - i != input.items.end(); i++, k++) - { - if (i->empty()) - { - continue; - } - sprintf(tmp,"%d",k); - lua_pushstring(L,tmp); - lua_pushstring(L,i->name.c_str()); - lua_settable(L, -3); - } - lua_setfield(L, -2, "items"); - setintfield(L, -1, "width", input.width); - switch (input.method) { - case CRAFT_METHOD_NORMAL: - lua_pushstring(L,"normal"); - break; - case CRAFT_METHOD_COOKING: - lua_pushstring(L,"cooking"); - break; - case CRAFT_METHOD_FUEL: - lua_pushstring(L,"fuel"); - break; - default: - lua_pushstring(L,"unknown"); - } - lua_setfield(L, -2, "type"); - } else { - lua_pushnil(L); - lua_setfield(L, -2, "items"); - setintfield(L, -1, "width", 0); - } - return 1; -} - -// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds -static int l_rollback_get_last_node_actor(lua_State *L) -{ - v3s16 p = read_v3s16(L, 1); - int range = luaL_checknumber(L, 2); - int seconds = luaL_checknumber(L, 3); - Server *server = get_server(L); - IRollbackManager *rollback = server->getRollbackManager(); - v3s16 act_p; - int act_seconds = 0; - std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds); - lua_pushstring(L, actor.c_str()); - push_v3s16(L, act_p); - lua_pushnumber(L, act_seconds); - return 3; -} - -// rollback_revert_actions_by(actor, seconds) -> bool, log messages -static int l_rollback_revert_actions_by(lua_State *L) -{ - std::string actor = luaL_checkstring(L, 1); - int seconds = luaL_checknumber(L, 2); - Server *server = get_server(L); - IRollbackManager *rollback = server->getRollbackManager(); - std::list actions = rollback->getRevertActions(actor, seconds); - std::list log; - bool success = server->rollbackRevertActions(actions, &log); - // Push boolean result - lua_pushboolean(L, success); - // Get the table insert function and push the log table - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int table_insert = lua_gettop(L); - lua_newtable(L); - int table = lua_gettop(L); - for(std::list::const_iterator i = log.begin(); - i != log.end(); i++) - { - lua_pushvalue(L, table_insert); - lua_pushvalue(L, table); - lua_pushstring(L, i->c_str()); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - } - lua_remove(L, -2); // Remove table - lua_remove(L, -2); // Remove insert - return 2; -} - -static const struct luaL_Reg minetest_f [] = { - {"debug", l_debug}, - {"log", l_log}, - {"request_shutdown", l_request_shutdown}, - {"get_server_status", l_get_server_status}, - {"register_item_raw", l_register_item_raw}, - {"register_alias_raw", l_register_alias_raw}, - {"register_craft", l_register_craft}, - {"register_biome", l_register_biome}, - {"register_biome_groups", l_register_biome_groups}, - {"setting_set", l_setting_set}, - {"setting_get", l_setting_get}, - {"setting_getbool", l_setting_getbool}, - {"setting_save",l_setting_save}, - {"chat_send_all", l_chat_send_all}, - {"chat_send_player", l_chat_send_player}, - {"get_player_privs", l_get_player_privs}, - {"get_ban_list", l_get_ban_list}, - {"get_ban_description", l_get_ban_description}, - {"ban_player", l_ban_player}, - {"unban_player_or_ip", l_unban_player_of_ip}, - {"get_inventory", l_get_inventory}, - {"create_detached_inventory_raw", l_create_detached_inventory_raw}, - {"show_formspec", l_show_formspec}, - {"get_dig_params", l_get_dig_params}, - {"get_hit_params", l_get_hit_params}, - {"get_current_modname", l_get_current_modname}, - {"get_modpath", l_get_modpath}, - {"get_modnames", l_get_modnames}, - {"get_worldpath", l_get_worldpath}, - {"sound_play", l_sound_play}, - {"sound_stop", l_sound_stop}, - {"is_singleplayer", l_is_singleplayer}, - {"get_password_hash", l_get_password_hash}, - {"notify_authentication_modified", l_notify_authentication_modified}, - {"get_craft_result", l_get_craft_result}, - {"get_craft_recipe", l_get_craft_recipe}, - {"rollback_get_last_node_actor", l_rollback_get_last_node_actor}, - {"rollback_revert_actions_by", l_rollback_revert_actions_by}, - {NULL, NULL} -}; - -/* - Main export function -*/ - -void scriptapi_export(lua_State *L, Server *server) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - verbosestream<<"scriptapi_export()"< trigger_contents; - lua_getfield(L, current_abm, "nodenames"); - if(lua_istable(L, -1)){ - int table = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TSTRING); - trigger_contents.insert(lua_tostring(L, -1)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } else if(lua_isstring(L, -1)){ - trigger_contents.insert(lua_tostring(L, -1)); - } - lua_pop(L, 1); - - std::set required_neighbors; - lua_getfield(L, current_abm, "neighbors"); - if(lua_istable(L, -1)){ - int table = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TSTRING); - required_neighbors.insert(lua_tostring(L, -1)); - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } else if(lua_isstring(L, -1)){ - required_neighbors.insert(lua_tostring(L, -1)); - } - lua_pop(L, 1); - - float trigger_interval = 10.0; - getfloatfield(L, current_abm, "interval", trigger_interval); - - int trigger_chance = 50; - getintfield(L, current_abm, "chance", trigger_chance); - - LuaABM *abm = new LuaABM(L, id, trigger_contents, - required_neighbors, trigger_interval, trigger_chance); - - env->addActiveBlockModifier(abm); - - // removes value, keeps key for next iteration - lua_pop(L, 1); - } - } - lua_pop(L, 1); -} - -#if 0 -// Dump stack top with the dump2 function -static void dump2(lua_State *L, const char *name) -{ - // Dump object (debug) - lua_getglobal(L, "dump2"); - luaL_checktype(L, -1, LUA_TFUNCTION); - lua_pushvalue(L, -2); // Get previous stack top as first parameter - lua_pushstring(L, name); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); -} -#endif - -/* - object_reference -*/ - -void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_add_object_reference: id="<getId()<getId()); // Push id - lua_pushvalue(L, object); // Copy object to top of stack - lua_settable(L, objectstable); -} - -void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_rm_object_reference: id="<getId()<getId()); // Push id - lua_gettable(L, objectstable); - // Set object reference to NULL - ObjectRef::set_null(L); - lua_pop(L, 1); // pop object - - // Set object_refs[id] = nil - lua_pushnumber(L, cobj->getId()); // Push id - lua_pushnil(L); - lua_settable(L, objectstable); -} - -/* - misc -*/ - -// What scriptapi_run_callbacks does with the return values of callbacks. -// Regardless of the mode, if only one callback is defined, -// its return value is the total return value. -// Modes only affect the case where 0 or >= 2 callbacks are defined. -enum RunCallbacksMode -{ - // Returns the return value of the first callback - // Returns nil if list of callbacks is empty - RUN_CALLBACKS_MODE_FIRST, - // Returns the return value of the last callback - // Returns nil if list of callbacks is empty - RUN_CALLBACKS_MODE_LAST, - // If any callback returns a false value, the first such is returned - // Otherwise, the first callback's return value (trueish) is returned - // Returns true if list of callbacks is empty - RUN_CALLBACKS_MODE_AND, - // Like above, but stops calling callbacks (short circuit) - // after seeing the first false value - RUN_CALLBACKS_MODE_AND_SC, - // If any callback returns a true value, the first such is returned - // Otherwise, the first callback's return value (falseish) is returned - // Returns false if list of callbacks is empty - RUN_CALLBACKS_MODE_OR, - // Like above, but stops calling callbacks (short circuit) - // after seeing the first true value - RUN_CALLBACKS_MODE_OR_SC, - // Note: "a true value" and "a false value" refer to values that - // are converted by lua_toboolean to true or false, respectively. -}; - -// Push the list of callbacks (a lua table). -// Then push nargs arguments. -// Then call this function, which -// - runs the callbacks -// - removes the table and arguments from the lua stack -// - pushes the return value, computed depending on mode -static void scriptapi_run_callbacks(lua_State *L, int nargs, - RunCallbacksMode mode) -{ - // Insert the return value into the lua stack, below the table - assert(lua_gettop(L) >= nargs + 1); - lua_pushnil(L); - lua_insert(L, -(nargs + 1) - 1); - // Stack now looks like this: - // ...
... - - int rv = lua_gettop(L) - nargs - 1; - int table = rv + 1; - int arg = table + 1; - - luaL_checktype(L, table, LUA_TTABLE); - - // Foreach - lua_pushnil(L); - bool first_loop = true; - while(lua_next(L, table) != 0){ - // key at index -2 and value at index -1 - luaL_checktype(L, -1, LUA_TFUNCTION); - // Call function - for(int i = 0; i < nargs; i++) - lua_pushvalue(L, arg+i); - if(lua_pcall(L, nargs, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - - // Move return value to designated space in stack - // Or pop it - if(first_loop){ - // Result of first callback is always moved - lua_replace(L, rv); - first_loop = false; - } else { - // Otherwise, what happens depends on the mode - if(mode == RUN_CALLBACKS_MODE_FIRST) - lua_pop(L, 1); - else if(mode == RUN_CALLBACKS_MODE_LAST) - lua_replace(L, rv); - else if(mode == RUN_CALLBACKS_MODE_AND || - mode == RUN_CALLBACKS_MODE_AND_SC){ - if((bool)lua_toboolean(L, rv) == true && - (bool)lua_toboolean(L, -1) == false) - lua_replace(L, rv); - else - lua_pop(L, 1); - } - else if(mode == RUN_CALLBACKS_MODE_OR || - mode == RUN_CALLBACKS_MODE_OR_SC){ - if((bool)lua_toboolean(L, rv) == false && - (bool)lua_toboolean(L, -1) == true) - lua_replace(L, rv); - else - lua_pop(L, 1); - } - else - assert(0); - } - - // Handle short circuit modes - if(mode == RUN_CALLBACKS_MODE_AND_SC && - (bool)lua_toboolean(L, rv) == false) - break; - else if(mode == RUN_CALLBACKS_MODE_OR_SC && - (bool)lua_toboolean(L, rv) == true) - break; - - // value removed, keep key for next iteration - } - - // Remove stuff from stack, leaving only the return value - lua_settop(L, rv); - - // Fix return value in case no callbacks were called - if(first_loop){ - if(mode == RUN_CALLBACKS_MODE_AND || - mode == RUN_CALLBACKS_MODE_AND_SC){ - lua_pop(L, 1); - lua_pushboolean(L, true); - } - else if(mode == RUN_CALLBACKS_MODE_OR || - mode == RUN_CALLBACKS_MODE_OR_SC){ - lua_pop(L, 1); - lua_pushboolean(L, false); - } - } -} - -bool scriptapi_on_chat_message(lua_State *L, const std::string &name, - const std::string &message) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_chat_messages - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_chat_messages"); - // Call callbacks - lua_pushstring(L, name.c_str()); - lua_pushstring(L, message.c_str()); - scriptapi_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC); - bool ate = lua_toboolean(L, -1); - return ate; -} - -void scriptapi_on_shutdown(lua_State *L) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get registered shutdown hooks - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_shutdown"); - // Call callbacks - scriptapi_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST); -} - -void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_newplayers - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_newplayers"); - // Call callbacks - objectref_get_or_create(L, player); - scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); -} - -void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_dieplayers - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_dieplayers"); - // Call callbacks - objectref_get_or_create(L, player); - scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); -} - -bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_respawnplayers - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_respawnplayers"); - // Call callbacks - objectref_get_or_create(L, player); - scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR); - bool positioning_handled_by_some = lua_toboolean(L, -1); - return positioning_handled_by_some; -} - -void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_joinplayers - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_joinplayers"); - // Call callbacks - objectref_get_or_create(L, player); - scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); -} - -void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Get minetest.registered_on_leaveplayers - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_leaveplayers"); - // Call callbacks - objectref_get_or_create(L, player); - scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); -} - -static void get_auth_handler(lua_State *L) -{ - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_auth_handler"); - if(lua_isnil(L, -1)){ - lua_pop(L, 1); - lua_getfield(L, -1, "builtin_auth_handler"); - } - if(lua_type(L, -1) != LUA_TTABLE) - throw LuaError(L, "Authentication handler table not valid"); -} - -bool scriptapi_get_auth(lua_State *L, const std::string &playername, - std::string *dst_password, std::set *dst_privs) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - get_auth_handler(L); - lua_getfield(L, -1, "get_auth"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing get_auth"); - lua_pushstring(L, playername.c_str()); - if(lua_pcall(L, 1, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - - // nil = login not allowed - if(lua_isnil(L, -1)) - return false; - luaL_checktype(L, -1, LUA_TTABLE); - - std::string password; - bool found = getstringfield(L, -1, "password", password); - if(!found) - throw LuaError(L, "Authentication handler didn't return password"); - if(dst_password) - *dst_password = password; - - lua_getfield(L, -1, "privileges"); - if(!lua_istable(L, -1)) - throw LuaError(L, - "Authentication handler didn't return privilege table"); - if(dst_privs) - read_privileges(L, -1, *dst_privs); - lua_pop(L, 1); - - return true; -} - -void scriptapi_create_auth(lua_State *L, const std::string &playername, - const std::string &password) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - get_auth_handler(L); - lua_getfield(L, -1, "create_auth"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing create_auth"); - lua_pushstring(L, playername.c_str()); - lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); -} - -bool scriptapi_set_password(lua_State *L, const std::string &playername, - const std::string &password) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - get_auth_handler(L); - lua_getfield(L, -1, "set_password"); - if(lua_type(L, -1) != LUA_TFUNCTION) - throw LuaError(L, "Authentication handler missing set_password"); - lua_pushstring(L, playername.c_str()); - lua_pushstring(L, password.c_str()); - if(lua_pcall(L, 2, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - return lua_toboolean(L, -1); -} - -/* - player -*/ - -void scriptapi_on_player_receive_fields(lua_State *L, - ServerActiveObject *player, - const std::string &formname, - const std::map &fields) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); + realitycheck(L); + assert(lua_checkstack(L, 20)); + StackUnroller stack_unroller(L); // Get minetest.registered_on_chat_messages lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_on_player_receive_fields"); + lua_getfield(L, -1, "registered_on_chat_messages"); // Call callbacks - // param 1 - objectref_get_or_create(L, player); - // param 2 - lua_pushstring(L, formname.c_str()); - // param 3 - lua_newtable(L); - for(std::map::const_iterator - i = fields.begin(); i != fields.end(); i++){ - const std::string &name = i->first; - const std::string &value = i->second; - lua_pushstring(L, name.c_str()); - lua_pushlstring(L, value.c_str(), value.size()); - lua_settable(L, -3); - } - scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC); -} - -/* - item callbacks and node callbacks -*/ - -// Retrieves minetest.registered_items[name][callbackname] -// If that is nil or on error, return false and stack is unchanged -// If that is a function, returns true and pushes the -// function onto the stack -// If minetest.registered_items[name] doesn't exist, minetest.nodedef_default -// is tried instead so unknown items can still be manipulated to some degree -static bool get_item_callback(lua_State *L, - const char *name, const char *callbackname) -{ - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_items"); - lua_remove(L, -2); - luaL_checktype(L, -1, LUA_TTABLE); - lua_getfield(L, -1, name); - lua_remove(L, -2); - // Should be a table - if(lua_type(L, -1) != LUA_TTABLE) - { - // Report error and clean up - errorstream<<"Item \""<ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch")) - return false; - - // Call function - push_v3s16(L, p); - pushnode(L, node, ndef); - objectref_get_or_create(L, puncher); - if(lua_pcall(L, 3, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - return true; + // Get registered shutdown hooks + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_shutdown"); + // Call callbacks + scriptapi_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST); } -bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node, - ServerActiveObject *digger) +void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig")) - return false; - - // Call function - push_v3s16(L, p); - pushnode(L, node, ndef); - objectref_get_or_create(L, digger); - if(lua_pcall(L, 3, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - return true; + // Get minetest.registered_on_newplayers + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_newplayers"); + // Call callbacks + objectref_get_or_create(L, player); + scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } -void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node) +void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_construct")) - return; - - // Call function - push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + // Get minetest.registered_on_dieplayers + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_dieplayers"); + // Call callbacks + objectref_get_or_create(L, player); + scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } -void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node) +bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_destruct")) - return; - - // Call function - push_v3s16(L, p); - if(lua_pcall(L, 1, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + // Get minetest.registered_on_respawnplayers + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_respawnplayers"); + // Call callbacks + objectref_get_or_create(L, player); + scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR); + bool positioning_handled_by_some = lua_toboolean(L, -1); + return positioning_handled_by_some; } -void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node) +void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "after_destruct")) - return; - - // Call function - push_v3s16(L, p); - pushnode(L, node, ndef); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + // Get minetest.registered_on_joinplayers + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_joinplayers"); + // Call callbacks + objectref_get_or_create(L, player); + scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } -bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime) +void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_timer")) - return false; - - // Call function - push_v3s16(L, p); - lua_pushnumber(L,dtime); - if(lua_pcall(L, 2, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true) - return true; - - return false; + // Get minetest.registered_on_leaveplayers + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_leaveplayers"); + // Call callbacks + objectref_get_or_create(L, player); + scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST); } -void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p, +/* + player +*/ +void scriptapi_on_player_receive_fields(lua_State *L, + ServerActiveObject *player, const std::string &formname, - const std::map &fields, - ServerActiveObject *sender) + const std::map &fields) { realitycheck(L); assert(lua_checkstack(L, 20)); StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) - return; - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_receive_fields")) - return; - - // Call function + // Get minetest.registered_on_chat_messages + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_player_receive_fields"); + // Call callbacks // param 1 - push_v3s16(L, p); + objectref_get_or_create(L, player); // param 2 lua_pushstring(L, formname.c_str()); // param 3 @@ -6422,784 +550,585 @@ void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p, lua_pushlstring(L, value.c_str(), value.size()); lua_settable(L, -3); } - // param 4 - objectref_get_or_create(L, sender); - if(lua_pcall(L, 4, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC); } +/*****************************************************************************/ +/* Api functions */ +/*****************************************************************************/ -/* - Node metadata inventory callbacks -*/ +// debug(text) +// Writes a line to dstream +static int l_debug(lua_State *L) +{ + std::string text = lua_tostring(L, 1); + dstream << text << std::endl; + return 0; +} -// Return number of accepted items to be moved -int scriptapi_nodemeta_inventory_allow_move(lua_State *L, v3s16 p, - const std::string &from_list, int from_index, - const std::string &to_list, int to_index, - int count, ServerActiveObject *player) +// log([level,] text) +// Writes a line to the logger. +// The one-argument version logs to infostream. +// The two-argument version accept a log level: error, action, info, or verbose. +static int l_log(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); + std::string text; + LogMessageLevel level = LMT_INFO; + if(lua_isnone(L, 2)) + { + text = lua_tostring(L, 1); + } + else + { + std::string levelname = luaL_checkstring(L, 1); + text = luaL_checkstring(L, 2); + if(levelname == "error") + level = LMT_ERROR; + else if(levelname == "action") + level = LMT_ACTION; + else if(levelname == "verbose") + level = LMT_VERBOSE; + } + log_printline(level, text); + return 0; +} + +// request_shutdown() +static int l_request_shutdown(lua_State *L) +{ + get_server(L)->requestShutdown(); + return 0; +} + +// get_server_status() +static int l_get_server_status(lua_State *L) +{ + lua_pushstring(L, wide_to_narrow(get_server(L)->getStatusString()).c_str()); + return 1; +} - INodeDefManager *ndef = get_server(L)->ndef(); +// register_biome_groups({frequencies}) +static int l_register_biome_groups(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + int index = 1; + if (!lua_istable(L, index)) + throw LuaError(L, "register_biome_groups: parameter is not a table"); - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) + BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); + if (!bmgr) { + verbosestream << "register_biome_groups: BiomeDefManager not active" << std::endl; return 0; + } - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "allow_metadata_inventory_move")) - return count; + lua_pushnil(L); + for (int i = 1; lua_next(L, index) != 0; i++) { + bmgr->addBiomeGroup(lua_tonumber(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); - // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 7, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_move should return a number"); - return luaL_checkinteger(L, -1); + return 0; } -// Return number of accepted items to be put -int scriptapi_nodemeta_inventory_allow_put(lua_State *L, v3s16 p, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// register_biome({lots of stuff}) +static int l_register_biome(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - INodeDefManager *ndef = get_server(L)->ndef(); + luaL_checktype(L, 1, LUA_TTABLE); + int index = 1, groupid; + std::string nodename; - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) + IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager(); + BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); + if (!bmgr) { + verbosestream << "register_biome: BiomeDefManager not active" << std::endl; return 0; + } - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "allow_metadata_inventory_put")) - return stack.count; + groupid = getintfield_default(L, index, "group_id", 0); - // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_put should return a number"); - return luaL_checkinteger(L, -1); + enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index, + "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL); + Biome *b = bmgr->createBiome(terrain); + + b->name = getstringfield_default(L, index, "name", ""); + + if (getstringfield(L, index, "node_top", nodename)) + b->n_top = MapNode(ndef->getId(nodename)); + else + b->n_top = MapNode(CONTENT_IGNORE); + + if (getstringfield(L, index, "node_filler", nodename)) + b->n_filler = MapNode(ndef->getId(nodename)); + else + b->n_filler = b->n_top; + + b->ntopnodes = getintfield_default(L, index, "num_top_nodes", 0); + + b->height_min = getintfield_default(L, index, "height_min", 0); + b->height_max = getintfield_default(L, index, "height_max", 0); + b->heat_min = getfloatfield_default(L, index, "heat_min", 0.); + b->heat_max = getfloatfield_default(L, index, "heat_max", 0.); + b->humidity_min = getfloatfield_default(L, index, "humidity_min", 0.); + b->humidity_max = getfloatfield_default(L, index, "humidity_max", 0.); + + b->np = new NoiseParams; // should read an entire NoiseParams later on... + getfloatfield(L, index, "scale", b->np->scale); + getfloatfield(L, index, "offset", b->np->offset); + + b->groupid = (s8)groupid; + b->flags = 0; //reserved + + bmgr->addBiome(b); + + verbosestream << "register_biome: " << b->name << std::endl; + return 0; } -// Return number of accepted items to be taken -int scriptapi_nodemeta_inventory_allow_take(lua_State *L, v3s16 p, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - INodeDefManager *ndef = get_server(L)->ndef(); - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) - return 0; +// setting_set(name, value) +static int l_setting_set(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + const char *value = luaL_checkstring(L, 2); + g_settings->set(name, value); + return 0; +} - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "allow_metadata_inventory_take")) - return stack.count; +// setting_get(name) +static int l_setting_get(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + try{ + std::string value = g_settings->get(name); + lua_pushstring(L, value.c_str()); + } catch(SettingNotFoundException &e){ + lua_pushnil(L); + } + return 1; +} - // Call function(pos, listname, index, count, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_metadata_inventory_take should return a number"); - return luaL_checkinteger(L, -1); +// setting_getbool(name) +static int l_setting_getbool(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + try{ + bool value = g_settings->getBool(name); + lua_pushboolean(L, value); + } catch(SettingNotFoundException &e){ + lua_pushnil(L); + } + return 1; } -// Report moved items -void scriptapi_nodemeta_inventory_on_move(lua_State *L, v3s16 p, - const std::string &from_list, int from_index, - const std::string &to_list, int to_index, - int count, ServerActiveObject *player) +// setting_save() +static int l_setting_save(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - INodeDefManager *ndef = get_server(L)->ndef(); - - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) - return; - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "on_metadata_inventory_move")) - return; - - // function(pos, from_list, from_index, to_list, to_index, count, player) - // pos - push_v3s16(L, p); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 7, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + get_server(L)->saveConfig(); + return 0; } -// Report put items -void scriptapi_nodemeta_inventory_on_put(lua_State *L, v3s16 p, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// chat_send_all(text) +static int l_chat_send_all(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - INodeDefManager *ndef = get_server(L)->ndef(); - - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) - return; - - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "on_metadata_inventory_put")) - return; - - // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + const char *text = luaL_checkstring(L, 1); + // Get server from registry + Server *server = get_server(L); + // Send + server->notifyPlayers(narrow_to_wide(text)); + return 0; } -// Report taken items -void scriptapi_nodemeta_inventory_on_take(lua_State *L, v3s16 p, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// chat_send_player(name, text) +static int l_chat_send_player(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - INodeDefManager *ndef = get_server(L)->ndef(); - - // If node doesn't exist, we don't know what callback to call - MapNode node = get_env(L)->getMap().getNodeNoEx(p); - if(node.getContent() == CONTENT_IGNORE) - return; + const char *name = luaL_checkstring(L, 1); + const char *text = luaL_checkstring(L, 2); + // Get server from registry + Server *server = get_server(L); + // Send + server->notifyPlayer(name, narrow_to_wide(text)); + return 0; +} - // Push callback function on stack - if(!get_item_callback(L, ndef->get(node).name.c_str(), - "on_metadata_inventory_take")) - return; +// get_player_privs(name, text) +static int l_get_player_privs(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + // Get server from registry + Server *server = get_server(L); + // Do it + lua_newtable(L); + int table = lua_gettop(L); + std::set privs_s = server->getPlayerEffectivePrivs(name); + for(std::set::const_iterator + i = privs_s.begin(); i != privs_s.end(); i++){ + lua_pushboolean(L, true); + lua_setfield(L, table, i->c_str()); + } + lua_pushvalue(L, table); + return 1; +} - // Call function(pos, listname, index, stack, player) - // pos - push_v3s16(L, p); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); +// get_ban_list() +static int l_get_ban_list(lua_State *L) +{ + lua_pushstring(L, get_server(L)->getBanDescription("").c_str()); + return 1; } -/* - Detached inventory callbacks -*/ +// get_ban_description() +static int l_get_ban_description(lua_State *L) +{ + const char * ip_or_name = luaL_checkstring(L, 1); + lua_pushstring(L, get_server(L)->getBanDescription(std::string(ip_or_name)).c_str()); + return 1; +} -// Retrieves minetest.detached_inventories[name][callbackname] -// If that is nil or on error, return false and stack is unchanged -// If that is a function, returns true and pushes the -// function onto the stack -static bool get_detached_inventory_callback(lua_State *L, - const std::string &name, const char *callbackname) +// ban_player() +static int l_ban_player(lua_State *L) { - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "detached_inventories"); - lua_remove(L, -2); - luaL_checktype(L, -1, LUA_TTABLE); - lua_getfield(L, -1, name.c_str()); - lua_remove(L, -2); - // Should be a table - if(lua_type(L, -1) != LUA_TTABLE) - { - errorstream<<"Item \""<getPlayer(name); + if(player == NULL) { - return true; + lua_pushboolean(L, false); // no such player + return 1; } - else if(lua_isnil(L, -1)) + try { - lua_pop(L, 1); - return false; + Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id); + std::string ip_str = addr.serializeString(); + get_server(L)->setIpBanned(ip_str, name); } - else + catch(con::PeerNotFoundException) // unlikely { - errorstream<<"Detached inventory \""<unsetIpBanned(ip_or_name); + lua_pushboolean(L, true); + return 1; } -// Return number of accepted items to be put -int scriptapi_detached_inventory_allow_put(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// show_formspec(playername,formname,formspec) +static int l_show_formspec(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "allow_put")) - return stack.count; // All will be accepted + const char *playername = luaL_checkstring(L, 1); + const char *formname = luaL_checkstring(L, 2); + const char *formspec = luaL_checkstring(L, 3); - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_put should return a number"); - return luaL_checkinteger(L, -1); + if(get_server(L)->showFormspec(playername,formspec,formname)) + { + lua_pushboolean(L, true); + }else{ + lua_pushboolean(L, false); + } + return 1; } -// Return number of accepted items to be taken -int scriptapi_detached_inventory_allow_take(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// get_dig_params(groups, tool_capabilities[, time_from_last_punch]) +static int l_get_dig_params(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "allow_take")) - return stack.count; // All will be accepted - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_take should return a number"); - return luaL_checkinteger(L, -1); + std::map groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); + if(lua_isnoneornil(L, 3)) + push_dig_params(L, getDigParams(groups, &tp)); + else + push_dig_params(L, getDigParams(groups, &tp, + luaL_checknumber(L, 3))); + return 1; } -// Report moved items -void scriptapi_detached_inventory_on_move(lua_State *L, - const std::string &name, - const std::string &from_list, int from_index, - const std::string &to_list, int to_index, - int count, ServerActiveObject *player) +// get_hit_params(groups, tool_capabilities[, time_from_last_punch]) +static int l_get_hit_params(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); + std::map groups; + read_groups(L, 1, groups); + ToolCapabilities tp = read_tool_capabilities(L, 2); + if(lua_isnoneornil(L, 3)) + push_hit_params(L, getHitParams(groups, &tp)); + else + push_hit_params(L, getHitParams(groups, &tp, + luaL_checknumber(L, 3))); + return 1; +} - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_move")) - return; +// get_current_modname() +static int l_get_current_modname(lua_State *L) +{ + lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname"); + return 1; +} - // function(inv, from_list, from_index, to_list, to_index, count, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 7, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); +// get_modpath(modname) +static int l_get_modpath(lua_State *L) +{ + std::string modname = luaL_checkstring(L, 1); + // Do it + if(modname == "__builtin"){ + std::string path = get_server(L)->getBuiltinLuaPath(); + lua_pushstring(L, path.c_str()); + return 1; + } + const ModSpec *mod = get_server(L)->getModSpec(modname); + if(!mod){ + lua_pushnil(L); + return 1; + } + lua_pushstring(L, mod->path.c_str()); + return 1; } -// Report put items -void scriptapi_detached_inventory_on_put(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// get_modnames() +// the returned list is sorted alphabetically for you +static int l_get_modnames(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); + // Get a list of mods + core::list mods_unsorted, mods_sorted; + get_server(L)->getModNames(mods_unsorted); - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_put")) - return; + // Take unsorted items from mods_unsorted and sort them into + // mods_sorted; not great performance but the number of mods on a + // server will likely be small. + for(core::list::Iterator i = mods_unsorted.begin(); + i != mods_unsorted.end(); i++) + { + bool added = false; + for(core::list::Iterator x = mods_sorted.begin(); + x != mods_unsorted.end(); x++) + { + // I doubt anybody using Minetest will be using + // anything not ASCII based :) + if((*i).compare(*x) <= 0) + { + mods_sorted.insert_before(x, *i); + added = true; + break; + } + } + if(!added) + mods_sorted.push_back(*i); + } - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + // Get the table insertion function from Lua. + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int insertion_func = lua_gettop(L); + + // Package them up for Lua + lua_newtable(L); + int new_table = lua_gettop(L); + core::list::Iterator i = mods_sorted.begin(); + while(i != mods_sorted.end()) + { + lua_pushvalue(L, insertion_func); + lua_pushvalue(L, new_table); + lua_pushstring(L, (*i).c_str()); + if(lua_pcall(L, 2, 0, 0) != 0) + { + script_error(L, "error: %s", lua_tostring(L, -1)); + } + i++; + } + return 1; } -// Report taken items -void scriptapi_detached_inventory_on_take(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) +// get_worldpath() +static int l_get_worldpath(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_take")) - return; - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); + std::string worldpath = get_server(L)->getWorldPath(); + lua_pushstring(L, worldpath.c_str()); + return 1; } -/* - environment -*/ - -void scriptapi_environment_step(lua_State *L, float dtime) +// sound_play(spec, parameters) +static int l_sound_play(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_environment_step"<playSound(spec, params); + lua_pushinteger(L, handle); + return 1; } -void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp, - u32 blockseed) +// sound_stop(handle) +static int l_sound_stop(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_environment_on_generated"<stopSound(handle); + return 0; } -/* - luaentity -*/ - -bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name) +// is_singleplayer() +static int l_is_singleplayer(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - verbosestream<<"scriptapi_luaentity_add: id="<isSingleplayer()); + return 1; } -void scriptapi_luaentity_activate(lua_State *L, u16 id, - const std::string &staticdata, u32 dtime_s) +// get_password_hash(name, raw_password) +static int l_get_password_hash(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - verbosestream<<"scriptapi_luaentity_activate: id="<reportPrivsModified(name); + return 0; } -std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id) +// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds +static int l_rollback_get_last_node_actor(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_luaentity_get_staticdata: id="<getRollbackManager(); + v3s16 act_p; + int act_seconds = 0; + std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds); + lua_pushstring(L, actor.c_str()); + push_v3s16(L, act_p); + lua_pushnumber(L, act_seconds); + return 3; } -void scriptapi_luaentity_get_properties(lua_State *L, u16 id, - ObjectProperties *prop) +// rollback_revert_actions_by(actor, seconds) -> bool, log messages +static int l_rollback_revert_actions_by(lua_State *L) { - realitycheck(L); - assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_luaentity_get_properties: id="<hp_max = 10; - - /* Read stuff */ - - prop->hp_max = getintfield_default(L, -1, "hp_max", 10); - - getboolfield(L, -1, "physical", prop->physical); - - getfloatfield(L, -1, "weight", prop->weight); - - lua_getfield(L, -1, "collisionbox"); - if(lua_istable(L, -1)) - prop->collisionbox = read_aabb3f(L, -1, 1.0); - lua_pop(L, 1); - - getstringfield(L, -1, "visual", prop->visual); + std::string actor = luaL_checkstring(L, 1); + int seconds = luaL_checknumber(L, 2); + Server *server = get_server(L); + IRollbackManager *rollback = server->getRollbackManager(); + std::list actions = rollback->getRevertActions(actor, seconds); + std::list log; + bool success = server->rollbackRevertActions(actions, &log); + // Push boolean result + lua_pushboolean(L, success); + // Get the table insert function and push the log table + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + lua_newtable(L); + int table = lua_gettop(L); + for(std::list::const_iterator i = log.begin(); + i != log.end(); i++) + { + lua_pushvalue(L, table_insert); + lua_pushvalue(L, table); + lua_pushstring(L, i->c_str()); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); + } + lua_remove(L, -2); // Remove table + lua_remove(L, -2); // Remove insert + return 2; +} - getstringfield(L, -1, "mesh", prop->mesh); +static const struct luaL_Reg minetest_f [] = { + {"debug", l_debug}, + {"log", l_log}, + {"request_shutdown", l_request_shutdown}, + {"get_server_status", l_get_server_status}, + {"register_item_raw", l_register_item_raw}, + {"register_alias_raw", l_register_alias_raw}, + {"register_craft", l_register_craft}, + {"register_biome", l_register_biome}, + {"register_biome_groups", l_register_biome_groups}, + {"setting_set", l_setting_set}, + {"setting_get", l_setting_get}, + {"setting_getbool", l_setting_getbool}, + {"setting_save",l_setting_save}, + {"chat_send_all", l_chat_send_all}, + {"chat_send_player", l_chat_send_player}, + {"get_player_privs", l_get_player_privs}, + {"get_ban_list", l_get_ban_list}, + {"get_ban_description", l_get_ban_description}, + {"ban_player", l_ban_player}, + {"unban_player_or_ip", l_unban_player_of_ip}, + {"get_inventory", l_get_inventory}, + {"create_detached_inventory_raw", l_create_detached_inventory_raw}, + {"show_formspec", l_show_formspec}, + {"get_dig_params", l_get_dig_params}, + {"get_hit_params", l_get_hit_params}, + {"get_current_modname", l_get_current_modname}, + {"get_modpath", l_get_modpath}, + {"get_modnames", l_get_modnames}, + {"get_worldpath", l_get_worldpath}, + {"sound_play", l_sound_play}, + {"sound_stop", l_sound_stop}, + {"is_singleplayer", l_is_singleplayer}, + {"get_password_hash", l_get_password_hash}, + {"notify_authentication_modified", l_notify_authentication_modified}, + {"get_craft_result", l_get_craft_result}, + {"get_craft_recipe", l_get_craft_recipe}, + {"rollback_get_last_node_actor", l_rollback_get_last_node_actor}, + {"rollback_revert_actions_by", l_rollback_revert_actions_by}, + {NULL, NULL} +}; - // Deprecated: read object properties directly - read_object_properties(L, -1, prop); - // Read initial_properties - lua_getfield(L, -1, "initial_properties"); - read_object_properties(L, -1, prop); - lua_pop(L, 1); -} +/* + Main export function +*/ -void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime) +void scriptapi_export(lua_State *L, Server *server) { realitycheck(L); assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_luaentity_step: id="< Date: Mon, 4 Mar 2013 01:55:16 +0100 Subject: Added method to get all registered recipes for item(node) --- doc/lua_api.txt | 5 ++++ src/craftdef.cpp | 37 ++++++++++++++++++++++++++++ src/craftdef.h | 4 +++ src/scriptapi.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) (limited to 'src/scriptapi.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 8246377e2..809d3d9d0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -922,12 +922,17 @@ minetest.get_craft_result(input) -> output, decremented_input ^ output.time = number, if unsuccessful: 0 ^ decremented_input = like input minetest.get_craft_recipe(output) -> input +^ returns last registered recipe for output item (node) ^ output is a node or item type such as 'default:torch' ^ input.method = 'normal' or 'cooking' or 'fuel' ^ input.width = for example 3 ^ input.items = for example { stack 1, stack 2, stack 3, stack 4, stack 5, stack 6, stack 7, stack 8, stack 9 } ^ input.items = nil if no recipe found +minetest.get_all_craft_recipes(output) -> table or nil +^ returns table with all registered recipes for output item (node) +^ returns nil if no recipe was found +^ table entries have same format as minetest.get_craft_recipe minetest.handle_node_drops(pos, drops, digger) ^ drops: list of itemstrings ^ Handles drops from nodes after digging: Default action is to put them into diff --git a/src/craftdef.cpp b/src/craftdef.cpp index 99e3fcc3d..c79408f99 100644 --- a/src/craftdef.cpp +++ b/src/craftdef.cpp @@ -987,6 +987,43 @@ public: } return false; } + virtual std::vector getCraftRecipes(CraftOutput &output, + IGameDef *gamedef) const + { + std::vector recipes_list; + CraftInput input; + CraftOutput tmpout; + tmpout.item = ""; + tmpout.time = 0; + + for(std::vector::const_reverse_iterator + i = m_craft_definitions.rbegin(); + i != m_craft_definitions.rend(); i++) + { + CraftDefinition *def = *i; + + /*infostream<<"Checking "<dump()<getOutput(input, gamedef); + if(tmpout.item.substr(0,output.item.length()) == output.item) + { + // Get output, then decrement input (if requested) + input = def->getInput(output, gamedef); + recipes_list.push_back(*i); + } + } + catch(SerializationError &e) + { + errorstream<<"getCraftResult: ERROR: " + <<"Serialization error in recipe " + <dump()< getCraftRecipes(CraftOutput &output, + IGameDef *gamedef) const=0; // Print crafting recipes for debugging virtual std::string dump() const=0; @@ -376,6 +378,8 @@ public: bool decrementInput, IGameDef *gamedef) const=0; virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output, IGameDef *gamedef) const=0; + virtual std::vector getCraftRecipes(CraftOutput &output, + IGameDef *gamedef) const=0; // Print crafting recipes for debugging virtual std::string dump() const=0; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index ef8a1454a..074a2eb0d 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -1000,6 +1000,79 @@ static int l_notify_authentication_modified(lua_State *L) return 0; } +// get_craft_recipes(result item) +static int l_get_all_craft_recipes(lua_State *L) +{ + char tmp[20]; + int input_i = 1; + std::string o_item = luaL_checkstring(L,input_i); + IGameDef *gdef = get_server(L); + ICraftDefManager *cdef = gdef->cdef(); + CraftInput input; + CraftOutput output(o_item,0); + std::vector recipes_list = cdef->getCraftRecipes(output, gdef); + if (recipes_list.empty()) + { + lua_pushnil(L); + return 1; + } + // Get the table insert function + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + lua_newtable(L); + int table = lua_gettop(L); + for(std::vector::const_iterator + i = recipes_list.begin(); + i != recipes_list.end(); i++) + { + CraftOutput tmpout; + tmpout.item = ""; + tmpout.time = 0; + CraftDefinition *def = *i; + tmpout = def->getOutput(input, gdef); + if(tmpout.item.substr(0,output.item.length()) == output.item) + { + input = def->getInput(output, gdef); + lua_pushvalue(L, table_insert); + lua_pushvalue(L, table); + lua_newtable(L); + int k = 0; + lua_newtable(L); + for(std::vector::const_iterator + i = input.items.begin(); + i != input.items.end(); i++, k++) + { + if (i->empty()) continue; + sprintf(tmp,"%d",k); + lua_pushstring(L,tmp); + lua_pushstring(L,i->name.c_str()); + lua_settable(L, -3); + } + lua_setfield(L, -2, "items"); + setintfield(L, -1, "width", input.width); + switch (input.method) + { + case CRAFT_METHOD_NORMAL: + lua_pushstring(L,"normal"); + break; + case CRAFT_METHOD_COOKING: + lua_pushstring(L,"cooking"); + break; + case CRAFT_METHOD_FUEL: + lua_pushstring(L,"fuel"); + break; + default: + lua_pushstring(L,"unknown"); + } + lua_setfield(L, -2, "type"); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); + } + } + return 1; +} + // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds static int l_rollback_get_last_node_actor(lua_State *L) { @@ -1086,6 +1159,7 @@ static const struct luaL_Reg minetest_f [] = { {"notify_authentication_modified", l_notify_authentication_modified}, {"get_craft_result", l_get_craft_result}, {"get_craft_recipe", l_get_craft_recipe}, + {"get_all_craft_recipes", l_get_all_craft_recipes}, {"rollback_get_last_node_actor", l_rollback_get_last_node_actor}, {"rollback_revert_actions_by", l_rollback_revert_actions_by}, {NULL, NULL} -- cgit v1.2.3 From 6a1670dbc31cc0e44178bbd9ad34ff0d5981a060 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Thu, 20 Dec 2012 21:19:49 +0400 Subject: Migrate to STL containers/algorithms. --- src/chat.cpp | 20 +-- src/chat.h | 14 +- src/client.cpp | 102 ++++++------ src/client.h | 15 +- src/clientmap.cpp | 55 +++---- src/clientmap.h | 8 +- src/clientobject.cpp | 12 +- src/clientobject.h | 5 +- src/connection.cpp | 254 +++++++++++++++--------------- src/connection.h | 23 +-- src/content_abm.cpp | 21 +-- src/content_cao.cpp | 2 +- src/content_mapblock.cpp | 12 +- src/content_sao.cpp | 2 +- src/debug.cpp | 29 ++-- src/debug.h | 29 ++-- src/emerge.cpp | 12 +- src/environment.cpp | 398 +++++++++++++++++++++++------------------------ src/environment.h | 35 +++-- src/farmesh.cpp | 8 +- src/game.h | 25 +-- src/guiChatConsole.cpp | 2 +- src/guiFormSpecMenu.h | 10 +- src/itemdef.cpp | 6 +- src/keycode.cpp | 13 +- src/localplayer.cpp | 2 +- src/localplayer.h | 3 +- src/main.cpp | 104 ++++++------- src/mainmenumanager.h | 15 +- src/map.cpp | 314 +++++++++++++++++-------------------- src/map.h | 92 +++++------ src/mapblock.cpp | 4 +- src/mapblock.h | 3 +- src/mapblock_mesh.cpp | 12 +- src/mapblock_mesh.h | 6 +- src/mapgen.cpp | 4 +- src/mapgen_v6.cpp | 4 +- src/mapsector.cpp | 41 +++-- src/mapsector.h | 8 +- src/mods.h | 4 +- src/object_properties.h | 5 +- src/profiler.h | 63 ++++---- src/scriptapi.cpp | 16 +- src/scriptapi_env.cpp | 6 +- src/server.cpp | 394 +++++++++++++++++++++++----------------------- src/server.h | 27 ++-- src/serverobject.cpp | 12 +- src/serverobject.h | 2 +- src/settings.h | 113 ++++++-------- src/shader.cpp | 36 ++--- src/staticobject.cpp | 12 +- src/staticobject.h | 14 +- src/test.cpp | 43 ++--- src/tile.cpp | 78 +++++----- src/treegen.cpp | 20 +-- src/util/container.h | 88 ++++++----- src/util/numeric.cpp | 2 +- src/util/numeric.h | 3 +- src/util/thread.h | 16 +- src/voxel.cpp | 37 ++--- src/voxel.h | 12 +- src/voxelalgorithms.cpp | 12 +- src/voxelalgorithms.h | 8 +- 63 files changed, 1330 insertions(+), 1417 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/chat.cpp b/src/chat.cpp index c3509ae49..1135ccdf7 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -117,8 +117,8 @@ void ChatBuffer::deleteOldest(u32 count) --count; } - m_unformatted.erase(0, del_unformatted); - m_formatted.erase(0, del_formatted); + m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted); + m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted); } void ChatBuffer::deleteByAge(f32 maxAge) @@ -232,10 +232,10 @@ void ChatBuffer::scrollTop() } u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, - core::array& destination) const + std::vector& destination) const { u32 num_added = 0; - core::array next_frags; + std::vector next_frags; ChatFormattedLine next_line; ChatFormattedFragment temp_frag; u32 out_column = 0; @@ -292,7 +292,7 @@ u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, frag.column = out_column; next_line.fragments.push_back(frag); out_column += frag.text.size(); - next_frags.erase(0, 1); + next_frags.erase(next_frags.begin()); } else { @@ -414,7 +414,7 @@ std::wstring ChatPrompt::submit() if (!line.empty()) m_history.push_back(line); if (m_history.size() > m_history_limit) - m_history.erase(0); + m_history.erase(m_history.begin()); m_history_index = m_history.size(); m_view = 0; m_cursor = 0; @@ -464,7 +464,7 @@ void ChatPrompt::historyNext() } } -void ChatPrompt::nickCompletion(const core::list& names, bool backwards) +void ChatPrompt::nickCompletion(const std::list& names, bool backwards) { // Two cases: // (a) m_nick_completion_start == m_nick_completion_end == 0 @@ -492,10 +492,10 @@ void ChatPrompt::nickCompletion(const core::list& names, bool back std::wstring prefix = m_line.substr(prefix_start, prefix_end - prefix_start); // find all names that start with the selected prefix - core::array completions; - for (core::list::ConstIterator + std::vector completions; + for (std::list::const_iterator i = names.begin(); - i != names.end(); i++) + i != names.end(); ++i) { if (str_starts_with(*i, prefix, true)) { diff --git a/src/chat.h b/src/chat.h index 27863922c..8a40c7ccf 100644 --- a/src/chat.h +++ b/src/chat.h @@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include +#include +#include // Chat console related classes, only used by the client @@ -55,7 +57,7 @@ struct ChatFormattedFragment struct ChatFormattedLine { // Array of text fragments - core::array fragments; + std::vector fragments; // true if first line of one formatted ChatLine bool first; }; @@ -110,7 +112,7 @@ public: // Appends the formatted lines to the destination array and // returns the number of formatted lines. u32 formatChatLine(const ChatLine& line, u32 cols, - core::array& destination) const; + std::vector& destination) const; protected: s32 getTopScrollPos() const; @@ -120,7 +122,7 @@ private: // Scrollback size u32 m_scrollback; // Array of unformatted chat lines - core::array m_unformatted; + std::vector m_unformatted; // Number of character columns in console u32 m_cols; @@ -129,7 +131,7 @@ private: // Scroll position (console's top line index into m_formatted) s32 m_scroll; // Array of formatted lines - core::array m_formatted; + std::vector m_formatted; // Empty formatted line, for error returns ChatFormattedLine m_empty_formatted_line; }; @@ -158,7 +160,7 @@ public: void historyNext(); // Nick completion - void nickCompletion(const core::list& names, bool backwards); + void nickCompletion(const std::list& names, bool backwards); // Update console size and reformat the visible portion of the prompt void reformat(u32 cols); @@ -209,7 +211,7 @@ private: // Currently edited line std::wstring m_line; // History buffer - core::array m_history; + std::vector m_history; // History index (0 <= m_history_index <= m_history.size()) u32 m_history_index; // Maximum number of history entries diff --git a/src/client.cpp b/src/client.cpp index be35db5de..2ccace842 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -232,8 +232,8 @@ void * MediaFetchThread::Thread() #if USE_CURL CURL *curl; CURLcode res; - for (core::list::Iterator i = m_file_requests.begin(); - i != m_file_requests.end(); i++) { + for (std::list::iterator i = m_file_requests.begin(); + i != m_file_requests.end(); ++i) { curl = curl_easy_init(); assert(curl); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); @@ -360,8 +360,8 @@ Client::~Client() } } - for (core::list::Iterator i = m_media_fetch_threads.begin(); - i != m_media_fetch_threads.end(); i++) + for (std::list::iterator i = m_media_fetch_threads.begin(); + i != m_media_fetch_threads.end(); ++i) delete *i; } @@ -585,7 +585,7 @@ void Client::step(float dtime) if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) { ScopeProfiler sp(g_profiler, "Client: map timer and unload"); - core::list deleted_blocks; + std::list deleted_blocks; m_env.getMap().timerUpdate(map_timer_and_unload_dtime, g_settings->getFloat("client_unload_unused_data_timeout"), &deleted_blocks); @@ -599,8 +599,8 @@ void Client::step(float dtime) NOTE: This loop is intentionally iterated the way it is. */ - core::list::Iterator i = deleted_blocks.begin(); - core::list sendlist; + std::list::iterator i = deleted_blocks.begin(); + std::list sendlist; for(;;) { if(sendlist.size() == 255 || i == deleted_blocks.end()) @@ -619,9 +619,9 @@ void Client::step(float dtime) writeU16(&reply[0], TOSERVER_DELETEDBLOCKS); reply[2] = sendlist.size(); u32 k = 0; - for(core::list::Iterator + for(std::list::iterator j = sendlist.begin(); - j != sendlist.end(); j++) + j != sendlist.end(); ++j) { writeV3S16(&reply[2+1+6*k], *j); k++; @@ -635,7 +635,7 @@ void Client::step(float dtime) } sendlist.push_back(*i); - i++; + ++i; } } @@ -727,7 +727,7 @@ void Client::step(float dtime) < 0) + while(!m_mesh_update_thread.m_queue_out.empty()) { num_processed_meshes++; MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_front(); @@ -779,10 +779,10 @@ void Client::step(float dtime) */ if (m_media_receive_started) { bool all_stopped = true; - for (core::list::Iterator thread = m_media_fetch_threads.begin(); - thread != m_media_fetch_threads.end(); thread++) { + for (std::list::iterator thread = m_media_fetch_threads.begin(); + thread != m_media_fetch_threads.end(); ++thread) { all_stopped &= !(*thread)->IsRunning(); - while ((*thread)->m_file_data.size() > 0) { + while (!(*thread)->m_file_data.empty()) { std::pair out = (*thread)->m_file_data.pop_front(); ++m_media_received_count; @@ -803,9 +803,9 @@ void Client::step(float dtime) } { - core::map::Node *n; + std::map::iterator n; n = m_media_name_sha1_map.find(out.first); - if(n == NULL) + if(n == m_media_name_sha1_map.end()) errorstream<<"The server sent a file that has not " <<"been announced."< fetch_failed; - for (core::list::Iterator thread = m_media_fetch_threads.begin(); - thread != m_media_fetch_threads.end(); thread++) { - for (core::list::Iterator request = (*thread)->m_failed.begin(); - request != (*thread)->m_failed.end(); request++) + std::list fetch_failed; + for (std::list::iterator thread = m_media_fetch_threads.begin(); + thread != m_media_fetch_threads.end(); ++thread) { + for (std::list::iterator request = (*thread)->m_failed.begin(); + request != (*thread)->m_failed.end(); ++request) fetch_failed.push_back(*request); (*thread)->m_failed.clear(); } @@ -1015,14 +1015,14 @@ void Client::deletingPeer(con::Peer *peer, bool timeout) string name } */ -void Client::request_media(const core::list &file_requests) +void Client::request_media(const std::list &file_requests) { std::ostringstream os(std::ios_base::binary); writeU16(os, TOSERVER_REQUEST_MEDIA); writeU16(os, file_requests.size()); - for(core::list::ConstIterator i = file_requests.begin(); - i != file_requests.end(); i++) { + for(std::list::const_iterator i = file_requests.begin(); + i != file_requests.end(); ++i) { os<name); } @@ -1622,7 +1622,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) infostream<<"Client: Received media announcement: packet size: " < file_requests; + std::list file_requests; for(int i=0; i::Iterator cur = m_media_fetch_threads.begin(); - for(core::list::Iterator i = file_requests.begin(); - i != file_requests.end(); i++) { + std::list::iterator cur = m_media_fetch_threads.begin(); + for(std::list::iterator i = file_requests.begin(); + i != file_requests.end(); ++i) { (*cur)->m_file_requests.push_back(*i); cur++; if (cur == m_media_fetch_threads.end()) cur = m_media_fetch_threads.begin(); } - for (core::list::Iterator i = m_media_fetch_threads.begin(); - i != m_media_fetch_threads.end(); i++) { + for (std::list::iterator i = m_media_fetch_threads.begin(); + i != m_media_fetch_threads.end(); ++i) { (*i)->m_remote_url = remote_media; (*i)->Start(); } @@ -1762,9 +1762,9 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) } { - core::map::Node *n; + std::map::iterator n; n = m_media_name_sha1_map.find(name); - if(n == NULL) + if(n == m_media_name_sha1_map.end()) errorstream<<"The server sent a file that has not " <<"been announced."< modified_blocks; + std::map modified_blocks; try { @@ -2245,12 +2245,11 @@ void Client::removeNode(v3s16 p) // add urgent task to update the modified node addUpdateMeshTaskForNode(p, false, true); - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - addUpdateMeshTaskWithEdge(p); + addUpdateMeshTaskWithEdge(i->first); } } @@ -2258,7 +2257,7 @@ void Client::addNode(v3s16 p, MapNode n) { TimeTaker timer1("Client::addNode()"); - core::map modified_blocks; + std::map modified_blocks; try { @@ -2268,12 +2267,11 @@ void Client::addNode(v3s16 p, MapNode n) catch(InvalidPositionException &e) {} - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - addUpdateMeshTaskWithEdge(p); + addUpdateMeshTaskWithEdge(i->first); } } @@ -2373,7 +2371,7 @@ ClientActiveObject * Client::getSelectedActiveObject( core::line3d shootline_on_map ) { - core::array objects; + std::vector objects; m_env.getActiveObjects(from_pos_f_on_map, max_d, objects); @@ -2381,7 +2379,7 @@ ClientActiveObject * Client::getSelectedActiveObject( // Sort them. // After this, the closest object is the first in the array. - objects.sort(); + std::sort(objects.begin(), objects.end()); for(u32 i=0; i Client::getConnectedPlayerNames() +std::list Client::getConnectedPlayerNames() { - core::list players = m_env.getPlayers(true); - core::list playerNames; - for(core::list::Iterator + std::list players = m_env.getPlayers(true); + std::list playerNames; + for(std::list::iterator i = players.begin(); - i != players.end(); i++) + i != players.end(); ++i) { Player *player = *i; playerNames.push_back(narrow_to_wide(player->getName())); diff --git a/src/client.h b/src/client.h index 809e98b81..570a6b3b0 100644 --- a/src/client.h +++ b/src/client.h @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server.h" #include "particles.h" #include "util/pointedthing.h" +#include struct MeshMakeData; class MapBlockMesh; @@ -142,9 +143,9 @@ public: void * Thread(); - core::list m_file_requests; + std::list m_file_requests; MutexedQueue > m_file_data; - core::list m_failed; + std::list m_failed; std::string m_remote_url; IGameDef *m_gamedef; }; @@ -282,7 +283,7 @@ public: // Prints a line or two of info void printDebugInfo(std::ostream &os); - core::list getConnectedPlayerNames(); + std::list getConnectedPlayerNames(); float getAnimationTime(); @@ -347,7 +348,7 @@ private: // Insert a media file appropriately into the appropriate manager bool loadMedia(const std::string &data, const std::string &filename); - void request_media(const core::list &file_requests); + void request_media(const std::list &file_requests); // Virtual methods from con::PeerHandler void peerAdded(con::Peer *peer); @@ -377,7 +378,7 @@ private: MtEventManager *m_event; MeshUpdateThread m_mesh_update_thread; - core::list m_media_fetch_threads; + std::list m_media_fetch_threads; ClientEnvironment m_env; con::Connection m_con; IrrlichtDevice *m_device; @@ -387,7 +388,7 @@ private: bool m_inventory_updated; Inventory *m_inventory_from_server; float m_inventory_from_server_age; - core::map m_active_blocks; + std::set m_active_blocks; PacketCounter m_packetcounter; // Block mesh animation parameters float m_animation_time; @@ -405,7 +406,7 @@ private: Queue m_client_event_queue; FileCache m_media_cache; // Mapping from media file name to SHA1 checksum - core::map m_media_name_sha1_map; + std::map m_media_name_sha1_map; bool m_media_receive_started; u32 m_media_count; u32 m_media_received_count; diff --git a/src/clientmap.cpp b/src/clientmap.cpp index aa92dfdee..c08068367 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "profiler.h" #include "settings.h" #include "util/mathconstants.h" +#include #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -83,7 +84,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d) { //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out - m_sectors.insert(p2d, sector); + m_sectors[p2d] = sector; } return sector; @@ -164,11 +165,11 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) INodeDefManager *nodemgr = m_gamedef->ndef(); - for(core::map::Iterator - i = m_drawlist.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_drawlist.begin(); + i != m_drawlist.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); + MapBlock *block = i->second; block->refDrop(); } m_drawlist.clear(); @@ -215,11 +216,11 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) // Blocks from which stuff was actually drawn //u32 blocks_without_stuff = 0; - for(core::map::Iterator - si = m_sectors.getIterator(); - si.atEnd() == false; si++) + for(std::map::iterator + si = m_sectors.begin(); + si != m_sectors.end(); ++si) { - MapSector *sector = si.getNode()->getValue(); + MapSector *sector = si->second; v2s16 sp = sector->getPos(); if(m_control.range_all == false) @@ -231,7 +232,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) continue; } - core::list< MapBlock * > sectorblocks; + std::list< MapBlock * > sectorblocks; sector->getBlocks(sectorblocks); /* @@ -240,7 +241,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) u32 sector_blocks_drawn = 0; - core::list< MapBlock * >::Iterator i; + std::list< MapBlock * >::iterator i; for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++) { MapBlock *block = *i; @@ -350,7 +351,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) } // foreach sectorblocks if(sector_blocks_drawn != 0) - m_last_drawn_sectors[sp] = true; + m_last_drawn_sectors.insert(sp); } m_control.blocks_would_have_drawn = blocks_would_have_drawn; @@ -368,12 +369,12 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) struct MeshBufList { video::SMaterial m; - core::list bufs; + std::list bufs; }; struct MeshBufListList { - core::list lists; + std::list lists; void clear() { @@ -382,8 +383,8 @@ struct MeshBufListList void add(scene::IMeshBuffer *buf) { - for(core::list::Iterator i = lists.begin(); - i != lists.end(); i++){ + for(std::list::iterator i = lists.begin(); + i != lists.end(); ++i){ MeshBufList &l = *i; if(l.m == buf->getMaterial()){ l.bufs.push_back(buf); @@ -487,11 +488,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) MeshBufListList drawbufs; - for(core::map::Iterator - i = m_drawlist.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_drawlist.begin(); + i != m_drawlist.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); + MapBlock *block = i->second; // If the mesh of the block happened to get deleted, ignore it if(block->mesh == NULL) @@ -569,11 +570,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) } } - core::list &lists = drawbufs.lists; + std::list &lists = drawbufs.lists; int timecheck_counter = 0; - for(core::list::Iterator i = lists.begin(); - i != lists.end(); i++) + for(std::list::iterator i = lists.begin(); + i != lists.end(); ++i) { { timecheck_counter++; @@ -595,8 +596,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) driver->setMaterial(list.m); - for(core::list::Iterator j = list.bufs.begin(); - j != list.bufs.end(); j++) + for(std::list::iterator j = list.bufs.begin(); + j != list.bufs.end(); ++j) { scene::IMeshBuffer *buf = *j; driver->drawMeshBuffer(buf); @@ -769,7 +770,7 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor, float sunlight_min_d = max_d*0.8; if(sunlight_min_d > 35*BS) sunlight_min_d = 35*BS; - core::array values; + std::vector values; for(u32 i=0; i= 10) num_values_to_use -= num_values_to_use/2; diff --git a/src/clientmap.h b/src/clientmap.h index 786f35b77..7f63704d3 100644 --- a/src/clientmap.h +++ b/src/clientmap.h @@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "map.h" +#include +#include struct MapDrawControl { @@ -128,7 +130,7 @@ public: // Check if sector was drawn on last render() bool sectorWasDrawn(v2s16 p) { - return (m_last_drawn_sectors.find(p) != NULL); + return (m_last_drawn_sectors.find(p) != m_last_drawn_sectors.end()); } private: @@ -143,9 +145,9 @@ private: f32 m_camera_fov; JMutex m_camera_mutex; - core::map m_drawlist; + std::map m_drawlist; - core::map m_last_drawn_sectors; + std::set m_last_drawn_sectors; }; #endif diff --git a/src/clientobject.cpp b/src/clientobject.cpp index e7c735dac..37f693c5e 100644 --- a/src/clientobject.cpp +++ b/src/clientobject.cpp @@ -43,9 +43,9 @@ ClientActiveObject* ClientActiveObject::create(u8 type, IGameDef *gamedef, ClientEnvironment *env) { // Find factory function - core::map::Node *n; + std::map::iterator n; n = m_types.find(type); - if(n == NULL) + if(n == m_types.end()) { // If factory is not found, just return. dstream<<"WARNING: ClientActiveObject: No factory for type=" @@ -53,18 +53,18 @@ ClientActiveObject* ClientActiveObject::create(u8 type, IGameDef *gamedef, return NULL; } - Factory f = n->getValue(); + Factory f = n->second; ClientActiveObject *object = (*f)(gamedef, env); return object; } void ClientActiveObject::registerType(u16 type, Factory f) { - core::map::Node *n; + std::map::iterator n; n = m_types.find(type); - if(n) + if(n != m_types.end()) return; - m_types.insert(type, f); + m_types[type] = f; } diff --git a/src/clientobject.h b/src/clientobject.h index d1ee366cf..8cbf3d60b 100644 --- a/src/clientobject.h +++ b/src/clientobject.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "activeobject.h" +#include /* @@ -96,7 +97,7 @@ protected: ClientEnvironment *m_env; private: // Used for creating objects based on type - static core::map m_types; + static std::map m_types; }; struct DistanceSortedActiveObject @@ -110,7 +111,7 @@ struct DistanceSortedActiveObject d = a_d; } - bool operator < (DistanceSortedActiveObject &other) + bool operator < (const DistanceSortedActiveObject &other) const { return d < other.d; } diff --git a/src/connection.cpp b/src/connection.cpp index 7a3018bfd..7bff5b113 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -76,19 +76,20 @@ SharedBuffer makeOriginalPacket( return b; } -core::list > makeSplitPacket( +std::list > makeSplitPacket( SharedBuffer data, u32 chunksize_max, u16 seqnum) { // Chunk packets, containing the TYPE_SPLIT header - core::list > chunks; + std::list > chunks; u32 chunk_header_size = 7; u32 maximum_data_size = chunksize_max - chunk_header_size; u32 start = 0; u32 end = 0; u32 chunk_num = 0; + u16 chunk_count = 0; do{ end = start + maximum_data_size - 1; if(end > data.getSize() - 1) @@ -106,16 +107,15 @@ core::list > makeSplitPacket( memcpy(&chunk[chunk_header_size], &data[start], payload_size); chunks.push_back(chunk); + chunk_count++; start = end + 1; chunk_num++; } while(end != data.getSize() - 1); - u16 chunk_count = chunks.getSize(); - - core::list >::Iterator i = chunks.begin(); - for(; i != chunks.end(); i++) + for(std::list >::iterator i = chunks.begin(); + i != chunks.end(); ++i) { // Write chunk_count writeU16(&((*i)[3]), chunk_count); @@ -124,13 +124,13 @@ core::list > makeSplitPacket( return chunks; } -core::list > makeAutoSplitPacket( +std::list > makeAutoSplitPacket( SharedBuffer data, u32 chunksize_max, u16 &split_seqnum) { u32 original_header_size = 1; - core::list > list; + std::list > list; if(data.getSize() + original_header_size > chunksize_max) { list = makeSplitPacket(data, chunksize_max, split_seqnum); @@ -170,11 +170,13 @@ SharedBuffer makeReliablePacket( ReliablePacketBuffer */ +ReliablePacketBuffer::ReliablePacketBuffer(): m_list_size(0) {} + void ReliablePacketBuffer::print() { - core::list::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++) + for(std::list::iterator i = m_list.begin(); + i != m_list.end(); + ++i) { u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1])); dout_con<::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++) + std::list::iterator i = m_list.begin(); + for(; i != m_list.end(); ++i) { u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1])); /*dout_con<<"findPacket(): finding seqnum="<::Iterator i = m_list.begin(); - m_list.erase(i); + m_list.erase(m_list.begin()); + --m_list_size; return p; } BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum) @@ -231,6 +232,7 @@ BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum) } BufferedPacket p = *r; m_list.erase(r); + --m_list_size; return p; } void ReliablePacketBuffer::insert(BufferedPacket &p) @@ -240,6 +242,7 @@ void ReliablePacketBuffer::insert(BufferedPacket &p) assert(type == TYPE_RELIABLE); u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE+1]); + ++m_list_size; // Find the right place for the packet and insert it there // If list is empty, just add it @@ -250,12 +253,12 @@ void ReliablePacketBuffer::insert(BufferedPacket &p) return; } // Otherwise find the right place - core::list::Iterator i; - i = m_list.begin(); + std::list::iterator i = m_list.begin(); // Find the first packet in the list which has a higher seqnum - for(; i != m_list.end(); i++){ + for(; i != m_list.end(); ++i){ u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1])); if(s == seqnum){ + --m_list_size; throw AlreadyExistsException("Same seqnum in list"); } if(seqnum_higher(s, seqnum)){ @@ -271,14 +274,14 @@ void ReliablePacketBuffer::insert(BufferedPacket &p) return; } // Insert before i - m_list.insert_before(i, p); + m_list.insert(i, p); } void ReliablePacketBuffer::incrementTimeouts(float dtime) { - core::list::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++){ + for(std::list::iterator i = m_list.begin(); + i != m_list.end(); ++i) + { i->time += dtime; i->totaltime += dtime; } @@ -286,9 +289,9 @@ void ReliablePacketBuffer::incrementTimeouts(float dtime) void ReliablePacketBuffer::resetTimedOuts(float timeout) { - core::list::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++){ + for(std::list::iterator i = m_list.begin(); + i != m_list.end(); ++i) + { if(i->time >= timeout) i->time = 0.0; } @@ -296,21 +299,20 @@ void ReliablePacketBuffer::resetTimedOuts(float timeout) bool ReliablePacketBuffer::anyTotaltimeReached(float timeout) { - core::list::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++){ + for(std::list::iterator i = m_list.begin(); + i != m_list.end(); ++i) + { if(i->totaltime >= timeout) return true; } return false; } -core::list ReliablePacketBuffer::getTimedOuts(float timeout) +std::list ReliablePacketBuffer::getTimedOuts(float timeout) { - core::list timed_outs; - core::list::Iterator i; - i = m_list.begin(); - for(; i != m_list.end(); i++) + std::list timed_outs; + for(std::list::iterator i = m_list.begin(); + i != m_list.end(); ++i) { if(i->time >= timeout) timed_outs.push_back(*i); @@ -324,11 +326,10 @@ core::list ReliablePacketBuffer::getTimedOuts(float timeout) IncomingSplitBuffer::~IncomingSplitBuffer() { - core::map::Iterator i; - i = m_buf.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map::iterator i = m_buf.begin(); + i != m_buf.end(); ++i) { - delete i.getNode()->getValue(); + delete i->second; } } /* @@ -346,7 +347,7 @@ SharedBuffer IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable) u16 chunk_num = readU16(&p.data[BASE_HEADER_SIZE+5]); // Add if doesn't exist - if(m_buf.find(seqnum) == NULL) + if(m_buf.find(seqnum) == m_buf.end()) { IncomingSplitPacket *sp = new IncomingSplitPacket(); sp->chunk_count = chunk_count; @@ -369,7 +370,7 @@ SharedBuffer IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable) // If chunk already exists, ignore it. // Sometimes two identical packets may arrive when there is network // lag and the server re-sends stuff. - if(sp->chunks.find(chunk_num) != NULL) + if(sp->chunks.find(chunk_num) != sp->chunks.end()) return SharedBuffer(); // Cut chunk data out of packet @@ -386,11 +387,10 @@ SharedBuffer IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable) // Calculate total size u32 totalsize = 0; - core::map >::Iterator i; - i = sp->chunks.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map >::iterator i = sp->chunks.begin(); + i != sp->chunks.end(); ++i) { - totalsize += i.getNode()->getValue().getSize(); + totalsize += i->second.getSize(); } SharedBuffer fulldata(totalsize); @@ -407,34 +407,32 @@ SharedBuffer IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable) } // Remove sp from buffer - m_buf.remove(seqnum); + m_buf.erase(seqnum); delete sp; return fulldata; } void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout) { - core::list remove_queue; - core::map::Iterator i; - i = m_buf.getIterator(); - for(; i.atEnd() == false; i++) + std::list remove_queue; + for(std::map::iterator i = m_buf.begin(); + i != m_buf.end(); ++i) { - IncomingSplitPacket *p = i.getNode()->getValue(); + IncomingSplitPacket *p = i->second; // Reliable ones are not removed by timeout if(p->reliable == true) continue; p->time += dtime; if(p->time >= timeout) - remove_queue.push_back(i.getNode()->getKey()); + remove_queue.push_back(i->first); } - core::list::Iterator j; - j = remove_queue.begin(); - for(; j != remove_queue.end(); j++) + for(std::list::iterator j = remove_queue.begin(); + j != remove_queue.end(); ++j) { dout_con<<"NOTE: Removing timed out unreliable split packet" <::Iterator - j = m_peers.getIterator(); - j.atEnd() == false; j++) + for(std::map::iterator + j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); - delete peer; + delete j->second; } } @@ -591,7 +588,7 @@ void * Connection::Thread() runTimeouts(dtime); - while(m_command_queue.size() != 0){ + while(!m_command_queue.empty()){ ConnectionCommand c = m_command_queue.pop_front(); processCommand(c); } @@ -648,18 +645,18 @@ void Connection::processCommand(ConnectionCommand &c) void Connection::send(float dtime) { - for(core::map::Iterator - j = m_peers.getIterator(); - j.atEnd() == false; j++) + for(std::map::iterator + j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; peer->m_sendtime_accu += dtime; peer->m_num_sent = 0; peer->m_max_num_sent = peer->m_sendtime_accu * peer->m_max_packets_per_second; } Queue postponed_packets; - while(m_outgoing_queue.size() != 0){ + while(!m_outgoing_queue.empty()){ OutgoingPacket packet = m_outgoing_queue.pop_front(); Peer *peer = getPeerNoEx(packet.peer_id); if(!peer) @@ -674,14 +671,14 @@ void Connection::send(float dtime) postponed_packets.push_back(packet); } } - while(postponed_packets.size() != 0){ + while(!postponed_packets.empty()){ m_outgoing_queue.push_back(postponed_packets.pop_front()); } - for(core::map::Iterator - j = m_peers.getIterator(); - j.atEnd() == false; j++) + for(std::map::iterator + j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; peer->m_sendtime_accu -= (float)peer->m_num_sent / peer->m_max_packets_per_second; if(peer->m_sendtime_accu > 10. / peer->m_max_packets_per_second) @@ -751,11 +748,11 @@ void Connection::receive() Allow only entries that have has_sent_with_id==false. */ - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + std::map::iterator j; + j = m_peers.begin(); + for(; j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; if(peer->has_sent_with_id) continue; if(peer->address == sender) @@ -766,14 +763,14 @@ void Connection::receive() If no peer was found with the same address and port, we shall assume it is a new peer and create an entry. */ - if(j.atEnd()) + if(j == m_peers.end()) { // Pass on to adding the peer } // Else: A peer was found. else { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; peer_id = peer->id; PrintInfo(derr_con); derr_con<<"WARNING: Assuming unknown peer to be " @@ -797,7 +794,7 @@ void Connection::receive() for(;;) { // Check if exists - if(m_peers.find(peer_id_new) == NULL) + if(m_peers.find(peer_id_new) == m_peers.end()) break; // Check for overflow if(peer_id_new == 65535){ @@ -817,7 +814,7 @@ void Connection::receive() // Create a peer Peer *peer = new Peer(peer_id_new, sender); - m_peers.insert(peer->id, peer); + m_peers[peer->id] = peer; // Create peer addition event ConnectionEvent e; @@ -837,9 +834,9 @@ void Connection::receive() // Go on and process whatever it sent } - core::map::Node *node = m_peers.find(peer_id); + std::map::iterator node = m_peers.find(peer_id); - if(node == NULL) + if(node == m_peers.end()) { // Peer not found // This means that the peer id of the sender is not PEER_ID_INEXISTENT @@ -849,7 +846,7 @@ void Connection::receive() throw InvalidIncomingDataException("Peer not found (possible timeout)"); } - Peer *peer = node->getValue(); + Peer *peer = node->second; // Validate peer address if(peer->address != sender) @@ -902,12 +899,11 @@ void Connection::runTimeouts(float dtime) float congestion_control_min_rate = g_settings->getFloat("congestion_control_min_rate"); - core::list timeouted_peers; - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + std::list timeouted_peers; + for(std::map::iterator j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; // Update congestion control values peer->congestion_control_aim_rtt = congestion_control_aim_rtt; @@ -934,8 +930,7 @@ void Connection::runTimeouts(float dtime) float resend_timeout = peer->resend_timeout; for(u16 i=0; i timed_outs; - core::list::Iterator j; + std::list timed_outs; Channel *channel = &peer->channels[i]; @@ -966,8 +961,8 @@ void Connection::runTimeouts(float dtime) channel->outgoing_reliables.resetTimedOuts(resend_timeout); - j = timed_outs.begin(); - for(; j != timed_outs.end(); j++) + for(std::list::iterator j = timed_outs.begin(); + j != timed_outs.end(); ++j) { u16 peer_id = readPeerId(*(j->data)); u8 channel = readChannel(*(j->data)); @@ -1012,8 +1007,8 @@ nextpeer: } // Remove timed out peers - core::list::Iterator i = timeouted_peers.begin(); - for(; i != timeouted_peers.end(); i++) + for(std::list::iterator i = timeouted_peers.begin(); + i != timeouted_peers.end(); ++i) { PrintInfo(derr_con); derr_con<<"RunTimeouts(): Removing peer "<<(*i)<::Node *node = m_peers.find(PEER_ID_SERVER); - if(node != NULL){ + std::map::iterator node = m_peers.find(PEER_ID_SERVER); + if(node != m_peers.end()){ throw ConnectionException("Already connected to a server"); } Peer *peer = new Peer(PEER_ID_SERVER, address); - m_peers.insert(peer->id, peer); + m_peers[peer->id] = peer; // Create event ConnectionEvent e; @@ -1072,22 +1067,20 @@ void Connection::disconnect() writeU8(&data[1], CONTROLTYPE_DISCO); // Send to all - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + for(std::map::iterator j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; rawSendAsPacket(peer->id, 0, data, false); } } void Connection::sendToAll(u8 channelnum, SharedBuffer data, bool reliable) { - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + for(std::map::iterator j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; send(peer->id, channelnum, data, reliable); } } @@ -1108,13 +1101,12 @@ void Connection::send(u16 peer_id, u8 channelnum, if(reliable) chunksize_max -= RELIABLE_HEADER_SIZE; - core::list > originals; + std::list > originals; originals = makeAutoSplitPacket(data, chunksize_max, channel->next_outgoing_split_seqnum); - core::list >::Iterator i; - i = originals.begin(); - for(; i != originals.end(); i++) + for(std::list >::iterator i = originals.begin(); + i != originals.end(); ++i) { SharedBuffer original = *i; @@ -1187,40 +1179,39 @@ void Connection::rawSend(const BufferedPacket &packet) Peer* Connection::getPeer(u16 peer_id) { - core::map::Node *node = m_peers.find(peer_id); + std::map::iterator node = m_peers.find(peer_id); - if(node == NULL){ + if(node == m_peers.end()){ throw PeerNotFoundException("GetPeer: Peer not found (possible timeout)"); } // Error checking - assert(node->getValue()->id == peer_id); + assert(node->second->id == peer_id); - return node->getValue(); + return node->second; } Peer* Connection::getPeerNoEx(u16 peer_id) { - core::map::Node *node = m_peers.find(peer_id); + std::map::iterator node = m_peers.find(peer_id); - if(node == NULL){ + if(node == m_peers.end()){ return NULL; } // Error checking - assert(node->getValue()->id == peer_id); + assert(node->second->id == peer_id); - return node->getValue(); + return node->second; } -core::list Connection::getPeers() +std::list Connection::getPeers() { - core::list list; - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + std::list list; + for(std::map::iterator j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; list.push_back(peer); } return list; @@ -1228,11 +1219,10 @@ core::list Connection::getPeers() bool Connection::getFromBuffers(u16 &peer_id, SharedBuffer &dst) { - core::map::Iterator j; - j = m_peers.getIterator(); - for(; j.atEnd() == false; j++) + for(std::map::iterator j = m_peers.begin(); + j != m_peers.end(); ++j) { - Peer *peer = j.getNode()->getValue(); + Peer *peer = j->second; for(u16 i=0; ichannels[i]; @@ -1538,7 +1528,7 @@ SharedBuffer Connection::processPacket(Channel *channel, bool Connection::deletePeer(u16 peer_id, bool timeout) { - if(m_peers.find(peer_id) == NULL) + if(m_peers.find(peer_id) == m_peers.end()) return false; Peer *peer = m_peers[peer_id]; @@ -1549,7 +1539,7 @@ bool Connection::deletePeer(u16 peer_id, bool timeout) putEvent(e); delete m_peers[peer_id]; - m_peers.remove(peer_id); + m_peers.erase(peer_id); return true; } @@ -1557,7 +1547,7 @@ bool Connection::deletePeer(u16 peer_id, bool timeout) ConnectionEvent Connection::getEvent() { - if(m_event_queue.size() == 0){ + if(m_event_queue.empty()){ ConnectionEvent e; e.type = CONNEVENT_NONE; return e; @@ -1602,8 +1592,8 @@ bool Connection::Connected() if(m_peers.size() != 1) return false; - core::map::Node *node = m_peers.find(PEER_ID_SERVER); - if(node == NULL) + std::map::iterator node = m_peers.find(PEER_ID_SERVER); + if(node == m_peers.end()) return false; if(m_peer_id == PEER_ID_INEXISTENT) diff --git a/src/connection.h b/src/connection.h index 05b1ca2e8..486cf331f 100644 --- a/src/connection.h +++ b/src/connection.h @@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/thread.h" #include #include +#include +#include namespace con { @@ -142,14 +144,14 @@ SharedBuffer makeOriginalPacket( SharedBuffer data); // Split data in chunks and add TYPE_SPLIT headers to them -core::list > makeSplitPacket( +std::list > makeSplitPacket( SharedBuffer data, u32 chunksize_max, u16 seqnum); // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet // Increments split_seqnum if a split packet is made -core::list > makeAutoSplitPacket( +std::list > makeAutoSplitPacket( SharedBuffer data, u32 chunksize_max, u16 &split_seqnum); @@ -167,7 +169,7 @@ struct IncomingSplitPacket reliable = false; } // Key is chunk number, value is data without headers - core::map > chunks; + std::map > chunks; u32 chunk_count; float time; // Seconds from adding bool reliable; // If true, isn't deleted on timeout @@ -268,12 +270,12 @@ with a buffer in the receiving and transmitting end. for fast access to the smallest one. */ -typedef core::list::Iterator RPBSearchResult; +typedef std::list::iterator RPBSearchResult; class ReliablePacketBuffer { public: - + ReliablePacketBuffer(); void print(); bool empty(); u32 size(); @@ -286,10 +288,11 @@ public: void incrementTimeouts(float dtime); void resetTimedOuts(float timeout); bool anyTotaltimeReached(float timeout); - core::list getTimedOuts(float timeout); + std::list getTimedOuts(float timeout); private: - core::list m_list; + std::list m_list; + u16 m_list_size; }; /* @@ -310,7 +313,7 @@ public: private: // Key is seqnum - core::map m_buf; + std::map m_buf; }; class Connection; @@ -589,7 +592,7 @@ private: void rawSend(const BufferedPacket &packet); Peer* getPeer(u16 peer_id); Peer* getPeerNoEx(u16 peer_id); - core::list getPeers(); + std::list getPeers(); bool getFromBuffers(u16 &peer_id, SharedBuffer &dst); // Returns next data from a buffer if possible // If found, returns true; if not, false. @@ -619,7 +622,7 @@ private: UDPSocket m_socket; u16 m_peer_id; - core::map m_peers; + std::map m_peers; JMutex m_peers_mutex; // Backwards compatibility diff --git a/src/content_abm.cpp b/src/content_abm.cpp index 03fc82ed4..a88450095 100644 --- a/src/content_abm.cpp +++ b/src/content_abm.cpp @@ -114,7 +114,7 @@ public: actionstream<<"A sapling grows into a tree at " < modified_blocks; + std::map modified_blocks; v3s16 tree_p = p; ManualMapVoxelManipulator vmanip(map); v3s16 tree_blockp = getNodeBlockPos(tree_p); @@ -124,24 +124,19 @@ public: vmanip.blitBackAll(&modified_blocks); // update lighting - core::map lighting_modified_blocks; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) - { - lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue()); - } + std::map lighting_modified_blocks; + lighting_modified_blocks.insert(modified_blocks.begin(), modified_blocks.end()); map->updateLighting(lighting_modified_blocks, modified_blocks); // Send a MEET_OTHER event MapEditEvent event; event.type = MEET_OTHER; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) +// event.modified_blocks.insert(modified_blocks.begin(), modified_blocks.end()); + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - event.modified_blocks.insert(p, true); + event.modified_blocks.insert(i->first); } map->dispatchEvent(&event); } diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 5e5cb38ae..269667fe5 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -50,7 +50,7 @@ struct ToolCapabilities; #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" -core::map ClientActiveObject::m_types; +std::map ClientActiveObject::m_types; /* SmoothTranslator diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 0d80dc173..3b001510e 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -230,9 +230,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // Neighbor liquid levels (key = relative position) // Includes current node - core::map neighbor_levels; - core::map neighbor_contents; - core::map neighbor_flags; + std::map neighbor_levels; + std::map neighbor_contents; + std::map neighbor_flags; const u8 neighborflag_top_is_same_liquid = 0x01; v3s16 neighbor_dirs[9] = { v3s16(0,0,0), @@ -273,9 +273,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data, flags |= neighborflag_top_is_same_liquid; } - neighbor_levels.insert(neighbor_dirs[i], level); - neighbor_contents.insert(neighbor_dirs[i], content); - neighbor_flags.insert(neighbor_dirs[i], flags); + neighbor_levels[neighbor_dirs[i]] = level; + neighbor_contents[neighbor_dirs[i]] = content; + neighbor_flags[neighbor_dirs[i]] = flags; } // Corner heights (average between four liquids) diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 718a42dff..1e02ea5a5 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "genericobject.h" #include "util/serialize.h" -core::map ServerActiveObject::m_types; +std::map ServerActiveObject::m_types; /* DummyLoadSAO diff --git a/src/debug.cpp b/src/debug.cpp index e32cceb86..2e4992a78 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -130,7 +130,7 @@ void DebugStack::print(std::ostream &os, bool everything) os<<"Probably overflown."< g_debug_stacks; +std::map g_debug_stacks; JMutex g_debug_stacks_mutex; void debug_stacks_init() @@ -144,12 +144,11 @@ void debug_stacks_print_to(std::ostream &os) os<<"Debug stacks:"<::Iterator - i = g_debug_stacks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = g_debug_stacks.begin(); + i != g_debug_stacks.end(); ++i) { - DebugStack *stack = i.getNode()->getValue(); - stack->print(os, false); + i->second->print(os, false); } } @@ -159,11 +158,11 @@ void debug_stacks_print() DEBUGPRINT("Debug stacks:\n"); - for(core::map::Iterator - i = g_debug_stacks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = g_debug_stacks.begin(); + i != g_debug_stacks.end(); ++i) { - DebugStack *stack = i.getNode()->getValue(); + DebugStack *stack = i->second; for(int i=0; i::Node *n; + std::map::iterator n; n = g_debug_stacks.find(threadid); - if(n != NULL) + if(n != g_debug_stacks.end()) { - m_stack = n->getValue(); + m_stack = n->second; } else { /*DEBUGPRINT("Creating new debug stack for thread %x\n", (unsigned int)threadid);*/ m_stack = new DebugStack(threadid); - g_debug_stacks.insert(threadid, m_stack); + g_debug_stacks[threadid] = m_stack; } if(m_stack->stack_i >= DEBUG_STACK_SIZE) @@ -224,7 +223,7 @@ DebugStacker::~DebugStacker() /*DEBUGPRINT("Deleting debug stack for thread %x\n", (unsigned int)threadid);*/ delete m_stack; - g_debug_stacks.remove(threadid); + g_debug_stacks.erase(threadid); } } diff --git a/src/debug.h b/src/debug.h index 56952427c..1b14c4e0a 100644 --- a/src/debug.h +++ b/src/debug.h @@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "threads.h" #include "gettime.h" #include "exceptions.h" +#include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -165,7 +166,7 @@ struct DebugStack int stack_max_i; // Highest i that was seen }; -extern core::map g_debug_stacks; +extern std::map g_debug_stacks; extern JMutex g_debug_stacks_mutex; extern void debug_stacks_init(); @@ -205,42 +206,42 @@ public: void add(u16 command) { - core::map::Node *n = m_packets.find(command); - if(n == NULL) + std::map::iterator n = m_packets.find(command); + if(n == m_packets.end()) { m_packets[command] = 1; } else { - n->setValue(n->getValue()+1); + n->second++; } } void clear() { - for(core::map::Iterator - i = m_packets.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_packets.begin(); + i != m_packets.end(); ++i) { - i.getNode()->setValue(0); + i->second = 0; } } void print(std::ostream &o) { - for(core::map::Iterator - i = m_packets.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_packets.begin(); + i != m_packets.end(); ++i) { - o<<"cmd "<getKey() - <<" count "<getValue() + o<<"cmd "<first + <<" count "<second < m_packets; + std::map m_packets; }; /* diff --git a/src/emerge.cpp b/src/emerge.cpp index 6c6863eff..8a060d107 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -359,7 +359,7 @@ void *EmergeThread::Thread() { */ BlockMakeData data; MapBlock *block = NULL; - core::map modified_blocks; + std::map modified_blocks; if (getBlockOrStartGen(p, &block, &data, allow_generate)) { { @@ -415,13 +415,13 @@ void *EmergeThread::Thread() { JMutexAutoLock lock(m_server->m_con_mutex); // Add the originally fetched block to the modified list if (block) - modified_blocks.insert(p, block); + modified_blocks[p] = block; // Set the modified blocks unsent for all the clients - for (core::map::Iterator - i = m_server->m_clients.getIterator(); - i.atEnd() == false; i++) { - RemoteClient *client = i.getNode()->getValue(); + for (std::map::iterator + i = m_server->m_clients.begin(); + i != m_server->m_clients.end(); ++i) { + RemoteClient *client = i->second; if (modified_blocks.size() > 0) { // Remove block from sent history client->SetBlocksNotSent(modified_blocks); diff --git a/src/environment.cpp b/src/environment.cpp index e939672e7..7c93090b6 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -58,8 +58,8 @@ Environment::Environment(): Environment::~Environment() { // Deallocate players - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { delete (*i); } @@ -86,8 +86,8 @@ void Environment::removePlayer(u16 peer_id) { DSTACK(__FUNCTION_NAME); re_search: - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; if(player->peer_id != peer_id) @@ -103,8 +103,8 @@ re_search: Player * Environment::getPlayer(u16 peer_id) { - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; if(player->peer_id == peer_id) @@ -115,8 +115,8 @@ Player * Environment::getPlayer(u16 peer_id) Player * Environment::getPlayer(const char *name) { - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; if(strcmp(player->getName(), name) == 0) @@ -127,12 +127,12 @@ Player * Environment::getPlayer(const char *name) Player * Environment::getRandomConnectedPlayer() { - core::list connected_players = getPlayers(true); + std::list connected_players = getPlayers(true); u32 chosen_one = myrand() % connected_players.size(); u32 j = 0; - for(core::list::Iterator + for(std::list::iterator i = connected_players.begin(); - i != connected_players.end(); i++) + i != connected_players.end(); ++i) { if(j == chosen_one) { @@ -146,12 +146,12 @@ Player * Environment::getRandomConnectedPlayer() Player * Environment::getNearestConnectedPlayer(v3f pos) { - core::list connected_players = getPlayers(true); + std::list connected_players = getPlayers(true); f32 nearest_d = 0; Player *nearest_player = NULL; - for(core::list::Iterator + for(std::list::iterator i = connected_players.begin(); - i != connected_players.end(); i++) + i != connected_players.end(); ++i) { Player *player = *i; f32 d = player->getPosition().getDistanceFrom(pos); @@ -164,17 +164,17 @@ Player * Environment::getNearestConnectedPlayer(v3f pos) return nearest_player; } -core::list Environment::getPlayers() +std::list Environment::getPlayers() { return m_players; } -core::list Environment::getPlayers(bool ignore_disconnected) +std::list Environment::getPlayers(bool ignore_disconnected) { - core::list newlist; - for(core::list::Iterator + std::list newlist; + for(std::list::iterator i = m_players.begin(); - i != m_players.end(); i++) + i != m_players.end(); ++i) { Player *player = *i; @@ -193,7 +193,7 @@ core::list Environment::getPlayers(bool ignore_disconnected) void Environment::printPlayers(std::ostream &o) { o<<"Players in environment:"<::Iterator i = m_players.begin(); + for(std::list::iterator i = m_players.begin(); i != m_players.end(); i++) { Player *player = *i; @@ -251,7 +251,7 @@ ABMWithState::ABMWithState(ActiveBlockModifier *abm_): ActiveBlockList */ -void fillRadiusBlock(v3s16 p0, s16 r, core::map &list) +void fillRadiusBlock(v3s16 p0, s16 r, std::set &list) { v3s16 p; for(p.X=p0.X-r; p.X<=p0.X+r; p.X++) @@ -259,21 +259,21 @@ void fillRadiusBlock(v3s16 p0, s16 r, core::map &list) for(p.Z=p0.Z-r; p.Z<=p0.Z+r; p.Z++) { // Set in list - list[p] = true; + list.insert(p); } } -void ActiveBlockList::update(core::list &active_positions, +void ActiveBlockList::update(std::list &active_positions, s16 radius, - core::map &blocks_removed, - core::map &blocks_added) + std::set &blocks_removed, + std::set &blocks_added) { /* Create the new list */ - core::map newlist; - for(core::list::Iterator i = active_positions.begin(); - i != active_positions.end(); i++) + std::set newlist; + for(std::list::iterator i = active_positions.begin(); + i != active_positions.end(); ++i) { fillRadiusBlock(*i, radius, newlist); } @@ -282,37 +282,37 @@ void ActiveBlockList::update(core::list &active_positions, Find out which blocks on the old list are not on the new list */ // Go through old list - for(core::map::Iterator i = m_list.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator i = m_list.begin(); + i != m_list.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; // If not on new list, it's been removed - if(newlist.find(p) == NULL) - blocks_removed.insert(p, true); + if(newlist.find(p) == newlist.end()) + blocks_removed.insert(p); } /* Find out which blocks on the new list are not on the old list */ // Go through new list - for(core::map::Iterator i = newlist.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator i = newlist.begin(); + i != newlist.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; // If not on old list, it's been added - if(m_list.find(p) == NULL) - blocks_added.insert(p, true); + if(m_list.find(p) == m_list.end()) + blocks_added.insert(p); } /* Update m_list */ m_list.clear(); - for(core::map::Iterator i = newlist.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator i = newlist.begin(); + i != newlist.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - m_list.insert(p, true); + v3s16 p = *i; + m_list.insert(p); } } @@ -348,8 +348,8 @@ ServerEnvironment::~ServerEnvironment() m_map->drop(); // Delete ActiveBlockModifiers - for(core::list::Iterator - i = m_abms.begin(); i != m_abms.end(); i++){ + for(std::list::iterator + i = m_abms.begin(); i != m_abms.end(); ++i){ delete i->abm; } } @@ -370,7 +370,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir) std::string players_path = savedir + "/players"; fs::CreateDir(players_path); - core::map saved_players; + std::set saved_players; std::vector player_files = fs::GetDirListing(players_path); for(u32 i=0; iserialize(os); - saved_players.insert(player, true); + saved_players.insert(player); } } - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; - if(saved_players.find(player) != NULL) + if(saved_players.find(player) != saved_players.end()) { /*infostream<<"Player "<getName() <<" was already saved."<serialize(os); - saved_players.insert(player, true); + saved_players.insert(player); } } @@ -484,8 +484,6 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir) { std::string players_path = savedir + "/players"; - core::map saved_players; - std::vector player_files = fs::GetDirListing(players_path); for(u32 i=0; i > m_aabms; public: - ABMHandler(core::list &abms, + ABMHandler(std::list &abms, float dtime_s, ServerEnvironment *env, bool use_timers): m_env(env) @@ -635,8 +633,8 @@ public: if(dtime_s < 0.001) return; INodeDefManager *ndef = env->getGameDef()->ndef(); - for(core::list::Iterator - i = abms.begin(); i != abms.end(); i++){ + for(std::list::iterator + i = abms.begin(); i != abms.end(); ++i){ ActiveBlockModifier *abm = i->abm; float trigger_interval = abm->getTriggerInterval(); if(trigger_interval < 0.001) @@ -862,12 +860,12 @@ bool ServerEnvironment::removeNode(v3s16 p) std::set ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius) { std::set objects; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ServerActiveObject* obj = i.getNode()->getValue(); - u16 id = i.getNode()->getKey(); + ServerActiveObject* obj = i->second; + u16 id = i->first; v3f objectpos = obj->getBasePosition(); if(objectpos.getDistanceFrom(pos) > radius) continue; @@ -880,16 +878,16 @@ void ServerEnvironment::clearAllObjects() { infostream<<"ServerEnvironment::clearAllObjects(): " <<"Removing all active objects"< objects_to_remove; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + std::list objects_to_remove; + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ServerActiveObject* obj = i.getNode()->getValue(); + ServerActiveObject* obj = i->second; if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER) continue; - u16 id = i.getNode()->getKey(); - v3f objectpos = obj->getBasePosition(); + u16 id = i->first; + v3f objectpos = obj->getBasePosition(); // Delete static object if block is loaded if(obj->m_static_exists){ MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); @@ -919,13 +917,13 @@ void ServerEnvironment::clearAllObjects() objects_to_remove.push_back(id); } // Remove references from m_active_objects - for(core::list::Iterator i = objects_to_remove.begin(); - i != objects_to_remove.end(); i++) + for(std::list::iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); ++i) { - m_active_objects.remove(*i); + m_active_objects.erase(*i); } - core::list loadable_blocks; + std::list loadable_blocks; infostream<<"ServerEnvironment::clearAllObjects(): " <<"Listing all loadable blocks"<listAllLoadableBlocks(loadable_blocks); @@ -937,8 +935,8 @@ void ServerEnvironment::clearAllObjects() u32 num_blocks_checked = 0; u32 num_blocks_cleared = 0; u32 num_objs_cleared = 0; - for(core::list::Iterator i = loadable_blocks.begin(); - i != loadable_blocks.end(); i++) + for(std::list::iterator i = loadable_blocks.begin(); + i != loadable_blocks.end(); ++i) { v3s16 p = *i; MapBlock *block = m_map->emergeBlock(p, false); @@ -1002,8 +1000,8 @@ void ServerEnvironment::step(float dtime) */ { ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG); - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; @@ -1027,10 +1025,10 @@ void ServerEnvironment::step(float dtime) /* Get player block positions */ - core::list players_blockpos; - for(core::list::Iterator + std::list players_blockpos; + for(std::list::iterator i = m_players.begin(); - i != m_players.end(); i++) + i != m_players.end(); ++i) { Player *player = *i; // Ignore disconnected players @@ -1045,8 +1043,8 @@ void ServerEnvironment::step(float dtime) Update list of active blocks, collecting changes */ const s16 active_block_range = g_settings->getS16("active_block_range"); - core::map blocks_removed; - core::map blocks_added; + std::set blocks_removed; + std::set blocks_added; m_active_blocks.update(players_blockpos, active_block_range, blocks_removed, blocks_added); @@ -1057,11 +1055,11 @@ void ServerEnvironment::step(float dtime) // Convert active objects that are no more in active blocks to static deactivateFarObjects(false); - for(core::map::Iterator - i = blocks_removed.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = blocks_removed.begin(); + i != blocks_removed.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; /*infostream<<"Server: Block ("<::Iterator - i = blocks_added.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = blocks_added.begin(); + i != blocks_added.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; /*infostream<<"Server: Block ("<queueBlockEmerge(p, false); - m_active_blocks.m_list.remove(p); + m_active_blocks.m_list.erase(p); continue; } @@ -1108,11 +1106,11 @@ void ServerEnvironment::step(float dtime) float dtime = 1.0; - for(core::map::Iterator - i = m_active_blocks.m_list.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = m_active_blocks.m_list.begin(); + i != m_active_blocks.m_list.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; /*infostream<<"Server: Block ("<::Iterator - i = m_active_blocks.m_list.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = m_active_blocks.m_list.begin(); + i != m_active_blocks.m_list.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; /*infostream<<"Server: Block ("<::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ServerActiveObject* obj = i.getNode()->getValue(); + ServerActiveObject* obj = i->second; // Remove non-peaceful mobs on peaceful mode if(g_settings->getBool("only_peaceful_mobs")){ if(!obj->isPeaceful()) @@ -1232,7 +1230,7 @@ void ServerEnvironment::step(float dtime) // Step object obj->step(dtime, send_recommended); // Read messages from object - while(obj->m_messages_out.size() > 0) + while(!obj->m_messages_out.empty()) { m_active_object_messages.push_back( obj->m_messages_out.pop_front()); @@ -1255,31 +1253,24 @@ void ServerEnvironment::step(float dtime) ServerActiveObject* ServerEnvironment::getActiveObject(u16 id) { - core::map::Node *n; + std::map::iterator n; n = m_active_objects.find(id); - if(n == NULL) + if(n == m_active_objects.end()) return NULL; - return n->getValue(); + return n->second; } bool isFreeServerActiveObjectId(u16 id, - core::map &objects) + std::map &objects) { if(id == 0) return false; - - for(core::map::Iterator - i = objects.getIterator(); - i.atEnd()==false; i++) - { - if(i.getNode()->getKey() == id) - return false; - } - return true; + + return objects.find(id) == objects.end(); } u16 getFreeServerActiveObjectId( - core::map &objects) + std::map &objects) { u16 new_id = 1; for(;;) @@ -1351,8 +1342,8 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj) inside a radius around a position */ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius, - core::map ¤t_objects, - core::map &added_objects) + std::set ¤t_objects, + std::set &added_objects) { v3f pos_f = intToFloat(pos, BS); f32 radius_f = radius * BS; @@ -1363,13 +1354,13 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius, - discard objects that are found in current_objects. - add remaining objects to added_objects */ - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - u16 id = i.getNode()->getKey(); + u16 id = i->first; // Get object - ServerActiveObject *object = i.getNode()->getValue(); + ServerActiveObject *object = i->second; if(object == NULL) continue; // Discard if removed @@ -1382,12 +1373,12 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius, continue; } // Discard if already on current_objects - core::map::Node *n; + std::set::iterator n; n = current_objects.find(id); - if(n != NULL) + if(n != current_objects.end()) continue; // Add to added_objects - added_objects.insert(id, false); + added_objects.insert(id); } } @@ -1396,8 +1387,8 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius, inside a radius around a position */ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius, - core::map ¤t_objects, - core::map &removed_objects) + std::set ¤t_objects, + std::set &removed_objects) { v3f pos_f = intToFloat(pos, BS); f32 radius_f = radius * BS; @@ -1409,23 +1400,23 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius, - object has m_removed=true, or - object is too far away */ - for(core::map::Iterator - i = current_objects.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = current_objects.begin(); + i != current_objects.end(); ++i) { - u16 id = i.getNode()->getKey(); + u16 id = *i; ServerActiveObject *object = getActiveObject(id); if(object == NULL){ infostream<<"ServerEnvironment::getRemovedActiveObjects():" <<" object in current_objects is NULL"<m_removed) { - removed_objects.insert(id, false); + removed_objects.insert(id); continue; } @@ -1437,7 +1428,7 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius, if(distance_f >= radius_f) { - removed_objects.insert(id, false); + removed_objects.insert(id); continue; } @@ -1447,7 +1438,7 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius, ActiveObjectMessage ServerEnvironment::getActiveObjectMessage() { - if(m_active_object_messages.size() == 0) + if(m_active_object_messages.empty()) return ActiveObjectMessage(0); return m_active_object_messages.pop_front(); @@ -1488,7 +1479,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, /*infostream<<"ServerEnvironment::addActiveObjectRaw(): " <<"added (id="<getId()<<")"<getId(), object); + m_active_objects[object->getId()] = object; verbosestream<<"ServerEnvironment::addActiveObjectRaw(): " <<"Added id="<getId()<<"; there are now " @@ -1512,7 +1503,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); if(block) { - block->m_static_objects.m_active.insert(object->getId(), s_obj); + block->m_static_objects.m_active[object->getId()] = s_obj; object->m_static_exists = true; object->m_static_block = blockpos; @@ -1536,13 +1527,13 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, */ void ServerEnvironment::removeRemovedObjects() { - core::list objects_to_remove; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + std::list objects_to_remove; + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - u16 id = i.getNode()->getKey(); - ServerActiveObject* obj = i.getNode()->getValue(); + u16 id = i->first; + ServerActiveObject* obj = i->second; // This shouldn't happen but check it if(obj == NULL) { @@ -1593,10 +1584,10 @@ void ServerEnvironment::removeRemovedObjects() objects_to_remove.push_back(id); } // Remove references from m_active_objects - for(core::list::Iterator i = objects_to_remove.begin(); - i != objects_to_remove.end(); i++) + for(std::list::iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); ++i) { - m_active_objects.remove(*i); + m_active_objects.erase(*i); } } @@ -1663,11 +1654,11 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s) } // A list for objects that couldn't be converted to active for some // reason. They will be stored back. - core::list new_stored; + std::list new_stored; // Loop through stored static objects - for(core::list::Iterator + for(std::list::iterator i = block->m_static_objects.m_stored.begin(); - i != block->m_static_objects.m_stored.end(); i++) + i != block->m_static_objects.m_stored.end(); ++i) { /*infostream<<"Server: Creating an active object from " <<"static data"<m_static_objects.m_stored.clear(); // Add leftover failed stuff to stored list - for(core::list::Iterator + for(std::list::iterator i = new_stored.begin(); - i != new_stored.end(); i++) + i != new_stored.end(); ++i) { StaticObject &s_obj = *i; block->m_static_objects.m_stored.push_back(s_obj); @@ -1726,12 +1717,12 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s) */ void ServerEnvironment::deactivateFarObjects(bool force_delete) { - core::list objects_to_remove; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + std::list objects_to_remove; + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ServerActiveObject* obj = i.getNode()->getValue(); + ServerActiveObject* obj = i->second; assert(obj); // Do not deactivate if static data creation not allowed @@ -1742,7 +1733,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) if(!force_delete && obj->m_pending_deactivation) continue; - u16 id = i.getNode()->getKey(); + u16 id = i->first; v3f objectpos = obj->getBasePosition(); // The block in which the object resides in @@ -1778,10 +1769,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); - core::map::Node *n = + std::map::iterator n = block->m_static_objects.m_active.find(id); - if(n){ - StaticObject static_old = n->getValue(); + if(n != block->m_static_objects.m_active.end()){ + StaticObject static_old = n->second; float save_movem = obj->getMinimumSavedMovement(); @@ -1840,7 +1831,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) // This shouldn't happen, but happens rarely for some // unknown reason. Unsuccessful attempts have been made to // find said reason. - if(new_id && block->m_static_objects.m_active.find(new_id)){ + if(new_id && block->m_static_objects.m_active.find(new_id) != block->m_static_objects.m_active.end()){ infostream<<"ServerEnv: WARNING: Performing hack #83274" <m_static_objects.remove(new_id); @@ -1900,10 +1891,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) } // Remove references from m_active_objects - for(core::list::Iterator i = objects_to_remove.begin(); - i != objects_to_remove.end(); i++) + for(std::list::iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); ++i) { - m_active_objects.remove(*i); + m_active_objects.erase(*i); } } @@ -1930,15 +1921,15 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, ClientEnvironment::~ClientEnvironment() { // delete active objects - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - delete i.getNode()->getValue(); + delete i->second; } - for(core::list::Iterator - i = m_simple_objects.begin(); i != m_simple_objects.end(); i++) + for(std::list::iterator + i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i) { delete *i; } @@ -1971,8 +1962,8 @@ void ClientEnvironment::addPlayer(Player *player) LocalPlayer * ClientEnvironment::getLocalPlayer() { - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; if(player->isLocal()) @@ -1996,7 +1987,7 @@ void ClientEnvironment::step(float dtime) LocalPlayer *lplayer = getLocalPlayer(); assert(lplayer); // collision info queue - core::list player_collisions; + std::list player_collisions; /* Get the speed the player is going @@ -2113,9 +2104,9 @@ void ClientEnvironment::step(float dtime) //std::cout<<"Looped "<::Iterator + for(std::list::iterator i = player_collisions.begin(); - i != player_collisions.end(); i++) + i != player_collisions.end(); ++i) { CollisionInfo &info = *i; v3f speed_diff = info.new_speed - info.old_speed;; @@ -2179,8 +2170,8 @@ void ClientEnvironment::step(float dtime) /* Stuff that can be done in an arbitarily large dtime */ - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) + for(std::list::iterator i = m_players.begin(); + i != m_players.end(); ++i) { Player *player = *i; v3f playerpos = player->getPosition(); @@ -2214,11 +2205,11 @@ void ClientEnvironment::step(float dtime) */ bool update_lighting = m_active_object_light_update_interval.step(dtime, 0.21); - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ClientActiveObject* obj = i.getNode()->getValue(); + ClientActiveObject* obj = i->second; // Step object obj->step(dtime, this); @@ -2242,12 +2233,12 @@ void ClientEnvironment::step(float dtime) /* Step and handle simple objects */ - for(core::list::Iterator + for(std::list::iterator i = m_simple_objects.begin(); i != m_simple_objects.end();) { ClientSimpleObject *simple = *i; - core::list::Iterator cur = i; - i++; + std::list::iterator cur = i; + ++i; simple->step(dtime); if(simple->m_to_be_removed){ delete simple; @@ -2263,31 +2254,24 @@ void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple) ClientActiveObject* ClientEnvironment::getActiveObject(u16 id) { - core::map::Node *n; + std::map::iterator n; n = m_active_objects.find(id); - if(n == NULL) + if(n == m_active_objects.end()) return NULL; - return n->getValue(); + return n->second; } bool isFreeClientActiveObjectId(u16 id, - core::map &objects) + std::map &objects) { if(id == 0) return false; - - for(core::map::Iterator - i = objects.getIterator(); - i.atEnd()==false; i++) - { - if(i.getNode()->getKey() == id) - return false; - } - return true; + + return objects.find(id) == objects.end(); } u16 getFreeClientActiveObjectId( - core::map &objects) + std::map &objects) { u16 new_id = 1; for(;;) @@ -2326,7 +2310,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) } infostream<<"ClientEnvironment::addActiveObject(): " <<"added (id="<getId()<<")"<getId(), object); + m_active_objects[object->getId()] = object; object->addToScene(m_smgr, m_texturesource, m_irr); { // Update lighting immediately u8 light = 0; @@ -2389,7 +2373,7 @@ void ClientEnvironment::removeActiveObject(u16 id) } obj->removeFromScene(true); delete obj; - m_active_objects.remove(id); + m_active_objects.erase(id); } void ClientEnvironment::processActiveObjectMessage(u16 id, @@ -2445,13 +2429,13 @@ void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp) */ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d, - core::array &dest) + std::vector &dest) { - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { - ClientActiveObject* obj = i.getNode()->getValue(); + ClientActiveObject* obj = i->second; f32 d = (obj->getPosition() - origin).getLength(); @@ -2466,7 +2450,7 @@ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d, ClientEnvEvent ClientEnvironment::getClientEvent() { - if(m_client_event_queue.size() == 0) + if(m_client_event_queue.empty()) { ClientEnvEvent event; event.type = CEE_NONE; diff --git a/src/environment.h b/src/environment.h index 07a4d7635..02301e5d3 100644 --- a/src/environment.h +++ b/src/environment.h @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include +#include #include "irrlichttypes_extrabloated.h" #include "player.h" #include @@ -73,8 +74,8 @@ public: Player * getPlayer(const char *name); Player * getRandomConnectedPlayer(); Player * getNearestConnectedPlayer(v3f pos); - core::list getPlayers(); - core::list getPlayers(bool ignore_disconnected); + std::list getPlayers(); + std::list getPlayers(bool ignore_disconnected); void printPlayers(std::ostream &o); u32 getDayNightRatio(); @@ -102,7 +103,7 @@ public: protected: // peer_ids in here should be unique, except that there may be many 0s - core::list m_players; + std::list m_players; // Time of day in milli-hours (0-23999); determines day and night u32 m_time_of_day; // Time of day in 0...1 @@ -156,20 +157,20 @@ struct ABMWithState class ActiveBlockList { public: - void update(core::list &active_positions, + void update(std::list &active_positions, s16 radius, - core::map &blocks_removed, - core::map &blocks_added); + std::set &blocks_removed, + std::set &blocks_added); bool contains(v3s16 p){ - return (m_list.find(p) != NULL); + return (m_list.find(p) != m_list.end()); } void clear(){ m_list.clear(); } - core::map m_list; + std::set m_list; private: }; @@ -249,16 +250,16 @@ public: inside a radius around a position */ void getAddedActiveObjects(v3s16 pos, s16 radius, - core::map ¤t_objects, - core::map &added_objects); + std::set ¤t_objects, + std::set &added_objects); /* Find out what new objects have been removed from inside a radius around a position */ void getRemovedActiveObjects(v3s16 pos, s16 radius, - core::map ¤t_objects, - core::map &removed_objects); + std::set ¤t_objects, + std::set &removed_objects); /* Get the next message emitted by some active object. @@ -350,7 +351,7 @@ private: // Background block emerger (the server, in practice) IBackgroundBlockEmerger *m_emerger; // Active object list - core::map m_active_objects; + std::map m_active_objects; // Outgoing network message buffer for active objects Queue m_active_object_messages; // Some timers @@ -368,7 +369,7 @@ private: u32 m_game_time; // A helper variable for incrementing the latter float m_game_time_fraction_counter; - core::list m_abms; + std::list m_abms; // An interval for generally sending object positions and stuff float m_recommended_send_interval; }; @@ -463,7 +464,7 @@ public: // Get all nearby objects void getActiveObjects(v3f origin, f32 max_d, - core::array &dest); + std::vector &dest); // Get event from queue. CEE_NONE is returned if queue is empty. ClientEnvEvent getClientEvent(); @@ -476,8 +477,8 @@ private: ITextureSource *m_texturesource; IGameDef *m_gamedef; IrrlichtDevice *m_irr; - core::map m_active_objects; - core::list m_simple_objects; + std::map m_active_objects; + std::list m_simple_objects; Queue m_client_event_queue; IntervalLimiter m_active_object_light_update_interval; IntervalLimiter m_lava_hurt_interval; diff --git a/src/farmesh.cpp b/src/farmesh.cpp index 443e2b3bf..ecf01ee07 100644 --- a/src/farmesh.cpp +++ b/src/farmesh.cpp @@ -112,13 +112,13 @@ struct HeightPoint float have_sand; float tree_amount; }; -core::map g_heights; +std::map g_heights; HeightPoint ground_height(u64 seed, v2s16 p2d) { - core::map::Node *n = g_heights.find(p2d); - if(n) - return n->getValue(); + std::map::iterator n = g_heights.find(p2d); + if(n != g_heights.end()) + return n->second; HeightPoint hp; s16 level = Mapgen::find_ground_level_from_noise(seed, p2d, 3); hp.gh = (level-4)*BS; diff --git a/src/game.h b/src/game.h index fef777fea..a2c1fc09c 100644 --- a/src/game.h +++ b/src/game.h @@ -23,17 +23,18 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include #include "keycode.h" +#include -class KeyList : protected core::list +class KeyList : protected std::list { - typedef core::list super; - typedef super::Iterator Iterator; - typedef super::ConstIterator ConstIterator; + typedef std::list super; + typedef super::iterator iterator; + typedef super::const_iterator const_iterator; - virtual ConstIterator find(const KeyPress &key) const + virtual const_iterator find(const KeyPress &key) const { - ConstIterator f(begin()); - ConstIterator e(end()); + const_iterator f(begin()); + const_iterator e(end()); while (f!=e) { if (*f == key) return f; @@ -42,10 +43,10 @@ class KeyList : protected core::list return e; } - virtual Iterator find(const KeyPress &key) + virtual iterator find(const KeyPress &key) { - Iterator f(begin()); - Iterator e(end()); + iterator f(begin()); + iterator e(end()); while (f!=e) { if (*f == key) return f; @@ -65,14 +66,14 @@ public: void unset(const KeyPress &key) { - Iterator p(find(key)); + iterator p(find(key)); if (p != end()) erase(p); } void toggle(const KeyPress &key) { - Iterator p(this->find(key)); + iterator p(this->find(key)); if (p != end()) erase(p); else diff --git a/src/guiChatConsole.cpp b/src/guiChatConsole.cpp index f522af01f..5fc576cf8 100644 --- a/src/guiChatConsole.cpp +++ b/src/guiChatConsole.cpp @@ -535,7 +535,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) { // Tab or Shift-Tab pressed // Nick completion - core::list names = m_client->getConnectedPlayerNames(); + std::list names = m_client->getConnectedPlayerNames(); bool backwards = event.KeyInput.Shift; m_chat_backend->getPrompt().nickCompletion(names, backwards); return true; diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index aee16736e..17b202b18 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -209,11 +209,11 @@ protected: IFormSource *m_form_src; TextDest *m_text_dst; - core::array m_inventorylists; - core::array m_backgrounds; - core::array m_images; - core::array m_itemimages; - core::array m_fields; + std::vector m_inventorylists; + std::vector m_backgrounds; + std::vector m_images; + std::vector m_itemimages; + std::vector m_fields; ItemSpec *m_selected_item; u32 m_selected_amount; diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 5fd27fca3..4bd4181f9 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -211,8 +211,8 @@ public: virtual ~CItemDefManager() { #ifndef SERVER - const core::list &values = m_clientcached.getValues(); - for(core::list::ConstIterator + const std::list &values = m_clientcached.getValues(); + for(std::list::const_iterator i = values.begin(); i != values.end(); ++i) { ClientCached *cc = *i; @@ -599,7 +599,7 @@ public: void processQueue(IGameDef *gamedef) { #ifndef SERVER - while(m_get_clientcached_queue.size() > 0) + while(!m_get_clientcached_queue.empty()) { GetRequest request = m_get_clientcached_queue.pop(); diff --git a/src/keycode.cpp b/src/keycode.cpp index 8aadab2f1..96631b4ea 100644 --- a/src/keycode.cpp +++ b/src/keycode.cpp @@ -345,17 +345,16 @@ const KeyPress NumberKey[] = { */ // A simple cache for quicker lookup -core::map g_key_setting_cache; +std::map g_key_setting_cache; KeyPress getKeySetting(const char *settingname) { - core::map::Node *n; + std::map::iterator n; n = g_key_setting_cache.find(settingname); - if(n) - return n->getValue(); - g_key_setting_cache.insert(settingname, - g_settings->get(settingname).c_str()); - return g_key_setting_cache.find(settingname)->getValue(); + if(n != g_key_setting_cache.end()) + return n->second; + g_key_setting_cache[settingname] = g_settings->get(settingname).c_str(); + return g_key_setting_cache.find(settingname)->second; } void clearKeyCache() diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 0554302e0..9c36e75e6 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -58,7 +58,7 @@ LocalPlayer::~LocalPlayer() } void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, - core::list *collision_info) + std::list *collision_info) { INodeDefManager *nodemgr = m_gamedef->ndef(); diff --git a/src/localplayer.h b/src/localplayer.h index f372c787d..e46ca6147 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define LOCALPLAYER_HEADER #include "player.h" +#include class LocalPlayer : public Player { @@ -38,7 +39,7 @@ public: v3f overridePosition; void move(f32 dtime, Map &map, f32 pos_max_d, - core::list *collision_info); + std::list *collision_info); void move(f32 dtime, Map &map, f32 pos_max_d); void applyControl(float dtime); diff --git a/src/main.cpp b/src/main.cpp index cfd643ac7..696468049 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -700,14 +700,14 @@ void SpeedTests() } { - TimeTaker timer("Testing core::map speed"); + TimeTaker timer("Testing std::map speed"); - core::map map1; + std::map map1; tempf = -324; const s16 ii=300; for(s16 y=0; y allowed_options; - allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG, - _("Show allowed options"))); - allowed_options.insert("config", ValueSpec(VALUETYPE_STRING, - _("Load configuration from specified file"))); - allowed_options.insert("port", ValueSpec(VALUETYPE_STRING, - _("Set network port (UDP)"))); - allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG, - _("Disable unit tests"))); - allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG, - _("Enable unit tests"))); - allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING, - _("Same as --world (deprecated)"))); - allowed_options.insert("world", ValueSpec(VALUETYPE_STRING, - _("Set world path (implies local game) ('list' lists all)"))); - allowed_options.insert("worldname", ValueSpec(VALUETYPE_STRING, - _("Set world by name (implies local game)"))); - allowed_options.insert("info", ValueSpec(VALUETYPE_FLAG, - _("Print more information to console"))); - allowed_options.insert("verbose", ValueSpec(VALUETYPE_FLAG, - _("Print even more information to console"))); - allowed_options.insert("trace", ValueSpec(VALUETYPE_FLAG, - _("Print enormous amounts of information to log and console"))); - allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING, - _("Set logfile path ('' = no logging)"))); - allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING, - _("Set gameid (\"--gameid list\" prints available ones)"))); + std::map allowed_options; + allowed_options.insert(std::make_pair("help", ValueSpec(VALUETYPE_FLAG, + _("Show allowed options")))); + allowed_options.insert(std::make_pair("config", ValueSpec(VALUETYPE_STRING, + _("Load configuration from specified file")))); + allowed_options.insert(std::make_pair("port", ValueSpec(VALUETYPE_STRING, + _("Set network port (UDP)")))); + allowed_options.insert(std::make_pair("disable-unittests", ValueSpec(VALUETYPE_FLAG, + _("Disable unit tests")))); + allowed_options.insert(std::make_pair("enable-unittests", ValueSpec(VALUETYPE_FLAG, + _("Enable unit tests")))); + allowed_options.insert(std::make_pair("map-dir", ValueSpec(VALUETYPE_STRING, + _("Same as --world (deprecated)")))); + allowed_options.insert(std::make_pair("world", ValueSpec(VALUETYPE_STRING, + _("Set world path (implies local game) ('list' lists all)")))); + allowed_options.insert(std::make_pair("worldname", ValueSpec(VALUETYPE_STRING, + _("Set world by name (implies local game)")))); + allowed_options.insert(std::make_pair("info", ValueSpec(VALUETYPE_FLAG, + _("Print more information to console")))); + allowed_options.insert(std::make_pair("verbose", ValueSpec(VALUETYPE_FLAG, + _("Print even more information to console")))); + allowed_options.insert(std::make_pair("trace", ValueSpec(VALUETYPE_FLAG, + _("Print enormous amounts of information to log and console")))); + allowed_options.insert(std::make_pair("logfile", ValueSpec(VALUETYPE_STRING, + _("Set logfile path ('' = no logging)")))); + allowed_options.insert(std::make_pair("gameid", ValueSpec(VALUETYPE_STRING, + _("Set gameid (\"--gameid list\" prints available ones)")))); #ifndef SERVER - allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG, - _("Run speed tests"))); - allowed_options.insert("address", ValueSpec(VALUETYPE_STRING, - _("Address to connect to. ('' = local game)"))); - allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG, - _("Enable random user input, for testing"))); - allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG, - _("Run dedicated server"))); - allowed_options.insert("name", ValueSpec(VALUETYPE_STRING, - _("Set player name"))); - allowed_options.insert("password", ValueSpec(VALUETYPE_STRING, - _("Set password"))); - allowed_options.insert("go", ValueSpec(VALUETYPE_FLAG, - _("Disable main menu"))); + allowed_options.insert(std::make_pair("speedtests", ValueSpec(VALUETYPE_FLAG, + _("Run speed tests")))); + allowed_options.insert(std::make_pair("address", ValueSpec(VALUETYPE_STRING, + _("Address to connect to. ('' = local game)")))); + allowed_options.insert(std::make_pair("random-input", ValueSpec(VALUETYPE_FLAG, + _("Enable random user input, for testing")))); + allowed_options.insert(std::make_pair("server", ValueSpec(VALUETYPE_FLAG, + _("Run dedicated server")))); + allowed_options.insert(std::make_pair("name", ValueSpec(VALUETYPE_STRING, + _("Set player name")))); + allowed_options.insert(std::make_pair("password", ValueSpec(VALUETYPE_STRING, + _("Set password")))); + allowed_options.insert(std::make_pair("go", ValueSpec(VALUETYPE_FLAG, + _("Disable main menu")))); #endif Settings cmd_args; @@ -839,20 +839,20 @@ int main(int argc, char *argv[]) if(ret == false || cmd_args.getFlag("help") || cmd_args.exists("nonopt1")) { dstream<<_("Allowed options:")<::Iterator - i = allowed_options.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = allowed_options.begin(); + i != allowed_options.end(); ++i) { std::ostringstream os1(std::ios::binary); - os1<<" --"<getKey(); - if(i.getNode()->getValue().type == VALUETYPE_FLAG) + os1<<" --"<first; + if(i->second.type == VALUETYPE_FLAG) {} else os1<<_(" "); dstream<getValue().help != NULL) - dstream<getValue().help; + if(i->second.help != NULL) + dstream<second.help; dstream< filenames; + std::vector filenames; filenames.push_back(porting::path_user + DIR_DELIM + "minetest.conf"); // Legacy configuration file location diff --git a/src/mainmenumanager.h b/src/mainmenumanager.h index ce7684f11..a3133686b 100644 --- a/src/mainmenumanager.h +++ b/src/mainmenumanager.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" // assert #include "modalMenu.h" #include "guiPauseMenu.h" //For IGameCallback +#include extern gui::IGUIEnvironment* guienv; extern gui::IGUIStaticText *guiroot; @@ -37,15 +38,15 @@ class MainMenuManager : public IMenuManager public: virtual void createdMenu(GUIModalMenu *menu) { - for(core::list::Iterator + for(std::list::iterator i = m_stack.begin(); - i != m_stack.end(); i++) + i != m_stack.end(); ++i) { assert(*i != menu); } if(m_stack.size() != 0) - (*m_stack.getLast())->setVisible(false); + m_stack.back()->setVisible(false); m_stack.push_back(menu); } @@ -55,9 +56,9 @@ public: bool removed_entry; do{ removed_entry = false; - for(core::list::Iterator + for(std::list::iterator i = m_stack.begin(); - i != m_stack.end(); i++) + i != m_stack.end(); ++i) { if(*i == menu) { @@ -73,7 +74,7 @@ public: m_stack.erase(i);*/ if(m_stack.size() != 0) - (*m_stack.getLast())->setVisible(true); + m_stack.back()->setVisible(true); } u32 menuCount() @@ -81,7 +82,7 @@ public: return m_stack.size(); } - core::list m_stack; + std::list m_stack; }; extern MainMenuManager g_menumgr; diff --git a/src/map.cpp b/src/map.cpp index 4be094326..2439c7091 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -73,34 +73,30 @@ Map::~Map() /* Free all MapSectors */ - core::map::Iterator i = m_sectors.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map::iterator i = m_sectors.begin(); + i != m_sectors.end(); ++i) { - MapSector *sector = i.getNode()->getValue(); - delete sector; + delete i->second; } } void Map::addEventReceiver(MapEventReceiver *event_receiver) { - m_event_receivers.insert(event_receiver, false); + m_event_receivers.insert(event_receiver); } void Map::removeEventReceiver(MapEventReceiver *event_receiver) { - if(m_event_receivers.find(event_receiver) == NULL) - return; - m_event_receivers.remove(event_receiver); + m_event_receivers.erase(event_receiver); } void Map::dispatchEvent(MapEditEvent *event) { - for(core::map::Iterator - i = m_event_receivers.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = m_event_receivers.begin(); + i != m_event_receivers.end(); ++i) { - MapEventReceiver* event_receiver = i.getNode()->getKey(); - event_receiver->onMapEditEvent(event); + (*i)->onMapEditEvent(event); } } @@ -111,12 +107,12 @@ MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p) return sector; } - core::map::Node *n = m_sectors.find(p); + std::map::iterator n = m_sectors.find(p); - if(n == NULL) + if(n == m_sectors.end()) return NULL; - MapSector *sector = n->getValue(); + MapSector *sector = n->second; // Cache the last result m_sector_cache_p = p; @@ -236,9 +232,9 @@ void Map::setNode(v3s16 p, MapNode & n) values of from_nodes are lighting values. */ void Map::unspreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & light_sources, - core::map & modified_blocks) + std::map & from_nodes, + std::set & light_sources, + std::map & modified_blocks) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -256,9 +252,7 @@ void Map::unspreadLight(enum LightBank bank, u32 blockchangecount = 0; - core::map unlighted_nodes; - core::map::Iterator j; - j = from_nodes.getIterator(); + std::map unlighted_nodes; /* Initialize block cache @@ -268,9 +262,10 @@ void Map::unspreadLight(enum LightBank bank, // Cache this a bit, too bool block_checked_in_modified = false; - for(; j.atEnd() == false; j++) + for(std::map::iterator j = from_nodes.begin(); + j != from_nodes.end(); ++j) { - v3s16 pos = j.getNode()->getKey(); + v3s16 pos = j->first; v3s16 blockpos = getNodeBlockPos(pos); // Only fetch a new block if the block position has changed @@ -297,7 +292,7 @@ void Map::unspreadLight(enum LightBank bank, // Get node straight from the block MapNode n = block->getNode(relpos); - u8 oldlight = j.getNode()->getValue(); + u8 oldlight = j->second; // Loop through 6 neighbors for(u16 i=0; i<6; i++) @@ -354,7 +349,7 @@ void Map::unspreadLight(enum LightBank bank, n2.setLight(bank, 0, nodemgr); block->setNode(relpos, n2); - unlighted_nodes.insert(n2pos, current_light); + unlighted_nodes[n2pos] = current_light; changed = true; /* @@ -373,16 +368,16 @@ void Map::unspreadLight(enum LightBank bank, light_sources.remove(n2pos);*/ } else{ - light_sources.insert(n2pos, true); + light_sources.insert(n2pos); } // Add to modified_blocks if(changed == true && block_checked_in_modified == false) { // If the block is not found in modified_blocks, add. - if(modified_blocks.find(blockpos) == NULL) + if(modified_blocks.find(blockpos) == modified_blocks.end()) { - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; } block_checked_in_modified = true; } @@ -408,11 +403,11 @@ void Map::unspreadLight(enum LightBank bank, */ void Map::unLightNeighbors(enum LightBank bank, v3s16 pos, u8 lightwas, - core::map & light_sources, - core::map & modified_blocks) + std::set & light_sources, + std::map & modified_blocks) { - core::map from_nodes; - from_nodes.insert(pos, lightwas); + std::map from_nodes; + from_nodes[pos] = lightwas; unspreadLight(bank, from_nodes, light_sources, modified_blocks); } @@ -422,8 +417,8 @@ void Map::unLightNeighbors(enum LightBank bank, goes on recursively. */ void Map::spreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & modified_blocks) + std::set & from_nodes, + std::map & modified_blocks) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -441,9 +436,7 @@ void Map::spreadLight(enum LightBank bank, u32 blockchangecount = 0; - core::map lighted_nodes; - core::map::Iterator j; - j = from_nodes.getIterator(); + std::set lighted_nodes; /* Initialize block cache @@ -453,12 +446,10 @@ void Map::spreadLight(enum LightBank bank, // Cache this a bit, too bool block_checked_in_modified = false; - for(; j.atEnd() == false; j++) - //for(; j != from_nodes.end(); j++) + for(std::set::iterator j = from_nodes.begin(); + j != from_nodes.end(); ++j) { - v3s16 pos = j.getNode()->getKey(); - //v3s16 pos = *j; - //infostream<<"pos=("< undiminish_light(oldlight)) { - lighted_nodes.insert(n2pos, true); - //lighted_nodes.push_back(n2pos); + lighted_nodes.insert(n2pos); changed = true; } /* @@ -539,8 +529,7 @@ void Map::spreadLight(enum LightBank bank, { n2.setLight(bank, newlight, nodemgr); block->setNode(relpos, n2); - lighted_nodes.insert(n2pos, true); - //lighted_nodes.push_back(n2pos); + lighted_nodes.insert(n2pos); changed = true; } } @@ -549,9 +538,9 @@ void Map::spreadLight(enum LightBank bank, if(changed == true && block_checked_in_modified == false) { // If the block is not found in modified_blocks, add. - if(modified_blocks.find(blockpos) == NULL) + if(modified_blocks.find(blockpos) == modified_blocks.end()) { - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; } block_checked_in_modified = true; } @@ -577,10 +566,10 @@ void Map::spreadLight(enum LightBank bank, */ void Map::lightNeighbors(enum LightBank bank, v3s16 pos, - core::map & modified_blocks) + std::map & modified_blocks) { - core::map from_nodes; - from_nodes.insert(pos, true); + std::set from_nodes; + from_nodes.insert(pos); spreadLight(bank, from_nodes, modified_blocks); } @@ -635,7 +624,7 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p) Mud is turned into grass in where the sunlight stops. */ s16 Map::propagateSunlight(v3s16 start, - core::map & modified_blocks) + std::map & modified_blocks) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -662,7 +651,7 @@ s16 Map::propagateSunlight(v3s16 start, n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr); block->setNode(relpos, n); - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; } else { @@ -674,8 +663,8 @@ s16 Map::propagateSunlight(v3s16 start, } void Map::updateLighting(enum LightBank bank, - core::map & a_blocks, - core::map & modified_blocks) + std::map & a_blocks, + std::map & modified_blocks) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -688,22 +677,21 @@ void Map::updateLighting(enum LightBank bank, //bool debug=true; //u32 count_was = modified_blocks.size(); - core::map blocks_to_update; + std::map blocks_to_update; - core::map light_sources; + std::set light_sources; - core::map unlight_from; + std::map unlight_from; int num_bottom_invalid = 0; { //TimeTaker t("first stuff"); - core::map::Iterator i; - i = a_blocks.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map::iterator i = a_blocks.begin(); + i != a_blocks.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); + MapBlock *block = i->second; for(;;) { @@ -713,9 +701,8 @@ void Map::updateLighting(enum LightBank bank, v3s16 pos = block->getPos(); v3s16 posnodes = block->getPosRelative(); - modified_blocks.insert(pos, block); - - blocks_to_update.insert(pos, block); + modified_blocks[pos] = block; + blocks_to_update[pos] = block; /* Clear all light from block @@ -735,7 +722,7 @@ void Map::updateLighting(enum LightBank bank, // If node sources light, add to list u8 source = nodemgr->get(n).light_source; if(source != 0) - light_sources[p + posnodes] = true; + light_sources.insert(p + posnodes); // Collect borders for unlighting if((x==0 || x == MAP_BLOCKSIZE-1 @@ -744,7 +731,7 @@ void Map::updateLighting(enum LightBank bank, && oldlight != 0) { v3s16 p_map = p + posnodes; - unlight_from.insert(p_map, oldlight); + unlight_from[p_map] = oldlight; } } catch(InvalidPositionException &e) @@ -912,8 +899,8 @@ void Map::updateLighting(enum LightBank bank, //m_dout<<"Done ("< & a_blocks, - core::map & modified_blocks) +void Map::updateLighting(std::map & a_blocks, + std::map & modified_blocks) { updateLighting(LIGHTBANK_DAY, a_blocks, modified_blocks); updateLighting(LIGHTBANK_NIGHT, a_blocks, modified_blocks); @@ -921,11 +908,11 @@ void Map::updateLighting(core::map & a_blocks, /* Update information about whether day and night light differ */ - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); + MapBlock *block = i->second; block->expireDayNightDiff(); } } @@ -933,7 +920,7 @@ void Map::updateLighting(core::map & a_blocks, /* */ void Map::addNodeAndUpdate(v3s16 p, MapNode n, - core::map &modified_blocks) + std::map &modified_blocks) { INodeDefManager *ndef = m_gamedef->ndef(); @@ -952,7 +939,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, v3s16 bottompos = p + v3s16(0,-1,0); bool node_under_sunlight = true; - core::map light_sources; + std::set light_sources; /* Collect old node for rollback @@ -994,7 +981,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, v3s16 blockpos = getNodeBlockPos(p); MapBlock * block = getBlockNoCreate(blockpos); assert(block != NULL); - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; assert(isValidPosition(p)); @@ -1078,12 +1065,11 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, /* Update information about whether day and night light differ */ - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); - block->expireDayNightDiff(); + i->second->expireDayNightDiff(); } /* @@ -1132,7 +1118,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, /* */ void Map::removeNodeAndUpdate(v3s16 p, - core::map &modified_blocks) + std::map &modified_blocks) { INodeDefManager *ndef = m_gamedef->ndef(); @@ -1166,7 +1152,7 @@ void Map::removeNodeAndUpdate(v3s16 p, { } - core::map light_sources; + std::set light_sources; enum LightBank banks[] = { @@ -1214,7 +1200,7 @@ void Map::removeNodeAndUpdate(v3s16 p, v3s16 blockpos = getNodeBlockPos(p); MapBlock * block = getBlockNoCreate(blockpos); assert(block != NULL); - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; /* If the removed node was under sunlight, propagate the @@ -1270,12 +1256,11 @@ void Map::removeNodeAndUpdate(v3s16 p, /* Update information about whether day and night light differ */ - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); - block->expireDayNightDiff(); + i->second->expireDayNightDiff(); } /* @@ -1330,15 +1315,15 @@ bool Map::addNodeWithEvent(v3s16 p, MapNode n) bool succeeded = true; try{ - core::map modified_blocks; + std::map modified_blocks; addNodeAndUpdate(p, n, modified_blocks); // Copy modified_blocks to event - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - event.modified_blocks.insert(i.getNode()->getKey(), false); + event.modified_blocks.erase(i->first); } } catch(InvalidPositionException &e){ @@ -1358,15 +1343,15 @@ bool Map::removeNodeWithEvent(v3s16 p) bool succeeded = true; try{ - core::map modified_blocks; + std::map modified_blocks; removeNodeAndUpdate(p, modified_blocks); // Copy modified_blocks to event - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - event.modified_blocks.insert(i.getNode()->getKey(), false); + event.modified_blocks.erase(i->first); } } catch(InvalidPositionException &e){ @@ -1439,33 +1424,31 @@ bool Map::getDayNightDiff(v3s16 blockpos) Updates usage timers */ void Map::timerUpdate(float dtime, float unload_timeout, - core::list *unloaded_blocks) + std::list *unloaded_blocks) { bool save_before_unloading = (mapType() == MAPTYPE_SERVER); // Profile modified reasons Profiler modprofiler; - core::list sector_deletion_queue; + std::list sector_deletion_queue; u32 deleted_blocks_count = 0; u32 saved_blocks_count = 0; u32 block_count_all = 0; - core::map::Iterator si; - beginSave(); - si = m_sectors.getIterator(); - for(; si.atEnd() == false; si++) + for(std::map::iterator si = m_sectors.begin(); + si != m_sectors.end(); ++si) { - MapSector *sector = si.getNode()->getValue(); + MapSector *sector = si->second; bool all_blocks_deleted = true; - core::list blocks; + std::list blocks; sector->getBlocks(blocks); - for(core::list::Iterator i = blocks.begin(); - i != blocks.end(); i++) + for(std::list::iterator i = blocks.begin(); + i != blocks.end(); ++i) { MapBlock *block = (*i); @@ -1501,7 +1484,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, if(all_blocks_deleted) { - sector_deletion_queue.push_back(si.getNode()->getKey()); + sector_deletion_queue.push_back(si->first); } } endSave(); @@ -1526,17 +1509,17 @@ void Map::timerUpdate(float dtime, float unload_timeout, } } -void Map::deleteSectors(core::list &list) +void Map::deleteSectors(std::list &list) { - core::list::Iterator j; - for(j=list.begin(); j!=list.end(); j++) + for(std::list::iterator j = list.begin(); + j != list.end(); ++j) { MapSector *sector = m_sectors[*j]; // If sector is in sector cache, remove it from there if(m_sector_cache == sector) m_sector_cache = NULL; // Remove from map and delete - m_sectors.remove(*j); + m_sectors.erase(*j); delete sector; } } @@ -1642,7 +1625,7 @@ const v3s16 g_7dirs[7] = #define D_TOP 6 #define D_SELF 1 -void Map::transformLiquidsFinite(core::map & modified_blocks) +void Map::transformLiquidsFinite(std::map & modified_blocks) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -1663,7 +1646,7 @@ void Map::transformLiquidsFinite(core::map & modified_blocks) UniqueQueue must_reflow, must_reflow_second; // List of MapBlocks that will require a lighting update (due to lava) - core::map lighting_modified_blocks; + std::map lighting_modified_blocks; while(m_transforming_liquid.size() > 0) { @@ -1904,7 +1887,7 @@ void Map::transformLiquidsFinite(core::map & modified_blocks) v3s16 blockpos = getNodeBlockPos(p0); MapBlock *block = getBlockNoCreateNoEx(blockpos); if(block != NULL) { - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; // If node emits light, MapBlock requires lighting update if(nodemgr->get(n0).light_source != 0) lighting_modified_blocks[block->getPos()] = block; @@ -1925,11 +1908,11 @@ void Map::transformLiquidsFinite(core::map & modified_blocks) updateLighting(lighting_modified_blocks, modified_blocks); } -void Map::transformLiquids(core::map & modified_blocks) +void Map::transformLiquids(std::map & modified_blocks) { if (g_settings->getBool("liquid_finite")) return Map::transformLiquidsFinite(modified_blocks); - + INodeDefManager *nodemgr = m_gamedef->ndef(); DSTACK(__FUNCTION_NAME); @@ -1945,7 +1928,7 @@ void Map::transformLiquids(core::map & modified_blocks) UniqueQueue must_reflow; // List of MapBlocks that will require a lighting update (due to lava) - core::map lighting_modified_blocks; + std::map lighting_modified_blocks; while(m_transforming_liquid.size() != 0) { @@ -2165,7 +2148,7 @@ void Map::transformLiquids(core::map & modified_blocks) v3s16 blockpos = getNodeBlockPos(p0); MapBlock *block = getBlockNoCreateNoEx(blockpos); if(block != NULL) { - modified_blocks.insert(blockpos, block); + modified_blocks[blockpos] = block; // If node emits light, MapBlock requires lighting update if(nodemgr->get(n0).light_source != 0) lighting_modified_blocks[block->getPos()] = block; @@ -2571,7 +2554,7 @@ bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) } MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, - core::map &changed_blocks) + std::map &changed_blocks) { v3s16 blockpos_min = data->blockpos_min; v3s16 blockpos_max = data->blockpos_max; @@ -2676,10 +2659,10 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, /* Go through changed blocks */ - for(core::map::Iterator i = changed_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator i = changed_blocks.begin(); + i != changed_blocks.end(); ++i) { - MapBlock *block = i.getNode()->getValue(); + MapBlock *block = i->second; assert(block); /* Update day/night difference cache of the MapBlocks @@ -2797,7 +2780,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d) /* Insert to container */ - m_sectors.insert(p2d, sector); + m_sectors[p2d] = sector; return sector; } @@ -2808,7 +2791,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d) */ MapBlock * ServerMap::generateBlock( v3s16 p, - core::map &modified_blocks + std::map &modified_blocks ) { DSTACKF("%s: p=(%d,%d,%d)", __FUNCTION_NAME, p.X, p.Y, p.Z); @@ -3008,7 +2991,7 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank) } /*if(allow_generate) { - core::map modified_blocks; + std::map modified_blocks; MapBlock *block = generateBlock(p, modified_blocks); if(block) { @@ -3017,11 +3000,11 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank) event.p = p; // Copy modified_blocks to event - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - event.modified_blocks.insert(i.getNode()->getKey(), false); + event.modified_blocks.erase(i->first); } // Queue event @@ -3262,10 +3245,10 @@ void ServerMap::save(ModifiedState save_level) // Don't do anything with sqlite unless something is really saved bool save_started = false; - core::map::Iterator i = m_sectors.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map::iterator i = m_sectors.begin(); + i != m_sectors.end(); ++i) { - ServerMapSector *sector = (ServerMapSector*)i.getNode()->getValue(); + ServerMapSector *sector = (ServerMapSector*)i->second; assert(sector->getId() == MAPSECTOR_SERVER); if(sector->differs_from_disk || save_level == MOD_STATE_CLEAN) @@ -3273,11 +3256,11 @@ void ServerMap::save(ModifiedState save_level) saveSectorMeta(sector); sector_meta_count++; } - core::list blocks; + std::list blocks; sector->getBlocks(blocks); - core::list::Iterator j; - for(j=blocks.begin(); j!=blocks.end(); j++) + for(std::list::iterator j = blocks.begin(); + j != blocks.end(); ++j) { MapBlock *block = *j; @@ -3350,7 +3333,7 @@ v3s16 ServerMap::getIntegerAsBlock(sqlite3_int64 i) return v3s16(x,y,z); } -void ServerMap::listAllLoadableBlocks(core::list &dst) +void ServerMap::listAllLoadableBlocks(std::list &dst) { if(loadFromFolders()){ errorstream<<"Map::listAllLoadableBlocks(): Result will be missing " @@ -3487,7 +3470,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load <<" Continuing with a sector with no metadata." <::Node *n; + std::map::iterator n; n = m_loaded_blocks.find(p); - if(n != NULL) + if(n != m_loaded_blocks.end()) continue; bool block_data_inexistent = false; @@ -4017,7 +4000,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) if(block_data_inexistent) { flags |= VMANIP_BLOCK_DATA_INEXIST; - + VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1)); // Fill with VOXELFLAG_INEXISTENT for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) @@ -4033,7 +4016,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) flags |= VMANIP_BLOCK_CONTAINS_CIGNORE; }*/ - m_loaded_blocks.insert(p, flags); + m_loaded_blocks[p] = flags; } //infostream<<"emerge done"< & modified_blocks) + (std::map & modified_blocks) { if(m_area.getExtent() == v3s16(0,0,0)) return; @@ -4156,9 +4139,9 @@ void ManualMapVoxelManipulator::initialEmerge( u8 flags = 0; MapBlock *block; v3s16 p(x,y,z); - core::map::Node *n; + std::map::iterator n; n = m_loaded_blocks.find(p); - if(n != NULL) + if(n != m_loaded_blocks.end()) continue; bool block_data_inexistent = false; @@ -4199,12 +4182,12 @@ void ManualMapVoxelManipulator::initialEmerge( flags |= VMANIP_BLOCK_CONTAINS_CIGNORE; }*/ - m_loaded_blocks.insert(p, flags); + m_loaded_blocks[p] = flags; } } void ManualMapVoxelManipulator::blitBackAll( - core::map * modified_blocks) + std::map * modified_blocks) { if(m_area.getExtent() == v3s16(0,0,0)) return; @@ -4212,37 +4195,22 @@ void ManualMapVoxelManipulator::blitBackAll( /* Copy data of all blocks */ - for(core::map::Iterator - i = m_loaded_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_loaded_blocks.begin(); + i != m_loaded_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - u8 flags = i.getNode()->getValue(); - - bool existed = !(flags & VMANIP_BLOCK_DATA_INEXIST); - if(existed == false) - { - // The Great Bug was found using this - /*infostream<<"ManualMapVoxelManipulator::blitBackAll: " - <<"Inexistent ("<first; MapBlock *block = m_map->getBlockNoCreateNoEx(p); - if(block == NULL) + bool existed = !(i->second & VMANIP_BLOCK_DATA_INEXIST); + if(existed == false) { - infostream<<"WARNING: "<<__FUNCTION_NAME - <<": got NULL block " - <<"("<copyFrom(*this); - + if(modified_blocks) - modified_blocks->insert(p, block); + (*modified_blocks)[p] = block; } } diff --git a/src/map.h b/src/map.h index d356da2d1..3833cceb4 100644 --- a/src/map.h +++ b/src/map.h @@ -25,6 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include +#include +#include #include "irrlichttypes_bloated.h" #include "mapnode.h" @@ -75,7 +78,7 @@ struct MapEditEvent MapEditEventType type; v3s16 p; MapNode n; - core::map modified_blocks; + std::set modified_blocks; u16 already_known_by_peer; MapEditEvent(): @@ -90,14 +93,7 @@ struct MapEditEvent event->type = type; event->p = p; event->n = n; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd()==false; i++) - { - v3s16 p = i.getNode()->getKey(); - bool v = i.getNode()->getValue(); - event->modified_blocks.insert(p, v); - } + event->modified_blocks = modified_blocks; return event; } @@ -117,11 +113,11 @@ struct MapEditEvent case MEET_OTHER: { VoxelArea a; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = *i; v3s16 np1 = p*MAP_BLOCKSIZE; v3s16 np2 = np1 + v3s16(1,1,1)*MAP_BLOCKSIZE - v3s16(1,1,1); a.addPoint(np1); @@ -186,7 +182,7 @@ public: */ virtual MapSector * emergeSector(v2s16 p){ return NULL; } virtual MapSector * emergeSector(v2s16 p, - core::map &changed_blocks){ return NULL; } + std::map &changed_blocks){ return NULL; } // Returns InvalidPositionException if not found MapBlock * getBlockNoCreate(v3s16 p); @@ -212,42 +208,42 @@ public: MapNode getNodeNoEx(v3s16 p); void unspreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & light_sources, - core::map & modified_blocks); + std::map & from_nodes, + std::set & light_sources, + std::map & modified_blocks); void unLightNeighbors(enum LightBank bank, v3s16 pos, u8 lightwas, - core::map & light_sources, - core::map & modified_blocks); + std::set & light_sources, + std::map & modified_blocks); void spreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & modified_blocks); + std::set & from_nodes, + std::map & modified_blocks); void lightNeighbors(enum LightBank bank, v3s16 pos, - core::map & modified_blocks); + std::map & modified_blocks); v3s16 getBrightestNeighbour(enum LightBank bank, v3s16 p); s16 propagateSunlight(v3s16 start, - core::map & modified_blocks); + std::map & modified_blocks); void updateLighting(enum LightBank bank, - core::map & a_blocks, - core::map & modified_blocks); + std::map & a_blocks, + std::map & modified_blocks); - void updateLighting(core::map & a_blocks, - core::map & modified_blocks); + void updateLighting(std::map & a_blocks, + std::map & modified_blocks); /* These handle lighting but not faces. */ void addNodeAndUpdate(v3s16 p, MapNode n, - core::map &modified_blocks); + std::map &modified_blocks); void removeNodeAndUpdate(v3s16 p, - core::map &modified_blocks); + std::map &modified_blocks); /* Wrappers for the latter ones. @@ -281,12 +277,12 @@ public: Saves modified blocks before unloading on MAPTYPE_SERVER. */ void timerUpdate(float dtime, float unload_timeout, - core::list *unloaded_blocks=NULL); + std::list *unloaded_blocks=NULL); // Deletes sectors and their blocks from memory // Takes cache into account // If deleted sector is in sector cache, clears cache - void deleteSectors(core::list &list); + void deleteSectors(std::list &list); #if 0 /* @@ -301,8 +297,8 @@ public: // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: " virtual void PrintInfo(std::ostream &out); - void transformLiquids(core::map & modified_blocks); - void transformLiquidsFinite(core::map & modified_blocks); + void transformLiquids(std::map & modified_blocks); + void transformLiquidsFinite(std::map & modified_blocks); /* Node metadata @@ -325,7 +321,7 @@ public: /* Misc. */ - core::map *getSectorsPtr(){return &m_sectors;} + std::map *getSectorsPtr(){return &m_sectors;} /* Variables @@ -340,9 +336,9 @@ protected: IGameDef *m_gamedef; - core::map m_event_receivers; + std::set m_event_receivers; - core::map m_sectors; + std::map m_sectors; // Be sure to set this to NULL when the cached sector is deleted MapSector *m_sector_cache; @@ -385,13 +381,7 @@ public: */ bool initBlockMake(BlockMakeData *data, v3s16 blockpos); MapBlock *finishBlockMake(BlockMakeData *data, - core::map &changed_blocks); - - // A non-threaded wrapper to the above - DEFUNCT -/* MapBlock * generateBlock( - v3s16 p, - core::map &modified_blocks - );*/ + std::map &changed_blocks); /* Get a block from somewhere. @@ -444,9 +434,7 @@ public: void save(ModifiedState save_level); //void loadAll(); - - void listAllLoadableBlocks(core::list &dst); - + void listAllLoadableBlocks(std::list &dst); // Saves map seed and possibly other stuff void saveMapMeta(); void loadMapMeta(); @@ -538,15 +526,15 @@ public: virtual void emerge(VoxelArea a, s32 caller_id=-1); - void blitBack(core::map & modified_blocks); - + void blitBack(std::map & modified_blocks); + +protected: + Map *m_map; /* key = blockpos value = flags describing the block */ - core::map m_loaded_blocks; -protected: - Map *m_map; + std::map m_loaded_blocks; }; class ManualMapVoxelManipulator : public MapVoxelManipulator @@ -563,7 +551,7 @@ public: void initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max); // This is much faster with big chunks of generated data - void blitBackAll(core::map * modified_blocks); + void blitBackAll(std::map * modified_blocks); protected: bool m_create_area; diff --git a/src/mapblock.cpp b/src/mapblock.cpp index a6e9b3951..dd95ab77f 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -168,7 +168,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p) if black_air_left!=NULL, it is set to true if non-sunlighted air is left in block. */ -bool MapBlock::propagateSunlight(core::map & light_sources, +bool MapBlock::propagateSunlight(std::set & light_sources, bool remove_light, bool *black_air_left) { INodeDefManager *nodemgr = m_gamedef->ndef(); @@ -287,7 +287,7 @@ bool MapBlock::propagateSunlight(core::map & light_sources, if(diminish_light(current_light) != 0) { - light_sources.insert(pos_relative + pos, true); + light_sources.insert(pos_relative + pos); } if(current_light == 0 && stopped_to_solid_object) diff --git a/src/mapblock.h b/src/mapblock.h index 692b54318..05bb944a6 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include "debug.h" #include "irrlichttypes.h" #include "irr_v3d.h" @@ -352,7 +353,7 @@ public: } // See comments in mapblock.cpp - bool propagateSunlight(core::map & light_sources, + bool propagateSunlight(std::set & light_sources, bool remove_light=false, bool *black_air_left=NULL); // Copies data to VoxelManipulator to getPosRelative() diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index f4d57922a..d098065f8 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -445,7 +445,7 @@ struct FastFace }; static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, - v3f p, v3s16 dir, v3f scale, u8 light_source, core::array &dest) + v3f p, v3s16 dir, v3f scale, u8 light_source, std::vector &dest) { FastFace face; @@ -745,7 +745,7 @@ static void updateFastFaceRow( v3f translate_dir_f, v3s16 face_dir, v3f face_dir_f, - core::array &dest) + std::vector &dest) { v3s16 p = startpos; @@ -897,7 +897,7 @@ static void updateFastFaceRow( } static void updateAllFastFaceRows(MeshMakeData *data, - core::array &dest) + std::vector &dest) { /* Go through every y,z and get top(y+) faces in rows of x+ @@ -962,7 +962,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): // 24-155ms for MAP_BLOCKSIZE=32 (NOTE: probably outdated) //TimeTaker timer1("MapBlockMesh()"); - core::array fastfaces_new; + std::vector fastfaces_new; /* We are including the faces of the trailing edges of the block. @@ -1124,8 +1124,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): m_mesh->addMeshBuffer(buf); // Mesh grabbed it buf->drop(); - buf->append(p.vertices.pointer(), p.vertices.size(), - p.indices.pointer(), p.indices.size()); + buf->append(&p.vertices[0], p.vertices.size(), + &p.indices[0], p.indices.size()); } /* diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 5b33990c6..c75984021 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -143,13 +143,13 @@ private: struct PreMeshBuffer { TileSpec tile; - core::array indices; - core::array vertices; + std::vector indices; + std::vector vertices; }; struct MeshCollector { - core::array prebuffers; + std::vector prebuffers; void append(const TileSpec &material, const video::S3DVertex *vertices, u32 numVertices, diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4be47689b..1c59213ba 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -2275,8 +2275,8 @@ void make_block(BlockMakeData *data) { enum LightBank bank = banks[i]; - core::map light_sources; - core::map unlight_from; + std::set light_sources; + std::map unlight_from; voxalgo::clearLightAndCollectSources(vmanip, a, bank, ndef, light_sources, unlight_from); diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index bf12f3099..f4366c154 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -1422,8 +1422,8 @@ void MapgenV6::makeChunk(BlockMakeData *data) { enum LightBank bank = banks[i]; - core::map light_sources; - core::map unlight_from; + std::set light_sources; + std::map unlight_from; voxalgo::clearLightAndCollectSources(vmanip, a, bank, ndef, light_sources, unlight_from); diff --git a/src/mapsector.cpp b/src/mapsector.cpp index 108effa79..ebb050ec3 100644 --- a/src/mapsector.cpp +++ b/src/mapsector.cpp @@ -45,10 +45,10 @@ void MapSector::deleteBlocks() m_block_cache = NULL; // Delete all - core::map::Iterator i = m_blocks.getIterator(); - for(; i.atEnd() == false; i++) + for(std::map::iterator i = m_blocks.begin(); + i != m_blocks.end(); ++i) { - delete i.getNode()->getValue(); + delete i->second; } // Clear container @@ -64,14 +64,14 @@ MapBlock * MapSector::getBlockBuffered(s16 y) } // If block doesn't exist, return NULL - core::map::Node *n = m_blocks.find(y); - if(n == NULL) + std::map::iterator n = m_blocks.find(y); + if(n == m_blocks.end()) { block = NULL; } // If block exists, return it else{ - block = n->getValue(); + block = n->second; } // Cache the last result @@ -101,7 +101,7 @@ MapBlock * MapSector::createBlankBlock(s16 y) { MapBlock *block = createBlankBlockNoInsert(y); - m_blocks.insert(y, block); + m_blocks[y] = block; return block; } @@ -119,7 +119,7 @@ void MapSector::insertBlock(MapBlock *block) assert(p2d == m_pos); // Insert into container - m_blocks.insert(block_y, block); + m_blocks[block_y] = block; } void MapSector::deleteBlock(MapBlock *block) @@ -130,23 +130,18 @@ void MapSector::deleteBlock(MapBlock *block) m_block_cache = NULL; // Remove from container - m_blocks.remove(block_y); + m_blocks.erase(block_y); // Delete delete block; } -void MapSector::getBlocks(core::list &dest) +void MapSector::getBlocks(std::list &dest) { - core::list ref_list; - - core::map::Iterator bi; - - bi = m_blocks.getIterator(); - for(; bi.atEnd() == false; bi++) + for(std::map::iterator bi = m_blocks.begin(); + bi != m_blocks.end(); ++bi) { - MapBlock *b = bi.getNode()->getValue(); - dest.push_back(b); + dest.push_back(bi->second); } } @@ -189,7 +184,7 @@ ServerMapSector* ServerMapSector::deSerialize( std::istream &is, Map *parent, v2s16 p2d, - core::map & sectors, + std::map & sectors, IGameDef *gamedef ) { @@ -219,22 +214,22 @@ ServerMapSector* ServerMapSector::deSerialize( ServerMapSector *sector = NULL; - core::map::Node *n = sectors.find(p2d); + std::map::iterator n = sectors.find(p2d); - if(n != NULL) + if(n != sectors.end()) { dstream<<"WARNING: deSerializing existent sectors not supported " "at the moment, because code hasn't been tested." <getValue(); + MapSector *sector = n->second; assert(sector->getId() == MAPSECTOR_SERVER); return (ServerMapSector*)sector; } else { sector = new ServerMapSector(parent, p2d, gamedef); - sectors.insert(p2d, sector); + sectors[p2d] = sector; } /* diff --git a/src/mapsector.h b/src/mapsector.h index 88fc76b57..4f2b3f31f 100644 --- a/src/mapsector.h +++ b/src/mapsector.h @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include "exceptions.h" #include +#include +#include class MapBlock; class Map; @@ -60,7 +62,7 @@ public: void deleteBlock(MapBlock *block); - void getBlocks(core::list &dest); + void getBlocks(std::list &dest); // Always false at the moment, because sector contains no metadata. bool differs_from_disk; @@ -68,7 +70,7 @@ public: protected: // The pile of MapBlocks - core::map m_blocks; + std::map m_blocks; Map *m_parent; // Position on parent (in MapBlock widths) @@ -110,7 +112,7 @@ public: std::istream &is, Map *parent, v2s16 p2d, - core::map & sectors, + std::map & sectors, IGameDef *gamedef ); diff --git a/src/mods.h b/src/mods.h index 9761a9103..32bcfb471 100644 --- a/src/mods.h +++ b/src/mods.h @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include class ModError : public std::exception { @@ -68,7 +69,6 @@ struct ModSpec {} }; - std::map getModsInPath(std::string path); // expands modpack contents, but does not replace them. @@ -140,6 +140,4 @@ private: }; - #endif - diff --git a/src/object_properties.h b/src/object_properties.h index bde38bd66..eeb397efa 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include #include +#include struct ObjectProperties { @@ -35,8 +36,8 @@ struct ObjectProperties std::string visual; std::string mesh; v2f visual_size; - core::array textures; - core::array colors; + std::vector textures; + std::vector colors; v2s16 spritediv; v2s16 initial_sprite_basepos; bool is_visible; diff --git a/src/profiler.h b/src/profiler.h index b9fa22485..56b026880 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -45,21 +45,21 @@ public: JMutexAutoLock lock(m_mutex); { /* No average shall have been used; mark add used as -2 */ - core::map::Node *n = m_avgcounts.find(name); - if(n == NULL) + std::map::iterator n = m_avgcounts.find(name); + if(n == m_avgcounts.end()) m_avgcounts[name] = -2; else{ - if(n->getValue() == -1) - n->setValue(-2); - assert(n->getValue() == -2); + if(n->second == -1) + n->second = -2; + assert(n->second == -2); } } { - core::map::Node *n = m_data.find(name); - if(n == NULL) + std::map::iterator n = m_data.find(name); + if(n == m_data.end()) m_data[name] = value; else - n->setValue(n->getValue() + value); + n->second += value; } } @@ -67,35 +67,32 @@ public: { JMutexAutoLock lock(m_mutex); { - core::map::Node *n = m_avgcounts.find(name); - if(n == NULL) + std::map::iterator n = m_avgcounts.find(name); + if(n == m_avgcounts.end()) m_avgcounts[name] = 1; else{ /* No add shall have been used */ - assert(n->getValue() != -2); - if(n->getValue() <= 0) - n->setValue(1); - else - n->setValue(n->getValue() + 1); + assert(n->second != -2); + n->second = std::max(n->second, 0) + 1; } } { - core::map::Node *n = m_data.find(name); - if(n == NULL) + std::map::iterator n = m_data.find(name); + if(n == m_data.end()) m_data[name] = value; else - n->setValue(n->getValue() + value); + n->second += value; } } void clear() { JMutexAutoLock lock(m_mutex); - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_data.begin(); + i != m_data.end(); ++i) { - i.getNode()->setValue(0); + i->second = 0; } m_avgcounts.clear(); } @@ -112,9 +109,9 @@ public: u32 minindex, maxindex; paging(m_data.size(), page, pagecount, minindex, maxindex); - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_data.begin(); + i != m_data.end(); ++i) { if(maxindex == 0) break; @@ -126,12 +123,12 @@ public: continue; } - std::string name = i.getNode()->getKey(); + std::string name = i->first; int avgcount = 1; - core::map::Node *n = m_avgcounts.find(name); - if(n){ - if(n->getValue() >= 1) - avgcount = n->getValue(); + std::map::iterator n = m_avgcounts.find(name); + if(n != m_avgcounts.end()){ + if(n->second >= 1) + avgcount = n->second; } o<<" "<getValue() / avgcount); + o<<(i->second / avgcount); o< m_data; - core::map m_avgcounts; + std::map m_data; + std::map m_avgcounts; std::map m_graphvalues; }; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 074a2eb0d..04af4eb22 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -895,24 +895,24 @@ static int l_get_modpath(lua_State *L) static int l_get_modnames(lua_State *L) { // Get a list of mods - core::list mods_unsorted, mods_sorted; + std::list mods_unsorted, mods_sorted; get_server(L)->getModNames(mods_unsorted); // Take unsorted items from mods_unsorted and sort them into // mods_sorted; not great performance but the number of mods on a // server will likely be small. - for(core::list::Iterator i = mods_unsorted.begin(); - i != mods_unsorted.end(); i++) + for(std::list::iterator i = mods_unsorted.begin(); + i != mods_unsorted.end(); ++i) { bool added = false; - for(core::list::Iterator x = mods_sorted.begin(); - x != mods_unsorted.end(); x++) + for(std::list::iterator x = mods_sorted.begin(); + x != mods_unsorted.end(); ++x) { // I doubt anybody using Minetest will be using // anything not ASCII based :) if((*i).compare(*x) <= 0) { - mods_sorted.insert_before(x, *i); + mods_sorted.insert(x, *i); added = true; break; } @@ -929,7 +929,7 @@ static int l_get_modnames(lua_State *L) // Package them up for Lua lua_newtable(L); int new_table = lua_gettop(L); - core::list::Iterator i = mods_sorted.begin(); + std::list::iterator i = mods_sorted.begin(); while(i != mods_sorted.end()) { lua_pushvalue(L, insertion_func); @@ -939,7 +939,7 @@ static int l_get_modnames(lua_State *L) { script_error(L, "error: %s", lua_tostring(L, -1)); } - i++; + ++i; } return 1; } diff --git a/src/scriptapi_env.cpp b/src/scriptapi_env.cpp index d54a6ce01..4e068e377 100644 --- a/src/scriptapi_env.cpp +++ b/src/scriptapi_env.cpp @@ -532,10 +532,10 @@ int EnvRef::l_find_node_near(lua_State *L) } for(int d=1; d<=radius; d++){ - core::list list; + std::list list; getFacePositions(list, d); - for(core::list::Iterator i = list.begin(); - i != list.end(); i++){ + for(std::list::iterator i = list.begin(); + i != list.end(); ++i){ v3s16 p = pos + (*i); content_t c = env->getMap().getNodeNoEx(p).getContent(); if(filter.count(c) != 0){ diff --git a/src/server.cpp b/src/server.cpp index 41a7a4289..d699dc9d2 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -126,7 +126,7 @@ v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const } void RemoteClient::GetNextBlocks(Server *server, float dtime, - core::array &dest) + std::vector &dest) { DSTACK(__FUNCTION_NAME); @@ -274,11 +274,11 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Get the border/face dot coordinates of a "d-radiused" box */ - core::list list; + std::list list; getFacePositions(list, d); - core::list::Iterator li; - for(li=list.begin(); li!=list.end(); li++) + std::list::iterator li; + for(li=list.begin(); li!=list.end(); ++li) { v3s16 p = *li + center; @@ -305,7 +305,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, } // Don't send blocks that are currently being transferred - if(m_blocks_sending.find(p) != NULL) + if(m_blocks_sending.find(p) != m_blocks_sending.end()) continue; /* @@ -382,7 +382,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Don't send already sent blocks */ { - if(m_blocks_sent.find(p) != NULL) + if(m_blocks_sent.find(p) != m_blocks_sent.end()) { continue; } @@ -554,21 +554,21 @@ queue_full_break: void RemoteClient::GotBlock(v3s16 p) { - if(m_blocks_sending.find(p) != NULL) - m_blocks_sending.remove(p); + if(m_blocks_sending.find(p) != m_blocks_sending.end()) + m_blocks_sending.erase(p); else { /*infostream<<"RemoteClient::GotBlock(): Didn't find in" " m_blocks_sending"< &blocks) +void RemoteClient::SetBlocksNotSent(std::map &blocks) { m_nearest_unsent_d = 0; - for(core::map::Iterator - i = blocks.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = blocks.begin(); + i != blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); + v3s16 p = i->first; - if(m_blocks_sending.find(p) != NULL) - m_blocks_sending.remove(p); - if(m_blocks_sent.find(p) != NULL) - m_blocks_sent.remove(p); + if(m_blocks_sending.find(p) != m_blocks_sending.end()) + m_blocks_sending.erase(p); + if(m_blocks_sent.find(p) != m_blocks_sent.end()) + m_blocks_sent.erase(p); } } @@ -854,13 +854,13 @@ Server::~Server() /* Send the message to clients */ - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Get client and check that it is valid - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; @@ -909,13 +909,13 @@ Server::~Server() { JMutexAutoLock clientslock(m_con_mutex); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Delete client - delete i.getNode()->getValue(); + delete i->second; } } @@ -1073,11 +1073,11 @@ void Server::AsyncRunStep() //JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock conlock(m_con_mutex); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; SharedBuffer data = makePacket_TOCLIENT_TIME_OF_DAY( m_env->getTimeOfDay(), g_settings->getFloat("time_speed")); // Send as reliable @@ -1117,11 +1117,11 @@ void Server::AsyncRunStep() ScopeProfiler sp(g_profiler, "Server: handle players"); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; PlayerSAO *playersao = getPlayerSAO(client->peer_id); if(playersao == NULL) continue; @@ -1161,7 +1161,7 @@ void Server::AsyncRunStep() ScopeProfiler sp(g_profiler, "Server: liquid transform"); - core::map modified_blocks; + std::map modified_blocks; m_env->getMap().transformLiquids(modified_blocks); #if 0 /* @@ -1186,11 +1186,11 @@ void Server::AsyncRunStep() JMutexAutoLock lock2(m_con_mutex); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; if(modified_blocks.size() > 0) { @@ -1212,12 +1212,12 @@ void Server::AsyncRunStep() m_clients_number = 0; if(m_clients.size() != 0) infostream<<"Players:"<::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { //u16 peer_id = i.getNode()->getKey(); - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; Player *player = m_env->getPlayer(client->peer_id); if(player==NULL) continue; @@ -1259,11 +1259,11 @@ void Server::AsyncRunStep() s16 radius = g_settings->getS16("active_object_send_range_blocks"); radius *= MAP_BLOCKSIZE; - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; // If definitions and textures have not been sent, don't // send objects either @@ -1281,8 +1281,8 @@ void Server::AsyncRunStep() } v3s16 pos = floatToInt(player->getPosition(), BS); - core::map removed_objects; - core::map added_objects; + std::set removed_objects; + std::set added_objects; m_env->getRemovedActiveObjects(pos, radius, client->m_known_objects, removed_objects); m_env->getAddedActiveObjects(pos, radius, @@ -1302,20 +1302,20 @@ void Server::AsyncRunStep() // Handle removed objects writeU16((u8*)buf, removed_objects.size()); data_buffer.append(buf, 2); - for(core::map::Iterator - i = removed_objects.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = removed_objects.begin(); + i != removed_objects.end(); ++i) { // Get object - u16 id = i.getNode()->getKey(); + u16 id = *i; ServerActiveObject* obj = m_env->getActiveObject(id); // Add to data buffer for sending - writeU16((u8*)buf, i.getNode()->getKey()); + writeU16((u8*)buf, id); data_buffer.append(buf, 2); // Remove from known objects - client->m_known_objects.remove(i.getNode()->getKey()); + client->m_known_objects.erase(id); if(obj && obj->m_known_by_count > 0) obj->m_known_by_count--; @@ -1324,12 +1324,12 @@ void Server::AsyncRunStep() // Handle added objects writeU16((u8*)buf, added_objects.size()); data_buffer.append(buf, 2); - for(core::map::Iterator - i = added_objects.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = added_objects.begin(); + i != added_objects.end(); ++i) { // Get object - u16 id = i.getNode()->getKey(); + u16 id = *i; ServerActiveObject* obj = m_env->getActiveObject(id); // Get object type @@ -1353,7 +1353,7 @@ void Server::AsyncRunStep() data_buffer.append(serializeLongString("")); // Add to known objects - client->m_known_objects.insert(i.getNode()->getKey(), false); + client->m_known_objects.insert(id); if(obj) obj->m_known_by_count++; @@ -1412,7 +1412,7 @@ void Server::AsyncRunStep() // Key = object id // Value = data sent by object - core::map* > buffered_messages; + std::map* > buffered_messages; // Get active object messages from environment for(;;) @@ -1421,43 +1421,43 @@ void Server::AsyncRunStep() if(aom.id == 0) break; - core::list* message_list = NULL; - core::map* >::Node *n; + std::list* message_list = NULL; + std::map* >::iterator n; n = buffered_messages.find(aom.id); - if(n == NULL) + if(n == buffered_messages.end()) { - message_list = new core::list; - buffered_messages.insert(aom.id, message_list); + message_list = new std::list; + buffered_messages[aom.id] = message_list; } else { - message_list = n->getValue(); + message_list = n->second; } message_list->push_back(aom); } // Route data to every client - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; std::string reliable_data; std::string unreliable_data; // Go through all objects in message buffer - for(core::map* >::Iterator - j = buffered_messages.getIterator(); - j.atEnd()==false; j++) + for(std::map* >::iterator + j = buffered_messages.begin(); + j != buffered_messages.end(); ++j) { // If object is not known by client, skip it - u16 id = j.getNode()->getKey(); - if(client->m_known_objects.find(id) == NULL) + u16 id = j->first; + if(client->m_known_objects.find(id) == client->m_known_objects.end()) continue; // Get message list of object - core::list* list = j.getNode()->getValue(); + std::list* list = j->second; // Go through every message - for(core::list::Iterator - k = list->begin(); k != list->end(); k++) + for(std::list::iterator + k = list->begin(); k != list->end(); ++k) { // Compose the full new data with header ActiveObjectMessage aom = *k; @@ -1508,11 +1508,11 @@ void Server::AsyncRunStep() } // Clear buffered_messages - for(core::map* >::Iterator - i = buffered_messages.getIterator(); - i.atEnd()==false; i++) + for(std::map* >::iterator + i = buffered_messages.begin(); + i != buffered_messages.end(); ++i) { - delete i.getNode()->getValue(); + delete i->second; } } @@ -1546,7 +1546,7 @@ void Server::AsyncRunStep() // Players far away from the change are stored here. // Instead of sending the changes, MapBlocks are set not sent // for them. - core::list far_players; + std::list far_players; if(event->type == MEET_ADDNODE) { @@ -1580,12 +1580,11 @@ void Server::AsyncRunStep() { infostream<<"Server: MEET_OTHER"<::Iterator - i = event->modified_blocks.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = event->modified_blocks.begin(); + i != event->modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - setBlockNotSent(p); + setBlockNotSent(*i); } } else @@ -1601,19 +1600,18 @@ void Server::AsyncRunStep() if(far_players.size() > 0) { // Convert list format to that wanted by SetBlocksNotSent - core::map modified_blocks2; - for(core::map::Iterator - i = event->modified_blocks.getIterator(); - i.atEnd()==false; i++) + std::map modified_blocks2; + for(std::set::iterator + i = event->modified_blocks.begin(); + i != event->modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - modified_blocks2.insert(p, - m_env->getMap().getBlockNoCreateNoEx(p)); + modified_blocks2[*i] = + m_env->getMap().getBlockNoCreateNoEx(*i); } // Set blocks not sent - for(core::list::Iterator + for(std::list::iterator i = far_players.begin(); - i != far_players.end(); i++) + i != far_players.end(); ++i) { u16 peer_id = *i; RemoteClient *client = getClient(peer_id); @@ -1792,7 +1790,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) u8 client_max = data[2]; u8 our_max = SER_FMT_VER_HIGHEST; // Use the highest version supported by both - u8 deployed = core::min_(client_max, our_max); + u8 deployed = std::min(client_max, our_max); // If it's lower than the lowest supported, give up. if(deployed < SER_FMT_VER_LOWEST) deployed = SER_FMT_VER_INVALID; @@ -2143,12 +2141,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) */ { std::ostringstream os(std::ios_base::binary); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; // Get player @@ -2520,13 +2518,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) /* Send the message to clients */ - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Get client and check that it is valid - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; @@ -2651,7 +2649,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); - core::list tosend; + std::list tosend; u16 numfiles = readU16(is); infostream<<"Sending "< Server::getPlayerInfo() +std::list Server::getPlayerInfo() { DSTACK(__FUNCTION_NAME); JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock conlock(m_con_mutex); - core::list list; + std::list list; - core::list players = m_env->getPlayers(); + std::list players = m_env->getPlayers(); - core::list::Iterator i; + std::list::iterator i; for(i = players.begin(); - i != players.end(); i++) + i != players.end(); ++i) { PlayerInfo info; @@ -3470,13 +3468,13 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, co void Server::BroadcastChatMessage(const std::wstring &message) { - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Get client and check that it is valid - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; @@ -3595,10 +3593,10 @@ s32 Server::playSound(const SimpleSoundSpec &spec, } else { - for(core::map::Iterator - i = m_clients.getIterator(); i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; Player *player = m_env->getPlayer(client->peer_id); if(!player) continue; @@ -3668,7 +3666,7 @@ void Server::stopSound(s32 handle) } void Server::sendRemoveNode(v3s16 p, u16 ignore_id, - core::list *far_players, float far_d_nodes) + std::list *far_players, float far_d_nodes) { float maxd = far_d_nodes*BS; v3f p_f = intToFloat(p, BS); @@ -3681,13 +3679,13 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, writeS16(&reply[4], p.Y); writeS16(&reply[6], p.Z); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Get client and check that it is valid - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; @@ -3717,18 +3715,18 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, } void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, - core::list *far_players, float far_d_nodes) + std::list *far_players, float far_d_nodes) { float maxd = far_d_nodes*BS; v3f p_f = intToFloat(p, BS); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { // Get client and check that it is valid - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; @@ -3768,11 +3766,11 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, void Server::setBlockNotSent(v3s16 p) { - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); + RemoteClient *client = i->second; client->SetBlockNotSent(p); } } @@ -3839,19 +3837,19 @@ void Server::SendBlocks(float dtime) ScopeProfiler sp(g_profiler, "Server: sel and send blocks to clients"); - core::array queue; + std::vector queue; s32 total_sending = 0; { ScopeProfiler sp(g_profiler, "Server: selecting blocks for sending"); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); // If definitions and textures have not been sent, don't // send MapBlocks either @@ -3870,7 +3868,7 @@ void Server::SendBlocks(float dtime) // Sort. // Lowest priority number comes first. // Lowest is most important. - queue.sort(); + std::sort(queue.begin(), queue.end()); for(u32 i=0; i file_announcements; + std::list file_announcements; for(std::map::iterator i = m_media.begin(); i != m_media.end(); i++){ @@ -4043,9 +4041,9 @@ void Server::sendMediaAnnouncement(u16 peer_id) writeU16(os, TOCLIENT_ANNOUNCE_MEDIA); writeU16(os, file_announcements.size()); - for(core::list::Iterator + for(std::list::iterator j = file_announcements.begin(); - j != file_announcements.end(); j++){ + j != file_announcements.end(); ++j){ os<name); os<sha1_digest); } @@ -4074,7 +4072,7 @@ struct SendableMedia }; void Server::sendRequestedMedia(u16 peer_id, - const core::list &tosend) + const std::list &tosend) { DSTACK(__FUNCTION_NAME); @@ -4086,13 +4084,13 @@ void Server::sendRequestedMedia(u16 peer_id, // Put 5kB in one bunch (this is not accurate) u32 bytes_per_bunch = 5000; - core::array< core::list > file_bunches; - file_bunches.push_back(core::list()); + std::vector< std::list > file_bunches; + file_bunches.push_back(std::list()); u32 file_size_bunch_total = 0; - for(core::list::ConstIterator i = tosend.begin(); - i != tosend.end(); i++) + for(std::list::const_iterator i = tosend.begin(); + i != tosend.end(); ++i) { if(m_media.find(i->name) == m_media.end()){ errorstream<<"Server::sendRequestedMedia(): Client asked for " @@ -4138,7 +4136,7 @@ void Server::sendRequestedMedia(u16 peer_id, // Start next bunch if got enough data if(file_size_bunch_total >= bytes_per_bunch){ - file_bunches.push_back(core::list()); + file_bunches.push_back(std::list()); file_size_bunch_total = 0; } @@ -4169,9 +4167,9 @@ void Server::sendRequestedMedia(u16 peer_id, writeU16(os, i); writeU32(os, file_bunches[i].size()); - for(core::list::Iterator + for(std::list::iterator j = file_bunches[i].begin(); - j != file_bunches[i].end(); j++){ + j != file_bunches[i].end(); ++j){ os<name); os<data); } @@ -4212,10 +4210,10 @@ void Server::sendDetachedInventoryToAll(const std::string &name) { DSTACK(__FUNCTION_NAME); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++){ - RemoteClient *client = i.getNode()->getValue(); + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i){ + RemoteClient *client = i->second; sendDetachedInventory(name, client->peer_id); } } @@ -4299,11 +4297,11 @@ RemoteClient* Server::getClient(u16 peer_id) { DSTACK(__FUNCTION_NAME); //JMutexAutoLock lock(m_con_mutex); - core::map::Node *n; + std::map::iterator n; n = m_clients.find(peer_id); // A client should exist for all peers - assert(n != NULL); - return n->getValue(); + assert(n != m_clients.end()); + return n->second; } std::wstring Server::getStatusString() @@ -4315,15 +4313,15 @@ std::wstring Server::getStatusString() // Uptime os<getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; // Get player @@ -4363,10 +4361,10 @@ bool Server::checkPriv(const std::string &name, const std::string &priv) void Server::reportPrivsModified(const std::string &name) { if(name == ""){ - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++){ - RemoteClient *client = i.getNode()->getValue(); + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i){ + RemoteClient *client = i->second; Player *player = m_env->getPlayer(client->peer_id); reportPrivsModified(player->getName()); } @@ -4579,11 +4577,11 @@ const ModSpec* Server::getModSpec(const std::string &modname) } return NULL; } -void Server::getModNames(core::list &modlist) +void Server::getModNames(std::list &modlist) { for(std::vector::iterator i = m_mods.begin(); i != m_mods.end(); i++) { - modlist.push_back((*i).name); + modlist.push_back(i->name); } } std::string Server::getBuiltinLuaPath() @@ -4733,15 +4731,15 @@ void Server::handlePeerChange(PeerChange &c) */ // Error check - core::map::Node *n; + std::map::iterator n; n = m_clients.find(c.peer_id); // The client shouldn't already exist - assert(n == NULL); + assert(n == m_clients.end()); // Create client RemoteClient *client = new RemoteClient(); client->peer_id = c.peer_id; - m_clients.insert(client->peer_id, client); + m_clients[client->peer_id] = client; } // PEER_ADDED else if(c.type == PEER_REMOVED) @@ -4751,22 +4749,22 @@ void Server::handlePeerChange(PeerChange &c) */ // Error check - core::map::Node *n; + std::map::iterator n; n = m_clients.find(c.peer_id); // The client should exist - assert(n != NULL); + assert(n != m_clients.end()); /* Mark objects to be not known by the client */ - RemoteClient *client = n->getValue(); + RemoteClient *client = n->second; // Handle objects - for(core::map::Iterator - i = client->m_known_objects.getIterator(); - i.atEnd()==false; i++) + for(std::set::iterator + i = client->m_known_objects.begin(); + i != client->m_known_objects.end(); ++i) { // Get object - u16 id = i.getNode()->getKey(); + u16 id = *i; ServerActiveObject* obj = m_env->getActiveObject(id); if(obj && obj->m_known_by_count > 0) @@ -4824,12 +4822,12 @@ void Server::handlePeerChange(PeerChange &c) if(player != NULL) { std::ostringstream os(std::ios_base::binary); - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); ++i) { - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + RemoteClient *client = i->second; + assert(client->peer_id == i->first); if(client->serialization_version == SER_FMT_VER_INVALID) continue; // Get player @@ -4849,7 +4847,7 @@ void Server::handlePeerChange(PeerChange &c) // Delete client delete m_clients[c.peer_id]; - m_clients.remove(c.peer_id); + m_clients.erase(c.peer_id); // Send player info to all remaining clients //SendPlayerInfos(); diff --git a/src/server.h b/src/server.h index d7700791c..63717eaec 100644 --- a/src/server.h +++ b/src/server.h @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include "rollback_interface.h" // Needed for rollbackRevertActions() #include // Needed for rollbackRevertActions() +#include #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -166,7 +167,7 @@ struct PrioritySortedBlockTransfer pos = a_pos; peer_id = a_peer_id; } - bool operator < (PrioritySortedBlockTransfer &other) + bool operator < (const PrioritySortedBlockTransfer &other) const { return priority < other.priority; } @@ -271,14 +272,14 @@ public: dtime is used for resetting send radius at slow interval */ void GetNextBlocks(Server *server, float dtime, - core::array &dest); + std::vector &dest); void GotBlock(v3s16 p); void SentBlock(v3s16 p); void SetBlockNotSent(v3s16 p); - void SetBlocksNotSent(core::map &blocks); + void SetBlocksNotSent(std::map &blocks); s32 SendingCount() { @@ -314,7 +315,7 @@ public: List of active objects that the client knows of. Value is dummy. */ - core::map m_known_objects; + std::set m_known_objects; private: /* @@ -326,7 +327,7 @@ private: Key is position, value is dummy. No MapBlock* is stored here because the blocks can get deleted. */ - core::map m_blocks_sent; + std::set m_blocks_sent; s16 m_nearest_unsent_d; v3s16 m_last_center; float m_nearest_unsent_reset_timer; @@ -339,7 +340,7 @@ private: Block is removed when GOTBLOCKS is received. Value is time from sending. (not used at the moment) */ - core::map m_blocks_sending; + std::map m_blocks_sending; /* Count of excess GotBlocks(). @@ -381,7 +382,7 @@ public: void Receive(); void ProcessData(u8 *data, u32 datasize, u16 peer_id); - core::list getPlayerInfo(); + std::list getPlayerInfo(); // Environment must be locked when called void setTimeOfDay(u32 time) @@ -494,7 +495,7 @@ public: IWritableCraftDefManager* getWritableCraftDefManager(); const ModSpec* getModSpec(const std::string &modname); - void getModNames(core::list &modlist); + void getModNames(std::list &modlist); std::string getBuiltinLuaPath(); std::string getWorldPath(){ return m_path_world; } @@ -553,9 +554,9 @@ private: */ // Envlock and conlock should be locked when calling these void sendRemoveNode(v3s16 p, u16 ignore_id=0, - core::list *far_players=NULL, float far_d_nodes=100); + std::list *far_players=NULL, float far_d_nodes=100); void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0, - core::list *far_players=NULL, float far_d_nodes=100); + std::list *far_players=NULL, float far_d_nodes=100); void setBlockNotSent(v3s16 p); // Environment and Connection must be locked when called @@ -567,7 +568,7 @@ private: void fillMediaCache(); void sendMediaAnnouncement(u16 peer_id); void sendRequestedMedia(u16 peer_id, - const core::list &tosend); + const std::list &tosend); void sendDetachedInventory(const std::string &name, u16 peer_id); void sendDetachedInventoryToAll(const std::string &name); @@ -655,7 +656,7 @@ private: con::Connection m_con; JMutex m_con_mutex; // Connected clients (behind the con mutex) - core::map m_clients; + std::map m_clients; u16 m_clients_number; //for announcing masterserver // Bann checking @@ -735,7 +736,7 @@ private: */ // Mod parent directory paths - core::list m_modspaths; + std::list m_modspaths; bool m_shutdown_requested; diff --git a/src/serverobject.cpp b/src/serverobject.cpp index beb17d31f..95735de17 100644 --- a/src/serverobject.cpp +++ b/src/serverobject.cpp @@ -43,9 +43,9 @@ ServerActiveObject* ServerActiveObject::create(u8 type, const std::string &data) { // Find factory function - core::map::Node *n; + std::map::iterator n; n = m_types.find(type); - if(n == NULL) + if(n == m_types.end()) { // If factory is not found, just return. dstream<<"WARNING: ServerActiveObject: No factory for type=" @@ -53,18 +53,18 @@ ServerActiveObject* ServerActiveObject::create(u8 type, return NULL; } - Factory f = n->getValue(); + Factory f = n->second; ServerActiveObject *object = (*f)(env, pos, data); return object; } void ServerActiveObject::registerType(u16 type, Factory f) { - core::map::Node *n; + std::map::iterator n; n = m_types.find(type); - if(n) + if(n != m_types.end()) return; - m_types.insert(type, f); + m_types[type] = f; } float ServerActiveObject::getMinimumSavedMovement() diff --git a/src/serverobject.h b/src/serverobject.h index 6525270f6..7a5b47bd1 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -235,7 +235,7 @@ protected: private: // Used for creating objects based on type - static core::map m_types; + static std::map m_types; }; #endif diff --git a/src/settings.h b/src/settings.h index 7ac308cc0..0696b8190 100644 --- a/src/settings.h +++ b/src/settings.h @@ -33,6 +33,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "util/string.h" #include "porting.h" +#include +#include +#include enum ValueType { @@ -63,12 +66,12 @@ public: { JMutexAutoLock lock(m_mutex); - for(core::map::Iterator - i = m_settings.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { - std::string name = i.getNode()->getKey(); - std::string value = i.getNode()->getValue(); + std::string name = i->first; + std::string value = i->second; os< getNames(){ std::vector names; - for(core::map::Iterator - i = m_settings.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { - std::string name = i.getNode()->getKey(); - names.push_back(name); + names.push_back(i->first); } return names; } @@ -89,7 +91,7 @@ public: // remove a setting bool remove(const std::string& name) { - return m_settings.remove(name); + return m_settings.erase(name); } @@ -188,8 +190,8 @@ public: Returns false on EOF */ bool getUpdatedConfigObject(std::istream &is, - core::list &dst, - core::map &updated, + std::list &dst, + std::set &updated, bool &value_changed) { JMutexAutoLock lock(m_mutex); @@ -228,7 +230,7 @@ public: std::string value = sf.next("\n"); value = trim(value); - if(m_settings.find(name)) + if(m_settings.find(name) != m_settings.end()) { std::string newvalue = m_settings[name]; @@ -242,7 +244,7 @@ public: dst.push_back(name + " = " + newvalue + line_end); - updated[name] = true; + updated.insert(name); } else //file contains a setting which is not in m_settings value_changed=true; @@ -260,8 +262,8 @@ public: infostream<<"Updating configuration file: \"" < objects; - core::map updated; + std::list objects; + std::set updated; bool something_actually_changed = false; // Read and modify stuff @@ -286,11 +288,11 @@ public: // If something not yet determined to have been changed, check if // any new stuff was added if(!something_actually_changed){ - for(core::map::Iterator - i = m_settings.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { - if(updated.find(i.getNode()->getKey())) + if(updated.find(i->first) != updated.end()) continue; something_actually_changed = true; break; @@ -318,9 +320,9 @@ public: /* Write updated stuff */ - for(core::list::Iterator + for(std::list::iterator i = objects.begin(); - i != objects.end(); i++) + i != objects.end(); ++i) { os<<(*i); } @@ -328,14 +330,14 @@ public: /* Write stuff that was not already in the file */ - for(core::map::Iterator - i = m_settings.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { - if(updated.find(i.getNode()->getKey())) + if(updated.find(i->first) != updated.end()) continue; - std::string name = i.getNode()->getKey(); - std::string value = i.getNode()->getValue(); + std::string name = i->first; + std::string value = i->second; infostream<<"Adding \""< &allowed_options) + std::map &allowed_options) { int nonopt_index = 0; int i=1; @@ -379,16 +381,16 @@ public: std::string name = argname.substr(2); - core::map::Node *n; + std::map::iterator n; n = allowed_options.find(name); - if(n == NULL) + if(n == allowed_options.end()) { errorstream<<"Unknown command-line parameter \"" <getValue().type; + ValueType type = n->second.type; std::string value = ""; @@ -444,25 +446,25 @@ public: { JMutexAutoLock lock(m_mutex); - return (m_settings.find(name) || m_defaults.find(name)); + return (m_settings.find(name) != m_settings.end() || m_defaults.find(name) != m_defaults.end()); } std::string get(std::string name) { JMutexAutoLock lock(m_mutex); - core::map::Node *n; + std::map::iterator n; n = m_settings.find(name); - if(n == NULL) + if(n == m_settings.end()) { n = m_defaults.find(name); - if(n == NULL) + if(n == m_defaults.end()) { throw SettingNotFoundException("Setting not found"); } } - return n->getValue(); + return n->second; } bool getBool(std::string name) @@ -919,19 +921,8 @@ fail: if(&other == this) return; - for(core::map::Iterator - i = other.m_settings.getIterator(); - i.atEnd() == false; i++) - { - m_settings[i.getNode()->getKey()] = i.getNode()->getValue(); - } - - for(core::map::Iterator - i = other.m_defaults.getIterator(); - i.atEnd() == false; i++) - { - m_defaults[i.getNode()->getKey()] = i.getNode()->getValue(); - } + m_settings.insert(other.m_settings.begin(), other.m_settings.end()); + m_defaults.insert(other.m_defaults.begin(), other.m_defaults.end()); return; } @@ -944,21 +935,7 @@ fail: if(&other == this) return *this; - for(core::map::Iterator - i = other.m_settings.getIterator(); - i.atEnd() == false; i++) - { - m_settings.insert(i.getNode()->getKey(), - i.getNode()->getValue()); - } - - for(core::map::Iterator - i = other.m_defaults.getIterator(); - i.atEnd() == false; i++) - { - m_defaults.insert(i.getNode()->getKey(), - i.getNode()->getValue()); - } + update(other); return *this; @@ -979,8 +956,8 @@ fail: } private: - core::map m_settings; - core::map m_defaults; + std::map m_settings; + std::map m_defaults; // All methods that access m_settings/m_defaults directly should lock this. JMutex m_mutex; }; diff --git a/src/shader.cpp b/src/shader.cpp index 7e3d16e8b..a224c82bb 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -125,10 +125,10 @@ public: const std::string &filename) { std::string combined = name_of_shader + DIR_DELIM + filename; - core::map::Node *n; + std::map::iterator n; n = m_programs.find(combined); - if(n) - return n->getValue(); + if(n != m_programs.end()) + return n->second; return ""; } // Primarily fetches from cache, secondarily tries to read from filesystem @@ -136,10 +136,10 @@ public: const std::string &filename) { std::string combined = name_of_shader + DIR_DELIM + filename; - core::map::Node *n; + std::map::iterator n; n = m_programs.find(combined); - if(n) - return n->getValue(); + if(n != m_programs.end()) + return n->second; std::string path = getShaderPath(name_of_shader, filename); if(path == ""){ infostream<<"SourceShaderCache::getOrLoad(): No path found for \"" @@ -156,7 +156,7 @@ public: return ""; } private: - core::map m_programs; + std::map m_programs; std::string readFile(const std::string &path) { std::ifstream is(path.c_str(), std::ios::binary); @@ -332,9 +332,9 @@ private: // A shader id is index in this array. // The first position contains a dummy shader. - core::array m_shaderinfo_cache; + std::vector m_shaderinfo_cache; // Maps a shader name to an index in the former. - core::map m_name_to_id; + std::map m_name_to_id; // The two former containers are behind this mutex JMutex m_shaderinfo_cache_mutex; @@ -343,7 +343,7 @@ private: // Global constant setters // TODO: Delete these in the destructor - core::array m_global_setters; + std::vector m_global_setters; }; IWritableShaderSource* createShaderSource(IrrlichtDevice *device) @@ -399,10 +399,10 @@ u32 ShaderSource::getShaderId(const std::string &name) See if shader already exists */ JMutexAutoLock lock(m_shaderinfo_cache_mutex); - core::map::Node *n; + std::map::iterator n; n = m_name_to_id.find(name); - if(n != NULL) - return n->getValue(); + if(n != m_name_to_id.end()) + return n->second; } /* @@ -471,12 +471,12 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name) { JMutexAutoLock lock(m_shaderinfo_cache_mutex); - core::map::Node *n; + std::map::iterator n; n = m_name_to_id.find(name); - if(n != NULL){ + if(n != m_name_to_id.end()){ /*infostream<<"getShaderIdDirect(): \""<getValue(); + return n->second; } } @@ -494,7 +494,7 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name) u32 id = m_shaderinfo_cache.size(); m_shaderinfo_cache.push_back(info); - m_name_to_id.insert(name, id); + m_name_to_id[name] = id; /*infostream<<"getShaderIdDirect(): " <<"Returning id="< 0){ + if(!m_get_shader_queue.empty()){ GetRequest request = m_get_shader_queue.pop(); diff --git a/src/staticobject.cpp b/src/staticobject.cpp index 48fadaf06..973257fcf 100644 --- a/src/staticobject.cpp +++ b/src/staticobject.cpp @@ -58,18 +58,18 @@ void StaticObjectList::serialize(std::ostream &os) u16 count = m_stored.size() + m_active.size(); writeU16((u8*)buf, count); os.write(buf, 2); - for(core::list::Iterator + for(std::list::iterator i = m_stored.begin(); - i != m_stored.end(); i++) + i != m_stored.end(); ++i) { StaticObject &s_obj = *i; s_obj.serialize(os); } - for(core::map::Iterator - i = m_active.getIterator(); - i.atEnd()==false; i++) + for(std::map::iterator + i = m_active.begin(); + i != m_active.end(); ++i) { - StaticObject s_obj = i.getNode()->getValue(); + StaticObject s_obj = i->second; s_obj.serialize(os); } } diff --git a/src/staticobject.h b/src/staticobject.h index c8427fe47..640747e96 100644 --- a/src/staticobject.h +++ b/src/staticobject.h @@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include #include +#include +#include #include "debug.h" struct StaticObject @@ -62,27 +64,27 @@ public: } else { - if(m_active.find(id) != NULL) + if(m_active.find(id) != m_active.end()) { dstream<<"ERROR: StaticObjectList::insert(): " <<"id already exists"< m_stored; - core::map m_active; + std::list m_stored; + std::map m_active; private: }; diff --git a/src/test.cpp b/src/test.cpp index d86868118..d18bd8b93 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -42,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/serialize.h" #include "noise.h" // PseudoRandom used for random data for compression #include "clientserver.h" // LATEST_PROTOCOL_VERSION +#include /* Asserts that the exception occurs @@ -508,26 +509,26 @@ struct TestVoxelManipulator: public TestBase // An area that is 1 bigger in x+ and z- VoxelArea d(v3s16(-2,-2,-3), v3s16(3,2,2)); - core::list aa; + std::list aa; d.diff(c, aa); // Correct results - core::array results; + std::vector results; results.push_back(VoxelArea(v3s16(-2,-2,-3),v3s16(3,2,-3))); results.push_back(VoxelArea(v3s16(3,-2,-2),v3s16(3,2,2))); UASSERT(aa.size() == results.size()); infostream<<"Result of diff:"<::Iterator - i = aa.begin(); i != aa.end(); i++) + for(std::list::const_iterator + i = aa.begin(); i != aa.end(); ++i) { i->print(infostream); infostream<::iterator j = std::find(results.begin(), results.end(), *i); + UASSERT(j != results.end()); + results.erase(j); } @@ -582,7 +583,7 @@ struct TestVoxelAlgorithms: public TestBase } VoxelArea a(v3s16(0,0,0), v3s16(2,2,2)); { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); @@ -593,7 +594,7 @@ struct TestVoxelAlgorithms: public TestBase } v.setNodeNoRef(v3s16(0,0,0), MapNode(CONTENT_STONE)); { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); @@ -602,7 +603,7 @@ struct TestVoxelAlgorithms: public TestBase == LIGHT_SUN); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, false, light_sources, ndef); @@ -612,7 +613,7 @@ struct TestVoxelAlgorithms: public TestBase } v.setNodeNoRef(v3s16(1,3,2), MapNode(CONTENT_STONE)); { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); @@ -621,7 +622,7 @@ struct TestVoxelAlgorithms: public TestBase == 0); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, false, light_sources, ndef); @@ -635,14 +636,14 @@ struct TestVoxelAlgorithms: public TestBase v.setNodeNoRef(v3s16(1,-1,2), n); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); UASSERT(res.bottom_sunlight_valid == true); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, false, light_sources, ndef); @@ -654,14 +655,14 @@ struct TestVoxelAlgorithms: public TestBase v.setNodeNoRef(v3s16(1,-1,2), n); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); UASSERT(res.bottom_sunlight_valid == false); } { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, false, light_sources, ndef); @@ -669,7 +670,7 @@ struct TestVoxelAlgorithms: public TestBase } v.setNodeNoRef(v3s16(1,3,2), MapNode(CONTENT_IGNORE)); { - core::map light_sources; + std::set light_sources; voxalgo::setLight(v, a, 0, ndef); voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight( v, a, true, light_sources, ndef); @@ -697,16 +698,16 @@ struct TestVoxelAlgorithms: public TestBase v.setNode(v3s16(1,1,2), n); } { - core::map light_sources; - core::map unlight_from; + std::set light_sources; + std::map unlight_from; voxalgo::clearLightAndCollectSources(v, a, LIGHTBANK_DAY, ndef, light_sources, unlight_from); //v.print(dstream, ndef, VOXELPRINT_LIGHT_DAY); UASSERT(v.getNode(v3s16(0,1,1)).getLight(LIGHTBANK_DAY, ndef) == 0); - UASSERT(light_sources.find(v3s16(1,1,1)) != NULL); + UASSERT(light_sources.find(v3s16(1,1,1)) != light_sources.end()); UASSERT(light_sources.size() == 1); - UASSERT(unlight_from.find(v3s16(1,1,2)) != NULL); + UASSERT(unlight_from.find(v3s16(1,1,2)) != unlight_from.end()); UASSERT(unlight_from.size() == 1); } } diff --git a/src/tile.cpp b/src/tile.cpp index 7286293d8..aea9665f5 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -206,10 +206,10 @@ public: { assert(img); // Remove old image - core::map::Node *n; + std::map::iterator n; n = m_images.find(name); - if(n){ - video::IImage *oldimg = n->getValue(); + if(n != m_images.end()){ + video::IImage *oldimg = n->second; if(oldimg) oldimg->drop(); } @@ -229,20 +229,20 @@ public: } video::IImage* get(const std::string &name) { - core::map::Node *n; + std::map::iterator n; n = m_images.find(name); - if(n) - return n->getValue(); + if(n != m_images.end()) + return n->second; return NULL; } // Primarily fetches from cache, secondarily tries to read from filesystem video::IImage* getOrLoad(const std::string &name, IrrlichtDevice *device) { - core::map::Node *n; + std::map::iterator n; n = m_images.find(name); - if(n){ - n->getValue()->grab(); // Grab for caller - return n->getValue(); + if(n != m_images.end()){ + n->second->grab(); // Grab for caller + return n->second; } video::IVideoDriver* driver = device->getVideoDriver(); std::string path = getTexturePath(name.c_str()); @@ -263,7 +263,7 @@ public: return img; } private: - core::map m_images; + std::map m_images; }; /* @@ -417,9 +417,9 @@ private: // A texture id is index in this array. // The first position contains a NULL texture. - core::array m_atlaspointer_cache; + std::vector m_atlaspointer_cache; // Maps a texture name to an index in the former. - core::map m_name_to_id; + std::map m_name_to_id; // The two former containers are behind this mutex JMutex m_atlaspointer_cache_mutex; @@ -465,11 +465,11 @@ u32 TextureSource::getTextureId(const std::string &name) See if texture already exists */ JMutexAutoLock lock(m_atlaspointer_cache_mutex); - core::map::Node *n; + std::map::iterator n; n = m_name_to_id.find(name); - if(n != NULL) + if(n != m_name_to_id.end()) { - return n->getValue(); + return n->second; } } @@ -579,13 +579,13 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) { JMutexAutoLock lock(m_atlaspointer_cache_mutex); - core::map::Node *n; + std::map::iterator n; n = m_name_to_id.find(name); - if(n != NULL) + if(n != m_name_to_id.end()) { /*infostream<<"getTextureIdDirect(): \""<getValue(); + return n->second; } } @@ -724,7 +724,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) baseimg_dim = baseimg->getDimension(); SourceAtlasPointer nap(name, ap, baseimg, v2s32(0,0), baseimg_dim); m_atlaspointer_cache.push_back(nap); - m_name_to_id.insert(name, id); + m_name_to_id[name] = id; /*infostream<<"getTextureIdDirect(): " <<"Returning id="< 0) + if(!m_get_texture_queue.empty()) { GetRequest request = m_get_texture_queue.pop(); @@ -872,7 +872,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef) main content features */ - core::map sourcelist; + std::set sourcelist; for(u16 j=0; j::Iterator - i = sourcelist.getIterator(); - i.atEnd() == false; i++) + for(std::set::iterator + i = sourcelist.begin(); + i != sourcelist.end(); ++i) { - std::string name = i.getNode()->getKey(); + std::string name = *i; infostream<<"\""<::Iterator - i = sourcelist.getIterator(); - i.atEnd() == false; i++) + for(std::set::iterator + i = sourcelist.begin(); + i != sourcelist.end(); ++i) { - std::string name = i.getNode()->getKey(); + std::string name = *i; // Generate image by name video::IImage *img2 = generate_image_from_scratch(name, m_device, @@ -1026,11 +1026,11 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef) bool reuse_old_id = false; u32 id = m_atlaspointer_cache.size(); // Check old id without fetching a texture - core::map::Node *n; + std::map::iterator n; n = m_name_to_id.find(name); // If it exists, we will replace the old definition - if(n){ - id = n->getValue(); + if(n != m_name_to_id.end()){ + id = n->second; reuse_old_id = true; /*infostream<<"TextureSource::buildMainAtlas(): " <<"Replacing old AtlasPointer"<::Iterator - i = sourcelist.getIterator(); - i.atEnd() == false; i++) + for(std::set::iterator + i = sourcelist.begin(); + i != sourcelist.end(); ++i) { - std::string name = i.getNode()->getKey(); - if(m_name_to_id.find(name) == NULL) + std::string name = *i; + if(m_name_to_id.find(name) == m_name_to_id.end()) continue; u32 id = m_name_to_id[name]; //infostream<<"id of name "<getServerMap(); - core::map modified_blocks; + std::map modified_blocks; ManualMapVoxelManipulator vmanip(map); v3s16 tree_blockp = getNodeBlockPos(p0); vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,3,1)); @@ -122,23 +122,17 @@ void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeD vmanip.blitBackAll(&modified_blocks); // update lighting - core::map lighting_modified_blocks; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) - { - lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue()); - } + std::map lighting_modified_blocks; + lighting_modified_blocks.insert(modified_blocks.begin(), modified_blocks.end()); map->updateLighting(lighting_modified_blocks, modified_blocks); // Send a MEET_OTHER event MapEditEvent event; event.type = MEET_OTHER; - for(core::map::Iterator - i = modified_blocks.getIterator(); - i.atEnd() == false; i++) + for(std::map::iterator + i = modified_blocks.begin(); + i != modified_blocks.end(); ++i) { - v3s16 p = i.getNode()->getKey(); - event.modified_blocks.insert(p, true); + event.modified_blocks.insert(i->first); } map->dispatchEvent(&event); } diff --git a/src/util/container.h b/src/util/container.h index 775372649..9bb388f0e 100644 --- a/src/util/container.h +++ b/src/util/container.h @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "../porting.h" // For sleep_ms +#include +#include /* Queue with unique values with fast checking of value existence @@ -43,11 +45,11 @@ public: bool push_back(Value value) { // Check if already exists - if(m_map.find(value) != NULL) + if(m_map.find(value) != m_map.end()) return false; // Add - m_map.insert(value, 0); + m_map[value] = 0; m_list.push_back(value); return true; @@ -55,22 +57,21 @@ public: Value pop_front() { - typename core::list::Iterator i = m_list.begin(); + typename std::list::iterator i = m_list.begin(); Value value = *i; - m_map.remove(value); + m_map.erase(value); m_list.erase(i); return value; } u32 size() { - assert(m_list.size() == m_map.size()); - return m_list.size(); + return m_map.size(); } private: - core::map m_map; - core::list m_list; + std::map m_map; + std::list m_list; }; #if 1 @@ -95,31 +96,31 @@ public: { JMutexAutoLock lock(m_mutex); - typename core::map::Node *n; + typename std::map::iterator n; n = m_values.find(name); - if(n == NULL) + if(n == m_values.end()) return false; if(result != NULL) - *result = n->getValue(); + *result = n->second; return true; } - core::list getValues() + std::list getValues() { - core::list result; - for(typename core::map::Iterator - i = m_values.getIterator(); - i.atEnd() == false; i++){ - result.push_back(i.getNode()->getValue()); + std::list result; + for(typename std::map::iterator + i = m_values.begin(); + i != m_values.end(); ++i){ + result.push_back(i->second); } return result; } private: - core::map m_values; + std::map m_values; JMutex m_mutex; }; #endif @@ -163,10 +164,10 @@ public: u32 getId(const T &value) { JMutexAutoLock lock(m_mutex); - typename core::map::Node *n; + typename std::map::iterator n; n = m_value_to_id.find(value); - if(n != NULL) - return n->getValue(); + if(n != m_value_to_id.end()) + return n->second; m_id_to_value.push_back(value); u32 new_id = m_id_to_value.size(); m_value_to_id.insert(value, new_id); @@ -176,8 +177,8 @@ public: private: JMutex m_mutex; // Values are stored here at id-1 position (id 1 = [0]) - core::array m_id_to_value; - core::map m_value_to_id; + std::vector m_id_to_value; + std::map m_value_to_id; }; /* @@ -187,39 +188,52 @@ template class Queue { public: + Queue(): + m_list_size(0) + {} + void push_back(T t) { m_list.push_back(t); + ++m_list_size; } T pop_front() { - if(m_list.size() == 0) + if(m_list.empty()) throw ItemNotFoundException("Queue: queue is empty"); - typename core::list::Iterator begin = m_list.begin(); + typename std::list::iterator begin = m_list.begin(); T t = *begin; m_list.erase(begin); + --m_list_size; return t; } T pop_back() { - if(m_list.size() == 0) + if(m_list.empty()) throw ItemNotFoundException("Queue: queue is empty"); - typename core::list::Iterator last = m_list.getLast(); + typename std::list::iterator last = m_list.back(); T t = *last; m_list.erase(last); + --m_list_size; return t; } u32 size() { - return m_list.size(); + return m_list_size; + } + + bool empty() + { + return m_list.empty(); } protected: - core::list m_list; + std::list m_list; + u32 m_list_size; }; /* @@ -234,10 +248,10 @@ public: { m_mutex.Init(); } - u32 size() + bool empty() { JMutexAutoLock lock(m_mutex); - return m_list.size(); + return m_list.empty(); } void push_back(T t) { @@ -253,9 +267,9 @@ public: { JMutexAutoLock lock(m_mutex); - if(m_list.size() > 0) + if(!m_list.empty()) { - typename core::list::Iterator begin = m_list.begin(); + typename std::list::iterator begin = m_list.begin(); T t = *begin; m_list.erase(begin); return t; @@ -279,9 +293,9 @@ public: { JMutexAutoLock lock(m_mutex); - if(m_list.size() > 0) + if(!m_list.empty()) { - typename core::list::Iterator last = m_list.getLast(); + typename std::list::iterator last = m_list.back(); T t = *last; m_list.erase(last); return t; @@ -302,14 +316,14 @@ public: return m_mutex; } - core::list & getList() + std::list & getList() { return m_list; } protected: JMutex m_mutex; - core::list m_list; + std::list m_list; }; #endif diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index a79454628..ed83df7d7 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include // Calculate the borders of a "d-radius" cube -void getFacePositions(core::list &list, u16 d) +void getFacePositions(std::list &list, u16 d) { if(d == 0) { diff --git a/src/util/numeric.h b/src/util/numeric.h index 450a98e40..e66af2376 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -25,9 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "../irr_v3d.h" #include "../irr_aabb3d.h" #include +#include // Calculate the borders of a "d-radius" cube -void getFacePositions(core::list &list, u16 d); +void getFacePositions(std::list &list, u16 d); class IndentationRaiser { diff --git a/src/util/thread.h b/src/util/thread.h index 949bb4204..6b2cf5b6c 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -120,7 +120,7 @@ class GetResult public: Key key; T item; - core::list > callers; + std::list > callers; }; template @@ -152,16 +152,16 @@ public: Key key; ResultQueue *dest; - core::list > callers; + std::list > callers; }; template class RequestQueue { public: - u32 size() + bool empty() { - return m_queue.size(); + return m_queue.empty(); } void add(Key key, Caller caller, CallerData callerdata, @@ -172,17 +172,17 @@ public: /* If the caller is already on the list, only update CallerData */ - for(typename core::list< GetRequest >::Iterator + for(typename std::list< GetRequest >::iterator i = m_queue.getList().begin(); - i != m_queue.getList().end(); i++) + i != m_queue.getList().end(); ++i) { GetRequest &request = *i; if(request.key == key) { - for(typename core::list< CallerInfo >::Iterator + for(typename std::list< CallerInfo >::iterator i = request.callers.begin(); - i != request.callers.end(); i++) + i != request.callers.end(); ++i) { CallerInfo &ca = *i; if(ca.caller == caller) diff --git a/src/voxel.cpp b/src/voxel.cpp index c55f3f539..f859a1f03 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -302,7 +302,7 @@ void VoxelManipulator::clearFlag(u8 flags) } void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, - core::map & light_sources, INodeDefManager *nodemgr) + std::set & light_sources, INodeDefManager *nodemgr) { v3s16 dirs[6] = { v3s16(0,0,1), // back @@ -360,7 +360,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, } } else{ - light_sources.insert(n2pos, true); + light_sources.insert(n2pos); } } } @@ -384,24 +384,16 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, values of from_nodes are lighting values. */ void VoxelManipulator::unspreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & light_sources, INodeDefManager *nodemgr) + std::map & from_nodes, + std::set & light_sources, INodeDefManager *nodemgr) { if(from_nodes.size() == 0) return; - core::map::Iterator j; - j = from_nodes.getIterator(); - - for(; j.atEnd() == false; j++) + for(std::map::iterator j = from_nodes.begin(); + j != from_nodes.end(); ++j) { - v3s16 pos = j.getNode()->getKey(); - - //MapNode &n = m_data[m_area.index(pos)]; - - u8 oldlight = j.getNode()->getValue(); - - unspreadLight(bank, pos, oldlight, light_sources, nodemgr); + unspreadLight(bank, j->first, j->second, light_sources, nodemgr); } } #endif @@ -609,7 +601,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, goes on recursively. */ void VoxelManipulator::spreadLight(enum LightBank bank, - core::map & from_nodes, INodeDefManager *nodemgr) + std::set & from_nodes, INodeDefManager *nodemgr) { const v3s16 dirs[6] = { v3s16(0,0,1), // back @@ -623,13 +615,12 @@ void VoxelManipulator::spreadLight(enum LightBank bank, if(from_nodes.size() == 0) return; - core::map lighted_nodes; - core::map::Iterator j; - j = from_nodes.getIterator(); + std::set lighted_nodes; - for(; j.atEnd() == false; j++) + for(std::set::iterator j = from_nodes.begin(); + j != from_nodes.end(); ++j) { - v3s16 pos = j.getNode()->getKey(); + v3s16 pos = *j; emerge(VoxelArea(pos - v3s16(1,1,1), pos + v3s16(1,1,1))); @@ -666,7 +657,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, */ if(light2 > undiminish_light(oldlight)) { - lighted_nodes.insert(n2pos, true); + lighted_nodes.insert(n2pos); } /* If the neighbor is dimmer than how much light this node @@ -677,7 +668,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, if(nodemgr->get(n2).light_propagates) { n2.setLight(bank, newlight, nodemgr); - lighted_nodes.insert(n2pos, true); + lighted_nodes.insert(n2pos); } } } diff --git a/src/voxel.h b/src/voxel.h index b48943624..bed35b57e 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "debug.h" #include "mapnode.h" +#include +#include class INodeDefManager; @@ -186,7 +188,7 @@ public: a: area inside *this */ - void diff(const VoxelArea &a, core::list &result) + void diff(const VoxelArea &a, std::list &result) { /* This can result in a maximum of 6 areas @@ -519,14 +521,14 @@ public: // TODO: Move to voxelalgorithms.h void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, - core::map & light_sources, INodeDefManager *nodemgr); + std::set & light_sources, INodeDefManager *nodemgr); void unspreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & light_sources, INodeDefManager *nodemgr); + std::map & from_nodes, + std::set & light_sources, INodeDefManager *nodemgr); void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr); void spreadLight(enum LightBank bank, - core::map & from_nodes, INodeDefManager *nodemgr); + std::set & from_nodes, INodeDefManager *nodemgr); /* Virtual functions diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp index bd8f816b8..14638a827 100644 --- a/src/voxelalgorithms.cpp +++ b/src/voxelalgorithms.cpp @@ -39,8 +39,8 @@ void setLight(VoxelManipulator &v, VoxelArea a, u8 light, void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a, enum LightBank bank, INodeDefManager *ndef, - core::map & light_sources, - core::map & unlight_from) + std::set & light_sources, + std::map & unlight_from) { // The full area we shall touch VoxelArea required_a = a; @@ -60,7 +60,7 @@ void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a, // If node sources light, add to list u8 source = ndef->get(n).light_source; if(source != 0) - light_sources[p] = true; + light_sources.insert(p); // Collect borders for unlighting if((x==a.MinEdge.X || x == a.MaxEdge.X @@ -68,14 +68,14 @@ void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a, || z==a.MinEdge.Z || z == a.MaxEdge.Z) && oldlight != 0) { - unlight_from.insert(p, oldlight); + unlight_from[p] = oldlight; } } } SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a, bool inexistent_top_provides_sunlight, - core::map & light_sources, + std::set & light_sources, INodeDefManager *ndef) { // Return values @@ -127,7 +127,7 @@ SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a, n.setLight(LIGHTBANK_DAY, incoming_light, ndef); if(diminish_light(incoming_light) != 0) - light_sources.insert(p, true); + light_sources.insert(p); } // Check validity of sunlight at top of block below if it diff --git a/src/voxelalgorithms.h b/src/voxelalgorithms.h index 2a5fc394e..2eba6a176 100644 --- a/src/voxelalgorithms.h +++ b/src/voxelalgorithms.h @@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include "mapnode.h" +#include +#include namespace voxalgo { @@ -33,8 +35,8 @@ void setLight(VoxelManipulator &v, VoxelArea a, u8 light, void clearLightAndCollectSources(VoxelManipulator &v, VoxelArea a, enum LightBank bank, INodeDefManager *ndef, - core::map & light_sources, - core::map & unlight_from); + std::set & light_sources, + std::map & unlight_from); struct SunlightPropagateResult { @@ -47,7 +49,7 @@ struct SunlightPropagateResult SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a, bool inexistent_top_provides_sunlight, - core::map & light_sources, + std::set & light_sources, INodeDefManager *ndef); } // namespace voxalgo -- cgit v1.2.3 From eb90c3d92dac8a04019ccca875a9162739ddd7f1 Mon Sep 17 00:00:00 2001 From: sapier Date: Thu, 7 Mar 2013 23:22:54 +0000 Subject: Move l_get_all_craft_recipes to scriptapi_craft --- src/scriptapi.cpp | 73 ------------------------------------------------- src/scriptapi_craft.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ src/scriptapi_craft.h | 1 + 3 files changed, 74 insertions(+), 73 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 04af4eb22..f95f5a29d 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -1000,79 +1000,6 @@ static int l_notify_authentication_modified(lua_State *L) return 0; } -// get_craft_recipes(result item) -static int l_get_all_craft_recipes(lua_State *L) -{ - char tmp[20]; - int input_i = 1; - std::string o_item = luaL_checkstring(L,input_i); - IGameDef *gdef = get_server(L); - ICraftDefManager *cdef = gdef->cdef(); - CraftInput input; - CraftOutput output(o_item,0); - std::vector recipes_list = cdef->getCraftRecipes(output, gdef); - if (recipes_list.empty()) - { - lua_pushnil(L); - return 1; - } - // Get the table insert function - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int table_insert = lua_gettop(L); - lua_newtable(L); - int table = lua_gettop(L); - for(std::vector::const_iterator - i = recipes_list.begin(); - i != recipes_list.end(); i++) - { - CraftOutput tmpout; - tmpout.item = ""; - tmpout.time = 0; - CraftDefinition *def = *i; - tmpout = def->getOutput(input, gdef); - if(tmpout.item.substr(0,output.item.length()) == output.item) - { - input = def->getInput(output, gdef); - lua_pushvalue(L, table_insert); - lua_pushvalue(L, table); - lua_newtable(L); - int k = 0; - lua_newtable(L); - for(std::vector::const_iterator - i = input.items.begin(); - i != input.items.end(); i++, k++) - { - if (i->empty()) continue; - sprintf(tmp,"%d",k); - lua_pushstring(L,tmp); - lua_pushstring(L,i->name.c_str()); - lua_settable(L, -3); - } - lua_setfield(L, -2, "items"); - setintfield(L, -1, "width", input.width); - switch (input.method) - { - case CRAFT_METHOD_NORMAL: - lua_pushstring(L,"normal"); - break; - case CRAFT_METHOD_COOKING: - lua_pushstring(L,"cooking"); - break; - case CRAFT_METHOD_FUEL: - lua_pushstring(L,"fuel"); - break; - default: - lua_pushstring(L,"unknown"); - } - lua_setfield(L, -2, "type"); - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - } - } - return 1; -} - // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds static int l_rollback_get_last_node_actor(lua_State *L) { diff --git a/src/scriptapi_craft.cpp b/src/scriptapi_craft.cpp index 617bb86a3..183eeb840 100644 --- a/src/scriptapi_craft.cpp +++ b/src/scriptapi_craft.cpp @@ -379,3 +379,76 @@ int l_get_craft_recipe(lua_State *L) } return 1; } + +// get_all_craft_recipes(result item) +int l_get_all_craft_recipes(lua_State *L) +{ + char tmp[20]; + int input_i = 1; + std::string o_item = luaL_checkstring(L,input_i); + IGameDef *gdef = get_server(L); + ICraftDefManager *cdef = gdef->cdef(); + CraftInput input; + CraftOutput output(o_item,0); + std::vector recipes_list = cdef->getCraftRecipes(output, gdef); + if (recipes_list.empty()) + { + lua_pushnil(L); + return 1; + } + // Get the table insert function + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + lua_newtable(L); + int table = lua_gettop(L); + for(std::vector::const_iterator + i = recipes_list.begin(); + i != recipes_list.end(); i++) + { + CraftOutput tmpout; + tmpout.item = ""; + tmpout.time = 0; + CraftDefinition *def = *i; + tmpout = def->getOutput(input, gdef); + if(tmpout.item.substr(0,output.item.length()) == output.item) + { + input = def->getInput(output, gdef); + lua_pushvalue(L, table_insert); + lua_pushvalue(L, table); + lua_newtable(L); + int k = 0; + lua_newtable(L); + for(std::vector::const_iterator + i = input.items.begin(); + i != input.items.end(); i++, k++) + { + if (i->empty()) continue; + sprintf(tmp,"%d",k); + lua_pushstring(L,tmp); + lua_pushstring(L,i->name.c_str()); + lua_settable(L, -3); + } + lua_setfield(L, -2, "items"); + setintfield(L, -1, "width", input.width); + switch (input.method) + { + case CRAFT_METHOD_NORMAL: + lua_pushstring(L,"normal"); + break; + case CRAFT_METHOD_COOKING: + lua_pushstring(L,"cooking"); + break; + case CRAFT_METHOD_FUEL: + lua_pushstring(L,"fuel"); + break; + default: + lua_pushstring(L,"unknown"); + } + lua_setfield(L, -2, "type"); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); + } + } + return 1; +} diff --git a/src/scriptapi_craft.h b/src/scriptapi_craft.h index 2e209d4ae..f28989fd9 100644 --- a/src/scriptapi_craft.h +++ b/src/scriptapi_craft.h @@ -33,6 +33,7 @@ extern "C" { /*****************************************************************************/ int l_register_craft(lua_State *L); int l_get_craft_recipe(lua_State *L); +int l_get_all_craft_recipes(lua_State *L); int l_get_craft_result(lua_State *L); /*****************************************************************************/ -- cgit v1.2.3 From 66750dc88e3b1001e2141dd965345ae51095e0bb Mon Sep 17 00:00:00 2001 From: sapier Date: Thu, 14 Mar 2013 00:24:07 +0000 Subject: fix typo invalid for loop end --- src/scriptapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/scriptapi.cpp') diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index f95f5a29d..13696eabf 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -906,7 +906,7 @@ static int l_get_modnames(lua_State *L) { bool added = false; for(std::list::iterator x = mods_sorted.begin(); - x != mods_unsorted.end(); ++x) + x != mods_sorted.end(); ++x) { // I doubt anybody using Minetest will be using // anything not ASCII based :) -- cgit v1.2.3 From e1ff5b13619666e5b987ecf4faaf294400ffd979 Mon Sep 17 00:00:00 2001 From: Jeija Date: Wed, 23 Jan 2013 18:32:02 +0100 Subject: Allow spawning particles from the server, from lua Spawn single particles or make use of ParticleSpawner for many randomly spawned particles. Accessible in Lua using minetest.spawn_particle and minetest.add_particlespawner. Increase Protocol Version to 17. Conflicts: src/clientserver.h --- doc/lua_api.txt | 31 +++++ src/CMakeLists.txt | 1 + src/client.cpp | 83 ++++++++++++ src/client.h | 34 ++++- src/clientserver.h | 44 ++++++ src/game.cpp | 49 ++++++- src/particles.cpp | 320 +++++++++++++++++++++++++++++++++++++------- src/particles.h | 72 +++++++++- src/scriptapi.cpp | 4 + src/scriptapi_particles.cpp | 143 ++++++++++++++++++++ src/scriptapi_particles.h | 32 +++++ src/server.cpp | 232 ++++++++++++++++++++++++++++++++ src/server.h | 69 ++++++++++ 13 files changed, 1059 insertions(+), 55 deletions(-) create mode 100644 src/scriptapi_particles.cpp create mode 100644 src/scriptapi_particles.h (limited to 'src/scriptapi.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 3d47785ba..4edca5adb 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1028,6 +1028,37 @@ minetest.get_ban_description(ip_or_name) -> ban description (string) minetest.ban_player(name) -> ban a player minetest.unban_player_or_ip(name) -> unban player or IP address +Particles: +minetest.add_particle(pos, velocity, acceleration, expirationtime, + size, collisiondetection, texture, playername) +^ Spawn particle at pos with velocity and acceleration +^ Disappears after expirationtime seconds +^ collisiondetection: if true collides with physical objects +^ Uses texture (string) +^ Playername is optional, if specified spawns particle only on the player's client + +minetest.add_particlespawner(amount, time, + minpos, maxpos, + minvel, maxvel, + minacc, maxacc, + minexptime, maxexptime, + minsize, maxsize, + collisiondetection, texture, playername) +^ Add a particlespawner, an object that spawns an amount of particles over time seconds +^ The particle's properties are random values in between the boundings: +^ minpos/maxpos, minvel/maxvel (velocity), minacc/maxacc (acceleration), +^ minsize/maxsize, minexptime/maxexptime (expirationtime) +^ collisiondetection: if true uses collisiondetection +^ Uses texture (string) +^ Playername is optional, if specified spawns particle only on the player's client +^ If time is 0 has infinite lifespan and spawns the amount on a per-second base +^ Returns and id + +minetest.delete_particlespawner(id, player) +^ Delete ParticleSpawner with id (return value from add_particlespawner) +^ If playername is specified, only deletes on the player's client, +^ otherwise on all clients + Random: minetest.get_connected_players() -> list of ObjectRefs minetest.hash_node_position({x=,y=,z=}) -> 48-bit integer diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c2890f76..8f0cc1ac5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -219,6 +219,7 @@ set(common_SRCS scriptapi_object.cpp scriptapi_nodemeta.cpp scriptapi_inventory.cpp + scriptapi_particles.cpp scriptapi.cpp script.cpp log.cpp diff --git a/src/client.cpp b/src/client.cpp index 2ccace842..f27f95d98 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1936,6 +1936,89 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) event.show_formspec.formname = new std::string(formname); m_client_event_queue.push_back(event); } + else if(command == TOCLIENT_SPAWN_PARTICLE) + { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + v3f pos = readV3F1000(is); + v3f vel = readV3F1000(is); + v3f acc = readV3F1000(is); + float expirationtime = readF1000(is); + float size = readF1000(is); + bool collisiondetection = readU8(is); + std::string texture = deSerializeLongString(is); + + ClientEvent event; + event.type = CE_SPAWN_PARTICLE; + event.spawn_particle.pos = new v3f (pos); + event.spawn_particle.vel = new v3f (vel); + event.spawn_particle.acc = new v3f (acc); + + event.spawn_particle.expirationtime = expirationtime; + event.spawn_particle.size = size; + event.add_particlespawner.collisiondetection = + collisiondetection; + event.spawn_particle.texture = new std::string(texture); + + m_client_event_queue.push_back(event); + } + else if(command == TOCLIENT_ADD_PARTICLESPAWNER) + { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + u16 amount = readU16(is); + float spawntime = readF1000(is); + v3f minpos = readV3F1000(is); + v3f maxpos = readV3F1000(is); + v3f minvel = readV3F1000(is); + v3f maxvel = readV3F1000(is); + v3f minacc = readV3F1000(is); + v3f maxacc = readV3F1000(is); + float minexptime = readF1000(is); + float maxexptime = readF1000(is); + float minsize = readF1000(is); + float maxsize = readF1000(is); + bool collisiondetection = readU8(is); + std::string texture = deSerializeLongString(is); + u32 id = readU32(is); + + ClientEvent event; + event.type = CE_ADD_PARTICLESPAWNER; + event.add_particlespawner.amount = amount; + event.add_particlespawner.spawntime = spawntime; + + event.add_particlespawner.minpos = new v3f (minpos); + event.add_particlespawner.maxpos = new v3f (maxpos); + event.add_particlespawner.minvel = new v3f (minvel); + event.add_particlespawner.maxvel = new v3f (maxvel); + event.add_particlespawner.minacc = new v3f (minacc); + event.add_particlespawner.maxacc = new v3f (maxacc); + + event.add_particlespawner.minexptime = minexptime; + event.add_particlespawner.maxexptime = maxexptime; + event.add_particlespawner.minsize = minsize; + event.add_particlespawner.maxsize = maxsize; + event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.texture = new std::string(texture); + event.add_particlespawner.id = id; + + m_client_event_queue.push_back(event); + } + else if(command == TOCLIENT_DELETE_PARTICLESPAWNER) + { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + u32 id = readU16(is); + + ClientEvent event; + event.type = CE_DELETE_PARTICLESPAWNER; + event.delete_particlespawner.id = id; + + m_client_event_queue.push_back(event); + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/client.h b/src/client.h index 570a6b3b0..d476a1d51 100644 --- a/src/client.h +++ b/src/client.h @@ -157,7 +157,10 @@ enum ClientEventType CE_PLAYER_FORCE_MOVE, CE_DEATHSCREEN, CE_TEXTURES_UPDATED, - CE_SHOW_FORMSPEC + CE_SHOW_FORMSPEC, + CE_SPAWN_PARTICLE, + CE_ADD_PARTICLESPAWNER, + CE_DELETE_PARTICLESPAWNER }; struct ClientEvent @@ -185,6 +188,35 @@ struct ClientEvent } show_formspec; struct{ } textures_updated; + struct{ + v3f *pos; + v3f *vel; + v3f *acc; + f32 expirationtime; + f32 size; + bool collisiondetection; + std::string *texture; + } spawn_particle; + struct{ + u16 amount; + f32 spawntime; + v3f *minpos; + v3f *maxpos; + v3f *minvel; + v3f *maxvel; + v3f *minacc; + v3f *maxacc; + f32 minexptime; + f32 maxexptime; + f32 minsize; + f32 maxsize; + bool collisiondetection; + std::string *texture; + u32 id; + } add_particlespawner; + struct{ + u32 id; + } delete_particlespawner; }; }; diff --git a/src/clientserver.h b/src/clientserver.h index 6d830b92b..535fc04d8 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -82,6 +82,9 @@ SharedBuffer makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed); PROTOCOL_VERSION 17: Serialization format change: include backface_culling flag in TileDef Added rightclickable field in nodedef + TOCLIENT_SPAWN_PARTICLE + TOCLIENT_ADD_PARTICLESPAWNER + TOCLIENT_DELETE_PARTICLESPAWNER */ #define LATEST_PROTOCOL_VERSION 17 @@ -359,6 +362,7 @@ enum ToClientCommand u8[len] name [2] serialized inventory */ + TOCLIENT_SHOW_FORMSPEC = 0x44, /* [0] u16 command @@ -384,6 +388,46 @@ enum ToClientCommand f1000 movement_liquid_sink f1000 movement_gravity */ + + TOCLIENT_SPAWN_PARTICLE = 0x46, + /* + u16 command + v3f1000 pos + v3f1000 velocity + v3f1000 acceleration + f1000 expirationtime + f1000 size + u8 bool collisiondetection + u32 len + u8[len] texture + */ + + TOCLIENT_ADD_PARTICLESPAWNER = 0x47, + /* + u16 command + u16 amount + f1000 spawntime + v3f1000 minpos + v3f1000 maxpos + v3f1000 minvel + v3f1000 maxvel + v3f1000 minacc + v3f1000 maxacc + f1000 minexptime + f1000 maxexptime + f1000 minsize + f1000 maxsize + u8 bool collisiondetection + u32 len + u8[len] texture + u32 id + */ + + TOCLIENT_DELETE_PARTICLESPAWNER = 0x48, + /* + u16 command + u32 id + */ }; enum ToServerCommand diff --git a/src/game.cpp b/src/game.cpp index 1ae29b13b..58ca654a0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2186,6 +2186,47 @@ void the_game( { update_wielded_item_trigger = true; } + else if(event.type == CE_SPAWN_PARTICLE) + { + LocalPlayer* player = client.getEnv().getLocalPlayer(); + AtlasPointer ap = + gamedef->tsrc()->getTexture(*(event.spawn_particle.texture)); + + new Particle(gamedef, smgr, player, client.getEnv(), + *event.spawn_particle.pos, + *event.spawn_particle.vel, + *event.spawn_particle.acc, + event.spawn_particle.expirationtime, + event.spawn_particle.size, + event.spawn_particle.collisiondetection, ap); + } + else if(event.type == CE_ADD_PARTICLESPAWNER) + { + LocalPlayer* player = client.getEnv().getLocalPlayer(); + AtlasPointer ap = + gamedef->tsrc()->getTexture(*(event.add_particlespawner.texture)); + + new ParticleSpawner(gamedef, smgr, player, + event.add_particlespawner.amount, + event.add_particlespawner.spawntime, + *event.add_particlespawner.minpos, + *event.add_particlespawner.maxpos, + *event.add_particlespawner.minvel, + *event.add_particlespawner.maxvel, + *event.add_particlespawner.minacc, + *event.add_particlespawner.maxacc, + event.add_particlespawner.minexptime, + event.add_particlespawner.maxexptime, + event.add_particlespawner.minsize, + event.add_particlespawner.maxsize, + event.add_particlespawner.collisiondetection, + ap, + event.add_particlespawner.id); + } + else if(event.type == CE_DELETE_PARTICLESPAWNER) + { + delete_particlespawner (event.delete_particlespawner.id); + } } } @@ -2415,7 +2456,8 @@ void the_game( const ContentFeatures &features = client.getNodeDefManager()->get(n); addPunchingParticles - (gamedef, smgr, player, nodepos, features.tiles); + (gamedef, smgr, player, client.getEnv(), + nodepos, features.tiles); } } @@ -2453,7 +2495,8 @@ void the_game( const ContentFeatures &features = client.getNodeDefManager()->get(wasnode); addDiggingParticles - (gamedef, smgr, player, nodepos, features.tiles); + (gamedef, smgr, player, client.getEnv(), + nodepos, features.tiles); } dig_time = 0; @@ -2734,6 +2777,7 @@ void the_game( */ allparticles_step(dtime, client.getEnv()); + allparticlespawners_step(dtime, client.getEnv()); /* Fog @@ -3220,6 +3264,7 @@ void the_game( clouds->drop(); if(gui_chat_console) gui_chat_console->drop(); + clear_particles (); /* Draw a "shutting down" screen, which will be shown while the map diff --git a/src/particles.cpp b/src/particles.cpp index fef21d91b..0445d7726 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -32,19 +32,34 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clientmap.h" #include "mapnode.h" +/* + Utility +*/ + +v3f random_v3f(v3f min, v3f max) +{ + return v3f( rand()/(float)RAND_MAX*(max.X-min.X)+min.X, + rand()/(float)RAND_MAX*(max.Y-min.Y)+min.Y, + rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); +} + +std::vector all_particles; +std::map all_particlespawners; + Particle::Particle( IGameDef *gamedef, scene::ISceneManager* smgr, LocalPlayer *player, - s32 id, + ClientEnvironment &env, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, + bool collisiondetection, AtlasPointer ap ): - scene::ISceneNode(smgr->getRootSceneNode(), smgr, id) + scene::ISceneNode(smgr->getRootSceneNode(), smgr) { // Misc m_gamedef = gamedef; @@ -57,7 +72,6 @@ Particle::Particle( m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_material.setTexture(0, ap.atlas); m_ap = ap; - m_light = 0; // Particle related @@ -68,10 +82,20 @@ Particle::Particle( m_time = 0; m_player = player; m_size = size; + m_collisiondetection = collisiondetection; - // Irrlicht stuff (TODO) - m_collisionbox = core::aabbox3d(-size/2,-size/2,-size/2,size/2,size/2,size/2); + // Irrlicht stuff + m_collisionbox = core::aabbox3d + (-size/2,-size/2,-size/2,size/2,size/2,size/2); this->setAutomaticCulling(scene::EAC_OFF); + + // Init lighting + updateLight(env); + + // Init model + updateVertices(); + + all_particles.push_back(this); } Particle::~Particle() @@ -82,8 +106,10 @@ void Particle::OnRegisterSceneNode() { if (IsVisible) { - SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); - SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + SceneManager->registerNodeForRendering + (this, scene::ESNRP_TRANSPARENT); + SceneManager->registerNodeForRendering + (this, scene::ESNRP_SOLID); } ISceneNode::OnRegisterSceneNode(); @@ -96,45 +122,45 @@ void Particle::render() video::IVideoDriver* driver = SceneManager->getVideoDriver(); driver->setMaterial(m_material); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); - video::SColor c(255, m_light, m_light, m_light); - - video::S3DVertex vertices[4] = - { - video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, c, m_ap.x0(), m_ap.y1()), - video::S3DVertex(m_size/2,-m_size/2,0, 0,0,0, c, m_ap.x1(), m_ap.y1()), - video::S3DVertex(m_size/2,m_size/2,0, 0,0,0, c, m_ap.x1(), m_ap.y0()), - video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0, c ,m_ap.x0(), m_ap.y0()), - }; - - for(u16 i=0; i<4; i++) - { - vertices[i].Pos.rotateYZBy(m_player->getPitch()); - vertices[i].Pos.rotateXZBy(m_player->getYaw()); - m_box.addInternalPoint(vertices[i].Pos); - vertices[i].Pos += m_pos*BS; - } u16 indices[] = {0,1,2, 2,3,0}; - driver->drawVertexPrimitiveList(vertices, 4, indices, 2, - video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); + driver->drawVertexPrimitiveList(m_vertices, 4, + indices, 2, video::EVT_STANDARD, + scene::EPT_TRIANGLES, video::EIT_16BIT); } void Particle::step(float dtime, ClientEnvironment &env) { - core::aabbox3d box = m_collisionbox; - v3f p_pos = m_pos*BS; - v3f p_velocity = m_velocity*BS; - v3f p_acceleration = m_acceleration*BS; - collisionMoveSimple(&env.getClientMap(), m_gamedef, - BS*0.5, box, - 0, dtime, - p_pos, p_velocity, p_acceleration); - m_pos = p_pos/BS; - m_velocity = p_velocity/BS; - m_acceleration = p_acceleration/BS; m_time += dtime; + if (m_collisiondetection) + { + core::aabbox3d box = m_collisionbox; + v3f p_pos = m_pos*BS; + v3f p_velocity = m_velocity*BS; + v3f p_acceleration = m_acceleration*BS; + collisionMoveSimple(&env.getClientMap(), m_gamedef, + BS*0.5, box, + 0, dtime, + p_pos, p_velocity, p_acceleration); + m_pos = p_pos/BS; + m_velocity = p_velocity/BS; + m_acceleration = p_acceleration/BS; + } + else + { + m_velocity += m_acceleration * dtime; + m_pos += m_velocity * dtime; + } // Update lighting + updateLight(env); + + // Update model + updateVertices(); +} + +void Particle::updateLight(ClientEnvironment &env) +{ u8 light = 0; try{ v3s16 p = v3s16( @@ -151,11 +177,37 @@ void Particle::step(float dtime, ClientEnvironment &env) m_light = decode_light(light); } -std::vector all_particles; +void Particle::updateVertices() +{ + video::SColor c(255, m_light, m_light, m_light); + m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, + c, m_ap.x0(), m_ap.y1()); + m_vertices[1] = video::S3DVertex(m_size/2,-m_size/2,0, 0,0,0, + c, m_ap.x1(), m_ap.y1()); + m_vertices[2] = video::S3DVertex(m_size/2,m_size/2,0, 0,0,0, + c, m_ap.x1(), m_ap.y0()); + m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0, + c ,m_ap.x0(), m_ap.y0()); + + for(u16 i=0; i<4; i++) + { + m_vertices[i].Pos.rotateYZBy(m_player->getPitch()); + m_vertices[i].Pos.rotateXZBy(m_player->getYaw()); + m_box.addInternalPoint(m_vertices[i].Pos); + m_vertices[i].Pos += m_pos*BS; + } +} + + +/* + Helpers +*/ + void allparticles_step (float dtime, ClientEnvironment &env) { - for(std::vector::iterator i = all_particles.begin(); i != all_particles.end();) + for(std::vector::iterator i = all_particles.begin(); + i != all_particles.end();) { if ((*i)->get_expired()) { @@ -171,22 +223,28 @@ void allparticles_step (float dtime, ClientEnvironment &env) } } -void addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]) +void addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, v3s16 pos, + const TileSpec tiles[]) { for (u16 j = 0; j < 32; j++) // set the amount of particles here { - addNodeParticle(gamedef, smgr, player, pos, tiles); + addNodeParticle(gamedef, smgr, player, env, pos, tiles); } } -void addPunchingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]) +void addPunchingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, + v3s16 pos, const TileSpec tiles[]) { - addNodeParticle(gamedef, smgr, player, pos, tiles); + addNodeParticle(gamedef, smgr, player, env, pos, tiles); } // add a particle of a node // used by digging and punching particles -void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]) +void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, v3s16 pos, + const TileSpec tiles[]) { // Texture u8 texid = myrand_range(0,5); @@ -205,7 +263,10 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer ap.pos.Y = ap.y0() + (y1 - ap.y0()) * ((rand()%64)/64.-texsize); // Physics - v3f velocity((rand()%100/50.-1)/1.5, rand()%100/35., (rand()%100/50.-1)/1.5); + v3f velocity( (rand()%100/50.-1)/1.5, + rand()%100/35., + (rand()%100/50.-1)/1.5); + v3f acceleration(0,-9,0); v3f particlepos = v3f( (f32)pos.X+rand()%100/200.-0.25, @@ -213,17 +274,180 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer (f32)pos.Z+rand()%100/200.-0.25 ); - Particle *particle = new Particle( + new Particle( gamedef, smgr, player, - 0, + env, particlepos, velocity, acceleration, rand()%100/100., // expiration time visual_size, + true, ap); +} - all_particles.push_back(particle); +/* + ParticleSpawner +*/ + +ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, LocalPlayer *player, + u16 amount, float time, + v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, + float minexptime, float maxexptime, float minsize, float maxsize, + bool collisiondetection, AtlasPointer ap, u32 id) +{ + m_gamedef = gamedef; + m_smgr = smgr; + m_player = player; + m_amount = amount; + m_spawntime = time; + m_minpos = minpos; + m_maxpos = maxpos; + m_minvel = minvel; + m_maxvel = maxvel; + m_minacc = minacc; + m_maxacc = maxacc; + m_minexptime = minexptime; + m_maxexptime = maxexptime; + m_minsize = minsize; + m_maxsize = maxsize; + m_collisiondetection = collisiondetection; + m_ap = ap; + m_time = 0; + + for (u16 i = 0; i<=m_amount; i++) + { + float spawntime = (float)rand()/(float)RAND_MAX*m_spawntime; + m_spawntimes.push_back(spawntime); + } + + all_particlespawners.insert(std::pair(id, this)); +} + +ParticleSpawner::~ParticleSpawner() {} + +void ParticleSpawner::step(float dtime, ClientEnvironment &env) +{ + m_time += dtime; + + if (m_spawntime != 0) // Spawner exists for a predefined timespan + { + for(std::vector::iterator i = m_spawntimes.begin(); + i != m_spawntimes.end();) + { + if ((*i) <= m_time && m_amount > 0) + { + m_amount--; + + v3f pos = random_v3f(m_minpos, m_maxpos); + v3f vel = random_v3f(m_minvel, m_maxvel); + v3f acc = random_v3f(m_minacc, m_maxacc); + float exptime = rand()/(float)RAND_MAX + *(m_maxexptime-m_minexptime) + +m_minexptime; + float size = rand()/(float)RAND_MAX + *(m_maxsize-m_minsize) + +m_minsize; + + new Particle( + m_gamedef, + m_smgr, + m_player, + env, + pos, + vel, + acc, + exptime, + size, + m_collisiondetection, + m_ap); + m_spawntimes.erase(i); + } + else + { + i++; + } + } + } + else // Spawner exists for an infinity timespan, spawn on a per-second base + { + for (int i = 0; i <= m_amount; i++) + { + if (rand()/(float)RAND_MAX < dtime) + { + v3f pos = random_v3f(m_minpos, m_maxpos); + v3f vel = random_v3f(m_minvel, m_maxvel); + v3f acc = random_v3f(m_minacc, m_maxacc); + float exptime = rand()/(float)RAND_MAX + *(m_maxexptime-m_minexptime) + +m_minexptime; + float size = rand()/(float)RAND_MAX + *(m_maxsize-m_minsize) + +m_minsize; + + new Particle( + m_gamedef, + m_smgr, + m_player, + env, + pos, + vel, + acc, + exptime, + size, + m_collisiondetection, + m_ap); + } + } + } +} + +void allparticlespawners_step (float dtime, ClientEnvironment &env) +{ + for(std::map::iterator i = + all_particlespawners.begin(); + i != all_particlespawners.end();) + { + if (i->second->get_expired()) + { + delete i->second; + all_particlespawners.erase(i++); + } + else + { + i->second->step(dtime, env); + i++; + } + } +} + +void delete_particlespawner (u32 id) +{ + if (all_particlespawners.find(id) != all_particlespawners.end()) + { + delete all_particlespawners.find(id)->second; + all_particlespawners.erase(id); + } +} + +void clear_particles () +{ + for(std::map::iterator i = + all_particlespawners.begin(); + i != all_particlespawners.end();) + { + delete i->second; + all_particlespawners.erase(i++); + } + + for(std::vector::iterator i = + all_particles.begin(); + i != all_particles.end();) + { + (*i)->remove(); + delete *i; + all_particles.erase(i); + } } diff --git a/src/particles.h b/src/particles.h index b317549e7..308da551f 100644 --- a/src/particles.h +++ b/src/particles.h @@ -35,12 +35,13 @@ class Particle : public scene::ISceneNode IGameDef* gamedef, scene::ISceneManager* mgr, LocalPlayer *player, - s32 id, + ClientEnvironment &env, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, + bool collisiondetection, AtlasPointer texture ); ~Particle(); @@ -69,6 +70,10 @@ class Particle : public scene::ISceneNode { return m_expiration < m_time; } private: + void updateLight(ClientEnvironment &env); + void updateVertices(); + + video::S3DVertex m_vertices[4]; float m_time; float m_expiration; @@ -87,12 +92,71 @@ private: float m_size; AtlasPointer m_ap; u8 m_light; + bool m_collisiondetection; +}; + +class ParticleSpawner +{ + public: + ParticleSpawner(IGameDef* gamedef, + scene::ISceneManager *smgr, + LocalPlayer *player, + u16 amount, + float time, + v3f minp, v3f maxp, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, + AtlasPointer ap, + u32 id); + + ~ParticleSpawner(); + + void step(float dtime, ClientEnvironment &env); + + bool get_expired () + { return (m_amount <= 0) && m_spawntime != 0; } + + private: + float m_time; + IGameDef *m_gamedef; + scene::ISceneManager *m_smgr; + LocalPlayer *m_player; + u16 m_amount; + float m_spawntime; + v3f m_minpos; + v3f m_maxpos; + v3f m_minvel; + v3f m_maxvel; + v3f m_minacc; + v3f m_maxacc; + float m_minexptime; + float m_maxexptime; + float m_minsize; + float m_maxsize; + AtlasPointer m_ap; + std::vector m_spawntimes; + bool m_collisiondetection; }; void allparticles_step (float dtime, ClientEnvironment &env); +void allparticlespawners_step (float dtime, ClientEnvironment &env); + +void delete_particlespawner (u32 id); +void clear_particles (); + +void addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, v3s16 pos, + const TileSpec tiles[]); + +void addPunchingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, v3s16 pos, + const TileSpec tiles[]); -void addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]); -void addPunchingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]); -void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, LocalPlayer *player, v3s16 pos, const TileSpec tiles[]); +void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, + LocalPlayer *player, ClientEnvironment &env, v3s16 pos, + const TileSpec tiles[]); #endif diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 13696eabf..29494ff69 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -44,6 +44,7 @@ extern "C" { #include "scriptapi_item.h" #include "scriptapi_content.h" #include "scriptapi_craft.h" +#include "scriptapi_particles.h" /*****************************************************************************/ /* Mod related */ @@ -1089,6 +1090,9 @@ static const struct luaL_Reg minetest_f [] = { {"get_all_craft_recipes", l_get_all_craft_recipes}, {"rollback_get_last_node_actor", l_rollback_get_last_node_actor}, {"rollback_revert_actions_by", l_rollback_revert_actions_by}, + {"add_particle", l_add_particle}, + {"add_particlespawner", l_add_particlespawner}, + {"delete_particlespawner", l_delete_particlespawner}, {NULL, NULL} }; diff --git a/src/scriptapi_particles.cpp b/src/scriptapi_particles.cpp new file mode 100644 index 000000000..dc9b3776e --- /dev/null +++ b/src/scriptapi_particles.cpp @@ -0,0 +1,143 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "scriptapi.h" +#include "scriptapi_particles.h" +#include "server.h" +#include "script.h" +#include "scriptapi_types.h" +#include "scriptapi_common.h" + +// add_particle(pos, velocity, acceleration, expirationtime, +// size, collisiondetection, texture, player) +// pos/velocity/acceleration = {x=num, y=num, z=num} +// expirationtime = num (seconds) +// size = num +// texture = e.g."default_wood.png" +int l_add_particle(lua_State *L) +{ + // Get server from registry + Server *server = get_server(L); + // Get parameters + v3f pos = check_v3f(L, 1); + v3f vel = check_v3f(L, 2); + v3f acc = check_v3f(L, 3); + float expirationtime = luaL_checknumber(L, 4); + float size = luaL_checknumber(L, 5); + bool collisiondetection = lua_toboolean(L, 6); + std::string texture = luaL_checkstring(L, 7); + + if (lua_gettop(L) == 8) // only spawn for a single player + { + const char *playername = luaL_checkstring(L, 8); + server->spawnParticle(playername, + pos, vel, acc, expirationtime, + size, collisiondetection, texture); + } + else // spawn for all players + { + server->spawnParticleAll(pos, vel, acc, + expirationtime, size, collisiondetection, texture); + } + return 1; +} + +// add_particlespawner(amount, time, +// minpos, maxpos, +// minvel, maxvel, +// minacc, maxacc, +// minexptime, maxexptime, +// minsize, maxsize, +// collisiondetection, +// texture, +// player) +// minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num} +// minexptime/maxexptime = num (seconds) +// minsize/maxsize = num +// collisiondetection = bool +// texture = e.g."default_wood.png" +int l_add_particlespawner(lua_State *L) +{ + // Get server from registry + Server *server = get_server(L); + // Get parameters + u16 amount = luaL_checknumber(L, 1); + float time = luaL_checknumber(L, 2); + v3f minpos = check_v3f(L, 3); + v3f maxpos = check_v3f(L, 4); + v3f minvel = check_v3f(L, 5); + v3f maxvel = check_v3f(L, 6); + v3f minacc = check_v3f(L, 7); + v3f maxacc = check_v3f(L, 8); + float minexptime = luaL_checknumber(L, 9); + float maxexptime = luaL_checknumber(L, 10); + float minsize = luaL_checknumber(L, 11); + float maxsize = luaL_checknumber(L, 12); + bool collisiondetection = lua_toboolean(L, 13); + std::string texture = luaL_checkstring(L, 14); + + if (lua_gettop(L) == 15) // only spawn for a single player + { + const char *playername = luaL_checkstring(L, 15); + u32 id = server->addParticleSpawner(playername, + amount, time, + minpos, maxpos, + minvel, maxvel, + minacc, maxacc, + minexptime, maxexptime, + minsize, maxsize, + collisiondetection, + texture); + lua_pushnumber(L, id); + } + else // spawn for all players + { + u32 id = server->addParticleSpawnerAll( amount, time, + minpos, maxpos, + minvel, maxvel, + minacc, maxacc, + minexptime, maxexptime, + minsize, maxsize, + collisiondetection, + texture); + lua_pushnumber(L, id); + } + return 1; +} + +// delete_particlespawner(id, player) +// player (string) is optional +int l_delete_particlespawner(lua_State *L) +{ + // Get server from registry + Server *server = get_server(L); + // Get parameters + u32 id = luaL_checknumber(L, 1); + + if (lua_gettop(L) == 2) // only delete for one player + { + const char *playername = luaL_checkstring(L, 2); + server->deleteParticleSpawner(playername, id); + } + else // delete for all players + { + server->deleteParticleSpawnerAll(id); + } + return 1; +} diff --git a/src/scriptapi_particles.h b/src/scriptapi_particles.h new file mode 100644 index 000000000..4b37d7ce1 --- /dev/null +++ b/src/scriptapi_particles.h @@ -0,0 +1,32 @@ +/* +Minetest-c55 +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef LUA_PARTICLES_H_ +#define LUA_PARTICLES_H_ + +extern "C" { +#include +#include +} + +int l_add_particle(lua_State *L); +int l_add_particlespawner(lua_State *L); +int l_delete_particlespawner(lua_State *L); + +#endif diff --git a/src/server.cpp b/src/server.cpp index f77ac6ad9..644f89349 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server.h" #include #include +#include #include "clientserver.h" #include "map.h" #include "jmutexautolock.h" @@ -3474,6 +3475,132 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, co m_con.Send(peer_id, 0, data, true); } +// Spawns a particle on peer with peer_id +void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture) +{ + DSTACK(__FUNCTION_NAME); + + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOCLIENT_SPAWN_PARTICLE); + writeV3F1000(os, pos); + writeV3F1000(os, velocity); + writeV3F1000(os, acceleration); + writeF1000(os, expirationtime); + writeF1000(os, size); + writeU8(os, collisiondetection); + os< data((u8*)s.c_str(), s.size()); + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} + +// Spawns a particle on all peers +void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture) +{ + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); i++) + { + // Get client and check that it is valid + RemoteClient *client = i->second; + assert(client->peer_id == i->first); + if(client->serialization_version == SER_FMT_VER_INVALID) + continue; + + SendSpawnParticle(client->peer_id, pos, velocity, acceleration, + expirationtime, size, collisiondetection, texture); + } +} + +// Adds a ParticleSpawner on peer with peer_id +void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, + float minsize, float maxsize, bool collisiondetection, std::string texture, u32 id) +{ + DSTACK(__FUNCTION_NAME); + + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOCLIENT_ADD_PARTICLESPAWNER); + + writeU16(os, amount); + writeF1000(os, spawntime); + writeV3F1000(os, minpos); + writeV3F1000(os, maxpos); + writeV3F1000(os, minvel); + writeV3F1000(os, maxvel); + writeV3F1000(os, minacc); + writeV3F1000(os, maxacc); + writeF1000(os, minexptime); + writeF1000(os, maxexptime); + writeF1000(os, minsize); + writeF1000(os, maxsize); + writeU8(os, collisiondetection); + os< data((u8*)s.c_str(), s.size()); + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} + +// Adds a ParticleSpawner on all peers +void Server::SendAddParticleSpawnerAll(u16 amount, float spawntime, v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, + float minsize, float maxsize, bool collisiondetection, std::string texture, u32 id) +{ + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); i++) + { + // Get client and check that it is valid + RemoteClient *client = i->second; + assert(client->peer_id == i->first); + if(client->serialization_version == SER_FMT_VER_INVALID) + continue; + + SendAddParticleSpawner(client->peer_id, amount, spawntime, + minpos, maxpos, minvel, maxvel, minacc, maxacc, + minexptime, maxexptime, minsize, maxsize, collisiondetection, texture, id); + } +} + +void Server::SendDeleteParticleSpawner(u16 peer_id, u32 id) +{ + DSTACK(__FUNCTION_NAME); + + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOCLIENT_DELETE_PARTICLESPAWNER); + + writeU16(os, id); + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8*)s.c_str(), s.size()); + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} + +void Server::SendDeleteParticleSpawnerAll(u32 id) +{ + for(std::map::iterator + i = m_clients.begin(); + i != m_clients.end(); i++) + { + // Get client and check that it is valid + RemoteClient *client = i->second; + assert(client->peer_id == i->first); + if(client->serialization_version == SER_FMT_VER_INVALID) + continue; + + SendDeleteParticleSpawner(client->peer_id, id); + } +} + void Server::BroadcastChatMessage(const std::wstring &message) { for(std::map::iterator @@ -4432,6 +4559,111 @@ void Server::notifyPlayers(const std::wstring msg) BroadcastChatMessage(msg); } +void Server::spawnParticle(const char *playername, v3f pos, + v3f velocity, v3f acceleration, + float expirationtime, float size, bool + collisiondetection, std::string texture) +{ + Player *player = m_env->getPlayer(playername); + if(!player) + return; + SendSpawnParticle(player->peer_id, pos, velocity, acceleration, + expirationtime, size, collisiondetection, texture); +} + +void Server::spawnParticleAll(v3f pos, v3f velocity, v3f acceleration, + float expirationtime, float size, + bool collisiondetection, std::string texture) +{ + SendSpawnParticleAll(pos, velocity, acceleration, + expirationtime, size, collisiondetection, texture); +} + +u32 Server::addParticleSpawner(const char *playername, + u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture) +{ + Player *player = m_env->getPlayer(playername); + if(!player) + return -1; + + u32 id = 0; + for(;;) // look for unused particlespawner id + { + id++; + if (std::find(m_particlespawner_ids.begin(), + m_particlespawner_ids.end(), id) + == m_particlespawner_ids.end()) + { + m_particlespawner_ids.push_back(id); + break; + } + } + + SendAddParticleSpawner(player->peer_id, amount, spawntime, + minpos, maxpos, minvel, maxvel, minacc, maxacc, + minexptime, maxexptime, minsize, maxsize, + collisiondetection, texture, id); + + return id; +} + +u32 Server::addParticleSpawnerAll(u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture) +{ + u32 id = 0; + for(;;) // look for unused particlespawner id + { + id++; + if (std::find(m_particlespawner_ids.begin(), + m_particlespawner_ids.end(), id) + == m_particlespawner_ids.end()) + { + m_particlespawner_ids.push_back(id); + break; + } + } + + SendAddParticleSpawnerAll(amount, spawntime, + minpos, maxpos, minvel, maxvel, minacc, maxacc, + minexptime, maxexptime, minsize, maxsize, + collisiondetection, texture, id); + + return id; +} + +void Server::deleteParticleSpawner(const char *playername, u32 id) +{ + Player *player = m_env->getPlayer(playername); + if(!player) + return; + + m_particlespawner_ids.erase( + std::remove(m_particlespawner_ids.begin(), + m_particlespawner_ids.end(), id), + m_particlespawner_ids.end()); + SendDeleteParticleSpawner(player->peer_id, id); +} + +void Server::deleteParticleSpawnerAll(u32 id) +{ + m_particlespawner_ids.erase( + std::remove(m_particlespawner_ids.begin(), + m_particlespawner_ids.end(), id), + m_particlespawner_ids.end()); + SendDeleteParticleSpawnerAll(id); +} + void Server::queueBlockEmerge(v3s16 blockpos, bool allow_generate) { m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, blockpos, allow_generate); diff --git a/src/server.h b/src/server.h index 63717eaec..813dc9828 100644 --- a/src/server.h +++ b/src/server.h @@ -456,6 +456,35 @@ public: // Envlock and conlock should be locked when calling this void notifyPlayer(const char *name, const std::wstring msg); void notifyPlayers(const std::wstring msg); + void spawnParticle(const char *playername, + v3f pos, v3f velocity, v3f acceleration, + float expirationtime, float size, + bool collisiondetection, std::string texture); + + void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration, + float expirationtime, float size, + bool collisiondetection, std::string texture); + + u32 addParticleSpawner(const char *playername, + u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture); + + u32 addParticleSpawnerAll(u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture); + + void deleteParticleSpawner(const char *playername, u32 id); + void deleteParticleSpawnerAll(u32 id); + void queueBlockEmerge(v3s16 blockpos, bool allow_generate); @@ -574,6 +603,41 @@ private: void sendDetachedInventoryToAll(const std::string &name); void sendDetachedInventories(u16 peer_id); + // Adds a ParticleSpawner on peer with peer_id + void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture, u32 id); + + // Adds a ParticleSpawner on all peers + void SendAddParticleSpawnerAll(u16 amount, float spawntime, + v3f minpos, v3f maxpos, + v3f minvel, v3f maxvel, + v3f minacc, v3f maxacc, + float minexptime, float maxexptime, + float minsize, float maxsize, + bool collisiondetection, std::string texture, u32 id); + + // Deletes ParticleSpawner on a single client + void SendDeleteParticleSpawner(u16 peer_id, u32 id); + + // Deletes ParticleSpawner on all clients + void SendDeleteParticleSpawnerAll(u32 id); + + // Spawns particle on single client + void SendSpawnParticle(u16 peer_id, + v3f pos, v3f velocity, v3f acceleration, + float expirationtime, float size, + bool collisiondetection, std::string texture); + + // Spawns particle on all clients + void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, + float expirationtime, float size, + bool collisiondetection, std::string texture); + /* Something random */ @@ -790,6 +854,11 @@ private: */ // key = name std::map m_detached_inventories; + + /* + Particles + */ + std::vector m_particlespawner_ids; }; /* -- cgit v1.2.3 From 57cbb8bfd8daaa1b8b1aa876723ff6355d21f7fc Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 24 Mar 2013 01:43:38 -0400 Subject: Add Ore infrastructure and l_register_ore() --- src/emerge.h | 3 +- src/mapgen.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mapgen.h | 43 ++++++++++++++++ src/mapgen_indev.cpp | 4 +- src/mapgen_indev.h | 4 +- src/mapgen_v6.cpp | 14 +++-- src/mapgen_v6.h | 6 ++- src/scriptapi.cpp | 46 ++++++++++++++++- src/scriptapi_noise.cpp | 2 + src/server.cpp | 9 ++-- 10 files changed, 248 insertions(+), 17 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/emerge.h b/src/emerge.h index 70b67e731..3d717bce3 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -63,8 +63,9 @@ public: std::map blocks_enqueued; std::map peer_queue_count; - //biome manager + //Mapgen-related structures BiomeDefManager *biomedef; + std::vector ores; EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef); ~EmergeManager(); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index dc6dab6bb..53b5d6867 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -49,6 +49,140 @@ FlagDesc flagdesc_mapgen[] = { /////////////////////////////////////////////////////////////////////////////// +Ore *createOre(OreType type) { + switch (type) { + case ORE_SCATTER: + return new OreScatter; + case ORE_SHEET: + return new OreSheet; + //case ORE_CLAYLIKE: //TODO: implement this! + // return new OreClaylike; + default: + return NULL; + } +} + + +void Ore::resolveNodeNames(INodeDefManager *ndef) { + if (ore == CONTENT_IGNORE) { + ore = ndef->getId(ore_name); + if (ore == CONTENT_IGNORE) { + errorstream << "Ore::resolveNodeNames: ore node '" + << ore_name << "' not defined"; + ore = CONTENT_AIR; + wherein = CONTENT_AIR; + } + } + + if (wherein == CONTENT_IGNORE) { + wherein = ndef->getId(wherein_name); + if (wherein == CONTENT_IGNORE) { + errorstream << "Ore::resolveNodeNames: wherein node '" + << wherein_name << "' not defined"; + ore = CONTENT_AIR; + wherein = CONTENT_AIR; + } + } +} + + +void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { + if (nmin.Y > height_max || nmax.Y < height_min) + return; + + resolveNodeNames(mg->ndef); + + MapNode n_ore(ore); + ManualMapVoxelManipulator *vm = mg->vm; + PseudoRandom pr(blockseed); + + int ymin = MYMAX(nmin.Y, height_min); + int ymax = MYMIN(nmax.Y, height_max); + if (clust_size >= ymax - ymin + 1) + return; + + int volume = (nmax.X - nmin.X + 1) * + (nmax.Y - nmin.Y + 1) * + (nmax.Z - nmin.Z + 1); + int csize = clust_size; + int orechance = (csize * csize * csize) / clust_num_ores; + int nclusters = volume / clust_scarcity; + + for (int i = 0; i != nclusters; i++) { + int x0 = pr.range(nmin.X, nmax.X - csize + 1); + int y0 = pr.range(ymin, ymax - csize + 1); + int z0 = pr.range(nmin.Z, nmax.Z - csize + 1); + + if (np && (NoisePerlin3D(np, x0, y0, z0, mg->seed) < nthresh)) + continue; + + for (int z1 = 0; z1 != csize; z1++) + for (int y1 = 0; y1 != csize; y1++) + for (int x1 = 0; x1 != csize; x1++) { + if (pr.range(1, orechance) != 1) + continue; + + u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1); + if (vm->m_data[i].getContent() == wherein) + vm->m_data[i] = n_ore; + } + } +} + + +void OreSheet::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { + if (nmin.Y > height_max || nmax.Y < height_min) + return; + + resolveNodeNames(mg->ndef); + + MapNode n_ore(ore); + ManualMapVoxelManipulator *vm = mg->vm; + PseudoRandom pr(blockseed + 4234); + + int ymin = MYMAX(nmin.Y, height_min); + int ymax = MYMIN(nmax.Y, height_max); + + int x0 = nmin.X; + int z0 = nmin.Z; + + int x1 = nmax.X; + int z1 = nmax.Z; + + int max_height = clust_size; + + int y_start = pr.range(ymin, ymax - max_height); + + if (!noise) { + int sx = nmax.X - nmin.X + 1; + int sz = nmax.Z - nmin.Z + 1; + noise = new Noise(np, 0, sx, sz); + } + noise->seed = mg->seed + y_start; + noise->perlinMap2D(x0, z0); + + int index = 0; + for (int z = z0; z != z1; z++) + for (int x = x0; x != x1; x++) { + + if (noise->result[index++] < nthresh) + continue; + + int height = max_height * (1. / pr.range(1, 3)); + int y0 = y_start + pr.range(1, 3) - 1; + int y1 = y0 + height; + for (int y = y0; y != y1; y++) { + u32 i = vm->m_area.index(x, y, z); + if (!vm->m_area.contains(i)) + continue; + + if (vm->m_data[i].getContent() == wherein) + vm->m_data[i] = n_ore; + } + } +} + + void Mapgen::updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax) { bool isliquid, wasliquid; v3s16 em = vm->m_area.getExtent(); diff --git a/src/mapgen.h b/src/mapgen.h index 2e917a3aa..a900985da 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -97,5 +97,48 @@ struct MapgenFactory { virtual MapgenParams *createMapgenParams() = 0; }; +enum OreType { + ORE_SCATTER, + ORE_SHEET, + ORE_CLAYLIKE +}; + +class Ore { +public: + std::string ore_name; + std::string wherein_name; + + content_t ore; + content_t wherein; // the node to be replaced + s16 clust_scarcity; // + s16 clust_num_ores; // how many ore nodes are in a chunk + s16 clust_size; // how large (in nodes) a chunk of ore is + s16 height_min; + s16 height_max; + float nthresh; // threshhold for noise at which an ore is placed + NoiseParams *np; // noise for distribution of clusters (NULL for uniform scattering) + Noise *noise; + + Ore() { + ore = CONTENT_IGNORE; + wherein = CONTENT_IGNORE; + np = NULL; + noise = NULL; + } + + void resolveNodeNames(INodeDefManager *ndef); + virtual void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) = 0; +}; + +class OreScatter : public Ore { + void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); +}; + +class OreSheet : public Ore { + void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); +}; + +Ore *createOre(OreType type); + #endif diff --git a/src/mapgen_indev.cpp b/src/mapgen_indev.cpp index 6956fc63f..5d455827a 100644 --- a/src/mapgen_indev.cpp +++ b/src/mapgen_indev.cpp @@ -80,7 +80,9 @@ void NoiseIndev::transformNoiseMapFarScale(float xx, float yy, float zz) { } } -MapgenIndev::MapgenIndev(int mapgenid, MapgenIndevParams *params) : MapgenV6(mapgenid, params) { +MapgenIndev::MapgenIndev(int mapgenid, MapgenIndevParams *params, EmergeManager *emerge) + : MapgenV6(mapgenid, params, emerge) +{ noiseindev_terrain_base = new NoiseIndev(params->npindev_terrain_base, seed, csize.X, csize.Z); noiseindev_terrain_higher = new NoiseIndev(params->npindev_terrain_higher, seed, csize.X, csize.Z); noiseindev_steepness = new NoiseIndev(params->npindev_steepness, seed, csize.X, csize.Z); diff --git a/src/mapgen_indev.h b/src/mapgen_indev.h index 7ce65dfe3..fdac1ba20 100644 --- a/src/mapgen_indev.h +++ b/src/mapgen_indev.h @@ -126,7 +126,7 @@ class MapgenIndev : public MapgenV6 { NoiseIndev *noiseindev_float_islands2; NoiseIndev *noiseindev_float_islands3; - MapgenIndev(int mapgenid, MapgenIndevParams *params); + MapgenIndev(int mapgenid, MapgenIndevParams *params, EmergeManager *emerge); ~MapgenIndev(); void calculateNoise(); @@ -141,7 +141,7 @@ class MapgenIndev : public MapgenV6 { struct MapgenFactoryIndev : public MapgenFactoryV6 { Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) { - return new MapgenIndev(mgid, (MapgenIndevParams *)params); + return new MapgenIndev(mgid, (MapgenIndevParams *)params, emerge); }; MapgenParams *createMapgenParams() { diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 1efa3ad74..0b419617d 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -64,9 +64,10 @@ NoiseParams nparams_v6_def_apple_trees = /////////////////////////////////////////////////////////////////////////////// -MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params) { +MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge) { this->generating = false; this->id = mapgenid; + this->emerge = emerge; this->seed = (int)params->seed; this->water_level = params->water_level; @@ -463,6 +464,12 @@ void MapgenV6::makeChunk(BlockMakeData *data) { if (flags & MG_TREES) placeTreesAndJungleGrass(); + // Generate the registered ores + for (unsigned int i = 0; i != emerge->ores.size(); i++) { + Ore *ore = emerge->ores[i]; + ore->generate(this, blockseed + i, node_min, node_max); + } + // Calculate lighting calcLighting(node_min, node_max); @@ -494,14 +501,13 @@ void MapgenV6::calculateNoise() { noise_height_select->perlinMap2D( x + 0.5 * noise_height_select->np->spread.X, z + 0.5 * noise_height_select->np->spread.Z); - } - - if (!(flags & MG_FLAT)) { + noise_mud->perlinMap2D( x + 0.5 * noise_mud->np->spread.X, z + 0.5 * noise_mud->np->spread.Z); noise_mud->transformNoiseMap(); } + noise_beach->perlinMap2D( x + 0.2 * noise_beach->np->spread.X, z + 0.7 * noise_beach->np->spread.Z); diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h index 89a3324cd..d37e406cb 100644 --- a/src/mapgen_v6.h +++ b/src/mapgen_v6.h @@ -91,6 +91,8 @@ struct MapgenV6Params : public MapgenParams { class MapgenV6 : public Mapgen { public: + EmergeManager *emerge; + int ystride; v3s16 csize; u32 flags; @@ -128,7 +130,7 @@ public: content_t c_desert_sand; content_t c_desert_stone; - MapgenV6(int mapgenid, MapgenV6Params *params); + MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge); ~MapgenV6(); void makeChunk(BlockMakeData *data); @@ -172,7 +174,7 @@ public: struct MapgenFactoryV6 : public MapgenFactory { Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) { - return new MapgenV6(mgid, (MapgenV6Params *)params); + return new MapgenV6(mgid, (MapgenV6Params *)params, emerge); }; MapgenParams *createMapgenParams() { diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 29494ff69..ddffbb0b7 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -30,6 +30,7 @@ extern "C" { #include "settings.h" // For accessing g_settings #include "main.h" // For g_settings #include "biome.h" +#include "emerge.h" #include "script.h" #include "rollback.h" @@ -242,6 +243,14 @@ struct EnumString es_BiomeTerrainType[] = {0, NULL}, }; +struct EnumString es_OreType[] = +{ + {ORE_SCATTER, "scatter"}, + {ORE_SHEET, "sheet"}, + {ORE_CLAYLIKE, "claylike"}, + {0, NULL}, +}; + /*****************************************************************************/ /* Parameters */ /*****************************************************************************/ @@ -612,8 +621,6 @@ static int l_register_biome_groups(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); int index = 1; - if (!lua_istable(L, index)) - throw LuaError(L, "register_biome_groups: parameter is not a table"); BiomeDefManager *bmgr = get_server(L)->getBiomeDef(); if (!bmgr) { @@ -686,6 +693,40 @@ static int l_register_biome(lua_State *L) } +static int l_register_ore(lua_State *L) +{ + int index = 1; + luaL_checktype(L, index, LUA_TTABLE); + + IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager(); + EmergeManager *emerge = get_server(L)->getEmergeManager(); + + enum OreType oretype = (OreType)getenumfield(L, index, + "ore_type", es_OreType, ORE_SCATTER); + Ore *ore = createOre(oretype); + + ore->ore_name = getstringfield_default(L, index, "ore", ""); + ore->wherein_name = getstringfield_default(L, index, "wherein", ""); + ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 0); + ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 0); + ore->clust_size = getintfield_default(L, index, "clust_size", 0); + ore->height_min = getintfield_default(L, index, "height_min", 0); + ore->height_max = getintfield_default(L, index, "height_max", 0); + ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.); + + lua_getfield(L, index, "noise_params"); + ore->np = read_noiseparams(L, -1); + lua_pop(L, 1); + + ore->noise = NULL; + + emerge->ores.push_back(ore); + + verbosestream << "register_ore: ore '" << ore->ore_name + << "' registered" << std::endl; + return 0; +} + // setting_set(name, value) static int l_setting_set(lua_State *L) @@ -1060,6 +1101,7 @@ static const struct luaL_Reg minetest_f [] = { {"register_craft", l_register_craft}, {"register_biome", l_register_biome}, {"register_biome_groups", l_register_biome_groups}, + {"register_ore", l_register_ore}, {"setting_set", l_setting_set}, {"setting_get", l_setting_get}, {"setting_getbool", l_setting_getbool}, diff --git a/src/scriptapi_noise.cpp b/src/scriptapi_noise.cpp index 1dd6ef8e0..2c1a83c4c 100644 --- a/src/scriptapi_noise.cpp +++ b/src/scriptapi_noise.cpp @@ -269,6 +269,7 @@ NoiseParams *read_noiseparams(lua_State *L, int index) np->scale = getfloatfield_default(L, index, "scale", 0.0); lua_getfield(L, index, "spread"); np->spread = read_v3f(L, -1); + lua_pop(L, 1); np->seed = getintfield_default(L, index, "seed", 0); np->octaves = getintfield_default(L, index, "octaves", 0); np->persist = getfloatfield_default(L, index, "persist", 0.0); @@ -276,6 +277,7 @@ NoiseParams *read_noiseparams(lua_State *L, int index) return np; } + /* LuaPseudoRandom */ diff --git a/src/server.cpp b/src/server.cpp index 644f89349..db05b95cc 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -653,7 +653,6 @@ Server::Server( m_craftdef(createCraftDefManager()), m_event(new EventManager()), m_thread(this), - //m_emergethread(this), m_time_of_day_send_timer(0), m_uptime(0), m_shutdown_requested(false), @@ -698,7 +697,10 @@ Server::Server( // Create biome definition manager m_biomedef = new BiomeDefManager(this); - + + // Create emerge manager + m_emerge = new EmergeManager(this, m_biomedef); + // Create rollback manager std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt"; m_rollback = createRollbackManager(rollback_path, this); @@ -814,9 +816,6 @@ Server::Server( // Add default biomes after nodedef had its aliases added m_biomedef->addDefaultBiomes(); - // Create emerge manager - m_emerge = new EmergeManager(this, m_biomedef); - // Initialize Environment ServerMap *servermap = new ServerMap(path_world, this, m_emerge); m_env = new ServerEnvironment(servermap, m_lua, this, this); -- cgit v1.2.3 From 0e07a7157f4865c26b4d7d0ba6fb12f1de59373c Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 24 Mar 2013 15:29:23 -0400 Subject: Add more error checking to l_register_ore --- src/scriptapi.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index ddffbb0b7..80abffa2b 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -704,11 +704,16 @@ static int l_register_ore(lua_State *L) enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = createOre(oretype); + if (!ore) { + errorstream << "register_ore: ore_type " + << oretype << " not implemented"; + return 0; + } ore->ore_name = getstringfield_default(L, index, "ore", ""); ore->wherein_name = getstringfield_default(L, index, "wherein", ""); - ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 0); - ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 0); + ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); + ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->height_min = getintfield_default(L, index, "height_min", 0); ore->height_max = getintfield_default(L, index, "height_max", 0); @@ -720,6 +725,13 @@ static int l_register_ore(lua_State *L) ore->noise = NULL; + if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { + errorstream << "register_ore: clust_scarcity and clust_num_ores" + "must be greater than 0"; + delete ore; + return 0; + } + emerge->ores.push_back(ore); verbosestream << "register_ore: ore '" << ore->ore_name -- cgit v1.2.3