Scripting WIP

This commit is contained in:
Perttu Ahola 2011-11-12 11:59:56 +02:00
parent dcedfdacd1
commit 526eedf98e
8 changed files with 203 additions and 100 deletions

@ -163,6 +163,12 @@ function TNT:on_punch(hitter)
end end
-- Called when object is right-clicked -- 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) function TNT:on_rightclick(clicker)
print("TNT:on_rightclick()") print("TNT:on_rightclick()")
print("self: "..dump(self)) 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} pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
--minetest.env:add_node(pos, 0) --minetest.env:add_node(pos, 0)
end end
--]]
print("TNT dump: "..dump(TNT)) print("TNT dump: "..dump(TNT))

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef ACTIVEOBJECT_HEADER #ifndef ACTIVEOBJECT_HEADER
#define ACTIVEOBJECT_HEADER #define ACTIVEOBJECT_HEADER
#include "common_irrlicht.h" #include "irrlichttypes.h"
#include <string> #include <string>
#define ACTIVEOBJECT_TYPE_INVALID 0 #define ACTIVEOBJECT_TYPE_INVALID 0

@ -1276,8 +1276,10 @@ LuaEntityCAO proto_LuaEntityCAO;
LuaEntityCAO::LuaEntityCAO(): LuaEntityCAO::LuaEntityCAO():
ClientActiveObject(0), ClientActiveObject(0),
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.), 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_position(v3f(0,10*BS,0)),
m_yaw(0),
m_prop(new LuaEntityProperties) m_prop(new LuaEntityProperties)
{ {
ClientActiveObject::registerType(getType(), create); ClientActiveObject::registerType(getType(), create);
@ -1295,65 +1297,39 @@ ClientActiveObject* LuaEntityCAO::create()
void LuaEntityCAO::addToScene(scene::ISceneManager *smgr) void LuaEntityCAO::addToScene(scene::ISceneManager *smgr)
{ {
if(m_node != NULL) if(m_meshnode != NULL || m_spritenode != NULL)
return; return;
video::IVideoDriver* driver = smgr->getVideoDriver(); //video::IVideoDriver* driver = smgr->getVideoDriver();
scene::SMesh *mesh = new scene::SMesh(); if(m_prop->visual == "single_sprite"){
scene::IMeshBuffer *buf = new scene::SMeshBuffer(); } else if(m_prop->visual == "cube"){
video::SColor c(255,255,255,255); } else {
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();
} }
void LuaEntityCAO::removeFromScene() void LuaEntityCAO::removeFromScene()
{ {
if(m_node == NULL) if(m_meshnode){
return; m_meshnode->remove();
m_meshnode = NULL;
m_node->remove(); }
m_node = NULL; if(m_spritenode){
m_spritenode->remove();
m_spritenode = NULL;
}
} }
void LuaEntityCAO::updateLight(u8 light_at_pos) void LuaEntityCAO::updateLight(u8 light_at_pos)
{ {
if(m_node == NULL)
return;
u8 li = decode_light(light_at_pos); u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li); 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() v3s16 LuaEntityCAO::getLightPosition()
@ -1363,25 +1339,17 @@ v3s16 LuaEntityCAO::getLightPosition()
void LuaEntityCAO::updateNodePos() void LuaEntityCAO::updateNodePos()
{ {
if(m_node == NULL) if(m_meshnode){
return; m_meshnode->setPosition(pos_translator.vect_show);
}
m_node->setPosition(m_position); if(m_spritenode){
m_spritenode->setPosition(pos_translator.vect_show);
}
} }
void LuaEntityCAO::step(float dtime, ClientEnvironment *env) void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
{ {
if(m_node) pos_translator.translate(dtime);
{
/*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);
}
} }
void LuaEntityCAO::processMessage(const std::string &data) void LuaEntityCAO::processMessage(const std::string &data)
@ -1392,8 +1360,17 @@ void LuaEntityCAO::processMessage(const std::string &data)
u8 cmd = readU8(is); u8 cmd = readU8(is);
if(cmd == 0) if(cmd == 0)
{ {
// do_interpolate
bool do_interpolate = readU8(is);
// pos // pos
m_position = readV3F1000(is); m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
if(do_interpolate)
pos_translator.update(m_position);
else
pos_translator.init(m_position);
updateNodePos(); updateNodePos();
} }
} }
@ -1410,11 +1387,15 @@ void LuaEntityCAO::initialize(const std::string &data)
return; return;
// pos // pos
m_position = readV3F1000(is); m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
// properties // properties
std::istringstream prop_is(deSerializeLongString(is), std::ios::binary); std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
m_prop->deSerialize(prop_is); m_prop->deSerialize(prop_is);
infostream<<"m_prop: "<<m_prop->dump()<<std::endl; infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
pos_translator.init(m_position);
updateNodePos(); updateNodePos();
} }

@ -410,13 +410,16 @@ public:
core::aabbox3d<f32>* getSelectionBox() core::aabbox3d<f32>* getSelectionBox()
{return &m_selection_box;} {return &m_selection_box;}
v3f getPosition() v3f getPosition()
{return m_position;} {return pos_translator.vect_show;}
private: private:
core::aabbox3d<f32> m_selection_box; core::aabbox3d<f32> m_selection_box;
scene::IMeshSceneNode *m_node; scene::IMeshSceneNode *m_meshnode;
scene::MyBillboardSceneNode *m_spritenode;
v3f m_position; v3f m_position;
float m_yaw;
struct LuaEntityProperties *m_prop; struct LuaEntityProperties *m_prop;
SmoothTranslator pos_translator;
}; };

@ -1506,7 +1506,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_init_name(name), m_init_name(name),
m_init_state(state), m_init_state(state),
m_registered(false), 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 // Only register type if no environment supplied
if(env == NULL){ if(env == NULL){
@ -1562,6 +1565,13 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
lua_State *L = m_env->getLua(); lua_State *L = m_env->getLua();
scriptapi_luaentity_step(L, m_id, dtime); 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() std::string LuaEntitySAO::getClientInitializationData()
@ -1571,6 +1581,8 @@ std::string LuaEntitySAO::getClientInitializationData()
writeU8(os, 0); writeU8(os, 0);
// pos // pos
writeV3F1000(os, m_base_position); writeV3F1000(os, m_base_position);
// yaw
writeF1000(os, m_yaw);
// properties // properties
std::ostringstream prop_os(std::ios::binary); std::ostringstream prop_os(std::ios::binary);
m_prop->serialize(prop_os); m_prop->serialize(prop_os);
@ -1619,3 +1631,34 @@ void LuaEntitySAO::rightClick(Player *player)
scriptapi_luaentity_rightclick_player(L, m_id, player->getName()); 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);
}

@ -215,11 +215,20 @@ public:
u16 punch(const std::string &toolname, v3f dir, u16 punch(const std::string &toolname, v3f dir,
const std::string &playername); const std::string &playername);
void rightClick(Player *player); void rightClick(Player *player);
void setPos(v3f pos);
void moveTo(v3f pos);
private: private:
void sendPosition(bool do_interpolate);
std::string m_init_name; std::string m_init_name;
std::string m_init_state; std::string m_init_state;
bool m_registered; bool m_registered;
struct LuaEntityProperties *m_prop; struct LuaEntityProperties *m_prop;
float m_yaw;
float m_last_sent_yaw;
v3f m_last_sent_position;
}; };
#endif #endif

@ -34,6 +34,7 @@ extern "C" {
#include "script.h" #include "script.h"
//#include "luna.h" //#include "luna.h"
#include "luaentity_common.h" #include "luaentity_common.h"
#include "content_sao.h" // For LuaEntitySAO
/* /*
TODO: 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 new object prototype
// register_entity(name, prototype) // register_entity(name, prototype)
static int l_register_entity(lua_State *L) static int l_register_entity(lua_State *L)
@ -149,16 +173,18 @@ static const struct luaL_Reg minetest_f [] = {
{NULL, NULL} {NULL, NULL}
}; };
static int l_entity_set_deleted(lua_State *L) /*
{ LuaEntity functions
return 0; */
}
static const struct luaL_Reg minetest_entity_m [] = { static const struct luaL_Reg minetest_entity_m [] = {
{"set_deleted", l_entity_set_deleted},
{NULL, NULL} {NULL, NULL}
}; };
/*
Getters for stuff in main tables
*/
static void objectref_get(lua_State *L, u16 id) static void objectref_get(lua_State *L, u16 id)
{ {
// Get minetest.object_refs[i] // Get minetest.object_refs[i]
@ -324,12 +350,28 @@ private:
return *(ObjectRef**)ud; // unbox pointer 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 // Exported functions
static int l_remove(lua_State *L) static int l_remove(lua_State *L)
{ {
ObjectRef *o = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = o->m_object; ServerActiveObject *co = getobject(ref);
if(co == NULL) return 0; if(co == NULL) return 0;
infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl; infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
co->m_removed = true; co->m_removed = true;
@ -338,8 +380,8 @@ private:
static int l_getpos(lua_State *L) static int l_getpos(lua_State *L)
{ {
ObjectRef *o = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = o->m_object; ServerActiveObject *co = getobject(ref);
if(co == NULL) return 0; if(co == NULL) return 0;
infostream<<"ObjectRef::l_getpos(): id="<<co->getId()<<std::endl; infostream<<"ObjectRef::l_getpos(): id="<<co->getId()<<std::endl;
v3f pos = co->getBasePosition() / BS; v3f pos = co->getBasePosition() / BS;
@ -353,6 +395,32 @@ private:
return 1; 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) { static int gc_object(lua_State *L) {
//ObjectRef *o = checkobject(L, 1); //ObjectRef *o = checkobject(L, 1);
ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1)); ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
@ -426,6 +494,8 @@ const char ObjectRef::className[] = "ObjectRef";
const luaL_reg ObjectRef::methods[] = { const luaL_reg ObjectRef::methods[] = {
method(ObjectRef, remove), method(ObjectRef, remove),
method(ObjectRef, getpos), method(ObjectRef, getpos),
method(ObjectRef, setpos),
method(ObjectRef, moveto),
{0,0} {0,0}
}; };
@ -438,6 +508,7 @@ void scriptapi_export(lua_State *L, Server *server)
realitycheck(L); realitycheck(L);
assert(lua_checkstack(L, 20)); assert(lua_checkstack(L, 20));
infostream<<"scriptapi_export"<<std::endl; infostream<<"scriptapi_export"<<std::endl;
StackUnroller stack_unroller(L);
// Register global functions in table minetest // Register global functions in table minetest
lua_newtable(L); lua_newtable(L);
@ -459,14 +530,6 @@ void scriptapi_export(lua_State *L, Server *server)
lua_newtable(L); lua_newtable(L);
lua_setfield(L, -2, "luaentities"); 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 // Create entity prototype
luaL_newmetatable(L, "minetest.entity"); luaL_newmetatable(L, "minetest.entity");
// metatable.__index = metatable // metatable.__index = metatable
@ -488,6 +551,7 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
realitycheck(L); realitycheck(L);
assert(lua_checkstack(L, 20)); assert(lua_checkstack(L, 20));
infostream<<"scriptapi_add_environment"<<std::endl; infostream<<"scriptapi_add_environment"<<std::endl;
StackUnroller stack_unroller(L);
// Create EnvRef on stack // Create EnvRef on stack
EnvRef::create(L, env); EnvRef::create(L, env);
@ -498,9 +562,6 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
luaL_checktype(L, -1, LUA_TTABLE); luaL_checktype(L, -1, LUA_TTABLE);
lua_pushvalue(L, envref); lua_pushvalue(L, envref);
lua_setfield(L, -2, "env"); lua_setfield(L, -2, "env");
// pop minetest and envref
lua_pop(L, 2);
} }
// Dump stack top with the dump2 function // Dump stack top with the dump2 function
@ -524,6 +585,7 @@ void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
realitycheck(L); realitycheck(L);
assert(lua_checkstack(L, 20)); assert(lua_checkstack(L, 20));
infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl; infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
StackUnroller stack_unroller(L);
// Create object on stack // Create object on stack
ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) 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_pushnumber(L, cobj->getId()); // Push id
lua_pushvalue(L, object); // Copy object to top of stack lua_pushvalue(L, object); // Copy object to top of stack
lua_settable(L, objectstable); 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) 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); realitycheck(L);
assert(lua_checkstack(L, 20)); assert(lua_checkstack(L, 20));
infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl; infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
StackUnroller stack_unroller(L);
// Get minetest.object_refs table // Get minetest.object_refs table
lua_getglobal(L, "minetest"); 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_pushnumber(L, cobj->getId()); // Push id
lua_pushnil(L); lua_pushnil(L);
lua_settable(L, objectstable); lua_settable(L, objectstable);
// pop object_refs, minetest
lua_pop(L, 2);
} }
/* /*

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef SERVEROBJECT_HEADER #ifndef SERVEROBJECT_HEADER
#define SERVEROBJECT_HEADER #define SERVEROBJECT_HEADER
#include "common_irrlicht.h" #include "irrlichttypes.h"
#include "activeobject.h" #include "activeobject.h"
#include "utility.h" #include "utility.h"
@ -64,13 +64,16 @@ public:
/* /*
Some simple getters/setters Some simple getters/setters
*/ */
v3f getBasePosition() v3f getBasePosition(){ return m_base_position; }
{return m_base_position;} void setBasePosition(v3f pos){ m_base_position = pos; }
void setBasePosition(v3f pos) ServerEnvironment* getEnv(){ return m_env; }
{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. Step object in time.
Messages added to messages are sent to client over network. Messages added to messages are sent to client over network.