JNR
aiNPCDialog.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 laNPCDialog::laNPCDialog()
34 {
35  _bFinished = M_FALSE;
36 
37  _ttBlink.parameters(0.8, 0.8, M_TRUE);
38  _ttNext.parameters(0.3);
39 }
40 
41 laNPCDialog::~laNPCDialog()
42 {
43 }
44 
45 void laNPCDialog::load(laFileParser *fp)
46 {
47  fp->readBool(&bObligatory);
48  fp->readText(strNextDialogueFile);
49  fp->readUnsigned(&nDialogSteps);
50 
51  arText_NPC = new fxAnimatedText[nDialogSteps];
52  arText_Player = new fxAnimatedText[nDialogSteps];
53 
54  for(unsigned i=0; i<nDialogSteps; i++)
55  {
56  fp->readObj(arText_NPC + i, M_FALSE);
57  fp->readObj(arText_Player + i, M_FALSE);
58 
59  arText_NPC[i].parameters(
60  laSystemIntegrator::getRenderer()->font("plain"),
61  0.1*M_UNIT, 1.5, laColor(50,50,50, 200), 1);
62 
63  arText_Player[i].parameters(
64  laSystemIntegrator::getRenderer()->font("plain"),
65  0.1*M_UNIT, 1.5, laColor(50,50,50, 200), 1);
66 
67  //_fxNarratorText.enableSlideFX();
68  //_fxNarratorText.enableRambleFX();
69  }
70 
71  nCurrentStep = 0;
72 }
73 
74 void laNPCDialog::animate(laTimer &t)
75 {
76  // Text blinking
77  _ttBlink.animate(t);
78 
79  // Play NPC and player text
80  //
81  arText_NPC[nCurrentStep].animate(t);
82 
83  if( arText_NPC[nCurrentStep].isFinished() )
84  {
85  arText_Player[nCurrentStep].animate(t);
86  }
87 
88  // Progress to next stage
89  // or exit dialog if the last stage is active
90  _ttNext.animate(t);
91 
92  if( ( in::key(KEY_RETURN) || in::key(KEY_SPACE) ) && _ttNext.isElapsed() )
93  {
94  _ttNext.reset();
95 
96  if( (!arText_NPC[nCurrentStep].isFinished()) || (!arText_Player[nCurrentStep].isFinished()) )
97  {
98  arText_NPC[nCurrentStep].force();
99  arText_Player[nCurrentStep].force();
100  }
101  else if( nCurrentStep < nDialogSteps-1 )
102  {
103  nCurrentStep++;
104  _ttBlink.reset();
105  }
106  else _bFinished = M_TRUE;
107  }
108 
109  if( isFinished() )
110  pMonster->fxMessages.add(1, laColor(255,255,255), "Good luck!");
111 }
112 
113 laPoint3 _baloon_pos(laPoint3 ptBasePos, laObject* pObject, laPoint3 sizeBaloon)
114 {
115  laPoint3 pos = ptBasePos + pObject->getPosition();
116 
117  //pos[0] -= sizeBaloon.x/2;
118  pos.y( pos.y() - pObject->getPivot()->size.y() + sizeBaloon.y() + M_UNIT/2.0);
119  return pos;
120 }
121 
122 laPoint3 _mouth_pos(laPoint3 ptBasePos, laObject* pObject)
123 {
124  laPoint3 pos = ptBasePos + pObject->getPosition();
125 
126  pos.y( pos.y() - pObject->getPivot()->size.y() + M_UNIT/5.0 );
127 
128  //pos[0] -= sizeBaloon.x/2;
129 
130  return pos;
131 }
132 
133 void _shift_baloons(laPoint3 *pt1, laPoint3 *pt2, laPoint3 sz1, laPoint3 sz2)
134 {
135  //double w = laSystemIntegrator::getSettings()->graphics_resolution_w;
136  //double h = laSystemIntegrator::getSettings()->graphics_resolution_h;
137 
138  if( pt1->x() > pt2->x() )
139  {
140  laPoint3* pt;
141  laPoint3 t;
142 
143  pt = pt1; pt1 = pt2; pt2 = pt;
144  t = sz1; sz1 = sz2; sz2 = t;
145  }
146 
147  pt1->x( pt1->x() - M_MIN(2*M_UNIT, sz1.x()*0.6) );
148  pt2->x( pt2->x() - M_MIN(2*M_UNIT, sz2.x()*0.4) );
149 
150  //double overlapx = (pt1->x+sz1.x) - (pt2->x);
151 
152  double overlapy1 = M_ABS((pt1->y()+sz1.y()) - (pt2->y()));
153  if( overlapy1 < M_UNIT/3.0)
154  {
155  pt1->y( pt1->y() - ( M_UNIT/3.0 - overlapy1 ) );
156  }
157 
158  double overlapy2 = M_ABS((pt2->y()+sz2.y()) - (pt1->y()));
159  if( overlapy2 < M_UNIT/3.0)
160  {
161  pt2->y( pt2->y() - ( M_UNIT/3.0 - overlapy2 ) );
162  }
163 
164  /*if( overlap > 0)
165  {
166  pt1->x()= pt1->x()- overlap*0.5;
167  pt2->x()= pt2->x()+ overlap*0.5;
168 
169  overlap = (pt1->x+sz1.x) - (pt2->x);
170  }*/
171 }
172 
173 void laNPCDialog::draw(laRenderer *r, laPoint3 ptBasePos)
174 {
175  // Position baloons
176  //
177  laPoint3 sizePlayerBaloon = laPoint3(arText_Player[nCurrentStep].width()+0.1*M_UNIT, arText_Player[nCurrentStep].height()+0.1*M_UNIT);
178  laPoint3 posPlayerBaloon = _baloon_pos(ptBasePos, pPlayer, sizePlayerBaloon);
179  laPoint3 posPlayerMouth = _mouth_pos(ptBasePos, pPlayer);
180 
181  laPoint3 sizeNPCBaloon = laPoint3(arText_NPC[nCurrentStep].width()+0.1*M_UNIT, arText_NPC[nCurrentStep].height()+0.1*M_UNIT);
182  laPoint3 posNPCBaloon = _baloon_pos(ptBasePos, pMonster, sizeNPCBaloon);
183  laPoint3 posNPCMouth = _mouth_pos(ptBasePos, pMonster);
184 
185  _shift_baloons(&posPlayerBaloon, &posNPCBaloon, sizePlayerBaloon, sizeNPCBaloon);
186 
187  // Draw baloons and text
188  //
189  _draw_baloon(r, posNPCBaloon, posNPCMouth, sizeNPCBaloon, arText_NPC+nCurrentStep);
190 
191  if( arText_NPC[nCurrentStep].isFinished() )
192  {
193  _draw_baloon(r, posPlayerBaloon, posPlayerMouth, sizePlayerBaloon, arText_Player+nCurrentStep);
194  }
195 
196 }
197 
198 #include "GL/GL.h"
199 
200 void laNPCDialog::drawGUI(laRenderer *r, laPoint3 ptBasePos)
201 {
202  glEnable(GL_STENCIL_TEST); // in order to shouw up on top of the cinematic shutter
203  glStencilFunc(GL_ALWAYS, 1 /*p.id/*1*/, 0xFFF /*-1*/);
204  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); //only if no obstacle;
205  glDisable(GL_DEPTH_TEST);
206 
207  // Rogress reminder
208  //
209  if( arText_Player[nCurrentStep].isFinished() )
210  {
211  double w = laSystemIntegrator::getSettings()->graphics_resolution_w;
212  double h = laSystemIntegrator::getSettings()->graphics_resolution_h;
213 
214  if(_ttBlink.isElapsed())
215  {
216  r->modeInterface();
217  laSystemIntegrator::getRenderer()->font("plain")->ctlSize( 15 );
218  laSystemIntegrator::getRenderer()->font("plain")->ctlAlignV(M_AM);
219 
220  r->styleSet(laColor(50,50,50,255));
221  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2+2, h-50+2), "[Press ENTER to continue]");
222 
223  r->styleSet(laColor(255,255,255,255));
224  laSystemIntegrator::getRenderer()->font("plain")->draw(laPoint3(w/2, h-50), "[Press ENTER to continue]");
225  }
226  }
227 
228  glDisable(GL_STENCIL_TEST);
229 }
230 
231 void laNPCDialog::_draw_baloon(laRenderer *r,
232  laPoint3 pos, laPoint3 pos_mouth, laPoint3 size,
233  fxAnimatedText* txt)
234 {
235  uiDialogBaloon b;
236 
237  b.create( pos, size );
238  b.setMouthPos( pos_mouth );
239  b.setAnimText(txt);
240  b.mode3D(M_TRUE);
241 
242  b.draw();
243 }
laFont * font(char *strName)
Get a font renderer.
Definition: laRenderer.h:192
#define M_UNIT
Unit of 1 meter.
#define M_AM
Text align middle.
#define M_ABS(a)
Return abs(a)
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
virtual void modeInterface()=0
Switch to interface rendering (2D projection mode)
Base Class for Level Objects.
Definition: laObject.h:43
File Parser.
Definition: laFileParser.h:41