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 * Originally written by Syn9 in FreeBASIC with SDL
23 * http://syn9.thehideoutgames.com/index_backup.php
24 *
25 * Ported to plain C for GCW-Zero handheld by Dmitry Smagin
26 * http://github.com/dmitrysmagin/griffon_legend
27 *
28 *
29 * Programming/Graphics: Daniel "Syn9" Kennedy
30 * Music/Sound effects: David Turner
31 *
32 * Beta testing and gameplay design help:
33 * Deleter, Cha0s, Aether Fox, and Kiz
34 *
35 */
36
37 #include "griffon/griffon.h"
38 #include "griffon/console.h"
39
40 namespace Griffon {
41
attack()42 void GriffonEngine::attack() {
43 float npx = _player.px + 12;
44 float npy = _player.py + 20;
45
46 int lx = (int)npx / 16;
47 int ly = (int)npy / 16;
48
49 // if facing up
50 if (_player.walkDir == 0) {
51 if (ly > 0) {
52 int o2 = 0; // ??
53 int o = _objectMap[lx][ly - 1];
54 if (ly > 1 && (_curMap == 54 || _curMap == 58))
55 o2 = _objectMap[lx][ly - 2];
56
57 // cst
58 if ((_objectInfo[o].type == 1 && (o == 0 || o > 4)) || (_objectInfo[o2].type == 0 && o2 == 10)) {
59 if (o2 == 10)
60 o = 10;
61
62 int oscript = _objectInfo[o].script;
63 switch (oscript) {
64 case kScriptFlask:
65 if (_player.inventory[kInvFlask] < 9) {
66 _player.inventory[kInvFlask]++;
67 addFloatIcon(6, lx * 16, (ly - 1) * 16);
68
69 _objectMapFull[_curMap][lx][ly - 1] = 1;
70
71 if (config.effects) {
72 int snd = playSound(_sfx[kSndPowerUp]);
73 setChannelVolume(snd, config.effectsVol);
74 }
75
76 if (_objectInfo[o].type == 1)
77 _objectMap[lx][ly - 1] = 3;
78
79 eventText("Found Flask!");
80 } else {
81 if (config.effects) {
82 int snd = playSound(_sfx[kSndChest]);
83 setChannelVolume(snd, config.effectsVol);
84 }
85
86 eventText("Cannot Carry any more Flasks!");
87 }
88 _itemTicks = _ticks + 215;
89 return;
90 break;
91 case kScriptMasterKey:
92 _player.inventory[kInvMasterKey]++;
93
94 addFloatIcon(14, lx * 16, (ly - 1) * 16);
95
96 _itemTicks = _ticks + 215;
97
98 if (_curMap == 34)
99 _scriptFlag[kScriptMasterKey][0] = 2;
100 else if (_curMap == 62)
101 _scriptFlag[kScriptGardenMasterKey][0] = 2;
102 else if (_curMap == 81)
103 _scriptFlag[kScriptCitadelMasterKey][0] = 2;
104
105 if (config.effects) {
106 int snd = playSound(_sfx[kSndPowerUp]);
107 setChannelVolume(snd, config.effectsVol);
108 }
109
110 if (_objectInfo[o].type == 1)
111 _objectMap[lx][ly - 1] = 3;
112 eventText("Found the Temple Key!");
113 return;
114 case kScriptFindCrystal:
115 _player.foundSpell[0] = 1;
116 _player.spellCharge[0] = 0;
117
118 addFloatIcon(7, lx * 16, (ly - 1) * 16);
119
120 if (config.effects) {
121 int snd = playSound(_sfx[kSndPowerUp]);
122 setChannelVolume(snd, config.effectsVol);
123 }
124
125 if (_objectInfo[o].type == 1)
126 _objectMap[lx][ly - 1] = 3;
127
128 eventText("Found the Infinite Crystal!");
129 _itemTicks = _ticks + 215;
130 return;
131 case kScriptFindShield:
132 if (_player.shield == 1) {
133 _player.shield = 2;
134
135 addFloatIcon(4, lx * 16, (ly - 1) * 16);
136
137 _itemTicks = _ticks + 215;
138
139 if (config.effects) {
140 int snd = playSound(_sfx[kSndPowerUp]);
141 setChannelVolume(snd, config.effectsVol);
142 }
143
144 if (_objectInfo[o].type == 1)
145 _objectMap[lx][ly - 1] = 3;
146
147 eventText("Found the Obsidian Shield!");
148 _objectMapFull[4][1][2] = 1;
149 return;
150 }
151 break;
152 case kScriptFindSword:
153 if (_player.sword == 1) {
154 _player.sword = 2;
155
156 addFloatIcon(3, lx * 16, (ly - 1) * 16);
157
158 _itemTicks = _ticks + 215;
159
160 if (config.effects) {
161 int snd = playSound(_sfx[kSndPowerUp]);
162 setChannelVolume(snd, config.effectsVol);
163 }
164
165 if (_objectInfo[o].type == 1)
166 _objectMap[lx][ly - 1] = 3;
167 eventText("Found the Fidelis Sword!");
168 return;
169 }
170 break;
171 case kScriptKeyChest:
172 if (_player.inventory[kInvNormalKey] < 9) {
173 _player.inventory[kInvNormalKey]++;
174
175 for (int s = 20; s <= 23; s++) {
176 if (_scriptFlag[s][0] == 1) {
177 _scriptFlag[s][0] = 2;
178 }
179 }
180
181 if (config.effects) {
182 int snd = playSound(_sfx[kSndPowerUp]);
183 setChannelVolume(snd, config.effectsVol);
184 }
185
186 _objectMapFull[_curMap][lx][ly - 1] = 1;
187
188 if (_objectInfo[o].type == 1)
189 _objectMap[lx][ly - 1] = 3;
190
191 eventText("Found Key");
192 addFloatIcon(16, lx * 16, (ly - 1) * 16);
193 } else {
194 if (config.effects) {
195 int snd = playSound(_sfx[kSndChest]);
196 setChannelVolume(snd, config.effectsVol);
197 }
198
199 eventText("Cannot Carry Any More Keys");
200 }
201 break;
202 case kScriptBlueFlask:
203 if (_player.inventory[kInvDoubleFlask] < 9) {
204 _player.inventory[kInvDoubleFlask]++;
205 addFloatIcon(12, lx * 16, (ly - 1) * 16);
206
207 _objectMapFull[_curMap][lx][ly - 1] = 1;
208
209 if (config.effects) {
210 int snd = playSound(_sfx[kSndPowerUp]);
211 setChannelVolume(snd, config.effectsVol);
212 }
213
214 if (_objectInfo[o].type == 1)
215 _objectMap[lx][ly - 1] = 3;
216
217 eventText("Found Mega Flask!");
218 } else {
219 if (config.effects) {
220 int snd = playSound(_sfx[kSndChest]);
221 setChannelVolume(snd, config.effectsVol);
222 }
223
224 eventText("Cannot Carry any more Mega Flasks!");
225 }
226
227 _itemTicks = _ticks + 215;
228 return;
229 break;
230 case kScriptBlueFlaskChest:
231 if (_player.inventory[kInvDoubleFlask] < 9) {
232 _player.inventory[kInvDoubleFlask]++;
233 addFloatIcon(12, lx * 16, (ly - 1) * 16);
234
235 _objectMapFull[_curMap][lx][ly - 1] = 1;
236
237 if (config.effects) {
238 int snd = playSound(_sfx[kSndPowerUp]);
239 setChannelVolume(snd, config.effectsVol);
240 }
241
242 if (_objectInfo[o].type == 1)
243 _objectMap[lx][ly - 1] = 3;
244
245 eventText("Found Mega Flask!");
246 } else {
247 if (config.effects) {
248 int snd = playSound(_sfx[kSndChest]);
249 setChannelVolume(snd, config.effectsVol);
250 }
251
252 eventText("Cannot Carry any more Mega Flasks!");
253 }
254 _itemTicks = _ticks + 215;
255 return;
256 break;
257 case kScriptLightningChest:
258 if (_player.inventory[kInvShock] < 9) {
259 _player.inventory[kInvShock]++;
260 addFloatIcon(17, lx * 16, (ly - 1) * 16);
261
262 _objectMapFull[_curMap][lx][ly - 1] = 1;
263
264 if (config.effects) {
265 int snd = playSound(_sfx[kSndPowerUp]);
266 setChannelVolume(snd, config.effectsVol);
267 }
268
269 if (_objectInfo[o].type == 1)
270 _objectMap[lx][ly - 1] = 3;
271
272 eventText("Found Lightning Bomb!");
273 } else {
274 if (config.effects) {
275 int snd = playSound(_sfx[kSndChest]);
276 setChannelVolume(snd, config.effectsVol);
277 }
278
279 eventText("Cannot Carry any more Lightning Bombs!");
280 }
281 _itemTicks = _ticks + 215;
282 return;
283 break;
284 case kScriptArmourChest:
285 if (_player.armour == 1) {
286 _player.armour = 2;
287
288 addFloatIcon(5, lx * 16, (ly - 1) * 16);
289
290 if (config.effects) {
291 int snd = playSound(_sfx[kSndPowerUp]);
292 setChannelVolume(snd, config.effectsVol);
293 }
294
295 if (_objectInfo[o].type == 1)
296 _objectMap[lx][ly - 1] = 3;
297
298 eventText("Found the Fidelis Mail!");
299 _itemTicks = _ticks + 215;
300 return;
301 }
302 break;
303 case kScriptLever:
304 if (_curMap == 58 && _scriptFlag[kScriptLever][0] == 0) {
305 _scriptFlag[kScriptLever][0] = 1;
306
307 if (config.effects) {
308 int snd = playSound(_sfx[kSndLever]);
309 setChannelVolume(snd, config.effectsVol);
310 }
311 } else if (_curMap == 58 && _scriptFlag[kScriptLever][0] > 0) {
312 if (config.effects) {
313 int snd = playSound(_sfx[kSndDoor]);
314 setChannelVolume(snd, config.effectsVol);
315 }
316
317 eventText("It's stuck!");
318 } else if (_curMap == 54 && _scriptFlag[kScriptLever][0] == 1) {
319 if (config.effects) {
320 int snd = playSound(_sfx[kSndLever]);
321 setChannelVolume(snd, config.effectsVol);
322 }
323
324 _scriptFlag[kScriptLever][0] = 2;
325 } else if (_curMap == 54 && _scriptFlag[kScriptLever][0] > 1) {
326 if (config.effects) {
327 int snd = playSound(_sfx[kSndDoor]);
328 setChannelVolume(snd, config.effectsVol);
329 }
330
331 eventText("It's stuck!");
332 }
333 break;
334 case kScriptGetSword3:
335 if (_player.sword < 3) {
336 _player.sword = 3;
337
338 addFloatIcon(18, lx * 16, (ly - 1) * 16);
339
340 _itemTicks = _ticks + 215;
341
342 if (config.effects) {
343 int snd = playSound(_sfx[kSndPowerUp]);
344 setChannelVolume(snd, config.effectsVol);
345 }
346
347 if (_objectInfo[o].type == 1)
348 _objectMap[lx][ly - 1] = 3;
349 eventText("Found the Blood Sword!");
350 _objectMapFull[4][1][2] = 1;
351 return;
352 }
353 break;
354 case kScriptShield3:
355 if (_player.shield < 3) {
356 _player.shield = 3;
357 addFloatIcon(19, lx * 16, (ly - 1) * 16);
358 _itemTicks = _ticks + 215;
359
360 if (config.effects) {
361 int snd = playSound(_sfx[kSndPowerUp]);
362 setChannelVolume(snd, config.effectsVol);
363 }
364
365 if (_objectInfo[o].type == 1)
366 _objectMap[lx][ly - 1] = 3;
367 eventText("Found the Entropy Shield!");
368 _objectMapFull[4][1][2] = 1;
369 return;
370 }
371 break;
372 case kScriptArmour3:
373 if (_player.armour < 3) {
374 _player.armour = 3;
375 addFloatIcon(20, lx * 16, (ly - 1) * 16);
376 _itemTicks = _ticks + 215;
377
378 if (config.effects) {
379 int snd = playSound(_sfx[kSndPowerUp]);
380 setChannelVolume(snd, config.effectsVol);
381 }
382
383 if (_objectInfo[o].type == 1)
384 _objectMap[lx][ly - 1] = 3;
385 eventText("Found the Rubyscale Armour!");
386 _objectMapFull[4][1][2] = 1;
387 return;
388 }
389 break;
390 default:
391 break;
392 }
393 }
394 }
395 }
396
397 _attacking = true;
398 _player.attackFrame = 0;
399 _movingUp = false;
400 _movingDown = false;
401 _movingLeft = false;
402 _movingRight = false;
403
404 for (int i = 0; i <= 15; i++) {
405 for (int a = 0; a <= 3; a++) {
406 _playerAttackOfs[a][i].completed = false;
407 }
408 }
409 }
410
castSpell(int spellnum,float homex,float homey,float enemyx,float enemyy,int damagewho)411 void GriffonEngine::castSpell(int spellnum, float homex, float homey, float enemyx, float enemyy, int damagewho) {
412 // spellnum 7 = sprite 6 spitfire
413
414 for (int i = 0; i < kMaxSpell; i++) {
415 if (ABS(_spellInfo[i].frame) < kEpsilon) {
416 _spellInfo[i].homex = homex;
417 _spellInfo[i].homey = homey;
418 _spellInfo[i].enemyx = enemyx;
419 _spellInfo[i].enemyy = enemyy;
420 _spellInfo[i].spellnum = spellnum;
421 int dw = 0;
422 int npc = 0;
423 if (damagewho > 0) {
424 dw = 1;
425 npc = damagewho;
426 }
427
428 _spellInfo[i].damagewho = dw;
429 _spellInfo[i].npc = npc;
430
431 _spellInfo[i].frame = 32.0f;
432 if (damagewho == 0) {
433 _spellInfo[i].strength = _player.spellStrength / 100;
434 if (ABS(_player.spellStrength - 100) < kEpsilon)
435 _spellInfo[i].strength = 1.5f;
436 }
437
438 switch(spellnum) {
439 case 1:
440 if (config.effects) {
441 int snd = playSound(_sfx[kSndThrow]);
442 setChannelVolume(snd, config.effectsVol);
443 }
444 break;
445 case 2:
446 // set earthslide vars
447 for (int f = 0; f <= 8; f++) {
448 _spellInfo[i].rocky[f] = 0;
449 _spellInfo[i].rockimg[f] = (int)(RND() * 4);
450 _spellInfo[i].rockdeflect[f] = ((int)(RND() * 128) - 64) * 1.5;
451 }
452 break;
453 case 3:
454 // set fire vars
455 for (int f = 0; f <= 4; f++)
456 _spellInfo[i].legalive[f] = 32;
457
458 break;
459 case 5:
460 if (config.effects) {
461 int snd = playSound(_sfx[kSndCrystal]);
462 setChannelVolume(snd, config.effectsVol);
463 }
464 break;
465 case 6: {
466 // room fireball vars
467 int nballs = 0;
468 for (int x = 0; x <= 19; x++) {
469 for (int y = 0; y <= 14; y++) {
470 if ((_objectMap[x][y] == 1 || _objectMap[x][y] == 2) && nballs < 5 && (int)(RND() * 4) == 0) {
471 int ax = x * 16;
472 int ay = y * 16;
473
474 _spellInfo[i].fireballs[nballs][0] = ax;
475 _spellInfo[i].fireballs[nballs][1] = ay;
476 _spellInfo[i].fireballs[nballs][2] = 0;
477 _spellInfo[i].fireballs[nballs][3] = 0;
478
479 _spellInfo[i].ballon[nballs] = 1;
480 ++nballs;
481 }
482 }
483 }
484 _spellInfo[i].nfballs = nballs;
485 }
486 break;
487 case 8:
488 case 9:
489 if (config.effects) {
490 int snd = playSound(_sfx[kSndLightning]);
491 setChannelVolume(snd, config.effectsVol);
492 }
493 break;
494 default:
495 break;
496 }
497
498 return;
499 }
500 }
501 }
502
checkHit()503 void GriffonEngine::checkHit() {
504 if (_attacking) {
505 for (int i = 1; i <= _lastNpc; i++) {
506 if (_npcInfo[i].hp > 0 && _npcInfo[i].pause < _ticks && (int)(RND() * 2) == 0) {
507 float npx = _npcInfo[i].x;
508 float npy = _npcInfo[i].y;
509
510 float xdif = _player.px - npx;
511 float ydif = _player.py - npy;
512
513 float ps = _player.sword;
514 if (ps > 1)
515 ps *= 0.75;
516 float damage = (float)_player.swordDamage * (1.0 + RND() * 1.0) * _player.attackStrength / 100.0 * ps;
517
518 if (_console->_godMode == kGodModeAll)
519 damage = 1000;
520
521 if (ABS(_player.attackStrength - 100) < kEpsilon)
522 damage *= 1.5;
523
524 bool hit = false;
525 if (_player.walkDir == 0) {
526 if (ABS(xdif) <= 8 && ydif >= 0 && ydif < 8)
527 hit = true;
528 } else if (_player.walkDir == 1) {
529 if (ABS(xdif) <= 8 && ydif <= 0 && ydif > -8)
530 hit = true;
531 } else if (_player.walkDir == 2) {
532 if (ABS(ydif) <= 8 && xdif >= -8 && xdif < 8)
533 hit = true;
534 } else if (_player.walkDir == 3) {
535 if (ABS(ydif) <= 8 && xdif <= 8 && xdif > -8)
536 hit = true;
537 }
538
539 if (hit) {
540 if (config.effects) {
541 int snd = playSound(_sfx[kSndSwordHit]);
542 setChannelVolume(snd, config.effectsVol);
543 }
544
545 damageNPC(i, damage, 0);
546 }
547 }
548 }
549 }
550 }
551
damageNPC(int npcnum,int damage,int spell)552 void GriffonEngine::damageNPC(int npcnum, int damage, int spell) {
553 char line[256];
554 int fcol;
555
556 if (damage == 0) {
557 strcpy(line, "miss!");
558 fcol = 2;
559 } else {
560 int ratio = 0;
561 int heal = 0;
562 if (damage < 0)
563 heal = 1;
564 damage = ABS(damage);
565
566 if (heal == 0) {
567 if (damage > _npcInfo[npcnum].hp) {
568 ratio = (damage - _npcInfo[npcnum].hp) * 100 / damage;
569 damage = _npcInfo[npcnum].hp;
570 }
571
572 _npcInfo[npcnum].hp -= damage;
573 if (_npcInfo[npcnum].hp < 0)
574 _npcInfo[npcnum].hp = 0;
575
576 sprintf(line, "-%i", damage);
577 fcol = 1;
578 } else {
579 _npcInfo[npcnum].hp += damage;
580 if (_npcInfo[npcnum].hp > _npcInfo[npcnum].maxhp)
581 _npcInfo[npcnum].hp = _npcInfo[npcnum].maxhp;
582
583 sprintf(line, "+%i", damage);
584 fcol = 5;
585 }
586
587 _npcInfo[npcnum].pause = _ticks + 900;
588
589 if (spell == 0)
590 _player.attackStrength = ratio;
591 }
592
593 addFloatText(line, _npcInfo[npcnum].x + 12 - 4 * strlen(line), _npcInfo[npcnum].y + 16, fcol);
594
595 if (_npcInfo[npcnum].spriteset == kMonsterBatKitty)
596 castSpell(9, _npcInfo[npcnum].x, _npcInfo[npcnum].y, _player.px, _player.py, npcnum);
597
598 // if enemy is killed
599 if (_npcInfo[npcnum].hp == 0) {
600 _player.exp += _npcInfo[npcnum].maxhp;
601
602 if (_npcInfo[npcnum].spriteset == kMonsterBabyDragon || _npcInfo[npcnum].spriteset == kMonsterPriest ||
603 _npcInfo[npcnum].spriteset == kMonsterRedDragon) {
604 int ff = (int)(RND() * _player.level * 3);
605 if (ff == 0) {
606 float npx = _npcInfo[npcnum].x + 12;
607 float npy = _npcInfo[npcnum].y + 20;
608
609 int lx = (int)npx / 16;
610 int ly = (int)npy / 16;
611
612 if (_objectMap[lx][ly] == -1)
613 _objectMap[lx][ly] = 4;
614 }
615 }
616
617 if (_npcInfo[npcnum].spriteset == kMonsterOneWing || _npcInfo[npcnum].spriteset == kMonsterTwoWing ||
618 _npcInfo[npcnum].spriteset == kMonsterBlackKnight || _npcInfo[npcnum].spriteset == kMonsterFireHydra) {
619 int ff = (int)(RND() * _player.level);
620 if (ff == 0) {
621 float npx = _npcInfo[npcnum].x + 12;
622 float npy = _npcInfo[npcnum].y + 20;
623
624 int lx = (int)npx / 16;
625 int ly = (int)npy / 16;
626
627 if (_objectMap[lx][ly] == -1)
628 _objectMap[lx][ly] = 12;
629 }
630 }
631
632 if (_npcInfo[npcnum].spriteset == kMonsterTwoWing || _npcInfo[npcnum].spriteset == kMonsterDragon2 ||
633 _npcInfo[npcnum].spriteset == kMonsterFireHydra) {
634 int ff = (int)(RND() * _player.level * 2);
635 if (ff == 0) {
636 float npx = _npcInfo[npcnum].x + 12;
637 float npy = _npcInfo[npcnum].y + 20;
638
639 int lx = (int)npx / 16;
640 int ly = (int)npy / 16;
641
642 if (_objectMap[lx][ly] == -1)
643 _objectMap[lx][ly] = 13;
644 }
645 }
646
647 // academy master key chest script
648 if (_npcInfo[npcnum].script == kScriptMasterKey) {
649 bool alive = false;
650 for (int i = 1; i <= _lastNpc; i++) {
651 if (_npcInfo[i].hp > 0)
652 alive = true;
653 }
654
655 if (!alive) {
656 int cx = 9;
657 int cy = 7;
658
659 _objectMap[cx][cy] = 5;
660
661 rcDest.left = cx * 8;
662 rcDest.top = cy * 8;
663 rcDest.setWidth(8);
664 rcDest.setHeight(8);
665
666 float npx = _player.px + 12;
667 float npy = _player.py + 20;
668
669 int lx = (int)npx / 16;
670 int ly = (int)npy / 16;
671
672 if (lx == cx && ly == cy)
673 _player.py += 16;
674 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
675 _scriptFlag[kScriptMasterKey][0] = 1;
676 }
677 }
678
679 // academy crystal chest script
680 if (_npcInfo[npcnum].script == kScriptFindCrystal) {
681 bool alive = false;
682 for (int i = 1; i <= _lastNpc; i++) {
683 if (_npcInfo[i].hp > 0)
684 alive = true;
685 }
686
687 if (!alive) {
688 int cx = 9;
689 int cy = 7;
690
691 _objectMap[cx][cy] = 6;
692
693 rcDest.left = cx * 8;
694 rcDest.top = cy * 8;
695 rcDest.setWidth(8);
696 rcDest.setHeight(8);
697
698 float npx = _player.px + 12;
699 float npy = _player.py + 20;
700
701 int lx = (int)npx / 16;
702 int ly = (int)npy / 16;
703
704 if (lx == cx && ly == cy)
705 _player.py += 16;
706 _scriptFlag[kScriptFindCrystal][0] = 1;
707 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
708 }
709 }
710
711 // tower shield chest script
712 if (_npcInfo[npcnum].script == kScriptFindShield && _scriptFlag[kScriptFindShield][0] == 0) {
713 _triggerLoc[9][7] = 5004;
714
715 int curTile = 40;
716 int curTileL = 0;
717 int curTileX = curTile % 20;
718 int curTileY = (curTile - curTileX) / 20;
719
720 int l = 0; // ?? not defined in original code
721 _tileinfo[l][9][7][0] = curTile + 1;
722 _tileinfo[l][9][7][1] = 0;
723
724 rcSrc.left = curTileX * 16;
725 rcSrc.top = curTileY * 16;
726 rcSrc.setWidth(16);
727 rcSrc.setHeight(16);
728
729 rcDest.left = 9 * 16;
730 rcDest.top = 7 * 16;
731 rcDest.setWidth(16);
732 rcDest.setHeight(16);
733
734 _tiles[curTileL]->blit(*_mapBg, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc);
735 }
736
737 // firehydra sword chest
738 if (_npcInfo[npcnum].script == kScriptFindSword) {
739 bool alive = false;
740 for (int i = 1; i <= _lastNpc; i++) {
741 if (_npcInfo[i].hp > 0)
742 alive = true;
743 }
744
745 if (!alive) {
746 int cx = 9;
747 int cy = 6;
748
749 _objectMap[cx][cy] = 9;
750
751 rcDest.left = cx * 8;
752 rcDest.top = cy * 8;
753 rcDest.setWidth(8);
754 rcDest.setHeight(8);
755
756 float npx = _player.px + 12;
757 float npy = _player.py + 20;
758
759 int lx = (int)npx / 16;
760 int ly = (int)npy / 16;
761
762 if (lx == cx && ly == cy)
763 _player.py += 16;
764 _scriptFlag[kScriptFindSword][0] = 1;
765 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
766 }
767
768 }
769
770 // gardens master key script
771 if (_npcInfo[npcnum].script == kScriptGardenMasterKey && _scriptFlag[kScriptKeyChest][0] == 0) {
772 bool alive = false;
773 for (int i = 1; i <= _lastNpc; i++) {
774 if (_npcInfo[i].hp > 0)
775 alive = true;
776 }
777
778 if (!alive) {
779 int cx = 13;
780 int cy = 7;
781
782 _objectMap[cx][cy] = 5;
783
784 rcDest.left = cx * 8;
785 rcDest.top = cy * 8;
786 rcDest.setWidth(8);
787 rcDest.setHeight(8);
788
789 float npx = _player.px + 12;
790 float npy = _player.py + 20;
791
792 int lx = (int)npx / 16;
793 int ly = (int)npy / 16;
794
795 if (lx == cx && ly == cy)
796 _player.py += 16;
797 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
798 _scriptFlag[kScriptGardenMasterKey][0] = 1;
799 }
800 }
801
802 // regular key chest 1
803 for (int s = 20; s <= 23; s++) {
804 if (_npcInfo[npcnum].script == s && _scriptFlag[s][0] < 2) {
805 bool alive = false;
806 for (int i = 1; i <= _lastNpc; i++) {
807 if (_npcInfo[i].hp > 0)
808 alive = true;
809 }
810
811 if (!alive) {
812 int cx = 9;
813 int cy = 7;
814
815 _objectMap[cx][cy] = 11;
816
817 rcDest.left = cx * 8;
818 rcDest.top = cy * 8;
819 rcDest.setWidth(8);
820 rcDest.setHeight(8);
821
822 float npx = _player.px + 12;
823 float npy = _player.py + 20;
824
825 int lx = (int)npx / 16;
826 int ly = (int)npy / 16;
827
828 if (lx == cx && ly == cy)
829 _player.py += 16;
830 _scriptFlag[s][0] = 1;
831 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
832 }
833 }
834 }
835
836 // pickup lightning bomb
837 if (_npcInfo[npcnum].script == kScriptLightningBomb && (_curMap == 41 && _scriptFlag[kScriptLightningBomb][1] == 0)) {
838 bool alive = false;
839 for (int i = 1; i <= _lastNpc; i++) {
840 if (_npcInfo[i].hp > 0)
841 alive = true;
842 }
843
844 if (!alive) {
845 int cx = 9;
846 int cy = 7;
847
848 _objectMap[cx][cy] = 13;
849
850 rcDest.left = cx * 8;
851 rcDest.top = cy * 8;
852 rcDest.setWidth(8);
853 rcDest.setHeight(8);
854
855 float npx = _player.px + 12;
856 float npy = _player.py + 20;
857
858 int lx = (int)npx / 16;
859 int ly = (int)npy / 16;
860
861 if (lx == cx && ly == cy)
862 _player.py += 16;
863 }
864 }
865
866 // citadel armour chest
867 if (_npcInfo[npcnum].script == kScriptArmourChest) {
868 bool alive = false;
869 for (int i = 1; i <= _lastNpc; i++) {
870 if (_npcInfo[i].hp > 0)
871 alive = true;
872 }
873
874 if (!alive) {
875 int cx = 8;
876 int cy = 7;
877
878 _objectMap[cx][cy] = 16;
879
880 rcDest.left = cx * 8;
881 rcDest.top = cy * 8;
882 rcDest.setWidth(8);
883 rcDest.setHeight(8);
884
885 float npx = _player.px + 12;
886 float npy = _player.py + 20;
887
888 int lx = (int)npx / 16;
889 int ly = (int)npy / 16;
890
891 if (lx == cx && ly == cy)
892 _player.py += 16;
893 _scriptFlag[kScriptArmourChest][0] = 1;
894 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
895 }
896 }
897
898 // citadel master key script
899 if (_npcInfo[npcnum].script == kScriptCitadelMasterKey && _scriptFlag[kScriptCitadelMasterKey][0] == 0) {
900 bool alive = false;
901 for (int i = 1; i <= _lastNpc; i++) {
902 if (_npcInfo[i].hp > 0)
903 alive = true;
904 }
905
906 if (!alive) {
907 int cx = 11;
908 int cy = 10;
909
910 _objectMap[cx][cy] = 5;
911
912 rcDest.left = cx * 8;
913 rcDest.top = cy * 8;
914 rcDest.setWidth(8);
915 rcDest.setHeight(8);
916
917 float npx = _player.px + 12;
918 float npy = _player.py + 20;
919
920 int lx = (int)npx / 16;
921 int ly = (int)npy / 16;
922
923 if (lx == cx && ly == cy)
924 _player.py += 16;
925 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
926 _scriptFlag[kScriptCitadelMasterKey][0] = 1;
927 }
928 }
929
930 // max ups
931 if (_npcInfo[npcnum].script == kScriptGetSword3 && _scriptFlag[kScriptGetSword3][0] == 0) {
932 bool alive = false;
933 for (int i = 1; i <= _lastNpc; i++) {
934 if (_npcInfo[i].hp > 0)
935 alive = true;
936 }
937
938 if (!alive) {
939 int cx = 6;
940 int cy = 8;
941
942 _objectMap[cx][cy] = 18;
943
944 rcDest.left = cx * 8;
945 rcDest.top = cy * 8;
946 rcDest.setWidth(8);
947 rcDest.setHeight(8);
948
949 float npx = _player.px + 12;
950 float npy = _player.py + 20;
951
952 int lx = (int)npx / 16;
953 int ly = (int)npy / 16;
954
955 if (lx == cx && ly == cy)
956 _player.py += 16;
957 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
958 _scriptFlag[kScriptGetSword3][0] = 1;
959
960 cx = 9;
961 cy = 8;
962
963 _objectMap[cx][cy] = 19;
964
965 rcDest.left = cx * 8;
966 rcDest.top = cy * 8;
967 rcDest.setWidth(8);
968 rcDest.setHeight(8);
969
970 npx = _player.px + 12;
971 npy = _player.py + 20;
972
973 lx = (int)npx / 16;
974 ly = (int)npy / 16;
975
976 if (lx == cx && ly == cy)
977 _player.py += 16;
978 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
979
980 _scriptFlag[kScriptShield3][0] = 1;
981
982 cx = 12;
983 cy = 8;
984
985 _objectMap[cx][cy] = 20;
986
987 rcDest.left = cx * 8;
988 rcDest.top = cy * 8;
989 rcDest.setWidth(8);
990 rcDest.setHeight(8);
991
992 npx = _player.px + 12;
993 npy = _player.py + 20;
994
995 lx = (int)npx / 16;
996 ly = (int)npy / 16;
997
998 if (lx == cx && ly == cy)
999 _player.py += 16;
1000 _clipBg2->fillRect(rcDest, _clipBg->format.RGBToColor(255, 255, 255));
1001 _scriptFlag[kScriptArmour3][0] = 1;
1002 }
1003 }
1004
1005 if (_npcInfo[npcnum].script == kScriptEndOfGame) {
1006 endOfGame();
1007 _gameMode = kGameModeIntro;
1008 }
1009 }
1010 }
1011
damagePlayer(int damage)1012 void GriffonEngine::damagePlayer(int damage) {
1013 char line[256];
1014
1015 if (_console->_godMode != kGodModeNone)
1016 damage = 0;
1017
1018 _player.hp -= damage;
1019
1020 if (_player.hp < 0)
1021 _player.hp = 0;
1022
1023 sprintf(line, "-%i", damage);
1024 if (damage == 0)
1025 strcpy(line, "miss!");
1026
1027 addFloatText(line, _player.px + 12 - 4 * strlen(line), _player.py + 16, 4);
1028
1029 _player.pause = _ticks + 1000;
1030 }
1031
1032
1033 } // end of namespace Griffon
1034