From 96898c179458174f858bab6363636ef231b49865 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Tue, 18 Dec 2012 13:23:16 -0500 Subject: Add initial Lua biomedef support, fixed biome selection --- src/scriptapi.cpp | 268 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 177 insertions(+), 91 deletions(-) (limited to 'src/scriptapi.cpp') diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 69ee48a76..27f48be27 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -37,6 +37,7 @@ extern "C" { #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 @@ -436,6 +437,16 @@ struct EnumString es_TileAnimationType[] = {0, NULL}, }; +struct EnumString es_BiomeTerrainType[] = +{ + {BIOME_TERRAIN_NORMAL, "normal"}, + {BIOME_TERRAIN_LIQUID, "liquid"}, + {BIOME_TERRAIN_NETHER, "nether"}, + {BIOME_TERRAIN_AETHER, "aether"}, + {BIOME_TERRAIN_FLAT, "flat"}, + {0, NULL}, +}; + /* C struct <-> Lua table converter functions */ @@ -988,7 +999,7 @@ static void read_object_properties(lua_State *L, int index, 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); @@ -1032,7 +1043,7 @@ static ItemDefinition read_item_definition(lua_State *L, int index, 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( @@ -1067,7 +1078,7 @@ 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 @@ -1113,7 +1124,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) 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; @@ -1138,7 +1149,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) 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 @@ -1173,7 +1184,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) } } lua_pop(L, 1); - + // special_tiles = {} lua_getfield(L, index, "special_tiles"); // If nil, try the deprecated name "special_materials" instead @@ -1204,7 +1215,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) 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); @@ -1228,7 +1239,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) "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); @@ -1264,7 +1275,7 @@ static ContentFeatures read_content_features(lua_State *L, int 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); @@ -1279,7 +1290,7 @@ static ContentFeatures read_content_features(lua_State *L, int index) 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)){ @@ -1368,7 +1379,7 @@ private: static const luaL_reg methods[]; // Exported functions - + // garbage collector static int gc_object(lua_State *L) { @@ -1621,7 +1632,7 @@ public: { 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) @@ -1810,7 +1821,7 @@ private: if(!ud) luaL_typerror(L, narg, className); return *(InvRef**)ud; // unbox pointer } - + static Inventory* getinv(lua_State *L, InvRef *ref) { return get_server(L)->getInventory(ref->m_loc); @@ -1830,9 +1841,9 @@ private: // 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)); @@ -2185,7 +2196,7 @@ private: 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); @@ -2212,9 +2223,9 @@ private: 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)); @@ -2327,7 +2338,7 @@ private: InvRef::createNodeMeta(L, ref->m_p); return 1; } - + // to_table(self) static int l_to_table(lua_State *L) { @@ -2373,7 +2384,7 @@ private: { NodeMetaRef *ref = checkobject(L, 1); int base = 2; - + if(lua_isnil(L, base)){ // No metadata ref->m_env->getMap().removeNodeMetadata(ref->m_p); @@ -2497,7 +2508,7 @@ public: if(!ud) luaL_typerror(L, narg, className); return *(ObjectRef**)ud; // unbox pointer } - + static ServerActiveObject* getobject(ObjectRef *ref) { ServerActiveObject *co = ref->m_object; @@ -2513,7 +2524,7 @@ private: return NULL; return (LuaEntitySAO*)obj; } - + static PlayerSAO* getplayersao(ObjectRef *ref) { ServerActiveObject *obj = getobject(ref); @@ -2523,7 +2534,7 @@ private: return NULL; return (PlayerSAO*)obj; } - + static Player* getplayer(ObjectRef *ref) { PlayerSAO *playersao = getplayersao(ref); @@ -2531,9 +2542,9 @@ private: return NULL; return playersao->getPlayer(); } - + // Exported functions - + // garbage collector static int gc_object(lua_State *L) { ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1)); @@ -2552,7 +2563,7 @@ private: co->m_removed = true; return 0; } - + // getpos(self) // returns: {x=num, y=num, z=num} static int l_getpos(lua_State *L) @@ -2570,7 +2581,7 @@ private: lua_setfield(L, -2, "z"); return 1; } - + // setpos(self, pos) static int l_setpos(lua_State *L) { @@ -2584,7 +2595,7 @@ private: co->setPos(pos); return 0; } - + // moveto(self, pos, continuous=false) static int l_moveto(lua_State *L) { @@ -2856,7 +2867,7 @@ private: co->setVelocity(pos); return 0; } - + // getvelocity(self) static int l_getvelocity(lua_State *L) { @@ -2868,7 +2879,7 @@ private: pushFloatPos(L, v); return 1; } - + // setacceleration(self, {x=num, y=num, z=num}) static int l_setacceleration(lua_State *L) { @@ -2881,7 +2892,7 @@ private: co->setAcceleration(pos); return 0; } - + // getacceleration(self) static int l_getacceleration(lua_State *L) { @@ -2893,7 +2904,7 @@ private: pushFloatPos(L, v); return 1; } - + // setyaw(self, radians) static int l_setyaw(lua_State *L) { @@ -2905,7 +2916,7 @@ private: co->setYaw(yaw); return 0; } - + // getyaw(self) static int l_getyaw(lua_State *L) { @@ -2917,7 +2928,7 @@ private: lua_pushnumber(L, yaw); return 1; } - + // settexturemod(self, mod) static int l_settexturemod(lua_State *L) { @@ -2929,7 +2940,7 @@ private: 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) @@ -2966,7 +2977,7 @@ private: lua_pushstring(L, name.c_str()); return 1; } - + // get_luaentity(self) static int l_get_luaentity(lua_State *L) { @@ -2977,7 +2988,7 @@ private: luaentity_get(L, co->getId()); return 1; } - + /* Player-only */ // is_player(self) @@ -2988,7 +2999,7 @@ private: lua_pushboolean(L, (player != NULL)); return 1; } - + // get_player_name(self) static int l_get_player_name(lua_State *L) { @@ -3002,7 +3013,7 @@ private: lua_pushstring(L, player->getName()); return 1; } - + // get_look_dir(self) static int l_get_look_dir(lua_State *L) { @@ -3144,7 +3155,7 @@ public: ObjectRef *o = checkobject(L, -1); o->m_object = NULL; } - + static void Register(lua_State *L) { lua_newtable(L); @@ -3370,7 +3381,7 @@ private: if(!ud) luaL_typerror(L, narg, className); return *(NodeTimerRef**)ud; // unbox pointer } - + static int l_set(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3381,7 +3392,7 @@ private: env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e)); return 0; } - + static int l_start(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3391,7 +3402,7 @@ private: env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0)); return 0; } - + static int l_stop(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3400,7 +3411,7 @@ private: env->getMap().removeNodeTimer(o->m_p); return 0; } - + static int l_is_started(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3411,7 +3422,7 @@ private: lua_pushboolean(L,(t.timeout != 0)); return 1; } - + static int l_get_timeout(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3422,7 +3433,7 @@ private: lua_pushnumber(L,t.timeout); return 1; } - + static int l_get_elapsed(lua_State *L) { NodeTimerRef *o = checkobject(L, 1); @@ -3460,7 +3471,7 @@ public: NodeTimerRef *o = checkobject(L, -1); o->m_env = NULL; } - + static void Register(lua_State *L) { lua_newtable(L); @@ -3525,7 +3536,7 @@ private: if(!ud) luaL_typerror(L, narg, className); return *(EnvRef**)ud; // unbox pointer } - + // Exported functions // EnvRef:set_node(pos, node) @@ -3969,7 +3980,7 @@ private: 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++) @@ -4094,7 +4105,7 @@ public: EnvRef *o = checkobject(L, -1); o->m_env = NULL; } - + static void Register(lua_State *L) { lua_newtable(L); @@ -4147,6 +4158,8 @@ const luaL_reg EnvRef::methods[] = { method(EnvRef, find_node_near), method(EnvRef, find_nodes_in_area), method(EnvRef, get_perlin), + //method{EnvRef, get_perlin_map_2d}, + //method{EnvRef, get_perlin_map_3d}, method(EnvRef, clear_objects), method(EnvRef, spawn_tree), {0,0} @@ -4166,7 +4179,7 @@ private: static const luaL_reg methods[]; // Exported functions - + // garbage collector static int gc_object(lua_State *L) { @@ -4217,7 +4230,7 @@ public: { return m_pseudo; } - + // LuaPseudoRandom(seed) // Creates an LuaPseudoRandom and leaves it on top of stack static int create_object(lua_State *L) @@ -4321,7 +4334,7 @@ public: 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); @@ -4337,7 +4350,7 @@ public: 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"); @@ -4442,6 +4455,77 @@ static int l_get_server_status(lua_State *L) 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)) { + + return 0; + } + + BiomeDefManager *bmgr = get_server(L)->getEmergeManager()->biomedef; + + 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)->getEmergeManager()->biomedef; + + 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.); + +//////hrm, what to do about the noiseparams... + b->np = new NoiseParams; /////just a hacky solution + getfloatfield(L, index, "scale", b->np->scale); + getfloatfield(L, index, "offset", b->np->offset); + //TODO: add configurable spread factor and octaves!? + //I'd have to create a Noise for every Biome... + bmgr->addBiome(groupid, b); + printf(" - added biome '%s' - %d %d\n", b->name.c_str(), b->n_top.param0, b->n_filler.param0); + + return 0; +} + // register_item_raw({lots of stuff}) static int l_register_item_raw(lua_State *L) { @@ -4481,7 +4565,7 @@ static int l_register_item_raw(lua_State *L) else def.node_placement_prediction = ""; } - + // Register item definition idef->registerItem(def); @@ -4504,9 +4588,9 @@ static int l_register_alias_raw(lua_State *L) // 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 */ } @@ -4615,7 +4699,7 @@ static int l_register_craft(lua_State *L) // Get the writable craft definition manager from the server IWritableCraftDefManager *craftdef = get_server(L)->getWritableCraftDefManager(); - + std::string type = getstringfield_default(L, table, "type", "shaped"); /* @@ -4899,7 +4983,7 @@ static int l_get_inventory(lua_State *L) std::string name = checkstringfield(L, 1, "name"); loc.setDetached(name); } - + if(get_server(L)->getInventory(loc) != NULL) InvRef::create(L, loc); else @@ -5116,7 +5200,7 @@ static int l_get_craft_result(lua_State *L) 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); @@ -5151,7 +5235,7 @@ static int l_get_craft_recipe(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; @@ -5254,6 +5338,8 @@ static const struct luaL_Reg minetest_f [] = { {"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}, @@ -5304,7 +5390,7 @@ void scriptapi_export(lua_State *L, Server *server) lua_newtable(L); luaL_register(L, NULL, minetest_f); lua_setglobal(L, "minetest"); - + // Get the main minetest table lua_getglobal(L, "minetest"); @@ -5337,7 +5423,7 @@ bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath, <<"Only chararacters [a-z0-9_] are allowed."<addActiveBlockModifier(abm); // removes value, keeps key for next iteration @@ -5476,7 +5562,7 @@ void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj) lua_getfield(L, -1, "object_refs"); luaL_checktype(L, -1, LUA_TTABLE); int objectstable = lua_gettop(L); - + // object_refs[id] = object lua_pushnumber(L, cobj->getId()); // Push id lua_pushvalue(L, object); // Copy object to top of stack @@ -5495,7 +5581,7 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj) lua_getfield(L, -1, "object_refs"); luaL_checktype(L, -1, LUA_TTABLE); int objectstable = lua_gettop(L); - + // Get object_refs[id] lua_pushnumber(L, cobj->getId()); // Push id lua_gettable(L, objectstable); @@ -5759,7 +5845,7 @@ bool scriptapi_get_auth(lua_State *L, const std::string &playername, 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) @@ -5767,12 +5853,12 @@ bool scriptapi_get_auth(lua_State *L, const std::string &playername, 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) @@ -5787,7 +5873,7 @@ bool scriptapi_get_auth(lua_State *L, const std::string &playername, if(dst_privs) read_privileges(L, -1, *dst_privs); lua_pop(L, 1); - + return true; } @@ -5797,7 +5883,7 @@ void scriptapi_create_auth(lua_State *L, const std::string &playername, 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) @@ -5814,7 +5900,7 @@ bool scriptapi_set_password(lua_State *L, const std::string &playername, 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) @@ -5830,7 +5916,7 @@ bool scriptapi_set_password(lua_State *L, const std::string &playername, player */ -void scriptapi_on_player_receive_fields(lua_State *L, +void scriptapi_on_player_receive_fields(lua_State *L, ServerActiveObject *player, const std::string &formname, const std::map &fields) @@ -6097,7 +6183,7 @@ bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime) 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; } @@ -6111,7 +6197,7 @@ void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p, 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) @@ -6679,7 +6765,7 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name) verbosestream<<"scriptapi_luaentity_add: id="<hp_max = 10; - + /* Read stuff */ - + prop->hp_max = getintfield_default(L, -1, "hp_max", 10); getboolfield(L, -1, "physical", prop->physical); @@ -6829,10 +6915,10 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id, getstringfield(L, -1, "visual", prop->visual); getstringfield(L, -1, "mesh", prop->mesh); - + // 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); -- cgit v1.2.3