Scripting WIP
authorPerttu Ahola <celeron55@gmail.com>
Sat, 12 Nov 2011 09:59:56 +0000 (11:59 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:39 +0000 (19:13 +0200)
data/scripts/default.lua
src/activeobject.h
src/content_cao.cpp
src/content_cao.h
src/content_sao.cpp
src/content_sao.h
src/scriptapi.cpp
src/serverobject.h

index baf541f465d55c8f366a8525279603a4ca36f61a..c355583415bd944cc7bbd65e7a820c86cf99a7a5 100644 (file)
@@ -163,6 +163,12 @@ function TNT:on_punch(hitter)
 end
 
 -- Called when object is right-clicked
+function TNT:on_rightclick(clicker)
+       pos = self.object:getpos()
+       pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
+       self.object:moveto(pos)
+end
+--[[
 function TNT:on_rightclick(clicker)
        print("TNT:on_rightclick()")
        print("self: "..dump(self))
@@ -173,6 +179,7 @@ function TNT:on_rightclick(clicker)
        pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
        --minetest.env:add_node(pos, 0)
 end
+--]]
 
 print("TNT dump: "..dump(TNT))
 
index 09ee23a14c61bec788c2a9e8d9cabd8c14b25698..c46ae61b2a980987a258e45895713f928e2a2bb2 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef ACTIVEOBJECT_HEADER
 #define ACTIVEOBJECT_HEADER
 
-#include "common_irrlicht.h"
+#include "irrlichttypes.h"
 #include <string>
 
 #define ACTIVEOBJECT_TYPE_INVALID 0
index 70bcbac180bae4336f2eb1ccb33d06abebb54ac3..28c2787e1ac84aa2e6f109d37a6900d4fac8cfed 100644 (file)
@@ -1276,8 +1276,10 @@ LuaEntityCAO proto_LuaEntityCAO;
 LuaEntityCAO::LuaEntityCAO():
        ClientActiveObject(0),
        m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
-       m_node(NULL),
+       m_meshnode(NULL),
+       m_spritenode(NULL),
        m_position(v3f(0,10*BS,0)),
+       m_yaw(0),
        m_prop(new LuaEntityProperties)
 {
        ClientActiveObject::registerType(getType(), create);
@@ -1295,65 +1297,39 @@ ClientActiveObject* LuaEntityCAO::create()
 
 void LuaEntityCAO::addToScene(scene::ISceneManager *smgr)
 {
-       if(m_node != NULL)
+       if(m_meshnode != NULL || m_spritenode != NULL)
                return;
        
-       video::IVideoDriver* driver = smgr->getVideoDriver();
-       
-       scene::SMesh *mesh = new scene::SMesh();
-       scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-       video::SColor c(255,255,255,255);
-       video::S3DVertex vertices[4] =
-       {
-               /*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
-               video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
-               video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
-               video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
-               video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
-               video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
-               video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
-               video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
-       };
-       u16 indices[] = {0,1,2,2,3,0};
-       buf->append(vertices, 4, indices, 6);
-       // Set material
-       buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-       buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-       //buf->getMaterial().setTexture(0, NULL);
-       // Initialize with the stick texture
-       buf->getMaterial().setTexture
-                       (0, driver->getTexture(getTexturePath("mese.png").c_str()));
-       buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-       buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
-       buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-       // Add to mesh
-       mesh->addMeshBuffer(buf);
-       buf->drop();
-       m_node = smgr->addMeshSceneNode(mesh, NULL);
-       mesh->drop();
-       // Set it to use the materials of the meshbuffers directly.
-       // This is needed for changing the texture in the future
-       m_node->setReadOnlyMaterials(true);
-       updateNodePos();
+       //video::IVideoDriver* driver = smgr->getVideoDriver();
+
+       if(m_prop->visual == "single_sprite"){
+       } else if(m_prop->visual == "cube"){
+       } else {
+       }
 }
 
 void LuaEntityCAO::removeFromScene()
 {
-       if(m_node == NULL)
-               return;
-
-       m_node->remove();
-       m_node = NULL;
+       if(m_meshnode){
+               m_meshnode->remove();
+               m_meshnode = NULL;
+       }
+       if(m_spritenode){
+               m_spritenode->remove();
+               m_spritenode = NULL;
+       }
 }
 
 void LuaEntityCAO::updateLight(u8 light_at_pos)
 {
-       if(m_node == NULL)
-               return;
-
        u8 li = decode_light(light_at_pos);
        video::SColor color(255,li,li,li);
-       setMeshVerticesColor(m_node->getMesh(), color);
+       if(m_meshnode){
+               setMeshVerticesColor(m_meshnode->getMesh(), color);
+       }
+       if(m_spritenode){
+               m_spritenode->setColor(color);
+       }
 }
 
 v3s16 LuaEntityCAO::getLightPosition()
@@ -1363,25 +1339,17 @@ v3s16 LuaEntityCAO::getLightPosition()
 
 void LuaEntityCAO::updateNodePos()
 {
-       if(m_node == NULL)
-               return;
-
-       m_node->setPosition(m_position);
+       if(m_meshnode){
+               m_meshnode->setPosition(pos_translator.vect_show);
+       }
+       if(m_spritenode){
+               m_spritenode->setPosition(pos_translator.vect_show);
+       }
 }
 
 void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
 {
-       if(m_node)
-       {
-               /*v3f rot = m_node->getRotation();
-               rot.Y += dtime * 120;
-               m_node->setRotation(rot);*/
-               LocalPlayer *player = env->getLocalPlayer();
-               assert(player);
-               v3f rot = m_node->getRotation();
-               rot.Y = 180.0 - (player->getYaw());
-               m_node->setRotation(rot);
-       }
+       pos_translator.translate(dtime);
 }
 
 void LuaEntityCAO::processMessage(const std::string &data)
@@ -1392,8 +1360,17 @@ void LuaEntityCAO::processMessage(const std::string &data)
        u8 cmd = readU8(is);
        if(cmd == 0)
        {
+               // do_interpolate
+               bool do_interpolate = readU8(is);
                // pos
                m_position = readV3F1000(is);
+               // yaw
+               m_yaw = readF1000(is);
+               
+               if(do_interpolate)
+                       pos_translator.update(m_position);
+               else
+                       pos_translator.init(m_position);
                updateNodePos();
        }
 }
@@ -1410,11 +1387,15 @@ void LuaEntityCAO::initialize(const std::string &data)
                return;
        // pos
        m_position = readV3F1000(is);
+       // yaw
+       m_yaw = readF1000(is);
        // properties
        std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
        m_prop->deSerialize(prop_is);
 
        infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
+               
+       pos_translator.init(m_position);
        
        updateNodePos();
 }
