Improve luaentity sprite functionality (and add some random stuff)

This commit is contained in:
Perttu Ahola 2011-11-27 04:31:05 +02:00
parent b4e6ca63b5
commit 82a460ec90
11 changed files with 413 additions and 168 deletions

@ -49,6 +49,9 @@
-- - setpos(pos); pos={x=num, y=num, z=num} -- - setpos(pos); pos={x=num, y=num, z=num}
-- - moveto(pos, continuous=false): interpolated move -- - moveto(pos, continuous=false): interpolated move
-- - add_to_inventory(itemstring): add an item to object inventory -- - add_to_inventory(itemstring): add an item to object inventory
-- - settexturemod(mod)
-- - setsprite(p={x=0,y=0}, num_frames=1, framelength=0.2,
-- - select_horiz_by_yawpitch=false)
-- --
-- Registered entities: -- Registered entities:
-- - Functions receive a "luaentity" as self: -- - Functions receive a "luaentity" as self:
@ -1171,8 +1174,6 @@ local TNT = {
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "cube", visual = "cube",
textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"}, textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
--visual = "single_sprite",
--textures = {"mese.png^[forcesingle"},
-- Initial value for our timer -- Initial value for our timer
timer = 0, timer = 0,
-- Number of punches required to defuse -- Number of punches required to defuse
@ -1227,6 +1228,36 @@ print("TNT dump: "..dump(TNT))
print("Registering TNT"); print("Registering TNT");
minetest.register_entity("TNT", TNT) minetest.register_entity("TNT", TNT)
minetest.register_entity("testentity", {
-- Static definition
physical = true, -- Collides with things
-- weight = 5,
collisionbox = {-0.7,-1.35,-0.7, 0.7,1.0,0.7},
--collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "sprite",
visual_size = {x=2, y=3},
textures = {"dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
spritediv = {x=6, y=5},
initial_sprite_basepos = {x=0, y=0},
on_activate = function(self, staticdata)
print("testentity.on_activate")
self.object:setsprite({x=0,y=0}, 1, 0, true)
--self.object:setsprite({x=0,y=0}, 4, 0.3, true)
-- Set gravity
self.object:setacceleration({x=0, y=-10, z=0})
-- Jump a bit upwards
self.object:setvelocity({x=0, y=10, z=0})
end,
on_punch = function(self, hitter)
self.object:remove()
hitter:add_to_inventory('CraftItem testobject1 1')
end,
})
-- --
-- Falling stuff -- Falling stuff
-- --

@ -72,11 +72,16 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
/* /*
Go through every node around the object Go through every node around the object
TODO: Calculate the range of nodes that need to be checked
*/ */
for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++) s16 min_x = (box_0.MinEdge.X / BS) - 2;
for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++) s16 min_y = (box_0.MinEdge.Y / BS) - 2;
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++) s16 min_z = (box_0.MinEdge.Z / BS) - 2;
s16 max_x = (box_0.MaxEdge.X / BS) + 1;
s16 max_y = (box_0.MaxEdge.Y / BS) + 1;
s16 max_z = (box_0.MaxEdge.Z / BS) + 1;
for(s16 y = oldpos_i.Y + min_y; y <= oldpos_i.Y + max_y; y++)
for(s16 z = oldpos_i.Z + min_z; z <= oldpos_i.Z + max_z; z++)
for(s16 x = oldpos_i.X + min_x; x <= oldpos_i.X + max_x; x++)
{ {
try{ try{
// Object collides into walkable nodes // Object collides into walkable nodes

@ -899,8 +899,8 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
/*infostream<<"MobV2CAO::addToScene using texture_name="<< /*infostream<<"MobV2CAO::addToScene using texture_name="<<
m_texture_name<<std::endl;*/ m_texture_name<<std::endl;*/
std::string texture_string = "[makealpha2:128,0,0;128,128,0:"; std::string texture_string = m_texture_name +
texture_string += m_texture_name; "^[makealpha:128,0,0^[makealpha:128,128,0";
scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode( scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1)); smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
@ -1281,8 +1281,81 @@ private:
float m_yaw; float m_yaw;
struct LuaEntityProperties *m_prop; struct LuaEntityProperties *m_prop;
SmoothTranslator pos_translator; SmoothTranslator pos_translator;
// Spritesheet/animation stuff
v2f m_tx_size;
v2s16 m_tx_basepos;
bool m_tx_select_horiz_by_yawpitch;
int m_anim_frame;
int m_anim_num_frames;
float m_anim_framelength;
float m_anim_timer;
public: public:
CLuaEntityCAO(IGameDef *gamedef):
LuaEntityCAO(gamedef),
m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
m_meshnode(NULL),
m_spritenode(NULL),
m_position(v3f(0,10*BS,0)),
m_velocity(v3f(0,0,0)),
m_acceleration(v3f(0,0,0)),
m_yaw(0),
m_prop(new LuaEntityProperties),
m_tx_size(1,1),
m_tx_basepos(0,0),
m_tx_select_horiz_by_yawpitch(false),
m_anim_frame(0),
m_anim_num_frames(1),
m_anim_framelength(0.2),
m_anim_timer(0)
{
ClientActiveObject::registerType(getType(), create);
}
void initialize(const std::string &data)
{
infostream<<"CLuaEntityCAO: Got init data"<<std::endl;
std::istringstream is(data, std::ios::binary);
// version
u8 version = readU8(is);
// check version
if(version != 0)
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;
m_selection_box = m_prop->collisionbox;
m_selection_box.MinEdge *= BS;
m_selection_box.MaxEdge *= BS;
pos_translator.init(m_position);
m_tx_size.X = 1.0 / m_prop->spritediv.X;
m_tx_size.Y = 1.0 / m_prop->spritediv.Y;
m_tx_basepos.X = m_tx_size.X * m_prop->initial_sprite_basepos.X;
m_tx_basepos.Y = m_tx_size.Y * m_prop->initial_sprite_basepos.Y;
updateNodePos();
}
~CLuaEntityCAO()
{
delete m_prop;
}
static ClientActiveObject* create(IGameDef *gamedef)
{
return new CLuaEntityCAO(gamedef);
}
u8 getType() const u8 getType() const
{ {
return ACTIVEOBJECT_TYPE_LUAENTITY; return ACTIVEOBJECT_TYPE_LUAENTITY;
@ -1296,30 +1369,6 @@ public:
return pos_translator.vect_show; return pos_translator.vect_show;
} }
CLuaEntityCAO(IGameDef *gamedef):
LuaEntityCAO(gamedef),
m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
m_meshnode(NULL),
m_spritenode(NULL),
m_position(v3f(0,10*BS,0)),
m_velocity(v3f(0,0,0)),
m_acceleration(v3f(0,0,0)),
m_yaw(0),
m_prop(new LuaEntityProperties)
{
ClientActiveObject::registerType(getType(), create);
}
~CLuaEntityCAO()
{
delete m_prop;
}
static ClientActiveObject* create(IGameDef *gamedef)
{
return new CLuaEntityCAO(gamedef);
}
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc) void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
{ {
if(m_meshnode != NULL || m_spritenode != NULL) if(m_meshnode != NULL || m_spritenode != NULL)
@ -1327,7 +1376,7 @@ public:
//video::IVideoDriver* driver = smgr->getVideoDriver(); //video::IVideoDriver* driver = smgr->getVideoDriver();
if(m_prop->visual == "single_sprite"){ if(m_prop->visual == "sprite"){
infostream<<"CLuaEntityCAO::addToScene(): single_sprite"<<std::endl; infostream<<"CLuaEntityCAO::addToScene(): single_sprite"<<std::endl;
m_spritenode = new scene::MyBillboardSceneNode( m_spritenode = new scene::MyBillboardSceneNode(
smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1)); smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
@ -1339,7 +1388,7 @@ public:
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
m_spritenode->setColor(video::SColor(255,0,0,0)); m_spritenode->setColor(video::SColor(255,0,0,0));
m_spritenode->setVisible(false); /* Set visible when brightness is known */ m_spritenode->setVisible(false); /* Set visible when brightness is known */
m_spritenode->setSize(v2f(1,1)*1.0*BS); m_spritenode->setSize(m_prop->visual_size*BS);
{ {
const float txs = 1.0 / 1; const float txs = 1.0 / 1;
const float tys = 1.0 / 1; const float tys = 1.0 / 1;
@ -1387,6 +1436,9 @@ public:
for(u32 i=0; i<24; ++i){ for(u32 i=0; i<24; ++i){
vertices[i].Pos *= BS; vertices[i].Pos *= BS;
vertices[i].Pos.Y *= m_prop->visual_size.Y;
vertices[i].Pos.X *= m_prop->visual_size.X;
vertices[i].Pos.Z *= m_prop->visual_size.X;
} }
u16 indices[6] = {0,1,2,2,3,0}; u16 indices[6] = {0,1,2,2,3,0};
@ -1487,6 +1539,66 @@ public:
pos_translator.translate(dtime); pos_translator.translate(dtime);
updateNodePos(); updateNodePos();
} }
m_anim_timer += dtime;
if(m_anim_timer >= m_anim_framelength){
m_anim_timer -= m_anim_framelength;
m_anim_frame++;
if(m_anim_frame >= m_anim_num_frames)
m_anim_frame = 0;
}
updateTexturePos();
}
void updateTexturePos()
{
if(m_spritenode){
scene::ICameraSceneNode* camera =
m_spritenode->getSceneManager()->getActiveCamera();
if(!camera)
return;
v3f cam_to_entity = m_spritenode->getAbsolutePosition()
- camera->getAbsolutePosition();
cam_to_entity.normalize();
int row = m_tx_basepos.Y;
int col = m_tx_basepos.X;
if(m_tx_select_horiz_by_yawpitch)
{
if(cam_to_entity.Y > 0.75)
col += 5;
else if(cam_to_entity.Y < -0.75)
col += 4;
else{
float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / PI * 180.;
float dir = mob_dir - m_yaw;
dir = wrapDegrees_180(dir);
//infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
col += 2;
else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
col += 3;
else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
col += 0;
else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
col += 1;
else
col += 4;
}
}
// Animation goes downwards
row += m_anim_frame;
float txs = m_tx_size.X;
float tys = m_tx_size.Y;
m_spritenode->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
m_spritenode->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
m_spritenode->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
m_spritenode->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
}
} }
void updateTextures(const std::string &mod) void updateTextures(const std::string &mod)
@ -1562,35 +1674,20 @@ public:
std::string mod = deSerializeString(is); std::string mod = deSerializeString(is);
updateTextures(mod); updateTextures(mod);
} }
} else if(cmd == 2) // set sprite
{
v2s16 p = readV2S16(is);
int num_frames = readU16(is);
float framelength = readF1000(is);
bool select_horiz_by_yawpitch = readU8(is);
void initialize(const std::string &data) m_tx_basepos = p;
{ m_anim_num_frames = num_frames;
infostream<<"CLuaEntityCAO: Got init data"<<std::endl; m_anim_framelength = framelength;
m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
std::istringstream is(data, std::ios::binary); updateTexturePos();
// version }
u8 version = readU8(is);
// check version
if(version != 0)
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;
m_selection_box = m_prop->collisionbox;
m_selection_box.MinEdge *= BS;
m_selection_box.MaxEdge *= BS;
pos_translator.init(m_position);
updateNodePos();
} }
}; };

