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 #ifndef MAPBLOCKOBJECT_HEADER
21 #define MAPBLOCKOBJECT_HEADER
23 #include "common_irrlicht.h"
26 #include "serialization.h"
28 #include "constants.h"
31 #define MAPBLOCKOBJECT_TYPE_TEST 0
32 #define MAPBLOCKOBJECT_TYPE_TEST2 1
33 #define MAPBLOCKOBJECT_TYPE_SIGN 2
34 #define MAPBLOCKOBJECT_TYPE_RAT 3
35 // Used for handling selecting special stuff
36 //#define MAPBLOCKOBJECT_TYPE_PSEUDO 4
43 MapBlockObject(MapBlock *block, s16 id, v3f pos):
44 m_collision_box(NULL),
45 m_selection_box(NULL),
51 virtual ~MapBlockObject()
64 // Writes id, pos and typeId
65 void serializeBase(std::ostream &os, u8 version)
71 os.write((char*)buf, 2);
74 // stored as x1000/BS v3s16
75 v3s16 pos_i(m_pos.X*1000/BS, m_pos.Y*1000/BS, m_pos.Z*1000/BS);
76 writeV3S16(buf, pos_i);
77 os.write((char*)buf, 6);
80 writeU16(buf, getTypeId());
81 os.write((char*)buf, 2);
84 // Get floating point position on map
87 void setBlockChanged();
89 // Shootline is relative to block
90 bool isSelected(core::line3d<f32> shootline)
92 if(m_selection_box == NULL)
95 core::aabbox3d<f32> offsetted_box(
96 m_selection_box->MinEdge + m_pos,
97 m_selection_box->MaxEdge + m_pos
100 return offsetted_box.intersectsWithLine(shootline);
103 core::aabbox3d<f32> getSelectionBoxOnMap()
105 v3f absolute_pos = getAbsolutePos();
107 core::aabbox3d<f32> box(
108 m_selection_box->MinEdge + absolute_pos,
109 m_selection_box->MaxEdge + absolute_pos
116 Implementation interface
119 virtual u16 getTypeId() const = 0;
120 // Shall call serializeBase and then write the parameters
121 virtual void serialize(std::ostream &os, u8 version) = 0;
122 // Shall read parameters from stream
123 virtual void update(std::istream &is, u8 version) = 0;
125 virtual std::string getInventoryString() { return "None"; }
127 // Reimplementation shall call this.
128 virtual void updatePos(v3f pos)
133 // Shall move the object around, modify it and possibly delete it.
134 // Typical dtimes are 0.2 and 10000.
135 // A return value of true requests deletion of the object by the caller.
136 // NOTE: Only server calls this.
137 virtual bool serverStep(float dtime) { return false; };
138 // This should do slight animations only or so
139 virtual void clientStep(float dtime) {};
141 // NOTE: These functions should do nothing if the asked state is
142 // same as the current state
143 // Shall add and remove relevant scene nodes for rendering the
144 // object in the game world
145 virtual void addToScene(scene::ISceneManager *smgr) {};
146 // Shall remove stuff from the scene
147 // Should return silently if there is nothing to remove
148 // NOTE: This has to be called before calling destructor
149 virtual void removeFromScene() {};
151 virtual std::string infoText() { return ""; }
153 // Shall be left NULL if doesn't collide
154 // Position is relative to m_pos in block
155 core::aabbox3d<f32> * m_collision_box;
157 // Shall be left NULL if can't be selected
158 core::aabbox3d<f32> * m_selection_box;
162 // This differentiates the instance of the object
163 // Not same as typeId.
165 // Position of the object inside the block
166 // Units is node coordinates * BS
169 friend class MapBlockObjectList;
174 Used for handling selections of special stuff
176 class PseudoMBObject : public MapBlockObject
179 // The constructor of every MapBlockObject should be like this
180 PseudoMBObject(MapBlock *block, s16 id, v3f pos):
181 MapBlockObject(block, id, pos)
184 virtual ~PseudoMBObject()
187 delete m_selection_box;
191 Implementation interface
193 virtual u16 getTypeId() const
195 return MAPBLOCKOBJECT_TYPE_PSEUDO;
197 virtual void serialize(std::ostream &os, u8 version)
201 virtual void update(std::istream &is, u8 version)
205 virtual bool serverStep(float dtime)
214 void setSelectionBox(core::aabbox3d<f32> box)
216 m_selection_box = new core::aabbox3d<f32>(box);
223 class MovingObject : public MapBlockObject
226 // The constructor of every MapBlockObject should be like this
227 MovingObject(MapBlock *block, s16 id, v3f pos):
228 MapBlockObject(block, id, pos),
231 m_touching_ground = false;
233 virtual ~MovingObject()
238 Implementation interface
241 virtual u16 getTypeId() const = 0;
243 virtual void serialize(std::ostream &os, u8 version)
245 serializeBase(os, version);
250 // stored as x100/BS v3s16
251 v3s16 speed_i(m_speed.X*100/BS, m_speed.Y*100/BS, m_speed.Z*100/BS);
252 writeV3S16(buf, speed_i);
253 os.write((char*)buf, 6);
255 virtual void update(std::istream &is, u8 version)
260 // stored as x100/BS v3s16
261 is.read((char*)buf, 6);
262 v3s16 speed_i = readV3S16(buf);
263 v3f speed((f32)speed_i.X/100*BS,
264 (f32)speed_i.Y/100*BS,
265 (f32)speed_i.Z/100*BS);
270 virtual bool serverStep(float dtime) { return false; };
271 virtual void clientStep(float dtime) {};
273 virtual void addToScene(scene::ISceneManager *smgr) = 0;
274 virtual void removeFromScene() = 0;
280 // Moves with collision detection
281 void move(float dtime, v3f acceleration);
285 bool m_touching_ground;
288 class RatObject : public MovingObject
291 RatObject(MapBlock *block, s16 id, v3f pos):
292 MovingObject(block, id, pos),
295 m_collision_box = new core::aabbox3d<f32>
296 (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3);
297 m_selection_box = new core::aabbox3d<f32>
298 (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3);
305 delete m_collision_box;
306 delete m_selection_box;
310 Implementation interface
312 virtual u16 getTypeId() const
314 return MAPBLOCKOBJECT_TYPE_RAT;
316 virtual void serialize(std::ostream &os, u8 version)
318 MovingObject::serialize(os, version);
322 writeS16(buf, m_yaw * 10);
323 os.write((char*)buf, 2);
326 virtual void update(std::istream &is, u8 version)
328 MovingObject::update(is, version);
332 is.read((char*)buf, 2);
333 s16 yaw_i = readS16(buf);
334 m_yaw = (f32)yaw_i / 10;
339 virtual bool serverStep(float dtime)
341 v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
345 m_speed.X = speed * dir.X;
346 m_speed.Z = speed * dir.Z;
348 if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
362 m_counter2 += (float)(rand()%100)/100*3.0;
363 m_yaw += ((float)(rand()%200)-100)/100*180;
364 m_yaw = wrapDegrees(m_yaw);
372 move(dtime, v3f(0, -9.81*BS, 0));
379 virtual void clientStep(float dtime)
381 m_pos += m_speed * dtime;
386 virtual void addToScene(scene::ISceneManager *smgr)
391 video::IVideoDriver* driver = smgr->getVideoDriver();
393 scene::SMesh *mesh = new scene::SMesh();
394 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
395 video::SColor c(255,255,255,255);
396 video::S3DVertex vertices[4] =
398 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
399 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
400 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
401 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
403 u16 indices[] = {0,1,2,2,3,0};
404 buf->append(vertices, 4, indices, 6);
406 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
407 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
408 buf->getMaterial().setTexture
409 (0, driver->getTexture("../data/rat.png"));
410 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
411 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
413 mesh->addMeshBuffer(buf);
415 m_node = smgr->addMeshSceneNode(mesh, NULL);
417 m_node->setPosition(getAbsolutePos());
419 virtual void removeFromScene()
428 virtual std::string getInventoryString()
430 // There must be a space after the name
432 return std::string("Rat ");
443 m_node->setPosition(getAbsolutePos());
444 m_node->setRotation(v3f(0, -m_yaw+180, 0));
449 scene::IMeshSceneNode *m_node;
457 class SignObject : public MapBlockObject
460 // The constructor of every MapBlockObject should be like this
461 SignObject(MapBlock *block, s16 id, v3f pos):
462 MapBlockObject(block, id, pos),
465 m_selection_box = new core::aabbox3d<f32>
466 (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);
468 virtual ~SignObject()
470 delete m_selection_box;
474 Implementation interface
476 virtual u16 getTypeId() const
478 return MAPBLOCKOBJECT_TYPE_SIGN;
480 virtual void serialize(std::ostream &os, u8 version)
482 serializeBase(os, version);
486 writeS16(buf, m_yaw * 10);
487 os.write((char*)buf, 2);
490 writeU16(buf, m_text.size());
491 os.write((char*)buf, 2);
494 os.write(m_text.c_str(), m_text.size());
496 virtual void update(std::istream &is, u8 version)
501 is.read((char*)buf, 2);
502 s16 yaw_i = readS16(buf);
503 m_yaw = (f32)yaw_i / 10;
506 is.read((char*)buf, 2);
507 u16 size = readU16(buf);
511 for(u16 i=0; i<size; i++)
513 is.read((char*)buf, 1);
519 virtual bool serverStep(float dtime)
523 virtual void addToScene(scene::ISceneManager *smgr)
528 video::IVideoDriver* driver = smgr->getVideoDriver();
530 scene::SMesh *mesh = new scene::SMesh();
532 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
533 video::SColor c(255,255,255,255);
534 video::S3DVertex vertices[4] =
536 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
537 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
538 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
539 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),
541 u16 indices[] = {0,1,2,2,3,0};
542 buf->append(vertices, 4, indices, 6);
544 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
545 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
546 buf->getMaterial().setTexture
547 (0, driver->getTexture("../data/sign.png"));
548 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
549 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
551 mesh->addMeshBuffer(buf);
555 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
556 video::SColor c(255,255,255,255);
557 video::S3DVertex vertices[4] =
559 video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
560 video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
561 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
562 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
564 u16 indices[] = {0,1,2,2,3,0};
565 buf->append(vertices, 4, indices, 6);
567 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
568 //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
569 buf->getMaterial().setTexture
570 (0, driver->getTexture("../data/sign_back.png"));
571 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
572 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
574 mesh->addMeshBuffer(buf);
577 m_node = smgr->addMeshSceneNode(mesh, NULL);
582 virtual void removeFromScene()
591 virtual std::string infoText()
593 return std::string("\"") + m_text + "\"";
596 virtual std::string getInventoryString()
598 return std::string("Sign ")+m_text;
605 void updateSceneNode()
609 m_node->setPosition(getAbsolutePos());
610 m_node->setRotation(v3f(0, m_yaw, 0));
614 void setText(std::string text)
616 if(text.size() > SIGN_TEXT_MAX_LENGTH)
617 text = text.substr(0, SIGN_TEXT_MAX_LENGTH);
631 scene::IMeshSceneNode *m_node;
636 struct DistanceSortedObject
638 DistanceSortedObject(MapBlockObject *a_obj, f32 a_d)
647 bool operator < (DistanceSortedObject &other)
653 class MapBlockObjectList
656 MapBlockObjectList(MapBlock *block);
657 ~MapBlockObjectList();
658 // Writes the count, id, the type id and the parameters of all objects
659 void serialize(std::ostream &os, u8 version);
660 // Reads ids, type_ids and parameters.
661 // Creates, updates and deletes objects.
662 // If smgr!=NULL, new objects are added to the scene
663 void update(std::istream &is, u8 version, scene::ISceneManager *smgr);
664 // Finds a new unique id
665 s16 getFreeId() throw(ContainerFullException);
668 Set id to -1 to have this set it to a suitable one.
669 The block pointer member is set to this block.
671 void add(MapBlockObject *object)
672 throw(ContainerFullException, AlreadyExistsException);
674 // Deletes and removes all objects
679 Ignores inexistent objects
683 References an object.
684 The object will not be valid after step() or of course if
686 Grabbing the lock is recommended while processing.
688 MapBlockObject * get(s16 id);
690 // You'll want to grab this in a SharedPtr
691 JMutexAutoLock * getLock()
693 return new JMutexAutoLock(m_mutex);
696 // Steps all objects and if server==true, removes those that
697 // want to be removed
698 void step(float dtime, bool server);
700 // Wraps an object that wants to move onto this block from an another
701 // Returns true if wrapping was impossible
702 bool wrapObject(MapBlockObject *object);
704 // origin is relative to block
705 void getObjects(v3f origin, f32 max_d,
706 core::array<DistanceSortedObject> &dest);
711 return m_objects.size();
717 core::map<s16, MapBlockObject*> m_objects;