index 53336c7b99110840f39126be840c6e136cdf9b73..3231a190f0a665cf5cfd1b60e1a0181111d7e1f0 100644 (file)
@@ -410,13 +410,16 @@ public:
        core::aabbox3d<f32>* getSelectionBox()
                {return &m_selection_box;}
        v3f getPosition()
-               {return m_position;}
+               {return pos_translator.vect_show;}
 
 private:
        core::aabbox3d<f32> m_selection_box;
-       scene::IMeshSceneNode *m_node;
+       scene::IMeshSceneNode *m_meshnode;
+       scene::MyBillboardSceneNode *m_spritenode;
        v3f m_position;
+       float m_yaw;
        struct LuaEntityProperties *m_prop;
+       SmoothTranslator pos_translator;
 };
 
 
index 3802129cbfdc75ee7156b0f83009a1c9b0c51152..6cc0106b6d13580184d775c59f8c55943502e5e2 100644 (file)
@@ -1506,7 +1506,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
        m_init_name(name),
        m_init_state(state),
        m_registered(false),
-       m_prop(new LuaEntityProperties)
+       m_prop(new LuaEntityProperties),
+       m_yaw(0),
+       m_last_sent_yaw(0),
+       m_last_sent_position(0,0,0)
 {
        // Only register type if no environment supplied
        if(env == NULL){
@@ -1562,6 +1565,13 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                lua_State *L = m_env->getLua();
                scriptapi_luaentity_step(L, m_id, dtime);
        }
+
+       if(send_recommended == false)
+               return;
+       if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS
+                       || fabs(m_yaw - m_last_sent_yaw) > 1.0){
+               sendPosition(true);
+       }
 }
 
 std::string LuaEntitySAO::getClientInitializationData()
@@ -1571,6 +1581,8 @@ std::string LuaEntitySAO::getClientInitializationData()
        writeU8(os, 0);
        // pos
        writeV3F1000(os, m_base_position);
+       // yaw
+       writeF1000(os, m_yaw);
        // properties
        std::ostringstream prop_os(std::ios::binary);
        m_prop->serialize(prop_os);
@@ -1619,3 +1631,34 @@ void LuaEntitySAO::rightClick(Player *player)
        scriptapi_luaentity_rightclick_player(L, m_id, player->getName());
 }
 
