Improve luaentity sprite functionality (and add some random stuff)
authorPerttu Ahola <celeron55@gmail.com>
Sun, 27 Nov 2011 02:31:05 +0000 (04:31 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:54 +0000 (19:13 +0200)
data/mods/default/init.lua
src/collision.cpp
src/content_cao.cpp
src/content_inventory.cpp
src/content_sao.cpp
src/content_sao.h
src/luaentity_common.cpp
src/luaentity_common.h
src/scriptapi.cpp
src/tile.cpp
src/utility.h

index 6ea15b4ee984ea65a6335e3e6dd160caba871ecf..ea6bf3da9ab3662127b9679137371c9bc78b5df5 100644 (file)
@@ -49,6 +49,9 @@
 -- - setpos(pos); pos={x=num, y=num, z=num}
 -- - moveto(pos, continuous=false): interpolated move
 -- - 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:
 -- - 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},
        visual = "cube",
        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
        timer = 0,
        -- Number of punches required to defuse
@@ -1227,6 +1228,36 @@ print("TNT dump: "..dump(TNT))
 print("Registering 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
 --
index 24f1e9d18614889e93ac1db48f57dcdbf13ca3d0..3460b04fdb719f75072c444ae243f61a5957de0a 100644 (file)
@@ -72,11 +72,16 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
        
        /*
                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++)
-       for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++)
-       for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
+       s16 min_x = (box_0.MinEdge.X / BS) - 2;
+       s16 min_y = (box_0.MinEdge.Y / BS) - 2;
+       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{
                        // Object collides into walkable nodes
index 984a216d86609f48e1ad3f218e2651f2409abc8c..ba8739df7d2b2689c2e7d659201e895b516873e0 100644 (file)
@@ -899,8 +899,8 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
        
        /*infostream<<"MobV2CAO::addToScene using texture_name="<<
                        m_texture_name<<std::endl;*/
-       std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
-       texture_string += m_texture_name;
+       std::string texture_string = m_texture_name +
+                       "^[makealpha:128,0,0^[makealpha:128,128,0";
        
        scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
                        smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
@@ -1281,21 +1281,16 @@ private:
        float m_yaw;
        struct LuaEntityProperties *m_prop;
        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:
-       u8 getType() const
-       {
-               return ACTIVEOBJECT_TYPE_LUAENTITY;
-       }
-       core::aabbox3d<f32>* getSelectionBox()
-       {
-               return &m_selection_box;
-       }
-       v3f getPosition()
-       {
-               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.),
@@ -1305,11 +1300,52 @@ public:
                m_velocity(v3f(0,0,0)),
                m_acceleration(v3f(0,0,0)),
                m_yaw(0),
-               m_prop(new LuaEntityProperties)
+               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;
@@ -1320,6 +1356,19 @@ public:
                return new CLuaEntityCAO(gamedef);
        }
 
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_LUAENTITY;
+       }
+       core::aabbox3d<f32>* getSelectionBox()
+       {
+               return &m_selection_box;
+       }
+       v3f getPosition()
+       {
+               return pos_translator.vect_show;
+       }
+               
        void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
        {
                if(m_meshnode != NULL || m_spritenode != NULL)
@@ -1327,7 +1376,7 @@ public:
                
                //video::IVideoDriver* driver = smgr->getVideoDriver();
 
-               if(m_prop->visual == "single_sprite"){
+               if(m_prop->visual == "sprite"){
                        infostream<<"CLuaEntityCAO::addToScene(): single_sprite"<<std::endl;
                        m_spritenode = new scene::MyBillboardSceneNode(
                                        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->setColor(video::SColor(255,0,0,0));
                        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 tys = 1.0 / 1;
@@ -1387,6 +1436,9 @@ public:
                        
                        for(u32 i=0; i<24; ++i){
                                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};
@@ -1487,6 +1539,66 @@ public:
                        pos_translator.translate(dtime);
                        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)
@@ -1562,35 +1674,20 @@ public:
                        std::string mod = deSerializeString(is);
                        updateTextures(mod);
                }
-       }
-
-       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;
+               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);
                        
-               pos_translator.init(m_position);
-               
-               updateNodePos();
+                       m_tx_basepos = p;
+                       m_anim_num_frames = num_frames;
+                       m_anim_framelength = framelength;
+                       m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
+
+                       updateTexturePos();
+               }
        }
 };
 
