JNR
laSegment.h
1 /*
2 
3 Jump'n'Run Engine
4 http://www.atanaslaskov.com/jnr/
5 
6 BSD LICENSE
7 Copyright (c) 2007-2013, Atanas Laskov
8 All rights reserved.
9 
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 */
29 #ifndef M_SEGMENT_H
30 #define M_SEGMENT_H
31 
33 
34 
47 
48 class laSegment: public laLoadableObj
49 {
50 protected:
51 
52  unsigned _nSegmentIndex;
53 
54  friend class laLevel; // the level builds a list of segments at initalization time
55  laSegment* _pPrev;
56  laSegment* _pNext;
57 
58  laTileset* _pTileset; // and sets the tileset
59  class laLevel* _pLevel;
60 
61  // Background
62  //
63  unsigned _nBackgroundElement;
64 
65  laLitterBox _arLitterBox[M_MAXLITTER_BOX];
66  unsigned _nLitterBoxCount;
67 
68  // Grid of tiles
69  //
70  laTile _arTiles[M_SEGW][M_SEGH];
71  unsigned _nCompilationID;
72 
73  unsigned _nCollisionDomains; // n. of domains
74  unsigned _nCollisionDomainSize; // n. of lines in all domains
75 
76  // List of objects currently within the bounds of the segment
77  // NOTE: This is std::list and not vector in order to speed up adding/removing obj dynamically (should be rare anyway);
78  // There is no need for direct indexing, only iteration, so having an array would not result in speed up.
79  //
80  // See laSegment::animate() for the routine that handles obj migration.
81  //
82  std::list<class laObject*> _listObjects;
83  M_BOOL _bObjectListReset;
84 
85  inline void _migrate_object( class laObject* pobj ) {
86  _listObjects.insert( _listObjects.begin(), pobj );
87  pobj->setSegment( this );
88  }
89 
90  void _init_object_list ( class laObject** par, unsigned n ); // called by friend laLevel::load()
91 
92  // Animated wave / used for various effects (e[1]. lava traps)
93  //
94  double _arWave[M_SEGW+1];
95 
96  // Curviture parameters at the start of this segment
97  // NOTE: laLevel blends those with the neighbouring semgnets, and builds terrain curviture on their basis
98  //
99  //
100  double _arTerrainCurvitureParams[4];
101 
102  void _update_curviture_parameters();
103  void _update_wave();
104  void _draw_static(laRenderer *r);
105  void _draw_dynamic(laRenderer *r);
106 
107 public:
108 
109  inline laSegment* previous() const { return _pPrev; }
110  inline laSegment* next() const { return _pNext; }
111 
112  inline void next( laSegment *pnext )
113  {
114  ASSERT(pnext, "Can't set NULL for next domain");
115  _pNext = pnext;
116  _pNext->_pPrev = this;
117 
118  lastDomain()->setNextDomain( next()->firstDomain() );
119  }
120 
121  // Constructor/destructor
122  //
123  laSegment(unsigned nIndex=0);
124  virtual ~laSegment(void);
125 
126  // Drawing the segment
127  //
128  void drawTerrain(laRenderer *r);
129  void drawObjects(laRenderer *r);
130  void drawFx(laRenderer *r, const laPoint3 &pos);
131 
132  // Animating the segment
133  //
134  void animate(laTimer &t);
135 
136  // This method is part of the laLoadableObj interface,
137  // loads the level segment
138  virtual void load(laFileParser* fp);
139 
140  // Data get/set methods
141  //
142  void setTS(laTileset* pTileset) { _pTileset = pTileset; };
143  void setLevel(class laLevel* pLvl) { _pLevel = pLvl; };
144 
145  void setBackgroundElement(unsigned i) {_nBackgroundElement = i;};
146 
147  laTileset* getTS() { return _pTileset; }
148  unsigned getBackgroundElement() { return _nBackgroundElement; }
149 
150  inline laTile* get(int ix, int iy) {
151  ASSERT( (ix>=0) && (ix<M_SEGW), "ix out of bounds");
152  ASSERT( (iy>=0) && (iy<M_SEGH), "iy out of bounds");
153 
154  // NOTE: Out of bound values here really don't make sense so
155  // forcing them into the bounds would only mask a bug
156  //
157  //ix = M_CLAMP(0, M_SEGW-1, ix);
158  //iy = M_CLAMP(0, M_SEGH-1, iy);
159 
160  return _arTiles[ix]+iy;
161  }
162 
163  inline laTile* get( const laPoint3 &pos ) {
164  return get(pos.x()/M_UNIT, pos.y()/M_UNIT);
165  }
166 
167  // Initalize the collision domains
168  //
169  void bulidDomains(laPoint3 pos);
170  inline unsigned collisionDomains() { return _nCollisionDomains; }
171 
172  unsigned countDomains(unsigned range)
173  {
174  ASSERT(range, "Nil range");
175  unsigned n = 0;
176  laSegment* ps = this;
177 
178  do{
179  n += ps->collisionDomains();
180  ps = ps->next();
181  }
182  while( ps && (--range) );
183 
184  return n;
185  }
186 
187  inline laCollisionDomain* firstDomain() {
188  return get(0,0)->getDomain();
189  }
190 
191  inline laCollisionDomain* lastDomain() {
192  return get(M_SEGW-1, M_SEGH-1)->getDomain();
193  }
194 
195  inline laCollisionDomain* firstNonemptyDomain() {
196  laCollisionDomain *pd = get(0,0)->getDomain();
197 
198  while( !(pd->countLines()) )
199  {
200  if( !(pd->nextDomain()) ) return pd;
201  pd = pd->nextDomain();
202  //ASSERT(pd, "End of domain chain reached");
203  }
204  return pd;
205  }
206 
207  // Wave (used for e[1]. trap lava surface)
208  //
209  inline double getWave(int nX) {
210  //ASSERT( (nX>=0) && (nX<M_SEGW) , "nX out of bounds");
211  //nX = M_CLAMP(0, M_SEGW, nX);
212 
213  if( nX<0 )
214  return _pPrev ? _pPrev->getWave(M_SEGW-1) : getWave(0);
215  else if( nX>=M_SEGW )
216  return _pNext ? _pNext->getWave(0) : getWave(M_SEGW-1);
217 
218  return _arWave[nX];
219  }
220 
221  // Terrain curviture
222  //
223  double terrainZOffset(int nX);
224  double terrainAngle(int nX);
225  double terrainScale(int nX);
226 
227  inline void curvitureParams(double* ar4) {
228  memcpy(ar4, _arTerrainCurvitureParams, sizeof(double)*4);
229  };
230 
231 };
233 #endif //#ifndef M_SEGMENT_H
Level Terrain Building-block.
Definition: laTile.h:42
#define M_UNIT
Unit of 1 meter.
Interface for loadable objects.
Definition: laLoadableObj.h:43
: JR Level
Definition: laLevel.h:48
"Litter Box" Background
Definition: laLitterBox.h:80
Terrain Semgnet.
Definition: laSegment.h:48
Collision Domain.
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
Base Class for Level Objects.
Definition: laObject.h:43
Tileset Class.
Definition: laTileset.h:46
File Parser.
Definition: laFileParser.h:41