3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 // This file contains the DEPRECATED MapBlockObject system
22 #include "mapblockobject.h"
24 // For object wrapping
26 #include "inventory.h"
27 #include "irrlichtwrapper.h"
34 // This is here because it uses the MapBlock
35 v3f MapBlockObject::getAbsolutePos()
40 // getPosRelative gets nodepos relative to map origin
41 v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
42 return blockpos + m_pos;
45 void MapBlockObject::setBlockChanged()
48 m_block->setChangedFlag();
55 v3f MovingObject::getAbsoluteShowPos()
60 // getPosRelative gets nodepos relative to map origin
61 v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
62 return blockpos + m_showpos;
65 void MovingObject::move(float dtime, v3f acceleration)
67 DSTACK("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
68 ", dtime=%f, acc=(%f,%f,%f)",
71 m_pos.X, m_pos.Y, m_pos.Z,
72 m_speed.X, m_speed.Y, m_speed.Z,
74 acceleration.X, acceleration.Y, acceleration.Z
77 v3s16 oldpos_i = floatToInt(m_pos, BS);
79 if(m_block->isValidPosition(oldpos_i) == false)
81 // Should have wrapped, cancelling further movement.
85 // No collisions if there is no collision box
86 if(m_collision_box == NULL)
88 m_speed += dtime * acceleration;
89 m_pos += m_speed * dtime;
93 // Set insane speed to zero
94 // Otherwise there will be divides by zero and other silly stuff
95 if(m_speed.getLength() > 1000.0*BS)
98 // Limit speed to a reasonable value
99 float speed_limit = 20.0*BS;
100 if(m_speed.getLength() > speed_limit)
101 m_speed = m_speed * (speed_limit / m_speed.getLength());
103 v3f position = m_pos;
104 v3f oldpos = position;
106 /*std::cout<<"oldpos_i=("<<oldpos_i.X<<","<<oldpos_i.Y<<","
107 <<oldpos_i.Z<<")"<<std::endl;*/
109 // Maximum time increment (for collision detection etc)
110 // Allow 0.1 blocks per increment
111 // time = distance / speed
112 // NOTE: In the loop below collisions are detected at 0.15*BS radius
113 float speedlength = m_speed.getLength();
114 f32 dtime_max_increment;
115 if(fabs(speedlength) > 0.001)
116 dtime_max_increment = 0.05*BS / speedlength;
118 dtime_max_increment = 0.5;
120 m_touching_ground = false;
128 if(dtime > dtime_max_increment)
129 dtime_part = dtime_max_increment;
134 // Begin of dtime limited code
136 m_speed += acceleration * dtime_part;
137 position += m_speed * dtime_part;
143 v3s16 pos_i = floatToInt(position, BS);
145 // The loop length is limited to the object moving a distance
146 f32 d = (float)BS * 0.15;
148 core::aabbox3d<f32> objectbox(
149 m_collision_box->MinEdge + position,
150 m_collision_box->MaxEdge + position
153 core::aabbox3d<f32> objectbox_old(
154 m_collision_box->MinEdge + oldpos,
155 m_collision_box->MaxEdge + oldpos
158 //TODO: Get these ranges from somewhere
159 for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++)
160 for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++)
161 for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
164 if(content_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
168 catch(InvalidPositionException &e)
170 // Doing nothing here will block the object from
171 // walking over map borders
174 core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS);
176 // See if the object is touching ground
178 fabs(nodebox.MaxEdge.Y-objectbox.MinEdge.Y) < d
179 && nodebox.MaxEdge.X-d > objectbox.MinEdge.X
180 && nodebox.MinEdge.X+d < objectbox.MaxEdge.X
181 && nodebox.MaxEdge.Z-d > objectbox.MinEdge.Z
182 && nodebox.MinEdge.Z+d < objectbox.MaxEdge.Z
184 m_touching_ground = true;
187 if(objectbox.intersectsWithBox(nodebox))
195 for(u16 i=0; i<3; i++)
197 f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]);
198 f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]);
199 f32 playermax = objectbox.MaxEdge.dotProduct(dirs[i]);
200 f32 playermin = objectbox.MinEdge.dotProduct(dirs[i]);
201 f32 playermax_old = objectbox_old.MaxEdge.dotProduct(dirs[i]);
202 f32 playermin_old = objectbox_old.MinEdge.dotProduct(dirs[i]);
204 bool main_edge_collides =
205 ((nodemax > playermin && nodemax <= playermin_old + d
206 && m_speed.dotProduct(dirs[i]) < 0)
208 (nodemin < playermax && nodemin >= playermax_old - d
209 && m_speed.dotProduct(dirs[i]) > 0));
211 bool other_edges_collide = true;
212 for(u16 j=0; j<3; j++)
216 f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]);
217 f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]);
218 f32 playermax = objectbox.MaxEdge.dotProduct(dirs[j]);
219 f32 playermin = objectbox.MinEdge.dotProduct(dirs[j]);
220 if(!(nodemax - d > playermin && nodemin + d < playermax))
222 other_edges_collide = false;
227 if(main_edge_collides && other_edges_collide)
229 m_speed -= m_speed.dotProduct(dirs[i]) * dirs[i];
230 position -= position.dotProduct(dirs[i]) * dirs[i];
231 position += oldpos.dotProduct(dirs[i]) * dirs[i];
236 } // if(objectbox.intersectsWithBox(nodebox))
239 } // End of dtime limited loop
240 while(dtime > 0.001);
245 void MovingObject::simpleMove(float dtime)
247 m_pos_animation_time_counter += dtime;
248 m_pos_animation_counter += dtime;
249 v3f movevector = m_pos - m_oldpos;
251 if(m_pos_animation_time < 0.001)
254 moveratio = m_pos_animation_counter / m_pos_animation_time;
257 m_showpos = m_oldpos + movevector * moveratio;
264 void RatObject::addToScene(scene::ISceneManager *smgr)
269 video::IVideoDriver* driver = smgr->getVideoDriver();
271 scene::SMesh *mesh = new scene::SMesh();
272 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
273 video::SColor c(255,255,255,255);
274 video::S3DVertex vertices[4] =
276 video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
277 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
278 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
279 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
281 u16 indices[] = {0,1,2,2,3,0};
282 buf->append(vertices, 4, indices, 6);
284 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
285 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
286 buf->getMaterial().setTexture
287 (0, driver->getTexture(porting::getDataPath("rat.png").c_str()));
288 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
289 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
290 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
292 mesh->addMeshBuffer(buf);
294 m_node = smgr->addMeshSceneNode(mesh, NULL);
304 void ItemObject::addToScene(scene::ISceneManager *smgr)
309 //video::IVideoDriver* driver = smgr->getVideoDriver();
311 // Get image of item for showing
312 video::ITexture *texture = getItemImage();
318 scene::SMesh *mesh = new scene::SMesh();
320 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
321 video::SColor c(255,255,255,255);
322 video::S3DVertex vertices[4] =
324 /*video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
325 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
326 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
327 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),*/
328 video::S3DVertex(BS/3,-BS/2,0, 0,0,0, c, 0,1),
329 video::S3DVertex(-BS/3,-BS/2,0, 0,0,0, c, 1,1),
330 video::S3DVertex(-BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 1,0),
331 video::S3DVertex(BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 0,0),
333 u16 indices[] = {0,1,2,2,3,0};
334 buf->append(vertices, 4, indices, 6);
336 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
337 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
338 buf->getMaterial().setTexture(0, texture);
339 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
340 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
341 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
343 mesh->addMeshBuffer(buf);
346 m_node = smgr->addMeshSceneNode(mesh, NULL);
347 // Set it to use the materials of the meshbuffers directly.
348 // This is needed for changing the texture in the future
349 ((scene::IMeshSceneNode*)m_node)->setReadOnlyMaterials(true);
355 video::ITexture * ItemObject::getItemImage()
358 Create an inventory item to see what is its image
360 video::ITexture *texture = NULL;
361 InventoryItem *item = createInventoryItem();
363 texture = item->getImage();
365 texture = g_irrlicht->getTexture(porting::getDataPath("cloud.png").c_str());*/
373 InventoryItem * ItemObject::createInventoryItem()
376 std::istringstream is(m_itemstring, std::ios_base::binary);
377 InventoryItem *item = InventoryItem::deSerialize(is);
378 dstream<<__FUNCTION_NAME<<": m_itemstring=\""
379 <<m_itemstring<<"\" -> item="<<item
383 catch(SerializationError &e)
385 dstream<<__FUNCTION_NAME<<": serialization error: "
386 <<"m_itemstring=\""<<m_itemstring<<"\""<<std::endl;
395 void PlayerObject::addToScene(scene::ISceneManager *smgr)
400 video::IVideoDriver* driver = smgr->getVideoDriver();
402 // Attach a simple mesh to the player for showing an image
403 scene::SMesh *mesh = new scene::SMesh();
405 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
406 video::SColor c(255,255,255,255);
407 video::S3DVertex vertices[4] =
409 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
410 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
411 video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
412 video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
414 u16 indices[] = {0,1,2,2,3,0};
415 buf->append(vertices, 4, indices, 6);
417 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
418 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
419 buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player.png").c_str()));
420 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
421 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
422 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
423 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
425 mesh->addMeshBuffer(buf);
429 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
430 video::SColor c(255,255,255,255);
431 video::S3DVertex vertices[4] =
433 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
434 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
435 video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
436 video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
438 u16 indices[] = {0,1,2,2,3,0};
439 buf->append(vertices, 4, indices, 6);
441 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
442 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
443 buf->getMaterial().setTexture(0, driver->getTexture(porting::getDataPath("player_back.png").c_str()));
444 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
445 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
446 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
448 mesh->addMeshBuffer(buf);
452 m_node = smgr->addMeshSceneNode(mesh, NULL);
462 MapBlockObjectList::MapBlockObjectList(MapBlock *block):
468 MapBlockObjectList::~MapBlockObjectList()
474 The serialization format:
475 [0] u16 number of entries
476 [2] entries (id, typeId, parameters)
479 void MapBlockObjectList::serialize(std::ostream &os, u8 version)
481 JMutexAutoLock lock(m_mutex);
484 writeU16(buf, m_objects.size());
485 os.write((char*)buf, 2);
487 for(core::map<s16, MapBlockObject*>::Iterator
488 i = m_objects.getIterator();
489 i.atEnd() == false; i++)
491 i.getNode()->getValue()->serialize(os, version);
495 void MapBlockObjectList::update(std::istream &is, u8 version,
496 scene::ISceneManager *smgr, u32 daynight_ratio)
498 JMutexAutoLock lock(m_mutex);
501 Collect all existing ids to a set.
503 As things are updated, they are removed from this.
505 All remaining ones are deleted.
507 core::map<s16, bool> ids_to_delete;
508 for(core::map<s16, MapBlockObject*>::Iterator
509 i = m_objects.getIterator();
510 i.atEnd() == false; i++)
512 ids_to_delete.insert(i.getNode()->getKey(), true);
517 is.read((char*)buf, 2);
518 u16 count = readU16(buf);
520 for(u16 i=0; i<count; i++)
523 is.read((char*)buf, 2);
524 s16 id = readS16(buf);
527 // stored as x1000/BS v3s16
528 is.read((char*)buf, 6);
529 v3s16 pos_i = readV3S16(buf);
530 v3f pos((f32)pos_i.X/1000*BS,
531 (f32)pos_i.Y/1000*BS,
532 (f32)pos_i.Z/1000*BS);
535 is.read((char*)buf, 2);
536 u16 type_id = readU16(buf);
538 bool create_new = false;
540 // Find an object with the id
541 core::map<s16, MapBlockObject*>::Node *n;
542 n = m_objects.find(id);
543 // If no entry is found for id
546 // Insert dummy pointer node
547 m_objects.insert(id, NULL);
549 n = m_objects.find(id);
550 // A new object will be created at this node
553 // If type_id differs
554 else if(n->getValue()->getTypeId() != type_id)
557 delete n->getValue();
558 // A new object will be created at this node
562 MapBlockObject *obj = NULL;
566 /*dstream<<"MapBlockObjectList adding new object"
570 if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
572 obj = new SignObject(m_block, id, pos);
574 else if(type_id == MAPBLOCKOBJECT_TYPE_RAT)
576 obj = new RatObject(m_block, id, pos);
578 else if(type_id == MAPBLOCKOBJECT_TYPE_ITEM)
580 obj = new ItemObject(m_block, id, pos);
584 // This is fatal because we cannot know the length
585 // of the object's data
586 throw SerializationError
587 ("MapBlockObjectList::update(): Unknown MapBlockObject type");
591 //obj->addToScene(smgr, daynight_ratio);
592 obj->addToScene(smgr);
600 /*if(daynight_ratio != m_last_update_daynight_ratio)
602 obj->removeFromScene();
603 obj->addToScene(smgr, daynight_ratio);
607 // Now there is an object in obj.
610 obj->update(is, version);
613 Update light on client
617 u8 light = LIGHT_MAX;
619 v3s16 relpos_i = floatToInt(obj->m_pos, BS);
620 MapNode n = m_block->getNodeParent(relpos_i);
621 light = n.getLightBlend(daynight_ratio);
623 catch(InvalidPositionException &e) {}
624 obj->updateLight(light);
627 // Remove from deletion list
628 if(ids_to_delete.find(id) != NULL)
629 ids_to_delete.remove(id);
632 // Delete all objects whose ids_to_delete remain in ids_to_delete
633 for(core::map<s16, bool>::Iterator
634 i = ids_to_delete.getIterator();
635 i.atEnd() == false; i++)
637 s16 id = i.getNode()->getKey();
639 /*dstream<<"MapBlockObjectList deleting object"
643 MapBlockObject *obj = m_objects[id];
644 obj->removeFromScene();
646 m_objects.remove(id);
649 m_last_update_daynight_ratio = daynight_ratio;
652 s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
657 if(m_objects.find(id) == NULL)
660 throw ContainerFullException
661 ("MapBlockObjectList doesn't fit more objects");
666 void MapBlockObjectList::add(MapBlockObject *object)
667 throw(ContainerFullException, AlreadyExistsException)
671 dstream<<"MapBlockObjectList::add(): NULL object"<<std::endl;
675 JMutexAutoLock lock(m_mutex);
677 // Create unique id if id==-1
678 if(object->m_id == -1)
680 object->m_id = getFreeId();
683 if(m_objects.find(object->m_id) != NULL)
685 dstream<<"MapBlockObjectList::add(): "
686 "object with same id already exists"<<std::endl;
687 throw AlreadyExistsException
688 ("MapBlockObjectList already has given id");
691 object->m_block = m_block;
693 /*v3f p = object->m_pos;
694 dstream<<"MapBlockObjectList::add(): "
695 <<"m_block->getPos()=("
696 <<m_block->getPos().X<<","
697 <<m_block->getPos().Y<<","
698 <<m_block->getPos().Z<<")"
699 <<" inserting object with id="<<object->m_id
701 <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
704 m_objects.insert(object->m_id, object);
707 void MapBlockObjectList::clear()
709 JMutexAutoLock lock(m_mutex);
711 for(core::map<s16, MapBlockObject*>::Iterator
712 i = m_objects.getIterator();
713 i.atEnd() == false; i++)
715 MapBlockObject *obj = i.getNode()->getValue();
716 //FIXME: This really shouldn't be NULL at any time,
717 // but this condition was added because it was.
720 obj->removeFromScene();
728 void MapBlockObjectList::remove(s16 id)
730 JMutexAutoLock lock(m_mutex);
732 core::map<s16, MapBlockObject*>::Node *n;
733 n = m_objects.find(id);
737 n->getValue()->removeFromScene();
738 delete n->getValue();
739 m_objects.remove(id);
742 MapBlockObject * MapBlockObjectList::get(s16 id)
744 core::map<s16, MapBlockObject*>::Node *n;
745 n = m_objects.find(id);
749 return n->getValue();
752 void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
754 DSTACK(__FUNCTION_NAME);
756 JMutexAutoLock lock(m_mutex);
758 core::map<s16, bool> ids_to_delete;
761 DSTACK("%s: stepping objects", __FUNCTION_NAME);
763 for(core::map<s16, MapBlockObject*>::Iterator
764 i = m_objects.getIterator();
765 i.atEnd() == false; i++)
767 MapBlockObject *obj = i.getNode()->getValue();
769 DSTACK("%s: stepping object type %i", __FUNCTION_NAME,
775 u8 light = LIGHT_MAX;
777 v3s16 relpos_i = floatToInt(obj->m_pos, BS);
778 MapNode n = m_block->getNodeParent(relpos_i);
779 light = n.getLightBlend(daynight_ratio);
781 catch(InvalidPositionException &e) {}
782 obj->updateLight(light);
784 bool to_delete = obj->serverStep(dtime, daynight_ratio);
787 ids_to_delete.insert(obj->m_id, true);
791 obj->clientStep(dtime);
797 DSTACK("%s: deleting objects", __FUNCTION_NAME);
799 // Delete objects in delete queue
800 for(core::map<s16, bool>::Iterator
801 i = ids_to_delete.getIterator();
802 i.atEnd() == false; i++)
804 s16 id = i.getNode()->getKey();
806 MapBlockObject *obj = m_objects[id];
807 obj->removeFromScene();
809 m_objects.remove(id);
814 Wrap objects on server
821 DSTACK("%s: object wrap loop", __FUNCTION_NAME);
823 for(core::map<s16, MapBlockObject*>::Iterator
824 i = m_objects.getIterator();
825 i.atEnd() == false; i++)
827 MapBlockObject *obj = i.getNode()->getValue();
829 v3s16 pos_i = floatToInt(obj->m_pos, BS);
831 if(m_block->isValidPosition(pos_i))
837 bool impossible = wrapObject(obj);
846 i = m_objects.getIterator();
851 bool MapBlockObjectList::wrapObject(MapBlockObject *object)
853 DSTACK(__FUNCTION_NAME);
855 // No lock here; this is called so that the lock is already locked.
856 //JMutexAutoLock lock(m_mutex);
858 assert(object->m_block == m_block);
859 assert(m_objects.find(object->m_id) != NULL);
860 assert(m_objects[object->m_id] == object);
862 NodeContainer *parentcontainer = m_block->getParent();
863 // This will only work if the parent is the map
864 if(parentcontainer->nodeContainerId() != NODECONTAINER_ID_MAP)
866 dstream<<"WARNING: Wrapping object not possible: "
867 "MapBlock's parent is not map"<<std::endl;
870 // OK, we have the map!
871 Map *map = (Map*)parentcontainer;
873 // Calculate blockpos on map
874 v3s16 oldblock_pos_i_on_map = m_block->getPosRelative();
875 v3f pos_f_on_oldblock = object->m_pos;
876 v3s16 pos_i_on_oldblock = floatToInt(pos_f_on_oldblock, BS);
877 v3s16 pos_i_on_map = pos_i_on_oldblock + oldblock_pos_i_on_map;
878 v3s16 pos_blocks_on_map = getNodeBlockPos(pos_i_on_map);
883 newblock = map->getBlockNoCreate(pos_blocks_on_map);
885 catch(InvalidPositionException &e)
887 // Couldn't find block -> not wrapping
888 /*dstream<<"WARNING: Wrapping object not possible: "
889 <<"could not find new block"
890 <<"("<<pos_blocks_on_map.X
891 <<","<<pos_blocks_on_map.Y
892 <<","<<pos_blocks_on_map.Z
894 /*dstream<<"pos_f_on_oldblock=("
895 <<pos_f_on_oldblock.X<<","
896 <<pos_f_on_oldblock.Y<<","
897 <<pos_f_on_oldblock.Z<<")"
902 if(newblock == m_block)
904 dstream<<"WARNING: Wrapping object not possible: "
905 "newblock == oldblock"<<std::endl;
909 // Calculate position on new block
910 v3f oldblock_pos_f_on_map = intToFloat(oldblock_pos_i_on_map, BS);
911 v3s16 newblock_pos_i_on_map = newblock->getPosRelative();
912 v3f newblock_pos_f_on_map = intToFloat(newblock_pos_i_on_map, BS);
913 v3f pos_f_on_newblock = pos_f_on_oldblock
914 - newblock_pos_f_on_map + oldblock_pos_f_on_map;
916 // Remove object from this block
917 m_objects.remove(object->m_id);
919 // Add object to new block
920 object->m_pos = pos_f_on_newblock;
922 object->m_block = NULL;
923 newblock->addObject(object);
925 //dstream<<"NOTE: Wrapped object"<<std::endl;
930 void MapBlockObjectList::getObjects(v3f origin, f32 max_d,
931 core::array<DistanceSortedObject> &dest)
933 for(core::map<s16, MapBlockObject*>::Iterator
934 i = m_objects.getIterator();
935 i.atEnd() == false; i++)
937 MapBlockObject *obj = i.getNode()->getValue();
939 f32 d = (obj->getRelativeShowPos() - origin).getLength();
944 DistanceSortedObject dso(obj, d);