index 2a05b76f00cfe7174e98ada99f6d05a800d9b770..21acad30740b64687753fbc05cd376fafc26309e 100644 (file)
@@ -77,7 +77,7 @@ ServerActiveObject* item_craft_create_object(const std::string &subname,
        }
        else if(subname == "testobject1")
        {
-               ServerActiveObject *obj = new LuaEntitySAO(env, pos, "TNT", "");
+               ServerActiveObject *obj = new LuaEntitySAO(env, pos, "testentity", "");
                return obj;
        }
 
index 74824d5733b3148c70ee6b9e12055cd16f2f2e7a..b013069aaf673858c99945d63f2c3e616e7f0883 100644 (file)
@@ -1748,6 +1748,11 @@ void LuaEntitySAO::setAcceleration(v3f acceleration)
        m_acceleration = acceleration;
 }
 
+v3f LuaEntitySAO::getAcceleration()
+{
+       return m_acceleration;
+}
+
 void LuaEntitySAO::setTextureMod(const std::string &mod)
 {
        std::ostringstream os(std::ios::binary);
@@ -1760,6 +1765,22 @@ void LuaEntitySAO::setTextureMod(const std::string &mod)
        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)
 {
        m_last_sent_move_precision = m_base_position.getDistanceFrom(
index 6f5bab31022178a820f5c70aa5bdbdb163347293..c5e1471bc2c4666fa7d172f913c1e6145392f438 100644 (file)
@@ -219,7 +219,10 @@ public:
        /* LuaEntitySAO-specific */
        void setVelocity(v3f velocity);
        void setAcceleration(v3f acceleration);
+       v3f getAcceleration();
        void setTextureMod(const std::string &mod);
+       void setSprite(v2s16 p, int num_frames, float framelength,
+                       bool select_horiz_by_yawpitch);
 private:
        void sendPosition(bool do_interpolate, bool is_movement_end);
 
index 503083d0b7fdfd2039081940bfee8f9b30e06786..cf1ac7bedbfebc9fed365b9bdaad556ae5b607ed 100644 (file)
@@ -22,12 +22,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "utility.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
+#define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
 
 LuaEntityProperties::LuaEntityProperties():
        physical(false),
        weight(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");
 }
@@ -39,11 +43,14 @@ std::string LuaEntityProperties::dump()
        os<<", weight="<<weight;
        os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
        os<<", visual="<<visual;
+       os<<", visual_size="<<PP2(visual_size);
        os<<", textures=[";
        for(u32 i=0; i<textures.size(); i++){
                os<<"\""<<textures[i]<<"\" ";
        }
        os<<"]";
+       os<<", spritediv="<<PP2(spritediv);
+       os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos);
        return os.str();
 }
 
@@ -55,10 +62,13 @@ void LuaEntityProperties::serialize(std::ostream &os)
        writeV3F1000(os, collisionbox.MinEdge);
        writeV3F1000(os, collisionbox.MaxEdge);
        os<<serializeString(visual);
+       writeV2F1000(os, visual_size);
        writeU16(os, textures.size());
        for(u32 i=0; i<textures.size(); i++){
                os<<serializeString(textures[i]);
        }
+       writeV2S16(os, spritediv);
+       writeV2S16(os, initial_sprite_basepos);
 }
 
 void LuaEntityProperties::deSerialize(std::istream &is)
@@ -71,11 +81,14 @@ void LuaEntityProperties::deSerialize(std::istream &is)
        collisionbox.MinEdge = readV3F1000(is);
        collisionbox.MaxEdge = readV3F1000(is);
        visual = deSerializeString(is);
+       visual_size = readV2F1000(is);
        textures.clear();
        u32 texture_count = readU16(is);
        for(u32 i=0; i<texture_count; i++){
                textures.push_back(deSerializeString(is));
        }
+       spritediv = readV2S16(is);
+       initial_sprite_basepos = readV2S16(is);
 }
 
 
index 6e5f11385ffe59012d7c0282c8df0163c2db1f44..bc2871a94e34031dbacd95d947f201b4af31e8ff 100644 (file)
@@ -31,7 +31,10 @@ struct LuaEntityProperties
        float weight;
        core::aabbox3d<f32> collisionbox;
        std::string visual;
+       v2f visual_size;
        core::array<std::string> textures;
+       v2s16 spritediv;
+       v2s16 initial_sprite_basepos;
 
        LuaEntityProperties();
        std::string dump();
