#include "mapblock.h"
// Only for ::getNodeBox, TODO: Get rid of this
#include "map.h"
+#include "inventory.h"
+#include "irrlichtwrapper.h"
/*
MapBlockObject
/*
MovingObject
*/
+
+v3f MovingObject::getAbsoluteShowPos()
+{
+ if(m_block == NULL)
+ return m_pos;
+
+ // getPosRelative gets nodepos relative to map origin
+ v3f blockpos = intToFloat(m_block->getPosRelative());
+ return blockpos + m_showpos;
+}
+
void MovingObject::move(float dtime, v3f acceleration)
{
DSTACK("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
float speedlength = m_speed.getLength();
f32 dtime_max_increment;
if(fabs(speedlength) > 0.001)
- dtime_max_increment = 0.1*BS / speedlength;
+ dtime_max_increment = 0.05*BS / speedlength;
else
dtime_max_increment = 0.5;
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
{
try{
- if(material_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
+ if(content_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
== false)
continue;
}
catch(InvalidPositionException &e)
{
- // Doing nothing here will block the player from
+ // Doing nothing here will block the object from
// walking over map borders
}
core::aabbox3d<f32> nodebox = Map::getNodeBox(
v3s16(x,y,z));
- // See if the player is touching ground
+ // See if the object is touching ground
if(
fabs(nodebox.MaxEdge.Y-objectbox.MinEdge.Y) < d
&& nodebox.MaxEdge.X-d > objectbox.MinEdge.X
m_pos = position;
}
+void MovingObject::simpleMove(float dtime)
+{
+ m_pos_animation_time_counter += dtime;
+ m_pos_animation_counter += dtime;
+ v3f movevector = m_pos - m_oldpos;
+ f32 moveratio;
+ if(m_pos_animation_time < 0.001)
+ moveratio = 1.0;
+ else
+ moveratio = m_pos_animation_counter / m_pos_animation_time;
+ if(moveratio > 1.5)
+ moveratio = 1.5;
+ m_showpos = m_oldpos + movevector * moveratio;
+}
+
+#ifndef SERVER
+/*
+ RatObject
+*/
+void RatObject::addToScene(scene::ISceneManager *smgr)
+{
+ if(m_node != NULL)
+ return;
+
+ video::IVideoDriver* driver = smgr->getVideoDriver();
+
+ scene::SMesh *mesh = new scene::SMesh();
+ scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+ video::SColor c(255,255,255,255);
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
+ };
+ u16 indices[] = {0,1,2,2,3,0};
+ buf->append(vertices, 4, indices, 6);
+ // Set material
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+ buf->getMaterial().setTexture
+ (0, driver->getTexture(porting::getDataPath("rat.png").c_str()));
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+ buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+ buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ // Add to mesh
+ mesh->addMeshBuffer(buf);
+ buf->drop();
+ m_node = smgr->addMeshSceneNode(mesh, NULL);
+ mesh->drop();
+ updateNodePos();
+}
+#endif
+
+/*
+ ItemObject
+*/
+#ifndef SERVER
+void ItemObject::addToScene(scene::ISceneManager *smgr)
+{
+ if(m_node != NULL)
+ return;
+
+ //video::IVideoDriver* driver = smgr->getVideoDriver();
+
+ // Get image of item for showing
+ video::ITexture *texture = getItemImage();
+
+ /*
+ Create a mesh
+ */
+
+ scene::SMesh *mesh = new scene::SMesh();
+ {
+ scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+ video::SColor c(255,255,255,255);
+ video::S3DVertex vertices[4] =
+ {
+ /*video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
+ video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
+ video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
+ video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),*/
+ video::S3DVertex(BS/3,-BS/2,0, 0,0,0, c, 0,1),
+ video::S3DVertex(-BS/3,-BS/2,0, 0,0,0, c, 1,1),
+ video::S3DVertex(-BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 1,0),
+ video::S3DVertex(BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 0,0),
+ };
+ u16 indices[] = {0,1,2,2,3,0};
+ buf->append(vertices, 4, indices, 6);
+ // Set material
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+ buf->getMaterial().setTexture(0, texture);
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+ buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+ buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ // Add to mesh
+ mesh->addMeshBuffer(buf);
+ buf->drop();
+ }
+ m_node = smgr->addMeshSceneNode(mesh, NULL);
+ // Set it to use the materials of the meshbuffers directly.
+ // This is needed for changing the texture in the future
+ ((scene::IMeshSceneNode*)m_node)->setReadOnlyMaterials(true);
+ mesh->drop();
+
+ updateSceneNode();
+}
+
+video::ITexture * ItemObject::getItemImage()
+{
+ /*
+ Create an inventory item to see what is its image
+ */
+ video::ITexture *texture = NULL;
+ InventoryItem *item = createInventoryItem();
+ if(item)
+ texture = item->getImage();
+ /*else
+ texture = g_irrlicht->getTexture(porting::getDataPath("cloud.png").c_str());*/
+ if(item)
+ delete item;
+ return texture;
+}
+
+#endif
+
+InventoryItem * ItemObject::createInventoryItem()
+{
+ try{
+ std::istringstream is(m_itemstring, std::ios_base::binary);
+ InventoryItem *item = InventoryItem::deSerialize(is);
+ dstream<<__FUNCTION_NAME<<": m_itemstring=\""
+ <<m_itemstring<<"\" -> item="<<item
+ <<std::endl;
+ return item;
+ }
+ catch(SerializationError &e)
+ {
+ dstream<<__FUNCTION_NAME<<": serialization error: "
+ <<"m_itemstring=\""<<m_itemstring<<"\""<<std::endl;
+ return NULL;
+ }
+}
+
+/*
+ PlayerObject
+*/
+#ifndef SERVER
+void PlayerObject::addToScene(scene::ISceneManager *smgr)
+{
+ if(m_node != NULL)
+ return;
+
+ video::IVideoDriver* driver = smgr->getVideoDriver();
+
+ // Attach a simple mesh to the player for showing an image
+ scene::SMesh *mesh = new scene::SMesh();
+ { // Front
+ scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+ video::SColor c(255,255,255,255);
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
+ };
+ u16 indices[] = {0,1,2,2,3,0};
+ buf->append(vertices, 4, indices, 6);
+ // Set material
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+ buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str()));
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+ buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+ //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ // Add to mesh
+ mesh->addMeshBuffer(buf);
+ buf->drop();
+ }
+ { // Back
+ scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+ video::SColor c(255,255,255,255);
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
+ video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
+ video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
+ video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
+ };
+ u16 indices[] = {0,1,2,2,3,0};
+ buf->append(vertices, 4, indices, 6);
+ // Set material
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+ buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str()));
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+ buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+ buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ // Add to mesh
+ mesh->addMeshBuffer(buf);
+ buf->drop();
+ }
+
+ m_node = smgr->addMeshSceneNode(mesh, NULL);
+ mesh->drop();
+ updateNodePos();
+}
+#endif
+
/*
MapBlockObjectList
*/
}
void MapBlockObjectList::update(std::istream &is, u8 version,
- scene::ISceneManager *smgr)
+ scene::ISceneManager *smgr, u32 daynight_ratio)
{
JMutexAutoLock lock(m_mutex);
" id="<<id
<<std::endl;*/
- if(type_id == MAPBLOCKOBJECT_TYPE_TEST)
- {
- // The constructors of objects shouldn't need
- // any more parameters than this.
- obj = new TestObject(m_block, id, pos);
- }
- else if(type_id == MAPBLOCKOBJECT_TYPE_TEST2)
- {
- obj = new Test2Object(m_block, id, pos);
- }
- else if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
+ if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
{
obj = new SignObject(m_block, id, pos);
}
{
obj = new RatObject(m_block, id, pos);
}
+ else if(type_id == MAPBLOCKOBJECT_TYPE_ITEM)
+ {
+ obj = new ItemObject(m_block, id, pos);
+ }
else
{
+ // This is fatal because we cannot know the length
+ // of the object's data
throw SerializationError
("MapBlockObjectList::update(): Unknown MapBlockObject type");
}
if(smgr != NULL)
+ //obj->addToScene(smgr, daynight_ratio);
obj->addToScene(smgr);
n->setValue(obj);
{
obj = n->getValue();
obj->updatePos(pos);
+ /*if(daynight_ratio != m_last_update_daynight_ratio)
+ {
+ obj->removeFromScene();
+ obj->addToScene(smgr, daynight_ratio);
+ }*/
}
// Now there is an object in obj.
obj->update(is, version);
+ /*
+ Update light on client
+ */
+ if(smgr != NULL)
+ {
+ u8 light = LIGHT_MAX;
+ try{
+ v3s16 relpos_i = floatToInt(obj->m_pos);
+ MapNode n = m_block->getNodeParent(relpos_i);
+ light = n.getLightBlend(daynight_ratio);
+ }
+ catch(InvalidPositionException &e) {}
+ obj->updateLight(light);
+ }
+
// Remove from deletion list
if(ids_to_delete.find(id) != NULL)
ids_to_delete.remove(id);
delete obj;
m_objects.remove(id);
}
+
+ m_last_update_daynight_ratio = daynight_ratio;
}
s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
return n->getValue();
}
-void MapBlockObjectList::step(float dtime, bool server)
+void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
{
DSTACK(__FUNCTION_NAME);
if(server)
{
- bool to_delete = obj->serverStep(dtime);
+ // Update light
+ u8 light = LIGHT_MAX;
+ try{
+ v3s16 relpos_i = floatToInt(obj->m_pos);
+ MapNode n = m_block->getNodeParent(relpos_i);
+ light = n.getLightBlend(daynight_ratio);
+ }
+ catch(InvalidPositionException &e) {}
+ obj->updateLight(light);
+
+ bool to_delete = obj->serverStep(dtime, daynight_ratio);
if(to_delete)
ids_to_delete.insert(obj->m_id, true);
{
MapBlockObject *obj = i.getNode()->getValue();
- f32 d = (obj->m_pos - origin).getLength();
+ f32 d = (obj->getRelativeShowPos() - origin).getLength();
if(d > max_d)
continue;