mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Improve luaentity sprite functionality (and add some random stuff)
This commit is contained in:
parent
b4e6ca63b5
commit
82a460ec90
@ -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
|
||||
--
|
||||
|
@ -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
|
||||
|
@ -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,8 +1281,81 @@ 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:
|
||||
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
|
||||
{
|
||||
return ACTIVEOBJECT_TYPE_LUAENTITY;
|
||||
@ -1296,30 +1369,6 @@ public:
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
115
src/tile.cpp
115
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;*/
|
||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
||||
|
||||
video::IImage *image = sourcecache->getOrLoad(filename, device);
|
||||
|
||||
if(image == NULL)
|
||||
/*video::IImage *oldbaseimg = baseimg;
|
||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
|
||||
oldbaseimg->copyTo(baseimg);
|
||||
oldbaseimg->drop();*/
|
||||
|
||||
// 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 \""
|
||||
<<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("");
|
||||
|
||||
/*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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user