index 976b482c227317bd1b1fc3e2fd03442136f0583d..711a02cbc5e5c616bc772bca243b58b554d1f102 100644 (file)
@@ -142,6 +142,18 @@ static v3f readFloatPos(lua_State *L, int index)
        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)
 {
        lua_newtable(L);
@@ -239,6 +251,32 @@ static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
        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,
                const char *fieldname, std::string &result)
 {
@@ -307,6 +345,14 @@ static int getintfield_default(lua_State *L, int table,
        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,
                const char *fieldname, bool default_)
 {
@@ -1235,6 +1281,18 @@ private:
                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)
        // returns: true if item was added, false otherwise
        static int l_add_to_inventory(lua_State *L)
@@ -1272,6 +1330,30 @@ private:
                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:
        ObjectRef(ServerActiveObject *object):
                m_object(object)
@@ -1343,6 +1425,7 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, setacceleration),
        method(ObjectRef, add_to_inventory),
        method(ObjectRef, settexturemod),
+       method(ObjectRef, setsprite),
        {0,0}
 };
 
@@ -1859,25 +1942,24 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
        luaentity_get(L, id);
        //int object = lua_gettop(L);
 
-       lua_getfield(L, -1, "physical");
-       if(lua_isboolean(L, -1))
-               prop->physical = lua_toboolean(L, -1);
-       lua_pop(L, 1);
+       /* Read stuff */
        
-       lua_getfield(L, -1, "weight");
-       prop->weight = lua_tonumber(L, -1);
-       lua_pop(L, 1);
+       getboolfield(L, -1, "physical", prop->physical);
+
+       getfloatfield(L, -1, "weight", prop->weight);
 
        lua_getfield(L, -1, "collisionbox");
        if(lua_istable(L, -1))
                prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
        lua_pop(L, 1);
 
-       lua_getfield(L, -1, "visual");
-       if(lua_isstring(L, -1))
-               prop->visual = lua_tostring(L, -1);
-       lua_pop(L, 1);
+       getstringfield(L, -1, "visual", prop->visual);
        
+       lua_getfield(L, -1, "visual_size");
+       if(lua_istable(L, -1))
+               prop->visual_size = read_v2f(L, -1);
+       lua_pop(L, 1);
+
        lua_getfield(L, -1, "textures");
        if(lua_istable(L, -1)){
                prop->textures.clear();
@@ -1894,7 +1976,16 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
                }
        }
        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)
index f7d577b1fcab29f053b6a3143dfc3df32100b4c0..206d81289f14893fc86ff92e4b99fff17357a597 100644 (file)
@@ -1361,14 +1361,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        }
                }
                /*
-                       "[makealpha:R,G,B:filename.png"
-                       Use an image with converting one color to transparent.
+                       "[makealpha:R,G,B"
+                       Convert one color to transparent.
                */
                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
                                                <<"\", cancelling."<<std::endl;
                                return false;
@@ -1377,99 +1377,28 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        Strfnd sf(part_of_name.substr(11));
                        u32 r1 = stoi(sf.next(","));
                        u32 g1 = stoi(sf.next(","));
-                       u32 b1 = stoi(sf.next(":"));
+                       u32 b1 = stoi(sf.next(""));
                        std::string filename = sf.next("");
 
-                       /*infostream<<"generate_image(): Loading file \""<<filename
-                                       <<"\""<<std::endl;*/
-                       
-                       video::IImage *image = sourcecache->getOrLoad(filename, device);
+                       core::dimension2d<u32> dim = baseimg->getDimension();
                        
-                       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))
-                                               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("");
+                       /*video::IImage *oldbaseimg = baseimg;
+                       baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                       oldbaseimg->copyTo(baseimg);
+                       oldbaseimg->drop();*/
 
-                       /*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
+                       // Set alpha to full
+                       for(u32 y=0; y<dim.Height; y++)
+                       for(u32 x=0; x<dim.Width; x++)
                        {
-                               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);
-                               }
+                               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);
                        }
                }
                /*
index 935df4b2e29d8af9737b99a9fa68ed076486ae2c..97f902b995f8ee8699f1712a00fa1861a6923e67 100644 (file)
@@ -148,6 +148,19 @@ inline v3f readV3F1000(u8 *data)
        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)
 {
        writeS16(&data[0], p.X);
@@ -274,6 +287,45 @@ inline v3f readV3F1000(std::istream &is)
        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
 */