Mode node definition loading from Lua (still not finished), fix metadata creation...
authorPerttu Ahola <celeron55@gmail.com>
Fri, 25 Nov 2011 14:34:12 +0000 (16:34 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:51 +0000 (19:13 +0200)
data/mods/default/init.lua
src/content_nodemeta.cpp
src/content_nodemeta.h
src/nodemetadata.cpp
src/nodemetadata.h
src/scriptapi.cpp

index b15315e24ccedb477d5cbecc102eabdcf15c05ab..dbc96381e9381581e868912396e4bad826220c77 100644 (file)
@@ -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
 --
index 25ad3f0fd801359773ac22f259a865a90f6bdae8..72be1df3917be419bd382948502fe90fc7a6eb89 100644 (file)
@@ -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);
index 2535e985e0cd80e700d10f38f759a08ea5103369..8888d6f1fb50105ea00d81e0304cfa1ed973ca6d 100644 (file)
@@ -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;}
index 2f47aba22b184c9dd141170a129671537530ae3c..7abf824262fbdbfeebfe99a4b3afa0b1fd51911a 100644 (file)
@@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 core::map<u16, NodeMetadata::Factory> NodeMetadata::m_types;
-core::map<std::string, NodeMetadata::Factory> NodeMetadata::m_names;
+core::map<std::string, NodeMetadata::Factory2> 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<std::string, Factory>::Node *n;
+       core::map<std::string, Factory2>::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<<serializeString(oss.str());
 }
 
-void NodeMetadata::registerType(u16 id, const std::string &name, Factory f)
+void NodeMetadata::registerType(u16 id, const std::string &name, Factory f,
+               Factory2 f2)
 {
        { // typeId
                core::map<u16, Factory>::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<std::string, Factory>::Node *n;
+               core::map<std::string, Factory2>::Node *n;
                n = m_names.find(name);
                if(!n)
-                       m_names.insert(name, f);
+                       m_names.insert(name, f2);
        }
 }
 
index 67b80b64265b51fcb26bdcb3255b02dfb2c16a62..37668268e21038892eb9fc6499a6a8a0444a2838 100644 (file)
@@ -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<u16, Factory> m_types;
-       static core::map<std::string, Factory> m_names;
+       static core::map<std::string, Factory2> m_names;
 };
 
 /*
index b4c79cd285090b6baccee5ad21c4f5f5ec1fd17f..f19e98893b5a87b8de0f8cca93f12a4805a9d69a 100644 (file)
@@ -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<f32> read_aabbox3df32(lua_State *L, int index)
+{
+       core::aabbox3d<f32> 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 */