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))
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))
#ifndef ACTIVEOBJECT_HEADER
#define ACTIVEOBJECT_HEADER
-#include "common_irrlicht.h"
+#include "irrlichttypes.h"
#include <string>
#define ACTIVEOBJECT_TYPE_INVALID 0
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);
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()
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)
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();
}
}
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();
}
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;
};
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){
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()
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);
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);
+}
+
+
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
#include "script.h"
//#include "luna.h"
#include "luaentity_common.h"
+#include "content_sao.h" // For LuaEntitySAO
/*
TODO:
}
};
+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)
{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]
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;
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;
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));
const luaL_reg ObjectRef::methods[] = {
method(ObjectRef, remove),
method(ObjectRef, getpos),
+ method(ObjectRef, setpos),
+ method(ObjectRef, moveto),
{0,0}
};
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);
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
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);
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
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
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)
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");
lua_pushnumber(L, cobj->getId()); // Push id
lua_pushnil(L);
lua_settable(L, objectstable);
-
- // pop object_refs, minetest
- lua_pop(L, 2);
}
/*
#ifndef SERVEROBJECT_HEADER
#define SERVEROBJECT_HEADER
-#include "common_irrlicht.h"
+#include "irrlichttypes.h"
#include "activeobject.h"
#include "utility.h"
/*
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.