1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "hdb/hdb.h"
24 #include "hdb/ai.h"
25 #include "hdb/gfx.h"
26 #include "hdb/lua-script.h"
27 #include "hdb/map.h"
28 #include "hdb/sound.h"
29 #include "hdb/window.h"
30
31 namespace HDB {
32
33 static const char *cineTypeStr[] = {
34 "C_NO_COMMAND",
35 "C_STOPCINE",
36 "C_LOCKPLAYER",
37 "C_UNLOCKPLAYER",
38 "C_SETCAMERA",
39 "C_MOVECAMERA",
40 "C_WAIT",
41 "C_WAITUNTILDONE",
42 "C_MOVEENTITY",
43 "C_DIALOG",
44 "C_ANIMENTITY",
45 "C_RESETCAMERA",
46 "C_SETENTITY",
47 "C_STARTMAP",
48 "C_MOVEPIC",
49 "C_MOVEMASKEDPIC",
50 "C_DRAWPIC",
51 "C_DRAWMASKEDPIC",
52 "C_FADEIN",
53 "C_FADEOUT",
54 "C_SPAWNENTITY",
55 "C_PLAYSOUND",
56 "C_CLEAR_FG",
57 "C_SET_FG",
58 "C_SET_BG",
59 "C_FUNCTION",
60 "C_ENTITYFACE",
61 "C_USEENTITY",
62 "C_REMOVEENTITY",
63 "C_SETANIMFRAME",
64 "C_TEXTOUT",
65 "C_CENTERTEXTOUT",
66 "C_PLAYVOICE",
67
68 "C_ENDLIST"
69 };
70
processCines()71 void AI::processCines() {
72 if (!_cineActive)
73 return;
74
75 // Make sure Dialogs are timing out
76 g_hdb->_window->checkDialogClose(0, 0);
77
78 // Make sure Cine Pics are drawing
79 for (int i = 0; i < _numCineBlitList; i++) {
80 if (_cineBlitList[i]->masked == false)
81 _cineBlitList[i]->pic->draw(_cineBlitList[i]->x, _cineBlitList[i]->y);
82 else
83 _cineBlitList[i]->pic->drawMasked(_cineBlitList[i]->x, _cineBlitList[i]->y);
84 }
85
86 // Check for Game Pause
87 if (g_hdb->getPause())
88 return;
89
90 bool bailOut = false;
91 bool complete = false;
92
93 for (uint i = 0; i < _cine.size(); i++) {
94 debug(3, "processCines: [%d] %s now: %d start: %d delay: %d", i, cineTypeStr[_cine[i]->cmdType],
95 g_system->getMillis(), _cine[i]->start, _cine[i]->delay);
96
97 switch (_cine[i]->cmdType) {
98 case C_STOPCINE:
99 {
100 char func[64];
101 memset(func, 0, 64);
102
103 if (_cine[i]->title)
104 Common::strlcpy(func, _cine[i]->title, 64);
105
106 cineCleanup();
107 if (func[0])
108 g_hdb->_lua->callFunction(func, 0);
109 }
110 break;
111 case C_STARTMAP:
112 {
113 const char *title = _cine[i]->title;
114 // free all gfx alloc'ed during cine
115 cineFreeGfx();
116 _cineActive = false;
117 _playerLock = false;
118 _cameraLock = false;
119 g_hdb->_window->setInfobarDark(0);
120 g_hdb->_gfx->setPointerState(1);
121 _cine.resize(0);
122 _numCineFreeList = 0;
123 _numCineBlitList = 0;
124 // if cine is aborted and an abort function was specified, call it
125 if (_cineAborted && _cineAbortFunc)
126 g_hdb->_lua->callFunction(_cineAbortFunc, 0);
127 g_hdb->changeMap(title);
128 return;
129 }
130 break;
131 case C_LOCKPLAYER:
132 _playerLock = true;
133 complete = true;
134 if (_player)
135 stopEntity(_player);
136 clearWaypoints();
137 break;
138 case C_UNLOCKPLAYER:
139 _playerLock = false;
140 complete = true;
141 break;
142 case C_SETCAMERA:
143 _cameraX = _cine[i]->x;
144 _cameraY = _cine[i]->y;
145 g_hdb->_map->centerMapXY((int)_cameraX + 16, (int)_cameraY + 16);
146 _cameraLock = true;
147 complete = true;
148 break;
149 case C_RESETCAMERA:
150 {
151 _cameraLock = false;
152 int px, py;
153 g_hdb->_ai->getPlayerXY(&px, &py);
154 g_hdb->_map->centerMapXY(px + 16, py + 16);
155 complete = true;
156 }
157 break;
158 case C_MOVECAMERA:
159 _cameraLock = true;
160 if (!(_cine[i]->start)) {
161 debug(3, "C_MOVECAMERA: [%d] now: x: %f, y: %f, speed: %d", i, _cine[i]->x, _cine[i]->y, _cine[i]->speed);
162 _cine[i]->xv = (((double)_cine[i]->x) - _cameraX) / (double)_cine[i]->speed;
163 _cine[i]->yv = (((double)_cine[i]->y) - _cameraY) / (double)_cine[i]->speed;
164 _cine[i]->start = 1;
165 }
166 _cameraX += _cine[i]->xv;
167 _cameraY += _cine[i]->yv;
168 debug(3, "C_MOVECAMERA: _cine[%d]->xv: %f, _cine[%d]->yv: %f", i, _cine[i]->xv, i, _cine[i]->yv);
169 debug(3, "C_MOVECAMERA: abs(_cameraX - _cine[i]->x): %f, abs(_cameraY - _cine[i]->y): %f", fabs(_cameraX - _cine[i]->x), fabs(_cameraY - _cine[i]->y));
170 if (fabs(_cameraX - _cine[i]->x) <= 1 && fabs(_cameraY - _cine[i]->y) <= 1) {
171 _cameraX = _cine[i]->x;
172 _cameraY = _cine[i]->y;
173 complete = true;
174 }
175 g_hdb->_map->centerMapXY((int)_cameraX + 16, (int)_cameraY + 16);
176 break;
177 case C_WAIT:
178 if (!(_cine[i]->start)) {
179 _cine[i]->start = 1;
180 _cine[i]->delay = g_system->getMillis() + _cine[i]->delay * 1000;
181 } else if (_cine[i]->delay < g_system->getMillis())
182 complete = true;
183 else
184 bailOut = true;
185 break;
186 case C_WAITUNTILDONE:
187 if (!i)
188 complete = true;
189 else
190 bailOut = true;
191
192 break;
193 case C_SETENTITY:
194 _cine[i]->e = locateEntity(_cine[i]->string);
195 if (_cine[i]->e) {
196 _cine[i]->e->tileX = (int)_cine[i]->x / kTileWidth;
197 _cine[i]->e->x = (int)_cine[i]->x;
198 _cine[i]->e->tileY = (int)_cine[i]->y / kTileHeight;
199 _cine[i]->e->y = (int)_cine[i]->y;
200 _cine[i]->e->level = (int)_cine[i]->x2;
201 debug(2, "Found '%s' in setEntity", _cine[i]->string);
202 } else
203 warning("Can't locate '%s' in setEntity", _cine[i]->string);
204
205 complete = true;
206 break;
207 case C_MOVEENTITY:
208 if (!_cine[i]->start) {
209 AIEntity *e = locateEntity(_cine[i]->title);
210 if (e) {
211 _cine[i]->e = e;
212 _cine[i]->e->moveSpeed = _cine[i]->speed;
213 _cine[i]->e->level = (int)_cine[i]->x2;
214 setEntityGoal(_cine[i]->e, (int)_cine[i]->x, (int)_cine[i]->y);
215 _cine[i]->start = 1;
216 } else
217 warning("Can't locate '%s' in moveEntity", _cine[i]->title);
218 } else {
219 debug(3, "C_MOVEENTITY: %d, %s tileX: %d, goalX: %d tileY %d, goalY: %d", i, AIType2Str(_cine[i]->e->type), _cine[i]->e->tileX, _cine[i]->e->goalX, _cine[i]->e->tileY, _cine[i]->e->goalY);
220 if (!_cine[i]->e->goalX)
221 complete = true;
222 }
223 break;
224 case C_ANIMENTITY:
225 if (!_cine[i]->start) {
226 AIEntity *e = locateEntity(_cine[i]->title);
227 if (e) {
228 _cine[i]->e = e;
229 e->state = (AIState)_cine[i]->speed;
230 _cine[i]->start = 1;
231 if (_cine[i]->end) // Loop ?
232 complete = true;
233 e->animFrame = 0;
234 e->animDelay = e->animCycle;
235 animEntFrames(e);
236 } else {
237 warning("Can't locate '%s' in animEntity", _cine[i]->title);
238 complete = true;
239 }
240 } else {
241 AIEntity *e = _cine[i]->e;
242 if (!e->animFrame && e->animDelay == e->animCycle) {
243 e->state = STATE_STANDDOWN;
244 e->animFrame = 0;
245 e->animDelay = e->animCycle;
246 complete = true;
247 }
248 }
249 break;
250 case C_SETANIMFRAME:
251 {
252 AIEntity *e = locateEntity(_cine[i]->title);
253 if (e) {
254 e->state = (AIState)_cine[i]->start;
255 e->animFrame = _cine[i]->end;
256 e->animDelay = e->animCycle;
257 animEntFrames(e);
258 e->state = STATE_NONE;
259 complete = true;
260 }
261 }
262 break;
263 case C_ENTITYFACE:
264 {
265 AIEntity *e = locateEntity(_cine[i]->title);
266
267 if (e) {
268 int d = (int)_cine[i]->x;
269 e->dir = (AIDir)d;
270 switch (e->dir) {
271 case DIR_UP:
272 e->state = STATE_STANDUP;
273 break;
274 case DIR_DOWN:
275 e->state = STATE_STANDDOWN;
276 break;
277 case DIR_LEFT:
278 e->state = STATE_STANDLEFT;
279 break;
280 case DIR_RIGHT:
281 e->state = STATE_STANDRIGHT;
282 break;
283 default:
284 break;
285 }
286 } else
287 warning("Can't find %s to ENTITYFACE", _cine[i]->title);
288
289 complete = true;
290 }
291 break;
292 case C_DIALOG:
293 if (_cine[i]->start) {
294 g_hdb->_window->openDialog(_cine[i]->title, -1, _cine[i]->string, 0, nullptr);
295 g_hdb->_window->setDialogDelay(_cine[i]->delay);
296 _cine[i]->start = 0;
297 } else if (g_hdb->_window->getDialogDelay() < g_hdb->getTimeSlice())
298 complete = true;
299 break;
300 case C_TEXTOUT:
301 if (!_cine[i]->start) {
302 g_hdb->_window->textOut(_cine[i]->title, _cine[i]->x, _cine[i]->y, _cine[i]->end);
303 _cine[i]->start = 1;
304 } else if (!g_hdb->_window->textOutActive())
305 complete = true;
306 break;
307 case C_CENTERTEXTOUT:
308 if (!_cine[i]->start) {
309 g_hdb->_window->centerTextOut(_cine[i]->title, _cine[i]->y, _cine[i]->end);
310 _cine[i]->start = 1;
311 } else if (!g_hdb->_window->textOutActive())
312 complete = true;
313 break;
314 case C_DRAWPIC:
315 {
316 Picture *p = cineFindInBlitList(_cine[i]->id);
317 if (p == nullptr) {
318 p = g_hdb->_gfx->loadPic(_cine[i]->string);
319 cineAddToFreeList(p);
320 cineAddToBlitList(_cine[i]->id, p, (int)_cine[i]->x, (int)_cine[i]->y, false);
321 }
322 _cine[i]->pic = p;
323 _cine[i]->pic->draw((int)_cine[i]->x, (int)_cine[i]->y);
324 complete = true;
325 }
326 break;
327 case C_DRAWMASKEDPIC:
328 {
329 Picture *p = cineFindInBlitList(_cine[i]->id);
330 if (p == nullptr) {
331 p = g_hdb->_gfx->loadPic(_cine[i]->string);
332 cineAddToFreeList(p);
333 cineAddToBlitList(_cine[i]->id, p, (int)_cine[i]->x, (int)_cine[i]->y, true);
334 }
335 _cine[i]->pic = p;
336 _cine[i]->pic->drawMasked((int)_cine[i]->x, (int)_cine[i]->y);
337 complete = true;
338 }
339 break;
340
341 case C_MOVEPIC:
342 if (!_cine[i]->start) {
343 Picture *pic = cineFindInBlitList(_cine[i]->id);
344 if (!pic) {
345 pic = g_hdb->_gfx->loadPic(_cine[i]->string);
346 cineAddToFreeList(pic);
347 } else
348 cineRemoveFromBlitList(_cine[i]->id);
349 _cine[i]->pic = pic;
350 _cine[i]->start = 1;
351 }
352
353 cineRemoveFromBlitList(_cine[i]->id);
354 _cine[i]->x += _cine[i]->xv;
355 _cine[i]->y += _cine[i]->yv;
356 cineAddToBlitList(_cine[i]->id, _cine[i]->pic, (int)_cine[i]->x, (int)_cine[i]->y, false);
357 if (abs((int)(_cine[i]->x - _cine[i]->x2)) <= 1 && abs((int)(_cine[i]->y - _cine[i]->y2)) <= 1)
358 complete = true;
359 break;
360
361 case C_MOVEMASKEDPIC:
362 if (!_cine[i]->start) {
363 Picture *pic = cineFindInBlitList(_cine[i]->id);
364 if (!pic) {
365 pic = g_hdb->_gfx->loadPic(_cine[i]->string);
366 cineAddToFreeList(pic);
367 } else
368 cineRemoveFromBlitList(_cine[i]->id);
369 _cine[i]->pic = pic;
370 _cine[i]->start = 1;
371 }
372
373 cineRemoveFromBlitList(_cine[i]->id);
374 _cine[i]->x += _cine[i]->xv;
375 _cine[i]->y += _cine[i]->yv;
376 cineAddToBlitList(_cine[i]->id, _cine[i]->pic, (int)_cine[i]->x, (int)_cine[i]->y, true);
377 if (abs((int)(_cine[i]->x - _cine[i]->x2)) <= 1 && abs((int)(_cine[i]->y - _cine[i]->y2)) <= 1)
378 complete = true;
379 break;
380
381 case C_USEENTITY:
382 for (Common::Array<AIEntity *>::iterator it = _ents->begin(); it != _ents->end(); ++it) {
383 if (Common::matchString((*it)->entityName, _cine[i]->string, true))
384 g_hdb->useEntity((*it));
385 }
386 for (int k = 0; k < kMaxActions; k++) {
387 if (Common::matchString(_actions[k].entityName, _cine[i]->string, true)) {
388 checkActionList(&_dummyPlayer, _actions[k].x1, _actions[k].y1, false);
389 checkActionList(&_dummyPlayer, _actions[k].x2, _actions[k].y2, false);
390 }
391 }
392 for (int j = 0; j < kMaxAutoActions; j++) {
393 if (Common::matchString(_autoActions[j].entityName, _cine[i]->string, true) && !_autoActions[j].activated)
394 checkAutoList(&_dummyPlayer, _autoActions[j].x, _autoActions[j].y);
395 }
396 complete = true;
397 break;
398 case C_PLAYSOUND:
399 g_hdb->_sound->playSound((int)_cine[i]->start);
400 complete = true;
401 break;
402 case C_PLAYVOICE:
403 g_hdb->_sound->playVoice((int)_cine[i]->x, (int)_cine[i]->y);
404 complete = true;
405 break;
406 case C_FADEIN:
407 if (!_cine[i]->start) {
408 g_hdb->_gfx->setFade(true, (bool)_cine[i]->end, _cine[i]->speed);
409 _cine[i]->start = 1;
410 } else if (!g_hdb->_gfx->isFadeActive())
411 complete = true;
412 break;
413 case C_FADEOUT:
414 if (!_cine[i]->start) {
415 g_hdb->_gfx->setFade(false, (bool)_cine[i]->end, _cine[i]->speed);
416 _cine[i]->start = 1;
417 } else if (!g_hdb->_gfx->isFadeActive())
418 complete = true;
419 break;
420 case C_SPAWNENTITY:
421 {
422 int x2 = (int)_cine[i]->x2;
423 int y2 = (int)_cine[i]->y2;
424 spawn((AIType)x2, (AIDir)y2, (int)_cine[i]->x, (int)_cine[i]->y, _cine[i]->title, _cine[i]->string,
425 _cine[i]->id, (AIDir)_cine[i]->start, (int)_cine[i]->end, (int)_cine[i]->delay, (int)_cine[i]->speed, 1);
426 complete = true;
427 }
428 break;
429 case C_REMOVEENTITY:
430 {
431 AIEntity *e = locateEntity(_cine[i]->string);
432 if (e)
433 removeEntity(e);
434 complete = true;
435 }
436 break;
437 case C_CLEAR_FG:
438 g_hdb->_map->setMapFGTileIndex((int)_cine[i]->x, (int)_cine[i]->y, -1);
439 g_hdb->_map->removeFGTileAnimation((int)_cine[i]->x, (int)_cine[i]->y);
440 complete = true;
441 break;
442 case C_SET_BG:
443 g_hdb->_map->setMapBGTileIndex((int)_cine[i]->x, (int)_cine[i]->y, (int)_cine[i]->start);
444 g_hdb->_map->addBGTileAnimation((int)_cine[i]->x, (int)_cine[i]->y);
445 complete = true;
446 break;
447 case C_SET_FG:
448 g_hdb->_map->setMapFGTileIndex((int)_cine[i]->x, (int)_cine[i]->y, (int)_cine[i]->start);
449 g_hdb->_map->addFGTileAnimation((int)_cine[i]->x, (int)_cine[i]->y);
450 complete = true;
451 break;
452 case C_FUNCTION:
453 g_hdb->_lua->callFunction(_cine[i]->title, 0);
454 complete = true;
455 break;
456 default:
457 break;
458 }
459
460 if (bailOut)
461 return;
462
463 if (complete && _cine.size()) {
464 delete _cine[i];
465 _cine.remove_at(i);
466 i--;
467 complete = false;
468 }
469 }
470 }
471
cineCleanup()472 void AI::cineCleanup() {
473 cineFreeGfx();
474 _cineActive = false;
475 // If aborted and abort function specified, call it
476 if (_cineAborted && _cineAbortFunc)
477 g_hdb->_lua->callFunction(_cineAbortFunc, 0);
478
479 _cameraLock = false;
480 _playerLock = false;
481 g_hdb->_window->setInfobarDark(0);
482 g_hdb->_gfx->setPointerState(1);
483
484 int px, py;
485 getPlayerXY(&px, &py);
486 g_hdb->_map->centerMapXY(px + 16, py + 16);
487 }
488
cineAbort()489 void AI::cineAbort() {
490 for (uint i = 0; i < _cine.size(); i++) {
491 if (_cine[i]->cmdType == C_STARTMAP || _cine[i]->cmdType == C_STOPCINE)
492 _cine[0] = _cine[i];
493 }
494
495 _cine.resize(1);
496
497 g_hdb->_window->closeAll();
498
499 if (_player)
500 stopEntity(_player);
501 _cineAborted = true;
502 }
503
cineAddToBlitList(const char * id,Picture * pic,int x,int y,bool masked)504 void AI::cineAddToBlitList(const char *id, Picture *pic, int x, int y, bool masked) {
505 _cineBlitList[_numCineBlitList] = new CineBlit;
506 _cineBlitList[_numCineBlitList]->id = id;
507 _cineBlitList[_numCineBlitList]->pic = pic;
508 _cineBlitList[_numCineBlitList]->x = x;
509 _cineBlitList[_numCineBlitList]->y = y;
510 _cineBlitList[_numCineBlitList]->masked = masked;
511 _numCineBlitList++;
512 }
513
cineFindInBlitList(const char * name)514 Picture *AI::cineFindInBlitList(const char *name) {
515 for (int i = 0; i < _numCineBlitList; i++) {
516 if (Common::matchString(_cineBlitList[i]->id, name, true))
517 return _cineBlitList[i]->pic;
518 }
519 return nullptr;
520 }
521
cineRemoveFromBlitList(const char * name)522 void AI::cineRemoveFromBlitList(const char *name) {
523 for (int i = 0; i < _numCineBlitList; i++) {
524 if (Common::matchString(_cineBlitList[i]->id, name, true)) {
525 delete _cineBlitList[i];
526 for (; i < _numCineBlitList - 1; i++)
527 _cineBlitList[i] = _cineBlitList[i + 1];
528 _numCineBlitList--;
529 _cineBlitList[_numCineBlitList] = nullptr;
530 return;
531 }
532 }
533 }
534
cineAddToFreeList(Picture * pic)535 void AI::cineAddToFreeList(Picture *pic) {
536 if (_numCineFreeList >= kMaxCineGfx) {
537 warning("cineAddToFreeList: Too many gfx in Cinematic!");
538 return;
539 }
540 _cineFreeList[_numCineFreeList] = pic;
541 _numCineFreeList++;
542 }
543
cineFreeGfx()544 void AI::cineFreeGfx() {
545 for (int i = 0; i < _numCineFreeList; i++)
546 delete _cineFreeList[i];
547
548 _numCineFreeList = 0;
549 }
550
cineStart(bool abortable,const char * abortFunc)551 void AI::cineStart(bool abortable, const char *abortFunc) {
552 _cineAbortable = abortable;
553 _cineAborted = false;
554 _cineAbortFunc = abortFunc;
555 _numCineBlitList = 0;
556 _numCineFreeList = 0;
557 _cineActive = true;
558 _playerLock = false;
559 _cameraLock = false;
560
561 _cine.clear();
562 }
563
cineStop(const char * funcNext)564 void AI::cineStop(const char *funcNext) {
565 CineCommand *cmd = new CineCommand;
566 cmd->cmdType = C_STOPCINE;
567 cmd->title = funcNext;
568 _cine.push_back(cmd);
569 }
570
cineStartMap(const char * mapName)571 void AI::cineStartMap(const char *mapName) {
572 CineCommand *cmd = new CineCommand;
573 cmd->cmdType = C_STARTMAP;
574 cmd->title = mapName;
575 _cine.push_back(cmd);
576 }
577
cineLockPlayer()578 void AI::cineLockPlayer() {
579 CineCommand *cmd = new CineCommand;
580 cmd->cmdType = C_LOCKPLAYER;
581 _cine.push_back(cmd);
582 }
583
cineUnlockPlayer()584 void AI::cineUnlockPlayer() {
585 CineCommand *cmd = new CineCommand;
586 cmd->cmdType = C_UNLOCKPLAYER;
587 _cine.push_back(cmd);
588 }
589
cineSetCamera(int x,int y)590 void AI::cineSetCamera(int x, int y) {
591 CineCommand *cmd = new CineCommand;
592 cmd->x = x * kTileWidth;
593 cmd->y = y * kTileHeight;
594 cmd->cmdType = C_SETCAMERA;
595 _cine.push_back(cmd);
596 }
597
cineResetCamera()598 void AI::cineResetCamera() {
599 CineCommand *cmd = new CineCommand;
600 cmd->cmdType = C_RESETCAMERA;
601 _cine.push_back(cmd);
602 }
603
cineMoveCamera(int x,int y,int speed)604 void AI::cineMoveCamera(int x, int y, int speed) {
605 CineCommand *cmd = new CineCommand;
606 cmd->start = 0;
607 cmd->x = x * kTileWidth;
608 cmd->y = y * kTileHeight;
609 cmd->speed = speed;
610 debug(2, "Setting up C_MOVECAMERA: x: %f, y: %f", cmd->x, cmd->y);
611 cmd->cmdType = C_MOVECAMERA;
612 _cine.push_back(cmd);
613 }
614
cineWait(int seconds)615 void AI::cineWait(int seconds) {
616 CineCommand *cmd = new CineCommand;
617 cmd->start = 0;
618 cmd->cmdType = C_WAIT;
619 cmd->delay = seconds;
620 _cine.push_back(cmd);
621 }
622
cineWaitUntilDone()623 void AI::cineWaitUntilDone() {
624 CineCommand *cmd = new CineCommand;
625 cmd->cmdType = C_WAITUNTILDONE;
626 _cine.push_back(cmd);
627 }
628
cineSetEntity(const char * entName,int x,int y,int level)629 void AI::cineSetEntity(const char *entName, int x, int y, int level) {
630 CineCommand *cmd = new CineCommand;
631 cmd->string = entName;
632 cmd->x = x * kTileWidth;
633 cmd->y = y * kTileHeight;
634 cmd->x2 = level;
635 cmd->cmdType = C_SETENTITY;
636 _cine.push_back(cmd);
637 }
638
cineMoveEntity(const char * entName,int x,int y,int level,int speed)639 void AI::cineMoveEntity(const char *entName, int x, int y, int level, int speed) {
640 CineCommand *cmd = new CineCommand;
641 cmd->x = x;
642 cmd->y = y;
643 cmd->x2 = level;
644 cmd->start = 0;
645 cmd->speed = speed;
646 cmd->title = entName;
647 cmd->cmdType = C_MOVEENTITY;
648 _cine.push_back(cmd);
649 }
650
cineAnimEntity(const char * entName,AIState state,int loop)651 void AI::cineAnimEntity(const char *entName, AIState state, int loop) {
652 CineCommand *cmd = new CineCommand;
653 cmd->start = 0;
654 cmd->title = entName;
655 cmd->speed = state;
656 cmd->end = loop;
657 cmd->cmdType = C_ANIMENTITY;
658 _cine.push_back(cmd);
659 }
660
cineSetAnimFrame(const char * entName,AIState state,int frame)661 void AI::cineSetAnimFrame(const char *entName, AIState state, int frame) {
662 CineCommand *cmd = new CineCommand;
663 cmd->start = state;
664 cmd->title = entName;
665 cmd->end = frame;
666 cmd->cmdType = C_SETANIMFRAME;
667 _cine.push_back(cmd);
668 }
669
cineEntityFace(const char * luaName,double dir)670 void AI::cineEntityFace(const char *luaName, double dir) {
671 CineCommand *cmd = new CineCommand;
672 cmd->title = luaName;
673 cmd->x = dir;
674 cmd->cmdType = C_ENTITYFACE;
675 _cine.push_back(cmd);
676 }
677
cineSpawnEntity(AIType t,AIDir d,int x,int y,const char * func_init,const char * func_action,const char * func_use,AIDir d2,int level,int value1,int value2)678 void AI::cineSpawnEntity(AIType t, AIDir d, int x, int y, const char *func_init, const char *func_action,
679 const char *func_use, AIDir d2, int level, int value1, int value2) {
680 CineCommand *cmd = new CineCommand;
681 cmd->cmdType = C_SPAWNENTITY;
682 cmd->x2 = (double)t;
683 cmd->y2 = (double)d;
684 cmd->x = (double)x;
685 cmd->y = (double)y;
686 cmd->title = func_init;
687 cmd->string = func_action;
688 cmd->id = func_use;
689 cmd->start = (int)d2;
690 cmd->end = level;
691 cmd->delay = value1;
692 cmd->speed = value2;
693
694 _cine.push_back(cmd);
695 }
696
cineRemoveEntity(const char * entName)697 void AI::cineRemoveEntity(const char *entName) {
698 CineCommand *cmd = new CineCommand;
699 cmd->string = entName;
700 cmd->cmdType = C_REMOVEENTITY;
701 _cine.push_back(cmd);
702 }
703
cineDialog(const char * title,const char * string,int seconds)704 void AI::cineDialog(const char *title, const char *string, int seconds) {
705 CineCommand *cmd = new CineCommand;
706 cmd->title = title;
707 cmd->string = string;
708 cmd->delay = seconds;
709 cmd->start = 1;
710 if (!title || !string)
711 warning("cineDialog: Missing Title or Text");
712 cmd->cmdType = C_DIALOG;
713 debug(6, "In cineDialog: C_DIALOG created. cmd->start: %d, cmd->title: %s", cmd->start, cmd->title);
714 _cine.push_back(cmd);
715 }
716
cineTextOut(const char * text,int x,int y,int timer)717 void AI::cineTextOut(const char *text, int x, int y, int timer) {
718 CineCommand *cmd = new CineCommand;
719 cmd->title = text;
720 cmd->x = x;
721 cmd->y = y;
722 cmd->end = timer;
723 cmd->start = 0;
724 cmd->cmdType = C_TEXTOUT;
725 _cine.push_back(cmd);
726 }
727
cineCenterTextOut(const char * text,int y,int timer)728 void AI::cineCenterTextOut(const char *text, int y, int timer) {
729 CineCommand *cmd = new CineCommand;
730 cmd->title = text;
731 cmd->y = y;
732 cmd->end = timer;
733 cmd->start = 0;
734 cmd->cmdType = C_CENTERTEXTOUT;
735 _cine.push_back(cmd);
736 }
737
cineDrawPic(const char * id,const char * pic,int x,int y)738 void AI::cineDrawPic(const char *id, const char *pic, int x, int y) {
739 if (!pic || !id) {
740 warning("cineDrawPic: Missing ID or PIC");
741 return;
742 }
743
744 CineCommand *cmd = new CineCommand;
745 cmd->x = x;
746 cmd->y = y;
747 cmd->string = pic;
748 cmd->id = id;
749 cmd->cmdType = C_DRAWPIC;
750 _cine.push_back(cmd);
751 }
752
cineDrawMaskedPic(const char * id,const char * pic,int x,int y)753 void AI::cineDrawMaskedPic(const char *id, const char *pic, int x, int y) {
754 if (!pic || !id) {
755 warning("cineDrawMaskedPic: Missing ID or PIC");
756 return;
757 }
758
759 CineCommand *cmd = new CineCommand;
760 cmd->x = x;
761 cmd->y = y;
762 cmd->string = pic;
763 cmd->id = id;
764 cmd->cmdType = C_DRAWMASKEDPIC;
765 _cine.push_back(cmd);
766 }
767
cineMovePic(const char * id,const char * pic,int x1,int y1,int x2,int y2,int speed)768 void AI::cineMovePic(const char *id, const char *pic, int x1, int y1, int x2, int y2, int speed) {
769 if (!pic || !id) {
770 warning("cineMovePic: Missing ID or PIC");
771 return;
772 }
773
774 CineCommand *cmd = new CineCommand;
775 cmd->x = x1;
776 cmd->y = y1;
777 cmd->x2 = x2;
778 cmd->y2 = y2;
779 cmd->speed = speed;
780 cmd->xv = ((double)(x2-x1)) / (double)speed;
781 cmd->yv = ((double)(y2-y1)) / (double)speed;
782 cmd->start = 0;
783 cmd->string = pic;
784 cmd->id = id;
785 cmd->cmdType = C_MOVEPIC;
786 _cine.push_back(cmd);
787 }
788
cineMoveMaskedPic(const char * id,const char * pic,int x1,int y1,int x2,int y2,int speed)789 void AI::cineMoveMaskedPic(const char *id, const char *pic, int x1, int y1, int x2, int y2, int speed) {
790 if (!pic || !id) {
791 warning("cineMoveMaskedPic: Missing ID or PIC");
792 return;
793 }
794
795 CineCommand *cmd = new CineCommand;
796 cmd->x = x1;
797 cmd->y = y1;
798 cmd->x2 = x2;
799 cmd->y2 = y2;
800 cmd->speed = speed;
801 cmd->xv = ((double)(x2-x1)) / (double)speed;
802 cmd->yv = ((double)(y2-y1)) / (double)speed;
803 cmd->start = 0;
804 cmd->string = pic;
805 cmd->id = id;
806 cmd->cmdType = C_MOVEMASKEDPIC;
807 _cine.push_back(cmd);
808 }
809
cineUse(const char * entName)810 void AI::cineUse(const char *entName) {
811 CineCommand *cmd = new CineCommand;
812 cmd->string = entName;
813 cmd->cmdType = C_USEENTITY;
814 _cine.push_back(cmd);
815 }
816
cinePlaySound(int index)817 void AI::cinePlaySound(int index) {
818 CineCommand *cmd = new CineCommand;
819 cmd->start = index;
820 cmd->cmdType = C_PLAYSOUND;
821 _cine.push_back(cmd);
822 }
823
cinePlayVoice(int index,int actor)824 void AI::cinePlayVoice(int index, int actor) {
825 CineCommand *cmd = new CineCommand;
826 cmd->x = index;
827 cmd->y = actor;
828 cmd->cmdType = C_PLAYVOICE;
829 _cine.push_back(cmd);
830 }
831
cineFadeIn(bool isBlack,int steps)832 void AI::cineFadeIn(bool isBlack, int steps) {
833 CineCommand *cmd = new CineCommand;
834 cmd->speed = steps;
835 cmd->end = (int)isBlack;
836 cmd->start = 0;
837 cmd->cmdType = C_FADEIN;
838 _cine.push_back(cmd);
839 }
840
cineFadeOut(bool isBlack,int steps)841 void AI::cineFadeOut(bool isBlack, int steps) {
842 CineCommand *cmd = new CineCommand;
843 cmd->speed = steps;
844 cmd->end = (int)isBlack;
845 cmd->start = 0;
846 cmd->cmdType = C_FADEOUT;
847 _cine.push_back(cmd);
848 }
849
cineClearForeground(int x,int y)850 void AI::cineClearForeground(int x, int y) {
851 CineCommand *cmd = new CineCommand;
852 cmd->x = x;
853 cmd->y = y;
854 cmd->cmdType = C_CLEAR_FG;
855 _cine.push_back(cmd);
856 }
857
cineSetBackground(int x,int y,int index)858 void AI::cineSetBackground(int x, int y, int index) {
859 CineCommand *cmd = new CineCommand;
860 cmd->x = x;
861 cmd->y = y;
862 cmd->start = index;
863 cmd->cmdType = C_SET_BG;
864 _cine.push_back(cmd);
865 }
866
cineSetForeground(int x,int y,int index)867 void AI::cineSetForeground(int x, int y, int index) {
868 CineCommand *cmd = new CineCommand;
869 cmd->x = x;
870 cmd->y = y;
871 cmd->start = index;
872 cmd->cmdType = C_SET_FG;
873 _cine.push_back(cmd);
874 }
875
cineFunction(const char * func)876 void AI::cineFunction(const char *func) {
877 CineCommand *cmd = new CineCommand;
878 cmd->title = func;
879 cmd->cmdType = C_FUNCTION;
880 _cine.push_back(cmd);
881 }
882
883 } // End of Namespace
884