diff --git a/data/scripts/default.lua b/data/scripts/default.lua index baf541f..c355583 100644 --- a/data/scripts/default.lua +++ b/data/scripts/default.lua @@ -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)) diff --git a/src/activeobject.h b/src/activeobject.h index 09ee23a..c46ae61 100644 --- a/src/activeobject.h +++ b/src/activeobject.h @@ -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 #define ACTIVEOBJECT_TYPE_INVALID 0 diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 70bcbac..28c2787 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -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: "<dump()<* getSelectionBox() {return &m_selection_box;} v3f getPosition() - {return m_position;} + {return pos_translator.vect_show;} private: core::aabbox3d 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; }; diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 3802129..6cc0106 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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); +} + + diff --git a/src/content_sao.h b/src/content_sao.h index ef22f29..4bb35b7 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -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 diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index a50516e..b0a9904 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -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="<getId()<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="<getId()<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"<getId()); // Push id lua_pushnil(L); lua_settable(L, objectstable); - - // pop object_refs, minetest - lua_pop(L, 2); } /* diff --git a/src/serverobject.h b/src/serverobject.h index 8d6bfd6..fce72ac 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -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.