JNR
aiMobState_LavaJumper.cpp
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 
30 #include "stdafx.h"
31 #include "ai.h"
32 
33 aiMobState_LavaJumper::aiMobState_LavaJumper(void)
34 {
35 }
36 
37 aiMobState_LavaJumper::~aiMobState_LavaJumper(void)
38 {
39 }
40 
41 void aiMobState_LavaJumper::load(laFileParser *fp)
42 {
43  aiMobState::load(fp);
44 
45  //Load global params
46  //
47  double dWait;
48  fp->readDouble(&dWait);
49  _ttWait.parameters(dWait,dWait);
50  _ttWait.enable();
51  _ttWait.force();
52 
53  fp->readBool(&_bAlwaysDoSameJump);
54  fp->readBool(&_bLavaJumper);
55  fp->readBool(&_bFollowCurve);
56 
57  _tJumpAvg = 2;
58  _nJumpSamples = 1;
59 
60  _ttTurn.parameters(_tJumpAvg, _tJumpAvg);
61  _ttTurn.enable(); // NOTE: if this M_FALSE, the initial _tJumpAvg could be mangled up
62  _ttTurn.force();
63 }
64 
65 void aiMobState_LavaJumper::perceive_active( std::string strID_Old )
66 {
67  laMonster* pMonster = (laMonster*) self();
68  laPlayer* pPlayer = (laPlayer*) player();
69 
70  pMonster->agressive(M_TRUE);
71  pMonster->enableBattleGUI(M_FALSE);
72 
73  pMonster->getPivot()-> bSimulateGravitation = M_TRUE;
74  pMonster->move(0);
75 
76  _ptOriginalPos = pMonster->getPosition();
77 
78  // Turning left and righrt interferes with the
79  // rot along Y, that's necessary for following the jump curve
80  // so turn it off
81  //
82  // NOTE: this alos interfires with sommersaults sometiems,
83  // principaly, rot shoud be with vec+ang, or qu,
84  // an easy fix: buit in rot into the 3d model anim
85  //
86  if( _bFollowCurve )
87  {
88  pMonster->setExplicitFacing(1);
89  }
90 }
91 
92 void aiMobState_LavaJumper::perceive_inactive( std::string strID_New )
93 {
94  laMonster* pMonster = (laMonster*) self();
95  laPlayer* pPlayer = (laPlayer*) player();
96 }
97 
98 /*void aiMobState_LavaJumper::perceive_InTerritory(unsigned state)
99 {
100  laMonster* pMonster = (laMonster*) self();
101  laPlayer* pPlayer = (laPlayer*) player();
102 }
103 
104 void aiMobState_LavaJumper::perceive_InRange(unsigned state)
105 {
106  laMonster* pMonster = (laMonster*) self();
107  laPlayer* pPlayer = (laPlayer*) player();
108 }
109 
110 void aiMobState_LavaJumper::perceive_Touched(unsigned state)
111 {
112  laMonster* pMonster = (laMonster*) self();
113  laPlayer* pPlayer = (laPlayer*) player();
114 }
115 
116 void aiMobState_LavaJumper::perceive_UnderAttack(unsigned state)
117 {
118  laMonster* pMonster = (laMonster*) self();
119  laPlayer* pPlayer = (laPlayer*) player();
120 }*/
121 
122 void aiMobState_LavaJumper::perceive(unsigned state, M_BOOL global, unsigned id, aiPerceptData data)
123 {
124  laMonster* pMonster = (laMonster*) self();
125  laPlayer* pPlayer = (laPlayer*) player();
126 
127  if(_bFollowCurve) _follow_curve();
128  if(_bLavaJumper) _update_trail();
129 
130  int direction = pMonster->getMoveDirection();
131  pMonster->move( this->_update_direction( direction ) );
132 
133  _ttWait.animate( *(::laSystemIntegrator::getEnvironment()->getTimer()) );
134  _ttTurn.animate( *(::laSystemIntegrator::getEnvironment()->getTimer()) );
135 
136  aiMobState::perceive(state, global, id, data);
137 }
138 
139 void aiMobState_LavaJumper::_follow_curve()
140 {
141  laMonster* pMonster = (laMonster*) self();
142  laPivot *pMobPivot = pMonster->getPivot();
143  double ang = 0;
144 
145  if( pMobPivot->bOnGround )
146  {
147  if( _ttTurn.isEnabled())
148  {
149  // Estimate jump duration
150  //
151  _tJump.frameEnd();
152  _tJumpAvg = ( _tJumpAvg * _nJumpSamples + _tJump.delta() ) / ( (double)_nJumpSamples + 1.0 );
153  _nJumpSamples++;
154 
155  //_ttTurn.setParameters(_tJump.delta(), _tJump.delta());
156  _ttTurn.parameters(_tJumpAvg, _tJumpAvg);
157 
158  // Make sure we wand underground
159  _ttTurn.force();
160  _ttTurn.enable(M_FALSE);
161  }
162  }
163  else if ( !_ttTurn.isEnabled() )
164  {
165  _ttTurn.enable();
166  _ttTurn.reset();
167 
168  _tJump.frameStart();
169  }
170 
171 
172  ang = (1 - _ttTurn.reminder()) * 180;
173  if( _ptTargetPos.x() <= pMobPivot->x() ) ang *= -1;
174 
175  if(_ttTurn.isEnabled())
176  pMobPivot->ptGeometryOffset.y( -0.5*(1 - _ttTurn.reminder())*M_UNIT ); // rotate around center
177  else
178  pMobPivot->ptGeometryOffset.y(0); // hide underground
179 
180  pMobPivot->angleZ = ang;
181 }
182 
183 int aiMobState_LavaJumper::_update_direction(int direction)
184 {
185  laMonster* pMonster = (laMonster*) self();
186  laPivot *pMobPivot = pMonster->getPivot();
187 
188  // Commence a new jump when on the ground
189  //
190  if( pMobPivot->bOnGround )
191  {
192  if( _ttWait.isEnabled() )
193  {
194  if( _ttWait.isElapsed() )
195  {
196  _ptTargetPos = _find_target();
197  pMonster->jump();
198  }
199  }
200  else
201  {
202  _ttWait.enable();
203  _ttWait.reset();
204  }
205 
206  //return 0;
207  }
208  // Naivgate in the air
209  //
210  else
211  {
212  _ttWait.enable(M_FALSE);
213 
214  if( pMobPivot->x()> _ptTargetPos.x() + M_UNIT*0.1 ) return -1;
215 
216  if( pMobPivot->x()< _ptTargetPos.x() - M_UNIT*0.1 ) return +1;
217  }
218 
219  return 0;
220 }
221 
222 laPoint3 aiMobState_LavaJumper::_find_target()
223 {
224  laMonster* pMonster = (laMonster*) self();
225  double dDL = pMonster->getLeftRange();// * M_UNIT;
226  double dDR = pMonster->getRightRange();// * M_UNIT;
227 
228  double x = 0;
229 
230  if( rand()%2 )
231  {
232  x -= (dDL * (rand()%100) / 100.0 );
233 
234  //(_bLavaJumper && !bInLava) || (!_bLavaJumper && bInLava)
235  if(_bLavaJumper) while( !_trap_below(x) && ( x < dDR) )
236  x += M_UNIT;
237  }
238  else
239  {
240  x += (dDR * (rand()%100) / 100.0);
241 
242  if(_bLavaJumper) while( !_trap_below(x) && ( x > -1*dDL ) )
243  x -= M_UNIT;
244 
245 
246  }
247  if( ( x > dDR) || (x < -1*dDL) )
248  {
249  x = 0; // no lava found, default to original pos
250  }
251  else if(_bLavaJumper)
252  {
253  // lava jumper placed where there's no lava
254  // => try to fix
255  //
256  if( !_trap_below(0) )
257  {
258  _ptOriginalPos[0] += x;
259  }
260  }
261 
262  return laPoint3(_ptOriginalPos.x() + x, _ptOriginalPos.y());
263 }
264 
265 void aiMobState_LavaJumper::_update_trail()
266 {
267  laMonster* pMonster = (laMonster*) self();
268  laPivot *pMobPivot = pMonster->getPivot();
269  rpgTrap* ptrap;
270 
271  if( _trap_below(_ptTargetPos.x() - _ptOriginalPos.x(), &ptrap) )
272  {
273  pMonster->_fxTrail.copyStyle( ptrap->pTSE->getFx("fx") );
274 
275  /*pMonster->_fxTrail._cbParam.p_rgb = ptrap->pTSE->getFx("fx")->_cbParam.p_rgb;
276  pMonster->_fxTrail.texSprite = ptrap->pTSE->getFx("fx")->texSprite;*/
277  }
278 
279  pMonster->_fxTrail.enable();
280  //pMonster->_fxTrail.position(pMobPivot->x, pMobPivot->y);
281 }
282 
283 M_BOOL aiMobState_LavaJumper::_trap_below(double dx, rpgTrap** ppt)
284 {
285  laMonster* pMonster = (laMonster*) self();
286  laPivot *pMobPivot = pMonster->getPivot();
287 
288  laPoint3 vTentacle(0, +4*M_UNIT, 0); //should point downwards
289 
290  laPivot vPivot = (*pMobPivot);
291  vPivot[0] = _ptOriginalPos.x() + dx;
292  vPivot[1] = vPivot.y() - 2.0 * M_UNIT;
293 
294  M_BOOL bTrap1 = M_FALSE;
295  vPivot[0] -= vPivot.size.x() * 0.5;
296  vPivot.projectVector(vTentacle, &bTrap1, ppt);
297 
298  M_BOOL bTrap2 = M_FALSE;
299  vPivot[0] += vPivot.size.x() * 1.0;
300  vPivot.projectVector(vTentacle, &bTrap2, ppt);
301 
302  return bTrap1 && bTrap2;
303 }
Playable Character.
Definition: laPlayer.h:46
#define M_UNIT
Unit of 1 meter.
Trap Properties.
Definition: rpgTrap.h:42
Adds capabilities and percepts specific to monster creatures.
Definition: laMonster.h:45
Dynamic Object Pivot.
Definition: laPivot.h:44
File Parser.
Definition: laFileParser.h:41