+void LuaEntitySAO::setPos(v3f pos)
+{
+       m_base_position = pos;
+       sendPosition(false);
+}
+
+void LuaEntitySAO::moveTo(v3f pos)
+{
+       m_base_position = pos;
+}
+
+void LuaEntitySAO::sendPosition(bool do_interpolate)
+{
+       m_last_sent_yaw = m_yaw;
+       m_last_sent_position = m_base_position;
+
+       std::ostringstream os(std::ios::binary);
+       // command (0 = update position)
+       writeU8(os, 0);
+       // do_interpolate
+       writeU8(os, do_interpolate);
+       // pos
+       writeV3F1000(os, m_base_position);
+       // yaw
+       writeF1000(os, m_yaw);
+       // create message and add to list
+       ActiveObjectMessage aom(getId(), false, os.str());
+       m_messages_out.push_back(aom);
+}
+
+
index ef22f297499fc5779d8e917eae80ffa3ba93c856..4bb35b70deeb2966ac4d1a9d10f4d43a991889c7 100644 (file)
@@ -215,11 +215,20 @@ public:
        u16 punch(const std::string &toolname, v3f dir,
                        const std::string &playername);
        void rightClick(Player *player);
+
+       void setPos(v3f pos);
+       void moveTo(v3f pos);
 private:
+       void sendPosition(bool do_interpolate);
+
        std::string m_init_name;
        std::string m_init_state;
        bool m_registered;
        struct LuaEntityProperties *m_prop;
+       
+       float m_yaw;
+       float m_last_sent_yaw;
+       v3f m_last_sent_position;
 };
 
 #endif
index a50516edfc6c56afd51055f4d8486a31f13bef46..b0a99041e6ed43556e08c01aaf159f575be97c91 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 #include "script.h"
 //#include "luna.h"
 #include "luaentity_common.h"
+#include "content_sao.h" // For LuaEntitySAO
 
 /*
 TODO:
@@ -110,6 +111,29 @@ public:
        }
 };
 
+v3f readFloatPos(lua_State *L, int index)
+{
+       v3f pos;
+       lua_pushvalue(L, index); // Push pos
+       luaL_checktype(L, -1, LUA_TTABLE);
+       lua_getfield(L, -1, "x");
+       pos.X = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       lua_getfield(L, -1, "y");
+       pos.Y = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       lua_getfield(L, -1, "z");
+       pos.Z = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       lua_pop(L, 1); // Pop pos
+       pos *= BS; // Scale to internal format
+       return pos;
+}
+
+/*
+       Global functions
+*/
+
 // Register new object prototype
 // register_entity(name, prototype)
 static int l_register_entity(lua_State *L)
@@ -149,16 +173,18 @@ static const struct luaL_Reg minetest_f [] = {
        {NULL, NULL}
 };
 
-static int l_entity_set_deleted(lua_State *L)
-{
-       return 0;
-}
+/*
+       LuaEntity functions
+*/
 
 static const struct luaL_Reg minetest_entity_m [] = {
-       {"set_deleted", l_entity_set_deleted},
        {NULL, NULL}
 };
 
+/*
+       Getters for stuff in main tables
+*/
+
 static void objectref_get(lua_State *L, u16 id)
 {
        // Get minetest.object_refs[i]
@@ -324,12 +350,28 @@ private:
                return *(ObjectRef**)ud;  // unbox pointer
        }
        
+       static ServerActiveObject* getobject(ObjectRef *ref)
+       {
+               ServerActiveObject *co = ref->m_object;
+               return co;
+       }
+       
+       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;
+       }
+       
        // Exported functions
 
        static int l_remove(lua_State *L)
        {
-               ObjectRef *o = checkobject(L, 1);
-               ServerActiveObject *co = o->m_object;
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
                if(co == NULL) return 0;
                infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
                co->m_removed = true;
@@ -338,8 +380,8 @@ private:
 
        static int l_getpos(lua_State *L)
        {
-               ObjectRef *o = checkobject(L, 1);
-               ServerActiveObject *co = o->m_object;
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
                if(co == NULL) return 0;
                infostream<<"ObjectRef::l_getpos(): id="<<co->getId()<<std::endl;
                v3f pos = co->getBasePosition() / BS;
@@ -353,6 +395,32 @@ private:
                return 1;
        }
 
+       static int l_setpos(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               //LuaEntitySAO *co = getluaobject(ref);
+               ServerActiveObject *co = getobject(ref);
+               if(co == NULL) return 0;
+               // pos
+               v3f pos = readFloatPos(L, 2);
+               // Do it
+               co->setPos(pos);
+               return 0;
+       }
+
+       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 = readFloatPos(L, 2);
+               // Do it
+               co->moveTo(pos);
+               return 0;
+       }
+
        static int gc_object(lua_State *L) {
                //ObjectRef *o = checkobject(L, 1);
                ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
@@ -426,6 +494,8 @@ const char ObjectRef::className[] = "ObjectRef";
 const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, remove),
        method(ObjectRef, getpos),
