aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/mods/default/init.lua35
-rw-r--r--src/collision.cpp13
-rw-r--r--src/content_cao.cpp189
-rw-r--r--src/content_inventory.cpp2
-rw-r--r--src/content_sao.cpp21
-rw-r--r--src/content_sao.h3
-rw-r--r--src/luaentity_common.cpp15
-rw-r--r--src/luaentity_common.h3
-rw-r--r--src/scriptapi.cpp113
-rw-r--r--src/tile.cpp113
-rw-r--r--src/utility.h52
11 files changed, 402 insertions, 157 deletions
diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua
index 6ea15b4ee..ea6bf3da9 100644
--- a/data/mods/default/init.lua
+++ b/data/mods/default/init.lua
@@ -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
--
diff --git a/src/collision.cpp b/src/collision.cpp
index 24f1e9d18..3460b04fd 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -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
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index 984a216d8..ba8739df7 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -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();
+ }
}
};
diff --git a/src/content_inventory.cpp b/src/content_inventory.cpp
index 2a05b76f0..21acad307 100644
--- a/src/content_inventory.cpp
+++ b/src/content_inventory.cpp
@@ -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;
}
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 74824d573..b013069aa 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -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(
diff --git a/src/content_sao.h b/src/content_sao.h
index 6f5bab310..c5e1471bc 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -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);
diff --git a/src/luaentity_common.cpp b/src/luaentity_common.cpp
index 503083d0b..cf1ac7bed 100644
--- a/src/luaentity_common.cpp
+++ b/src/luaentity_common.cpp
@@ -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);
}
diff --git a/src/luaentity_common.h b/src/luaentity_common.h
index 6e5f11385..bc2871a94 100644
--- a/src/luaentity_common.h
+++ b/src/luaentity_common.h
@@ -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();
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 976b482c2..711a02cbc 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -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)
diff --git a/src/tile.cpp b/src/tile.cpp
index f7d577b1f..206d81289 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -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);
}
}
/*
diff --git a/src/utility.h b/src/utility.h
index 935df4b2e..97f902b99 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -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
*/