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 #ifndef MAPBLOCKOBJECT_HEADER
23 #define MAPBLOCKOBJECT_HEADER
25 #include "common_irrlicht.h"
28 #include "serialization.h"
30 #include "constants.h"
33 #define MAPBLOCKOBJECT_TYPE_PLAYER 0
34 #define MAPBLOCKOBJECT_TYPE_SIGN 2
35 #define MAPBLOCKOBJECT_TYPE_RAT 3
36 #define MAPBLOCKOBJECT_TYPE_ITEM 4
37 // Used for handling selecting special stuff
38 //#define MAPBLOCKOBJECT_TYPE_PSEUDO 1000
45 MapBlockObject(MapBlock *block, s16 id, v3f pos):
46 m_collision_box(NULL),
47 m_selection_box(NULL),
53 virtual ~MapBlockObject()
66 // Writes id, pos and typeId
67 void serializeBase(std::ostream &os, u8 version)
73 os.write((char*)buf, 2);
76 // stored as x1000/BS v3s16
77 v3s16 pos_i(m_pos.X*1000/BS, m_pos.Y*1000/BS, m_pos.Z*1000/BS);
78 writeV3S16(buf, pos_i);
79 os.write((char*)buf, 6);
82 writeU16(buf, getTypeId());
83 os.write((char*)buf, 2);
86 // Position where the object is drawn relative to block
87 virtual v3f getRelativeShowPos()
91 // Get floating point position on map
94 void setBlockChanged();
96 // Shootline is relative to block
97 bool isSelected(core::line3d<f32> shootline)
99 if(m_selection_box == NULL)
102 core::aabbox3d<f32> offsetted_box(
103 m_selection_box->MinEdge + m_pos,
104 m_selection_box->MaxEdge + m_pos
107 return offsetted_box.intersectsWithLine(shootline);
110 core::aabbox3d<f32> getSelectionBoxOnMap()
112 v3f absolute_pos = getAbsolutePos();
114 core::aabbox3d<f32> box(
115 m_selection_box->MinEdge + absolute_pos,
116 m_selection_box->MaxEdge + absolute_pos
123 Implementation interface
126 virtual u16 getTypeId() const = 0;
127 // Shall call serializeBase and then write the parameters
128 virtual void serialize(std::ostream &os, u8 version) = 0;
129 // Shall read parameters from stream
130 virtual void update(std::istream &is, u8 version) = 0;
132 virtual std::string getInventoryString() { return "None"; }
134 // Reimplementation shall call this.
135 virtual void updatePos(v3f pos)
140 // Shall move the object around, modify it and possibly delete it.
141 // Typical dtimes are 0.2 and 10000.
142 // A return value of true requests deletion of the object by the caller.
143 // NOTE: Only server calls this.
144 virtual bool serverStep(float dtime, u32 daynight_ratio)
148 void clientStep(float dtime) {};
149 void addToScene(void *smgr) {};
150 void removeFromScene() {};
151 void updateLight(u8 light_at_pos) {};
153 // This should do slight animations only or so
154 virtual void clientStep(float dtime) {};
156 // NOTE: These functions should do nothing if the asked state is
157 // same as the current state
158 // Shall add and remove relevant scene nodes for rendering the
159 // object in the game world
160 virtual void addToScene(scene::ISceneManager *smgr) = 0;
161 // Shall remove stuff from the scene
162 // Should return silently if there is nothing to remove
163 // NOTE: This has to be called before calling destructor
164 virtual void removeFromScene() = 0;
166 // 0 <= light_at_pos <= LIGHT_SUN
167 virtual void updateLight(u8 light_at_pos) {};
170 virtual std::string infoText() { return ""; }
172 // Shall be left NULL if doesn't collide
173 // Position is relative to m_pos in block
174 core::aabbox3d<f32> * m_collision_box;
176 // Shall be left NULL if can't be selected
177 core::aabbox3d<f32> * m_selection_box;
181 // This differentiates the instance of the object
182 // Not same as typeId.
184 // Position of the object inside the block
185 // Units is node coordinates * BS
188 friend class MapBlockObjectList;
193 Used for handling selections of special stuff
195 class PseudoMBObject : public MapBlockObject
198 // The constructor of every MapBlockObject should be like this
199 PseudoMBObject(MapBlock *block, s16 id, v3f pos):
200 MapBlockObject(block, id, pos)
203 virtual ~PseudoMBObject()
206 delete m_selection_box;
210 Implementation interface
212 virtual u16 getTypeId() const
214 return MAPBLOCKOBJECT_TYPE_PSEUDO;
216 virtual void serialize(std::ostream &os, u8 version)
220 virtual void update(std::istream &is, u8 version)
224 virtual bool serverStep(float dtime, u32 daynight_ratio)
233 void setSelectionBox(core::aabbox3d<f32> box)
235 m_selection_box = new core::aabbox3d<f32>(box);
242 class MovingObject : public MapBlockObject
245 // The constructor of every MapBlockObject should be like this
246 MovingObject(MapBlock *block, s16 id, v3f pos):
247 MapBlockObject(block, id, pos),
250 m_pos_animation_time(0),
253 m_touching_ground = false;
255 virtual ~MovingObject()
260 Implementation interface
263 virtual u16 getTypeId() const = 0;
265 virtual void serialize(std::ostream &os, u8 version)
267 serializeBase(os, version);
272 // stored as x100/BS v3s16
273 v3s16 speed_i(m_speed.X*100/BS, m_speed.Y*100/BS, m_speed.Z*100/BS);
274 writeV3S16(buf, speed_i);
275 os.write((char*)buf, 6);
277 virtual void update(std::istream &is, u8 version)
282 // stored as x100/BS v3s16
283 is.read((char*)buf, 6);
284 v3s16 speed_i = readV3S16(buf);
285 v3f speed((f32)speed_i.X/100*BS,
286 (f32)speed_i.Y/100*BS,
287 (f32)speed_i.Z/100*BS);
292 // Reimplementation shall call this.
293 virtual void updatePos(v3f pos)
295 m_oldpos = m_showpos;
298 if(m_pos_animation_time < 0.001 || m_pos_animation_time > 1.0)
299 m_pos_animation_time = m_pos_animation_time_counter;
301 m_pos_animation_time = m_pos_animation_time * 0.9
302 + m_pos_animation_time_counter * 0.1;
303 m_pos_animation_time_counter = 0;
304 m_pos_animation_counter = 0;
307 // Position where the object is drawn relative to block
308 virtual v3f getRelativeShowPos()
312 // Returns m_showpos relative to whole map
313 v3f getAbsoluteShowPos();
315 virtual bool serverStep(float dtime, u32 daynight_ratio)
317 virtual void clientStep(float dtime)
320 /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
321 virtual void removeFromScene() = 0;*/
327 // Move with collision detection, server side
328 void move(float dtime, v3f acceleration);
330 // Move from old position to new position, client side
331 void simpleMove(float dtime);
335 bool m_touching_ground;
336 // Client-side moving
338 f32 m_pos_animation_counter;
339 f32 m_pos_animation_time;
340 f32 m_pos_animation_time_counter;
344 class SignObject : public MapBlockObject
347 // The constructor of every MapBlockObject should be like this
348 SignObject(MapBlock *block, s16 id, v3f pos):
349 MapBlockObject(block, id, pos),
352 m_selection_box = new core::aabbox3d<f32>
353 (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);
355 virtual ~SignObject()
357 delete m_selection_box;
361 Implementation interface
363 virtual u16 getTypeId() const
365 return MAPBLOCKOBJECT_TYPE_SIGN;
367 virtual void serialize(std::ostream &os, u8 version)
369 serializeBase(os, version);
373 writeS16(buf, m_yaw * 10);
374 os.write((char*)buf, 2);
377 writeU16(buf, m_text.size());
378 os.write((char*)buf, 2);
381 os.write(m_text.c_str(), m_text.size());
383 virtual void update(std::istream &is, u8 version)
388 is.read((char*)buf, 2);
389 s16 yaw_i = readS16(buf);
390 m_yaw = (f32)yaw_i / 10;
393 is.read((char*)buf, 2);
394 u16 size = readU16(buf);
398 for(u16 i=0; i<size; i++)
400 is.read((char*)buf, 1);
406 virtual bool serverStep(float dtime, u32 daynight_ratio)
411 virtual void addToScene(scene::ISceneManager *smgr)
416 video::IVideoDriver* driver = smgr->getVideoDriver();
418 scene::SMesh *mesh = new scene::SMesh();
420 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
421 video::SColor c(255,255,255,255);
422 video::S3DVertex vertices[4] =
424 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
425 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
426 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
427 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),
429 u16 indices[] = {0,1,2,2,3,0};
430 buf->append(vertices, 4, indices, 6);
432 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
433 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
434 buf->getMaterial().setTexture
435 (0, driver->getTexture(getTexturePath("sign.png").c_str()));
436 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
437 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
438 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
440 mesh->addMeshBuffer(buf);
444 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
445 video::SColor c(255,255,255,255);
446 video::S3DVertex vertices[4] =
448 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
449 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
450 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
451 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
453 u16 indices[] = {0,1,2,2,3,0};
454 buf->append(vertices, 4, indices, 6);
456 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
457 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
458 buf->getMaterial().setTexture
459 (0, driver->getTexture(getTexturePath("sign_back.png").c_str()));
460 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
461 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
462 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
464 mesh->addMeshBuffer(buf);
467 m_node = smgr->addMeshSceneNode(mesh, NULL);
472 virtual void removeFromScene()
480 virtual void updateLight(u8 light_at_pos)
485 u8 li = decode_light(light_at_pos);
486 video::SColor color(255,li,li,li);
488 scene::IMesh *mesh = m_node->getMesh();
490 u16 mc = mesh->getMeshBufferCount();
491 for(u16 j=0; j<mc; j++)
493 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
494 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
495 u16 vc = buf->getVertexCount();
496 for(u16 i=0; i<vc; i++)
498 vertices[i].Color = color;
504 virtual std::string infoText()
506 return std::string("\"") + m_text + "\"";
509 virtual std::string getInventoryString()
511 return std::string("Sign ")+m_text;
517 void updateSceneNode()
522 m_node->setPosition(getAbsolutePos());
523 m_node->setRotation(v3f(0, m_yaw, 0));
528 void setText(std::string text)
530 if(text.size() > SIGN_TEXT_MAX_LENGTH)
531 text = text.substr(0, SIGN_TEXT_MAX_LENGTH);
537 std::string getText()
550 scene::IMeshSceneNode *m_node;
555 class RatObject : public MovingObject
558 RatObject(MapBlock *block, s16 id, v3f pos):
559 MovingObject(block, id, pos),
562 m_collision_box = new core::aabbox3d<f32>
563 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
564 m_selection_box = new core::aabbox3d<f32>
565 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
574 delete m_collision_box;
575 delete m_selection_box;
579 Implementation interface
581 virtual u16 getTypeId() const
583 return MAPBLOCKOBJECT_TYPE_RAT;
585 virtual void serialize(std::ostream &os, u8 version)
587 MovingObject::serialize(os, version);
591 writeS16(buf, m_yaw * 10);
592 os.write((char*)buf, 2);
595 virtual void update(std::istream &is, u8 version)
597 MovingObject::update(is, version);
601 is.read((char*)buf, 2);
602 s16 yaw_i = readS16(buf);
603 m_yaw = (f32)yaw_i / 10;
608 virtual bool serverStep(float dtime, u32 daynight_ratio)
615 v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
619 m_speed.X = speed * dir.X;
620 m_speed.Z = speed * dir.Z;
622 if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
636 m_counter2 += (float)(myrand()%100)/100*3.0;
637 m_yaw += ((float)(myrand()%200)-100)/100*180;
638 m_yaw = wrapDegrees(m_yaw);
646 move(dtime, v3f(0, -9.81*BS, 0));
653 virtual void clientStep(float dtime)
655 //m_pos += m_speed * dtime;
656 MovingObject::simpleMove(dtime);
661 virtual void addToScene(scene::ISceneManager *smgr);
663 virtual void removeFromScene()
672 virtual void updateLight(u8 light_at_pos)
677 u8 li = decode_light(light_at_pos);
678 video::SColor color(255,li,li,li);
680 scene::IMesh *mesh = m_node->getMesh();
682 u16 mc = mesh->getMeshBufferCount();
683 for(u16 j=0; j<mc; j++)
685 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
686 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
687 u16 vc = buf->getVertexCount();
688 for(u16 i=0; i<vc; i++)
690 vertices[i].Color = color;
697 virtual std::string getInventoryString()
699 // There must be a space after the name
701 return std::string("Rat ");
713 m_node->setPosition(getAbsoluteShowPos());
714 m_node->setRotation(v3f(0, -m_yaw+180, 0));
718 scene::IMeshSceneNode *m_node;
727 An object on the map that represents an inventory item
732 class ItemObject : public MapBlockObject
735 // The constructor of every MapBlockObject should be like this
736 ItemObject(MapBlock *block, s16 id, v3f pos):
737 MapBlockObject(block, id, pos),
740 /*m_selection_box = new core::aabbox3d<f32>
741 (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);*/
742 m_selection_box = new core::aabbox3d<f32>
743 (-BS/3,-BS/2,-BS/3, BS/3,-BS/2+BS*2/3,BS/3);
746 virtual ~ItemObject()
748 delete m_selection_box;
752 Implementation interface
754 virtual u16 getTypeId() const
756 return MAPBLOCKOBJECT_TYPE_ITEM;
758 virtual void serialize(std::ostream &os, u8 version)
760 serializeBase(os, version);
764 writeU16(buf, m_itemstring.size());
765 os.write((char*)buf, 2);
768 os.write(m_itemstring.c_str(), m_itemstring.size());
770 virtual void update(std::istream &is, u8 version)
775 is.read((char*)buf, 2);
776 u16 size = readU16(buf);
779 std::string old_itemstring = m_itemstring;
780 m_itemstring.clear();
781 for(u16 i=0; i<size; i++)
783 is.read((char*)buf, 1);
784 m_itemstring += buf[0];
788 if(m_itemstring != old_itemstring && m_node)
793 video::ITexture *texture = getItemImage();
794 scene::IMesh *mesh = m_node->getMesh();
795 if(mesh->getMeshBufferCount() >= 1)
797 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
798 //dstream<<"Setting texture "<<texture<<std::endl;
799 buf->getMaterial().setTexture(0, texture);
807 virtual bool serverStep(float dtime, u32 daynight_ratio)
813 virtual void clientStep(float dtime)
822 virtual void addToScene(scene::ISceneManager *smgr);
824 virtual void removeFromScene()
832 virtual void updateLight(u8 light_at_pos)
837 u8 li = decode_light(light_at_pos);
838 video::SColor color(255,li,li,li);
840 scene::IMesh *mesh = m_node->getMesh();
842 u16 mc = mesh->getMeshBufferCount();
843 for(u16 j=0; j<mc; j++)
845 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
846 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
847 u16 vc = buf->getVertexCount();
848 for(u16 i=0; i<vc; i++)
850 vertices[i].Color = color;
856 virtual std::string infoText()
858 return std::string("\"") + m_itemstring + "\"";
861 virtual std::string getInventoryString()
863 return std::string("ItemObj ")+m_itemstring;
870 InventoryItem * createInventoryItem();
873 video::ITexture * getItemImage();
875 void updateSceneNode()
879 m_node->setPosition(getAbsolutePos());
880 m_node->setRotation(v3f(0, m_yaw, 0));
885 void setItemString(std::string inventorystring)
887 m_itemstring = inventorystring;
891 std::string getItemString()
897 scene::IMeshSceneNode *m_node;
898 std::string m_itemstring;
905 class PlayerObject : public MovingObject
908 PlayerObject(MapBlock *block, s16 id, v3f pos):
909 MovingObject(block, id, pos),
913 m_collision_box = new core::aabbox3d<f32>
914 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
915 /*m_selection_box = new core::aabbox3d<f32>
916 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);*/
918 virtual ~PlayerObject()
921 delete m_collision_box;
923 delete m_selection_box;
927 Implementation interface
929 virtual u16 getTypeId() const
931 return MAPBLOCKOBJECT_TYPE_PLAYER;
933 virtual void serialize(std::ostream &os, u8 version)
935 // Object data is generated from actual player
937 virtual void update(std::istream &is, u8 version)
939 MovingObject::update(is, version);
943 is.read((char*)buf, 2);
944 s16 yaw_i = readS16(buf);
945 m_yaw = (f32)yaw_i / 10;
950 virtual bool serverStep(float dtime, u32 daynight_ratio)
952 // Player is handled elsewhere.
955 // Actually, fail very loudly:
960 virtual void clientStep(float dtime)
962 MovingObject::simpleMove(dtime);
967 virtual void addToScene(scene::ISceneManager *smgr);
969 virtual void removeFromScene()
978 virtual void updateLight(u8 light_at_pos)
983 u8 li = decode_light(light_at_pos);
984 video::SColor color(255,li,li,li);
986 scene::IMesh *mesh = m_node->getMesh();
988 u16 mc = mesh->getMeshBufferCount();
989 for(u16 j=0; j<mc; j++)
991 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
992 video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
993 u16 vc = buf->getVertexCount();
994 for(u16 i=0; i<vc; i++)
996 vertices[i].Color = color;
1007 void updateNodePos()
1012 m_node->setPosition(getAbsoluteShowPos());
1013 m_node->setRotation(v3f(0, -m_yaw+180, 0));
1017 scene::IMeshSceneNode *m_node;
1023 struct DistanceSortedObject
1025 DistanceSortedObject(MapBlockObject *a_obj, f32 a_d)
1031 MapBlockObject *obj;
1034 bool operator < (DistanceSortedObject &other)
1040 class MapBlockObjectList
1043 MapBlockObjectList(MapBlock *block);
1044 ~MapBlockObjectList();
1046 // Writes the count, id, the type id and the parameters of all objects
1047 void serialize(std::ostream &os, u8 version);
1049 // Reads ids, type_ids and parameters.
1050 // Creates, updates and deletes objects.
1051 // If smgr!=NULL, new objects are added to the scene
1052 void update(std::istream &is, u8 version, scene::ISceneManager *smgr,
1053 u32 daynight_ratio);
1055 // Finds a new unique id
1056 s16 getFreeId() throw(ContainerFullException);
1059 Set id to -1 to have this set it to a suitable one.
1060 The block pointer member is set to this block.
1062 void add(MapBlockObject *object)
1063 throw(ContainerFullException, AlreadyExistsException);
1065 // Deletes and removes all objects
1070 Ignores inexistent objects
1072 void remove(s16 id);
1074 References an object.
1075 The object will not be valid after step() or of course if
1077 Grabbing the lock is recommended while processing.
1079 MapBlockObject * get(s16 id);
1081 // You'll want to grab this in a SharedPtr
1082 JMutexAutoLock * getLock()
1084 return new JMutexAutoLock(m_mutex);
1087 // Steps all objects and if server==true, removes those that
1088 // want to be removed
1089 void step(float dtime, bool server, u32 daynight_ratio);
1091 // Wraps an object that wants to move onto this block from an another
1092 // Returns true if wrapping was impossible
1093 bool wrapObject(MapBlockObject *object);
1095 // origin is relative to block
1096 void getObjects(v3f origin, f32 max_d,
1097 core::array<DistanceSortedObject> &dest);
1099 // Number of objects
1102 return m_objects.size();
1108 core::map<s16, MapBlockObject*> m_objects;
1111 u32 m_last_update_daynight_ratio;