+       method(ObjectRef, setpos),
+       method(ObjectRef, moveto),
        {0,0}
 };
 
@@ -438,6 +508,7 @@ void scriptapi_export(lua_State *L, Server *server)
        realitycheck(L);
        assert(lua_checkstack(L, 20));
        infostream<<"scriptapi_export"<<std::endl;
+       StackUnroller stack_unroller(L);
        
        // Register global functions in table minetest
        lua_newtable(L);
@@ -459,14 +530,6 @@ void scriptapi_export(lua_State *L, Server *server)
        lua_newtable(L);
        lua_setfield(L, -2, "luaentities");
 
-       // Load and run some base Lua stuff
-       /*script_load(L, (porting::path_data + DIR_DELIM + "scripts"
-                       + DIR_DELIM + "base.lua").c_str());*/
-       
-       // Create entity reference metatable
-       //luaL_newmetatable(L, "minetest.entity_reference");
-       //lua_pop(L, 1);
-       
        // Create entity prototype
        luaL_newmetatable(L, "minetest.entity");
        // metatable.__index = metatable
@@ -488,6 +551,7 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
        realitycheck(L);
        assert(lua_checkstack(L, 20));
        infostream<<"scriptapi_add_environment"<<std::endl;
+       StackUnroller stack_unroller(L);
 
        // Create EnvRef on stack
        EnvRef::create(L, env);
@@ -498,9 +562,6 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
        luaL_checktype(L, -1, LUA_TTABLE);
        lua_pushvalue(L, envref);
        lua_setfield(L, -2, "env");
-       
-       // pop minetest and envref
-       lua_pop(L, 2);
 }
 
 // Dump stack top with the dump2 function
@@ -524,6 +585,7 @@ void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
        realitycheck(L);
        assert(lua_checkstack(L, 20));
        infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
+       StackUnroller stack_unroller(L);
 
        // Create object on stack
        ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
@@ -539,9 +601,6 @@ void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
        lua_pushnumber(L, cobj->getId()); // Push id
        lua_pushvalue(L, object); // Copy object to top of stack
        lua_settable(L, objectstable);
-       
-       // pop object_refs, minetest and the object
-       lua_pop(L, 3);
 }
 
 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
@@ -549,6 +608,7 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
        realitycheck(L);
        assert(lua_checkstack(L, 20));
        infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
+       StackUnroller stack_unroller(L);
 
        // Get minetest.object_refs table
        lua_getglobal(L, "minetest");
@@ -567,9 +627,6 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
        lua_pushnumber(L, cobj->getId()); // Push id
        lua_pushnil(L);
        lua_settable(L, objectstable);
-       
-       // pop object_refs, minetest
-       lua_pop(L, 2);
 }
 
 /*
index 8d6bfd6e8b5982264e0056b200c9c758fd10c273..fce72ac640b130df366b0d7cec5abd7e45c1b2e3 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef SERVEROBJECT_HEADER
 #define SERVEROBJECT_HEADER
 
-#include "common_irrlicht.h"
+#include "irrlichttypes.h"
 #include "activeobject.h"
 #include "utility.h"
 
@@ -64,13 +64,16 @@ public:
        /*
                Some simple getters/setters
        */
-       v3f getBasePosition()
-               {return m_base_position;}
-       void setBasePosition(v3f pos)
-               {m_base_position = pos;}
-       ServerEnvironment* getEnv()
-               {return m_env;}
+       v3f getBasePosition(){ return m_base_position; }
+       void setBasePosition(v3f pos){ m_base_position = pos; }
+       ServerEnvironment* getEnv(){ return m_env; }
        
+       /*
+               Some more dynamic interface
+       */
+       virtual void setPos(v3f pos){ setBasePosition(pos); }
+       virtual void moveTo(v3f pos){ setBasePosition(pos); }
+
        /*
                Step object in time.
                Messages added to messages are sent to client over network.