mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 03:10:22 +00:00
2355 lines
68 KiB
C++
2355 lines
68 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*
|
|
* Originally written by Syn9 in FreeBASIC with SDL
|
|
* http://syn9.thehideoutgames.com/index_backup.php
|
|
*
|
|
* Ported to plain C for GCW-Zero handheld by Dmitry Smagin
|
|
* http://github.com/dmitrysmagin/griffon_legend
|
|
*
|
|
*
|
|
* Programming/Graphics: Daniel "Syn9" Kennedy
|
|
* Music/Sound effects: David Turner
|
|
*
|
|
* Beta testing and gameplay design help:
|
|
* Deleter, Cha0s, Aether Fox, and Kiz
|
|
*
|
|
*/
|
|
|
|
#include "griffon/griffon.h"
|
|
|
|
namespace Griffon {
|
|
|
|
// memo
|
|
|
|
/*
|
|
chests
|
|
0 - regular flask
|
|
11 - key chest
|
|
14 - blue flask chest
|
|
15 - lightning chest
|
|
16 - armour chest
|
|
17 - citadel master key
|
|
18 - sword3
|
|
19 - shield3
|
|
20 - armour3
|
|
|
|
*/
|
|
|
|
// element tile locations
|
|
const int8 elementmap[15][20] = {
|
|
{ 2, 2, 2, 2, -1, -1, -1, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ 2, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ 2, -1, 2, 2, -1, -1, -1, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ 2, -1, 2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ 2, 2, 2, 2, 2, -1, -1, -1, 2, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, 2, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, 0, 0, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
|
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
|
|
};
|
|
|
|
|
|
void GriffonEngine::updateAnims() {
|
|
for (int i = 0; i <= _lastObj; i++) {
|
|
int nFrames = _objectInfo[i].nFrames;
|
|
int objAnimSpeed = _objectInfo[i].speed;
|
|
float frame = _objectFrame[i][0];
|
|
|
|
if (nFrames > 1) {
|
|
frame += objAnimSpeed / 50 * _fpsr;
|
|
while (frame >= nFrames)
|
|
frame -= nFrames;
|
|
|
|
int cframe = (int)frame; // truncate fractional part
|
|
if (cframe < 0)
|
|
cframe = 0;
|
|
|
|
_objectFrame[i][0] = frame;
|
|
_objectFrame[i][1] = cframe;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GriffonEngine::updateY() {
|
|
for (int i = 0; i <= 2400; i++)
|
|
_ysort[i] = -1;
|
|
|
|
int ff = (int)(_player.py * 10);
|
|
if (ff < 0) // HACKFIX or _ysort[yy] may go out of bounds
|
|
ff = 0;
|
|
_player.ysort = ff;
|
|
_ysort[ff] = 0;
|
|
|
|
_firsty = 2400;
|
|
_lasty = 0;
|
|
|
|
for (int i = 1; i <= _lastNpc; i++) {
|
|
if (!_npcInfo[i].onMap)
|
|
continue;
|
|
|
|
int yy = (int)(_npcInfo[i].y * 10);
|
|
|
|
do {
|
|
if (_ysort[yy] == -1 || yy == 2400)
|
|
break;
|
|
++yy;
|
|
} while (1);
|
|
|
|
_ysort[yy] = i;
|
|
if (yy < _firsty)
|
|
_firsty = yy;
|
|
if (yy > _lasty)
|
|
_lasty = yy;
|
|
}
|
|
}
|
|
|
|
void GriffonEngine::updateNPCs() {
|
|
for (int i = 1; i <= _lastNpc; i++) {
|
|
if (_npcInfo[i].hp > 0) {
|
|
// is npc walking
|
|
int pass = 0;
|
|
if (!_npcInfo[i].attacking)
|
|
pass = 1;
|
|
if (_npcInfo[i].spriteset == kMonsterFireHydra)
|
|
pass = 1;
|
|
if (pass == 1) {
|
|
bool moveup = false;
|
|
bool movedown = false;
|
|
bool moveleft = false;
|
|
bool moveright = false;
|
|
|
|
float npx = _npcInfo[i].x;
|
|
float npy = _npcInfo[i].y;
|
|
|
|
float onpx = npx;
|
|
float onpy = npy;
|
|
|
|
float wspd = _npcInfo[i].walkspd / 4;
|
|
|
|
if (_npcInfo[i].spriteset == kMonsterDragon2)
|
|
wspd = wspd * 2;
|
|
int wdir = _npcInfo[i].walkdir;
|
|
|
|
int mode = _npcInfo[i].movementmode;
|
|
|
|
float xdif = _player.px - npx;
|
|
float ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 4 * 16 && ABS(ydif) < 4 * 16 && mode < 3)
|
|
mode = 0;
|
|
if (_npcInfo[i].hp < _npcInfo[i].maxhp * 0.25)
|
|
mode = 3;
|
|
|
|
if (_npcInfo[i].pause > _ticks)
|
|
mode = -1;
|
|
if (_npcInfo[i].spriteset == kMonsterOneWing && _npcInfo[i].castPause > _ticks)
|
|
mode = -1;
|
|
|
|
if (mode == 3) {
|
|
mode = 1;
|
|
if (ABS(xdif) < 4 * 16 && ABS(ydif) < 4 * 16)
|
|
mode = 3;
|
|
}
|
|
|
|
bool checkpass = false;
|
|
|
|
// npc AI CODE
|
|
// --------------
|
|
|
|
// *** aggressive
|
|
if (mode == 0) {
|
|
wspd = _npcInfo[i].walkspd / 2;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) > ABS(ydif)) {
|
|
if (xdif < 4)
|
|
wdir = 2;
|
|
if (xdif > -4)
|
|
wdir = 3;
|
|
} else {
|
|
if (ydif < 4)
|
|
wdir = 0;
|
|
if (ydif > -4)
|
|
wdir = 1;
|
|
}
|
|
|
|
if (xdif < 4)
|
|
moveleft = true;
|
|
if (xdif > -4)
|
|
moveright = true;
|
|
if (ydif < 4)
|
|
moveup = true;
|
|
if (ydif > -4)
|
|
movedown = true;
|
|
}
|
|
// *******************
|
|
|
|
// *** defensive
|
|
if (mode == 1) {
|
|
|
|
int movingdir = _npcInfo[i].movingdir;
|
|
|
|
if (_npcInfo[i].ticks > _ticks + 100000)
|
|
_npcInfo[i].ticks = _ticks;
|
|
|
|
if (_npcInfo[i].ticks < _ticks) {
|
|
_npcInfo[i].ticks = _ticks + 2000;
|
|
movingdir = (int)(RND() * 8);
|
|
_npcInfo[i].movingdir = movingdir;
|
|
}
|
|
|
|
if (movingdir == 0) {
|
|
wdir = 2; // left
|
|
moveup = true;
|
|
moveleft = true;
|
|
} else if (movingdir == 1) {
|
|
wdir = 0; // up
|
|
moveup = true;
|
|
} else if (movingdir == 2) {
|
|
wdir = 3; // right
|
|
moveup = true;
|
|
moveright = true;
|
|
} else if (movingdir == 3) {
|
|
wdir = 3; // right
|
|
moveright = true;
|
|
} else if (movingdir == 4) {
|
|
wdir = 3; // right
|
|
moveright = true;
|
|
movedown = true;
|
|
} else if (movingdir == 5) {
|
|
wdir = 1; // down
|
|
movedown = true;
|
|
} else if (movingdir == 6) {
|
|
wdir = 2; // left
|
|
movedown = true;
|
|
moveleft = true;
|
|
} else if (movingdir == 7) {
|
|
wdir = 2; // left
|
|
moveleft = true;
|
|
}
|
|
|
|
checkpass = true;
|
|
}
|
|
// *******************
|
|
|
|
// *** run away
|
|
if (mode == 3) {
|
|
wspd = _npcInfo[i].walkspd / 2;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) > ABS(ydif)) {
|
|
if (xdif < 4)
|
|
wdir = 3;
|
|
if (xdif > -4)
|
|
wdir = 2;
|
|
} else {
|
|
if (ydif < 4)
|
|
wdir = 1;
|
|
if (ydif > -4)
|
|
wdir = 0;
|
|
}
|
|
|
|
if (xdif < 4)
|
|
moveright = true;
|
|
if (xdif > -4)
|
|
moveleft = true;
|
|
if (ydif < 4)
|
|
movedown = true;
|
|
if (ydif > -4)
|
|
moveup = true;
|
|
}
|
|
// *******************
|
|
|
|
// -------------- ?? move*** vs movin***
|
|
bool movinup = false;
|
|
bool movindown = false;
|
|
bool movinleft = false;
|
|
bool movinright = false;
|
|
|
|
float xp = (npx / 2 + 6);
|
|
float yp = (npy / 2 + 10);
|
|
|
|
if (_npcInfo[i].spriteset == kMonsterDragon2)
|
|
wspd = wspd * 2;
|
|
|
|
float ii = wspd * _fpsr;
|
|
if (ii < 1)
|
|
ii = 1;
|
|
|
|
if (moveup) {
|
|
int sx = xp;
|
|
int sy = yp - ii;
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
|
|
if (dq == 0)
|
|
movinup = true;
|
|
if (dq > 0) {
|
|
sx = xp - ii;
|
|
sy = yp - ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinup = true;
|
|
movinleft = true;
|
|
}
|
|
}
|
|
if (dq > 0) {
|
|
sx = xp + ii;
|
|
sy = yp - ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinup = true;
|
|
movinright = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (movedown) {
|
|
int sx = xp;
|
|
int sy = yp + ii;
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0)
|
|
movindown = true;
|
|
if (dq > 0) {
|
|
sx = xp - ii;
|
|
sy = yp + ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movindown = true;
|
|
movinleft = true;
|
|
}
|
|
}
|
|
if (dq > 0) {
|
|
sx = xp + ii;
|
|
sy = yp + ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movindown = true;
|
|
movinright = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (moveleft) {
|
|
int sx = xp - ii;
|
|
int sy = yp;
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0)
|
|
movinleft = true;
|
|
if (dq > 0) {
|
|
sx = xp - ii;
|
|
sy = yp - ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinleft = true;
|
|
movinup = true;
|
|
}
|
|
}
|
|
if (dq > 0) {
|
|
sx = xp - ii;
|
|
sy = yp + ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinleft = true;
|
|
movindown = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (moveright) {
|
|
int sx = xp + ii;
|
|
int sy = yp;
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0)
|
|
movinright = true;
|
|
if (dq > 0) {
|
|
sx = xp + ii;
|
|
sy = yp - ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinright = true;
|
|
movinup = true;
|
|
}
|
|
}
|
|
if (dq > 0) {
|
|
sx = xp + ii;
|
|
sy = yp + ii;
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
dq = 0;
|
|
if (dq == 0) {
|
|
movinright = true;
|
|
movindown = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (movinup)
|
|
npy -= wspd * _fpsr;
|
|
if (movindown)
|
|
npy += wspd * _fpsr;
|
|
if (movinleft)
|
|
npx -= wspd * _fpsr;
|
|
if (movinright)
|
|
npx += wspd * _fpsr;
|
|
|
|
if (checkpass) {
|
|
pass = 0;
|
|
if (npx >= _npcInfo[i].x1 * 16 - 8 && npx <= _npcInfo[i].x2 * 16 + 8 && npy >= _npcInfo[i].y1 * 16 - 8 && npy <= _npcInfo[i].y2 * 16 + 8)
|
|
pass = 1;
|
|
if (pass == 0) {
|
|
npx = onpx;
|
|
npy = onpy;
|
|
_npcInfo[i].ticks = _ticks;
|
|
}
|
|
}
|
|
|
|
float aspd = wspd;
|
|
|
|
if (_npcInfo[i].spriteset == kMonsterDragon2)
|
|
aspd = wspd / 2;
|
|
|
|
xp = (npx / 2 + 6);
|
|
yp = (npy / 2 + 10);
|
|
|
|
int sx = xp;
|
|
int sy = yp;
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 bgc = *temp;
|
|
|
|
float anpx = npx + 12;
|
|
float anpy = npy + 20;
|
|
|
|
int lx = (int)anpx / 16;
|
|
int ly = (int)anpy / 16;
|
|
|
|
if (_triggerLoc[lx][ly] > -1)
|
|
bgc = 1;
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss)
|
|
bgc = 0;
|
|
|
|
bool rst = false;
|
|
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss) {
|
|
if (npx < 40 || npx > 280 || npy < 36 || npy > 204)
|
|
rst = true;
|
|
}
|
|
|
|
if (bgc > 0 || rst) {
|
|
npx = onpx;
|
|
npy = onpy;
|
|
}
|
|
|
|
_npcInfo[i].x = npx;
|
|
_npcInfo[i].y = npy;
|
|
|
|
_npcInfo[i].walkdir = wdir;
|
|
_npcInfo[i].moving = false;
|
|
|
|
if (npx != onpx || npy != onpy)
|
|
_npcInfo[i].moving = true;
|
|
|
|
if (_npcInfo[i].moving) {
|
|
float frame = _npcInfo[i].frame;
|
|
|
|
frame += aspd * _fpsr;
|
|
while (frame >= 16)
|
|
frame -= 16;
|
|
|
|
int cframe = (int)(frame);
|
|
if (cframe < 0)
|
|
cframe = 0;
|
|
|
|
_npcInfo[i].frame = frame;
|
|
_npcInfo[i].cframe = cframe;
|
|
}
|
|
|
|
// spriteset1 specific
|
|
if (_npcInfo[i].spriteset == kMonsterBabyDragon && _npcInfo[i].attackattempt < _ticks) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 20 && ABS(ydif) < 20) {
|
|
_npcInfo[i].attackattempt = _ticks + 100;
|
|
if ((int)(RND() * 2) == 0) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndEnemyHit]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool dospell = false;
|
|
|
|
// onewing specific
|
|
if (_npcInfo[i].spriteset == kMonsterOneWing) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 24 && ABS(ydif) < 24) {
|
|
float dist = sqrt(xdif * xdif + ydif * ydif);
|
|
|
|
if ((dist) < 24) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndBite]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
|
|
_npcInfo[i].headTargetX[0] = _player.px + 12;
|
|
_npcInfo[i].headTargetY[0] = _player.py - 4;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
dospell = false;
|
|
|
|
if (!_npcInfo[i].attacking && _npcInfo[i].castPause < _ticks) {
|
|
_npcInfo[i].swaySpeed = _npcInfo[i].swaySpeed + _npcInfo[i].swaySpeed / 200 * _fpsr;
|
|
if (_npcInfo[i].swaySpeed > 15) {
|
|
dospell = true;
|
|
_npcInfo[i].swaySpeed = 1;
|
|
}
|
|
|
|
// sway code
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle + _npcInfo[i].swaySpeed * _fpsr;
|
|
if (_npcInfo[i].swayAngle >= 360)
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle - 360;
|
|
|
|
_npcInfo[i].headTargetX[0] = _npcInfo[i].x + (24 - _npcInfo[i].swaySpeed / 2) * sin(3.14159 / 180 * _npcInfo[i].swayAngle) + 12;
|
|
_npcInfo[i].headTargetY[0] = _npcInfo[i].y - 36 + 16 + 8 * sin(3.14159 * 2 / 180 * _npcInfo[i].swayAngle);
|
|
}
|
|
|
|
if (dospell) {
|
|
_npcInfo[i].pause = _ticks + 3000;
|
|
_npcInfo[i].attacknext = _ticks + 4500;
|
|
_npcInfo[i].castPause = _ticks + 4500;
|
|
|
|
castSpell(3, _npcInfo[i].x, _npcInfo[i].y, _npcInfo[i].x, _npcInfo[i].y, i);
|
|
|
|
_npcInfo[i].headTargetX[0] = _npcInfo[i].x;
|
|
_npcInfo[i].headTargetY[0] = _npcInfo[i].y - 36 + 16;
|
|
}
|
|
|
|
// targethead code
|
|
xdif = _npcInfo[i].bodysection[7].x - _npcInfo[i].headTargetX[0];
|
|
ydif = _npcInfo[i].bodysection[7].y - _npcInfo[i].headTargetY[0];
|
|
|
|
|
|
_npcInfo[i].bodysection[7].x = _npcInfo[i].bodysection[7].x - xdif * 0.4 * _fpsr;
|
|
_npcInfo[i].bodysection[7].y = _npcInfo[i].bodysection[7].y - ydif * 0.4 * _fpsr;
|
|
|
|
|
|
_npcInfo[i].bodysection[0].x = _npcInfo[i].x + 12;
|
|
_npcInfo[i].bodysection[0].y = _npcInfo[i].y + 12;
|
|
|
|
for (int f = 6; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[f + 1].x - _npcInfo[i].bodysection[f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[f + 1].y - _npcInfo[i].bodysection[f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[f].x = _npcInfo[i].bodysection[f].x - (_npcInfo[i].bodysection[f].x - tx) / 3;
|
|
_npcInfo[i].bodysection[f].y = _npcInfo[i].bodysection[f].y - (_npcInfo[i].bodysection[f].y - ty) / 3;
|
|
}
|
|
}
|
|
|
|
// boss1 specific and blackknight
|
|
if (_npcInfo[i].spriteset == kMonsterBoss1 || _npcInfo[i].spriteset == kMonsterBlackKnight) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
|
|
castSpell(1, _npcInfo[i].x, _npcInfo[i].y, _player.px, _player.py, i);
|
|
}
|
|
|
|
if (_npcInfo[i].castPause < _ticks) {
|
|
castSpell(6, _npcInfo[i].x, _npcInfo[i].y, _player.px, _player.py, i);
|
|
_npcInfo[i].castPause = _ticks + 12000;
|
|
}
|
|
}
|
|
|
|
|
|
// firehydra specific
|
|
if (_npcInfo[i].spriteset == kMonsterFireHydra) {
|
|
_npcInfo[i].swaySpeed = 4;
|
|
|
|
// sway code
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle + _npcInfo[i].swaySpeed * _fpsr;
|
|
if (_npcInfo[i].swayAngle >= 360)
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle - 360;
|
|
|
|
for (int ff = 0; ff <= 2; ff++) {
|
|
if (_npcInfo[i].hp > 10 * ff * 20) {
|
|
if (_npcInfo[i].pause < _ticks && _npcInfo[i].attacking2[ff] == 0 && _npcInfo[i].attacknext2[ff] < _ticks) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 48 && ABS(ydif) < 48) {
|
|
float dist = sqrt(xdif * xdif + ydif * ydif);
|
|
|
|
if ((dist) < 36) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndBite]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attacking2[ff] = 1;
|
|
_npcInfo[i].attackframe2[ff] = 0;
|
|
|
|
_npcInfo[i].headTargetX[ff] = _player.px + 12;
|
|
_npcInfo[i].headTargetY[ff] = _player.py - 4;
|
|
|
|
_npcInfo[i].swayAngle = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (_npcInfo[i].attacking2[ff] == 0) {
|
|
_npcInfo[i].headTargetX[ff] = _npcInfo[i].x + 38 * sin(3.14159 / 180 * (_npcInfo[i].swayAngle + 120 * ff)) + 12;
|
|
_npcInfo[i].headTargetY[ff] = _npcInfo[i].y - 46 + 16 + 16 * sin(3.14159 * 2 / 180 * (_npcInfo[i].swayAngle + 120 * ff));
|
|
}
|
|
|
|
// targethead code
|
|
xdif = _npcInfo[i].bodysection[10 * ff + 9].x - _npcInfo[i].headTargetX[ff];
|
|
ydif = _npcInfo[i].bodysection[10 * ff + 9].y - _npcInfo[i].headTargetY[ff];
|
|
|
|
_npcInfo[i].bodysection[10 * ff + 9].x = _npcInfo[i].bodysection[10 * ff + 9].x - xdif * 0.4 * _fpsr;
|
|
_npcInfo[i].bodysection[10 * ff + 9].y = _npcInfo[i].bodysection[10 * ff + 9].y - ydif * 0.4 * _fpsr;
|
|
|
|
_npcInfo[i].bodysection[10 * ff].x = _npcInfo[i].x + 12 + 8 * cos(3.141592 * 2 * (_itemyloc / 16 + ff * 120 / 360));
|
|
_npcInfo[i].bodysection[10 * ff].y = _npcInfo[i].y + 12 + 8 * sin(3.141592 * 2 * (_itemyloc / 16 + ff * 120 / 360));
|
|
|
|
for (int f = 8; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[ff * 10 + f + 1].x - _npcInfo[i].bodysection[ff * 10 + f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[ff * 10 + f + 1].y - _npcInfo[i].bodysection[ff * 10 + f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[ff * 10 + f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[ff * 10 + f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[ff * 10 + f].x = _npcInfo[i].bodysection[ff * 10 + f].x - (_npcInfo[i].bodysection[ff * 10 + f].x - tx) / 3;
|
|
_npcInfo[i].bodysection[ff * 10 + f].y = _npcInfo[i].bodysection[ff * 10 + f].y - (_npcInfo[i].bodysection[ff * 10 + f].y - ty) / 3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// spriteset6 specific
|
|
if (_npcInfo[i].spriteset == kMonsterRedDragon && _npcInfo[i].attackattempt < _ticks) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
pass = 0;
|
|
if (ABS(xdif) < 48 && ABS(ydif) < 6)
|
|
pass = 1;
|
|
if (ABS(ydif) < 48 && ABS(xdif) < 6)
|
|
pass = 2;
|
|
|
|
if (pass > 0) {
|
|
_npcInfo[i].attackattempt = _ticks + 100;
|
|
if ((int)(RND() * 2) == 0) {
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
float nnxa = 0, nnya = 0, nnxb = 0, nnyb = 0;
|
|
|
|
if (pass == 1 && xdif < 0) {
|
|
nnxa = npx - 8;
|
|
nnya = npy + 4;
|
|
nnxb = npx - 48 - 8;
|
|
nnyb = npy + 4;
|
|
} else if (pass == 1 && xdif > 0) {
|
|
nnxa = npx + 16;
|
|
nnya = npy + 4;
|
|
nnxb = npx + 16 + 48;
|
|
nnyb = npy + 4;
|
|
} else if (pass == 2 && ydif < 0) {
|
|
nnya = npy;
|
|
nnxa = npx + 4;
|
|
nnyb = npy - 48;
|
|
nnxb = npx + 4;
|
|
} else if (pass == 2 && ydif > 0) {
|
|
nnya = npy + 20;
|
|
nnxa = npx + 4;
|
|
nnyb = npy + 20 + 48;
|
|
nnxb = npx + 4;
|
|
}
|
|
|
|
castSpell(7, nnxa, nnya, nnxb, nnyb, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// wizard1 specific
|
|
if (_npcInfo[i].spriteset == kMonsterPriest) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
|
|
castSpell(9, _npcInfo[i].x, _npcInfo[i].y, _player.px, _player.py, i);
|
|
}
|
|
|
|
if (_npcInfo[i].castPause < _ticks) {
|
|
// castSpell 6, _npcinfo[i].x, _npcinfo[i].y, _player.px, _player.py, i
|
|
// _npcinfo[i].castpause = _ticks + 12000
|
|
}
|
|
|
|
}
|
|
|
|
// spriteset6 specific
|
|
if (_npcInfo[i].spriteset == kMonsterYellowDragon && _npcInfo[i].attackattempt < _ticks) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
pass = 0;
|
|
if (ABS(xdif) < 56 && ABS(ydif) < 6)
|
|
pass = 1;
|
|
if (ABS(ydif) < 56 && ABS(xdif) < 6)
|
|
pass = 2;
|
|
|
|
if (pass > 0) {
|
|
_npcInfo[i].attackattempt = _ticks + 100;
|
|
if ((int)(RND() * 2) == 0) {
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
|
|
float nnxa = 0, nnya = 0, nnxb = 0, nnyb = 0;
|
|
if (pass == 1 && xdif < 0) {
|
|
nnxa = npx - 8;
|
|
nnya = npy + 4;
|
|
nnxb = npx - 56 - 8;
|
|
nnyb = npy + 4;
|
|
_npcInfo[i].walkdir = 2;
|
|
} else if (pass == 1 && xdif > 0) {
|
|
nnxa = npx + 16;
|
|
nnya = npy + 4;
|
|
nnxb = npx + 16 + 56;
|
|
nnyb = npy + 4;
|
|
_npcInfo[i].walkdir = 3;
|
|
} else if (pass == 2 && ydif < 0) {
|
|
nnya = npy;
|
|
nnxa = npx + 4;
|
|
nnyb = npy - 56;
|
|
nnxb = npx + 4;
|
|
_npcInfo[i].walkdir = 0;
|
|
} else if (pass == 2 && ydif > 0) {
|
|
nnya = npy + 20;
|
|
nnxa = npx + 4;
|
|
nnyb = npy + 20 + 56;
|
|
nnxb = npx + 4;
|
|
_npcInfo[i].walkdir = 1;
|
|
}
|
|
|
|
castSpell(7, nnxa, nnya, nnxb, nnyb, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// twowing specific
|
|
if (_npcInfo[i].spriteset == kMonsterTwoWing) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].bodysection[7].x;
|
|
npy = _npcInfo[i].bodysection[7].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 24 && ABS(ydif) < 24) {
|
|
float dist = sqrt(xdif * xdif + ydif * ydif);
|
|
|
|
if ((dist) < 24) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndBite]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
|
|
_npcInfo[i].headTargetX[0] = _player.px + 12;
|
|
_npcInfo[i].headTargetY[0] = _player.py - 4;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (!_npcInfo[i].attacking && _npcInfo[i].castPause < _ticks) {
|
|
_npcInfo[i].swaySpeed = 4;
|
|
|
|
// sway code
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle + _npcInfo[i].swaySpeed * _fpsr;
|
|
if (_npcInfo[i].swayAngle >= 360)
|
|
_npcInfo[i].swayAngle = _npcInfo[i].swayAngle - 360;
|
|
|
|
_npcInfo[i].headTargetX[0] = _npcInfo[i].x + (24 - _npcInfo[i].swaySpeed / 2) * sin(3.14159 / 180 * _npcInfo[i].swayAngle) + 12;
|
|
_npcInfo[i].headTargetY[0] = _npcInfo[i].y - 36 + 16 + 8 * sin(3.14159 * 2 / 180 * _npcInfo[i].swayAngle);
|
|
}
|
|
|
|
if (dospell) {
|
|
_npcInfo[i].pause = _ticks + 3000;
|
|
_npcInfo[i].attacknext = _ticks + 5000;
|
|
_npcInfo[i].castPause = _ticks + 3000;
|
|
|
|
castSpell(3, _npcInfo[i].x, _npcInfo[i].y, _npcInfo[i].x, _npcInfo[i].y, i);
|
|
|
|
_npcInfo[i].headTargetX[0] = _npcInfo[i].x;
|
|
_npcInfo[i].headTargetY[0] = _npcInfo[i].y - 36 + 16;
|
|
}
|
|
|
|
// targethead code
|
|
xdif = _npcInfo[i].bodysection[7].x - _npcInfo[i].headTargetX[0];
|
|
ydif = _npcInfo[i].bodysection[7].y - _npcInfo[i].headTargetY[0];
|
|
|
|
|
|
_npcInfo[i].bodysection[7].x = _npcInfo[i].bodysection[7].x - xdif * 0.4 * _fpsr;
|
|
_npcInfo[i].bodysection[7].y = _npcInfo[i].bodysection[7].y - ydif * 0.4 * _fpsr;
|
|
|
|
_npcInfo[i].bodysection[0].x = _npcInfo[i].x + 12;
|
|
_npcInfo[i].bodysection[0].y = _npcInfo[i].y + 12;
|
|
|
|
for (int f = 6; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[f + 1].x - _npcInfo[i].bodysection[f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[f + 1].y - _npcInfo[i].bodysection[f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[f].x = _npcInfo[i].bodysection[f].x - (_npcInfo[i].bodysection[f].x - tx) / 3;
|
|
_npcInfo[i].bodysection[f].y = _npcInfo[i].bodysection[f].y - (_npcInfo[i].bodysection[f].y - ty) / 3;
|
|
}
|
|
|
|
}
|
|
|
|
// dragon2 specific
|
|
if (_npcInfo[i].spriteset == kMonsterDragon2 && _npcInfo[i].attackattempt < _ticks) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 32 && ABS(ydif) < 32) {
|
|
_npcInfo[i].attackattempt = _ticks + 100;
|
|
if ((int)(RND() * 2) == 0) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndEnemyHit]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// endboss specific
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss && _npcInfo[i].attackattempt < _ticks) {
|
|
if (_npcInfo[i].attacknext < _ticks && _npcInfo[i].pause < _ticks && !_npcInfo[i].attacking) {
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
xdif = _player.px - npx;
|
|
ydif = _player.py - npy;
|
|
|
|
if (ABS(xdif) < 38 && ABS(ydif) < 38) {
|
|
_npcInfo[i].attackattempt = _ticks + 100;
|
|
if ((int)(RND() * 2) == 0) {
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndIce]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
_npcInfo[i].attacking = true;
|
|
_npcInfo[i].attackframe = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
float npx = _npcInfo[i].x;
|
|
float npy = _npcInfo[i].y;
|
|
|
|
int xp = (npx / 2 + 6);
|
|
int yp = (npy / 2 + 10);
|
|
|
|
rcSrc.left = xp - 1;
|
|
rcSrc.top = yp - 1;
|
|
rcSrc.setWidth(3);
|
|
rcSrc.setHeight(3);
|
|
|
|
if (_npcInfo[i].pause < _ticks)
|
|
_clipBg->fillRect(rcSrc, i);
|
|
|
|
|
|
pass = 0;
|
|
if (_npcInfo[i].attacking)
|
|
pass = 1;
|
|
if (_npcInfo[i].spriteset == kMonsterFireHydra) {
|
|
if (_npcInfo[i].attacking2[0] || _npcInfo[i].attacking2[1] || _npcInfo[i].attacking2[2])
|
|
pass = 1;
|
|
}
|
|
|
|
if (pass == 1) {
|
|
int dist;
|
|
float damage;
|
|
// spriteset1 specific
|
|
if (_npcInfo[i].spriteset == kMonsterBabyDragon) {
|
|
_npcInfo[i].attackframe = _npcInfo[i].attackframe + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe >= 16) {
|
|
_npcInfo[i].attackframe = 0;
|
|
_npcInfo[i].attacking = false;
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
float xdif = _player.px - npx;
|
|
float ydif = _player.py - npy;
|
|
|
|
dist = 10;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe = 0;
|
|
// _npcinfo[i].attacking = false;
|
|
|
|
damage = (float)_npcInfo[i].attackDamage * (0.5 + RND() * 1.0);
|
|
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
|
|
if (_npcInfo[i].spriteset == kMonsterOneWing) {
|
|
// targethead code
|
|
float xdif = _npcInfo[i].bodysection[7].x - _npcInfo[i].headTargetX[0];
|
|
float ydif = _npcInfo[i].bodysection[7].y - _npcInfo[i].headTargetY[0];
|
|
|
|
_npcInfo[i].bodysection[7].x = _npcInfo[i].bodysection[7].x - xdif * 0.4 * _fpsr;
|
|
_npcInfo[i].bodysection[7].y = _npcInfo[i].bodysection[7].y - ydif * 0.4 * _fpsr;
|
|
|
|
_npcInfo[i].bodysection[0].x = _npcInfo[i].x + 12;
|
|
_npcInfo[i].bodysection[0].y = _npcInfo[i].y + 12;
|
|
|
|
for (int f = 6; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[f + 1].x - _npcInfo[i].bodysection[f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[f + 1].y - _npcInfo[i].bodysection[f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[f].x = _npcInfo[i].bodysection[f].x - (_npcInfo[i].bodysection[f].x - tx);
|
|
_npcInfo[i].bodysection[f].y = _npcInfo[i].bodysection[f].y - (_npcInfo[i].bodysection[f].y - ty);
|
|
}
|
|
|
|
_npcInfo[i].attackframe = _npcInfo[i].attackframe + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe >= 16) {
|
|
_npcInfo[i].attackframe = 0;
|
|
_npcInfo[i].attacking = false;
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].bodysection[7].x;
|
|
npy = (_npcInfo[i].bodysection[7].y + 16);
|
|
|
|
xdif = (_player.px + 12) - npx;
|
|
ydif = (_player.py + 12) - npy;
|
|
|
|
dist = 8;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe = 0
|
|
// _npcinfo[i].attacking = false
|
|
damage = (float)_npcInfo[i].attackDamage * (1.0 + (RND() * 0.5));
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
|
|
|
|
// firehydra
|
|
if (_npcInfo[i].spriteset == kMonsterFireHydra) {
|
|
for (int ff = 0; ff <= 2; ff++) {
|
|
if (_npcInfo[i].attacking2[ff]) {
|
|
float xdif = _npcInfo[i].bodysection[10 * ff + 9].x - _npcInfo[i].headTargetX[ff];
|
|
float ydif = _npcInfo[i].bodysection[10 * ff + 9].y - _npcInfo[i].headTargetY[ff];
|
|
|
|
_npcInfo[i].bodysection[10 * ff + 9].x = _npcInfo[i].bodysection[10 * ff + 9].x - xdif * .2 * _fpsr;
|
|
_npcInfo[i].bodysection[10 * ff + 9].y = _npcInfo[i].bodysection[10 * ff + 9].y - ydif * .2 * _fpsr;
|
|
|
|
_npcInfo[i].bodysection[10 * ff].x = _npcInfo[i].x + 12 + 8 * cos(3.141592 * 2 * (_itemyloc / 16 + ff * 120 / 360));
|
|
_npcInfo[i].bodysection[10 * ff].y = _npcInfo[i].y + 12 + 8 * sin(3.141592 * 2 * (_itemyloc / 16 + ff * 120 / 360));
|
|
|
|
for (int f = 8; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[ff * 10 + f + 1].x - _npcInfo[i].bodysection[ff * 10 + f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[ff * 10 + f + 1].y - _npcInfo[i].bodysection[ff * 10 + f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[ff * 10 + f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[ff * 10 + f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[ff * 10 + f].x = _npcInfo[i].bodysection[ff * 10 + f].x - (_npcInfo[i].bodysection[ff * 10 + f].x - tx) / 3;
|
|
_npcInfo[i].bodysection[ff * 10 + f].y = _npcInfo[i].bodysection[ff * 10 + f].y - (_npcInfo[i].bodysection[ff * 10 + f].y - ty) / 3;
|
|
}
|
|
|
|
_npcInfo[i].attackframe2[ff] = _npcInfo[i].attackframe2[ff] + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe2[ff] >= 16) {
|
|
_npcInfo[i].attackframe2[ff] = 0;
|
|
_npcInfo[i].attacking2[ff] = false;
|
|
_npcInfo[i].attacknext2[ff] = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].bodysection[10 * ff + 9].x;
|
|
npy = (_npcInfo[i].bodysection[10 * ff + 9].y + 16);
|
|
|
|
xdif = (_player.px + 12) - npx;
|
|
ydif = (_player.py + 12) - npy;
|
|
|
|
dist = 8;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext2[ff] = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe2(ff) = 0
|
|
// _npcinfo[i].attacking2(ff) = false
|
|
damage = (float)_npcInfo[i].attackDamage * (1.0 + RND() * 0.5);
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// twowing specific
|
|
if (_npcInfo[i].spriteset == kMonsterTwoWing) {
|
|
// targethead code
|
|
float xdif = _npcInfo[i].bodysection[7].x - _npcInfo[i].headTargetX[0];
|
|
float ydif = _npcInfo[i].bodysection[7].y - _npcInfo[i].headTargetY[0];
|
|
|
|
_npcInfo[i].bodysection[7].x = _npcInfo[i].bodysection[7].x - xdif * 0.4 * _fpsr;
|
|
_npcInfo[i].bodysection[7].y = _npcInfo[i].bodysection[7].y - ydif * 0.4 * _fpsr;
|
|
|
|
_npcInfo[i].bodysection[0].x = _npcInfo[i].x + 12;
|
|
_npcInfo[i].bodysection[0].y = _npcInfo[i].y + 12;
|
|
|
|
for (int f = 6; f >= 1; f--) {
|
|
xdif = _npcInfo[i].bodysection[f + 1].x - _npcInfo[i].bodysection[f - 1].x;
|
|
ydif = _npcInfo[i].bodysection[f + 1].y - _npcInfo[i].bodysection[f - 1].y;
|
|
|
|
float tx = _npcInfo[i].bodysection[f - 1].x + xdif / 2;
|
|
float ty = _npcInfo[i].bodysection[f - 1].y + ydif / 2;
|
|
|
|
_npcInfo[i].bodysection[f].x = _npcInfo[i].bodysection[f].x - (_npcInfo[i].bodysection[f].x - tx);
|
|
_npcInfo[i].bodysection[f].y = _npcInfo[i].bodysection[f].y - (_npcInfo[i].bodysection[f].y - ty);
|
|
}
|
|
|
|
_npcInfo[i].attackframe = _npcInfo[i].attackframe + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe >= 16) {
|
|
_npcInfo[i].attackframe = 0;
|
|
_npcInfo[i].attacking = false;
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].bodysection[7].x;
|
|
npy = (_npcInfo[i].bodysection[7].y + 16);
|
|
|
|
xdif = (_player.px + 12) - npx;
|
|
ydif = (_player.py + 12) - npy;
|
|
|
|
dist = 8;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe = 0
|
|
// _npcinfo[i].attacking = false
|
|
damage = (float)_npcInfo[i].attackDamage * (1.0 + RND() * 0.5);
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
|
|
// dragon 2 specific
|
|
if (_npcInfo[i].spriteset == kMonsterDragon2) {
|
|
|
|
_npcInfo[i].attackframe = _npcInfo[i].attackframe + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe >= 16) {
|
|
_npcInfo[i].attackframe = 0;
|
|
_npcInfo[i].attacking = false;
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
float xdif = _player.px - npx;
|
|
float ydif = _player.py - npy;
|
|
|
|
dist = 16 + _npcInfo[i].attackframe;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe = 0
|
|
// _npcinfo[i].attacking = false
|
|
damage = (float)_npcInfo[i].attackDamage * (0.5 + RND() * 1.0);
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
|
|
// endboss specific
|
|
if (_npcInfo[i].spriteset == kMonsterFinalBoss) {
|
|
_npcInfo[i].attackframe = _npcInfo[i].attackframe + _npcInfo[i].attackspd * _fpsr;
|
|
if (_npcInfo[i].attackframe >= 16) {
|
|
_npcInfo[i].attackframe = 0;
|
|
_npcInfo[i].attacking = false;
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
}
|
|
|
|
_npcInfo[i].cattackframe = (int)(_npcInfo[i].attackframe);
|
|
|
|
npx = _npcInfo[i].x;
|
|
npy = _npcInfo[i].y;
|
|
|
|
float xdif = _player.px - npx;
|
|
float ydif = _player.py - npy;
|
|
|
|
dist = 36;
|
|
|
|
if (ABS(xdif) < dist && ABS(ydif) < dist && _player.pause < _ticks) {
|
|
_npcInfo[i].attacknext = _ticks + _npcInfo[i].attackdelay;
|
|
// _npcinfo[i].attackframe = 0
|
|
// _npcinfo[i].attacking = false
|
|
damage = (float)_npcInfo[i].attackDamage * (0.5 + RND() * 1.0);
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
}
|
|
// -------end fight code
|
|
}
|
|
}
|
|
}
|
|
|
|
void GriffonEngine::updateSpells() {
|
|
float xloc = 0, yloc = 0;
|
|
|
|
for (int i = 0; i < kMaxSpell; i++) {
|
|
if (_spellInfo[i].frame > 0) {
|
|
int spellnum = _spellInfo[i].spellnum;
|
|
|
|
// water
|
|
if (spellnum == 0 && !_forcePause) {
|
|
float fr = (32 - _spellInfo[i].frame);
|
|
int ll[4][2];
|
|
|
|
ll[0][0] = -2;
|
|
ll[0][1] = -3;
|
|
ll[1][0] = 2;
|
|
ll[1][1] = -3;
|
|
ll[2][0] = -4;
|
|
ll[2][1] = -2;
|
|
ll[3][0] = 4;
|
|
ll[3][1] = -2;
|
|
|
|
for (int f = 0; f <= 3; f++) {
|
|
if (fr > f * 4 && fr < f * 4 + 16) {
|
|
float alf = 255;
|
|
|
|
if (fr < f * 4 + 8) {
|
|
int fi = (int)((fr - f * 4) * 3) % 4;
|
|
rcSrc.left = 32 + fi * 16;
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
xloc = _spellInfo[i].enemyx + 12 + ll[f][0] * 16;
|
|
yloc = _spellInfo[i].enemyy + 16 + ll[f][1] * 16;
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
alf = 255 * ((fr - f * 4) / 8);
|
|
}
|
|
|
|
if (fr >= f * 4 + 8) {
|
|
int fi = 0; // ??
|
|
|
|
if (f == 0 || f == 2)
|
|
fi = 0;
|
|
if (f == 1 || f == 3)
|
|
fi = 1;
|
|
rcSrc.left = 32 + fi * 16;
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
float xst = _spellInfo[i].enemyx + 12 + ll[f][0] * 16;
|
|
float yst = _spellInfo[i].enemyy + 16 + ll[f][1] * 16;
|
|
|
|
float xi = (_spellInfo[i].enemyx - xst) * 2 / 8;
|
|
float yi = (_spellInfo[i].enemyy - yst) * 2 / 8;
|
|
|
|
float fl = (fr - f * 4 - 8) / 2;
|
|
xloc = xst + xi * fl * fl;
|
|
yloc = yst + yi * fl * fl;
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
alf = 255;
|
|
}
|
|
|
|
if (xloc > -16 && xloc < 304 && yloc > -16 && yloc < 224) {
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB((int)alf, 255, 255, 255));
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (xloc + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (yloc + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
float damage = (float)_player.spellDamage * (1.0 + RND() * 0.5) * (float)_spellInfo[i].strength;
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks) {
|
|
damageNPC(e, damage, 1);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndIce]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndIce]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// metal
|
|
if (spellnum == 1 && !_forcePause) {
|
|
int fr = (int)((32 - _spellInfo[i].frame) * 4) % 3;
|
|
|
|
rcSrc.left = fr * 48;
|
|
rcSrc.top = 0;
|
|
rcSrc.setWidth(48);
|
|
rcSrc.setHeight(48);
|
|
|
|
float c1 = (32 - _spellInfo[i].frame) / 16;
|
|
|
|
float halfx = (_spellInfo[i].homex - 12) + ((_spellInfo[i].enemyx - 12) - (_spellInfo[i].homex - 12)) / 2;
|
|
float halfy = (_spellInfo[i].homey - 12) + ((_spellInfo[i].enemyy - 12) - (_spellInfo[i].homey - 12)) / 2;
|
|
|
|
float wdth = (halfx - _spellInfo[i].homex) * 1.2;
|
|
float hight = (halfy - _spellInfo[i].homey) * 1.2;
|
|
|
|
xloc = halfx + wdth * cos(3.14159 + 3.14159 * 2 * c1);
|
|
yloc = halfy + hight * sin(3.14159 + 3.14159 * 2 * c1);
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(255, 255, 255, 255));
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.2 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (xloc + 24) - (_npcInfo[e].x + 12);
|
|
float ydif = (yloc + 24) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 24 && ABS(ydif) < 24)) {
|
|
float damage = (float)_player.spellDamage * (1.0 + RND() * 0.5) * (float)_spellInfo[i].strength;
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks) {
|
|
damageNPC(e, damage, 1);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndMetalHit]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_spellInfo[i].damagewho == 1) {
|
|
// --------- boss 1 specific
|
|
if (ABS(_spellInfo[i].frame) < 0 && _npcInfo[_spellInfo[i].npc].spriteset == kMonsterBoss1) {
|
|
int npc = _spellInfo[i].npc;
|
|
_npcInfo[npc].attackframe = 0;
|
|
_npcInfo[npc].attacking = false;
|
|
|
|
_npcInfo[npc].pause = _ticks + 1000;
|
|
_npcInfo[npc].attacknext = _ticks + 4000;
|
|
}
|
|
// ---------------
|
|
|
|
// --------- blackknight specific
|
|
if (ABS(_spellInfo[i].frame) < 0 && _npcInfo[_spellInfo[i].npc].spriteset == kMonsterBlackKnight) {
|
|
int npc = _spellInfo[i].npc;
|
|
_npcInfo[npc].attackframe = 0;
|
|
_npcInfo[npc].attacking = false;
|
|
|
|
_npcInfo[npc].pause = _ticks + 1000;
|
|
_npcInfo[npc].attacknext = _ticks + 3500;
|
|
}
|
|
// ---------------
|
|
|
|
float xdif = (xloc + 24) - (_player.px + 12);
|
|
float ydif = (yloc + 24) - (_player.py + 12);
|
|
|
|
if ((ABS(xdif) < 24 && ABS(ydif) < 24) && _player.pause < _ticks) {
|
|
float damage = (float)_npcInfo[_spellInfo[i].npc].spellDamage * (1.0 + RND() * 0.5);
|
|
|
|
if (_player.hp > 0) {
|
|
damagePlayer(damage);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndMetalHit]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// check for(int post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 24) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 24) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 24 && ABS(ydif) < 24)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndMetalHit]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// earth
|
|
if (spellnum == 2 && !_forcePause) {
|
|
float hght = 240 - _spellInfo[i].enemyy;
|
|
|
|
for (int f = 8; f >= 0; f--) {
|
|
|
|
float fr = (32 - _spellInfo[i].frame);
|
|
|
|
if (fr > f && fr < f + 16) {
|
|
rcSrc.left = 32 * _spellInfo[i].rockimg[f];
|
|
rcSrc.top = 48;
|
|
rcSrc.setWidth(32);
|
|
rcSrc.setHeight(32);
|
|
|
|
bool scatter = false;
|
|
if (fr < 8 + f) {
|
|
xloc = _spellInfo[i].enemyx - 4;
|
|
yloc = _spellInfo[i].enemyy * (1 - cos(3.14159 / 2 * (fr - f) / 8)); // ^ 2;
|
|
yloc *= yloc;
|
|
} else {
|
|
scatter = true;
|
|
xloc = _spellInfo[i].enemyx - 4 - _spellInfo[i].rockdeflect[f] * sin(3.14159 / 2 * ((fr - f) - 8) / 8);
|
|
yloc = _spellInfo[i].enemyy + hght * (1 - cos(3.14159 / 2 * ((fr - f) - 8) / 8));
|
|
}
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
if (xloc > -16 && xloc < 304 && yloc > -16 && yloc < 224) {
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(255, 255, 255, 255));
|
|
|
|
if (scatter) {
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (xloc + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (yloc + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
float damage = (float)_player.spellDamage * (1.0 + RND() * 0.5) * (float)_spellInfo[i].strength;
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks) {
|
|
damageNPC(e, damage, 1);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndRocks]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// check for(int post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndRocks]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.2 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
}
|
|
|
|
// crystal
|
|
if (spellnum == 5) {
|
|
|
|
float fra = (32 - _spellInfo[i].frame);
|
|
int fr = (int)((_spellInfo[i].frame) * 2) % 8;
|
|
|
|
rcSrc.left = fr * 32;
|
|
rcSrc.top = 96 + 48;
|
|
rcSrc.setWidth(32);
|
|
rcSrc.setHeight(64);
|
|
|
|
rcDest.left = _player.px - 4;
|
|
rcDest.top = _player.py + 16 - 48;
|
|
|
|
int f = 160;
|
|
if (fra < 8)
|
|
f = 192 * fra / 8;
|
|
if (fra > 24)
|
|
f = 192 * (1 - (fra - 24) / 8);
|
|
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(f, 255, 255, 255));
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.3 * _fpsr;
|
|
if (_spellInfo[i].frame < 0) {
|
|
_spellInfo[i].frame = 0;
|
|
_forcePause = false;
|
|
|
|
float npx = _player.px + 12;
|
|
float npy = _player.py + 20;
|
|
|
|
int lx = (int)npx / 16;
|
|
int ly = (int)npy / 16;
|
|
|
|
bool foundel[5];
|
|
for (int f1 = 0; f1 < 5; f1++) { // !! f < 5
|
|
foundel[f1] = false;
|
|
}
|
|
|
|
for (int xo = -2; xo <= 2; xo++) {
|
|
for (int yo = -2; yo <= 2; yo++) {
|
|
|
|
int sx = lx + xo;
|
|
int sy = ly + yo;
|
|
|
|
if (sx > -1 && sx < 20 && sy > -1 && sy < 15) {
|
|
for (int l = 0; l <= 2; l++) {
|
|
int curtile = _tileinfo[l][sx][sy][0];
|
|
int curtilel = _tileinfo[l][sx][sy][1];
|
|
|
|
if (curtile > 0) {
|
|
curtile = curtile - 1;
|
|
int curtilex = curtile % 20;
|
|
int curtiley = (curtile - curtilex) / 20;
|
|
|
|
int element = elementmap[curtiley][curtilex];
|
|
if (element > -1 && curtilel == 0)
|
|
foundel[element + 1] = true;
|
|
}
|
|
}
|
|
|
|
int o = _objectMap[sx][sy];
|
|
if (o > -1) {
|
|
if (_objectInfo[o].type == 1)
|
|
foundel[2] = true;
|
|
if (o == 1 || o == 2) {
|
|
foundel[2] = true;
|
|
foundel[4] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
char line[256];
|
|
strcpy(line, "Found... nothing...");
|
|
|
|
for (int f1 = 0; f1 < 5; f1++) {
|
|
if (foundel[f1] && !_player.foundSpell[f1]) {
|
|
_player.foundSpell[f1] = 1;
|
|
_player.spellCharge[f1] = 0;
|
|
if (f1 == 1)
|
|
strcpy(line, "Found... Water Essence");
|
|
if (f1 == 2)
|
|
strcpy(line, "Found... Metal Essence");
|
|
if (f1 == 3)
|
|
strcpy(line, "Found... Earth Essence");
|
|
if (f1 == 4)
|
|
strcpy(line, "Found... Fire Essence");
|
|
break;
|
|
}
|
|
}
|
|
|
|
eventText(line);
|
|
}
|
|
}
|
|
|
|
// room fireballs
|
|
if (spellnum == 6 && !_forcePause) {
|
|
|
|
if (_spellInfo[i].frame > 16) {
|
|
float fr = (32 - _spellInfo[i].frame);
|
|
|
|
int alpha = 192 * sin(3.14159 * fr / 4);
|
|
|
|
rcSrc.left = 16 * (int)(RND() * 2);
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
for (int ff = 0; ff <= _spellInfo[i].nfballs - 1; ff++) {
|
|
|
|
xloc = _spellInfo[i].fireballs[ff][0] + (int)(RND() * 3) - 1;
|
|
yloc = _spellInfo[i].fireballs[ff][1] + (int)(RND() * 3) - 1;
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(alpha, 255, 255, 255));
|
|
}
|
|
} else {
|
|
|
|
rcSrc.left = 16 * (int)(RND() * 2);
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
for (int ff = 0; ff <= _spellInfo[i].nfballs - 1; ff++) {
|
|
float ax = _spellInfo[i].fireballs[ff][0];
|
|
float ay = _spellInfo[i].fireballs[ff][1];
|
|
float bx = _player.px + 4;
|
|
float by = _player.py + 4;
|
|
float d = sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
|
|
|
|
float tx = (bx - ax) / d;
|
|
float ty = (by - ay) / d;
|
|
|
|
_spellInfo[i].fireballs[ff][2] += tx * 1.2 * _fpsr;
|
|
_spellInfo[i].fireballs[ff][3] += ty * 1.2 * _fpsr;
|
|
|
|
if (_spellInfo[i].ballon[ff] == 1) {
|
|
_spellInfo[i].fireballs[ff][0] = ax + _spellInfo[i].fireballs[ff][2] * 0.2 * _fpsr;
|
|
_spellInfo[i].fireballs[ff][1] = ay + _spellInfo[i].fireballs[ff][3] * 0.2 * _fpsr;
|
|
|
|
xloc = _spellInfo[i].fireballs[ff][0] + (int)(RND() * 3) - 1;
|
|
yloc = _spellInfo[i].fireballs[ff][1] + (int)(RND() * 3) - 1;
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(192, 255, 255, 255));
|
|
}
|
|
|
|
if (xloc < -1 || yloc < -1 || xloc > 304 || yloc > 224)
|
|
_spellInfo[i].ballon[ff] = 0;
|
|
}
|
|
}
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.2 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
|
|
if (_spellInfo[i].damagewho == 1) {
|
|
for (int ff = 0; ff <= _spellInfo[i].nfballs - 1; ff++) {
|
|
if (_spellInfo[i].ballon[ff] == 1) {
|
|
xloc = _spellInfo[i].fireballs[ff][0] + (int)(RND() * 3) - 1;
|
|
yloc = _spellInfo[i].fireballs[ff][1] + (int)(RND() * 3) - 1;
|
|
|
|
float xdif = (xloc + 8) - (_player.px + 12);
|
|
float ydif = (yloc + 8) - (_player.py + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8) && _player.pause < _ticks) {
|
|
float damage = _npcInfo[_spellInfo[i].npc].spellDamage * (1 + RND() * 0.5) / 3;
|
|
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndFire]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// lightning bomb
|
|
if (spellnum == 8) {
|
|
long cl1 = _videoBuffer->format.RGBToColor(0, 32, 204);
|
|
long cl2 = _videoBuffer->format.RGBToColor(142, 173, 191);
|
|
long cl3 = _videoBuffer->format.RGBToColor(240, 240, 240);
|
|
|
|
float px = _player.px + 12;
|
|
float py = _player.py + 12;
|
|
|
|
int apx = px + (int)(RND() * 5 - 2);
|
|
int apy = py + (int)(RND() * 5 - 2);
|
|
|
|
for (int f = 0; f <= 0; f++) { // ??
|
|
int y = apy;
|
|
int orn = 0;
|
|
for (int x = apx; x <= 319; x++) {
|
|
int rn = (int)(RND() * 3);
|
|
|
|
if (orn == 0)
|
|
--y;
|
|
else if (orn == 2)
|
|
++y;
|
|
|
|
drawLine(_videoBuffer, x, y - 1, x, y + 2, cl1);
|
|
drawLine(_videoBuffer, x, y, x, y + 1, cl3);
|
|
|
|
if (rn == 0)
|
|
drawLine(_videoBuffer, x, y + 1, x, y + 1, cl2);
|
|
if (rn == 2)
|
|
drawLine(_videoBuffer, x, y, x, y, cl2);
|
|
|
|
orn = rn;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (x + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (y + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
float damage = 30 * (1 + RND() * 0.5);
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks)
|
|
damageNPC(e, damage, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
y = apy;
|
|
orn = 0;
|
|
for (int x = apx; x >= 0; x--) {
|
|
int rn = (int)(RND() * 3);
|
|
|
|
if (orn == 0)
|
|
--y;
|
|
else if (orn == 2)
|
|
++y;
|
|
|
|
drawLine(_videoBuffer, x, y - 1, x, y + 2, cl1);
|
|
drawLine(_videoBuffer, x, y, x, y + 1, cl3);
|
|
|
|
if (rn == 0)
|
|
drawLine(_videoBuffer, x, y + 1, x, y + 1, cl2);
|
|
if (rn == 2)
|
|
drawLine(_videoBuffer, x, y, x, y, cl2);
|
|
|
|
orn = rn;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (x + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (y + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
float damage = 30 * (1 + RND() * 0.5);
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks)
|
|
damageNPC(e, damage, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int x = apx;
|
|
orn = 0;
|
|
for (y = apy; y <= 239; y++) {
|
|
int rn = (int)(RND() * 3);
|
|
|
|
if (orn == 0)
|
|
x = x - 1;
|
|
if (orn == 2)
|
|
x = x + 1;
|
|
|
|
drawLine(_videoBuffer, x - 1, y, x + 2, y, cl1);
|
|
drawLine(_videoBuffer, x, y, x + 1, y, cl3);
|
|
|
|
if (rn == 0)
|
|
drawLine(_videoBuffer, x + 1, y, x + 1, y, cl2);
|
|
if (rn == 2)
|
|
drawLine(_videoBuffer, x, y, x, y, cl2);
|
|
|
|
orn = rn;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (x + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (y + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
float damage = 30 * (1 + RND() * 0.5);
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks)
|
|
damageNPC(e, damage, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
x = apx;
|
|
orn = 0;
|
|
for (y = apy; y >= 0; y--) {
|
|
int rn = (int)(RND() * 3);
|
|
|
|
if (orn == 0)
|
|
x = x - 1;
|
|
if (orn == 2)
|
|
x = x + 1;
|
|
|
|
drawLine(_videoBuffer, x - 1, y, x + 2, y, cl1);
|
|
drawLine(_videoBuffer, x, y, x + 1, y, cl3);
|
|
|
|
if (rn == 0)
|
|
drawLine(_videoBuffer, x + 1, y, x + 1, y, cl2);
|
|
if (rn == 2)
|
|
drawLine(_videoBuffer, x, y, x, y, cl2);
|
|
|
|
orn = rn;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (x + 16) - (_npcInfo[e].x + 12);
|
|
float ydif = (y + 16) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
float damage = 30 * (1 + RND() * 0.5);
|
|
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks)
|
|
damageNPC(e, damage, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 16) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 16) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 16 && ABS(ydif) < 16)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_spellInfo[i].frame -= 0.5 * _fpsr;
|
|
if (_spellInfo[i].frame < 0) {
|
|
_spellInfo[i].frame = 0;
|
|
_forcePause = false;
|
|
}
|
|
}
|
|
|
|
// wizard 1 lightning
|
|
if (spellnum == 9) {
|
|
long cl1 = _videoBuffer->format.RGBToColor(0, 32, 204);
|
|
long cl2 = _videoBuffer->format.RGBToColor(142, 173, 191);
|
|
long cl3 = _videoBuffer->format.RGBToColor(240, 240, 240);
|
|
|
|
int px = _spellInfo[i].enemyx + 12;
|
|
int py = _spellInfo[i].enemyy + 24;
|
|
|
|
int apx = px + (int)(RND() * 20 - 10);
|
|
int apy = py + (int)(RND() * 20 - 10);
|
|
|
|
int x = apx;
|
|
int orn = 0;
|
|
for (int y = 0; y <= apy; y++) {
|
|
if (y < 240) {
|
|
int rn = (int)(RND() * 3);
|
|
|
|
if (orn == 0)
|
|
x = x - 1;
|
|
if (orn == 2)
|
|
x = x + 1;
|
|
|
|
drawLine(_videoBuffer, x - 1, y, x + 2, y, cl1);
|
|
drawLine(_videoBuffer, x, y, x + 1, y, cl3);
|
|
|
|
if (rn == 0)
|
|
drawLine(_videoBuffer, x + 1, y, x + 1, y, cl2);
|
|
if (rn == 2)
|
|
drawLine(_videoBuffer, x, y, x, y, cl2);
|
|
|
|
orn = rn;
|
|
|
|
if (_spellInfo[i].damagewho == 1) {
|
|
float xdif = (x + 8) - (_player.px + 12);
|
|
float ydif = (y + 8) - (_player.py + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8) && _player.pause < _ticks) {
|
|
float damage = ((float)_player.hp * 0.75) * (RND() * 0.5 + 0.5);
|
|
if (damage < 5)
|
|
damage = 5;
|
|
|
|
if ((_npcInfo[_spellInfo[i].npc].spriteset == kMonsterBatKitty) && (damage < 50))
|
|
damage = 40 + (int)(RND() * 40);
|
|
|
|
if (_player.hp > 0)
|
|
damagePlayer(damage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_spellInfo[i].frame -= 0.5 * _fpsr;
|
|
if (_spellInfo[i].frame < 0) {
|
|
_spellInfo[i].frame = 0;
|
|
|
|
_npcInfo[_spellInfo[i].npc].attacking = false;
|
|
_npcInfo[_spellInfo[i].npc].attacknext = _ticks + _npcInfo[_spellInfo[i].npc].attackdelay;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GriffonEngine::updateSpellsUnder() {
|
|
if (_forcePause)
|
|
return;
|
|
|
|
for (int i = 0; i < kMaxSpell; i++) {
|
|
if (_spellInfo[i].frame > 0) {
|
|
int spellnum = _spellInfo[i].spellnum;
|
|
|
|
// water
|
|
if (spellnum == 0) {
|
|
int fra = (32 - _spellInfo[i].frame);
|
|
int fr = (int)((32 - _spellInfo[i].frame) * 2) % 4;
|
|
|
|
rcSrc.left = fr * 48;
|
|
rcSrc.top = 96;
|
|
rcSrc.setWidth(48);
|
|
rcSrc.setHeight(48);
|
|
|
|
rcDest.left = _spellInfo[i].enemyx - 12;
|
|
rcDest.top = _spellInfo[i].enemyy - 8;
|
|
|
|
int f = 160;
|
|
if (fra < 8)
|
|
f = 160 * fra / 8;
|
|
if (fra > 24)
|
|
f = 160 * (1 - (fra - 24) / 8);
|
|
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(f, 255, 255, 255));
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.2 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
|
|
|
|
for (f = 1; f <= _lastNpc; f++) {
|
|
int xdif = _spellInfo[i].enemyx - _npcInfo[f].x;
|
|
int ydif = _spellInfo[i].enemyy - _npcInfo[f].y;
|
|
|
|
float dist = sqrt((float)(xdif * xdif + ydif * ydif));
|
|
|
|
if (dist > 20)
|
|
dist = 20;
|
|
|
|
if (dist > 5) {
|
|
float ratio = (1 - dist / 25);
|
|
|
|
float newx = _npcInfo[f].x + ratio * xdif / 3 * _fpsr;
|
|
float newy = _npcInfo[f].y + ratio * ydif / 3 * _fpsr;
|
|
|
|
int sx = (newx / 2 + 6);
|
|
int sy = (newy / 2 + 10);
|
|
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
|
|
if (dq == 0) {
|
|
_npcInfo[f].x = newx;
|
|
_npcInfo[f].y = newy;
|
|
// _npcinfo[f].castpause = _ticks + 200;
|
|
} else {
|
|
int xpass = 0;
|
|
int ypass = 0;
|
|
|
|
sx = (newx / 2 + 6);
|
|
sy = (_npcInfo[f].y / 2 + 10);
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
|
|
if (dq == 0)
|
|
xpass = 1;
|
|
|
|
|
|
sx = (_npcInfo[f].x / 2 + 6);
|
|
sy = (newy / 2 + 10);
|
|
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
dq = *temp;
|
|
|
|
if (dq == 0)
|
|
ypass = 1;
|
|
|
|
if (ypass == 1) {
|
|
newx = _npcInfo[f].x;
|
|
} else if (xpass == 1) {
|
|
newy = _npcInfo[f].y;
|
|
}
|
|
|
|
if (xpass == 1 || ypass == 1) {
|
|
_npcInfo[f].x = newx;
|
|
_npcInfo[f].y = newy;
|
|
// _npcinfo[f].castpause = _ticks + 200;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// fire
|
|
if (spellnum == 3) {
|
|
float fr = (32 - _spellInfo[i].frame);
|
|
|
|
fr = fr * fr * (1 - cos(3.14159 / 4 + 3.14159 / 4 * fr / 32));
|
|
|
|
if (fr > 32)
|
|
fr = 32;
|
|
|
|
float s = 8;
|
|
if (_spellInfo[i].frame < 8)
|
|
s = _spellInfo[i].frame;
|
|
|
|
int fra = (int)fr;
|
|
|
|
for (int f = 0; f <= 4; f++) {
|
|
for (int x = 0; x <= fra; x += 2) {
|
|
if (_spellInfo[i].legalive[f] >= x) {
|
|
int alpha = 192 * sin(3.14159 * x / 32) * s / 8;
|
|
|
|
float an = 360 / 5 * f + x / 32 * 180;
|
|
|
|
rcSrc.left = 16 * (int)(RND() * 2);
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
float xloc = (float)(_spellInfo[i].enemyx + 4 + x * 2 * cos(3.14159 / 180 * an) + (int)(RND() * 3) - 1);
|
|
float yloc = (float)(_spellInfo[i].enemyy + 4 + x * 2 * sin(3.14159 / 180 * an) + (int)(RND() * 3) - 1);
|
|
rcDest.left = (int)xloc;
|
|
rcDest.top = (int)yloc;
|
|
|
|
if (xloc > -1 && xloc < 304 && yloc > -1 && yloc < 224) {
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(alpha, 255, 255, 255));
|
|
|
|
int sx = (xloc / 2 + 4);
|
|
int sy = (yloc / 2 + 8);
|
|
|
|
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
|
uint32 dq = *temp;
|
|
|
|
if (dq > 1000 && x > 4)
|
|
_spellInfo[i].legalive[f] = x;
|
|
|
|
if (_spellInfo[i].damagewho == 0) {
|
|
for (int e = 1; e <= _lastNpc; e++) {
|
|
float xdif = (xloc + 8) - (_npcInfo[e].x + 12);
|
|
float ydif = (yloc + 8) - (_npcInfo[e].y + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
float damage = (float)_player.spellDamage * (1.0 + RND() * 0.5) * (float)_spellInfo[i].strength;
|
|
|
|
if (_npcInfo[e].spriteset == kMonsterFireHydra)
|
|
damage = -damage;
|
|
if (_npcInfo[e].spriteset == kMonsterFinalBoss)
|
|
damage = -damage;
|
|
if (_npcInfo[e].hp > 0 && _npcInfo[e].pause < _ticks) {
|
|
damageNPC(e, damage, 1);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndFire]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_spellInfo[i].damagewho == 1) {
|
|
float xdif = (xloc + 8) - (_player.px + 12);
|
|
float ydif = (yloc + 8) - (_player.py + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8) && _player.pause < _ticks) {
|
|
float damage = (float)_npcInfo[_spellInfo[i].npc].spellDamage * (1.0 + RND() * 0.5);
|
|
|
|
if (_player.hp > 0) {
|
|
damagePlayer(damage);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndFire]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for post damage
|
|
if (_postInfoNbr > 0) {
|
|
for (int e = 0; e <= _postInfoNbr - 1; e++) {
|
|
float xdif = (xloc + 8) - (_postInfo[e][0] + 8);
|
|
float ydif = (yloc + 8) - (_postInfo[e][1] + 8);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8)) {
|
|
_objectMapFull[_curMap][(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = 1;
|
|
_objectMap[(int)_postInfo[e][0] / 16][(int)_postInfo[e][1] / 16] = -1;
|
|
|
|
rcSrc.left = _postInfo[e][0] / 2;
|
|
rcSrc.top = _postInfo[e][1] / 2;
|
|
rcSrc.setWidth(8);
|
|
rcSrc.setHeight(8);
|
|
|
|
_clipBg2->fillRect(rcSrc, 0);
|
|
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndFire]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
|
|
addFloatIcon(99, _postInfo[e][0], _postInfo[e][1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.2 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
// sprite 6 spitfire
|
|
if (spellnum == 7) {
|
|
float xspan = _spellInfo[i].enemyx - _spellInfo[i].homex;
|
|
float yspan = _spellInfo[i].enemyy - _spellInfo[i].homey;
|
|
float fr = (32 - _spellInfo[i].frame);
|
|
|
|
for (int f = 0; f <= 7; f++) {
|
|
int alpha = 0;
|
|
float xx = 0;
|
|
if (fr > f * 2 && fr < f * 2 + 16)
|
|
xx = fr - f * 2;
|
|
if (xx < 8)
|
|
alpha = 255 * xx / 8;
|
|
if (xx > 8)
|
|
alpha = 255 * (1 - (xx - 8) / 8);
|
|
float yy = 16 * sin(3.141592 / 2 * xx / 16) - 8;
|
|
|
|
alpha = CLIP(alpha, 0, 255);
|
|
|
|
rcSrc.left = 16 * (int)(RND() * 2);
|
|
rcSrc.top = 80;
|
|
rcSrc.setWidth(16);
|
|
rcSrc.setHeight(16);
|
|
|
|
float xloc = _spellInfo[i].homex + xspan / 7 * f;
|
|
float yloc = _spellInfo[i].homey + yspan / 7 * f - yy;
|
|
|
|
rcDest.left = xloc;
|
|
rcDest.top = yloc;
|
|
|
|
if (xloc > -16 && xloc < 320 && yloc > -16 && yloc < 240) {
|
|
_spellImg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(alpha, 255, 255, 255));
|
|
|
|
if (_spellInfo[i].damagewho == 1) {
|
|
float xdif = (xloc + 8) - (_player.px + 12);
|
|
float ydif = (yloc + 8) - (_player.py + 12);
|
|
|
|
if ((ABS(xdif) < 8 && ABS(ydif) < 8) && _player.pause < _ticks && alpha > 64) {
|
|
float damage = (float)_npcInfo[_spellInfo[i].npc].spellDamage * (1.0 + RND() * 0.5);
|
|
|
|
if (_player.hp > 0) {
|
|
damagePlayer(damage);
|
|
if (config.effects) {
|
|
int snd = playSound(_sfx[kSndFire]);
|
|
setChannelVolume(snd, config.effectsVol);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_spellInfo[i].frame = _spellInfo[i].frame - 0.5 * _fpsr;
|
|
if (_spellInfo[i].frame < 0)
|
|
_spellInfo[i].frame = 0;
|
|
|
|
if (ABS(_spellInfo[i].frame) < kEpsilon) {
|
|
_npcInfo[_spellInfo[i].npc].attacking = false;
|
|
_npcInfo[_spellInfo[i].npc].attacknext = _ticks + _npcInfo[_spellInfo[i].npc].attackdelay;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} // end of namespace Griffon
|