@ -77,7 +77,7 @@ ServerActiveObject* item_craft_create_object(const std::string &subname,
} }
else if(subname == "testobject1") else if(subname == "testobject1")
{ {
ServerActiveObject *obj = new LuaEntitySAO(env, pos, "TNT", ""); ServerActiveObject *obj = new LuaEntitySAO(env, pos, "testentity", "");
return obj; return obj;
} }

@ -1748,6 +1748,11 @@ void LuaEntitySAO::setAcceleration(v3f acceleration)
m_acceleration = acceleration; m_acceleration = acceleration;
} }
v3f LuaEntitySAO::getAcceleration()
{
return m_acceleration;
}
void LuaEntitySAO::setTextureMod(const std::string &mod) void LuaEntitySAO::setTextureMod(const std::string &mod)
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
@ -1760,6 +1765,22 @@ void LuaEntitySAO::setTextureMod(const std::string &mod)
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
} }
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
bool select_horiz_by_yawpitch)
{
std::ostringstream os(std::ios::binary);
// command (2 = set sprite)
writeU8(os, 2);
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF1000(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
{ {
m_last_sent_move_precision = m_base_position.getDistanceFrom( m_last_sent_move_precision = m_base_position.getDistanceFrom(

@ -219,7 +219,10 @@ public:
/* LuaEntitySAO-specific */ /* LuaEntitySAO-specific */
void setVelocity(v3f velocity); void setVelocity(v3f velocity);
void setAcceleration(v3f acceleration); void setAcceleration(v3f acceleration);
v3f getAcceleration();
void setTextureMod(const std::string &mod); void setTextureMod(const std::string &mod);
void setSprite(v2s16 p, int num_frames, float framelength,
bool select_horiz_by_yawpitch);
private: private:
void sendPosition(bool do_interpolate, bool is_movement_end); void sendPosition(bool do_interpolate, bool is_movement_end);

@ -22,12 +22,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h" #include "utility.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
LuaEntityProperties::LuaEntityProperties(): LuaEntityProperties::LuaEntityProperties():
physical(false), physical(false),
weight(5), weight(5),
collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5), collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
visual("single_sprite") visual("single_sprite"),
visual_size(1,1),
spritediv(1,1),
initial_sprite_basepos(0,0)
{ {
textures.push_back("unknown_object.png"); textures.push_back("unknown_object.png");
} }
@ -39,11 +43,14 @@ std::string LuaEntityProperties::dump()
os<<", weight="<<weight; os<<", weight="<<weight;
os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge); os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
os<<", visual="<<visual; os<<", visual="<<visual;
os<<", visual_size="<<PP2(visual_size);
os<<", textures=["; os<<", textures=[";
for(u32 i=0; i<textures.size(); i++){ for(u32 i=0; i<textures.size(); i++){
os<<"\""<<textures[i]<<"\" "; os<<"\""<<textures[i]<<"\" ";
} }
os<<"]"; os<<"]";
os<<", spritediv="<<PP2(spritediv);
os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos);
return os.str(); return os.str();
} }
@ -55,10 +62,13 @@ void LuaEntityProperties::serialize(std::ostream &os)
writeV3F1000(os, collisionbox.MinEdge); writeV3F1000(os, collisionbox.MinEdge);
writeV3F1000(os, collisionbox.MaxEdge); writeV3F1000(os, collisionbox.MaxEdge);
os<<serializeString(visual); os<<serializeString(visual);
writeV2F1000(os, visual_size);
writeU16(os, textures.size()); writeU16(os, textures.size());
for(u32 i=0; i<textures.size(); i++){ for(u32 i=0; i<textures.size(); i++){
os<<serializeString(textures[i]); os<<serializeString(textures[i]);
} }
writeV2S16(os, spritediv);
writeV2S16(os, initial_sprite_basepos);
} }
void LuaEntityProperties::deSerialize(std::istream &is) void LuaEntityProperties::deSerialize(std::istream &is)
@ -71,11 +81,14 @@ void LuaEntityProperties::deSerialize(std::istream &is)
collisionbox.MinEdge = readV3F1000(is); collisionbox.MinEdge = readV3F1000(is);
collisionbox.MaxEdge = readV3F1000(is); collisionbox.MaxEdge = readV3F1000(is);
visual = deSerializeString(is); visual = deSerializeString(is);
visual_size = readV2F1000(is);
textures.clear(); textures.clear();
u32 texture_count = readU16(is); u32 texture_count = readU16(is);
for(u32 i=0; i<texture_count; i++){ for(u32 i=0; i<texture_count; i++){
textures.push_back(deSerializeString(is)); textures.push_back(deSerializeString(is));
} }
spritediv = readV2S16(is);
initial_sprite_basepos = readV2S16(is);
} }

