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)
354 m_selection_box = new core::aabbox3d<f32>
355 (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);
357 virtual ~SignObject()
359 delete m_selection_box;
363 Implementation interface
365 virtual u16 getTypeId() const
367 return MAPBLOCKOBJECT_TYPE_SIGN;
369 virtual void serialize(std::ostream &os, u8 version)
371 serializeBase(os, version);
375 writeS16(buf, m_yaw * 10);
376 os.write((char*)buf, 2);
379 writeU16(buf, m_text.size());
380 os.write((char*)buf, 2);
383 os.write(m_text.c_str(), m_text.size());
385 virtual void update(std::istream &is, u8 version)
390 is.read((char*)buf, 2);
391 s16 yaw_i = readS16(buf);
392 m_yaw = (f32)yaw_i / 10;
395 is.read((char*)buf, 2);
396 u16 size = readU16(buf);
400 for(u16 i=0; i<size; i++)
402 is.read((char*)buf, 1);
408 virtual bool serverStep(float dtime, u32 daynight_ratio)
413 virtual void addToScene(scene::ISceneManager *smgr)
418 video::IVideoDriver* driver = smgr->getVideoDriver();
420 scene::SMesh *mesh = new scene::SMesh();
422 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
423 video::SColor c(255,255,255,255);
424 video::S3DVertex vertices[4] =
426 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
427 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
428 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
429 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),
431 u16 indices[] = {0,1,2,2,3,0};
432 buf->append(vertices, 4, indices, 6);
434 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
435 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
436 buf->getMaterial().setTexture
437 (0, driver->getTexture(getTexturePath("sign.png").c_str()));
438 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
439 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
440 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
442 mesh->addMeshBuffer(buf);
446 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
447 video::SColor c(255,255,255,255);
448 video::S3DVertex vertices[4] =
450 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
451 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
452 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
453 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
455 u16 indices[] = {0,1,2,2,3,0};
456 buf->append(vertices, 4, indices, 6);
458 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
459 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
460 buf->getMaterial().setTexture
461 (0, driver->getTexture(getTexturePath("sign_back.png").c_str()));
462 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
463 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
464 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
466 mesh->addMeshBuffer(buf);
469 m_node = smgr->addMeshSceneNode(mesh, NULL);
474 virtual void removeFromScene()
482 virtual void updateLight(u8 light_at_pos)
487 u8 li = decode_light(light_at_pos);
488 video::SColor color(255,li,li,li);
489 setMeshVerticesColor(m_node->getMesh(), color);
493 virtual std::string infoText()
495 return std::string("\"") + m_text + "\"";
498 virtual std::string getInventoryString()
500 return std::string("Sign ")+m_text;
506 void updateSceneNode()
511 m_node->setPosition(getAbsolutePos());
512 m_node->setRotation(v3f(0, m_yaw, 0));
517 void setText(std::string text)
519 if(text.size() > SIGN_TEXT_MAX_LENGTH)
520 text = text.substr(0, SIGN_TEXT_MAX_LENGTH);
526 std::string getText()
540 scene::IMeshSceneNode *m_node;
546 class RatObject : public MovingObject
549 RatObject(MapBlock *block, s16 id, v3f pos):
550 MovingObject(block, id, pos)
555 m_collision_box = new core::aabbox3d<f32>
556 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
557 m_selection_box = new core::aabbox3d<f32>
558 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
567 delete m_collision_box;
568 delete m_selection_box;
572 Implementation interface
574 virtual u16 getTypeId() const
576 return MAPBLOCKOBJECT_TYPE_RAT;
578 virtual void serialize(std::ostream &os, u8 version)
580 MovingObject::serialize(os, version);
584 writeS16(buf, m_yaw * 10);
585 os.write((char*)buf, 2);
588 virtual void update(std::istream &is, u8 version)
590 MovingObject::update(is, version);
594 is.read((char*)buf, 2);
595 s16 yaw_i = readS16(buf);
596 m_yaw = (f32)yaw_i / 10;
601 virtual bool serverStep(float dtime, u32 daynight_ratio)
608 v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
612 m_speed.X = speed * dir.X;
613 m_speed.Z = speed * dir.Z;
615 if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
629 m_counter2 += (float)(myrand()%100)/100*3.0;
630 m_yaw += ((float)(myrand()%200)-100)/100*180;
631 m_yaw = wrapDegrees(m_yaw);
639 move(dtime, v3f(0, -9.81*BS, 0));
646 virtual void clientStep(float dtime)
648 //m_pos += m_speed * dtime;
649 MovingObject::simpleMove(dtime);
654 virtual void addToScene(scene::ISceneManager *smgr);
656 virtual void removeFromScene()
665 virtual void updateLight(u8 light_at_pos)
670 u8 li = decode_light(light_at_pos);
671 video::SColor color(255,li,li,li);
672 setMeshVerticesColor(m_node->getMesh(), color);
677 virtual std::string getInventoryString()
679 // There must be a space after the name
681 return std::string("Rat ");
694 m_node->setPosition(getAbsoluteShowPos());
695 m_node->setRotation(v3f(0, -m_yaw+180, 0));
701 scene::IMeshSceneNode *m_node;
711 An object on the map that represents an inventory item
716 class ItemObject : public MapBlockObject
719 // The constructor of every MapBlockObject should be like this
720 ItemObject(MapBlock *block, s16 id, v3f pos):
721 MapBlockObject(block, id, pos)
726 /*m_selection_box = new core::aabbox3d<f32>
727 (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);*/
728 m_selection_box = new core::aabbox3d<f32>
729 (-BS/3,-BS/2,-BS/3, BS/3,-BS/2+BS*2/3,BS/3);
732 virtual ~ItemObject()
734 delete m_selection_box;
738 Implementation interface
740 virtual u16 getTypeId() const
742 return MAPBLOCKOBJECT_TYPE_ITEM;
744 virtual void serialize(std::ostream &os, u8 version)
746 serializeBase(os, version);
750 writeU16(buf, m_itemstring.size());
751 os.write((char*)buf, 2);
754 os.write(m_itemstring.c_str(), m_itemstring.size());
756 virtual void update(std::istream &is, u8 version)
761 is.read((char*)buf, 2);
762 u16 size = readU16(buf);
765 std::string old_itemstring = m_itemstring;
766 m_itemstring.clear();
767 for(u16 i=0; i<size; i++)
769 is.read((char*)buf, 1);
770 m_itemstring += buf[0];
774 if(m_itemstring != old_itemstring && m_node)
779 video::ITexture *texture = getItemImage();
780 scene::IMesh *mesh = m_node->getMesh();
781 if(mesh->getMeshBufferCount() >= 1)
783 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
784 //dstream<<"Setting texture "<<texture<<std::endl;
785 buf->getMaterial().setTexture(0, texture);
793 virtual bool serverStep(float dtime, u32 daynight_ratio)
799 virtual void clientStep(float dtime)
808 virtual void addToScene(scene::ISceneManager *smgr);
810 virtual void removeFromScene()
818 virtual void updateLight(u8 light_at_pos)
823 u8 li = decode_light(light_at_pos);
824 video::SColor color(255,li,li,li);
825 setMeshVerticesColor(m_node->getMesh(), color);
829 virtual std::string infoText()
831 return std::string("\"") + m_itemstring + "\"";
834 virtual std::string getInventoryString()
836 return std::string("ItemObj ")+m_itemstring;
843 InventoryItem * createInventoryItem();
846 video::ITexture * getItemImage();
848 void updateSceneNode()
852 m_node->setPosition(getAbsolutePos());
853 m_node->setRotation(v3f(0, m_yaw, 0));
858 void setItemString(std::string inventorystring)
860 m_itemstring = inventorystring;
864 std::string getItemString()
871 scene::IMeshSceneNode *m_node;
873 std::string m_itemstring;
880 class PlayerObject : public MovingObject
883 PlayerObject(MapBlock *block, s16 id, v3f pos):
884 MovingObject(block, id, pos),
890 m_collision_box = new core::aabbox3d<f32>
891 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
892 /*m_selection_box = new core::aabbox3d<f32>
893 (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);*/
895 virtual ~PlayerObject()
898 delete m_collision_box;
900 delete m_selection_box;
904 Implementation interface
906 virtual u16 getTypeId() const
908 return MAPBLOCKOBJECT_TYPE_PLAYER;
910 virtual void serialize(std::ostream &os, u8 version)
912 // Object data is generated from actual player
914 virtual void update(std::istream &is, u8 version)
916 MovingObject::update(is, version);
920 is.read((char*)buf, 2);
921 s16 yaw_i = readS16(buf);
922 m_yaw = (f32)yaw_i / 10;
927 virtual bool serverStep(float dtime, u32 daynight_ratio)
929 // Player is handled elsewhere.
932 // Actually, fail very loudly:
937 virtual void clientStep(float dtime)
939 MovingObject::simpleMove(dtime);
944 virtual void addToScene(scene::ISceneManager *smgr);
946 virtual void removeFromScene()
955 virtual void updateLight(u8 light_at_pos)
960 u8 li = decode_light(light_at_pos);
961 video::SColor color(255,li,li,li);
962 setMeshVerticesColor(m_node->getMesh(), color);
977 m_node->setPosition(getAbsoluteShowPos());
978 m_node->setRotation(v3f(0, -m_yaw+180, 0));
984 scene::IMeshSceneNode *m_node;
991 struct DistanceSortedObject
993 DistanceSortedObject(MapBlockObject *a_obj, f32 a_d)
1002 bool operator < (DistanceSortedObject &other)
1010 class ISceneManager;
1013 using namespace irr;
1015 class MapBlockObjectList
1018 MapBlockObjectList(MapBlock *block);
1019 ~MapBlockObjectList();
1021 // Writes the count, id, the type id and the parameters of all objects
1022 void serialize(std::ostream &os, u8 version);
1024 // Reads ids, type_ids and parameters.
1025 // Creates, updates and deletes objects.
1026 // If smgr!=NULL, new objects are added to the scene
1027 void update(std::istream &is, u8 version, scene::ISceneManager *smgr,
1028 u32 daynight_ratio);
1030 // Finds a new unique id
1031 s16 getFreeId() throw(ContainerFullException);
1034 Set id to -1 to have this set it to a suitable one.
1035 The block pointer member is set to this block.
1037 void add(MapBlockObject *object)
1038 throw(ContainerFullException, AlreadyExistsException);
1040 // Deletes and removes all objects
1045 Ignores inexistent objects
1047 void remove(s16 id);
1049 References an object.
1050 The object will not be valid after step() or of course if
1052 Grabbing the lock is recommended while processing.
1054 MapBlockObject * get(s16 id);
1056 // You'll want to grab this in a SharedPtr
1057 JMutexAutoLock * getLock()
1059 return new JMutexAutoLock(m_mutex);
1062 // Steps all objects and if server==true, removes those that
1063 // want to be removed
1064 void step(float dtime, bool server, u32 daynight_ratio);
1066 // Wraps an object that wants to move onto this block from an another
1067 // Returns true if wrapping was impossible
1068 bool wrapObject(MapBlockObject *object);
1070 // origin is relative to block
1071 void getObjects(v3f origin, f32 max_d,
1072 core::array<DistanceSortedObject> &dest);
1074 // Number of objects
1077 return m_objects.size();
1083 core::map<s16, MapBlockObject*> m_objects;
1086 u32 m_last_update_daynight_ratio;