From 18bb0ea1ead82406bcfb89ea14908a4d0063209e Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 25 Nov 2011 16:34:12 +0200 Subject: [PATCH] Mode node definition loading from Lua (still not finished), fix metadata creation from name --- data/mods/default/init.lua | 50 +++++++++++--- src/content_nodemeta.cpp | 27 ++++++-- src/content_nodemeta.h | 4 ++ src/nodemetadata.cpp | 17 +++-- src/nodemetadata.h | 6 +- src/scriptapi.cpp | 135 +++++++++++++++++++++++++++++-------- 6 files changed, 188 insertions(+), 51 deletions(-) diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua index b15315e24..dbc96381e 100644 --- a/data/mods/default/init.lua +++ b/data/mods/default/init.lua @@ -131,6 +131,10 @@ end -- print("minetest dump: "..dump(minetest)) +-- +-- Tool definition +-- + minetest.register_tool("WPick", { image = "tool_woodpick.png", basetime = 2.0, @@ -330,15 +334,9 @@ minetest.register_tool("horribletool", { }) --]] -minetest.register_node("somenode", { - tile_images = {"lava.png", "mese.png", "stone.png", "grass.png", "cobble.png", "tree_top.png"}, - inventory_image = "treeprop.png" -}) - -minetest.register_node("TNT", { - tile_images = {"tnt_top.png", "tnt_bottom.png", "tnt_side.png", "tnt_side.png", "tnt_side.png", "tnt_side.png"}, - inventory_image = "tnt_side.png" -}) +-- +-- Crafting definition +-- minetest.register_craft({ output = 'NodeItem "wood" 4', @@ -617,6 +615,40 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = 'NodeItem "somenode" 4', + recipe = { + {'CraftItem "Stick" 1'}, + } +}) + +-- +-- Node definitions +-- + +minetest.register_node("somenode", { + tile_images = {"lava.png", "mese.png", "stone.png", "grass.png", "cobble.png", "tree_top.png"}, + inventory_image = "treeprop.png", + material = { + diggability = "normal", + weight = 0, + crackiness = 0, + crumbliness = 0, + cuttability = 0, + flammability = 0 + }, + metadata_name = "chest", +}) + +minetest.register_node("TNT", { + tile_images = {"tnt_top.png", "tnt_bottom.png", "tnt_side.png", "tnt_side.png", "tnt_side.png", "tnt_side.png"}, + inventory_image = "tnt_side.png", + dug_item = '', -- Get nothing + material = { + diggability = "not", + }, +}) + -- -- Some common functions -- diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index 25ad3f0fd..72be1df39 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -38,7 +38,7 @@ SignNodeMetadata::SignNodeMetadata(IGameDef *gamedef, std::string text): NodeMetadata(gamedef), m_text(text) { - NodeMetadata::registerType(typeId(), typeName(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); } u16 SignNodeMetadata::typeId() const { @@ -49,6 +49,10 @@ NodeMetadata* SignNodeMetadata::create(std::istream &is, IGameDef *gamedef) std::string text = deSerializeString(is); return new SignNodeMetadata(gamedef, text); } +NodeMetadata* SignNodeMetadata::create(IGameDef *gamedef) +{ + return new SignNodeMetadata(gamedef, ""); +} NodeMetadata* SignNodeMetadata::clone(IGameDef *gamedef) { return new SignNodeMetadata(gamedef, m_text); @@ -72,7 +76,7 @@ ChestNodeMetadata proto_ChestNodeMetadata(NULL); ChestNodeMetadata::ChestNodeMetadata(IGameDef *gamedef): NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), typeName(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); m_inventory = new Inventory(); m_inventory->addList("0", 8*4); @@ -91,6 +95,11 @@ NodeMetadata* ChestNodeMetadata::create(std::istream &is, IGameDef *gamedef) d->m_inventory->deSerialize(is, gamedef); return d; } +NodeMetadata* ChestNodeMetadata::create(IGameDef *gamedef) +{ + ChestNodeMetadata *d = new ChestNodeMetadata(gamedef); + return d; +} NodeMetadata* ChestNodeMetadata::clone(IGameDef *gamedef) { ChestNodeMetadata *d = new ChestNodeMetadata(gamedef); @@ -135,7 +144,7 @@ LockingChestNodeMetadata proto_LockingChestNodeMetadata(NULL); LockingChestNodeMetadata::LockingChestNodeMetadata(IGameDef *gamedef): NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), typeName(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); m_inventory = new Inventory(); m_inventory->addList("0", 8*4); @@ -155,6 +164,11 @@ NodeMetadata* LockingChestNodeMetadata::create(std::istream &is, IGameDef *gamed d->m_inventory->deSerialize(is, gamedef); return d; } +NodeMetadata* LockingChestNodeMetadata::create(IGameDef *gamedef) +{ + LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef); + return d; +} NodeMetadata* LockingChestNodeMetadata::clone(IGameDef *gamedef) { LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef); @@ -200,7 +214,7 @@ FurnaceNodeMetadata proto_FurnaceNodeMetadata(NULL); FurnaceNodeMetadata::FurnaceNodeMetadata(IGameDef *gamedef): NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), typeName(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); m_inventory = new Inventory(); m_inventory->addList("fuel", 1); @@ -241,6 +255,11 @@ NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef) return d; } +NodeMetadata* FurnaceNodeMetadata::create(IGameDef *gamedef) +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef); + return d; +} void FurnaceNodeMetadata::serializeBody(std::ostream &os) { m_inventory->serialize(os); diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h index 2535e985e..8888d6f1f 100644 --- a/src/content_nodemeta.h +++ b/src/content_nodemeta.h @@ -34,6 +34,7 @@ public: virtual const char* typeName() const { return "sign"; } static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); virtual NodeMetadata* clone(IGameDef *gamedef); virtual void serializeBody(std::ostream &os); virtual std::string infoText(); @@ -56,6 +57,7 @@ public: virtual const char* typeName() const { return "chest"; } static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); virtual NodeMetadata* clone(IGameDef *gamedef); virtual void serializeBody(std::ostream &os); virtual std::string infoText(); @@ -77,6 +79,7 @@ public: virtual const char* typeName() const { return "locked_chest"; } static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); virtual NodeMetadata* clone(IGameDef *gamedef); virtual void serializeBody(std::ostream &os); virtual std::string infoText(); @@ -103,6 +106,7 @@ public: { return "furnace"; } virtual NodeMetadata* clone(IGameDef *gamedef); static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); virtual void serializeBody(std::ostream &os); virtual std::string infoText(); virtual Inventory* getInventory() {return m_inventory;} diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 2f47aba22..7abf82426 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ core::map NodeMetadata::m_types; -core::map NodeMetadata::m_names; +core::map NodeMetadata::m_names; NodeMetadata::NodeMetadata(IGameDef *gamedef): m_gamedef(gamedef) @@ -45,7 +45,7 @@ NodeMetadata::~NodeMetadata() NodeMetadata* NodeMetadata::create(const std::string &name, IGameDef *gamedef) { // Find factory function - core::map::Node *n; + core::map::Node *n; n = m_names.find(name); if(n == NULL) { @@ -58,10 +58,8 @@ NodeMetadata* NodeMetadata::create(const std::string &name, IGameDef *gamedef) // Try to load the metadata. If it fails, just return. try { - std::istringstream iss("", std::ios_base::binary); - - Factory f = n->getValue(); - NodeMetadata *meta = (*f)(iss, gamedef); + Factory2 f2 = n->getValue(); + NodeMetadata *meta = (*f2)(gamedef); return meta; } catch(SerializationError &e) @@ -120,7 +118,8 @@ void NodeMetadata::serialize(std::ostream &os) os<::Node *n; @@ -129,10 +128,10 @@ void NodeMetadata::registerType(u16 id, const std::string &name, Factory f) m_types.insert(id, f); } { // typeName - core::map::Node *n; + core::map::Node *n; n = m_names.find(name); if(!n) - m_names.insert(name, f); + m_names.insert(name, f2); } } diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 67b80b642..37668268e 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -40,6 +40,7 @@ class NodeMetadata { public: typedef NodeMetadata* (*Factory)(std::istream&, IGameDef *gamedef); + typedef NodeMetadata* (*Factory2)(IGameDef *gamedef); NodeMetadata(IGameDef *gamedef); virtual ~NodeMetadata(); @@ -70,11 +71,12 @@ public: virtual std::string getText(){ return ""; } virtual void setText(const std::string &t){} protected: - static void registerType(u16 id, const std::string &name, Factory f); + static void registerType(u16 id, const std::string &name, Factory f, + Factory2 f2); IGameDef *m_gamedef; private: static core::map m_types; - static core::map m_names; + static core::map m_names; }; /* diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index b4c79cd28..f19e98893 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -48,7 +48,7 @@ TODO: - Blink effect - Spritesheets and animation - LuaNodeMetadata - blockdef.metadata_type = + blockdef.metadata_name = "" "sign" "furnace" @@ -212,6 +212,32 @@ static video::SColor readARGB8(lua_State *L, int index) return color; } +static core::aabbox3d read_aabbox3df32(lua_State *L, int index) +{ + core::aabbox3d box; + if(lua_istable(L, -1)){ + lua_rawgeti(L, -1, 1); + box.MinEdge.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 2); + box.MinEdge.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 3); + box.MinEdge.Z = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 4); + box.MaxEdge.X = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 5); + box.MaxEdge.Y = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 6); + box.MaxEdge.Z = lua_tonumber(L, -1); + lua_pop(L, 1); + } + return box; +} + static bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result) { @@ -356,6 +382,27 @@ struct EnumString es_ContentParamType[] = {CPT_FACEDIR_SIMPLE, "facedir_simple"}, }; +struct EnumString es_LiquidType[] = +{ + {LIQUID_NONE, "none"}, + {LIQUID_FLOWING, "flowing"}, + {LIQUID_SOURCE, "source"}, +}; + +struct EnumString es_NodeBoxType[] = +{ + {NODEBOX_REGULAR, "regular"}, + {NODEBOX_FIXED, "fixed"}, + {NODEBOX_WALLMOUNTED, "wallmounted"}, +}; + +struct EnumString es_Diggability[] = +{ + {DIGGABLE_NOT, "not"}, + {DIGGABLE_NORMAL, "normal"}, + {DIGGABLE_CONSTANT, "constant"}, +}; + /* Global functions */ @@ -441,17 +488,26 @@ static int l_register_node(lua_State *L) // And get the writable node definition manager from the server IWritableNodeDefManager *nodedef = server->getWritableNodeDefManager(); + + /* + Create definition + */ ContentFeatures f; - f.name = name; + // Default to getting the corresponding NodeItem when dug + f.dug_item = std::string("NodeItem \"")+name+"\" 1"; /* - Visual definition + Read definiton from Lua */ + f.name = name; + + /* Visual definition */ + f.drawtype = (NodeDrawType)getenumfield(L, table0, "drawtype", es_DrawType, - f.drawtype); + NDT_NORMAL); getfloatfield(L, table0, "visual_scale", f.visual_scale); lua_getfield(L, table0, "tile_images"); @@ -505,16 +561,15 @@ static int l_register_node(lua_State *L) f.alpha = getintfield_default(L, table0, "alpha", 255); - /* - Other stuff - */ + /* Other stuff */ lua_getfield(L, table0, "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, table0, "paramtype", - es_ContentParamType, f.param_type); + es_ContentParamType, CPT_NONE); // True for all ground-like things like stone and mud, false for eg. trees getboolfield(L, table0, "is_ground_content", f.is_ground_content); @@ -551,8 +606,8 @@ static int l_register_node(lua_State *L) // Metadata name of node (eg. "furnace") getstringfield(L, table0, "metadata_name", f.metadata_name); // Whether the node is non-liquid, source liquid or flowing liquid - // TODO: Enum read - // enum LiquidType liquid_type; + f.liquid_type = (LiquidType)getenumfield(L, table0, "liquidtype", + es_LiquidType, LIQUID_NONE); // If the content is liquid, this is the flowing version of the liquid. // TODO: as name // content_t liquid_alternative_flowing; @@ -569,30 +624,56 @@ static int l_register_node(lua_State *L) "light_source", f.light_source); f.damage_per_second = getintfield_default(L, table0, "damage_per_second", f.damage_per_second); - // TODO - //NodeBox selection_box; - // TODO - //MaterialProperties material; + + lua_getfield(L, table0, "selection_box"); + if(lua_istable(L, -1)){ + f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type", + es_NodeBoxType, NODEBOX_REGULAR); + + lua_getfield(L, -1, "fixed"); + if(lua_istable(L, -1)) + f.selection_box.fixed = read_aabbox3df32(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "wall_top"); + if(lua_istable(L, -1)) + f.selection_box.wall_top = read_aabbox3df32(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "wall_bottom"); + if(lua_istable(L, -1)) + f.selection_box.wall_bottom = read_aabbox3df32(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "wall_side"); + if(lua_istable(L, -1)) + f.selection_box.wall_side = read_aabbox3df32(L, -1); + lua_pop(L, 1); + } + lua_pop(L, 1); + + lua_getfield(L, table0, "material"); + if(lua_istable(L, -1)){ + f.material.diggability = (Diggability)getenumfield(L, -1, "diggability", + es_Diggability, DIGGABLE_NORMAL); + + getfloatfield(L, -1, "constant_time", f.material.constant_time); + getfloatfield(L, -1, "weight", f.material.weight); + getfloatfield(L, -1, "crackiness", f.material.crackiness); + getfloatfield(L, -1, "crumbliness", f.material.crumbliness); + getfloatfield(L, -1, "cuttability", f.material.cuttability); + getfloatfield(L, -1, "flammability", f.material.flammability); + } + lua_pop(L, 1); + getstringfield(L, table0, "cookresult_item", f.cookresult_item); getfloatfield(L, table0, "furnace_cooktime", f.furnace_cooktime); getfloatfield(L, table0, "furnace_burntime", f.furnace_burntime); - /* - Temporary stuff - */ - - // TODO: Replace with actual parameter reading - // Temporarily set some sane parameters to allow digging - f.material.diggability = DIGGABLE_NORMAL; - f.material.weight = 0; - f.material.crackiness = 0; - f.material.crumbliness = 0; - f.material.cuttability = 0; - f.dug_item = std::string("NodeItem \"")+name+"\" 1"; - /* Register it */ + nodedef->set(name, f); return 0; /* number of results */