@ -31,7 +31,10 @@ struct LuaEntityProperties
float weight; float weight;
core::aabbox3d<f32> collisionbox; core::aabbox3d<f32> collisionbox;
std::string visual; std::string visual;
v2f visual_size;
core::array<std::string> textures; core::array<std::string> textures;
v2s16 spritediv;
v2s16 initial_sprite_basepos;
LuaEntityProperties(); LuaEntityProperties();
std::string dump(); std::string dump();

@ -142,6 +142,18 @@ static v3f readFloatPos(lua_State *L, int index)
return pos; return pos;
} }
static void pushFloatPos(lua_State *L, v3f p)
{
p /= BS;
lua_newtable(L);
lua_pushnumber(L, p.X);
lua_setfield(L, -2, "x");
lua_pushnumber(L, p.Y);
lua_setfield(L, -2, "y");
lua_pushnumber(L, p.Z);
lua_setfield(L, -2, "z");
}
static void pushpos(lua_State *L, v3s16 p) static void pushpos(lua_State *L, v3s16 p)
{ {
lua_newtable(L); lua_newtable(L);
@ -239,6 +251,32 @@ static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
return box; return box;
} }
static v2s16 read_v2s16(lua_State *L, int index)
{
v2s16 p;
luaL_checktype(L, index, LUA_TTABLE);
lua_getfield(L, index, "x");
p.X = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, index, "y");
p.Y = lua_tonumber(L, -1);
lua_pop(L, 1);
return p;
}
static v2f read_v2f(lua_State *L, int index)
{
v2f p;
luaL_checktype(L, index, LUA_TTABLE);
lua_getfield(L, index, "x");
p.X = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, index, "y");
p.Y = lua_tonumber(L, -1);
lua_pop(L, 1);
return p;
}
static bool getstringfield(lua_State *L, int table, static bool getstringfield(lua_State *L, int table,
const char *fieldname, std::string &result) const char *fieldname, std::string &result)
{ {
@ -307,6 +345,14 @@ static int getintfield_default(lua_State *L, int table,
return result; return result;
} }
/*static float getfloatfield_default(lua_State *L, int table,
const char *fieldname, float default_)
{
float result = default_;
getfloatfield(L, table, fieldname, result);
return result;
}*/
static bool getboolfield_default(lua_State *L, int table, static bool getboolfield_default(lua_State *L, int table,
const char *fieldname, bool default_) const char *fieldname, bool default_)
{ {
@ -1235,6 +1281,18 @@ private:
return 0; return 0;
} }
// getacceleration(self)
static int l_getacceleration(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *co = getluaobject(ref);
if(co == NULL) return 0;
// Do it
v3f v = co->getAcceleration();
pushFloatPos(L, v);
return 1;
}
// add_to_inventory(self, itemstring) // add_to_inventory(self, itemstring)
// returns: true if item was added, false otherwise // returns: true if item was added, false otherwise
static int l_add_to_inventory(lua_State *L) static int l_add_to_inventory(lua_State *L)
@ -1272,6 +1330,30 @@ private:
return 0; return 0;
} }
// setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
// select_horiz_by_yawpitch=false)
static int l_setsprite(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
LuaEntitySAO *co = getluaobject(ref);
if(co == NULL) return 0;
// Do it
v2s16 p(0,0);
if(!lua_isnil(L, 2))
p = read_v2s16(L, 2);
int num_frames = 1;
if(!lua_isnil(L, 3))
num_frames = lua_tonumber(L, 3);
float framelength = 0.2;
if(!lua_isnil(L, 4))
framelength = lua_tonumber(L, 4);
bool select_horiz_by_yawpitch = false;
if(!lua_isnil(L, 5))
select_horiz_by_yawpitch = lua_toboolean(L, 5);
co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
return 0;
}
public: public:
ObjectRef(ServerActiveObject *object): ObjectRef(ServerActiveObject *object):
m_object(object) m_object(object)
@ -1343,6 +1425,7 @@ const luaL_reg ObjectRef::methods[] = {
method(ObjectRef, setacceleration), method(ObjectRef, setacceleration),
method(ObjectRef, add_to_inventory), method(ObjectRef, add_to_inventory),
method(ObjectRef, settexturemod), method(ObjectRef, settexturemod),
method(ObjectRef, setsprite),
{0,0} {0,0}
}; };
@ -1859,23 +1942,22 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
luaentity_get(L, id); luaentity_get(L, id);
//int object = lua_gettop(L); //int object = lua_gettop(L);
lua_getfield(L, -1, "physical"); /* Read stuff */
if(lua_isboolean(L, -1))
prop->physical = lua_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "weight"); getboolfield(L, -1, "physical", prop->physical);
prop->weight = lua_tonumber(L, -1);
lua_pop(L, 1); getfloatfield(L, -1, "weight", prop->weight);
lua_getfield(L, -1, "collisionbox"); lua_getfield(L, -1, "collisionbox");
if(lua_istable(L, -1)) if(lua_istable(L, -1))
prop->collisionbox = read_aabbox3df32(L, -1, 1.0); prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "visual"); getstringfield(L, -1, "visual", prop->visual);
if(lua_isstring(L, -1))
prop->visual = lua_tostring(L, -1); lua_getfield(L, -1, "visual_size");
if(lua_istable(L, -1))
prop->visual_size = read_v2f(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "textures"); lua_getfield(L, -1, "textures");
@ -1895,6 +1977,15 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
} }
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "spritediv");
if(lua_istable(L, -1))
prop->spritediv = read_v2s16(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "initial_sprite_basepos");
if(lua_istable(L, -1))
prop->initial_sprite_basepos = read_v2s16(L, -1);
lua_pop(L, 1);
} }
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime) void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)

