summaryrefslogtreecommitdiff
path: root/src/mapblockobject.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-10-15 02:28:57 +0300
committerPerttu Ahola <celeron55@gmail.com>2011-10-15 02:28:57 +0300
commit43a28f04fa3ddf4b612f58c25a896293a01567e3 (patch)
tree58ca2cac232c28ffd59609ad3998b97628f13e33 /src/mapblockobject.cpp
parent080002f8ed1af6d34cdc6f5abff0f51586ca831c (diff)
downloadminetest-43a28f04fa3ddf4b612f58c25a896293a01567e3.tar.gz
minetest-43a28f04fa3ddf4b612f58c25a896293a01567e3.tar.bz2
minetest-43a28f04fa3ddf4b612f58c25a896293a01567e3.zip
mobv2
Diffstat (limited to 'src/mapblockobject.cpp')
-rw-r--r--src/mapblockobject.cpp939
1 files changed, 0 insertions, 939 deletions
diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp
deleted file mode 100644
index 071a14b0c..000000000
--- a/src/mapblockobject.cpp
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-// This file contains the DEPRECATED MapBlockObject system
-
-#include "mapblockobject.h"
-#include "mapblock.h"
-// For object wrapping
-#include "map.h"
-#include "inventory.h"
-#include "utility.h"
-#include "mapblock.h"
-
-/*
- MapBlockObject
-*/
-
-// This is here because it uses the MapBlock
-v3f MapBlockObject::getAbsolutePos()
-{
- if(m_block == NULL)
- return m_pos;
-
- // getPosRelative gets nodepos relative to map origin
- v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
- return blockpos + m_pos;
-}
-
-void MapBlockObject::setBlockChanged()
-{
- if(m_block)
- m_block->setChangedFlag();
-}
-
-/*
- MovingObject
-*/
-
-v3f MovingObject::getAbsoluteShowPos()
-{
- if(m_block == NULL)
- return m_pos;
-
- // getPosRelative gets nodepos relative to map origin
- v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
- return blockpos + m_showpos;
-}
-
-void MovingObject::move(float dtime, v3f acceleration)
-{
- DSTACKF("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
- ", dtime=%f, acc=(%f,%f,%f)",
- __FUNCTION_NAME,
- getTypeId(),
- m_pos.X, m_pos.Y, m_pos.Z,
- m_speed.X, m_speed.Y, m_speed.Z,
- dtime,
- acceleration.X, acceleration.Y, acceleration.Z
- );
-
- v3s16 oldpos_i = floatToInt(m_pos, BS);
-
- if(m_block->isValidPosition(oldpos_i) == false)
- {
- // Should have wrapped, cancelling further movement.
- return;
- }
-
- // No collisions if there is no collision box
- if(m_collision_box == NULL)
- {
- m_speed += dtime * acceleration;
- m_pos += m_speed * dtime;
- return;
- }
-
- // Set insane speed to zero
- // Otherwise there will be divides by zero and other silly stuff
- if(m_speed.getLength() > 1000.0*BS)
- m_speed = v3f(0,0,0);
-
- // Limit speed to a reasonable value
- float speed_limit = 20.0*BS;
- if(m_speed.getLength() > speed_limit)
- m_speed = m_speed * (speed_limit / m_speed.getLength());
-
- v3f position = m_pos;
- v3f oldpos = position;
-
- /*std::cout<<"oldpos_i=("<<oldpos_i.X<<","<<oldpos_i.Y<<","
- <<oldpos_i.Z<<")"<<std::endl;*/
-
- // Maximum time increment (for collision detection etc)
- // Allow 0.1 blocks per increment
- // time = distance / speed
- // NOTE: In the loop below collisions are detected at 0.15*BS radius
- float speedlength = m_speed.getLength();
- f32 dtime_max_increment;
- if(fabs(speedlength) > 0.001)
- dtime_max_increment = 0.05*BS / speedlength;
- else
- dtime_max_increment = 0.5;
-
- m_touching_ground = false;
-
- u32 loopcount = 0;
- do
- {
- loopcount++;
-
- f32 dtime_part;
- if(dtime > dtime_max_increment)
- dtime_part = dtime_max_increment;
- else
- dtime_part = dtime;
- dtime -= dtime_part;
-
- // Begin of dtime limited code
-
- m_speed += acceleration * dtime_part;
- position += m_speed * dtime_part;
-
- /*
- Collision detection
- */
-
- v3s16 pos_i = floatToInt(position, BS);
-
- // The loop length is limited to the object moving a distance
- f32 d = (float)BS * 0.15;
-
- core::aabbox3d<f32> objectbox(
- m_collision_box->MinEdge + position,
- m_collision_box->MaxEdge + position
- );
-
- core::aabbox3d<f32> objectbox_old(
- m_collision_box->MinEdge + oldpos,
- m_collision_box->MaxEdge + oldpos
- );
-
- //TODO: Get these ranges from somewhere
- 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++)
- {
- try{
- MapNode n = m_block->getNodeParent(v3s16(x,y,z));
- if(content_features(n).walkable == false)
- continue;
- }
- catch(InvalidPositionException &e)
- {
- // Doing nothing here will block the object from
- // walking over map borders
- }
-
- core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS);
-
- // See if the object is touching ground
- if(
- fabs(nodebox.MaxEdge.Y-objectbox.MinEdge.Y) < d
- && nodebox.MaxEdge.X-d > objectbox.MinEdge.X
- && nodebox.MinEdge.X+d < objectbox.MaxEdge.X
- && nodebox.MaxEdge.Z-d > objectbox.MinEdge.Z
- && nodebox.MinEdge.Z+d < objectbox.MaxEdge.Z
- ){
- m_touching_ground = true;
- }
-
- if(objectbox.intersectsWithBox(nodebox))
- {
-
- v3f dirs[3] = {
- v3f(0,0,1), // back
- v3f(0,1,0), // top
- v3f(1,0,0), // right
- };
- for(u16 i=0; i<3; i++)
- {
- f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]);
- f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]);
- f32 playermax = objectbox.MaxEdge.dotProduct(dirs[i]);
- f32 playermin = objectbox.MinEdge.dotProduct(dirs[i]);
- f32 playermax_old = objectbox_old.MaxEdge.dotProduct(dirs[i]);
- f32 playermin_old = objectbox_old.MinEdge.dotProduct(dirs[i]);
-
- bool main_edge_collides =
- ((nodemax > playermin && nodemax <= playermin_old + d
- && m_speed.dotProduct(dirs[i]) < 0)
- ||
- (nodemin < playermax && nodemin >= playermax_old - d
- && m_speed.dotProduct(dirs[i]) > 0));
-
- bool other_edges_collide = true;
- for(u16 j=0; j<3; j++)
- {
- if(j == i)
- continue;
- f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]);
- f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]);
- f32 playermax = objectbox.MaxEdge.dotProduct(dirs[j]);
- f32 playermin = objectbox.MinEdge.dotProduct(dirs[j]);
- if(!(nodemax - d > playermin && nodemin + d < playermax))
- {
- other_edges_collide = false;
- break;
- }
- }
-
- if(main_edge_collides && other_edges_collide)
- {
- m_speed -= m_speed.dotProduct(dirs[i]) * dirs[i];
- position -= position.dotProduct(dirs[i]) * dirs[i];
- position += oldpos.dotProduct(dirs[i]) * dirs[i];
- }
-
- }
-
- } // if(objectbox.intersectsWithBox(nodebox))
- } // for y
-
- } // End of dtime limited loop
- while(dtime > 0.001);
-
- 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(getTexturePath("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();
- 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(getTexturePath("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(getTexturePath("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
-*/
-
-MapBlockObjectList::MapBlockObjectList(MapBlock *block):
- m_block(block)
-{
- m_mutex.Init();
-}
-
-MapBlockObjectList::~MapBlockObjectList()
-{
- clear();
-}
-
-/*
- The serialization format:
- [0] u16 number of entries
- [2] entries (id, typeId, parameters)
-*/
-
-void MapBlockObjectList::serialize(std::ostream &os, u8 version)
-{
- JMutexAutoLock lock(m_mutex);
-
- u8 buf[2];
- writeU16(buf, m_objects.size());
- os.write((char*)buf, 2);
-
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- i.getNode()->getValue()->serialize(os, version);
- }
-}
-
-void MapBlockObjectList::update(std::istream &is, u8 version,
- scene::ISceneManager *smgr, u32 daynight_ratio)
-{
- JMutexAutoLock lock(m_mutex);
-
- /*
- Collect all existing ids to a set.
-
- As things are updated, they are removed from this.
-
- All remaining ones are deleted.
- */
- core::map<s16, bool> ids_to_delete;
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- ids_to_delete.insert(i.getNode()->getKey(), true);
- }
-
- u8 buf[6];
-
- is.read((char*)buf, 2);
- u16 count = readU16(buf);
-
- for(u16 i=0; i<count; i++)
- {
- // Read id
- is.read((char*)buf, 2);
- s16 id = readS16(buf);
-
- // Read position
- // stored as x1000/BS v3s16
- is.read((char*)buf, 6);
- v3s16 pos_i = readV3S16(buf);
- v3f pos((f32)pos_i.X/1000*BS,
- (f32)pos_i.Y/1000*BS,
- (f32)pos_i.Z/1000*BS);
-
- // Read typeId
- is.read((char*)buf, 2);
- u16 type_id = readU16(buf);
-
- bool create_new = false;
-
- // Find an object with the id
- core::map<s16, MapBlockObject*>::Node *n;
- n = m_objects.find(id);
- // If no entry is found for id
- if(n == NULL)
- {
- // Insert dummy pointer node
- m_objects.insert(id, NULL);
- // Get node
- n = m_objects.find(id);
- // A new object will be created at this node
- create_new = true;
- }
- // If type_id differs
- else if(n->getValue()->getTypeId() != type_id)
- {
- // Delete old object
- delete n->getValue();
- // A new object will be created at this node
- create_new = true;
- }
-
- MapBlockObject *obj = NULL;
-
- if(create_new)
- {
- /*dstream<<"MapBlockObjectList adding new object"
- " id="<<id
- <<std::endl;*/
-
- if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
- {
- obj = new SignObject(m_block, id, pos);
- }
- else if(type_id == MAPBLOCKOBJECT_TYPE_RAT)
- {
- 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);
- }
- else
- {
- 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.
- // Update it.
-
- obj->update(is, version);
-
- /*
- Update light on client
- */
- if(smgr != NULL)
- {
- u8 light = LIGHT_MAX;
- try{
- v3s16 relpos_i = floatToInt(obj->m_pos, BS);
- 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 all objects whose ids_to_delete remain in ids_to_delete
- for(core::map<s16, bool>::Iterator
- i = ids_to_delete.getIterator();
- i.atEnd() == false; i++)
- {
- s16 id = i.getNode()->getKey();
-
- /*dstream<<"MapBlockObjectList deleting object"
- " id="<<id
- <<std::endl;*/
-
- MapBlockObject *obj = m_objects[id];
- obj->removeFromScene();
- delete obj;
- m_objects.remove(id);
- }
-
- m_last_update_daynight_ratio = daynight_ratio;
-}
-
-s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
-{
- s16 id = 0;
- for(;;)
- {
- if(m_objects.find(id) == NULL)
- return id;
- if(id == 32767)
- throw ContainerFullException
- ("MapBlockObjectList doesn't fit more objects");
- id++;
- }
-}
-
-void MapBlockObjectList::add(MapBlockObject *object)
- throw(ContainerFullException, AlreadyExistsException)
-{
- if(object == NULL)
- {
- dstream<<"MapBlockObjectList::add(): NULL object"<<std::endl;
- return;
- }
-
- JMutexAutoLock lock(m_mutex);
-
- // Create unique id if id==-1
- if(object->m_id == -1)
- {
- object->m_id = getFreeId();
- }
-
- if(m_objects.find(object->m_id) != NULL)
- {
- dstream<<"MapBlockObjectList::add(): "
- "object with same id already exists"<<std::endl;
- throw AlreadyExistsException
- ("MapBlockObjectList already has given id");
- }
-
- object->m_block = m_block;
-
- /*v3f p = object->m_pos;
- dstream<<"MapBlockObjectList::add(): "
- <<"m_block->getPos()=("
- <<m_block->getPos().X<<","
- <<m_block->getPos().Y<<","
- <<m_block->getPos().Z<<")"
- <<" inserting object with id="<<object->m_id
- <<" pos="
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
- <<std::endl;*/
-
- m_objects.insert(object->m_id, object);
-}
-
-void MapBlockObjectList::clear()
-{
- JMutexAutoLock lock(m_mutex);
-
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- MapBlockObject *obj = i.getNode()->getValue();
- //FIXME: This really shouldn't be NULL at any time,
- // but this condition was added because it was.
- if(obj != NULL)
- {
- obj->removeFromScene();
- delete obj;
- }
- }
-
- m_objects.clear();
-}
-
-void MapBlockObjectList::remove(s16 id)
-{
- JMutexAutoLock lock(m_mutex);
-
- core::map<s16, MapBlockObject*>::Node *n;
- n = m_objects.find(id);
- if(n == NULL)
- return;
-
- n->getValue()->removeFromScene();
- delete n->getValue();
- m_objects.remove(id);
-}
-
-MapBlockObject * MapBlockObjectList::get(s16 id)
-{
- core::map<s16, MapBlockObject*>::Node *n;
- n = m_objects.find(id);
- if(n == NULL)
- return NULL;
- else
- return n->getValue();
-}
-
-void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
-{
- DSTACK(__FUNCTION_NAME);
-
- JMutexAutoLock lock(m_mutex);
-
- core::map<s16, bool> ids_to_delete;
-
- {
- DSTACKF("%s: stepping objects", __FUNCTION_NAME);
-
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- MapBlockObject *obj = i.getNode()->getValue();
-
- DSTACKF("%s: stepping object type %i", __FUNCTION_NAME,
- obj->getTypeId());
-
- if(server)
- {
- // Update light
- u8 light = LIGHT_MAX;
- try{
- v3s16 relpos_i = floatToInt(obj->m_pos, BS);
- 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);
- }
- else
- {
- obj->clientStep(dtime);
- }
- }
- }
-
- {
- DSTACKF("%s: deleting objects", __FUNCTION_NAME);
-
- // Delete objects in delete queue
- for(core::map<s16, bool>::Iterator
- i = ids_to_delete.getIterator();
- i.atEnd() == false; i++)
- {
- s16 id = i.getNode()->getKey();
-
- MapBlockObject *obj = m_objects[id];
- obj->removeFromScene();
- delete obj;
- m_objects.remove(id);
- }
- }
-
- /*
- Wrap objects on server
- */
-
- if(server == false)
- return;
-
- {
- DSTACKF("%s: object wrap loop", __FUNCTION_NAME);
-
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- MapBlockObject *obj = i.getNode()->getValue();
-
- v3s16 pos_i = floatToInt(obj->m_pos, BS);
-
- if(m_block->isValidPosition(pos_i))
- {
- // No wrap
- continue;
- }
-
- bool impossible = wrapObject(obj);
-
- if(impossible)
- {
- // No wrap
- continue;
- }
-
- // Restart find
- i = m_objects.getIterator();
- }
- }
-}
-
-bool MapBlockObjectList::wrapObject(MapBlockObject *object)
-{
- DSTACK(__FUNCTION_NAME);
-
- // No lock here; this is called so that the lock is already locked.
- //JMutexAutoLock lock(m_mutex);
-
- assert(object->m_block == m_block);
- assert(m_objects.find(object->m_id) != NULL);
- assert(m_objects[object->m_id] == object);
-
- Map *map = m_block->getParent();
-
- // Calculate blockpos on map
- v3s16 oldblock_pos_i_on_map = m_block->getPosRelative();
- v3f pos_f_on_oldblock = object->m_pos;
- v3s16 pos_i_on_oldblock = floatToInt(pos_f_on_oldblock, BS);
- v3s16 pos_i_on_map = pos_i_on_oldblock + oldblock_pos_i_on_map;
- v3s16 pos_blocks_on_map = getNodeBlockPos(pos_i_on_map);
-
- // Get new block
- MapBlock *newblock;
- try{
- newblock = map->getBlockNoCreate(pos_blocks_on_map);
- }
- catch(InvalidPositionException &e)
- {
- // Couldn't find block -> not wrapping
- /*dstream<<"WARNING: Wrapping object not possible: "
- <<"could not find new block"
- <<"("<<pos_blocks_on_map.X
- <<","<<pos_blocks_on_map.Y
- <<","<<pos_blocks_on_map.Z
- <<")"<<std::endl;*/
- /*dstream<<"pos_f_on_oldblock=("
- <<pos_f_on_oldblock.X<<","
- <<pos_f_on_oldblock.Y<<","
- <<pos_f_on_oldblock.Z<<")"
- <<std::endl;*/
- return true;
- }
-
- if(newblock == m_block)
- {
- dstream<<"WARNING: Wrapping object not possible: "
- "newblock == oldblock"<<std::endl;
- return true;
- }
-
- // Calculate position on new block
- v3f oldblock_pos_f_on_map = intToFloat(oldblock_pos_i_on_map, BS);
- v3s16 newblock_pos_i_on_map = newblock->getPosRelative();
- v3f newblock_pos_f_on_map = intToFloat(newblock_pos_i_on_map, BS);
- v3f pos_f_on_newblock = pos_f_on_oldblock
- - newblock_pos_f_on_map + oldblock_pos_f_on_map;
-
- // Remove object from this block
- m_objects.remove(object->m_id);
-
- // Add object to new block
- object->m_pos = pos_f_on_newblock;
- object->m_id = -1;
- object->m_block = NULL;
- newblock->addObject(object);
-
- //dstream<<"NOTE: Wrapped object"<<std::endl;
-
- return false;
-}
-
-void MapBlockObjectList::getObjects(v3f origin, f32 max_d,
- core::array<DistanceSortedObject> &dest)
-{
- for(core::map<s16, MapBlockObject*>::Iterator
- i = m_objects.getIterator();
- i.atEnd() == false; i++)
- {
- MapBlockObject *obj = i.getNode()->getValue();
-
- f32 d = (obj->getRelativeShowPos() - origin).getLength();
-
- if(d > max_d)
- continue;
-
- DistanceSortedObject dso(obj, d);
-
- dest.push_back(dso);
- }
-}
-
-//END