JNR
cubicObj_TerminalInterface.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 #include "laObj_TerminalInterface.h"
33 
34 #define TERMI_SPACING 20
35 #define TERMI_OFFSET 50
36 
37 void uiContainer_SkillInfo::load(rpgSkill *pSkill, unsigned col, unsigned row)
38 {
39  uiContainer::load("ui\\dialogs\\jr-skill-info.cui");
40  ptShadowOffset.x(1);
41  ptShadowOffset.y(1);
42  //_ptSize = ptSkWindowSize;
43 
44  _pSkill = pSkill;
45 
46  _col = col;
47  _row = row;
48  _ptPos.x( _ptPos.x() + _col*(getSize().x()+30) + 20 );
49 
50  ang = rand()%90;
51  bSelected = M_FALSE;
52 
53  //Icon
54  //
55  _pIcon = new uiIcon3D( new uiSkillDescriptor(_pSkill) );
56  _pIcon->move( laPoint3(-20, -5), M_AL, M_AT);
57  insert(_pIcon);
58 }
59 
60 uiContainer_SkillInfo::uiContainer_SkillInfo(void)
61 {
62  _pIcon = NULL;
63 }
64 
65 uiContainer_SkillInfo::~uiContainer_SkillInfo(void)
66 {
67  if(_pIcon) delete _pIcon;
68 }
69 
70 void uiContainer_SkillInfo::reply()
71 {
72  double dt = ::laSystemIntegrator::getEnvironment()->getTimer()->delta();
73 
74  if( _ptPos.y() < _row*(getSize().y()+TERMI_SPACING) + TERMI_OFFSET) _ptPos.y( _ptPos.y() + 150 * dt );
75  //if( _ptPos.x() < _col*(getSize().x+30)+30) _ptPos[0] +=150 * dt;
76  else
77  {
78  //_ptPos[0] -= sin(ang) * 15;
79  //_ptPos[1] -= cos(ang) * 15;
80 
81  //Move a bit
82  //
83  ang += dt * 10;
84  _ptPos.x( _ptPos.x() + dt * sin(ang) * 10 );
85  _ptPos.y( _ptPos.y() + dt * cos(ang) * 10 );
86  }
87 
88  char strSkillName[64];
89  sprintf(strSkillName, "%s %d", _pSkill->name(), _pSkill->getCurrentIndex()+1 );
90  caption.setText(strSkillName);
91 
93 }
94 
95 void uiContainer_SkillInfo::draw()
96 {
97  if(bSelected)
98  {
99  col = _pSkin->parameter("CL_CONTAINER_SELECTED").color();
100  _pIcon->select();
101 
102  }else{
103  col = _pSkin->parameter("CL_CONTAINER").color();
104  _pIcon->select(M_FALSE);
105  }
106 
108 }
109 
110 laObj_TerminalInterface::laObj_TerminalInterface(laPlayer* pp, laActiveObject* pao, fxAnimatedText* pt,
111  unsigned npt)
112 {
113  mkL.set(KEY_LEFT, 1, 1);
114  mkR.set(KEY_RIGHT, 1, 1);
115  mkU.set(KEY_UP, 1, 1);
116  mkD.set(KEY_DOWN, 1, 1);
117 
118  mkEnter.set(KEY_RETURN, 1, 1);
119 
120  nSel = nRow = nCol = 0;
121 
122  _bProceed = _bCompleted = M_FALSE;
123 
124  pPlayer = pp;
125  pAO = pao;
126  pText = pt;
127  nPoints = npt;
128 
129  pText->parameters(
130  laSystemIntegrator::getRenderer()->font("plain"),
131  0.1*M_UNIT, 1.5, laColor(50,50,50, 200), 0.8, M_AL);
132  pText->reset();
133  pText->enableSlideFX(1, 15,0);
134 
135  pText->replace("$point", "%d", npt);
136  if(npt==1) pText->replace("Points", "Point");
137 
138  _baloon.create( pAO->getPosition() + laPoint3(-1*pText->width()*0.2, -1.5*M_UNIT),
139  laPoint3(pText->width() + 0.1*M_UNIT, pText->height() + 0.1*M_UNIT) );
140  _baloon.setMouthPos( pAO->getPosition() );
141  _baloon.setAnimText(pText);
142 
143  _init_skills();
144 }
145 
146 rpgSheet_PlayableChar* laObj_TerminalInterface::_player_sheet(){
147  return (rpgSheet_PlayableChar*)( pPlayer->getSheet() );
148 }
149 
150 rpgSkillsInventory *laObj_TerminalInterface::_skills_inventory(){
151  return &( _player_sheet()->properties()->skills );
152 }
153 
154 void laObj_TerminalInterface::_init_skills()
155 {
156  double h = laSystemIntegrator::getSettings()->graphics_resolution_h;
157 
158  rpgSkillsInventory* psi = _skills_inventory();
159  unsigned nLevel = _player_sheet()->properties()->nLevel;
160 
161  unsigned col=0, row=0;
162 
163  nRow_Max = 1; // limit set changed below
164  nCol_Max = 1;
165 
166  for(unsigned i=0; i< psi->size(); i++)
167  {
168  rpgSkill* pSkill = psi->skill(i);
169 
170  if( nLevel >= pSkill->prerequisite() )
171  {
172  _vSkillWindows.push_back( new uiContainer_SkillInfo() );
173  _vSkillWindows[i]->load( pSkill, col, row );
174 
175  //Update vertical limit for n of skill windows
176  if(i==0)
177  nRow_Max = h / ( TERMI_SPACING + _vSkillWindows[i]->getSize().y() + TERMI_OFFSET ) + 1;
178 
179  row++;
180  if(row>=nRow_Max) { row=0; col++; nCol_Max++; };
181  }
182  }
183 
184  nRow_Min = row; // last row may not be competed;
185 
186  ASSERT(psi->size(), "0 skills registered.");
187  _vSkillWindows[0]->select(M_TRUE);
188 }
189 
190 laObj_TerminalInterface::~laObj_TerminalInterface(void)
191 {
192  rpgSkillsInventory* psi = _skills_inventory();
193 
194  for(unsigned i=0; i< psi->size(); i++)
195  delete _vSkillWindows[i];
196 }
197 
198 // Draw the object
199 //
200 void laObj_TerminalInterface::drawGeometry(laRenderer *r, laPoint3 ptBasePos)
201 {
202 }
203 
204 void laObj_TerminalInterface::drawFx(laRenderer *r, laPoint3 ptBasePos)
205 {
206  r->transPush();
207  r->transTranslate( ptBasePos );
208 
209  _baloon.mode3D(M_TRUE);
210  _baloon.draw();
211 
212  r->transPop();
213 }
214 
215 #include <GL\GL.h>
216 void laObj_TerminalInterface::drawInterface(laRenderer *r, laPoint3 ptBasePos)
217 {
218  //r->transPush();
219  //r->transTranslate( ptBasePos /*laPoint3(0,0, pPlayer->getPosition().z)*/ );
220  //r->transPop();
221 
222  glEnable(GL_STENCIL_TEST); // in order to show on top of the cinematic shutter
223  glStencilFunc(GL_ALWAYS, 1 , 0xFFF );
224  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); //only if no obstacle;
225  glDisable(GL_DEPTH_TEST);
226 
227  if( (pText->currentEmotion()==1) || _bProceed)
228  for(unsigned i=0; i<_vSkillWindows.size(); i++)
229  _vSkillWindows[i]->draw();
230 
231  // Rogress reminder
232  //
233  //if( arText_Player[nCurrentStep].isFinished() )
234  {
235  char str1[] = "[Use Arrows to Select a Skill]";
236  char str2[] = "[Press ENTER to Train]";
237  char str3[] = "[Press ENTER to Quit Terminal]";
238  char str4[] = "[Press Q to Quit Terminal]";
239  //char str3[] = "[Press ENTER to confirm choice]";
240  double w = laSystemIntegrator::getSettings()->graphics_resolution_w;
241  double h = laSystemIntegrator::getSettings()->graphics_resolution_h;
242 
243  //if(_ttBlink.isElapsed())
244  //{
245  r->modeInterface();
246  laSystemIntegrator::getRenderer()->font("plain")->ctlSize( 15 );
247  laSystemIntegrator::getRenderer()->font("plain")->ctlAlignV(M_AM);
248  laSystemIntegrator::getRenderer()->font("plain")->ctlAlignH(M_AC);
249 
250  r->styleSet(laColor(50,50,50,255));
251 
252  if(_bProceed) laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-50+2), str3 );
253  else if(pText->currentEmotion()==1)
254  {
255  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-80+2), str1 );
256  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-60+2), str2 );
257  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-20+2), str4 );
258  }
259  //else laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-50+2), str4 );
260 
261  r->styleSet(laColor(255,255,255,255));
262 
263  if(_bProceed) laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-50+2), str3 );
264  else if(pText->currentEmotion()==1)
265  {
266  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2, h-80), str1);
267  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2, h-60), str2);
268  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-20+2), str4 );
269  }
270  //else laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-50+2), str4 );
271  //}
272  }
273 
274  glDisable(GL_STENCIL_TEST);
275 }
276 
277 // Animate the object
278 //
279 void laObj_TerminalInterface::animate(laTimer &t)
280 {
281  laInputManager* pi = ::laSystemIntegrator::getInput();
282 
283  if( (pText->currentEmotion()==0) || (_bProceed) ) pText->animate(t);
284 
285  if( (pText->currentEmotion()==1) || _bProceed)
286  for(unsigned i=0; i<_vSkillWindows.size(); i++)
287  _vSkillWindows[i]->reply();
288 
289 
290  mkEnter.animate(pi, t);
291 
292  if(mkEnter.isActivated())
293  {
294  mkEnter.reset();
295 
296  if(!_bProceed)
297  {
298  if(pText->currentEmotion()==1)
299  {
300  _upgrade_skill(_vSkillWindows[nSel]->getSkill());
301 
302  if( nPoints <= 0 )
303  {
304  _bProceed = M_TRUE;
305  _vSkillWindows[nSel]->select(M_FALSE);
306  }
307  }
308  }
309  else _bCompleted = M_TRUE;
310  }
311 
312  if(in::key(KEY_Q)) _bCompleted = M_TRUE;
313 
314  if(pText->currentEmotion()==1)
315  {
316  mkL.animate(pi, t);
317  mkR.animate(pi, t);
318  mkU.animate(pi, t);
319  mkD.animate(pi, t);
320  }
321 
322  if(mkL.isActivated())
323  {
324  mkL.reset();
325  /*if(nCol)*/ nCol--;
326  _update_sel();
327  }
328 
329  if(mkR.isActivated())
330  {
331  mkR.reset();
332  /*if(nCol<nCol_Max-1)*/ nCol++;
333  _update_sel();
334  }
335 
336  if(mkU.isActivated())
337  {
338  mkU.reset();
339  /*if(nRow)*/ nRow--;
340  _update_sel();
341  }
342 
343  if(mkD.isActivated())
344  {
345  mkD.reset();
346  /*if(nRow<nRow_Max)*/ nRow++;
347  _update_sel();
348 
349  }
350 }
351 
352 void laObj_TerminalInterface::_update_sel()
353 {
354  // Limits
355  //
356  if(nCol<0) nCol = 0;
357  if(nRow<0) nRow = 0;
358 
359  if(nCol>=nCol_Max) nCol = nCol_Max-1;
360  if(nRow>=nRow_Max) nRow = nRow_Max-1;
361 
362  if( nCol==(nCol_Max-1) && (nRow >= nRow_Min) ) nRow = nRow_Min-1;
363 
364  // Update sel
365  //
366  _vSkillWindows[nSel]->select(M_FALSE);
367 
368  nSel = nCol*nRow_Max + nRow;
369  _vSkillWindows[nSel]->select(M_TRUE);
370 }
371 
372 void laObj_TerminalInterface::_upgrade_skill(rpgSkill *pSkill)
373 {
374  rpgSkillsInventory* psi = _skills_inventory();
375 
376  if( psi->skill(nSel)->getCurrentIndex() + 1 < psi->skill(nSel)->getUpgradeCount() )
377  {
378  // Substract points
379  //
380  char strN[8];
381  sprintf(strN, "%d", nPoints--);
382  pText->replace(strN, "%d", nPoints);
383 
384  // up the skill
385  //
386  pPlayer->skillUp( nSel );
387  _player_sheet()->properties()->nTrainingPoints = nPoints;
388 
389  //_skills_inventory()->skill(nSel)->upgrade();
390  //pPlayer->fxMessages.add(1, laColor(255,255,0), "Skill Acquired");
391  }
392  else
393  {
394  //_vSkillWindows[nSel]->disable();
395  //todo: play sound
396  //pPlayer->fxMessages.add(1, laColor(255,255,0), "Max reached");
397  }
398 }
laFont * font(char *strName)
Get a font renderer.
Definition: laRenderer.h:192
Playable Character.
Definition: laPlayer.h:46
#define M_UNIT
Unit of 1 meter.
#define M_AM
Text align middle.
#define M_AL
Text align left.
#define M_AT
Text align top.
virtual void draw()
Display the window.
Player RPG Properties.
Object that can be activated by the player.
#define M_AC
Text align center.
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
virtual void modeInterface()=0
Switch to interface rendering (2D projection mode)
virtual void reply()
Handle input message.
GUI icon object that can siplay 3D models as icons.
Definition: uiIcon3D.h:52