@ -1361,14 +1361,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
} }
} }
/* /*
"[makealpha:R,G,B:filename.png" "[makealpha:R,G,B"
Use an image with converting one color to transparent. Convert one color to transparent.
*/ */
else if(part_of_name.substr(0,11) == "[makealpha:") else if(part_of_name.substr(0,11) == "[makealpha:")
{ {
if(baseimg != NULL) if(baseimg == NULL)
{ {
errorstream<<"generate_image(): baseimg!=NULL " errorstream<<"generate_image(): baseimg==NULL "
<<"for part_of_name=\""<<part_of_name <<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl; <<"\", cancelling."<<std::endl;
return false; return false;
@ -1377,99 +1377,28 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
Strfnd sf(part_of_name.substr(11)); Strfnd sf(part_of_name.substr(11));
u32 r1 = stoi(sf.next(",")); u32 r1 = stoi(sf.next(","));
u32 g1 = stoi(sf.next(",")); u32 g1 = stoi(sf.next(","));
u32 b1 = stoi(sf.next(":")); u32 b1 = stoi(sf.next(""));
std::string filename = sf.next(""); std::string filename = sf.next("");
/*infostream<<"generate_image(): Loading file \""<<filename core::dimension2d<u32> dim = baseimg->getDimension();
<<"\""<<std::endl;*/
video::IImage *image = sourcecache->getOrLoad(filename, device); /*video::IImage *oldbaseimg = baseimg;
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
oldbaseimg->copyTo(baseimg);
oldbaseimg->drop();*/
if(image == NULL) // Set alpha to full
for(u32 y=0; y<dim.Height; y++)
for(u32 x=0; x<dim.Width; x++)
{ {
errorstream<<"generate_image(): Loading file \"" video::SColor c = baseimg->getPixel(x,y);
<<filename<<"\" failed"<<std::endl; u32 r = c.getRed();
} u32 g = c.getGreen();
else u32 b = c.getBlue();
{ if(!(r == r1 && g == g1 && b == b1))
core::dimension2d<u32> dim = image->getDimension(); continue;
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); c.setAlpha(0);
baseimg->setPixel(x,y,c);
// Blit
image->copyTo(baseimg);
image->drop();
for(u32 y=0; y<dim.Height; y++)
for(u32 x=0; x<dim.Width; x++)
{
video::SColor c = baseimg->getPixel(x,y);
u32 r = c.getRed();
u32 g = c.getGreen();
u32 b = c.getBlue();
if(!(r == r1 && g == g1 && b == b1))
continue;
c.setAlpha(0);
baseimg->setPixel(x,y,c);
}
}
}
/*
"[makealpha2:R,G,B;R2,G2,B2:filename.png"
Use an image with converting two colors to transparent.
*/
else if(part_of_name.substr(0,12) == "[makealpha2:")
{
if(baseimg != NULL)
{
errorstream<<"generate_image(): baseimg!=NULL "
<<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl;
return false;
}
Strfnd sf(part_of_name.substr(12));
u32 r1 = stoi(sf.next(","));
u32 g1 = stoi(sf.next(","));
u32 b1 = stoi(sf.next(";"));
u32 r2 = stoi(sf.next(","));
u32 g2 = stoi(sf.next(","));
u32 b2 = stoi(sf.next(":"));
std::string filename = sf.next("");
/*infostream<<"generate_image(): Loading filename \""<<filename
<<"\""<<std::endl;*/
video::IImage *image = sourcecache->getOrLoad(filename, device);
if(image == NULL)
{
errorstream<<"generate_image(): Loading file \""
<<filename<<"\" failed"<<std::endl;
}
else
{
core::dimension2d<u32> dim = image->getDimension();
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
// Blit
image->copyTo(baseimg);
image->drop();
for(u32 y=0; y<dim.Height; y++)
for(u32 x=0; x<dim.Width; x++)
{
video::SColor c = baseimg->getPixel(x,y);
u32 r = c.getRed();
u32 g = c.getGreen();
u32 b = c.getBlue();
if(!(r == r1 && g == g1 && b == b1) &&
!(r == r2 && g == g2 && b == b2))
continue;
c.setAlpha(0);
baseimg->setPixel(x,y,c);
}
} }
} }
/* /*

@ -148,6 +148,19 @@ inline v3f readV3F1000(u8 *data)
return p; return p;
} }
inline void writeV2F1000(u8 *data, v2f p)
{
writeF1000(&data[0], p.X);
writeF1000(&data[4], p.Y);
}
inline v2f readV2F1000(u8 *data)
{
v2f p;
p.X = (float)readF1000(&data[0]);
p.Y = (float)readF1000(&data[4]);
return p;
}
inline void writeV2S16(u8 *data, v2s16 p) inline void writeV2S16(u8 *data, v2s16 p)
{ {
writeS16(&data[0], p.X); writeS16(&data[0], p.X);
@ -274,6 +287,45 @@ inline v3f readV3F1000(std::istream &is)
return readV3F1000((u8*)buf); return readV3F1000((u8*)buf);
} }
inline void writeV2F1000(std::ostream &os, v2f p)
{
char buf[8];
writeV2F1000((u8*)buf, p);
os.write(buf, 8);
}
inline v2f readV2F1000(std::istream &is)
{
char buf[8];
is.read(buf, 8);
return readV2F1000((u8*)buf);
}
inline void writeV2S16(std::ostream &os, v2s16 p)
{
char buf[4];
writeV2S16((u8*)buf, p);
os.write(buf, 4);
}
inline v2s16 readV2S16(std::istream &is)
{
char buf[4];
is.read(buf, 4);
return readV2S16((u8*)buf);
}
inline void writeV3S16(std::ostream &os, v3s16 p)
{
char buf[6];
writeV3S16((u8*)buf, p);
os.write(buf, 6);
}
inline v3s16 readV3S16(std::istream &is)
{
char buf[6];
is.read(buf, 6);
return readV3S16((u8*)buf);
}
/* /*
None of these are used at the moment None of these are used at the moment
*/ */